My story:
I have a zoo of actors and sensors for Illumination at home. Lamps controlled through homematic actors, Lightify and Tradfri ones. Sensors (switches) from homematic traditional and IP with motion detection and without.
When I started it was really frustrating, pressing the switch sometime gave result sometime not, sometime it was just delayed. There was no clear picture what factor influenced this behaviour. pressing the switch too fast gave also unexpected results.
Expectation:
Certain rules can execute silent in the background and nobody cares about how real-time they are fired.
Others like pressing a wall switch and expecting the light to come on immediately, pressing again and switching it off, holding the switch down to dim, or what ever is programmed.
I have gone through a learning curve and want to summarize my experience and findings here in this thread
Topics I will touch:
- Switch initial state NULL
- Switch Channels v.s. Item
- Thread Pool
- Java Memory Management
- Rule Compilation
- Visual Studio Code
- Sample Code
Switch initial state NULL
I had my rules defined this way
rule "LivingRoom Toggle Light"
when
Item switchXY changed from OFF to ON
then
.......
end
This resulted in the situation that when OH was rebooted the 1st pressing was ignored, because switch state was initially not UNDEF or NULL, going from NULL/UNDEF to ON. I have persistence enabled, though when rebooting this was the last value which was persisted .
My behaviour was then to once again and again… resulting weird things.
I fixed this after analysing the log.
Switch Channel v.s. Item
What I have seen is that when I pressed the switch in sequence too fast, expecting on/off of lamp I had to wait certain time between each step.
The reason was that the item had to go through states OFF-ON-OFF and this takes some time.
Some Things generate channel messages for particular messages. These channel messages come more then less real-time. You can verify in the log messages if this particular channel generates such
my particular wall mount switches did and I changed the rules to
rule "LivingRoom Toggle Light"
when
Channel "homematic:HM-Sen-MDIR-WM55:3014f711a0001f58a992fb22:4711:1#PRESS" triggered SHORT
then
......
end
The channel trigger PRESS has also the values LONG, CONT, LONG_RELEASE, which can be used for dimming rules
Thread Pool
I have increased the thread pool to a higher value
editing /etc/openhab2/service/runtime.cfg and adding line
org.eclipse.smarthome.threadpool:RuleEngine=20
This might give some relieve, though programming the rules the right way should be a better way to go, e.g using timers instead sleeps.
Java Memory Management
I am running OH on a RPI3, memory is some sort short, in order to give the max to OH edit /etc/default/openhab2 and add
EXTRA_JAVA_OPTS="-Xms400m -Xmx650m"
This gives min and max memory of 650 MB which is 2/3 of total , figures differ for other platforms, 2/3 could be a rule if OH is the only app running.
Rule Compilation
I have witnessed that when I reboot the OH, just edit a rules file or after some period of time, the execution of an action is delayed by some seconds (5-10). The reason is that a rules files gets compiled just in time. Just in time mean when the first rule needs to be executed. That means that the rules file is just pre-parsed at boot/save for the when clause, the actual compilation and loading in memory happens when needed. That might be fine for memory management, for the real-time execution it’s a no go.
As a result I added in each rules file a almost empty rule triggered by system started event
rule "Initiate 4711.rules"
when
System started
// or Time cron " 0 0/1 * 1/1 * ? *"
hen
logInfo("Initiate 4711.rules", "finished")
end
the good thing is that the system started event gets fired at boot time (multiple time !?) but also when a rules file is saved, and the best, just for that particular file saved (other rules files are not triggering)
I did not implement yet, but as an idea a cron statement additionally to system started could keep the rules file in memory. Not sure if there would be a side effect of flooding the thread pool if at once to many refreshes start.
Visual Studio Code
I love Visual Studio Code, but when run, it’s killer for OH performance. Seen that it even stops some processes when existed (workaround should be there already). I have witnessed that when I had a VSC session, during but also after one, rules got really unresponsive. That might be because the language server consumes much memory and rules are recycled, I do not but I also for the moment do not care.
I have created on a other server (rock64, RPI3+ should be fine too) a shadow OH instance
From the production node I exported by NFS
/etc/openhab2 veveohab-vss(rw,sync,no_subtree_check,all_squash)
/var/lib/openhab2/jsondb veveohab-vss(ro,sync,no_subtree_check,all_squash)
and mounted to the same folders in the shadow node
veveohab-pro:/etc/openhab2 /etc/openhab2 nfs rw 0 0
veveohab-pro:/var/lib/openhab2/jsondb /var/lib/openhab2/jsondb nfs ro 0 0
I use NFS, samba should fine too, instruction on details how to can be found on the web.
The VSC now I point to the config directory of the production as openhab server (language server) I set the shadow one. The syntax check is not faster, though I do not care as long it does not affect the production.
There are issues with new added item in items file, these are not seen by the shadow node server and restart of OH-shaddow is needed (have find out how fix that)
Sample Code - Lambdas for Light Control
I have created following lambdas
val dimmLight= [ GenericItem dimLampItem |
try{
sendCommand(dimLampItem, (dimLampItem.state as Number + 5).toString)
} catch(Exception e) {
sendCommand(dimLamItem, OFF)
}
dimLamItem.state.toString
]
val toggleLight= [ GenericItem dimLampItem, GenericItem dimLampItemColor |
try{
if ( dimLampItem.state == 0) {
if (isBedTime.state == ON)
sendCommand(dimLampItem, "5")
else
sendCommand(dimLampItem, "100")
if (dimLampItemColor !== null)
sendCommand(dimLampItemColor, "2500")
}
else
{sendCommand(dimLampItem, OFF)}
} catch(Exception e) {
sendCommand(dimLampItem, OFF)
}
dimLampItem.state.toString
]
val motionToggleLight= [ GenericItem motionSensor, GenericItem motionSensorIlum, GenericItem dimLampItem |
try{
if (isBedTime.state == OFF) {
if ( motionSensor.state == ON && motionSensorIlum.state < 50) {
if (motionSensorIlum.state < 20) sendCommand(dimLampItem, "5") else sendCommand(dimLampItem, "100")
}
else {
sendCommand(dimLampItem, OFF)
}
}
} catch(Exception e) {
sendCommand(dimLampItem, OFF)
}
dimLampItem.state.toString
]
sample rules
rule "StairsHallway motion light "
when
Item g_TreppeGangObenMotion changed
then
motionToggleLight.apply(g_TreppeGangObenMotion, g_TreppeGangObenMotionBrightness, TreppeGangOGLicht_1LEVEL)
end
rule "StairsHallway dimm light"
when
Channel "homematic:HM-Sen-MDIR-WM55:3014f711a0001f58a992fb22:4711:1#PRESS" triggered SHORT or
Channel "homematic:HM-Sen-MDIR-WM55:3014f711a0001f58a992fb22:4711:2#PRESS" triggered SHORT or
Channel "homematic:HM-Sen-MDIR-WM55:3014f711a0001f58a992fb22:4711:1#PRESS" triggered SHORT or
Channel "homematic:HM-Sen-MDIR-WM55:3014f711a0001f58a992fb22:4711:2#PRESS" triggered SHORT or
Channel "homematic:HM-Sen-MDIR-WM55:3014f711a0001f58a992fb22:4711:1#PRESS" triggered SHORT or
Channel "homematic:HM-Sen-MDIR-WM55:3014f711a0001f58a992fb22:4711:2#PRESS" triggered SHORT
then
toggleLight.apply(TreppeGangOGLicht_1LEVEL, null)
end
rule "StairsHallway toggle light"
when
Channel "homematic:HM-Sen-MDIR-WM55:3014f711a0001f58a992fb22:4711:1#PRESS" triggered CONT or
Channel "homematic:HM-Sen-MDIR-WM55:3014f711a0001f58a992fb22:4711:2#PRESS" triggered CONT or
Channel "homematic:HM-Sen-MDIR-WM55:3014f711a0001f58a992fb22:4711:1#PRESS" triggered CONT or
Channel "homematic:HM-Sen-MDIR-WM55:3014f711a0001f58a992fb22:4711:2#PRESS" triggered CONT or
Channel "homematic:HM-Sen-MDIR-WM55:3014f711a0001f58a992fb22:4711:1#PRESS" triggered CONT or
Channel "homematic:HM-Sen-MDIR-WM55:3014f711a0001f58a992fb22:4711:2#PRESS" triggered CONT
then
dimmLight.apply(TreppeGangOGLicht_1LEVEL)
end
isBedTime is an Item which is set when going to bed, night time.
Toggle, dim and motion light works well. The timer for motion light is managed by the homematic motion detection devices.