From 5dfbd86f656527e63ff43066cf255d2d4e139c90 Mon Sep 17 00:00:00 2001 From: kongo09 Date: Wed, 10 Jan 2024 00:10:31 +0100 Subject: [PATCH 01/73] start support for AMF765 and CX5120 --- .../philips_airpurifier_coap/const.py | 16 ++++++ .../philips_airpurifier_coap/philips.py | 55 ++++++++++++++++++- 2 files changed, 68 insertions(+), 3 deletions(-) diff --git a/custom_components/philips_airpurifier_coap/const.py b/custom_components/philips_airpurifier_coap/const.py index 0c60da1..5a90162 100644 --- a/custom_components/philips_airpurifier_coap/const.py +++ b/custom_components/philips_airpurifier_coap/const.py @@ -113,6 +113,8 @@ class FanModel(StrEnum): AC4550 = "AC4550" AC4558 = "AC4558" AC5659 = "AC5659" + AMF765 = "AMF765" + CX5120 = "CX5120" class PresetMode: @@ -293,6 +295,7 @@ class PhilipsApi: SWITCH_ON: "1", SWITCH_OFF: "0", } + # the AC1715 seems to follow a new scheme, this should later be refactored NEW_NAME = "D01-03" NEW_MODEL_ID = "D01-05" @@ -304,6 +307,12 @@ class PhilipsApi: NEW_PM25 = "D03-33" NEW_PREFERRED_INDEX = "D03-42" + # there is a third generation of devices with yet another scheme + NEW2_NAME = "D01S03" + NEW2_MODEL_ID = "D01S05" + NEW2_POWER = "D03102" + NEW2_DISPLAY_BACKLIGHT = "D0312D" + PREFERRED_INDEX_MAP = { "0": ("Indoor Allergen Index", ICON.IAI), "1": ("PM2.5", ICON.PM25), @@ -506,6 +515,13 @@ class PhilipsApi: SWITCH_ON: 100, SWITCH_OFF: 0, }, + PhilipsApi.NEW2_DISPLAY_BACKLIGHT: { + ATTR_ICON: ICON.LIGHT_DIMMING_BUTTON, + FanAttributes.LABEL: FanAttributes.DISPLAY_BACKLIGHT, + CONF_ENTITY_CATEGORY: EntityCategory.CONFIG, + SWITCH_ON: 100, + SWITCH_OFF: 0, + }, } SELECT_TYPES: dict[str, SelectDescription] = { diff --git a/custom_components/philips_airpurifier_coap/philips.py b/custom_components/philips_airpurifier_coap/philips.py index 7784995..6e3f87a 100644 --- a/custom_components/philips_airpurifier_coap/philips.py +++ b/custom_components/philips_airpurifier_coap/philips.py @@ -537,6 +537,45 @@ class PhilipsNewGenericCoAPFan(PhilipsGenericCoAPFanBase): STATE_POWER_OFF = "OFF" +class PhilipsNew2GenericCoAPFan(PhilipsGenericCoAPFanBase): + """Class to manage another new generic CoAP fan.""" + + AVAILABLE_PRESET_MODES = {} + AVAILABLE_SPEEDS = {} + + AVAILABLE_ATTRIBUTES = [ + # device information + (FanAttributes.NAME, PhilipsApi.NEW2_NAME), + (FanAttributes.MODEL_ID, PhilipsApi.NEW2_MODEL_ID), + (FanAttributes.PRODUCT_ID, PhilipsApi.PRODUCT_ID), + (FanAttributes.DEVICE_ID, PhilipsApi.DEVICE_ID), + # (FanAttributes.SOFTWARE_VERSION, PhilipsApi.SOFTWARE_VERSION), + (FanAttributes.WIFI_VERSION, PhilipsApi.WIFI_VERSION), + # (FanAttributes.ERROR_CODE, PhilipsApi.ERROR_CODE), + # (FanAttributes.ERROR, PhilipsApi.ERROR_CODE, PhilipsApi.ERROR_CODE_MAP), + # device configuration + # ( + # FanAttributes.PREFERRED_INDEX, + # PhilipsApi.NEW_PREFERRED_INDEX, + # PhilipsApi.NEW_PREFERRED_INDEX_MAP, + # ), + # device sensors + # ( + # FanAttributes.RUNTIME, + # PhilipsApi.RUNTIME, + # lambda x, _: str(timedelta(seconds=round(x / 1000))), + # ), + ] + + AVAILABLE_LIGHTS = [PhilipsApi.NEW2_DISPLAY_BACKLIGHT] + AVAILABLE_SWITCHES = [] + AVAILABLE_SELECTS = [] + + KEY_PHILIPS_POWER = PhilipsApi.NEW2_POWER + STATE_POWER_ON = 1 + STATE_POWER_OFF = 0 + + class PhilipsHumidifierMixin(PhilipsGenericCoAPFanBase): """Mixin for humidifiers.""" @@ -1153,9 +1192,9 @@ class PhilipsAC3836(PhilipsGenericCoAPFan): AVAILABLE_PRESET_MODES = { PresetMode.AUTO: { - PhilipsApi.POWER: "1", - PhilipsApi.MODE: "AG", - PhilipsApi.SPEED: "1" + PhilipsApi.POWER: "1", + PhilipsApi.MODE: "AG", + PhilipsApi.SPEED: "1", }, # make speeds available as preset PresetMode.SLEEP: { @@ -1469,6 +1508,14 @@ class PhilipsAC5659(PhilipsGenericCoAPFan): AVAILABLE_SELECTS = [PhilipsApi.PREFERRED_INDEX] +class PhilipsAMF765(PhilipsNew2GenericCoAPFan): + """AMF765.""" + + +class PhilipsCX5120(PhilipsNew2GenericCoAPFan): + """CX5120.""" + + model_to_class = { FanModel.AC0850: PhilipsAC0850, FanModel.AC1214: PhilipsAC1214, @@ -1495,4 +1542,6 @@ class PhilipsAC5659(PhilipsGenericCoAPFan): FanModel.AC4550: PhilipsAC4550, FanModel.AC4558: PhilipsAC4558, FanModel.AC5659: PhilipsAC5659, + FanModel.AMF765: PhilipsAMF765, + FanModel.CX5120: PhilipsCX5120, } From 92981a47be3a34082c257c1ef79e6a5030ce1f82 Mon Sep 17 00:00:00 2001 From: kongo09 Date: Wed, 10 Jan 2024 00:11:58 +0100 Subject: [PATCH 02/73] start support for AMF765 and CX5120 --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index fb70b77..ce69d75 100644 --- a/README.md +++ b/README.md @@ -78,6 +78,8 @@ Note: `configuration.yaml` is no longer supported and your configuration is not - AC4550 - AC4558 - AC5659 +- AMF765 +- CX5120 ## Is your model not supported yet? From a3557e755fea538c835c74e427ec266958733de6 Mon Sep 17 00:00:00 2001 From: kongo09 Date: Wed, 10 Jan 2024 11:00:07 +0100 Subject: [PATCH 03/73] debug model detection --- .../philips_airpurifier_coap/config_flow.py | 37 +++++++++++++++---- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/custom_components/philips_airpurifier_coap/config_flow.py b/custom_components/philips_airpurifier_coap/config_flow.py index 9d805a9..d591f00 100644 --- a/custom_components/philips_airpurifier_coap/config_flow.py +++ b/custom_components/philips_airpurifier_coap/config_flow.py @@ -215,16 +215,37 @@ async def async_step_user(self, user_input: dict[str, Any] = None) -> FlowResult _LOGGER.warning(r"Failed to connect: %s", ex) raise exceptions.ConfigEntryNotReady from ex - # autodetect model and name - self._model = list( - filter( - None, - map(status.get, [PhilipsApi.MODEL_ID, PhilipsApi.NEW_MODEL_ID]), - ) - )[0][:9] + # autodetect model + model_map = map( + status.get, + [ + PhilipsApi.MODEL_ID, + PhilipsApi.NEW_MODEL_ID, + PhilipsApi.NEW2_MODEL_ID, + ], + ) + _LOGGER.debug("model_map retrieved: %s", model_map) + model_filter = filter(None, model_map) + _LOGGER.debug("model_filter applied: %s", model_filter) + model_list = list(model_filter) + _LOGGER.debug("model_list built: %s", model_list) + first_model = model_list[0] + _LOGGER.debug("first model selected: %s", first_model) + self._model = first_model[:9] + _LOGGER.debug("model type extracted: %s", self._model) + + # autodetect name self._name = list( filter( - None, map(status.get, [PhilipsApi.NAME, PhilipsApi.NEW_NAME]) + None, + map( + status.get, + [ + PhilipsApi.NAME, + PhilipsApi.NEW_NAME, + PhilipsApi.NEW2_NAME, + ], + ), ) )[0] self._device_id = status[PhilipsApi.DEVICE_ID] From 84148c6c5d85eb67fa5953085a457aa8909b749e Mon Sep 17 00:00:00 2001 From: kongo09 Date: Wed, 10 Jan 2024 13:16:20 +0100 Subject: [PATCH 04/73] put debugging into DHCP discovery --- .../philips_airpurifier_coap/config_flow.py | 32 +++++++++++++++---- 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/custom_components/philips_airpurifier_coap/config_flow.py b/custom_components/philips_airpurifier_coap/config_flow.py index d591f00..f3e7366 100644 --- a/custom_components/philips_airpurifier_coap/config_flow.py +++ b/custom_components/philips_airpurifier_coap/config_flow.py @@ -91,14 +91,34 @@ async def async_step_dhcp(self, discovery_info: dhcp.DhcpServiceInfo) -> FlowRes _LOGGER.warning(r"Failed to connect: %s", ex) raise exceptions.ConfigEntryNotReady from ex - # autodetect model and name - self._model = list( + # autodetect model + model_map = map( + status.get, + [ + PhilipsApi.MODEL_ID, + PhilipsApi.NEW_MODEL_ID, + PhilipsApi.NEW2_MODEL_ID, + ], + ) + _LOGGER.debug("model_map retrieved: %s", model_map) + model_filter = filter(None, model_map) + _LOGGER.debug("model_filter applied: %s", model_filter) + model_list = list(model_filter) + _LOGGER.debug("model_list built: %s", model_list) + first_model = model_list[0] + _LOGGER.debug("first model selected: %s", first_model) + self._model = first_model[:9] + _LOGGER.debug("model type extracted: %s", self._model) + + # autodetect name + self._name = list( filter( - None, map(status.get, [PhilipsApi.MODEL_ID, PhilipsApi.NEW_MODEL_ID]) + None, + map( + status.get, + [PhilipsApi.NAME, PhilipsApi.NEW_NAME, PhilipsApi.NEW2_NAME], + ), ) - )[0][:9] - self._name = list( - filter(None, map(status.get, [PhilipsApi.NAME, PhilipsApi.NEW_NAME])) )[0] self._device_id = status[PhilipsApi.DEVICE_ID] _LOGGER.debug( From 9024a3f0f0d16ae9dceaa106d43e01daa4335f91 Mon Sep 17 00:00:00 2001 From: kongo09 Date: Wed, 10 Jan 2024 15:33:47 +0100 Subject: [PATCH 05/73] fix base class for new models --- custom_components/philips_airpurifier_coap/philips.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/custom_components/philips_airpurifier_coap/philips.py b/custom_components/philips_airpurifier_coap/philips.py index 6e3f87a..28500e5 100644 --- a/custom_components/philips_airpurifier_coap/philips.py +++ b/custom_components/philips_airpurifier_coap/philips.py @@ -183,7 +183,10 @@ def __init__(self, coordinator: Coordinator) -> None: # noqa: D107 self._name = list( filter( None, - map(coordinator.status.get, [PhilipsApi.NAME, PhilipsApi.NEW_NAME]), + map( + coordinator.status.get, + [PhilipsApi.NAME, PhilipsApi.NEW_NAME, PhilipsApi.NEW2_NAME], + ), ) )[0] # self._modelName = coordinator.status["modelid"] @@ -192,7 +195,11 @@ def __init__(self, coordinator: Coordinator) -> None: # noqa: D107 None, map( coordinator.status.get, - [PhilipsApi.MODEL_ID, PhilipsApi.NEW_MODEL_ID], + [ + PhilipsApi.MODEL_ID, + PhilipsApi.NEW_MODEL_ID, + PhilipsApi.NEW2_MODEL_ID, + ], ), ) )[0] From 497ae125ec8a4b912492196cccdc36a43196acf0 Mon Sep 17 00:00:00 2001 From: Jorim Tielemans Date: Wed, 10 Jan 2024 16:36:23 +0100 Subject: [PATCH 06/73] Allow user to adjust brightness --- custom_components/philips_airpurifier_coap/const.py | 1 + 1 file changed, 1 insertion(+) diff --git a/custom_components/philips_airpurifier_coap/const.py b/custom_components/philips_airpurifier_coap/const.py index 5a90162..8b95f65 100644 --- a/custom_components/philips_airpurifier_coap/const.py +++ b/custom_components/philips_airpurifier_coap/const.py @@ -521,6 +521,7 @@ class PhilipsApi: CONF_ENTITY_CATEGORY: EntityCategory.CONFIG, SWITCH_ON: 100, SWITCH_OFF: 0, + DIMMABLE: True, }, } From b621ca0ee93654215b95296c061c743bdf8724dc Mon Sep 17 00:00:00 2001 From: kongo09 Date: Thu, 11 Jan 2024 00:40:19 +0100 Subject: [PATCH 07/73] add temperature sensor --- custom_components/philips_airpurifier_coap/const.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/custom_components/philips_airpurifier_coap/const.py b/custom_components/philips_airpurifier_coap/const.py index 8b95f65..44cb9bf 100644 --- a/custom_components/philips_airpurifier_coap/const.py +++ b/custom_components/philips_airpurifier_coap/const.py @@ -312,6 +312,7 @@ class PhilipsApi: NEW2_MODEL_ID = "D01S05" NEW2_POWER = "D03102" NEW2_DISPLAY_BACKLIGHT = "D0312D" + NEW2_TEMPERATURE = "D03224" PREFERRED_INDEX_MAP = { "0": ("Indoor Allergen Index", ICON.IAI), @@ -401,6 +402,18 @@ class PhilipsApi: ATTR_STATE_CLASS: SensorStateClass.MEASUREMENT, FanAttributes.UNIT: UnitOfTemperature.CELSIUS, }, + PhilipsApi.NEW2_TEMPERATURE: { + ATTR_DEVICE_CLASS: SensorDeviceClass.TEMPERATURE, + FanAttributes.ICON_MAP: { + 0: "mdi:thermometer-low", + 17: "mdi:thermometer", + 23: "mdi:thermometer-high", + }, + FanAttributes.LABEL: ATTR_TEMPERATURE, + FanAttributes.VALUE: lambda value, _: int(value / 10), + ATTR_STATE_CLASS: SensorStateClass.MEASUREMENT, + FanAttributes.UNIT: UnitOfTemperature.CELSIUS, + }, # diagnostic information PhilipsApi.WATER_LEVEL: { FanAttributes.ICON_MAP: {0: ICON.WATER_REFILL, 10: "mdi:water"}, From 5cd455af3ed6f78acfe411f28e02eb477725f7ad Mon Sep 17 00:00:00 2001 From: kongo09 Date: Thu, 11 Jan 2024 01:03:56 +0100 Subject: [PATCH 08/73] add firmware detection --- custom_components/philips_airpurifier_coap/const.py | 1 + custom_components/philips_airpurifier_coap/philips.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/custom_components/philips_airpurifier_coap/const.py b/custom_components/philips_airpurifier_coap/const.py index 44cb9bf..8900256 100644 --- a/custom_components/philips_airpurifier_coap/const.py +++ b/custom_components/philips_airpurifier_coap/const.py @@ -313,6 +313,7 @@ class PhilipsApi: NEW2_POWER = "D03102" NEW2_DISPLAY_BACKLIGHT = "D0312D" NEW2_TEMPERATURE = "D03224" + NEW2_SOFTWARE_VERSION = "D01S12" PREFERRED_INDEX_MAP = { "0": ("Indoor Allergen Index", ICON.IAI), diff --git a/custom_components/philips_airpurifier_coap/philips.py b/custom_components/philips_airpurifier_coap/philips.py index 28500e5..41dd08f 100644 --- a/custom_components/philips_airpurifier_coap/philips.py +++ b/custom_components/philips_airpurifier_coap/philips.py @@ -556,7 +556,7 @@ class PhilipsNew2GenericCoAPFan(PhilipsGenericCoAPFanBase): (FanAttributes.MODEL_ID, PhilipsApi.NEW2_MODEL_ID), (FanAttributes.PRODUCT_ID, PhilipsApi.PRODUCT_ID), (FanAttributes.DEVICE_ID, PhilipsApi.DEVICE_ID), - # (FanAttributes.SOFTWARE_VERSION, PhilipsApi.SOFTWARE_VERSION), + (FanAttributes.SOFTWARE_VERSION, PhilipsApi.NEW2_SOFTWARE_VERSION), (FanAttributes.WIFI_VERSION, PhilipsApi.WIFI_VERSION), # (FanAttributes.ERROR_CODE, PhilipsApi.ERROR_CODE), # (FanAttributes.ERROR, PhilipsApi.ERROR_CODE, PhilipsApi.ERROR_CODE_MAP), From f283585cd9fd9f74ff40bc9d007f533e9ea1af5e Mon Sep 17 00:00:00 2001 From: kongo09 Date: Thu, 11 Jan 2024 01:05:14 +0100 Subject: [PATCH 09/73] adding runtime detection --- custom_components/philips_airpurifier_coap/philips.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/custom_components/philips_airpurifier_coap/philips.py b/custom_components/philips_airpurifier_coap/philips.py index 41dd08f..fcfbf21 100644 --- a/custom_components/philips_airpurifier_coap/philips.py +++ b/custom_components/philips_airpurifier_coap/philips.py @@ -567,11 +567,11 @@ class PhilipsNew2GenericCoAPFan(PhilipsGenericCoAPFanBase): # PhilipsApi.NEW_PREFERRED_INDEX_MAP, # ), # device sensors - # ( - # FanAttributes.RUNTIME, - # PhilipsApi.RUNTIME, - # lambda x, _: str(timedelta(seconds=round(x / 1000))), - # ), + ( + FanAttributes.RUNTIME, + PhilipsApi.RUNTIME, + lambda x, _: str(timedelta(seconds=round(x / 1000))), + ), ] AVAILABLE_LIGHTS = [PhilipsApi.NEW2_DISPLAY_BACKLIGHT] From e6020cda530d580f4f0521b491d04013fecb4604 Mon Sep 17 00:00:00 2001 From: kongo09 Date: Thu, 11 Jan 2024 01:10:15 +0100 Subject: [PATCH 10/73] add child lock for AMF --- custom_components/philips_airpurifier_coap/const.py | 8 ++++++++ custom_components/philips_airpurifier_coap/philips.py | 2 ++ 2 files changed, 10 insertions(+) diff --git a/custom_components/philips_airpurifier_coap/const.py b/custom_components/philips_airpurifier_coap/const.py index 8900256..9ef70e7 100644 --- a/custom_components/philips_airpurifier_coap/const.py +++ b/custom_components/philips_airpurifier_coap/const.py @@ -314,6 +314,7 @@ class PhilipsApi: NEW2_DISPLAY_BACKLIGHT = "D0312D" NEW2_TEMPERATURE = "D03224" NEW2_SOFTWARE_VERSION = "D01S12" + NEW2_CHILD_LOCK = "D03103" PREFERRED_INDEX_MAP = { "0": ("Indoor Allergen Index", ICON.IAI), @@ -504,6 +505,13 @@ class PhilipsApi: SWITCH_ON: True, SWITCH_OFF: False, }, + PhilipsApi.NEW2_CHILD_LOCK: { + ATTR_ICON: ICON.CHILD_LOCK_BUTTON, + FanAttributes.LABEL: FanAttributes.CHILD_LOCK, + CONF_ENTITY_CATEGORY: EntityCategory.CONFIG, + SWITCH_ON: 1, + SWITCH_OFF: 0, + }, } LIGHT_TYPES: dict[str, LightDescription] = { diff --git a/custom_components/philips_airpurifier_coap/philips.py b/custom_components/philips_airpurifier_coap/philips.py index fcfbf21..0ae500b 100644 --- a/custom_components/philips_airpurifier_coap/philips.py +++ b/custom_components/philips_airpurifier_coap/philips.py @@ -1518,6 +1518,8 @@ class PhilipsAC5659(PhilipsGenericCoAPFan): class PhilipsAMF765(PhilipsNew2GenericCoAPFan): """AMF765.""" + AVAILABLE_SWITCHES = [PhilipsApi.NEW2_CHILD_LOCK] + class PhilipsCX5120(PhilipsNew2GenericCoAPFan): """CX5120.""" From 76e6c4cf2f57fc6325df94f73ed890c771310029 Mon Sep 17 00:00:00 2001 From: kongo09 Date: Thu, 11 Jan 2024 01:13:31 +0100 Subject: [PATCH 11/73] add IAI and PM25 sensors --- .../philips_airpurifier_coap/const.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/custom_components/philips_airpurifier_coap/const.py b/custom_components/philips_airpurifier_coap/const.py index 9ef70e7..1146328 100644 --- a/custom_components/philips_airpurifier_coap/const.py +++ b/custom_components/philips_airpurifier_coap/const.py @@ -315,6 +315,8 @@ class PhilipsApi: NEW2_TEMPERATURE = "D03224" NEW2_SOFTWARE_VERSION = "D01S12" NEW2_CHILD_LOCK = "D03103" + NEW2_INDOOR_ALLERGEN_INDEX = "D03120" + NEW2_PM25 = "D03121" PREFERRED_INDEX_MAP = { "0": ("Indoor Allergen Index", ICON.IAI), @@ -365,6 +367,11 @@ class PhilipsApi: FanAttributes.LABEL: FanAttributes.INDOOR_ALLERGEN_INDEX, ATTR_STATE_CLASS: SensorStateClass.MEASUREMENT, }, + PhilipsApi.NEW2_INDOOR_ALLERGEN_INDEX: { + FanAttributes.ICON_MAP: {0: ICON.IAI}, + FanAttributes.LABEL: FanAttributes.INDOOR_ALLERGEN_INDEX, + ATTR_STATE_CLASS: SensorStateClass.MEASUREMENT, + }, PhilipsApi.PM25: { ATTR_DEVICE_CLASS: SensorDeviceClass.PM25, FanAttributes.ICON_MAP: {0: ICON.PM25}, @@ -379,6 +386,13 @@ class PhilipsApi: FanAttributes.UNIT: CONCENTRATION_MICROGRAMS_PER_CUBIC_METER, ATTR_STATE_CLASS: SensorStateClass.MEASUREMENT, }, + PhilipsApi.NEW2_PM25: { + ATTR_DEVICE_CLASS: SensorDeviceClass.PM25, + FanAttributes.ICON_MAP: {0: ICON.PM25}, + FanAttributes.LABEL: FanAttributes.PM25, + FanAttributes.UNIT: CONCENTRATION_MICROGRAMS_PER_CUBIC_METER, + ATTR_STATE_CLASS: SensorStateClass.MEASUREMENT, + }, PhilipsApi.TOTAL_VOLATILE_ORGANIC_COMPOUNDS: { ATTR_DEVICE_CLASS: SensorDeviceClass.VOLATILE_ORGANIC_COMPOUNDS, FanAttributes.ICON_MAP: {0: "mdi:blur"}, From 403737cc69d81208b8a69b1f04474c26f3dce294 Mon Sep 17 00:00:00 2001 From: kongo09 Date: Thu, 11 Jan 2024 01:23:06 +0100 Subject: [PATCH 12/73] add humidity and beeping --- .../philips_airpurifier_coap/const.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/custom_components/philips_airpurifier_coap/const.py b/custom_components/philips_airpurifier_coap/const.py index 1146328..9b925e1 100644 --- a/custom_components/philips_airpurifier_coap/const.py +++ b/custom_components/philips_airpurifier_coap/const.py @@ -181,6 +181,7 @@ class FanAttributes(StrEnum): AIR_QUALITY_INDEX = "air_quality_index" CHILD_LOCK = "child_lock" + BEEP = "beep" DEVICE_ID = "device_id" DEVICE_VERSION = "device_version" DISPLAY_BACKLIGHT = "display_backlight" @@ -315,8 +316,10 @@ class PhilipsApi: NEW2_TEMPERATURE = "D03224" NEW2_SOFTWARE_VERSION = "D01S12" NEW2_CHILD_LOCK = "D03103" + NEW2_BEEP = "D03130" NEW2_INDOOR_ALLERGEN_INDEX = "D03120" NEW2_PM25 = "D03121" + NEW2_HUMIDITY = "D03125" PREFERRED_INDEX_MAP = { "0": ("Indoor Allergen Index", ICON.IAI), @@ -407,6 +410,13 @@ class PhilipsApi: ATTR_STATE_CLASS: SensorStateClass.MEASUREMENT, FanAttributes.UNIT: PERCENTAGE, }, + PhilipsApi.NEW2_HUMIDITY: { + ATTR_DEVICE_CLASS: SensorDeviceClass.HUMIDITY, + FanAttributes.ICON_MAP: {0: "mdi:water-percent"}, + FanAttributes.LABEL: FanAttributes.HUMIDITY, + ATTR_STATE_CLASS: SensorStateClass.MEASUREMENT, + FanAttributes.UNIT: PERCENTAGE, + }, PhilipsApi.TEMPERATURE: { ATTR_DEVICE_CLASS: SensorDeviceClass.TEMPERATURE, FanAttributes.ICON_MAP: { @@ -526,6 +536,13 @@ class PhilipsApi: SWITCH_ON: 1, SWITCH_OFF: 0, }, + PhilipsApi.NEW2_BEEP: { + ATTR_ICON: "mdi:volume-high", + FanAttributes.LABEL: FanAttributes.BEEP, + CONF_ENTITY_CATEGORY: EntityCategory.CONFIG, + SWITCH_ON: 100, + SWITCH_OFF: 0, + }, } LIGHT_TYPES: dict[str, LightDescription] = { From 498d8a2a31854bdca5f9ceda6b0fdc7b9568b807 Mon Sep 17 00:00:00 2001 From: kongo09 Date: Thu, 11 Jan 2024 01:29:37 +0100 Subject: [PATCH 13/73] add filter sensors --- .../philips_airpurifier_coap/const.py | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/custom_components/philips_airpurifier_coap/const.py b/custom_components/philips_airpurifier_coap/const.py index 9b925e1..c91e669 100644 --- a/custom_components/philips_airpurifier_coap/const.py +++ b/custom_components/philips_airpurifier_coap/const.py @@ -320,6 +320,10 @@ class PhilipsApi: NEW2_INDOOR_ALLERGEN_INDEX = "D03120" NEW2_PM25 = "D03121" NEW2_HUMIDITY = "D03125" + NEW2_FILTER_NANOPROTECT_PREFILTER = "D0520D" + NEW2_FILTER_NANOPROTECT = "D0540E" + NEW2_FILTER_NANOPROTECT_PREFILTER_TOTAL = "D05207" + NEW2_FILTER_NANOPROTECT_TOTAL = "D05408" PREFERRED_INDEX_MAP = { "0": ("Indoor Allergen Index", ICON.IAI), @@ -519,6 +523,24 @@ class PhilipsApi: FanAttributes.TOTAL: PhilipsApi.FILTER_NANOPROTECT_CLEAN_TOTAL, FanAttributes.TYPE: "", }, + PhilipsApi.NEW2_FILTER_NANOPROTECT: { + FanAttributes.ICON_MAP: { + 0: ICON.FILTER_REPLACEMENT, + 10: ICON.NANOPROTECT_FILTER, + }, + FanAttributes.LABEL: FanAttributes.FILTER_NANOPROTECT, + FanAttributes.TOTAL: PhilipsApi.NEW2_FILTER_NANOPROTECT_TOTAL, + FanAttributes.TYPE: "", + }, + PhilipsApi.NEW2_FILTER_NANOPROTECT_PREFILTER: { + FanAttributes.ICON_MAP: { + 0: ICON.PREFILTER_CLEANING, + 10: ICON.NANOPROTECT_FILTER, + }, + FanAttributes.LABEL: FanAttributes.FILTER_NANOPROTECT_CLEAN, + FanAttributes.TOTAL: PhilipsApi.NEW2_FILTER_NANOPROTECT_CLEAN_TOTAL, + FanAttributes.TYPE: "", + }, } SWITCH_TYPES: dict[str, SwitchDescription] = { From 76b42abd77f2e2a5628aa5f8f543abde3823739f Mon Sep 17 00:00:00 2001 From: Jorim Tielemans Date: Thu, 11 Jan 2024 04:03:01 +0100 Subject: [PATCH 14/73] Fix pre-filter constant --- custom_components/philips_airpurifier_coap/const.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/philips_airpurifier_coap/const.py b/custom_components/philips_airpurifier_coap/const.py index c91e669..a27e4d9 100644 --- a/custom_components/philips_airpurifier_coap/const.py +++ b/custom_components/philips_airpurifier_coap/const.py @@ -538,7 +538,7 @@ class PhilipsApi: 10: ICON.NANOPROTECT_FILTER, }, FanAttributes.LABEL: FanAttributes.FILTER_NANOPROTECT_CLEAN, - FanAttributes.TOTAL: PhilipsApi.NEW2_FILTER_NANOPROTECT_CLEAN_TOTAL, + FanAttributes.TOTAL: PhilipsApi.NEW2_FILTER_NANOPROTECT_PREFILTER_TOTAL, FanAttributes.TYPE: "", }, } From 803784a3a1a4dbfb2e20ddd42600aea6c38fff1b Mon Sep 17 00:00:00 2001 From: kongo09 Date: Thu, 11 Jan 2024 07:39:33 +0100 Subject: [PATCH 15/73] use temperature decimals --- custom_components/philips_airpurifier_coap/const.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/philips_airpurifier_coap/const.py b/custom_components/philips_airpurifier_coap/const.py index a27e4d9..4a101eb 100644 --- a/custom_components/philips_airpurifier_coap/const.py +++ b/custom_components/philips_airpurifier_coap/const.py @@ -440,7 +440,7 @@ class PhilipsApi: 23: "mdi:thermometer-high", }, FanAttributes.LABEL: ATTR_TEMPERATURE, - FanAttributes.VALUE: lambda value, _: int(value / 10), + FanAttributes.VALUE: lambda value, _: value / 10, ATTR_STATE_CLASS: SensorStateClass.MEASUREMENT, FanAttributes.UNIT: UnitOfTemperature.CELSIUS, }, From 28115c687f0cde9e07741122bf8b318a39c54b5e Mon Sep 17 00:00:00 2001 From: kongo09 Date: Thu, 11 Jan 2024 21:43:38 +0100 Subject: [PATCH 16/73] fix display backlight for CX --- .../philips_airpurifier_coap/const.py | 23 +++++++++++++++++++ .../philips_airpurifier_coap/philips.py | 5 +++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/custom_components/philips_airpurifier_coap/const.py b/custom_components/philips_airpurifier_coap/const.py index 4a101eb..4f42184 100644 --- a/custom_components/philips_airpurifier_coap/const.py +++ b/custom_components/philips_airpurifier_coap/const.py @@ -179,6 +179,7 @@ class FanService(StrEnum): class FanAttributes(StrEnum): """The attributes of a fan.""" + ACTUAL_FAN_SPEED = "actual_fan_speed" AIR_QUALITY_INDEX = "air_quality_index" CHILD_LOCK = "child_lock" BEEP = "beep" @@ -313,6 +314,7 @@ class PhilipsApi: NEW2_MODEL_ID = "D01S05" NEW2_POWER = "D03102" NEW2_DISPLAY_BACKLIGHT = "D0312D" + NEW2_DISPLAY_BACKLIGHT2 = "D03105" NEW2_TEMPERATURE = "D03224" NEW2_SOFTWARE_VERSION = "D01S12" NEW2_CHILD_LOCK = "D03103" @@ -324,6 +326,7 @@ class PhilipsApi: NEW2_FILTER_NANOPROTECT = "D0540E" NEW2_FILTER_NANOPROTECT_PREFILTER_TOTAL = "D05207" NEW2_FILTER_NANOPROTECT_TOTAL = "D05408" + NEW2_FAN_SPEED = "D0310D" PREFERRED_INDEX_MAP = { "0": ("Indoor Allergen Index", ICON.IAI), @@ -444,6 +447,18 @@ class PhilipsApi: ATTR_STATE_CLASS: SensorStateClass.MEASUREMENT, FanAttributes.UNIT: UnitOfTemperature.CELSIUS, }, + PhilipsApi.NEW2_FAN_SPEED: { + ATTR_DEVICE_CLASS: SensorDeviceClass.SPEED, + FanAttributes.ICON_MAP: { + 0: "mdi:thermometer-low", + 17: "mdi:thermometer", + 23: "mdi:thermometer-high", + }, + FanAttributes.LABEL: ATTR_TEMPERATURE, + FanAttributes.VALUE: lambda value, _: value / 10, + ATTR_STATE_CLASS: SensorStateClass.MEASUREMENT, + FanAttributes.UNIT: UnitOfTemperature.CELSIUS, + }, # diagnostic information PhilipsApi.WATER_LEVEL: { FanAttributes.ICON_MAP: {0: ICON.WATER_REFILL, 10: "mdi:water"}, @@ -598,6 +613,14 @@ class PhilipsApi: SWITCH_OFF: 0, DIMMABLE: True, }, + PhilipsApi.NEW2_DISPLAY_BACKLIGHT2: { + ATTR_ICON: ICON.LIGHT_DIMMING_BUTTON, + FanAttributes.LABEL: FanAttributes.DISPLAY_BACKLIGHT, + CONF_ENTITY_CATEGORY: EntityCategory.CONFIG, + SWITCH_ON: 100, + SWITCH_OFF: 0, + DIMMABLE: True, + }, } SELECT_TYPES: dict[str, SelectDescription] = { diff --git a/custom_components/philips_airpurifier_coap/philips.py b/custom_components/philips_airpurifier_coap/philips.py index 0ae500b..5e2daca 100644 --- a/custom_components/philips_airpurifier_coap/philips.py +++ b/custom_components/philips_airpurifier_coap/philips.py @@ -574,7 +574,7 @@ class PhilipsNew2GenericCoAPFan(PhilipsGenericCoAPFanBase): ), ] - AVAILABLE_LIGHTS = [PhilipsApi.NEW2_DISPLAY_BACKLIGHT] + AVAILABLE_LIGHTS = [] AVAILABLE_SWITCHES = [] AVAILABLE_SELECTS = [] @@ -1518,12 +1518,15 @@ class PhilipsAC5659(PhilipsGenericCoAPFan): class PhilipsAMF765(PhilipsNew2GenericCoAPFan): """AMF765.""" + AVAILABLE_LIGHTS = [PhilipsApi.NEW2_DISPLAY_BACKLIGHT] AVAILABLE_SWITCHES = [PhilipsApi.NEW2_CHILD_LOCK] class PhilipsCX5120(PhilipsNew2GenericCoAPFan): """CX5120.""" + AVAILABLE_LIGHTS = [PhilipsApi.NEW2_DISPLAY_BACKLIGHT2] + model_to_class = { FanModel.AC0850: PhilipsAC0850, From 9927475b09dde5da6e557062576d196efcc02ff1 Mon Sep 17 00:00:00 2001 From: kongo09 Date: Thu, 11 Jan 2024 23:48:03 +0100 Subject: [PATCH 17/73] add new icons --- custom_components/philips_airpurifier_coap/const.py | 5 +++++ .../philips_airpurifier_coap/icons/pap/circulate.svg | 4 ++++ .../philips_airpurifier_coap/icons/pap/clean.svg | 4 ++++ .../philips_airpurifier_coap/icons/pap/mode.svg | 4 ++++ .../philips_airpurifier_coap/icons/pap/pm25b.svg | 4 ++++ .../philips_airpurifier_coap/icons/pap/rotate.svg | 7 +++++++ 6 files changed, 28 insertions(+) create mode 100644 custom_components/philips_airpurifier_coap/icons/pap/circulate.svg create mode 100644 custom_components/philips_airpurifier_coap/icons/pap/clean.svg create mode 100644 custom_components/philips_airpurifier_coap/icons/pap/mode.svg create mode 100644 custom_components/philips_airpurifier_coap/icons/pap/pm25b.svg create mode 100644 custom_components/philips_airpurifier_coap/icons/pap/rotate.svg diff --git a/custom_components/philips_airpurifier_coap/const.py b/custom_components/philips_airpurifier_coap/const.py index 4f42184..1a256a3 100644 --- a/custom_components/philips_airpurifier_coap/const.py +++ b/custom_components/philips_airpurifier_coap/const.py @@ -64,6 +64,11 @@ class ICON(StrEnum): PREFILTER_WICK_CLEANING = "pap:prefilter_wick_cleaning" PM25 = "pap:pm25" IAI = "pap:iai" + PM25B = "pap:pm25b" + CIRCULATE = "pap:circulate" + CLEAN = "pap:clean" + MODE = "pap:mode" + ROTATE = "pap:rotate" DATA_EXTRA_MODULE_URL = "frontend_extra_module_url" diff --git a/custom_components/philips_airpurifier_coap/icons/pap/circulate.svg b/custom_components/philips_airpurifier_coap/icons/pap/circulate.svg new file mode 100644 index 0000000..e2cc318 --- /dev/null +++ b/custom_components/philips_airpurifier_coap/icons/pap/circulate.svg @@ -0,0 +1,4 @@ + + + + diff --git a/custom_components/philips_airpurifier_coap/icons/pap/clean.svg b/custom_components/philips_airpurifier_coap/icons/pap/clean.svg new file mode 100644 index 0000000..ade5e26 --- /dev/null +++ b/custom_components/philips_airpurifier_coap/icons/pap/clean.svg @@ -0,0 +1,4 @@ + + + + diff --git a/custom_components/philips_airpurifier_coap/icons/pap/mode.svg b/custom_components/philips_airpurifier_coap/icons/pap/mode.svg new file mode 100644 index 0000000..7095a29 --- /dev/null +++ b/custom_components/philips_airpurifier_coap/icons/pap/mode.svg @@ -0,0 +1,4 @@ + + + + diff --git a/custom_components/philips_airpurifier_coap/icons/pap/pm25b.svg b/custom_components/philips_airpurifier_coap/icons/pap/pm25b.svg new file mode 100644 index 0000000..b7acf73 --- /dev/null +++ b/custom_components/philips_airpurifier_coap/icons/pap/pm25b.svg @@ -0,0 +1,4 @@ + + + + diff --git a/custom_components/philips_airpurifier_coap/icons/pap/rotate.svg b/custom_components/philips_airpurifier_coap/icons/pap/rotate.svg new file mode 100644 index 0000000..bf213ce --- /dev/null +++ b/custom_components/philips_airpurifier_coap/icons/pap/rotate.svg @@ -0,0 +1,7 @@ + + + + + + + From cd1d96ca5f618fdb1b21942651f671070eb9e313 Mon Sep 17 00:00:00 2001 From: kongo09 Date: Thu, 11 Jan 2024 23:58:04 +0100 Subject: [PATCH 18/73] add swing for CX --- custom_components/philips_airpurifier_coap/const.py | 9 +++++++++ custom_components/philips_airpurifier_coap/philips.py | 1 + 2 files changed, 10 insertions(+) diff --git a/custom_components/philips_airpurifier_coap/const.py b/custom_components/philips_airpurifier_coap/const.py index 1a256a3..f30d49e 100644 --- a/custom_components/philips_airpurifier_coap/const.py +++ b/custom_components/philips_airpurifier_coap/const.py @@ -230,6 +230,7 @@ class FanAttributes(StrEnum): WARN_VALUE = "warn_value" WARN_ICON = "warn_icon" RSSI = "rssi" + SWING = "swing" class FanUnits(StrEnum): @@ -332,6 +333,7 @@ class PhilipsApi: NEW2_FILTER_NANOPROTECT_PREFILTER_TOTAL = "D05207" NEW2_FILTER_NANOPROTECT_TOTAL = "D05408" NEW2_FAN_SPEED = "D0310D" + NEW2_SWING = "D0320F" PREFERRED_INDEX_MAP = { "0": ("Indoor Allergen Index", ICON.IAI), @@ -585,6 +587,13 @@ class PhilipsApi: SWITCH_ON: 100, SWITCH_OFF: 0, }, + PhilipsApi.NEW2_SWING: { + ATTR_ICON: ICON.ROTATE, + FanAttributes.LABEL: FanAttributes.SWING, + CONF_ENTITY_CATEGORY: EntityCategory.CONFIG, + SWITCH_ON: 17920, + SWITCH_OFF: 0, + }, } LIGHT_TYPES: dict[str, LightDescription] = { diff --git a/custom_components/philips_airpurifier_coap/philips.py b/custom_components/philips_airpurifier_coap/philips.py index 5e2daca..9c6b7f8 100644 --- a/custom_components/philips_airpurifier_coap/philips.py +++ b/custom_components/philips_airpurifier_coap/philips.py @@ -1526,6 +1526,7 @@ class PhilipsCX5120(PhilipsNew2GenericCoAPFan): """CX5120.""" AVAILABLE_LIGHTS = [PhilipsApi.NEW2_DISPLAY_BACKLIGHT2] + AVAILABLE_SWITCHES = [PhilipsApi.NEW2_SWING] model_to_class = { From 07dd64adec44da9f933a79fb0d02e13f5609ed5a Mon Sep 17 00:00:00 2001 From: kongo09 Date: Fri, 12 Jan 2024 00:10:09 +0100 Subject: [PATCH 19/73] add circulation function --- custom_components/philips_airpurifier_coap/const.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/custom_components/philips_airpurifier_coap/const.py b/custom_components/philips_airpurifier_coap/const.py index f30d49e..5b46697 100644 --- a/custom_components/philips_airpurifier_coap/const.py +++ b/custom_components/philips_airpurifier_coap/const.py @@ -334,6 +334,7 @@ class PhilipsApi: NEW2_FILTER_NANOPROTECT_TOTAL = "D05408" NEW2_FAN_SPEED = "D0310D" NEW2_SWING = "D0320F" + NEW2_CIRCULATION = "D0310A" PREFERRED_INDEX_MAP = { "0": ("Indoor Allergen Index", ICON.IAI), @@ -352,6 +353,10 @@ class PhilipsApi: "P": ("Purification", ICON.PURIFICATION_ONLY_MODE), "PH": ("Purification and Humidification", ICON.TWO_IN_ONE_MODE), } + CIRCULATION_MAP = { + "1": ("Purification", ICON.CLEAN), + "2": ("Circulation", ICON.CIRCULATE), + } HUMIDITY_TARGET_MAP = { 40: ("40%", ICON.HUMIDITY_BUTTON), 50: ("50%", ICON.HUMIDITY_BUTTON), @@ -668,4 +673,9 @@ class PhilipsApi: CONF_ENTITY_CATEGORY: EntityCategory.CONFIG, OPTIONS: PhilipsApi.NEW_PREFERRED_INDEX_MAP, }, + PhilipsApi.NEW2_CIRCULATION: { + FanAttributes.LABEL: FanAttributes.FUNCTION, + CONF_ENTITY_CATEGORY: EntityCategory.CONFIG, + OPTIONS: PhilipsApi.CIRCULATION_MAP, + }, } From d5cf0b5fbba1615afb86585015a76d3589e71834 Mon Sep 17 00:00:00 2001 From: kongo09 Date: Mon, 15 Jan 2024 13:49:34 +0100 Subject: [PATCH 20/73] fix speed sensor --- .../philips_airpurifier_coap/const.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/custom_components/philips_airpurifier_coap/const.py b/custom_components/philips_airpurifier_coap/const.py index 5b46697..4416fe3 100644 --- a/custom_components/philips_airpurifier_coap/const.py +++ b/custom_components/philips_airpurifier_coap/const.py @@ -231,6 +231,7 @@ class FanAttributes(StrEnum): WARN_ICON = "warn_icon" RSSI = "rssi" SWING = "swing" + TURBO = "turbo" class FanUnits(StrEnum): @@ -460,16 +461,17 @@ class PhilipsApi: FanAttributes.UNIT: UnitOfTemperature.CELSIUS, }, PhilipsApi.NEW2_FAN_SPEED: { - ATTR_DEVICE_CLASS: SensorDeviceClass.SPEED, FanAttributes.ICON_MAP: { - 0: "mdi:thermometer-low", - 17: "mdi:thermometer", - 23: "mdi:thermometer-high", + 0: ICON.FAN_SPEED_BUTTON, + 1: ICON.SPEED_1, + 6: ICON.SPEED_2, + 18: ICON.SPEED_3, }, - FanAttributes.LABEL: ATTR_TEMPERATURE, - FanAttributes.VALUE: lambda value, _: value / 10, + FanAttributes.VALUE: lambda value, _: value + if int(value) < 18 + else FanAttributes.TURBO, + FanAttributes.LABEL: FanAttributes.ACTUAL_FAN_SPEED, ATTR_STATE_CLASS: SensorStateClass.MEASUREMENT, - FanAttributes.UNIT: UnitOfTemperature.CELSIUS, }, # diagnostic information PhilipsApi.WATER_LEVEL: { From f19d92041d1a0d4ed9b180134dc35d88aa79b76b Mon Sep 17 00:00:00 2001 From: kongo09 Date: Mon, 15 Jan 2024 23:55:28 +0100 Subject: [PATCH 21/73] fix circulation select --- custom_components/philips_airpurifier_coap/philips.py | 1 + 1 file changed, 1 insertion(+) diff --git a/custom_components/philips_airpurifier_coap/philips.py b/custom_components/philips_airpurifier_coap/philips.py index 9c6b7f8..7b5fcbe 100644 --- a/custom_components/philips_airpurifier_coap/philips.py +++ b/custom_components/philips_airpurifier_coap/philips.py @@ -1520,6 +1520,7 @@ class PhilipsAMF765(PhilipsNew2GenericCoAPFan): AVAILABLE_LIGHTS = [PhilipsApi.NEW2_DISPLAY_BACKLIGHT] AVAILABLE_SWITCHES = [PhilipsApi.NEW2_CHILD_LOCK] + AVAILABLE_SELECTS = [PhilipsApi.NEW2_CIRCULATION] class PhilipsCX5120(PhilipsNew2GenericCoAPFan): From edeb5d73bc8778403526ae22b90f8b806ae5d0ab Mon Sep 17 00:00:00 2001 From: kongo09 Date: Tue, 16 Jan 2024 01:44:28 +0100 Subject: [PATCH 22/73] added oscillation for AMF --- .../philips_airpurifier_coap/__init__.py | 2 +- .../philips_airpurifier_coap/const.py | 22 +++ .../icons/pap/oscillate.svg | 4 + .../philips_airpurifier_coap/model.py | 13 ++ .../philips_airpurifier_coap/number.py | 126 ++++++++++++++++++ .../philips_airpurifier_coap/philips.py | 2 + 6 files changed, 168 insertions(+), 1 deletion(-) create mode 100644 custom_components/philips_airpurifier_coap/icons/pap/oscillate.svg create mode 100644 custom_components/philips_airpurifier_coap/number.py diff --git a/custom_components/philips_airpurifier_coap/__init__.py b/custom_components/philips_airpurifier_coap/__init__.py index ac48208..51b8e60 100644 --- a/custom_components/philips_airpurifier_coap/__init__.py +++ b/custom_components/philips_airpurifier_coap/__init__.py @@ -32,7 +32,7 @@ _LOGGER = logging.getLogger(__name__) -PLATFORMS = ["fan", "sensor", "switch", "light", "select"] +PLATFORMS = ["fan", "sensor", "switch", "light", "select", "number"] # icons code thanks to Thomas Loven: diff --git a/custom_components/philips_airpurifier_coap/const.py b/custom_components/philips_airpurifier_coap/const.py index 4416fe3..bac3351 100644 --- a/custom_components/philips_airpurifier_coap/const.py +++ b/custom_components/philips_airpurifier_coap/const.py @@ -24,6 +24,7 @@ from .model import ( FilterDescription, LightDescription, + NumberDescription, SelectDescription, SensorDescription, SwitchDescription, @@ -69,6 +70,7 @@ class ICON(StrEnum): CLEAN = "pap:clean" MODE = "pap:mode" ROTATE = "pap:rotate" + OSCILLATE = "pap:oscillate" DATA_EXTRA_MODULE_URL = "frontend_extra_module_url" @@ -232,6 +234,12 @@ class FanAttributes(StrEnum): RSSI = "rssi" SWING = "swing" TURBO = "turbo" + OSCILLATION = "oscillation" + VALUE_LIST = "value_list" + OFF = "off" + MIN = "min" + MAX = "max" + STEP = "step" class FanUnits(StrEnum): @@ -336,6 +344,7 @@ class PhilipsApi: NEW2_FAN_SPEED = "D0310D" NEW2_SWING = "D0320F" NEW2_CIRCULATION = "D0310A" + NEW2_OSCILLATION = "D0320F" PREFERRED_INDEX_MAP = { "0": ("Indoor Allergen Index", ICON.IAI), @@ -681,3 +690,16 @@ class PhilipsApi: OPTIONS: PhilipsApi.CIRCULATION_MAP, }, } + +NUMBER_TYPES: dict[str, NumberDescription] = { + PhilipsApi.NEW2_OSCILLATION: { + FanAttributes.LABEL: FanAttributes.OSCILLATION, + ATTR_ICON: ICON.OSCILLATE, + CONF_ENTITY_CATEGORY: EntityCategory.CONFIG, + FanAttributes.UNIT: "°", + FanAttributes.OFF: 0, + FanAttributes.MIN: 45, + FanAttributes.MAX: 350, + FanAttributes.STEP: 5, + } +} diff --git a/custom_components/philips_airpurifier_coap/icons/pap/oscillate.svg b/custom_components/philips_airpurifier_coap/icons/pap/oscillate.svg new file mode 100644 index 0000000..ca7f6d3 --- /dev/null +++ b/custom_components/philips_airpurifier_coap/icons/pap/oscillate.svg @@ -0,0 +1,4 @@ + + + + diff --git a/custom_components/philips_airpurifier_coap/model.py b/custom_components/philips_airpurifier_coap/model.py index 069cefc..b43a0f4 100644 --- a/custom_components/philips_airpurifier_coap/model.py +++ b/custom_components/philips_airpurifier_coap/model.py @@ -65,3 +65,16 @@ class SelectDescription(TypedDict): label: str entity_category: str options: dict[Any, tuple[str, str]] + + +class NumberDescription(TypedDict): + """Number class.""" + + icon: str + label: str + entity_category: str + unit: str + off: int + min: int + max: int + step: int diff --git a/custom_components/philips_airpurifier_coap/number.py b/custom_components/philips_airpurifier_coap/number.py new file mode 100644 index 0000000..c7ba878 --- /dev/null +++ b/custom_components/philips_airpurifier_coap/number.py @@ -0,0 +1,126 @@ +"""Philips Air Purifier & Humidifier Numbers.""" +from __future__ import annotations + +from collections.abc import Callable +import logging +from typing import Any + +from homeassistant.components.number import NumberEntity +from homeassistant.config_entries import ConfigEntry +from homeassistant.const import ( + ATTR_DEVICE_CLASS, + ATTR_ICON, + CONF_ENTITY_CATEGORY, + CONF_HOST, + CONF_NAME, +) +from homeassistant.core import HomeAssistant +from homeassistant.exceptions import PlatformNotReady +from homeassistant.helpers.entity import Entity + +from .const import ( + CONF_MODEL, + DATA_KEY_COORDINATOR, + DOMAIN, + NUMBER_TYPES, + FanAttributes, + PhilipsApi, +) +from .philips import Coordinator, PhilipsEntity, model_to_class + +_LOGGER = logging.getLogger(__name__) + + +async def async_setup_entry( + hass: HomeAssistant, + entry: ConfigEntry, + async_add_entities: Callable[[list[Entity], bool], None], +) -> None: + """Set up the number platform.""" + _LOGGER.debug("async_setup_entry called for platform number") + + host = entry.data[CONF_HOST] + model = entry.data[CONF_MODEL] + name = entry.data[CONF_NAME] + + data = hass.data[DOMAIN][host] + + coordinator = data[DATA_KEY_COORDINATOR] + + model_class = model_to_class.get(model) + if model_class: + available_numbers = [] + + for cls in reversed(model_class.__mro__): + cls_available_numbers = getattr(cls, "AVAILABLE_NUMBERS", []) + available_numbers.extend(cls_available_numbers) + + numbers = [] + + for number in NUMBER_TYPES: + if number in available_numbers: + numbers.append(PhilipsNumber(coordinator, name, model, number)) + + async_add_entities(numbers, update_before_add=False) + + else: + _LOGGER.error("Unsupported model: %s", model) + return + + +class PhilipsNumber(PhilipsEntity, NumberEntity): + """Define a Philips AirPurifier number.""" + + def __init__( # noqa: D107 + self, coordinator: Coordinator, name: str, model: str, number: str + ) -> None: + super().__init__(coordinator) + self._model = model + self._description = NUMBER_TYPES[number] + self._attr_device_class = self._description.get(ATTR_DEVICE_CLASS) + label = FanAttributes.LABEL + label = label.partition("#")[0] + self._attr_name = f"{name} {self._description[label].replace('_', ' ').title()}" + self._attr_entity_category = self._description.get(CONF_ENTITY_CATEGORY) + self._attr_icon = self._description.get(ATTR_ICON) + self._attr_mode = "slider" # hardwired for now + self._attr_unit_of_measurement = self._description.get(FanAttributes.UNIT) + + self._attr_min = self._description.get(FanAttributes.OFF) + self._min = self._description.get(FanAttributes.MIN) + self._attr_max = self._description.get(FanAttributes.MAX) + self._attr_step = self._description.get(FanAttributes.STEP) + + try: + device_id = self._device_status[PhilipsApi.DEVICE_ID] + self._attr_unique_id = f"{self._model}-{device_id}-{number.lower()}" + except Exception as e: + _LOGGER.error("Failed retrieving unique_id: %s", e) + raise PlatformNotReady + self._attrs: dict[str, Any] = {} + self.kind = number + + @property + def native_value(self) -> float | None: + """Return the current number.""" + value = self._device_status.get(self.kind) + return value + + async def async_set_native_value(self, value: float) -> None: + """Select a number.""" + + _LOGGER.debug("async_set_native_value called with: %s", value) + + # Catch the boundaries + if value is None or value < 0: + value = 0 + if value % self._attr_step > 0: + value = value // self._attr_step * self._attr_step + if value > 0 and value < self._min: + value = self._min + if value > self._attr_max: + value = self._attr_max + + _LOGGER.debug("setting number with: %s", value) + + await self.coordinator.client.set_control_value(self.kind, int(value)) diff --git a/custom_components/philips_airpurifier_coap/philips.py b/custom_components/philips_airpurifier_coap/philips.py index 7b5fcbe..f408bc2 100644 --- a/custom_components/philips_airpurifier_coap/philips.py +++ b/custom_components/philips_airpurifier_coap/philips.py @@ -283,6 +283,7 @@ class PhilipsGenericCoAPFanBase(PhilipsGenericFan): AVAILABLE_ATTRIBUTES = [] AVAILABLE_SWITCHES = [] AVAILABLE_LIGHTS = [] + AVAILABLE_NUMBERS = [] KEY_PHILIPS_POWER = PhilipsApi.POWER STATE_POWER_ON = "1" @@ -1521,6 +1522,7 @@ class PhilipsAMF765(PhilipsNew2GenericCoAPFan): AVAILABLE_LIGHTS = [PhilipsApi.NEW2_DISPLAY_BACKLIGHT] AVAILABLE_SWITCHES = [PhilipsApi.NEW2_CHILD_LOCK] AVAILABLE_SELECTS = [PhilipsApi.NEW2_CIRCULATION] + AVAILABLE_NUMBERS = [PhilipsApi.NEW2_OSCILLATION] class PhilipsCX5120(PhilipsNew2GenericCoAPFan): From c0ce7354ee84be8445ab23cd17c371715e626b8c Mon Sep 17 00:00:00 2001 From: kongo09 Date: Wed, 17 Jan 2024 00:58:22 +0100 Subject: [PATCH 23/73] exclude unavailable sensor from CX --- .../philips_airpurifier_coap/philips.py | 1 + .../philips_airpurifier_coap/sensor.py | 15 +++++++++------ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/custom_components/philips_airpurifier_coap/philips.py b/custom_components/philips_airpurifier_coap/philips.py index f408bc2..efc3dcd 100644 --- a/custom_components/philips_airpurifier_coap/philips.py +++ b/custom_components/philips_airpurifier_coap/philips.py @@ -1530,6 +1530,7 @@ class PhilipsCX5120(PhilipsNew2GenericCoAPFan): AVAILABLE_LIGHTS = [PhilipsApi.NEW2_DISPLAY_BACKLIGHT2] AVAILABLE_SWITCHES = [PhilipsApi.NEW2_SWING] + UNAVAILABLE_SENSORS = [PhilipsApi.NEW2_FAN_SPEED] model_to_class = { diff --git a/custom_components/philips_airpurifier_coap/sensor.py b/custom_components/philips_airpurifier_coap/sensor.py index 5709a42..ca05c88 100644 --- a/custom_components/philips_airpurifier_coap/sensor.py +++ b/custom_components/philips_airpurifier_coap/sensor.py @@ -51,19 +51,22 @@ async def async_setup_entry( # noqa: D103 coordinator = data[DATA_KEY_COORDINATOR] status = coordinator.status - sensors = [] - - for sensor in SENSOR_TYPES: - if sensor in status: - sensors.append(PhilipsSensor(coordinator, name, model, sensor)) - model_class = model_to_class.get(model) unavailable_filters = [] + unavailable_sensors = [] if model_class: for cls in reversed(model_class.__mro__): cls_unavailable_filters = getattr(cls, "UNAVAILABLE_FILTERS", []) unavailable_filters.extend(cls_unavailable_filters) + cls_unavailable_sensors = getattr(cls, "UNAVAILABLE_SENSORS", []) + unavailable_sensors.extend(cls_unavailable_sensors) + + sensors = [] + + for sensor in SENSOR_TYPES: + if sensor in status and sensor not in unavailable_sensors: + sensors.append(PhilipsSensor(coordinator, name, model, sensor)) for _filter in FILTER_TYPES: if _filter in status and _filter not in unavailable_filters: From 37c722c115a165b09fec9901fc776c2ea3963f8b Mon Sep 17 00:00:00 2001 From: kongo09 Date: Wed, 17 Jan 2024 01:09:01 +0100 Subject: [PATCH 24/73] fix wording of circulation option --- custom_components/philips_airpurifier_coap/const.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/custom_components/philips_airpurifier_coap/const.py b/custom_components/philips_airpurifier_coap/const.py index bac3351..8e3f62f 100644 --- a/custom_components/philips_airpurifier_coap/const.py +++ b/custom_components/philips_airpurifier_coap/const.py @@ -364,8 +364,8 @@ class PhilipsApi: "PH": ("Purification and Humidification", ICON.TWO_IN_ONE_MODE), } CIRCULATION_MAP = { - "1": ("Purification", ICON.CLEAN), - "2": ("Circulation", ICON.CIRCULATE), + "1": ("Fan", ICON.CLEAN), + "3": ("Circulation", ICON.CIRCULATE), } HUMIDITY_TARGET_MAP = { 40: ("40%", ICON.HUMIDITY_BUTTON), From 78e74c62f1e82e56f8251dd865cdb5bcc22ea475 Mon Sep 17 00:00:00 2001 From: kongo09 Date: Wed, 17 Jan 2024 01:20:59 +0100 Subject: [PATCH 25/73] fix circulation setting --- custom_components/philips_airpurifier_coap/const.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/philips_airpurifier_coap/const.py b/custom_components/philips_airpurifier_coap/const.py index 8e3f62f..e5e5849 100644 --- a/custom_components/philips_airpurifier_coap/const.py +++ b/custom_components/philips_airpurifier_coap/const.py @@ -365,7 +365,7 @@ class PhilipsApi: } CIRCULATION_MAP = { "1": ("Fan", ICON.CLEAN), - "3": ("Circulation", ICON.CIRCULATE), + "2": ("Circulation", ICON.CIRCULATE), } HUMIDITY_TARGET_MAP = { 40: ("40%", ICON.HUMIDITY_BUTTON), From a8f5adc0562ecc12512a91b68e5b3734f0184ca0 Mon Sep 17 00:00:00 2001 From: kongo09 Date: Wed, 17 Jan 2024 01:24:47 +0100 Subject: [PATCH 26/73] fix number slider --- .../philips_airpurifier_coap/number.py | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/custom_components/philips_airpurifier_coap/number.py b/custom_components/philips_airpurifier_coap/number.py index c7ba878..f3b5c9b 100644 --- a/custom_components/philips_airpurifier_coap/number.py +++ b/custom_components/philips_airpurifier_coap/number.py @@ -84,12 +84,14 @@ def __init__( # noqa: D107 self._attr_entity_category = self._description.get(CONF_ENTITY_CATEGORY) self._attr_icon = self._description.get(ATTR_ICON) self._attr_mode = "slider" # hardwired for now - self._attr_unit_of_measurement = self._description.get(FanAttributes.UNIT) + self._attr_native_unit_of_measurement = self._description.get( + FanAttributes.UNIT + ) - self._attr_min = self._description.get(FanAttributes.OFF) + self._attr_native_min = self._description.get(FanAttributes.OFF) self._min = self._description.get(FanAttributes.MIN) - self._attr_max = self._description.get(FanAttributes.MAX) - self._attr_step = self._description.get(FanAttributes.STEP) + self._attr_native_max = self._description.get(FanAttributes.MAX) + self._attr_native_step = self._description.get(FanAttributes.STEP) try: device_id = self._device_status[PhilipsApi.DEVICE_ID] @@ -112,14 +114,14 @@ async def async_set_native_value(self, value: float) -> None: _LOGGER.debug("async_set_native_value called with: %s", value) # Catch the boundaries - if value is None or value < 0: - value = 0 - if value % self._attr_step > 0: - value = value // self._attr_step * self._attr_step + if value is None or value < self._attr_native_min: + value = self._attr_native_min + if value % self._attr_native_step > 0: + value = value // self._attr_native_step * self._attr_native_step if value > 0 and value < self._min: value = self._min - if value > self._attr_max: - value = self._attr_max + if value > self._attr_native_max: + value = self._attr_native_max _LOGGER.debug("setting number with: %s", value) From 438725578338275c430fc7df88b58b654253d792 Mon Sep 17 00:00:00 2001 From: kongo09 Date: Wed, 17 Jan 2024 23:43:14 +0100 Subject: [PATCH 27/73] add beep switch --- custom_components/philips_airpurifier_coap/philips.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/custom_components/philips_airpurifier_coap/philips.py b/custom_components/philips_airpurifier_coap/philips.py index efc3dcd..33485e5 100644 --- a/custom_components/philips_airpurifier_coap/philips.py +++ b/custom_components/philips_airpurifier_coap/philips.py @@ -1520,7 +1520,7 @@ class PhilipsAMF765(PhilipsNew2GenericCoAPFan): """AMF765.""" AVAILABLE_LIGHTS = [PhilipsApi.NEW2_DISPLAY_BACKLIGHT] - AVAILABLE_SWITCHES = [PhilipsApi.NEW2_CHILD_LOCK] + AVAILABLE_SWITCHES = [PhilipsApi.NEW2_CHILD_LOCK, PhilipsApi.NEW2_BEEP] AVAILABLE_SELECTS = [PhilipsApi.NEW2_CIRCULATION] AVAILABLE_NUMBERS = [PhilipsApi.NEW2_OSCILLATION] @@ -1529,7 +1529,7 @@ class PhilipsCX5120(PhilipsNew2GenericCoAPFan): """CX5120.""" AVAILABLE_LIGHTS = [PhilipsApi.NEW2_DISPLAY_BACKLIGHT2] - AVAILABLE_SWITCHES = [PhilipsApi.NEW2_SWING] + AVAILABLE_SWITCHES = [PhilipsApi.NEW2_SWING, PhilipsApi.NEW2_BEEP] UNAVAILABLE_SENSORS = [PhilipsApi.NEW2_FAN_SPEED] From ce16d167ee0f78efc5876adb5571e2948550c322 Mon Sep 17 00:00:00 2001 From: kongo09 Date: Wed, 17 Jan 2024 23:57:18 +0100 Subject: [PATCH 28/73] add modes for CX --- .../philips_airpurifier_coap/const.py | 5 +++ .../philips_airpurifier_coap/philips.py | 35 +++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/custom_components/philips_airpurifier_coap/const.py b/custom_components/philips_airpurifier_coap/const.py index e5e5849..3c52cf0 100644 --- a/custom_components/philips_airpurifier_coap/const.py +++ b/custom_components/philips_airpurifier_coap/const.py @@ -142,6 +142,9 @@ class PresetMode: TURBO = "turbo" GAS = "gas" POLLUTION = "pollution" + LOW = "low" + HIGH = "high" + VENTILATION = "ventilation" ICON_MAP = { ALLERGEN: ICON.ALLERGEN_MODE, @@ -345,6 +348,8 @@ class PhilipsApi: NEW2_SWING = "D0320F" NEW2_CIRCULATION = "D0310A" NEW2_OSCILLATION = "D0320F" + NEW2_MODE_A = "D0310A" + NEW2_MODE_B = "D0310C" PREFERRED_INDEX_MAP = { "0": ("Indoor Allergen Index", ICON.IAI), diff --git a/custom_components/philips_airpurifier_coap/philips.py b/custom_components/philips_airpurifier_coap/philips.py index 33485e5..46b4d41 100644 --- a/custom_components/philips_airpurifier_coap/philips.py +++ b/custom_components/philips_airpurifier_coap/philips.py @@ -1528,6 +1528,41 @@ class PhilipsAMF765(PhilipsNew2GenericCoAPFan): class PhilipsCX5120(PhilipsNew2GenericCoAPFan): """CX5120.""" + AVAILABLE_PRESET_MODES = { + PresetMode.AUTO: { + PhilipsApi.NEW2_POWER: 1, + PhilipsApi.NEW2_MODE_A: 3, + PhilipsApi.NEW2_MODE_B: 0, + }, + PresetMode.HIGH: { + PhilipsApi.POWER: 1, + PhilipsApi.NEW2_MODE_A: 3, + PhilipsApi.NEW2_MODE_B: 65, + }, + PresetMode.LOW: { + PhilipsApi.POWER: 1, + PhilipsApi.NEW2_MODE_A: 3, + PhilipsApi.NEW2_MODE_B: 66, + }, + PresetMode.VENTILATION: { + PhilipsApi.POWER: 1, + PhilipsApi.NEW2_MODE_A: 1, + PhilipsApi.NEW2_MODE_B: -127, + }, + } + AVAILABLE_SPEEDS = { + PresetMode.HIGH: { + PhilipsApi.POWER: 1, + PhilipsApi.NEW2_MODE_A: 3, + PhilipsApi.NEW2_MODE_B: 65, + }, + PresetMode.LOW: { + PhilipsApi.POWER: 1, + PhilipsApi.NEW2_MODE_A: 3, + PhilipsApi.NEW2_MODE_B: 66, + }, + } + AVAILABLE_LIGHTS = [PhilipsApi.NEW2_DISPLAY_BACKLIGHT2] AVAILABLE_SWITCHES = [PhilipsApi.NEW2_SWING, PhilipsApi.NEW2_BEEP] UNAVAILABLE_SENSORS = [PhilipsApi.NEW2_FAN_SPEED] From c9b3ad2dcca94ca4c298e59dc85eb12fff1cf62a Mon Sep 17 00:00:00 2001 From: kongo09 Date: Thu, 18 Jan 2024 00:28:05 +0100 Subject: [PATCH 29/73] add timer for CX --- .../philips_airpurifier_coap/const.py | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/custom_components/philips_airpurifier_coap/const.py b/custom_components/philips_airpurifier_coap/const.py index 3c52cf0..d0042a1 100644 --- a/custom_components/philips_airpurifier_coap/const.py +++ b/custom_components/philips_airpurifier_coap/const.py @@ -243,6 +243,7 @@ class FanAttributes(StrEnum): MIN = "min" MAX = "max" STEP = "step" + TIMER = "timer" class FanUnits(StrEnum): @@ -350,6 +351,7 @@ class PhilipsApi: NEW2_OSCILLATION = "D0320F" NEW2_MODE_A = "D0310A" NEW2_MODE_B = "D0310C" + NEW2_TIMER = "D03110" PREFERRED_INDEX_MAP = { "0": ("Indoor Allergen Index", ICON.IAI), @@ -372,6 +374,21 @@ class PhilipsApi: "1": ("Fan", ICON.CLEAN), "2": ("Circulation", ICON.CIRCULATE), } + TIMER_MAP = { + 0: ("Off", "mdi:clock-plus"), + 2: ("1h", "mdi:clock-time-one"), + 3: ("2h", "mdi:clock-time-two"), + 4: ("3h", "mdi:clock-time-three"), + 5: ("4h", "mdi:clock-time-four"), + 6: ("5h", "mdi:clock-time-five"), + 7: ("6h", "mdi:clock-time-six"), + 8: ("7h", "mdi:clock-time-seven"), + 9: ("8h", "mdi:clock-time-eight"), + 10: ("9h", "mdi:clock-time-nine"), + 11: ("10h", "mdi:clock-time-ten"), + 12: ("11h", "mdi:clock-time-eleven"), + 13: ("12h", "mdi:clock-time-twelve"), + } HUMIDITY_TARGET_MAP = { 40: ("40%", ICON.HUMIDITY_BUTTON), 50: ("50%", ICON.HUMIDITY_BUTTON), @@ -694,6 +711,11 @@ class PhilipsApi: CONF_ENTITY_CATEGORY: EntityCategory.CONFIG, OPTIONS: PhilipsApi.CIRCULATION_MAP, }, + PhilipsApi.NEW2_TIMER: { + FanAttributes.LABEL: FanAttributes.TIMER, + CONF_ENTITY_CATEGORY: EntityCategory.CONFIG, + OPTIONS: PhilipsApi.TIMER_MAP, + }, } NUMBER_TYPES: dict[str, NumberDescription] = { From b5499b5aaa77e64e3d7ab16473be37e5a177c89e Mon Sep 17 00:00:00 2001 From: kongo09 Date: Thu, 18 Jan 2024 00:35:12 +0100 Subject: [PATCH 30/73] add missing select for CX --- custom_components/philips_airpurifier_coap/philips.py | 1 + 1 file changed, 1 insertion(+) diff --git a/custom_components/philips_airpurifier_coap/philips.py b/custom_components/philips_airpurifier_coap/philips.py index 46b4d41..501e03b 100644 --- a/custom_components/philips_airpurifier_coap/philips.py +++ b/custom_components/philips_airpurifier_coap/philips.py @@ -1566,6 +1566,7 @@ class PhilipsCX5120(PhilipsNew2GenericCoAPFan): AVAILABLE_LIGHTS = [PhilipsApi.NEW2_DISPLAY_BACKLIGHT2] AVAILABLE_SWITCHES = [PhilipsApi.NEW2_SWING, PhilipsApi.NEW2_BEEP] UNAVAILABLE_SENSORS = [PhilipsApi.NEW2_FAN_SPEED] + AVAILABLE_SELECTS = [PhilipsApi.NEW2_TIMER] model_to_class = { From af79edd30edc06a6d839bc744eb3ddc1397cce18 Mon Sep 17 00:00:00 2001 From: kongo09 Date: Thu, 18 Jan 2024 00:42:06 +0100 Subject: [PATCH 31/73] add target temp for CX --- .../philips_airpurifier_coap/const.py | 14 +++++++++++++- .../philips_airpurifier_coap/philips.py | 1 + 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/custom_components/philips_airpurifier_coap/const.py b/custom_components/philips_airpurifier_coap/const.py index d0042a1..d3e2d98 100644 --- a/custom_components/philips_airpurifier_coap/const.py +++ b/custom_components/philips_airpurifier_coap/const.py @@ -244,6 +244,7 @@ class FanAttributes(StrEnum): MAX = "max" STEP = "step" TIMER = "timer" + TARGET_TEMP = "target_temperature" class FanUnits(StrEnum): @@ -352,6 +353,7 @@ class PhilipsApi: NEW2_MODE_A = "D0310A" NEW2_MODE_B = "D0310C" NEW2_TIMER = "D03110" + NEW2_TARGET_TEMP = "D0310E" PREFERRED_INDEX_MAP = { "0": ("Indoor Allergen Index", ICON.IAI), @@ -728,5 +730,15 @@ class PhilipsApi: FanAttributes.MIN: 45, FanAttributes.MAX: 350, FanAttributes.STEP: 5, - } + }, + PhilipsApi.NEW2_TARGET_TEMP: { + FanAttributes.LABEL: FanAttributes.TARGET_TEMP, + ATTR_ICON: "mdi:thermometer", + CONF_ENTITY_CATEGORY: EntityCategory.CONFIG, + FanAttributes.UNIT: "°", + FanAttributes.OFF: 1, + FanAttributes.MIN: 1, + FanAttributes.MAX: 37, + FanAttributes.STEP: 1, + }, } diff --git a/custom_components/philips_airpurifier_coap/philips.py b/custom_components/philips_airpurifier_coap/philips.py index 501e03b..ddeca08 100644 --- a/custom_components/philips_airpurifier_coap/philips.py +++ b/custom_components/philips_airpurifier_coap/philips.py @@ -1567,6 +1567,7 @@ class PhilipsCX5120(PhilipsNew2GenericCoAPFan): AVAILABLE_SWITCHES = [PhilipsApi.NEW2_SWING, PhilipsApi.NEW2_BEEP] UNAVAILABLE_SENSORS = [PhilipsApi.NEW2_FAN_SPEED] AVAILABLE_SELECTS = [PhilipsApi.NEW2_TIMER] + AVAILABLE_NUMBERS = [PhilipsApi.NEW2_TARGET_TEMP] model_to_class = { From ffeabf3247654baa6b5ce624d94406da77c84295 Mon Sep 17 00:00:00 2001 From: kongo09 Date: Thu, 18 Jan 2024 21:53:21 +0100 Subject: [PATCH 32/73] change string to int for function --- custom_components/philips_airpurifier_coap/const.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/custom_components/philips_airpurifier_coap/const.py b/custom_components/philips_airpurifier_coap/const.py index d3e2d98..cbc5a24 100644 --- a/custom_components/philips_airpurifier_coap/const.py +++ b/custom_components/philips_airpurifier_coap/const.py @@ -373,8 +373,8 @@ class PhilipsApi: "PH": ("Purification and Humidification", ICON.TWO_IN_ONE_MODE), } CIRCULATION_MAP = { - "1": ("Fan", ICON.CLEAN), - "2": ("Circulation", ICON.CIRCULATE), + 1: ("Fan", ICON.CLEAN), + 2: ("Circulation", ICON.CIRCULATE), } TIMER_MAP = { 0: ("Off", "mdi:clock-plus"), From ed3c8aa2b1299fdf57543c95314c2002c3e97018 Mon Sep 17 00:00:00 2001 From: kongo09 Date: Thu, 18 Jan 2024 22:54:05 +0100 Subject: [PATCH 33/73] speed and presets for AMF --- .../philips_airpurifier_coap/const.py | 7 +++ .../philips_airpurifier_coap/philips.py | 61 +++++++++++++++++++ 2 files changed, 68 insertions(+) diff --git a/custom_components/philips_airpurifier_coap/const.py b/custom_components/philips_airpurifier_coap/const.py index cbc5a24..1ca2d6f 100644 --- a/custom_components/philips_airpurifier_coap/const.py +++ b/custom_components/philips_airpurifier_coap/const.py @@ -131,6 +131,13 @@ class PresetMode: SPEED_GENTLE_1 = "gentle/speed 1" SPEED_2 = "speed 2" SPEED_3 = "speed 3" + SPEED_4 = "speed 4" + SPEED_5 = "speed 5" + SPEED_6 = "speed 6" + SPEED_7 = "speed 7" + SPEED_8 = "spped 8" + SPEED_9 = "spped 9" + SPEED_10 = "speed 10" ALLERGEN = "allergen" AUTO = "auto" AUTO_GENERAL = "auto general" diff --git a/custom_components/philips_airpurifier_coap/philips.py b/custom_components/philips_airpurifier_coap/philips.py index ddeca08..35d739e 100644 --- a/custom_components/philips_airpurifier_coap/philips.py +++ b/custom_components/philips_airpurifier_coap/philips.py @@ -1519,6 +1519,67 @@ class PhilipsAC5659(PhilipsGenericCoAPFan): class PhilipsAMF765(PhilipsNew2GenericCoAPFan): """AMF765.""" + AVAILABLE_PRESET_MODES = { + PresetMode.AUTO: { + PhilipsApi.POWER: 1, + PhilipsApi.NEW2_MODE_B: 0, + }, + PresetMode.SLEEP: { + PhilipsApi.POWER: 1, + PhilipsApi.NEW2_MODE_B: 17, + }, + PresetMode.TURBO: { + PhilipsApi.POWER: 1, + PhilipsApi.NEW2_MODE_B: 18, + }, + } + AVAILABLE_SPEEDS = { + PresetMode.SPEED_1: { + PhilipsApi.POWER: 1, + PhilipsApi.NEW2_MODE_B: 1, + }, + PresetMode.SPEED_2: { + PhilipsApi.POWER: 1, + PhilipsApi.NEW2_MODE_B: 2, + }, + PresetMode.SPEED_3: { + PhilipsApi.POWER: 1, + PhilipsApi.NEW2_MODE_B: 3, + }, + PresetMode.SPEED_4: { + PhilipsApi.POWER: 1, + PhilipsApi.NEW2_MODE_B: 4, + }, + PresetMode.SPEED_5: { + PhilipsApi.POWER: 1, + PhilipsApi.NEW2_MODE_B: 5, + }, + PresetMode.SPEED_6: { + PhilipsApi.POWER: 1, + PhilipsApi.NEW2_MODE_B: 6, + }, + PresetMode.SPEED_7: { + PhilipsApi.POWER: 1, + PhilipsApi.NEW2_MODE_B: 7, + }, + PresetMode.SPEED_8: { + PhilipsApi.POWER: 1, + PhilipsApi.NEW2_MODE_B: 8, + }, + PresetMode.SPEED_9: { + PhilipsApi.POWER: 1, + PhilipsApi.NEW2_MODE_B: 9, + }, + PresetMode.SPEED_10: { + PhilipsApi.POWER: 1, + PhilipsApi.NEW2_MODE_B: 10, + }, + PresetMode.TURBO: { + PhilipsApi.POWER: 1, + PhilipsApi.NEW2_MODE_B: 18, + }, + } + AVAILABLE_LIGHTS = [PhilipsApi.NEW2_DISPLAY_BACKLIGHT] AVAILABLE_SWITCHES = [PhilipsApi.NEW2_CHILD_LOCK, PhilipsApi.NEW2_BEEP] AVAILABLE_SELECTS = [PhilipsApi.NEW2_CIRCULATION] From 872cd1cb021b9cee4ab681757d2ee7dc05096b60 Mon Sep 17 00:00:00 2001 From: kongo09 Date: Thu, 18 Jan 2024 22:55:55 +0100 Subject: [PATCH 34/73] timer for AMF --- custom_components/philips_airpurifier_coap/const.py | 1 + 1 file changed, 1 insertion(+) diff --git a/custom_components/philips_airpurifier_coap/const.py b/custom_components/philips_airpurifier_coap/const.py index 1ca2d6f..ca5a433 100644 --- a/custom_components/philips_airpurifier_coap/const.py +++ b/custom_components/philips_airpurifier_coap/const.py @@ -385,6 +385,7 @@ class PhilipsApi: } TIMER_MAP = { 0: ("Off", "mdi:clock-plus"), + 1: ("0.5h", "mdi:clock-time-one"), 2: ("1h", "mdi:clock-time-one"), 3: ("2h", "mdi:clock-time-two"), 4: ("3h", "mdi:clock-time-three"), From af4d51ea5c7f0ca16c1363766e7711ecc06b6430 Mon Sep 17 00:00:00 2001 From: kongo09 Date: Thu, 18 Jan 2024 22:57:43 +0100 Subject: [PATCH 35/73] timer for AMF --- custom_components/philips_airpurifier_coap/philips.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/philips_airpurifier_coap/philips.py b/custom_components/philips_airpurifier_coap/philips.py index 35d739e..a699858 100644 --- a/custom_components/philips_airpurifier_coap/philips.py +++ b/custom_components/philips_airpurifier_coap/philips.py @@ -1582,7 +1582,7 @@ class PhilipsAMF765(PhilipsNew2GenericCoAPFan): AVAILABLE_LIGHTS = [PhilipsApi.NEW2_DISPLAY_BACKLIGHT] AVAILABLE_SWITCHES = [PhilipsApi.NEW2_CHILD_LOCK, PhilipsApi.NEW2_BEEP] - AVAILABLE_SELECTS = [PhilipsApi.NEW2_CIRCULATION] + AVAILABLE_SELECTS = [PhilipsApi.NEW2_CIRCULATION, PhilipsApi.NEW2_TIMER] AVAILABLE_NUMBERS = [PhilipsApi.NEW2_OSCILLATION] From 910cacdff36b95752de151e6ccc91dea78b77b85 Mon Sep 17 00:00:00 2001 From: kongo09 Date: Thu, 18 Jan 2024 23:02:09 +0100 Subject: [PATCH 36/73] add standby sensor switch for AMF --- custom_components/philips_airpurifier_coap/const.py | 8 ++++++++ custom_components/philips_airpurifier_coap/philips.py | 6 +++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/custom_components/philips_airpurifier_coap/const.py b/custom_components/philips_airpurifier_coap/const.py index ca5a433..907add6 100644 --- a/custom_components/philips_airpurifier_coap/const.py +++ b/custom_components/philips_airpurifier_coap/const.py @@ -252,6 +252,7 @@ class FanAttributes(StrEnum): STEP = "step" TIMER = "timer" TARGET_TEMP = "target_temperature" + STANDBY_SENSORS = "standby_sensors" class FanUnits(StrEnum): @@ -361,6 +362,7 @@ class PhilipsApi: NEW2_MODE_B = "D0310C" NEW2_TIMER = "D03110" NEW2_TARGET_TEMP = "D0310E" + NEW2_STANDBY_SENSORS = "D03134" PREFERRED_INDEX_MAP = { "0": ("Indoor Allergen Index", ICON.IAI), @@ -642,6 +644,12 @@ class PhilipsApi: SWITCH_ON: 17920, SWITCH_OFF: 0, }, + PhilipsApi.NEW2_STANDBY_SENSORS: { + ATTR_ICON: "mdi:power-settings", + FanAttributes.LABEL: FanAttributes.STANDBY_SENSORS, + SWITCH_ON: 1, + SWITCH_OFF: 0, + }, } LIGHT_TYPES: dict[str, LightDescription] = { diff --git a/custom_components/philips_airpurifier_coap/philips.py b/custom_components/philips_airpurifier_coap/philips.py index a699858..6a9c36d 100644 --- a/custom_components/philips_airpurifier_coap/philips.py +++ b/custom_components/philips_airpurifier_coap/philips.py @@ -1581,7 +1581,11 @@ class PhilipsAMF765(PhilipsNew2GenericCoAPFan): } AVAILABLE_LIGHTS = [PhilipsApi.NEW2_DISPLAY_BACKLIGHT] - AVAILABLE_SWITCHES = [PhilipsApi.NEW2_CHILD_LOCK, PhilipsApi.NEW2_BEEP] + AVAILABLE_SWITCHES = [ + PhilipsApi.NEW2_CHILD_LOCK, + PhilipsApi.NEW2_BEEP, + PhilipsApi.NEW2_STANDBY_SENSORS, + ] AVAILABLE_SELECTS = [PhilipsApi.NEW2_CIRCULATION, PhilipsApi.NEW2_TIMER] AVAILABLE_NUMBERS = [PhilipsApi.NEW2_OSCILLATION] From b225bf2ae4648dc9f985c2ccb55f725a528bcfde Mon Sep 17 00:00:00 2001 From: kongo09 Date: Thu, 18 Jan 2024 23:12:50 +0100 Subject: [PATCH 37/73] add auto plus for AMF --- custom_components/philips_airpurifier_coap/const.py | 8 ++++++++ custom_components/philips_airpurifier_coap/philips.py | 1 + 2 files changed, 9 insertions(+) diff --git a/custom_components/philips_airpurifier_coap/const.py b/custom_components/philips_airpurifier_coap/const.py index 907add6..2a74cca 100644 --- a/custom_components/philips_airpurifier_coap/const.py +++ b/custom_components/philips_airpurifier_coap/const.py @@ -253,6 +253,7 @@ class FanAttributes(StrEnum): TIMER = "timer" TARGET_TEMP = "target_temperature" STANDBY_SENSORS = "standby_sensors" + AUTO_PLUS = "auto_plus" class FanUnits(StrEnum): @@ -363,6 +364,7 @@ class PhilipsApi: NEW2_TIMER = "D03110" NEW2_TARGET_TEMP = "D0310E" NEW2_STANDBY_SENSORS = "D03134" + NEW2_AUTO_PLUS_AI = "D03180" PREFERRED_INDEX_MAP = { "0": ("Indoor Allergen Index", ICON.IAI), @@ -650,6 +652,12 @@ class PhilipsApi: SWITCH_ON: 1, SWITCH_OFF: 0, }, + PhilipsApi.NEW2_AUTO_PLUS_AI: { + ATTR_ICON: "mdi:format-annotation-plus", + FanAttributes.LABEL: FanAttributes.AUTO_PLUS, + SWITCH_ON: 1, + SWITCH_OFF: 0, + }, } LIGHT_TYPES: dict[str, LightDescription] = { diff --git a/custom_components/philips_airpurifier_coap/philips.py b/custom_components/philips_airpurifier_coap/philips.py index 6a9c36d..ee5a964 100644 --- a/custom_components/philips_airpurifier_coap/philips.py +++ b/custom_components/philips_airpurifier_coap/philips.py @@ -1585,6 +1585,7 @@ class PhilipsAMF765(PhilipsNew2GenericCoAPFan): PhilipsApi.NEW2_CHILD_LOCK, PhilipsApi.NEW2_BEEP, PhilipsApi.NEW2_STANDBY_SENSORS, + PhilipsApi.NEW2_AUTO_PLUS_AI, ] AVAILABLE_SELECTS = [PhilipsApi.NEW2_CIRCULATION, PhilipsApi.NEW2_TIMER] AVAILABLE_NUMBERS = [PhilipsApi.NEW2_OSCILLATION] From 20ee14f75f55aabd8e34da6c4d44c06dfc16b9c4 Mon Sep 17 00:00:00 2001 From: kongo09 Date: Sat, 20 Jan 2024 17:53:34 +0100 Subject: [PATCH 38/73] fix timer for CX --- .../philips_airpurifier_coap/const.py | 20 +++++++++++++++++++ .../philips_airpurifier_coap/philips.py | 2 +- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/custom_components/philips_airpurifier_coap/const.py b/custom_components/philips_airpurifier_coap/const.py index 2a74cca..37e14df 100644 --- a/custom_components/philips_airpurifier_coap/const.py +++ b/custom_components/philips_airpurifier_coap/const.py @@ -403,6 +403,21 @@ class PhilipsApi: 12: ("11h", "mdi:clock-time-eleven"), 13: ("12h", "mdi:clock-time-twelve"), } + TIMER2_MAP = { + 0: ("Off", "mdi:clock-plus"), + 2: ("1h", "mdi:clock-time-one"), + 3: ("2h", "mdi:clock-time-two"), + 4: ("3h", "mdi:clock-time-three"), + 5: ("4h", "mdi:clock-time-four"), + 6: ("5h", "mdi:clock-time-five"), + 7: ("6h", "mdi:clock-time-six"), + 8: ("7h", "mdi:clock-time-seven"), + 9: ("8h", "mdi:clock-time-eight"), + 10: ("9h", "mdi:clock-time-nine"), + 11: ("10h", "mdi:clock-time-ten"), + 12: ("11h", "mdi:clock-time-eleven"), + 13: ("12h", "mdi:clock-time-twelve"), + } HUMIDITY_TARGET_MAP = { 40: ("40%", ICON.HUMIDITY_BUTTON), 50: ("50%", ICON.HUMIDITY_BUTTON), @@ -742,6 +757,11 @@ class PhilipsApi: CONF_ENTITY_CATEGORY: EntityCategory.CONFIG, OPTIONS: PhilipsApi.TIMER_MAP, }, + PhilipsApi.NEW2_TIMER2: { + FanAttributes.LABEL: FanAttributes.TIMER, + CONF_ENTITY_CATEGORY: EntityCategory.CONFIG, + OPTIONS: PhilipsApi.TIMER2_MAP, + }, } NUMBER_TYPES: dict[str, NumberDescription] = { diff --git a/custom_components/philips_airpurifier_coap/philips.py b/custom_components/philips_airpurifier_coap/philips.py index ee5a964..46c1b1e 100644 --- a/custom_components/philips_airpurifier_coap/philips.py +++ b/custom_components/philips_airpurifier_coap/philips.py @@ -1632,7 +1632,7 @@ class PhilipsCX5120(PhilipsNew2GenericCoAPFan): AVAILABLE_LIGHTS = [PhilipsApi.NEW2_DISPLAY_BACKLIGHT2] AVAILABLE_SWITCHES = [PhilipsApi.NEW2_SWING, PhilipsApi.NEW2_BEEP] UNAVAILABLE_SENSORS = [PhilipsApi.NEW2_FAN_SPEED] - AVAILABLE_SELECTS = [PhilipsApi.NEW2_TIMER] + AVAILABLE_SELECTS = [PhilipsApi.NEW2_TIMER2] AVAILABLE_NUMBERS = [PhilipsApi.NEW2_TARGET_TEMP] From 4964ae298acc1f8c155c0b7e3150b372ff0fc252 Mon Sep 17 00:00:00 2001 From: kongo09 Date: Sat, 20 Jan 2024 17:55:07 +0100 Subject: [PATCH 39/73] fix time for CX --- custom_components/philips_airpurifier_coap/const.py | 1 + 1 file changed, 1 insertion(+) diff --git a/custom_components/philips_airpurifier_coap/const.py b/custom_components/philips_airpurifier_coap/const.py index 37e14df..09aab45 100644 --- a/custom_components/philips_airpurifier_coap/const.py +++ b/custom_components/philips_airpurifier_coap/const.py @@ -362,6 +362,7 @@ class PhilipsApi: NEW2_MODE_A = "D0310A" NEW2_MODE_B = "D0310C" NEW2_TIMER = "D03110" + NEW2_TIMER2 = "D03110" NEW2_TARGET_TEMP = "D0310E" NEW2_STANDBY_SENSORS = "D03134" NEW2_AUTO_PLUS_AI = "D03180" From b225a4c8ce8a96cba6eb65d4e7882c7410c8994c Mon Sep 17 00:00:00 2001 From: kongo09 Date: Sat, 20 Jan 2024 17:55:47 +0100 Subject: [PATCH 40/73] fix oscillation for AMF --- custom_components/philips_airpurifier_coap/const.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/philips_airpurifier_coap/const.py b/custom_components/philips_airpurifier_coap/const.py index 09aab45..e470641 100644 --- a/custom_components/philips_airpurifier_coap/const.py +++ b/custom_components/philips_airpurifier_coap/const.py @@ -772,7 +772,7 @@ class PhilipsApi: CONF_ENTITY_CATEGORY: EntityCategory.CONFIG, FanAttributes.UNIT: "°", FanAttributes.OFF: 0, - FanAttributes.MIN: 45, + FanAttributes.MIN: 30, FanAttributes.MAX: 350, FanAttributes.STEP: 5, }, From 8f79ab6d474f042df6afcf717ac8668151725f4f Mon Sep 17 00:00:00 2001 From: kongo09 Date: Sat, 20 Jan 2024 18:57:41 +0100 Subject: [PATCH 41/73] remove speed sensor and change pm25 icon --- .../philips_airpurifier_coap/const.py | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/custom_components/philips_airpurifier_coap/const.py b/custom_components/philips_airpurifier_coap/const.py index e470641..fda2803 100644 --- a/custom_components/philips_airpurifier_coap/const.py +++ b/custom_components/philips_airpurifier_coap/const.py @@ -63,9 +63,9 @@ class ICON(StrEnum): WATER_REFILL = "pap:water_refill" PREFILTER_CLEANING = "pap:prefilter_cleaning" PREFILTER_WICK_CLEANING = "pap:prefilter_wick_cleaning" - PM25 = "pap:pm25" + PM25 = "pap:pm25b" IAI = "pap:iai" - PM25B = "pap:pm25b" + # PM25B = "pap:pm25b" CIRCULATE = "pap:circulate" CLEAN = "pap:clean" MODE = "pap:mode" @@ -521,19 +521,19 @@ class PhilipsApi: ATTR_STATE_CLASS: SensorStateClass.MEASUREMENT, FanAttributes.UNIT: UnitOfTemperature.CELSIUS, }, - PhilipsApi.NEW2_FAN_SPEED: { - FanAttributes.ICON_MAP: { - 0: ICON.FAN_SPEED_BUTTON, - 1: ICON.SPEED_1, - 6: ICON.SPEED_2, - 18: ICON.SPEED_3, - }, - FanAttributes.VALUE: lambda value, _: value - if int(value) < 18 - else FanAttributes.TURBO, - FanAttributes.LABEL: FanAttributes.ACTUAL_FAN_SPEED, - ATTR_STATE_CLASS: SensorStateClass.MEASUREMENT, - }, + # PhilipsApi.NEW2_FAN_SPEED: { + # FanAttributes.ICON_MAP: { + # 0: ICON.FAN_SPEED_BUTTON, + # 1: ICON.SPEED_1, + # 6: ICON.SPEED_2, + # 18: ICON.SPEED_3, + # }, + # FanAttributes.VALUE: lambda value, _: value + # if int(value) < 18 + # else FanAttributes.TURBO, + # FanAttributes.LABEL: FanAttributes.ACTUAL_FAN_SPEED, + # ATTR_STATE_CLASS: SensorStateClass.MEASUREMENT, + # }, # diagnostic information PhilipsApi.WATER_LEVEL: { FanAttributes.ICON_MAP: {0: ICON.WATER_REFILL, 10: "mdi:water"}, From 2519e4987033680f83a8a65d80156e4bee868fb0 Mon Sep 17 00:00:00 2001 From: kongo09 Date: Sat, 20 Jan 2024 18:57:58 +0100 Subject: [PATCH 42/73] fix speed setting for AMF --- custom_components/philips_airpurifier_coap/philips.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/custom_components/philips_airpurifier_coap/philips.py b/custom_components/philips_airpurifier_coap/philips.py index 46c1b1e..458bf8e 100644 --- a/custom_components/philips_airpurifier_coap/philips.py +++ b/custom_components/philips_airpurifier_coap/philips.py @@ -279,7 +279,9 @@ class PhilipsGenericCoAPFanBase(PhilipsGenericFan): """Class as basis to manage a generic Philips CoAP fan.""" AVAILABLE_PRESET_MODES = {} + REPLACE_PRESET = None AVAILABLE_SPEEDS = {} + REPLACE_SPEED = None AVAILABLE_ATTRIBUTES = [] AVAILABLE_SWITCHES = [] AVAILABLE_LIGHTS = [] @@ -386,6 +388,9 @@ def preset_mode(self) -> Optional[str]: """Return the selected preset mode.""" for preset_mode, status_pattern in self._available_preset_modes.items(): for k, v in status_pattern.items(): + # check if the speed sensor also used for presets is different from the setting field + if self.REPLACE_PRESET is not None and k == self.REPLACE_PRESET[0]: + k = self.REPLACE_PRESET[1] if self._device_status.get(k) != v: break else: @@ -407,6 +412,9 @@ def percentage(self) -> Optional[int]: """Return the speed percentages.""" for speed, status_pattern in self._available_speeds.items(): for k, v in status_pattern.items(): + # check if the speed sensor is different from the speed setting field + if self.REPLACE_SPEED is not None and k == self.REPLACE_SPEED[0]: + k = self.REPLACE_SPEED[1] if self._device_status.get(k) != v: break else: @@ -1519,6 +1527,7 @@ class PhilipsAC5659(PhilipsGenericCoAPFan): class PhilipsAMF765(PhilipsNew2GenericCoAPFan): """AMF765.""" + REPLACE_PRESET = [PhilipsApi.NEW2_MODE_B, PhilipsApi.NEW2_FAN_SPEED] AVAILABLE_PRESET_MODES = { PresetMode.AUTO: { PhilipsApi.POWER: 1, @@ -1533,6 +1542,7 @@ class PhilipsAMF765(PhilipsNew2GenericCoAPFan): PhilipsApi.NEW2_MODE_B: 18, }, } + REPLACE_SPEED = [PhilipsApi.NEW2_MODE_B, PhilipsApi.NEW2_FAN_SPEED] AVAILABLE_SPEEDS = { PresetMode.SPEED_1: { PhilipsApi.POWER: 1, From 5871c1c540df1f87c9e9a0bb3008ee7334a146ba Mon Sep 17 00:00:00 2001 From: kongo09 Date: Sat, 20 Jan 2024 23:41:59 +0100 Subject: [PATCH 43/73] make osciallation a fan property --- .../philips_airpurifier_coap/const.py | 21 +++++++---- .../philips_airpurifier_coap/philips.py | 35 ++++++++++++++++++- 2 files changed, 48 insertions(+), 8 deletions(-) diff --git a/custom_components/philips_airpurifier_coap/const.py b/custom_components/philips_airpurifier_coap/const.py index fda2803..7e52be3 100644 --- a/custom_components/philips_airpurifier_coap/const.py +++ b/custom_components/philips_airpurifier_coap/const.py @@ -327,6 +327,11 @@ class PhilipsApi: SWITCH_OFF: "0", } + OSCILLATION_MAP = { + SWITCH_ON: 17920, + SWITCH_OFF: 0, + } + # the AC1715 seems to follow a new scheme, this should later be refactored NEW_NAME = "D01-03" NEW_MODEL_ID = "D01-05" @@ -655,13 +660,15 @@ class PhilipsApi: SWITCH_ON: 100, SWITCH_OFF: 0, }, - PhilipsApi.NEW2_SWING: { - ATTR_ICON: ICON.ROTATE, - FanAttributes.LABEL: FanAttributes.SWING, - CONF_ENTITY_CATEGORY: EntityCategory.CONFIG, - SWITCH_ON: 17920, - SWITCH_OFF: 0, - }, + # Oscillation is part of the fan model, so the switch is removed here + # + # PhilipsApi.NEW2_SWING: { + # ATTR_ICON: ICON.ROTATE, + # FanAttributes.LABEL: FanAttributes.SWING, + # CONF_ENTITY_CATEGORY: EntityCategory.CONFIG, + # SWITCH_ON: 17920, + # SWITCH_OFF: 0, + # }, PhilipsApi.NEW2_STANDBY_SENSORS: { ATTR_ICON: "mdi:power-settings", FanAttributes.LABEL: FanAttributes.STANDBY_SENSORS, diff --git a/custom_components/philips_airpurifier_coap/philips.py b/custom_components/philips_airpurifier_coap/philips.py index 458bf8e..6f42524 100644 --- a/custom_components/philips_airpurifier_coap/philips.py +++ b/custom_components/philips_airpurifier_coap/philips.py @@ -23,6 +23,7 @@ from .const import ( DOMAIN, ICON, + SWITCH_OFF, SWITCH_ON, FanAttributes, FanModel, @@ -291,6 +292,8 @@ class PhilipsGenericCoAPFanBase(PhilipsGenericFan): STATE_POWER_ON = "1" STATE_POWER_OFF = "0" + KEY_OSCILLATION = None + def __init__( # noqa: D107 self, coordinator: Coordinator, @@ -376,6 +379,8 @@ def supported_features(self) -> int: features = FanEntityFeature.PRESET_MODE if self._speeds: features |= FanEntityFeature.SET_SPEED + if self.KEY_OSCILLATION is not None: + features |= FanEntityFeature.OSCILLATE return features @property @@ -407,6 +412,31 @@ def speed_count(self) -> int: """Return the number of speed options.""" return len(self._speeds) + @property + def oscillating(self) -> bool | None: + """Return if the fan is oscillating.""" + if self.KEY_OSCILLATION is None: + return None + + key = next(iter(self.KEY_OSCILLATION)) + status = self._device_status.get(key) + on = self.KEY_OSCILLATION.get(key).get(SWITCH_ON) + return status is not None and status == on + + async def async_oscillate(self, oscillating: bool) -> None: + """Osciallate the fan.""" + if self.KEY_OSCILLATION is None: + return None + + key = next(iter(self.KEY_OSCILLATION)) + values = self.KEY_OSCILLATION.get(key) + on = values.get(SWITCH_ON) + off = values.get(SWITCH_OFF) + if oscillating: + await self.coordinator.client.set_control_value(key, on) + else: + await self.coordinator.client.set_control_value(key, off) + @property def percentage(self) -> Optional[int]: """Return the speed percentages.""" @@ -1638,9 +1668,12 @@ class PhilipsCX5120(PhilipsNew2GenericCoAPFan): PhilipsApi.NEW2_MODE_B: 66, }, } + KEY_OSCILLATION = { + PhilipsApi.NEW2_OSCILLATION: PhilipsApi.OSCILLATION_MAP, + } AVAILABLE_LIGHTS = [PhilipsApi.NEW2_DISPLAY_BACKLIGHT2] - AVAILABLE_SWITCHES = [PhilipsApi.NEW2_SWING, PhilipsApi.NEW2_BEEP] + AVAILABLE_SWITCHES = [PhilipsApi.NEW2_BEEP] UNAVAILABLE_SENSORS = [PhilipsApi.NEW2_FAN_SPEED] AVAILABLE_SELECTS = [PhilipsApi.NEW2_TIMER2] AVAILABLE_NUMBERS = [PhilipsApi.NEW2_TARGET_TEMP] From c8618ff4c211621f8ee35f3ff8c66d648f9dbc7f Mon Sep 17 00:00:00 2001 From: kongo09 Date: Sat, 20 Jan 2024 23:54:34 +0100 Subject: [PATCH 44/73] prepare AMF870 --- custom_components/philips_airpurifier_coap/const.py | 2 +- custom_components/philips_airpurifier_coap/philips.py | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/custom_components/philips_airpurifier_coap/const.py b/custom_components/philips_airpurifier_coap/const.py index 7e52be3..86ecabf 100644 --- a/custom_components/philips_airpurifier_coap/const.py +++ b/custom_components/philips_airpurifier_coap/const.py @@ -17,7 +17,6 @@ PERCENTAGE, SIGNAL_STRENGTH_DECIBELS_MILLIWATT, UnitOfTemperature, - UnitOfTime, ) from homeassistant.helpers.entity import EntityCategory @@ -121,6 +120,7 @@ class FanModel(StrEnum): AC4558 = "AC4558" AC5659 = "AC5659" AMF765 = "AMF765" + AMF870 = "AMF870" CX5120 = "CX5120" diff --git a/custom_components/philips_airpurifier_coap/philips.py b/custom_components/philips_airpurifier_coap/philips.py index 6f42524..0cc2e85 100644 --- a/custom_components/philips_airpurifier_coap/philips.py +++ b/custom_components/philips_airpurifier_coap/philips.py @@ -1631,6 +1631,10 @@ class PhilipsAMF765(PhilipsNew2GenericCoAPFan): AVAILABLE_NUMBERS = [PhilipsApi.NEW2_OSCILLATION] +class PhilipsAMF870(PhilipsAMF765): + """AMF870.""" + + class PhilipsCX5120(PhilipsNew2GenericCoAPFan): """CX5120.""" @@ -1706,5 +1710,6 @@ class PhilipsCX5120(PhilipsNew2GenericCoAPFan): FanModel.AC4558: PhilipsAC4558, FanModel.AC5659: PhilipsAC5659, FanModel.AMF765: PhilipsAMF765, + FanModel.AMF870: PhilipsAMF870, FanModel.CX5120: PhilipsCX5120, } From 09ffbda37a7abf6576f62fb98d3a3402aca201db Mon Sep 17 00:00:00 2001 From: kongo09 Date: Sat, 20 Jan 2024 23:55:48 +0100 Subject: [PATCH 45/73] start support for AMF870 --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index ce69d75..529a842 100644 --- a/README.md +++ b/README.md @@ -79,6 +79,7 @@ Note: `configuration.yaml` is no longer supported and your configuration is not - AC4558 - AC5659 - AMF765 +- AMF870 - CX5120 From 58d64a3e5d67a81758f5b79fe8b3049ae17e1b29 Mon Sep 17 00:00:00 2001 From: kongo09 Date: Sun, 21 Jan 2024 11:45:05 +0100 Subject: [PATCH 46/73] fix pm2.5 sensor for AMF --- custom_components/philips_airpurifier_coap/const.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/philips_airpurifier_coap/const.py b/custom_components/philips_airpurifier_coap/const.py index 86ecabf..c5f5bc5 100644 --- a/custom_components/philips_airpurifier_coap/const.py +++ b/custom_components/philips_airpurifier_coap/const.py @@ -354,7 +354,7 @@ class PhilipsApi: NEW2_CHILD_LOCK = "D03103" NEW2_BEEP = "D03130" NEW2_INDOOR_ALLERGEN_INDEX = "D03120" - NEW2_PM25 = "D03121" + NEW2_PM25 = "D03221" NEW2_HUMIDITY = "D03125" NEW2_FILTER_NANOPROTECT_PREFILTER = "D0520D" NEW2_FILTER_NANOPROTECT = "D0540E" From 2d38799a1210704adf897916dd4f9500200b9d92 Mon Sep 17 00:00:00 2001 From: kongo09 Date: Sun, 21 Jan 2024 11:47:53 +0100 Subject: [PATCH 47/73] remove turbo from speed settings for AMF --- custom_components/philips_airpurifier_coap/philips.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/custom_components/philips_airpurifier_coap/philips.py b/custom_components/philips_airpurifier_coap/philips.py index 0cc2e85..0f0853d 100644 --- a/custom_components/philips_airpurifier_coap/philips.py +++ b/custom_components/philips_airpurifier_coap/philips.py @@ -1614,10 +1614,10 @@ class PhilipsAMF765(PhilipsNew2GenericCoAPFan): PhilipsApi.POWER: 1, PhilipsApi.NEW2_MODE_B: 10, }, - PresetMode.TURBO: { - PhilipsApi.POWER: 1, - PhilipsApi.NEW2_MODE_B: 18, - }, + # PresetMode.TURBO: { + # PhilipsApi.POWER: 1, + # PhilipsApi.NEW2_MODE_B: 18, + # }, } AVAILABLE_LIGHTS = [PhilipsApi.NEW2_DISPLAY_BACKLIGHT] From 5d37ce632852be64125ab7bfff855aa2b9508a78 Mon Sep 17 00:00:00 2001 From: kongo09 Date: Sun, 21 Jan 2024 11:51:51 +0100 Subject: [PATCH 48/73] try to fix speed and preset for AMF --- .../philips_airpurifier_coap/const.py | 1 + .../philips_airpurifier_coap/philips.py | 24 +++++++++---------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/custom_components/philips_airpurifier_coap/const.py b/custom_components/philips_airpurifier_coap/const.py index c5f5bc5..00f793a 100644 --- a/custom_components/philips_airpurifier_coap/const.py +++ b/custom_components/philips_airpurifier_coap/const.py @@ -366,6 +366,7 @@ class PhilipsApi: NEW2_OSCILLATION = "D0320F" NEW2_MODE_A = "D0310A" NEW2_MODE_B = "D0310C" + NEW2_MODE_C = "D0310D" NEW2_TIMER = "D03110" NEW2_TIMER2 = "D03110" NEW2_TARGET_TEMP = "D0310E" diff --git a/custom_components/philips_airpurifier_coap/philips.py b/custom_components/philips_airpurifier_coap/philips.py index 0f0853d..ab21f25 100644 --- a/custom_components/philips_airpurifier_coap/philips.py +++ b/custom_components/philips_airpurifier_coap/philips.py @@ -1557,7 +1557,7 @@ class PhilipsAC5659(PhilipsGenericCoAPFan): class PhilipsAMF765(PhilipsNew2GenericCoAPFan): """AMF765.""" - REPLACE_PRESET = [PhilipsApi.NEW2_MODE_B, PhilipsApi.NEW2_FAN_SPEED] + # REPLACE_PRESET = [PhilipsApi.NEW2_MODE_B, PhilipsApi.NEW2_FAN_SPEED] AVAILABLE_PRESET_MODES = { PresetMode.AUTO: { PhilipsApi.POWER: 1, @@ -1572,47 +1572,47 @@ class PhilipsAMF765(PhilipsNew2GenericCoAPFan): PhilipsApi.NEW2_MODE_B: 18, }, } - REPLACE_SPEED = [PhilipsApi.NEW2_MODE_B, PhilipsApi.NEW2_FAN_SPEED] + # REPLACE_SPEED = [PhilipsApi.NEW2_MODE_B, PhilipsApi.NEW2_FAN_SPEED] AVAILABLE_SPEEDS = { PresetMode.SPEED_1: { PhilipsApi.POWER: 1, - PhilipsApi.NEW2_MODE_B: 1, + PhilipsApi.NEW2_MODE_C: 1, }, PresetMode.SPEED_2: { PhilipsApi.POWER: 1, - PhilipsApi.NEW2_MODE_B: 2, + PhilipsApi.NEW2_MODE_C: 2, }, PresetMode.SPEED_3: { PhilipsApi.POWER: 1, - PhilipsApi.NEW2_MODE_B: 3, + PhilipsApi.NEW2_MODE_C: 3, }, PresetMode.SPEED_4: { PhilipsApi.POWER: 1, - PhilipsApi.NEW2_MODE_B: 4, + PhilipsApi.NEW2_MODE_C: 4, }, PresetMode.SPEED_5: { PhilipsApi.POWER: 1, - PhilipsApi.NEW2_MODE_B: 5, + PhilipsApi.NEW2_MODE_C: 5, }, PresetMode.SPEED_6: { PhilipsApi.POWER: 1, - PhilipsApi.NEW2_MODE_B: 6, + PhilipsApi.NEW2_MODE_C: 6, }, PresetMode.SPEED_7: { PhilipsApi.POWER: 1, - PhilipsApi.NEW2_MODE_B: 7, + PhilipsApi.NEW2_MODE_C: 7, }, PresetMode.SPEED_8: { PhilipsApi.POWER: 1, - PhilipsApi.NEW2_MODE_B: 8, + PhilipsApi.NEW2_MODE_C: 8, }, PresetMode.SPEED_9: { PhilipsApi.POWER: 1, - PhilipsApi.NEW2_MODE_B: 9, + PhilipsApi.NEW2_MODE_C: 9, }, PresetMode.SPEED_10: { PhilipsApi.POWER: 1, - PhilipsApi.NEW2_MODE_B: 10, + PhilipsApi.NEW2_MODE_C: 10, }, # PresetMode.TURBO: { # PhilipsApi.POWER: 1, From 4315385da731af37273e38a8d732ee6873b0e448 Mon Sep 17 00:00:00 2001 From: kongo09 Date: Sun, 21 Jan 2024 14:41:57 +0100 Subject: [PATCH 49/73] extend autodiscovery for AMF --- .../philips_airpurifier_coap/manifest.json | 45 ++++++++++--------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/custom_components/philips_airpurifier_coap/manifest.json b/custom_components/philips_airpurifier_coap/manifest.json index bac990c..44fd951 100644 --- a/custom_components/philips_airpurifier_coap/manifest.json +++ b/custom_components/philips_airpurifier_coap/manifest.json @@ -1,23 +1,26 @@ { - "domain": "philips_airpurifier_coap", - "name": "Philips AirPurifier (with CoAP)", - "codeowners": ["@kongo09"], - "config_flow": true, - "dependencies": ["frontend", "http"], - "dhcp": [ - { - "macaddress": "B0F893*" - }, - { - "macaddress": "047863*" - }, - { - "hostname": "mxchip*" - } - ], - "documentation": "https://github.com/kongo09/philips-airpurifier-coap", - "iot_class": "local_push", - "issue_tracker": "https://github.com/kongo09/philips-airpurifier-coap/issues", - "requirements": ["aioairctrl==0.2.5"], - "version": "0.10.9" + "domain": "philips_airpurifier_coap", + "name": "Philips AirPurifier (with CoAP)", + "codeowners": ["@kongo09"], + "config_flow": true, + "dependencies": ["frontend", "http"], + "dhcp": [ + { + "macaddress": "B0F893*" + }, + { + "macaddress": "047863*" + }, + { + "macaddress": "849DC2*" + }, + { + "hostname": "mxchip*" + } + ], + "documentation": "https://github.com/kongo09/philips-airpurifier-coap", + "iot_class": "local_push", + "issue_tracker": "https://github.com/kongo09/philips-airpurifier-coap/issues", + "requirements": ["aioairctrl==0.2.5"], + "version": "0.10.9" } From 19656fab0df40765226bc44347a1ff65b7a5cbea Mon Sep 17 00:00:00 2001 From: kongo09 Date: Sun, 21 Jan 2024 19:57:44 +0100 Subject: [PATCH 50/73] add icons for heating and gas --- .../philips_airpurifier_coap/const.py | 22 ++++++++++++++----- .../icons/pap/gas.svg | 4 ++++ .../icons/pap/heating.svg | 4 ++++ .../philips_airpurifier_coap/philips.py | 2 ++ 4 files changed, 26 insertions(+), 6 deletions(-) create mode 100644 custom_components/philips_airpurifier_coap/icons/pap/gas.svg create mode 100644 custom_components/philips_airpurifier_coap/icons/pap/heating.svg diff --git a/custom_components/philips_airpurifier_coap/const.py b/custom_components/philips_airpurifier_coap/const.py index 00f793a..31b8272 100644 --- a/custom_components/philips_airpurifier_coap/const.py +++ b/custom_components/philips_airpurifier_coap/const.py @@ -70,6 +70,8 @@ class ICON(StrEnum): MODE = "pap:mode" ROTATE = "pap:rotate" OSCILLATE = "pap:oscillate" + GAS = "pap:gas" + HEATING = "pap:heating" DATA_EXTRA_MODULE_URL = "frontend_extra_module_url" @@ -355,6 +357,7 @@ class PhilipsApi: NEW2_BEEP = "D03130" NEW2_INDOOR_ALLERGEN_INDEX = "D03120" NEW2_PM25 = "D03221" + NEW2_GAS = "D03122" NEW2_HUMIDITY = "D03125" NEW2_FILTER_NANOPROTECT_PREFILTER = "D0520D" NEW2_FILTER_NANOPROTECT = "D0540E" @@ -372,15 +375,16 @@ class PhilipsApi: NEW2_TARGET_TEMP = "D0310E" NEW2_STANDBY_SENSORS = "D03134" NEW2_AUTO_PLUS_AI = "D03180" + NEW2_PREFERRED_INDEX = "D0312A" PREFERRED_INDEX_MAP = { - "0": ("Indoor Allergen Index", ICON.IAI), - "1": ("PM2.5", ICON.PM25), + 0: ("Indoor Allergen Index", ICON.IAI), + 1: ("PM2.5", ICON.PM25), } GAS_PREFERRED_INDEX_MAP = { - "0": ("Indoor Allergen Index", ICON.IAI), - "1": ("PM2.5", ICON.PM25), - "2": ("Gas", "mdi:air"), + 0: ("Indoor Allergen Index", ICON.IAI), + 1: ("PM2.5", ICON.PM25), + 2: ("Gas", ICON.GAS), } NEW_PREFERRED_INDEX_MAP = { "IAI": ("Indoor Allergen Index", ICON.IAI), @@ -483,6 +487,12 @@ class PhilipsApi: FanAttributes.UNIT: CONCENTRATION_MICROGRAMS_PER_CUBIC_METER, ATTR_STATE_CLASS: SensorStateClass.MEASUREMENT, }, + PhilipsApi.NEW2_GAS: { + FanAttributes.ICON_MAP: {0: "mdi:air"}, + FanAttributes.LABEL: FanAttributes.PM25, + FanAttributes.UNIT: CONCENTRATION_MICROGRAMS_PER_CUBIC_METER, + ATTR_STATE_CLASS: SensorStateClass.MEASUREMENT, + }, PhilipsApi.TOTAL_VOLATILE_ORGANIC_COMPOUNDS: { ATTR_DEVICE_CLASS: SensorDeviceClass.VOLATILE_ORGANIC_COMPOUNDS, FanAttributes.ICON_MAP: {0: "mdi:blur"}, @@ -741,7 +751,7 @@ class PhilipsApi: CONF_ENTITY_CATEGORY: EntityCategory.CONFIG, OPTIONS: PhilipsApi.PREFERRED_INDEX_MAP, }, - PhilipsApi.PREFERRED_INDEX: { + PhilipsApi.NEW2_PREFERRED_INDEX: { FanAttributes.LABEL: FanAttributes.PREFERRED_INDEX, CONF_ENTITY_CATEGORY: EntityCategory.CONFIG, OPTIONS: PhilipsApi.PREFERRED_INDEX_MAP, diff --git a/custom_components/philips_airpurifier_coap/icons/pap/gas.svg b/custom_components/philips_airpurifier_coap/icons/pap/gas.svg new file mode 100644 index 0000000..1aa23ec --- /dev/null +++ b/custom_components/philips_airpurifier_coap/icons/pap/gas.svg @@ -0,0 +1,4 @@ + + + + diff --git a/custom_components/philips_airpurifier_coap/icons/pap/heating.svg b/custom_components/philips_airpurifier_coap/icons/pap/heating.svg new file mode 100644 index 0000000..d161a9e --- /dev/null +++ b/custom_components/philips_airpurifier_coap/icons/pap/heating.svg @@ -0,0 +1,4 @@ + + + + diff --git a/custom_components/philips_airpurifier_coap/philips.py b/custom_components/philips_airpurifier_coap/philips.py index ab21f25..4da1fe7 100644 --- a/custom_components/philips_airpurifier_coap/philips.py +++ b/custom_components/philips_airpurifier_coap/philips.py @@ -1634,6 +1634,8 @@ class PhilipsAMF765(PhilipsNew2GenericCoAPFan): class PhilipsAMF870(PhilipsAMF765): """AMF870.""" + AVAILABLE_SELECTS = [PhilipsApi.NEW2_PREFERRED_INDEX] + class PhilipsCX5120(PhilipsNew2GenericCoAPFan): """CX5120.""" From 3deb12124bb95ab1b6aa30c9c6db9e270e849570 Mon Sep 17 00:00:00 2001 From: kongo09 Date: Sun, 21 Jan 2024 19:59:01 +0100 Subject: [PATCH 51/73] fix icon for gas sensor --- custom_components/philips_airpurifier_coap/const.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/philips_airpurifier_coap/const.py b/custom_components/philips_airpurifier_coap/const.py index 31b8272..d96474d 100644 --- a/custom_components/philips_airpurifier_coap/const.py +++ b/custom_components/philips_airpurifier_coap/const.py @@ -488,7 +488,7 @@ class PhilipsApi: ATTR_STATE_CLASS: SensorStateClass.MEASUREMENT, }, PhilipsApi.NEW2_GAS: { - FanAttributes.ICON_MAP: {0: "mdi:air"}, + FanAttributes.ICON_MAP: {0: ICON.GAS}, FanAttributes.LABEL: FanAttributes.PM25, FanAttributes.UNIT: CONCENTRATION_MICROGRAMS_PER_CUBIC_METER, ATTR_STATE_CLASS: SensorStateClass.MEASUREMENT, From 9102f8dcf6b9b7c17285fd59c2e0c9a57ac1c5a0 Mon Sep 17 00:00:00 2001 From: kongo09 Date: Sun, 21 Jan 2024 20:02:17 +0100 Subject: [PATCH 52/73] refactor AMF classes and introduce gas sensor --- .../philips_airpurifier_coap/philips.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/custom_components/philips_airpurifier_coap/philips.py b/custom_components/philips_airpurifier_coap/philips.py index 4da1fe7..b8f8760 100644 --- a/custom_components/philips_airpurifier_coap/philips.py +++ b/custom_components/philips_airpurifier_coap/philips.py @@ -1554,8 +1554,8 @@ class PhilipsAC5659(PhilipsGenericCoAPFan): AVAILABLE_SELECTS = [PhilipsApi.PREFERRED_INDEX] -class PhilipsAMF765(PhilipsNew2GenericCoAPFan): - """AMF765.""" +class PhilipsAMFxxx(PhilipsNew2GenericCoAPFan): + """AMF family.""" # REPLACE_PRESET = [PhilipsApi.NEW2_MODE_B, PhilipsApi.NEW2_FAN_SPEED] AVAILABLE_PRESET_MODES = { @@ -1631,7 +1631,13 @@ class PhilipsAMF765(PhilipsNew2GenericCoAPFan): AVAILABLE_NUMBERS = [PhilipsApi.NEW2_OSCILLATION] -class PhilipsAMF870(PhilipsAMF765): +class PhilipsAMF765(PhilipsAMFxxx): + """AMF765.""" + + UNAVAILABLE_SENSORS = [PhilipsApi.NEW2_GAS] + + +class PhilipsAMF870(PhilipsAMFxxx): """AMF870.""" AVAILABLE_SELECTS = [PhilipsApi.NEW2_PREFERRED_INDEX] @@ -1680,7 +1686,7 @@ class PhilipsCX5120(PhilipsNew2GenericCoAPFan): AVAILABLE_LIGHTS = [PhilipsApi.NEW2_DISPLAY_BACKLIGHT2] AVAILABLE_SWITCHES = [PhilipsApi.NEW2_BEEP] - UNAVAILABLE_SENSORS = [PhilipsApi.NEW2_FAN_SPEED] + UNAVAILABLE_SENSORS = [PhilipsApi.NEW2_FAN_SPEED, PhilipsApi.NEW2_GAS] AVAILABLE_SELECTS = [PhilipsApi.NEW2_TIMER2] AVAILABLE_NUMBERS = [PhilipsApi.NEW2_TARGET_TEMP] From 9a4d1cdbb1223b20dac6feb28bfb530f315e3d01 Mon Sep 17 00:00:00 2001 From: kongo09 Date: Sun, 21 Jan 2024 20:19:36 +0100 Subject: [PATCH 53/73] fix timer and add gas sensor for AMF --- .../philips_airpurifier_coap/const.py | 16 +++++++++++----- .../philips_airpurifier_coap/philips.py | 5 ++++- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/custom_components/philips_airpurifier_coap/const.py b/custom_components/philips_airpurifier_coap/const.py index d96474d..523a563 100644 --- a/custom_components/philips_airpurifier_coap/const.py +++ b/custom_components/philips_airpurifier_coap/const.py @@ -370,12 +370,13 @@ class PhilipsApi: NEW2_MODE_A = "D0310A" NEW2_MODE_B = "D0310C" NEW2_MODE_C = "D0310D" - NEW2_TIMER = "D03110" - NEW2_TIMER2 = "D03110" + NEW2_TIMER = "D03110#1" + NEW2_TIMER2 = "D03110#2" NEW2_TARGET_TEMP = "D0310E" NEW2_STANDBY_SENSORS = "D03134" NEW2_AUTO_PLUS_AI = "D03180" - NEW2_PREFERRED_INDEX = "D0312A" + NEW2_PREFERRED_INDEX = "D0312A#1" + NEW2_GAS_PREFERRED_INDEX = "D0312A#2" PREFERRED_INDEX_MAP = { 0: ("Indoor Allergen Index", ICON.IAI), @@ -751,6 +752,11 @@ class PhilipsApi: CONF_ENTITY_CATEGORY: EntityCategory.CONFIG, OPTIONS: PhilipsApi.PREFERRED_INDEX_MAP, }, + PhilipsApi.NEW_PREFERRED_INDEX: { + FanAttributes.LABEL: FanAttributes.PREFERRED_INDEX, + CONF_ENTITY_CATEGORY: EntityCategory.CONFIG, + OPTIONS: PhilipsApi.NEW_PREFERRED_INDEX_MAP, + }, PhilipsApi.NEW2_PREFERRED_INDEX: { FanAttributes.LABEL: FanAttributes.PREFERRED_INDEX, CONF_ENTITY_CATEGORY: EntityCategory.CONFIG, @@ -761,10 +767,10 @@ class PhilipsApi: CONF_ENTITY_CATEGORY: EntityCategory.CONFIG, OPTIONS: PhilipsApi.GAS_PREFERRED_INDEX_MAP, }, - PhilipsApi.NEW_PREFERRED_INDEX: { + PhilipsApi.NEW2_GAS_PREFERRED_INDEX: { FanAttributes.LABEL: FanAttributes.PREFERRED_INDEX, CONF_ENTITY_CATEGORY: EntityCategory.CONFIG, - OPTIONS: PhilipsApi.NEW_PREFERRED_INDEX_MAP, + OPTIONS: PhilipsApi.GAS_PREFERRED_INDEX_MAP, }, PhilipsApi.NEW2_CIRCULATION: { FanAttributes.LABEL: FanAttributes.FUNCTION, diff --git a/custom_components/philips_airpurifier_coap/philips.py b/custom_components/philips_airpurifier_coap/philips.py index b8f8760..525e437 100644 --- a/custom_components/philips_airpurifier_coap/philips.py +++ b/custom_components/philips_airpurifier_coap/philips.py @@ -1640,7 +1640,10 @@ class PhilipsAMF765(PhilipsAMFxxx): class PhilipsAMF870(PhilipsAMFxxx): """AMF870.""" - AVAILABLE_SELECTS = [PhilipsApi.NEW2_PREFERRED_INDEX] + AVAILABLE_SELECTS = [ + PhilipsApi.NEW2_PREFERRED_INDEX, + PhilipsApi.NEW2_GAS_PREFERRED_INDEX, + ] class PhilipsCX5120(PhilipsNew2GenericCoAPFan): From 82b9b41b82cbdf91acf51b409172bb68e00216e5 Mon Sep 17 00:00:00 2001 From: kongo09 Date: Sun, 21 Jan 2024 20:26:17 +0100 Subject: [PATCH 54/73] add heating function for AMF870 --- custom_components/philips_airpurifier_coap/const.py | 13 ++++++++++++- .../philips_airpurifier_coap/philips.py | 4 +++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/custom_components/philips_airpurifier_coap/const.py b/custom_components/philips_airpurifier_coap/const.py index 523a563..b36b427 100644 --- a/custom_components/philips_airpurifier_coap/const.py +++ b/custom_components/philips_airpurifier_coap/const.py @@ -365,7 +365,8 @@ class PhilipsApi: NEW2_FILTER_NANOPROTECT_TOTAL = "D05408" NEW2_FAN_SPEED = "D0310D" NEW2_SWING = "D0320F" - NEW2_CIRCULATION = "D0310A" + NEW2_CIRCULATION = "D0310A#1" + NEW2_HEATING = "D0310A#2" NEW2_OSCILLATION = "D0320F" NEW2_MODE_A = "D0310A" NEW2_MODE_B = "D0310C" @@ -399,6 +400,11 @@ class PhilipsApi: 1: ("Fan", ICON.CLEAN), 2: ("Circulation", ICON.CIRCULATE), } + HEATING_MAP = { + 1: ("Fan", ICON.CLEAN), + 2: ("Circulation", ICON.CIRCULATE), + 3: ("Heating", ICON.HEATING), + } TIMER_MAP = { 0: ("Off", "mdi:clock-plus"), 1: ("0.5h", "mdi:clock-time-one"), @@ -777,6 +783,11 @@ class PhilipsApi: CONF_ENTITY_CATEGORY: EntityCategory.CONFIG, OPTIONS: PhilipsApi.CIRCULATION_MAP, }, + PhilipsApi.NEW2_HEATING: { + FanAttributes.LABEL: FanAttributes.FUNCTION, + CONF_ENTITY_CATEGORY: EntityCategory.CONFIG, + OPTIONS: PhilipsApi.HEATING_MAP, + }, PhilipsApi.NEW2_TIMER: { FanAttributes.LABEL: FanAttributes.TIMER, CONF_ENTITY_CATEGORY: EntityCategory.CONFIG, diff --git a/custom_components/philips_airpurifier_coap/philips.py b/custom_components/philips_airpurifier_coap/philips.py index 525e437..f06e406 100644 --- a/custom_components/philips_airpurifier_coap/philips.py +++ b/custom_components/philips_airpurifier_coap/philips.py @@ -1627,13 +1627,14 @@ class PhilipsAMFxxx(PhilipsNew2GenericCoAPFan): PhilipsApi.NEW2_STANDBY_SENSORS, PhilipsApi.NEW2_AUTO_PLUS_AI, ] - AVAILABLE_SELECTS = [PhilipsApi.NEW2_CIRCULATION, PhilipsApi.NEW2_TIMER] + AVAILABLE_SELECTS = [PhilipsApi.NEW2_TIMER] AVAILABLE_NUMBERS = [PhilipsApi.NEW2_OSCILLATION] class PhilipsAMF765(PhilipsAMFxxx): """AMF765.""" + AVAILABLE_SELECTS = [PhilipsApi.NEW2_CIRCULATION] UNAVAILABLE_SENSORS = [PhilipsApi.NEW2_GAS] @@ -1643,6 +1644,7 @@ class PhilipsAMF870(PhilipsAMFxxx): AVAILABLE_SELECTS = [ PhilipsApi.NEW2_PREFERRED_INDEX, PhilipsApi.NEW2_GAS_PREFERRED_INDEX, + PhilipsApi.NEW2_HEATING, ] From ead88a81b5c153d3aeb0e69815941d6e4401091e Mon Sep 17 00:00:00 2001 From: kongo09 Date: Sun, 21 Jan 2024 20:27:18 +0100 Subject: [PATCH 55/73] add target temp for AMF870 --- custom_components/philips_airpurifier_coap/philips.py | 1 + 1 file changed, 1 insertion(+) diff --git a/custom_components/philips_airpurifier_coap/philips.py b/custom_components/philips_airpurifier_coap/philips.py index f06e406..ae0e901 100644 --- a/custom_components/philips_airpurifier_coap/philips.py +++ b/custom_components/philips_airpurifier_coap/philips.py @@ -1646,6 +1646,7 @@ class PhilipsAMF870(PhilipsAMFxxx): PhilipsApi.NEW2_GAS_PREFERRED_INDEX, PhilipsApi.NEW2_HEATING, ] + AVAILABLE_NUMBERS = [PhilipsApi.NEW2_TARGET_TEMP] class PhilipsCX5120(PhilipsNew2GenericCoAPFan): From d677b9419e5fddf753d00ddc1f6b4ef14f9d81c2 Mon Sep 17 00:00:00 2001 From: kongo09 Date: Sun, 21 Jan 2024 20:29:15 +0100 Subject: [PATCH 56/73] add oscillation for AMF870 --- custom_components/philips_airpurifier_coap/philips.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/custom_components/philips_airpurifier_coap/philips.py b/custom_components/philips_airpurifier_coap/philips.py index ae0e901..d478686 100644 --- a/custom_components/philips_airpurifier_coap/philips.py +++ b/custom_components/philips_airpurifier_coap/philips.py @@ -1647,6 +1647,9 @@ class PhilipsAMF870(PhilipsAMFxxx): PhilipsApi.NEW2_HEATING, ] AVAILABLE_NUMBERS = [PhilipsApi.NEW2_TARGET_TEMP] + KEY_OSCILLATION = { + PhilipsApi.NEW2_OSCILLATION: PhilipsApi.OSCILLATION_MAP, + } class PhilipsCX5120(PhilipsNew2GenericCoAPFan): From e286a8b7ce02368f06b283457a0ed7f4ad0d8c5f Mon Sep 17 00:00:00 2001 From: kongo09 Date: Sun, 21 Jan 2024 20:43:36 +0100 Subject: [PATCH 57/73] fix gas sensor label --- custom_components/philips_airpurifier_coap/const.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/custom_components/philips_airpurifier_coap/const.py b/custom_components/philips_airpurifier_coap/const.py index b36b427..eb2ba86 100644 --- a/custom_components/philips_airpurifier_coap/const.py +++ b/custom_components/philips_airpurifier_coap/const.py @@ -230,6 +230,7 @@ class FanAttributes(StrEnum): MODEL_ID = "model_id" NAME = "name" PM25 = "PM2.5" + GAS = "gas_level" PREFERRED_INDEX = "preferred_index" PRODUCT_ID = "product_id" RUNTIME = "runtime" @@ -496,7 +497,7 @@ class PhilipsApi: }, PhilipsApi.NEW2_GAS: { FanAttributes.ICON_MAP: {0: ICON.GAS}, - FanAttributes.LABEL: FanAttributes.PM25, + FanAttributes.LABEL: FanAttributes.GAS, FanAttributes.UNIT: CONCENTRATION_MICROGRAMS_PER_CUBIC_METER, ATTR_STATE_CLASS: SensorStateClass.MEASUREMENT, }, From 41f1e8820236767a468b63b0559b65e1cac56b72 Mon Sep 17 00:00:00 2001 From: kongo09 Date: Sun, 21 Jan 2024 20:47:47 +0100 Subject: [PATCH 58/73] remove wrong oscillation for AMF870 --- custom_components/philips_airpurifier_coap/philips.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/custom_components/philips_airpurifier_coap/philips.py b/custom_components/philips_airpurifier_coap/philips.py index d478686..ae0e901 100644 --- a/custom_components/philips_airpurifier_coap/philips.py +++ b/custom_components/philips_airpurifier_coap/philips.py @@ -1647,9 +1647,6 @@ class PhilipsAMF870(PhilipsAMFxxx): PhilipsApi.NEW2_HEATING, ] AVAILABLE_NUMBERS = [PhilipsApi.NEW2_TARGET_TEMP] - KEY_OSCILLATION = { - PhilipsApi.NEW2_OSCILLATION: PhilipsApi.OSCILLATION_MAP, - } class PhilipsCX5120(PhilipsNew2GenericCoAPFan): From ad5b740f819405781091afabbf7d6c396defecfa Mon Sep 17 00:00:00 2001 From: kongo09 Date: Sun, 21 Jan 2024 21:36:55 +0100 Subject: [PATCH 59/73] add preferred index attribute --- .../philips_airpurifier_coap/philips.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/custom_components/philips_airpurifier_coap/philips.py b/custom_components/philips_airpurifier_coap/philips.py index ae0e901..051f58f 100644 --- a/custom_components/philips_airpurifier_coap/philips.py +++ b/custom_components/philips_airpurifier_coap/philips.py @@ -450,6 +450,8 @@ def percentage(self) -> Optional[int]: else: return ordered_list_item_to_percentage(self._speeds, speed) + return None + async def async_set_percentage(self, percentage: int) -> None: """Return the selected speed percentage.""" if percentage == 0: @@ -600,11 +602,11 @@ class PhilipsNew2GenericCoAPFan(PhilipsGenericCoAPFanBase): # (FanAttributes.ERROR_CODE, PhilipsApi.ERROR_CODE), # (FanAttributes.ERROR, PhilipsApi.ERROR_CODE, PhilipsApi.ERROR_CODE_MAP), # device configuration - # ( - # FanAttributes.PREFERRED_INDEX, - # PhilipsApi.NEW_PREFERRED_INDEX, - # PhilipsApi.NEW_PREFERRED_INDEX_MAP, - # ), + ( + FanAttributes.PREFERRED_INDEX, + PhilipsApi.NEW2_GAS_PREFERRED_INDEX, + PhilipsApi.GAS_PREFERRED_INDEX_MAP, + ), # device sensors ( FanAttributes.RUNTIME, From 9e4c7f0fdb397acd3b8104ea730f075cd711f9ae Mon Sep 17 00:00:00 2001 From: kongo09 Date: Sun, 21 Jan 2024 22:11:07 +0100 Subject: [PATCH 60/73] try to fix presets and speed for AMF --- .../philips_airpurifier_coap/philips.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/custom_components/philips_airpurifier_coap/philips.py b/custom_components/philips_airpurifier_coap/philips.py index 051f58f..3217ee6 100644 --- a/custom_components/philips_airpurifier_coap/philips.py +++ b/custom_components/philips_airpurifier_coap/philips.py @@ -1564,56 +1564,69 @@ class PhilipsAMFxxx(PhilipsNew2GenericCoAPFan): PresetMode.AUTO: { PhilipsApi.POWER: 1, PhilipsApi.NEW2_MODE_B: 0, + PhilipsApi.NEW2_MODE_C: 3, }, PresetMode.SLEEP: { PhilipsApi.POWER: 1, PhilipsApi.NEW2_MODE_B: 17, + PhilipsApi.NEW2_MODE_C: 1, }, PresetMode.TURBO: { PhilipsApi.POWER: 1, PhilipsApi.NEW2_MODE_B: 18, + PhilipsApi.NEW2_MODE_C: 18, }, } # REPLACE_SPEED = [PhilipsApi.NEW2_MODE_B, PhilipsApi.NEW2_FAN_SPEED] AVAILABLE_SPEEDS = { PresetMode.SPEED_1: { PhilipsApi.POWER: 1, + PhilipsApi.NEW2_MODE_B: 1, PhilipsApi.NEW2_MODE_C: 1, }, PresetMode.SPEED_2: { PhilipsApi.POWER: 1, + PhilipsApi.NEW2_MODE_B: 2, PhilipsApi.NEW2_MODE_C: 2, }, PresetMode.SPEED_3: { PhilipsApi.POWER: 1, + PhilipsApi.NEW2_MODE_B: 3, PhilipsApi.NEW2_MODE_C: 3, }, PresetMode.SPEED_4: { PhilipsApi.POWER: 1, + PhilipsApi.NEW2_MODE_B: 4, PhilipsApi.NEW2_MODE_C: 4, }, PresetMode.SPEED_5: { PhilipsApi.POWER: 1, + PhilipsApi.NEW2_MODE_B: 5, PhilipsApi.NEW2_MODE_C: 5, }, PresetMode.SPEED_6: { PhilipsApi.POWER: 1, + PhilipsApi.NEW2_MODE_B: 6, PhilipsApi.NEW2_MODE_C: 6, }, PresetMode.SPEED_7: { PhilipsApi.POWER: 1, + PhilipsApi.NEW2_MODE_B: 7, PhilipsApi.NEW2_MODE_C: 7, }, PresetMode.SPEED_8: { PhilipsApi.POWER: 1, + PhilipsApi.NEW2_MODE_B: 8, PhilipsApi.NEW2_MODE_C: 8, }, PresetMode.SPEED_9: { PhilipsApi.POWER: 1, + PhilipsApi.NEW2_MODE_B: 9, PhilipsApi.NEW2_MODE_C: 9, }, PresetMode.SPEED_10: { PhilipsApi.POWER: 1, + PhilipsApi.NEW2_MODE_B: 10, PhilipsApi.NEW2_MODE_C: 10, }, # PresetMode.TURBO: { From 84e54ecadac96f0c38d6ac44fbcd82d6371dcc64 Mon Sep 17 00:00:00 2001 From: kongo09 Date: Mon, 22 Jan 2024 18:57:59 +0100 Subject: [PATCH 61/73] fix units of gas sensor --- custom_components/philips_airpurifier_coap/const.py | 1 - 1 file changed, 1 deletion(-) diff --git a/custom_components/philips_airpurifier_coap/const.py b/custom_components/philips_airpurifier_coap/const.py index eb2ba86..6fbd278 100644 --- a/custom_components/philips_airpurifier_coap/const.py +++ b/custom_components/philips_airpurifier_coap/const.py @@ -498,7 +498,6 @@ class PhilipsApi: PhilipsApi.NEW2_GAS: { FanAttributes.ICON_MAP: {0: ICON.GAS}, FanAttributes.LABEL: FanAttributes.GAS, - FanAttributes.UNIT: CONCENTRATION_MICROGRAMS_PER_CUBIC_METER, ATTR_STATE_CLASS: SensorStateClass.MEASUREMENT, }, PhilipsApi.TOTAL_VOLATILE_ORGANIC_COMPOUNDS: { From 304f0e62ad8551703671bc5514becae7dfc0060f Mon Sep 17 00:00:00 2001 From: kongo09 Date: Mon, 22 Jan 2024 19:01:45 +0100 Subject: [PATCH 62/73] remove extra preferred index --- custom_components/philips_airpurifier_coap/philips.py | 1 - 1 file changed, 1 deletion(-) diff --git a/custom_components/philips_airpurifier_coap/philips.py b/custom_components/philips_airpurifier_coap/philips.py index 3217ee6..2715627 100644 --- a/custom_components/philips_airpurifier_coap/philips.py +++ b/custom_components/philips_airpurifier_coap/philips.py @@ -1657,7 +1657,6 @@ class PhilipsAMF870(PhilipsAMFxxx): """AMF870.""" AVAILABLE_SELECTS = [ - PhilipsApi.NEW2_PREFERRED_INDEX, PhilipsApi.NEW2_GAS_PREFERRED_INDEX, PhilipsApi.NEW2_HEATING, ] From 518cad71a0c1572b2e38aa26764b0f09ed068329 Mon Sep 17 00:00:00 2001 From: kongo09 Date: Mon, 22 Jan 2024 19:21:28 +0100 Subject: [PATCH 63/73] change ints to str in attempt to fix presets, speed and swing --- custom_components/philips_airpurifier_coap/const.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/custom_components/philips_airpurifier_coap/const.py b/custom_components/philips_airpurifier_coap/const.py index 6fbd278..062e5a9 100644 --- a/custom_components/philips_airpurifier_coap/const.py +++ b/custom_components/philips_airpurifier_coap/const.py @@ -331,8 +331,8 @@ class PhilipsApi: } OSCILLATION_MAP = { - SWITCH_ON: 17920, - SWITCH_OFF: 0, + SWITCH_ON: "17920", + SWITCH_OFF: "0", } # the AC1715 seems to follow a new scheme, this should later be refactored From 24a2bfd3c6801cccde98190154234ae5e66794f3 Mon Sep 17 00:00:00 2001 From: kongo09 Date: Mon, 22 Jan 2024 19:22:02 +0100 Subject: [PATCH 64/73] change ints to str in an attempt to fix presets, speed and swing --- .../philips_airpurifier_coap/philips.py | 114 +++++++++--------- 1 file changed, 57 insertions(+), 57 deletions(-) diff --git a/custom_components/philips_airpurifier_coap/philips.py b/custom_components/philips_airpurifier_coap/philips.py index 2715627..ba01ec6 100644 --- a/custom_components/philips_airpurifier_coap/philips.py +++ b/custom_components/philips_airpurifier_coap/philips.py @@ -1562,72 +1562,72 @@ class PhilipsAMFxxx(PhilipsNew2GenericCoAPFan): # REPLACE_PRESET = [PhilipsApi.NEW2_MODE_B, PhilipsApi.NEW2_FAN_SPEED] AVAILABLE_PRESET_MODES = { PresetMode.AUTO: { - PhilipsApi.POWER: 1, - PhilipsApi.NEW2_MODE_B: 0, - PhilipsApi.NEW2_MODE_C: 3, + PhilipsApi.POWER: "1", + PhilipsApi.NEW2_MODE_B: "0", + PhilipsApi.NEW2_MODE_C: "3", }, PresetMode.SLEEP: { - PhilipsApi.POWER: 1, - PhilipsApi.NEW2_MODE_B: 17, - PhilipsApi.NEW2_MODE_C: 1, + PhilipsApi.POWER: "1", + PhilipsApi.NEW2_MODE_B: "17", + PhilipsApi.NEW2_MODE_C: "1", }, PresetMode.TURBO: { - PhilipsApi.POWER: 1, - PhilipsApi.NEW2_MODE_B: 18, - PhilipsApi.NEW2_MODE_C: 18, + PhilipsApi.POWER: "1", + PhilipsApi.NEW2_MODE_B: "18", + PhilipsApi.NEW2_MODE_C: "18", }, } # REPLACE_SPEED = [PhilipsApi.NEW2_MODE_B, PhilipsApi.NEW2_FAN_SPEED] AVAILABLE_SPEEDS = { PresetMode.SPEED_1: { - PhilipsApi.POWER: 1, - PhilipsApi.NEW2_MODE_B: 1, - PhilipsApi.NEW2_MODE_C: 1, + PhilipsApi.POWER: "1", + PhilipsApi.NEW2_MODE_B: "1", + PhilipsApi.NEW2_MODE_C: "1", }, PresetMode.SPEED_2: { - PhilipsApi.POWER: 1, - PhilipsApi.NEW2_MODE_B: 2, - PhilipsApi.NEW2_MODE_C: 2, + PhilipsApi.POWER: "1", + PhilipsApi.NEW2_MODE_B: "2", + PhilipsApi.NEW2_MODE_C: "2", }, PresetMode.SPEED_3: { - PhilipsApi.POWER: 1, - PhilipsApi.NEW2_MODE_B: 3, - PhilipsApi.NEW2_MODE_C: 3, + PhilipsApi.POWER: "1", + PhilipsApi.NEW2_MODE_B: "3", + PhilipsApi.NEW2_MODE_C: "3", }, PresetMode.SPEED_4: { - PhilipsApi.POWER: 1, - PhilipsApi.NEW2_MODE_B: 4, - PhilipsApi.NEW2_MODE_C: 4, + PhilipsApi.POWER: "1", + PhilipsApi.NEW2_MODE_B: "4", + PhilipsApi.NEW2_MODE_C: "4", }, PresetMode.SPEED_5: { - PhilipsApi.POWER: 1, - PhilipsApi.NEW2_MODE_B: 5, - PhilipsApi.NEW2_MODE_C: 5, + PhilipsApi.POWER: "1", + PhilipsApi.NEW2_MODE_B: "5", + PhilipsApi.NEW2_MODE_C: "5", }, PresetMode.SPEED_6: { - PhilipsApi.POWER: 1, - PhilipsApi.NEW2_MODE_B: 6, - PhilipsApi.NEW2_MODE_C: 6, + PhilipsApi.POWER: "1", + PhilipsApi.NEW2_MODE_B: "6", + PhilipsApi.NEW2_MODE_C: "6", }, PresetMode.SPEED_7: { - PhilipsApi.POWER: 1, - PhilipsApi.NEW2_MODE_B: 7, - PhilipsApi.NEW2_MODE_C: 7, + PhilipsApi.POWER: "1", + PhilipsApi.NEW2_MODE_B: "7", + PhilipsApi.NEW2_MODE_C: "7", }, PresetMode.SPEED_8: { - PhilipsApi.POWER: 1, - PhilipsApi.NEW2_MODE_B: 8, - PhilipsApi.NEW2_MODE_C: 8, + PhilipsApi.POWER: "1", + PhilipsApi.NEW2_MODE_B: "8", + PhilipsApi.NEW2_MODE_C: "8", }, PresetMode.SPEED_9: { - PhilipsApi.POWER: 1, - PhilipsApi.NEW2_MODE_B: 9, - PhilipsApi.NEW2_MODE_C: 9, + PhilipsApi.POWER: "1", + PhilipsApi.NEW2_MODE_B: "9", + PhilipsApi.NEW2_MODE_C: "9", }, PresetMode.SPEED_10: { - PhilipsApi.POWER: 1, - PhilipsApi.NEW2_MODE_B: 10, - PhilipsApi.NEW2_MODE_C: 10, + PhilipsApi.POWER: "1", + PhilipsApi.NEW2_MODE_B: "10", + PhilipsApi.NEW2_MODE_C: "10", }, # PresetMode.TURBO: { # PhilipsApi.POWER: 1, @@ -1668,36 +1668,36 @@ class PhilipsCX5120(PhilipsNew2GenericCoAPFan): AVAILABLE_PRESET_MODES = { PresetMode.AUTO: { - PhilipsApi.NEW2_POWER: 1, - PhilipsApi.NEW2_MODE_A: 3, - PhilipsApi.NEW2_MODE_B: 0, + PhilipsApi.NEW2_POWER: "1", + PhilipsApi.NEW2_MODE_A: "3", + PhilipsApi.NEW2_MODE_B: "0", }, PresetMode.HIGH: { - PhilipsApi.POWER: 1, - PhilipsApi.NEW2_MODE_A: 3, - PhilipsApi.NEW2_MODE_B: 65, + PhilipsApi.POWER: "1", + PhilipsApi.NEW2_MODE_A: "3", + PhilipsApi.NEW2_MODE_B: "65", }, PresetMode.LOW: { - PhilipsApi.POWER: 1, - PhilipsApi.NEW2_MODE_A: 3, - PhilipsApi.NEW2_MODE_B: 66, + PhilipsApi.POWER: "1", + PhilipsApi.NEW2_MODE_A: "3", + PhilipsApi.NEW2_MODE_B: "66", }, PresetMode.VENTILATION: { - PhilipsApi.POWER: 1, - PhilipsApi.NEW2_MODE_A: 1, - PhilipsApi.NEW2_MODE_B: -127, + PhilipsApi.POWER: "1", + PhilipsApi.NEW2_MODE_A: "1", + PhilipsApi.NEW2_MODE_B: "-127", }, } AVAILABLE_SPEEDS = { PresetMode.HIGH: { - PhilipsApi.POWER: 1, - PhilipsApi.NEW2_MODE_A: 3, - PhilipsApi.NEW2_MODE_B: 65, + PhilipsApi.POWER: "1", + PhilipsApi.NEW2_MODE_A: "3", + PhilipsApi.NEW2_MODE_B: "65", }, PresetMode.LOW: { - PhilipsApi.POWER: 1, - PhilipsApi.NEW2_MODE_A: 3, - PhilipsApi.NEW2_MODE_B: 66, + PhilipsApi.POWER: "1", + PhilipsApi.NEW2_MODE_A: "3", + PhilipsApi.NEW2_MODE_B: "66", }, } KEY_OSCILLATION = { From f925a35a133b1e8ba5417cc56a8dd4a014c1b59a Mon Sep 17 00:00:00 2001 From: kongo09 Date: Mon, 22 Jan 2024 19:49:51 +0100 Subject: [PATCH 65/73] fix temperature unit --- custom_components/philips_airpurifier_coap/const.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/custom_components/philips_airpurifier_coap/const.py b/custom_components/philips_airpurifier_coap/const.py index 062e5a9..566cc92 100644 --- a/custom_components/philips_airpurifier_coap/const.py +++ b/custom_components/philips_airpurifier_coap/const.py @@ -3,6 +3,7 @@ from enum import StrEnum +from homeassistant.components.number.const import NumberDeviceClass from homeassistant.components.sensor import ( ATTR_STATE_CLASS, SensorDeviceClass, @@ -815,7 +816,8 @@ class PhilipsApi: FanAttributes.LABEL: FanAttributes.TARGET_TEMP, ATTR_ICON: "mdi:thermometer", CONF_ENTITY_CATEGORY: EntityCategory.CONFIG, - FanAttributes.UNIT: "°", + ATTR_DEVICE_CLASS: NumberDeviceClass.TEMPERATURE, + FanAttributes.UNIT: "°C", FanAttributes.OFF: 1, FanAttributes.MIN: 1, FanAttributes.MAX: 37, From cfac2413ba95998fdea5df30e61c4973e9a466c2 Mon Sep 17 00:00:00 2001 From: kongo09 Date: Mon, 22 Jan 2024 19:51:50 +0100 Subject: [PATCH 66/73] fix number ranges --- custom_components/philips_airpurifier_coap/number.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/custom_components/philips_airpurifier_coap/number.py b/custom_components/philips_airpurifier_coap/number.py index f3b5c9b..2ee11a8 100644 --- a/custom_components/philips_airpurifier_coap/number.py +++ b/custom_components/philips_airpurifier_coap/number.py @@ -88,9 +88,9 @@ def __init__( # noqa: D107 FanAttributes.UNIT ) - self._attr_native_min = self._description.get(FanAttributes.OFF) + self._attr_native_min_value = self._description.get(FanAttributes.OFF) self._min = self._description.get(FanAttributes.MIN) - self._attr_native_max = self._description.get(FanAttributes.MAX) + self._attr_native_max_value = self._description.get(FanAttributes.MAX) self._attr_native_step = self._description.get(FanAttributes.STEP) try: @@ -114,14 +114,14 @@ async def async_set_native_value(self, value: float) -> None: _LOGGER.debug("async_set_native_value called with: %s", value) # Catch the boundaries - if value is None or value < self._attr_native_min: - value = self._attr_native_min + if value is None or value < self._attr_native_min_value: + value = self._attr_native_min_value if value % self._attr_native_step > 0: value = value // self._attr_native_step * self._attr_native_step if value > 0 and value < self._min: value = self._min - if value > self._attr_native_max: - value = self._attr_native_max + if value > self._attr_native_max_value: + value = self._attr_native_max_value _LOGGER.debug("setting number with: %s", value) From e34f2b63f4f3a5963ffba1419fff09eb788fd3e4 Mon Sep 17 00:00:00 2001 From: kongo09 Date: Mon, 22 Jan 2024 19:57:05 +0100 Subject: [PATCH 67/73] fix import --- custom_components/philips_airpurifier_coap/const.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/philips_airpurifier_coap/const.py b/custom_components/philips_airpurifier_coap/const.py index 566cc92..5038f87 100644 --- a/custom_components/philips_airpurifier_coap/const.py +++ b/custom_components/philips_airpurifier_coap/const.py @@ -3,7 +3,7 @@ from enum import StrEnum -from homeassistant.components.number.const import NumberDeviceClass +from homeassistant.components.number import NumberDeviceClass from homeassistant.components.sensor import ( ATTR_STATE_CLASS, SensorDeviceClass, From a73be34a79d154addfcd5253773c184765a1f284 Mon Sep 17 00:00:00 2001 From: kongo09 Date: Mon, 22 Jan 2024 20:23:29 +0100 Subject: [PATCH 68/73] revert ints and introduce debugging --- .../philips_airpurifier_coap/philips.py | 93 +++++++++++-------- 1 file changed, 53 insertions(+), 40 deletions(-) diff --git a/custom_components/philips_airpurifier_coap/philips.py b/custom_components/philips_airpurifier_coap/philips.py index ba01ec6..df3c7ba 100644 --- a/custom_components/philips_airpurifier_coap/philips.py +++ b/custom_components/philips_airpurifier_coap/philips.py @@ -391,16 +391,29 @@ def preset_modes(self) -> Optional[list[str]]: @property def preset_mode(self) -> Optional[str]: """Return the selected preset mode.""" + _LOGGER.debug("fan %s preset mode requested", self._attr_name) for preset_mode, status_pattern in self._available_preset_modes.items(): + _LOGGER.debug( + " testing preset mode '%s' with status pattern: %s", + preset_mode, + status_pattern, + ) for k, v in status_pattern.items(): + _LOGGER.debug(" checking key, value pair: %s - %s", k, v) # check if the speed sensor also used for presets is different from the setting field if self.REPLACE_PRESET is not None and k == self.REPLACE_PRESET[0]: k = self.REPLACE_PRESET[1] - if self._device_status.get(k) != v: + status = self._device_status.get(k) + _LOGGER.debug(" status is: %s", status) + if status != v: + _LOGGER.debug(" status doesn't match value, stop trying") break else: + _LOGGER.debug(" found preset mode: %s", preset_mode) return preset_mode + _LOGGER.debug(" nothing found, sorry") + async def async_set_preset_mode(self, preset_mode: str) -> None: """Set the preset mode of the fan.""" status_pattern = self._available_preset_modes.get(preset_mode) @@ -1562,72 +1575,72 @@ class PhilipsAMFxxx(PhilipsNew2GenericCoAPFan): # REPLACE_PRESET = [PhilipsApi.NEW2_MODE_B, PhilipsApi.NEW2_FAN_SPEED] AVAILABLE_PRESET_MODES = { PresetMode.AUTO: { - PhilipsApi.POWER: "1", - PhilipsApi.NEW2_MODE_B: "0", - PhilipsApi.NEW2_MODE_C: "3", + PhilipsApi.POWER: 1, + PhilipsApi.NEW2_MODE_B: 0, + PhilipsApi.NEW2_MODE_C: 3, }, PresetMode.SLEEP: { - PhilipsApi.POWER: "1", - PhilipsApi.NEW2_MODE_B: "17", - PhilipsApi.NEW2_MODE_C: "1", + PhilipsApi.POWER: 1, + PhilipsApi.NEW2_MODE_B: 17, + PhilipsApi.NEW2_MODE_C: 1, }, PresetMode.TURBO: { - PhilipsApi.POWER: "1", - PhilipsApi.NEW2_MODE_B: "18", - PhilipsApi.NEW2_MODE_C: "18", + PhilipsApi.POWER: 1, + PhilipsApi.NEW2_MODE_B: 18, + PhilipsApi.NEW2_MODE_C: 18, }, } # REPLACE_SPEED = [PhilipsApi.NEW2_MODE_B, PhilipsApi.NEW2_FAN_SPEED] AVAILABLE_SPEEDS = { PresetMode.SPEED_1: { - PhilipsApi.POWER: "1", - PhilipsApi.NEW2_MODE_B: "1", - PhilipsApi.NEW2_MODE_C: "1", + PhilipsApi.POWER: 1, + PhilipsApi.NEW2_MODE_B: 1, + PhilipsApi.NEW2_MODE_C: 1, }, PresetMode.SPEED_2: { - PhilipsApi.POWER: "1", - PhilipsApi.NEW2_MODE_B: "2", - PhilipsApi.NEW2_MODE_C: "2", + PhilipsApi.POWER: 1, + PhilipsApi.NEW2_MODE_B: 2, + PhilipsApi.NEW2_MODE_C: 2, }, PresetMode.SPEED_3: { - PhilipsApi.POWER: "1", - PhilipsApi.NEW2_MODE_B: "3", - PhilipsApi.NEW2_MODE_C: "3", + PhilipsApi.POWER: 1, + PhilipsApi.NEW2_MODE_B: 3, + PhilipsApi.NEW2_MODE_C: 3, }, PresetMode.SPEED_4: { - PhilipsApi.POWER: "1", - PhilipsApi.NEW2_MODE_B: "4", - PhilipsApi.NEW2_MODE_C: "4", + PhilipsApi.POWER: 1, + PhilipsApi.NEW2_MODE_B: 4, + PhilipsApi.NEW2_MODE_C: 4, }, PresetMode.SPEED_5: { - PhilipsApi.POWER: "1", - PhilipsApi.NEW2_MODE_B: "5", - PhilipsApi.NEW2_MODE_C: "5", + PhilipsApi.POWER: 1, + PhilipsApi.NEW2_MODE_B: 5, + PhilipsApi.NEW2_MODE_C: 5, }, PresetMode.SPEED_6: { - PhilipsApi.POWER: "1", - PhilipsApi.NEW2_MODE_B: "6", - PhilipsApi.NEW2_MODE_C: "6", + PhilipsApi.POWER: 1, + PhilipsApi.NEW2_MODE_B: 6, + PhilipsApi.NEW2_MODE_C: 6, }, PresetMode.SPEED_7: { - PhilipsApi.POWER: "1", - PhilipsApi.NEW2_MODE_B: "7", - PhilipsApi.NEW2_MODE_C: "7", + PhilipsApi.POWER: 1, + PhilipsApi.NEW2_MODE_B: 7, + PhilipsApi.NEW2_MODE_C: 7, }, PresetMode.SPEED_8: { - PhilipsApi.POWER: "1", - PhilipsApi.NEW2_MODE_B: "8", - PhilipsApi.NEW2_MODE_C: "8", + PhilipsApi.POWER: 1, + PhilipsApi.NEW2_MODE_B: 8, + PhilipsApi.NEW2_MODE_C: 8, }, PresetMode.SPEED_9: { - PhilipsApi.POWER: "1", - PhilipsApi.NEW2_MODE_B: "9", - PhilipsApi.NEW2_MODE_C: "9", + PhilipsApi.POWER: 1, + PhilipsApi.NEW2_MODE_B: 9, + PhilipsApi.NEW2_MODE_C: 9, }, PresetMode.SPEED_10: { - PhilipsApi.POWER: "1", - PhilipsApi.NEW2_MODE_B: "10", - PhilipsApi.NEW2_MODE_C: "10", + PhilipsApi.POWER: 1, + PhilipsApi.NEW2_MODE_B: 10, + PhilipsApi.NEW2_MODE_C: 10, }, # PresetMode.TURBO: { # PhilipsApi.POWER: 1, From f9deb9b5edf3b37215e9ca1b530eed9da3ffe60d Mon Sep 17 00:00:00 2001 From: kongo09 Date: Mon, 22 Jan 2024 20:44:30 +0100 Subject: [PATCH 69/73] introduce more debugging --- custom_components/philips_airpurifier_coap/philips.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/custom_components/philips_airpurifier_coap/philips.py b/custom_components/philips_airpurifier_coap/philips.py index df3c7ba..4559726 100644 --- a/custom_components/philips_airpurifier_coap/philips.py +++ b/custom_components/philips_airpurifier_coap/philips.py @@ -391,7 +391,7 @@ def preset_modes(self) -> Optional[list[str]]: @property def preset_mode(self) -> Optional[str]: """Return the selected preset mode.""" - _LOGGER.debug("fan %s preset mode requested", self._attr_name) + _LOGGER.debug("fan %s preset mode requested", self._name) for preset_mode, status_pattern in self._available_preset_modes.items(): _LOGGER.debug( " testing preset mode '%s' with status pattern: %s", @@ -400,14 +400,17 @@ def preset_mode(self) -> Optional[str]: ) for k, v in status_pattern.items(): _LOGGER.debug(" checking key, value pair: %s - %s", k, v) + _LOGGER.debug(" value is of type: %s", type(v)) # check if the speed sensor also used for presets is different from the setting field if self.REPLACE_PRESET is not None and k == self.REPLACE_PRESET[0]: k = self.REPLACE_PRESET[1] status = self._device_status.get(k) _LOGGER.debug(" status is: %s", status) + _LOGGER.debug(" status is of type: %s", type(status)) if status != v: _LOGGER.debug(" status doesn't match value, stop trying") break + _LOGGER.debug(" match!") else: _LOGGER.debug(" found preset mode: %s", preset_mode) return preset_mode From 10e5aaab88eaafa3d351026aed24948530cadf61 Mon Sep 17 00:00:00 2001 From: kongo09 Date: Mon, 22 Jan 2024 21:37:03 +0100 Subject: [PATCH 70/73] fix power key --- .../philips_airpurifier_coap/philips.py | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/custom_components/philips_airpurifier_coap/philips.py b/custom_components/philips_airpurifier_coap/philips.py index 4559726..40c6a12 100644 --- a/custom_components/philips_airpurifier_coap/philips.py +++ b/custom_components/philips_airpurifier_coap/philips.py @@ -1578,17 +1578,17 @@ class PhilipsAMFxxx(PhilipsNew2GenericCoAPFan): # REPLACE_PRESET = [PhilipsApi.NEW2_MODE_B, PhilipsApi.NEW2_FAN_SPEED] AVAILABLE_PRESET_MODES = { PresetMode.AUTO: { - PhilipsApi.POWER: 1, + PhilipsApi.NEW2_POWER: 1, PhilipsApi.NEW2_MODE_B: 0, PhilipsApi.NEW2_MODE_C: 3, }, PresetMode.SLEEP: { - PhilipsApi.POWER: 1, + PhilipsApi.NEW2_POWER: 1, PhilipsApi.NEW2_MODE_B: 17, PhilipsApi.NEW2_MODE_C: 1, }, PresetMode.TURBO: { - PhilipsApi.POWER: 1, + PhilipsApi.NEW2_POWER: 1, PhilipsApi.NEW2_MODE_B: 18, PhilipsApi.NEW2_MODE_C: 18, }, @@ -1596,57 +1596,57 @@ class PhilipsAMFxxx(PhilipsNew2GenericCoAPFan): # REPLACE_SPEED = [PhilipsApi.NEW2_MODE_B, PhilipsApi.NEW2_FAN_SPEED] AVAILABLE_SPEEDS = { PresetMode.SPEED_1: { - PhilipsApi.POWER: 1, + PhilipsApi.NEW2_POWER: 1, PhilipsApi.NEW2_MODE_B: 1, PhilipsApi.NEW2_MODE_C: 1, }, PresetMode.SPEED_2: { - PhilipsApi.POWER: 1, + PhilipsApi.NEW2_POWER: 1, PhilipsApi.NEW2_MODE_B: 2, PhilipsApi.NEW2_MODE_C: 2, }, PresetMode.SPEED_3: { - PhilipsApi.POWER: 1, + PhilipsApi.NEW2_POWER: 1, PhilipsApi.NEW2_MODE_B: 3, PhilipsApi.NEW2_MODE_C: 3, }, PresetMode.SPEED_4: { - PhilipsApi.POWER: 1, + PhilipsApi.NEW2_POWER: 1, PhilipsApi.NEW2_MODE_B: 4, PhilipsApi.NEW2_MODE_C: 4, }, PresetMode.SPEED_5: { - PhilipsApi.POWER: 1, + PhilipsApi.NEW2_POWER: 1, PhilipsApi.NEW2_MODE_B: 5, PhilipsApi.NEW2_MODE_C: 5, }, PresetMode.SPEED_6: { - PhilipsApi.POWER: 1, + PhilipsApi.NEW2_POWER: 1, PhilipsApi.NEW2_MODE_B: 6, PhilipsApi.NEW2_MODE_C: 6, }, PresetMode.SPEED_7: { - PhilipsApi.POWER: 1, + PhilipsApi.NEW2_POWER: 1, PhilipsApi.NEW2_MODE_B: 7, PhilipsApi.NEW2_MODE_C: 7, }, PresetMode.SPEED_8: { - PhilipsApi.POWER: 1, + PhilipsApi.NEW2_POWER: 1, PhilipsApi.NEW2_MODE_B: 8, PhilipsApi.NEW2_MODE_C: 8, }, PresetMode.SPEED_9: { - PhilipsApi.POWER: 1, + PhilipsApi.NEW2_POWER: 1, PhilipsApi.NEW2_MODE_B: 9, PhilipsApi.NEW2_MODE_C: 9, }, PresetMode.SPEED_10: { - PhilipsApi.POWER: 1, + PhilipsApi.NEW2_POWER: 1, PhilipsApi.NEW2_MODE_B: 10, PhilipsApi.NEW2_MODE_C: 10, }, # PresetMode.TURBO: { - # PhilipsApi.POWER: 1, + # PhilipsApi.NEW2_POWER: 1, # PhilipsApi.NEW2_MODE_B: 18, # }, } From 1e8cc8fec5d5871e395c44817d1ca7a47256c3e0 Mon Sep 17 00:00:00 2001 From: kongo09 Date: Mon, 22 Jan 2024 23:33:57 +0100 Subject: [PATCH 71/73] only try to set/read first register and consider auto+ --- .../philips_airpurifier_coap/const.py | 13 ++++---- .../philips_airpurifier_coap/philips.py | 33 +++++++++++-------- 2 files changed, 27 insertions(+), 19 deletions(-) diff --git a/custom_components/philips_airpurifier_coap/const.py b/custom_components/philips_airpurifier_coap/const.py index 5038f87..8939215 100644 --- a/custom_components/philips_airpurifier_coap/const.py +++ b/custom_components/philips_airpurifier_coap/const.py @@ -144,6 +144,7 @@ class PresetMode: ALLERGEN = "allergen" AUTO = "auto" AUTO_GENERAL = "auto general" + AUTO_PLUS = "auto+" BACTERIA = "bacteria" GENTLE = "gentle" NIGHT = "night" @@ -694,12 +695,12 @@ class PhilipsApi: SWITCH_ON: 1, SWITCH_OFF: 0, }, - PhilipsApi.NEW2_AUTO_PLUS_AI: { - ATTR_ICON: "mdi:format-annotation-plus", - FanAttributes.LABEL: FanAttributes.AUTO_PLUS, - SWITCH_ON: 1, - SWITCH_OFF: 0, - }, + # PhilipsApi.NEW2_AUTO_PLUS_AI: { + # ATTR_ICON: "mdi:format-annotation-plus", + # FanAttributes.LABEL: FanAttributes.AUTO_PLUS, + # SWITCH_ON: 1, + # SWITCH_OFF: 0, + # }, } LIGHT_TYPES: dict[str, LightDescription] = { diff --git a/custom_components/philips_airpurifier_coap/philips.py b/custom_components/philips_airpurifier_coap/philips.py index 40c6a12..bd272cc 100644 --- a/custom_components/philips_airpurifier_coap/philips.py +++ b/custom_components/philips_airpurifier_coap/philips.py @@ -1577,20 +1577,27 @@ class PhilipsAMFxxx(PhilipsNew2GenericCoAPFan): # REPLACE_PRESET = [PhilipsApi.NEW2_MODE_B, PhilipsApi.NEW2_FAN_SPEED] AVAILABLE_PRESET_MODES = { + PresetMode.AUTO_PLUS: { + PhilipsApi.NEW2_POWER: 1, + PhilipsApi.NEW2_MODE_B: 0, + PhilipsApi.NEW2_AUTO_PLUS_AI: 1, + # PhilipsApi.NEW2_MODE_C: 3, + }, PresetMode.AUTO: { PhilipsApi.NEW2_POWER: 1, PhilipsApi.NEW2_MODE_B: 0, - PhilipsApi.NEW2_MODE_C: 3, + PhilipsApi.NEW2_AUTO_PLUS_AI: 0, + # PhilipsApi.NEW2_MODE_C: 3, }, PresetMode.SLEEP: { PhilipsApi.NEW2_POWER: 1, PhilipsApi.NEW2_MODE_B: 17, - PhilipsApi.NEW2_MODE_C: 1, + # PhilipsApi.NEW2_MODE_C: 1, }, PresetMode.TURBO: { PhilipsApi.NEW2_POWER: 1, PhilipsApi.NEW2_MODE_B: 18, - PhilipsApi.NEW2_MODE_C: 18, + # PhilipsApi.NEW2_MODE_C: 18, }, } # REPLACE_SPEED = [PhilipsApi.NEW2_MODE_B, PhilipsApi.NEW2_FAN_SPEED] @@ -1598,52 +1605,52 @@ class PhilipsAMFxxx(PhilipsNew2GenericCoAPFan): PresetMode.SPEED_1: { PhilipsApi.NEW2_POWER: 1, PhilipsApi.NEW2_MODE_B: 1, - PhilipsApi.NEW2_MODE_C: 1, + # PhilipsApi.NEW2_MODE_C: 1, }, PresetMode.SPEED_2: { PhilipsApi.NEW2_POWER: 1, PhilipsApi.NEW2_MODE_B: 2, - PhilipsApi.NEW2_MODE_C: 2, + # PhilipsApi.NEW2_MODE_C: 2, }, PresetMode.SPEED_3: { PhilipsApi.NEW2_POWER: 1, PhilipsApi.NEW2_MODE_B: 3, - PhilipsApi.NEW2_MODE_C: 3, + # PhilipsApi.NEW2_MODE_C: 3, }, PresetMode.SPEED_4: { PhilipsApi.NEW2_POWER: 1, PhilipsApi.NEW2_MODE_B: 4, - PhilipsApi.NEW2_MODE_C: 4, + # PhilipsApi.NEW2_MODE_C: 4, }, PresetMode.SPEED_5: { PhilipsApi.NEW2_POWER: 1, PhilipsApi.NEW2_MODE_B: 5, - PhilipsApi.NEW2_MODE_C: 5, + # PhilipsApi.NEW2_MODE_C: 5, }, PresetMode.SPEED_6: { PhilipsApi.NEW2_POWER: 1, PhilipsApi.NEW2_MODE_B: 6, - PhilipsApi.NEW2_MODE_C: 6, + # PhilipsApi.NEW2_MODE_C: 6, }, PresetMode.SPEED_7: { PhilipsApi.NEW2_POWER: 1, PhilipsApi.NEW2_MODE_B: 7, - PhilipsApi.NEW2_MODE_C: 7, + # PhilipsApi.NEW2_MODE_C: 7, }, PresetMode.SPEED_8: { PhilipsApi.NEW2_POWER: 1, PhilipsApi.NEW2_MODE_B: 8, - PhilipsApi.NEW2_MODE_C: 8, + # PhilipsApi.NEW2_MODE_C: 8, }, PresetMode.SPEED_9: { PhilipsApi.NEW2_POWER: 1, PhilipsApi.NEW2_MODE_B: 9, - PhilipsApi.NEW2_MODE_C: 9, + # PhilipsApi.NEW2_MODE_C: 9, }, PresetMode.SPEED_10: { PhilipsApi.NEW2_POWER: 1, PhilipsApi.NEW2_MODE_B: 10, - PhilipsApi.NEW2_MODE_C: 10, + # PhilipsApi.NEW2_MODE_C: 10, }, # PresetMode.TURBO: { # PhilipsApi.NEW2_POWER: 1, From 821aaa61dcfd72dce9d7f33d2d0cddc0b280d96f Mon Sep 17 00:00:00 2001 From: kongo09 Date: Tue, 23 Jan 2024 21:54:52 +0000 Subject: [PATCH 72/73] re-enable Auto+ switch and remove from preset --- .../philips_airpurifier_coap/const.py | 12 ++++++------ .../philips_airpurifier_coap/philips.py | 14 +++++++------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/custom_components/philips_airpurifier_coap/const.py b/custom_components/philips_airpurifier_coap/const.py index 8939215..607d08a 100644 --- a/custom_components/philips_airpurifier_coap/const.py +++ b/custom_components/philips_airpurifier_coap/const.py @@ -695,12 +695,12 @@ class PhilipsApi: SWITCH_ON: 1, SWITCH_OFF: 0, }, - # PhilipsApi.NEW2_AUTO_PLUS_AI: { - # ATTR_ICON: "mdi:format-annotation-plus", - # FanAttributes.LABEL: FanAttributes.AUTO_PLUS, - # SWITCH_ON: 1, - # SWITCH_OFF: 0, - # }, + PhilipsApi.NEW2_AUTO_PLUS_AI: { + ATTR_ICON: "mdi:format-annotation-plus", + FanAttributes.LABEL: FanAttributes.AUTO_PLUS, + SWITCH_ON: 1, + SWITCH_OFF: 0, + }, } LIGHT_TYPES: dict[str, LightDescription] = { diff --git a/custom_components/philips_airpurifier_coap/philips.py b/custom_components/philips_airpurifier_coap/philips.py index bd272cc..40530d4 100644 --- a/custom_components/philips_airpurifier_coap/philips.py +++ b/custom_components/philips_airpurifier_coap/philips.py @@ -1577,16 +1577,16 @@ class PhilipsAMFxxx(PhilipsNew2GenericCoAPFan): # REPLACE_PRESET = [PhilipsApi.NEW2_MODE_B, PhilipsApi.NEW2_FAN_SPEED] AVAILABLE_PRESET_MODES = { - PresetMode.AUTO_PLUS: { - PhilipsApi.NEW2_POWER: 1, - PhilipsApi.NEW2_MODE_B: 0, - PhilipsApi.NEW2_AUTO_PLUS_AI: 1, - # PhilipsApi.NEW2_MODE_C: 3, - }, + # PresetMode.AUTO_PLUS: { + # PhilipsApi.NEW2_POWER: 1, + # PhilipsApi.NEW2_MODE_B: 0, + # PhilipsApi.NEW2_AUTO_PLUS_AI: 1, + # # PhilipsApi.NEW2_MODE_C: 3, + # }, PresetMode.AUTO: { PhilipsApi.NEW2_POWER: 1, PhilipsApi.NEW2_MODE_B: 0, - PhilipsApi.NEW2_AUTO_PLUS_AI: 0, + # PhilipsApi.NEW2_AUTO_PLUS_AI: 0, # PhilipsApi.NEW2_MODE_C: 3, }, PresetMode.SLEEP: { From 6568b82ed85d5b7eb2ca2537797c47e819db39a3 Mon Sep 17 00:00:00 2001 From: kongo09 Date: Wed, 24 Jan 2024 13:32:51 +0000 Subject: [PATCH 73/73] remove debug output --- .../philips_airpurifier_coap/philips.py | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/custom_components/philips_airpurifier_coap/philips.py b/custom_components/philips_airpurifier_coap/philips.py index 40530d4..dd1607e 100644 --- a/custom_components/philips_airpurifier_coap/philips.py +++ b/custom_components/philips_airpurifier_coap/philips.py @@ -391,32 +391,17 @@ def preset_modes(self) -> Optional[list[str]]: @property def preset_mode(self) -> Optional[str]: """Return the selected preset mode.""" - _LOGGER.debug("fan %s preset mode requested", self._name) for preset_mode, status_pattern in self._available_preset_modes.items(): - _LOGGER.debug( - " testing preset mode '%s' with status pattern: %s", - preset_mode, - status_pattern, - ) for k, v in status_pattern.items(): - _LOGGER.debug(" checking key, value pair: %s - %s", k, v) - _LOGGER.debug(" value is of type: %s", type(v)) # check if the speed sensor also used for presets is different from the setting field if self.REPLACE_PRESET is not None and k == self.REPLACE_PRESET[0]: k = self.REPLACE_PRESET[1] status = self._device_status.get(k) - _LOGGER.debug(" status is: %s", status) - _LOGGER.debug(" status is of type: %s", type(status)) if status != v: - _LOGGER.debug(" status doesn't match value, stop trying") break - _LOGGER.debug(" match!") else: - _LOGGER.debug(" found preset mode: %s", preset_mode) return preset_mode - _LOGGER.debug(" nothing found, sorry") - async def async_set_preset_mode(self, preset_mode: str) -> None: """Set the preset mode of the fan.""" status_pattern = self._available_preset_modes.get(preset_mode)