UNPKG

homebridge-smartsystem

Version:

SmartServer (Proxy TCP sockets to the cloud, Smappee MQTT, Duotecno IP Nodes, Homekit interface)

285 lines 13.6 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Platform = void 0; const types_1 = require("../duotecno/types"); const logger_1 = require("../duotecno/logger"); const system_1 = require("../duotecno/system"); const smappee_1 = require("./smappee"); const smartapp_1 = require("./smartapp"); const dimmer_1 = require("../accessories/dimmer"); const switch_1 = require("../accessories/switch"); const bulb_1 = require("../accessories/bulb"); const windowcovering_1 = require("../accessories/windowcovering"); const garagedoor_1 = require("../accessories/garagedoor"); const mood_1 = require("../accessories/mood"); const temperature_1 = require("../accessories/temperature"); const base_1 = require("./base"); const socapp_1 = require("./socapp"); const door_1 = require("../accessories/door"); const lock_1 = require("../accessories/lock"); const p1_1 = require("./p1"); const shelly_1 = require("./shelly"); const config_1 = require("../duotecno/config"); const fs_1 = require("fs"); const proxy_1 = require("./proxy"); class Platform extends base_1.Base { constructor(logger, pConfig, api) { var _a; super("homebridge"); this.accessoryList = []; this.ready = false; this.startWaiting = 0; if (logger.info) (0, logger_1.setLogFunction)(logger.info); this.config = Object.assign({}, pConfig); this.config.debug = (pConfig && ("debug" in pConfig)) ? pConfig.debug : false; if (this.config.debug) logger_1.logSettings["homebridge"] = logger_1.LogLevel.debug; if (typeof this.config.system.cmasters === "undefined") { (0, logger_1.log)("homebridge", "try doing upgrade from pre v6.2 versions"); this.doUpgradeV62(); } // we're running under HomeBridge/Platform -> always set proxy kind to "gw" if (!this.config.proxy) { this.config.proxy = Object.assign({}, proxy_1.kEmptyProxy); } else if (this.config.proxy.kind !== "gw") { this.config.proxy.kind = "gw"; } (0, logger_1.log)("homebridge", "running in " + ((this.config.debug) ? "debug" : "prod") + " mode in directory: " + process.cwd()); (0, logger_1.log)("homebridge", "with config:" + JSON.stringify(this.config, null, 2)); // save config for other components (0, config_1.setConfig)(this.config); // remember api for later use this.homebridgeAPI = api; if (this.config.system) { try { this.system = new system_1.System(); this.system.openMasters(true); this.system.emitter.on('ready', this.systemReady.bind(this)); this.system.emitter.on('update', this.updateState.bind(this)); } catch (err) { (0, logger_1.log)("homebridge", err); if (!this.system) { (0, logger_1.log)("homebridge", "platform - Can't run without a System."); return; } } } else { (0, logger_1.log)("homebridge", "platform - No System configured -> can't run !!!"); return; } // start power managers this.power = {}; this.startPower("smappee", smappee_1.Smappee); this.startPower("p1", p1_1.P1); this.startPower("shelly", shelly_1.Shelly); // startup a smartApp if configured if (this.config.smartapp) { try { this.smartapp = new smartapp_1.SmartApp(this.system, this.power, this); this.smartapp.serve(); // Register webapp with proxy for graceful shutdown const { setWebApp } = require('./proxy'); setWebApp(this.smartapp); } catch (err) { (0, logger_1.log)("homebridge", err); if (!this.smartapp) { (0, logger_1.log)("homebridge", "platform - No SmartApp started."); } } } else { (0, logger_1.log)("homebridge", "platform - No SmartApp configured."); } // startup a SocApp if configured -> for proxy (not needed for normal operations) if (this.config.socapp) { try { // reuse the config file from the smartapp this.smartsoc = new socapp_1.SocApp(this.system, 'socapp'); this.smartsoc.serve(); } catch (err) { (0, logger_1.log)("homebridge", err); if (!this.smartsoc) { (0, logger_1.log)("homebridge", "platform - No SocApp started."); } } } else { (0, logger_1.log)("homebridge", "platform - No SocApp configured."); } // Always set proxy kind to "gw" when running under Platform/HomeBridge // This prevents auto-restart on errors even if proxy is not configured if (this.config.proxy && ((_a = this.config.proxy) === null || _a === void 0 ? void 0 : _a.uniqueId)) { this.config.proxy.kind = "gw"; (0, proxy_1.setProxyConfig)(this.config.proxy); (0, proxy_1.cleanStart)(true); (0, logger_1.log)("homebridge", "platform - Proxy configured: " + JSON.stringify(this.config.proxy, null, 2)); } else { (0, logger_1.log)("homebridge", "platform - No Proxy configured."); // Still set kind to "gw" to prevent auto-restart on web server errors (0, proxy_1.setProxyConfig)(Object.assign(Object.assign({}, this.config.proxy), { kind: "gw" })); } } startPower(type, PowerMgr) { // startup a power handler, if configured if (this.config[type]) { try { this.power[type] = new PowerMgr(this.system); } catch (err) { (0, logger_1.log)("homebridge", err); if (!this.power[type]) { (0, logger_1.log)("homebridge", "platform - No " + type + " started."); } } } else { (0, logger_1.log)("homebridge", "platform - No " + type + " configured."); } } updateState(unit) { const accessory = this.accessoryList.find((acc) => unit.isUnit(acc.unit)); if (accessory) { accessory.updateState(); } } systemReady() { const inConfig = this.system.activeUnitsConfig().length; const inSystem = this.system.allActiveUnits().length; (0, logger_1.log)("homebridge", "=== SYSTEM READY received update -> addMasters: " + inSystem + " of " + inConfig + " ==="); this.ready = (inSystem == inConfig); // trigger status request of all active units in 2 seconds. setTimeout(() => __awaiter(this, void 0, void 0, function* () { let units = this.system.allActiveUnits(); for (let u of units) { yield u.node.master.requestUnitStatus(u); } }), 2000); } accessories(callback) { // waiting until the database is complete or give up after 5 minutes const kMaxWaiting = 5 * 60; const inConfig = this.system.activeUnitsConfig().length; const inSystem = this.system.allActiveUnits().length; this.ready = (inSystem == inConfig); if (this.ready) { (0, logger_1.log)("homebridge", "=== running after timeout of " + this.startWaiting + " secs --> " + inSystem + " == " + inConfig + " units -> " + (inConfig == inSystem) + ", will start in 10 seconds ==="); setTimeout(() => { this.doAccessories(callback); }, 10 * 1000); } else if (this.startWaiting > kMaxWaiting) { // give up, retry connection to the masters, a manager like "forever" or "pm2" will restart us. (0, logger_1.log)("homebridge", "=== giving up after " + kMaxWaiting + " secs -> auto restart system ==="); process.exit(-1); } else { // wait another 5 seconds. (0, logger_1.log)("homebridge", "=== waiting >> found " + inSystem + " units out of " + inConfig + " selected after " + this.startWaiting + " sec ==="); this.startWaiting += 5; setTimeout(() => { this.accessories(callback); }, 5000); } } doAccessories(callback) { (0, logger_1.log)("homebridge", "platform - accessories() called by Homebridge - System is ready"); this.addAccessories() .then(list => { (0, logger_1.log)("homebridge", "platform - addAccessories returned: " + list.length + " accessories."); callback(list); }) .catch(reason => { (0, logger_1.log)("homebridge", "platform - addAccessories errored: " + reason); callback([]); }); } addAccessories() { return __awaiter(this, void 0, void 0, function* () { if (!this.system) { (0, logger_1.log)("homebridge", "platform - No System -> No accessories"); this.accessoryList = []; return; } // clear our list this.accessoryList = []; this.system.allActiveUnits().forEach(unit => { (0, logger_1.log)("homebridge", "adding accessory: " + unit.getDescription()); switch (unit.getType()) { case types_1.UnitExtendedType.kDimmer: this.accessoryList.push(new dimmer_1.Dimmer(this.homebridgeAPI, unit)); break; case types_1.UnitExtendedType.kSwitch: this.accessoryList.push(new switch_1.Switch(this.homebridgeAPI, unit)); break; case types_1.UnitExtendedType.kLightbulb: this.accessoryList.push(new bulb_1.Bulb(this.homebridgeAPI, unit)); break; case types_1.UnitExtendedType.kSwitchingMotor: this.accessoryList.push(new windowcovering_1.WindowCovering(this.homebridgeAPI, unit)); break; case types_1.UnitExtendedType.kGarageDoor: this.accessoryList.push(new garagedoor_1.GarageDoor(this.homebridgeAPI, unit)); break; case types_1.UnitExtendedType.kDoor: this.accessoryList.push(new door_1.Door(this.homebridgeAPI, unit)); break; case types_1.UnitExtendedType.kLock: case types_1.UnitExtendedType.kUnlocker: this.accessoryList.push(new lock_1.Lock(this.homebridgeAPI, unit)); break; case types_1.UnitExtendedType.kMood: case types_1.UnitExtendedType.kCondition: case types_1.UnitExtendedType.kInput: this.accessoryList.push(new mood_1.Mood(this.homebridgeAPI, unit)); break; case types_1.UnitExtendedType.kTemperature: this.accessoryList.push(new temperature_1.Temperature(this.homebridgeAPI, unit)); break; default: (0, logger_1.log)("homebridge", "platform - addAccessories: accessory type not yet supported: " + unit.typeName() + " (" + unit.getName() + ")"); break; } }); return this.accessoryList; }); } doUpgradeV62() { function readFile(type) { const fn = config_1.kConfigFiles + "/config." + type + ".json"; try { const configBuf = (0, fs_1.readFileSync)(fn); const configStr = configBuf.toString(); return (types_1.Sanitizers[type])(JSON.parse(configStr)); } catch (err) { (0, logger_1.log)("system", "Couldn't read my config file (" + fn + ") -- setting to 'false'"); return false; } } this.config.system = readFile("system"); this.config.smartapp = readFile("smartapp"); this.config.scenes = readFile("scenes"); this.config.settings = readFile("settings"); this.config.smappee = readFile("smappee"); this.config.p1 = readFile("p1"); this.config.shelly = readFile("shelly"); (0, config_1.setConfig)(this.config); (0, logger_1.log)("homebridge", "Upgraded the config file -> NOW: log in and save something..."); } } exports.Platform = Platform; //# sourceMappingURL=platform.js.map