Add blood glucose concentration device class (#129340)

pull/130209/head
epenet 2024-11-09 11:29:24 +01:00 committed by GitHub
parent 0304588bb8
commit 25fb70f281
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 100 additions and 3 deletions

View File

@ -9,9 +9,9 @@ from typing import Any
from aiohttp import ClientError
from py_nightscout import Api as NightscoutAPI
from homeassistant.components.sensor import SensorEntity
from homeassistant.components.sensor import SensorDeviceClass, SensorEntity
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import ATTR_DATE
from homeassistant.const import ATTR_DATE, UnitOfBloodGlucoseConcentration
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
@ -37,7 +37,10 @@ async def async_setup_entry(
class NightscoutSensor(SensorEntity):
"""Implementation of a Nightscout sensor."""
_attr_native_unit_of_measurement = "mg/dL"
_attr_device_class = SensorDeviceClass.BLOOD_GLUCOSE_CONCENTRATION
_attr_native_unit_of_measurement = (
UnitOfBloodGlucoseConcentration.MILLIGRAMS_PER_DECILITER
)
_attr_icon = "mdi:cloud-question"
def __init__(self, api: NightscoutAPI, name: str, unique_id: str | None) -> None:

View File

@ -17,6 +17,7 @@ from homeassistant.const import (
SIGNAL_STRENGTH_DECIBELS,
SIGNAL_STRENGTH_DECIBELS_MILLIWATT,
UnitOfApparentPower,
UnitOfBloodGlucoseConcentration,
UnitOfConductivity,
UnitOfDataRate,
UnitOfElectricCurrent,
@ -109,6 +110,12 @@ class NumberDeviceClass(StrEnum):
Unit of measurement: `%`
"""
BLOOD_GLUCOSE_CONCENTRATION = "blood_glucose_concentration"
"""Blood glucose concentration.
Unit of measurement: `mg/dL`, `mmol/L`
"""
CO = "carbon_monoxide"
"""Carbon Monoxide gas concentration.
@ -429,6 +436,7 @@ DEVICE_CLASS_UNITS: dict[NumberDeviceClass, set[type[StrEnum] | str | None]] = {
NumberDeviceClass.AQI: {None},
NumberDeviceClass.ATMOSPHERIC_PRESSURE: set(UnitOfPressure),
NumberDeviceClass.BATTERY: {PERCENTAGE},
NumberDeviceClass.BLOOD_GLUCOSE_CONCENTRATION: set(UnitOfBloodGlucoseConcentration),
NumberDeviceClass.CO: {CONCENTRATION_PARTS_PER_MILLION},
NumberDeviceClass.CO2: {CONCENTRATION_PARTS_PER_MILLION},
NumberDeviceClass.CONDUCTIVITY: set(UnitOfConductivity),

View File

@ -15,6 +15,9 @@
"battery": {
"default": "mdi:battery"
},
"blood_glucose_concentration": {
"default": "mdi:spoon-sugar"
},
"carbon_dioxide": {
"default": "mdi:molecule-co2"
},

View File

@ -43,6 +43,9 @@
"battery": {
"name": "[%key:component::sensor::entity_component::battery::name%]"
},
"blood_glucose_concentration": {
"name": "[%key:component::sensor::entity_component::blood_glucose_concentration::name%]"
},
"carbon_dioxide": {
"name": "[%key:component::sensor::entity_component::carbon_dioxide::name%]"
},

View File

@ -28,6 +28,7 @@ from homeassistant.helpers.typing import UNDEFINED, UndefinedType
from homeassistant.util import dt as dt_util
from homeassistant.util.unit_conversion import (
BaseUnitConverter,
BloodGlugoseConcentrationConverter,
ConductivityConverter,
DataRateConverter,
DistanceConverter,
@ -128,6 +129,11 @@ QUERY_STATISTICS_SUMMARY_SUM = (
STATISTIC_UNIT_TO_UNIT_CONVERTER: dict[str | None, type[BaseUnitConverter]] = {
**{
unit: BloodGlugoseConcentrationConverter
for unit in BloodGlugoseConcentrationConverter.VALID_UNITS
},
**{unit: ConductivityConverter for unit in ConductivityConverter.VALID_UNITS},
**{unit: ConductivityConverter for unit in ConductivityConverter.VALID_UNITS},
**{unit: DataRateConverter for unit in DataRateConverter.VALID_UNITS},
**{unit: DistanceConverter for unit in DistanceConverter.VALID_UNITS},

View File

@ -16,6 +16,7 @@ from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.json import json_bytes
from homeassistant.util import dt as dt_util
from homeassistant.util.unit_conversion import (
BloodGlugoseConcentrationConverter,
ConductivityConverter,
DataRateConverter,
DistanceConverter,
@ -54,6 +55,9 @@ UPDATE_STATISTICS_METADATA_TIME_OUT = 10
UNIT_SCHEMA = vol.Schema(
{
vol.Optional("blood_glucose_concentration"): vol.In(
BloodGlugoseConcentrationConverter.VALID_UNITS
),
vol.Optional("conductivity"): vol.In(ConductivityConverter.VALID_UNITS),
vol.Optional("data_rate"): vol.In(DataRateConverter.VALID_UNITS),
vol.Optional("distance"): vol.In(DistanceConverter.VALID_UNITS),

View File

@ -17,6 +17,7 @@ from homeassistant.const import (
SIGNAL_STRENGTH_DECIBELS,
SIGNAL_STRENGTH_DECIBELS_MILLIWATT,
UnitOfApparentPower,
UnitOfBloodGlucoseConcentration,
UnitOfConductivity,
UnitOfDataRate,
UnitOfElectricCurrent,
@ -47,6 +48,7 @@ from homeassistant.helpers.deprecation import (
)
from homeassistant.util.unit_conversion import (
BaseUnitConverter,
BloodGlugoseConcentrationConverter,
ConductivityConverter,
DataRateConverter,
DistanceConverter,
@ -127,6 +129,12 @@ class SensorDeviceClass(StrEnum):
Unit of measurement: `%`
"""
BLOOD_GLUCOSE_CONCENTRATION = "blood_glucose_concentration"
"""Blood glucose concentration.
Unit of measurement: `mg/dL`, `mmol/L`
"""
CO = "carbon_monoxide"
"""Carbon Monoxide gas concentration.
@ -493,6 +501,7 @@ STATE_CLASSES: Final[list[str]] = [cls.value for cls in SensorStateClass]
UNIT_CONVERTERS: dict[SensorDeviceClass | str | None, type[BaseUnitConverter]] = {
SensorDeviceClass.ATMOSPHERIC_PRESSURE: PressureConverter,
SensorDeviceClass.BLOOD_GLUCOSE_CONCENTRATION: BloodGlugoseConcentrationConverter,
SensorDeviceClass.CONDUCTIVITY: ConductivityConverter,
SensorDeviceClass.CURRENT: ElectricCurrentConverter,
SensorDeviceClass.DATA_RATE: DataRateConverter,
@ -524,6 +533,7 @@ DEVICE_CLASS_UNITS: dict[SensorDeviceClass, set[type[StrEnum] | str | None]] = {
SensorDeviceClass.AQI: {None},
SensorDeviceClass.ATMOSPHERIC_PRESSURE: set(UnitOfPressure),
SensorDeviceClass.BATTERY: {PERCENTAGE},
SensorDeviceClass.BLOOD_GLUCOSE_CONCENTRATION: set(UnitOfBloodGlucoseConcentration),
SensorDeviceClass.CO: {CONCENTRATION_PARTS_PER_MILLION},
SensorDeviceClass.CO2: {CONCENTRATION_PARTS_PER_MILLION},
SensorDeviceClass.CONDUCTIVITY: set(UnitOfConductivity),
@ -599,6 +609,7 @@ DEVICE_CLASS_STATE_CLASSES: dict[SensorDeviceClass, set[SensorStateClass]] = {
SensorDeviceClass.AQI: {SensorStateClass.MEASUREMENT},
SensorDeviceClass.ATMOSPHERIC_PRESSURE: {SensorStateClass.MEASUREMENT},
SensorDeviceClass.BATTERY: {SensorStateClass.MEASUREMENT},
SensorDeviceClass.BLOOD_GLUCOSE_CONCENTRATION: {SensorStateClass.MEASUREMENT},
SensorDeviceClass.CO: {SensorStateClass.MEASUREMENT},
SensorDeviceClass.CO2: {SensorStateClass.MEASUREMENT},
SensorDeviceClass.CONDUCTIVITY: {SensorStateClass.MEASUREMENT},

View File

@ -37,6 +37,7 @@ CONF_IS_APPARENT_POWER = "is_apparent_power"
CONF_IS_AQI = "is_aqi"
CONF_IS_ATMOSPHERIC_PRESSURE = "is_atmospheric_pressure"
CONF_IS_BATTERY_LEVEL = "is_battery_level"
CONF_IS_BLOOD_GLUCOSE_CONCENTRATION = "is_blood_glucose_concentration"
CONF_IS_CO = "is_carbon_monoxide"
CONF_IS_CO2 = "is_carbon_dioxide"
CONF_IS_CONDUCTIVITY = "is_conductivity"
@ -87,6 +88,9 @@ ENTITY_CONDITIONS = {
SensorDeviceClass.AQI: [{CONF_TYPE: CONF_IS_AQI}],
SensorDeviceClass.ATMOSPHERIC_PRESSURE: [{CONF_TYPE: CONF_IS_ATMOSPHERIC_PRESSURE}],
SensorDeviceClass.BATTERY: [{CONF_TYPE: CONF_IS_BATTERY_LEVEL}],
SensorDeviceClass.BLOOD_GLUCOSE_CONCENTRATION: [
{CONF_TYPE: CONF_IS_BLOOD_GLUCOSE_CONCENTRATION}
],
SensorDeviceClass.CO: [{CONF_TYPE: CONF_IS_CO}],
SensorDeviceClass.CO2: [{CONF_TYPE: CONF_IS_CO2}],
SensorDeviceClass.CONDUCTIVITY: [{CONF_TYPE: CONF_IS_CONDUCTIVITY}],
@ -151,6 +155,7 @@ CONDITION_SCHEMA = vol.All(
CONF_IS_AQI,
CONF_IS_ATMOSPHERIC_PRESSURE,
CONF_IS_BATTERY_LEVEL,
CONF_IS_BLOOD_GLUCOSE_CONCENTRATION,
CONF_IS_CO,
CONF_IS_CO2,
CONF_IS_CONDUCTIVITY,

View File

@ -36,6 +36,7 @@ CONF_APPARENT_POWER = "apparent_power"
CONF_AQI = "aqi"
CONF_ATMOSPHERIC_PRESSURE = "atmospheric_pressure"
CONF_BATTERY_LEVEL = "battery_level"
CONF_BLOOD_GLUCOSE_CONCENTRATION = "blood_glucose_concentration"
CONF_CO = "carbon_monoxide"
CONF_CO2 = "carbon_dioxide"
CONF_CONDUCTIVITY = "conductivity"
@ -86,6 +87,9 @@ ENTITY_TRIGGERS = {
SensorDeviceClass.AQI: [{CONF_TYPE: CONF_AQI}],
SensorDeviceClass.ATMOSPHERIC_PRESSURE: [{CONF_TYPE: CONF_ATMOSPHERIC_PRESSURE}],
SensorDeviceClass.BATTERY: [{CONF_TYPE: CONF_BATTERY_LEVEL}],
SensorDeviceClass.BLOOD_GLUCOSE_CONCENTRATION: [
{CONF_TYPE: CONF_BLOOD_GLUCOSE_CONCENTRATION}
],
SensorDeviceClass.CO: [{CONF_TYPE: CONF_CO}],
SensorDeviceClass.CO2: [{CONF_TYPE: CONF_CO2}],
SensorDeviceClass.CONDUCTIVITY: [{CONF_TYPE: CONF_CONDUCTIVITY}],
@ -151,6 +155,7 @@ TRIGGER_SCHEMA = vol.All(
CONF_AQI,
CONF_ATMOSPHERIC_PRESSURE,
CONF_BATTERY_LEVEL,
CONF_BLOOD_GLUCOSE_CONCENTRATION,
CONF_CO,
CONF_CO2,
CONF_CONDUCTIVITY,

View File

@ -12,6 +12,9 @@
"atmospheric_pressure": {
"default": "mdi:thermometer-lines"
},
"blood_glucose_concentration": {
"default": "mdi:spoon-sugar"
},
"carbon_dioxide": {
"default": "mdi:molecule-co2"
},

View File

@ -6,6 +6,7 @@
"is_aqi": "Current {entity_name} air quality index",
"is_atmospheric_pressure": "Current {entity_name} atmospheric pressure",
"is_battery_level": "Current {entity_name} battery level",
"is_blood_glucose_concentration": "Current {entity_name} blood glucose concentration",
"is_carbon_monoxide": "Current {entity_name} carbon monoxide concentration level",
"is_carbon_dioxide": "Current {entity_name} carbon dioxide concentration level",
"is_conductivity": "Current {entity_name} conductivity",
@ -56,6 +57,7 @@
"aqi": "{entity_name} air quality index changes",
"atmospheric_pressure": "{entity_name} atmospheric pressure changes",
"battery_level": "{entity_name} battery level changes",
"blood_glucose_concentration": "{entity_name} blood glucose concentration changes",
"carbon_monoxide": "{entity_name} carbon monoxide concentration changes",
"carbon_dioxide": "{entity_name} carbon dioxide concentration changes",
"conductivity": "{entity_name} conductivity changes",
@ -149,6 +151,9 @@
"battery": {
"name": "Battery"
},
"blood_glucose_concentration": {
"name": "Blood glucose concentration"
},
"carbon_monoxide": {
"name": "Carbon monoxide"
},

View File

@ -1358,6 +1358,13 @@ CONCENTRATION_PARTS_PER_MILLION: Final = "ppm"
CONCENTRATION_PARTS_PER_BILLION: Final = "ppb"
class UnitOfBloodGlucoseConcentration(StrEnum):
"""Blood glucose concentration units."""
MILLIGRAMS_PER_DECILITER = "mg/dL"
MILLIMOLE_PER_LITER = "mmol/L"
# Speed units
class UnitOfSpeed(StrEnum):
"""Speed units."""

View File

@ -10,6 +10,7 @@ from homeassistant.const import (
CONCENTRATION_PARTS_PER_MILLION,
PERCENTAGE,
UNIT_NOT_RECOGNIZED_TEMPLATE,
UnitOfBloodGlucoseConcentration,
UnitOfConductivity,
UnitOfDataRate,
UnitOfElectricCurrent,
@ -173,6 +174,17 @@ class DistanceConverter(BaseUnitConverter):
}
class BloodGlugoseConcentrationConverter(BaseUnitConverter):
"""Utility to convert blood glucose concentration values."""
UNIT_CLASS = "blood_glucose_concentration"
_UNIT_CONVERSION: dict[str | None, float] = {
UnitOfBloodGlucoseConcentration.MILLIGRAMS_PER_DECILITER: 18,
UnitOfBloodGlucoseConcentration.MILLIMOLE_PER_LITER: 1,
}
VALID_UNITS = set(UnitOfBloodGlucoseConcentration)
class ConductivityConverter(BaseUnitConverter):
"""Utility to convert electric current values."""

View File

@ -11,6 +11,7 @@ from homeassistant.const import (
CONCENTRATION_PARTS_PER_BILLION,
CONCENTRATION_PARTS_PER_MILLION,
PERCENTAGE,
UnitOfBloodGlucoseConcentration,
UnitOfConductivity,
UnitOfDataRate,
UnitOfElectricCurrent,
@ -32,6 +33,7 @@ from homeassistant.exceptions import HomeAssistantError
from homeassistant.util import unit_conversion
from homeassistant.util.unit_conversion import (
BaseUnitConverter,
BloodGlugoseConcentrationConverter,
ConductivityConverter,
DataRateConverter,
DistanceConverter,
@ -59,6 +61,7 @@ INVALID_SYMBOL = "bob"
_ALL_CONVERTERS: dict[type[BaseUnitConverter], list[str | None]] = {
converter: sorted(converter.VALID_UNITS, key=lambda x: (x is None, x))
for converter in (
BloodGlugoseConcentrationConverter,
ConductivityConverter,
DataRateConverter,
DistanceConverter,
@ -80,6 +83,11 @@ _ALL_CONVERTERS: dict[type[BaseUnitConverter], list[str | None]] = {
# Dict containing all converters with a corresponding unit ratio.
_GET_UNIT_RATIO: dict[type[BaseUnitConverter], tuple[str | None, str | None, float]] = {
BloodGlugoseConcentrationConverter: (
UnitOfBloodGlucoseConcentration.MILLIGRAMS_PER_DECILITER,
UnitOfBloodGlucoseConcentration.MILLIMOLE_PER_LITER,
18,
),
ConductivityConverter: (
UnitOfConductivity.MICROSIEMENS_PER_CM,
UnitOfConductivity.MILLISIEMENS_PER_CM,
@ -130,6 +138,20 @@ _GET_UNIT_RATIO: dict[type[BaseUnitConverter], tuple[str | None, str | None, flo
_CONVERTED_VALUE: dict[
type[BaseUnitConverter], list[tuple[float, str | None, float, str | None]]
] = {
BloodGlugoseConcentrationConverter: [
(
90,
UnitOfBloodGlucoseConcentration.MILLIGRAMS_PER_DECILITER,
5,
UnitOfBloodGlucoseConcentration.MILLIMOLE_PER_LITER,
),
(
1,
UnitOfBloodGlucoseConcentration.MILLIMOLE_PER_LITER,
18,
UnitOfBloodGlucoseConcentration.MILLIGRAMS_PER_DECILITER,
),
],
ConductivityConverter: [
# Deprecated to deprecated
(5, UnitOfConductivity.SIEMENS, 5e3, UnitOfConductivity.MILLISIEMENS),