enabling SSH

https://randomnerdtutorials.com/installing-raspbian-lite-enabling-and-connecting-with-ssh/


Establishing an SSH Communication

$ sudo ssh pi@192.168.178.25

user: pi, pass: pi


Shutting Down

$ sudo poweroff





https://randomnerdtutorials.com/raspberry-pi-apache-mysql-php-lamp-server/

https://www.instructables.com/Installing-LAMP-Linux-Apache-MySQL-PHP-on-a-Raspbe/



Updating and Upgrading

$ sudo apt update && sudo apt upgrade -y





Install Apache2

$ sudo apt install apache2 -y


Testing Apache installation

$ cd /var/www/html

$ ls -al

This should show “index.html”


get RasPi IP address

$ hostname -I


enter IP address into Browser → the Apache Debian page should appear





Install PHP

$ cd /var/www/html

$ sudo apt install php -y

$ sudo rm index.html


$ sudo nano index.php

Add following script into the php file:

<?php echo "hello world"; ?>

Save with Ctrl+X >> y >> Enter, or Ctrl+O >> Enter >> Ctrl+X

OR

<?php phpinfo(); ?>

OR

$ echo "<?php phpinfo ();?>" > /var/www/html/index.php


Restart Apache

$ sudo service apache2 restart


test if Apache2 is serving .php files by opening RasPi IP address in browser


if all is fine, index.php can be removed

$ sudo rm index.php




Install MySQL (MariaDB Server)

$ sudo apt install mariadb-server php-mysql -y

$ sudo service apache2 restart

$ sudo mysql_secure_installation

In all cases, answer with y


create new user “admin” with password “your_password”

$ sudo mysql --user=root --password

> create user admin@localhost identified by 'your_password';

> grant all privileges on *.* to admin@localhost;

> FLUSH PRIVILEGES;

> exit;


Important to generate user that is not limited to a certain domain!!

> grant all privileges on *.* to 'admin3'@'%';





Install phpMyAdmin

$ cd /var/www/html

$ sudo apt install phpmyadmin -y


Options:


$ sudo phpenmod mysqli

$ sudo service apache2 restart


open following address

http://192.168.178.25/phpmyadmin


if “Not Found”

$ cd /var/www/html

$ sudo ln -s /usr/share/phpmyadmin /var/www/html/phpmyadmin

$ ls

>> phpmyadmin


again, open following address

http://192.168.178.25/phpmyadmin


login with username=root, password=pi





change the permissions for your /var/www/html/ folder.

$ cd ~

$ ls -lh /var/www/

$ sudo chown -R pi:www-data /var/www/html/

$ sudo chmod -R 770 /var/www/html/

$ ls -lh /var/www/













https://randomnerdtutorials.com/esp32-esp8266-raspberry-pi-lamp-server/



Create database:



Create table by calling SQL query:

CREATE TABLE SensorData (

id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,

sensor VARCHAR(30) NOT NULL,

location VARCHAR(30) NOT NULL,

value1 VARCHAR(10),

value2 VARCHAR(10),

value3 VARCHAR(10),

reading_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP

)



PHP script that is responsible for receiving incoming requests from the ESP32 or ESP8266 and inserting the data into a MySQL database.

$ cd ~

$ nano /var/www/html/post-esp-data.php








https://github.com/ChuckBell/MySQL_Connector_Arduino/wiki/Troubleshooting

tr to connect to msql from another computer:

$ mysql -uadmin -ppi –h192.168.178.25 –port=3306

$ mysql --user=admin --password=pi --host=192.168.178.25 --port=3306

$ mysql --user=admin --password=pi --host= 127.0.0.1 --port=3306


$ mysql -u admin -p pi -h 127.0.0.1 test_arduino




Important in case of “ERROR 2003 (HY000): Can't connect to local MySQL server through socket”

$ sudo nano /etc/mysql/mariadb.conf.d/50-server.cnf

Here, the binding address = 127.0.0.1 must be commented out!!!






https://pawelrychlicki.pl/Article/Details/65/fixing-sqlstatehy000-2002-in-the-nextcloudowncloud-with-the-mysqlmariadb-and-the-tlsssl-ubuntu-linux-1804-server







1Configuring WiFi in headless mode

https://www.raspberrypi.org/documentation/configuration/wireless/wireless-cli.md

