12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241 |
- #!/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())
-
- count_used_out_sensors = 0
- sum_out_sensors_temp = 0
- sum_out_sensors_hum = 0
-
- # "declare" variables with invalid high values - will be overwritten later or keep unused
- sum_out_sensors_temp_min = 100
- sum_out_sensors_temp_max = -50
- sum_out_sensors_hum_min = 100
- sum_out_sensors_hum_max = -50
-
- out_temp_publishvalue = 200
- out_hum_publishvalue = 200
- out_dewpoint = 200
- out_abshum = 200
-
- # arrays for median calculation
- 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 - used for average
- sum_out_sensors_temp = sum_out_sensors_temp + tmpval_t
- sum_out_sensors_hum = sum_out_sensors_hum + tmpval_h
-
- # memorize values from sensor with lowest reading
- if tmpval_t < sum_out_sensors_temp_min:
- sum_out_sensors_temp_min = tmpval_t
- sum_out_sensors_hum_min = tmpval_h
-
- # memorize values from sensor with highest reading
- if tmpval_t > sum_out_sensors_temp_max:
- sum_out_sensors_temp_max = tmpval_t
- 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))
-
-
- # calc MEDIAN if there are more than 2 outside sensors
- out_temp_median = 0
- out_hum_median = 0
- if count_used_out_sensors > 2:
- 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))
-
-
- # use MINIMUM if outside_sensors_force_minimum_value is enabled
- if(config['sensors'].getboolean('outside_sensors_force_minimum_value')):
- if sum_out_sensors_temp_min < 100:
- out_temp_publishvalue = sum_out_sensors_temp_min
- if sum_out_sensors_hum_min < 100:
- out_hum_publishvalue = sum_out_sensors_hum_min
-
- # use MEDIAN if outside_sensors_use_median is enabled and there are more than 2 sensors
- elif(config['sensors'].getboolean('outside_sensors_use_median')) and count_used_out_sensors > 2:
- out_temp_publishvalue = out_temp_median
- out_hum_publishvalue = out_hum_median
- # otherwise user AVERAGE
- 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)
-
- # publish AVERAGE
- 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)
-
- # publish MEDIAN
- if count_used_out_sensors > 2:
- 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)
-
- # publish last update
- mqttc.publish(topic_prefix_outside_temphum + '/lastUpdate', strftime("%Y-%m-%d %H:%M:%S", localtime()), qos=0, retain=True)
-
- # publish TempHumText
- 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)
-
- if count_used_out_sensors > 2:
- lacrosse_json = lacrosse_json + \
- ", \"temp_median\":" + str(out_temp_median) + \
- ", \"hum_median\":" + str(out_temp_median)
-
- # publish MIN
- 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_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)
-
- # publish MAX
- 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_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()
|