@elshaer/homebridge-lg-thinq
Version:
A Homebridge plugin for controlling/monitoring LG ThinQ device via LG ThinQ platform.
246 lines • 9.68 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.DeviceModel = exports.ValueType = void 0;
var ValueType;
(function (ValueType) {
ValueType["Bit"] = "Bit";
ValueType["Enum"] = "Enum";
ValueType["Range"] = "Range";
ValueType["Reference"] = "Reference";
ValueType["StringComment"] = "StringComment";
})(ValueType = exports.ValueType || (exports.ValueType = {}));
class DeviceModel {
constructor(data) {
this.data = data;
}
get monitoringValue() {
return this.data.MonitoringValue;
}
value(name) {
var _a, _b, _c, _d, _e, _f;
let data = this.data.Value[name];
if (data === undefined && ((_a = this.data.Monitoring) === null || _a === void 0 ? void 0 : _a.type) === 'THINQ2') {
// convert key to thinq2 monitoring value
const protocol = (_b = this.data.Monitoring) === null || _b === void 0 ? void 0 : _b.protocol;
/**
* sample: "protocol": {
* "state": "State",
* "process": "Process",
* "error": "Error",
* "initialTimeHour": "Initial_Time_H",
* "initialTimeMinute": "Initial_Time_M",
* "course": "Course",
* "courseType": "CourseType",
* "remainTimeHour": "Remain_Time_H",
* "remainTimeMinute": "Remain_Time_M",
* "reserveTimeHour": "Reserve_Time_H",
* "reserveTimeMinute": "Reserve_Time_M",
* "childLock": "ChildLock",
* "door": "Door",
* "rinseRefill": "RinseRefill",
* "saltRefill": "SaltRefill",
* "signalLevel": "SignalLevel",
* "mcReminderSetting": "MCReminderSetting",
* "cleanLReminder": "CleanLReminder",
* "nightDry": "NightDry",
* "delayStart": "DelayStart",
* "energySaver": "EnergySaver",
* "extraDry": "ExtraDry",
* "highTemp": "HighTemp",
* "dualZone": "DualZone",
* "halfLoad": "HalfLoad",
* "autoDoor": "AutoDoor",
* "preSteam": "PreSteam",
* "steam": "Steam",
* "rinseLevel": "RinseLevel",
* "softeningLevel": "SofteningLevel",
* "smartCourse": "SmartCourse",
* "currentDownloadCourse": "CurrentDownloadCourse",
* "tclCount": "TclCount"
* }
*/
if (protocol.constructor.name === 'Object' && protocol[name] !== undefined) {
data = this.data.Value[(_c = this.data.Monitoring) === null || _c === void 0 ? void 0 : _c.protocol[name]];
}
/**
* sample: "protocol": [{
* "_comment": "Hood Operation State(1byte)",
* "superSet": "hoodState.hoodState",
* "value": "HoodState"
* },
* {
* "_comment": "VentState",
* "superSet": "hoodState.ventLevel",
* "value": "VentLevel"
* },
* {
* "_comment": "VentMode",
* "superSet": "hoodState.ventMode",
* "value": "VentMode"
* },
* {
* "_comment": "TimerMin",
* "superSet": "hoodState.remainTimeMinute",
* "value": "TimerMin"
* },
* {
* "_comment": "TimerSec",
* "superSet": "hoodState.remainTimeSecond",
* "value": "TimerSec"
* },
* {
* "_comment": "LightState",
* "superSet": "hoodState.lampLevel",
* "value": "LampLevel"
* },
* {
* "_comment": "Dummy-meaningless",
* "superSet": "hoodState.dummyData",
* "value": "Dummy"
* },
* {
* "_comment": "HoodStateInfo",
* "superSet": null,
* "value": "HoodStateInfo"
* },
* {
* "_comment": "WiFi Access Enable",
* "superSet": null,
* "value": "WiFiAccess"
* }
* ]
*/
else if (protocol.constructor.name === 'Array' && protocol.find(p => p.superSet === name) !== undefined) {
data = this.data.Value[protocol.find(p => p.superSet === name).value];
}
}
if (data === undefined) {
return null;
}
const type = data.type || data.data_type;
switch (type.toLowerCase()) {
case 'enum':
return {
type: ValueType.Enum,
options: data.option || data.value_mapping,
};
case 'range':
return {
type: ValueType.Range,
min: (_d = (data.option || data.value_validation)) === null || _d === void 0 ? void 0 : _d.min,
max: (_e = (data.option || data.value_validation)) === null || _e === void 0 ? void 0 : _e.max,
step: ((_f = (data.option || data.value_validation)) === null || _f === void 0 ? void 0 : _f.step) || 1,
};
case 'bit': {
const bitValues = Object.values(data.option).reduce((obj, value) => ({
...obj,
[value.startbit]: value.values,
}), {});
return { type: ValueType.Bit, options: bitValues };
}
case 'reference': {
const [ref] = data.option;
return { type: ValueType.Reference, reference: this.data[ref] };
}
case 'string':
if (typeof data._comment === 'string') {
return { type: ValueType.StringComment, comment: data._comment };
}
return null;
default:
throw new Error(`Unsupported value type: ${data.type}`);
}
}
default(name) {
var _a, _b;
return (_b = (_a = this.data) === null || _a === void 0 ? void 0 : _a.Value[name]) === null || _b === void 0 ? void 0 : _b.default;
}
enumValue(key, name) {
var _a;
if (((_a = this.value(key)) === null || _a === void 0 ? void 0 : _a.type) !== ValueType.Enum) {
return null;
}
const options = this.value(key).options;
// invert them pa
const optionsInv = ((obj) => {
const ret = {};
Object.keys(obj).forEach(key => {
ret[obj[key]] = key;
});
return ret;
})(options);
return optionsInv[name];
}
enumName(key, value) {
var _a;
if (((_a = this.value(key)) === null || _a === void 0 ? void 0 : _a.type) !== ValueType.Enum) {
return null;
}
const options = this.value(key).options;
if (!(value in options)) {
return null;
}
return options[value];
}
monitoringValueMapping(key) {
if (this.data.Value && this.value(key)) {
return this.value(key).options;
}
if (typeof this.monitoringValue !== 'object' || !(key in this.monitoringValue)) {
return null;
}
return this.monitoringValue[key].valueMapping || null;
}
lookupMonitorValue(key, name, default_value = null) {
var _a;
if (this.data.Value) {
return this.enumName(key, name) || default_value;
}
if (!this.monitoringValueMapping(key) || !(name in this.monitoringValueMapping(key))) {
return default_value;
}
return ((_a = this.monitoringValueMapping(key)[name]) === null || _a === void 0 ? void 0 : _a.label) || default_value || null;
}
lookupMonitorName(key, label) {
if (this.data.Value) {
return this.enumValue(key, label);
}
if (!(key in this.monitoringValue)) {
return null;
}
function getKeyByValue(obj, value) {
return Object.keys(obj).find(key => obj[key].label === value);
}
return getKeyByValue(this.monitoringValue[key].valueMapping, label) || null;
}
decodeMonitor(data) {
var _a, _b;
if (((_a = this.data.Monitoring) === null || _a === void 0 ? void 0 : _a.type) === 'BINARY(BYTE)') {
return this.decodeMonitorBinary(data);
}
else if (((_b = this.data.Monitoring) === null || _b === void 0 ? void 0 : _b.type) === 'BINARY(HEX)') {
return this.decodeMonitorBinary(data, 16);
}
try {
return JSON.parse(data.toString());
}
catch (err) {
return data;
}
}
decodeMonitorBinary(data, length = 8) {
const decoded = {};
for (const item of this.data.Monitoring.protocol) {
const key = item.value;
let value = 0;
for (let i = item.startByte; i < item.startByte + item.length; i++) {
const v = data[i];
value = (value << length) + v;
decoded[key] = isNaN(value) ? null : String(value);
}
}
return decoded;
}
}
exports.DeviceModel = DeviceModel;
//# sourceMappingURL=DeviceModel.js.map