Openremote default configuration suffers the illness of cheap Chinese devices — it forgets almost everything after power on/off cycle. This article describes how to preserve in-memory variables. If you want to save your in memory variables with rules presented here, please follow these guidelines:
- A name of in-memory variable, which should be preserved between restarts, must begin with capital string “GV”, for example “GVRememberThis”;
- This in-memory variable should have command ‘status’;
- Sensor associated with this command should have exactly the same name — in our example “GVRememberThis”;
- The sensor should be of type ‘custom’.
When you follow these guidelines and add following rules in the designer then Openremote controller will miraculously remember all “GV” started in-memory variables. GV stays for Global Variable.
package org.openremote.controller.protocol.preserve;
import java.io.*;
import org.openremote.controller.protocol.Event;
global org.openremote.controller.statuscache.CommandFacade execute;
function void _WriteToFile(String fn, Object o){
String vl = o.toString();
PrintWriter writer = new PrintWriter(fn+".txt", "UTF-8");
try{
writer.println(vl);
} finally {
writer.close();
}
}
function String _ReadFromFile(String fn, String dft){
String result = dft;
try{
BufferedReader fr = new BufferedReader(new InputStreamReader(new FileInputStream(fn+".txt"), "UTF-8"));
try{
result = fr.readLine();
} finally {
fr.close();
}
} catch (IOException e) {
e.printStackTrace();
}
return(result);
}
rule "Store values"
timer(int: 1s)
when
Event($s:source matches "^GV.*", $v:value!="status")
then
_WriteToFile($s, $v);
end
rule "Init values"
salience 100
when
(OR
Event($s:source matches "^GV.*", value=="")
Event($s:source matches "^GV.*", value=="status")
)
then
execute.command($s, _ReadFromFile($s, "-"));
end
You can either use these rules in designer or save it separately in your controller’s subdirectory [path to the controller]/webapps/controller/rules/. The second solution has an advantage that these rules will always be available — even if there are no rules in the designer or rules are with errors. It should be a part of the standard Openremote distribution if you ask me 😉
Hi i want to use your script because it looks very usefull and should indeed be in by default. But i put the script in.
can you just send me a screenshot on how i should create the custom sensor? and how i should create rules for that custom sensor?
just 2 lines and a screenshot and i will get the picture i hope 🙂
I’ll add example screenshots to the post in few days.
problem is that i am using a KNX status command.
that status command i want to use for the custom sensor.
also in the file i see N/A instead of the value.
but i am very sure we can solve this issue. Hope that it works with KNX (which i think is also an in-memory variabele)
thx again for the quick reply. It is because of Guys like you that the opensource community can grow and exist.
You don’t need persistence for a KNX sensor. This technique is applicable only to in-memory virtual commands, which are in fact memory locations which get reset after power-on cycle.
if i now reset my openremote machine, then the openremote will do a lot of read commands to my knx bus. so if i write a 0 to these values he stops reading the values. that is why i want to keep them stored as well.
now each time i reboot i need to write all the values on the bus again.
In this case you need a different solution – initialise values after system reboot. This can be achieved with a rule. Suppose that you want to write ‘0’ 10 seconds after system reboot. The following rule does it:
rule “Init 10s after system start”
timer(int: 10s)
then
execute.command(“KNX write command”, “0”);
end
OK.
that is feasable. But can i directy set the value of a sensor?
for example like this?
rule “Init 10s after system start”
timer(int: 10s)
then
Event(source == “Fasttel relais 3”).setvalue(“off”);
end
Unfortunately, the value of a sensor cannot be set directly unless you have a command which does it. A little misleading is the fact that with in-memory virtual command you can indeed set a value with the same command which is used for reading. However, this is not usually true for other protocols.
package org.openremote.controller.model.event
global org.openremote.controller.statuscache.CommandFacade execute;
global org.openremote.controller.statuscache.SwitchFacade switches;
global org.openremote.controller.statuscache.LevelFacade levels;
import java.util.concurrent.TimeUnit;
import org.openremote.controller.protocol.*;
rule “init” when
timer (int: 10s)
then
execute.command( “voordeur on/off (OFF)” );
end
give me this error:
[ERR 102] Line 9:12 mismatched input ’10’ expecting ‘identifier’ in rule “init” in pattern timer
Please remove “when” from your rule’s definition. Just like in my example above.
no the problem gets even worse.
first of all the action does not work at startup but this is now not the real issue anymore.
the real issue is that if i execute all the commands to write the values to the bus he keeps reading them.
So if openremote writes to the bus he does not listen at the same time to that values.
This seems to be rather a KNX problem and not persistent in-memory virtual commands (in-memory virtual commands are different protocol than KNX). You should describe what you are trying to do at http://www.openremote.org forums, as myself I’m not an expert with KNX.
i have posted here: http://www.openremote.org/display/forums/openremote+updating+knx+values+not+seen+by+openremote
can you also have a quick look if i am not telling stupid things