homebridge-slwf-01pro 0.1.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 +109 -0
- package/LICENSE +22 -0
- package/README.md +266 -0
- package/config-sample.json +31 -0
- package/config.schema.json +215 -0
- package/index.js +50 -0
- package/lib/DeviceAccessory.js +470 -0
- package/lib/classifyEntity.js +47 -0
- package/lib/discovery.js +57 -0
- package/lib/esphome.js +149 -0
- package/lib/eve.js +37 -0
- package/lib/state.js +121 -0
- package/lib/stateManager.js +152 -0
- package/package.json +57 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `homebridge-SLWF-01Pro` are documented here.
|
|
4
|
+
Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
|
5
|
+
|
|
6
|
+
This package is a maintained fork of [`homebridge-esphome-ac`](https://github.com/nitaybz/homebridge-esphome-ac). Pre-fork history below is the upstream history, kept for context.
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## [0.1.0] — Unreleased
|
|
11
|
+
|
|
12
|
+
First fork release — bug fixes, full multi-entity rewrite, and a substantial feature expansion. Adds mDNS auto-discovery, multi-entity HomeKit composition (humidity / outdoor temperature / power / beeper / display switches), DRY + FAN_ONLY mode tiles, Eve.Energy power graphs, and HEAT_COOL-mode AC support. Three independent code-review passes drove a follow-up cleanup.
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
|
|
16
|
+
- **mDNS auto-discovery.** New `autoDiscover` (and optional `discoveryTimeout`) config flag. When enabled, the plugin browses `_esphomelib._tcp` and creates accessories for any discovered ESPHome device that exposes a `Climate` entity. Manually configured devices in `devices[]` continue to work and are required for encrypted devices (the Noise key is not broadcast over mDNS).
|
|
17
|
+
- **Multi-entity per accessory.** A single ESPHome device's `Climate` + `Sensor` + `Switch` + `Button` entities are now bundled into one HomeKit accessory with multiple services. Previously only the climate entity was used; everything else from the device was silently dropped.
|
|
18
|
+
- **`Service.HumiditySensor`** when the ESPHome device exposes a `*humidity*` sensor entity. Hide with `disableHumiditySensor` (global) or `devices[].disableHumiditySensor` (per device) — useful for ACs that report a fake `0 %` because no probe is fitted.
|
|
19
|
+
- **`Service.TemperatureSensor` (outdoor)** when an `*outdoor*temp*` sensor is exposed. Hide with `disableOutdoorTempSensor`.
|
|
20
|
+
- **Eve.Energy power consumption** characteristic (`E863F10D-...`) on the climate accessory when a `*power*` sensor is exposed. Includes optional `fakegato-history` integration for Eve.app graphs. Hide with `disablePowerSensor`.
|
|
21
|
+
- **Beeper Switch** when the device exposes a `Switch` entity matching `*beeper*`. Hide with `disableBeeperSwitch`.
|
|
22
|
+
- **Display Toggle Switch** when the device exposes a `Button` entity matching `*display*`. Auto-resets to off after each tap (the underlying ESPHome entity is a stateless Button). Hide with `disableDisplaySwitch`.
|
|
23
|
+
- **DRY-mode Switch.** Companion `Service.Switch` on devices that advertise `ESP_MODE.DRY (5)`. Toggling ON sets the AC to DRY mode; toggling OFF restores the previous primary mode (HEAT/COOL/AUTO), or OFF if the device had no prior primary mode. Hide with `disableDryMode`.
|
|
24
|
+
- **FAN_ONLY-mode Switch.** Same pattern as DRY for `ESP_MODE.FAN_ONLY (4)`. Hide with `disableFanOnlyMode`.
|
|
25
|
+
- **`StatusActive` and `StatusFault` characteristics** on the climate service. Mirror the ESPHome client's connected/disconnected events: `StatusFault` flips to `GENERAL_FAULT` (red badge in HomeKit) when the device drops, and back to `NO_FAULT` on reconnect.
|
|
26
|
+
- **`FirmwareRevision` accessory characteristic** populated from the ESPHome `deviceInfo.esphomeVersion` field.
|
|
27
|
+
- **`lib/discovery.js`** — wraps the upstream `Discovery` class with a Promise-based API plus `prettyNameFromHostname` helper for naming auto-discovered devices.
|
|
28
|
+
- **`lib/classifyEntity.js`** — pure helper that maps ESPHome entities to HomeKit-service slots by name/objectId pattern. Unit-tested.
|
|
29
|
+
- **`lib/eve.js`** — Eve.Energy custom characteristic factory with HAP-NodeJS Formats/Perms fallback chain (handles HB 2.0 / HAP-NodeJS 2.x removal of static accessors).
|
|
30
|
+
- **`fakegato-history` dependency** at `^0.6.7`. Best-effort at runtime — `lib/DeviceAccessory.js` `try/catch`-wraps the `require` and disables history quietly if the module is unavailable.
|
|
31
|
+
- **`jest` test suite (78 tests).** Covers `lib/state.js` (mode mappers, fan conversions, swing defaults, capability checks), `lib/classifyEntity.js` (entity classification + bundling), and `lib/discovery.js` (hostname formatting + dedupe). `npm test` runs them.
|
|
32
|
+
- **`pickAutoMode`, `supportsCool`, `supportsHeat`** helpers in `lib/state.js` — encode the rule "AUTO and HEAT_COOL are interchangeable for HomeKit's AUTO target state".
|
|
33
|
+
- **`CLAUDE.md`, `AGENTS.md`, `ROADMAP.md`, `QA_TESTS.md`, this `CHANGELOG.md`** — full warmup-style doc set covering project memory, milestone plan, manual pre-release checklist.
|
|
34
|
+
- **GitHub Actions CI workflow** (`.github/workflows/ci.yml`) — lint + unit tests + smoke on Node 18.20.4, 20.15.1, 22.x, 24.x for every push and PR.
|
|
35
|
+
- **GitHub Actions release workflow** (`.github/workflows/release.yml`) — tag-driven (`v*`); verifies the tag matches `package.json` version, runs lint + tests, publishes to npm with `--provenance`, extracts release notes from CHANGELOG and creates a GitHub Release.
|
|
36
|
+
|
|
37
|
+
### Fixed
|
|
38
|
+
|
|
39
|
+
- **`HEAT_COOL (1)` vs `AUTO (6)` confusion.** The original code only handled ESPHome mode 6 (`AUTO`) when filtering valid HomeKit target states and when sending the AUTO command. Many AC devices (visible in real SLWF-01Pro web UIs) advertise `HEAT_COOL` (1) instead — so the HomeKit AUTO button would either not appear or send a mode the device couldn't honor. `pickAutoMode(supportedModesList)` now picks `AUTO` when supported, falling back to `HEAT_COOL`. `supportsCool/Heat` also recognize `HEAT_COOL` as implying both directions.
|
|
40
|
+
- **Multi-device commands could be lost.** `stateManager.js` used a module-level `sendTimeout` shared across every configured ESPHome device. The debounce timer is now per-device (`that._sendTimeout`).
|
|
41
|
+
- **Crash on disconnected device.** `stateManager.sendState` referenced an undefined `log` symbol — every send to a disconnected device threw `ReferenceError: log is not defined` instead of returning a clean HomeKit "Not Responding". Now uses `that.log.error` and rejects with `HapStatusError(SERVICE_COMMUNICATION_FAILURE)`.
|
|
42
|
+
- **Stacked `connected`/`disconnected` listeners.** Listeners were attached *inside* the `entity.once('state', …)` callback in `esphome.js`. Now attached at platform scope, exactly once per `Client`. Initialization is gated on the `Client` `initialized` event so the entire entity bundle is available, not just whatever happened to arrive first.
|
|
43
|
+
- **Plugin registered as a static platform instead of dynamic.** `api.registerPlatform(name, alias, Class)` was missing the trailing `true` flag. Added.
|
|
44
|
+
- **`package.json` `repository.url` pointed to upstream.** Would break npm sigstore provenance on publish (HTTP 422). Now points to the fork's GitHub URL.
|
|
45
|
+
- **`HeaterCooler.updateState` mutated incoming state** when clamping `targetTemperature`. Replaced with a non-mutating `clampTargetTemperature(value)` helper.
|
|
46
|
+
- **Lint errors.** Two indentation mismatches in the original `lib/HeaterCooler.js` resolved; the file itself was retired in favour of `lib/DeviceAccessory.js`.
|
|
47
|
+
|
|
48
|
+
### Fixed (post-review cleanup)
|
|
49
|
+
|
|
50
|
+
Three independent code-review passes (general bug-hunt, HomeKit/ESPHome semantics, docs/handoff) surfaced the following correctness issues that were addressed before tagging 0.1.0:
|
|
51
|
+
|
|
52
|
+
- **`climateCommandService(that.state)` was sending all state fields including stale `target_temperature_low/high = 0` and `legacy_away = false` on every command.** Critical for HEAT_COOL-mode devices, where this would actively overwrite the device's heat/cool band to `[0, 0]` on each user interaction. `lib/stateManager.js` now builds a clean payload with only the fields actually mutated by the current `.onSet` cycle (tracked via `markDirty`), plus the entity `key`.
|
|
53
|
+
- **`pruneOrphanedAccessories` ran with an empty live-host set when auto-discovery returned zero devices.** A transient mDNS failure (Wi-Fi blip, router reboot) would silently unregister every cached HomeKit accessory — losing room assignments and automations. The plugin now keeps cached accessories when discovery fails (with a clear error log) and only prunes when it has positive evidence the device list is genuinely empty.
|
|
54
|
+
- **`Active` characteristic initialised to ON for a freshly-loaded OFF device** because `state.mode === undefined` made `state.mode !== 0` evaluate to `true`. Replaced with an explicit `isModeActive(mode)` helper.
|
|
55
|
+
- **Empty `validValues` array for HeaterCooler `TargetHeaterCoolerState`** when a device's `supportedModesList` had no HEAT/COOL/AUTO/HEAT_COOL primary modes (e.g. DRY+FAN_ONLY-only). HAP-NodeJS rejects empty validValues. Now falls back to `[AUTO]` so the accessory still serializes.
|
|
56
|
+
- **`client.once('initialized')` skipped re-initialization** if the user added a new ESPHome entity (fresh YAML flash) and the device reconnected. Switched to `client.on('initialized')` with a per-client `initialized` flag.
|
|
57
|
+
- **ESPHome's `missingState` flag was ignored** — a sensor reporting `missingState: true` (no reading available) decoded to `state.state = 0` and the plugin published `0%`/`0°C`/`0W`. New `readSensorValue` helper checks `missingState` and `Number.isFinite` before returning a value.
|
|
58
|
+
- **DRY/FAN_ONLY OFF-toggle defaulted to COOL** even on a fresh device that had never been in a primary mode. Now snapshots `accessory.context.preSupplementaryMode` when entering DRY/FAN_ONLY and falls back to OFF if no prior primary mode was recorded.
|
|
59
|
+
- **Display Toggle Switch fired on both ON and OFF taps.** The HomeKit Switch's `.onSet(value)` handler ignored `value` and called `Button.push()` unconditionally. Now: if `!value`, return early; the toggle is one-way (auto-resets to off after 250 ms).
|
|
60
|
+
- **HumiditySensor add/remove subtype mismatch.** `addService(..., 'humidity')` used a subtype, but `getService(...)` lookup didn't — could match the wrong service if multiple were ever present. Now uses `getServiceById(..., 'humidity')` consistently with the other optional services.
|
|
61
|
+
- **`fakegato-history`'s reaction to NaN sensor data.** Same `readSensorValue` guard prevents NaN from making it into Eve.app's history series.
|
|
62
|
+
- **`getCharacteristic(eve.CurrentPowerConsumption)` already auto-adds.** The `existing || addCharacteristic(...)` ternary in `attachPowerCharacteristic` was dead code (the second branch could never run). Cleaned up.
|
|
63
|
+
- **`SwingMode` and `RotationSpeed` setters** now dedupe identical values (early-resolve when target equals current) — matches the existing pattern used by `Active`/`TargetHeaterCoolerState`/temperature thresholds, avoids spurious roundtrips.
|
|
64
|
+
- **`setConnectedStatus` race during accessory construction.** Wrapped in try/catch + service-presence guard, so a disconnect during the brief window between `'initialized'` and the constructor finishing won't crash the platform.
|
|
65
|
+
- **Unused `TotalConsumption` Eve characteristic** removed from `lib/eve.js` — kWh totalisation isn't implemented and the dead export was misleading.
|
|
66
|
+
|
|
67
|
+
### Changed
|
|
68
|
+
|
|
69
|
+
- **`lib/HeaterCooler.js` retired; replaced by `lib/DeviceAccessory.js`.** The class is now a multi-service composer rather than a climate-only wrapper. Service-binding methods are split: `addClimateService`, `addOptionalSensorServices`, `addOptionalSwitchServices`, `addModeSwitchServices`, `removeDisabledServices`. Cached service cleanup is honored — disabling a flag on a previously-enabled service unregisters the service on next launch.
|
|
70
|
+
- **`lib/esphome.js` rewritten async.** Orchestrates manual `devices[]` + auto-discovered devices (deduped by host); spawns a `Client` per device; waits for the Client's `initialized` event; routes connected/disconnected events into `setConnectedStatus(bool)` on the accessory.
|
|
71
|
+
- **`fanSpeedToFanMode` / `fanModeToSpeed` are inverses.** Previously the conversion only existed for HomeKit-set → ESPHome direction; the reverse was inlined ad-hoc and inconsistent. Both directions live in `lib/state.js` now.
|
|
72
|
+
- **`engines.node` raised to `^18.20.4 || ^20.15.1 || ^22.0.0 || ^24.0.0`.** Old `>=18.0.0` allowed long-EOL Node 18 patch releases.
|
|
73
|
+
- **`engines.homebridge` widened to `^1.8.0 || ^2.0.0`.**
|
|
74
|
+
- **`displayName` added to `package.json`** as "Homebridge SLWF-01Pro / ESPHome AC".
|
|
75
|
+
- **`package.json` `description`** updated from inherited upstream wording to mention SLWF-01Pro and the multi-entity feature set.
|
|
76
|
+
- **`package.json` `funding`** block (PayPal / Patreon / Ko-fi pointing at the original author) removed; donations should not flow to a maintainer who isn't shipping the fork.
|
|
77
|
+
- **`package.json` `files`** array added to scope what `npm publish` ships — prevents `test/`, `CLAUDE.md`, `ROADMAP.md`, `QA_TESTS.md`, and `.claude/` from leaking into the published tarball.
|
|
78
|
+
- **`.gitignore`** replaced with a minimal Node-only ignore set; the inherited Xcode/iOS boilerplate from upstream is gone.
|
|
79
|
+
- **npm package renamed** from inherited `homebridge-esphome-ac` to **`homebridge-slwf-01pro`** to avoid colliding with the upstream package on the npm registry. The Homebridge platform identifier in users' `config.json` (`"platform": "ESPHomeAC"`) is unchanged for migration compatibility — only the install command differs (`sudo npm uninstall -g homebridge-esphome-ac && sudo npm install -g homebridge-slwf-01pro`).
|
|
80
|
+
- **`PLUGIN_NAME` constant in `index.js`** updated to match the new npm name. Existing users of upstream `homebridge-esphome-ac@0.0.4` will see their cached accessories re-pair on first launch (the HomeKit UUIDs are still derived from `entity.config.uniqueId` so they reattach to the same Home app tile).
|
|
81
|
+
- **LICENSE** preserves the original 2020 Nitay Ben Zvi MIT copyright + adds the 2026 Karol Nowacki fork copyright.
|
|
82
|
+
- **README rewritten** with SLWF-01Pro device context (hardware revisions, supported AC brands, ESPHome-specific quirks like intake-mounted sensor inaccuracy and `midea_ac.follow_me`), full configuration reference, troubleshooting, and child-bridge recommendation.
|
|
83
|
+
|
|
84
|
+
### Internal
|
|
85
|
+
|
|
86
|
+
- `Service` and `Characteristic` lookups hoisted to module scope in `DeviceAccessory.js` (set once on first construction).
|
|
87
|
+
- `index.js` `log.easyDebug` now uses `Array#map` + `Array#join` instead of `Array#reduce` string concatenation; mixed string + object arguments stringify cleanly.
|
|
88
|
+
- `SET_DEBOUNCE_MS` / `ACTIVE_BATCH_MS` / `TEMP_BATCH_MS` are named constants instead of magic numbers.
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## [0.0.4] — pre-fork (upstream `nitaybz/homebridge-esphome-ac`)
|
|
93
|
+
|
|
94
|
+
The point at which this fork was taken. Upstream history below is preserved for context.
|
|
95
|
+
|
|
96
|
+
### Fixed (in upstream)
|
|
97
|
+
|
|
98
|
+
- Bug fixes (commit `7ce4654`).
|
|
99
|
+
- `set` commands changed to return promises (commit `5a1930d`) — switched from `.on('set', cb)` to `.onSet(async)`.
|
|
100
|
+
- Removed stray `%` from swing log line (commit `0cf6d7d`).
|
|
101
|
+
- Stable per-entity unique id used for HomeKit UUID instead of host (commit `f4461f0`).
|
|
102
|
+
|
|
103
|
+
### Initial release (upstream)
|
|
104
|
+
|
|
105
|
+
- ESPHome native-API integration via `@2colors/esphome-native-api`.
|
|
106
|
+
- HomeKit `Service.HeaterCooler` exposing Active, Current/TargetHeaterCoolerState, CurrentTemperature, Heating/CoolingThresholdTemperature, SwingMode, RotationSpeed.
|
|
107
|
+
- Auto-discovery of climate-entity capabilities (modes/fan modes/swing modes/visual temp range).
|
|
108
|
+
- `config.schema.json` for the Homebridge UI.
|
|
109
|
+
- One platform-level `debug` flag.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2020 Nitay Ben Zvi (original homebridge-esphome-ac)
|
|
4
|
+
Copyright (c) 2026 Karol Nowacki (homebridge-slwf-01pro fork)
|
|
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
ADDED
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
# homebridge-SLWF-01Pro
|
|
2
|
+
|
|
3
|
+
[Homebridge](https://homebridge.io) plugin for the **[SLWF-01Pro Wi-Fi dongle](https://smartlight.me/smart-home-devices/wifi-devices/wifi-dongle-air-conditioners-midea-idea-electrolux-for-home-assistant)** flashed with ESPHome — exposes the AC it's plugged into as a HomeKit `HeaterCooler` accessory with full mode, fan-speed and swing control.
|
|
4
|
+
|
|
5
|
+
The SLWF-01Pro is a Wi-Fi dongle from **[SMLIGHT](https://smartlight.me)** (Ukraine) that drops into the proprietary serial Wi-Fi port on Midea-protocol air conditioners — replacing the OEM Tuya/SmartLife stick. Hardware revisions in the wild: **v1.1**, **v1.2** (ESP8266) and **v2.1** (ESP32); pinouts differ between revisions. Once flashed with [ESPHome](https://esphome.io) (typically the [`midea_ac`](https://esphome.io/components/climate/midea.html) component) the dongle exposes the AC as a `Climate` entity over the ESPHome native API — this plugin bridges that entity into HomeKit.
|
|
6
|
+
|
|
7
|
+
This is a **maintained fork** of [`homebridge-esphome-ac`](https://github.com/nitaybz/homebridge-esphome-ac) by nitaybz, focused on the SLWF-01Pro use case: bug fixes, cleanup, and longer-term polish around multi-device reliability.
|
|
8
|
+
|
|
9
|
+
## Why this fork exists
|
|
10
|
+
|
|
11
|
+
The upstream plugin works for single-device setups but has a few sharp edges that bite multi-AC households (the typical SLWF-01Pro buyer often has multiple Midea/Electrolux units). The fork addresses correctness *and* expands HomeKit coverage:
|
|
12
|
+
|
|
13
|
+
- **HEAT_COOL devices got no AUTO button.** Many SLWF-01Pro / Midea ACs advertise mode `HEAT_COOL` (1) instead of `AUTO` (6). The original plugin only checked for mode 6 → HomeKit AUTO didn't appear. The fork picks whichever mode the device supports.
|
|
14
|
+
- **Wire-format payload was leaky.** The original sent the *entire* climate-state object with every command, including stale `target_temperature_low/high = 0`. On HEAT_COOL devices this overwrites the heat/cool band on every interaction. The fork builds a clean payload of only the fields you actually changed.
|
|
15
|
+
- **Multi-device command coalescing.** A module-level send timeout meant changing one AC could cancel a pending command on another. Each AC now owns its own debouncer.
|
|
16
|
+
- **Crash on disconnected device.** The upstream `device disconnected` error path referenced an undefined `log` symbol → `ReferenceError` instead of a clean HomeKit error. Fixed.
|
|
17
|
+
- **Auto-discovery via mDNS** — listed `_esphomelib._tcp` services are picked up automatically; you don't need to type six IP addresses for six ACs.
|
|
18
|
+
- **Multi-entity bundling** — humidity, outdoor temperature, power consumption, beeper, display toggle, DRY, and FAN_ONLY all show up in HomeKit when the device exposes them.
|
|
19
|
+
|
|
20
|
+
See [CHANGELOG.md](CHANGELOG.md) for the full restoration story.
|
|
21
|
+
|
|
22
|
+
## Supported devices
|
|
23
|
+
|
|
24
|
+
Anything that publishes a `Climate` entity over the ESPHome native API will work. The intended target is the SLWF-01Pro itself, but the plugin is hardware-agnostic — any ESPHome `climate:` component (e.g. an ESP32 with [`midea_ac`](https://esphome.io/components/climate/midea.html) directly soldered) will be picked up.
|
|
25
|
+
|
|
26
|
+
| AC brand families known to work with SLWF-01Pro | Notes |
|
|
27
|
+
|---|---|
|
|
28
|
+
| **Midea**, Idea, Electrolux, Bosch, Beko, Neoclima | Manufacturer's primary tested set; all Midea-protocol mini-splits |
|
|
29
|
+
| Senville (Leto), Yitahome, Mr. Cool, AUX | Other Midea-platform rebadges |
|
|
30
|
+
| Alpine, Pioneer, Samsung, Toshiba, Zanussi | ~30 brands total — see [smartlight.me](https://smartlight.me/smart-home-devices/wifi-devices/wifi-dongle-air-conditioners-midea-idea-electrolux-for-home-assistant) for the full list |
|
|
31
|
+
| Newer 2024+ AC firmwares with proprietary protocols | May not work — check the manufacturer's compatibility notes before buying |
|
|
32
|
+
|
|
33
|
+
DRY and FAN_ONLY ESPHome modes are surfaced as **companion `Switch` services** ("AC Dry", "AC Fan Only") next to the main `HeaterCooler` tile. Toggling one ON puts the AC into that mode; toggling OFF restores the previous primary mode (HEAT/COOL/AUTO). Hide via `disableDryMode` / `disableFanOnlyMode`.
|
|
34
|
+
|
|
35
|
+
ESPHome's **custom fan modes** (`silent`, `turbo` on Midea) and **presets** (`eco`, `boost`, `sleep`, `away`) are not yet surfaced — the plugin only handles the standard fan-modes list. See [ROADMAP.md](ROADMAP.md).
|
|
36
|
+
|
|
37
|
+
## Install
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
sudo npm install -g homebridge-slwf-01pro
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Or from the Homebridge UI: search for **homebridge-slwf-01pro** in the plugin browser.
|
|
44
|
+
|
|
45
|
+
To install straight from git instead of npm (e.g. to pin a specific commit):
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
sudo npm install -g github:nookied/homebridge-SLWF-01Pro#<sha>
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Configuration
|
|
52
|
+
|
|
53
|
+
The simplest config — auto-discover everything on the local network:
|
|
54
|
+
|
|
55
|
+
```jsonc
|
|
56
|
+
{
|
|
57
|
+
"platforms": [
|
|
58
|
+
{
|
|
59
|
+
"platform": "ESPHomeAC",
|
|
60
|
+
"name": "ESPHomeAC",
|
|
61
|
+
"autoDiscover": true
|
|
62
|
+
}
|
|
63
|
+
]
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Or fully manual (required for encrypted devices and any device not on the same broadcast domain):
|
|
68
|
+
|
|
69
|
+
```jsonc
|
|
70
|
+
{
|
|
71
|
+
"platforms": [
|
|
72
|
+
{
|
|
73
|
+
"platform": "ESPHomeAC",
|
|
74
|
+
"name": "ESPHomeAC",
|
|
75
|
+
"debug": false,
|
|
76
|
+
"devices": [
|
|
77
|
+
{
|
|
78
|
+
"name": "Living Room AC",
|
|
79
|
+
"host": "192.168.1.120",
|
|
80
|
+
"port": 6053,
|
|
81
|
+
"encryptionKey": "",
|
|
82
|
+
"disableHumiditySensor": true
|
|
83
|
+
}
|
|
84
|
+
]
|
|
85
|
+
}
|
|
86
|
+
]
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
You can mix both — listed devices in `devices[]` take precedence; auto-discovered devices are added on top.
|
|
91
|
+
|
|
92
|
+
### Platform-level keys
|
|
93
|
+
|
|
94
|
+
| Key | Required | Default | Notes |
|
|
95
|
+
|---|---|---|---|
|
|
96
|
+
| `platform` | yes | — | Must be exactly `"ESPHomeAC"` (the platform identifier — same as the upstream plugin so existing configs migrate without edits) |
|
|
97
|
+
| `name` | no | `ESPHomeAC` | Display name in Homebridge logs |
|
|
98
|
+
| `debug` | no | `false` | Surface ESPHome state-change chatter to the main log instead of `log.debug` |
|
|
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
|
+
| `discoveryTimeout` | no | `5` | Seconds to wait for mDNS responses before continuing. |
|
|
101
|
+
| `disableHumiditySensor` | no | `false` | Hide the HumiditySensor service for **every** device (e.g. ACs that report a fake `0 %` because no probe is fitted). |
|
|
102
|
+
| `disableOutdoorTempSensor` | no | `false` | Hide the outdoor TemperatureSensor service. |
|
|
103
|
+
| `disablePowerSensor` | no | `false` | Hide the Eve.Energy CurrentPowerConsumption characteristic. |
|
|
104
|
+
| `disableBeeperSwitch` | no | `false` | Hide the Beeper Switch service. |
|
|
105
|
+
| `disableDisplaySwitch` | no | `false` | Hide the Display Toggle Switch service. |
|
|
106
|
+
| `disableDryMode` | no | `false` | Hide the DRY mode Switch service. |
|
|
107
|
+
| `disableFanOnlyMode` | no | `false` | Hide the FAN_ONLY mode Switch service. |
|
|
108
|
+
| `devices` | no | `[]` | Manual list of ESPHome devices. Required for encrypted devices; optional otherwise if `autoDiscover: true`. |
|
|
109
|
+
|
|
110
|
+
### Per-device keys (under `devices[]`)
|
|
111
|
+
|
|
112
|
+
| Key | Required | Default | Notes |
|
|
113
|
+
|---|---|---|---|
|
|
114
|
+
| `name` | yes | — | Display name in HomeKit |
|
|
115
|
+
| `host` | yes | — | IP address or hostname of the SLWF-01Pro / ESPHome device |
|
|
116
|
+
| `port` | no | `6053` | ESPHome native API port |
|
|
117
|
+
| `encryptionKey` | no | `""` | Base64 ESPHome `api: encryption` key, if set in the device's YAML |
|
|
118
|
+
| `disableHumiditySensor` | no | `false` | Per-device override; if true, hides the HumiditySensor for **this** device only. |
|
|
119
|
+
| `disableOutdoorTempSensor` | no | `false` | Per-device override |
|
|
120
|
+
| `disablePowerSensor` | no | `false` | Per-device override |
|
|
121
|
+
| `disableBeeperSwitch` | no | `false` | Per-device override |
|
|
122
|
+
| `disableDisplaySwitch` | no | `false` | Per-device override |
|
|
123
|
+
| `disableDryMode` | no | `false` | Per-device override |
|
|
124
|
+
| `disableFanOnlyMode` | no | `false` | Per-device override |
|
|
125
|
+
|
|
126
|
+
Per-device disable flags **override** the platform-wide flag (logical OR — `device[key] || platform[key]`). The platform-wide flag turns the service off for every device; the per-device flag turns it off for just that one. There's no way to enable a service that's globally disabled.
|
|
127
|
+
|
|
128
|
+
The plugin auto-discovers the climate entity's capabilities (supported modes, fan modes, swing modes, visual min/max temperatures, target step) directly from ESPHome — no model-specific config required.
|
|
129
|
+
|
|
130
|
+
`config.schema.json` provides a form-based editor in the Homebridge UI.
|
|
131
|
+
|
|
132
|
+
## Recommended: enable Child Bridge
|
|
133
|
+
|
|
134
|
+
If you have **two or more** SLWF-01Pro dongles, run this plugin in a Homebridge **Child Bridge**. ESPHome devices on Wi-Fi can blip out for a few seconds during router restarts; isolating the plugin means a hung reconnect can't block your other accessories.
|
|
135
|
+
|
|
136
|
+
In the Homebridge UI: **Plugins** tab → click the gear icon on the plugin → **Bridge Settings** → enable **Child Bridge**. Restart when prompted.
|
|
137
|
+
|
|
138
|
+
## What ends up in HomeKit
|
|
139
|
+
|
|
140
|
+
Per ESPHome device, all of these services land on a single HomeKit accessory if the device exposes the matching entity (and the corresponding `disable*` flag is `false`):
|
|
141
|
+
|
|
142
|
+
| HomeKit service | Source ESPHome entity | Disable flag |
|
|
143
|
+
|---|---|---|
|
|
144
|
+
| `Service.HeaterCooler` (mandatory) | `Climate` entity | — |
|
|
145
|
+
| `Service.HumiditySensor` | Sensor matching `*humidity*` | `disableHumiditySensor` |
|
|
146
|
+
| `Service.TemperatureSensor` (outdoor) | Sensor matching `*outdoor*temp*` | `disableOutdoorTempSensor` |
|
|
147
|
+
| Eve.Energy `CurrentPowerConsumption` (W) on the AC accessory | Sensor matching `*power*` | `disablePowerSensor` |
|
|
148
|
+
| `Service.Switch` "Beeper" | Switch matching `*beeper*` | `disableBeeperSwitch` |
|
|
149
|
+
| `Service.Switch` "Display" | Button matching `*display*` (auto-resets after press) | `disableDisplaySwitch` |
|
|
150
|
+
| `Service.Switch` "Dry" | Climate device's `DRY` mode | `disableDryMode` |
|
|
151
|
+
| `Service.Switch` "Fan Only" | Climate device's `FAN_ONLY` mode | `disableFanOnlyMode` |
|
|
152
|
+
| `StatusActive` + `StatusFault` (on the climate service) | Mirrors ESPHome client connect/disconnect | — (always on) |
|
|
153
|
+
|
|
154
|
+
Entities the plugin deliberately ignores: Wi-Fi RSSI, Uptime, Factory Reset (dangerous to expose).
|
|
155
|
+
|
|
156
|
+
## Behaviour
|
|
157
|
+
|
|
158
|
+
### Modes
|
|
159
|
+
|
|
160
|
+
The HomeKit `HeaterCooler` accessory uses three modes; this plugin maps them as follows:
|
|
161
|
+
|
|
162
|
+
| HomeKit | ESPHome `ClimateMode` | What happens |
|
|
163
|
+
|---|---|---|
|
|
164
|
+
| **Off** (Active=0) | `OFF` (0) | AC turns off; HomeKit remembers the previous mode for the next "On" tap |
|
|
165
|
+
| **Heat** | `HEAT` (3) | AC switches to heating mode |
|
|
166
|
+
| **Cool** | `COOL` (2) | AC switches to cooling mode |
|
|
167
|
+
| **Auto** | `AUTO` (6) | AC switches to auto / heat-cool mode |
|
|
168
|
+
|
|
169
|
+
The mode-list shown to HomeKit is filtered to the modes ESPHome actually advertises (`supportedModesList`), so a cooling-only AC won't show a Heat button.
|
|
170
|
+
|
|
171
|
+
### Temperature
|
|
172
|
+
|
|
173
|
+
HomeKit sends one of two temperature characteristics depending on mode: `CoolingThresholdTemperature` (in Cool / Auto) or `HeatingThresholdTemperature` (in Heat / Auto). Both currently set the same single `target_temperature` ESPHome field — the plugin doesn't yet use the device's two-point `target_temperature_low`/`target_temperature_high` even when supported. See [ROADMAP.md](ROADMAP.md).
|
|
174
|
+
|
|
175
|
+
Slider drags are debounced — the plugin sends one ESPHome command 600 ms after you stop, not one per tick.
|
|
176
|
+
|
|
177
|
+
### Fan speed
|
|
178
|
+
|
|
179
|
+
HomeKit's `RotationSpeed` (0–100%) is split evenly across the device's `supportedFanModesList`. So if your AC supports `[LOW, MEDIUM, HIGH]`, 1–33% maps to LOW, 34–66% to MEDIUM, 67–100% to HIGH. The `AUTO` fan mode (if supported) is selected when you set rotation speed to 0.
|
|
180
|
+
|
|
181
|
+
### Swing
|
|
182
|
+
|
|
183
|
+
If the device advertises any swing mode beyond OFF, a HomeKit Swing toggle is exposed. The plugin chooses the most useful swing direction at startup (BOTH > VERTICAL > HORIZONTAL) and the toggle flips between that direction and OFF.
|
|
184
|
+
|
|
185
|
+
## Migration
|
|
186
|
+
|
|
187
|
+
If you're moving from the upstream `homebridge-esphome-ac`:
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
sudo npm uninstall -g homebridge-esphome-ac
|
|
191
|
+
sudo npm install -g homebridge-slwf-01pro
|
|
192
|
+
sudo systemctl restart homebridge # or: hb-service restart
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
**Your `config.json` does not need changes.** The platform identifier (`"platform": "ESPHomeAC"`) is unchanged for compatibility — only the npm package name differs.
|
|
196
|
+
|
|
197
|
+
If accessories appear duplicated after the migration, clear Homebridge's cached accessories from the UI (Settings → Remove Single Cached Accessory) for the orphaned ones from the old plugin. The new plugin will re-pair them automatically on the next restart with stable UUIDs derived from each device's ESPHome `entity.config.uniqueId`.
|
|
198
|
+
|
|
199
|
+
## Known SLWF-01Pro quirks
|
|
200
|
+
|
|
201
|
+
These are device-side issues, not plugin bugs — listed here so you know what to expect:
|
|
202
|
+
|
|
203
|
+
- **Intake-mounted temperature sensor reads warm/cold air, not room temp.** HomeKit will show a value that's a few degrees off the actual room. Mitigation: ESPHome's [`midea_ac.follow_me`](https://esphome.io/components/climate/midea.html) action pushes an external Home Assistant sensor reading into the AC, but it's a Home-Assistant-only feature and (on some Senville/Midea units) requires a small hardware mod soldering IO13 to the display board's "Rec 1 OUT" pin.
|
|
204
|
+
- **Pinout differs between v1.1, v1.2 and v2.1** of the dongle. Wrong YAML for your hardware revision means no UART communication. Check the SMLIGHT product page for the matching firmware before flashing.
|
|
205
|
+
- **Outdoor temperature and humidity setpoint** are model-specific (e.g. Midea Mission II doesn't expose them); expect them to be missing on most installs.
|
|
206
|
+
- **Newer Midea firmwares** with proprietary key exchange may refuse to talk to the dongle. SMLIGHT's compatibility list is the source of truth.
|
|
207
|
+
|
|
208
|
+
## Troubleshooting
|
|
209
|
+
|
|
210
|
+
### Plugin starts but the AC tile in HomeKit is "Not Responding"
|
|
211
|
+
Check that the SLWF-01Pro is reachable from the Homebridge host (`ping <host>` and `nc -vz <host> 6053`). The plugin connects on `didFinishLaunching` and reconnects every 5 s if the device drops; if you see no `<name> client connected` line followed by `Initialized "<name>" with N mapped entit(y|ies)` in the log within a minute, ESPHome isn't accepting the connection. Common causes: wrong `encryptionKey`, firewall, ESPHome `api:` block missing.
|
|
212
|
+
|
|
213
|
+
### "ESPHome device" appears but no temperature shown
|
|
214
|
+
ESPHome may not have published the initial `state` event yet. Wait 30 s; if still empty, restart the SLWF-01Pro.
|
|
215
|
+
|
|
216
|
+
### Multi-AC: changing one AC's setting cancels another's
|
|
217
|
+
This was a real bug in upstream `homebridge-esphome-ac@0.0.4` (module-level send timeout, shared across all devices). Fixed in this fork's first release.
|
|
218
|
+
|
|
219
|
+
### My AC has no humidity probe but HomeKit shows 0 %
|
|
220
|
+
Set `disableHumiditySensor: true` (either platform-wide or just under that device's `devices[]` entry). The HumiditySensor service will be removed on the next restart.
|
|
221
|
+
|
|
222
|
+
### Auto-discovery doesn't see one of my ACs
|
|
223
|
+
Likely causes: (1) the device has `api: encryption: key:` set in its ESPHome YAML, in which case mDNS doesn't broadcast the Noise key — add it manually to `devices[]`. (2) The device is on a different VLAN/subnet that blocks mDNS. (3) ESPHome's `mdns:` block is disabled. Quickest fix: list it manually in `devices[]`.
|
|
224
|
+
|
|
225
|
+
### HomeKit AUTO button missing on a device that supports auto mode
|
|
226
|
+
Your device probably advertises `HEAT_COOL` (mode 1) instead of `AUTO` (mode 6). Both are now handled equivalently as of this fork's first release; if you're on upstream `homebridge-esphome-ac@0.0.4`, this was the bug.
|
|
227
|
+
|
|
228
|
+
### Debug logs
|
|
229
|
+
Set `"debug": true` in the platform config — every state change and outgoing command will surface in the main log.
|
|
230
|
+
|
|
231
|
+
## Development
|
|
232
|
+
|
|
233
|
+
```bash
|
|
234
|
+
git clone https://github.com/nookied/homebridge-SLWF-01Pro.git
|
|
235
|
+
cd homebridge-SLWF-01Pro
|
|
236
|
+
npm install
|
|
237
|
+
npm run lint # ESLint
|
|
238
|
+
npm test # Jest — 78 unit tests
|
|
239
|
+
node -e "require('./index.js')" # smoke test (loads cleanly)
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
See [QA_TESTS.md](QA_TESTS.md) for the manual pre-release checklist and [ROADMAP.md](ROADMAP.md) for what's planned next.
|
|
243
|
+
|
|
244
|
+
## Releasing
|
|
245
|
+
|
|
246
|
+
After the pre-release checklist in [QA_TESTS.md](QA_TESTS.md) passes:
|
|
247
|
+
|
|
248
|
+
```bash
|
|
249
|
+
npm version 0.1.0 # bumps package.json + creates v0.1.0 tag
|
|
250
|
+
git push --follow-tags # pushes commit + tag
|
|
251
|
+
npm pack --dry-run # sanity-check tarball contents
|
|
252
|
+
gh release create v0.1.0 --notes-from-tag # GitHub Release from tag message
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
`package.json` has a `files` array, so `npm publish` ships only `index.js`, `lib/`, `config.schema.json`, `config-sample.json`, `LICENSE`, `README.md`, `CHANGELOG.md`. Internal docs (`CLAUDE.md`, `ROADMAP.md`, `QA_TESTS.md`, `test/`) stay out of the published tarball.
|
|
256
|
+
|
|
257
|
+
## License
|
|
258
|
+
|
|
259
|
+
[MIT](LICENSE). Copyright 2020 Nitay Ben Zvi (original) + 2026 Karol Nowacki (this fork). The MIT license is preserved from the original.
|
|
260
|
+
|
|
261
|
+
## Credits
|
|
262
|
+
|
|
263
|
+
- **[nitaybz](https://github.com/nitaybz)** — original `homebridge-esphome-ac` plugin (2020), the basis for this fork.
|
|
264
|
+
- **[smartlight.me](https://smartlight.me)** — designs and ships the SLWF-01Pro hardware + ESPHome firmware.
|
|
265
|
+
- **[ESPHome](https://esphome.io)** — the firmware and native-API protocol the plugin speaks.
|
|
266
|
+
- **[@2colors/esphome-native-api](https://github.com/2colors/esphome-native-api)** — Node.js client for the ESPHome native API.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"bridge": {
|
|
3
|
+
"name": "Homebridge",
|
|
4
|
+
"username": "CD:22:3D:E3:CE:30",
|
|
5
|
+
"port": 51826,
|
|
6
|
+
"pin": "031-45-154"
|
|
7
|
+
},
|
|
8
|
+
|
|
9
|
+
"description": "Sample config for the homebridge-SLWF-01Pro fork. Pick auto-discovery OR manual devices, or both.",
|
|
10
|
+
"platforms": [
|
|
11
|
+
{
|
|
12
|
+
"platform": "ESPHomeAC",
|
|
13
|
+
"name": "ESPHomeAC",
|
|
14
|
+
"debug": false,
|
|
15
|
+
"autoDiscover": true,
|
|
16
|
+
"discoveryTimeout": 5,
|
|
17
|
+
"disableHumiditySensor": false,
|
|
18
|
+
"devices": [
|
|
19
|
+
{
|
|
20
|
+
"name": "Living Room AC",
|
|
21
|
+
"host": "192.168.1.120",
|
|
22
|
+
"port": 6053,
|
|
23
|
+
"encryptionKey": "",
|
|
24
|
+
"disableHumiditySensor": true
|
|
25
|
+
}
|
|
26
|
+
]
|
|
27
|
+
}
|
|
28
|
+
],
|
|
29
|
+
|
|
30
|
+
"accessories": []
|
|
31
|
+
}
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
{
|
|
2
|
+
"pluginAlias": "ESPHomeAC",
|
|
3
|
+
"pluginType": "platform",
|
|
4
|
+
"singular": true,
|
|
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.",
|
|
6
|
+
"footerDisplay": "Original by @nitaybz; SLWF-01Pro fork by @nookied.",
|
|
7
|
+
"schema": {
|
|
8
|
+
"type": "object",
|
|
9
|
+
"properties": {
|
|
10
|
+
"name": {
|
|
11
|
+
"title": "Plugin Name (for logs)",
|
|
12
|
+
"type": "string",
|
|
13
|
+
"default": "ESPHomeAC",
|
|
14
|
+
"required": false
|
|
15
|
+
},
|
|
16
|
+
"debug": {
|
|
17
|
+
"title": "Enable Debug Logs",
|
|
18
|
+
"description": "Surface ESPHome state-change chatter to the main log (otherwise sent to log.debug).",
|
|
19
|
+
"type": "boolean",
|
|
20
|
+
"default": false,
|
|
21
|
+
"required": false
|
|
22
|
+
},
|
|
23
|
+
"autoDiscover": {
|
|
24
|
+
"title": "Auto-discover ESPHome devices via mDNS",
|
|
25
|
+
"description": "Browses _esphomelib._tcp on the local network and adds any ESPHome devices with a Climate entity. Only works for unencrypted ESPHome API. Manually configured devices in the list below take precedence and are required for encrypted devices.",
|
|
26
|
+
"type": "boolean",
|
|
27
|
+
"default": false,
|
|
28
|
+
"required": false
|
|
29
|
+
},
|
|
30
|
+
"discoveryTimeout": {
|
|
31
|
+
"title": "Discovery timeout (seconds)",
|
|
32
|
+
"type": "integer",
|
|
33
|
+
"default": 5,
|
|
34
|
+
"minimum": 2,
|
|
35
|
+
"maximum": 30,
|
|
36
|
+
"required": false,
|
|
37
|
+
"condition": { "functionBody": "return model.autoDiscover === true;" }
|
|
38
|
+
},
|
|
39
|
+
"disableHumiditySensor": {
|
|
40
|
+
"title": "Hide Humidity sensor service (for ACs without a real humidity probe)",
|
|
41
|
+
"type": "boolean",
|
|
42
|
+
"default": false,
|
|
43
|
+
"required": false
|
|
44
|
+
},
|
|
45
|
+
"disableOutdoorTempSensor": {
|
|
46
|
+
"title": "Hide Outdoor Temperature sensor service",
|
|
47
|
+
"type": "boolean",
|
|
48
|
+
"default": false,
|
|
49
|
+
"required": false
|
|
50
|
+
},
|
|
51
|
+
"disablePowerSensor": {
|
|
52
|
+
"title": "Hide Power Usage characteristic (Eve.Energy)",
|
|
53
|
+
"type": "boolean",
|
|
54
|
+
"default": false,
|
|
55
|
+
"required": false
|
|
56
|
+
},
|
|
57
|
+
"disableBeeperSwitch": {
|
|
58
|
+
"title": "Hide Beeper switch",
|
|
59
|
+
"type": "boolean",
|
|
60
|
+
"default": false,
|
|
61
|
+
"required": false
|
|
62
|
+
},
|
|
63
|
+
"disableDisplaySwitch": {
|
|
64
|
+
"title": "Hide Display Toggle switch",
|
|
65
|
+
"type": "boolean",
|
|
66
|
+
"default": false,
|
|
67
|
+
"required": false
|
|
68
|
+
},
|
|
69
|
+
"disableDryMode": {
|
|
70
|
+
"title": "Hide DRY mode switch",
|
|
71
|
+
"type": "boolean",
|
|
72
|
+
"default": false,
|
|
73
|
+
"required": false
|
|
74
|
+
},
|
|
75
|
+
"disableFanOnlyMode": {
|
|
76
|
+
"title": "Hide FAN_ONLY mode switch",
|
|
77
|
+
"type": "boolean",
|
|
78
|
+
"default": false,
|
|
79
|
+
"required": false
|
|
80
|
+
},
|
|
81
|
+
"devices": {
|
|
82
|
+
"type": "array",
|
|
83
|
+
"required": false,
|
|
84
|
+
"items": {
|
|
85
|
+
"title": "Devices",
|
|
86
|
+
"type": "object",
|
|
87
|
+
"properties": {
|
|
88
|
+
"name": {
|
|
89
|
+
"title": "Display name in HomeKit",
|
|
90
|
+
"type": "string",
|
|
91
|
+
"required": true
|
|
92
|
+
},
|
|
93
|
+
"host": {
|
|
94
|
+
"title": "Hostname or IP address",
|
|
95
|
+
"type": "string",
|
|
96
|
+
"required": true
|
|
97
|
+
},
|
|
98
|
+
"port": {
|
|
99
|
+
"title": "ESPHome native API port",
|
|
100
|
+
"type": "integer",
|
|
101
|
+
"default": 6053,
|
|
102
|
+
"minimum": 1,
|
|
103
|
+
"maximum": 65535,
|
|
104
|
+
"required": false
|
|
105
|
+
},
|
|
106
|
+
"encryptionKey": {
|
|
107
|
+
"title": "ESPHome API Noise encryption key (base64)",
|
|
108
|
+
"type": "string",
|
|
109
|
+
"required": false
|
|
110
|
+
},
|
|
111
|
+
"disableHumiditySensor": {
|
|
112
|
+
"title": "Hide Humidity sensor for this device",
|
|
113
|
+
"type": "boolean",
|
|
114
|
+
"default": false,
|
|
115
|
+
"required": false
|
|
116
|
+
},
|
|
117
|
+
"disableOutdoorTempSensor": {
|
|
118
|
+
"title": "Hide Outdoor Temperature for this device",
|
|
119
|
+
"type": "boolean",
|
|
120
|
+
"default": false,
|
|
121
|
+
"required": false
|
|
122
|
+
},
|
|
123
|
+
"disablePowerSensor": {
|
|
124
|
+
"title": "Hide Power Usage for this device",
|
|
125
|
+
"type": "boolean",
|
|
126
|
+
"default": false,
|
|
127
|
+
"required": false
|
|
128
|
+
},
|
|
129
|
+
"disableBeeperSwitch": {
|
|
130
|
+
"title": "Hide Beeper switch for this device",
|
|
131
|
+
"type": "boolean",
|
|
132
|
+
"default": false,
|
|
133
|
+
"required": false
|
|
134
|
+
},
|
|
135
|
+
"disableDisplaySwitch": {
|
|
136
|
+
"title": "Hide Display Toggle for this device",
|
|
137
|
+
"type": "boolean",
|
|
138
|
+
"default": false,
|
|
139
|
+
"required": false
|
|
140
|
+
},
|
|
141
|
+
"disableDryMode": {
|
|
142
|
+
"title": "Hide DRY mode switch for this device",
|
|
143
|
+
"type": "boolean",
|
|
144
|
+
"default": false,
|
|
145
|
+
"required": false
|
|
146
|
+
},
|
|
147
|
+
"disableFanOnlyMode": {
|
|
148
|
+
"title": "Hide FAN_ONLY mode switch for this device",
|
|
149
|
+
"type": "boolean",
|
|
150
|
+
"default": false,
|
|
151
|
+
"required": false
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
},
|
|
158
|
+
"layout": [
|
|
159
|
+
{ "key": "name" },
|
|
160
|
+
{ "key": "debug" },
|
|
161
|
+
{
|
|
162
|
+
"type": "fieldset",
|
|
163
|
+
"title": "Auto-discovery",
|
|
164
|
+
"expandable": true,
|
|
165
|
+
"expanded": true,
|
|
166
|
+
"items": ["autoDiscover", "discoveryTimeout"]
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
"type": "fieldset",
|
|
170
|
+
"title": "Global service toggles (apply to all devices)",
|
|
171
|
+
"expandable": true,
|
|
172
|
+
"expanded": false,
|
|
173
|
+
"items": [
|
|
174
|
+
"disableHumiditySensor",
|
|
175
|
+
"disableOutdoorTempSensor",
|
|
176
|
+
"disablePowerSensor",
|
|
177
|
+
"disableBeeperSwitch",
|
|
178
|
+
"disableDisplaySwitch",
|
|
179
|
+
"disableDryMode",
|
|
180
|
+
"disableFanOnlyMode"
|
|
181
|
+
]
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
"key": "devices",
|
|
185
|
+
"type": "array",
|
|
186
|
+
"title": "Manual device list",
|
|
187
|
+
"description": "Optional. Required for encrypted ESPHome devices. Per-device toggles override the globals.",
|
|
188
|
+
"orderable": false,
|
|
189
|
+
"buttonText": "Add Device",
|
|
190
|
+
"expandable": true,
|
|
191
|
+
"expanded": false,
|
|
192
|
+
"items": [
|
|
193
|
+
"devices[].name",
|
|
194
|
+
"devices[].host",
|
|
195
|
+
"devices[].port",
|
|
196
|
+
"devices[].encryptionKey",
|
|
197
|
+
{
|
|
198
|
+
"type": "fieldset",
|
|
199
|
+
"title": "Per-device service toggles",
|
|
200
|
+
"expandable": true,
|
|
201
|
+
"expanded": false,
|
|
202
|
+
"items": [
|
|
203
|
+
"devices[].disableHumiditySensor",
|
|
204
|
+
"devices[].disableOutdoorTempSensor",
|
|
205
|
+
"devices[].disablePowerSensor",
|
|
206
|
+
"devices[].disableBeeperSwitch",
|
|
207
|
+
"devices[].disableDisplaySwitch",
|
|
208
|
+
"devices[].disableDryMode",
|
|
209
|
+
"devices[].disableFanOnlyMode"
|
|
210
|
+
]
|
|
211
|
+
}
|
|
212
|
+
]
|
|
213
|
+
}
|
|
214
|
+
]
|
|
215
|
+
}
|