Add threshold sensor to Aranet (#137291)

* Add threshold level sensor description to Aranet component

* Use Color enum for status options

* Add threshold level sensor tests for Aranet components

* Rename `threshold_level` key to `status`

* Update test to expect 7 sensors instead of 6

* Map sensor status to more human-friendly strings

* Rename `threshold_level` key to `concentration_status`

* Update docstring for  function

* Simplify `get_friendly_status()`

* Rename `concentration_status` to `concentration_level`

* Rename `concentration_status` to `concentration_level` in sensor tests

* Refactor concentration level handling and tests

* Normalize concentration level status values to lowercase

* Add error to translations

* Don't scale status string

* Apply suggestions from code review

Co-authored-by: Shay Levy <levyshay1@gmail.com>

* Rename `concentration_level` to `threshold_indication`

* Update threshold indication translations

* `threshold_indication` → `threshold`

* Capitalize sensor name

Co-Authored-By: Shay Levy <levyshay1@gmail.com>

---------

Co-authored-by: Shay Levy <levyshay1@gmail.com>
pull/138790/head
Parker Brown 2025-02-18 11:16:50 -07:00 committed by GitHub
parent 096468baa4
commit 8dd1e9d101
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 39 additions and 5 deletions

View File

@ -5,7 +5,7 @@ from __future__ import annotations
from dataclasses import dataclass from dataclasses import dataclass
from typing import Any from typing import Any
from aranet4.client import Aranet4Advertisement from aranet4.client import Aranet4Advertisement, Color
from bleak.backends.device import BLEDevice from bleak.backends.device import BLEDevice
from homeassistant.components.bluetooth.passive_update_processor import ( from homeassistant.components.bluetooth.passive_update_processor import (
@ -74,6 +74,13 @@ SENSOR_DESCRIPTIONS = {
native_unit_of_measurement=UnitOfPressure.HPA, native_unit_of_measurement=UnitOfPressure.HPA,
state_class=SensorStateClass.MEASUREMENT, state_class=SensorStateClass.MEASUREMENT,
), ),
"status": AranetSensorEntityDescription(
key="threshold",
translation_key="threshold",
name="Threshold",
device_class=SensorDeviceClass.ENUM,
options=[status.name.lower() for status in Color],
),
"co2": AranetSensorEntityDescription( "co2": AranetSensorEntityDescription(
key="co2", key="co2",
name="Carbon Dioxide", name="Carbon Dioxide",
@ -161,7 +168,10 @@ def sensor_update_to_bluetooth_data_update(
val = getattr(adv.readings, key) val = getattr(adv.readings, key)
if val == -1: if val == -1:
continue continue
val *= desc.scale if key == "status":
val = val.name.lower()
else:
val *= desc.scale
data[tag] = val data[tag] = val
names[tag] = desc.name names[tag] = desc.name
descs[tag] = desc descs[tag] = desc

View File

@ -21,5 +21,17 @@
"no_devices_found": "No unconfigured Aranet devices found.", "no_devices_found": "No unconfigured Aranet devices found.",
"outdated_version": "This device is using outdated firmware. Please update it to at least v1.2.0 and try again." "outdated_version": "This device is using outdated firmware. Please update it to at least v1.2.0 and try again."
} }
},
"entity": {
"sensor": {
"threshold": {
"state": {
"error": "Error",
"green": "Green",
"yellow": "Yellow",
"red": "Red"
}
}
}
} }
} }

View File

