Add Daikin local-API driver — MAC-matched subnet sweep instead of UDP broadcast
Daikin BRP069/BRP072-class units are WiFi/DHCP with no fixed IP. hvac's backend runs as a Docker container on its own bridge network (not directly on the LXC's admin-VLAN NIC), so UDP broadcast discovery risked silently failing to egress — instead, every unit is identified by MAC (external_ref), and a background poller periodically HTTP-sweeps the configured subnet CIDR and matches replies by MAC, self-healing zone_devices.device_ip whenever a lease changes. Only needs plain outbound HTTP, same path already proven by the MHI Modbus TCP driver. - lib/drivers/daikin.js: discover()/getStatus()/setTarget() against the local /common/basic_info + /aircon/get_control_info + /aircon/set_control_info API (confirmed live against firmware 4_2_303, 2026-08-25). Mode/fan-rate encoding taken from community reverse-engineering, not yet verified against a live setTarget() call — flagged in comments for first real control test. - lib/daikin-poller.js: 60s status poll (cached IP) + 5min subnet resweep (self-heal IP + auto-register new units, never auto-assigned to a zone). - lib/device-registry.js: shared discover-upsert, extracted so both the manual Discover button and the background sweep record device_ip the same way. - ac-control.js / routes/override.js: daikin-status/daikin-control endpoints and commandAcDevice() branch, mirroring the existing MHI control path. - Settings page: new "Daikin subnet (CIDR)" field (daikin_subnet_cidr config key) — sweeps do nothing until this is set. - Frontend: DaikinControlPanel.tsx (on/off/mode/setpoint/fan), wired into ZoneDetailModal; daikin moved from NOT_YET_IMPLEMENTED to a real driver. Backend node --check and frontend tsc --noEmit both clean. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
5fc576aabd
commit
373f66ef5c
12 changed files with 559 additions and 27 deletions
|
|
@ -1,6 +1,6 @@
|
|||
import type {
|
||||
Zone, ZoneStatus, Device, DevicePhoto, ActivityEntry, NewbookSite, AppConfig,
|
||||
MhiGateway, MhiStatus, ActiveAcTemplate,
|
||||
MhiGateway, MhiStatus, ActiveAcTemplate, DaikinStatus,
|
||||
} from './types'
|
||||
|
||||
const BASE = '/hvac/api'
|
||||
|
|
@ -144,6 +144,14 @@ export function sendMhiControl(deviceId: number, body: { onOff?: boolean; mode?:
|
|||
return request(`/devices/${deviceId}/mhi-control`, { method: 'POST', body: JSON.stringify(body) })
|
||||
}
|
||||
|
||||
// Daikin manual control (device-level — daikin rows only)
|
||||
export function fetchDaikinStatus(deviceId: number): Promise<DaikinStatus> {
|
||||
return request(`/devices/${deviceId}/daikin-status`)
|
||||
}
|
||||
export function sendDaikinControl(deviceId: number, body: { onOff?: boolean; mode?: string; tempC?: number; fanSpeed?: string }): Promise<{ ok: boolean }> {
|
||||
return request(`/devices/${deviceId}/daikin-control`, { method: 'POST', body: JSON.stringify(body) })
|
||||
}
|
||||
|
||||
// Config / settings
|
||||
export function fetchConfig(): Promise<AppConfig> {
|
||||
return request('/config')
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue