on
Improvements to Desktop Backlight!
To make better use of Home Assistant’s wide variety of components, I removed the REST commands in exchange for MQTT
compatibility.
I’m using MQTT JSON Light Component and the paho-mqtt python module.
The MQTT JSON Lights module supports a number of features like, rgb color
, effects
and transitions
. It sends a JSON string on a user specified topic containing the various attributes.
In my case I wanted to support the basic ON/OFF
behavior and two effects: solid
and rainbow
.
So I can expect JSON
strings like the following:
{
"state": "ON"
}
{
"effect": "solid",
"color": {"r": 255, "g": 0, "b": 0}
}
{
"effect": "rainbow"
}
Create an MQTT client class that can subscribe to the command topic.
import json
import paho.mqtt.client as mqtt
class BacklightMqttClient(object):
COMMAND_TOPIC = '/home/backlight/set'
STATE_TOPIC = '/home/backlight/state'
def __init__(self, backlight):
self._backlight = backlight
# Backlight driver manages its state. Allow it to publish on the state topic
self._backlight.set_state_callback(self._publish_state)
# setup MQTT client
self._client = mqtt.Client()
self._client.on_connect = self._on_connect
self._client.on_message = self._on_message
self._topic_to_callback = {}
# register the command topic callback
self.register(self.COMMAND_TOPIC, self._on_command)
def _on_command(self, command):
# ...
pass
def _publish_state(self, state):
# publish the state to home assistant
self._client.publish(self.STATE_TOPIC, json.dumps(state))
def _on_connect(self, client, userdata, flags, rc):
# subscribe to all the topics
for topic in self._topic_to_callback.keys():
client.subscibe(topic)
# publish the initial state of the driver
self._publish_state(self._backlight.get_state())
def _on_message(self, client, userdata, msg):
# get the callback for this topic
callback = self._topic_to_callback.get(msg.topic, None)
if callback:
# decode the payload
payload = msg.payload.decode('utf-8')
try:
# convert to a JSON object
json_data = json.loads(payload)
callback(json_data)
except (ValueError, TypeError) as e:
pass
def register(self, topic, callback):
self._topic_to_callback[topic] = callback
def connect(self, broker='localhost'):
self._client.connect(broker)
def spin(self):
self._client.loop_forever()
Process commands.
...
def _on_command(self, command):
if 'state' in command:
state = command['state']
if state == 'ON':
self._backlight.turn_on()
elif state == 'OFF':
self._backlight.turn_off()
if 'effect' in command:
effect = command['effect']
self._backlight.set_effect(effect)
if 'color' in command:
color = command['color']
self._backlight.set_solid_color(color)
...
Not a big change but a lot more integrated with Home Assistant!
Here is the config for home assistant:
light:
- platform: mqtt_json
name: Desktop Backlight
command_topic: "/home/backlight/set"
state_topic: "/home/backlight/state"
effect: true
effect_list:
- rainbow
- solid
rgb: true
optimistic: false
qos: 0
I’ve also added the functionality for the backlight to turn on/off depending on whether my PC is on.
# configuration.yaml
binary_sensor:
- platform: ping
name: workstation
host: 192.168.0.17
scan_interval: 5
# automation.yaml
- id: '1530945123989'
alias: Backlight On
trigger:
- entity_id: binary_sensor.workstation
from: 'off'
to: 'on'
platform: state
condition: []
action:
- alias: ''
data:
entity_id: light.desktop_backlight
service: light.turn_on
- id: '1530945171790'
alias: Backlight Off
trigger:
- entity_id: binary_sensor.workstation
from: 'on'
to: 'off'
platform: state
condition: []
action:
- data:
entity_id: light.desktop_backlight
service: light.turn_off