MQTT Discovery in Python
Voor een toepassing met een 32x32 led matrix van Adafruit zocht ik een manier om bepaalde instellingen van dit display te kunnen triggeren vanaf Home Assistant.
Mijn opstelling was als volgt:
- Een Raspberry Pi 3B+ met Adafruit's RGB Matrix bonnet
- Een 32x32 RGB Matrix LED display
- Een grote rode knop met LED
- Een script dat luistert op een MQTT topic en dit schrijft naar een 'named pipe' in linux
- Een script dat deze 'named topic' uitleest en actie onderneemt als er iets op gezet wordt
- Publiceer een 'light' voor de helderheid van het LED display op MQTT
- Publiceer een scène voor elke animatie op MQTT
- Luister op de bijbehorende MQTT topics en pas de animatie aan op basis van de invoer
global songinfo, songpic, rt2
if message.topic == ha_command_topic:
payload_txt = json.loads(str(message.payload.decode("utf-8")))
if payload_txt["state"] == "ON":
print("Switching on display")
if "brightness" in payload_txt:
b_255 = int((payload_txt["brightness"]))
b = int(mapFromTo(b_255, 0, 255, 0, 100))
subprocess.call(["/usr/local/bin/ledmenu", "-b", str(b)])
message = { "state" : "ON", "brightness" : b_255 }
send_status(client, ha_status_topic, message)
else:
subprocess.call(["/usr/local/bin/ledmenu"])
message = { "state" : "ON" }
send_status(client, ha_status_topic, message)
else:
print("Switching off display")
subprocess.call(["/usr/local/bin/ledmenu", "-k"])
message = { "state" : "OFF" }
send_status(client, ha_status_topic, message)
payload_txt = json.loads(str(message.payload.decode("utf-8")))
if "activate_scene" in payload_txt:
print("Activating scene")
mode = (switch_demo(payload_txt["activate_scene"]))
subprocess.call(["/usr/local/bin/ledmenu", "-m", str(mode)])
elif message.topic == ha_topic_song:
songinfo = message.payload.decode("utf-8")
elif message.topic == ha_topic_songpic:
songpic = message.payload.decode("utf-8")
device_info = {
"name" : ha_name_buttonlight,
"uniq_id" : ha_uniq_id_buttonlight,
"stat_t" : ha_status_topic_buttonlight,
"cmd_t" : ha_command_topic_buttonlight,
"schema" : "json",
"brightness" : False,
"effect" : True,
"effect_list" : ["Blink short", "Blink long"],
"flash_time_short" : blink_short,
"flash_time_long" : blink_long
}
device_info["dev"] = { "name" : ha_discovery_id, "mdl" : ha_model_id, "mf" : ha_manufacterer_id }
device_info["dev"]["ids"] = [ ha_client_id ]
device_info["dev"]["cns"] = [ "ip", local_ip ],[ "mac", local_mac ]
json_device_info = json.dumps(device_info)
config_topic = "homeassistant/light/" + ha_uniq_id_buttonlight + "/config"
client.publish(config_topic, json_device_info)
Ik maak hiermee dus een 'light' aan in Home Assistant, zonder brightness (helaas geen PWM pinnen meer over), maar wel met een paar 'effects': 'Blink short' en 'Blink long'
Vervolgens de commando's verwerken in de callback routine:
elif message.topic == ha_command_topic_buttonlight:
payload_txt = json.loads(str(message.payload.decode("utf-8")))
if payload_txt["state"] == "ON":
print("Switching on led button")
if "effect" in payload_txt:
try:
rt2.stop()
except:
print("No thread running")
effect = payload_txt["effect"]
if effect == 'Blink short':
rt2 = RepeatedTimer(blink_short, blinkled, client)
print("Starting thread")
print(rt2)
elif effect == 'Blink long':
rt2 = RepeatedTimer(blink_long, blinkled, client)
print("Starting thread")
print(rt2)
else:
switchled(True)
message = { "state" : "ON" }
send_status(client, ha_status_topic_buttonlight, message)
else:
print("Switching off led button")
try:
rt2.stop()
except:
print("No thread running")
switchled(False)
message = { "state" : "OFF" }
send_status(client, ha_status_topic_buttonlight, message)
En zo kan ik de hele besturing van het display en de knop via een enkel python script regelen.
Reacties
Een reactie posten