homebridge-slwf-01pro 0.1.2 → 0.2.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 +51 -0
- package/README.md +34 -14
- package/config-sample.json +2 -2
- package/config.schema.json +1 -1
- package/index.js +1 -1
- package/lib/esphome.js +50 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,57 @@ This package is a maintained fork of [`homebridge-esphome-ac`](https://github.co
|
|
|
7
7
|
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
+
## [0.2.0] — 2026-05-06
|
|
11
|
+
|
|
12
|
+
Clean separation from upstream `homebridge-esphome-ac`. Breaking config change (one-line edit) but eliminates all namespace collision risk.
|
|
13
|
+
|
|
14
|
+
### ⚠️ Breaking — config.json edit required
|
|
15
|
+
|
|
16
|
+
The Homebridge platform identifier has been renamed from `"ESPHomeAC"` (shared with upstream) to **`"SLWFOnePro"`** (ours alone). Update your `config.json`:
|
|
17
|
+
|
|
18
|
+
```diff
|
|
19
|
+
- "platform": "ESPHomeAC",
|
|
20
|
+
+ "platform": "SLWFOnePro",
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Restart Homebridge after the edit. The plugin detects orphaned cached accessories from the old identifier and logs a clear warning with cleanup instructions on first start.
|
|
24
|
+
|
|
25
|
+
### Why
|
|
26
|
+
|
|
27
|
+
Before 0.2.0, the platform identifier was shared with upstream `homebridge-esphome-ac` for "drop-in migration" compatibility. In practice this caused two real problems:
|
|
28
|
+
|
|
29
|
+
1. **Cache collisions** — when both plugins were ever installed in the same Homebridge (even temporarily during a migration), accessories cached under upstream's plugin name became orphans that no live plugin claims, but the platform identifier overlap made it ambiguous which plugin "owned" them.
|
|
30
|
+
2. **Confusing logs** — Homebridge's startup log lists all installed platforms by `<plugin>.<platformName>`. Both plugins claiming `ESPHomeAC` made the dependency graph unreadable.
|
|
31
|
+
|
|
32
|
+
After 0.2.0, the two plugins are completely independent: separate npm names, separate platform identifiers, no shared state. Both can coexist on the same Homebridge without interfering.
|
|
33
|
+
|
|
34
|
+
### Added
|
|
35
|
+
|
|
36
|
+
- **`detectOrphanedAccessories(platform)` in `lib/esphome.js`.** Best-effort scan of the bridge's `cachedAccessories.<bridgeId>` files at startup. Warns about:
|
|
37
|
+
- Accessories cached under upstream `homebridge-esphome-ac`
|
|
38
|
+
- Accessories cached under our plugin name but the **legacy** `ESPHomeAC` platform identifier (i.e. pre-0.2.0 entries left after the rename)
|
|
39
|
+
Both warnings include explicit cleanup paths (Homebridge UI step + filesystem path). Best-effort — wrapped in try/catch, never throws, falls through silently if the cache directory doesn't exist or files are malformed.
|
|
40
|
+
|
|
41
|
+
### Changed
|
|
42
|
+
|
|
43
|
+
- **Platform identifier `ESPHomeAC` → `SLWFOnePro`** in `index.js` `PLATFORM_NAME`, `config.schema.json` `pluginAlias`, `config-sample.json`, README, CLAUDE.md, QA_TESTS.md.
|
|
44
|
+
- **Upstream git remote removed** (`git remote remove upstream`). The fork is intentionally divergent. CLAUDE.md fork rules updated; if anyone needs upstream history they can re-add the remote ad-hoc.
|
|
45
|
+
|
|
46
|
+
### Migration
|
|
47
|
+
|
|
48
|
+
For anyone on `homebridge-slwf-01pro@0.1.x`:
|
|
49
|
+
1. `sudo npm install -g homebridge-slwf-01pro@latest`
|
|
50
|
+
2. Edit `config.json`: `"platform": "ESPHomeAC"` → `"platform": "SLWFOnePro"` (and the `name` field if you used the default).
|
|
51
|
+
3. Restart Homebridge.
|
|
52
|
+
4. Log will warn about the orphaned 0.1.x cached accessories. Clean via Homebridge UI → Settings → Remove Single Cached Accessory.
|
|
53
|
+
|
|
54
|
+
For anyone migrating from upstream `homebridge-esphome-ac`:
|
|
55
|
+
1. `sudo npm uninstall -g homebridge-esphome-ac && sudo npm install -g homebridge-slwf-01pro`
|
|
56
|
+
2. Same `config.json` edit as above.
|
|
57
|
+
3. Restart. Log warns about upstream's orphaned cache entries. Clean via UI.
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
10
61
|
## [0.1.2] — 2026-05-06
|
|
11
62
|
|
|
12
63
|
Critical bug fix surfaced by the first real-hardware test of 0.1.0/0.1.1.
|
package/README.md
CHANGED
|
@@ -56,8 +56,8 @@ The simplest config — auto-discover everything on the local network:
|
|
|
56
56
|
{
|
|
57
57
|
"platforms": [
|
|
58
58
|
{
|
|
59
|
-
"platform": "
|
|
60
|
-
"name": "
|
|
59
|
+
"platform": "SLWFOnePro",
|
|
60
|
+
"name": "SLWFOnePro",
|
|
61
61
|
"autoDiscover": true
|
|
62
62
|
}
|
|
63
63
|
]
|
|
@@ -70,8 +70,8 @@ Or fully manual (required for encrypted devices and any device not on the same b
|
|
|
70
70
|
{
|
|
71
71
|
"platforms": [
|
|
72
72
|
{
|
|
73
|
-
"platform": "
|
|
74
|
-
"name": "
|
|
73
|
+
"platform": "SLWFOnePro",
|
|
74
|
+
"name": "SLWFOnePro",
|
|
75
75
|
"debug": false,
|
|
76
76
|
"devices": [
|
|
77
77
|
{
|
|
@@ -93,8 +93,8 @@ You can mix both — listed devices in `devices[]` take precedence; auto-discove
|
|
|
93
93
|
|
|
94
94
|
| Key | Required | Default | Notes |
|
|
95
95
|
|---|---|---|---|
|
|
96
|
-
| `platform` | yes | — | Must be exactly `"
|
|
97
|
-
| `name` | no | `
|
|
96
|
+
| `platform` | yes | — | Must be exactly `"SLWFOnePro"` (the platform identifier — distinct from upstream `homebridge-esphome-ac`'s `"ESPHomeAC"` to guarantee no namespace collision when both plugins are installed). Pre-0.2.0 configs using `"ESPHomeAC"` need a one-line edit. |
|
|
97
|
+
| `name` | no | `SLWFOnePro` | Display name in Homebridge logs |
|
|
98
98
|
| `debug` | no | `false` | Surface ESPHome state-change chatter to the main log instead of `log.debug` |
|
|
99
99
|
| `autoDiscover` | no | `false` | mDNS-browse for ESPHome devices on the local network and create accessories automatically. Encrypted devices still need a manual `devices[]` entry — the Noise key is not broadcast. |
|
|
100
100
|
| `discoveryTimeout` | no | `5` | Seconds to wait for mDNS responses before continuing. |
|
|
@@ -184,17 +184,37 @@ If the device advertises any swing mode beyond OFF, a HomeKit Swing toggle is ex
|
|
|
184
184
|
|
|
185
185
|
## Migration
|
|
186
186
|
|
|
187
|
-
|
|
187
|
+
### From upstream `homebridge-esphome-ac`
|
|
188
188
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
189
|
+
Both the npm package name AND the Homebridge platform identifier are different from upstream — that's deliberate, and it means the two plugins never share cache or namespace. Migration is two short steps:
|
|
190
|
+
|
|
191
|
+
1. **Replace the package**:
|
|
192
|
+
```bash
|
|
193
|
+
sudo npm uninstall -g homebridge-esphome-ac
|
|
194
|
+
sudo npm install -g homebridge-slwf-01pro
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
2. **Edit `config.json`** — change `"platform": "ESPHomeAC"` to `"platform": "SLWFOnePro"`:
|
|
198
|
+
```jsonc
|
|
199
|
+
{
|
|
200
|
+
"platforms": [
|
|
201
|
+
{
|
|
202
|
+
"platform": "SLWFOnePro", // ← was "ESPHomeAC"
|
|
203
|
+
"name": "SLWFOnePro", // ← rename to match (or keep your custom name)
|
|
204
|
+
"autoDiscover": true,
|
|
205
|
+
"devices": [ /* ...same as before... */ ]
|
|
206
|
+
}
|
|
207
|
+
]
|
|
208
|
+
}
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
3. **Restart Homebridge**: `sudo systemctl restart homebridge` (or via UI).
|
|
212
|
+
|
|
213
|
+
The plugin will detect any cached accessories left over from upstream and **log a warning** with cleanup instructions on startup. Clean them via Homebridge UI → Settings → Remove Single Cached Accessory, or stop the (child) bridge and delete the relevant `cachedAccessories.<bridgeId>` file. The new accessories from this plugin will re-pair automatically on the next restart with stable UUIDs derived from each device's ESPHome `unique_id` (or from the MAC + `object_id` when `unique_id` isn't set).
|
|
194
214
|
|
|
195
|
-
|
|
215
|
+
### From a pre-0.2.0 release of this plugin
|
|
196
216
|
|
|
197
|
-
If
|
|
217
|
+
If you upgraded from `homebridge-slwf-01pro@0.1.x`, the platform identifier rename is the only change you need to apply (step 2 above). The plugin will detect old `"ESPHomeAC"` cached entries and log a warning the same way.
|
|
198
218
|
|
|
199
219
|
## Known SLWF-01Pro quirks
|
|
200
220
|
|
package/config-sample.json
CHANGED
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
"description": "Sample config for the homebridge-SLWF-01Pro fork. Pick auto-discovery OR manual devices, or both.",
|
|
10
10
|
"platforms": [
|
|
11
11
|
{
|
|
12
|
-
"platform": "
|
|
13
|
-
"name": "
|
|
12
|
+
"platform": "SLWFOnePro",
|
|
13
|
+
"name": "SLWFOnePro",
|
|
14
14
|
"debug": false,
|
|
15
15
|
"autoDiscover": true,
|
|
16
16
|
"discoveryTimeout": 5,
|
package/config.schema.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"pluginAlias": "
|
|
2
|
+
"pluginAlias": "SLWFOnePro",
|
|
3
3
|
"pluginType": "platform",
|
|
4
4
|
"singular": true,
|
|
5
5
|
"headerDisplay": "Homebridge plugin for ESPHome AC controllers (SLWF-01Pro Wi-Fi dongle and other ESPHome `Climate` entities). Supports auto-discovery, humidity / outdoor-temperature / power sensors, beeper / display switches, and DRY / FAN_ONLY mode tiles.",
|
package/index.js
CHANGED
package/lib/esphome.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
1
3
|
const { Client } = require('@2colors/esphome-native-api');
|
|
2
4
|
const DeviceAccessory = require('./DeviceAccessory');
|
|
3
5
|
const { discoverDevices } = require('./discovery');
|
|
@@ -6,13 +8,61 @@ const { bundleEntities } = require('./classifyEntity');
|
|
|
6
8
|
const RECONNECT_INTERVAL_MS = 5000;
|
|
7
9
|
const DEFAULT_DISCOVERY_TIMEOUT_S = 5;
|
|
8
10
|
|
|
11
|
+
const UPSTREAM_PLUGIN_NAME = 'homebridge-esphome-ac';
|
|
12
|
+
const LEGACY_PLATFORM_NAME = 'ESPHomeAC';
|
|
13
|
+
|
|
9
14
|
function normalizeHost(value) {
|
|
10
15
|
if (!value) return '';
|
|
11
16
|
return value.toString().toLowerCase().replace(/\.local\.?$/, '').replace(/\.$/, '');
|
|
12
17
|
}
|
|
13
18
|
|
|
19
|
+
function detectOrphanedAccessories(platform) {
|
|
20
|
+
try {
|
|
21
|
+
const cacheDir = path.join(platform.api.user.persistPath(), 'accessories');
|
|
22
|
+
if (!fs.existsSync(cacheDir)) return;
|
|
23
|
+
|
|
24
|
+
const files = fs.readdirSync(cacheDir).filter(f => f.startsWith('cachedAccessories.'));
|
|
25
|
+
let upstreamCount = 0;
|
|
26
|
+
let legacyPlatformCount = 0;
|
|
27
|
+
|
|
28
|
+
for (const file of files) {
|
|
29
|
+
let content;
|
|
30
|
+
try {
|
|
31
|
+
content = JSON.parse(fs.readFileSync(path.join(cacheDir, file), 'utf8'));
|
|
32
|
+
} catch (_e) {
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
if (!Array.isArray(content)) continue;
|
|
36
|
+
for (const acc of content) {
|
|
37
|
+
if (!acc) continue;
|
|
38
|
+
if (acc.plugin === UPSTREAM_PLUGIN_NAME) upstreamCount++;
|
|
39
|
+
else if (acc.plugin === platform.PLUGIN_NAME && acc.platform === LEGACY_PLATFORM_NAME) legacyPlatformCount++;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (upstreamCount > 0) {
|
|
44
|
+
platform.log.warn(
|
|
45
|
+
`Detected ${upstreamCount} cached accessor${upstreamCount === 1 ? 'y' : 'ies'} from upstream "${UPSTREAM_PLUGIN_NAME}". ` +
|
|
46
|
+
`These are orphans (this plugin is "${platform.PLUGIN_NAME}", different name). ` +
|
|
47
|
+
`Clean up via Homebridge UI → Settings → Remove Single Cached Accessory, ` +
|
|
48
|
+
`or stop Homebridge and delete cachedAccessories.* in ${cacheDir}, then restart.`
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
if (legacyPlatformCount > 0) {
|
|
52
|
+
platform.log.warn(
|
|
53
|
+
`Detected ${legacyPlatformCount} cached accessor${legacyPlatformCount === 1 ? 'y' : 'ies'} using the legacy "${LEGACY_PLATFORM_NAME}" platform identifier (pre-0.2.0). ` +
|
|
54
|
+
`The platform was renamed to "SLWFOnePro" in v0.2.0; the old entries are orphans. ` +
|
|
55
|
+
`Update your config.json (\`"platform": "SLWFOnePro"\`) and clean up via Homebridge UI → Settings → Remove Single Cached Accessory.`
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
} catch (err) {
|
|
59
|
+
platform.log.easyDebug(`Orphan detection failed (non-fatal): ${err.message || err}`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
14
63
|
async function init() {
|
|
15
64
|
const platform = this;
|
|
65
|
+
detectOrphanedAccessories(platform);
|
|
16
66
|
platform._clients = [];
|
|
17
67
|
|
|
18
68
|
const manualDevices = (platform.devices || []).map(d => ({
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "homebridge-slwf-01pro",
|
|
3
3
|
"description": "Homebridge plugin for the SMLIGHT SLWF-01Pro Wi-Fi dongle and other ESPHome Climate entities. Auto-discovery, multi-entity bundling, and full Midea-protocol AC support.",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.2.0",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "git+https://github.com/nookied/homebridge-SLWF-01Pro.git"
|