Add Homee wind_monitoring_state to numbers (#139848)

This commit is contained in:
Markus Adrario 2025-04-21 21:21:15 +02:00 committed by GitHub
parent 80f34620c8
commit f0cf620854
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 225 additions and 78 deletions

View File

@ -1,5 +1,8 @@
"""The Homee number platform.""" """The Homee number platform."""
from collections.abc import Callable
from dataclasses import dataclass
from pyHomee.const import AttributeType from pyHomee.const import AttributeType
from pyHomee.model import HomeeAttribute from pyHomee.model import HomeeAttribute
@ -8,7 +11,7 @@ from homeassistant.components.number import (
NumberEntity, NumberEntity,
NumberEntityDescription, NumberEntityDescription,
) )
from homeassistant.const import EntityCategory from homeassistant.const import EntityCategory, UnitOfSpeed
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
@ -18,69 +21,89 @@ from .entity import HomeeEntity
PARALLEL_UPDATES = 0 PARALLEL_UPDATES = 0
@dataclass(frozen=True, kw_only=True)
class HomeeNumberEntityDescription(NumberEntityDescription):
"""A class that describes Homee number entities."""
native_value_fn: Callable[[float], float] = lambda value: value
set_native_value_fn: Callable[[float], float] = lambda value: value
NUMBER_DESCRIPTIONS = { NUMBER_DESCRIPTIONS = {
AttributeType.DOWN_POSITION: NumberEntityDescription( AttributeType.DOWN_POSITION: HomeeNumberEntityDescription(
key="down_position", key="down_position",
entity_category=EntityCategory.CONFIG, entity_category=EntityCategory.CONFIG,
), ),
AttributeType.DOWN_SLAT_POSITION: NumberEntityDescription( AttributeType.DOWN_SLAT_POSITION: HomeeNumberEntityDescription(
key="down_slat_position", key="down_slat_position",
entity_category=EntityCategory.CONFIG, entity_category=EntityCategory.CONFIG,
), ),
AttributeType.DOWN_TIME: NumberEntityDescription( AttributeType.DOWN_TIME: HomeeNumberEntityDescription(
key="down_time", key="down_time",
device_class=NumberDeviceClass.DURATION, device_class=NumberDeviceClass.DURATION,
entity_category=EntityCategory.CONFIG, entity_category=EntityCategory.CONFIG,
), ),
AttributeType.ENDPOSITION_CONFIGURATION: NumberEntityDescription( AttributeType.ENDPOSITION_CONFIGURATION: HomeeNumberEntityDescription(
key="endposition_configuration", key="endposition_configuration",
entity_category=EntityCategory.CONFIG, entity_category=EntityCategory.CONFIG,
), ),
AttributeType.MOTION_ALARM_CANCELATION_DELAY: NumberEntityDescription( AttributeType.MOTION_ALARM_CANCELATION_DELAY: HomeeNumberEntityDescription(
key="motion_alarm_cancelation_delay", key="motion_alarm_cancelation_delay",
device_class=NumberDeviceClass.DURATION, device_class=NumberDeviceClass.DURATION,
entity_category=EntityCategory.CONFIG, entity_category=EntityCategory.CONFIG,
), ),
AttributeType.OPEN_WINDOW_DETECTION_SENSIBILITY: NumberEntityDescription( AttributeType.OPEN_WINDOW_DETECTION_SENSIBILITY: HomeeNumberEntityDescription(
key="open_window_detection_sensibility", key="open_window_detection_sensibility",
entity_category=EntityCategory.CONFIG, entity_category=EntityCategory.CONFIG,
), ),
AttributeType.POLLING_INTERVAL: NumberEntityDescription( AttributeType.POLLING_INTERVAL: HomeeNumberEntityDescription(
key="polling_interval", key="polling_interval",
device_class=NumberDeviceClass.DURATION, device_class=NumberDeviceClass.DURATION,
entity_category=EntityCategory.CONFIG, entity_category=EntityCategory.CONFIG,
), ),
AttributeType.SHUTTER_SLAT_TIME: NumberEntityDescription( AttributeType.SHUTTER_SLAT_TIME: HomeeNumberEntityDescription(
key="shutter_slat_time", key="shutter_slat_time",
device_class=NumberDeviceClass.DURATION, device_class=NumberDeviceClass.DURATION,
entity_category=EntityCategory.CONFIG, entity_category=EntityCategory.CONFIG,
), ),
AttributeType.SLAT_MAX_ANGLE: NumberEntityDescription( AttributeType.SLAT_MAX_ANGLE: HomeeNumberEntityDescription(
key="slat_max_angle", key="slat_max_angle",
entity_category=EntityCategory.CONFIG, entity_category=EntityCategory.CONFIG,
), ),
AttributeType.SLAT_MIN_ANGLE: NumberEntityDescription( AttributeType.SLAT_MIN_ANGLE: HomeeNumberEntityDescription(
key="slat_min_angle", key="slat_min_angle",
entity_category=EntityCategory.CONFIG, entity_category=EntityCategory.CONFIG,
), ),
AttributeType.SLAT_STEPS: NumberEntityDescription( AttributeType.SLAT_STEPS: HomeeNumberEntityDescription(
key="slat_steps", key="slat_steps",
entity_category=EntityCategory.CONFIG, entity_category=EntityCategory.CONFIG,
), ),
AttributeType.TEMPERATURE_OFFSET: NumberEntityDescription( AttributeType.TEMPERATURE_OFFSET: HomeeNumberEntityDescription(
key="temperature_offset", key="temperature_offset",
entity_category=EntityCategory.CONFIG, entity_category=EntityCategory.CONFIG,
), ),
AttributeType.UP_TIME: NumberEntityDescription( AttributeType.UP_TIME: HomeeNumberEntityDescription(
key="up_time", key="up_time",
device_class=NumberDeviceClass.DURATION, device_class=NumberDeviceClass.DURATION,
entity_category=EntityCategory.CONFIG, entity_category=EntityCategory.CONFIG,
), ),
AttributeType.WAKE_UP_INTERVAL: NumberEntityDescription( AttributeType.WAKE_UP_INTERVAL: HomeeNumberEntityDescription(
key="wake_up_interval", key="wake_up_interval",
device_class=NumberDeviceClass.DURATION, device_class=NumberDeviceClass.DURATION,
entity_category=EntityCategory.CONFIG, entity_category=EntityCategory.CONFIG,
), ),
AttributeType.WIND_MONITORING_STATE: HomeeNumberEntityDescription(
key="wind_monitoring_state",
device_class=NumberDeviceClass.WIND_SPEED,
entity_category=EntityCategory.CONFIG,
native_min_value=0,
native_max_value=22.5,
native_step=2.5,
native_unit_of_measurement=UnitOfSpeed.METERS_PER_SECOND,
native_value_fn=lambda value: value * 2.5,
set_native_value_fn=lambda value: value / 2.5,
),
} }
@ -102,20 +125,25 @@ async def async_setup_entry(
class HomeeNumber(HomeeEntity, NumberEntity): class HomeeNumber(HomeeEntity, NumberEntity):
"""Representation of a Homee number.""" """Representation of a Homee number."""
entity_description: HomeeNumberEntityDescription
def __init__( def __init__(
self, self,
attribute: HomeeAttribute, attribute: HomeeAttribute,
entry: HomeeConfigEntry, entry: HomeeConfigEntry,
description: NumberEntityDescription, description: HomeeNumberEntityDescription,
) -> None: ) -> None:
"""Initialize a Homee number entity.""" """Initialize a Homee number entity."""
super().__init__(attribute, entry) super().__init__(attribute, entry)
self.entity_description = description self.entity_description = description
self._attr_translation_key = description.key self._attr_translation_key = description.key
self._attr_native_unit_of_measurement = HOMEE_UNIT_TO_HA_UNIT[attribute.unit] self._attr_native_unit_of_measurement = (
self._attr_native_min_value = attribute.minimum description.native_unit_of_measurement
self._attr_native_max_value = attribute.maximum or HOMEE_UNIT_TO_HA_UNIT[attribute.unit]
self._attr_native_step = attribute.step_value )
self._attr_native_min_value = description.native_min_value or attribute.minimum
self._attr_native_max_value = description.native_max_value or attribute.maximum
self._attr_native_step = description.native_step or attribute.step_value
@property @property
def available(self) -> bool: def available(self) -> bool:
@ -123,10 +151,12 @@ class HomeeNumber(HomeeEntity, NumberEntity):
return super().available and self._attribute.editable return super().available and self._attribute.editable
@property @property
def native_value(self) -> int: def native_value(self) -> float | None:
"""Return the native value of the number.""" """Return the native value of the number."""
return int(self._attribute.current_value) return self.entity_description.native_value_fn(self._attribute.current_value)
async def async_set_native_value(self, value: float) -> None: async def async_set_native_value(self, value: float) -> None:
"""Set the selected value.""" """Set the selected value."""
await self.async_set_homee_value(value) await self.async_set_homee_value(
self.entity_description.set_native_value_fn(value)
)

View File

@ -189,6 +189,9 @@
}, },
"wake_up_interval": { "wake_up_interval": {
"name": "Wake-up interval" "name": "Wake-up interval"
},
"wind_monitoring_state": {
"name": "Threshold for wind trigger"
} }
}, },
"select": { "select": {

View File

@ -19,7 +19,7 @@
"security": 0, "security": 0,
"attributes": [ "attributes": [
{ {
"id": 2, "id": 1,
"node_id": 1, "node_id": 1,
"instance": 0, "instance": 0,
"minimum": 0, "minimum": 0,
@ -40,7 +40,7 @@
"name": "" "name": ""
}, },
{ {
"id": 3, "id": 2,
"node_id": 1, "node_id": 1,
"instance": 0, "instance": 0,
"minimum": -75, "minimum": -75,
@ -61,7 +61,7 @@
"name": "" "name": ""
}, },
{ {
"id": 4, "id": 3,
"node_id": 1, "node_id": 1,
"instance": 0, "instance": 0,
"minimum": 4, "minimum": 4,
@ -82,7 +82,7 @@
"name": "" "name": ""
}, },
{ {
"id": 5, "id": 4,
"node_id": 1, "node_id": 1,
"instance": 0, "instance": 0,
"minimum": 0, "minimum": 0,
@ -103,7 +103,7 @@
"name": "" "name": ""
}, },
{ {
"id": 6, "id": 5,
"node_id": 1, "node_id": 1,
"instance": 0, "instance": 0,
"minimum": 1, "minimum": 1,
@ -124,7 +124,7 @@
"name": "" "name": ""
}, },
{ {
"id": 7, "id": 6,
"node_id": 1, "node_id": 1,
"instance": 0, "instance": 0,
"minimum": 0, "minimum": 0,
@ -145,7 +145,7 @@
"name": "" "name": ""
}, },
{ {
"id": 8, "id": 7,
"node_id": 1, "node_id": 1,
"instance": 0, "instance": 0,
"minimum": 5, "minimum": 5,
@ -166,7 +166,7 @@
"name": "" "name": ""
}, },
{ {
"id": 9, "id": 8,
"node_id": 1, "node_id": 1,
"instance": 0, "instance": 0,
"minimum": 0, "minimum": 0,
@ -187,7 +187,7 @@
"name": "" "name": ""
}, },
{ {
"id": 10, "id": 9,
"node_id": 1, "node_id": 1,
"instance": 0, "instance": 0,
"minimum": -127, "minimum": -127,
@ -208,7 +208,7 @@
"name": "" "name": ""
}, },
{ {
"id": 11, "id": 10,
"node_id": 1, "node_id": 1,
"instance": 0, "instance": 0,
"minimum": -127, "minimum": -127,
@ -229,7 +229,7 @@
"name": "" "name": ""
}, },
{ {
"id": 12, "id": 11,
"node_id": 1, "node_id": 1,
"instance": 0, "instance": 0,
"minimum": 1, "minimum": 1,
@ -250,7 +250,7 @@
"name": "" "name": ""
}, },
{ {
"id": 13, "id": 12,
"node_id": 1, "node_id": 1,
"instance": 0, "instance": 0,
"minimum": -5, "minimum": -5,
@ -271,7 +271,7 @@
"name": "" "name": ""
}, },
{ {
"id": 14, "id": 13,
"node_id": 1, "node_id": 1,
"instance": 0, "instance": 0,
"minimum": 4, "minimum": 4,
@ -292,7 +292,7 @@
"name": "" "name": ""
}, },
{ {
"id": 15, "id": 14,
"node_id": 1, "node_id": 1,
"instance": 0, "instance": 0,
"minimum": 30, "minimum": 30,
@ -313,7 +313,7 @@
"name": "" "name": ""
}, },
{ {
"id": 16, "id": 15,
"node_id": 1, "node_id": 1,
"instance": 0, "instance": 0,
"minimum": 0, "minimum": 0,
@ -332,6 +332,27 @@
"based_on": 1, "based_on": 1,
"data": "fixed_value", "data": "fixed_value",
"name": "" "name": ""
},
{
"id": 16,
"node_id": 1,
"instance": 0,
"minimum": 0,
"maximum": 9,
"current_value": 2.0,
"target_value": 2.0,
"last_value": 2.0,
"unit": "n/a",
"step_value": 1.0,
"editable": 1,
"type": 338,
"state": 1,
"last_changed": 1684668852,
"changed_by": 1,
"changed_by_id": 0,
"based_on": 1,
"data": "",
"name": ""
} }
] ]
} }

