homebridge-philips-airplus-cloud 0.0.0-stage → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,23 @@
1
+ # Changelog — Homebridge plugin
2
+
3
+ The Home Assistant integration in `custom_components/` is unchanged from upstream and keeps its own history.
4
+
5
+ ## 0.3.0 — 2026-10-11
6
+
7
+ - Published on npm as `homebridge-philips-airplus-cloud` (the name `homebridge-philips-airplus` belongs to an unrelated humidifier plugin). Installs from the earlier `.tgz` or git builds were named `homebridge-philips-airplus`: uninstall that first.
8
+ - Option `sleepSwitchStyle: "purifier"`: Sleep shown as a second air purifier (purifier icon in Home), linked to the main one.
9
+ - Diagnostics option `logDeviceData`: logs every port and the cloud shadow the purifier publishes.
10
+ - Display light also detected on `D03104` (0/115/123); manual override with `displayLightProperty`.
11
+ - Sleep, Display, Air Quality and filter services are linked to the purifier with short labels, so Home shows them as labelled controls inside the purifier.
12
+
13
+ ## 0.2.0 — 2026-10-11
14
+
15
+ - Sleep mode switch.
16
+ - Display light as a dimmable light when the purifier reports it.
17
+ - Speed slider back to 0–100 %, one band per manual mode (the Home app always shows it as a percentage).
18
+
19
+ ## 0.1.0 — 2026-10-10
20
+
21
+ - First version: email + code login (Homebridge UI panel or `philips-airplus-login`), automatic token refresh, MQTT over the Philips/Versuni cloud.
22
+ - HomeKit Air Purifier (power, Auto/Manual, speed), Air Quality Sensor (PM2.5), Filter Maintenance for filter and pre-filter with reset.
23
+ - Device definitions read from the shared `models.yaml`.
package/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025-2026 ShorMeneses (https://github.com/ShorMeneses/philips-airplus-homeassistant)
4
+ Portions copyright (c) 2026 Markus Stephany
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in all
14
+ copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,127 @@
1
- # Temporary Holding Version
1
+ # homebridge-philips-airplus-cloud
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Homebridge plugin for **Philips Air+** air purifiers (AC0650, AC0651, AC1715, PureProtect 3200i and others in the same family). It brings them into Apple Home through the Philips/Versuni **cloud**, with the same MQTT protocol used by the official Air+ app and Google Home. No local connection, IP address or port forwarding is needed.
4
+
5
+ ## A Homebridge port of a Home Assistant integration
6
+
7
+ This repository is a fork of [NikGro/philips-air-plus-homeassistant](https://github.com/NikGro/philips-air-plus-homeassistant), a Home Assistant integration that is itself based on [ShorMeneses/philips-airplus-homeassistant](https://github.com/ShorMeneses/philips-airplus-homeassistant). The fork ports that integration to Homebridge:
8
+
9
+ - the cloud protocol (email + code login, token refresh, MQTT over WebSocket with the AWS custom authorizer) is re-implemented in Node.js in `src/`;
10
+ - device definitions are **not** duplicated: the plugin reads the same `custom_components/philips_airplus/models.yaml` as the Home Assistant integration, so modes and property keys stay in sync with upstream;
11
+ - the Home Assistant integration in `custom_components/` is kept unchanged from upstream so the two can be merged easily. If you use Home Assistant, install it from [the upstream repository](https://github.com/NikGro/philips-air-plus-homeassistant) instead.
12
+
13
+ ## What you get in HomeKit
14
+
15
+ One accessory per purifier with:
16
+
17
+ - **Air Purifier** — on/off, Auto/Manual, and a speed slider split into one band per manual mode of your model (e.g. 0–33% Sleep, 34–66% Medium, 67–100% Turbo on the AC0651/10); it snaps to the band after each change. Switching back to Manual restores the last manual speed.
18
+ - **Sleep switch** — turns Sleep mode on; turning it off returns to Auto.
19
+ - **Display light** — the purifier's display/LED as a dimmable light. It appears after the purifier first reports its light setting (property `D03104`, `D03105` or `D0312D`); devices with three light levels are detected automatically.
20
+ - **Air Quality Sensor** — PM2.5 (µg/m³) and a HomeKit air-quality level derived from it.
21
+ - **Filter Maintenance** — main filter and pre-filter (cleaning), with life level, change alert (below 10% by default) and reset from the Home app. The reset writes the same value the official app does.
22
+
23
+ State changes arrive in real time over MQTT; a status poll runs every 120 s as a safety net.
24
+
25
+ ## Install
26
+
27
+ Search for **Philips Air+ cloud** in Homebridge UI → Plugins and install it, or from a terminal:
28
+
29
+ ```bash
30
+ # Homebridge Raspberry Pi image / hb-service (Homebridge UI → ⋮ → Terminal)
31
+ cd /var/lib/homebridge
32
+ npm install homebridge-philips-airplus-cloud
33
+
34
+ # global npm install of Homebridge
35
+ sudo npm install -g homebridge-philips-airplus-cloud
36
+ ```
37
+
38
+ Then restart Homebridge. Node 18.17 or newer and Homebridge 1.6+ (including 2.0 betas) are supported.
39
+
40
+ To try the latest unreleased code, install from GitHub instead: `npm install git+https://github.com/Micheledipaola/homebridge-philips-airplus.git`.
41
+
42
+ Homebridge does not need to be on the same network as the purifier: everything goes through the Philips cloud.
43
+
44
+ > The npm package is called `homebridge-philips-airplus-cloud` because `homebridge-philips-airplus` is an unrelated plugin for Philips Air+ humidifiers.
45
+
46
+ ## Log in
47
+
48
+ 1. Homebridge UI → Plugins → **Philips Air+** → Settings.
49
+ 2. Enter the email of your Philips account (Air+ or HomeID app) and press **Send code**.
50
+ 3. Type the code from the email and press **Log in**. The panel lists the purifiers it found and saves the login.
51
+ 4. Restart Homebridge.
52
+
53
+ Every purifier in the account is added. To pick only some, or to rename them, fill in **Devices** with the UUIDs shown after login.
54
+
55
+ Without Homebridge UI, run the login from a shell and paste the printed block into the `platforms` array of `config.json`:
56
+
57
+ ```bash
58
+ philips-airplus-login you@example.com
59
+ ```
60
+
61
+ ```json
62
+ {
63
+ "platform": "PhilipsAirPlus",
64
+ "name": "Philips Air+",
65
+ "email": "you@example.com",
66
+ "refreshToken": "…",
67
+ "clientId": "-XsK7O6iEkLml77yDGDUi0ku",
68
+ "userId": "…"
69
+ }
70
+ ```
71
+
72
+ The refresh token rotates on every use; the plugin keeps the current one in `<homebridge storage>/philips-airplus/`. If the Philips login ever expires, the log says so: log in again from the settings panel and restart.
73
+
74
+ ## Options
75
+
76
+ | Key | Default | Meaning |
77
+ |---|---|---|
78
+ | `devices` | all | `[{ "uuid": "…", "name": "…", "model": "AC0651/10" }]` — pick/rename devices; `model` is only needed if auto-detection fails |
79
+ | `airQualitySensor` | `true` | Show the PM2.5 sensor |
80
+ | `filterSensors` | `true` | Show filter and pre-filter status |
81
+ | `sleepSwitch` | `true` | Show the Sleep mode switch |
82
+ | `sleepSwitchStyle` | `switch` | `purifier` shows the Sleep control as a second air purifier (purifier icon in Home) that only turns Sleep on/off |
83
+ | `displayLight` | `true` | Show the display light |
84
+ | `displayLightProperty` | — | Property key of the display light, if it is not detected (see the `Status properties reported by the device` log line) |
85
+ | `logDeviceData` | `false` | Diagnostics: at startup, log every port and the cloud shadow the purifier publishes |
86
+ | `filterChangeThreshold` | `10` | Filter life (%) at or below which HomeKit shows "replace filter" |
87
+ | `pollInterval` | `120` | Seconds between safety-net status polls |
88
+
89
+ ## Running alongside Home Assistant or the app
90
+
91
+ Each client uses its own MQTT client id (`…_hb` for Homebridge, `…_ha` for Home Assistant), so the Air+ app, Home Assistant and Homebridge can all stay connected at the same time.
92
+
93
+ ## Notes
94
+
95
+ - Tested on an AC0651/10. The other models in `models.yaml` use the same protocol but have not been tried with Homebridge yet — reports are welcome.
96
+ - The AC0651/10 does not expose its display brightness through the cloud (the Philips app has no control for it either; the display turns off by itself in Sleep), so no Display control appears for it.
97
+ - Models not in `models.yaml` still get on/off, PM2.5 and filters, and a warning in the log; modes need a `models.yaml` entry.
98
+ - The AC3221 (PureProtect 3200i) mapping is unverified (see below), and so is its speed order in HomeKit.
99
+ - `npm test` runs the plugin tests (protocol, HomeKit mapping, login flow with a mocked cloud).
100
+
101
+ ## Models
102
+
103
+ Model support comes from `models.yaml`:
104
+
105
+ | Model | Modes | Air quality |
106
+ |-------|-------|-------------|
107
+ | AC0650/10 | Auto, Sleep, Turbo | PM2.5 |
108
+ | AC0651/10 | Auto, Medium, Sleep, Turbo | PM2.5 (allergen index not shown in HomeKit) |
109
+ | AC1715/11 | Auto, Medium, Sleep, Fast, Turbo | PM2.5 |
110
+ | AC1715/70 | Auto, Medium, Sleep, Fast, Turbo | PM2.5 |
111
+ | AC3221 (PureProtect 3200i) | Auto, Speed 1–5, Sleep, Medium, Turbo | PM2.5 (mapping unverified upstream) |
112
+
113
+ New models are added with an entry in `models.yaml`, with no code changes, and then work in both Homebridge and Home Assistant. The cloud property keys (`D03xxx`/`D05xxx`) follow the same scheme as the local CoAP API documented by [kongo09/philips-airpurifier-coap](https://github.com/kongo09/philips-airpurifier-coap).
114
+
115
+ ## Credits
116
+
117
+ The protocol work comes from the Home Assistant integration this plugin is ported from. Thanks to:
118
+ - @ShorMeneses — original cloud/MQTT integration this fork is based on
119
+ - @vkostakos
120
+ - @markusstephany
121
+ - @renaudallard — the email OTP authentication flow is adapted from the [Philips HomeID integration](https://github.com/renaudallard/homeassistant_philips_homeid)
122
+ - @rgpublic — AC1715/11 model configuration
123
+ - @NikGro — PureProtect 3200i (AC3221) mapping and the email + code onboarding
124
+
125
+ ## License
126
+
127
+ Released under the MIT License, like the integration it is based on. See LICENSE.
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ // Command-line login for setups without Homebridge UI: asks for the email and
5
+ // the verification code, then prints the platform block for config.json.
6
+
7
+ const readline = require('node:readline/promises');
8
+ const { LoginSession } = require('../src/cloud');
9
+
10
+ (async () => {
11
+ const rl = readline.createInterface({ input: process.stdin, output: process.stderr });
12
+ try {
13
+ const email = (process.argv[2] || (await rl.question('Philips account email: '))).trim();
14
+ const s = new LoginSession({ log: (m) => console.error(` ${m}`) });
15
+ await s.sendCode(email);
16
+ const code = await rl.question(`Code sent to ${email}. Enter it: `);
17
+ await s.verifyCode(code);
18
+ const r = await s.completeLogin();
19
+
20
+ console.error(`\nLogged in. Purifiers in the account:`);
21
+ for (const d of r.devices) console.error(` - ${d.name} [${d.model || '?'}] ${d.uuid}`);
22
+ if (!r.devices.length) console.error(' (none found — add "devices": [{ "uuid": "..." }] by hand)');
23
+
24
+ console.error('\nAdd this to the "platforms" array of your Homebridge config.json:\n');
25
+ console.log(
26
+ JSON.stringify(
27
+ { platform: 'PhilipsAirPlus', name: 'Philips Air+', email, refreshToken: r.refreshToken, clientId: r.clientId, userId: r.userId },
28
+ null,
29
+ 2,
30
+ ),
31
+ );
32
+ } catch (e) {
33
+ console.error(`\nLogin failed: ${e.message}`);
34
+ process.exitCode = 1;
35
+ } finally {
36
+ rl.close();
37
+ }
38
+ })();
@@ -0,0 +1,172 @@
1
+ {
2
+ "pluginAlias": "PhilipsAirPlus",
3
+ "pluginType": "platform",
4
+ "singular": true,
5
+ "customUi": true,
6
+ "headerDisplay": "Philips Air+ purifiers through the Philips cloud (same protocol as the Air+ app and Google Home). Log in with the email of your Philips account; a verification code will be sent there.",
7
+ "schema": {
8
+ "type": "object",
9
+ "properties": {
10
+ "name": {
11
+ "title": "Name",
12
+ "type": "string",
13
+ "default": "Philips Air+",
14
+ "required": true
15
+ },
16
+ "email": {
17
+ "title": "Philips account email",
18
+ "type": "string",
19
+ "description": "For reference only — log in from the panel above."
20
+ },
21
+ "refreshToken": {
22
+ "title": "Refresh token",
23
+ "type": "string",
24
+ "description": "Filled in automatically by the login panel (or by the philips-airplus-login command)."
25
+ },
26
+ "clientId": {
27
+ "title": "OAuth client id",
28
+ "type": "string",
29
+ "description": "Filled in automatically. Air+ app client unless your account only works with the HomeID app."
30
+ },
31
+ "userId": {
32
+ "title": "User id",
33
+ "type": "string"
34
+ },
35
+ "devices": {
36
+ "title": "Devices",
37
+ "description": "Leave empty to add every purifier in the account. Add entries to pick devices or rename them.",
38
+ "type": "array",
39
+ "items": {
40
+ "type": "object",
41
+ "properties": {
42
+ "uuid": {
43
+ "title": "Device UUID",
44
+ "type": "string",
45
+ "required": true
46
+ },
47
+ "name": {
48
+ "title": "Name in HomeKit",
49
+ "type": "string"
50
+ },
51
+ "model": {
52
+ "title": "Model (optional)",
53
+ "type": "string",
54
+ "description": "e.g. AC0651/10. Normally detected automatically."
55
+ }
56
+ }
57
+ }
58
+ },
59
+ "airQualitySensor": {
60
+ "title": "Show air quality sensor (PM2.5)",
61
+ "type": "boolean",
62
+ "default": true
63
+ },
64
+ "filterSensors": {
65
+ "title": "Show filter and pre-filter status",
66
+ "type": "boolean",
67
+ "default": true
68
+ },
69
+ "sleepSwitch": {
70
+ "title": "Show a Sleep mode switch",
71
+ "type": "boolean",
72
+ "default": true
73
+ },
74
+ "sleepSwitchStyle": {
75
+ "title": "Sleep control style",
76
+ "type": "string",
77
+ "default": "switch",
78
+ "oneOf": [
79
+ {
80
+ "title": "Switch",
81
+ "enum": [
82
+ "switch"
83
+ ]
84
+ },
85
+ {
86
+ "title": "Air purifier (purifier icon)",
87
+ "enum": [
88
+ "purifier"
89
+ ]
90
+ }
91
+ ],
92
+ "description": "'Air purifier' shows Sleep with the purifier icon in the Home app; it only turns Sleep mode on and off."
93
+ },
94
+ "displayLight": {
95
+ "title": "Show the display light as a dimmable light",
96
+ "type": "boolean",
97
+ "default": true,
98
+ "description": "Appears once the purifier reports its light setting."
99
+ },
100
+ "displayLightProperty": {
101
+ "title": "Display light property (advanced)",
102
+ "type": "string",
103
+ "placeholder": "D03105",
104
+ "description": "Only if the light does not appear: the property key that holds the light setting, as shown in the log line 'Status properties reported by the device'."
105
+ },
106
+ "filterChangeThreshold": {
107
+ "title": "Filter change alert below (%)",
108
+ "type": "integer",
109
+ "default": 10,
110
+ "minimum": 0,
111
+ "maximum": 50
112
+ },
113
+ "pollInterval": {
114
+ "title": "Status refresh interval (seconds)",
115
+ "type": "integer",
116
+ "default": 120,
117
+ "minimum": 30,
118
+ "description": "The device also pushes changes in real time; this is only a safety net."
119
+ },
120
+ "logDeviceData": {
121
+ "title": "Log all device data (diagnostics)",
122
+ "type": "boolean",
123
+ "default": false,
124
+ "description": "At startup, ask the purifier for all its ports and cloud shadow and write them to the log. Turn off again afterwards."
125
+ }
126
+ }
127
+ },
128
+ "layout": [
129
+ "name",
130
+ {
131
+ "type": "fieldset",
132
+ "title": "Account",
133
+ "expandable": true,
134
+ "expanded": false,
135
+ "items": [
136
+ "email",
137
+ "refreshToken",
138
+ "clientId",
139
+ "userId"
140
+ ]
141
+ },
142
+ {
143
+ "key": "devices",
144
+ "type": "array",
145
+ "title": "Devices",
146
+ "expandable": true,
147
+ "expanded": false,
148
+ "items": [
149
+ "devices[].uuid",
150
+ "devices[].name",
151
+ "devices[].model"
152
+ ]
153
+ },
154
+ {
155
+ "type": "fieldset",
156
+ "title": "Options",
157
+ "expandable": true,
158
+ "expanded": false,
159
+ "items": [
160
+ "airQualitySensor",
161
+ "filterSensors",
162
+ "sleepSwitch",
163
+ "sleepSwitchStyle",
164
+ "displayLight",
165
+ "displayLightProperty",
166
+ "filterChangeThreshold",
167
+ "pollInterval",
168
+ "logDeviceData"
169
+ ]
170
+ }
171
+ ]
172
+ }
@@ -0,0 +1,228 @@
1
+ # Philips Air+ Device Models Configuration
2
+
3
+ models:
4
+ "AC0650/10":
5
+ name: "Philips Air+ AC0650/10"
6
+ modes:
7
+ Auto: 1
8
+ Sleep: 17
9
+ Turbo: 18
10
+ ports:
11
+ status: "Status"
12
+ control: "Control"
13
+ config: "Config"
14
+ filter_read: "filtRd"
15
+ filter_write: "filtWr"
16
+ properties:
17
+ fan_speed: "D0310C"
18
+ mode: "D0310C"
19
+ power: "D0310D"
20
+ filter_replace_nominal: "D05408"
21
+ filter_replace_remaining: "D0540E"
22
+ filter_clean_nominal: "D05207"
23
+ filter_clean_remaining: "D0520D"
24
+ filter_clean_reset_raw: "D0520D"
25
+ filter_clean_reset_value: 720 # hours written back when resetting clean-filter timer
26
+ filter_replace_reset_raw: "D0540E"
27
+ filter_replace_reset_value: 4800 # hours written back when resetting replace-filter timer
28
+ device_model: "ctn"
29
+ device_brand: "D01S04"
30
+ pm25: "D03221" # PM2.5 concentration (µg/m³)
31
+ fan_level: "D0310D" # Actual fan speed level (0=off, 1=slow … 18=turbo)
32
+ sensors:
33
+ - filter_replace_percentage
34
+ - filter_replace_hours_remaining
35
+ - filter_clean_percentage
36
+ - filter_clean_hours_remaining
37
+ - pm25
38
+ - fan_level
39
+ buttons:
40
+ - reset_filter_clean
41
+ - reset_filter_replace
42
+
43
+ "AC0651/10":
44
+ name: "Philips Air+ AC0651/10"
45
+ modes:
46
+ Auto: 0
47
+ Medium: 1
48
+ Sleep: 17
49
+ Turbo: 18
50
+ ports:
51
+ status: "Status"
52
+ control: "Control"
53
+ config: "Config"
54
+ filter_read: "filtRd"
55
+ filter_write: "filtWr"
56
+ properties:
57
+ fan_speed: "D0310C"
58
+ mode: "D0310C"
59
+ power: "D0310D"
60
+ filter_replace_nominal: "D05408"
61
+ filter_replace_remaining: "D0540E"
62
+ filter_clean_nominal: "D05207"
63
+ filter_clean_remaining: "D0520D"
64
+ filter_clean_reset_raw: "D0520D"
65
+ filter_clean_reset_value: 720 # hours written back when resetting clean-filter timer
66
+ filter_replace_reset_raw: "D0540E"
67
+ filter_replace_reset_value: 4800 # hours written back when resetting replace-filter timer
68
+ device_model: "ctn"
69
+ device_brand: "D01S04"
70
+ pm25: "D03221" # PM2.5 concentration (µg/m³)
71
+ allergen_index: "D03120" # Allergen index
72
+ standby_monitor: "D03134" # Sensor standby monitor (diagnostic)
73
+ diag_D0312C: "D0312C" # Unknown diagnostic property (always 4 on AC0651/10)
74
+ fan_level: "D0310D" # Actual fan speed level (0=off, 1=slow … 18=turbo)
75
+ sensors:
76
+ - filter_replace_percentage
77
+ - filter_replace_hours_remaining
78
+ - filter_clean_percentage
79
+ - filter_clean_hours_remaining
80
+ - pm25
81
+ - allergen_index
82
+ - fan_level
83
+ - diag_D0312C
84
+ switches:
85
+ - standby_monitor
86
+ buttons:
87
+ - reset_filter_clean
88
+ - reset_filter_replace
89
+
90
+ "AC1715/70":
91
+ name: "Philips Air+ AC1715/70"
92
+ modes:
93
+ Auto: 0
94
+ Sleep: 17
95
+ Medium: 1
96
+ Fast: 2
97
+ Turbo: 18
98
+ ports:
99
+ status: "Status"
100
+ control: "Control"
101
+ config: "Config"
102
+ filter_read: "filtRd"
103
+ filter_write: "filtWr"
104
+ properties:
105
+ fan_speed: "D0310C"
106
+ mode: "D0310C"
107
+ power: "D0310D"
108
+ filter_replace_nominal: "D05408"
109
+ filter_replace_remaining: "D0540E"
110
+ filter_clean_nominal: "D05207"
111
+ filter_clean_remaining: "D0520D"
112
+ filter_clean_reset_raw: "D0520D"
113
+ filter_clean_reset_value: 720
114
+ filter_replace_reset_raw: "D0540E"
115
+ filter_replace_reset_value: 4800
116
+ device_model: "ctn"
117
+ device_brand: "D01S04"
118
+ pm25: "D03221"
119
+ fan_level: "D0310D"
120
+ sensors:
121
+ - filter_replace_percentage
122
+ - filter_replace_hours_remaining
123
+ - filter_clean_percentage
124
+ - filter_clean_hours_remaining
125
+ - pm25
126
+ - fan_level
127
+ buttons:
128
+ - reset_filter_clean
129
+ - reset_filter_replace
130
+
131
+ "AC1715/11":
132
+ name: "Philips Air+ AC1715/11"
133
+ modes:
134
+ Auto: 0
135
+ Sleep: 17
136
+ Medium: 1
137
+ Fast: 2
138
+ Turbo: 18
139
+ ports:
140
+ status: "Status"
141
+ control: "Control"
142
+ config: "Config"
143
+ filter_read: "filtRd"
144
+ filter_write: "filtWr"
145
+ properties:
146
+ fan_speed: "D0310C"
147
+ mode: "D0310C"
148
+ power: "D0310D"
149
+ filter_replace_nominal: "D05408"
150
+ filter_replace_remaining: "D0540E"
151
+ filter_clean_nominal: "D05207"
152
+ filter_clean_remaining: "D0520D"
153
+ filter_clean_reset_raw: "D0520D"
154
+ filter_clean_reset_value: 720
155
+ filter_replace_reset_raw: "D0540E"
156
+ filter_replace_reset_value: 4800
157
+ device_model: "ctn"
158
+ device_brand: "D01S04"
159
+ pm25: "D03221"
160
+ allergen_index: "D03120"
161
+ fan_level: "D0310D"
162
+ sensors:
163
+ - filter_replace_percentage
164
+ - filter_replace_hours_remaining
165
+ - filter_clean_percentage
166
+ - filter_clean_hours_remaining
167
+ - pm25
168
+ - fan_level
169
+ - allergen_index
170
+ buttons:
171
+ - reset_filter_clean
172
+ - reset_filter_replace
173
+
174
+ "AC3221":
175
+ # PureProtect 3200i. Property keys are unverified against real device
176
+ # traffic (mapped from the equivalent CoAP "D03/D05" property scheme
177
+ # shared with kongo09/philips-airpurifier-coap's AC32xx family, which
178
+ # uses the identical D03xxx/D05xxx addressing for fan mode, PM2.5,
179
+ # allergen index and filter properties as the already-confirmed
180
+ # AC1715/AC0650 entries above). Model matching is by prefix, so any
181
+ # reported ctn starting with "AC3221" (e.g. "AC3221/10") picks this up.
182
+ # Please open an issue with debug logs if any entity reports an
183
+ # incorrect value so this can be corrected.
184
+ name: "Philips PureProtect 3200i (AC3221)"
185
+ modes:
186
+ Auto: 0
187
+ Speed1: 1
188
+ Speed2: 2
189
+ Speed3: 3
190
+ Speed4: 4
191
+ Speed5: 5
192
+ Sleep: 17
193
+ Turbo: 18
194
+ Medium: 19
195
+ ports:
196
+ status: "Status"
197
+ control: "Control"
198
+ config: "Config"
199
+ filter_read: "filtRd"
200
+ filter_write: "filtWr"
201
+ properties:
202
+ fan_speed: "D0310C"
203
+ mode: "D0310C"
204
+ power: "D0310D"
205
+ filter_replace_nominal: "D05408"
206
+ filter_replace_remaining: "D0540E"
207
+ filter_clean_nominal: "D05207"
208
+ filter_clean_remaining: "D0520D"
209
+ filter_clean_reset_raw: "D0520D"
210
+ filter_clean_reset_value: 720
211
+ filter_replace_reset_raw: "D0540E"
212
+ filter_replace_reset_value: 4800
213
+ device_model: "ctn"
214
+ device_brand: "D01S04"
215
+ pm25: "D03221"
216
+ allergen_index: "D03120"
217
+ fan_level: "D0310D"
218
+ sensors:
219
+ - filter_replace_percentage
220
+ - filter_replace_hours_remaining
221
+ - filter_clean_percentage
222
+ - filter_clean_hours_remaining
223
+ - pm25
224
+ - allergen_index
225
+ - fan_level
226
+ buttons:
227
+ - reset_filter_clean
228
+ - reset_filter_replace