Thomas Dietrich 8 лет назад
Родитель
Сommit
569f2db419
1 измененных файлов с 54 добавлено и 39 удалено
  1. 54 39
      miflora-mqtt-daemon.py

+ 54 - 39
miflora-mqtt-daemon.py

@@ -6,6 +6,7 @@ import json
 import os.path
 from time import sleep, localtime, strftime
 from configparser import ConfigParser
+import unicodedata
 from miflora.miflora_poller import MiFloraPoller, MI_BATTERY, MI_CONDUCTIVITY, MI_LIGHT, MI_MOISTURE, MI_TEMPERATURE
 import paho.mqtt.client as mqtt
 import sdnotify
@@ -58,8 +59,8 @@ config.read([os.path.join(sys.path[0], 'config.ini'), os.path.join(sys.path[0],
 
 reporting_mode = config['General'].get('reporting_method', 'mqtt-json')
 daemon_enabled = config['Daemon'].getboolean('enabled', True)
-base_topic = config['MQTT'].get('base_topic', 'homie' if reporting_mode == 'mqtt-homie' else 'miflora')
-device_id = config['MQTT'].get('homie_device_id', 'miflora-mqtt-daemon')
+base_topic = config['MQTT'].get('base_topic', 'homie' if reporting_mode == 'mqtt-homie' else 'miflora').lower()
+device_id = config['MQTT'].get('homie_device_id', 'miflora-mqtt-daemon').lower()
 sleep_period = config['Daemon'].getint('period', 300)
 #miflora_cache_timeout = config['MiFlora'].getint('cache_timeout', 600)
 miflora_cache_timeout = sleep_period - 1
@@ -105,19 +106,27 @@ sd_notifier.notify('READY=1')
 # Initialize Mi Flora sensors
 flores = dict()
 for [name, mac] in config['Sensors'].items():
-    location = ''
-    if '@' in name:
-        name, location = name.split("@")
     if not re.match("C4:7C:8D:[0-9A-F]{2}:[0-9A-F]{2}:[0-9A-F]{2}", mac):
         print('Error. The MAC address "{}" seems to be in the wrong format. Please check your configuration.'.format(mac), file=sys.stderr)
         sd_notifier.notify('STATUS=The MAC address "{}" seems to be in the wrong format. Please check your configuration.'.format(mac))
         sys.exit(1)
+
+    location = ''
+    if '@' in name:
+        name, location = name.split("@")
+        location = location.replace(' ', '-')
+    name_pretty = name
+    name_clean = unicodedata.normalize('NFKD', name.lower()).replace(' ', '-')
+
+
     flora = dict()
     print('Adding sensor to device list and testing connection ...')
-    print('Name:         "{}"'.format(name))
-    sd_notifier.notify('STATUS=Attempting initial connection to Mi Flora sensor "{}" ({})'.format(name, mac))
+    print('Name:          "{}"'.format(name_pretty))
+    sd_notifier.notify('STATUS=Attempting initial connection to Mi Flora sensor "{}" ({})'.format(name_pretty, mac))
+
     flora_poller = MiFloraPoller(mac=mac, cache_timeout=miflora_cache_timeout, retries=9)
     flora['poller'] = flora_poller
+    flora['pretty'] = name_pretty
     flora['mac'] = flora_poller._mac
     flora['refresh'] = sleep_period
     flora['location'] = location
@@ -126,15 +135,16 @@ for [name, mac] in config['Sensors'].items():
         flora_poller.parameter_value(MI_LIGHT)
         flora['firmware'] = flora_poller.firmware_version()
     except IOError:
-        print('Error. Initial connection to Mi Flora sensor "{}" ({}) failed. Please check your setup and the MAC address.'.format(name, mac), file=sys.stderr)
-        sd_notifier.notify('STATUS=Initial connection to Mi Flora sensor "{}" ({}) failed'.format(name, mac))
+        print('Error. Initial connection to Mi Flora sensor "{}" ({}) failed. Please check your setup and the MAC address.'.format(name_pretty, mac), file=sys.stderr)
+        sd_notifier.notify('STATUS=Initial connection to Mi Flora sensor "{}" ({}) failed'.format(name_pretty, mac))
         continue
     else:
-        print('Device name:  "{}"'.format(flora_poller.name()))
-        print('MAC address:  {}'.format(flora_poller._mac))
-        print('Firmware:     {}'.format(flora_poller.firmware_version()))
+        print('Internal name: "{}"'.format(name_clean))
+        print('Device name:   "{}"'.format(flora_poller.name()))
+        print('MAC address:   {}'.format(flora_poller._mac))
+        print('Firmware:      {}'.format(flora_poller.firmware_version()))
         print()
-    flores[name] = flora
+    flores[name_clean] = flora
 
 # Discovery Announcement
 if reporting_mode == 'mqtt-json':
@@ -158,33 +168,37 @@ elif reporting_mode == 'mqtt-homie':
     mqtt_client.publish('{}/{}/$nodes'.format(base_topic, device_id), nodes_list, 1, True)
 
     for [flora_name, flora] in flores.items():
-        mqtt_client.publish('{}/{}/{}/$type'.format(base_topic, device_id, flora_name), 'miflora', 1, True)
-        mqtt_client.publish('{}/{}/{}/$properties'.format(base_topic, device_id, flora_name), 'battery,conductivity,light,moisture,temperature', 1, True)
-        mqtt_client.publish('{}/{}/{}/battery/$settable'.format(base_topic, device_id, flora_name), 'false', 1, True)
-        mqtt_client.publish('{}/{}/{}/battery/$unit'.format(base_topic, device_id, flora_name), 'percent', 1, True)
-        mqtt_client.publish('{}/{}/{}/battery/$datatype'.format(base_topic, device_id, flora_name), 'int', 1, True)
-        mqtt_client.publish('{}/{}/{}/battery/$range'.format(base_topic, device_id, flora_name), '0:100', 1, True)
-        mqtt_client.publish('{}/{}/{}/conductivity/$settable'.format(base_topic, device_id, flora_name), 'false', 1, True)
-        mqtt_client.publish('{}/{}/{}/conductivity/$unit'.format(base_topic, device_id, flora_name), 'µS/cm', 1, True)
-        mqtt_client.publish('{}/{}/{}/conductivity/$datatype'.format(base_topic, device_id, flora_name), 'int', 1, True)
-        mqtt_client.publish('{}/{}/{}/conductivity/$range'.format(base_topic, device_id, flora_name), '0:*', 1, True)
-        mqtt_client.publish('{}/{}/{}/light/$settable'.format(base_topic, device_id, flora_name), 'false', 1, True)
-        mqtt_client.publish('{}/{}/{}/light/$unit'.format(base_topic, device_id, flora_name), 'lux', 1, True)
-        mqtt_client.publish('{}/{}/{}/light/$datatype'.format(base_topic, device_id, flora_name), 'int', 1, True)
-        mqtt_client.publish('{}/{}/{}/light/$range'.format(base_topic, device_id, flora_name), '0:50000', 1, True)
-        mqtt_client.publish('{}/{}/{}/moisture/$settable'.format(base_topic, device_id, flora_name), 'false', 1, True)
-        mqtt_client.publish('{}/{}/{}/moisture/$unit'.format(base_topic, device_id, flora_name), 'percent', 1, True)
-        mqtt_client.publish('{}/{}/{}/moisture/$datatype'.format(base_topic, device_id, flora_name), 'int', 1, True)
-        mqtt_client.publish('{}/{}/{}/moisture/$range'.format(base_topic, device_id, flora_name), '0:100', 1, True)
-        mqtt_client.publish('{}/{}/{}/temperature/$settable'.format(base_topic, device_id, flora_name), 'false', 1, True)
-        mqtt_client.publish('{}/{}/{}/temperature/$unit'.format(base_topic, device_id, flora_name), '°C', 1, True)
-        mqtt_client.publish('{}/{}/{}/temperature/$datatype'.format(base_topic, device_id, flora_name), 'float', 1, True)
-        mqtt_client.publish('{}/{}/{}/temperature/$range'.format(base_topic, device_id, flora_name), '*', 1, True)
+        topic_path = '{}/{}/{}'.format(base_topic, device_id, flora_name)
+        mqtt_client.publish('{}/$name'.format(topic_path), flora['pretty'], 1, True)
+        mqtt_client.publish('{}/$type'.format(topic_path), 'miflora', 1, True)
+        mqtt_client.publish('{}/$properties'.format(topic_path), 'battery,conductivity,light,moisture,temperature', 1, True)
+        mqtt_client.publish('{}/battery/$settable'.format(topic_path), 'false', 1, True)
+        mqtt_client.publish('{}/battery/$unit'.format(topic_path), 'percent', 1, True)
+        mqtt_client.publish('{}/battery/$datatype'.format(topic_path), 'int', 1, True)
+        mqtt_client.publish('{}/battery/$range'.format(topic_path), '0:100', 1, True)
+        mqtt_client.publish('{}/conductivity/$settable'.format(topic_path), 'false', 1, True)
+        mqtt_client.publish('{}/conductivity/$unit'.format(topic_path), 'µS/cm', 1, True)
+        mqtt_client.publish('{}/conductivity/$datatype'.format(topic_path), 'int', 1, True)
+        mqtt_client.publish('{}/conductivity/$range'.format(topic_path), '0:*', 1, True)
+        mqtt_client.publish('{}/light/$settable'.format(topic_path), 'false', 1, True)
+        mqtt_client.publish('{}/light/$unit'.format(topic_path), 'lux', 1, True)
+        mqtt_client.publish('{}/light/$datatype'.format(topic_path), 'int', 1, True)
+        mqtt_client.publish('{}/light/$range'.format(topic_path), '0:50000', 1, True)
+        mqtt_client.publish('{}/moisture/$settable'.format(topic_path), 'false', 1, True)
+        mqtt_client.publish('{}/moisture/$unit'.format(topic_path), 'percent', 1, True)
+        mqtt_client.publish('{}/moisture/$datatype'.format(topic_path), 'int', 1, True)
+        mqtt_client.publish('{}/moisture/$range'.format(topic_path), '0:100', 1, True)
+        mqtt_client.publish('{}/temperature/$settable'.format(topic_path), 'false', 1, True)
+        mqtt_client.publish('{}/temperature/$unit'.format(topic_path), '°C', 1, True)
+        mqtt_client.publish('{}/temperature/$datatype'.format(topic_path), 'float', 1, True)
+        mqtt_client.publish('{}/temperature/$range'.format(topic_path), '*', 1, True)
     sleep(0.5) # some slack for the publish roundtrip and callback function
     print()
 
 sd_notifier.notify('STATUS=Initialization complete, starting MQTT publish loop')
 
+#flores_to_openhab_items(flores)
+
 # Sensor data retrieval and publication
 while True:
     for [flora_name, flora] in flores.items():
@@ -195,8 +209,8 @@ while True:
                 flora['poller'].fill_cache()
                 flora['poller'].parameter_value(MI_LIGHT)
             except IOError:
-                print('Failed to retrieve data from Mi Flora Sensor "{}" ({}). Retrying ...'.format(flora_name, flora['mac']), file=sys.stderr)
-                sd_notifier.notify('STATUS=Failed to retrieve data from Mi Flora Sensor "{}" ({}). Retrying ...'.format(flora_name, flora['mac']))
+                print('Failed to retrieve data from Mi Flora Sensor "{}" ({}). Retrying ...'.format(flora['pretty'], flora['mac']), file=sys.stderr)
+                sd_notifier.notify('STATUS=Failed to retrieve data from Mi Flora Sensor "{}" ({}). Retrying ...'.format(flora['pretty'], flora['mac']))
                 retries = retries - 1
         if not flora['poller']._cache:
             continue
@@ -206,12 +220,12 @@ while True:
         timestamp = strftime('%Y-%m-%d %H:%M:%S', localtime())
 
         if reporting_mode == 'mqtt-json':
-            print('[{}] Attempting to publishing to MQTT topic "{}/{}" ...\nData: {}'.format(timestamp, base_topic, flora_name, json.dumps(data)))
+            print('[{}] Attempting to publishing to MQTT topic "{}/{}" ...\nData: {}'.format(timestamp, base_topic, flora['pretty'], json.dumps(data)))
             mqtt_client.publish('{}/{}'.format(base_topic, flora_name), json.dumps(data))
             sleep(0.5) # some slack for the publish roundtrip and callback function
             print()
         elif reporting_mode == 'mqtt-homie':
-            print('[{}] Attempting to publishing data for Mi Flora "{}" ...\nData: {}'.format(timestamp, flora_name, str(data)))
+            print('[{}] Attempting to publishing data for Mi Flora "{}" ...\nData: {}'.format(timestamp, flora['pretty'], str(data)))
             for [param, value] in data.items():
                 mqtt_client.publish('{}/{}/{}/{}'.format(base_topic, device_id, flora_name, param), value, 1, False)
             sleep(0.5) # some slack for the publish roundtrip and callback function
@@ -219,6 +233,7 @@ while True:
         elif reporting_mode == 'json':
             data['timestamp'] = timestamp
             data['name'] = flora_name
+            data['pretty_name'] = flora['pretty']
             data['mac'] = flora['mac']
             data['firmware'] = flora['firmware']
             print('Data:', json.dumps(data))