https://www.seeedstudio.com/blog/2021/01/25/three-methods-to-configure-raspberry-pi-wifi/



1.1ssh

To enable SSH on a headless Raspberry Pi, simply place a file named “ssh”, without any extension, onto the boot partition of the SD card from another computer. This will tell Raspberry Pi to enable SSH when booting. The content of the file does not matter.



1.2wpa_supplicant.conf

$ sudo nano /etc/wpa_supplicant/wpa_supplicant.conf



ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev

update_config=1

country=<Country Code>

network={

ssid="<SSID>"

psk="<PASSWORD>"

scan_ssid=1

}



2Arduino script for writing to MariaDB/MySQL database

Check sketch “Complex_Insert_WiFi_BE”







3Showing DB content as html page

https://randomnerdtutorials.com/esp32-esp8266-raspberry-pi-lamp-server/



$ nano /var/www/html/esp-data.php



open page http://192.168.178.25/esp-data.php



3.1esp-data.php

<!DOCTYPE html>

<html><body>

<?php

/*

Rui Santos

Complete project details at https://RandomNerdTutorials.com/esp32-esp8266-mysql-database-php/

Permission is hereby granted, free of charge, to any person obtaining a copy

of this software and associated documentation files.

The above copyright notice and this permission notice shall be included in all

copies or substantial portions of the Software.

*/



$servername = "192.168.178.25";



// REPLACE with your Database name

$dbname = "test_arduino";

// REPLACE with Database user

$username = "admin3";

// REPLACE with Database user password

$password = "pi";



// Create connection

$conn = new mysqli($servername, $username, $password, $dbname);

// Check connection

if ($conn->connect_error) {

die("Connection failed: " . $conn->connect_error);

}



$sql = "SELECT num, message, sensor_num, value, recorded FROM hello_sensor ORDER BY num DESC";



echo '<table cellspacing="5" cellpadding="5">

<tr>

<td>num</td>

<td>message</td>

<td>sensor_num</td>

<td>value</td>

<td>recorded</td>

</tr>';

if ($result = $conn->query($sql)) {

while ($row = $result->fetch_assoc()) {

$row_num = $row["num"];

$row_message = $row["message"];

$row_sensor_num = $row["sensor_num"];

$row_value = $row["value"];

$row_recorded = $row["recorded"];

// Uncomment to set timezone to - 1 hour (you can change 1 to any number)

//$row_reading_time = date("Y-m-d H:i:s", strtotime("$row_reading_time - 1 hours"));

// Uncomment to set timezone to + 4 hours (you can change 4 to any number)

//$row_reading_time = date("Y-m-d H:i:s", strtotime("$row_reading_time + 4 hours"));

echo '<tr>

<td>' . $row_num . '</td>

<td>' . $row_message . '</td>

<td>' . $row_sensor_num . '</td>

<td>' . $row_value . '</td>

<td>' . $row_recorded . '</td>

</tr>';

}

$result->free();

}



$conn->close();

?>

</table>

</body>

</html>







4Plotting of data from MariaDB/MySQL database

https://randomnerdtutorials.com/visualize-esp32-esp8266-sensor-readings-from-anywhere/



$ sudo nano /var/www/html/esp-chart.php

4.1esp-chart.php



<!--

Rui Santos

Complete project details at https://RandomNerdTutorials.com

Permission is hereby granted, free of charge, to any person obtaining a copy

of this software and associated documentation files.

The above copyright notice and this permission notice shall be included in all

copies or substantial portions of the Software.



-->

<?php



$servername = "192.168.178.25";



// REPLACE with your Database name

$dbname = "test_arduino";

// REPLACE with Database user

$username = "admin3";

// REPLACE with Database user password

$password = "pi";



// Create connection

$conn = new mysqli($servername, $username, $password, $dbname);

// Check connection

if ($conn->connect_error) {

die("Connection failed: " . $conn->connect_error);

}



$sql = "SELECT num, message, sensor_num, value, value_h, recorded FROM hello_sensor WHERE sensor_num = 0 ORDER BY num DESC limit 40";



$result = $conn->query($sql);



while ($data = $result->fetch_assoc()){

$sensor_data[] = $data;

}



$recorded = array_column($sensor_data, 'recorded');



