Hi
Thanks to the work already done by a lot of users, I’ve created a Thermostat rule, that works from a One-Wire slave thermocouple, using a DigiTemp command line and a relay / switch.
The requirement is to keep a water tank within a temperature range, but be able to adjust both the target temperature and the offset.
The offset is there is prevent the heater oscillating too much, once the system has been commissioned and monitored for a few weeks, I doubt the offset will be adjusted, so I will copy the user set value to the system start part of the rule.
(And yes, there is a mechanical thermostat on the tank to prevent it boiling if the rule fails)
The topics that I referenced for the piece are :–
https://docs.openhab.org/configuration/rules-dsl.html
The following rule relies on these items, all confirgured in PaperUI, so I don’t have a .items file to share
Exec Command : DigiTemp, with polling
One-Wire temperature value, as String (Because that’s what it has to be for ExecCommand Output) // This caused a big headache as I had to learn how to change it from a String to a usable number type.
One-Wire command last updated, as date/time
Virtual items:
Target temperature, as Number
Offset value, as Number
A switch item linked to the relay of choice
Optional…
Velbus OLED glass panels have an option to send a text string to the display, so I added that in as a sanity check and to show the tank temperature.
I hope this rule helps someone save a few hours of development.
FYI, I’m not a coder, so I know this could probably be done in a much neater way, but it works, which is good enough for me
You’ll also notice my liberal use of the Say command, which is just my quick way of debugging while standing next to the tank, so that I don’t have to look away at a screen
var int offset = 10
var int target = 25
var int High = 26
var int Low = 23
var int temp = 30
rule "reset thermostat"
when
System started
then
target = 50
offset = 3
temp = 130
OneWire_Thermostat_Offset.sendCommand(3)
OneWire_Thermostat_SetPoint.sendCommand(50)
OneWire_Temperature_Output.sendCommand(120)
say("Hello. This is the One Wire thermostat rule", "voicerss:enGB", "webaudio")
OneWire_Thermostat_Switch.sendCommand(OFF)
end
rule "One-Wire Thermostat"
when
Item OneWire_Temperature_LastExecution changed or Item OneWire_Thermostat_Offset changed or Item OneWire_Thermostat_SetPoint changed
then
// say("Updated", "voicerss:enGB", "webaudio")
offset = (OneWire_Thermostat_Offset.state as Number)
target = (OneWire_Thermostat_SetPoint.state as Number)
temp = Float::parseFloat(String::format("%s",OneWire_Temperature_Output.state))
//say("Offset at " + offset + "Target at " + target + "Temperature at " + temp, "voicerss:enGB", "webaudio")
High = (target as DecimalType) + (offset as DecimalType)
Low = (target as DecimalType) - (offset as DecimalType)
//say("Offset at " + offset + "Target at " + target + "Temperature at " + temp +"High at " + High + "Low at " + Low, "voicerss:enGB", "webaudio")
if ( (temp as Number) < (Low as Number) ){
OneWire_Thermostat_Switch.sendCommand(ON)
Cabin_Memo_Text.sendCommand("Temp is "+ temp + "Target is " + target + " " + "Heat is " + OneWire_Thermostat_Switch.state)
say("Temp is"+ temp + "Target is " + target + " " + "Heat is " +OneWire_Thermostat_Switch.state, "voicerss:enGB", "webaudio")
}
else if( (temp as Number) > (High as Number)){
OneWire_Thermostat_Switch.sendCommand(OFF)
Cabin_Memo_Text.sendCommand("Temp is "+ temp + "Target is " + target + " " + "Heat is " + OneWire_Thermostat_Switch.state)
say("Temp is"+ temp + "Target is" + target + " " + "Heat is " +OneWire_Thermostat_Switch.state, "voicerss:enGB", "webaudio")
}
end