homebridge-philips-airplus-cloud 0.3.5 → 0.3.8
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 +12 -0
- package/README.md +1 -1
- package/config.schema.json +18 -14
- package/package.json +2 -1
- package/src/accessory.js +8 -41
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
The Home Assistant integration in `custom_components/` is unchanged from upstream and keeps its own history.
|
|
4
4
|
|
|
5
|
+
## 0.3.8 — 2026-10-11
|
|
6
|
+
|
|
7
|
+
- Homebridge verification: `supports-hap` keyword; config schema uses object-level `required` arrays instead of per-field `required: true`. No functional changes.
|
|
8
|
+
|
|
9
|
+
## 0.3.7 — 2026-10-11
|
|
10
|
+
|
|
11
|
+
- Removed the `labelRefresh` option added in 0.3.5: it did not help, the missing labels were caused by linked components (fixed in 0.3.6). A leftover `labelRefresh` value in the config is simply ignored.
|
|
12
|
+
|
|
13
|
+
## 0.3.6 — 2026-10-11
|
|
14
|
+
|
|
15
|
+
- Components (Sleep, Air Quality, Filter, Pre-filter, Display) are no longer linked to the purifier by default. The Home app draws linked components as controls of the purifier without their names; unlinked ones get their own labelled tile in the purifier's combined view. Existing links are removed on startup. Set `linkComponents: true` to link them again.
|
|
16
|
+
|
|
5
17
|
## 0.3.5 — 2026-10-11
|
|
6
18
|
|
|
7
19
|
- Option `labelRefresh`: if the Home app does not show the labels under the purifier's components in its combined view, set any new value and restart. About 40 s after startup the plugin renames the components in two steps (long name, then short label), replaying the rename that made Home show the labels before. Names set in the Home app are replaced by the defaults.
|
package/README.md
CHANGED
|
@@ -80,11 +80,11 @@ The refresh token rotates on every use; the plugin keeps the current one in `<ho
|
|
|
80
80
|
| `filterSensors` | `true` | Show filter and pre-filter status |
|
|
81
81
|
| `sleepSwitch` | `true` | Show the Sleep mode switch |
|
|
82
82
|
| `sleepSwitchStyle` | `switch` | `purifier` shows the Sleep control as a second air purifier (purifier icon in Home) that only turns Sleep on/off |
|
|
83
|
+
| `linkComponents` | `false` | Link Sleep, air quality and filters to the purifier. Off: each gets its own labelled tile in the purifier's combined view. On: Home shows them as controls inside the purifier, without labels |
|
|
83
84
|
| `displayLight` | `true` | Show the display light |
|
|
84
85
|
| `displayLightProperty` | — | Property key of the display light, if it is not detected (see the `Status properties reported by the device` log line) |
|
|
85
86
|
| `logDeviceData` | `false` | Diagnostics: at startup, log every port and the cloud shadow the purifier publishes |
|
|
86
87
|
| `homekitIdentity` | — | Change to any new value to give the purifier a new HomeKit identity (use only if the Home app refuses to move or rename it; reassign the room afterwards) |
|
|
87
|
-
| `labelRefresh` | — | Change to any new value if the Home app does not show the labels under the components; the plugin renames them in two steps ~40 s after startup (Home-app renames are replaced) |
|
|
88
88
|
| `filterChangeThreshold` | `10` | Filter life (%) at or below which HomeKit shows "replace filter" |
|
|
89
89
|
| `pollInterval` | `120` | Seconds between safety-net status polls |
|
|
90
90
|
|
package/config.schema.json
CHANGED
|
@@ -10,8 +10,7 @@
|
|
|
10
10
|
"name": {
|
|
11
11
|
"title": "Name",
|
|
12
12
|
"type": "string",
|
|
13
|
-
"default": "Philips Air+"
|
|
14
|
-
"required": true
|
|
13
|
+
"default": "Philips Air+"
|
|
15
14
|
},
|
|
16
15
|
"email": {
|
|
17
16
|
"title": "Philips account email",
|
|
@@ -41,8 +40,7 @@
|
|
|
41
40
|
"properties": {
|
|
42
41
|
"uuid": {
|
|
43
42
|
"title": "Device UUID",
|
|
44
|
-
"type": "string"
|
|
45
|
-
"required": true
|
|
43
|
+
"type": "string"
|
|
46
44
|
},
|
|
47
45
|
"name": {
|
|
48
46
|
"title": "Name in HomeKit",
|
|
@@ -53,7 +51,10 @@
|
|
|
53
51
|
"type": "string",
|
|
54
52
|
"description": "e.g. AC0651/10. Normally detected automatically."
|
|
55
53
|
}
|
|
56
|
-
}
|
|
54
|
+
},
|
|
55
|
+
"required": [
|
|
56
|
+
"uuid"
|
|
57
|
+
]
|
|
57
58
|
}
|
|
58
59
|
},
|
|
59
60
|
"airQualitySensor": {
|
|
@@ -91,6 +92,12 @@
|
|
|
91
92
|
],
|
|
92
93
|
"description": "'Air purifier' shows Sleep with the purifier icon in the Home app; it only turns Sleep mode on and off."
|
|
93
94
|
},
|
|
95
|
+
"linkComponents": {
|
|
96
|
+
"title": "Link components to the purifier",
|
|
97
|
+
"type": "boolean",
|
|
98
|
+
"default": false,
|
|
99
|
+
"description": "Off (default): Sleep, air quality and filters get their own labelled tile in the purifier's combined view. On: the Home app shows them as controls inside the purifier, without labels."
|
|
100
|
+
},
|
|
94
101
|
"displayLight": {
|
|
95
102
|
"title": "Show the display light as a dimmable light",
|
|
96
103
|
"type": "boolean",
|
|
@@ -128,14 +135,11 @@
|
|
|
128
135
|
"type": "string",
|
|
129
136
|
"placeholder": "e.g. 2",
|
|
130
137
|
"description": "Only if the Home app refuses to move or rename the purifier: type any new value (e.g. 2, then 3 next time) and restart. Home will see the purifier as a new accessory; reassign its room and check your scenes afterwards."
|
|
131
|
-
},
|
|
132
|
-
"labelRefresh": {
|
|
133
|
-
"title": "Refresh component labels (advanced)",
|
|
134
|
-
"type": "string",
|
|
135
|
-
"placeholder": "e.g. 1",
|
|
136
|
-
"description": "If the Home app does not show the labels under the purifier's components, type any new value and restart: about 40 seconds after startup the plugin renames the components in two steps so Home picks the labels up. Names you set in the Home app are replaced by the default ones."
|
|
137
138
|
}
|
|
138
|
-
}
|
|
139
|
+
},
|
|
140
|
+
"required": [
|
|
141
|
+
"name"
|
|
142
|
+
]
|
|
139
143
|
},
|
|
140
144
|
"layout": [
|
|
141
145
|
"name",
|
|
@@ -173,13 +177,13 @@
|
|
|
173
177
|
"filterSensors",
|
|
174
178
|
"sleepSwitch",
|
|
175
179
|
"sleepSwitchStyle",
|
|
180
|
+
"linkComponents",
|
|
176
181
|
"displayLight",
|
|
177
182
|
"displayLightProperty",
|
|
178
183
|
"filterChangeThreshold",
|
|
179
184
|
"pollInterval",
|
|
180
185
|
"logDeviceData",
|
|
181
|
-
"homekitIdentity"
|
|
182
|
-
"labelRefresh"
|
|
186
|
+
"homekitIdentity"
|
|
183
187
|
]
|
|
184
188
|
}
|
|
185
189
|
]
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "homebridge-philips-airplus-cloud",
|
|
3
3
|
"displayName": "Philips Air+",
|
|
4
|
-
"version": "0.3.
|
|
4
|
+
"version": "0.3.8",
|
|
5
5
|
"description": "Homebridge plugin for Philips Air+ / PureProtect air purifiers via the Philips (Versuni) cloud — the same MQTT protocol used by the Air+ app and Google Home.",
|
|
6
6
|
"main": "src/index.js",
|
|
7
7
|
"license": "MIT",
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
"homepage": "https://github.com/Micheledipaola/homebridge-philips-airplus#readme",
|
|
16
16
|
"keywords": [
|
|
17
17
|
"homebridge-plugin",
|
|
18
|
+
"supports-hap",
|
|
18
19
|
"philips",
|
|
19
20
|
"air purifier",
|
|
20
21
|
"air+",
|
package/src/accessory.js
CHANGED
|
@@ -90,7 +90,6 @@ class PurifierAccessory {
|
|
|
90
90
|
|
|
91
91
|
start() {
|
|
92
92
|
this.conn.start();
|
|
93
|
-
this._scheduleLabelRefresh();
|
|
94
93
|
const pollS = Math.max(30, Number(this.platform.config.pollInterval) || C.STATUS_POLL_INTERVAL_S);
|
|
95
94
|
// Watchdog: the cloud connection can stay open but stop delivering data.
|
|
96
95
|
// Every poll asks the device for its status, so if nothing has arrived for
|
|
@@ -120,44 +119,7 @@ class PurifierAccessory {
|
|
|
120
119
|
}, C.FILTER_POLL_INTERVAL_MS);
|
|
121
120
|
}
|
|
122
121
|
|
|
123
|
-
/**
|
|
124
|
-
* labelRefresh: replays what made the Home app show labels under each
|
|
125
|
-
* component in the purifier's combined view — the plugin renaming the
|
|
126
|
-
* components while Home is connected (as the 0.2.1 update did, from
|
|
127
|
-
* "<purifier> Air Quality" to "Air Quality"). Runs once per new value.
|
|
128
|
-
* Names given in the Home app are replaced by the default labels.
|
|
129
|
-
*/
|
|
130
|
-
_scheduleLabelRefresh() {
|
|
131
|
-
const want = String(this.platform.config.labelRefresh || '').trim();
|
|
132
|
-
if (!want || this.accessory.context.labelRefresh === want) return;
|
|
133
|
-
const { Characteristic } = this.hap;
|
|
134
|
-
const STEP_MS = 20000;
|
|
135
|
-
const targets = () => this.accessory.services.filter((x) => x.__label && x !== this.purifier);
|
|
136
|
-
const rename = (long) => {
|
|
137
|
-
for (const x of targets()) {
|
|
138
|
-
const name = long ? `${this.accessory.displayName} ${x.__label}` : x.__label;
|
|
139
|
-
x.updateCharacteristic(Characteristic.Name, name);
|
|
140
|
-
if (x.testCharacteristic(Characteristic.ConfiguredName)) x.updateCharacteristic(Characteristic.ConfiguredName, name);
|
|
141
|
-
}
|
|
142
|
-
};
|
|
143
|
-
this._labelTimers = [
|
|
144
|
-
setTimeout(() => {
|
|
145
|
-
if (!targets().length) return;
|
|
146
|
-
this.log.info('labelRefresh: renaming components in two steps so the Home app shows their labels');
|
|
147
|
-
rename(true);
|
|
148
|
-
}, STEP_MS),
|
|
149
|
-
setTimeout(() => {
|
|
150
|
-
if (!targets().length) return;
|
|
151
|
-
rename(false);
|
|
152
|
-
this.accessory.context.labelRefresh = want;
|
|
153
|
-
this.platform.updateAccessory(this.accessory);
|
|
154
|
-
this.log.info('labelRefresh: done');
|
|
155
|
-
}, 2 * STEP_MS),
|
|
156
|
-
];
|
|
157
|
-
}
|
|
158
|
-
|
|
159
122
|
stop() {
|
|
160
|
-
(this._labelTimers || []).forEach(clearTimeout);
|
|
161
123
|
clearInterval(this.pollTimer);
|
|
162
124
|
clearInterval(this.filterTimer);
|
|
163
125
|
this.conn.stop();
|
|
@@ -227,7 +189,6 @@ class PurifierAccessory {
|
|
|
227
189
|
? this.accessory.getServiceById(type, subtype)
|
|
228
190
|
: this.accessory.services.find((x) => x.UUID === type.UUID && !x.subtype);
|
|
229
191
|
const s = existing || this.accessory.addService(type, label, subtype);
|
|
230
|
-
s.__label = label; // default label, used by labelRefresh (not persisted)
|
|
231
192
|
// Set the label on new services, and once on services created by older
|
|
232
193
|
// versions (which used long "<device> Sleep" names). Later user renames
|
|
233
194
|
// made in the Home app are kept.
|
|
@@ -238,8 +199,14 @@ class PurifierAccessory {
|
|
|
238
199
|
s.setCharacteristic(Characteristic.ConfiguredName, label);
|
|
239
200
|
}
|
|
240
201
|
}
|
|
241
|
-
|
|
242
|
-
|
|
202
|
+
// linkComponents (default off): linked components are drawn by the Home
|
|
203
|
+
// app as controls of the purifier, without their names; unlinked ones get
|
|
204
|
+
// their own labelled tile in the purifier's combined view.
|
|
205
|
+
if (this.purifier && s !== this.purifier) {
|
|
206
|
+
const linked = this.purifier.linkedServices.includes(s);
|
|
207
|
+
const want = link && this.platform.config.linkComponents === true;
|
|
208
|
+
if (want && !linked) this.purifier.addLinkedService(s);
|
|
209
|
+
if (!want && linked) this.purifier.removeLinkedService(s);
|
|
243
210
|
}
|
|
244
211
|
return s;
|
|
245
212
|
}
|