Julien Riou
bb65a7c6b6
The sound module may not be available so the parse function fails. This commit makes the parsing function more generic by giving a list of metrics to retreive in order. Signed-off-by: Julien Riou <julien@riou.xyz>
113 lines
3.4 KiB
Python
Executable file
113 lines
3.4 KiB
Python
Executable file
#!/usr/bin/env python3
|
|
import argparse
|
|
import configparser
|
|
import logging
|
|
import os
|
|
import sys
|
|
import time
|
|
|
|
import paho.mqtt.client as paho
|
|
import serial
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def read_serial(interface):
|
|
try:
|
|
logger.debug('reading serial interface {}'.format(interface))
|
|
s = serial.Serial(interface)
|
|
s.flushInput()
|
|
for i in range(2):
|
|
data = s.readline()
|
|
if i > 0:
|
|
return data
|
|
except Exception as err:
|
|
logger.warning(str(err))
|
|
time.sleep(2)
|
|
|
|
|
|
def parse_sensor_values(data):
|
|
"""
|
|
Input line: <humidity>,<temperature>,<sound>
|
|
Output structure:
|
|
{
|
|
'humidity': <humidity>,
|
|
'temperature': <temperature>,
|
|
'sound': <sound>
|
|
}
|
|
"""
|
|
metrics = ['humidity', 'temperature', 'sound']
|
|
values = data.decode('utf-8').strip().split(',')
|
|
return dict(zip(metrics, values))
|
|
|
|
|
|
def connect_mqtt(config):
|
|
"""Connect to MQTT broken from MQTT config and return client"""
|
|
mqtt_host = config.get('host', 'localhost')
|
|
mqtt_port = int(config.get('port', 1883))
|
|
mqtt_username = config.get('username')
|
|
mqtt_password = config.get('password')
|
|
mqtt_client_id = config.get('client_id', 'serial2mqtt')
|
|
|
|
client = paho.Client(client_id=mqtt_client_id)
|
|
client.on_connect = on_connect
|
|
if mqtt_username:
|
|
client.username_pw_set(username=mqtt_username, password=mqtt_password)
|
|
logging.debug('connecting to MQTT broker at {}:{}'.format(mqtt_host, mqtt_port))
|
|
client.connect(mqtt_host, mqtt_port)
|
|
return client
|
|
|
|
|
|
def publish(client, topic, value):
|
|
logger.debug('publishing to topic "{}" with value "{}"'.format(topic, value))
|
|
client.publish(topic, value)
|
|
|
|
|
|
def on_connect(client, userdata, flags, rc):
|
|
if rc > 0:
|
|
logger.error(paho.connack_string(rc))
|
|
else:
|
|
logger.info('connected to MQTT broker')
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument('-c', '--config', help='path to configuration file', default='serial2mqtt.ini')
|
|
parser.add_argument('-v', '--verbose', dest='loglevel', action='store_const', const=logging.INFO,
|
|
help='print more output')
|
|
parser.add_argument('-d', '--debug', dest='loglevel', action='store_const', const=logging.DEBUG,
|
|
default=logging.WARNING, help='print even more output')
|
|
args = parser.parse_args()
|
|
|
|
logging.basicConfig(format='%(levelname)s: %(message)s', level=args.loglevel)
|
|
|
|
config = configparser.ConfigParser()
|
|
if os.path.isfile(args.config):
|
|
config.read(args.config)
|
|
|
|
mqtt_config = config['mqtt'] if 'mqtt' in config else {}
|
|
mqtt_topic_prefix = mqtt_config.get('topic_prefix', 'sensors')
|
|
serial_config = config['serial'] if 'serial' in config else {}
|
|
|
|
try:
|
|
client = connect_mqtt(mqtt_config)
|
|
except Exception as err:
|
|
logger.error('connection to MQTT broker failed: {}'.format(str(err)))
|
|
sys.exit(1)
|
|
|
|
try:
|
|
client.loop_start()
|
|
|
|
while True:
|
|
data = read_serial(serial_config.get('interface', '/dev/cuaU0'))
|
|
if data:
|
|
data = parse_sensor_values(data)
|
|
for sensor_name, value in data.items():
|
|
topic = '/'.join([mqtt_topic_prefix, sensor_name])
|
|
publish(client, topic, value)
|
|
except KeyboardInterrupt:
|
|
pass
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|