UNPKG

node-red-contrib-smartnora

Version:

Google Smart Home integration via Smart Nora https://smart-nora.eu/

113 lines (112 loc) 4.32 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getSafeUpdate = getSafeUpdate; const skipRoundingStatePaths = new Set([ 'color.spectrumHsv.hue', 'color.spectrumHsv.saturation', 'color.spectrumHsv.value', ]); const roundTo = new Map([ ['thermostatHumidityAmbient', 1], ['humidityAmbientPercent', 1], ['currentFanSpeedPercent', 1], ]); const keepPathsIfSameValue = [ /^openState\.\d+\.openDirection$/, /^currentSensorStateData\.\d+\.name$/, /^(?:capacityRemaining|capacityUntilFull)\..*$/, ]; const arrayItemKeyMap = new Map([ ['openState', 'openDirection'], ['currentSensorStateData', 'name'], ]); function getSafeUpdate({ update, currentState, safeUpdateObject, isValid, mapping, path = 'msg.payload.', statePath, warn, }) { var _a, _b, _c; for (const [key, v] of Object.entries(update)) { if (typeof key !== 'string') { continue; } if (typeof v === 'undefined') { continue; } let updateValue = v; const updateKey = (_b = (_a = mapping === null || mapping === void 0 ? void 0 : mapping.find(m => m.from === key)) === null || _a === void 0 ? void 0 : _a.to) !== null && _b !== void 0 ? _b : key; const currentStatePath = statePath ? `${statePath}.${String(updateKey)}` : String(updateKey); let previousValue; const keyName = statePath && arrayItemKeyMap.get(statePath); if (keyName && Array.isArray(currentState)) { const keyValue = v[keyName]; previousValue = currentState.find(pv => pv[keyName] === keyValue); if (!previousValue) { warn === null || warn === void 0 ? void 0 : warn(`${path}${key}.${keyName}[${keyValue}]`); continue; } } else { previousValue = currentState[updateKey]; } if (typeof previousValue !== typeof updateValue) { if (typeof previousValue === 'number') { updateValue = +updateValue; } if (typeof previousValue === 'boolean') { updateValue = !!updateValue; } } if (typeof updateValue === 'number') { const skipRoundingNumbers = skipRoundingStatePaths.has(currentStatePath); if (!skipRoundingNumbers) { const roundToDigits = (_c = roundTo.get(currentStatePath)) !== null && _c !== void 0 ? _c : 10; updateValue = Math.round(updateValue * roundToDigits) / roundToDigits; } } if (typeof updateValue === 'object' && typeof previousValue === 'object') { const updateChild = Array.isArray(updateValue) ? [] : {}; const remove = append(safeUpdateObject, updateKey, updateChild); getSafeUpdate({ update: updateValue, currentState: previousValue, safeUpdateObject: updateChild, isValid, mapping, path: `${path}${key}.`, statePath: currentStatePath, warn, }); remove(); updateValue = updateChild; } const skipRemove = keepPathsIfSameValue.some(t => t.test(currentStatePath)); if (!skipRemove && updateValue === previousValue) { updateValue = undefined; } if (statePath && updateValue && arrayItemKeyMap.has(statePath) && Object.keys(updateValue).length === 1) { updateValue = undefined; } if (Array.isArray(updateValue) && updateValue.length === 0) { updateValue = undefined; } if (updateValue !== undefined) { const remove = append(safeUpdateObject, updateKey, updateValue); if (!isValid()) { remove(); warn === null || warn === void 0 ? void 0 : warn(`${path}${key}`); } } } } function append(parent, key, child) { if (Array.isArray(parent)) { parent.push(child); return () => { const index = parent.indexOf(child); parent.splice(index, 1); }; } else { parent[key] = child; return () => { delete parent[key]; }; } }