From 0a78409f22f9f135313b5c2d1927bf73d05397ab Mon Sep 17 00:00:00 2001 From: Andrey Khrolenok Date: Fri, 3 May 2024 22:22:39 +0300 Subject: [PATCH] Update index calculation metrics --- custom_components/iaquk/__init__.py | 40 +++++++++++---------- tests/test__init.py | 55 +++++++++++++++++++++++------ 2 files changed, 67 insertions(+), 28 deletions(-) diff --git a/custom_components/iaquk/__init__.py b/custom_components/iaquk/__init__.py index dc37665..3daf293 100644 --- a/custom_components/iaquk/__init__.py +++ b/custom_components/iaquk/__init__.py @@ -55,7 +55,7 @@ MWEIGTH_NO2, MWEIGTH_TVOC, STARTUP_MESSAGE, - UNIT_PPB, + UNIT_MGM3, UNIT_PPM, UNIT_UGM3, ) @@ -331,6 +331,8 @@ def _get_number_state( entity_unit = entity_unit.copy() if "ppb" in (unit, target_unit): mweight /= 1000 + if "µg/m³" in (unit, target_unit): + mweight *= 1000 if unit in {"ppm", "ppb"}: entity_unit[unit] = mweight / 24.45 else: @@ -419,7 +421,7 @@ def _co2_index(self) -> Optional[int]: return None index = 1 - if value <= 600: # ppm + if value < 600: # ppm index = 5 elif value <= 800: # ppm index = 4 @@ -437,19 +439,19 @@ def _tvoc_index(self) -> Optional[int]: return None value = self._get_number_state( - entity_id, UNIT_PPB, CONF_TVOC, mweight=MWEIGTH_TVOC + entity_id, UNIT_MGM3, CONF_TVOC, mweight=MWEIGTH_TVOC ) if value is None: return None index = 1 - if value <= 24: # ppb + if value < 0.1: # mg/m³ index = 5 - elif value <= 73: # ppb + elif value <= 0.3: # mg/m³ index = 4 - elif value <= 122: # ppb + elif value <= 0.5: # mg/m³ index = 3 - elif value <= 245: # ppb + elif value <= 1.0: # mg/m³ index = 2 return index @@ -521,15 +523,15 @@ def _no2_index(self) -> Optional[int]: return None value = self._get_number_state( - entity_id, UNIT_PPB, CONF_NO2, mweight=MWEIGTH_NO2 + entity_id, UNIT_MGM3, CONF_NO2, mweight=MWEIGTH_NO2 ) if value is None: return None index = 1 - if value <= 106: # ppb + if value < 0.2: # mg/m³ index = 5 - elif value <= 213: # ppb + elif value <= 0.4: # mg/m³ index = 3 return index @@ -540,14 +542,16 @@ def _co_index(self) -> Optional[int]: if entity_id is None: return None - value = self._get_number_state(entity_id, UNIT_PPB, CONF_CO, mweight=MWEIGTH_CO) + value = self._get_number_state( + entity_id, UNIT_MGM3, CONF_CO, mweight=MWEIGTH_CO + ) if value is None: return None index = 1 - if value <= 785.7: # ppb + if value == 0: # mg/m³ index = 5 - elif value <= 6111: # ppb + elif value <= 7: # mg/m³ index = 3 return index @@ -559,19 +563,19 @@ def _hcho_index(self) -> Optional[int]: return None value = self._get_number_state( - entity_id, UNIT_PPB, CONF_HCHO, mweight=MWEIGTH_HCHO + entity_id, UNIT_UGM3, CONF_HCHO, mweight=MWEIGTH_HCHO ) if value is None: return None index = 1 - if value <= 16: # ppb + if value < 20: # µg/m³ index = 5 - elif value <= 41: # ppb + elif value <= 50: # µg/m³ index = 4 - elif value <= 82: # ppb + elif value <= 100: # µg/m³ index = 3 - elif value <= 163: # ppb + elif value <= 200: # µg/m³ index = 2 return index diff --git a/tests/test__init.py b/tests/test__init.py index 3b37752..4cca5af 100644 --- a/tests/test__init.py +++ b/tests/test__init.py @@ -31,10 +31,12 @@ MWEIGTH_HCHO, MWEIGTH_NO2, MWEIGTH_TVOC, + UNIT_PPM, Iaquk, _deslugify, check_voc_keys, ) +from custom_components.iaquk.const import UNIT_MGM3, UNIT_PPB, UNIT_UGM3 from homeassistant.const import ( ATTR_UNIT_OF_MEASUREMENT, PERCENTAGE, @@ -239,7 +241,7 @@ async def test__get_number_state(hass: HomeAssistant): pytest.approx(controller._get_number_state(entity_id, "", mweight=1), 0.01) == 729.10 ) - assert controller._get_number_state(entity_id, "ppb", mweight=1) == 729099 + assert controller._get_number_state(entity_id, UNIT_PPB, mweight=1) == 729099 hass.states.async_set(entity_id, STATE_UNKNOWN) # @@ -248,7 +250,7 @@ async def test__get_number_state(hass: HomeAssistant): hass.states.async_set(entity_id, 12.5, {ATTR_UNIT_OF_MEASUREMENT: "ppm"}) # for mw, res in { - 10: 5.110, + 10: 5.112, MWEIGTH_CO: 14.320, MWEIGTH_CO2: 22.500, MWEIGTH_HCHO: 15.351, @@ -257,10 +259,16 @@ async def test__get_number_state(hass: HomeAssistant): }.items(): assert ( pytest.approx( - controller._get_number_state(entity_id, "mg/m³", mweight=mw), 0.001 + controller._get_number_state(entity_id, UNIT_MGM3, mweight=mw), 0.001 ) == res ) + assert ( + pytest.approx( + controller._get_number_state(entity_id, UNIT_UGM3, mweight=mw), 0.001 + ) + == res * 1000 + ) hass.states.async_set(entity_id, 12.5, {ATTR_UNIT_OF_MEASUREMENT: "mg/m³"}) # @@ -274,10 +282,34 @@ async def test__get_number_state(hass: HomeAssistant): }.items(): assert ( pytest.approx( - controller._get_number_state(entity_id, "ppm", mweight=mw), 0.001 + controller._get_number_state(entity_id, UNIT_PPM, mweight=mw), 0.001 ) == res ) + assert ( + pytest.approx( + controller._get_number_state(entity_id, UNIT_PPB, mweight=mw), 0.001 + ) + == res * 1000 + ) + + for tval, tunit, esval, esunit in [ + (12.5, "ppb", 0.0125, UNIT_PPM), + (12.5, "ppm", 12500, UNIT_PPB), + (12.5, "µg/m3", 12.5, UNIT_UGM3), + (12.5, "ug/m³", 12.5, UNIT_UGM3), + (12.5, "mg/m³", 12500, UNIT_UGM3), + (12.5, "mg/m^3", 12500, UNIT_UGM3), + (12.5, "mg/m^3", 12.5, UNIT_MGM3), + (12.5, "µg/m³", 0.0125, UNIT_MGM3), + (12.5, "µg/m3", 0.0125, UNIT_MGM3), + (12.5, "ug/m³", 0.0125, UNIT_MGM3), + ]: + hass.states.async_set(entity_id, tval, {ATTR_UNIT_OF_MEASUREMENT: tunit}) + assert ( + pytest.approx(controller._get_number_state(entity_id, esunit), 0.001) + == esval + ) async def test__temperature_index(hass: HomeAssistant): @@ -345,11 +377,11 @@ async def test__co2_index(hass: HomeAssistant): controller = Iaquk(hass, "test", "Test", {CONF_CO2: entity_id}) - for i, value in enumerate([1801, 1800, 1500, 800, 600]): + for i, value in enumerate([1801, 1800, 1500, 800, 599]): hass.states.async_set(entity_id, value, {ATTR_UNIT_OF_MEASUREMENT: "ppm"}) assert controller._co2_index == i + 1 - for i, value in enumerate([1801, 1501, 801, 601, 600]): + for i, value in enumerate([1801, 1501, 801, 600, 599]): hass.states.async_set(entity_id, value, {ATTR_UNIT_OF_MEASUREMENT: "ppm"}) assert controller._co2_index == i + 1 @@ -370,11 +402,11 @@ async def test__tvoc_index(hass: HomeAssistant): controller = Iaquk(hass, "test", "Test", {CONF_TVOC: entity_id}) - for i, value in enumerate([0.792, 0.791, 0.393, 0.235, 0.077]): + for i, value in enumerate([1.01, 1.0, 0.5, 0.3, 0.09]): hass.states.async_set(entity_id, value, {ATTR_UNIT_OF_MEASUREMENT: "mg/m3"}) assert controller._tvoc_index == i + 1 - for i, value in enumerate([0.792, 0.394, 0.236, 0.078, 0.077]): + for i, value in enumerate([1.01, 0.51, 0.31, 0.1, 0.09]): hass.states.async_set(entity_id, value, {ATTR_UNIT_OF_MEASUREMENT: "mg/m3"}) assert controller._tvoc_index == i + 1 @@ -473,11 +505,11 @@ async def test__co_index(hass: HomeAssistant): controller = Iaquk(hass, "test", "Test", {CONF_CO: entity_id}) - for i, value in enumerate([7.1, 7, 0.9]): + for i, value in enumerate([7.1, 7, 0]): hass.states.async_set(entity_id, value, {ATTR_UNIT_OF_MEASUREMENT: "mg/m3"}) assert controller._co_index == i * 2 + 1 - hass.states.async_set(entity_id, 1, {ATTR_UNIT_OF_MEASUREMENT: "mg/m3"}) + hass.states.async_set(entity_id, 0.1, {ATTR_UNIT_OF_MEASUREMENT: "mg/m3"}) assert controller._co_index == 3 @@ -505,6 +537,9 @@ async def test__hcho_index(hass: HomeAssistant): hass.states.async_set(entity_id, value, {ATTR_UNIT_OF_MEASUREMENT: "mg/m3"}) assert controller._hcho_index == i + 1 + hass.states.async_set(entity_id, 4, {ATTR_UNIT_OF_MEASUREMENT: "µg/m³"}) + assert controller._hcho_index == 5 + async def test__radon_index(hass: HomeAssistant): """Test transform indoor Radon (Rn) values to IAQ points."""