misensor-mqtt-daemon/mqtt-flora.py

85 lines
3.3 KiB
Python
Raw Normal View History

2017-02-09 21:15:25 +01:00
#!/usr/bin/env python3
import sys
2017-02-09 21:15:25 +01:00
import json
from time import sleep, localtime, strftime
from configparser import ConfigParser
from miflora.miflora_poller import MiFloraPoller, MI_BATTERY, MI_CONDUCTIVITY, MI_LIGHT, MI_MOISTURE, MI_TEMPERATURE
import paho.mqtt.client as mqtt
parameters = [MI_BATTERY, MI_CONDUCTIVITY, MI_LIGHT, MI_MOISTURE, MI_TEMPERATURE]
2017-02-09 21:15:25 +01:00
print('Xiaomi Mi Flora Plant Sensor MQTT Client/Daemon')
print('Source: https://github.com/janwh/miflora-mqtt-daemon')
print()
2017-02-09 21:15:25 +01:00
# Load configuration file
2017-02-09 21:15:25 +01:00
config = ConfigParser(delimiters=('=', ))
config.optionxform = str
2017-02-09 21:15:25 +01:00
config.read('config.ini')
daemon_enabled = config['Daemon'].getboolean('enabled', True)
sleep_period = config['Daemon'].getint('period', 60)
topic_prefix = config['MQTT'].get('topic_prefix', 'miflora')
miflora_cache_timeout = config['MiFlora'].getint('cache_timeout', 600)
if not config['Sensors']:
print('Error. Please add at least one sensor to the configuration file "config.ini".', file=sys.stderr)
print('Scan for available Miflora sensors with "hcitool lescan".', file=sys.stderr)
sys.exit(1)
2017-02-09 21:15:25 +01:00
# Initialize Mi Flora sensors
2017-02-09 21:15:25 +01:00
flores = {}
for flora in config['Sensors'].items():
print('Adding device from config to Mi Flora device list ...')
print('Name: "{}"'.format(flora[0]))
flores[flora[0]] = MiFloraPoller(mac=flora[1], cache_timeout=miflora_cache_timeout)
print('Device name: "{}"'.format(flores[flora[0]].name()))
print('MAC address: {}'.format(flora[1]))
print('Firmware: {}'.format(flores[flora[0]].firmware_version()))
print()
2017-02-09 21:15:25 +01:00
# Callbacks http://www.eclipse.org/paho/clients/python/docs/#callbacks
def on_connect(client, userdata, flags, rc):
if rc != 0:
print('Connected with result code {}: {}'.format(str(rc), mqtt.connack_string(rc)), file=sys.stderr)
sys.exit(1)
def on_publish(client, userdata, mid):
print('Data successfully published!')
2017-02-09 21:15:25 +01:00
# MQTT connection
print('Connecting to MQTT broker ...')
mqtt_client = mqtt.Client()
mqtt_client.on_connect = on_connect
mqtt_client.on_publish = on_publish
if config['MQTT'].get('username'):
mqtt_client.username_pw_set(config['MQTT'].get('username'), config['MQTT'].get('password', None))
try:
mqtt_client.connect(config['MQTT'].get('hostname', 'localhost'),
port=config['MQTT'].getint('port', 1883),
keepalive=config['MQTT'].getint('keepalive', 60))
except:
print('Error. Please check your MQTT connection settings in the configuration file "config.ini".', file=sys.stderr)
sys.exit(1)
else:
print('Connected.\n')
mqtt_client.loop_start()
2017-02-09 21:15:25 +01:00
# Sensor data retrieval and publishing
2017-02-09 21:15:25 +01:00
while True:
for flora in flores:
data = {}
for param in parameters:
data[param] = flores.get(flora).parameter_value(param)
print(strftime('[%Y-%m-%d %H:%M:%S]', localtime()), end=' ')
print('Attempting to publishing to MQTT topic "{}/{}" ...\nData: {}'.format(topic_prefix, flora, json.dumps(data)))
mqtt_client.publish('{}/{}'.format(topic_prefix, flora), json.dumps(data))
sleep(0.5) # some slack for the publish roundtrip and callback function
print()
if not daemon_enabled:
break
print('Sleeping ({} seconds) ...'.format(sleep_period))
sleep(sleep_period)
print()
2017-02-09 21:15:25 +01:00
mqtt_client.disconnect()
2017-02-09 21:15:25 +01:00