// ******* Uncomment to convert readings time array to your timezone ********

/*$i = 0;

foreach ($readings_time as $reading){

// Uncomment to set timezone to - 1 hour (you can change 1 to any number)

$readings_time[$i] = date("Y-m-d H:i:s", strtotime("$reading - 1 hours"));

// Uncomment to set timezone to + 4 hours (you can change 4 to any number)

//$readings_time[$i] = date("Y-m-d H:i:s", strtotime("$reading + 4 hours"));

$i += 1;

}*/



$value = json_encode(array_reverse(array_column($sensor_data, 'value')), JSON_NUMERIC_CHECK);

$value_h = json_encode(array_reverse(array_column($sensor_data, 'value_h')), JSON_NUMERIC_CHECK);

$recorded = json_encode(array_reverse($recorded), JSON_NUMERIC_CHECK);



/*echo $value1;

echo $value2;

echo $value3;

echo $reading_time;*/



$result->free();

$conn->close();

?>



<!DOCTYPE html>

<html>

<meta name="viewport" content="width=device-width, initial-scale=1">

<script src="https://code.highcharts.com/highcharts.js"></script>

<style>

body {

min-width: 310px;

max-width: 1280px;

height: 500px;

margin: 0 auto;

}

h2 {

font-family: Arial;

font-size: 2.5rem;

text-align: center;

}

</style>

<body>

<h2>ESP Weather Station</h2>

<div id="chart-temperature" class="container"></div>

<div id="chart-humidity" class="container"></div>

<script>



var value = <?php echo $value; ?>;

var value_h = <?php echo $value_h; ?>;

var recorded = <?php echo $recorded; ?>;



var chartT = new Highcharts.Chart({

chart:{ renderTo : 'chart-temperature' },

title: { text: 'BME280 Temperature' },

series: [{

showInLegend: false,

data: value

}],

plotOptions: {

line: { animation: false,

dataLabels: { enabled: true }

},

series: { color: '#059e8a' }

},

xAxis: {

type: 'datetime',

categories: recorded

},

yAxis: {

title: { text: 'Temperature (Celsius)' }

//title: { text: 'Temperature (Fahrenheit)' }

},

credits: { enabled: false }

});







var chartH = new Highcharts.Chart({

chart:{ renderTo:'chart-humidity' },

title: { text: 'BME280 Humidity' },

series: [{

showInLegend: false,

data: value_h

}],

plotOptions: {

line: { animation: false,

dataLabels: { enabled: true }

}

},

xAxis: {

type: 'datetime',

//dateTimeLabelFormats: { second: '%H:%M:%S' },

categories: recorded

},

yAxis: {

title: { text: 'Humidity (%)' }

},

credits: { enabled: false }

});



</script>

</body>

</html>











5Using canvas.js

https://canvasjs.com/php-charts/multiseries-chart/







6External access to LAMP server

port 22 (ssh), port 80 (http)



https://raspberrypi.stackexchange.com/questions/105080/how-to-remote-to-raspberry-pi-from-outside-local-network



https://howtoraspberrypi.com/enable-mysql-remote-connection-raspberry-pi/

Configure MySQL to accept external connections to Raspberry Pi

$ sudo nano /etc/mysql/my.cnf

#bind-address = 127.0.0.1 <<<<< comment the line bind-address

optionally modify the MySQL port to reduce risk of attacks, e.g.

port = 8457



$ /etc/init.d/mysql restart





7RasPi as Samba server

https://aallan.medium.com/adding-an-external-disk-to-a-raspberry-pi-and-sharing-it-over-the-network-5b321efce86a

SMB is the best protocol for use on multiple platforms due to superior interoperability



in case of issue “chown: changing ownership of '...': Operation not permitted”:

https://stackoverflow.com/questions/25559700/chown-command-returning-operation-not-permitted

get uid:

$ cat /etc/passwd |grep pi

get gid:

$ cat /etc/group |grep pi

Give pi:pi access to the entire /mnt/usb mount:

$ sudo mount -o remount,gid=<pi's gid>,uid=<pi's uid> /mnt/usb



Attention: FAT file system doesn't support such permissions, so they can't be applied after the drive is mounted

https://raspberrypi.stackexchange.com/questions/40408/how-to-change-permissions-on-external-hard-drive-connected-to-raspberry

