Add minimum and maximum targets (#151387)

This commit is contained in:
Joakim Plate
2025-08-29 17:42:28 +02:00
committed by GitHub
parent d72b35a0cd
commit 846e6d96a4
4 changed files with 612 additions and 25 deletions

View File

@@ -2,14 +2,16 @@
from __future__ import annotations from __future__ import annotations
from collections.abc import Callable, Mapping from collections.abc import Callable, Generator, Mapping
from dataclasses import dataclass from dataclasses import dataclass
from typing import Any from typing import Any
from togrill_bluetooth.packets import ( from togrill_bluetooth.packets import (
AlarmType,
PacketA0Notify, PacketA0Notify,
PacketA6Write, PacketA6Write,
PacketA8Notify, PacketA8Notify,
PacketA300Write,
PacketA301Write, PacketA301Write,
PacketWrite, PacketWrite,
) )
@@ -37,44 +39,94 @@ class ToGrillNumberEntityDescription(NumberEntityDescription):
"""Description of entity.""" """Description of entity."""
get_value: Callable[[ToGrillCoordinator], float | None] get_value: Callable[[ToGrillCoordinator], float | None]
set_packet: Callable[[float], PacketWrite] set_packet: Callable[[ToGrillCoordinator, float], PacketWrite]
entity_supported: Callable[[Mapping[str, Any]], bool] = lambda _: True entity_supported: Callable[[Mapping[str, Any]], bool] = lambda _: True
probe_number: int | None = None probe_number: int | None = None
def _get_temperature_target_description( def _get_temperature_descriptions(
probe_number: int, probe_number: int,
) -> ToGrillNumberEntityDescription: ) -> Generator[ToGrillNumberEntityDescription]:
def _set_packet(value: float | None) -> PacketWrite: def _get_description(
variant: str,
icon: str | None,
set_packet: Callable[[ToGrillCoordinator, float], PacketWrite],
get_value: Callable[[ToGrillCoordinator], float | None],
) -> ToGrillNumberEntityDescription:
return ToGrillNumberEntityDescription(
key=f"temperature_{variant}_{probe_number}",
translation_key=f"temperature_{variant}",
translation_placeholders={"probe_number": f"{probe_number}"},
device_class=NumberDeviceClass.TEMPERATURE,
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
native_min_value=0,
native_max_value=250,
mode=NumberMode.BOX,
set_packet=set_packet,
get_value=get_value,
entity_supported=lambda x: probe_number <= x[CONF_PROBE_COUNT],
probe_number=probe_number,
)
def _get_temperatures(
coordinator: ToGrillCoordinator, alarm_type: AlarmType
) -> tuple[None | float, None | float]:
if not (packet := coordinator.get_packet(PacketA8Notify, probe_number)):
return None, None
if packet.alarm_type != alarm_type:
return None, None
return packet.temperature_1, packet.temperature_2
def _set_target(
coordinator: ToGrillCoordinator, value: float | None
) -> PacketWrite:
if value == 0.0: if value == 0.0:
value = None value = None
return PacketA301Write(probe=probe_number, target=value) return PacketA301Write(probe=probe_number, target=value)
def _get_value(coordinator: ToGrillCoordinator) -> float | None: def _set_minimum(
if packet := coordinator.get_packet(PacketA8Notify, probe_number): coordinator: ToGrillCoordinator, value: float | None
if packet.alarm_type == PacketA8Notify.AlarmType.TEMPERATURE_TARGET: ) -> PacketWrite:
return packet.temperature_1 _, maximum = _get_temperatures(coordinator, AlarmType.TEMPERATURE_RANGE)
return None if value == 0.0:
value = None
return PacketA300Write(probe=probe_number, minimum=value, maximum=maximum)
return ToGrillNumberEntityDescription( def _set_maximum(
key=f"temperature_target_{probe_number}", coordinator: ToGrillCoordinator, value: float | None
translation_key="temperature_target", ) -> PacketWrite:
device_class=NumberDeviceClass.TEMPERATURE, minimum, _ = _get_temperatures(coordinator, AlarmType.TEMPERATURE_RANGE)
native_unit_of_measurement=UnitOfTemperature.CELSIUS, if value == 0.0:
native_min_value=0, value = None
native_max_value=250, return PacketA300Write(probe=probe_number, minimum=minimum, maximum=value)
mode=NumberMode.BOX,
set_packet=_set_packet, yield _get_description(
get_value=_get_value, "target",
entity_supported=lambda x: probe_number <= x[CONF_PROBE_COUNT], None,
probe_number=probe_number, _set_target,
lambda x: _get_temperatures(x, AlarmType.TEMPERATURE_TARGET)[0],
)
yield _get_description(
"minimum",
"mdi:thermometer-chevron-down",
_set_minimum,
lambda x: _get_temperatures(x, AlarmType.TEMPERATURE_RANGE)[0],
)
yield _get_description(
"maximum",
"mdi:thermometer-chevron-up",
_set_maximum,
lambda x: _get_temperatures(x, AlarmType.TEMPERATURE_RANGE)[1],
) )
ENTITY_DESCRIPTIONS = ( ENTITY_DESCRIPTIONS = (
*[ *[
_get_temperature_target_description(probe_number) description
for probe_number in range(1, MAX_PROBE_COUNT + 1) for probe_number in range(1, MAX_PROBE_COUNT + 1)
for description in _get_temperature_descriptions(probe_number)
], ],
ToGrillNumberEntityDescription( ToGrillNumberEntityDescription(
key="alarm_interval", key="alarm_interval",
@@ -85,7 +137,7 @@ ENTITY_DESCRIPTIONS = (
native_max_value=15, native_max_value=15,
native_step=5, native_step=5,
mode=NumberMode.BOX, mode=NumberMode.BOX,
set_packet=lambda x: ( set_packet=lambda coordinator, x: (
PacketA6Write(temperature_unit=None, alarm_interval=round(x)) PacketA6Write(temperature_unit=None, alarm_interval=round(x))
), ),
get_value=lambda x: ( get_value=lambda x: (
@@ -135,5 +187,5 @@ class ToGrillNumber(ToGrillEntity, NumberEntity):
async def async_set_native_value(self, value: float) -> None: async def async_set_native_value(self, value: float) -> None:
"""Set value on device.""" """Set value on device."""
packet = self.entity_description.set_packet(value) packet = self.entity_description.set_packet(self.coordinator, value)
await self._write_packet(packet) await self._write_packet(packet)

View File

@@ -43,6 +43,12 @@
"temperature_target": { "temperature_target": {
"name": "Target temperature" "name": "Target temperature"
}, },
"temperature_minimum": {
"name": "Minimum temperature"
},
"temperature_maximum": {
"name": "Maximum temperature"
},
"alarm_interval": { "alarm_interval": {
"name": "Alarm interval" "name": "Alarm interval"
} }

View File

@@ -58,6 +58,124 @@
'state': '0', 'state': '0',
}) })
# --- # ---
# name: test_setup[no_data][number.probe_1_maximum_temperature-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'max': 250,
'min': 0,
'mode': <NumberMode.BOX: 'box'>,
'step': 1.0,
}),
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'number',
'entity_category': None,
'entity_id': 'number.probe_1_maximum_temperature',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': <NumberDeviceClass.TEMPERATURE: 'temperature'>,
'original_icon': None,
'original_name': 'Maximum temperature',
'platform': 'togrill',
'previous_unique_id': None,
'suggested_object_id': None,
'supported_features': 0,
'translation_key': 'temperature_maximum',
'unique_id': '00000000-0000-0000-0000-000000000001_temperature_maximum_1',
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
})
# ---
# name: test_setup[no_data][number.probe_1_maximum_temperature-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'temperature',
'friendly_name': 'Probe 1 Maximum temperature',
'max': 250,
'min': 0,
'mode': <NumberMode.BOX: 'box'>,
'step': 1.0,
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
}),
'context': <ANY>,
'entity_id': 'number.probe_1_maximum_temperature',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'unknown',
})
# ---
# name: test_setup[no_data][number.probe_1_minimum_temperature-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'max': 250,
'min': 0,
'mode': <NumberMode.BOX: 'box'>,
'step': 1.0,
}),
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'number',
'entity_category': None,
'entity_id': 'number.probe_1_minimum_temperature',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': <NumberDeviceClass.TEMPERATURE: 'temperature'>,
'original_icon': None,
'original_name': 'Minimum temperature',
'platform': 'togrill',
'previous_unique_id': None,
'suggested_object_id': None,
'supported_features': 0,
'translation_key': 'temperature_minimum',
'unique_id': '00000000-0000-0000-0000-000000000001_temperature_minimum_1',
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
})
# ---
# name: test_setup[no_data][number.probe_1_minimum_temperature-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'temperature',
'friendly_name': 'Probe 1 Minimum temperature',
'max': 250,
'min': 0,
'mode': <NumberMode.BOX: 'box'>,
'step': 1.0,
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
}),
'context': <ANY>,
'entity_id': 'number.probe_1_minimum_temperature',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'unknown',
})
# ---
# name: test_setup[no_data][number.probe_1_target_temperature-entry] # name: test_setup[no_data][number.probe_1_target_temperature-entry]
EntityRegistryEntrySnapshot({ EntityRegistryEntrySnapshot({
'aliases': set({ 'aliases': set({
@@ -117,6 +235,124 @@
'state': 'unknown', 'state': 'unknown',
}) })
# --- # ---
# name: test_setup[no_data][number.probe_2_maximum_temperature-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'max': 250,
'min': 0,
'mode': <NumberMode.BOX: 'box'>,
'step': 1.0,
}),
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'number',
'entity_category': None,
'entity_id': 'number.probe_2_maximum_temperature',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': <NumberDeviceClass.TEMPERATURE: 'temperature'>,
'original_icon': None,
'original_name': 'Maximum temperature',
'platform': 'togrill',
'previous_unique_id': None,
'suggested_object_id': None,
'supported_features': 0,
'translation_key': 'temperature_maximum',
'unique_id': '00000000-0000-0000-0000-000000000001_temperature_maximum_2',
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
})
# ---
# name: test_setup[no_data][number.probe_2_maximum_temperature-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'temperature',
'friendly_name': 'Probe 2 Maximum temperature',
'max': 250,
'min': 0,
'mode': <NumberMode.BOX: 'box'>,
'step': 1.0,
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
}),
'context': <ANY>,
'entity_id': 'number.probe_2_maximum_temperature',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'unknown',
})
# ---
# name: test_setup[no_data][number.probe_2_minimum_temperature-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'max': 250,
'min': 0,
'mode': <NumberMode.BOX: 'box'>,
'step': 1.0,
}),
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'number',
'entity_category': None,
'entity_id': 'number.probe_2_minimum_temperature',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': <NumberDeviceClass.TEMPERATURE: 'temperature'>,
'original_icon': None,
'original_name': 'Minimum temperature',
'platform': 'togrill',
'previous_unique_id': None,
'suggested_object_id': None,
'supported_features': 0,
'translation_key': 'temperature_minimum',
'unique_id': '00000000-0000-0000-0000-000000000001_temperature_minimum_2',
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
})
# ---
# name: test_setup[no_data][number.probe_2_minimum_temperature-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'temperature',
'friendly_name': 'Probe 2 Minimum temperature',
'max': 250,
'min': 0,
'mode': <NumberMode.BOX: 'box'>,
'step': 1.0,
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
}),
'context': <ANY>,
'entity_id': 'number.probe_2_minimum_temperature',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'unknown',
})
# ---
# name: test_setup[no_data][number.probe_2_target_temperature-entry] # name: test_setup[no_data][number.probe_2_target_temperature-entry]
EntityRegistryEntrySnapshot({ EntityRegistryEntrySnapshot({
'aliases': set({ 'aliases': set({
@@ -235,6 +471,124 @@
'state': '5', 'state': '5',
}) })
# --- # ---
# name: test_setup[one_probe_with_target_alarm][number.probe_1_maximum_temperature-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'max': 250,
'min': 0,
'mode': <NumberMode.BOX: 'box'>,
'step': 1.0,
}),
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'number',
'entity_category': None,
'entity_id': 'number.probe_1_maximum_temperature',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': <NumberDeviceClass.TEMPERATURE: 'temperature'>,
'original_icon': None,
'original_name': 'Maximum temperature',
'platform': 'togrill',
'previous_unique_id': None,
'suggested_object_id': None,
'supported_features': 0,
'translation_key': 'temperature_maximum',
'unique_id': '00000000-0000-0000-0000-000000000001_temperature_maximum_1',
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
})
# ---
# name: test_setup[one_probe_with_target_alarm][number.probe_1_maximum_temperature-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'temperature',
'friendly_name': 'Probe 1 Maximum temperature',
'max': 250,
'min': 0,
'mode': <NumberMode.BOX: 'box'>,
'step': 1.0,
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
}),
'context': <ANY>,
'entity_id': 'number.probe_1_maximum_temperature',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'unknown',
})
# ---
# name: test_setup[one_probe_with_target_alarm][number.probe_1_minimum_temperature-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'max': 250,
'min': 0,
'mode': <NumberMode.BOX: 'box'>,
'step': 1.0,
}),
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'number',
'entity_category': None,
'entity_id': 'number.probe_1_minimum_temperature',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': <NumberDeviceClass.TEMPERATURE: 'temperature'>,
'original_icon': None,
'original_name': 'Minimum temperature',
'platform': 'togrill',
'previous_unique_id': None,
'suggested_object_id': None,
'supported_features': 0,
'translation_key': 'temperature_minimum',
'unique_id': '00000000-0000-0000-0000-000000000001_temperature_minimum_1',
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
})
# ---
# name: test_setup[one_probe_with_target_alarm][number.probe_1_minimum_temperature-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'temperature',
'friendly_name': 'Probe 1 Minimum temperature',
'max': 250,
'min': 0,
'mode': <NumberMode.BOX: 'box'>,
'step': 1.0,
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
}),
'context': <ANY>,
'entity_id': 'number.probe_1_minimum_temperature',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'unknown',
})
# ---
# name: test_setup[one_probe_with_target_alarm][number.probe_1_target_temperature-entry] # name: test_setup[one_probe_with_target_alarm][number.probe_1_target_temperature-entry]
EntityRegistryEntrySnapshot({ EntityRegistryEntrySnapshot({
'aliases': set({ 'aliases': set({
@@ -294,6 +648,124 @@
'state': '50.0', 'state': '50.0',
}) })
# --- # ---
# name: test_setup[one_probe_with_target_alarm][number.probe_2_maximum_temperature-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'max': 250,
'min': 0,
'mode': <NumberMode.BOX: 'box'>,
'step': 1.0,
}),
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'number',
'entity_category': None,
'entity_id': 'number.probe_2_maximum_temperature',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': <NumberDeviceClass.TEMPERATURE: 'temperature'>,
'original_icon': None,
'original_name': 'Maximum temperature',
'platform': 'togrill',
'previous_unique_id': None,
'suggested_object_id': None,
'supported_features': 0,
'translation_key': 'temperature_maximum',
'unique_id': '00000000-0000-0000-0000-000000000001_temperature_maximum_2',
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
})
# ---
# name: test_setup[one_probe_with_target_alarm][number.probe_2_maximum_temperature-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'temperature',
'friendly_name': 'Probe 2 Maximum temperature',
'max': 250,
'min': 0,
'mode': <NumberMode.BOX: 'box'>,
'step': 1.0,
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
}),
'context': <ANY>,
'entity_id': 'number.probe_2_maximum_temperature',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'unknown',
})
# ---
# name: test_setup[one_probe_with_target_alarm][number.probe_2_minimum_temperature-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'max': 250,
'min': 0,
'mode': <NumberMode.BOX: 'box'>,
'step': 1.0,
}),
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'number',
'entity_category': None,
'entity_id': 'number.probe_2_minimum_temperature',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': <NumberDeviceClass.TEMPERATURE: 'temperature'>,
'original_icon': None,
'original_name': 'Minimum temperature',
'platform': 'togrill',
'previous_unique_id': None,
'suggested_object_id': None,
'supported_features': 0,
'translation_key': 'temperature_minimum',
'unique_id': '00000000-0000-0000-0000-000000000001_temperature_minimum_2',
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
})
# ---
# name: test_setup[one_probe_with_target_alarm][number.probe_2_minimum_temperature-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'temperature',
'friendly_name': 'Probe 2 Minimum temperature',
'max': 250,
'min': 0,
'mode': <NumberMode.BOX: 'box'>,
'step': 1.0,
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
}),
'context': <ANY>,
'entity_id': 'number.probe_2_minimum_temperature',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'unknown',
})
# ---
# name: test_setup[one_probe_with_target_alarm][number.probe_2_target_temperature-entry] # name: test_setup[one_probe_with_target_alarm][number.probe_2_target_temperature-entry]
EntityRegistryEntrySnapshot({ EntityRegistryEntrySnapshot({
'aliases': set({ 'aliases': set({

View File

@@ -10,6 +10,7 @@ from togrill_bluetooth.packets import (
PacketA0Notify, PacketA0Notify,
PacketA6Write, PacketA6Write,
PacketA8Notify, PacketA8Notify,
PacketA300Write,
PacketA301Write, PacketA301Write,
) )
@@ -105,6 +106,62 @@ async def test_setup(
PacketA301Write(probe=1, target=None), PacketA301Write(probe=1, target=None),
id="probe_clear", id="probe_clear",
), ),
pytest.param(
[
PacketA8Notify(
probe=1,
alarm_type=PacketA8Notify.AlarmType.TEMPERATURE_RANGE,
temperature_1=50.0,
temperature_2=80.0,
),
],
"number.probe_1_minimum_temperature",
100.0,
PacketA300Write(probe=1, minimum=100.0, maximum=80.0),
id="minimum",
),
pytest.param(
[
PacketA8Notify(
probe=1,
alarm_type=PacketA8Notify.AlarmType.TEMPERATURE_RANGE,
temperature_1=None,
temperature_2=80.0,
),
],
"number.probe_1_minimum_temperature",
0.0,
PacketA300Write(probe=1, minimum=None, maximum=80.0),
id="minimum_clear",
),
pytest.param(
[
PacketA8Notify(
probe=1,
alarm_type=PacketA8Notify.AlarmType.TEMPERATURE_RANGE,
temperature_1=50.0,
temperature_2=80.0,
),
],
"number.probe_1_maximum_temperature",
100.0,
PacketA300Write(probe=1, minimum=50.0, maximum=100.0),
id="maximum",
),
pytest.param(
[
PacketA8Notify(
probe=1,
alarm_type=PacketA8Notify.AlarmType.TEMPERATURE_RANGE,
temperature_1=50.0,
temperature_2=None,
),
],
"number.probe_1_maximum_temperature",
0.0,
PacketA300Write(probe=1, minimum=50.0, maximum=None),
id="maximum_clear",
),
pytest.param( pytest.param(
[ [
PacketA0Notify( PacketA0Notify(