node-red-contrib-smartnora
Version:
Google Smart Home integration via Smart Nora https://smart-nora.eu/
195 lines (194 loc) • 9.88 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const nora_firebase_common_1 = require("@andrei-tatar/nora-firebase-common");
const util_1 = require("./util");
module.exports = function (RED) {
RED.nodes.registerType('noraf-sensor', function (config) {
var _a, _b, _c, _d, _e, _f;
RED.nodes.createNode(this, config);
const noraConfig = RED.nodes.getNode(config.nora);
if (!(noraConfig === null || noraConfig === void 0 ? void 0 : noraConfig.valid)) {
return;
}
const deviceConfig = {
type: 'action.devices.types.SENSOR',
traits: [],
name: {
name: config.devicename,
},
roomHint: config.roomhint,
willReportState: true,
state: {
online: true,
},
noraSpecific: {},
attributes: {},
};
if (config.temperature) {
deviceConfig.traits.push('action.devices.traits.TemperatureControl');
if ((0, nora_firebase_common_1.isTemperatureControl)(deviceConfig)) {
const temperatureControlAttributes = {
queryOnlyTemperatureControl: true,
temperatureUnitForUX: config.unit,
temperatureRange: {
minThresholdCelsius: -100,
maxThresholdCelsius: 100,
},
};
deviceConfig.attributes = Object.assign(Object.assign({}, deviceConfig.attributes), temperatureControlAttributes);
}
}
if (config.humidity) {
deviceConfig.traits.push('action.devices.traits.HumiditySetting');
if ((0, nora_firebase_common_1.isHumiditySetting)(deviceConfig)) {
const humiditySettingAttributes = {
queryOnlyHumiditySetting: true,
};
deviceConfig.attributes = Object.assign(Object.assign({}, deviceConfig.attributes), humiditySettingAttributes);
}
}
if (config.sensorSupport) {
const NUMERIC = [
['PARTS_PER_MILLION', ['CarbonMonoxideLevel', 'SmokeLevel', 'CarbonDioxideLevel']],
['AQI', ['AirQuality']],
['MICROGRAMS_PER_CUBIC_METER', ['PM2.5', 'PM10']],
['PARTS_PER_MILLION', ['VolatileOrganicCompounds']],
['PERCENTAGE', ['FilterLifeTime', 'PreFilterLifeTime', 'HEPAFilterLifeTime', 'Max2FilterLifeTime']],
];
deviceConfig.traits.push('action.devices.traits.SensorState');
if ((0, nora_firebase_common_1.isSensorState)(deviceConfig)) {
const numericType = (_a = NUMERIC.find(n => n[1].includes(config.sensorType))) === null || _a === void 0 ? void 0 : _a[0];
const numericSupport = numericType && (config.sensorNumeric || !((_b = config.sensorStates) === null || _b === void 0 ? void 0 : _b.length));
const typeSupportsNotifications = nora_firebase_common_1.SENSOR_TYPE_NOTIFICATION_SUPPORT.includes(config.sensorType);
deviceConfig.noraSpecific.sensorCapabilitiesThatReportNotifications =
typeSupportsNotifications && ((_c = config.sensorStatesThatNotify) === null || _c === void 0 ? void 0 : _c.length)
? config.sensorStatesThatNotify
: undefined;
deviceConfig.notificationSupportedByAgent =
!!((_d = deviceConfig.noraSpecific.sensorCapabilitiesThatReportNotifications) === null || _d === void 0 ? void 0 : _d.length);
deviceConfig.attributes.sensorStatesSupported = [Object.assign(Object.assign({ name: config.sensorType }, (((_e = config.sensorStates) === null || _e === void 0 ? void 0 : _e.length) ? {
descriptiveCapabilities: {
availableStates: config.sensorStates,
},
} : {})), (numericSupport ? {
numericCapabilities: {
rawValueUnit: numericType,
},
} : {}))];
deviceConfig.state.currentSensorStateData = [Object.assign(Object.assign({ name: config.sensorType }, (((_f = config.sensorStates) === null || _f === void 0 ? void 0 : _f.length) ? {
currentSensorState: 'unknown',
} : {})), (numericSupport ? {
rawValue: 0,
} : {}))];
}
}
if (config.openCloseSupport) {
deviceConfig.traits.push('action.devices.traits.OpenClose');
if ((0, nora_firebase_common_1.isOpenClose)(deviceConfig)) {
deviceConfig.attributes.queryOnlyOpenClose = true;
deviceConfig.attributes.discreteOnlyOpenClose = !!config.openCloseDiscrete;
const openCloseState = {
openPercent: 0,
};
deviceConfig.state = Object.assign(Object.assign({}, deviceConfig.state), openCloseState);
}
}
if (config.onOffSupport) {
deviceConfig.traits.push('action.devices.traits.OnOff');
if ((0, nora_firebase_common_1.isOnOff)(deviceConfig)) {
deviceConfig.attributes.queryOnlyOnOff = true;
deviceConfig.state.on = false;
}
}
(0, util_1.registerNoraDevice)(this, RED, config, {
deviceConfig,
updateStatus: ({ state, update }) => {
const statuses = [];
if (isOnOffState(state)) {
statuses.push(state.on ? 'on' : 'off');
}
if (isOpenCloseState(state) && 'openPercent' in state) {
statuses.push(config.openCloseDiscrete
? (state.openPercent ? 'opened' : 'closed')
: `open:${state.openPercent}%`);
}
if (isTemperatureState(state)) {
statuses.push(`T:${state.temperatureAmbientCelsius}C`);
}
if (isHumidityState(state)) {
statuses.push(`H:${state.humidityAmbientPercent}%`);
}
if (isSensorState(state)) {
const sensorState = state.currentSensorStateData[0];
if ('currentSensorState' in sensorState &&
sensorState.currentSensorState &&
sensorState.currentSensorState !== 'unknown') {
statuses.push(sensorState.currentSensorState);
}
if ('rawValue' in sensorState && typeof sensorState.rawValue === 'number') {
statuses.push(`S:${sensorState.rawValue}`);
}
}
update(statuses.join(' '));
},
handleNodeInput: async ({ msg, updateState }) => {
var _a;
if (typeof msg.payload !== 'object') {
return;
}
const update = Object.assign({}, msg.payload);
if ((0, nora_firebase_common_1.isSensorState)(deviceConfig)) {
const stateConfig = deviceConfig.attributes.sensorStatesSupported[0];
const sensorState = {
name: config.sensorType,
};
if ('state' in update &&
'descriptiveCapabilities' in stateConfig &&
((_a = stateConfig.descriptiveCapabilities) === null || _a === void 0 ? void 0 : _a.availableStates.includes(update.state))) {
sensorState.currentSensorState = update.state;
delete update.state;
update.currentSensorStateData = [sensorState];
}
if ('value' in update) {
sensorState.rawValue = update.value;
delete update.value;
update.currentSensorStateData = [sensorState];
}
}
if (config.openCloseSupport) {
if (typeof update.open === 'boolean') {
update.open = update.open ? 100 : 0;
}
if (config.openCloseDiscrete) {
update.open = +update.open ? 100 : 0;
}
}
await updateState(update, [{
from: 'open',
to: 'openPercent',
}, {
from: 'temperature',
to: 'temperatureAmbientCelsius',
}, {
from: 'humidity',
to: 'humidityAmbientPercent',
}]);
},
});
function isHumidityState(state) {
return (0, nora_firebase_common_1.isHumiditySetting)(deviceConfig) && 'humidityAmbientPercent' in state;
}
function isTemperatureState(state) {
return (0, nora_firebase_common_1.isTemperatureControl)(deviceConfig) && 'temperatureAmbientCelsius' in state;
}
function isSensorState(state) {
return (0, nora_firebase_common_1.isSensorState)(deviceConfig) && 'currentSensorStateData' in state;
}
function isOpenCloseState(state) {
return (0, nora_firebase_common_1.isOpenClose)(deviceConfig) && 'openPercent' in state;
}
function isOnOffState(state) {
return (0, nora_firebase_common_1.isOnOff)(deviceConfig) && 'on' in state;
}
});
};