UNPKG

thing-it-device-enocean-ip

Version:

[thing-it-node] Device Plugin for EnOcean IP products.

471 lines (438 loc) 15.7 kB
module.exports = { metadata: { plugin: "heatingSystem", label: "Micropelt to Thermokon Heating System", role: "actor", family: "heatingSystem", deviceTypes: ["enocean-ip/gateway"], tangible: false, services: [{ label: "Set Temperature", id: "setTemperature" }, { label: "Close Valve", id: "closeValve" }], events: [{ label:"Low Battery", id: "lowBattery" }, { label: 'Button A0 Pressed', id: 'buttonA0Pressed' }, { label: 'Button A0 Released', id: 'buttonA0Released' }, { label: 'Button AI Pressed', id: 'buttonAIPressed' }, { label: 'Button AI Released', id: 'buttonAIReleased' }, { label: 'Button B0 Pressed', id: 'buttonB0Pressed' }, { label: 'Button B0 Released', id: 'buttonB0Released' }, { label: 'Button BI Pressed', id: 'buttonBIPressed' }, { label: 'Button BI Released', id: 'buttonBIReleased' }, { label: 'Set', id: 'set' }, { label: 'Valve Closed', id: 'valveClosed' }], state: [{ label: "Valve", id: "valve", type: { id: "decimal" } }, { label: "Battery Low", id: "batteryLow", type: { id: "boolean" } }, { label: "Actuator Obstructed", id: "actuatorObstructed", type: { id: "boolean" } }, { label: "Temperature", id: "temperature", type: { id: "decimal" } }, { label: "Temperature Setpoint", id: "setpoint", type: { id: "decimal" } }, { label: 'Last Button Operation', id: 'lastButtonOperation' }, { label: "Heat Active", id:"heatActive", type: { id: "boolean" } }, { label: "Cool Active", id: "coolActive", type: { id: "boolean" } }, { label: "Window is Open", id: "window", type: { id: "boolean" } }], configuration: [{ label: "Micropelt Device ID", id: "micropeltDeviceId", type: { id: "string" } }, { label: "Thermokon Device ID", id: "thermokonDeviceId", type: { id: "string" } }, { label: "Button Device ID", id: "buttonDeviceId", type: { id: "string" } }, { label: "Temperature Base Point", id:"temperatureBasePoint", type: { id: "decimal" }, defaultValue: 22.00 }, { label: "Set Point Scale", id: "setPointScale", type:{ id: "decimal" }, defaultValue: 1.0 }] }, create: function () { return new HeatingSystem(); } }; var q = require('q'); var _ = require('lodash'); /** * */ function HeatingSystem() { /** * */ HeatingSystem.prototype.start = function () { var deferred = q.defer(); this.state = {window: false}; if (this.isSimulated()) { this.publishStateChange(); } else { //Set Thermokon Basepoint and Setpoint values if(this.configuration.setPointScale < 1.0 || this.configuration.setPointScale > 10.0){ this.logInfo("Set Point Scale value invalid. Setting to default."); this.configuration.setPointScale = 1; } if(this.configuration.temperatureBasePoint < 15 || this.configuration.temperatureBasePoint > 30){ this.logInfo("Temperature Base Point value invalid. Setting to default."); this.configuration.temperatureBasePoint = 22; } //Retrieve Thermokon Current State this.device.adapter.getDeviceState(this.configuration.thermokonDeviceId).then(function(body){ let tempDiff; for(let n in body.state.functions){ //console.log(body.state.functions[n]); if (body.state.functions[n].key === "temperature") { this.state.temperature = body.state.functions[n].value; //console.log(this.state.temperature); } } tempDiff = this.state.temperature - this.state.setpoint; if (tempDiff > 0) { this.state.coolActive = true; this.state.heatActive = false; } else if (tempDiff < 0) { this.state.coolActive = false; this.state.heatActive = true; } else { this.state.coolActive = false; this.state.heatActive = false; } this.publishStateChange(); console.log(this.state); }.bind(this), function (err){ console.log(err) }.bind(this)); // Retrieve Radiator current state this.device.adapter.getDeviceState(this.configuration.micropeltDeviceId).then(function(body){ for(let n in body.state.functions){ console.log(body.state.functions[n]); if(body.state.functions[n].key === "valve"){ this.state.valve = body.state.functions[n].value; } if(body.state.functions[n].key === "batteryLow"){ if(body.state.functions[n].value === "true"){ this.state.batteryLow = true; this.publishEvent("lowBattery", {}); } else this.state.batteryLow = false; } if(body.state.functions[n].key === "actuatorObstructed"){ if(body.state.functions[n].value === "true"){ this.state.actuatorObstructed = true; } else this.state.actuatorObstructed = false; } } this.publishStateChange(); console.log(this.state); }.bind(this), function (err){ console.log(err) }.bind(this)); //Retrieve incoming state changes this.device.adapter.listeners.push(telegram => { // Updates the state of radiator valve if (telegram.deviceId === this.configuration.micropeltDeviceId) { console.log(telegram.functions); for(let n in telegram.functions){ if(telegram.functions[n].key === "valve"){ this.state.valve = telegram.functions[n].value; } if(telegram.functions[n].key === "batteryLow"){ if(telegram.functions[n].value === "true"){ this.state.batteryLow = true; this.publishEvent("lowBattery", {}); } else this.state.batteryLow = false; } if(telegram.functions[n].key === "actuatorObstructed"){ if(telegram.functions[n].value === "true"){ this.state.actuatorObstructed = true; } else this.state.actuatorObstructed = false; } } this.publishStateChange(); } // Updates the state of the thermostat if(telegram.deviceId === this.configuration.thermokonDeviceId) { for (let n in telegram.functions) { let tempDiff; if (telegram.functions[n].key === "temperature") { this.state.temperature = telegram.functions[n].value; } if (telegram.functions[n].key === "setpoint") { this.state.setpoint = setpointConversion(telegram.functions[n].value, this.configuration.temperatureBasePoint, this.configuration.setPointScale); } //this.publishStateChange(); tempDiff = this.state.temperature - this.state.setpoint; if (tempDiff > 0) { this.state.coolActive = true; this.state.heatActive = false; } else if (tempDiff < 0){ this.state.coolActive = false; this.state.heatActive = true; } else { this.state.coolActive = false; this.state.heatActive = false; } } if(!this.state.window || this.state.window === false) { this.setTemperature(this.state.setpoint, this.state.temperature); } this.publishStateChange(); } // Updates the state of the light switches if(telegram.deviceId === this.configuration.buttonDeviceId){ for (let n in telegram.functions) { if (telegram.functions[n].key.indexOf('button') === 0) { this.publishEvent(telegram.functions[n].key + capitalizeFirstLetter(telegram.functions[n].value), {}); this.state.lastButtonOperation = capitalizeFirstLetter(telegram.functions[n].key) + ' ' + capitalizeFirstLetter(telegram.functions[n].value); //this.publishStateChange(); } } this.publishStateChange(); } }); deferred.resolve(); } this.logInfo("Actor Started"); return deferred.promise; }; /** * */ HeatingSystem.prototype.getState = function () { return this.state; }; /** * */ HeatingSystem.prototype.setState = function (state) { let updatedState = this.updateState(state); this.state = updatedState; this.publishStateChange(); this.publishEvent('set', {}); }; /** * */ HeatingSystem.prototype.stop = function () { if (this.isSimulated()) { if (this.interval) { clearInterval(this.interval); } } }; /** * Sends the Temperature values to the radiator valve */ HeatingSystem.prototype.setTemperature = function (setPointTemperature, currentTemperature) { if(setPointTemperature === undefined || currentTemperature === undefined) return; let deltaTemperature = currentTemperature - setPointTemperature; let functions = []; if(deltaTemperature !== 0){ this.logInfo("Setting Temperature to: ", setPointTemperature); functions = [{"key": "temperature", "value": currentTemperature},{"key": "temperatureSetpoint", "value": setPointTemperature}]; this.device.adapter.setDeviceState(this.configuration.micropeltDeviceId, functions); console.log('######## Temperature has been set to: ', setPointTemperature, ' ########') } } /** * Closes the valve of the radiator */ HeatingSystem.prototype.closeValve = function () { this.device.adapter.setDeviceState(this.configuration.micropeltDeviceId,[{"key": "valve", "value": 0}]) this.publishEvent('valveClosed', {}); } /** * updates this.state so that the setState function does not clear other state values */ HeatingSystem.prototype.updateState = function(state){ if (_.isObjectLike(state)) { if (_.isNumber(state.setpoint) && state.setpoint !== this.state.setpoint) { this.state.setpoint = state.setpoint; if(!this.state.window || state.window === false) { this.setTemperature(this.state.setpoint, this.state.temperature); } } if(_.isBoolean(state.window) && state.window !== this.state.window) { this.state.window = state.window; if (this.state.window || this.state.window === true){ this.closeValve(); } else{ this.setTemperature(this.state.setpoint, this.state.temperature); } } } return this.state; } } /** * Using the bit value given by Theromokon Room Controller, determines the setpoint temperature */ function setpointConversion(value, baseTemp, scale){ let setVar; let setPoint; switch (value) { case 0.00: setVar = -3.0; setPoint = baseTemp + scale*setVar; break; case 21.00: setVar = -2.5; setPoint = baseTemp + scale*setVar; break; case 42.00: setVar = -2.0; setPoint = baseTemp + scale*setVar; break; case 63.00: setVar = -1.5; setPoint = baseTemp + scale*setVar; break; case 85.00: setVar = -1.0; setPoint = baseTemp + scale*setVar; break; case 106.00: setVar = -0.5; setPoint = baseTemp + scale*setVar; break; case 128.00: setVar = 0.0; setPoint = baseTemp + scale*setVar; break; case 149.00: setVar = 0.5; setPoint = baseTemp + scale*setVar; break; case 171.00: setVar = 1.0; setPoint = baseTemp + scale*setVar; break; case 192.00: setVar = 1.5; setPoint = baseTemp + scale*setVar; break; case 213.00: setVar = 2.0; setPoint = baseTemp + scale*setVar; break; case 234.00: setVar = 2.5; setPoint = baseTemp + scale*setVar; break; case 255.00: setVar = 3.0; setPoint = baseTemp + scale*setVar; break; } if(setPoint < 15.00){ setPoint = 15.00; return setPoint; } else if(setPoint > 30.00){ setPoint = 30.00; return setPoint; } else{ return setPoint; } } /** * Caplitalizes the fist letter in a string */ function capitalizeFirstLetter(string) { return string.charAt(0).toUpperCase() + string.slice(1); }