Skip to content

System Control

tvdtogt edited this page May 3, 2020 · 1 revision

The Astroplant has a central control that schedules measurements, lighting and other actions. To get started we make a few modules to learn how to control a Pi.

Combining the separate sensor test scripts into one central control script

Step 1 Read and display all

Starting from the scripts we used in block 2 to test the individual sensors, we can make a complete script to read all sensors and display the measurements on the LCD display. With a loop in your script, you can repeat this every x minutes. One way to do this is to concatenate all original test scripts in one large script, but that will make it unreadable. Instead we use the test scripts as modules that can be called from the central script.

To use the sensor test scripts as modules it is important that these contain a function that you can call. For example the light sensor script bh1750.py has a function readLight() that returns a value. To import the script from the central script use 'import bh1750' (notice that you omit the .py) To read the sensor from the central script then use 'bh1750.readLight()'

To prevent the script to hang if one sensor is not responding, you can use a 'try'/'except' statement that will return an exception.

Exercise

Try if you can make a script yourself that displays all measurements on the LCD in a loop (once a minute)

Step 2 Read and write all

Since you do not want to monitor your Astroplant all the time yourself, you could write all measurements to a logfile. We choose the CSV file format for this. CSV stands for Comma Separated Value. CSV-files use a comma to seperate the data fields. Instead of a comma, you can use a semi-colon (;) or other delimitator. A CSV file stores tabular data (numbers and text) in plain text. Each line of the file is a data record and each record consists of one or more fields. CSV-files can be opened with either text-editors, such as Notepad or MS Word, or with spreadsheets, such as MS Excel.

Before we write our measurement data to a file, we check if there is already a file with the given file name: if not we make one and add a header row, with Datetime (Y-m-d h:m), temperature, humidity, co2, light, water temperature. If the file already exists we append our measurements as a additional row.

An example can be found as read_and_write_all.py

Or alternative: csv_writer.py

Step 3: Starting your script automatically on boot

The Raspberry Pi's operating system Raspbian enables us to add extra processes to the start up schedule. We can do this with the functions crontab or systemd.

Crontab

Crontab is short for cron table and is a time based job-scheduler, but it can also run scripts at boot. However, with crontab we are not able to schedule the order of the processes, we can only start it at boot. Cron is very easy to use. We can open it by typing

$ crontab -e

The general usage of cron is described in the table below:

# ┌───────────── minute (0 - 59)
# │ ┌───────────── hour (0 - 23)
# │ │ ┌───────────── day of the month (1 - 31)
# │ │ │ ┌───────────── month (1 - 12)
# │ │ │ │ ┌───────────── day of the week (0 - 6) (Sunday to Saturday;
# │ │ │ │ │                                   7 is also Sunday on some systems)
# │ │ │ │ │
# │ │ │ │ │
# * * * * * command to execute

However, since we want to run our script at boot we use the command "@reboot". We add a line at the bottom with the following structure:

$ @reboot python3 /home/your/path/yourfile.py

Systemd

Systemd is somewhat more recent than crontab. With systemd we have control over the order of the processes. If we want to run a python file at boot we have to create two files: the python file AND a service file that runs the python file.

Two good resources on systemd can be found on the raspberry pi website and in this blog post

We added an example of such a service file read_and_send_all.service, which you can adapt. To use a script first copy it to /lib/systemd/system/

To start:

sudo systemctl start read_and_send_all.service

To stop:

sudo systemctl stop read_and_send_all.service

To check:

sudo systemctl status read_and_send_all.service

If everything works fine you can configure your service to start automatically on reboot with:

sudo systemctl enable read_and_send_all.service

Exercise

Open the csv_writer.py file with an editor to check the code. Make sure the path of the 4 scripts to read the sensors is right. Test it separately first.

Now you can open crontab and set the csv_writer.py script to be run every 5 minutes. Crontab uses the time of the Raspberry Pi to start a certain script. Cron uses the following structure:

`$ m h dom mon dow command path/file

Here 'm' stands for minute, 'h' for hour, 'dom' for day-of-month, 'mon' for month, 'dow' for day of week. In the example below a script is called every monday at 5 am:

`$ 0 5 * * 1 python3 /home/pi/Desktop/script.py

In the example below a script is read every thirty minutes:

`$ */30 * * * * python3 /home/pi/Desktop/script.py

In the last example the script is read at 6 AM and 18 PM:

`$ * 6,18 * * * python3 /home/pi/Desktop/script.py

Step 4: Add LED and fan control

A script led_control_from_light_recipe.py controls the LEDs of the AstroPlant Explorer. It uses an external file 'light_recipe.json' to read the required light settings for a day.

Exercise

Try to combine this script with the script you made to read the sensors and display/write the measurements. What do you think is better: to run these processes after each other or in parallel?

Step 5: Add WiFi connection management

Since most of the Astroplant Explorers will run headless (that is without monitor and keyboard) it might be hard to know what is going on. So if you move your Explorer to another location and start it up, you will not see to what network it connects and what IP address it is given. That will make it very difficult to access it remotely. You can add some scripts that sart up at boot, to avoid that you will be locked out.

Connected to a known network

If the AstroPlant is (automatically) connected to a known network, it would be nice to show its IP address at start-up. To do this, you can use the script showIP.py. This script should be started automatically at boot in the background. (with cron or a systemd service like show_ip_at_startup.service)

We can use 'SSH' or Secure Shell to make a connection to the Raspberry from another computer, for example your laptop. With SSH you can send commands to your Raspberry, for example to read sensors. Normally we use a SSH-client such as PuTTy to connect to the RPi. VNC is also a great way to control your Pi remotely, but be aware that a Pi Zero might be pretty slow on that.

No known network: RaspiWiFi

The official AstroPlant is using RaspiWiFi software to make it easy to connect to your AstroPlant even if it is in a new environment and has no credentials for the local network. With a push on a button, the Pi will set up its own access point (with a SSID name like "AstroPlant AP" ) to which you can connect. When connected you can use any webbrowser to go to a webpage (on 10.0.0.1) , choose the name of the local network from a list, type in the Passkey, and restart the Pi which will show up nicely on the local network.

Alternative background control for safe shutdown

In the 'official' AstroPlant a background script (adapted from RaspiWiFi) will listen to the state of buttons 2 and 3. If button 3 is pressed lang enough, the Astroplant will either reboot to Access Point mode, if button 2 is pressed lang enough, the Astroplant will shutdown safely. Notice a considerable delay might occur.

Script shutdown_button.py will shutdown the RPi when pressed button 3 is pressed down for 5 seconds. Using crontab, this script could also be started at boot and will run in the background.