Use Service Callbacks for tightly coupled characteristics
devWhen multiple characteristics are updated together (e.g., 'On' and 'Brightness' for a lightbulb), using individual characteristic callbacks can cause race conditions or redundant updates.
To handle these as a single atomic request, use a Service Callback. Instead of setting callbacks on individual characteristics, set the setter_callback on the Service itself. The callback receives a dictionary of all changed characteristic values.
from pyhap.accessory import Accessory
from pyhap.const import Category
class Light(Accessory):
category = Category.CATEGORY_LIGHTBULB
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
serv_light = self.add_preload_service('Lightbulb')
# Configure characteristics
self.char_on = serv_light.configure_char('On', value=False)
self.char_brightness = serv_light.configure_char('Brightness', value=100)
# Set the callback on the SERVICE, not the characteristic
serv_light.setter_callback = self._set_chars
def _set_chars(self, char_values):
# char_values is a dict containing all changed keys
if "On" in char_values:
print('On changed to: ', char_values["On"])
if "Brightness" in char_values:
print('Brightness changed to: ', char_values["Brightness"])
@Accessory.run_at_interval(3)
def run(self):
import random
self.char_on.set_value(random.randint(0, 1))
self.char_brightness.set_value(random.randint(1, 100))
def stop(self):
print('Stopping accessory.')