Browse Source

## 2022-11-14

* fix config mqtt/enable did not work (was always true)
* fix config sensors/outside_sensors_use_median did not work (was always true)
* add dewpoint calculation and config settings calculate_dewpoint, write_dewpoint_to_influxdb
* add absolute humidity calculation and config setting calculate_absolute_humidity, write_abshum_to_influxdb
* add config switches: publish_unknown_sensors, publish_unknown_new_sensors
* add InfluxDB fieldnames/datatypes for dewpoint and absolute humidity
* fixed wrong defined influx_default_datatype_humidity
* add store combined outdoor sensors to InfluxDB
FloKra 1 year ago
parent
commit
d3e50eb271

+ 11 - 0
CHANGELOG.md

@@ -1,5 +1,16 @@
 # JeeLinkLogMQTT - change log
 
+## 2022-11-14
+
+* fix config mqtt/enable did not work (was always true)
+* fix config sensors/outside_sensors_use_median did not work (was always true)
+* add dewpoint calculation and config settings calculate_dewpoint, write_dewpoint_to_influxdb
+* add absolute humidity calculation and config setting calculate_absolute_humidity, write_abshum_to_influxdb
+* add config switches: publish_unknown_sensors, publish_unknown_new_sensors
+* add InfluxDB fieldnames/datatypes for dewpoint and absolute humidity
+* fixed wrong defined influx_default_datatype_humidity
+* add store combined outdoor sensors to InfluxDB
+
 ## 2022-11-08
 
 * updated README.md

+ 19 - 2
jeelinklog/jeelinklog.ini

@@ -11,7 +11,7 @@ serialport = /dev/serial/by-id/usb-FTDI_FT232R_USB_UART_AL01MYTF-if00-port0
 baudrate = 57600
 
 [mqtt]
-enable = true
+enable = True
 server = 127.0.0.1
 port = 1883
 user = 
@@ -19,16 +19,21 @@ password =
 
 # topic prefix
 topic_prefix = LaCrosse
-
 topic_prefix_outside_temphum = wetter/atemphum
 
 # additional single topics for outside temp/hum
 topic_outside_temp = wetter/atemp
 topic_outside_hum = wetter/ahum
+topic_outside_dew = wetter/dewpoint
+topic_outside_abshum = wetter/abshum
 
 # topic for notifications (low battery, new sensor found...)
 subtopic_notify = NOTIFY
 
+publish_unknown_sensors = False
+publish_unknown_new_sensors = True
+
+
 [sensors]
 # average sensor values - average over that many received readings
 average_value_steps = 5
@@ -43,7 +48,19 @@ publish_interval = 60
 # interval in s to store data in InfluxDB
 store_interval = 300
 
+publish_interval_outside = 120
+store_interval_outside = 300
+
 data_maxage = 600
 
 outside_sensors_use_median = True
 # otherwise average is used
+
+calculate_dewpoint = True
+calculate_absolute_humidity = True
+write_dewpoint_to_influxdb = True
+write_abshum_to_influxdb = True
+
+# for calculated (averaged from multiple sensors)
+influxdb_instance_combined_outside_sensors = wetter
+influxdb_sensorname_combined_outside_sensors = Outside

+ 364 - 34
jeelinklog/jeelinklog.py

@@ -16,6 +16,7 @@ import paho.mqtt.client as mqtt
 import yaml
 import json
 import statistics
+import math
 #import math
 #import numpy as np
 #import httplib
@@ -33,6 +34,8 @@ 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')
@@ -122,12 +125,16 @@ sensors_new_alreadyNotified = dict()
 
 sensors_outside_sensors = []
 outSens_lastRun = 0
-outSens_interval = 120
+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_temperature = 'int'
+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)
 
@@ -138,6 +145,59 @@ def list_duplicates(seq):
   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")
@@ -525,8 +585,18 @@ try:
                     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")
@@ -554,6 +624,8 @@ try:
                             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)
                             
@@ -567,6 +639,14 @@ try:
                                 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)
@@ -574,12 +654,28 @@ try:
                             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)
                                 
-                                lacrosse_json = "{\"temperature\":" + str(s_currAvgTemp) + ", \"humidity\":" + str(s_currAvgHum) + ", \"battery\":\"" + str(s_battState) + "\"}"
+                                # 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) + "%"
@@ -599,6 +695,8 @@ try:
                                         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')
@@ -610,6 +708,16 @@ try:
                                             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
@@ -633,6 +741,24 @@ try:
                                             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:
@@ -643,6 +769,18 @@ try:
                                         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,
@@ -657,12 +795,22 @@ try:
                                             }
                                         ]
                                         
+                                        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...")
+                                            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:
@@ -672,17 +820,19 @@ try:
                         else: # this is an unknown sensor
                             if publishNow:
                                 if s_battNew:
-                                    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+"/UnknownSensor/"+str(id)+"/batteryNew", s_battNew_str, qos=0, retain=False)
+                                    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:
-                                    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 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) > outSens_interval:
+        if (int(time.time()) - outSens_lastRun) > int(config['sensors'].get('publish_interval_outside', 60)):
             outSens_lastRun = int(time.time())
             
             sum_out_sensors_temp = 0
@@ -693,9 +843,16 @@ try:
             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
-            out_sensors_temp_median_values = []
-            out_sensors_hum_median_values = []
+            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)
@@ -721,53 +878,71 @@ try:
                             sum_out_sensors_hum_max = tmpval_h                        
                         
                         # median
-                        out_sensors_temp_median_values.append(tmpval_t)
-                        out_sensors_hum_median_values.append(tmpval_h)
+                        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))
-                
-                # median
-                out_temp_median = round(statistics.median(out_sensors_temp_median_values), 1)
-                out_hum_median = int(statistics.median(out_sensors_hum_median_values))
-                
-                out_temp_publishvalue = out_temp_avg
-                out_hum_publishvalue = out_hum_avg
-                if(config['sensors'].get('outside_sensors_use_median')):
+                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)
-                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)
+                
+                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) + "}"
+                                ", \"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 = "{\"temperature\":" + str(out_hum_publishvalue) + \
-                                ", \"humidity\":" + str(out_hum_publishvalue) + \
-                                ", \"usedSensors\":" + str(count_used_out_sensors) + \
+                lacrosse_json = lacrosse_json + \
                                 ", \"temp_average\":" + str(out_temp_avg) + \
                                 ", \"hum_average\":" + str(out_hum_avg) + \
                                 ", \"temp_median\":" + str(out_temp_median) + \
@@ -786,11 +961,166 @@ try:
                     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)
                 
-                lacrosse_json = lacrosse_json + "}"
-            
+                
             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:

+ 9 - 1
jeelinklog/jeelinklog_influxdb.yml

@@ -8,9 +8,13 @@ wetter:
   fieldnames:
     temperature: temp
     humidity: hum
+    dewpoint: dewpoint
+    abshum: absHum
   datatypes:
     temperature: float
     humidity: int
+    dewpoint: float
+    abshum: float
 test:
   host: localhost
   port: 8086
@@ -21,6 +25,10 @@ test:
   fieldnames:
     temperature: temp
     humidity: hum
+    dewpoint: dewpoint
+    abshum: absHum
   datatypes:
     temperature: float
-    humidity: int
+    humidity: int
+    dewpoint: float
+    abshum: float

+ 14 - 0
jeelinklog/jeelinklog_sensors.yml

@@ -3,6 +3,8 @@ Garten:
   DomoticzIdx: 94
   #Topic_Temp: "Test/Atemp"
   #Topic_Hum: "Test/Ahum"
+  #Topic_Dew: "Test/Dewpoint"
+  #Topic_AbsHum: "Test/AbsoluteHumidity"
   InfluxDB_Instance: wetter
   isOutsideTempSensor: true
 Parkplatz:
@@ -10,6 +12,8 @@ Parkplatz:
   DomoticzIdx: 113
   #Topic_Temp: ""
   #Topic_Hum: ""
+  #Topic_Dew: "Test/Dewpoint"
+  #Topic_AbsHum: "Test/AbsoluteHumidity"
   InfluxDB_Instance: wetter
   isOutsideTempSensor: true
 Stiegenhaus:
@@ -17,28 +21,38 @@ Stiegenhaus:
   DomoticzIdx: 264
   #Topic_Temp: ""
   #Topic_Hum: ""
+  #Topic_Dew: "Test/Dewpoint"
+  #Topic_AbsHum: "Test/AbsoluteHumidity"
   InfluxDB_Instance: KS61
 T5-Arbeitszimmer:
   LaCrosseID: 32
   DomoticzIdx: 1
   #Topic_Temp: ""
   #Topic_Hum: ""
+  #Topic_Dew: "Test/Dewpoint"
+  #Topic_AbsHum: "Test/AbsoluteHumidity"
   InfluxDB_Instance: KS61T5
 T5-Bad:
   LaCrosseID: 19
   DomoticzIdx: 4
   #Topic_Temp: ""
   #Topic_Hum: ""
+  #Topic_Dew: "Test/Dewpoint"
+  #Topic_AbsHum: "Test/AbsoluteHumidity"
   InfluxDB_Instance: KS61T5
 T5-Balkon:
   LaCrosseID: 22
   DomoticzIdx: 88
   #Topic_Temp: ""
   #Topic_Hum: ""
+  #Topic_Dew: "Test/Dewpoint"
+  #Topic_AbsHum: "Test/AbsoluteHumidity"
   InfluxDB_Instance: wetter
 T5-Kueche:
   LaCrosseID: 5
   DomoticzIdx: 6
   #Topic_Temp: ""
   #Topic_Hum: ""
+  #Topic_Dew: "Test/Dewpoint"
+  #Topic_AbsHum: "Test/AbsoluteHumidity"
   InfluxDB_Instance: KS61T5