@ -3,7 +3,7 @@
import pytest import pytest
from homeassistant.components.aranet.const import DOMAIN from homeassistant.components.aranet.const import DOMAIN
from homeassistant.components.sensor import ATTR_STATE_CLASS from homeassistant.components.sensor import ATTR_OPTIONS, ATTR_STATE_CLASS
from homeassistant.const import ATTR_FRIENDLY_NAME, ATTR_UNIT_OF_MEASUREMENT from homeassistant.const import ATTR_FRIENDLY_NAME, ATTR_UNIT_OF_MEASUREMENT
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers import device_registry as dr, entity_registry as er from homeassistant.helpers import device_registry as dr, entity_registry as er
@ -170,7 +170,7 @@ async def test_sensors_aranet4(
assert len(hass.states.async_all("sensor")) == 0 assert len(hass.states.async_all("sensor")) == 0
inject_bluetooth_service_info(hass, VALID_DATA_SERVICE_INFO) inject_bluetooth_service_info(hass, VALID_DATA_SERVICE_INFO)
await hass.async_block_till_done() await hass.async_block_till_done()
assert len(hass.states.async_all("sensor")) == 6 assert len(hass.states.async_all("sensor")) == 7
batt_sensor = hass.states.get("sensor.aranet4_12345_battery") batt_sensor = hass.states.get("sensor.aranet4_12345_battery")
batt_sensor_attrs = batt_sensor.attributes batt_sensor_attrs = batt_sensor.attributes
@ -214,6 +214,12 @@ async def test_sensors_aranet4(
assert interval_sensor_attrs[ATTR_UNIT_OF_MEASUREMENT] == "s" assert interval_sensor_attrs[ATTR_UNIT_OF_MEASUREMENT] == "s"
assert interval_sensor_attrs[ATTR_STATE_CLASS] == "measurement" assert interval_sensor_attrs[ATTR_STATE_CLASS] == "measurement"
status_sensor = hass.states.get("sensor.aranet4_12345_threshold")
status_sensor_attrs = status_sensor.attributes
assert status_sensor.state == "green"
assert status_sensor_attrs[ATTR_FRIENDLY_NAME] == "Aranet4 12345 Threshold"
assert status_sensor_attrs[ATTR_OPTIONS] == ["error", "green", "yellow", "red"]
# Check device context for the battery sensor # Check device context for the battery sensor
entity = entity_registry.async_get("sensor.aranet4_12345_battery") entity = entity_registry.async_get("sensor.aranet4_12345_battery")
device = device_registry.async_get(entity.device_id) device = device_registry.async_get(entity.device_id)
@ -245,7 +251,7 @@ async def test_sensors_aranetrn(
assert len(hass.states.async_all("sensor")) == 0 assert len(hass.states.async_all("sensor")) == 0
inject_bluetooth_service_info(hass, VALID_ARANET_RADON_DATA_SERVICE_INFO) inject_bluetooth_service_info(hass, VALID_ARANET_RADON_DATA_SERVICE_INFO)
await hass.async_block_till_done() await hass.async_block_till_done()
assert len(hass.states.async_all("sensor")) == 6 assert len(hass.states.async_all("sensor")) == 7
batt_sensor = hass.states.get("sensor.aranetrn_12345_battery") batt_sensor = hass.states.get("sensor.aranetrn_12345_battery")
batt_sensor_attrs = batt_sensor.attributes batt_sensor_attrs = batt_sensor.attributes
@ -291,6 +297,12 @@ async def test_sensors_aranetrn(
assert interval_sensor_attrs[ATTR_UNIT_OF_MEASUREMENT] == "s" assert interval_sensor_attrs[ATTR_UNIT_OF_MEASUREMENT] == "s"
assert interval_sensor_attrs[ATTR_STATE_CLASS] == "measurement" assert interval_sensor_attrs[ATTR_STATE_CLASS] == "measurement"
status_sensor = hass.states.get("sensor.aranetrn_12345_threshold")
status_sensor_attrs = status_sensor.attributes
assert status_sensor.state == "green"
assert status_sensor_attrs[ATTR_FRIENDLY_NAME] == "AranetRn+ 12345 Threshold"
assert status_sensor_attrs[ATTR_OPTIONS] == ["error", "green", "yellow", "red"]
# Check device context for the battery sensor # Check device context for the battery sensor
entity = entity_registry.async_get("sensor.aranetrn_12345_battery") entity = entity_registry.async_get("sensor.aranetrn_12345_battery")
device = device_registry.async_get(entity.device_id) device = device_registry.async_get(entity.device_id)