-
Notifications
You must be signed in to change notification settings - Fork 0
/
mqtt-readmeter.py
executable file
·126 lines (106 loc) · 3.45 KB
/
mqtt-readmeter.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#!/usr/bin/env python
# -*- coding: iso-8859-1 -*-
__author__ = "Kyle Gordon"
__copyright__ = "Copyright (C) Kyle Gordon"
import mosquitto
import os
import logging
import signal
import socket
import time
import sys
import mosquitto
import ConfigParser
# Read the config file
config = ConfigParser.RawConfigParser()
config.read("/etc/mqtt-readmeter/mqtt-readmeter.cfg")
# Use ConfigParser to pick out the settings
DEBUG = config.getboolean("global", "debug")
LOGFILE = config.get("global", "logfile")
METERSOURCE = config.get("global", "metersource")
MQTT_HOST = config.get("global", "mqtt_host")
MQTT_PORT = config.getint("global", "mqtt_port")
MQTT_TOPIC="/raw/" + socket.getfqdn() + config.get("global", "MQTT_SUBTOPIC")
client_id = "Readmeter_%d" % os.getpid()
mqttc = mosquitto.Mosquitto(client_id)
LOGFORMAT = '%(asctime)-15s %(message)s'
if DEBUG:
logging.basicConfig(filename=LOGFILE, level=logging.DEBUG, format=LOGFORMAT)
else:
logging.basicConfig(filename=LOGFILE, level=logging.INFO, format=LOGFORMAT)
logging.info('Starting mqtt-readmeter')
logging.info('INFO MODE')
logging.debug('DEBUG MODE')
def cleanup(signum, frame):
"""
Signal handler to ensure we disconnect cleanly
in the event of a SIGTERM or SIGINT.
"""
logging.info("Disconnecting from broker")
# FIXME - This status topis too far up the hierarchy.
mqttc.publish("/status/" + socket.getfqdn(), "Offline")
mqttc.disconnect()
logging.info("Exiting on signal %d", signum)
sys.exit(signum)
def connect():
"""
Connect to the broker, define the callbacks, and subscribe
"""
result = mqttc.connect(MQTT_HOST, MQTT_PORT, 60, True)
if result != 0:
logging.info("Connection failed with error code %s. Retrying", result)
time.sleep(10)
connect()
#define the callbacks
mqttc.on_message = on_message
mqttc.on_connect = on_connect
mqttc.on_disconnect = on_disconnect
mqttc.subscribe(MQTT_TOPIC, 2)
def on_connect(result_code):
"""
Handle connections (or failures) to the broker.
"""
## FIXME - needs fleshing out http://mosquitto.org/documentation/python/
if result_code == 0:
logging.info("Connected to broker")
mqttc.publish("/status/" + socket.getfqdn(), "Online")
else:
logging.warning("Something went wrong")
cleanup()
def on_disconnect(result_code):
"""
Handle disconnections from the broker
"""
if result_code == 0:
logging.info("Clean disconnection")
else:
logging.info("Unexpected disconnection! Reconnecting in 5 seconds")
logging.debug("Result code: %s", result_code)
time.sleep(5)
connect()
main_loop()
def on_message(msg):
"""
What to do once we receive a message
"""
logging.debug("Received: " + msg.topic)
if msg.topic == "/status" and msg.payload == "status?":
mqttc.publish("/status/" + socket.getfqdn(), "Online")
def main_loop():
"""
The main loop in which we stay connected to the broker
"""
oldwatts = ""
while mqttc.loop() == 0:
logging.debug("Looping")
watts = open(METERSOURCE, 'r').read()
watts = watts.rstrip('\n')
if watts != oldwatts:
mqttc.publish(MQTT_TOPIC, watts)
oldwatts = watts
# Use the signal module to handle signals
signal.signal(signal.SIGTERM, cleanup)
signal.signal(signal.SIGINT, cleanup)
# Connect to the broker and enter the main loop
connect()
main_loop()