I am trying to access the actions of the astro binding in jruby, and seem to fail in spectacular fashion.
My PoC code:
require 'openhab'
astroSun = actions("astro", "astro:sun:local")
rule 'Testing actions' do
every :minute
run do
astroTime = astroSun.getEventTime("SUN_SET")
logger.info("We have some astro time: #{astroTime.to_s}")
end
end
I would expect this to log the time that the sun will set today.
It however logs nothing, and starts loading the CPU, until the point openHAB crashes.
I don’t use jRuby but often in the other languages, the rules file can be parsed before the Thing is online and available. If that occurs, astroTime will be null (or what ever they call it in Ruby). You should pull the action inside the rule just before you use it.
require 'openhab'
rule 'Testing actions' do
every :minute
run do
astro_time = things['astro:sun:local'].getEventTime('SUN_SET', nil, nil)
logger.info("We have some astro time: #{astro_time}")
end
end
Now if I replace things['astro:sun:local'] with actions('astro', 'astro:sun:local'), as I would have deducted from the documentation, my instance explodes again.
2022-07-26 12:25:31.366 [WARN ] [.util.thread.strategy.EatWhatYouKill] -
java.lang.OutOfMemoryError: Java heap space
2022-07-26 12:25:31.367 [ERROR] [org.apache.felix.fileinstall ] - In main loop, we have serious trouble
java.lang.OutOfMemoryError: Java heap space
Changing the existing rule makes it crash, restarting openHAB makes it work.
So if I save the rule with syntax a, check that it works, and then change it to syntax b, it will run out of memory and crash.
If I then restart openHAB, it will just work fine with syntax b.
During testing I noticed that often, I see 2 lines in my logs when changing (reloading) a script:
require 'openhab'
astroSun = actions('astro', 'astro:sun:home')
rule 'Testing actions' do
every :second
run do
astroTime = astroSun.getEventTime('SUN_SET', nil, nil)
logger.info("We have some astro time: #{astroTime}")
end
end
I only saw this once in my log when saving the file:
It’s pretty reproducible. Open the script, change a couple of letters in the variable name, save, and watch it burn.
Using the following code at the moment
require 'openhab'
rule 'Testing actions' do
every :minute
run do
astro_t = actions('astro', 'astro:sun:local').getEventTime("SUN_SET", nil, nil)
logger.info("We have some astro time: #{astro_t}")
end
end
And changing the astro_t variable name is enough to make it go out of control.
The double log entry seems pretty consistent as well. Open and edit any script, save it, and there will be two entries.
I’ve checked and there is only one JRuby bundle loaded
I’ve been using vscode and it doesn’t cause the double notify / double loading. Try vim inotify twice - Google Suche and see whether it’s related to your openhab crashing.
sed -i 's/astro_t/astro_time/' test.rb
sed -i 's/astro_time/astro_t/' test.rb
No issues whatsoever. A single ScriptFileWatcher line per command.
vim -c ':%s/astro_t/astro_time/g' -c ':wq' test.rb
vim -c ':%s/astro_time/astro_t/g' -c ':wq' test.rb
Double log entries, and the system is going down.
I’ve been editing the script files using vim for quite some time now, and with these astro actions, its the first time this manifests itself.
I guess it’s good to know, and might also be related to the limited CPU power of the device openHAB is running on.
It’s hardly obvious. Well done for spotting and reporting the double rule load, few would.
Guess the underlying issue is some horror about (re) loading rules before last attempt has finished, and likely about Actions in general or Astro in particular.
It would be “nice” to get that fixed, because I’ll bet it can manifest in other nasty obscure ways. So I’d recommend if you could log a Github issue for posterity, outlining how you could reproduce this.
I doubt it’ll get looked at to be honest,but it might help someone else one day
I have encountered this double loading although not related to vim. It happens programmatically when moving a (temp) script file from a different mountpoint in a linux filesystem to conf/automation/jsr223/ruby/personal/. I just implemented a workaround by creating that temp file in the same mountpoint before moving it. Since this was easily avoidable I didn’t bother opening an issue with openhab-core and just moved on.
Come to think of it, I have had CPUs going crazy (caused by openhab) on my development laptop too but I didn’t link the two issues together, and instead just moved development into a linux server. I’m not sure that I experienced or noticed the double loading on my laptop, so I’m not sure if they’re related.
I can confirm that this happened on my system too, except my openhab process didn’t crash nor did it cause a cpu spike. My system has lots of RAM so perhaps that helped. I am also using an openhab 3.4-snapshot from a few days ago.
Furthermore, I tried this on a RulesDSL file in conf/rules/test.rules and yes, openhab loaded the rule twice there too.
I thought it might be nice to share were I was going with this. Maybe someone else can take inspiration from it
This is part of my bedroom automation, closing the blinds when the sun’s down and the lights are turned on.
require 'openhab'
BEDROOM_LIGHTS = Bedroom
.equipments(Semantics::Lightbulb)
.members
.points(Semantics::Control)
rule 'Turn off lights when sleep tracking has started' do
changed SleepasAndroid_Event,
from: ->f { ! ['sleep_tracking_started', 'sleep_tracking_paused'].include?(f) },
to: ->t { ['sleep_tracking_started', 'sleep_tracking_paused'].include?(t) }
delay 5.seconds
run do
# Turn the lights off
BEDROOM_LIGHTS.ensure.off
# Close the blnnds
BlindsBedroomWindow_Vane.ensure.command(0)
end
end
rule 'Close blinds when it is dark outside and lights are on' do
changed BEDROOM_LIGHTS, to: ->t { t.on? }
run do |event|
logger.info("#{event.item} turned on while dark outside, closing the blinds")
BlindsBedroomWindow_Position.ensure.down
BlindsBedroomWindow_Vane.ensure.command(0)
end
only_if { actions("astro","astro:sun:local").getElevation(nil) <= -6 }
end
You are completely right. I have a switched light, and a ceiling dimmer in the bedroom. The on? method works on both.
Sure! I have Luxaflex (HunterDouglas) Powerview blinds around the house, the vertical venetian type. In the bedroom they have room darkening fabric, which works really well
For one I totally forgot about the word-array operator in ruby, and the fact you can pass the to: parameter an array. But! there is also a issue I ran into;
I’d like to trigger the rule only at the very start of sleep tracking. When SleepAsAndroid starts the session, it will pause tracking for a couple of minutes, sending the sleep_tracking_started and sleep_tracking_paused in very quick succession. While both end up fine on the MQTT broker, openHAB seems to have trouble keeping up, and just sometimes skips the first sleep_tracking_started state.
Without this bug, it could be just simply to: "sleep_tracking_started".