Skip to content

Commit

Permalink
more coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
dmulcahey committed Nov 13, 2024
1 parent 08aa07f commit cf904ef
Show file tree
Hide file tree
Showing 10 changed files with 53 additions and 40 deletions.
3 changes: 3 additions & 0 deletions tests/test_button.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,9 @@ async def test_button(
)
assert entity.PLATFORM == Platform.BUTTON

assert entity.args == [5]
assert entity.kwargs == {}

with patch(
"zigpy.zcl.Cluster.request",
return_value=mock_coro([0x00, zcl_f.Status.SUCCESS]),
Expand Down
2 changes: 2 additions & 0 deletions tests/test_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,8 @@ async def async_test_illuminance(
await send_attributes_report(zha_gateway, cluster, {0: 0xFFFF})
assert_state(entity, None, "lx")

assert entity.extra_state_attribute_names is None


async def async_test_metering(
zha_gateway: Gateway, cluster: Cluster, entity: PlatformEntity
Expand Down
41 changes: 40 additions & 1 deletion tests/websocket/test_client_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,12 @@
WriteClusterAttributeResponse,
)
from zha.zigbee.device import Device, WebSocketClientDevice
from zha.zigbee.group import Group, GroupMemberReference, WebSocketClientGroup
from zha.zigbee.group import (
Group,
GroupMemberReference,
WebSocketClientGroup,
WebSocketClientGroupMember,
)
from zha.zigbee.model import GroupInfo

from ..common import (
Expand Down Expand Up @@ -481,3 +486,37 @@ async def test_ws_client_gateway_groups(
assert response.name == "Test Group Controller"
assert client_device1.ieee in response.members_by_ieee
assert client_device2.ieee in response.members_by_ieee

# test member info and removal from member

member_info = response.members_by_ieee[client_device1.ieee]
assert member_info is not None
assert member_info.endpoint_id == entity1.info_object.endpoint_id
assert member_info.ieee == entity1.info_object.device_ieee
assert member_info.device_info is not None
assert member_info.device_info.ieee == entity1._device.extended_device_info.ieee
assert member_info.device_info.nwk == entity1._device.extended_device_info.nwk
assert (
member_info.device_info.manufacturer
== entity1._device.extended_device_info.manufacturer
)
assert member_info.device_info.model == entity1._device.extended_device_info.model
assert (
member_info.device_info.signature
== entity1._device.extended_device_info.signature
)

client_group: WebSocketClientGroup = ws_client_gateway.get_group(response.group_id)
assert client_group is not None
members = client_group.members
assert len(members) == 2
entity_1_member: WebSocketClientGroupMember
for member in members:
if member.member_info.ieee == entity1.info_object.device_ieee:
entity_1_member = member
break

assert entity_1_member is not None
await entity_1_member.async_remove_from_group()
await zha_gateway.async_block_till_done()
assert len(client_group.members) == 1
3 changes: 2 additions & 1 deletion zha/application/gateway.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@
SwitchHelper,
UpdateHelper,
)
from zha.websocket.const import ControllerEvents, DeviceEvents
from zha.websocket.const import WEBSOCKET_API, ControllerEvents, DeviceEvents
from zha.websocket.server.client import ClientManager, load_api as load_client_api
from zha.zigbee.device import BaseDevice, Device, WebSocketClientDevice
from zha.zigbee.endpoint import ATTR_IN_CLUSTERS, ATTR_OUT_CLUSTERS
Expand Down Expand Up @@ -813,6 +813,7 @@ def __init__(self, config: ZHAData) -> None:
self.data: dict[Any, Any] = {}
for platform in discovery.PLATFORMS:
self.data.setdefault(platform, [])
self.data.setdefault(WEBSOCKET_API, {})
self._register_api_commands()

@property
Expand Down
10 changes: 0 additions & 10 deletions zha/application/platforms/climate/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,10 +154,6 @@ async def async_set_preset_mode(self, preset_mode: str) -> None:
async def async_set_temperature(self, **kwargs: Any) -> None:
"""Set new target temperature."""

@abstractmethod
async def async_preset_handler(self, preset: str, enable: bool = False) -> None:
"""Set the preset mode via handler."""


@MULTI_MATCH(
cluster_handler_names=CLUSTER_HANDLER_THERMOSTAT,
Expand Down Expand Up @@ -1081,9 +1077,3 @@ async def async_set_temperature(self, **kwargs: Any) -> None:
await self._device.gateway.thermostats.set_temperature(
self.info_object, **kwargs
)

async def async_preset_handler(self, preset: str, enable: bool = False) -> None:
"""Set the preset mode via handler."""
await self._device.gateway.thermostats.preset_handler(
self.info_object, preset, enable
)
4 changes: 1 addition & 3 deletions zha/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,7 @@ def serialize_ieee(self, ieee: EUI64):
)
def serialize_nwk(self, nwk: NWK):
"""Serialize nwk as hex string."""
if nwk is not None:
return repr(nwk)
return nwk
return repr(nwk)


class TypedBaseModel(BaseModel):
Expand Down
3 changes: 2 additions & 1 deletion zha/websocket/client/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
CoverSetPositionCommand,
CoverSetTiltPositionCommand,
CoverStopCommand,
CoverStopTiltCommand,
)
from zha.application.platforms.fan.model import FanEntityInfo
from zha.application.platforms.fan.websocket_api import (
Expand Down Expand Up @@ -371,7 +372,7 @@ async def stop_cover_tilt(
self, cover_platform_entity: CoverEntityInfo
) -> WebSocketCommandResponse:
"""Stop a cover tilt."""
command = CoverStopCommand(
command = CoverStopTiltCommand(
ieee=cover_platform_entity.device_ieee,
unique_id=cover_platform_entity.unique_id,
)
Expand Down
4 changes: 1 addition & 3 deletions zha/websocket/server/api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,4 @@ def register_api_command(
model = handler._ws_command_model # type: ignore[attr-defined]
else:
command = command_or_handler
if (handlers := gateway.data.get(WEBSOCKET_API)) is None:
handlers = gateway.data[WEBSOCKET_API] = {}
handlers[command] = (handler, model)
gateway.data[WEBSOCKET_API][command] = (handler, model)
7 changes: 1 addition & 6 deletions zha/websocket/server/api/decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,7 @@ async def _handle_async_response(
msg: T_WebSocketCommand,
) -> None:
"""Create a response and handle exception."""
try:
await func(gateway, client, msg)
except Exception as err: # pylint: disable=broad-except
# TODO fix this to send a real error code and message
_LOGGER.exception("Error handling message", exc_info=err)
client.send_result_error(msg, "API_COMMAND_HANDLER_ERROR", str(err))
await func(gateway, client, msg)


def async_response(
Expand Down
16 changes: 1 addition & 15 deletions zha/zigbee/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@
)

if TYPE_CHECKING:
from zha.application.gateway import BaseGateway, Gateway, WebSocketClientGateway
from zha.application.gateway import Gateway, WebSocketClientGateway
from zha.application.platforms.events import EntityStateChangedEvent

_LOGGER = logging.getLogger(__name__)
Expand Down Expand Up @@ -212,11 +212,6 @@ def sw_version(self) -> int | None:
def platform_entities(self) -> dict[tuple[Platform, str], T]:
"""Return the platform entities for this device."""

@property
def gateway(self) -> BaseGateway:
"""Return the gateway for this device."""
return self._gateway

def get_platform_entity(self, platform: Platform, unique_id: str) -> T:
"""Get a platform entity by unique id."""
return self.platform_entities[(platform, unique_id)]
Expand Down Expand Up @@ -459,15 +454,6 @@ def gateway(self) -> Gateway:
"""Return the gateway for this device."""
return self._gateway

@cached_property
def device_automation_commands(self) -> dict[str, list[tuple[str, str]]]:
"""Return the a lookup of commands to etype/sub_type."""
commands: dict[str, list[tuple[str, str]]] = {}
for etype_subtype, trigger in self.device_automation_triggers.items():
if command := trigger.get(ATTR_COMMAND):
commands.setdefault(command, []).append(etype_subtype)
return commands

@cached_property
def device_automation_triggers(self) -> dict[tuple[str, str], dict[str, Any]]:
"""Return the device automation triggers for this device."""
Expand Down

0 comments on commit cf904ef

Please sign in to comment.