Merge branch 'dev' into ma_identify

This commit is contained in:
Ludovic BOUÉ
2025-11-10 22:15:06 +01:00
committed by GitHub
16 changed files with 1205 additions and 102 deletions

View File

@@ -4,6 +4,7 @@ import logging
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from aiopvapi.resources.model import PowerviewData from aiopvapi.resources.model import PowerviewData
from aiopvapi.resources.shade_data import PowerviewShadeData
from aiopvapi.rooms import Rooms from aiopvapi.rooms import Rooms
from aiopvapi.scenes import Scenes from aiopvapi.scenes import Scenes
from aiopvapi.shades import Shades from aiopvapi.shades import Shades
@@ -16,7 +17,6 @@ from homeassistant.helpers import device_registry as dr, entity_registry as er
from .const import DOMAIN, HUB_EXCEPTIONS, MANUFACTURER from .const import DOMAIN, HUB_EXCEPTIONS, MANUFACTURER
from .coordinator import PowerviewShadeUpdateCoordinator from .coordinator import PowerviewShadeUpdateCoordinator
from .model import PowerviewConfigEntry, PowerviewEntryData from .model import PowerviewConfigEntry, PowerviewEntryData
from .shade_data import PowerviewShadeData
from .util import async_connect_hub from .util import async_connect_hub
PARALLEL_UPDATES = 1 PARALLEL_UPDATES = 1

View File

@@ -8,6 +8,7 @@ import logging
from aiopvapi.helpers.aiorequest import PvApiMaintenance from aiopvapi.helpers.aiorequest import PvApiMaintenance
from aiopvapi.hub import Hub from aiopvapi.hub import Hub
from aiopvapi.resources.shade_data import PowerviewShadeData
from aiopvapi.shades import Shades from aiopvapi.shades import Shades
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
@@ -15,7 +16,6 @@ from homeassistant.core import HomeAssistant
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
from .const import HUB_EXCEPTIONS from .const import HUB_EXCEPTIONS
from .shade_data import PowerviewShadeData
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)

View File

@@ -208,13 +208,13 @@ class PowerViewShadeBase(ShadeEntity, CoverEntity):
async def _async_execute_move(self, move: ShadePosition) -> None: async def _async_execute_move(self, move: ShadePosition) -> None:
"""Execute a move that can affect multiple positions.""" """Execute a move that can affect multiple positions."""
_LOGGER.debug("Move request %s: %s", self.name, move) _LOGGER.debug("Move request %s: %s", self.name, move)
# Store the requested positions so subsequent move
# requests contain the secondary shade positions
self.data.update_shade_position(self._shade.id, move)
async with self.coordinator.radio_operation_lock: async with self.coordinator.radio_operation_lock:
response = await self._shade.move(move) response = await self._shade.move(move)
_LOGGER.debug("Move response %s: %s", self.name, response) _LOGGER.debug("Move response %s: %s", self.name, response)
# Process the response from the hub (including new positions)
self.data.update_shade_position(self._shade.id, response)
async def _async_set_cover_position(self, target_hass_position: int) -> None: async def _async_set_cover_position(self, target_hass_position: int) -> None:
"""Move the shade to a position.""" """Move the shade to a position."""
target_hass_position = self._clamp_cover_limit(target_hass_position) target_hass_position = self._clamp_cover_limit(target_hass_position)

View File

@@ -3,6 +3,7 @@
import logging import logging
from aiopvapi.resources.shade import BaseShade, ShadePosition from aiopvapi.resources.shade import BaseShade, ShadePosition
from aiopvapi.resources.shade_data import PowerviewShadeData
from homeassistant.helpers import device_registry as dr from homeassistant.helpers import device_registry as dr
from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.device_registry import DeviceInfo
@@ -11,7 +12,6 @@ from homeassistant.helpers.update_coordinator import CoordinatorEntity
from .const import DOMAIN, MANUFACTURER from .const import DOMAIN, MANUFACTURER
from .coordinator import PowerviewShadeUpdateCoordinator from .coordinator import PowerviewShadeUpdateCoordinator
from .model import PowerviewDeviceInfo from .model import PowerviewDeviceInfo
from .shade_data import PowerviewShadeData
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)

View File

