Pythonskript für Temperaturmonitoring Schritt 2

Im letzten Beitrag habe ich die ersten Schritte zur Temperaturüberwachung beschrieben. Dabei hatte ich ein Skript von raspiprojekt.de eingesetzt. Als Freund von Klassen habe ich diesen Code nun gleich entsprechend umgeschrieben, was an den verfügbaren Funktionen erst einmal nichts ändert, sondern nur die Übersichtlichkeit des Codes erhöht.

Daher habe ich den Code in zwei Klassen zerlegt:

  • w1_temp_sensor (stellt einen Temperatursensor dar)
  • sensor_pool (verwaltet den Zugriff auf die Sensoren)

Beide Klassen sind nicht besonders aufregend und werden hier nur kurz dargestellt:

'''
Created on 26.12.2013
@author: mstuebner
'''
class w1_temp_sensor(object):
 '''
 classdocs
 '''
 STATUS_YES = 'YES'

 def __init__(self, sensor_name, driver_path = None):
 '''
 Constructor
 '''
 self.driver_path = '/sys/bus/w1/devices/'
 self.driver_file = self.driver_path + str(sensor_name) + '/w1_slave'
def read_data(self):
 '''
 Funktion reads sensor data from driver file and returns (status, temperature)
 '''
file_name = self.driver_file
sfile = open(file_name)
 filecontent = sfile.read() # Inhalt des 1-wire Slave File auslesen
 sfile.close()
status = filecontent.split("n")[0].split(" ")[11]
if status == self.STATUS_YES:
 # Temperatur konvertieren
 temperature = float(filecontent.split("n")[1].split(" ")[9][2:]) / 1000
 else:
 temperature = None
return status, temperature

Die Klasse w1_temp_sensor hat nur den Konstruktor __init__() und die Methode read_data(). Während der Konstruktor zwei Variablen definiert, bzw. mit dem übergebenen Namen des Sensors den Pfad zur auszulesenden Datei bildet liefert die Methode read_data() die aktuell am Sensor verfügbaren Daten zurück.

Der erste Reückgabewert ist dabei der Status der Daten (in der Sensordatei als CRC), der zweite Wert der Temperaturwert. War der gelesene Statuswert ungleich YES wird anstelle der Temperatur None zurück gegeben, da der Temperaturwert nicht valide ist.

Die zweite Klasse “verwaltet” die Sensoren auf eine an dieser Stelle sehr triviale Art und Weise: Sie liest die Verfügbaren Sensoren aus

'''
Created on 26.12.2013
@author: mstuebner
'''
class sensor_pool(object):
 '''
 classdocs
 '''
 SLAVE_PATH = '/sys/bus/w1/devices/w1_bus_master1/w1_master_slaves'
def __init__(self):
 '''
 Constructor
 '''
 self.sensors = []
def get_sensors(self):
 # 1-Wire Slave-Liste oeffnen
 sfile = open(self.SLAVE_PATH) #Verzeichniss evtl. anpassen
 w1_slaves = sfile.readlines()
 sfile.close()
for line in w1_slaves:
 self.sensors.append(line.split("n")[0])
return self.sensors

Im Ergebnis ändert sich das aufrufende Skript dadurch wie folgt:

#!/usr/bin/python
# coding: utf-8
# Die Sensoren muessen mit "modprobe w1-gpio" und "modprobe w1-therm" aktiviert werden!

# Import der Module
from time import localtime , strftime
from sensors.w1_temp_sensor import w1_temp_sensor
from sensors.sensors import sensor_pool

# Zeitvariable definieren
lt = localtime()
sens = sensor_pool()
sensor_list = sens.get_sensors()
# Fuer jeden 1-Wire Slave eine Ausgabe
for sensor in sensor_list:
w1_sensor = w1_temp_sensor(sensor)
 status, temperature = w1_sensor.read_data()
# Textdatei oeffnen
 fobj_out = open("/home/pi/python/monitoring/sensor-data-{}.txt".format(sensor),"a")
 # Daten in Textdatei schreiben
 fobj_out.write('{} {} {}n'.format(strftime("%d.%m.%Y"),
 strftime("%H:%M:%S"),
 temperature)
 )

 fobj_out.close()

WICHTIG: Konsequenter Weise lege ich nicht alle Dateien im selben Verzeichnis ab, sondern habe dafür ein “./Library/sensors” angelegt, um den der PYTHONPATH natürlich erweitert werden muss. Beim Aufruf aus dem cron heraus wird aber die .bashrc aus dem eigenen Profil nicht gelesen, somit ist auch der PYTHONPATH nicht definiert und der Import schlägt fehl. Um dies zu vermeiden muss der PYTHONPATH direkt im cron definiert werden. Es muss also vor dem Croneintrag die Zeile

# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
#
# For more information see the manual pages of crontab(5) and cron(8)
#
PYTHONPATH=.:/home/pi/python/monitoring/Library
# m h dom mon dow command
*/5 * * * * python /home/pi/python/monitoring/basics_class.py

definiert werden. Diese definiert den PYTHONPATH bei jedem Aufruf und die Klassendateien können gefunden werden.

Ersten Kommentar schreiben

Antworten