Allow None device_class and UOM for mqtt entities (#91240)
* Allow None device_class and UOM for mqtt entities * Rever not needed changes * Revert another unwanted change
This commit is contained in:
parent
325733158d
commit
e36fd5f222
10 changed files with 190 additions and 76 deletions
|
@ -125,7 +125,7 @@ _PLATFORM_SCHEMA_BASE = MQTT_RW_SCHEMA.extend(
|
|||
vol.Optional(
|
||||
CONF_DEVICE_CLASS, default=HumidifierDeviceClass.HUMIDIFIER
|
||||
): vol.In(
|
||||
[HumidifierDeviceClass.HUMIDIFIER, HumidifierDeviceClass.DEHUMIDIFIER]
|
||||
[HumidifierDeviceClass.HUMIDIFIER, HumidifierDeviceClass.DEHUMIDIFIER, None]
|
||||
),
|
||||
vol.Optional(CONF_MODE_COMMAND_TEMPLATE): cv.template,
|
||||
vol.Optional(CONF_MODE_STATE_TOPIC): valid_subscribe_topic,
|
||||
|
|
|
@ -97,7 +97,7 @@ _PLATFORM_SCHEMA_BASE = MQTT_RW_SCHEMA.extend(
|
|||
vol.Optional(CONF_STEP, default=DEFAULT_STEP): vol.All(
|
||||
vol.Coerce(float), vol.Range(min=1e-3)
|
||||
),
|
||||
vol.Optional(CONF_UNIT_OF_MEASUREMENT): cv.string,
|
||||
vol.Optional(CONF_UNIT_OF_MEASUREMENT): vol.Any(cv.string, None),
|
||||
vol.Optional(CONF_VALUE_TEMPLATE): cv.template,
|
||||
},
|
||||
).extend(MQTT_ENTITY_COMMON_SCHEMA.schema)
|
||||
|
|
|
@ -107,7 +107,7 @@ _PLATFORM_SCHEMA_BASE = MQTT_RO_SCHEMA.extend(
|
|||
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
|
||||
vol.Optional(CONF_SUGGESTED_DISPLAY_PRECISION): cv.positive_int,
|
||||
vol.Optional(CONF_STATE_CLASS): vol.Any(STATE_CLASSES_SCHEMA, None),
|
||||
vol.Optional(CONF_UNIT_OF_MEASUREMENT): cv.string,
|
||||
vol.Optional(CONF_UNIT_OF_MEASUREMENT): vol.Any(cv.string, None),
|
||||
}
|
||||
).extend(MQTT_ENTITY_COMMON_SCHEMA.schema)
|
||||
|
||||
|
|
|
@ -505,27 +505,44 @@ async def test_setting_sensor_value_via_mqtt_message_empty_template(
|
|||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"hass_config",
|
||||
("hass_config", "device_class"),
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
binary_sensor.DOMAIN: {
|
||||
"name": "test",
|
||||
"device_class": "motion",
|
||||
"state_topic": "test-topic",
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
binary_sensor.DOMAIN: {
|
||||
"name": "test",
|
||||
"device_class": "motion",
|
||||
"state_topic": "test-topic",
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"motion",
|
||||
),
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
binary_sensor.DOMAIN: {
|
||||
"name": "test",
|
||||
"device_class": None,
|
||||
"state_topic": "test-topic",
|
||||
}
|
||||
}
|
||||
},
|
||||
None,
|
||||
),
|
||||
],
|
||||
)
|
||||
async def test_valid_device_class(
|
||||
hass: HomeAssistant, mqtt_mock_entry: MqttMockHAClientGenerator
|
||||
hass: HomeAssistant,
|
||||
mqtt_mock_entry: MqttMockHAClientGenerator,
|
||||
device_class: str | None,
|
||||
) -> None:
|
||||
"""Test the setting of a valid sensor class."""
|
||||
"""Test the setting of a valid sensor class and ignoring an empty device_class."""
|
||||
await mqtt_mock_entry()
|
||||
|
||||
state = hass.states.get("binary_sensor.test")
|
||||
assert state.attributes.get("device_class") == "motion"
|
||||
assert state.attributes.get("device_class") == device_class
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
|
|
|
@ -477,6 +477,11 @@ async def test_invalid_device_class(
|
|||
"name": "Test 3",
|
||||
"command_topic": "test-topic",
|
||||
},
|
||||
{
|
||||
"name": "Test 4",
|
||||
"command_topic": "test-topic",
|
||||
"device_class": None,
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -867,6 +867,19 @@ async def test_attributes(
|
|||
},
|
||||
True,
|
||||
),
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
humidifier.DOMAIN: {
|
||||
"name": "test_valid_4",
|
||||
"command_topic": "command-topic",
|
||||
"target_humidity_command_topic": "humidity-command-topic",
|
||||
"device_class": None,
|
||||
}
|
||||
}
|
||||
},
|
||||
True,
|
||||
),
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
|
|
|
@ -18,7 +18,6 @@ from homeassistant.components.number import (
|
|||
ATTR_VALUE,
|
||||
DOMAIN as NUMBER_DOMAIN,
|
||||
SERVICE_SET_VALUE,
|
||||
NumberDeviceClass,
|
||||
)
|
||||
from homeassistant.const import (
|
||||
ATTR_ASSUMED_STATE,
|
||||
|
@ -76,45 +75,80 @@ def number_platform_only():
|
|||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"hass_config",
|
||||
("hass_config", "device_class", "unit_of_measurement", "values"),
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
number.DOMAIN: {
|
||||
"state_topic": "test/state_number",
|
||||
"command_topic": "test/cmd_number",
|
||||
"name": "Test Number",
|
||||
"device_class": "temperature",
|
||||
"unit_of_measurement": UnitOfTemperature.FAHRENHEIT.value,
|
||||
"payload_reset": "reset!",
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
number.DOMAIN: {
|
||||
"state_topic": "test/state_number",
|
||||
"command_topic": "test/cmd_number",
|
||||
"name": "Test Number",
|
||||
"device_class": "temperature",
|
||||
"unit_of_measurement": UnitOfTemperature.FAHRENHEIT.value,
|
||||
"payload_reset": "reset!",
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"temperature",
|
||||
UnitOfTemperature.CELSIUS.value,
|
||||
[("10", "-12.0"), ("20.5", "-6.4")], # 10 °F -> -12 °C
|
||||
),
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
number.DOMAIN: {
|
||||
"state_topic": "test/state_number",
|
||||
"command_topic": "test/cmd_number",
|
||||
"name": "Test Number",
|
||||
"device_class": "temperature",
|
||||
"unit_of_measurement": UnitOfTemperature.CELSIUS.value,
|
||||
"payload_reset": "reset!",
|
||||
}
|
||||
}
|
||||
},
|
||||
"temperature",
|
||||
UnitOfTemperature.CELSIUS.value,
|
||||
[("10", "10"), ("15", "15")],
|
||||
),
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
number.DOMAIN: {
|
||||
"state_topic": "test/state_number",
|
||||
"command_topic": "test/cmd_number",
|
||||
"name": "Test Number",
|
||||
"device_class": None,
|
||||
"unit_of_measurement": None,
|
||||
"payload_reset": "reset!",
|
||||
}
|
||||
}
|
||||
},
|
||||
None,
|
||||
None,
|
||||
[("10", "10"), ("20", "20")],
|
||||
),
|
||||
],
|
||||
)
|
||||
async def test_run_number_setup(
|
||||
hass: HomeAssistant, mqtt_mock_entry: MqttMockHAClientGenerator
|
||||
hass: HomeAssistant,
|
||||
mqtt_mock_entry: MqttMockHAClientGenerator,
|
||||
device_class: str | None,
|
||||
unit_of_measurement: UnitOfTemperature | None,
|
||||
values: list[tuple[str, str]],
|
||||
) -> None:
|
||||
"""Test that it fetches the given payload."""
|
||||
await mqtt_mock_entry()
|
||||
|
||||
async_fire_mqtt_message(hass, "test/state_number", "10")
|
||||
for payload, value in values:
|
||||
async_fire_mqtt_message(hass, "test/state_number", payload)
|
||||
|
||||
await hass.async_block_till_done()
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("number.test_number")
|
||||
assert state.state == "-12.0" # 10 °F -> -12 °C
|
||||
assert state.attributes.get(ATTR_DEVICE_CLASS) == NumberDeviceClass.TEMPERATURE
|
||||
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == "°C"
|
||||
|
||||
async_fire_mqtt_message(hass, "test/state_number", "20.5")
|
||||
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get("number.test_number")
|
||||
assert state.state == "-6.4" # 20.5 °F -> -6.4 °C
|
||||
assert state.attributes.get(ATTR_DEVICE_CLASS) == NumberDeviceClass.TEMPERATURE
|
||||
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == "°C"
|
||||
state = hass.states.get("number.test_number")
|
||||
assert state.state == value
|
||||
assert state.attributes.get(ATTR_DEVICE_CLASS) == device_class
|
||||
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == unit_of_measurement
|
||||
|
||||
async_fire_mqtt_message(hass, "test/state_number", "reset!")
|
||||
|
||||
|
@ -122,8 +156,8 @@ async def test_run_number_setup(
|
|||
|
||||
state = hass.states.get("number.test_number")
|
||||
assert state.state == "unknown"
|
||||
assert state.attributes.get(ATTR_DEVICE_CLASS) == NumberDeviceClass.TEMPERATURE
|
||||
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == "°C"
|
||||
assert state.attributes.get(ATTR_DEVICE_CLASS) == device_class
|
||||
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == unit_of_measurement
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
|
|
|
@ -851,16 +851,17 @@ async def test_invalid_device_class(
|
|||
"name": "Test 3",
|
||||
"state_topic": "test-topic",
|
||||
"device_class": None,
|
||||
"unit_of_measurement": None,
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
)
|
||||
async def test_valid_device_class(
|
||||
async def test_valid_device_class_and_uom(
|
||||
hass: HomeAssistant, mqtt_mock_entry: MqttMockHAClientGenerator
|
||||
) -> None:
|
||||
"""Test device_class option with valid values."""
|
||||
"""Test device_class option with valid values and test with an empty unit of measurement."""
|
||||
await mqtt_mock_entry()
|
||||
|
||||
state = hass.states.get("sensor.test_1")
|
||||
|
|
|
@ -62,31 +62,51 @@ def switch_platform_only():
|
|||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"hass_config",
|
||||
("hass_config", "device_class"),
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
switch.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
"command_topic": "command-topic",
|
||||
"payload_on": 1,
|
||||
"payload_off": 0,
|
||||
"device_class": "switch",
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
switch.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
"command_topic": "command-topic",
|
||||
"payload_on": 1,
|
||||
"payload_off": 0,
|
||||
"device_class": "switch",
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"switch",
|
||||
),
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
switch.DOMAIN: {
|
||||
"name": "test",
|
||||
"state_topic": "state-topic",
|
||||
"command_topic": "command-topic",
|
||||
"payload_on": 1,
|
||||
"payload_off": 0,
|
||||
"device_class": None,
|
||||
}
|
||||
}
|
||||
},
|
||||
None,
|
||||
),
|
||||
],
|
||||
)
|
||||
async def test_controlling_state_via_topic(
|
||||
hass: HomeAssistant, mqtt_mock_entry: MqttMockHAClientGenerator
|
||||
hass: HomeAssistant,
|
||||
mqtt_mock_entry: MqttMockHAClientGenerator,
|
||||
device_class: str | None,
|
||||
) -> None:
|
||||
"""Test the controlling state via topic."""
|
||||
await mqtt_mock_entry()
|
||||
|
||||
state = hass.states.get("switch.test")
|
||||
assert state.state == STATE_UNKNOWN
|
||||
assert state.attributes.get(ATTR_DEVICE_CLASS) == "switch"
|
||||
assert state.attributes.get(ATTR_DEVICE_CLASS) == device_class
|
||||
assert not state.attributes.get(ATTR_ASSUMED_STATE)
|
||||
|
||||
async_fire_mqtt_message(hass, "state-topic", "1")
|
||||
|
|
|
@ -63,25 +63,48 @@ def update_platform_only():
|
|||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"hass_config",
|
||||
("hass_config", "device_class"),
|
||||
[
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
update.DOMAIN: {
|
||||
"state_topic": "test/installed-version",
|
||||
"latest_version_topic": "test/latest-version",
|
||||
"name": "Test Update",
|
||||
"release_summary": "Test release summary",
|
||||
"release_url": "https://example.com/release",
|
||||
"title": "Test Update Title",
|
||||
"entity_picture": "https://example.com/icon.png",
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
update.DOMAIN: {
|
||||
"state_topic": "test/installed-version",
|
||||
"latest_version_topic": "test/latest-version",
|
||||
"name": "Test Update",
|
||||
"release_summary": "Test release summary",
|
||||
"release_url": "https://example.com/release",
|
||||
"title": "Test Update Title",
|
||||
"entity_picture": "https://example.com/icon.png",
|
||||
"device_class": "firmware",
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"firmware",
|
||||
),
|
||||
(
|
||||
{
|
||||
mqtt.DOMAIN: {
|
||||
update.DOMAIN: {
|
||||
"state_topic": "test/installed-version",
|
||||
"latest_version_topic": "test/latest-version",
|
||||
"name": "Test Update",
|
||||
"release_summary": "Test release summary",
|
||||
"release_url": "https://example.com/release",
|
||||
"title": "Test Update Title",
|
||||
"entity_picture": "https://example.com/icon.png",
|
||||
"device_class": None,
|
||||
}
|
||||
}
|
||||
},
|
||||
None,
|
||||
),
|
||||
],
|
||||
)
|
||||
async def test_run_update_setup(
|
||||
hass: HomeAssistant, mqtt_mock_entry: MqttMockHAClientGenerator
|
||||
hass: HomeAssistant,
|
||||
mqtt_mock_entry: MqttMockHAClientGenerator,
|
||||
device_class: str | None,
|
||||
) -> None:
|
||||
"""Test that it fetches the given payload."""
|
||||
installed_version_topic = "test/installed-version"
|
||||
|
@ -101,6 +124,7 @@ async def test_run_update_setup(
|
|||
assert state.attributes.get("release_url") == "https://example.com/release"
|
||||
assert state.attributes.get("title") == "Test Update Title"
|
||||
assert state.attributes.get("entity_picture") == "https://example.com/icon.png"
|
||||
assert state.attributes.get("device_class") == device_class
|
||||
|
||||
async_fire_mqtt_message(hass, latest_version_topic, "2.0.0")
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue