Home IO Control
ESPHome add-on for IO-Homecontrol devices
Loading...
Searching...
No Matches
light.py
Go to the documentation of this file.
1## @file
2## @brief ESPHome binary/dimmable light platform schema and code generation.
3## @ingroup hioc_codegen
4##
5## Defines the binary (default) or dimmable light integration and wires it to the shared hub.
6## Shared device-binding logic lives in platform_common.py; only light-specific entity
7## construction/registration stays here.
8
9import esphome.codegen as cg
10import esphome.config_validation as cv
11from esphome.components import light
12from esphome.const import CONF_DEFAULT_TRANSITION_LENGTH, CONF_OUTPUT_ID
13
14from . import home_io_control_ns
15from .platform_common import (
16 create_companion_sensors,
17 inject_companion_sensor_ids,
18 platform_schema_extension,
19 wire_device_binding,
20 CONF_HOME_IO_CONTROL_ID,
21)
22
23DEPENDENCIES = ["home_io_control"]
24
25IOHomeLight = home_io_control_ns.class_("IOHomeLight", light.LightOutput, cg.Component)
26
27# Opt-in: the protocol gives no machine-readable "is this dimmable" signal (DISCOVER_RESP's
28# subtype byte is manufacturer-opaque), so this defaults to false/binary rather than guessing.
29CONF_DIMMABLE = "dimmable"
30
31
33 # Light reads its entity ID from CONF_OUTPUT_ID rather than CONF_ID.
34 return inject_companion_sensor_ids(config, CONF_OUTPUT_ID)
35
36
37def _validate(config):
38 # The LightType passed to light.light_schema() determines which YAML keys are even accepted
39 # (e.g. gamma_correct only makes sense for a brightness-capable light), so it must be chosen
40 # from the raw dimmable: value before the rest of the schema runs.
41 light_type = (
42 light.LightType.BRIGHTNESS_ONLY
43 if cv.boolean(config.get(CONF_DIMMABLE, False))
44 else light.LightType.BINARY
45 )
46 schema = (
47 light.light_schema(IOHomeLight, light_type)
48 .extend(platform_schema_extension())
49 .extend({cv.Optional(CONF_DIMMABLE, default=False): cv.boolean})
50 .extend(cv.COMPONENT_SCHEMA)
51 )
52 if light_type == light.LightType.BRIGHTNESS_ONLY:
53 # ESPHome's light_schema() default (1s) client-side-fades every brightness change by
54 # repeatedly calling write_state() over that window (LightState::loop()'s transformer).
55 # Each of those calls is a real radio command over IO-Homecontrol's ~300ms round trip —
56 # unlike a PWM/LED output, write_state() here is not cheap, and the resulting stream of
57 # stale/superseding commands (plus each device reply re-triggering on_device_update_(),
58 # which performs another call and can restart the transition) was observed on real
59 # hardware to loop indefinitely. Default to instant application instead; still overridable
60 # in YAML by anyone who understands the tradeoff.
61 schema = schema.extend(
62 {cv.Optional(CONF_DEFAULT_TRANSITION_LENGTH, default="0s"): cv.positive_time_period_milliseconds}
63 )
64 return schema(config)
65
66
67CONFIG_SCHEMA = cv.All(_validate, _inject_companion_ids)
68
69
70async def to_code(config):
71 var = cg.new_Pvariable(config[CONF_OUTPUT_ID])
72 await cg.register_component(var, config)
73 await light.register_light(var, config)
74
75 cg.add(var.set_dimmable(config[CONF_DIMMABLE]))
76
77 parent = await cg.get_variable(config[CONF_HOME_IO_CONTROL_ID])
78 await wire_device_binding(var, parent, config)
79 await create_companion_sensors(config, parent)
_validate(config)
Definition light.py:37
_inject_companion_ids(config)
Definition light.py:32