Compare commits

...

1 Commits

Author SHA1 Message Date
Paulus Schoutsen
b315a31aab Subscribe to the Z-Wave JS Home ID 2025-10-05 22:34:26 -04:00
3 changed files with 55 additions and 27 deletions

View File

@@ -512,7 +512,10 @@ class EsphomeFlowHandler(ConfigFlow, domain=DOMAIN):
# Check if Z-Wave capabilities are present and start discovery flow # Check if Z-Wave capabilities are present and start discovery flow
next_flow_id: str | None = None next_flow_id: str | None = None
if self._device_info.zwave_proxy_feature_flags: if (
self._device_info.zwave_proxy_feature_flags
and self._device_info.zwave_home_id
):
assert self._connected_address is not None assert self._connected_address is not None
assert self._port is not None assert self._port is not None

View File

@@ -9,6 +9,7 @@ from dataclasses import dataclass, field
from functools import partial from functools import partial
import logging import logging
from operator import delitem from operator import delitem
import struct
from typing import TYPE_CHECKING, Any, Final, TypedDict, cast from typing import TYPE_CHECKING, Any, Final, TypedDict, cast
from aioesphomeapi import ( from aioesphomeapi import (
@@ -46,7 +47,7 @@ from aioesphomeapi import (
ValveInfo, ValveInfo,
build_unique_id, build_unique_id,
) )
from aioesphomeapi.model import ButtonInfo from aioesphomeapi.model import ButtonInfo, ZWaveProxyRequest, ZWaveProxyRequestType
from bleak_esphome.backend.device import ESPHomeBluetoothDevice from bleak_esphome.backend.device import ESPHomeBluetoothDevice
from homeassistant import config_entries from homeassistant import config_entries
@@ -489,22 +490,38 @@ class RuntimeEntryData:
if not device_info.zwave_proxy_feature_flags: if not device_info.zwave_proxy_feature_flags:
return return
self.client.subscribe_zwave_proxy_request(
partial(self._async_on_zwave_proxy_request, hass)
)
@callback
def _async_on_zwave_proxy_request(
self, hass: HomeAssistant, msg: ZWaveProxyRequest
) -> None:
"""Handle Z-Wave Proxy requests."""
if msg.type != ZWaveProxyRequestType.HOME_ID_CHANGE:
return
assert self.device_info
assert self.client.connected_address assert self.client.connected_address
home_id = struct.unpack(">I", msg.data)[0]
discovery_flow.async_create_flow( discovery_flow.async_create_flow(
hass, hass,
"zwave_js", "zwave_js",
{"source": config_entries.SOURCE_ESPHOME}, {"source": config_entries.SOURCE_ESPHOME},
ESPHomeServiceInfo( ESPHomeServiceInfo(
name=device_info.name, name=self.device_info.name,
zwave_home_id=device_info.zwave_home_id or None, zwave_home_id=home_id or None,
ip_address=self.client.connected_address, ip_address=self.client.connected_address,
port=self.client.port, port=self.client.port,
noise_psk=self.client.noise_psk, noise_psk=self.client.noise_psk,
), ),
discovery_key=discovery_flow.DiscoveryKey( discovery_key=discovery_flow.DiscoveryKey(
domain=DOMAIN, domain=DOMAIN,
key=device_info.mac_address, key=self.device_info.mac_address,
version=1, version=1,
), ),
) )

View File

@@ -8,6 +8,8 @@ from aioesphomeapi import (
SensorInfo, SensorInfo,
SensorState, SensorState,
) )
from aioesphomeapi.api_pb2 import ZWaveProxyRequest as ZWaveProxyRequestPb
from aioesphomeapi.model import ZWaveProxyRequest
from homeassistant.components.esphome import DOMAIN from homeassistant.components.esphome import DOMAIN
from homeassistant.components.esphome.entry_data import RuntimeEntryData from homeassistant.components.esphome.entry_data import RuntimeEntryData
@@ -95,28 +97,34 @@ async def test_discover_zwave() -> None:
) )
device_info.name = "mock-device-infoname" device_info.name = "mock-device-infoname"
entry_data.async_on_connect(
hass,
device_info,
None,
)
pb_request_home_id_change = ZWaveProxyRequestPb(type=2, data=b"1234")
request_home_id_change = ZWaveProxyRequest.from_pb(pb_request_home_id_change)
with patch( with patch(
"homeassistant.helpers.discovery_flow.async_create_flow" "homeassistant.helpers.discovery_flow.async_create_flow"
) as mock_create_flow: ) as mock_create_flow:
entry_data.async_on_connect( entry_data._async_on_zwave_proxy_request(hass, request_home_id_change)
hass,
device_info, mock_create_flow.assert_called_once_with(
None, hass,
) "zwave_js",
mock_create_flow.assert_called_once_with( {"source": "esphome"},
hass, ESPHomeServiceInfo(
"zwave_js", name="mock-device-infoname",
{"source": "esphome"}, zwave_home_id=825373492,
ESPHomeServiceInfo( ip_address="mock-client-address",
name="mock-device-infoname", port=1234,
zwave_home_id=1234, noise_psk=None,
ip_address="mock-client-address", ),
port=1234, discovery_key=discovery_flow.DiscoveryKey(
noise_psk=None, domain="esphome",
), key="mock-device-info-mac",
discovery_key=discovery_flow.DiscoveryKey( version=1,
domain="esphome", ),
key="mock-device-info-mac", )
version=1,
),
)