Skip to content

Commit

Permalink
Add blood glucose concentration device class (#129340)
Browse files Browse the repository at this point in the history
  • Loading branch information
epenet authored Nov 9, 2024
1 parent 0304588 commit 25fb70f
Show file tree
Hide file tree
Showing 14 changed files with 100 additions and 3 deletions.
9 changes: 6 additions & 3 deletions homeassistant/components/nightscout/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
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

Expand All @@ -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:
Expand Down
8 changes: 8 additions & 0 deletions homeassistant/components/number/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
SIGNAL_STRENGTH_DECIBELS,
SIGNAL_STRENGTH_DECIBELS_MILLIWATT,
UnitOfApparentPower,
UnitOfBloodGlucoseConcentration,
UnitOfConductivity,
UnitOfDataRate,
UnitOfElectricCurrent,
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -429,6 +436,7 @@ class NumberDeviceClass(StrEnum):
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),
Expand Down
3 changes: 3 additions & 0 deletions homeassistant/components/number/icons.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
"battery": {
"default": "mdi:battery"
},
"blood_glucose_concentration": {
"default": "mdi:spoon-sugar"
},
"carbon_dioxide": {
"default": "mdi:molecule-co2"
},
Expand Down
3 changes: 3 additions & 0 deletions homeassistant/components/number/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -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%]"
},
Expand Down
6 changes: 6 additions & 0 deletions homeassistant/components/recorder/statistics.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
from homeassistant.util import dt as dt_util
from homeassistant.util.unit_conversion import (
BaseUnitConverter,
BloodGlugoseConcentrationConverter,
ConductivityConverter,
DataRateConverter,
DistanceConverter,
Expand Down Expand Up @@ -128,6 +129,11 @@


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},
Expand Down
4 changes: 4 additions & 0 deletions homeassistant/components/recorder/websocket_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
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,
Expand Down Expand Up @@ -54,6 +55,9 @@

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),
Expand Down
11 changes: 11 additions & 0 deletions homeassistant/components/sensor/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
SIGNAL_STRENGTH_DECIBELS,
SIGNAL_STRENGTH_DECIBELS_MILLIWATT,
UnitOfApparentPower,
UnitOfBloodGlucoseConcentration,
UnitOfConductivity,
UnitOfDataRate,
UnitOfElectricCurrent,
Expand Down Expand Up @@ -47,6 +48,7 @@
)
from homeassistant.util.unit_conversion import (
BaseUnitConverter,
BloodGlugoseConcentrationConverter,
ConductivityConverter,
DataRateConverter,
DistanceConverter,
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -493,6 +501,7 @@ class SensorStateClass(StrEnum):

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,
Expand Down Expand Up @@ -524,6 +533,7 @@ class SensorStateClass(StrEnum):
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),
Expand Down Expand Up @@ -599,6 +609,7 @@ class SensorStateClass(StrEnum):
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},
Expand Down
5 changes: 5 additions & 0 deletions homeassistant/components/sensor/device_condition.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
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"
Expand Down Expand Up @@ -87,6 +88,9 @@
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}],
Expand Down Expand Up @@ -151,6 +155,7 @@
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,
Expand Down
5 changes: 5 additions & 0 deletions homeassistant/components/sensor/device_trigger.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
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"
Expand Down Expand Up @@ -86,6 +87,9 @@
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}],
Expand Down Expand Up @@ -151,6 +155,7 @@
CONF_AQI,
CONF_ATMOSPHERIC_PRESSURE,
CONF_BATTERY_LEVEL,
CONF_BLOOD_GLUCOSE_CONCENTRATION,
CONF_CO,
CONF_CO2,
CONF_CONDUCTIVITY,
Expand Down
3 changes: 3 additions & 0 deletions homeassistant/components/sensor/icons.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
"atmospheric_pressure": {
"default": "mdi:thermometer-lines"
},
"blood_glucose_concentration": {
"default": "mdi:spoon-sugar"
},
"carbon_dioxide": {
"default": "mdi:molecule-co2"
},
Expand Down
5 changes: 5 additions & 0 deletions homeassistant/components/sensor/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -149,6 +151,9 @@
"battery": {
"name": "Battery"
},
"blood_glucose_concentration": {
"name": "Blood glucose concentration"
},
"carbon_monoxide": {
"name": "Carbon monoxide"
},
Expand Down
7 changes: 7 additions & 0 deletions homeassistant/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -1358,6 +1358,13 @@ class UnitOfPrecipitationDepth(StrEnum):
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."""
Expand Down
12 changes: 12 additions & 0 deletions homeassistant/util/unit_conversion.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
CONCENTRATION_PARTS_PER_MILLION,
PERCENTAGE,
UNIT_NOT_RECOGNIZED_TEMPLATE,
UnitOfBloodGlucoseConcentration,
UnitOfConductivity,
UnitOfDataRate,
UnitOfElectricCurrent,
Expand Down Expand Up @@ -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."""

Expand Down
22 changes: 22 additions & 0 deletions tests/util/test_unit_conversion.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
CONCENTRATION_PARTS_PER_BILLION,
CONCENTRATION_PARTS_PER_MILLION,
PERCENTAGE,
UnitOfBloodGlucoseConcentration,
UnitOfConductivity,
UnitOfDataRate,
UnitOfElectricCurrent,
Expand All @@ -32,6 +33,7 @@
from homeassistant.util import unit_conversion
from homeassistant.util.unit_conversion import (
BaseUnitConverter,
BloodGlugoseConcentrationConverter,
ConductivityConverter,
DataRateConverter,
DistanceConverter,
Expand Down Expand Up @@ -59,6 +61,7 @@
_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,
Expand All @@ -80,6 +83,11 @@

# 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,
Expand Down Expand Up @@ -130,6 +138,20 @@
_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),
Expand Down

0 comments on commit 25fb70f

Please sign in to comment.