123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215 |
- #!/usr/bin/python3 -u
- # -*- coding: utf-8 -*-
- #
- import serial
- import time
- from time import localtime, strftime
- from datetime import datetime
- import configparser
- from influxdb import InfluxDBClient
- import os
- import sys
- import paho.mqtt.client as mqtt
- import yaml
- import json
- import statistics
- import math
- from time import sleep
- #import math
- #import numpy as np
- #import httplib
- # Change working dir to the same dir as this script
- os.chdir(sys.path[0])
- # stop program if nothing is received from JeeLink for 5 min (will be restarted by systemd)
- serialReceived_maxAge = 300
- config = configparser.ConfigParser()
- config.read('jeelinklog.ini')
- serialport = config['jeelink'].get('serialport')
- serialbaud = int(config['jeelink'].get('baudrate'))
- if config['jeelink'].get('initTimeout') != None:
- serialInitTimeout = int(config['jeelink'].get('initTimeout'))
- else:
- serialInitTimeout = 2
- jeelinkInitCmd = config['jeelink'].get('initCmd')
- if jeelinkInitCmd == None:
- jeelinkInitCmd = "30t 3m v" # init cmd for TX29 AND TX35 sensors (17.241 and 9.579 kbps toggle every 30s)
- #jeelinkInitCmd = "0t 1m v" # init cmd for TX29 sensors only (17.241 kbps, no toggle)
- mqtt_topic_prefix = config['mqtt'].get('topic_prefix')
- topic_prefix_outside_temphum = config['mqtt'].get('topic_prefix_outside_temphum')
- mqtt_topic_atemp = config['mqtt'].get('topic_outside_temp')
- mqtt_topic_ahum = config['mqtt'].get('topic_outside_hum')
- mqtt_topic_ahum = config['mqtt'].get('topic_outside_dew')
- mqtt_topic_ahum = config['mqtt'].get('topic_outside_abshum')
- mqtt_topic_domoticz_in = "domoticz/in"
- mqtt_subtopic_notify = config['mqtt'].get('subtopic_notify')
- logfile_new_sensors = config['main'].get('logfile_new_sensors')
- path_new_sensors_folder = config['main'].get('path_new_sensors_folder')
- log_path = config['main'].get('log_path')
- if not os.path.exists(log_path):
- os.makedirs(log_path)
- verbosemode = False
- #sensors_conf_file = "/home/pi/jeelink_sensors.csv"
- sensordata_maxage = int(config['sensors'].get('data_maxage'))
- #minUpdateInterval = 60
- #aTempHumPublishInterval = 60
- #override_updateinterval_on_change = False
- #atemp_sensor_idx = 94
- #atemp_sensor_idx_2 = 113
- average_value_steps = int(config['sensors'].get('average_value_steps'))
- if average_value_steps == 0:
- average_value_steps = 1
- 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) + "\n")
- #client.subscribe("wetter/atemp")
- def on_disconnect(client, userdata, rc):
- if rc != 0:
- print("Unexpected MQTT disconnection. Will auto-reconnect\n")
-
- #def on_message(client, userdata, msg):
- # #print(msg.topic + " " + str(msg.payload))
- # global atemp
- # atemp = msg.payload
- # dont edit below
- #starting values only..
- ##atemp = 61
- ##ahum = 101
- ##atemp1 = 61
- ##ahum1 = 101
- ##atemp2 = 61
- ##ahum2 = 101
- ##atemp_last = 61
- ##ahum_last = 101
- checkLastUpdateInterval = 60
- checkLastUpdateInterval_lastRun = 0
- lastPublishTime = 0
- lastStoreTime = 0
- sensors = dict()
- sensors_id_to_name = dict()
- #sensors_idx = dict()
- sensors_lastTemp = dict()
- sensors_lastHum = dict()
- sensors_lastUpdate = dict()
- sensors_lastReceivedValue_temp = dict()
- sensors_lastReceivedTime = dict()
- sensors_lastValues_temp = dict()
- sensors_lastValues_hum = dict()
- sensors_lastAvgValue_temp = dict()
- sensors_lastAvgValue_hum = dict()
- sensors_lastValues_lastIndex = dict()
- #sensors_unavailable = dict()
- sensors_batteryState = dict()
- sensors_new_alreadyNotified = dict()
- sensors_outside_sensors = []
- outSens_lastRun = 0
- outSens_store_lastRun = 0
- influx_default_fieldname_temperature = 'Temperature'
- influx_default_fieldname_humidity = 'Humidity'
- influx_default_fieldname_dewpoint = 'Dewpoint'
- influx_default_fieldname_abshum = 'AbsHumidity'
- influx_default_datatype_temperature = 'float'
- influx_default_datatype_humidity = 'int'
- influx_default_datatype_dewpoint = 'float'
- influx_default_datatype_abshum = 'float'
- sensors_yaml = yaml.load(open(config['main'].get('sensors_config_yml')), Loader=yaml.FullLoader)
- def list_duplicates(seq):
- seen = set()
- seen_add = seen.add
- # adds all elements it doesn't know yet to seen and all other to seen_twice
- seen_twice = set( x for x in seq if x in seen or seen_add(x) )
- # turn the set into a list (as requested)
- return list( seen_twice )
-
- # Dew point calculation based on formula and JS code found on: https://www.wetterochs.de/wetter/feuchte.html#f4
- # dew point from temperature, relative humidity
- # in °C
- def dewpoint(temp, relHum):
- if temp >= 0:
- a = 7.5
- b = 237.3
- else:
- a = 7.6
- b = 240.7
- c = math.log(vaporPressure(temp, relHum)/6.1078) * math.log10(math.e)
- return (b * c) / (a - c)
-
- def celsiusToKelvin(temp):
- return temp + 273.15
-
- def absoluteHumidity(relHum, temp):
- # AF = absolute Feuchte in g Wasserdampf pro m3 Luft
- # R* = 8314.3 J/(kmol*K) (universelle Gaskonstante)
- # mw = 18.016 kg/kmol (Molekulargewicht des Wasserdampfes)
- # r = relative Luftfeuchte
- # T = Temperatur in °C
- # TK = Temperatur in Kelvin (TK = T + 273.15)
- # TD = Taupunkttemperatur in °C
- #
- # mw/R* = 18.016 / 8314.3 = 0,0021668691290908
- #
- # AF(r,TK) = 10^5 * mw/R* * DD(T,r)/TK
- # unused 2nd formula: AF(TD,TK) = 10^5 * mw/R* * SDD(TD)/TK
- mw = 18.016
- R = 8314.3
- return 10**5 * mw/R * vaporPressure(temp, relHum) / celsiusToKelvin(temp)
-
- # Saettingungsdampfdruck / saturation vapour pressure
- # from temperature in hPa
- def saturationVaporPressure(temp):
- if temp >= 0:
- a = 7.5
- b = 237.3
- else:
- a = 7.6
- b = 240.7
- return 6.1078 * math.exp(((a*temp)/(b + temp))/ math.log10(math.e))
-
- # Dampfdruck / vapour pressure
- # from temperature, relative humidity in hPa
- def vaporPressure(temp, relHum):
- return relHum/100 * saturationVaporPressure(temp)
-
- if verbosemode:
- print("JeeLink2MQTT by Flo Kra")
- print("=======================================================================")
- print()
- print("JeeLink initCmd: " + jeelinkInitCmd)
- print()
- print()
- # load InfluxDB configuration
- influxdb_yaml = yaml.load(open(config['main'].get('influx_config_yml')), Loader=yaml.SafeLoader)
- if verbosemode:
- print("loading InfluxDB configuration...")
- print("InfluxDB Instances:")
- print(json.dumps(influxdb_yaml, indent=4))
- influxclient = dict()
- for instance in influxdb_yaml:
- i_host = influxdb_yaml[instance].get('host', None)
- i_port = int(influxdb_yaml[instance].get('port', 8086))
- i_username = influxdb_yaml[instance].get('username', None)
- i_password = influxdb_yaml[instance].get('password', None)
- i_database = influxdb_yaml[instance].get('database', None)
- if i_host != None and i_database != None:
- if i_username != None and i_password != None:
- influxclient[instance] = InfluxDBClient(i_host, i_port, i_username, i_password, i_database)
- else:
- influxclient[instance] = InfluxDBClient(i_host, i_port, i_database)
- if verbosemode:
- print()
- print()
- # load sensors configuration
- if verbosemode:
- print("loading sensors configuration: ")
- print(json.dumps(sensors_yaml, indent=3))
- print()
- for key in sensors_yaml:
- #print(key, '->', sensors_yaml[key])
- if verbosemode: print("Sensor name:", key)
- sensorName = key
-
- if sensors_yaml[key].get('LaCrosseID') >= 0:
- if verbosemode: print("LaCrosseID:", sensors_yaml[key].get('LaCrosseID'))
- sensorId = sensors_yaml[key].get('LaCrosseID')
- sensors_id_to_name[sensorId] = sensorName
-
- if sensors_yaml[key].get('DomoticzIdx'):
- if verbosemode: print("DomoticzIdx:", sensors_yaml[key].get('DomoticzIdx'))
- #sensors_idx[sensorId] = sensors_yaml[key].get('DomoticzIdx')
-
- if sensors_yaml[key].get('Topic_Temp'):
- if verbosemode: print("Topic_Temp:", sensors_yaml[key].get('Topic_Temp'))
-
- if sensors_yaml[key].get('Topic_Hum'):
- if verbosemode: print("Topic_Hum:", sensors_yaml[key].get('Topic_Hum'))
-
- if sensors_yaml[key].get('InfluxDB_Instance'):
- if verbosemode:
- print("InfluxDB_Instance:", sensors_yaml[key].get('InfluxDB_Instance'))
- if sensors_yaml[key].get('InfluxDB_Instance') not in influxdb_yaml:
- print("Error: invalid InfluxDB instance '" + sensors_yaml[key].get('InfluxDB_Instance') + "' configured for sensor '" + sensorName + "'")
-
- if sensors_yaml[key].get('isOutsideTempSensor'):
- if verbosemode: print("isOutsideTempSensor:", sensors_yaml[key].get('isOutsideTempSensor'))
- sensors_outside_sensors.append(sensorId)
-
- else:
- print("WARNING: Sensor " + key + " has no LaCrosseID!")
-
- if verbosemode:
- print()
-
- if verbosemode:
- print()
- print()
-
- #print(json.dumps(sensor))
- #print("sensors_id_to_name =",sensors_id_to_name)
- #print("outside sensors: ", sensors_outside_sensors)
-
-
- mqttc = mqtt.Client()
- mqttc.on_connect = on_connect
- mqttc.on_disconnect = on_disconnect
- ##mqttc.on_message = on_message
- if config['mqtt'].get('user') != "" and config['mqtt'].get('password') != "":
- mqttc.username_pw_set(config['mqtt'].get('user'), config['mqtt'].get('password'))
- mqttc.connect(config['mqtt'].get('server'), config['mqtt'].getint('port'), 60)
- mqttc.loop_start()
- #mqttc.loop_forever()
- ser = serial.Serial(port=serialport,
- baudrate = serialbaud,
- parity=serial.PARITY_NONE,
- stopbits=serial.STOPBITS_ONE,
- bytesize=serial.EIGHTBITS,
- timeout=1)
- checkLastUpdateInterval_lastRun = time.time() # first check after timeout expired
- # set serialReceivedLastTime to current time so that we can detect if nothing is received for some time
- serialReceivedLastTime = int(time.time())
- # init JeeLink device
- sleep(serialInitTimeout)
- ser.flushInput()
- ser.write(jeelinkInitCmd.encode('ascii')) # send init command to Jeelink
- #ser.write('v\r\n'.encode('ascii')) # get JeeLink version info
- sleep(0.2)
- try:
- while True:
- msg_was_sent = 0
-
- #clear serial buffer to remove junk and noise
- ###ser.flushInput()
-
- #read buffer until cr/lf
- serLine = ser.readline().strip()
- # catch exception on invalid char coming in: UnicodeDecodeError: 'ascii' codec can't decode byte 0xf4 in position 6: ordinal not in range(128)
- try:
- serLine = serLine.decode('ascii')
- except:
- serLine = False
- if(serLine):
- if serLine.find('LaCrosseITPlusReader') != -1:
- if verbosemode:
- print("Jeelink version/config: " + serLine)
- print()
- print()
-
- elif serLine.find('OK 9') != -1:
-
- # set serialReceivedLastTime to current time so that we can detect if nothing is received for some time
- serialReceivedLastTime = int(time.time())
-
- if verbosemode:
- print("RX: " + serLine + " => LaCrosse sensor")
- # uns interessieren nur reinkommende Zeilen die mit "OK 9 " beginnen
-
- # 0 1 2 3 4 5 6
- # OK 9 ID XXX XXX XXX XXX
- # | | | | | | |
- # | | | | | | --- Humidity incl. WeakBatteryFlag
- # | | | | | |------ Temp * 10 + 1000 LSB
- # | | | | |---------- Temp * 10 + 1000 MSB
- # | | | |-------------- Sensor type (1 or 2) +128 if NewBatteryFlag
- # | | |----------------- Sensor ID
- # | |------------------- fix "9"
- # |---------------------- fix "OK"
-
- serLineParts = serLine.split(' ')
-
- #print("Len: " + str(len(serLineParts)))
-
- if(len(serLineParts) == 7): # check correct size of incoming data
-
- #addr = serLineParts[2]
- #addr = "{0:x}".format(int(serLineParts[2]))
- #addr = hex((int(serLineParts[2])))
- addr = int(serLineParts[2])
- addrhex = "{0:x}".format(int(serLineParts[2]))
-
-
- lastUpdate = sensors_lastUpdate.get(addr, None)
- lastTemp = sensors_lastTemp.get(addr, None)
- lastHum = sensors_lastHum.get(addr, None)
-
- currentsensor_name = sensors_id_to_name.get(addr, None)
-
-
- # extract sensor data received from JeeLink
- if int(serLineParts[3]) >= 128:
- batt_new = 1
- type = int(serLineParts[3]) - 128
- else:
- batt_new = 0
- type = int(serLineParts[3])
-
- temp = (int(serLineParts[4])*256 + int(serLineParts[5]) - 1000)/10.0
-
- if int(serLineParts[6]) >= 128:
- batt_low = 1
- hum = int(serLineParts[6]) - 128
- else:
- batt_low = 0
- hum = int(serLineParts[6])
- if hum > 100:
- hum = 100
-
- if batt_new == 1:
- sensors_batteryState[addr] = 2
- elif batt_low == 1:
- sensors_batteryState[addr] = 1
- else:
- sensors_batteryState[addr] = 0
-
- lastValues_lastIndex = sensors_lastValues_lastIndex.get(addr, None)
-
- if sensors_lastValues_temp.get(addr, None) == None:
- sensors_lastValues_temp[addr] = [None] * average_value_steps
-
- if sensors_lastValues_hum.get(addr, None) == None:
- sensors_lastValues_hum[addr] = [None] * average_value_steps
-
- data_okay = False
-
- if sensors_lastReceivedValue_temp.get(addr, None) == None:
- # this is the first time we receive from that sensor in that session
- if verbosemode: print("first received from sensor",str(addr))
- sensors_lastReceivedValue_temp[addr] = temp
- sensors_lastReceivedTime[addr] = int(time.time())
- #lastValues_lastIndex = 0
- else:
- lastValue = sensors_lastReceivedValue_temp.get(addr, None)
-
- max_off_value = float(config['sensors'].get('max_off_value'))
- ignore_off_value_timeout = int(config['sensors'].get('ignore_off_value_timeout'))
-
- if lastValue != None and ((temp >= (lastValue - max_off_value) and temp <= (lastValue + max_off_value)) or ((int(time.time()) - sensors_lastReceivedTime.get(addr)) > ignore_off_value_timeout)): # discard off values
- sensors_lastReceivedValue_temp[addr] = temp
- sensors_lastReceivedTime[addr] = int(time.time())
- #print("Last Value=",lastValue,"currValue=",temp)
- data_okay = True
- else:
- if verbosemode: print("skipped sensor reading - Last Value=",lastValue,"currValue=",temp)
-
-
- if data_okay:
- if lastValues_lastIndex == None:
- lastValues_lastIndex = 0
- elif lastValues_lastIndex == (average_value_steps - 1):
- lastValues_lastIndex = 0
- else:
- lastValues_lastIndex += 1
- if verbosemode: print("lastValues_lastIndex =", lastValues_lastIndex)
-
- sensors_lastValues_lastIndex[addr] = lastValues_lastIndex
- sensors_lastValues_temp[addr][lastValues_lastIndex] = temp
- sensors_lastValues_hum[addr][lastValues_lastIndex] = hum
-
- sensors_lastUpdate[addr] = int(time.time())
-
- if verbosemode: print("sensors_lastValues_temp =", sensors_lastValues_temp[addr])
-
-
- if currentsensor_name is None:
- if batt_new == 1 and not sensors_new_alreadyNotified.get('addr', False):
- notifystr = "NEW sensor with ID " + str(addr)
- mqttc.publish(mqtt_topic_prefix+"/" + mqtt_subtopic_notify, notifystr, qos=0, retain=False)
-
- if not os.path.exists(log_path+'/new'):
- os.makedirs(log_path+'/new')
-
- fname = log_path + '/new/' + str(addr)
- if not os.path.exists(fname):
- try:
- touch(fname)
- except:
- pass
-
- try:
- f = open(log_path+'/'+logfile_new_sensors, 'a')
- f.write(str(datetime.now())+": "+notifystr+"\n")
- f.close()
- except:
- # guat dann hoit ned...
- pass
-
- sensors_new_alreadyNotified[addr] = True
- else:
- if not os.path.exists(log_path+'/unknown'):
- os.makedirs(log_path+'/unknown')
- fname = log_path + '/unknown/' + str(addr)
- if not os.path.exists(fname):
- try:
- touch(fname)
- except:
- pass
-
- if verbosemode:
- print("unknown sensor ID " + str(addr))
-
- if verbosemode:
- print("LaCrosse-ID: " + str(addr) + " = 0x" + str(addrhex) + " Type: " + str(type) + " Batt_New: " + str(batt_new) + " Batt_Low: " + str(batt_low) + " Temp: " + str(temp) + " Hum: " + str(hum) + " Name: " + str(currentsensor_name))
- print()
-
- #if senddata:
- # sensors_lastUpdate[str(addr)] = int(time.time())
- # sensors_lastTemp[str(addr)] = temp
- # sensors_lastHum[str(addr)] = hum
- #
- # isAtemp = False
- # if int(currentsensor_idx) == atemp_sensor_idx:
- # 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 or ((time.time() - atemphum_lastUpdate) > aTempHumPublishInterval):
- # atemphum_lastUpdate = time.time()
- # atemp_last = atemp
- # ahum_last = ahum
- # mqttc.publish(mqtt_topic_atemp, str(atemp), qos=0, retain=True)
- # mqttc.publish(mqtt_topic_ahum, str(ahum), qos=0, retain=True)
- # mqttc.publish(mqtt_topic_atemphum_lastUpdate, strftime("%Y-%m-%d %H:%M:%S", localtime()), qos=0, retain=False)
- #
- # domoticz_json = "{\"idx\":" + str(currentsensor_idx) + ",\"nvalue\":0,\"svalue\":\"" + str(temp) + ";" + str(hum) + ";1\"}"
- # #if verbosemode:
- # # print(domoticz_json)
- # mqttc.publish(mqtt_topic_domoticz_in, domoticz_json, qos=0, retain=False)
- #
- # mqttc.publish(mqtt_topic_prefix+"/"+str(currentsensor_name)+"/temperature", str(temp), qos=0, retain=False)
- # mqttc.publish(mqtt_topic_prefix+"/"+str(currentsensor_name)+"/humidity", str(hum), qos=0, retain=False)
- # mqttc.publish(mqtt_topic_prefix+"/"+str(currentsensor_name)+"/battery", str(batterystate), qos=0, retain=False)
- # mqttc.publish(mqtt_topic_prefix+"/"+str(currentsensor_name)+"/lastUpdate", strftime("%Y-%m-%d %H:%M:%S", localtime()), qos=0, retain=False)
- # mqttc.publish(mqtt_topic_prefix+"/"+str(currentsensor_name)+"/availability", "available", qos=0, retain=False)
- #
- # lacrosse_json = "{\"temperature\":" + str(temp) + ", \"humidity\":" + str(hum) + ", \"battery\":\"" + str(batterystate) + "\"}"
- # mqttc.publish(mqtt_topic_prefix+"/"+str(currentsensor_name)+"/json", lacrosse_json, qos=0, retain=False)
- #
- # tmptext = str(temp) + "° " + str(hum) + "%"
- # mqttc.publish(mqtt_topic_prefix+"/"+str(currentsensor_name)+"/TempHumText", tmptext, qos=0, retain=False)
- #
- # if verbosemode:
- # print("MQTT published")
- #
- # try:
- # touch("/tmp/jeelink2mqtt_running")
- # except:
- # # guat dann ned...
- # pass
- #
- #else:
- # if verbosemode:
- # if currentsensor_name is None:
- # print("MQTT published")
- # else:
- # print("MQTT publishing surpressed (interval not expired)")
- #
- #
- #if verbosemode:
- # print("\n")
-
- else:
- if verbosemode: print("RX: " + serLine + " => ignored invalid data")
- pass
- else:
- if verbosemode:
- print("RX: " + serLine)
- pass
-
-
- # publish on MQTT on set interval
- publishNow = False
- if (int(time.time()) - lastPublishTime) > int(config['sensors'].get('publish_interval')):
- if lastPublishTime == 0:
- lastPublishTime = int(time.time())
- else:
- publishNow = True
- lastPublishTime = int(time.time())
-
- #for sensor in
- #sensors_lastReceivedTime[str(addr)]
-
- # store to InfluxDB on set interval
- storeNow = False
- if (int(time.time()) - lastStoreTime) > int(config['sensors'].get('store_interval')):
- if lastStoreTime == 0:
- lastStoreTime = int(time.time())
- else:
- storeNow = True
- lastStoreTime = int(time.time())
-
- if publishNow or storeNow:
- #print("available sensor data: ", sensors_lastUpdate)
- for id in sensors_lastUpdate:
-
- if (time.time() - sensors_lastUpdate[id]) < sensordata_maxage:
- s_name = sensors_id_to_name.get(id, None)
- if verbosemode: print("current data available for:", id, s_name)
-
- sensorDataComplete = True
-
- sum_temp=0
- for val in sensors_lastValues_temp[id]:
- if val is None:
- sensorDataComplete = False
- else:
- sum_temp = sum_temp + val
-
- sum_hum=0
- for val in sensors_lastValues_hum[id]:
- if val is None:
- sensorDataComplete = False
- else:
- sum_hum = sum_hum + val
-
- if sensorDataComplete:
- s_currAvgTemp = round(sum_temp / len(sensors_lastValues_temp[id]), 1)
- s_currAvgHum = int(sum_hum / len(sensors_lastValues_hum[id]))
-
- # calc dewpoint
- if config['sensors'].getboolean('calculate_dewpoint', False):
- s_currDewpoint = round(dewpoint(s_currAvgTemp, s_currAvgHum), 1)
-
- # calc absolute humidity
- if config['sensors'].getboolean('calculate_absolute_humidity', False):
- s_currAbsHum = round(absoluteHumidity(s_currAvgHum, s_currAvgTemp), 2)
-
- sensors_lastAvgValue_temp[id] = s_currAvgTemp
- sensors_lastAvgValue_hum[id] = s_currAvgHum
-
- if verbosemode: print("s_currAvgTemp =", s_currAvgTemp, "s_currAvgHum =", s_currAvgHum)
- else:
- if verbosemode: print("s_currAvgTemp/s_currAvgHum: not yet enough readings available")
-
- if sensorDataComplete:
-
- # as Home Assistant MQTT binary sensor can only work with 2 states (unless using value templates):
- # -> removed "NEW" state string from /battery topic and added /batteryNew topic
- if sensors_batteryState.get(id,None) == 2:
- s_battNew = True
- s_battState = "OK"
- elif sensors_batteryState.get(id, None) == 1:
- s_battNew = False
- s_battState = "LOW"
- elif sensors_batteryState.get(id, None) == 0:
- s_battNew = False
- s_battState = "OK"
-
- if s_battNew:
- s_battNew_str = "YES"
- else:
- s_battNew_str = "NO"
-
- if s_name is not None:
- s_domIdx = sensors_yaml[s_name].get('DomoticzIdx', None)
- s_topic_temp = sensors_yaml[s_name].get('Topic_Temp', None)
- s_topic_hum = sensors_yaml[s_name].get('Topic_Hum', None)
- s_topic_dew = sensors_yaml[s_name].get('Topic_Dew', None)
- s_topic_absHum = sensors_yaml[s_name].get('Topic_AbsHum', None)
- s_influxInstance = sensors_yaml[s_name].get('InfluxDB_Instance', None)
- s_isOutsideTempSensor = sensors_yaml[s_name].get('isOutsideTempSensor', None)
-
- if s_domIdx is not None and publishNow:
- domoticz_json = "{\"idx\":" + str(s_domIdx) + ",\"nvalue\":0,\"svalue\":\"" + str(s_currAvgTemp) + ";" + str(s_currAvgHum) + ";1\"}"
- if verbosemode:
- print("Domoticz JSON:", domoticz_json)
- mqttc.publish(mqtt_topic_domoticz_in, domoticz_json, qos=0, retain=False)
-
- if s_topic_temp is not None and len(s_topic_temp)>5 and publishNow:
- if verbosemode: print("publishing temp on ", s_topic_temp)
- mqttc.publish(s_topic_temp, str(s_currAvgTemp), qos=0, retain=False)
-
- if s_topic_dew is not None and len(s_topic_dew)>5 and publishNow and config['sensors'].getboolean('calculate_dewpoint', False):
- if verbosemode: print("publishing dewpoint on ", s_topic_dew)
- mqttc.publish(s_topic_dew, str(s_currDewpoint), qos=0, retain=False)
-
- if s_topic_absHum is not None and len(s_topic_absHum)>5 and publishNow and config['sensors'].getboolean('calculate_absolute_humidity', False):
- if verbosemode: print("publishing absolute humidty on ", s_topic_absHum)
- mqttc.publish(s_topic_absHum, str(s_currAbsHum), qos=0, retain=False)
-
- if s_topic_hum is not None and len(s_topic_hum)>5 and publishNow:
- if verbosemode: print("publishing hum on ", s_topic_temp)
- mqttc.publish(s_topic_hum, str(s_currAvgHum), qos=0, retain=False)
-
- if publishNow:
- mqttc.publish(mqtt_topic_prefix+"/"+ s_name +"/temperature", str(s_currAvgTemp), qos=0, retain=False)
- mqttc.publish(mqtt_topic_prefix+"/"+ s_name +"/humidity", str(s_currAvgHum), qos=0, retain=False)
-
- if config['sensors'].getboolean('calculate_dewpoint', False):
- mqttc.publish(mqtt_topic_prefix+"/"+ s_name +"/dewpoint", str(s_currDewpoint), qos=0, retain=False)
- if config['sensors'].getboolean('calculate_absolute_humidity', False):
- mqttc.publish(mqtt_topic_prefix+"/"+ s_name +"/absoluteHumidity", str(s_currAbsHum), qos=0, retain=False)
-
- mqttc.publish(mqtt_topic_prefix+"/"+ s_name +"/battery", s_battState, qos=0, retain=False)
- mqttc.publish(mqtt_topic_prefix+"/"+ s_name +"/batteryNew", s_battNew_str, qos=0, retain=False)
- mqttc.publish(mqtt_topic_prefix+"/"+ s_name +"/availability", "available", qos=0, retain=False)
- mqttc.publish(mqtt_topic_prefix+"/"+ s_name +"/lastUpdate", strftime("%Y-%m-%d %H:%M:%S", localtime()), qos=0, retain=False)
-
- # publish global lastUpdate for monitoring purposes
- mqttc.publish(mqtt_topic_prefix+"/lastUpdate", strftime("%Y-%m-%d %H:%M:%S", localtime()), qos=0, retain=False)
-
- # JSON output
- lacrosse_json = "{\"temperature\":" + str(s_currAvgTemp) \
- + ", \"humidity\":" + str(s_currAvgHum) \
- + ", \"battery\":\"" + str(s_battState) + "\""
-
- if config['sensors'].getboolean('calculate_dewpoint', False):
- lacrosse_json = lacrosse_json + ", \"dewpoint\":" + str(s_currDewpoint)
- if config['sensors'].getboolean('calculate_absolute_humidity', False):
- lacrosse_json = lacrosse_json + ", \"absoluteHumidity\":" + str(s_currAbsHum)
-
- lacrosse_json = lacrosse_json + "}"
- mqttc.publish(mqtt_topic_prefix+"/"+ s_name +"/json", lacrosse_json, qos=0, retain=False)
-
- tmptext = str(s_currAvgTemp) + "° " + str(s_currAvgHum) + "%"
- mqttc.publish(mqtt_topic_prefix+"/"+ s_name +"/TempHumText", tmptext, qos=0, retain=False)
-
- if s_influxInstance is not None and storeNow:
- ### write to InfluxDB here
-
- if s_influxInstance in influxdb_yaml:
- influx_measurement = influxdb_yaml[s_influxInstance].get('measurement', None)
-
- t_utc = datetime.utcnow()
- t_str = t_utc.isoformat() + 'Z'
-
- if influx_measurement is not None:
- influx_fieldnames = influxdb_yaml[s_influxInstance].get('fieldnames', None)
- if influx_fieldnames == None:
- influx_fieldname_temperature = influx_default_fieldname_temperature
- influx_fieldname_humidity = influx_default_fieldname_humidity
- influx_fieldname_dewpoint = influx_default_fieldname_dewpoint
- influx_fieldname_abshum = influx_default_fieldname_abshum
- else:
- if influxdb_yaml[s_influxInstance]['fieldnames'].get('temperature', None) != None:
- influx_fieldname_temperature = influxdb_yaml[s_influxInstance]['fieldnames'].get('temperature')
- else:
- influx_fieldname_temperature = influx_default_fieldname_temperature
-
- if influxdb_yaml[s_influxInstance]['fieldnames'].get('humidity', None) != None:
- influx_fieldname_humidity = influxdb_yaml[s_influxInstance]['fieldnames'].get('humidity')
- else:
- influx_fieldname_humidity = influx_default_fieldname_humidity
-
- if influxdb_yaml[s_influxInstance]['fieldnames'].get('dewpoint', None) != None:
- influx_fieldname_dewpoint = influxdb_yaml[s_influxInstance]['fieldnames'].get('dewpoint')
- else:
- influx_fieldname_dewpoint = influx_default_fieldname_dewpoint
-
- if influxdb_yaml[s_influxInstance]['fieldnames'].get('abshum', None) != None:
- influx_fieldname_abshum = influxdb_yaml[s_influxInstance]['fieldnames'].get('abshum')
- else:
- influx_fieldname_abshum = influx_default_fieldname_abshum
-
- influx_datatypes = influxdb_yaml[s_influxInstance].get('datatypes', None)
- if influx_datatypes == None:
- influx_datatype_temperature = influx_default_datatype_temperature
- influx_datatype_humidity = influx_default_datatype_humidity
- else:
- if influxdb_yaml[s_influxInstance]['datatypes'].get('temperature', None) != None:
- tmpdt = influxdb_yaml[s_influxInstance]['datatypes'].get('temperature')
- if tmpdt == 'float' or tmpdt == 'int':
- influx_datatype_temperature = tmpdt
- else:
- influx_datatype_temperature = influx_default_datatype_temperature
- else:
- influx_datatype_temperature = influx_default_datatype_temperature
-
- if influxdb_yaml[s_influxInstance]['datatypes'].get('humidity', None) != None:
- tmpdt = influxdb_yaml[s_influxInstance]['datatypes'].get('humidity')
- if tmpdt == 'float' or tmpdt == 'int':
- influx_datatype_humidity = tmpdt
- else:
- influx_datatype_humidity = influx_default_datatype_humidity
- else:
- influx_datatype_humidity = influx_default_datatype_humidity
-
- if influxdb_yaml[s_influxInstance]['datatypes'].get('dewpoint', None) != None:
- tmpdt = influxdb_yaml[s_influxInstance]['datatypes'].get('dewpoint')
- if tmpdt == 'float' or tmpdt == 'int':
- influx_datatype_dewpoint = tmpdt
- else:
- influx_datatype_dewpoint = influx_default_datatype_dewpoint
- else:
- influx_datatype_dewpoint = influx_default_datatype_dewpoint
-
- if influxdb_yaml[s_influxInstance]['datatypes'].get('abshum', None) != None:
- tmpdt = influxdb_yaml[s_influxInstance]['datatypes'].get('abshum')
- if tmpdt == 'float' or tmpdt == 'int':
- influx_datatype_abshum = tmpdt
- else:
- influx_datatype_abshum = influx_default_datatype_abshum
- else:
- influx_datatype_abshum = influx_default_datatype_abshum
-
- if influx_datatype_temperature == 'int':
- influx_value_temp = int(s_currAvgTemp)
- else:
- influx_value_temp = float(s_currAvgTemp)
-
- if influx_datatype_humidity == 'int':
- influx_value_hum = int(s_currAvgHum)
- else:
- influx_value_hum = float(s_currAvgHum)
-
- if config['sensors'].getboolean('calculate_dewpoint', False) and config['sensors'].getboolean('write_dewpoint_to_influxdb', False):
- if influx_datatype_dewpoint == 'int':
- influx_value_dewpoint = int(s_currDewpoint)
- else:
- influx_value_dewpoint = float(s_currDewpoint)
-
- if config['sensors'].getboolean('calculate_absolute_humidity', False) and config['sensors'].getboolean('write_abshum_to_influxdb', False):
- if influx_datatype_abshum == 'int':
- influx_value_abshum = int(s_currAbsHum)
- else:
- influx_value_abshum = float(s_currAbsHum)
-
- influx_json = [
- {
- 'measurement': influx_measurement,
- 'tags': {
- 'sensor': s_name
- },
- 'time': t_str,
- 'fields': {
- influx_fieldname_temperature: influx_value_temp,
- influx_fieldname_humidity: influx_value_hum
- }
- }
- ]
-
- if config['sensors'].getboolean('calculate_dewpoint', False) and config['sensors'].getboolean('write_dewpoint_to_influxdb', False):
- influx_json[0]["fields"][influx_fieldname_dewpoint] = influx_value_dewpoint
-
- if config['sensors'].getboolean('calculate_absolute_humidity', False) and config['sensors'].getboolean('write_abshum_to_influxdb', False):
- influx_json[0]["fields"][influx_fieldname_abshum] = influx_value_abshum
-
-
- try:
- if verbosemode:
- print("write to InfluxDB...")
- print(influx_json)
- influxclient[s_influxInstance].write_points(influx_json)
- if verbosemode: print("DONE!")
- except Exception as e:
- print("Error writing to InfluxDB")
- print(influx_json)
- print(e)
- else:
- if verbosemode:
- print("Error: invalid InfluxDB instance '" + s_influxInstance + "' configured for sensor '" + s_name + "'")
-
-
- else: # this is an unknown sensor
- if publishNow:
- if s_battNew:
- if config['mqtt'].getboolean('publish_unknown_new_sensors'):
- mqttc.publish(mqtt_topic_prefix+"/NewUnknownSensor/"+str(id)+"/temperature", str(s_currAvgTemp), qos=0, retain=False)
- mqttc.publish(mqtt_topic_prefix+"/NewUnknownSensor/"+str(id)+"/humidity", str(s_currAvgHum), qos=0, retain=False)
- mqttc.publish(mqtt_topic_prefix+"/NewUnknownSensor/"+str(id)+"/batteryNew", s_battNew_str, qos=0, retain=False)
- else:
- if config['mqtt'].getboolean('publish_unknown_sensors'):
- mqttc.publish(mqtt_topic_prefix+"/UnknownSensor/"+str(id)+"/temperature", str(s_currAvgTemp), qos=0, retain=False)
- mqttc.publish(mqtt_topic_prefix+"/UnknownSensor/"+str(id)+"/humidity", str(s_currAvgHum), qos=0, retain=False)
- mqttc.publish(mqtt_topic_prefix+"/UnknownSensor/"+str(id)+"/battery", s_battState, qos=0, retain=False)
- if verbosemode: print()
-
- # outside sensors
- if (int(time.time()) - outSens_lastRun) > int(config['sensors'].get('publish_interval_outside', 60)):
- outSens_lastRun = int(time.time())
-
- sum_out_sensors_temp = 0
- sum_out_sensors_temp_min = 100
- sum_out_sensors_temp_max = -50
- sum_out_sensors_hum = 0
- sum_out_sensors_hum_min = 100
- sum_out_sensors_hum_max = -50
- count_used_out_sensors = 0
-
- # "declare" variables with invalid high values - will be overwritten later
- out_temp_publishvalue = 200
- out_hum_publishvalue = 200
- out_dewpoint = 200
- out_abshum = 200
-
- # median
- if(config['sensors'].getboolean('outside_sensors_use_median')):
- out_sensors_temp_median_values = []
- out_sensors_hum_median_values = []
-
- for id in sensors_outside_sensors:
- lupd = sensors_lastUpdate.get(id, None)
- tdiff = 0
- if lupd is not None:
- tdiff = int(time.time()) - lupd
-
- if lupd is not None and (tdiff < sensordata_maxage):
- tmpval_t = sensors_lastAvgValue_temp.get(id, None)
- tmpval_h = sensors_lastAvgValue_hum.get(id, None)
- if tmpval_t is not None and tmpval_h is not None:
- sum_out_sensors_temp = sum_out_sensors_temp + tmpval_t
- sum_out_sensors_hum = sum_out_sensors_hum + tmpval_h
-
- if tmpval_t < sum_out_sensors_temp_min:
- sum_out_sensors_temp_min = tmpval_t
- if tmpval_t < sum_out_sensors_hum_min:
- sum_out_sensors_hum_min = tmpval_h
-
- if tmpval_t > sum_out_sensors_temp_max:
- sum_out_sensors_temp_max = tmpval_t
- if tmpval_t > sum_out_sensors_hum_max:
- sum_out_sensors_hum_max = tmpval_h
-
- # median
- if(config['sensors'].getboolean('outside_sensors_use_median')):
- out_sensors_temp_median_values.append(tmpval_t)
- out_sensors_hum_median_values.append(tmpval_h)
-
- count_used_out_sensors += 1
-
- lacrosse_json = None
-
- if count_used_out_sensors > 0:
- out_temp_avg = round((sum_out_sensors_temp / count_used_out_sensors), 1)
- out_hum_avg = int(round((sum_out_sensors_hum / count_used_out_sensors), 0))
-
- if(config['sensors'].getboolean('outside_sensors_use_median')):
- # median
- out_temp_median = round(statistics.median(out_sensors_temp_median_values), 1)
- out_hum_median = int(round(statistics.median(out_sensors_hum_median_values), 0))
- out_temp_publishvalue = out_temp_median
- out_hum_publishvalue = out_hum_median
-
- else:
- out_temp_publishvalue = out_temp_avg
- out_hum_publishvalue = out_hum_avg
-
- # calc dewpoint
- if config['sensors'].getboolean('calculate_dewpoint', False):
- out_dewpoint = round(dewpoint(out_temp_avg, out_hum_avg), 1)
-
- # calc absolute humidity
- if config['sensors'].getboolean('calculate_absolute_humidity', False):
- out_abshum = round(absoluteHumidity(out_hum_avg, out_temp_avg), 2)
-
-
- mqttc.publish(mqtt_topic_atemp, str(out_temp_publishvalue), qos=0, retain=True)
- mqttc.publish(mqtt_topic_ahum, str(out_hum_publishvalue), qos=0, retain=True)
- mqttc.publish(topic_prefix_outside_temphum + '/temperature', str(out_temp_publishvalue), qos=0, retain=True)
- mqttc.publish(topic_prefix_outside_temphum + '/humidity', str(out_hum_publishvalue), qos=0, retain=True)
-
- if config['sensors'].getboolean('calculate_dewpoint', False):
- mqttc.publish(topic_prefix_outside_temphum + '/dewpoint', str(out_dewpoint), qos=0, retain=True)
-
- if config['sensors'].getboolean('calculate_absolute_humidity', False):
- mqttc.publish(topic_prefix_outside_temphum + '/absoluteHumidity', str(out_abshum), qos=0, retain=True)
-
- mqttc.publish(topic_prefix_outside_temphum + '/temp_average', str(out_temp_avg), qos=0, retain=True)
- mqttc.publish(topic_prefix_outside_temphum + '/hum_average', str(out_hum_avg), qos=0, retain=True)
-
- if(config['sensors'].getboolean('outside_sensors_use_median')):
- mqttc.publish(topic_prefix_outside_temphum + '/temp_median', str(out_temp_median), qos=0, retain=True)
- mqttc.publish(topic_prefix_outside_temphum + '/hum_median', str(out_hum_median), qos=0, retain=True)
-
- mqttc.publish(topic_prefix_outside_temphum + '/lastUpdate', strftime("%Y-%m-%d %H:%M:%S", localtime()), qos=0, retain=True)
-
- tmptext = str(out_temp_publishvalue) + "° " + str(out_hum_publishvalue) + "%"
- mqttc.publish(topic_prefix_outside_temphum + "/TempHumText", tmptext, qos=0, retain=False)
-
- lacrosse_json = "{\"temperature\":" + str(out_temp_publishvalue) + \
- ", \"humidity\":" + str(out_hum_publishvalue) + "\"" \
- ", \"usedSensors\":" + str(count_used_out_sensors)
-
- min = 100
- max = 100
- if count_used_out_sensors > 1:
- mqttc.publish(topic_prefix_outside_temphum + '/usedSensors', str(count_used_out_sensors), qos=0, retain=True)
-
- lacrosse_json = lacrosse_json + \
- ", \"temp_average\":" + str(out_temp_avg) + \
- ", \"hum_average\":" + str(out_hum_avg) + \
- ", \"temp_median\":" + str(out_temp_median) + \
- ", \"hum_median\":" + str(out_temp_median)
-
- if sum_out_sensors_temp_min < 100:
- mqttc.publish(topic_prefix_outside_temphum + '/temp_min', str(sum_out_sensors_temp_min), qos=0, retain=False)
- lacrosse_json = lacrosse_json + ", \"temp_min\":" + str(sum_out_sensors_temp_min)
- if sum_out_sensors_temp_max > -50:
- mqttc.publish(topic_prefix_outside_temphum + '/temp_max', str(sum_out_sensors_temp_max), qos=0, retain=False)
- lacrosse_json = lacrosse_json + ", \"temp_max\":" + str(sum_out_sensors_temp_max)
- if sum_out_sensors_hum_min < 100:
- mqttc.publish(topic_prefix_outside_temphum + '/hum_min', str(sum_out_sensors_hum_min), qos=0, retain=False)
- lacrosse_json = lacrosse_json + ", \"hum_min\":" + str(sum_out_sensors_hum_min)
- if sum_out_sensors_hum_max > -50:
- mqttc.publish(topic_prefix_outside_temphum + '/hum_max', str(sum_out_sensors_hum_max), qos=0, retain=False)
- lacrosse_json = lacrosse_json + ", \"hum_max\":" + str(sum_out_sensors_hum_max)
-
-
- if lacrosse_json is not None:
- if config['sensors'].getboolean('calculate_dewpoint', False):
- lacrosse_json = lacrosse_json + ", \"dewpoint\":" + str(out_dewpoint)
- if config['sensors'].getboolean('calculate_absolute_humidity', False):
- lacrosse_json = lacrosse_json + ", \"absoluteHumidity\":" + str(out_abshum)
-
- lacrosse_json = lacrosse_json + "}"
- mqttc.publish(topic_prefix_outside_temphum + "/json", lacrosse_json, qos=0, retain=False)
-
-
-
- # combined outside sensors to InfluxDB
-
- o_hasValidData = False
- if out_temp_publishvalue < 200 and out_hum_publishvalue < 200:
- o_hasValidData = True
-
- o_storeNow = False
- if (int(time.time()) - outSens_store_lastRun) > int(config['sensors'].get('store_interval_outside', 300)):
- if outSens_store_lastRun == 0:
- outSens_store_lastRun = int(time.time())
- else:
- o_storeNow = True
- outSens_store_lastRun = int(time.time())
-
- if o_storeNow and o_hasValidData:
- outSens_store_lastRun = int(time.time())
- o_influxInstance = config['sensors'].get('influxdb_instance_combined_outside_sensors')
- o_influxSensorName = config['sensors'].get('influxdb_sensorname_combined_outside_sensors', None)
- if o_influxInstance in influxdb_yaml and o_influxSensorName is not None:
- influx_measurement = influxdb_yaml[o_influxInstance].get('measurement', None)
-
- t_utc = datetime.utcnow()
- t_str = t_utc.isoformat() + 'Z'
-
- if influx_measurement is not None:
- influx_fieldnames = influxdb_yaml[o_influxInstance].get('fieldnames', None)
- if influx_fieldnames == None:
- influx_fieldname_temperature = influx_default_fieldname_temperature
- influx_fieldname_humidity = influx_default_fieldname_humidity
- influx_fieldname_dewpoint = influx_default_fieldname_dewpoint
- influx_fieldname_abshum = influx_default_fieldname_abshum
- else:
- if influxdb_yaml[o_influxInstance]['fieldnames'].get('temperature', None) != None:
- influx_fieldname_temperature = influxdb_yaml[o_influxInstance]['fieldnames'].get('temperature')
- else:
- influx_fieldname_temperature = influx_default_fieldname_temperature
-
- if influxdb_yaml[o_influxInstance]['fieldnames'].get('humidity', None) != None:
- influx_fieldname_humidity = influxdb_yaml[o_influxInstance]['fieldnames'].get('humidity')
- else:
- influx_fieldname_humidity = influx_default_fieldname_humidity
-
- if influxdb_yaml[o_influxInstance]['fieldnames'].get('dewpoint', None) != None:
- influx_fieldname_dewpoint = influxdb_yaml[o_influxInstance]['fieldnames'].get('dewpoint')
- else:
- influx_fieldname_dewpoint = influx_default_fieldname_dewpoint
-
- if influxdb_yaml[o_influxInstance]['fieldnames'].get('abshum', None) != None:
- influx_fieldname_abshum = influxdb_yaml[o_influxInstance]['fieldnames'].get('abshum')
- else:
- influx_fieldname_abshum = influx_default_fieldname_abshum
-
- influx_datatypes = influxdb_yaml[o_influxInstance].get('datatypes', None)
- if influx_datatypes == None:
- influx_datatype_temperature = influx_default_datatype_temperature
- influx_datatype_humidity = influx_default_datatype_humidity
- else:
- if influxdb_yaml[o_influxInstance]['datatypes'].get('temperature', None) != None:
- tmpdt = influxdb_yaml[o_influxInstance]['datatypes'].get('temperature')
- if tmpdt == 'float' or tmpdt == 'int':
- influx_datatype_temperature = tmpdt
- else:
- influx_datatype_temperature = influx_default_datatype_temperature
- else:
- influx_datatype_temperature = influx_default_datatype_temperature
-
- if influxdb_yaml[o_influxInstance]['datatypes'].get('humidity', None) != None:
- tmpdt = influxdb_yaml[o_influxInstance]['datatypes'].get('humidity')
- if tmpdt == 'float' or tmpdt == 'int':
- influx_datatype_humidity = tmpdt
- else:
- influx_datatype_humidity = influx_default_datatype_humidity
- else:
- influx_datatype_humidity = influx_default_datatype_humidity
-
- if influxdb_yaml[o_influxInstance]['datatypes'].get('dewpoint', None) != None:
- tmpdt = influxdb_yaml[o_influxInstance]['datatypes'].get('dewpoint')
- if tmpdt == 'float' or tmpdt == 'int':
- influx_datatype_dewpoint = tmpdt
- else:
- influx_datatype_dewpoint = influx_default_datatype_dewpoint
- else:
- influx_datatype_dewpoint = influx_default_datatype_dewpoint
-
- if influxdb_yaml[o_influxInstance]['datatypes'].get('abshum', None) != None:
- tmpdt = influxdb_yaml[o_influxInstance]['datatypes'].get('abshum')
- if tmpdt == 'float' or tmpdt == 'int':
- influx_datatype_abshum = tmpdt
- else:
- influx_datatype_abshum = influx_default_datatype_abshum
- else:
- influx_datatype_abshum = influx_default_datatype_abshum
-
- if influx_datatype_temperature == 'int':
- influx_value_temp = int(out_temp_publishvalue)
- else:
- influx_value_temp = float(out_temp_publishvalue)
-
- if influx_datatype_humidity == 'int':
- influx_value_hum = int(out_hum_publishvalue)
- else:
- influx_value_hum = float(out_hum_publishvalue)
-
- if config['sensors'].getboolean('calculate_dewpoint', False) and config['sensors'].getboolean('write_dewpoint_to_influxdb', False):
- if influx_datatype_dewpoint == 'int':
- influx_value_dewpoint = int(out_dewpoint)
- else:
- influx_value_dewpoint = float(out_dewpoint)
-
- if config['sensors'].getboolean('calculate_absolute_humidity', False) and config['sensors'].getboolean('write_abshum_to_influxdb', False):
- if influx_datatype_abshum == 'int':
- influx_value_abshum = int(out_abshum)
- else:
- influx_value_abshum = float(out_abshum)
-
- influx_json = [
- {
- 'measurement': influx_measurement,
- 'tags': {
- 'sensor': o_influxSensorName
- },
- 'time': t_str,
- 'fields': {
- influx_fieldname_temperature: influx_value_temp,
- influx_fieldname_humidity: influx_value_hum
- }
- }
- ]
-
- if config['sensors'].getboolean('calculate_dewpoint', False) and config['sensors'].getboolean('write_dewpoint_to_influxdb', False) and out_dewpoint < 200:
- influx_json[0]["fields"][influx_fieldname_dewpoint] = influx_value_dewpoint
-
- if config['sensors'].getboolean('calculate_absolute_humidity', False) and config['sensors'].getboolean('write_abshum_to_influxdb', False) and out_abshum < 200:
- influx_json[0]["fields"][influx_fieldname_abshum] = influx_value_abshum
-
-
- try:
- if verbosemode:
- print("write to InfluxDB...")
- print(influx_json)
- influxclient[o_influxInstance].write_points(influx_json)
- if verbosemode: print("DONE!")
- except Exception as e:
- print("Error writing to InfluxDB")
- print(influx_json)
- print(e)
-
-
- # handle outdated sensor values once a minute
- if (int(time.time()) - checkLastUpdateInterval_lastRun) > checkLastUpdateInterval:
-
- # exit program if nothing has been received from JeeLink for 5 min - will be restarted by systemd
- now = int(time.time())
- if (now - serialReceivedLastTime) > serialReceived_maxAge:
- print("Nothing received from JeeLink for " + str(now - serialReceivedLastTime) + "s - there is something wrong. Exiting program so that it will be restarted by systemd.")
- quit()
-
- checkLastUpdateInterval_lastRun = int(time.time())
- #print("check lastUpdate")
- for key in sensors_yaml:
- #print(key, '->', sensors_yaml[key])
- #print("Sensor name:", key)
- sensorId = sensors_yaml[key].get('LaCrosseID', None)
- if sensorId >= 0:
- lupd = sensors_lastUpdate.get(sensorId, None)
- tdiff = 0
- if lupd is not None:
- tdiff = int(time.time()) - lupd
-
- if lupd is None or (tdiff > sensordata_maxage):
-
- mqttc.publish(mqtt_topic_prefix+"/"+ key +"/availability", "unavailable", qos=0, retain=False)
- notifystr = "received no data from sensor '" + key + "' with ID " + str(sensorId) + " for " + str(tdiff) + "s"
- mqttc.publish(mqtt_topic_prefix+"/" + mqtt_subtopic_notify, notifystr, qos=0, retain=False)
-
- except KeyboardInterrupt:
- print('\n')
- exit()
|