View File

@ -34,7 +34,7 @@
'previous_unique_id': None, 'previous_unique_id': None,
'supported_features': 0, 'supported_features': 0,
'translation_key': 'down_time', 'translation_key': 'down_time',
'unique_id': '00055511EECC-1-4', 'unique_id': '00055511EECC-1-3',
'unit_of_measurement': <UnitOfTime.SECONDS: 's'>, 'unit_of_measurement': <UnitOfTime.SECONDS: 's'>,
}) })
# --- # ---
@ -54,7 +54,7 @@
'last_changed': <ANY>, 'last_changed': <ANY>,
'last_reported': <ANY>, 'last_reported': <ANY>,
'last_updated': <ANY>, 'last_updated': <ANY>,
'state': '57', 'state': '57.0',
}) })
# --- # ---
# name: test_number_snapshot[number.test_number_down_position-entry] # name: test_number_snapshot[number.test_number_down_position-entry]
@ -92,7 +92,7 @@
'previous_unique_id': None, 'previous_unique_id': None,
'supported_features': 0, 'supported_features': 0,
'translation_key': 'down_position', 'translation_key': 'down_position',
'unique_id': '00055511EECC-1-2', 'unique_id': '00055511EECC-1-1',
'unit_of_measurement': '%', 'unit_of_measurement': '%',
}) })
# --- # ---
@ -111,7 +111,7 @@
'last_changed': <ANY>, 'last_changed': <ANY>,
'last_reported': <ANY>, 'last_reported': <ANY>,
'last_updated': <ANY>, 'last_updated': <ANY>,
'state': '100', 'state': '100.0',
}) })
# --- # ---
# name: test_number_snapshot[number.test_number_down_slat_position-entry] # name: test_number_snapshot[number.test_number_down_slat_position-entry]
@ -149,7 +149,7 @@
'previous_unique_id': None, 'previous_unique_id': None,
'supported_features': 0, 'supported_features': 0,
'translation_key': 'down_slat_position', 'translation_key': 'down_slat_position',
'unique_id': '00055511EECC-1-3', 'unique_id': '00055511EECC-1-2',
'unit_of_measurement': '°', 'unit_of_measurement': '°',
}) })
# --- # ---
@ -168,7 +168,7 @@
'last_changed': <ANY>, 'last_changed': <ANY>,
'last_reported': <ANY>, 'last_reported': <ANY>,
'last_updated': <ANY>, 'last_updated': <ANY>,
'state': '38', 'state': '38.0',
}) })
# --- # ---
# name: test_number_snapshot[number.test_number_end_position-entry] # name: test_number_snapshot[number.test_number_end_position-entry]
@ -206,7 +206,7 @@
'previous_unique_id': None, 'previous_unique_id': None,
'supported_features': 0, 'supported_features': 0,
'translation_key': 'endposition_configuration', 'translation_key': 'endposition_configuration',
'unique_id': '00055511EECC-1-5', 'unique_id': '00055511EECC-1-4',
'unit_of_measurement': None, 'unit_of_measurement': None,
}) })
# --- # ---
@ -224,7 +224,7 @@
'last_changed': <ANY>, 'last_changed': <ANY>,
'last_reported': <ANY>, 'last_reported': <ANY>,
'last_updated': <ANY>, 'last_updated': <ANY>,
'state': '129', 'state': '129.0',
}) })
# --- # ---
# name: test_number_snapshot[number.test_number_maximum_slat_angle-entry] # name: test_number_snapshot[number.test_number_maximum_slat_angle-entry]
@ -262,7 +262,7 @@
'previous_unique_id': None, 'previous_unique_id': None,
'supported_features': 0, 'supported_features': 0,
'translation_key': 'slat_max_angle', 'translation_key': 'slat_max_angle',
'unique_id': '00055511EECC-1-10', 'unique_id': '00055511EECC-1-9',
'unit_of_measurement': '°', 'unit_of_measurement': '°',
}) })
# --- # ---
@ -281,7 +281,7 @@
'last_changed': <ANY>, 'last_changed': <ANY>,
'last_reported': <ANY>, 'last_reported': <ANY>,
'last_updated': <ANY>, 'last_updated': <ANY>,
'state': '75', 'state': '75.0',
}) })
# --- # ---
# name: test_number_snapshot[number.test_number_minimum_slat_angle-entry] # name: test_number_snapshot[number.test_number_minimum_slat_angle-entry]
@ -319,7 +319,7 @@
'previous_unique_id': None, 'previous_unique_id': None,
'supported_features': 0, 'supported_features': 0,
'translation_key': 'slat_min_angle', 'translation_key': 'slat_min_angle',
'unique_id': '00055511EECC-1-11', 'unique_id': '00055511EECC-1-10',
'unit_of_measurement': '°', 'unit_of_measurement': '°',
}) })
# --- # ---
@ -338,7 +338,7 @@
'last_changed': <ANY>, 'last_changed': <ANY>,
'last_reported': <ANY>, 'last_reported': <ANY>,
'last_updated': <ANY>, 'last_updated': <ANY>,
'state': '-75', 'state': '-75.0',
}) })
# --- # ---
# name: test_number_snapshot[number.test_number_motion_alarm_delay-entry] # name: test_number_snapshot[number.test_number_motion_alarm_delay-entry]
@ -376,7 +376,7 @@
'previous_unique_id': None, 'previous_unique_id': None,
'supported_features': 0, 'supported_features': 0,
'translation_key': 'motion_alarm_cancelation_delay', 'translation_key': 'motion_alarm_cancelation_delay',
'unique_id': '00055511EECC-1-6', 'unique_id': '00055511EECC-1-5',
'unit_of_measurement': <UnitOfTime.SECONDS: 's'>, 'unit_of_measurement': <UnitOfTime.SECONDS: 's'>,
}) })
# --- # ---
@ -434,7 +434,7 @@
'previous_unique_id': None, 'previous_unique_id': None,
'supported_features': 0, 'supported_features': 0,
'translation_key': 'polling_interval', 'translation_key': 'polling_interval',
'unique_id': '00055511EECC-1-8', 'unique_id': '00055511EECC-1-7',
'unit_of_measurement': <UnitOfTime.MINUTES: 'min'>, 'unit_of_measurement': <UnitOfTime.MINUTES: 'min'>,
}) })
# --- # ---
@ -454,7 +454,7 @@
'last_changed': <ANY>, 'last_changed': <ANY>,
'last_reported': <ANY>, 'last_reported': <ANY>,
'last_updated': <ANY>, 'last_updated': <ANY>,
'state': '30', 'state': '30.0',
}) })
# --- # ---
# name: test_number_snapshot[number.test_number_slat_steps-entry] # name: test_number_snapshot[number.test_number_slat_steps-entry]
@ -492,7 +492,7 @@
'previous_unique_id': None, 'previous_unique_id': None,
'supported_features': 0, 'supported_features': 0,
'translation_key': 'slat_steps', 'translation_key': 'slat_steps',
'unique_id': '00055511EECC-1-12', 'unique_id': '00055511EECC-1-11',
'unit_of_measurement': None, 'unit_of_measurement': None,
}) })
# --- # ---
@ -510,7 +510,7 @@
'last_changed': <ANY>, 'last_changed': <ANY>,
'last_reported': <ANY>, 'last_reported': <ANY>,
'last_updated': <ANY>, 'last_updated': <ANY>,
'state': '6', 'state': '6.0',
}) })
# --- # ---
# name: test_number_snapshot[number.test_number_slat_turn_duration-entry] # name: test_number_snapshot[number.test_number_slat_turn_duration-entry]
@ -548,7 +548,7 @@
'previous_unique_id': None, 'previous_unique_id': None,
'supported_features': 0, 'supported_features': 0,
'translation_key': 'shutter_slat_time', 'translation_key': 'shutter_slat_time',
'unique_id': '00055511EECC-1-9', 'unique_id': '00055511EECC-1-8',
'unit_of_measurement': <UnitOfTime.SECONDS: 's'>, 'unit_of_measurement': <UnitOfTime.SECONDS: 's'>,
}) })
# --- # ---
@ -568,7 +568,7 @@
'last_changed': <ANY>, 'last_changed': <ANY>,
'last_reported': <ANY>, 'last_reported': <ANY>,
'last_updated': <ANY>, 'last_updated': <ANY>,
'state': '1', 'state': '1.6',
}) })
# --- # ---
# name: test_number_snapshot[number.test_number_temperature_offset-entry] # name: test_number_snapshot[number.test_number_temperature_offset-entry]
@ -606,7 +606,7 @@
'previous_unique_id': None, 'previous_unique_id': None,
'supported_features': 0, 'supported_features': 0,
'translation_key': 'temperature_offset', 'translation_key': 'temperature_offset',
'unique_id': '00055511EECC-1-13', 'unique_id': '00055511EECC-1-12',
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>, 'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
}) })
# --- # ---
@ -628,6 +628,64 @@
'state': 'unavailable', 'state': 'unavailable',
}) })
# --- # ---
# name: test_number_snapshot[number.test_number_threshold_for_wind_trigger-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'max': 22.5,
'min': 0,
'mode': <NumberMode.AUTO: 'auto'>,
'step': 2.5,
}),
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'number',
'entity_category': <EntityCategory.CONFIG: 'config'>,
'entity_id': 'number.test_number_threshold_for_wind_trigger',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': <NumberDeviceClass.WIND_SPEED: 'wind_speed'>,
'original_icon': None,
'original_name': 'Threshold for wind trigger',
'platform': 'homee',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'wind_monitoring_state',
'unique_id': '00055511EECC-1-16',
'unit_of_measurement': <UnitOfSpeed.METERS_PER_SECOND: 'm/s'>,
})
# ---
# name: test_number_snapshot[number.test_number_threshold_for_wind_trigger-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'wind_speed',
'friendly_name': 'Test Number Threshold for wind trigger',
'max': 22.5,
'min': 0,
'mode': <NumberMode.AUTO: 'auto'>,
'step': 2.5,
'unit_of_measurement': <UnitOfSpeed.METERS_PER_SECOND: 'm/s'>,
}),
'context': <ANY>,
'entity_id': 'number.test_number_threshold_for_wind_trigger',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': '5.0',
})
# ---
# name: test_number_snapshot[number.test_number_up_movement_duration-entry] # name: test_number_snapshot[number.test_number_up_movement_duration-entry]
EntityRegistryEntrySnapshot({ EntityRegistryEntrySnapshot({
'aliases': set({ 'aliases': set({
@ -663,7 +721,7 @@
'previous_unique_id': None, 'previous_unique_id': None,
'supported_features': 0, 'supported_features': 0,
'translation_key': 'up_time', 'translation_key': 'up_time',
'unique_id': '00055511EECC-1-14', 'unique_id': '00055511EECC-1-13',
'unit_of_measurement': <UnitOfTime.SECONDS: 's'>, 'unit_of_measurement': <UnitOfTime.SECONDS: 's'>,
}) })
# --- # ---
@ -683,7 +741,7 @@
'last_changed': <ANY>, 'last_changed': <ANY>,
'last_reported': <ANY>, 'last_reported': <ANY>,
'last_updated': <ANY>, 'last_updated': <ANY>,
'state': '57', 'state': '57.0',
}) })
# --- # ---
# name: test_number_snapshot[number.test_number_wake_up_interval-entry] # name: test_number_snapshot[number.test_number_wake_up_interval-entry]
@ -721,7 +779,7 @@
'previous_unique_id': None, 'previous_unique_id': None,
'supported_features': 0, 'supported_features': 0,
'translation_key': 'wake_up_interval', 'translation_key': 'wake_up_interval',
'unique_id': '00055511EECC-1-15', 'unique_id': '00055511EECC-1-14',
'unit_of_measurement': <UnitOfTime.MINUTES: 'min'>, 'unit_of_measurement': <UnitOfTime.MINUTES: 'min'>,
}) })
# --- # ---
@ -741,7 +799,7 @@
'last_changed': <ANY>, 'last_changed': <ANY>,
'last_reported': <ANY>, 'last_reported': <ANY>,
'last_updated': <ANY>, 'last_updated': <ANY>,
'state': '600', 'state': '600.0',
}) })
# --- # ---
# name: test_number_snapshot[number.test_number_window_open_sensibility-entry] # name: test_number_snapshot[number.test_number_window_open_sensibility-entry]
@ -779,7 +837,7 @@
'previous_unique_id': None, 'previous_unique_id': None,
'supported_features': 0, 'supported_features': 0,
'translation_key': 'open_window_detection_sensibility', 'translation_key': 'open_window_detection_sensibility',
'unique_id': '00055511EECC-1-7', 'unique_id': '00055511EECC-1-6',
'unit_of_measurement': None, 'unit_of_measurement': None,
}) })
# --- # ---
@ -797,6 +855,6 @@
'last_changed': <ANY>, 'last_changed': <ANY>,
'last_reported': <ANY>, 'last_reported': <ANY>,
'last_updated': <ANY>, 'last_updated': <ANY>,
'state': '3', 'state': '3.0',
}) })
# --- # ---

