mirror of
https://github.com/home-assistant/core.git
synced 2025-07-19 03:07:37 +00:00
Fix Matter cover deviceclass and inverted position (#92063)
This commit is contained in:
parent
e7e50243d1
commit
3c44c7416f
@ -8,6 +8,7 @@ from chip.clusters import Objects as clusters
|
|||||||
|
|
||||||
from homeassistant.components.cover import (
|
from homeassistant.components.cover import (
|
||||||
ATTR_POSITION,
|
ATTR_POSITION,
|
||||||
|
CoverDeviceClass,
|
||||||
CoverEntity,
|
CoverEntity,
|
||||||
CoverEntityDescription,
|
CoverEntityDescription,
|
||||||
CoverEntityFeature,
|
CoverEntityFeature,
|
||||||
@ -25,6 +26,12 @@ from .models import MatterDiscoverySchema
|
|||||||
# The MASK used for extracting bits 0 to 1 of the byte.
|
# The MASK used for extracting bits 0 to 1 of the byte.
|
||||||
OPERATIONAL_STATUS_MASK = 0b11
|
OPERATIONAL_STATUS_MASK = 0b11
|
||||||
|
|
||||||
|
# map Matter window cover types to HA device class
|
||||||
|
TYPE_MAP = {
|
||||||
|
clusters.WindowCovering.Enums.Type.kAwning: CoverDeviceClass.AWNING,
|
||||||
|
clusters.WindowCovering.Enums.Type.kDrapery: CoverDeviceClass.CURTAIN,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class OperationalStatus(IntEnum):
|
class OperationalStatus(IntEnum):
|
||||||
"""Currently ongoing operations enumeration for coverings, as defined in the Matter spec."""
|
"""Currently ongoing operations enumeration for coverings, as defined in the Matter spec."""
|
||||||
@ -56,20 +63,6 @@ class MatterCover(MatterEntity, CoverEntity):
|
|||||||
| CoverEntityFeature.SET_POSITION
|
| CoverEntityFeature.SET_POSITION
|
||||||
)
|
)
|
||||||
|
|
||||||
@property
|
|
||||||
def current_cover_position(self) -> int:
|
|
||||||
"""Return the current position of cover."""
|
|
||||||
if self._attr_current_cover_position:
|
|
||||||
current_position = self._attr_current_cover_position
|
|
||||||
else:
|
|
||||||
current_position = self.get_matter_attribute_value(
|
|
||||||
clusters.WindowCovering.Attributes.CurrentPositionLiftPercentage
|
|
||||||
)
|
|
||||||
|
|
||||||
assert current_position is not None
|
|
||||||
|
|
||||||
return current_position
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_closed(self) -> bool:
|
def is_closed(self) -> bool:
|
||||||
"""Return true if cover is closed, else False."""
|
"""Return true if cover is closed, else False."""
|
||||||
@ -91,7 +84,8 @@ class MatterCover(MatterEntity, CoverEntity):
|
|||||||
"""Set the cover to a specific position."""
|
"""Set the cover to a specific position."""
|
||||||
position = kwargs[ATTR_POSITION]
|
position = kwargs[ATTR_POSITION]
|
||||||
await self.send_device_command(
|
await self.send_device_command(
|
||||||
clusters.WindowCovering.Commands.GoToLiftValue(position)
|
# value needs to be inverted and is sent in 100ths
|
||||||
|
clusters.WindowCovering.Commands.GoToLiftPercentage((100 - position) * 100)
|
||||||
)
|
)
|
||||||
|
|
||||||
async def send_device_command(self, command: Any) -> None:
|
async def send_device_command(self, command: Any) -> None:
|
||||||
@ -129,15 +123,25 @@ class MatterCover(MatterEntity, CoverEntity):
|
|||||||
self._attr_is_opening = False
|
self._attr_is_opening = False
|
||||||
self._attr_is_closing = False
|
self._attr_is_closing = False
|
||||||
|
|
||||||
self._attr_current_cover_position = self.get_matter_attribute_value(
|
# current position is inverted in matter (100 is closed, 0 is open)
|
||||||
|
current_cover_position = self.get_matter_attribute_value(
|
||||||
clusters.WindowCovering.Attributes.CurrentPositionLiftPercentage
|
clusters.WindowCovering.Attributes.CurrentPositionLiftPercentage
|
||||||
)
|
)
|
||||||
|
self._attr_current_cover_position = 100 - current_cover_position
|
||||||
|
|
||||||
LOGGER.debug(
|
LOGGER.debug(
|
||||||
"Current position: %s for %s",
|
"Current position for %s - raw: %s - corrected: %s",
|
||||||
self._attr_current_cover_position,
|
|
||||||
self.entity_id,
|
self.entity_id,
|
||||||
|
current_cover_position,
|
||||||
|
self.current_cover_position,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# map matter type to HA deviceclass
|
||||||
|
device_type: clusters.WindowCovering.Enums.Type = (
|
||||||
|
self.get_matter_attribute_value(clusters.WindowCovering.Attributes.Type)
|
||||||
|
)
|
||||||
|
self._attr_device_class = TYPE_MAP.get(device_type, CoverDeviceClass.AWNING)
|
||||||
|
|
||||||
|
|
||||||
# Discovery schema(s) to map Matter Attributes to HA entities
|
# Discovery schema(s) to map Matter Attributes to HA entities
|
||||||
DISCOVERY_SCHEMAS = [
|
DISCOVERY_SCHEMAS = [
|
||||||
@ -149,5 +153,5 @@ DISCOVERY_SCHEMAS = [
|
|||||||
clusters.WindowCovering.Attributes.CurrentPositionLiftPercentage,
|
clusters.WindowCovering.Attributes.CurrentPositionLiftPercentage,
|
||||||
clusters.WindowCovering.Attributes.OperationalStatus,
|
clusters.WindowCovering.Attributes.OperationalStatus,
|
||||||
),
|
),
|
||||||
),
|
)
|
||||||
]
|
]
|
||||||
|
@ -103,7 +103,7 @@ async def test_cover(
|
|||||||
assert matter_client.send_device_command.call_args == call(
|
assert matter_client.send_device_command.call_args == call(
|
||||||
node_id=window_covering.node_id,
|
node_id=window_covering.node_id,
|
||||||
endpoint_id=1,
|
endpoint_id=1,
|
||||||
command=clusters.WindowCovering.Commands.GoToLiftValue(50),
|
command=clusters.WindowCovering.Commands.GoToLiftPercentage(5000),
|
||||||
)
|
)
|
||||||
matter_client.send_device_command.reset_mock()
|
matter_client.send_device_command.reset_mock()
|
||||||
|
|
||||||
@ -121,7 +121,7 @@ async def test_cover(
|
|||||||
|
|
||||||
state = hass.states.get("cover.longan_link_wncv_da01")
|
state = hass.states.get("cover.longan_link_wncv_da01")
|
||||||
assert state
|
assert state
|
||||||
assert state.state == STATE_CLOSED
|
assert state.state == STATE_OPEN
|
||||||
|
|
||||||
set_node_attribute(window_covering, 1, 258, 8, 50)
|
set_node_attribute(window_covering, 1, 258, 8, 50)
|
||||||
set_node_attribute(window_covering, 1, 258, 10, 1)
|
set_node_attribute(window_covering, 1, 258, 10, 1)
|
||||||
@ -137,5 +137,5 @@ async def test_cover(
|
|||||||
|
|
||||||
state = hass.states.get("cover.longan_link_wncv_da01")
|
state = hass.states.get("cover.longan_link_wncv_da01")
|
||||||
assert state
|
assert state
|
||||||
assert state.attributes["current_position"] == 100
|
assert state.attributes["current_position"] == 0
|
||||||
assert state.state == STATE_OPEN
|
assert state.state == STATE_CLOSED
|
||||||
|
Loading…
x
Reference in New Issue
Block a user