3 from __future__
import annotations
5 from dataclasses
import dataclass
6 from datetime
import datetime, timedelta
9 from chip.clusters
import Objects
as clusters
10 from matter_server.common.errors
import UpdateCheckError, UpdateError
11 from matter_server.common.models
import MatterSoftwareVersion, UpdateSource
17 UpdateEntityDescription,
28 from .entity
import MatterEntity
29 from .helpers
import get_matter
30 from .models
import MatterDiscoverySchema
33 POLL_AFTER_INSTALL = 10
35 ATTR_SOFTWARE_UPDATE =
"software_update"
40 """Extra stored data for Matter node firmware update entity."""
42 software_update: MatterSoftwareVersion |
None =
None
45 """Return a dict representation of the extra data."""
47 ATTR_SOFTWARE_UPDATE: self.software_update.
as_dict()
48 if self.software_update
is not None
53 def from_dict(cls, data: dict[str, Any]) -> MatterUpdateExtraStoredData:
54 """Initialize the extra data from a dict."""
55 if data[ATTR_SOFTWARE_UPDATE]
is None:
57 return cls(MatterSoftwareVersion.from_dict(data[ATTR_SOFTWARE_UPDATE]))
62 config_entry: ConfigEntry,
63 async_add_entities: AddEntitiesCallback,
65 """Set up Matter lock from Config Entry."""
67 matter.register_platform_handler(Platform.UPDATE, async_add_entities)
71 """Representation of a Matter node capable of updating."""
76 _attr_should_poll =
True
77 _software_update: MatterSoftwareVersion |
None =
None
78 _cancel_update: CALLBACK_TYPE |
None =
None
79 _attr_supported_features = (
80 UpdateEntityFeature.INSTALL
81 | UpdateEntityFeature.PROGRESS
82 | UpdateEntityFeature.SPECIFIC_VERSION
83 | UpdateEntityFeature.RELEASE_NOTES
88 """Update from device."""
91 clusters.BasicInformation.Attributes.SoftwareVersionString
93 update_state: clusters.OtaSoftwareUpdateRequestor.Enums.UpdateStateEnum = (
95 clusters.OtaSoftwareUpdateRequestor.Attributes.UpdateState
100 == clusters.OtaSoftwareUpdateRequestor.Enums.UpdateStateEnum.kIdle
107 clusters.OtaSoftwareUpdateRequestor.Attributes.UpdateStateProgress
113 == clusters.OtaSoftwareUpdateRequestor.Enums.UpdateStateEnum.kDownloading
114 and update_progress
is not None
115 and update_progress > 0
122 """Call when the entity needs to be updated."""
124 update_information = await self.
matter_clientmatter_client.check_node_update(
125 node_id=self.
_endpoint_endpoint.node.node_id
127 if not update_information:
135 except UpdateCheckError
as err:
139 """Return full release notes.
141 This is suitable for a long changelog that does not fit in the release_summary
142 property. The returned string can contain markdown.
152 if self.
_software_update_software_update.update_source != UpdateSource.MAIN_NET_DCL:
154 "\n\n<ha-alert alert-type='warning'>"
155 f
"Update provided by {self._software_update.update_source.value}. "
156 "Installing this update is at your own risk and you may run into unexpected "
157 "problems such as the need to re-add and factory reset your device.</ha-alert>\n\n"
159 return release_notes + (
160 "\n\n<ha-alert alert-type='info'>The update process can take a while, "
161 "especially for battery powered devices. Please be patient and wait until the update "
162 "process is fully completed. Do not remove power from the device while it's updating. "
163 "The device may restart during the update process and be unavailable for several minutes."
168 """Call when the entity is added to hass."""
175 matter_extra_data := MatterUpdateExtraStoredData.from_dict(
186 """Return Matter specific state data to be restored."""
191 """Return the entity picture to use in the frontend.
193 This overrides UpdateEntity.entity_picture because the Matter brand picture
194 is not appropriate for a matter device which has its own brand.
199 self, version: str |
None, backup: bool, **kwargs: Any
201 """Install a new software version."""
204 clusters.OtaSoftwareUpdateRequestor.Attributes.UpdatePossible
208 software_version: str | int |
None = version
210 version
is None or version == self.
_software_update_software_update.software_version_string
216 if software_version
is None:
225 node_id=self.
_endpoint_endpoint.node.node_id,
226 software_version=software_version,
228 except UpdateCheckError
as err:
230 except UpdateError
as err:
240 """Request update."""
244 """Entity removed."""
250 DISCOVERY_SCHEMAS = [
252 platform=Platform.UPDATE,
254 key=
"MatterUpdate", device_class=UpdateDeviceClass.FIRMWARE, name=
None
256 entity_class=MatterUpdate,
257 required_attributes=(
258 clusters.BasicInformation.Attributes.SoftwareVersion,
259 clusters.BasicInformation.Attributes.SoftwareVersionString,
260 clusters.OtaSoftwareUpdateRequestor.Attributes.UpdatePossible,
261 clusters.OtaSoftwareUpdateRequestor.Attributes.UpdateState,
262 clusters.OtaSoftwareUpdateRequestor.Attributes.UpdateStateProgress,
Any get_matter_attribute_value(self, type[ClusterAttributeDescriptor] attribute, bool null_as_none=True)
None async_added_to_hass(self)
None _async_update_future(self, datetime|None now=None)
MatterUpdateExtraStoredData extra_restore_state_data(self)
str|None entity_picture(self)
str|None async_release_notes(self)
None async_will_remove_from_hass(self)
None _update_from_device(self)
None async_install(self, str|None version, bool backup, **Any kwargs)
None async_write_ha_state(self)
State|None async_get_last_state(self)
ExtraStoredData|None async_get_last_extra_data(self)
MatterAdapter get_matter(HomeAssistant hass)
None async_setup_entry(HomeAssistant hass, ConfigEntry config_entry, AddEntitiesCallback async_add_entities)
CALLBACK_TYPE async_call_later(HomeAssistant hass, float|timedelta delay, HassJob[[datetime], Coroutine[Any, Any, None]|None]|Callable[[datetime], Coroutine[Any, Any, None]|None] action)