sarabsethi / rpi-eco-monitoring

Software for long-term autonomous ecosystem monitoring on a Raspberry Pi
https://sarabsethi.github.io/autonomous_ecosystem_monitoring/
GNU General Public License v3.0
42 stars 10 forks source link

rpi-eco-monitoring

This is part of a project developing a fully autonomous ecosystem monitoring unit. The full details of the device is described in an academic paper, easy to follow step by step instructions of setting one up from scratch can be found on our website, and this page focuses more on the details of the software running on the device, targeted at more technical users.

Information on how to build these devices into a fully functional real-time monitoring network can be found in a further academic paper, and full code and deployment notes for the associated server-side software can be found in the acoustics-db GitHub repository.

This code is not being actively maintained and may not work on newer Raspberry Pi devices / OS images (originally written in 2018). Designs and firmware for a more recently built similar device, Bugg can be found open-source at https://github.com/bugg-resources.

Code design

The setup.py script is used to configure the required sensor to be used for data capture and creates a JSON config fle. Once a sensor configuration has been created, the recorder is started up using recorder_startup_script.sh, which runs the record() function from python_record.py. This then does the following:

  1. Sets up error logging.
  2. Logs the id of the Pi device running the code and the current git version of the recorder script.
  3. Loads the config file.
  4. Sets the reboot time.
  5. Checks the working and upload directories for data files and copies previous logs into the upload directory.
  6. Runs the configure_sensor function to instantiate a sensor class object.
  7. Attaches the function exit_handler to run if a SIGINT signal is detected either from reboot or user interrupt.
  8. Creates a thread instance that executes the FTP synchronisation at a server sync interval defined by the sensor config using the ftp_server_sync() function.
  9. Creates a thread instance that runs the continuous_recording() function. This function is just a wrapper that repeats the sensor_record function while the thread is running.
  10. The sensor_record function itself executes the sensor methods: a) sensor.capture_data() to record whatever it is the sensor records; b) sensor.postprocess() is run in a separate thread to avoid locking up the sensor_record loop; and then c) sensor.sleep() to pause until the next sample is due.
  11. When a SIGINT occurs then exit_handler intercepts SIGINT and raises a StopMonitoring exception to exit the recording. The exception handling sets a threading event instance that has been passed to the two threads running ftp_server_sync() and continuous_recording(), and signals that the functions running in these thread should finish their current loop and exit. The record() function then exits.
  12. As long as recorder_startup_script.sh is setup to run on boot, then the process repeats from the first step.

Setup

Setup from our pre-prepared SD card image

To setup the monitoring unit from our pre-prepared SD card image follow these steps:

Setup from a stock Raspbian image

If you would rather start using a stock Raspbian image, there's an extra couple of steps before you start the above process. The below steps assume you have downloaded and installed the Raspbian Stretch Lite image.

You will need the Pi to be connected to the internet for the below process.

N.B. This clones the long-term support branch, which will have software that has been extensively field-tested, whilst the dev branch will have the latest development code which may inherently be more unstable. For long remote deployments we recommend only using the LTS branch, and this is the branch used in our pre-prepared SD card images. If you plan on implementing a new sensor, fork the codebase and make your changes, but be sure to submit a pull request back to this repo when you're done!

Implementing new sensors

To implement a new sensor type simply create a class in the sensors directory that extends the SensorBase class. The SensorBase class contains default implementations of the required class methods, which can be overridden in derived sensor classes. The required methods are:

Note that threads are used to run the capture_data and postprocess methods so that they operate independently.

For worked examples see classes made for monitoring audio from a USB audio card (USBSoundcardMic.py) and for capturing time-lapse images from a USB camera (TimelapseCamera.py). For a really simple example, see the UnixDevice sensor (UnixDevice.py): this just demonstrates the use of the class methods to read data from one of the basic system devices.

Finally add from sensors.YourNewSensor import YourNewSensor to sensors/__init__.py

Authors

This is a cross disciplinary research project based at Imperial College London, across the Faculties of Engineering, Natural Sciences and Life Sciences.

Sarab Sethi, Rob Ewers, Nick Jones, David Orme, Lorenzo Picinali

Feel free to drop me an email with any questions, and contributions to this codebase are always welcome.

Citations

Please cite the below papers when referring to this work:

Sethi, SS, Ewers, RM, Jones, NS, Orme, CDL, Picinali, L. Robust, real‐time and autonomous monitoring of ecosystems with an open, low‐cost, networked device. Methods Ecol Evol. 2018; 9: 2383– 2387. https://doi.org/10.1111/2041-210X.13089

Sethi, SS, Ewers, RM, Jones, NS, Signorelli, A., Picinali, L, Orme, CDL. SAFE Acoustics: an open-source, real-time eco-acoustic monitoring network in the tropical rainforests of Borneo. biorxiv 968867. https://doi.org/10.1101/2020.02.27.968867