Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 24 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@ What it can do:
- **Even more**
There are some more goodies in to docs below. Enjoy!

_Note: currently this is limited to Blue switches using ZHA, but ideally Z2M and other Inovelli switches will be added in the future._

**Configure notifications** for multiple switches easily:

<img width="300" alt="Image" src="https://github.com/user-attachments/assets/02f4888b-836c-4114-8a1d-bff66738087e" />
Expand Down Expand Up @@ -273,6 +271,30 @@ Restore state functionality is provided via a subset of entities:

If you disable these entities, it is possible that various other entities may not be restored after restarting Home Assistant.

##### Z-Wave

Only the Red series switches are supported by this integration as the Black series switches do not have a concept of notifications.

Some of the older Red series switches only have a single LED or have a subset of available effects. Lampie will do the following for these switches:

- If an unsupported effect is used, it will choose something similar
- If [individual LEDs](#full-led-configuration) are used on a switch with just one LED, the first LED settings will be used

Unlike the Blue series switches under ZHA, there is no way to receive events for when a notification expires (it only supports, for instance, when the config button is dobule pressed `property_key_name="003"` and `value="KeyPressed2x"`). This may be supported in the firmware and not yet available for end user consumption.

This integration therefore handles notification expiration itself for switches configured with Z-Wave. This may change unexpectedly in the future—if and when it is possible, Lampie will change to sending durations to the firmware.

##### Matter

White series switches only have a single LED and do not support effects. Lampie will do the following for these switches:

- All will simply indicate to enable the notification (besides `CLEAR`)
- If [individual LEDs](#full-led-configuration) are configured, the first LED settings will be used

Unlike the Blue series switches under ZHA, there is no way to receive events for when a notification expires (it only supports, for instance, when the config button is dobule pressed via a state change on `event.<switch_id>_config` with `event_type="multi_press_2"`). This may be supported in the firmware and not yet available for end user consumption.

This integration therefore handles notification expiration itself for switches configured with Matter. This may change unexpectedly in the future—if and when it is possible, Lampie will change to sending durations to the firmware.

## More Screenshots

Once configured, the integration links the various entities to logical devices:
Expand Down
11 changes: 7 additions & 4 deletions custom_components/lampie/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,14 @@ async def async_setup_entry(hass: HomeAssistant, entry: LampieConfigEntry) -> bo
_LOGGER.debug("setup %s with config:%s", entry.title, entry.data)

if DOMAIN not in hass.data:
hass.data[DOMAIN] = LampieOrchestrator(hass)
orchestrator = LampieOrchestrator(hass)
hass.data[DOMAIN] = orchestrator

await orchestrator.setup()

coordinator = LampieUpdateCoordinator(hass, entry)
orchestrator: LampieOrchestrator = hass.data[DOMAIN]
orchestrator.add_coordinator(coordinator)
orchestrator = hass.data[DOMAIN]
await orchestrator.add_coordinator(coordinator)
entry.runtime_data = LampieConfigEntryRuntimeData(
orchestrator=orchestrator,
coordinator=coordinator,
Expand Down Expand Up @@ -123,7 +126,7 @@ async def async_unload_entry(hass: HomeAssistant, entry: LampieConfigEntry) -> b
unload_ok: bool = await hass.config_entries.async_unload_platforms(entry, PLATFORMS)

if orchestrator := entry.runtime_data.orchestrator:
orchestrator.remove_coordinator(coordinator)
await orchestrator.remove_coordinator(coordinator)

if orchestrator.teardown() and orchestrator == hass.data.get(DOMAIN):
hass.data.pop(DOMAIN)
Expand Down
10 changes: 5 additions & 5 deletions custom_components/lampie/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -620,19 +620,19 @@ def _is_inovelli_switch(
entity_registry: er.EntityRegistry,
entity_id: str,
) -> bool:
"""Check if entity_id should be included for dependent entities.
"""Check if entity_id should be included for the list of switches.

Determine if an entity_id represents an entity with a `state_class` of
`total_increasing` and a `unit_of_measurement` of `km`.
Determine if an entity_id represents an Inovelli switch.

Returns:
A flag indicating if the entity should be included.
"""

return bool(
(entity := entity_registry.async_get(entity_id))
and (device := device_registry.async_get(entity.device_id))
and (model := device.model)
and (model in INOVELLI_MODELS)
and ((model := device.model), (model_id := device.model_id))
and ((model in INOVELLI_MODELS) or (model_id in INOVELLI_MODELS))
)


Expand Down
92 changes: 88 additions & 4 deletions custom_components/lampie/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,94 @@
CONF_SWITCH_ENTITIES: Final = "switches"

INOVELLI_MODELS = {
"VZM30-SN", # switch
"VZM31-SN", # two in one switch/dimmer
"VZM35-SN", # fan switch
"VZM36", # canopy module
"LZW30-SN", # red on/off switch
"LZW31-SN", # red dimmer
"LZW36", # red fan/light combo
"VTM31-SN", # white dimmer (2-in-1 switch/dimmer)
"VTM35-SN", # white fan
"VZM30-SN", # blue switch
"VZM31-SN", # blue 2-in-1 switch/dimmer
"VZM35-SN", # blue fan switch
"VZM36", # blue canopy module
"VZW31-SN", # red 2-in-1 dimmer
}


ZWAVE_EFFECT_PARAMETERS = {
"LZW31-SN": 16, # red dimmer
"LZW30-SN": 8, # red on/off switch
"LZW36_light": 24, # red fan/light combo
"LZW36_fan": 25, # red fan/light combo
"VZW31-SN": 99, # red 2-in-1 dimmer
"VZW31-SN_individual_1": 64,
"VZW31-SN_individual_2": 69,
"VZW31-SN_individual_3": 74,
"VZW31-SN_individual_4": 79,
"VZW31-SN_individual_5": 84,
"VZW31-SN_individual_6": 89,
"VZW31-SN_individual_7": 94,
}

ZWAVE_EFFECT_MAPPING = {
"LZW30-SN": { # red on/off switch
"CLEAR": 0,
"AURORA": 4,
"MEDIUM_BLINK": 3,
"CHASE": 2,
"FAST_CHASE": 2,
"SLOW_CHASE": 3,
"FAST_FALLING": 2,
"MEDIUM_FALLING": 3,
"SLOW_FALLING": 3,
"OPEN_CLOSE": 4,
"FAST_RISING": 2,
"MEDIUM_RISING": 3,
"SLOW_RISING": 3,
"FAST_SIREN": 4,
"SLOW_SIREN": 4,
"SMALL_TO_BIG": 4,
},
"LZW31-SN": { # red dimmer
"AURORA": 4,
"FAST_BLINK": 3,
"MEDIUM_BLINK": 4,
"SLOW_BLINK": 4,
"CHASE": 2,
"FAST_CHASE": 2,
"SLOW_CHASE": 2,
"FAST_FALLING": 2,
"MEDIUM_FALLING": 2,
"SLOW_FALLING": 2,
"OPEN_CLOSE": 2,
"PULSE": 5,
"FAST_RISING": 2,
"MEDIUM_RISING": 2,
"SLOW_RISING": 2,
"SLOW_SIREN": 2,
"FAST_SIREN": 2,
"SMALL_TO_BIG": 2,
},
"LZW36": { # red fan/light combo
"AURORA": 4,
"FAST_BLINK": 3,
"MEDIUM_BLINK": 4,
"SLOW_BLINK": 4,
"CHASE": 2,
"FAST_CHASE": 2,
"SLOW_CHASE": 2,
"FAST_FALLING": 2,
"MEDIUM_FALLING": 2,
"SLOW_FALLING": 2,
"OPEN_CLOSE": 2,
"PULSE": 5,
"FAST_RISING": 2,
"MEDIUM_RISING": 2,
"SLOW_RISING": 2,
"SLOW_SIREN": 2,
"FAST_SIREN": 2,
"SMALL_TO_BIG": 2,
},
}


TRACE: Final = 5
2 changes: 1 addition & 1 deletion custom_components/lampie/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"@wbyoung"
],
"config_flow": true,
"dependencies": [],
"dependencies": ["mqtt"],
"documentation": "https://github.com/wbyoung/lampie",
"homekit": {},
"iot_class": "calculated",
Expand Down
Loading