Hallo,
ich möchte Euch heute mal meine Methode vorstellen, mit der ich 1wire-Temperaturdaten eines Raspis komfortabel an den Symconserver übertrage.
Voraussetzung:
[ul]
[li]Die 1wire Sensoren sind gemäß den üblichen Empfehlungen an den GPIO angeschlossen und es ist ein nicht zu altes Rasbian installiert. So dass die Daten der Sensoren im Verzeichnis
[/li]
/sys/devices/w1_bus_master1/w1_master_slaves
zu finden sind.
[li]Es ist Python installiert
[/li][/ul]
Auf den Raspi habe ich folgendes Script am Laufen, welches per cronjob alle 5 Minuten ausgeführt wird
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Import der Module
import sys
import os
from time import *
import requests, json
from requests.auth import HTTPBasicAuth
#############################
# JSON-RPS zu IPS definieren
#############################
def IpsRpc(methodIps, paramIps):
url = "http://thomas.gierth@gmx.de:symcon@192.168.0.10:83/api/"
headers = {'content-type': 'application/json'}
payload = {
"method": methodIps,
"params": paramIps,
"jsonrpc": "2.0",
"id": 0,
}
#print json.dumps(payload)
response = requests.post(url, data=json.dumps(payload), headers=headers).json
#print(response)
#IPS
IPS_KennungName=46082 #die Variable die die Kennung enthält
IPS_TemperaturID=18248 #die aktuelle Temperatur
# Zeitvariable definieren
lt = localtime()
# 1-Wire Slave-Liste oeffnen
file = open('/sys/devices/w1_bus_master1/w1_master_slaves') #Verzeichniss evtl. anpassen
# 1-Wire Slaves auslesen
w1_slaves = file.readlines()
# 1-Wire Slave-Liste schliessen
file.close()
# Header fuer Bildschirmausgabe
print('Sensor ID | Temperatur')
print('----------------------------')
# Fuer jeden 1-Wire Slave eine Ausgabe
for line in w1_slaves:
# 1-wire Slave extrahieren
w1_slave = line.split("
")[0]
# 1-wire Slave Datei oeffnen
file = open('/sys/bus/w1/devices/' + str(w1_slave) + '/w1_slave')
# Inhalt des 1-wire Slave File auslesen
filecontent = file.read()
# 1-wire Slave File schliessen
file.close()
# Temperatur Daten auslesen
stringvalue = filecontent.split("
")[1].split(" ")[9]
# Temperatur konvertieren
temperature = float(stringvalue[2:]) / 1000
# Temperatur ausgeben
# print(str(w1_slave) + ' | %5.3f °C' % temperature)
# Werte in Datei schreiben
# Zeit und Datum erfassen
# Datum = strftime("%d.%m.%Y")
# Uhrzeit = strftime("%H:%M:%S")
# Textdatei oeffnen
# fobj_out = open("temp-daten.txt","a")
# Daten in Textdatei schreiben
# fobj_out.write(Datum + ", " + Uhrzeit +", " + '%5.3f °C' % temperature + "
")
# Textdatei schliessen
# fobj_out.close()
# Die Daten ins IPS senden
IpsRpc("SetValue", [IPS_KennungName, str(w1_slave)])
IpsRpc("SetValue", [IPS_TemperaturID, float(temperature)])
# einen kurzen Moment warten um IPS Zeit zu geben die Werte zu verarbeiten
sleep(0.999) #1Sekunde sollte reichen
Dieses Python-Script ließt alle Tempsensoren aus und überträgt sie seriell an SYMCON, da ich es mir sparen möchte beim nachrüsten eines Sensors oder ersetzen desselben im python-script etwas ändern zu müssen, habe ich mir einen Mechanismus ausgedacht, der mir das erspart:
Dazu habe ich im IPSYMCON folgende Struktur:
An die beiden Interfacevariablen werden die Daten des Pythonscriptes via JSON übertragen (
# Die Daten ins IPS senden
IpsRpc("SetValue", [IPS_KennungName, str(w1_slave)])
IpsRpc("SetValue", [IPS_TemperaturID, float(temperature)])
)
Und zwar erst die Kennung und dann die Temperatur. Sobald diese Variable aktualisiert worden ist, startet der Script „werte_empfangen“ und verarbeitet die beiden Daten. Dabei wird geprüft, ob von der Sensor mit der Kennung bereits existiert, wenn ja wird die Temp aktualisiert, wenn nicht, wird der Sensor automatisch angelegt und der Wert gesetzt.
Der Script sieht so aus:
<?
//Empfängt 1-wire Werte aus dem Raspi
/*
Um doppelte Konfiguration zu sparen, werden per python-script zuerst die
Temperatur und anschließend die ID des Sensors übermittelt
Der Script wird ausgeführt, sobald die ID übermittelt wurde.
Als erstes wird geprüft, ob der Sensor neu ist, falls ja wird er angelegt,
ansosnten wird der aktuelle Sensorwert eingetragen
*/
$owID= GetValueString(46082 /*[05_Sonstiges\Raspi_Pool\1-wire\Interface\1w_interface_name]*/); //die SensorKennung des aktuellen Sensors
$owTemp= GetValueFloat(18248 /*[05_Sonstiges\Raspi_Pool\1-wire\Interface\1w_interface_temp]*/); //dessen Temperatur
$TempSensorKategorie=45560 /*[05_Sonstiges\Raspi_Pool\1-wire\TempSensoren]*/;
$SensorKennungsVarName="ID"; //der Name der Variablen,welche die SensorKennung beinhaltet
//prüfen, ob sensor existiert
$sensorlist=IPS_GetChildrenIDs($TempSensorKategorie); //Liste aller Sensoren einlesen
$neuerSensor=true;
foreach ($sensorlist as $sensorID)
{
//für jeden Sensor
//existiert eine SensorKennungs-Variable zur Temperaturvariablen?
@$ID=IPS_GetVariableIDByName($SensorKennungsVarName,$sensorID);
if ($ID)
{
$sID=GetValueString($ID);
//prüfen, ob die SensorKennung mit der übertragenen Kennung übereinstimmt
if ($sID==$owID)
{
//ja, ist der gleiche Sensor, Wert aktualisieren
SetValueFloat($sensorID, $owTemp);
$neuerSensor=false;
break; //Vorgang abgeschlossen
}
else
{
//nein,stimmt nicht überein, weitermachen
}
}
}
if ($neuerSensor)
{
//es wurde kein Sensor gefunden, der passt
//Variable anlegen
$VarID_Temp=IPS_CreateVariable(2); //Float
$VarID_Kennung=IPS_CreateVariable(3); //String anlegen
IPS_SetName($VarID_Temp,"neuer unbekannter Sensor");
IPS_SetParent($VarID_Temp,$TempSensorKategorie);
SetValueFloat($VarID_Temp,$owTemp);
IPS_SetName($VarID_Kennung,$SensorKennungsVarName);
IPS_SetParent($VarID_Kennung,$VarID_Temp);
SetValueString($VarID_Kennung,$owID);
}
?>
Ein neuer Sensor wird als neuer unbekannter Sensor angelegt, er kann dann umbenannt werden, da die Wiedererkennung an der ID erfolgt.
Vielleicht kann das jemand nutzen.
Viele Grüße
tommes