homebridge-modern-forms-fans
Version:
Add Modern Forms fans to your Home app using Homebridge.
73 lines • 5.69 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ModernFormsPlatform = void 0;
const network_1 = __importDefault(require("network"));
const rxjs_1 = require("rxjs");
const operators_1 = require("rxjs/operators");
const ping_1 = __importDefault(require("ping"));
const network_calculator_1 = __importDefault(require("network-calculator"));
const get_ip_range_1 = __importDefault(require("get-ip-range"));
const node_arp_1 = __importDefault(require("node-arp"));
const settings_1 = require("./settings");
const platformAccessory_1 = require("./platformAccessory");
const axios_1 = __importDefault(require("axios"));
const mqtt_1 = __importDefault(require("mqtt"));
class ModernFormsPlatform {
constructor(log, config, api) {
this.log = log;
this.config = config;
this.api = api;
this.Service = this.api.hap.Service;
this.Characteristic = this.api.hap.Characteristic;
this.accessories = [];
this.log.debug('Finished initializing platform:', this.config.name);
if (this.config.mqttUrl) {
this.mqtt = mqtt_1.default.connect(this.config.mqttUrl);
}
this.api.on('didFinishLaunching', () => {
this.log.debug('Executed didFinishLaunching callback');
this.discoverDevices();
});
}
async ping(ip) {
return axios_1.default
.post(`http://${ip}/mf`, { queryDynamicShadowData: 1 })
.then(res => res.data);
}
configureAccessory(accessory) {
this.log.info('Loading accessory from cache:', accessory.displayName);
this.accessories.push(accessory);
}
async discoverDevices() {
var _a, _b;
this.log.info('Looking for Modern Forms devices on network');
const getActiveInterface = (0, rxjs_1.bindNodeCallback)(network_1.default.get_active_interface);
const getMAC = (0, rxjs_1.bindNodeCallback)(node_arp_1.default.getMAC.bind(node_arp_1.default));
const cachedFansAddresses$ = (0, rxjs_1.from)((_a = this.accessories) !== null && _a !== void 0 ? _a : []).pipe((0, operators_1.map)(accessory => accessory.context.device), (0, operators_1.tap)(fan => this.log.debug('Found potential IP address from cached devices:', fan.ip)));
const configFansAddresses$ = (0, rxjs_1.from)((_b = this.config.fans) !== null && _b !== void 0 ? _b : []).pipe((0, operators_1.tap)(fan => this.log.debug('Found potential IP address from config:', fan.ip)));
const networkFansAddresses$ = (0, rxjs_1.of)(this.config.autoDiscover).pipe((0, operators_1.mergeMap)(autoDiscover => autoDiscover === false ? rxjs_1.EMPTY : getActiveInterface()), (0, operators_1.tap)(() => this.log.debug('Searching network for Modern Forms fans')), (0, operators_1.map)(int => { var _a, _b; return (0, network_calculator_1.default)((_a = int.ip_address) !== null && _a !== void 0 ? _a : '192.168.0.1', (_b = int.netmask) !== null && _b !== void 0 ? _b : '255.255.255.0'); }), (0, operators_1.map)(network => network.network + '/' + network.bitmask), (0, operators_1.mergeMap)(subnet => (0, get_ip_range_1.default)(subnet)), (0, operators_1.mergeMap)(ip => ping_1.default.promise.probe(ip).then(() => ip)), (0, operators_1.mergeMap)(ip => getMAC(ip).pipe((0, operators_1.map)(mac => { var _a; return (_a = mac === null || mac === void 0 ? void 0 : mac.toUpperCase()) !== null && _a !== void 0 ? _a : ''; }), (0, operators_1.filter)(mac => mac.startsWith('C8:93:46')), (0, operators_1.mapTo)({ ip: ip, light: true }))), (0, operators_1.tap)(fan => this.log.debug('Found potential IP address from network and filtering by MAC vendor:', fan.ip)));
const devices$ = (0, rxjs_1.concat)(cachedFansAddresses$, configFansAddresses$, networkFansAddresses$).pipe((0, operators_1.distinct)(), (0, operators_1.mergeMap)(fan => (0, rxjs_1.of)(fan).pipe((0, operators_1.mergeMap)(fan => this.ping(fan.ip).then(res => res.clientId).catch(() => null)), (0, operators_1.filter)((clientId) => clientId !== null), (0, operators_1.tap)(clientId => this.log.info(`Found device at ${fan.ip} with client ID of ${clientId}`)), (0, operators_1.map)(clientId => {
const uuid = this.api.hap.uuid.generate(clientId);
const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid);
return { fan, clientId, uuid, existingAccessory };
}))), (0, operators_1.share)());
const [newDevices$, existingDevices$] = (0, rxjs_1.partition)(devices$, device => !device.existingAccessory);
newDevices$.subscribe(({ uuid, fan, clientId }) => {
this.log.info('Adding new accessory:', clientId);
const accessory = new this.api.platformAccessory(clientId, uuid);
accessory.context.device = { uuid, ip: fan.ip, light: fan.light, switch: fan.switch, clientId };
new platformAccessory_1.ModernFormsPlatformAccessory(this, accessory);
this.api.registerPlatformAccessories(settings_1.PLUGIN_NAME, settings_1.PLATFORM_NAME, [accessory]);
});
existingDevices$.subscribe(({ uuid, fan, clientId, existingAccessory }) => {
this.log.info('Restoring existing accessory from cache:', clientId);
existingAccessory.context.device = { uuid, ip: fan.ip, light: fan.light, switch: fan.switch, clientId };
new platformAccessory_1.ModernFormsPlatformAccessory(this, existingAccessory);
});
}
}
exports.ModernFormsPlatform = ModernFormsPlatform;
//# sourceMappingURL=platform.js.map