Browse Source

Add support for creating sensor entities in HomeAssistant

This uses the MQTT Discovery component in HomeAssistant to create
sensors for each property of each Mi Flora device

See https://home-assistant.io/docs/mqtt/discovery/ for details
William Hughes 8 years ago
parent
commit
4a0d7f4022
2 changed files with 30 additions and 3 deletions
  1. 1 0
      README.md
  2. 29 3
      miflora-mqtt-daemon.py

+ 1 - 0
README.md

@@ -19,6 +19,7 @@ The program can be executed in **daemon mode** to run continuously in the backgr
     * JSON encoded
     * JSON encoded
     * following the [Homie Convention v2.0.5](https://github.com/marvinroger/homie)
     * following the [Homie Convention v2.0.5](https://github.com/marvinroger/homie)
     * following the [mqtt-smarthome architecture proposal](https://github.com/mqtt-smarthome/mqtt-smarthome)
     * following the [mqtt-smarthome architecture proposal](https://github.com/mqtt-smarthome/mqtt-smarthome)
+	* using the [HomeAssistant MQTT discovery format](https://home-assistant.io/docs/mqtt/discovery/)
 * Announcement messages to support auto-discovery services
 * Announcement messages to support auto-discovery services
 * MQTT authentication support
 * MQTT authentication support
 * No special/root privileges needed
 * No special/root privileges needed

+ 29 - 3
miflora-mqtt-daemon.py

@@ -122,13 +122,21 @@ config.read([os.path.join(sys.path[0], 'config.ini.dist'), os.path.join(sys.path
 reporting_mode = config['General'].get('reporting_method', 'mqtt-json')
 reporting_mode = config['General'].get('reporting_method', 'mqtt-json')
 used_adapter = config['General'].get('adapter', 'hci0')
 used_adapter = config['General'].get('adapter', 'hci0')
 daemon_enabled = config['Daemon'].getboolean('enabled', True)
 daemon_enabled = config['Daemon'].getboolean('enabled', True)
-base_topic = config['MQTT'].get('base_topic', 'homie' if reporting_mode == 'mqtt-homie' else 'miflora').lower()
+
+if reporting_mode == 'mqtt-homie':
+    default_base_topic = 'homie'
+elif reporting_mode == 'homeassistant-mqtt':
+    default_base_topic = 'homeassistant'
+else:
+    default_base_topic = 'miflora'
+
+base_topic = config['MQTT'].get('base_topic', default_base_topic).lower()
 device_id = config['MQTT'].get('homie_device_id', 'miflora-mqtt-daemon').lower()
 device_id = config['MQTT'].get('homie_device_id', 'miflora-mqtt-daemon').lower()
 sleep_period = config['Daemon'].getint('period', 300)
 sleep_period = config['Daemon'].getint('period', 300)
 miflora_cache_timeout = sleep_period - 1
 miflora_cache_timeout = sleep_period - 1
 
 
 # Check configuration
 # Check configuration
-if not reporting_mode in ['mqtt-json', 'mqtt-homie', 'json', 'mqtt-smarthome']:
+if reporting_mode not in ['mqtt-json', 'mqtt-homie', 'json', 'mqtt-smarthome', 'homeassistant-mqtt']:
     print_line('Configuration parameter reporting_mode set to an invalid value', error=True, sd_notify=True)
     print_line('Configuration parameter reporting_mode set to an invalid value', error=True, sd_notify=True)
     sys.exit(1)
     sys.exit(1)
 if not config['Sensors']:
 if not config['Sensors']:
@@ -138,7 +146,7 @@ if not config['Sensors']:
 print_line('Configuration accepted', console=False, sd_notify=True)
 print_line('Configuration accepted', console=False, sd_notify=True)
 
 
 # MQTT connection
 # MQTT connection
-if reporting_mode in ['mqtt-json', 'mqtt-homie', 'mqtt-smarthome']:
+if reporting_mode in ['mqtt-json', 'mqtt-homie', 'mqtt-smarthome', 'homeassistant-mqtt']:
     print_line('Connecting to MQTT broker ...')
     print_line('Connecting to MQTT broker ...')
     mqtt_client = mqtt.Client()
     mqtt_client = mqtt.Client()
     mqtt_client.on_connect = on_connect
     mqtt_client.on_connect = on_connect
@@ -273,6 +281,20 @@ elif reporting_mode == 'mqtt-homie':
         mqtt_client.publish('{}/temperature/$range'.format(topic_path), '*', 1, True)
         mqtt_client.publish('{}/temperature/$range'.format(topic_path), '*', 1, True)
     sleep(0.5) # some slack for the publish roundtrip and callback function
     sleep(0.5) # some slack for the publish roundtrip and callback function
     print()
     print()
+elif reporting_mode == 'homeassistant-mqtt':
+    print_line('Announcing Mi Flora devices to MQTT broker for auto-discovery ...')
+    for [flora_name, flora] in flores.items():
+        topic_path = '{}/sensor/{}'.format(base_topic, flora_name)
+        base_payload = {
+            "device_class": "sensor",
+            "state_topic": "{}/state".format(topic_path).lower()
+        }
+        for sensor, params in parameters.items():
+            payload = dict(base_payload.items())
+            payload['unit_of_measurement'] = params['unit']
+            payload['value_template'] = "{{ value_json.%s }}" % (sensor, )
+            payload['name'] = "{} {}".format(flora_name, sensor.title())
+            mqtt_client.publish('{}/{}_{}/config'.format(topic_path, flora_name, sensor).lower(), json.dumps(payload), 1, True)
 
 
 print_line('Initialization complete, starting MQTT publish loop', console=False, sd_notify=True)
 print_line('Initialization complete, starting MQTT publish loop', console=False, sd_notify=True)
 
 
@@ -315,6 +337,10 @@ while True:
             print_line('Publishing to MQTT topic "{}/{}"'.format(base_topic, flora_name))
             print_line('Publishing to MQTT topic "{}/{}"'.format(base_topic, flora_name))
             mqtt_client.publish('{}/{}'.format(base_topic, flora_name), 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
             sleep(0.5) # some slack for the publish roundtrip and callback function
+        elif reporting_mode == 'homeassistant-mqtt':
+            print_line('Publishing to MQTT topic "{}/sensor/{}/state"'.format(base_topic, flora_name).lower())
+            mqtt_client.publish('{}/sensor/{}/state'.format(base_topic, flora_name).lower(), json.dumps(data))
+            sleep(0.5) # some slack for the publish roundtrip and callback function
         elif reporting_mode == 'mqtt-homie':
         elif reporting_mode == 'mqtt-homie':
             print_line('Publishing data to MQTT base topic "{}/{}/{}"'.format(base_topic, device_id, flora_name))
             print_line('Publishing data to MQTT base topic "{}/{}/{}"'.format(base_topic, device_id, flora_name))
             for [param, value] in data.items():
             for [param, value] in data.items():