homebridge-smartsystem
Version:
SmartServer (Proxy Websockets to TCP sockets, Smappee MQTT, Duotecno IP Nodes, Homekit interface)
271 lines • 12.8 kB
JavaScript
"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();
}
(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();
}
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.");
}
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.");
}
}
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