Skip to content

Instantly share code, notes, and snippets.

@svrooij
Created March 6, 2020 11:12
Show Gist options
  • Save svrooij/2328eea1f05603827af0bb7eeff4a1b8 to your computer and use it in GitHub Desktop.
Save svrooij/2328eea1f05603827af0bb7eeff4a1b8 to your computer and use it in GitHub Desktop.
MQTT Lights for diyhue
#!/usr/bin/env python
import signal
import paho.mqtt.client as mqtt
import json
import sys
# Parameters
discoveryPrefix = "homeassistant" # Configurable
mqttServer = "192.168.x.x" # user input
mqttPort = 1883 # user input
mqttUser = "" # optional user input
mqttPassword = "" # optional user input
# Mqtt client creation
# You will need to keep this around, because it will manage all the pushed messages
client = mqtt.Client()
# on_connect handler (linked to client below)
def on_connect(client, userdata, flags, rc):
print("Connected with result code "+str(rc))
# Subscribing in on_connect() means that if we lose the connection and
# reconnect then subscriptions will be renewed.
autodiscoveryTopic = discoveryPrefix + "/light/+/light/config" # + in topic is wildcard
client.subscribe(autodiscoveryTopic)
# on_message handler (linked to client below)
def on_message(client, userdata, msg):
if msg.topic.startswith(discoveryPrefix + "/light/"):
on_autodiscovery_light(msg)
else:
on_state_update(msg)
# Will get called zero or more times depending on how many lights are available for autodiscovery
def on_autodiscovery_light(msg):
data = json.loads(msg.payload)
print("Auto discovery message on: " + msg.topic)
print(json.dumps(data, indent=4))
# output
# Auto discovery message on: homeassistant/light/0x001788/light/config
# {
# "brightness": true,
# "xy": true,
# "schema": "json",
# "command_topic": "zigbee2mqtt/bureau-lamp/set",
# "state_topic": "zigbee2mqtt/bureau-lamp",
# "json_attributes_topic": "zigbee2mqtt/bureau-lamp",
# "name": "bureau-lamp_light",
# "unique_id": "0x001788_light_zigbee2mqtt",
# "device": {
# "identifiers": [
# "zigbee2mqtt_0x001788"
# ],
# "name": "bureau-lamp",
# "sw_version": "Zigbee2mqtt 1.11.0",
# "model": "Hue Bloom (7299760PH)",
# "manufacturer": "Philips"
# },
# "availability_topic": "zigbee2mqtt/bridge/state"
# }
# ============ Auto discovery explaination ===============
# "brightness" = does this device support brightness
# "xy" = does this device support changing color
# "command_topic" = state messages to the light need to be send to this topic
# "state_topic" = any state updates from this light will be send to this topic
# "unique_id" = to find this light again if the name changes (the name of this light is bureau-lamp, and that is used in the topic.)
# Subscribe to the state message of this new found light
# this has to be done for every light after reconnecting.
client.subscribe(data['state_topic'])
# Will get called if a light has an updated state.
# The default config will only send a message if it's updated, so you wont get an initial state after connecting
# The msg.topic will match the state topic of the auto discovery
def on_state_update(msg):
print("State message on: " + msg.topic)
data = json.loads(msg.payload)
print(json.dumps(data, indent=4))
# Output
# State message on: zigbee2mqtt/bureau-lamp
# {
# "state": "ON",
# "brightness": 201,
# "color": {
# "x": 0.408,
# "y": 0.517
# }
# }
# State message on: zigbee2mqtt/bureau-lamp
# {
# "state": "OFF",
# "brightness": 201,
# "color": {
# "x": 0.408,
# "y": 0.517
# }
# }
# Send an update to a light.
# you need the command topic (set manually or from auto discovery)
# and this method accepts the same data as the tasmota protocol
def change_light(command_topic, data):
state = {}
for key, value in data.items():
if key == "on":
state['state'] = "ON" if value == True else "OFF"
if key == "bri":
state['brightness'] = value
if key == "xy":
state['color'] = {'x': value[0], 'y': value[1]}
if key == "alert":
state['alert'] = value
message = json.dumps(state);
client.publish(command_topic, message)
# ================= MQTT CLIENT Connection========================
# Set user/password on client if supplied
if mqttUser != "" and mqttPassword != "":
client.username_pw_set(mqttUser,mqttPassword)
# Setup handlers
client.on_connect = on_connect
client.on_message = on_message
# Connect to the server
client.connect(mqttServer, mqttPort)
# start the loop to keep receiving data
client.loop_start()
# ================= MQTT CLIENT Connection========================
# Keep proces running and cancel afterwards
def signal_handler(sig, frame):
client.disconnect()
client.loop_stop()
sys.exit(0)
signal.signal(signal.SIGINT, signal_handler)
print('Press Ctrl+C')
signal.pause()
paho-mqtt==1.5.0
Press Ctrl+C
Connected with result code 0
Auto discovery message on: homeassistant/light/0x001788/light/config
{
"brightness": true,
"xy": true,
"schema": "json",
"command_topic": "zigbee2mqtt/bureau-lamp/set",
"state_topic": "zigbee2mqtt/bureau-lamp",
"json_attributes_topic": "zigbee2mqtt/bureau-lamp",
"name": "bureau-lamp_light",
"unique_id": "0x001788_light_zigbee2mqtt",
"device": {
"identifiers": [
"zigbee2mqtt_0x001788"
],
"name": "bureau-lamp",
"sw_version": "Zigbee2mqtt 1.11.0",
"model": "Hue Bloom (7299760PH)",
"manufacturer": "Philips"
},
"availability_topic": "zigbee2mqtt/bridge/state"
}
State message on: zigbee2mqtt/bureau-lamp
{
"state": "ON",
"brightness": 201,
"color": {
"x": 0.408,
"y": 0.517
}
}
State message on: zigbee2mqtt/bureau-lamp
{
"state": "ON",
"brightness": 100,
"color": {
"x": 0.408,
"y": 0.517
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment