The first question to answer was how to store measurement data from the sensors in the database.
To give an example how it was done i'll start with a DS18B20 sensor. As a lot of stuff for the Rapsberry is avaiable in Python i decided to setup my adapter framework in Python. The DS18B20 is a 1W sensor where the reading can simply be done by opening a file (the mapping of sensor hw to the file is done by the Raspi OS already if setup properly - see project instructions on how to do that).
The adapter is setup as a python class:
#!/usr/bin/python
# Copyright (c) 2016
# Author: Andreas Wirthmueller
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
import time
import datetime
from datetime import datetime
from config import HOSTNAME
import logging
MODULE_NAME = 'DS18B20'
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s',
datefmt='%m-%d %H:%M',
filename='/home/pi/sensors/GreenMon/adapter_log.log'
)
class DS18B20_Adapter:
SENSOR_TYPE = "temperature"
MEASURE_T="Celsius"
def __init__(self, sensor_id,slave_id):
logging.info(MODULE_NAME+ ": constructor start")
self.sensor_id = sensor_id
self.slave_id = slave_id
logging.info(MODULE_NAME +": constructor exit")
def read(self):
# 1-wire Slave Datei lesen
filename = '/sys/bus/w1/devices/' + self.slave_id + '/w1_slave'
file = open(filename)
filecontent = file.read()
file.close()
# Temperaturwerte auslesen und konvertieren
stringvalue = filecontent.split("\n")[1].split(" ")[9]
temperature = float(stringvalue[2:]) / 1000
# Temperatur ausgeben
rueckgabewert = temperature
return(rueckgabewert)
def readJSON(self):
temp = self.read()
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
d_temp = {'hostname':HOSTNAME,
'type':self.SENSOR_TYPE,
"measure_temp": "Celsius",
'sensorid':self.sensor_id,
'temp':temp,
'datetime':str(timestamp)}
return d_temp
It is simply opening the file as defined by the 1W interface, converting the value and returning it in the read-function. It provides a second function which build on read and provides back a JSON document instead of the simple temperatur. This JSON will be used to store the sensor reading in RethinkDB later.
To instantiate a class and call the reading a simple script will do:
from DS18B20_adapter import DS18B20_Adapter
#measure temperature sensor 1
soil_temperature = DS18B20_Adapter('t_0001','28-04165b7853ff')
d_temp1 = soil_temperature.readJSON()
So now we have the adapter ready and we get back a JSON representation of the reading.Now we need to use the snipet to call the reader and store the JSON document in RethinkDB - which happens in monitor_adapters.py. Here's the relevant snippeds:
[...]
import rethinkdb as r
import time
import datetime
import sys
from datetime import datetime
from config import HOSTNAME, DB_HOST, DB_PORT, DB_NAME
from DS18B20_adapter import DS18B20_Adapter
MODULE_NAME = 'Readall_apaters'
import logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s',
datefmt='%m-%d %H:%M',
filename='/home/pi/GreenMon/log/adapter_log.log'
)
logging.info(MODULE_NAME+": ***************** Start ***************** ")
conn = r.connect(DB_HOST, DB_PORT, DB_NAME)
[...]
timezone = time.strftime("%z")
reql_tz = r.make_timezone(timezone[:3] + ":" + timezone[3:])
[...]
#measure temperature sensor 1
soil_temperature = DS18B20_Adapter('t_0001','28-04165b7853ff')
d_temp1 = soil_temperature.readJSON()
[...]
d_observation = {'pressure':[d_pressure],
'temperature':[d_temp1,d_temp2,d_temp3,d_temp4],
'luminosity':[d_luminosity],
'timestamp': str(datetime.now(reql_tz)),
'type':'sensors'
}
logging.info(MODULE_NAME+": measurement %s",str(d_observation))
r.table("observations").insert(d_observation).run(conn, durability='soft') #Soft durability since losing 't be the end of the world.
conn.close()
logging.info(MODULE_NAME+": measurements successfully written to db")
logging.info(MODULE_NAME+": ***************** End ***************** ")
This script now takes the reading and puts it into the table observations of RethinkDB database "greenhouse_pi". This script will be automatically triggered to run every five minutes to get up to date readings and store them in the database by
crontab -eand adding
*/5 * * * * sudo /usr/bin/python /home/pi/GreenMon/adapter_class/monitor_adapters.py >/home/pi/GreenMon/log/cron.log 2>&1 &
The full source code for the project including the adapters can be found on git: https://github.com/awirthmueller/GreenhousePi
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.