This repository has been archived by the owner on Feb 10, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmqtt2xbmc.py
executable file
·147 lines (123 loc) · 4.53 KB
/
mqtt2xbmc.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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import urllib
import urllib2
import paho.mqtt.client as paho # pip install paho-mqtt
import logging
import os
import signal
import sys
import time
__author__ = 'Ben Jones <ben.jones12()gmail.com>'
__copyright__ = 'Copyright 2014 Ben Jones'
__license__ = """Eclipse Public License - v 1.0 (http://www.eclipse.org/legal/epl-v10.html)"""
# script name used for conf/log file names etc
SCRIPTNAME = 'mqtt2xbmc'
# get the config and log file names
CONFIGFILE = os.getenv(SCRIPTNAME.upper() + 'CONF', SCRIPTNAME + ".conf")
LOGFILE = os.getenv(SCRIPTNAME.upper() + 'LOG', SCRIPTNAME + ".log")
# load configuration
conf = {}
try:
execfile(CONFIGFILE, conf)
except Exception, e:
print "Cannot load configuration %s: %s" % (CONFIGFILE, str(e))
sys.exit(2)
LOGLEVEL = conf.get('loglevel', logging.DEBUG)
LOGFORMAT = conf.get('logformat', '%(asctime)-15s %(message)s')
MQTT_HOST = conf.get('broker', 'localhost')
MQTT_PORT = int(conf.get('port', 1883))
MQTT_LWT = conf.get('lwt', None)
# initialise logging
logging.basicConfig(filename=LOGFILE, level=LOGLEVEL, format=LOGFORMAT)
logging.info("Starting " + SCRIPTNAME)
logging.info("INFO MODE")
logging.debug("DEBUG MODE")
# initialise MQTT broker connection
mqttc = paho.Client(SCRIPTNAME, clean_session=False)
# check for authentication
if conf['username'] is not None:
mqttc.username_pw_set(conf['username'], conf['password'])
# configure the last-will-and-testament
if MQTT_LWT is not None:
mqttc.will_set(MQTT_LWT, payload=SCRIPTNAME, qos=0, retain=False)
def connect():
"""
Connect to the broker
"""
logging.debug("Attempting connection to MQTT broker %s:%d..." % (MQTT_HOST, MQTT_PORT))
mqttc.on_connect = on_connect
mqttc.on_message = on_message
mqttc.on_disconnect = on_disconnect
result = mqttc.connect(MQTT_HOST, MQTT_PORT, 60)
if result == 0:
mqttc.loop_forever()
else:
logging.info("Connection failed with error code %s. Retrying in 10s...", result)
time.sleep(10)
connect()
def disconnect(signum, frame):
"""
Signal handler to ensure we disconnect cleanly
in the event of a SIGTERM or SIGINT.
"""
logging.debug("Disconnecting from MQTT broker...")
mqttc.loop_stop()
mqttc.disconnect()
logging.debug("Exiting on signal %d", signum)
sys.exit(signum)
def notify_xbmc(xbmchost, title, message):
command = '{"jsonrpc":"2.0","method":"GUI.ShowNotification","params":{"title":"%s","message":"%s"},"id":1}' % (title, message)
command = command.encode('utf-8')
url = 'http://%s/jsonrpc' % (xbmchost)
try:
req = urllib2.Request(url, command)
req.add_header("Content-type", "application/json")
response = urllib2.urlopen(req)
except urllib2.URLError, e:
logging.error("URLError sending %s to %s: %s" % (url, xbmchost, str(e)))
except Exception, e:
logging.error("Error sending JSON request to %s: %s" % (xbmchost, str(e)))
def on_connect(mosq, userdata, result_code):
logging.debug("Connected to MQTT broker, subscribing to topics...")
for topic in conf['topichost'].keys():
logging.debug("Subscribing to %s" % topic)
mqttc.subscribe(topic, 0)
def on_message(mosq, userdata, msg):
"""
Message received from the broker
"""
topic = msg.topic
payload = str(msg.payload)
logging.debug("Message received on %s: %s" % (topic, payload))
hosts = None
title = "Notification"
# Try to find matching settings for this topic
for sub in conf['topichost'].keys():
if paho.topic_matches_sub(sub, topic):
hosts = conf['topichost'][sub]
break
for sub in conf['topictitle'].keys():
if paho.topic_matches_sub(sub, topic):
title = conf['topictitle'][sub]
break
for host in hosts:
logging.debug("Sending XBMC notification to %s [%s]..." % (host, title))
xbmchost = conf['xbmchost'][host]
notify_xbmc(xbmchost, title, payload)
def on_disconnect(mosq, userdata, 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()
# use the signal module to handle signals
signal.signal(signal.SIGTERM, disconnect)
signal.signal(signal.SIGINT, disconnect)
# connect to broker and start listening
connect()