@@ -1,80 +0,0 @@
"""Shade data for the Hunter Douglas PowerView integration."""
from __future__ import annotations
from dataclasses import fields
from typing import Any
from aiopvapi.resources.model import PowerviewData
from aiopvapi.resources.shade import BaseShade, ShadePosition
from .util import async_map_data_by_id
POSITION_FIELDS = [field for field in fields(ShadePosition) if field.name != "velocity"]
def copy_position_data(source: ShadePosition, target: ShadePosition) -> ShadePosition:
"""Copy position data from source to target for None values only."""
for field in POSITION_FIELDS:
if (value := getattr(source, field.name)) is not None:
setattr(target, field.name, value)
class PowerviewShadeData:
"""Coordinate shade data between multiple api calls."""
def __init__(self) -> None:
"""Init the shade data."""
self._raw_data_by_id: dict[int, dict[str | int, Any]] = {}
self._shade_group_data_by_id: dict[int, BaseShade] = {}
self.positions: dict[int, ShadePosition] = {}
def get_raw_data(self, shade_id: int) -> dict[str | int, Any]:
"""Get data for the shade."""
return self._raw_data_by_id[shade_id]
def get_all_raw_data(self) -> dict[int, dict[str | int, Any]]:
"""Get data for all shades."""
return self._raw_data_by_id
def get_shade(self, shade_id: int) -> BaseShade:
"""Get specific shade from the coordinator."""
return self._shade_group_data_by_id[shade_id]
def get_shade_position(self, shade_id: int) -> ShadePosition:
"""Get positions for a shade."""
if shade_id not in self.positions:
shade_position = ShadePosition()
# If we have the group data, use it to populate the initial position
if shade := self._shade_group_data_by_id.get(shade_id):
copy_position_data(shade.current_position, shade_position)
self.positions[shade_id] = shade_position
return self.positions[shade_id]
def update_from_group_data(self, shade_id: int) -> None:
"""Process an update from the group data."""
data = self._shade_group_data_by_id[shade_id]
copy_position_data(data.current_position, self.get_shade_position(data.id))
def store_group_data(self, shade_data: PowerviewData) -> None:
"""Store data from the all shades endpoint.
This does not update the shades or positions (self.positions)
as the data may be stale. update_from_group_data
with a shade_id will update a specific shade
from the group data.
"""
self._shade_group_data_by_id = shade_data.processed
self._raw_data_by_id = async_map_data_by_id(shade_data.raw)
def update_shade_position(self, shade_id: int, new_position: ShadePosition) -> None:
"""Update a single shades position."""
copy_position_data(new_position, self.get_shade_position(shade_id))
def update_shade_velocity(self, shade_id: int, shade_data: ShadePosition) -> None:
"""Update a single shades velocity."""
# the hub will always return a velocity of 0 on initial connect,
# separate definition to store consistent value in HA
# this value is purely driven from HA
if shade_data.velocity is not None:
self.get_shade_position(shade_id).velocity = shade_data.velocity

View File

@@ -2,25 +2,15 @@
from __future__ import annotations from __future__ import annotations
from collections.abc import Iterable
from typing import Any
from aiopvapi.helpers.aiorequest import AioRequest from aiopvapi.helpers.aiorequest import AioRequest
from aiopvapi.helpers.constants import ATTR_ID
from aiopvapi.hub import Hub from aiopvapi.hub import Hub
from homeassistant.core import HomeAssistant, callback from homeassistant.core import HomeAssistant
from homeassistant.helpers.aiohttp_client import async_get_clientsession from homeassistant.helpers.aiohttp_client import async_get_clientsession
from .model import PowerviewAPI, PowerviewDeviceInfo from .model import PowerviewAPI, PowerviewDeviceInfo
@callback
def async_map_data_by_id(data: Iterable[dict[str | int, Any]]):
"""Return a dict with the key being the id for a list of entries."""
return {entry[ATTR_ID]: entry for entry in data}
async def async_connect_hub( async def async_connect_hub(
hass: HomeAssistant, address: str, api_version: int | None = None hass: HomeAssistant, address: str, api_version: int | None = None
) -> PowerviewAPI: ) -> PowerviewAPI:

View File

