UNPKG

homebridge-daikin-local

Version:

daikin plugin for homebridge: https://github.com/homebridge/homebridge

976 lines (777 loc) 32.4 kB
# ESP32-Faikout Support - Technical Documentation ## Overview This document describes the implementation of ESP32-Faikout controller support in homebridge-daikin-local. ESP32-Faikout controllers use the Daikin S21 protocol, which differs significantly from traditional Daikin WiFi modules and requires WebSocket communication for control commands. **Key Changes**: - Dual API architecture supporting both Faikout (S21) and traditional Daikin protocols - WebSocket client for Faikout control commands - Three special mode switches: Econo, Powerful, Night Quiet - Enhanced swing mode support with separate horizontal/vertical control - Always-accessible fan speed control - 100% backward compatibility with existing Daikin controllers > **Testing Environment**: Validated with Homebridge on HomeKit only. Other platforms not tested. --- ## Protocol Differences ### Traditional Daikin ``` GET /aircon/set_control_info?pow=1&mode=3&stemp=24&f_rate=A ``` HTTP GET requests with query string parameters. ### Faikout S21 ``` WebSocket: ws://[IP]/status Message: {"power": true, "mode": "C", "temp": 24, "fan": "A"} ``` WebSocket connection with JSON message payloads. **Why WebSocket**: - Faikout does not support REST API `/control` endpoint (returns 405 Method Not Allowed) - Native Faikout web UI uses WebSocket for all control commands - Provides bidirectional real-time communication for instant status updates - Single persistent connection eliminates polling overhead --- ## Implementation Details ### 1. Dual-Path Architecture All setter/getter methods check `this.isFaikout` flag and route to appropriate handler: ```javascript if (this.isFaikout) { this.sendFaikoutWebSocketCommand({econo: true}, callback); } else { this.sendGetRequest('/aircon/set_control_info?en_economode=1', callback); } ``` ### 2. WebSocket Implementation **Connection Management**: ```javascript connectFaikoutWebSocket() { this.FaikoutWs = new WebSocket(`ws://${this.apiIP}/status`); this.FaikoutWs.on('message', (data) => { const status = JSON.parse(data); this.updateHomeKitCharacteristics(status); }); this.FaikoutWs.on('close', () => { setTimeout(() => this.connectFaikoutWebSocket(), 5000); // Auto-reconnect }); } ``` **Features**: - Persistent connection with 5-second auto-reconnect - Command queueing during connection establishment - Real-time status update processing - Enhanced logging with directional indicators (`>>>>` / `<<<<`) ### 3. Special Modes Three separate HomeKit Switch accessories: | Mode | Faikout Command | Traditional Command | Function | |------|---------------|---------------------|----------| | Econo | `{econo: true}` | `en_economode=1` | Energy-saving mode | | Powerful | `{powerful: true}` | `en_powerful=1` | Maximum performance | | Night Quiet | `{fan: "Q"}` | `f_rate=B` | Silent operation | **Mutual Exclusivity**: Enabling one mode automatically disables the other two. Implemented in each setter to prevent conflicting states. ```javascript setEconoMode: function(value, callback) { if (value) { if (this.Powerful_Mode) { this.Powerful_Mode = false; this.powerfulModeService.updateCharacteristic(Characteristic.On, false); } if (this.NightQuiet_Mode) { this.NightQuiet_Mode = false; this.nightQuietModeService.updateCharacteristic(Characteristic.On, false); } } this.sendFaikoutWebSocketCommand({ econo: value, powerful: false, fan: value ? 'A' : undefined }, callback); } ``` ### 4. Swing Mode **Protocol Mapping**: - **Traditional**: Single `f_dir` parameter (0=off, 1=vertical, 2=horizontal, 3=both) - **Faikout**: Separate `swingh` and `swingv` boolean flags **Implementation**: Faikout always uses 3D swing (both flags set to same value). ```javascript // Faikout {swingh: true, swingv: true} // Traditional f_dir=3 // User-configurable via swingMode setting ``` ### 5. Fan Speed Control Added `RotationSpeed` characteristic to HeaterCooler service for always-accessible fan control: ``` HomeKit → AC Settings → Fan Speed slider ``` Separate Fan accessory still available via `enableFanAccessory` config option. ### 6. ConfiguredName Support Added `ConfiguredName` characteristic to all switch services: - Allows manual renaming in HomeKit app - Names persist across restarts - Initial names from config options (`econoModeName`, etc.) ### 7. Configuration UI Reorganized into 5 sections with conditional visibility: 1. Basic Settings 2. Temperature & Mode Settings 3. Fan Configuration 4. Additional Sensors 5. Special Modes `swingMode` dropdown hidden when `system = "Faikout"` since swing direction is fixed to 3D --- ## Configuration ### Basic Setup ```json { "accessory": "Daikin-Local", "name": "Living Room AC", "apiroute": "http://192.168.1.50", "system": "Faikout", "enableEconoMode": true, "enablePowerfulMode": true, "enableNightQuietMode": true } ``` ### Full Configuration ```json { "accessory": "Daikin-Local", "name": "Bedroom AC", "apiroute": "http://192.168.1.100", "system": "Faikout", "temperature_unit": 0, "enableEconoMode": true, "econoModeName": "Eco Mode", "enablePowerfulMode": true, "powerfulModeName": "Turbo Mode", "enableNightQuietMode": true, "nightQuietModeName": "Silent Mode", "enableFanAccessory": false } ``` ### Configuration Options | Option | Type | Default | Description | |--------|------|---------|-------------| | `system` | String | "Default" | "Default", "Skyfi", or "Faikout" | | `enableEconoMode` | Boolean | false | Enable Econo Mode switch | | `econoModeName` | String | "Econo Mode" | Custom switch name | | `enablePowerfulMode` | Boolean | false | Enable Powerful Mode switch | | `powerfulModeName` | String | "Powerful Mode" | Custom switch name | | `enableNightQuietMode` | Boolean | false | Enable Night Quiet Mode switch | | `nightQuietModeName` | String | "Night Quiet" | Custom switch name | | `swingMode` | String | "3" | For traditional controllers only (ignored for Faikout) | --- ## API Reference ### Faikout S21 Attributes | Attribute | Status | HomeKit Mapping | Notes | |-----------|--------|----------------|-------| | `power` | ✅ | Active | Existing implementation | | `mode` | ✅ | TargetHeaterCoolerState | Existing implementation | | `temp` | ✅ | CoolingThresholdTemperature / HeatingThresholdTemperature | Existing implementation | | `fan` | ✅ | RotationSpeed + Night Quiet switch | Enhanced with quiet mode | | `swingh` | ✅ | SwingMode (combined) | 3D swing only | | `swingv` | ✅ | SwingMode (combined) | 3D swing only | | `econo` | ✅ | Econo Mode switch | New implementation | | `powerful` | ✅ | Powerful Mode switch | New implementation | | `target` | ❌ | Not implemented | Future enhancement | | `env` | ❌ | Not implemented | Future enhancement | | `streamer` | ❌ | Not implemented | Future enhancement | **Coverage**: 8/11 attributes (73%) ### Command Format Comparison | Function | Faikout S21 | Traditional Daikin | |----------|-----------|-------------------| | Power ON | `{"power": true}` | `pow=1` | | Cool Mode | `{"mode": "C"}` | `mode=3` | | Set Temp 24°C | `{"temp": 24}` | `stemp=24` | | Fan Quiet | `{"fan": "Q"}` | `f_rate=B` | | 3D Swing | `{"swingh": true, "swingv": true}` | `f_dir=3` | | Econo Mode | `{"econo": true}` | `en_economode=1` | | Powerful Mode | `{"powerful": true}` | `en_powerful=1` | --- ## Known Issues ### AC Model Compatibility Some Daikin AC units reject Econo/Powerful mode commands via S21 protocol. **Symptom**: Switches turn ON briefly, then OFF after a few seconds. **Cause**: AC firmware does not support these modes. This occurs in both HomeKit and native Faikout web UI. **Verification**: 1. Open Faikout web UI (http://[IP]) 2. Toggle Econo or Powerful button 3. If button unchecks itself → AC model incompatibility **Workaround**: Disable non-functional switches in config: ```json { "enableEconoMode": false, "enablePowerfulMode": false } ``` **Note**: Night Quiet mode typically works on all models (standard fan control). ### HomeKit UI **SwingMode not visible in Apple Home app**: - HomeKit characteristic supported, but Apple Home app may not display it - Use third-party apps: Eve, Controller for HomeKit, Home+ - Swing control works via automations **Switch naming**: - Initial names: "Switch 1", "Switch 2", "Switch 3" - Solution: Toggle switches → Check logs → Rename in Home app - Names persist via `ConfiguredName` characteristic --- ## Migration ### Traditional Daikin → Faikout 1. Install ESP32-Faikout controller: https://github.com/revk/ESP32-Faikout 2. Update config: ```json { "apiroute": "http://[Faikout_IP]", "system": "Faikout" } ``` 3. Optional: Enable special modes 4. Restart Homebridge 5. Verify WebSocket connection in logs: ``` [Daikin] Connecting to Faikout WebSocket at ws://192.168.1.50/status [Daikin] Faikout WebSocket connected successfully ``` ### Faikout → Traditional Daikin Change `"system": "Faikout"` to `"system": "Default"` Special mode switches will not function (not supported by traditional controllers). --- ## Troubleshooting ### WebSocket Connection Failed **Checks**: 1. Verify Faikout accessible: `curl http://[IP]/status` 2. Check firewall rules 3. Enable debug logging 4. Review error details in logs **Note**: Auto-reconnect every 5 seconds. Temporary network issues resolve automatically. ### Switches Turn OFF Immediately **Diagnosis**: Check logs for: ``` >>>> Sending to Faikout: {"econo":true} <<<< Received status from Faikout: {"econo":false} ``` If `econo` returns `false` → AC model incompatibility. Test in Faikout web UI to confirm. ### Basic Controls Not Working **Checks**: 1. Verify `apiroute` is correct 2. Test WebSocket: `wscat -c ws://[IP]/status` 3. Update Faikout firmware if outdated --- ## Development ### Code Statistics - **Lines Changed**: ~600 - **New Functions**: 15 (6 getters, 6 setters, 3 WebSocket methods) - **New Dependencies**: `ws@8.18.0` - **New Config Options**: 7 - **New HomeKit Accessories**: 3 switches - **New HomeKit Characteristics**: 2 (RotationSpeed, ConfiguredName) - **Breaking Changes**: 0 ### State Variables ```javascript this.isFaikout = (this.system === 'Faikout'); this.Econo_Mode = false; this.Powerful_Mode = false; this.NightQuiet_Mode = false; this.FaikoutWs = null; this.FaikoutWsConnecting = false; this.FaikoutWsCommandQueue = []; ``` ### Helper Methods **WebSocket**: - `connectFaikoutWebSocket()`: Establish persistent connection - `sendFaikoutWebSocketCommand()`: Send commands, queue if connecting - `closeFaikoutWebSocket()`: Cleanup on shutdown **Dual-Path**: - `getEconoMode()` / `setEconoMode()` - `getPowerfulMode()` / `setPowerfulMode()` - `getNightQuietMode()` / `setNightQuietMode()` - `getSwingMode()` / `setSwingMode()` ### Git Commits 1. **2115263**: Fan speed slider on HeaterCooler 2. **9976a00**: Three-way mutual exclusivity 3. **e92a95a**: Fix Night Quiet WebSocket status 4. **41f7cac**: Enhanced WebSocket logging 5. **3cac189**: WebSocket implementation 6. **e51b2a9**: Fix Faikout fallback API parameters 7. **d641391**: Fallback mechanism 8. **30eaf9f**: ESP32-Faikout GitHub link in UI 9. **0a10d58**: SwingMode on Fan service 10. **f1c661f**: ConfiguredName characteristic 11. **45dd261**: UI reorganization 12. **4f4b18a**: Initial Econo/Powerful modes --- ## Future Enhancements ### Potential Additions - Streamer mode (air purification) - External temperature sensor support - Environment settings - Separate swing switch accessory - Enhanced fan control (granular speeds) - Energy monitoring ### Code Improvements - Consolidate dual-path logic - Unit tests for Faikout code paths - JSDoc documentation - TypeScript migration --- ## Credits - **ESP32-Faikout**: RevK - https://github.com/revk/ESP32-Faikout - **Original Plugin**: cbrandlehner/homebridge-daikin-local - **Implementation**: October 2025 --- *Last Updated: October 28, 2025* ### Basic Configuration Example ```json { "accessory": "Daikin-Local", "name": "Living Room AC", "apiroute": "http://192.168.1.50", "system": "Faikout", "temperature_unit": 0, "enableEconoMode": true, "econoModeName": "Eco Mode", "enablePowerfulMode": true, "powerfulModeName": "Turbo Mode", "enableNightQuietMode": true, "nightQuietModeName": "Silent Mode" } ``` ### Using with Homebridge Config UI X In the configuration interface, you'll find: 1. **Controller Type** dropdown - Select "Faikout" for ESP32-Faikout controllers 2. **Special Modes** section with checkboxes: - **Econo Mode switch enabled** - Adds energy-saving mode toggle - **Powerful Mode switch enabled** - Adds maximum output mode toggle - **Night Quiet switch enabled** - Adds silent operation mode toggle 3. **Custom name fields** appear when modes are enabled - personalize switch names ### Important Notes - **Mutual Exclusivity**: Econo and Powerful modes cannot be active simultaneously - enabling one automatically disables the other - **Faikout Swing**: When using Faikout controllers, swing mode automatically uses 3D swing (both horizontal and vertical) - **Switch Naming**: Switches may initially show as "Switch 1/2/3" in HomeKit - toggle them to identify via logs, then rename in the Home app --- ## Major Features Added > **Note**: This document consolidates all Faikout-related enhancements including Econo Mode and Powerful Mode features. ### 1. **ESP32-Faikout Controller Support** - **Date**: October 2025 - **Description**: Added full support for ESP32-Faikout open-source controllers - **Changes**: - Dual API architecture supporting both traditional Daikin and Faikout controllers - New configuration option: `"system": "Faikout"` (alongside existing "Default" and "Skyfi") - Automatic API selection based on controller type (`this.isFaikout` flag) - JSON POST endpoint support for Faikout `/control` API - Traditional query string support maintained for legacy controllers **Technical Implementation**: ```javascript // Faikout uses JSON POST requests this.sendFaikoutControl(controlData, callback); // Traditional uses query string GET requests this.sendGetRequest(this.set_control_info + '?' + query, callback); ``` --- ### 2. **Econo Mode Support** - **Feature**: Energy-saving economy mode toggle - **Implementation**: - **Faikout**: Uses `econo` boolean in JSON payload - **Traditional Daikin**: Uses `en_economode` parameter (0/1) - **HomeKit Integration**: Exposed as a separate Switch accessory - **Config Options**: - `enableEconoMode`: Enable/disable the feature (boolean) - `econoModeName`: Custom name for the switch (default: "Econo Mode") - **Mutual Exclusivity**: Automatically disables Powerful mode when enabled **API Examples**: ```javascript // Faikout POST /control {"econo": true, "powerful": false} // Traditional GET /aircon/set_control_info?...&en_economode=1&en_powerful=0 ``` --- ### 3. **Powerful Mode Support** - **Feature**: Maximum performance/turbo mode toggle - **Implementation**: - **Faikout**: Uses `powerful` boolean in JSON payload - **Traditional Daikin**: Uses `en_powerful` parameter (0/1) - **HomeKit Integration**: Exposed as a separate Switch accessory - **Config Options**: - `enablePowerfulMode`: Enable/disable the feature (boolean) - `powerfulModeName`: Custom name for the switch (default: "Powerful Mode") - **Mutual Exclusivity**: Automatically disables Econo mode when enabled --- ### 4. **Night Quiet Mode Support** - **Feature**: Silent operation mode for nighttime use - **Implementation**: - **Faikout**: Sets fan speed to `"Q"` (quiet mode) - **Traditional Daikin**: Sets fan rate to `"B"` (silent mode) - When disabled, reverts to `"A"` (auto fan speed) - **HomeKit Integration**: Exposed as a separate Switch accessory - **Config Options**: - `enableNightQuietMode`: Enable/disable the feature (boolean) - `nightQuietModeName`: Custom name for the switch (default: "Night Quiet") --- ### 5. **Enhanced Swing Mode Support** - **Feature**: Air direction swing control with dual-API support - **Implementation**: - **Faikout**: Uses separate `swingh` and `swingv` booleans for horizontal/vertical swing - When enabled, both are set to `true` (3D swing) - When disabled, both are set to `false` - **Traditional Daikin**: Uses `f_dir` parameter - 0 = No swing - 1 = Vertical swing - 2 = Horizontal swing - 3 = 3D swing (configured via `swingMode` setting) - **HomeKit Integration**: Registered on HeaterCooler service characteristic **Code Example**: ```javascript // Faikout - always 3D swing when enabled const controlData = { swingh: enableSwing, swingv: enableSwing }; // Traditional - user-configurable direction const query = `f_dir=${this.swingMode}`; // 1, 2, or 3 ``` --- ### 6. **WebSocket Support for Faikout S21 Protocol**: Real-time bidirectional communication with ESP32-Faikout controllers - **Problem Solved**: Faikout controllers don't support the `/control` JSON POST endpoint; they use WebSocket for control commands - **Implementation**: - Added `ws` npm package (v8.18.0) for WebSocket client - Persistent WebSocket connection to `ws://[IP]/status` endpoint - Auto-reconnect on disconnection (5-second delay) - Command queueing when WebSocket is connecting - Real-time status updates from Faikout controller - **Fallback Strategy**: 1. Try JSON POST to `/control` endpoint 2. On "Method Not Allowed" error → Use WebSocket 3. Send control commands via WebSocket just like the native Faikout web UI - **Benefits**: - ✅ Econo, Powerful, and Night Quiet modes now work correctly - ✅ Instant status updates when modes change - ✅ Matches native Faikout web UI behavior exactly - ✅ Bidirectional communication for better state synchronization **WebSocket Message Format**: ```javascript // Sending (matches Faikout web UI): ws.send(JSON.stringify({econo: true})) ws.send(JSON.stringify({powerful: true, econo: false})) ws.send(JSON.stringify({fan: "Q"})) // Receiving (status updates): { "protocol": "S21", "power": true, "mode": "C", "temp": 24, "fan": "A", "econo": false, "powerful": false, "quiet": false ... } ``` **Code Implementation**: ```javascript connectFaikoutWebSocket() { const protocol = this.apiroute.startsWith('https') ? 'wss://' : 'ws://'; const wsUrl = `${protocol}${this.apiIP}/status`; this.FaikoutWs = new WebSocket(wsUrl, { rejectUnauthorized: false }); this.FaikoutWs.on('open', () => { // Connection established, send pending commands }); this.FaikoutWs.on('message', (data) => { // Process status updates, update HomeKit characteristics }); this.FaikoutWs.on('close', () => { // Auto-reconnect after 5 seconds }); } ``` --- ### 7. **Three-Way Mutual Exclusivity** ⭐ NEW - **Feature**: Econo, Powerful, and Night Quiet modes are now fully mutually exclusive - **Behavior**: - **Turn ON Econo** → Disables Powerful + Night Quiet (resets fan to Auto) - **Turn ON Powerful** → Disables Econo + Night Quiet (resets fan to Auto) - **Turn ON Night Quiet** → Disables Econo + Powerful (sets fan to Quiet) - **HomeKit Experience**: When you toggle one switch ON, the other two automatically turn OFF - **Implementation**: Each setter now checks and disables the other two modes before enabling itself **Code Example**: ```javascript setEconoMode: function (value, callback) { if (value) { // Disable other modes if (this.Powerful_Mode) { this.Powerful_Mode = false; this.powerfulModeService.updateValue(false); } if (this.NightQuiet_Mode) { this.NightQuiet_Mode = false; this.nightQuietModeService.updateValue(false); } } const controlData = { econo: value, powerful: false, fan: value ? 'A' : undefined // Reset fan from Quiet mode }; } ``` --- ### 8. **Fan Speed Always Visible** ⭐ NEW - **Feature**: Fan speed slider now always available in HeaterCooler settings - **Implementation**: Added `RotationSpeed` characteristic to `heaterCoolerService` - **User Experience**: - **Always available**: Fan speed slider in AC accessory settings (like Oscillate) - **Optional**: Separate Fan accessory when `enableFanAccessory` is enabled in config - **Benefits**: - Two ways to control fan speed without requiring separate fan accessory - Consistent with how SwingMode (oscillate) is presented - More accessible fan control **Where to Find It**: ``` HomeKit → AC Accessory → Settings (⚙️) → Fan Speed slider ``` --- ### 9. **Enhanced Debug Logging** - **Feature**: Comprehensive logging for WebSocket communication - **Added Logs**: - `>>>> Sending to Faikout:` - Outgoing WebSocket commands - `<<<< Received status from Faikout:` - Incoming status updates - State change notifications for econo/powerful/quiet modes - Connection/reconnection status - Raw data on parse errors - **Benefits**: Easy troubleshooting of Faikout controller communication --- ### 10. **ConfiguredName Characteristic** - **Feature**: Allow users to manually rename switches in HomeKit - **Problem Solved**: HomeKit initially shows generic names like "Switch 1", "Switch 2", "Switch 3" - **Implementation**: - Added `ConfiguredName` characteristic to all switch services - Initial name set from config (econoModeName, powerfulModeName, nightQuietModeName) - Event handlers log when switches are renamed by users - Names persist across HomeKit restarts - **User Experience**: - Users can identify switches by toggling them and checking logs - Manual renaming in Home app now works and persists **Code Added**: ```javascript this.econoModeService.setCharacteristic(Characteristic.ConfiguredName, this.econoModeName); this.econoModeService .getCharacteristic(Characteristic.ConfiguredName) .on('set', (value, callback) => { this.log.info('Econo Mode switch renamed to: "%s"', value); callback(); }); ``` --- ### 11. **Enhanced Configuration UI** - **Feature**: Organized, user-friendly configuration interface - **Changes**: - Reorganized into **5 logical sections**: 1. Basic Settings (name, IP, system type) 2. Temperature & Mode Settings 3. Fan Configuration 4. Additional Sensors 5. Special Modes (Econo, Powerful, Night Quiet with custom names) - Added **conditional field visibility**: - `swingMode` dropdown hidden when `system = "Faikout"` (auto 3D swing) - Custom name fields appear only when corresponding mode is enabled - Added **help banner** explaining controller types and Faikout features - Improved descriptions for all fields **Conditional Visibility Example**: ```json { "key": "swingMode", "condition": { "functionBody": "return model.system !== 'Faikout';" } } ``` --- ## Technical Architecture Changes ### API Abstraction Layer ```javascript // Dual-path implementation throughout all setters/getters if (this.isFaikout) { // JSON POST to /control endpoint const controlData = { attribute: value }; this.sendFaikoutControl(controlData, callback); } else { // Query string GET to /aircon/set_control_info const query = body.replace(/,/g, '&').replace(/param=old/, `param=${value}`); this.sendGetRequest(this.set_control_info + '?' + query, callback); } ``` ### New Helper Methods 1. **sendFaikoutControl()**: POST JSON payloads to Faikout `/control` endpoint 2. Dual-path implementations for: - `getEconoMode()` / `setEconoMode()` - `getPowerfulMode()` / `setPowerfulMode()` - `getNightQuietMode()` / `setNightQuietMode()` - `getSwingMode()` / `setSwingMode()` ### State Management - Added state variables: `this.Econo_Mode`, `this.Powerful_Mode`, `this.NightQuiet_Mode` - Mutual exclusivity logic between Econo and Powerful modes - Early-return caching pattern maintained for all characteristics --- ## Configuration Schema Changes ### New Configuration Options ```json { "system": "Faikout", // or "Default" or "Skyfi" "enableEconoMode": true, "econoModeName": "Economy Mode", "enablePowerfulMode": true, "powerfulModeName": "Turbo Mode", "enableNightQuietMode": true, "nightQuietModeName": "Silent Mode" } ``` ### Example Complete Configuration ```json { "accessory": "Daikin-Local", "name": "Living Room AC", "apiroute": "http://192.168.1.100", "system": "Faikout", "swingMode": "3", "enableEconoMode": true, "econoModeName": "Eco Mode", "enablePowerfulMode": true, "powerfulModeName": "Boost Mode", "enableNightQuietMode": true, "nightQuietModeName": "Night Mode" } ``` --- ## Faikout API Attributes - Implementation Status | Attribute | Status | Description | Implementation | |-----------|--------|-------------|----------------| | `power` | ✅ Implemented | AC on/off | Existing `setActive()` | | `mode` | ✅ Implemented | Heat/Cool/Auto/Fan/Dry | Existing `setTargetHeaterCoolerState()` | | `temp` | ✅ Implemented | Target temperature | Existing `setCoolingTemperature()` / `setHeatingTemperature()` | | `fan` | ✅ Implemented | Fan speed (1-7, A=auto, Q=quiet) | Existing `setFanSpeed()` + Night Quiet | | `swingh` | ✅ Implemented | Horizontal swing (boolean) | New `setSwingMode()` Faikout path | | `swingv` | ✅ Implemented | Vertical swing (boolean) | New `setSwingMode()` Faikout path | | `powerful` | ✅ Implemented | Powerful/turbo mode (boolean) | New `setPowerfulMode()` | | `econo` | ✅ Implemented | Economy mode (boolean) | New `setEconoMode()` | | `target` | ❌ Not implemented | Target temperature sensor | Future enhancement | | `env` | ❌ Not implemented | Environmental settings | Future enhancement | | `streamer` | ❌ Not implemented | Streamer air purification | Future enhancement | **8 out of 11 Faikout attributes fully implemented (73% coverage)** --- ## Backward Compatibility ### 100% Maintained - All existing Daikin "Default" and "Skyfi" functionality unchanged - No breaking changes to existing configurations - Conditional logic ensures correct API calls based on `system` setting - Traditional controllers unaffected by new Faikout code paths ### Migration Path Users can switch between controller types by simply changing: ```json "system": "Default" → "system": "Faikout" ``` No other configuration changes required. --- ## Git Commits Summary ### Commit History (most recent first) 1. **2115263** - "Add fan speed (RotationSpeed) slider to HeaterCooler service" 2. **9976a00** - "Make Econo, Powerful, and Night Quiet modes mutually exclusive" 3. **e92a95a** - "Fix Night Quiet mode WebSocket status updates" 4. **41f7cac** - "Add enhanced WebSocket logging for debugging Faikout communication" 5. **3cac189** - "Implement WebSocket support for Faikout S21 protocol control" 6. **e51b2a9** - "Fix missing econo/powerful parameters in Faikout fallback API" 7. **d641391** - "Add fallback mechanism for Faikout controllers without JSON /control endpoint" 8. **30eaf9f** - "Add ESP32-Faikout GitHub link to Controller Type section in config UI" 9. **0a10d58** - "Add SwingMode to Fan service for easier access in HomeKit" 10. **f1c661f** - "Add ConfiguredName characteristic to allow manual switch renaming in HomeKit" 11. **45dd261** - "Reorganize config UI into logical sections with conditional visibility" 12. **4f4b18a** - "Implement Econo/Powerful mutual exclusivity and Faikout swing mode support" --- ## Testing & Validation ### Tested Scenarios ✅ Faikout controller with all special modes enabled ✅ Traditional Daikin controller (no regression) ✅ Skyfi controller (no regression) ✅ Mutual exclusivity between Econo and Powerful ✅ Switch naming and ConfiguredName persistence ✅ Conditional UI visibility in Homebridge Config UI X ✅ Swing mode for both controller types ✅ WebSocket communication with Faikout controllers ✅ Three-way mutual exclusivity (Econo, Powerful, Night Quiet) ### Known Limitations - SwingMode characteristic may not be visible in Apple Home app UI (HomeKit limitation) - Workaround: Use third-party HomeKit apps (Eve, Controller, Home+) - Alternative: Swing control works programmatically and via automations - Initial switch names may show as "Switch 1/2/3" until user renames them - Solution: Toggle switches to identify via logs, then rename in Home app - **Econo and Powerful modes may not work on all AC models** ⚠️ NEW - Issue: Some Daikin AC units don't properly acknowledge these S21 protocol commands - Symptom: Switches turn ON briefly, then automatically turn OFF after a few seconds - Cause: AC unit rejects the mode change via S21 protocol (not a plugin bug) - Verification: Same behavior occurs in native Faikout web UI - Recommendation: If this affects you, report to ESP32-Faikout project with AC model details - Workaround: Disable these switches in config if they don't work with your AC model - Note: Night Quiet mode (fan speed) typically works on all models --- ## User-Facing Benefits ### For Faikout Users 1. **Full native support** - No need for workarounds or custom configurations 2. **All major features** - Econo, Powerful, Night Quiet, 3D Swing all accessible 3. **Easy setup** - Just set `"system": "Faikout"` in config 4. **Proper JSON API** - Uses native Faikout POST endpoints, not query string hacks ### For Traditional Daikin Users 1. **No changes required** - Existing configurations work identically 2. **New features available** - Can now enable Econo, Powerful, Night Quiet modes 3. **Better organization** - Cleaner config UI with logical sections ### For All Users 1. **Switch renaming** - Can customize switch names in HomeKit 2. **Better UI** - Organized configuration interface with helpful descriptions 3. **Mutual exclusivity** - Econo and Powerful modes properly managed 4. **Logging** - Clear debug and info messages for troubleshooting --- ## Future Enhancement Opportunities ### Potential Additions 1. **Streamer Mode** - Air purification control (Faikout attribute) 2. **Target Temperature Sensor** - External temperature sensor support (Faikout attribute) 3. **Environmental Settings** - Advanced Faikout features (Faikout attribute) 4. **Swing Mode Switch** - Separate switch accessory for easier access (workaround for HomeKit UI limitation) 5. **Enhanced Fan Control** - Faikout supports more granular fan speeds 6. **Status Indicators** - Real-time mode indicators in HomeKit ### Code Quality Improvements 1. Consolidate dual-path implementations into helper methods 2. Add unit tests for Faikout-specific code paths 3. Create integration tests with mock Faikout controller 4. Add JSDoc documentation for all new methods --- ## Documentation Updates Needed ### README.md - ✅ Faikout attribute support table added - ✅ Controller type explanations documented - ⚠️ Consider adding: Full configuration examples section - ⚠️ Consider adding: Troubleshooting guide for switch naming ### config.schema.json - ✅ All new fields documented with descriptions - ✅ Conditional visibility implemented - ✅ Help banners added ### Code Comments - ✅ Dual-path logic clearly commented - ✅ API differences explained in comments - ⚠️ Consider adding: JSDoc function documentation --- ## Summary Statistics - **Lines of Code Changed**: ~600 lines - **New Functions Added**: 15 (6 getters + 6 setters for special modes + 3 WebSocket methods) - **New Configuration Options**: 7 - **New Dependencies**: 1 (`ws` package for WebSocket) - **New HomeKit Accessories**: 3 switches (Econo, Powerful, Night Quiet) - **New HomeKit Characteristics**: 2 (RotationSpeed on HeaterCooler, ConfiguredName on switches) - **API Compatibility**: 3 protocols supported (Faikout WebSocket + Faikout JSON + Traditional) - **Faikout Coverage**: 8/11 attributes (73%) - **Backward Compatibility**: 100% maintained - **Breaking Changes**: None --- ## Credits & Acknowledgments - **ESP32-Faikout Project**: RevK's open-source Daikin controller - **Original Plugin**: cbrandlehner/homebridge-daikin-local - **Implementation**: October 2025 feature additions - **Testing**: Faikout controller validation --- *Last Updated: October 28, 2025*