homebridge-philips-airplus-cloud 0.3.0 → 0.3.1
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 +4 -0
- package/package.json +1 -1
- package/src/accessory.js +5 -2
- package/src/models.js +13 -5
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,10 @@
|
|
|
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.1 — 2026-10-11
|
|
6
|
+
|
|
7
|
+
- Fix: on a fresh install the purifier started with the reduced profile ("Model AC0651 is not in models.yaml") because the cloud device list gives the model without its `/10` suffix. The short code now matches its `models.yaml` entry, and an unknown code waits for the exact one reported by the device.
|
|
8
|
+
|
|
5
9
|
## 0.3.0 — 2026-10-11
|
|
6
10
|
|
|
7
11
|
- 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.
|
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.1",
|
|
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",
|
package/src/accessory.js
CHANGED
|
@@ -78,9 +78,12 @@ class PurifierAccessory {
|
|
|
78
78
|
});
|
|
79
79
|
this.conn.on('message', (m, topic) => this._onMessage(m, topic));
|
|
80
80
|
|
|
81
|
+
// The cached/cloud model code is only a hint: if it does not match a
|
|
82
|
+
// models.yaml entry, wait for the device to report its exact code on the
|
|
83
|
+
// Config port instead of starting with the reduced fallback profile.
|
|
81
84
|
const known = accessory.context.model;
|
|
82
|
-
if (known) this._applyModel(known, false);
|
|
83
|
-
else this.log.info(
|
|
85
|
+
if (known && findModel(known)) this._applyModel(known, false);
|
|
86
|
+
else this.log.info(`Model ${known ? `${known} ` : ''}not identified yet; waiting for the device to report it`);
|
|
84
87
|
|
|
85
88
|
this._setInfo();
|
|
86
89
|
}
|
package/src/models.js
CHANGED
|
@@ -24,14 +24,22 @@ function loadModels(file = MODELS_FILE) {
|
|
|
24
24
|
return cache;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
/**
|
|
27
|
+
/**
|
|
28
|
+
* Exact match first, then prefix match either way:
|
|
29
|
+
* - "AC3221/10" -> "AC3221" (device reports a longer code than the yaml key)
|
|
30
|
+
* - "AC0651" -> "AC0651/10" (the cloud device list omits the /xx suffix)
|
|
31
|
+
*/
|
|
28
32
|
function findModel(ctn) {
|
|
29
33
|
if (!ctn) return null;
|
|
34
|
+
const code = String(ctn).trim().toUpperCase();
|
|
30
35
|
const models = loadModels();
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
36
|
+
const entries = Object.entries(models);
|
|
37
|
+
const exact = entries.find(([key]) => key.toUpperCase() === code);
|
|
38
|
+
if (exact) return { key: exact[0], ...exact[1] };
|
|
39
|
+
const longer = entries.find(([key]) => code.startsWith(key.toUpperCase()));
|
|
40
|
+
if (longer) return { key: longer[0], ...longer[1] };
|
|
41
|
+
const base = entries.find(([key]) => key.toUpperCase().startsWith(`${code}/`));
|
|
42
|
+
if (base) return { key: base[0], ...base[1] };
|
|
35
43
|
return null;
|
|
36
44
|
}
|
|
37
45
|
|