|
@@ -10,6 +10,7 @@ import time
|
|
|
from time import localtime, strftime
|
|
|
|
|
|
import os
|
|
|
+import sys
|
|
|
import paho.mqtt.client as mqtt
|
|
|
|
|
|
|
|
@@ -25,18 +26,22 @@ sensordata_maxage = 300
|
|
|
|
|
|
verbosemode = False
|
|
|
|
|
|
+if len(sys.argv) > 1 and str(sys.argv[1]) == "-v":
|
|
|
+ verbosemode = True
|
|
|
+
|
|
|
+
|
|
|
def touch(fname, times=None):
|
|
|
with open(fname, 'a'):
|
|
|
os.utime(fname, times)
|
|
|
|
|
|
def on_connect(client, userdata, flags, rc):
|
|
|
if verbosemode:
|
|
|
- print("MQTT connected with result code " + str(rc))
|
|
|
+ print("MQTT connected with result code " + str(rc) + "\n")
|
|
|
|
|
|
|
|
|
def on_disconnect(client, userdata, rc):
|
|
|
if rc != 0:
|
|
|
- print("Unexpected MQTT disconnection. Will auto-reconnect")
|
|
|
+ print("Unexpected MQTT disconnection. Will auto-reconnect\n")
|
|
|
|
|
|
|
|
|
|
|
@@ -48,6 +53,16 @@ minUpdateInterval = 60
|
|
|
mqtt_topic_prefix = "LaCrosse"
|
|
|
override_updateinterval_on_change = False
|
|
|
atemp_sensor_idx = 94
|
|
|
+atemp_sensor_idx_2 = 113
|
|
|
+
|
|
|
+atemp = 61
|
|
|
+ahum = 101
|
|
|
+atemp1 = 61
|
|
|
+ahum1 = 101
|
|
|
+atemp2 = 61
|
|
|
+ahum2 = 101
|
|
|
+atemp_last = 61
|
|
|
+ahum_last = 101
|
|
|
|
|
|
checkLastUpdateInterval = 60
|
|
|
checkLastUpdateInterval_lastRun = 0
|
|
@@ -59,6 +74,11 @@ sensors_lastHum = {}
|
|
|
sensors_lastUpdate = {}
|
|
|
sensors_unavailable = {}
|
|
|
|
|
|
+if verbosemode:
|
|
|
+ print("JeeLink2MQTT by Flo Kra")
|
|
|
+ print("=======================================================================")
|
|
|
+ print("loading sensors assignment: ")
|
|
|
+
|
|
|
with open("/home/pi/jeelink_sensors.csv", "r") as sensorscsv:
|
|
|
for line in sensorscsv:
|
|
|
if line.find('ID,DomoticzIdx,Name') == -1:
|
|
@@ -76,8 +96,11 @@ with open("/home/pi/jeelink_sensors.csv", "r") as sensorscsv:
|
|
|
sensors_lastUpdate[str(sensorId)] = 0
|
|
|
sensors_unavailable[str(sensorId)] = 1
|
|
|
if verbosemode:
|
|
|
- print("Sensor " + sensorId + " = '" + sensorName + "'")
|
|
|
+ idhex = "{0:x}".format(int(sensorId))
|
|
|
+ print("Sensor " + sensorId + " = 0x" + str(idhex) + ", Idx = " + str(domoticzIdx) + ", Name = '" + sensorName + "'")
|
|
|
|
|
|
+if verbosemode:
|
|
|
+ print("\n")
|
|
|
|
|
|
mqttc = mqtt.Client()
|
|
|
mqttc.on_connect = on_connect
|
|
@@ -100,9 +123,9 @@ ser = serial.Serial(port='/dev/serial/by-id/usb-FTDI_FT232R_USB_UART_AL01MYTF-if
|
|
|
|
|
|
|
|
|
|
|
|
-if verbosemode:
|
|
|
- print(sensors)
|
|
|
- print(sensors_idx)
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
|
|
|
|
|
|
checkLastUpdateInterval_lastRun = time.time()
|
|
@@ -116,14 +139,16 @@ try:
|
|
|
|
|
|
|
|
|
serLine = ser.readline().strip()
|
|
|
- serLine = serLine.decode('ascii')
|
|
|
+
|
|
|
+ try:
|
|
|
+ serLine = serLine.decode('ascii')
|
|
|
+ except:
|
|
|
+ serLine = ""
|
|
|
|
|
|
if(serLine):
|
|
|
- if verbosemode:
|
|
|
- print(serLine)
|
|
|
if serLine.find('OK 9') != -1:
|
|
|
if verbosemode:
|
|
|
- print("is LaCrosse sensor")
|
|
|
+ print(serLine + " = LaCrosse sensor")
|
|
|
|
|
|
|
|
|
|
|
@@ -153,25 +178,6 @@ try:
|
|
|
currentsensor_idx = sensors_idx.get(str(addr),None)
|
|
|
currentsensor_name = sensors.get(str(addr), None)
|
|
|
|
|
|
- senddata = False
|
|
|
- if currentsensor_idx is not None:
|
|
|
- if override_updateinterval_on_change:
|
|
|
- if lastTemp != str(temp) or lastHum != str(hum):
|
|
|
- senddata = True
|
|
|
-
|
|
|
-
|
|
|
- if lastUpdate is not None:
|
|
|
- timediff = int(time.time()) - lastUpdate
|
|
|
- if timediff >= minUpdateInterval:
|
|
|
- senddata = True
|
|
|
- elif sensors_unavailable[str(addr)] == 1:
|
|
|
- senddata = True
|
|
|
- else:
|
|
|
- senddata = True
|
|
|
-
|
|
|
- sensors_unavailable[str(addr)] = 0
|
|
|
-
|
|
|
-
|
|
|
if int(serLineParts[3]) >= 128:
|
|
|
batt_new = 1
|
|
|
type = int(serLineParts[3]) - 128
|
|
@@ -195,6 +201,25 @@ try:
|
|
|
else:
|
|
|
batterystate = "low"
|
|
|
|
|
|
+ senddata = False
|
|
|
+ if currentsensor_idx is not None:
|
|
|
+ if override_updateinterval_on_change:
|
|
|
+ if lastTemp != temp or lastHum != hum:
|
|
|
+ senddata = True
|
|
|
+ if verbosemode:
|
|
|
+ print("override interval (value changed): " + str(temp) + " != " + str(lastTemp) + " " + str(hum) + " != " + str(lastHum))
|
|
|
+
|
|
|
+ if lastUpdate is not None:
|
|
|
+ timediff = int(time.time()) - lastUpdate
|
|
|
+ if timediff >= minUpdateInterval:
|
|
|
+ senddata = True
|
|
|
+ elif sensors_unavailable[str(addr)] == 1:
|
|
|
+ senddata = True
|
|
|
+ else:
|
|
|
+ senddata = True
|
|
|
+
|
|
|
+ sensors_unavailable[str(addr)] = 0
|
|
|
+
|
|
|
|
|
|
if currentsensor_name is None:
|
|
|
if batt_new == 1:
|
|
@@ -211,24 +236,47 @@ try:
|
|
|
temp = (int(serLineParts[4])*256 + int(serLineParts[5]) - 1000)/10.0
|
|
|
if verbosemode:
|
|
|
print("unknown sensor ID " + str(addr))
|
|
|
- print("Temp: " + str(temp))
|
|
|
mqttc.publish(mqtt_topic_prefix+"/UnknownSensor/"+str(addr)+"/temperature", str(temp), qos=2, retain=False)
|
|
|
mqttc.publish(mqtt_topic_prefix+"/UnknownSensor/"+str(addr)+"/humidity", str(hum), qos=2, retain=False)
|
|
|
mqttc.publish(mqtt_topic_prefix+"/UnknownSensor/"+str(addr)+"/battNew", str(batt_new), qos=2, retain=False)
|
|
|
+
|
|
|
|
|
|
+ if verbosemode:
|
|
|
+ print("addr: " + str(addr) + " = 0x" + str(addrhex) + " batt_new: " + str(batt_new) + " type: " + str(type) + " batt_low: " + str(batt_low) + " temp: " + str(temp) + " hum: " + str(hum) + " Name: " + str(currentsensor_name))
|
|
|
|
|
|
if senddata:
|
|
|
sensors_lastUpdate[str(addr)] = int(time.time())
|
|
|
- sensors_lastTemp[str(addr)] = str(temp)
|
|
|
- sensors_lastHum[str(addr)] = str(hum)
|
|
|
+ sensors_lastTemp[str(addr)] = temp
|
|
|
+ sensors_lastHum[str(addr)] = hum
|
|
|
|
|
|
+ isAtemp = False
|
|
|
if int(currentsensor_idx) == atemp_sensor_idx:
|
|
|
- mqttc.publish("wetter/atemp", str(temp), qos=2, retain=True)
|
|
|
- mqttc.publish("wetter/ahum", str(hum), qos=2, retain=True)
|
|
|
+ atemp1 = temp
|
|
|
+ ahum1 = hum
|
|
|
+ isAtemp = True
|
|
|
+ elif int(currentsensor_idx) == atemp_sensor_idx_2:
|
|
|
+ atemp2 = temp
|
|
|
+ ahum2 = hum
|
|
|
+ isAtemp = True
|
|
|
+
|
|
|
+ if isAtemp:
|
|
|
+ if atemp1 <= atemp2:
|
|
|
+ atemp = atemp1
|
|
|
+ ahum = ahum1
|
|
|
+ else:
|
|
|
+ atemp = atemp2
|
|
|
+ ahum = ahum2
|
|
|
+
|
|
|
+ if atemp < 61 and ahum < 101:
|
|
|
+ if atemp != atemp_last or ahum != ahum_last:
|
|
|
+ atemp_last = atemp
|
|
|
+ ahum_last = ahum
|
|
|
+ mqttc.publish("wetter/atemp", str(atemp), qos=2, retain=True)
|
|
|
+ mqttc.publish("wetter/ahum", str(ahum), qos=2, retain=True)
|
|
|
|
|
|
domoticz_json = "{\"idx\":" + str(currentsensor_idx) + ",\"nvalue\":0,\"svalue\":\"" + str(temp) + ";" + str(hum) + ";1\"}"
|
|
|
- if verbosemode:
|
|
|
- print(domoticz_json)
|
|
|
+
|
|
|
+
|
|
|
mqttc.publish("domoticz/in", domoticz_json, qos=2, retain=False)
|
|
|
|
|
|
mqttc.publish(mqtt_topic_prefix+"/"+str(currentsensor_name)+"/temperature", str(temp), qos=2, retain=False)
|
|
@@ -241,14 +289,24 @@ try:
|
|
|
mqttc.publish(mqtt_topic_prefix+"/"+str(currentsensor_name)+"/json", lacrosse_json, qos=2, retain=False)
|
|
|
|
|
|
if verbosemode:
|
|
|
- print("addr: " + str(addr) + " = 0x" + str(addrhex) + " batt_new: " + str(batt_new) + " type: " + str(type) + " batt_low: " + str(batt_low) + " temp: " + str(temp) + " hum: " + str(hum) + " Name: " + str(currentsensor_name))
|
|
|
- print("\n")
|
|
|
+ print("MQTT published")
|
|
|
|
|
|
try:
|
|
|
touch("/tmp/jeelink2mqtt_running")
|
|
|
except:
|
|
|
|
|
|
pass
|
|
|
+
|
|
|
+ else:
|
|
|
+ if verbosemode:
|
|
|
+ if currentsensor_name is None:
|
|
|
+ print("MQTT published")
|
|
|
+ else:
|
|
|
+ print("MQTT publishing surpressed (interval not expired)")
|
|
|
+
|
|
|
+
|
|
|
+ if verbosemode:
|
|
|
+ print("\n")
|
|
|
|
|
|
|
|
|
if (time.time() - checkLastUpdateInterval_lastRun) > checkLastUpdateInterval:
|
|
@@ -257,9 +315,11 @@ try:
|
|
|
for key in sensors_lastUpdate:
|
|
|
|
|
|
if (time.time() - sensors_lastUpdate[key]) > sensordata_maxage:
|
|
|
- print(sensors[key], ' outd ->')
|
|
|
+ if verbosemode:
|
|
|
+ print(sensors[key], ' outd ->')
|
|
|
sensors_unavailable[key] = 1
|
|
|
mqttc.publish(mqtt_topic_prefix+"/"+str(sensors[key])+"/availability", "unavailable", qos=2, retain=False)
|
|
|
|
|
|
except KeyboardInterrupt:
|
|
|
print('\n')
|
|
|
+ exit()
|