3 from __future__
import annotations
5 from enum
import IntEnum
9 from chip.clusters
import Objects
as clusters
16 CoverEntityDescription,
24 from .const
import LOGGER
25 from .entity
import MatterEntity
26 from .helpers
import get_matter
27 from .models
import MatterDiscoverySchema
30 OPERATIONAL_STATUS_MASK = 0b11
34 clusters.WindowCovering.Enums.Type.kAwning: CoverDeviceClass.AWNING,
35 clusters.WindowCovering.Enums.Type.kDrapery: CoverDeviceClass.CURTAIN,
40 """Currently ongoing operations enumeration for coverings, as defined in the Matter spec."""
42 COVERING_IS_CURRENTLY_NOT_MOVING = 0b00
43 COVERING_IS_CURRENTLY_OPENING = 0b01
44 COVERING_IS_CURRENTLY_CLOSING = 0b10
50 config_entry: ConfigEntry,
51 async_add_entities: AddEntitiesCallback,
53 """Set up Matter Cover from Config Entry."""
55 matter.register_platform_handler(Platform.COVER, async_add_entities)
59 """Representation of a Matter Cover."""
61 entity_description: CoverEntityDescription
65 """Return true if cover is closed, if there is no position report, return None."""
66 if not self.
_entity_info_entity_info.endpoint.has_attribute(
67 None, clusters.WindowCovering.Attributes.CurrentPositionLiftPercent100ths
78 """Stop the cover movement."""
79 await self.
send_device_commandsend_device_command(clusters.WindowCovering.Commands.StopMotion())
83 await self.
send_device_commandsend_device_command(clusters.WindowCovering.Commands.UpOrOpen())
86 """Close the cover."""
87 await self.
send_device_commandsend_device_command(clusters.WindowCovering.Commands.DownOrClose())
90 """Set the cover to a specific position."""
91 position = kwargs[ATTR_POSITION]
94 clusters.WindowCovering.Commands.GoToLiftPercentage((100 - position) * 100)
98 """Set the cover tilt to a specific position."""
99 position = kwargs[ATTR_TILT_POSITION]
102 clusters.WindowCovering.Commands.GoToTiltPercentage((100 - position) * 100)
106 """Send device command."""
108 node_id=self.
_endpoint_endpoint.node.node_id,
109 endpoint_id=self.
_endpoint_endpoint.endpoint_id,
115 """Update from device."""
117 clusters.WindowCovering.Attributes.OperationalStatus
120 assert operational_status
is not None
123 "Operational status %s for %s",
124 f
"{operational_status:#010b}",
128 state = operational_status & OPERATIONAL_STATUS_MASK
130 case OperationalStatus.COVERING_IS_CURRENTLY_OPENING:
133 case OperationalStatus.COVERING_IS_CURRENTLY_CLOSING:
140 if self.
_entity_info_entity_info.endpoint.has_attribute(
141 None, clusters.WindowCovering.Attributes.CurrentPositionLiftPercent100ths
145 clusters.WindowCovering.Attributes.CurrentPositionLiftPercent100ths
148 100 - floor(current_cover_position / 100)
149 if current_cover_position
is not None
154 "Current position for %s - raw: %s - corrected: %s",
156 current_cover_position,
160 if self.
_entity_info_entity_info.endpoint.has_attribute(
161 None, clusters.WindowCovering.Attributes.CurrentPositionTiltPercent100ths
165 clusters.WindowCovering.Attributes.CurrentPositionTiltPercent100ths
168 100 - floor(current_cover_tilt_position / 100)
169 if current_cover_tilt_position
is not None
174 "Current tilt position for %s - raw: %s - corrected: %s",
176 current_cover_tilt_position,
181 device_type: clusters.WindowCovering.Enums.Type = (
186 supported_features = (
187 CoverEntityFeature.OPEN | CoverEntityFeature.CLOSE | CoverEntityFeature.STOP
190 clusters.WindowCovering.Attributes.AcceptedCommandList
192 if clusters.WindowCovering.Commands.GoToLiftPercentage.command_id
in commands:
193 supported_features |= CoverEntityFeature.SET_POSITION
194 if clusters.WindowCovering.Commands.GoToTiltPercentage.command_id
in commands:
195 supported_features |= CoverEntityFeature.SET_TILT_POSITION
200 DISCOVERY_SCHEMAS = [
202 platform=Platform.COVER,
207 entity_class=MatterCover,
208 required_attributes=(
209 clusters.WindowCovering.Attributes.OperationalStatus,
210 clusters.WindowCovering.Attributes.Type,
213 clusters.WindowCovering.Attributes.CurrentPositionLiftPercent100ths,
214 clusters.WindowCovering.Attributes.CurrentPositionTiltPercent100ths,
218 platform=Platform.COVER,
220 key=
"MatterCoverPositionAwareLift", name=
None
222 entity_class=MatterCover,
223 required_attributes=(
224 clusters.WindowCovering.Attributes.OperationalStatus,
225 clusters.WindowCovering.Attributes.Type,
226 clusters.WindowCovering.Attributes.CurrentPositionLiftPercent100ths,
229 clusters.WindowCovering.Attributes.CurrentPositionTiltPercent100ths,
233 platform=Platform.COVER,
235 key=
"MatterCoverPositionAwareTilt", name=
None
237 entity_class=MatterCover,
238 required_attributes=(
239 clusters.WindowCovering.Attributes.OperationalStatus,
240 clusters.WindowCovering.Attributes.Type,
241 clusters.WindowCovering.Attributes.CurrentPositionTiltPercent100ths,
244 clusters.WindowCovering.Attributes.CurrentPositionLiftPercent100ths,
248 platform=Platform.COVER,
250 key=
"MatterCoverPositionAwareLiftAndTilt", name=
None
252 entity_class=MatterCover,
253 required_attributes=(
254 clusters.WindowCovering.Attributes.OperationalStatus,
255 clusters.WindowCovering.Attributes.Type,
256 clusters.WindowCovering.Attributes.CurrentPositionLiftPercent100ths,
257 clusters.WindowCovering.Attributes.CurrentPositionTiltPercent100ths,
int|None current_cover_tilt_position(self)
current_cover_tilt_position
int|None current_cover_position(self)
None async_stop_cover(self, **Any kwargs)
_attr_current_cover_position
None async_open_cover(self, **Any kwargs)
None send_device_command(self, Any command)
None _update_from_device(self)
None async_set_cover_tilt_position(self, **Any kwargs)
None async_close_cover(self, **Any kwargs)
None async_set_cover_position(self, **Any kwargs)
_attr_current_cover_tilt_position
bool|None is_closed(self)
Any get_matter_attribute_value(self, type[ClusterAttributeDescriptor] attribute, bool null_as_none=True)
None async_setup_entry(HomeAssistant hass, ConfigEntry config_entry, AddEntitiesCallback async_add_entities)
MatterAdapter get_matter(HomeAssistant hass)