Die eigentliche Funktion des Scripts sollte hier nicht so wichtig sein, aber man kann ein paar Dinge sehen.
- mittels configparser Library werden die Zugangsdaten zum mqtt Server geholt. Liegt der entsprechende Wert nicht vor, wird ein Default Wert gesetzt.
- Auch das logging ist über einen Import bequem erledigt.
- Die Library, um die es eigentlich geht (paho.mqtt.client) und wie sie angesprochen wird.
Code: Alles auswählen
#!/usr/bin/python
import configparser
import logging
import paho.mqtt.client as mqtt
import time
from sysdmanager import SystemdManager
config = configparser.ConfigParser()
config.read('/etc/default/mqttclient')
log_file = (config['logging']).get('filename','/var/log/pymqtt.log')
log_level = int((config['logging']).get('level','30'))
logging.basicConfig(filename=log_file,format='%(asctime)s %(levelname)s:%(message)s', datefmt='%Y/%m/%d/ %H:%M:%S', level=log_level)
MQTT_SERVER = (config['mqtt']).get('url','localhost')
MQTT_PORT = int((config['mqtt']).get('port','1883'))
MQTT_RECONNECT = int((config['mqtt']).get('reconnect','60'))
MQTT_PATH = (config['mqtt']).get('path','/')
MQTT_COMMAND = (config['mqtt']).get('command','cmnd')
MQTT_STATE = (config['mqtt']).get('state','state')
MY_COMMAND = MQTT_PATH+MQTT_COMMAND
MY_STATE = MQTT_PATH+MQTT_STATE
# The callback for when the client receives a CONNACK response from the server.
def on_connect(client, userdata, flags, rc):
logging.info("Connected with result code "+str(rc))
if rc: logging.warning("Connecting resulted with" +str(rc))
# Subscribing in on_connect() means that if we lose the connection and
# reconnect then subscriptions will be renewed.
client.subscribe(MY_COMMAND)
logging.info("Subscribed to "+str(MY_COMMAND))
# The callback for when a PUBLISH message is received from the server.
def on_message(client, userdata, msg):
manager = SystemdManager()
logging.debug("got message!")
logging.info(msg.topic+" : "+str(msg.payload))
startunit=""
stopunit1=""
stopunit2=""
if str(msg.payload) == "1":
logging.debug("Payload is 1 -> CS")
stopunit1="cps.service"
startunit="calibre-server.service"
elif str(msg.payload) == "2":
logging.debug("Payload is 2 -> CPS")
startunit="cps.service"
stopunit1="calibre-server.service"
elif str(msg.payload) == "0":
logging.debug("Payload is 0 -> OFF")
stopunit2="cps.service"
stopunit1="calibre-server.service"
else:
logging.info("Payload is "+str(msg.payload)+" -> only send state")
if stopunit1 != "":
logging.debug("stop service "+stopunit1+"!")
manager.stop_unit(stopunit1)
if stopunit2 != "":
logging.debug("stop service "+stopunit2+"!")
manager.stop_unit(stopunit2)
client.publish(MY_STATE, payload="0", qos=0, retain=False)
logging.debug("published state 0 to "+MY_STATE)
if startunit != "":
logging.debug("wait until starting service!")
time.sleep(10)
logging.debug("starting service "+startunit+"!")
manager.start_unit(startunit)
logging.debug("publishing state")
if manager.is_active("cps.service"):
cpsstate="ON"
client.publish(MY_STATE, payload="2", qos=0, retain=False)
logging.debug("published state 2 to "+MY_STATE)
else:
cpsstate="OFF"
if manager.is_active("calibre-server.service"):
csstate="ON"
client.publish(MY_STATE, payload="1", qos=0, retain=False)
logging.debug("published state 1 to "+MY_STATE)
else:
csstate="OFF"
client.publish(MQTT_PATH+"cs/state", payload=csstate, qos=0, retain=False)
client.publish(MQTT_PATH+"cps/state", payload=cpsstate, qos=0, retain=False)
logging.debug("published state "+csstate+" to "+MQTT_PATH+"cs/state")
logging.debug("published state "+cpsstate+" to "+MQTT_PATH+"cps/state")
# more callbacks, etc
client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
client.connect(MQTT_SERVER, MQTT_PORT, MQTT_RECONNECT)
# Blocking call that processes network traffic, dispatches callbacks and
# handles reconnecting.
# Other loop*() functions are available that give a threaded interface and a
# manual interface.
client.loop_forever()
Code: Alles auswählen
client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
client.connect(MQTT_SERVER, MQTT_PORT, MQTT_RECONNECT)
client.loop_forever()
Danach geht der client in eine Endlosschleife (client.loop_forever).
in der connect-Routine wird nach dem connect ein Topic subscribed, auf welches der Client fortan reagiert. Die Reaktion passiert in on_message, hier findet die eigentliche Arbeit statt.
Das Script läuft bei mir als Daemon. Ich sollte vielleicht noch erwähnen, dass ich von python keine Ahnung habe