@@ -1009,7 +1009,7 @@
"cleaning_care_program": "Cleaning/care program", "cleaning_care_program": "Cleaning/care program",
"maintenance_program": "Maintenance program", "maintenance_program": "Maintenance program",
"normal_operation_mode": "Normal operation mode", "normal_operation_mode": "Normal operation mode",
"own_program": "Own program" "own_program": "Program"
} }
}, },
"remaining_time": { "remaining_time": {

View File

@@ -14,7 +14,7 @@
"velbus-protocol" "velbus-protocol"
], ],
"quality_scale": "bronze", "quality_scale": "bronze",
"requirements": ["velbus-aio==2025.8.0"], "requirements": ["velbus-aio==2025.11.0"],
"usb": [ "usb": [
{ {
"pid": "0B1B", "pid": "0B1B",

View File

@@ -1304,7 +1304,11 @@ def issues(hass: HomeAssistant) -> dict[tuple[str, str], dict[str, Any]]:
"""Return all open issues.""" """Return all open issues."""
current_issues = ir.async_get(hass).issues current_issues = ir.async_get(hass).issues
# Use JSON for safe representation # Use JSON for safe representation
return {k: v.to_json() for (k, v) in current_issues.items()} return {
key: issue_entry.to_json()
for (key, issue_entry) in current_issues.items()
if issue_entry.active
}
def issue(hass: HomeAssistant, domain: str, issue_id: str) -> dict[str, Any] | None: def issue(hass: HomeAssistant, domain: str, issue_id: str) -> dict[str, Any] | None:

2
requirements_all.txt generated
View File

@@ -3076,7 +3076,7 @@ vegehub==0.1.26
vehicle==2.2.2 vehicle==2.2.2
# homeassistant.components.velbus # homeassistant.components.velbus
velbus-aio==2025.8.0 velbus-aio==2025.11.0
# homeassistant.components.venstar # homeassistant.components.venstar
venstarcolortouch==0.21 venstarcolortouch==0.21

View File

@@ -2543,7 +2543,7 @@ vegehub==0.1.26
vehicle==2.2.2 vehicle==2.2.2
# homeassistant.components.velbus # homeassistant.components.velbus
velbus-aio==2025.8.0 velbus-aio==2025.11.0
# homeassistant.components.venstar # homeassistant.components.venstar
venstarcolortouch==0.21 venstarcolortouch==0.21

View File

@@ -79,6 +79,7 @@ async def integration_fixture(
"aqara_door_window_p2", "aqara_door_window_p2",
"aqara_motion_p2", "aqara_motion_p2",
"aqara_presence_fp300", "aqara_presence_fp300",
"aqara_sensor_w100",
"aqara_thermostat_w500", "aqara_thermostat_w500",
"aqara_u200", "aqara_u200",
"battery_storage", "battery_storage",

View File

@@ -0,0 +1,528 @@
{
"node_id": 75,
"date_commissioned": "2025-06-07T15:30:15.263101",
"last_interview": "2025-06-07T15:30:15.263113",
"interview_version": 6,
"available": true,
"is_bridge": false,
"attributes": {
"0/29/0": [
{
"0": 18,
"1": 1
},
{
"0": 22,
"1": 3
}
],
"0/29/1": [29, 31, 40, 42, 48, 49, 51, 52, 53, 60, 62, 63, 70],
"0/29/2": [41],
"0/29/3": [1, 2, 3, 4, 5, 6],
"0/29/65532": 0,
"0/29/65533": 2,
"0/29/65528": [],
"0/29/65529": [],
"0/29/65531": [0, 1, 2, 3, 65528, 65529, 65531, 65532, 65533],
"0/31/0": [
{
"1": 5,
"2": 2,
"3": [112233],
"4": null,
"254": 4
}
],
"0/31/1": [],
"0/31/2": 4,
"0/31/3": 3,
"0/31/4": 4,
"0/31/65532": 0,
"0/31/65533": 1,
"0/31/65528": [],
"0/31/65529": [],
"0/31/65531": [0, 1, 2, 3, 4, 65528, 65529, 65531, 65532, 65533],
"0/40/0": 17,
"0/40/1": "Aqara",
"0/40/2": 4447,
"0/40/3": "Aqara Climate Sensor W100",
"0/40/4": 8196,
"0/40/5": "Climate Sensor W100",
"0/40/6": "**REDACTED**",
"0/40/7": 12,
"0/40/8": "0.0.1.2",
"0/40/9": 1010,
"0/40/10": "1.0.1.0",
"0/40/11": "20250108",
"0/40/12": "AA016",
"0/40/13": "https://www.aqara.com/en/products.html",
"0/40/14": "Aqara Climate Sensor W100",
"0/40/15": "***************",
"0/40/16": false,
"0/40/18": "***************",
"0/40/19": {
"0": 3,
"1": 3
},
"0/40/21": 16973824,
"0/40/22": 1,
"0/40/65532": 0,
"0/40/65533": 3,
"0/40/65528": [],
"0/40/65529": [],
"0/40/65531": [
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 19, 21, 22,
65528, 65529, 65531, 65532, 65533
],
"0/42/0": [],
"0/42/1": true,
"0/42/2": 1,
"0/42/3": null,
"0/42/65532": 0,
"0/42/65533": 1,
"0/42/65528": [],
"0/42/65529": [0],
"0/42/65531": [0, 1, 2, 3, 65528, 65529, 65531, 65532, 65533],
"0/48/0": 0,
"0/48/1": {
"0": 60,
"1": 900
},
"0/48/2": 0,
"0/48/3": 0,
"0/48/4": true,
"0/48/65532": 0,
"0/48/65533": 1,
"0/48/65528": [1, 3, 5],
"0/48/65529": [0, 2, 4],
"0/48/65531": [0, 1, 2, 3, 4, 65528, 65529, 65531, 65532, 65533],
"0/49/0": 1,
"0/49/1": [
{
"0": "aFq/aOcqMFo=",
"1": true
}
],
"0/49/2": 10,
"0/49/3": 20,
"0/49/4": true,
"0/49/5": 0,
"0/49/6": "aFq/aOcqMFo=",
"0/49/7": null,
"0/49/9": 4,
"0/49/10": 4,
"0/49/65532": 2,
"0/49/65533": 2,
"0/49/65528": [1, 5, 7],
"0/49/65529": [0, 3, 4, 6, 8],
"0/49/65531": [
0, 1, 2, 3, 4, 5, 6, 7, 9, 10, 65528, 65529, 65531, 65532, 65533
],
"0/51/0": [
{
"0": "AqaraHome-0123",
"1": true,
"2": null,
"3": null,
"4": "piylcw37nWM=",
"5": [],
"6": [
"/RXRKakLAAFKcohVnCFKow==",
"/Z4/qUibGFsAAAD//gAcAg==",
"/Z4/qUibGFsYCaOd1Hp6Vg==",
"/oAAAAAAAACkLKVzDfudYw=="
],
"7": 4
}
],
"0/51/1": 1,
"0/51/2": 299,
"0/51/4": 6,
"0/51/5": [],
"0/51/8": false,
"0/51/65532": 0,
"0/51/65533": 2,
"0/51/65528": [2],
"0/51/65529": [0, 1],
"0/51/65531": [0, 1, 2, 4, 5, 8, 65528, 65529, 65531, 65532, 65533],
"0/52/0": [
{
"0": 2,
"1": "sys_evt",
"3": 1952
},
{
"0": 11,
"1": "Bluetoot",
"3": 1438
},
{
"0": 3,
"1": "THREAD",
"3": 1651
},
{
"0": 1,
"1": "Bluetoot",
"3": 306
},
{
"0": 10,
"1": "Bluetoot",
"3": 107
},
{
"0": 7,
"1": "Tmr Svc",
"3": 943
},
{
"0": 8,
"1": "app",
"3": 748
},
{
"0": 6,
"1": "IDLE",
"3": 231
},
{
"0": 4,
"1": "CHIP",
"3": 305
}
],
"0/52/1": 46224,
"0/52/2": 35696,
"0/52/3": 56048,
"0/52/65532": 1,
"0/52/65533": 1,
"0/52/65528": [],
"0/52/65529": [0],
"0/52/65531": [0, 1, 2, 3, 65528, 65529, 65531, 65532, 65533],
"0/53/0": 11,
"0/53/1": 2,
"0/53/2": "AqaraHome-0123",
"0/53/3": 23343,
"0/53/4": 7519532985124270170,
"0/53/5": "QP2eP6lImxhb",
"0/53/6": 0,
"0/53/7": [
{
"0": 17151429082474872369,
"1": 284,
"2": 7168,
"3": 295817,
"4": 111774,
"5": 3,
"6": -74,
"7": -74,
"8": 37,
"9": 0,
"10": true,
"11": true,
"12": true,
"13": false
}
],
"0/53/8": [
{
"0": 17151429082474872369,
"1": 7168,
"2": 7,
"3": 0,
"4": 0,
"5": 3,
"6": 3,
"7": 28,
"8": true,
"9": true
}
],
"0/53/9": 405350277,
"0/53/22": 2799,
"0/53/23": 2797,
"0/53/24": 2,
"0/53/39": 503,
"0/53/40": 503,
"0/53/41": 0,
"0/53/65532": 15,
"0/53/65533": 2,
"0/53/65528": [],
"0/53/65529": [0],
"0/53/65531": [
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 22, 23, 24, 39, 40, 41, 65528, 65529, 65531,
65532, 65533
],
"0/60/0": 0,
"0/60/1": null,
"0/60/2": null,
"0/60/65532": 1,
"0/60/65533": 1,
"0/60/65528": [],
"0/60/65529": [0, 1, 2],
"0/60/65531": [0, 1, 2, 65528, 65529, 65531, 65532, 65533],
"0/62/0": [
{
"1": "FTABAQEkAgE3AyQTAhgmBIAigScmBYAlTTo3BiQVAiQRSxgkBwEkCAEwCUEEL5gmAVxeNTcndwbt1d1SNaICqrmw8Mk3fQ7CkQlM0XhpLv0XzjnnmI+jorFA31RvWDYa0URByx588JSq6G/d7DcKNQEoARgkAgE2AwQCBAEYMAQUPES5ZFkTssoDCAkEz+kBgkL3jMcwBRRT9HTfU5Nds+HA8j+/MRP+0pVyIxgwC0B5OoI+cs5wwGlxvfMdinguUmA+VEWBZjQP6rEvd929qf4zpgpkfyjX7LFYCvoqqKJCOW052dLhgfYGUOqCfo7AGA==",
"2": "FTABAQEkAgE3AyQUARgmBIAigScmBYAlTTo3BiQTAhgkBwEkCAEwCUEEyT62Yt4qMI+MorlmQ/Hxh2CpLetznVknlAbhvYAwTexpSxp9GnhR09SrcUhz3mOb0eZa2TylqcnPBhHJ2Ih2RTcKNQEpARgkAmAwBBRT9HTfU5Nds+HA8j+/MRP+0pVyIzAFFOMCO8Jk7ZCknJquFGPtPzJiNqsDGDALQI/Kc38hQyK7AkT7/pN4hiYW3LoWKT3NA43+ssMJoVpDcaZ989GXBQKIbHKbBEXzUQ1J8wfL7l2pL0Z8Lso9JwgY",
"254": 4
}
],
"0/62/1": [
{
"1": "BIrruNo7r0gX6j6lq1dDi5zeK3jxcTavjt2o4adCCSCYtbxOakfb7C3GXqgV4LzulFSinbewmYkdqFBHqm5pxvU=",
"2": 4939,
"3": 2,
"4": 75,
"5": "",
"254": 4
}
],
"0/62/2": 5,
"0/62/3": 4,
"0/62/4": [
"FTABAQAkAgE3AyYUyakYCSYVj6gLsxgmBGoW1y8kBQA3BiYUyakYCSYVj6gLsxgkBwEkCAEwCUEEgYwxrTB+tyiEGfrRwjlXTG34MiQtJXbg5Qqd0ohdRW7MfwYY7vZiX/0h9hI8MqUralFaVPcnghAP0MSJm1YrqTcKNQEpARgkAmAwBBS3BS9aJzt+p6i28Nj+trB2Uu+vdzAFFLcFL1onO36nqLbw2P62sHZS7693GDALQMvassZTgvO/snCPohEojdKdGb2IpuRpSsu4HkM1JJQ9yFwhkyl0OOS2kvOVUNlfb2YnoJaH4L2jz0G9GVclBIgY",
"FTABAQAkAgE3AycUQhmZbaIbYjokFQIYJgRWZLcqJAUANwYnFEIZmW2iG2I6JBUCGCQHASQIATAJQQT2AlKGW/kOMjqayzeO0md523/fuhrhGEUU91uQpTiKo0I7wcPpKnmrwfQNPX6g0kEQl+VGaXa3e22lzfu5Tzp0Nwo1ASkBGCQCYDAEFOOMk13ScMKuT2hlaydi1yEJnhTqMAUU44yTXdJwwq5PaGVrJ2LXIQmeFOoYMAtAv2jJd1qd5miXbYesH1XrJ+vgyY0hzGuZ78N6Jw4Cb1oN1sLSpA+PNM0u7+hsEqcSvvn2eSV8EaRR+hg5YQjHDxg=",
"FTABD38O1NiPyscyxScZaN7uECQCATcDJhSoQfl2GCYEIqqfLyYFImy36zcGJhSoQfl2GCQHASQIATAJQQT5WrI2v6EgLRXdxlmZLlXX3rxeBe1C3NN/x9QV0tMVF+gH/FPSyq69dZKuoyskx0UOHcN20wdPffFuqgy/4uiaNwo1ASkBGCQCYDAEFM8XoLF/WKnSeqflSO5TQBQz4ObIMAUUzxegsX9YqdJ6p+VI7lNAFDPg5sgYMAtAHTWpsQPPwqR9gCqBGcDbPu2gusKeVuytcD5v7qK1/UjVr2/WGjMw3SYM10HWKdPTQZa2f3JI3uxv1nFnlcQpDBg=",
"FTABAQEkAgE3AyQUARgmBIAigScmBYAlTTo3BiQUARgkBwEkCAEwCUEEiuu42juvSBfqPqWrV0OLnN4rePFxNq+O3ajhp0IJIJi1vE5qR9vsLcZeqBXgvO6UVKKdt7CZiR2oUEeqbmnG9TcKNQEpARgkAmAwBBTjAjvCZO2QpJyarhRj7T8yYjarAzAFFOMCO8Jk7ZCknJquFGPtPzJiNqsDGDALQE7hTxTRg92QOxwA1hK3xv8DaxvxL71r6ZHcNRzug9wNnonJ+NC84SFKvKDxwcBxHYqFdIyDiDgwJNTQIBgasmIY"
],
"0/62/5": 4,
"0/62/65532": 0,
"0/62/65533": 1,
"0/62/65528": [1, 3, 5, 8],
"0/62/65529": [0, 2, 4, 6, 7, 9, 10, 11],
"0/62/65531": [0, 1, 2, 3, 4, 5, 65528, 65529, 65531, 65532, 65533],
"0/63/0": [],
"0/63/1": [],
"0/63/2": 4,
"0/63/3": 3,
"0/63/65532": 0,
"0/63/65533": 2,
"0/63/65528": [2, 5],
"0/63/65529": [0, 1, 3, 4],
"0/63/65531": [0, 1, 2, 3, 65528, 65529, 65531, 65532, 65533],
"0/70/0": 300,
"0/70/1": 0,
"0/70/2": 1000,
"0/70/65532": 0,
"0/70/65533": 2,
"0/70/65528": [],
"0/70/65529": [],
"0/70/65531": [0, 1, 2, 65528, 65529, 65531, 65532, 65533],
"1/3/0": 0,
"1/3/1": 4,
"1/3/65532": 0,
"1/3/65533": 4,
"1/3/65528": [],
"1/3/65529": [0],
"1/3/65531": [0, 1, 65528, 65529, 65531, 65532, 65533],
"1/29/0": [
{
"0": 770,
"1": 1
}
],
"1/29/1": [3, 29, 1026],
"1/29/2": [],
"1/29/3": [],
"1/29/65532": 0,
"1/29/65533": 2,
"1/29/65528": [],
"1/29/65529": [],
"1/29/65531": [0, 1, 2, 3, 65528, 65529, 65531, 65532, 65533],
"1/1026/0": 2773,
"1/1026/1": -4000,
"1/1026/2": 12500,
"1/1026/65532": 0,
"1/1026/65533": 4,
"1/1026/65528": [],
"1/1026/65529": [],
"1/1026/65531": [0, 1, 2, 65528, 65529, 65531, 65532, 65533],
"2/3/0": 0,
"2/3/1": 4,
"2/3/65532": 0,
"2/3/65533": 4,
"2/3/65528": [],
"2/3/65529": [0],
"2/3/65531": [0, 1, 65528, 65529, 65531, 65532, 65533],
"2/29/0": [
{
"0": 775,
"1": 1
}
],
"2/29/1": [3, 29, 1029],
"2/29/2": [],
"2/29/3": [],
"2/29/65532": 0,
"2/29/65533": 2,
"2/29/65528": [],
"2/29/65529": [],
"2/29/65531": [0, 1, 2, 3, 65528, 65529, 65531, 65532, 65533],
"2/1029/0": 4472,
"2/1029/1": 0,
"2/1029/2": 10000,
"2/1029/65532": 0,
"2/1029/65533": 3,
"2/1029/65528": [],
"2/1029/65529": [],
"2/1029/65531": [0, 1, 2, 65528, 65529, 65531, 65532, 65533],
"3/3/0": 0,
"3/3/1": 4,
"3/3/65532": 0,
"3/3/65533": 4,
"3/3/65528": [],
"3/3/65529": [0],
"3/3/65531": [0, 1, 65528, 65529, 65531, 65532, 65533],
"3/29/0": [
{
"0": 15,
"1": 3
}
],
"3/29/1": [3, 29, 59],
"3/29/2": [],
"3/29/3": [],
"3/29/4": [
{
"0": null,
"1": 7,
"2": 1
},
{
"0": null,
"1": 8,
"2": 2
}
],
"3/29/65532": 1,
"3/29/65533": 2,
"3/29/65528": [],
"3/29/65529": [],
"3/29/65531": [0, 1, 2, 3, 4, 65528, 65529, 65531, 65532, 65533],
"3/59/0": 2,
"3/59/1": 0,
"3/59/2": 2,
"3/59/65532": 30,
"3/59/65533": 1,
"3/59/65528": [],
"3/59/65529": [],
"3/59/65531": [0, 1, 2, 65528, 65529, 65531, 65532, 65533],
"4/3/0": 0,
"4/3/1": 4,
"4/3/65532": 0,
"4/3/65533": 4,
"4/3/65528": [],
"4/3/65529": [0],
"4/3/65531": [0, 1, 65528, 65529, 65531, 65532, 65533],
"4/29/0": [
{
"0": 15,
"1": 3
}
],
"4/29/1": [3, 29, 59],
"4/29/2": [],
"4/29/3": [],
"4/29/4": [
{
"0": null,
"1": 7,
"2": 2
},
{
"0": null,
"1": 8,
"2": 4
}
],
"4/29/65532": 1,
"4/29/65533": 2,
"4/29/65528": [],
"4/29/65529": [],
"4/29/65531": [0, 1, 2, 3, 4, 65528, 65529, 65531, 65532, 65533],
"4/59/0": 2,
"4/59/1": 0,
"4/59/2": 2,
"4/59/65532": 30,
"4/59/65533": 1,
"4/59/65528": [],
"4/59/65529": [],
"4/59/65531": [0, 1, 2, 65528, 65529, 65531, 65532, 65533],
"5/3/0": 0,
"5/3/1": 4,
"5/3/65532": 0,
"5/3/65533": 4,
"5/3/65528": [],
"5/3/65529": [0],
"5/3/65531": [0, 1, 65528, 65529, 65531, 65532, 65533],
"5/29/0": [
{
"0": 15,
"1": 3
}
],
"5/29/1": [3, 29, 59],
"5/29/2": [],
"5/29/3": [],
"5/29/4": [
{
"0": null,
"1": 7,
"2": 3
},
{
"0": null,
"1": 8,
"2": 3
}
],
"5/29/65532": 1,
"5/29/65533": 2,
"5/29/65528": [],
"5/29/65529": [],
"5/29/65531": [0, 1, 2, 3, 4, 65528, 65529, 65531, 65532, 65533],
"5/59/0": 2,
"5/59/1": 0,
"5/59/2": 2,
"5/59/65532": 30,
"5/59/65533": 1,
"5/59/65528": [],
"5/59/65529": [],
"5/59/65531": [0, 1, 2, 65528, 65529, 65531, 65532, 65533],
"6/29/0": [
{
"0": 17,
"1": 1
}
],
"6/29/1": [29, 47],
"6/29/2": [],
"6/29/3": [],
"6/29/65532": 0,
"6/29/65533": 2,
"6/29/65528": [],
"6/29/65529": [],
"6/29/65531": [0, 1, 2, 3, 65528, 65529, 65531, 65532, 65533],
"6/47/0": 1,
"6/47/1": 0,
"6/47/2": "Battery",
"6/47/11": 3120,
"6/47/12": 200,
"6/47/14": 0,
"6/47/15": false,
"6/47/16": 2,
"6/47/19": "CR2450",
"6/47/25": 2,
"6/47/31": [],
"6/47/65532": 10,
"6/47/65533": 2,
"6/47/65528": [],
"6/47/65529": [],
"6/47/65531": [
0, 1, 2, 11, 12, 14, 15, 16, 19, 25, 31, 65528, 65529, 65531, 65532, 65533
]
},
"attribute_subscriptions": []
}

View File

@@ -1,4 +1,193 @@
# serializer version: 1 # serializer version: 1
# name: test_events[aqara_sensor_w100][event.climate_sensor_w100_button_3-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'event_types': list([
'multi_press_1',
'multi_press_2',
'long_press',
'long_release',
]),
}),
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'event',
'entity_category': None,
'entity_id': 'event.climate_sensor_w100_button_3',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': <EventDeviceClass.BUTTON: 'button'>,
'original_icon': None,
'original_name': 'Button (3)',
'platform': 'matter',
'previous_unique_id': None,
'suggested_object_id': None,
'supported_features': 0,
'translation_key': 'button',
'unique_id': '00000000000004D2-000000000000004B-MatterNodeDevice-3-GenericSwitch-59-1',
'unit_of_measurement': None,
})
# ---
# name: test_events[aqara_sensor_w100][event.climate_sensor_w100_button_3-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'button',
'event_type': None,
'event_types': list([
'multi_press_1',
'multi_press_2',
'long_press',
'long_release',
]),
'friendly_name': 'Climate Sensor W100 Button (3)',
}),
'context': <ANY>,
'entity_id': 'event.climate_sensor_w100_button_3',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'unknown',
})
# ---
# name: test_events[aqara_sensor_w100][event.climate_sensor_w100_button_4-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'event_types': list([
'multi_press_1',
'multi_press_2',
'long_press',
'long_release',
]),
}),
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'event',
'entity_category': None,
'entity_id': 'event.climate_sensor_w100_button_4',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': <EventDeviceClass.BUTTON: 'button'>,
'original_icon': None,
'original_name': 'Button (4)',
'platform': 'matter',
'previous_unique_id': None,
'suggested_object_id': None,
'supported_features': 0,
'translation_key': 'button',
'unique_id': '00000000000004D2-000000000000004B-MatterNodeDevice-4-GenericSwitch-59-1',
'unit_of_measurement': None,
})
# ---
# name: test_events[aqara_sensor_w100][event.climate_sensor_w100_button_4-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'button',
'event_type': None,
'event_types': list([
'multi_press_1',
'multi_press_2',
'long_press',
'long_release',
]),
'friendly_name': 'Climate Sensor W100 Button (4)',
}),
'context': <ANY>,
'entity_id': 'event.climate_sensor_w100_button_4',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'unknown',
})
# ---
# name: test_events[aqara_sensor_w100][event.climate_sensor_w100_button_5-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'event_types': list([
'multi_press_1',
'multi_press_2',
'long_press',
'long_release',
]),
}),
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'event',
'entity_category': None,
'entity_id': 'event.climate_sensor_w100_button_5',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': <EventDeviceClass.BUTTON: 'button'>,
'original_icon': None,
'original_name': 'Button (5)',
'platform': 'matter',
'previous_unique_id': None,
'suggested_object_id': None,
'supported_features': 0,
'translation_key': 'button',
'unique_id': '00000000000004D2-000000000000004B-MatterNodeDevice-5-GenericSwitch-59-1',
'unit_of_measurement': None,
})
# ---
# name: test_events[aqara_sensor_w100][event.climate_sensor_w100_button_5-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'button',
'event_type': None,
'event_types': list([
'multi_press_1',
'multi_press_2',
'long_press',
'long_release',
]),
'friendly_name': 'Climate Sensor W100 Button (5)',
}),
'context': <ANY>,
'entity_id': 'event.climate_sensor_w100_button_5',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'unknown',
})
# ---
# name: test_events[generic_switch][event.mock_generic_switch_button-entry] # name: test_events[generic_switch][event.mock_generic_switch_button-entry]
EntityRegistryEntrySnapshot({ EntityRegistryEntrySnapshot({
'aliases': set({ 'aliases': set({

View File

@@ -1944,6 +1944,428 @@
'state': '27.94', 'state': '27.94',
}) })
# --- # ---
# name: test_sensors[aqara_sensor_w100][sensor.climate_sensor_w100_battery-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}),
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
'entity_id': 'sensor.climate_sensor_w100_battery',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': <SensorDeviceClass.BATTERY: 'battery'>,
'original_icon': None,
'original_name': 'Battery',
'platform': 'matter',
'previous_unique_id': None,
'suggested_object_id': None,
'supported_features': 0,
'translation_key': None,
'unique_id': '00000000000004D2-000000000000004B-MatterNodeDevice-6-PowerSource-47-12',
'unit_of_measurement': '%',
})
# ---
# name: test_sensors[aqara_sensor_w100][sensor.climate_sensor_w100_battery-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'battery',
'friendly_name': 'Climate Sensor W100 Battery',
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
'unit_of_measurement': '%',
}),
'context': <ANY>,
'entity_id': 'sensor.climate_sensor_w100_battery',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': '100',
})
# ---
# name: test_sensors[aqara_sensor_w100][sensor.climate_sensor_w100_battery_type-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
'entity_id': 'sensor.climate_sensor_w100_battery_type',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': None,
'original_icon': None,
'original_name': 'Battery type',
'platform': 'matter',
'previous_unique_id': None,
'suggested_object_id': None,
'supported_features': 0,
'translation_key': 'battery_replacement_description',
'unique_id': '00000000000004D2-000000000000004B-MatterNodeDevice-6-PowerSourceBatReplacementDescription-47-19',
'unit_of_measurement': None,
})
# ---
# name: test_sensors[aqara_sensor_w100][sensor.climate_sensor_w100_battery_type-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'friendly_name': 'Climate Sensor W100 Battery type',
}),
'context': <ANY>,
'entity_id': 'sensor.climate_sensor_w100_battery_type',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'CR2450',
})
# ---
# name: test_sensors[aqara_sensor_w100][sensor.climate_sensor_w100_battery_voltage-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}),
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
'entity_id': 'sensor.climate_sensor_w100_battery_voltage',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
'sensor': dict({
'suggested_display_precision': 0,
}),
'sensor.private': dict({
'suggested_unit_of_measurement': <UnitOfElectricPotential.VOLT: 'V'>,
}),
}),
'original_device_class': <SensorDeviceClass.VOLTAGE: 'voltage'>,
'original_icon': None,
'original_name': 'Battery voltage',
'platform': 'matter',
'previous_unique_id': None,
'suggested_object_id': None,
'supported_features': 0,
'translation_key': 'battery_voltage',
'unique_id': '00000000000004D2-000000000000004B-MatterNodeDevice-6-PowerSourceBatVoltage-47-11',
'unit_of_measurement': <UnitOfElectricPotential.VOLT: 'V'>,
})
# ---
# name: test_sensors[aqara_sensor_w100][sensor.climate_sensor_w100_battery_voltage-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'voltage',
'friendly_name': 'Climate Sensor W100 Battery voltage',
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
'unit_of_measurement': <UnitOfElectricPotential.VOLT: 'V'>,
}),
'context': <ANY>,
'entity_id': 'sensor.climate_sensor_w100_battery_voltage',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': '3.12',
})
# ---
# name: test_sensors[aqara_sensor_w100][sensor.climate_sensor_w100_current_switch_position_3-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}),
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
'entity_id': 'sensor.climate_sensor_w100_current_switch_position_3',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': None,
'original_icon': None,
'original_name': 'Current switch position (3)',
'platform': 'matter',
'previous_unique_id': None,
'suggested_object_id': None,
'supported_features': 0,
'translation_key': 'switch_current_position',
'unique_id': '00000000000004D2-000000000000004B-MatterNodeDevice-3-SwitchCurrentPosition-59-1',
'unit_of_measurement': None,
})
# ---
# name: test_sensors[aqara_sensor_w100][sensor.climate_sensor_w100_current_switch_position_3-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'friendly_name': 'Climate Sensor W100 Current switch position (3)',
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}),
'context': <ANY>,
'entity_id': 'sensor.climate_sensor_w100_current_switch_position_3',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': '0',
})
# ---
# name: test_sensors[aqara_sensor_w100][sensor.climate_sensor_w100_current_switch_position_4-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}),
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
'entity_id': 'sensor.climate_sensor_w100_current_switch_position_4',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': None,
'original_icon': None,
'original_name': 'Current switch position (4)',
'platform': 'matter',
'previous_unique_id': None,
'suggested_object_id': None,
'supported_features': 0,
'translation_key': 'switch_current_position',
'unique_id': '00000000000004D2-000000000000004B-MatterNodeDevice-4-SwitchCurrentPosition-59-1',
'unit_of_measurement': None,
})
# ---
# name: test_sensors[aqara_sensor_w100][sensor.climate_sensor_w100_current_switch_position_4-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'friendly_name': 'Climate Sensor W100 Current switch position (4)',
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}),
'context': <ANY>,
'entity_id': 'sensor.climate_sensor_w100_current_switch_position_4',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': '0',
})
# ---
# name: test_sensors[aqara_sensor_w100][sensor.climate_sensor_w100_current_switch_position_5-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}),
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
'entity_id': 'sensor.climate_sensor_w100_current_switch_position_5',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': None,
'original_icon': None,
'original_name': 'Current switch position (5)',
'platform': 'matter',
'previous_unique_id': None,
'suggested_object_id': None,
'supported_features': 0,
'translation_key': 'switch_current_position',
'unique_id': '00000000000004D2-000000000000004B-MatterNodeDevice-5-SwitchCurrentPosition-59-1',
'unit_of_measurement': None,
})
# ---
# name: test_sensors[aqara_sensor_w100][sensor.climate_sensor_w100_current_switch_position_5-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'friendly_name': 'Climate Sensor W100 Current switch position (5)',
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}),
'context': <ANY>,
'entity_id': 'sensor.climate_sensor_w100_current_switch_position_5',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': '0',
})
# ---
# name: test_sensors[aqara_sensor_w100][sensor.climate_sensor_w100_humidity-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}),
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.climate_sensor_w100_humidity',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': <SensorDeviceClass.HUMIDITY: 'humidity'>,
'original_icon': None,
'original_name': 'Humidity',
'platform': 'matter',
'previous_unique_id': None,
'suggested_object_id': None,
'supported_features': 0,
'translation_key': None,
'unique_id': '00000000000004D2-000000000000004B-MatterNodeDevice-2-HumiditySensor-1029-0',
'unit_of_measurement': '%',
})
# ---
# name: test_sensors[aqara_sensor_w100][sensor.climate_sensor_w100_humidity-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'humidity',
'friendly_name': 'Climate Sensor W100 Humidity',
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
'unit_of_measurement': '%',
}),
'context': <ANY>,
'entity_id': 'sensor.climate_sensor_w100_humidity',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': '44.72',
})
# ---
# name: test_sensors[aqara_sensor_w100][sensor.climate_sensor_w100_temperature-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}),
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.climate_sensor_w100_temperature',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
'sensor': dict({
'suggested_display_precision': 1,
}),
}),
'original_device_class': <SensorDeviceClass.TEMPERATURE: 'temperature'>,
'original_icon': None,
'original_name': 'Temperature',
'platform': 'matter',
'previous_unique_id': None,
'suggested_object_id': None,
'supported_features': 0,
'translation_key': None,
'unique_id': '00000000000004D2-000000000000004B-MatterNodeDevice-1-TemperatureSensor-1026-0',
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
})
# ---
# name: test_sensors[aqara_sensor_w100][sensor.climate_sensor_w100_temperature-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'temperature',
'friendly_name': 'Climate Sensor W100 Temperature',
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
}),
'context': <ANY>,
'entity_id': 'sensor.climate_sensor_w100_temperature',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': '27.73',
})
# ---
# name: test_sensors[aqara_thermostat_w500][sensor.floor_heating_thermostat_energy-entry] # name: test_sensors[aqara_thermostat_w500][sensor.floor_heating_thermostat_energy-entry]
EntityRegistryEntrySnapshot({ EntityRegistryEntrySnapshot({
'aliases': set({ 'aliases': set({

View File

@@ -2878,6 +2878,55 @@ async def test_issues(hass: HomeAssistant, issue_registry: ir.IssueRegistry) ->
assert_result_info(info, {}) assert_result_info(info, {})
assert info.rate_limit is None assert info.rate_limit is None
issue = ir.IssueEntry(
active=False,
breaks_in_ha_version="2025.12",
created=dt_util.utcnow(),
data=None,
dismissed_version=None,
domain="test",
is_fixable=False,
is_persistent=False,
issue_domain="test",
issue_id="issue 2",
learn_more_url=None,
severity="warning",
translation_key="abc_1234",
translation_placeholders={"abc": "123"},
)
# Add non active issue
issue_registry.issues[("test", "issue 2")] = issue
# Test non active issue is omitted
issue_entry = issue_registry.async_get_issue("test", "issue 2")
assert issue_entry
issue_2_created = issue_entry.created
assert issue_entry and not issue_entry.active
info = render_to_info(hass, "{{ issues() }}")
assert_result_info(info, {})
assert info.rate_limit is None
# Load and activate the issue
ir.async_create_issue(
hass=hass,
breaks_in_ha_version="2025.12",
data=None,
domain="test",
is_fixable=False,
is_persistent=False,
issue_domain="test",
issue_id="issue 2",
learn_more_url=None,
severity="warning",
translation_key="abc_1234",
translation_placeholders={"abc": "123"},
)
activated_issue_entry = issue_registry.async_get_issue("test", "issue 2")
assert activated_issue_entry and activated_issue_entry.active
assert issue_2_created == activated_issue_entry.created
info = render_to_info(hass, "{{ issues()['test', 'issue 2'] }}")
assert_result_info(info, activated_issue_entry.to_json())
assert info.rate_limit is None
async def test_issue(hass: HomeAssistant, issue_registry: ir.IssueRegistry) -> None: async def test_issue(hass: HomeAssistant, issue_registry: ir.IssueRegistry) -> None:
"""Test issue function.""" """Test issue function."""