Lights¶
bridge.lights owns Light models for on/off, dimming, color, color temperature,
and effects. Split main/trim zones appear as separate Light resources (see
Split devices).
Night-light color-mode¶
Some fixtures (e.g. Hampton Bay Penrose) expose night-light as a color-mode
value with the no-brightness category hint. That is distinct from any nightlight
sequence effect.
"night-light" in Light.color_modes— capability checkLight.color_mode_hints/color_mode_has_hint()— API category hintsset_state(..., color_mode="night-light")— omit brightness; select mode before power when turning on from off (aborting if that PUT fails); never send a color-mode change with turn-off. Leave night-light with a separateset_state(..., color_mode=...)while on, orset_state(on=False).
Dual-channel RGB+WW fixtures¶
Fixtures with separate color and white brightness channels (RGBCW strips,
flushmounts, and similar) always stay one combined Light. Capability is detected
from the device; aioafero does not split color/white into separate light resources.
Integrations that want dual entities create them themselves.
Combined fixtures expose:
Light.channels— map of instance name →LightChannel(brightness + on)Light.is_dual_channelLight.channel_brightness(name)/Light.channel_on(name)Light.dimming— overall brightness (usuallyprimary)
Color/white toggles are tracked on Light.channels only — they are not cloned
into Switch resources.
See is_dual_channel_rgb_fixture. True multi-zone fixtures (main/trim) still
split into separate lights; see get_split_instances.
Color modes: Afero exposes color-mode values such as color,
white, sequence, and (on these fixtures) mixed.
mixed is a single color-mode controller that keeps both the RGB and white
drivers active together — not a separate HA entity, and not the same idea as
is_dual_channel (which describes the hardware: independent color/white
brightness and toggles).
Writing: set_state routes dimming by command context on combined fixtures
(RGB → color, CCT → white). Pass channel="color"|"white" to toggle that
channel (instead of primary power) and to route brightness to that channel when
color_mode is omitted. Turning a channel off moves color-mode to the
remaining channel when one is still on (so leaving mixed becomes exclusive
color or white). Exclusive color / white color-mode requests
resolve to mixed when another channel is already on (LightChannel.on is True),
so the PUT does not shut off the other driver. Unknown channel values are ignored
(with a log) rather than falling through to primary power.
Controller¶
- class aioafero.v1.controllers.light.LightController(bridge: AferoBridgeV1)[source]
Bases:
BaseResourcesController[Light]Light devices on
bridge.lights(including split zones).- Parameters:
bridge (AferoBridgeV1)
- ITEM_CLS
alias of
Light
- async turn_on(device_id: str) None[source]
Turn on the light.
- Parameters:
device_id (str) – Device ID from this controller.
- Return type:
None
- async turn_off(device_id: str) None[source]
Turn off the light.
- Parameters:
device_id (str) – Device ID from this controller.
- Return type:
None
- async set_color_temperature(device_id: str, temperature: int) None[source]
Set color temperature or white mode when CCT is unavailable.
- async set_white(device_id: str, *, on: bool | None = True, brightness: int | None = None) None[source]
Set white mode without a color-temperature function.
- async set_brightness(device_id: str, brightness: int) None[source]
Set brightness, turning the light on if needed.
- async set_rgb(device_id: str, red: int, green: int, blue: int) None[source]
Set RGB color, turning the light on if needed.
- async set_effect(device_id: str, effect: str) None[source]
Set a color sequence effect, turning the light on if needed.
- async initialize_elem(afero_device: AferoDevice) Light[source]
Initialize the element.
- Parameters:
afero_device (AferoDevice) – Afero Device that contains the updated states
- Returns:
Newly initialized resource
- Return type:
- async update_elem(afero_device: AferoDevice) set[source]
Update the Light with the latest API data.
- Parameters:
afero_device (AferoDevice) – Afero Device that contains the updated states
- Returns:
States that have been modified
- Return type:
- async update_elem_color(cur_item: Light, color_seq_states: dict[str | None, AferoState]) set[source]
Perform the update for effects.
- Parameters:
cur_item (Light)
color_seq_states (dict[str | None, AferoState])
- Return type:
- async set_state(device_id: str, *, on: bool | None = None, temperature: int | None = None, brightness: int | None = None, color_mode: str | None = None, color: tuple[int, int, int] | None = None, effect: str | None = None, force_white_mode: int | None = None, numbers: dict[tuple[str, str | None], float] | None = None, channel: str | None = None) None[source]
Update light state in the cloud.
- Parameters:
device_id (str) – Device ID from this controller.
on (bool | None) – Power state.
temperature (int | None) – Color temperature in kelvin.
brightness (int | None) – Brightness percentage.
color_mode (str | None) – API color mode (
white,color,sequence,night-light, etc.).color (tuple[int, int, int] | None) – RGB tuple
(red, green, blue).effect (str | None) – Named color sequence effect.
force_white_mode (int | None) – Brightness to apply after forcing white mode.
numbers (dict[tuple[str, str | None], float] | None) – Number features keyed by
(functionClass, functionInstance).channel (str | None) – When set, target that dual-channel instance (
color/white):onuses the channel toggle, and brightness is routed to that channel whencolor_modeis omitted. Turning a channel off also movescolor-modeto the remaining channel when one is still on. Unknown channel names are ignored (logged) and do not fall through to primary power.
- Return type:
None
no-brightnessmodes omit brightness and, when turning on from off, select the mode before power (aborting if that PUT fails). Turn-off never includes a color-mode change.
- __getitem__(device_id: str) AferoResource
Get item by device_id.
- Parameters:
device_id (str)
- Return type:
AferoResource
- __init__(bridge: AferoBridgeV1) None
Initialize instance.
- Parameters:
bridge (AferoBridgeV1)
- Return type:
None
- async emit_to_subscribers(evt_type: EventType, item_id: str, item: AferoResource)
Emit updates to subscribers.
- generate_update_dev(device_id: str, states: list[AferoState]) AferoDevice
Generate update data for the event controller.
- Parameters:
device_id (str)
states (list[AferoState])
- Return type:
- get_device(device_id: str) AferoResource
Return the current model for a tracked device.
- Parameters:
device_id (str) – Device ID on this controller (split or parent metadevice ID).
- Returns:
Resource model with parsed feature state.
- Raises:
DeviceNotFound – If
device_idis not tracked by this controller.- Return type:
AferoResource
- get_filtered_devices(initial_data: list[dict]) list[AferoDevice]
Determine devices that align to the controller.
- Parameters:
- Return type:
- async initialize() None
Initialize controller the controller.
Initialization process should only occur once. During this process, it will subscribe to all updates for the given resources and register any device split callbacks for the event controller.
- Return type:
None
- async initialize_number(func_def: dict, state: AferoState) tuple[tuple[str, str | None], NumbersFeature] | None
Initialize a number from the provided data.
- Parameters:
func_def (dict)
state (AferoState)
- Return type:
tuple[tuple[str, str | None], NumbersFeature] | None
- async initialize_select(functions: list[dict], state: AferoState) tuple[tuple[str, str | None], SelectFeature] | None
Initialize a select from the provided data.
- Parameters:
state (AferoState)
- Return type:
tuple[tuple[str, str | None], SelectFeature] | None
- async initialize_sensor(state: AferoState, child_id: str) AferoSensor | AferoBinarySensor | None
Initialize the sensor.
- Parameters:
state (AferoState) – State to update
child_id (str) – device_id of the parent device
- Return type:
AferoSensor | AferoBinarySensor | None
- property initialized: bool
Determine if the controller has been initialized.
- property items: list[AferoResource]
Return all items for this resource.
- async split_sensor_data(state: AferoState) tuple[Any, str | None]
Split the sensor value and return a tuple of the sensor value and key.
- Parameters:
state (AferoState)
- Return type:
- subscribe(callback: Callable[[EventType, dict | None], None], id_filter: str | tuple[str] | None = None, event_filter: EventType | tuple[EventType] | None = None) Callable
Subscribe to status changes for this resource type.
- Parameters:
- Returns:
function to unsubscribe.
- Return type:
- property subscribers: dict[str, list[tuple[Callable[[EventType, dict | None], None], tuple[EventType] | None]]]
Get all subscribers aligned to this controller.
- async update(device_id: str, obj_in: AferoResource | None = None, states: list[dict] | None = None, send_duplicate_states: bool = False) ClientResponse | None
Update Afero IoT with the new data.
- async update_afero_api(device_id: str, states: list[dict]) ClientResponse | bool
Update Afero IoT API with the new states.
- async update_number(state: AferoState, cur_item: AferoResource) str | None
Update the number if its tracked and a change has been detected.
- Parameters:
state (AferoState) – State to update
cur_item (AferoResource) – Current item to update
- Returns:
Identifier of the number that was updated or None
- Return type:
str | None
- async update_select(state: AferoState, cur_item: AferoResource) str | None
Update the select if its tracked and a change has been detected.
- Parameters:
state (AferoState) – State to update
cur_item (AferoResource) – Current item to update
- Returns:
Identifier of the select that was updated or None
- Return type:
str | None
- async update_sensor(state: AferoState, cur_item: AferoResource) str | None
Update the sensor if its tracked and a change has been detected.
- Parameters:
state (AferoState) – State to update
cur_item (AferoResource) – Current item to update
- Returns:
Identifier of the sensor that was updated or None
- Return type:
str | None
Model¶
- class aioafero.v1.models.light.LightChannel(brightness: int | None = None, on: bool | None = None)[source]
Bases:
objectPer-channel brightness/on for a dual-channel light.
- class aioafero.v1.models.light.Light(*, _id: str, available: bool, device_information: ~aioafero.v1.models.resource.DeviceInformation = <factory>, split: ~aioafero.device.SplitDeviceId | None = None, numbers: dict[tuple[str, str | None], ~aioafero.v1.models.features.NumbersFeature] | None = <factory>, selects: dict[tuple[str, str | None], ~aioafero.v1.models.features.SelectFeature] | None = <factory>, sensors: dict[str, ~aioafero.v1.models.sensor.AferoSensor] = <factory>, binary_sensors: dict[str, ~aioafero.v1.models.sensor.AferoBinarySensor] = <factory>, type: ~aioafero.v1.models.resource.ResourceTypes = ResourceTypes.LIGHT, on: ~aioafero.v1.models.features.OnFeature | None = None, color: ~aioafero.v1.models.features.ColorFeature | None = None, color_mode: ~aioafero.v1.models.features.ColorModeFeature | None = None, color_modes: list[str] | None = None, color_mode_hints: dict[str, list[str]] | None = None, color_temperature: ~aioafero.v1.models.features.ColorTemperatureFeature | None = None, dimming: ~aioafero.v1.models.features.DimmingFeature | None = None, effect: ~aioafero.v1.models.features.EffectFeature | None = None, supports_white: bool = False, channels: dict[str, ~aioafero.v1.models.light.LightChannel] = <factory>)[source]
Bases:
StandardMixinRepresentation of an Afero Light.
- Parameters:
_id (str)
available (bool)
device_information (DeviceInformation)
split (SplitDeviceId | None)
numbers (dict[tuple[str, str | None], NumbersFeature] | None)
selects (dict[tuple[str, str | None], SelectFeature] | None)
sensors (dict[str, AferoSensor])
binary_sensors (dict[str, AferoBinarySensor])
type (ResourceTypes)
on (OnFeature | None)
color (ColorFeature | None)
color_mode (ColorModeFeature | None)
color_temperature (ColorTemperatureFeature | None)
dimming (DimmingFeature | None)
effect (EffectFeature | None)
supports_white (bool)
channels (dict[str, LightChannel])
- __post_init__()[source]
Determine if white only is supported.
- property supports_color: bool
Return if this light supports color control.
- property supports_color_temperature: bool
Return if this light supports color_temperature control.
- property supports_color_white: bool
Return if this light supports setting white.
- color_mode_has_hint(mode: str, hint: str) bool[source]
Return True when
modecarries the given API category hint.
- property supports_dimming: bool
Return if this light supports brightness control.
- property supports_effects: bool
Return if this light supports brightness control.
- property supports_on
If the light can be toggled on or off.
- property is_on: bool
Return bool if light is currently powered on.
- property brightness: float
Return current brightness of light.
- property is_dual_channel: bool
Return True when color and white channels are both present.
- feature_for_update_comparison(field_name: str, put_feature: object | None) object | None[source]
Compare channel toggles/dimming against
channels, not primary.
- __init__(*, _id: str, available: bool, device_information: ~aioafero.v1.models.resource.DeviceInformation = <factory>, split: ~aioafero.device.SplitDeviceId | None = None, numbers: dict[tuple[str, str | None], ~aioafero.v1.models.features.NumbersFeature] | None = <factory>, selects: dict[tuple[str, str | None], ~aioafero.v1.models.features.SelectFeature] | None = <factory>, sensors: dict[str, ~aioafero.v1.models.sensor.AferoSensor] = <factory>, binary_sensors: dict[str, ~aioafero.v1.models.sensor.AferoBinarySensor] = <factory>, type: ~aioafero.v1.models.resource.ResourceTypes = ResourceTypes.LIGHT, on: ~aioafero.v1.models.features.OnFeature | None = None, color: ~aioafero.v1.models.features.ColorFeature | None = None, color_mode: ~aioafero.v1.models.features.ColorModeFeature | None = None, color_modes: list[str] | None = None, color_mode_hints: dict[str, list[str]] | None = None, color_temperature: ~aioafero.v1.models.features.ColorTemperatureFeature | None = None, dimming: ~aioafero.v1.models.features.DimmingFeature | None = None, effect: ~aioafero.v1.models.features.EffectFeature | None = None, supports_white: bool = False, channels: dict[str, ~aioafero.v1.models.light.LightChannel] = <factory>) None
- Parameters:
_id (str)
available (bool)
device_information (DeviceInformation)
split (SplitDeviceId | None)
numbers (dict[tuple[str, str | None], NumbersFeature] | None)
selects (dict[tuple[str, str | None], SelectFeature] | None)
sensors (dict[str, AferoSensor])
binary_sensors (dict[str, AferoBinarySensor])
type (ResourceTypes)
on (OnFeature | None)
color (ColorFeature | None)
color_mode (ColorModeFeature | None)
color_temperature (ColorTemperatureFeature | None)
dimming (DimmingFeature | None)
effect (EffectFeature | None)
supports_white (bool)
channels (dict[str, LightChannel])
- Return type:
None