node-red-contrib-vib-smart-boiler
Version:
Smart boiler node to control multiple thermostat
234 lines (208 loc) • 11.4 kB
HTML
<script type="text/javascript">
// Terminal command node-red -v -D logging.console.level=trace
RED.nodes.registerType('smart-boiler',{
category: 'vib-node',
color: '#bdeeff',
defaults: {
name: {value:""},
topic:{value:""},
mqttSettings: {value: "", type: "smart-boiler-settings"},
boilerTempTopic:{value:""},
boilerSpTopic:{value:""},
boilerLeadingDeviceTopic:{value:""},
boilerLeadingDeviceIdTopic:{value:""},
extTempEntity:{value:""},
extTempBoilerTopic:{value:""},
boilerCHeatingSwTopic:{value:""},
mqttUpdates:{value:false},
debugInfo:{value:false},
boilerSecurity:{value:false},
triggerMode:{value:"triggerMode.statechange.startup",required: true},
cycleDuration: {value:60,required: true,validate:function(v) {
if (isNaN(v)){
return false;
}
if (v<0 || v> 600){
return false;
}
return true;
}},
outputUpdates:{value:true},
defaultSp:{value:5,required: true, validate:function(v) {
if (isNaN(v)){
return false;
}
if (v<0 || v> 35){
//this.warn("overrideSp need to be >0 et <= 35")
return false;
}
return true;
}},
defaultTemp:{value:10,required: true, validate:function(v) {
if (isNaN(v)){
return false;
}
if (v<0 || v> 35){
//this.warn("overrideSp need to be >0 et <= 35")
return false;
}
return true;
}},
maxDurationSinceLastInput:{value:"5",required: true, validate:function(v) {
if (isNaN(v)){
return false;
}
if (v<0 || v> 120){
//this.warn("overrideSp need to be >0 et <= 35")
return false;
}
return true;
}}
},
inputs:1,
outputs:1,
icon: "font-awesome/fa-fire",
label: function() {
return this.name||"smart-boiler";
},
oneditprepare: function() {
var node = this;
},
oneditsave: function() {
var node = this;
},
oneditresize: function() {
}
});
</script>
<script type="text/html" data-template-name="smart-boiler">
<div class="form-row">
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
<input type="text" title="node & home asssitant device name" id="node-input-name" placeholder="Name">
</div>
<div class="form-row">
<label for="node-input-topic"><i class="fa fa-tasks"></i> Topic</label>
<input type="text" title="msg output topic" id="node-input-topic" placeholder="Topic"></input>
</div>
<div class="form-row">
<label for="node-input-mqttSettings"><i class="fa fa-globe"></i> Mqtt</label>
<input type="text" id="node-input-mqttSettings"></input>
</div>
<div class="form-row">
<label for="node-input-mqttUpdates"><i class="fa fa-tasks"></i> Mqtt updates</label>
<input type="checkbox"title="" id="node-input-mqttUpdates" placeholder="temqtt topicmp"></input>
</div>
<div class="form-row">
<label for="node-input-outputUpdates"><i class="fa fa-tasks"></i> Output updates</label>
<input type="checkbox"title="" id="node-input-outputUpdates" placeholder="temqtt topicmp"></input>
</div>
<div class="form-row">
<label for="node-input-boilerSpTopic"><i class="fa fa-tasks"></i> Set point topic</label>
<input type="text" title="" id="node-input-boilerSpTopic" placeholder="temqtt topicmp"></input>
<label for="node-input-boilerSpTopic"></label>
</div>
<div class="form-row">
<label for="node-input-boilerTempTopic"><i class="fa fa-tasks"></i> Temperature topic</label>
<input type="text" title="" id="node-input-boilerTempTopic" placeholder="mqtt topic"></input>
<label for="node-input-boilerTempTopic"></label>
</div>
<div class="form-row">
<label for="node-input-extTempBoilerTopic"><i class="fa fa-tasks"></i> External temperature topic</label>
<input type="text" title="" id="node-input-extTempBoilerTopic" placeholder="mqtt topic"></input>
<label for="node-input-extTempBoilerTopic"></label>
</div>
<div class="form-row">
<label for="node-input-extTempEntity"><i class="fa fa-tasks"></i> External temperature</label>
<input type="text" title="" id="node-input-extTempEntity" placeholder=""></input>
<label for="node-input-extTempEntity">entity</label>
</div>
<div class="form-row">
<label for="node-input-boilerLeadingDeviceTopic"><i class="fa fa-tasks"></i> Leading device topic</label>
<input type="text" title="" id="node-input-boilerLeadingDeviceTopic" placeholder="mqtt topic"></input>
</div>
<div class="form-row">
<label for="node-input-boilerLeadingDeviceIdTopic"><i class="fa fa-tasks"></i> Leading device Id topic</label>
<input type="text" title="" id="node-input-boilerLeadingDeviceIdTopic" placeholder="mqtt topic"></input>
</div>
<div class="form-row">
<label for="node-input-boilerCHeatingSwTopic"><i class="fa fa-tasks"></i> Boiler Central Heating Sw Topic</label>
<input type="text" title="" id="node-input-boilerCHeatingSwTopic" placeholder="mqtt topic"></input>
</div>
<div class="form-row">
<label style="width:120px !important;" for="node-input-cycleDuration"><i class="fa fa-tasks"></i> Update cycle</label>
<input type="text" id="node-input-cycleDuration" style="width:60px !important; text-align: right;" placeholder="duration"></input>
<label for="node-input-cycleDuration2"></i> s</label>
</div>
<div class="form-row">
<label for="node-input-triggerMode"><i class="fa fa-play"></i> Trigger mode </label>
<select id="node-input-triggerMode">
<option value="triggerMode.statechange">wWhen state changes</option>
<option value="triggerMode.statechange.startup">When state changes + startup</option>
<option value="triggerMode.everyCycle">Every cycle</option>
</select>
</div>
<div class="form-row">
<label style="width:120px !important;" for="node-input-maxDurationSinceLastInput"><i class="fa fa-tasks"></i> Max duration</label>
<input type="text" id="node-input-maxDurationSinceLastInput" style="width:60px !important; text-align: right;" placeholder="duration"></input>
<label for="node-input-maxDurationSinceLastInput" style="width:200px;"> min since last input</label>
</div>
<div class="form-row">
<label for="node-input-boilerSecurity"><i class="fa fa-tasks"></i> Boiler security</label>
<input type="checkbox" title="" id="node-input-boilerSecurity" placeholder=""></input>
</div>
<div class="form-row">
<label style="width:120px !important;" for="node-input-defaultTemp"><i class="fa fa-tasks"></i> Default Temp</label>
<input type="text" id="node-input-defaultTemp" style="width:60px !important; text-align: right;" placeholder="duration"></input>
<label for="node-input-defaultTemp" style="width:200px;"></i> °C</label>
</div>
<div class="form-row">
<label style="width:120px !important;" for="node-input-defaultSp"><i class="fa fa-tasks"></i> Default set point</label>
<input type="text" id="node-input-defaultSp" style="width:60px !important; text-align: right;" placeholder="duration"></input>
<label for="node-input-defaultSp" style="width:200px;"> °C</label>
</div>
<div class="form-row">
<label style="width:120px !important;" for="node-input-debugInfo"><i class="fa fa-tasks"></i> Debug info</label>
<input type="checkbox" title="send debug information to the console" id="node-input-debugInfo" ></input>
</div>
</script>
<script type="text/html" data-help-name="smart-boiler">
<p>this node belongs to a suite of nodes to control heating made by multiple intelligent Valve and a Central Boiler.
The scheduling is done by Smart-Scheduler where multiple schedule and set-point can be defined,
The valve management is done by Smart-Valve where multiple valve can be grouped in one room or group of room.
And finally Smart-Boiler aims to control the boiler and to determine the right temperature and set point seeting according to the multiple valves.
<b>Smart-Boiler</b>
Received input from Smart-Valves and expect message as :
msg.payload with:
- sp for setpoint, int value
- temp for current valve temperature, int value,
- name for valve description, string value,
- id for unique valve identification, int value
ex input message:
msg.payload={ sp:23,temp:20,name:"Valve kitchen", id:1}
Each input received will either create a new entry in the valves stack or update the current entry in the stack.
Smart-Boiler will determined the active valve to be sent to the Boiler, the active valve is determine by valve set point (target temperature) > valve current temperature
and by the highest gap between set point and current temperature.
Exemple :
- Valve A : set point 19°C, current temperature 21 °C => inactive
- Valve B : set point 23°C, current temperature 20 °C, gap is 3 °C => active but not sent to boiler,
- Valve C : set point is 24°C and current temperature is 19°C, gap is 5°C => active and sent to the boiler.
Additionnal functionnal rules:
- If no active valve is found then highest sp of inactive valve is set as a reference to the boiler.
- If no input after max duration (defined in setting), security message is sent to the boiler to avoid endless heating,
Output:
- Can be directly to MQTT (preferred);
- regular output:
msg.payload={ sp:23,temp:20,name:"Valve kitchen", id:1, lastTsUpdate: ISOTIME};
Configuration settings:
MQTT: configuration node to define mqtt server connexion
MQTT updates: when checked, update messages are directly sent to the defined topics
Output updates: when checked, update messages are sent to the regular output,
Set point topic: MQTT set Boiler set point topic
Temperature topic: MQTT set Boiler current temperature topic
Leading Device topic: MQTT Boiler text topic to indicate which valves is driving the heating
Update cycle duration: valve stack evaluation duration cycle
Max Duration since last input: maximum duration before sending security message to the boiler with default values
Default temp: security message is sent with default temp
Default set point: security message is sent with default set point
</p>
</script>