mirror of
https://github.com/home-assistant/core.git
synced 2026-03-13 14:32:07 +01:00
Compare commits
33 Commits
state_attr
...
setpoint_c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9f876757f6 | ||
|
|
49586d1519 | ||
|
|
c63ded3522 | ||
|
|
28f70fab8d | ||
|
|
289490faa3 | ||
|
|
dea46f7b2e | ||
|
|
82e3221126 | ||
|
|
47e8fbc1ed | ||
|
|
0428d0b97f | ||
|
|
45344c04c1 | ||
|
|
c472b6ac5e | ||
|
|
58f533feb6 | ||
|
|
0af8c8fd8c | ||
|
|
b9d6c3b9fe | ||
|
|
b700940bb9 | ||
|
|
3b73f6d37e | ||
|
|
2812bb21da | ||
|
|
5d474675e8 | ||
|
|
ea7bcf6cda | ||
|
|
725bd3d671 | ||
|
|
cfc4fa6342 | ||
|
|
b650e71660 | ||
|
|
9ddf15e348 | ||
|
|
15082f9111 | ||
|
|
12f16611ff | ||
|
|
8041be3d08 | ||
|
|
40b021e755 | ||
|
|
aab57eda96 | ||
|
|
f0dd37caa5 | ||
|
|
662b178495 | ||
|
|
cb3d30884a | ||
|
|
49e6f20372 | ||
|
|
75d02661eb |
@@ -101,7 +101,10 @@ class AmazonSwitchEntity(AmazonEntity, SwitchEntity):
|
||||
assert method is not None
|
||||
|
||||
await method(self.device, state)
|
||||
await self.coordinator.async_request_refresh()
|
||||
self.coordinator.data[self.device.serial_number].sensors[
|
||||
self.entity_description.key
|
||||
].value = state
|
||||
self.async_write_ha_state()
|
||||
|
||||
async def async_turn_on(self, **kwargs: Any) -> None:
|
||||
"""Turn the switch on."""
|
||||
|
||||
@@ -140,6 +140,14 @@
|
||||
"pump_status": {
|
||||
"default": "mdi:pump"
|
||||
},
|
||||
"setpoint_change_source": {
|
||||
"default": "mdi:hand-back-right",
|
||||
"state": {
|
||||
"external": "mdi:webhook",
|
||||
"manual": "mdi:hand-back-right",
|
||||
"schedule": "mdi:calendar-clock"
|
||||
}
|
||||
},
|
||||
"tank_percentage": {
|
||||
"default": "mdi:water-boiler"
|
||||
},
|
||||
|
||||
@@ -183,6 +183,13 @@ EVSE_FAULT_STATE_MAP = {
|
||||
clusters.EnergyEvse.Enums.FaultStateEnum.kOther: "other",
|
||||
}
|
||||
|
||||
SETPOINT_CHANGE_SOURCE_MAP = {
|
||||
clusters.Thermostat.Enums.SetpointChangeSourceEnum.kManual: "manual",
|
||||
clusters.Thermostat.Enums.SetpointChangeSourceEnum.kSchedule: "schedule",
|
||||
clusters.Thermostat.Enums.SetpointChangeSourceEnum.kExternal: "external",
|
||||
clusters.Thermostat.Enums.SetpointChangeSourceEnum.kUnknownEnumValue: None,
|
||||
}
|
||||
|
||||
PUMP_CONTROL_MODE_MAP = {
|
||||
clusters.PumpConfigurationAndControl.Enums.ControlModeEnum.kConstantSpeed: "constant_speed",
|
||||
clusters.PumpConfigurationAndControl.Enums.ControlModeEnum.kConstantPressure: "constant_pressure",
|
||||
@@ -1579,4 +1586,48 @@ DISCOVERY_SCHEMAS = [
|
||||
required_attributes=(clusters.DoorLock.Attributes.DoorClosedEvents,),
|
||||
featuremap_contains=clusters.DoorLock.Bitmaps.Feature.kDoorPositionSensor,
|
||||
),
|
||||
MatterDiscoverySchema(
|
||||
platform=Platform.SENSOR,
|
||||
entity_description=MatterSensorEntityDescription(
|
||||
key="SetpointChangeSource",
|
||||
translation_key="setpoint_change_source",
|
||||
device_class=SensorDeviceClass.ENUM,
|
||||
state_class=None,
|
||||
options=[x for x in SETPOINT_CHANGE_SOURCE_MAP.values() if x is not None],
|
||||
device_to_ha=lambda x: SETPOINT_CHANGE_SOURCE_MAP[x],
|
||||
),
|
||||
entity_class=MatterSensor,
|
||||
required_attributes=(clusters.Thermostat.Attributes.SetpointChangeSource,),
|
||||
device_type=(device_types.Thermostat, device_types.RoomAirConditioner),
|
||||
),
|
||||
MatterDiscoverySchema(
|
||||
platform=Platform.SENSOR,
|
||||
entity_description=MatterSensorEntityDescription(
|
||||
key="SetpointChangeSourceTimestamp",
|
||||
translation_key="setpoint_change_timestamp",
|
||||
device_class=SensorDeviceClass.TIMESTAMP,
|
||||
state_class=None,
|
||||
device_to_ha=matter_epoch_seconds_to_utc,
|
||||
),
|
||||
entity_class=MatterSensor,
|
||||
required_attributes=(
|
||||
clusters.Thermostat.Attributes.SetpointChangeSourceTimestamp,
|
||||
),
|
||||
device_type=(device_types.Thermostat, device_types.RoomAirConditioner),
|
||||
),
|
||||
MatterDiscoverySchema(
|
||||
platform=Platform.SENSOR,
|
||||
entity_description=MatterSensorEntityDescription(
|
||||
key="ThermostatSetpointChangeAmount",
|
||||
translation_key="setpoint_change_amount",
|
||||
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
|
||||
suggested_display_precision=1,
|
||||
device_class=SensorDeviceClass.TEMPERATURE,
|
||||
device_to_ha=lambda x: x / TEMPERATURE_SCALING_FACTOR,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
),
|
||||
entity_class=MatterSensor,
|
||||
required_attributes=(clusters.Thermostat.Attributes.SetpointChangeAmount,),
|
||||
device_type=(device_types.Thermostat, device_types.RoomAirConditioner),
|
||||
),
|
||||
]
|
||||
|
||||
@@ -555,6 +555,20 @@
|
||||
"rms_voltage": {
|
||||
"name": "Effective voltage"
|
||||
},
|
||||
"setpoint_change_amount": {
|
||||
"name": "Last change amount"
|
||||
},
|
||||
"setpoint_change_source": {
|
||||
"name": "Last change source",
|
||||
"state": {
|
||||
"external": "External",
|
||||
"manual": "Manual",
|
||||
"schedule": "Schedule"
|
||||
}
|
||||
},
|
||||
"setpoint_change_timestamp": {
|
||||
"name": "Last change"
|
||||
},
|
||||
"switch_current_position": {
|
||||
"name": "Current switch position"
|
||||
},
|
||||
|
||||
@@ -196,6 +196,7 @@ class PortainerCoordinator(DataUpdateCoordinator[dict[int, PortainerCoordinatorD
|
||||
# Check if container belongs to a stack via docker compose label
|
||||
stack_name: str | None = (
|
||||
container.labels.get("com.docker.compose.project")
|
||||
or container.labels.get("com.docker.stack.namespace")
|
||||
if container.labels
|
||||
else None
|
||||
)
|
||||
|
||||
@@ -4075,6 +4075,171 @@
|
||||
'state': '100',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[eve_thermo_v5][sensor.eve_thermo_20ecd1701_last_change-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': None,
|
||||
'entity_id': 'sensor.eve_thermo_20ecd1701_last_change',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.TIMESTAMP: 'timestamp'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Last change',
|
||||
'platform': 'matter',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'setpoint_change_timestamp',
|
||||
'unique_id': '00000000000004D2-000000000000000C-MatterNodeDevice-1-SetpointChangeSourceTimestamp-513-50',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[eve_thermo_v5][sensor.eve_thermo_20ecd1701_last_change-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'timestamp',
|
||||
'friendly_name': 'Eve Thermo 20ECD1701 Last change',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.eve_thermo_20ecd1701_last_change',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'unknown',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[eve_thermo_v5][sensor.eve_thermo_20ecd1701_last_change_amount-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.eve_thermo_20ecd1701_last_change_amount',
|
||||
'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': 'Last change amount',
|
||||
'platform': 'matter',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'setpoint_change_amount',
|
||||
'unique_id': '00000000000004D2-000000000000000C-MatterNodeDevice-1-ThermostatSetpointChangeAmount-513-49',
|
||||
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[eve_thermo_v5][sensor.eve_thermo_20ecd1701_last_change_amount-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'temperature',
|
||||
'friendly_name': 'Eve Thermo 20ECD1701 Last change amount',
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.eve_thermo_20ecd1701_last_change_amount',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '0.0',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[eve_thermo_v5][sensor.eve_thermo_20ecd1701_last_change_source-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': dict({
|
||||
'options': list([
|
||||
'manual',
|
||||
'schedule',
|
||||
'external',
|
||||
]),
|
||||
}),
|
||||
'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.eve_thermo_20ecd1701_last_change_source',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.ENUM: 'enum'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Last change source',
|
||||
'platform': 'matter',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'setpoint_change_source',
|
||||
'unique_id': '00000000000004D2-000000000000000C-MatterNodeDevice-1-SetpointChangeSource-513-48',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[eve_thermo_v5][sensor.eve_thermo_20ecd1701_last_change_source-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'enum',
|
||||
'friendly_name': 'Eve Thermo 20ECD1701 Last change source',
|
||||
'options': list([
|
||||
'manual',
|
||||
'schedule',
|
||||
'external',
|
||||
]),
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.eve_thermo_20ecd1701_last_change_source',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'manual',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[eve_thermo_v5][sensor.eve_thermo_20ecd1701_temperature-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
@@ -10940,6 +11105,171 @@
|
||||
'state': '25',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[mock_thermostat][sensor.mock_thermostat_last_change-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': None,
|
||||
'entity_id': 'sensor.mock_thermostat_last_change',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.TIMESTAMP: 'timestamp'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Last change',
|
||||
'platform': 'matter',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'setpoint_change_timestamp',
|
||||
'unique_id': '00000000000004D2-0000000000000096-MatterNodeDevice-1-SetpointChangeSourceTimestamp-513-50',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[mock_thermostat][sensor.mock_thermostat_last_change-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'timestamp',
|
||||
'friendly_name': 'Mock Thermostat Last change',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.mock_thermostat_last_change',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '2025-01-01T00:00:00+00:00',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[mock_thermostat][sensor.mock_thermostat_last_change_amount-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.mock_thermostat_last_change_amount',
|
||||
'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': 'Last change amount',
|
||||
'platform': 'matter',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'setpoint_change_amount',
|
||||
'unique_id': '00000000000004D2-0000000000000096-MatterNodeDevice-1-ThermostatSetpointChangeAmount-513-49',
|
||||
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[mock_thermostat][sensor.mock_thermostat_last_change_amount-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'temperature',
|
||||
'friendly_name': 'Mock Thermostat Last change amount',
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.mock_thermostat_last_change_amount',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '1.5',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[mock_thermostat][sensor.mock_thermostat_last_change_source-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': dict({
|
||||
'options': list([
|
||||
'manual',
|
||||
'schedule',
|
||||
'external',
|
||||
]),
|
||||
}),
|
||||
'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.mock_thermostat_last_change_source',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.ENUM: 'enum'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Last change source',
|
||||
'platform': 'matter',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'setpoint_change_source',
|
||||
'unique_id': '00000000000004D2-0000000000000096-MatterNodeDevice-1-SetpointChangeSource-513-48',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[mock_thermostat][sensor.mock_thermostat_last_change_source-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'enum',
|
||||
'friendly_name': 'Mock Thermostat Last change source',
|
||||
'options': list([
|
||||
'manual',
|
||||
'schedule',
|
||||
'external',
|
||||
]),
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.mock_thermostat_last_change_source',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'manual',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[mock_thermostat][sensor.mock_thermostat_outdoor_temperature-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
|
||||
@@ -233,6 +233,100 @@ async def test_eve_thermo_sensor(
|
||||
assert state.state == "18.0"
|
||||
|
||||
|
||||
@pytest.mark.parametrize("node_fixture", ["eve_thermo_v5"])
|
||||
async def test_eve_thermo_v5_setpoint_change_source(
|
||||
hass: HomeAssistant,
|
||||
matter_client: MagicMock,
|
||||
matter_node: MatterNode,
|
||||
) -> None:
|
||||
"""Test Eve Thermo v5 SetpointChangeSource sensor."""
|
||||
entity_id = "sensor.eve_thermo_20ecd1701_last_change_source"
|
||||
|
||||
# Initial state and options
|
||||
state = hass.states.get(entity_id)
|
||||
assert state
|
||||
assert state.state == "manual"
|
||||
assert state.attributes["options"] == ["manual", "schedule", "external"]
|
||||
|
||||
# Change to schedule
|
||||
set_node_attribute(matter_node, 1, 513, 48, 1)
|
||||
await trigger_subscription_callback(hass, matter_client)
|
||||
|
||||
state = hass.states.get(entity_id)
|
||||
assert state
|
||||
assert state.state == "schedule"
|
||||
|
||||
# Change to external
|
||||
set_node_attribute(matter_node, 1, 513, 48, 2)
|
||||
await trigger_subscription_callback(hass, matter_client)
|
||||
|
||||
state = hass.states.get(entity_id)
|
||||
assert state
|
||||
assert state.state == "external"
|
||||
|
||||
|
||||
@pytest.mark.parametrize("node_fixture", ["eve_thermo_v5"])
|
||||
async def test_eve_thermo_v5_setpoint_change_timestamp(
|
||||
hass: HomeAssistant,
|
||||
matter_client: MagicMock,
|
||||
matter_node: MatterNode,
|
||||
) -> None:
|
||||
"""Test Eve Thermo v5 SetpointChangeSourceTimestamp sensor."""
|
||||
entity_id = "sensor.eve_thermo_20ecd1701_last_change"
|
||||
|
||||
# Initial is unknown per snapshot
|
||||
state = hass.states.get(entity_id)
|
||||
assert state
|
||||
assert state.state == "unknown"
|
||||
|
||||
# Update to 2024-01-01 00:00:00+00:00 (Matter epoch seconds since 2000)
|
||||
set_node_attribute(matter_node, 1, 513, 50, 757382400)
|
||||
await trigger_subscription_callback(hass, matter_client)
|
||||
|
||||
state = hass.states.get(entity_id)
|
||||
assert state
|
||||
assert state.state == "2024-01-01T00:00:00+00:00"
|
||||
|
||||
# Set to zero should yield unknown
|
||||
set_node_attribute(matter_node, 1, 513, 50, 0)
|
||||
await trigger_subscription_callback(hass, matter_client)
|
||||
|
||||
state = hass.states.get(entity_id)
|
||||
assert state
|
||||
assert state.state == "unknown"
|
||||
|
||||
|
||||
@pytest.mark.parametrize("node_fixture", ["eve_thermo_v5"])
|
||||
async def test_eve_thermo_v5_setpoint_change_amount(
|
||||
hass: HomeAssistant,
|
||||
matter_client: MagicMock,
|
||||
matter_node: MatterNode,
|
||||
) -> None:
|
||||
"""Test Eve Thermo v5 SetpointChangeAmount sensor."""
|
||||
entity_id = "sensor.eve_thermo_20ecd1701_last_change_amount"
|
||||
|
||||
# Initial per snapshot
|
||||
state = hass.states.get(entity_id)
|
||||
assert state
|
||||
assert state.state == "0.0"
|
||||
|
||||
# Update to 2.0°C (200 in Matter units)
|
||||
set_node_attribute(matter_node, 1, 513, 49, 200)
|
||||
await trigger_subscription_callback(hass, matter_client)
|
||||
|
||||
state = hass.states.get(entity_id)
|
||||
assert state
|
||||
assert state.state == "2.0"
|
||||
|
||||
# Update to -0.5°C (-50 in Matter units)
|
||||
set_node_attribute(matter_node, 1, 513, 49, -50)
|
||||
await trigger_subscription_callback(hass, matter_client)
|
||||
|
||||
state = hass.states.get(entity_id)
|
||||
assert state
|
||||
assert state.state == "-0.5"
|
||||
|
||||
|
||||
@pytest.mark.parametrize("node_fixture", ["longan_link_thermostat"])
|
||||
async def test_thermostat_outdoor(
|
||||
hass: HomeAssistant,
|
||||
|
||||
@@ -168,5 +168,31 @@
|
||||
],
|
||||
"State": "running",
|
||||
"Status": "Up 6 hours"
|
||||
},
|
||||
{
|
||||
"Id": "ff31facfb3b3ed4cd362c1e88fc89a53908ad05fb3a4103bca3f9b28292d14bf",
|
||||
"Names": ["/dashy_dashy.1.qgza68hnz4n1qvyz3iohynx05"],
|
||||
"Image": "docker.io/lissy93/dashy:latest",
|
||||
"ImageID": "sha256:7f8a4339a5c5d5d37d1262630108ab308d3e9ec7ed1c3286a32fe09856619a782",
|
||||
"Command": "node server",
|
||||
"Created": "1739816096",
|
||||
"Ports": [
|
||||
{
|
||||
"PrivatePort": 8080,
|
||||
"PublicPort": 4000,
|
||||
"Type": "tcp"
|
||||
}
|
||||
],
|
||||
"Labels": {
|
||||
"com.docker.stack.namespace": "dashy",
|
||||
"com.docker.swarm.node.id": "nggd3w8ntk2ivzkka6ecprjkh",
|
||||
"com.docker.swarm.service.id": "nk8zud67mpr6nyln0vhko65zb",
|
||||
"com.docker.swarm.service.name": "dashy_dashy",
|
||||
"com.docker.swarm.task": "",
|
||||
"com.docker.swarm.task.id": "qgza68hnz4n1qvyz3iohynx05",
|
||||
"com.docker.swarm.task.name": "dashy_dashy.1.qgza68hnz4n1qvyz3iohynx05"
|
||||
},
|
||||
"State": "running",
|
||||
"Status": "Up 3 hours"
|
||||
}
|
||||
]
|
||||
|
||||
@@ -10,5 +10,17 @@
|
||||
"CreatedBy": "admin",
|
||||
"CreationDate": 1739700000,
|
||||
"FromAppTemplate": false
|
||||
},
|
||||
{
|
||||
"Id": 2,
|
||||
"Name": "dashy",
|
||||
"Type": 1,
|
||||
"EndpointId": 1,
|
||||
"Status": 1,
|
||||
"EntryPoint": "docker-stack.yml",
|
||||
"ProjectPath": "/data/compose/dashy",
|
||||
"CreatedBy": "admin",
|
||||
"CreationDate": 1739710000,
|
||||
"FromAppTemplate": false
|
||||
}
|
||||
]
|
||||
|
||||
@@ -1,4 +1,104 @@
|
||||
# serializer version: 1
|
||||
# name: test_all_entities[binary_sensor.dashy_dashy_1_qgza68hnz4n1qvyz3iohynx05_status-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': 'binary_sensor',
|
||||
'entity_category': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
|
||||
'entity_id': 'binary_sensor.dashy_dashy_1_qgza68hnz4n1qvyz3iohynx05_status',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'object_id_base': 'Status',
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <BinarySensorDeviceClass.RUNNING: 'running'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Status',
|
||||
'platform': 'portainer',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'status',
|
||||
'unique_id': 'portainer_test_entry_123_dashy_dashy.1.qgza68hnz4n1qvyz3iohynx05_status',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[binary_sensor.dashy_dashy_1_qgza68hnz4n1qvyz3iohynx05_status-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'running',
|
||||
'friendly_name': 'dashy_dashy.1.qgza68hnz4n1qvyz3iohynx05 Status',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'binary_sensor.dashy_dashy_1_qgza68hnz4n1qvyz3iohynx05_status',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'on',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[binary_sensor.dashy_status-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': 'binary_sensor',
|
||||
'entity_category': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
|
||||
'entity_id': 'binary_sensor.dashy_status',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'object_id_base': 'Status',
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <BinarySensorDeviceClass.RUNNING: 'running'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Status',
|
||||
'platform': 'portainer',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'status',
|
||||
'unique_id': 'portainer_test_entry_123_2_stack_status',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[binary_sensor.dashy_status-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'running',
|
||||
'friendly_name': 'dashy Status',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'binary_sensor.dashy_status',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'on',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[binary_sensor.focused_einstein_status-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
|
||||
@@ -1,4 +1,54 @@
|
||||
# serializer version: 1
|
||||
# name: test_all_button_entities_snapshot[button.dashy_dashy_1_qgza68hnz4n1qvyz3iohynx05_restart_container-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': 'button',
|
||||
'entity_category': <EntityCategory.CONFIG: 'config'>,
|
||||
'entity_id': 'button.dashy_dashy_1_qgza68hnz4n1qvyz3iohynx05_restart_container',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'object_id_base': 'Restart container',
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <ButtonDeviceClass.RESTART: 'restart'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Restart container',
|
||||
'platform': 'portainer',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'restart_container',
|
||||
'unique_id': 'portainer_test_entry_123_dashy_dashy.1.qgza68hnz4n1qvyz3iohynx05_restart',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_button_entities_snapshot[button.dashy_dashy_1_qgza68hnz4n1qvyz3iohynx05_restart_container-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'restart',
|
||||
'friendly_name': 'dashy_dashy.1.qgza68hnz4n1qvyz3iohynx05 Restart container',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'button.dashy_dashy_1_qgza68hnz4n1qvyz3iohynx05_restart_container',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'unknown',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_button_entities_snapshot[button.focused_einstein_restart_container-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
|
||||
@@ -73,6 +73,15 @@
|
||||
'state': 'running',
|
||||
'status': 'Up 6 hours',
|
||||
}),
|
||||
dict({
|
||||
'id': 'ff31facfb3b3ed4cd362c1e88fc89a53908ad05fb3a4103bca3f9b28292d14bf',
|
||||
'image': 'docker.io/lissy93/dashy:latest',
|
||||
'names': list([
|
||||
'/dashy_dashy.1.qgza68hnz4n1qvyz3iohynx05',
|
||||
]),
|
||||
'state': 'running',
|
||||
'status': 'Up 3 hours',
|
||||
}),
|
||||
]),
|
||||
'endpoint': dict({
|
||||
'public_url': 'docker.mydomain.tld:2375',
|
||||
|
||||
@@ -146,6 +146,35 @@
|
||||
'sw_version': None,
|
||||
'via_device_id': <ANY>,
|
||||
}),
|
||||
DeviceRegistryEntrySnapshot({
|
||||
'area_id': None,
|
||||
'config_entries': <ANY>,
|
||||
'config_entries_subentries': <ANY>,
|
||||
'configuration_url': 'https://127.0.0.1:9000/#!/1/docker/stacks/dashy',
|
||||
'connections': set({
|
||||
}),
|
||||
'disabled_by': None,
|
||||
'entry_type': None,
|
||||
'hw_version': None,
|
||||
'id': <ANY>,
|
||||
'identifiers': set({
|
||||
tuple(
|
||||
'portainer',
|
||||
'portainer_test_entry_123_1_stack_2',
|
||||
),
|
||||
}),
|
||||
'labels': set({
|
||||
}),
|
||||
'manufacturer': 'Portainer',
|
||||
'model': 'Stack',
|
||||
'model_id': None,
|
||||
'name': 'dashy',
|
||||
'name_by_user': None,
|
||||
'primary_config_entry': <ANY>,
|
||||
'serial_number': None,
|
||||
'sw_version': None,
|
||||
'via_device_id': <ANY>,
|
||||
}),
|
||||
DeviceRegistryEntrySnapshot({
|
||||
'area_id': None,
|
||||
'config_entries': <ANY>,
|
||||
@@ -204,5 +233,34 @@
|
||||
'sw_version': None,
|
||||
'via_device_id': <ANY>,
|
||||
}),
|
||||
DeviceRegistryEntrySnapshot({
|
||||
'area_id': None,
|
||||
'config_entries': <ANY>,
|
||||
'config_entries_subentries': <ANY>,
|
||||
'configuration_url': 'https://127.0.0.1:9000/#!/1/docker/containers/ff31facfb3b3ed4cd362c1e88fc89a53908ad05fb3a4103bca3f9b28292d14bf',
|
||||
'connections': set({
|
||||
}),
|
||||
'disabled_by': None,
|
||||
'entry_type': <DeviceEntryType.SERVICE: 'service'>,
|
||||
'hw_version': None,
|
||||
'id': <ANY>,
|
||||
'identifiers': set({
|
||||
tuple(
|
||||
'portainer',
|
||||
'portainer_test_entry_123_1_dashy_dashy.1.qgza68hnz4n1qvyz3iohynx05',
|
||||
),
|
||||
}),
|
||||
'labels': set({
|
||||
}),
|
||||
'manufacturer': 'Portainer',
|
||||
'model': 'Container',
|
||||
'model_id': None,
|
||||
'name': 'dashy_dashy.1.qgza68hnz4n1qvyz3iohynx05',
|
||||
'name_by_user': None,
|
||||
'primary_config_entry': <ANY>,
|
||||
'serial_number': None,
|
||||
'sw_version': None,
|
||||
'via_device_id': <ANY>,
|
||||
}),
|
||||
])
|
||||
# ---
|
||||
|
||||
@@ -1,4 +1,466 @@
|
||||
# serializer version: 1
|
||||
# name: test_all_entities[sensor.dashy_containers-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.dashy_containers',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'object_id_base': 'Containers',
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Containers',
|
||||
'platform': 'portainer',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'stack_containers_count',
|
||||
'unique_id': 'portainer_test_entry_123_2_stack_containers_count',
|
||||
'unit_of_measurement': 'containers',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[sensor.dashy_containers-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'dashy Containers',
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
'unit_of_measurement': 'containers',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.dashy_containers',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '1',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[sensor.dashy_dashy_1_qgza68hnz4n1qvyz3iohynx05_cpu_usage_total-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.dashy_dashy_1_qgza68hnz4n1qvyz3iohynx05_cpu_usage_total',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'object_id_base': 'CPU usage total',
|
||||
'options': dict({
|
||||
'sensor': dict({
|
||||
'suggested_display_precision': 2,
|
||||
}),
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'CPU usage total',
|
||||
'platform': 'portainer',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'cpu_usage_total',
|
||||
'unique_id': 'portainer_test_entry_123_dashy_dashy.1.qgza68hnz4n1qvyz3iohynx05_cpu_usage_total',
|
||||
'unit_of_measurement': '%',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[sensor.dashy_dashy_1_qgza68hnz4n1qvyz3iohynx05_cpu_usage_total-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'dashy_dashy.1.qgza68hnz4n1qvyz3iohynx05 CPU usage total',
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
'unit_of_measurement': '%',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.dashy_dashy_1_qgza68hnz4n1qvyz3iohynx05_cpu_usage_total',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '0.0',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[sensor.dashy_dashy_1_qgza68hnz4n1qvyz3iohynx05_image-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': None,
|
||||
'entity_id': 'sensor.dashy_dashy_1_qgza68hnz4n1qvyz3iohynx05_image',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'object_id_base': 'Image',
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Image',
|
||||
'platform': 'portainer',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'image',
|
||||
'unique_id': 'portainer_test_entry_123_dashy_dashy.1.qgza68hnz4n1qvyz3iohynx05_image',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[sensor.dashy_dashy_1_qgza68hnz4n1qvyz3iohynx05_image-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'dashy_dashy.1.qgza68hnz4n1qvyz3iohynx05 Image',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.dashy_dashy_1_qgza68hnz4n1qvyz3iohynx05_image',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'docker.io/lissy93/dashy:latest',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[sensor.dashy_dashy_1_qgza68hnz4n1qvyz3iohynx05_memory_limit-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.dashy_dashy_1_qgza68hnz4n1qvyz3iohynx05_memory_limit',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'object_id_base': 'Memory limit',
|
||||
'options': dict({
|
||||
'sensor': dict({
|
||||
'suggested_display_precision': 1,
|
||||
}),
|
||||
'sensor.private': dict({
|
||||
'suggested_unit_of_measurement': <UnitOfInformation.MEGABYTES: 'MB'>,
|
||||
}),
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.DATA_SIZE: 'data_size'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Memory limit',
|
||||
'platform': 'portainer',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'memory_limit',
|
||||
'unique_id': 'portainer_test_entry_123_dashy_dashy.1.qgza68hnz4n1qvyz3iohynx05_memory_limit',
|
||||
'unit_of_measurement': <UnitOfInformation.MEGABYTES: 'MB'>,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[sensor.dashy_dashy_1_qgza68hnz4n1qvyz3iohynx05_memory_limit-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'data_size',
|
||||
'friendly_name': 'dashy_dashy.1.qgza68hnz4n1qvyz3iohynx05 Memory limit',
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
'unit_of_measurement': <UnitOfInformation.MEGABYTES: 'MB'>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.dashy_dashy_1_qgza68hnz4n1qvyz3iohynx05_memory_limit',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '67.108864',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[sensor.dashy_dashy_1_qgza68hnz4n1qvyz3iohynx05_memory_usage-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.dashy_dashy_1_qgza68hnz4n1qvyz3iohynx05_memory_usage',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'object_id_base': 'Memory usage',
|
||||
'options': dict({
|
||||
'sensor': dict({
|
||||
'suggested_display_precision': 1,
|
||||
}),
|
||||
'sensor.private': dict({
|
||||
'suggested_unit_of_measurement': <UnitOfInformation.MEGABYTES: 'MB'>,
|
||||
}),
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.DATA_SIZE: 'data_size'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Memory usage',
|
||||
'platform': 'portainer',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'memory_usage',
|
||||
'unique_id': 'portainer_test_entry_123_dashy_dashy.1.qgza68hnz4n1qvyz3iohynx05_memory_usage',
|
||||
'unit_of_measurement': <UnitOfInformation.MEGABYTES: 'MB'>,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[sensor.dashy_dashy_1_qgza68hnz4n1qvyz3iohynx05_memory_usage-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'data_size',
|
||||
'friendly_name': 'dashy_dashy.1.qgza68hnz4n1qvyz3iohynx05 Memory usage',
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
'unit_of_measurement': <UnitOfInformation.MEGABYTES: 'MB'>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.dashy_dashy_1_qgza68hnz4n1qvyz3iohynx05_memory_usage',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '6.537216',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[sensor.dashy_dashy_1_qgza68hnz4n1qvyz3iohynx05_memory_usage_percentage-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.dashy_dashy_1_qgza68hnz4n1qvyz3iohynx05_memory_usage_percentage',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'object_id_base': 'Memory usage percentage',
|
||||
'options': dict({
|
||||
'sensor': dict({
|
||||
'suggested_display_precision': 2,
|
||||
}),
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Memory usage percentage',
|
||||
'platform': 'portainer',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'memory_usage_percentage',
|
||||
'unique_id': 'portainer_test_entry_123_dashy_dashy.1.qgza68hnz4n1qvyz3iohynx05_memory_usage_percentage',
|
||||
'unit_of_measurement': '%',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[sensor.dashy_dashy_1_qgza68hnz4n1qvyz3iohynx05_memory_usage_percentage-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'dashy_dashy.1.qgza68hnz4n1qvyz3iohynx05 Memory usage percentage',
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
'unit_of_measurement': '%',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.dashy_dashy_1_qgza68hnz4n1qvyz3iohynx05_memory_usage_percentage',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '9.7412109375',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[sensor.dashy_dashy_1_qgza68hnz4n1qvyz3iohynx05_state-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': dict({
|
||||
'options': list([
|
||||
'running',
|
||||
'exited',
|
||||
'paused',
|
||||
'restarting',
|
||||
'created',
|
||||
'dead',
|
||||
]),
|
||||
}),
|
||||
'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.dashy_dashy_1_qgza68hnz4n1qvyz3iohynx05_state',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'object_id_base': 'State',
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.ENUM: 'enum'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'State',
|
||||
'platform': 'portainer',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'container_state',
|
||||
'unique_id': 'portainer_test_entry_123_dashy_dashy.1.qgza68hnz4n1qvyz3iohynx05_container_state',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[sensor.dashy_dashy_1_qgza68hnz4n1qvyz3iohynx05_state-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'enum',
|
||||
'friendly_name': 'dashy_dashy.1.qgza68hnz4n1qvyz3iohynx05 State',
|
||||
'options': list([
|
||||
'running',
|
||||
'exited',
|
||||
'paused',
|
||||
'restarting',
|
||||
'created',
|
||||
'dead',
|
||||
]),
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.dashy_dashy_1_qgza68hnz4n1qvyz3iohynx05_state',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'running',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[sensor.dashy_type-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': dict({
|
||||
'options': list([
|
||||
'swarm',
|
||||
'compose',
|
||||
'kubernetes',
|
||||
]),
|
||||
}),
|
||||
'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.dashy_type',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'object_id_base': 'Type',
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.ENUM: 'enum'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Type',
|
||||
'platform': 'portainer',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'stack_type',
|
||||
'unique_id': 'portainer_test_entry_123_2_stack_type',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[sensor.dashy_type-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'enum',
|
||||
'friendly_name': 'dashy Type',
|
||||
'options': list([
|
||||
'swarm',
|
||||
'compose',
|
||||
'kubernetes',
|
||||
]),
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.dashy_type',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'swarm',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[sensor.focused_einstein_cpu_usage_total-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
|
||||
@@ -1,4 +1,104 @@
|
||||
# serializer version: 1
|
||||
# name: test_all_switch_entities_snapshot[switch.dashy_dashy_1_qgza68hnz4n1qvyz3iohynx05_container-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': 'switch',
|
||||
'entity_category': None,
|
||||
'entity_id': 'switch.dashy_dashy_1_qgza68hnz4n1qvyz3iohynx05_container',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'object_id_base': 'Container',
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SwitchDeviceClass.SWITCH: 'switch'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Container',
|
||||
'platform': 'portainer',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'container',
|
||||
'unique_id': 'portainer_test_entry_123_dashy_dashy.1.qgza68hnz4n1qvyz3iohynx05_container',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_switch_entities_snapshot[switch.dashy_dashy_1_qgza68hnz4n1qvyz3iohynx05_container-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'switch',
|
||||
'friendly_name': 'dashy_dashy.1.qgza68hnz4n1qvyz3iohynx05 Container',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'switch.dashy_dashy_1_qgza68hnz4n1qvyz3iohynx05_container',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'on',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_switch_entities_snapshot[switch.dashy_stack-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': 'switch',
|
||||
'entity_category': None,
|
||||
'entity_id': 'switch.dashy_stack',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'object_id_base': 'Stack',
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SwitchDeviceClass.SWITCH: 'switch'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Stack',
|
||||
'platform': 'portainer',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'stack',
|
||||
'unique_id': 'portainer_test_entry_123_2_stack',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_switch_entities_snapshot[switch.dashy_stack-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'switch',
|
||||
'friendly_name': 'dashy Stack',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'switch.dashy_stack',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'on',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_switch_entities_snapshot[switch.focused_einstein_container-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
|
||||
@@ -183,3 +183,54 @@ async def test_device_registry(
|
||||
device_registry, mock_config_entry.entry_id
|
||||
)
|
||||
assert device_entries == snapshot
|
||||
|
||||
|
||||
async def test_container_stack_device_links(
|
||||
hass: HomeAssistant,
|
||||
mock_portainer_client: AsyncMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
device_registry: dr.DeviceRegistry,
|
||||
) -> None:
|
||||
"""Test that stack-linked containers are nested under the correct stack device."""
|
||||
await setup_integration(hass, mock_config_entry)
|
||||
|
||||
endpoint_device = device_registry.async_get_device(
|
||||
identifiers={(DOMAIN, f"{mock_config_entry.entry_id}_1")}
|
||||
)
|
||||
assert endpoint_device is not None
|
||||
|
||||
dashy_stack_device = device_registry.async_get_device(
|
||||
identifiers={(DOMAIN, f"{mock_config_entry.entry_id}_1_stack_2")}
|
||||
)
|
||||
assert dashy_stack_device is not None
|
||||
assert dashy_stack_device.via_device_id == endpoint_device.id
|
||||
|
||||
webstack_device = device_registry.async_get_device(
|
||||
identifiers={(DOMAIN, f"{mock_config_entry.entry_id}_1_stack_1")}
|
||||
)
|
||||
assert webstack_device is not None
|
||||
assert webstack_device.via_device_id == endpoint_device.id
|
||||
|
||||
swarm_container_device = device_registry.async_get_device(
|
||||
identifiers={
|
||||
(
|
||||
DOMAIN,
|
||||
f"{mock_config_entry.entry_id}_1_dashy_dashy.1.qgza68hnz4n1qvyz3iohynx05",
|
||||
)
|
||||
}
|
||||
)
|
||||
assert swarm_container_device is not None
|
||||
assert swarm_container_device.via_device_id == dashy_stack_device.id
|
||||
|
||||
compose_container_device = device_registry.async_get_device(
|
||||
identifiers={(DOMAIN, f"{mock_config_entry.entry_id}_1_serene_banach")}
|
||||
)
|
||||
assert compose_container_device is not None
|
||||
assert compose_container_device.via_device_id == webstack_device.id
|
||||
|
||||
standalone_container_device = device_registry.async_get_device(
|
||||
identifiers={(DOMAIN, f"{mock_config_entry.entry_id}_1_focused_einstein")}
|
||||
)
|
||||
|
||||
assert standalone_container_device is not None
|
||||
assert standalone_container_device.via_device_id == endpoint_device.id
|
||||
|
||||
Reference in New Issue
Block a user