homebridge-modern-forms-fans
Version:
Add Modern Forms fans to your Home app using Homebridge.
164 lines • 7.7 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ModernFormsPlatformAccessory = void 0;
const axios_1 = __importDefault(require("axios"));
const NUMBER_OF_FAN_SPEEDS = 6;
class ModernFormsPlatformAccessory {
constructor(platform, accessory) {
var _a, _b;
this.platform = platform;
this.accessory = accessory;
this.states = {
fanOn: false,
fanSpeed: 0,
fanDirection: 'forward',
lightOn: false,
lightBrightness: 0,
clientId: this.device().clientId,
};
this.getStepWithoutGoingOver = (steps) => {
return Math.floor(100 / steps * 1000) / 1000;
};
this.log = (...args) => {
this.platform.log.info(`[${this.device().ip}]`, ...args);
};
this.accessory.getService(this.platform.Service.AccessoryInformation)
.setCharacteristic(this.platform.Characteristic.Manufacturer, 'Modern Forms')
.setCharacteristic(this.platform.Characteristic.Model, 'Unknown')
.setCharacteristic(this.platform.Characteristic.SerialNumber, this.device().clientId);
// FAN SERVICE
this.fanService =
(_a = this.accessory.getService(this.platform.Service.Fan)) !== null && _a !== void 0 ? _a : this.accessory.addService(this.platform.Service.Fan);
this.fanService.setCharacteristic(this.platform.Characteristic.Name, accessory.context.device.ip);
this.fanService.getCharacteristic(this.platform.Characteristic.On)
.onGet(this.getFanOn.bind(this))
.onSet(this.setFanOn.bind(this));
this.fanService.getCharacteristic(this.platform.Characteristic.RotationSpeed)
.onSet(this.setRotationSpeed.bind(this))
.setProps({ minStep: this.getStepWithoutGoingOver(6) });
this.fanService.getCharacteristic(this.platform.Characteristic.RotationDirection)
.onSet(this.setRotationDirection.bind(this));
// LIGHT SERVICE
if (this.device().light) {
this.lightService =
(_b = this.accessory.getService(this.platform.Service.Lightbulb)) !== null && _b !== void 0 ? _b : this.accessory.addService(this.platform.Service.Lightbulb);
this.lightService.setCharacteristic(this.platform.Characteristic.Name, accessory.context.device.ip);
this.lightService.getCharacteristic(this.platform.Characteristic.On).onSet(this.setLightOn.bind(this));
this.lightService.getCharacteristic(this.platform.Characteristic.Brightness).onSet(this.setBrightness.bind(this));
}
else {
const oldLightService = this.accessory.getService(this.platform.Service.Lightbulb);
if (oldLightService) {
this.accessory.removeService(oldLightService);
}
}
if (this.device().switch) {
const mqttTopic = `stat/${this.device().switch}/RESULT`;
this.log(`Subscribing to messages on topic ${mqttTopic}...`);
this.platform.mqtt.subscribe(mqttTopic);
this.platform.mqtt.on('message', (topic, message) => {
var _a;
this.log(`Got message from topic ${topic}`);
if (topic === mqttTopic) {
const data = JSON.parse(message.toString());
this.log(`Message: ${JSON.stringify(data)}`);
if (((_a = data.Button1) === null || _a === void 0 ? void 0 : _a.Action) === 'SINGLE') {
this.log('Toggle fan on from MQTT');
this.states.fanOn = !this.states.fanOn;
this.sendUpdate();
}
}
});
}
setImmediate(this.poll.bind(this));
}
device() {
return this.accessory.context.device;
}
async request(payload) {
return axios_1.default
.post(`http://${this.device().ip}/mf`, payload)
.then(res => res.data);
}
// HELPERS
poll() {
this.platform.log.info(`Requesting updates from ${this.device().clientId} at IP ${this.device().ip}...`);
this.request({ queryDynamicShadowData: 1 })
.then(this.updateStates.bind(this))
.catch(error => {
this.platform.log.info(`Failed to get status of ${this.device().clientId} at IP ${this.device().ip}: ${error.message}`);
})
.finally(() => {
setTimeout(this.poll.bind(this), (this.platform.config.pollingInterval || 5) * 1000);
});
}
updateStates(data) {
this.platform.log.info(`Updating states for ${this.device().clientId}: ${JSON.stringify(data)}`);
this.states = data;
this.fanService.getCharacteristic(this.platform.Characteristic.On).updateValue(data.fanOn);
this.updateLed();
this.fanService.getCharacteristic(this.platform.Characteristic.RotationSpeed).updateValue(data.fanSpeed * 100 / NUMBER_OF_FAN_SPEEDS);
this.fanService.getCharacteristic(this.platform.Characteristic.RotationDirection).updateValue(data.fanDirection === 'forward' ? 0 : 1);
if (this.lightService) {
this.lightService.getCharacteristic(this.platform.Characteristic.On).updateValue(data.lightOn);
this.lightService.getCharacteristic(this.platform.Characteristic.Brightness).updateValue(data.lightBrightness);
}
}
updateLed() {
if (this.device().switch) {
const mqttTopic = `cmnd/${this.device().switch}/LedPower`;
this.platform.mqtt.publish(mqttTopic, this.states.fanOn ? 'ON' : 'OFF');
}
}
sendUpdate() {
this.platform.log.info(`Sending update to ${this.device().clientId}...`);
this.request(this.states)
.then(this.updateStates.bind(this))
.catch((error) => this.platform.log.info(`Failed to update fan states: ${error.message}`));
}
sendDelayedUpdate() {
if (this.updateTimer) {
clearTimeout(this.updateTimer);
}
this.platform.log.info(`Staging update to ${this.device().clientId}...`);
this.updateTimer = setTimeout(this.sendUpdate.bind(this), 500);
}
// FAN GETTERS / SETTERS
async getFanOn() {
this.log('Get Fan Characteristic On');
return this.states.fanOn;
}
async setFanOn(value) {
this.log('Set Fan Characteristic On ->', value);
this.states.fanOn = Boolean(value);
this.sendUpdate();
}
async setRotationDirection(value) {
this.log('Set Fan Characteristic On ->', value);
this.states.fanDirection = value === 0 ? 'forward' : 'reverse';
this.sendUpdate();
}
async setRotationSpeed(value) {
this.log('Set Fan Characteristic On ->', value);
this.states.fanOn = value > 0;
this.states.fanSpeed = Math.round(value / 100 * NUMBER_OF_FAN_SPEEDS);
this.sendDelayedUpdate();
}
// LIGHT GETTERS / SETTERS
async setLightOn(value) {
this.log('Set Light Characteristic On ->', value);
this.states.lightOn = Boolean(value);
this.sendUpdate();
}
async setBrightness(value) {
this.log('Set Characteristic Brightness -> ', value);
this.states.lightOn = value > 0;
this.states.lightBrightness = value;
this.sendDelayedUpdate();
}
}
exports.ModernFormsPlatformAccessory = ModernFormsPlatformAccessory;
//# sourceMappingURL=platformAccessory.js.map