UNPKG

iobroker.gree-hvac

Version:
232 lines (231 loc) 6.46 kB
"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var device_manager_exports = {}; __export(device_manager_exports, { DeviceManager: () => DeviceManager }); module.exports = __toCommonJS(device_manager_exports); var import_node_events = require("node:events"); var import_connection = require("./connection"); var import_encryptor = require("./encryptor"); const statusKeys = [ "Pow", "Mod", "TemUn", "SetTem", "TemRec", "WdSpd", "Air", "Blo", "Health", "SwhSlp", "Lig", "SwingLfRig", "SwUpDn", "Quiet", "Tur", "StHt", "SvSt", "TemSen", "time" ]; const TEMPERATURE_SENSOR_OFFSET = -40; const DeviceScanTimeoutMs = 5e3; class DeviceManager extends import_node_events.EventEmitter { logger; connection; devices = {}; /** * */ constructor(devicesList, logger, requestTimeoutMs = 1e3) { super(); this.logger = logger; this.connection = new import_connection.Connection(devicesList, logger, requestTimeoutMs); this.rescanDevices(devicesList); this.connection.on("dev", this._registerDevice.bind(this)); } /** * */ rescanDevices(devicesList) { const rescanTimeout = setTimeout(() => { const items = devicesList.split(";"); const readyDevices = Object.keys(this.devices).map((key) => this.devices[key].address); const rescanItems = items.filter((item) => !readyDevices.includes(item)); if (rescanItems.length === 0) { return; } const addresses = rescanItems.join(";"); try { this.connection.scan(addresses); } catch { } clearTimeout(rescanTimeout); this.rescanDevices(devicesList); }, DeviceScanTimeoutMs); } /** * */ async sendRegisterDevice(message, rinfo, encVersion) { var _a; const deviceId = message.cid || message.mac; this.logger.info(`New device found: ${message.name} (mac: ${deviceId}), binding encVer ${encVersion}...`); const { address, port } = rinfo; try { const response = await this.connection.sendRequest( address, port, { cid: "app", tcid: deviceId, mac: deviceId, t: "bind", uid: 0 }, encVersion ); const key = response.key; if (key) { const device = { ...message, mac: message.mac, name: message.name, address, port, key, encVersion }; this.devices[deviceId] = device; this.connection.registerKey(rinfo.address, key); this.connection.registerEncVersion(address, encVersion); this.emit("device_bound", deviceId, device); this.logger.info( `New device bound: ${device.name} (${device.address}:${device.port}) with encryption v${encVersion}` ); return device; } return null; } catch (e) { this.logger.error(`Failed to bind device ${deviceId}: ${e.message}`); this.logger.error((_a = e.stack) != null ? _a : String(e)); return null; } } /** * */ async _registerDevice(message, rinfo) { var _a; let encVersion = this.connection.getEncVersion(rinfo.address); let device; try { device = await this.sendRegisterDevice(message, rinfo, encVersion); if (!device) { this.logger.info("Registering failed, trying next encVer..."); this.connection.registerEncVersion(rinfo.address, encVersion % 2 + 1); encVersion = this.connection.getEncVersion(rinfo.address); if (encVersion === 1) { this.connection.registerKey(rinfo.address, import_encryptor.defaultKey); } else if (encVersion === 2) { this.connection.registerKey(rinfo.address, import_encryptor.defaultKeyGCM); } device = await this.sendRegisterDevice(message, rinfo, encVersion); } } catch (e) { this.logger.error((_a = e.stack) != null ? _a : String(e)); return void 0; } return device; } /** * */ close() { this.connection.close(); } /** * */ getDevices() { return Object.values(this.devices); } /** * */ async getDeviceStatus(deviceId) { const device = this.devices[deviceId]; if (!device) { throw new Error(`Device ${deviceId} not found`); } const payload = { cols: statusKeys, mac: device.mac, t: "status" }; const response = await this.connection.sendRequest(device.address, device.port, payload); const cols = response.cols; const dat = response.dat; const deviceStatus = cols.reduce( (acc, key, index) => ({ ...acc, [key]: dat[index] }), {} ); if ("TemSen" in deviceStatus) { deviceStatus.TemSen = deviceStatus.TemSen + TEMPERATURE_SENSOR_OFFSET; } this.emit("device_status", deviceId, deviceStatus); return deviceStatus; } /** * */ async setDeviceState(deviceId, state) { const device = this.devices[deviceId]; if (!device) { return null; } const payload = { mac: device.mac, opt: Object.keys(state), p: Object.values(state), t: "cmd" }; const response = await this.connection.sendRequest(device.address, device.port, payload); const opt = response.opt; const p = response.p; const deviceStatus = opt.reduce( (acc, key, index) => ({ ...acc, [key]: p[index] }), {} ); this.emit("device_status", deviceId, deviceStatus); return deviceStatus; } } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { DeviceManager }); //# sourceMappingURL=device_manager.js.map