Files
SRS IT 27be1892ed Initial release — Dibby Wemo Manager v2.0.0
Desktop (Electron/Windows): device dashboard, DWM scheduling engine,
native firmware rules editor, Windows background service, web remote,
sunrise/sunset support.

Homebridge plugin (homebridge-dibby-wemo v1.0.0): HomeKit switches for
all local Wemo devices, custom UI with DWM rules, device rules,
scheduler heartbeat, and location-based sunrise/sunset scheduling.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-28 16:30:43 -04:00

96 lines
3.9 KiB
JavaScript

'use strict';
/**
* WemoSwitchAccessory
*
* Represents a single Wemo device as a HomeKit Switch.
* State is polled on the configured interval and pushed to HomeKit.
*/
class WemoSwitchAccessory {
/**
* @param {object} params
* @param {object} params.platform - WemoPlatform instance
* @param {object} params.accessory - PlatformAccessory from Homebridge
* @param {object} params.device - { host, port, udn, friendlyName, ... }
* @param {object} params.wemoClient - wemo-client module
* @param {number} params.pollInterval - poll interval in seconds
*/
constructor({ platform, accessory, device, wemoClient, pollInterval = 30 }) {
this.platform = platform;
this.accessory = accessory;
this.device = device;
this.wemo = wemoClient;
this.pollInterval = pollInterval;
this.log = platform.log;
const { Service, Characteristic } = platform.api.hap;
// ── Accessory information ───────────────────────────────────────────────
this.accessory.getService(Service.AccessoryInformation)
?.setCharacteristic(Characteristic.Manufacturer, 'Belkin')
.setCharacteristic(Characteristic.Model, device.productModel ?? 'Wemo Switch')
.setCharacteristic(Characteristic.SerialNumber, device.udn ?? device.host);
// ── Switch service ──────────────────────────────────────────────────────
this.switchService = this.accessory.getService(Service.Switch)
|| this.accessory.addService(Service.Switch, device.friendlyName ?? device.host);
this.switchService.getCharacteristic(Characteristic.On)
.onGet(this._getOn.bind(this))
.onSet(this._setOn.bind(this));
// ── Initial state + poll ────────────────────────────────────────────────
this._currentState = false;
this._pollTimer = null;
this._startPolling();
}
// ── HomeKit handlers ──────────────────────────────────────────────────────
async _getOn() {
try {
this._currentState = await this.wemo.getBinaryState(this.device.host, this.device.port);
} catch (e) {
this.log.warn(`[${this.device.friendlyName}] getBinaryState failed: ${e.message}`);
}
return this._currentState;
}
async _setOn(value) {
try {
await this.wemo.setBinaryState(this.device.host, this.device.port, !!value);
this._currentState = !!value;
} catch (e) {
this.log.error(`[${this.device.friendlyName}] setBinaryState failed: ${e.message}`);
throw new this.platform.api.hap.HapStatusError(
this.platform.api.hap.HAPStatus.SERVICE_COMMUNICATION_FAILURE
);
}
}
// ── Polling ───────────────────────────────────────────────────────────────
_startPolling() {
this._pollTimer = setInterval(async () => {
try {
const newState = await this.wemo.getBinaryState(this.device.host, this.device.port);
if (newState !== this._currentState) {
this._currentState = newState;
const { Characteristic } = this.platform.api.hap;
this.switchService.updateCharacteristic(Characteristic.On, newState);
}
} catch { /* device unreachable — keep last state */ }
}, this.pollInterval * 1000);
}
stopPolling() {
if (this._pollTimer) {
clearInterval(this._pollTimer);
this._pollTimer = null;
}
}
}
module.exports = WemoSwitchAccessory;