AdSense

Sunday 30 August 2020

Home Automation with a Raspberry PI and ESP8266, part 1: Basics (Raspberry PI)

(Deutsche Version) Today, I want to start presenting my smart home system. I started half a year ago and by now, the system has grown quite big. The current system consists of:

  • 6 temperature- and humidity sensors inside
  • 3 temperature- and humidity sensors outside
  • 2 temperature- and humidity sensors in our terrarium
  • 1 CO2 sensor
  • 5 switchable plug sockets
  • 3 switchable lamps
  • 1 switch for the input of the sound system
  • Sensors at the washing mashine and tumble dryer
  • Microphone and two cameras at the 3d printer
  • Dashboard as website on an old tablet resp. on the smartphone
  • Telegram bot with automatic alerts and commandos

The basic for everything is a Raspberry PI 4, who acts as a server in the WiFi. All data is stored here, the website is placed here and all sensors communicate with the Raspberry. You don't have to setup much on the raspberry, I installed the apache2 webserver, you can find a lot of tutorials on this topic on the internet. Basically it can be condensed to this one command:

sudo apt install apache2

Additionally, I installed apache2 for php with this command:

sudo apt-get install php libapache2-mod-php

These are all the requirements on the Raspberry. I recommend to setup the folder /var/www/html/ as a network share, then you can access all files and scripts from other computers. Additionally, you should create the folder /var/www/html/data/, all data files are located here.

Now we can start with the scripts. I will only describe the basic script to send data, all other modifications and scripts will be presented with the relevant posts. To send data, I use the file "SendValues.php", which requests the following GET parameters from the sensor:

  • "name", the name of the sensor, e.g. "TemperatureSensor_1"
  • "split", how the data should be split. The problem would be files accumulating the data over years, making them very big and hard to handle. Therefore, the data is split by year, month or day. Split 0 means no splitting, 1 equals one file per year, 2 one file per month and 3 one file per day
  • "data", the relevant data, separated by comma, e.g. for a temperature and humidity sensor: 24.1,54.6

The script consists of the following parts. At first the header:

<html>
 <head>
  <title>Send Sensor Values</title>
 </head>
 <body>
  <?php 

Afterwards the relevant code. Here the data is read and the current date is determined:

$name = htmlspecialchars($_GET["name"]);
$split = htmlspecialchars($_GET["split"]);
$data = htmlspecialchars($_GET["data"]);

$date = gmdate("Y-m-d") . "T" . gmdate("H:i:s.u") . "Z";

Now, a [name]_last.csv file is created, which holds the newest value:

$file = "data/".$name."_last.csv";
$Saved_File = fopen($file, 'w');
fwrite($Saved_File, $date . "," . $data . "\r\n");
fclose($Saved_File);

Next, the splitting is performed. Therefore the filename is created, [name]_[year]-[month]-[day].csv. To have an overlap between two files, the next file is also created, for the next year, next month, next day and already holds the values. If e.g. the last year is requested this guarantees that every file contains at least one year of data, not only the values starting from January 1st. $file1 is the current file, $file2 the one for the next time period.

$file = "data/".$name.".csv";

if ($split == "1")
{
  $file = "data/".$name."_" . gmdate("Y") . ".csv";
  $file2 = "data/".$name."_" . gmdate("Y", strtotime("+1 year")) . ".csv";
}
if ($split == "2")
{
  $file = "data/".$name."_" . gmdate("Y-m") . ".csv";
  $file2 = "data/".$name."_" . gmdate("Y-m", strtotime("+1 month")) . ".csv";
}
if ($split == "3")
{
  $file = "data/".$name."_" . gmdate("Y-m-d") . ".csv";
  $file2 = "data/".$name."_" . gmdate("Y-m-d", strtotime("+1 day")) . ".csv";
}

Now the data is saved. If "split" is 0, the saving into the second file is skipped as there only exists one single file for the whole time.

$Saved_File = fopen($file, 'a');
fwrite($Saved_File, $date . "," . $data . "\r\n");
fclose($Saved_File);
if ($split == "0")
{
}
else
{
  $Saved_File = fopen($file2, 'a');
  fwrite($Saved_File, $date . "," . $data . "\r\n");
  fclose($Saved_File);
}

This already was the whole code, we now have to close all the tags and then SendValues.php is completed:

  ?>
 </body>
</html>

This is all you need on the server site, now the sensors can send their data. To test this, you can put the following text into your browser within your WiFI, this should create the files TemperatureSensor_1_last.csv, and two additional files with the current and the next year at the end:

http://raspberrypi/SendValues.php?name=TemperatureSensor_1&split=1&data=25.3,64.59

For everyone not wanting to copy the code parts, here is the complete code:

<html>
 <head>
  <title>Send Sensor Values</title>
 </head>
 <body>
  <?php
 
$name = htmlspecialchars($_GET["name"]);
$split = htmlspecialchars($_GET["split"]);
$data = htmlspecialchars($_GET["data"]);

$date = gmdate("Y-m-d") . "T" . gmdate("H:i:s.u") . "Z";

$file = "data/".$name."_last.csv";
$Saved_File = fopen($file, 'w');
fwrite($Saved_File, $date . "," . $data . "\r\n");
fclose($Saved_File);

$file = "data/".$name.".csv";

if ($split == "1")
{
  $file = "data/".$name."_" . gmdate("Y") . ".csv";
  $file2 = "data/".$name."_" . gmdate("Y", strtotime("+1 year")) . ".csv";
}
if ($split == "2")
{
  $file = "data/".$name."_" . gmdate("Y-m") . ".csv";
  $file2 = "data/".$name."_" . gmdate("Y-m", strtotime("+1 month")) . ".csv";
}
if ($split == "3")
{
  $file = "data/".$name."_" . gmdate("Y-m-d") . ".csv";
  $file2 = "data/".$name."_" . gmdate("Y-m-d", strtotime("+1 day")) . ".csv";
}
$Saved_File = fopen($file, 'a');
fwrite($Saved_File, $date . "," . $data . "\r\n");
fclose($Saved_File);
if ($split == "0")
{
}
else
{
  $Saved_File = fopen($file2, 'a');
  fwrite($Saved_File, $date . "," . $data . "\r\n");
  fclose($Saved_File);
}

  ?>
 </body>
</html>

No comments:

Post a Comment