Instead, drive should be formatted with pi user and/or ntfs file sstem?





Mounting USB drive that is NTFS???-formatted under specific name:

$ sudo fdisk -l

$ sudo umount /dev/sda1

$ sudo mkdir /mnt/usb

$ sudo chown -R pi:pi /mnt/usb

seems like this command has to be used each time the usb drive is connected: $ sudo mount /dev/sda1 /mnt/usb -o uid=pi,gid=pi



append following text to this file for automatic mounting under the specified path:

$ sudo nano /etc/fstab

/dev/sda1 /mnt/usb auto defaults,user 0 1

OR:

/dev/sda1 /mnt/usb ntfs-3g defaults,user,uid=1000,gid=1000,noatime 0 0

https://raspberrypi.stackexchange.com/questions/40408/how-to-change-permissions-on-external-hard-drive-connected-to-raspberry









Make the drive accessible from the network by adding following text:

$ sudo apt-get install samba samba-common-bin

$ sudo nano /etc/samba/smb.conf

[share]

Comment = Shared Folder

Path = /mnt/usb

Browseable = yes

Writeable = Yes

only guest = no

create mask = 0777

directory mask = 0777

Public = yes

Guest ok = yes



$ chmod 1777 /mnt/usb <<<< the uSB should be mounted under this name

$ sudo /etc/init.d/samba restart





sudo service smbd restart

sudo service smbd status





https://www.raspberrypi.org/forums/viewtopic.php?t=56149

$ sudo df

$ cd /media

$ sudo mkdir HDD

$ sudo nano /etc/fstab

/dev/sda1 /media/HDD ntfs-3g defaults,noatime 0 0

$ cp /etc/samba/smb.conf /etc/samba/smb.conf.bak //Make a backup of the config file

$ nano /etc/samba/smb.conf

[media]

comment = Media share

path = /media/HDD

valid users = @users

force group = users

create mask = 0660

directory mask = 0771

read only = no





sudo service samba restart

sudo useradd ChooseUsernameHere -m -G users

sudo passwd TheChosenUsername //after this choose a password for the new user

sudo smbpasswd -a TheChosenUsername //after this enter passwd again

>>>>>>>>>>> userA pi







mount in Win10/Linux/etc. as smb://192.168.178.25/







https://raspberrytips.com/format-mount-usb-drive/

Formatting USB stick with RasPi:

$ sudo fdisk -l

$ sudo fdisk /dev/sda1

Create a new partition table : g (for GPT, use help for other format)

Create a new partition : n

You can keep the default values for a single partition

Confirm with Y to remove the signature

And finally write and exit fdisk: w

$ sudo mkfs.ext4 /dev/sda1
OR: $ sudo mkfs.vfat /dev/sda1
OR: $ sudo mkfs.ntfs /dev/sda1





https://thepihut.com/blogs/raspberry-pi-tutorials/17699796-formatting-and-mounting-a-usb-drive-from-a-terminal-window

$ sudo mkfs -t vfat -I /dev/sda1

$ sudo mount /dev/sda1 /mnt/usb -o umask=000

$ sudo umount /mnt/usb







8Filtering rows with SQL

https://chartio.com/blog/simple-sql-filtering-rows/

SELECT column_name1, column_name2

FROM table_name

WHERE column_name1 operator value;



SELECT *

FROM hello_sensor

WHERE sensor_num = 0

ORDER BY `hello_sensor`.`recorded` DESC





9Python MySQL

9.1Python MySQL Querying Data

https://stackoverflow.com/questions/44634810/fastest-way-to-fetch-table-from-mysql-into-pandas

MyEngine=create_engine('[YourDatabase]://[User]:[Pass]@[Host]/[DatabaseName]', echo = True)

Downloading:

df = pd.read_sql_query('select * from [TableName]', con= MyEngine)

Uploading:

df.to_sql([TableName], MyEngine, if_exists = 'append', index=False)





9.2Using mysql module

https://www.mysqltutorial.org/python-mysql-query/

https://www.codespeedy.com/fetch-data-from-mysql-table-in-python-program/

https://www.krazyprogrammer.com/2020/11/fetch-and-display-data-from-mysql-using.html

pip install mysql-connector



https://www.tutorialspoint.com/python_mysql/python_mysql_select_data.htm