View File

@ -2,6 +2,7 @@
from unittest.mock import MagicMock, patch from unittest.mock import MagicMock, patch
import pytest
from syrupy.assertion import SnapshotAssertion from syrupy.assertion import SnapshotAssertion
from homeassistant.components.number import ( from homeassistant.components.number import (
@ -18,24 +19,62 @@ from . import build_mock_node, setup_integration
from tests.common import MockConfigEntry, snapshot_platform from tests.common import MockConfigEntry, snapshot_platform
async def test_set_value( async def setup_numbers(
hass: HomeAssistant, hass: HomeAssistant, mock_homee: MagicMock, mock_config_entry: MockConfigEntry
mock_homee: MagicMock,
mock_config_entry: MockConfigEntry,
) -> None: ) -> None:
"""Test set_value service.""" """Set up the number platform."""
mock_homee.nodes = [build_mock_node("numbers.json")] mock_homee.nodes = [build_mock_node("numbers.json")]
mock_homee.get_node_by_id.return_value = mock_homee.nodes[0] mock_homee.get_node_by_id.return_value = mock_homee.nodes[0]
await setup_integration(hass, mock_config_entry) await setup_integration(hass, mock_config_entry)
@pytest.mark.parametrize(
("entity_id", "expected"),
[
("number.test_number_down_position", 100.0),
("number.test_number_threshold_for_wind_trigger", 5.0),
],
)
async def test_value_fn(
hass: HomeAssistant,
mock_homee: MagicMock,
mock_config_entry: MockConfigEntry,
entity_id: str,
expected: float,
) -> None:
"""Test the value_fn of the number entity."""
await setup_numbers(hass, mock_homee, mock_config_entry)
assert hass.states.get(entity_id).state == str(expected)
@pytest.mark.parametrize(
("entity_id", "attribute_index", "value", "expected"),
[
("number.test_number_down_position", 0, 90, 90),
("number.test_number_threshold_for_wind_trigger", 15, 7.5, 3),
],
)
async def test_set_value(
hass: HomeAssistant,
mock_homee: MagicMock,
mock_config_entry: MockConfigEntry,
entity_id: str,
attribute_index: int,
value: float,
expected: float,
) -> None:
"""Test set_value service."""
await setup_numbers(hass, mock_homee, mock_config_entry)
await hass.services.async_call( await hass.services.async_call(
NUMBER_DOMAIN, NUMBER_DOMAIN,
SERVICE_SET_VALUE, SERVICE_SET_VALUE,
{ATTR_ENTITY_ID: "number.test_number_down_position", ATTR_VALUE: 90}, {ATTR_ENTITY_ID: entity_id, ATTR_VALUE: value},
blocking=True, blocking=True,
) )
number = mock_homee.nodes[0].attributes[0] number = mock_homee.nodes[0].attributes[attribute_index]
mock_homee.set_value.assert_called_once_with(number.node_id, number.id, 90) mock_homee.set_value.assert_called_once_with(number.node_id, number.id, expected)
async def test_set_value_not_editable( async def test_set_value_not_editable(
@ -44,9 +83,7 @@ async def test_set_value_not_editable(
mock_config_entry: MockConfigEntry, mock_config_entry: MockConfigEntry,
) -> None: ) -> None:
"""Test set_value if attribute is not editable.""" """Test set_value if attribute is not editable."""
mock_homee.nodes = [build_mock_node("numbers.json")] await setup_numbers(hass, mock_homee, mock_config_entry)
mock_homee.get_node_by_id.return_value = mock_homee.nodes[0]
await setup_integration(hass, mock_config_entry)
await hass.services.async_call( await hass.services.async_call(
NUMBER_DOMAIN, NUMBER_DOMAIN,
@ -66,9 +103,7 @@ async def test_number_snapshot(
snapshot: SnapshotAssertion, snapshot: SnapshotAssertion,
) -> None: ) -> None:
"""Test the multisensor snapshot.""" """Test the multisensor snapshot."""
mock_homee.nodes = [build_mock_node("numbers.json")]
mock_homee.get_node_by_id.return_value = mock_homee.nodes[0]
with patch("homeassistant.components.homee.PLATFORMS", [Platform.NUMBER]): with patch("homeassistant.components.homee.PLATFORMS", [Platform.NUMBER]):
await setup_integration(hass, mock_config_entry) await setup_numbers(hass, mock_homee, mock_config_entry)
await snapshot_platform(hass, entity_registry, snapshot, mock_config_entry.entry_id) await snapshot_platform(hass, entity_registry, snapshot, mock_config_entry.entry_id)