You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
mqtt-sensord/mqtt_sensord/mqtt_sensord.py

105 lines
3.4 KiB

#!/usr/bin/env python3
import sys
import time
if sys.implementation.name != 'micropython':
import argparse
from . import sensorlib
from .mqttlib import MQTTClient
else:
import sensorlib
from mqttlib import MQTTClient
def main():
if sys.implementation.name != 'micropython':
parser = argparse.ArgumentParser()
parser.add_argument("-c", "--config", default="/etc/mqtt-sensord.conf")
parser.add_argument("-d", "--debug", action="store_true", default=False)
args = parser.parse_args()
config_path = args.config
debug = args.debug
else:
# most probably on micropython
config_path = "mqtt-sensord.conf"
debug = False
config = sensorlib.load_config(config_path)
debug = debug or config.get('debug')
config['debug'] = debug
esp_reset_time = config['host'].get('esp-reset-time')
sensorlib.Sensor.configure(config['host']['name'], sys.platform)
mcfg = config['mqtt']
if 'client_id' in config['mqtt']:
client_id = config['mqtt']['client_id']
else:
client_id = None
mqtt_mode = config['mqtt'].get('mode', 'split')
mqtt = MQTTClient(mcfg['host'], mcfg['user'], mcfg['password'], client_id)
default_mqtt_topic = mcfg.get('sensor_topic')
print("Connected to", mqtt.host, "with default topic", default_mqtt_topic)
mqtt.set_callback(sensorlib.Sensor.run_mqtt_callback)
sensors = []
extra_topics = set()
for scfg in config['sensors']:
s = sensorlib.Sensor.make_sensor(**scfg)
s.register_callbacks()
for topic in s.get_topics():
extra_topics.add(topic)
sensors.append(s)
for topic in extra_topics:
print("Subscribe to", topic)
mqtt.subscribe(topic)
last_measurement = start_time = time.time()
while True:
# handle regular sensor data
if debug:
print("Getting values from sensors...")
if mqtt_mode == 'split':
for sensor in sensors:
if sensor.HAS_SENSOR_DATA:
data = sensor.gen_datapoint()
if debug:
print(default_mqtt_topic, data)
mqtt.send_data(default_mqtt_topic, data)
if not mqtt.is_async():
mqtt.process_mqtt()
elif mqtt_mode == 'combined':
data = {
'hostname': config['host']['name'],
'platform': sys.platform,
}
for sensor in sensors:
if sensor.HAS_SENSOR_DATA:
data[sensor.id] = sensor.get_data()
if debug:
print(default_mqtt_topic, data)
mqtt.send_data(default_mqtt_topic, data)
if not mqtt.is_async():
mqtt.process_mqtt()
else:
raise RuntimeError("Unknown mqtt mode {}".format(mqtt_mode))
if mqtt.is_async():
time.sleep(max(0.0, time.time() + config['host']['interval'] - last_measurement))
else:
while time.time() - last_measurement < config['host']['interval']:
mqtt.process_mqtt()
time.sleep(0.1)
last_measurement = time.time()
if sys.implementation.name == 'micropython' and esp_reset_time and \
last_measurement - start_time > esp_reset_time:
import machine
machine.reset()
if __name__ == '__main__':
main()