import mysql.connector



#establishing the connection

conn = mysql.connector.connect(

user='admin3', password='pi', host='192.168.178.25', database='test_arduino'

)



#Creating a cursor object using the cursor() method

cursor = conn.cursor()



#Retrieving single row

query = '''SELECT * from hello_sensor'''



#Executing the query

cursor.execute(query)



#Fetching 1st row from the table

result = cursor.fetchone();

print(result)



#Fetching first two rows from the table

result = cursor.fetchmany(size=2);

print(result)



#Fetching all rows from the table

result = cursor.fetchall();

print(result)



#Closing the connection

conn.close()





9.3Create table

https://www.tutorialspoint.com/python_mysql/python_mysql_create_table.htm

import mysql.connector



#establishing the connection

conn = mysql.connector.connect(

user='root', password='password', host='127.0.0.1', database='mydb'

)



#Creating a cursor object using the cursor() method

cursor = conn.cursor()



#Dropping EMPLOYEE table if already exists.

cursor.execute("DROP TABLE IF EXISTS EMPLOYEE")



#Creating table as per requirement

sql ='''CREATE TABLE EMPLOYEE(

FIRST_NAME CHAR(20) NOT NULL,

LAST_NAME CHAR(20),

AGE INT,

SEX CHAR(1),

INCOME FLOAT

)'''

cursor.execute(sql)



#Closing the connection

conn.close()



9.4Insert data

https://www.tutorialspoint.com/python_mysql/python_mysql_insert_data.htm

import mysql.connector

#establishing the connection

conn = mysql.connector.connect(

user='root', password='password', host='127.0.0.1', database='mydb'

)

#Creating a cursor object using the cursor() method

cursor = conn.cursor()

# Preparing SQL query to INSERT a record into the database.

insert_stmt = (

"INSERT INTO EMPLOYEE(FIRST_NAME, LAST_NAME, AGE, SEX, INCOME)"

"VALUES (%s, %s, %s, %s, %s)"

)

data = ('Ramya', 'Ramapriya', 25, 'F', 5000)

try:

# Executing the SQL command

cursor.execute(insert_stmt, data)

# Commit your changes in the database

conn.commit()

except:

# Rolling back in case of error

conn.rollback()

# Closing the connection

conn.close()







10Schedule periodic RasPi reboot

https://raspberrypi.stackexchange.com/questions/2150/how-do-i-reboot-at-a-specific-time

https://smarthomepursuits.com/how-to-reboot-raspberry-pi-on-a-schedule/

$ sudo crontab -e

>>>>> choose nano editor

>>>>> enter following command at end of file for daily reboot at 13:03:

03 13 * * * /sbin/shutdown -r now



Check time in Linux commandline:

https://www.lifewire.com/display-date-time-using-linux-command-line-4032698

$ date







11Install KeePass

https://keepass.info/download.html

https://sourceforge.net/p/keepass/discussion/329220/thread/17d1bd26/

sudo apt-add-repository ppa:jtaylor/keepass

sudo apt-get update

sudo apt-get install keepass2







12Clean the repository of downloaded packages

https://askubuntu.com/questions/634820/how-can-i-delete-ubuntu-temp-files-which-are-created-during-software-installatio

sudo apt-get autoclean

sudo apt-get clean







13cleanup a /var/log/journal in Linux



How to tell how much space is being taken?

$ journalctl --disk-usage



Fix: Option 3 (RECOMMENDED!):

$ journalctl --vacuum-size=500M

This will delete old log files until the directory reaches the threshold size stipulated, in our case, 500M.







14Change permission of mounted drive

$ sudo chmod -R 770 /media/bora/Medien

sudo mount -o rw,remount /media/bora/Medien



https://askubuntu.com/questions/948416/changing-ownership-of-read-only-file-system-i-cant-move-delete-rename-any-f

$ mount -v | grep "^/" | awk '{print "\nPartition identifier: " $1 "\n Mountpoint: " $3}'

$ sudo mount -o remount,rw /dev/sda5 /media/bora/Medien





If you are on a dual boot system and getting the error related to the read-only file system. One probable cause could be that your other system is not correctly shut down and might be in hibernation or sleep. So login to that system and shut it down properly and religion to your Linux system. this resolved the issue in my system”