UNPKG

@elshaer/homebridge-lg-thinq

Version:

A Homebridge plugin for controlling/monitoring LG ThinQ device via LG ThinQ platform.

198 lines 9.87 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.LGThinQHomebridgePlatform = void 0; const settings_1 = require("./settings"); const helper_1 = require("./helper"); const ThinQ_1 = require("./lib/ThinQ"); const events_1 = require("events"); const constants_1 = require("./lib/constants"); const errors_1 = require("./errors"); const characteristics_1 = __importDefault(require("./characteristics")); /** * HomebridgePlatform * This class is the main constructor for your plugin, this is where you should * parse the user config and discover/register accessories with Homebridge. */ class LGThinQHomebridgePlatform { 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.customCharacteristics = (0, characteristics_1.default)(this.api.hap.Characteristic); // this is used to track restored cached accessories this.accessories = []; // enable thinq1 support this.enable_thinq1 = false; this.events = new events_1.EventEmitter(); this.enable_thinq1 = config.thinq1; this.config.devices = this.config.devices || []; this.intervalTime = (config.refresh_interval || 5) * 1000; this.ThinQ = new ThinQ_1.ThinQ(this, config, log); if (!config.country || !config.language || !((config.username && config.password) || config.refresh_token)) { this.log.error('Missing required config parameter.'); return; } const didFinishLaunching = () => { // run the method to discover / register your devices as accessories this.ThinQ.isReady().then(() => { this.log.info('Successfully connected to the ThinQ API.'); const discoverDevices = () => { this.discoverDevices().then(async () => { await this.startMonitor(); }).catch(err => { if (err instanceof errors_1.NotConnectedError) { setTimeout(() => { discoverDevices(); }, 30000); } else { this.log.error(err.message); this.log.debug(err); } }); }; discoverDevices(); }).catch(err => { var _a; if (err.message === 'Internal Server Error' || ((_a = err.code) === null || _a === void 0 ? void 0 : _a.indexOf('ECONN')) === 0 || err instanceof errors_1.NotConnectedError) { this.log.error('LG ThinQ internal server error, try again later.'); } else { this.log.error('ThinQ API is not ready. please check configuration and try again.'); } this.log.error(err.message); this.log.debug(err); }); }; this.api.on('didFinishLaunching', async () => { this.log.debug('Executed didFinishLaunching callback'); didFinishLaunching(); }); } /** * This function is invoked when homebridge restores cached accessories from disk at startup. * It should be used to setup event handlers for characteristics and update respective values. */ configureAccessory(accessory) { this.log.info('Loading accessory from Homebridge cache:', accessory.displayName); // add the restored accessory to the accessories cache so we can track if it has already been registered this.accessories.push(accessory); } async discoverDevices() { const accessoriesToRemoveUUID = this.accessories.map(accessory => accessory.UUID); const devices = await this.ThinQ.devices(); if (!devices.length) { this.log.warn('No ThinQ devices in your account.'); } for (const device of devices) { this.log.debug('Device [' + device.name + ']: ', device.toString()); this.log.debug(JSON.stringify(device.data)); if (!this.enable_thinq1 && device.platform === constants_1.PlatformType.ThinQ1) { this.log.debug('Thinq1 device is skipped: ', device.toString()); continue; } if (this.config.devices.length && !this.config.devices.find(enabled => enabled.id === device.id)) { this.log.info('Device skipped: ', device.id); continue; } this.log.info('[' + device.name + '] Setting up device!'); const setupSuccess = await this.ThinQ.setup(device); if (!setupSuccess) { this.log.warn('[' + device.name + '] Failed to setup device!'); continue; } const accessoryType = helper_1.Helper.make(device); if (accessoryType === null) { this.log.info('Device not supported: ' + device.platform + ': ' + device.toString()); this.ThinQ.unregister(device).then(() => { this.log.debug(device.id, '- unregistered!'); }); continue; } let lgThinQDevice; const existingAccessory = this.accessories.find(accessory => accessory.UUID === device.id); if (existingAccessory) { accessoriesToRemoveUUID.splice(accessoriesToRemoveUUID.indexOf(device.id), 1); this.log.info('Restoring existing accessory:', device.toString()); existingAccessory.context.device = device; lgThinQDevice = new accessoryType(this, existingAccessory); } else { this.log.info('Adding new accessory:', device.toString()); const category = helper_1.Helper.category(device); // create a new accessory const accessory = new this.api.platformAccessory(device.name, device.id, category); accessory.context.device = device; lgThinQDevice = new accessoryType(this, accessory); // link the accessory to your platform this.api.registerPlatformAccessories(settings_1.PLUGIN_NAME, settings_1.PLATFORM_NAME, [accessory]); this.accessories.push(accessory); } this.events.on(device.id, lgThinQDevice.update.bind(lgThinQDevice)); // first time update lgThinQDevice.updateAccessoryCharacteristic(device); } const accessoriesToRemove = this.accessories.filter(accessory => accessoriesToRemoveUUID.includes(accessory.UUID)); if (accessoriesToRemove.length) { accessoriesToRemove.map(accessory => { this.log.info('Removing accessory:', accessory.displayName); this.accessories.splice(this.accessories.indexOf(accessory), 1); }); this.api.unregisterPlatformAccessories(settings_1.PLUGIN_NAME, settings_1.PLATFORM_NAME, accessoriesToRemove); } } async startMonitor() { // thinq2 device const thinq2devices = this.accessories.filter(accessory => accessory.context.device.platform === constants_1.PlatformType.ThinQ2); if (thinq2devices.length) { setInterval(() => { this.ThinQ.devices().then((devices) => { devices.filter(device => device.platform === constants_1.PlatformType.ThinQ2).forEach(device => { this.events.emit(device.id, device.snapshot); }); }); }, this.intervalTime); // every interval minute - backup method if mqtt not working this.log.info('Start MQTT listener for thinq2 device'); await this.ThinQ.registerMQTTListener((data) => { var _a, _b; if ('data' in data && 'deviceId' in data) { this.events.emit(data.deviceId, (_b = (_a = data.data) === null || _a === void 0 ? void 0 : _a.state) === null || _b === void 0 ? void 0 : _b.reported); } }); } if (this.accessories.length <= thinq2devices.length) { return; // no thinq1 device, stop here } // polling thinq1 device this.log.info('Start polling device data every ' + this.config.refresh_interval + ' second.'); const ThinQ = this.ThinQ; const interval = setInterval(async () => { try { for (const accessory of this.accessories) { const device = accessory.context.device; if (device.platform === constants_1.PlatformType.ThinQ1 && this.enable_thinq1) { const deviceWithSnapshot = await ThinQ.pollMonitor(device); if (deviceWithSnapshot.snapshot.raw !== null) { this.events.emit(device.id, deviceWithSnapshot.snapshot); } } } } catch (err) { if (err instanceof errors_1.ManualProcessNeeded) { this.log.info('Stop polling device data.'); this.log.warn(err.message); clearInterval(interval); return; // stop plugin here } } }, this.intervalTime); } } exports.LGThinQHomebridgePlatform = LGThinQHomebridgePlatform; //# sourceMappingURL=platform.js.map