Hi,
Assuming you are using influxdb as persistence, that’s the only thing you would need to adjust, indeed.
Good luck,
Dries
Hi,
Assuming you are using influxdb as persistence, that’s the only thing you would need to adjust, indeed.
Good luck,
Dries
Just a small question: does this work in OH3 as well? And where exactly do I enter this code?
If I do it via Rules --> Code, the code always “disappears” .
If i do it via Scripts --> the EXMAScript and the Rule DSL doesn’t do anything…
It should work in OH 3.
You need to save them to a .rules file in the conf/rules folder. The code above will not work in Ui created rule without changes.
Came here as the previous method I used (google calendar scheduler) is no longer supported in OH3.
Tried the great method in this thread but had a little difficulty at first but quickly found the answer here
In short, change this (from above code):
createTimer(now.plusMillis(i*presence_delay))
To this:
createTimer(now.toInstant().plusMillis(i*presence_delay).atZone(now.zone))
For completeness and for anyone else who is interested in this method here is what I have now which I can confirm works with OH3.
Make sure influxDB is setup, ether manually or via openhabian
Add following:
.items
Switch Swi_PreSim // used in sitemap to turn simulation on/off
Group gSim // add this group to items you wish to be included
example light to be included:
Dimmer Dim_Lounge_Rear "Lounge Rear" <light> (gSim) { channel="xyz" }
.persist
Items {
gSim* : strategy = everyChange
}
.rules
// **************************
// Global variables
// ***************************
var int presence_days = 1
var int presence_delay = 1000
var String persistence = "influxdb"
// ***************************
// Presence Simulation
// ***************************
rule "Presence Simulation"
when
//Time cron "0 0/1 * 1/1 * ? *" //every 60 sec
Time cron "0/30 0/1 * 1/1 * ? *" //every 30 sec
then
if (Swi_PreSim.state == ON) {
gSim.members.forEach(light,i |
if(light.historicState(now.minusDays(presence_days), persistence).state != light.state) {
//createTimer(now.plusMillis(i*presence_delay)) [| OH2
createTimer(now.toInstant().plusMillis(i*presence_delay).atZone(now.zone)) [| //OH3
logInfo("Pres_Sim",light.name + " state " + light.historicState(now.minusDays(presence_days), persistence).state)
light.sendCommand(light.historicState(now.minusDays(presence_days), persistence).state.toString)
]
}
)
}
end
Pleased I found this as it is so much simpler than the Google method, no messing about with their API and all done locally, wish I discovered this a while ago!
What would this rule look like if it was ported to javascript on OH3?
Let me share with you how far I got so far.
For timers some investigation is needed:
triggers:
- id: "1"
configuration:
cronExpression: 0 * * * * ? *
type: timer.GenericCronTrigger
conditions: []
actions:
- inputs: {}
id: "2"
configuration:
type: application/javascript
script: >-
var logger =
Java.type("org.slf4j.LoggerFactory").getLogger("org.openhab.model.script.Rules.Experiments");
var PersistenceExtensions = Java.type("org.openhab.core.persistence.extensions.PersistenceExtensions");
var ZonedDateTime = Java.type("java.time.ZonedDateTime");
logger.info("Running presence simulation");
var presence = ir.getItem("PresenceSimulation").state
var presenceOffset = 7
if (presence == ON) {
var group = ir.getItem("gPresenceSimulation");
group.allMembers.forEach(function (item) {
logger.info("processing gPresenceSimulation member {}", item.name);
var historicState = PersistenceExtensions.historicState(item, ZonedDateTime.now().minusDays(presenceOffset),"rrd4j").state;
if (historicState != item.state) {
logger.info("Pres_Sim {} set to {}", item.name, historicState);
events.sendCommand(item.name, historicState)
}
})
};
type: script.ScriptAction
Move the check to see if PresenceSimulation is ON in a Script Condition instead of the Script Action. That will make the Action a lot simpler.
Beyond that everything looks as I would expect. Is there anything not working?
What do you need the timers for here? Or are you just needing to look into Timers in general?
Thank you for the feedback on script condition.
I included timers to avoid overflow of the binding interface with simultaneous "sendCommand"s
I had to do so on my old installation, but I am not sure whether I still need with OH3 on raspi4 and newer v2 bindings.
triggers:
- id: "1"
configuration:
cronExpression: 0 * * * * ? *
type: timer.GenericCronTrigger
conditions:
- inputs: {}
id: "3"
configuration:
itemName: PresenceSimulation
state: ON
operator: =
type: core.ItemStateCondition
actions:
- inputs: {}
id: "2"
configuration:
type: application/javascript
script: >-
var logger =
Java.type("org.slf4j.LoggerFactory").getLogger('org.openhab.rule.' +
ctx.ruleUID);// "org.openhab.model.script.PresenceSimulation");
var PersistenceExtensions = Java.type("org.openhab.core.persistence.extensions.PersistenceExtensions");
var ZonedDateTime = Java.type("java.time.ZonedDateTime");
var ScriptExecution = Java.type("org.openhab.core.model.script.actions.ScriptExecution");
var presenceOffset = 7
var presenceDelay = 100000000
var group = ir.getItem("gPresenceSimulation");
group.allMembers.forEach(function (item, index) {
logger.info("processing gPresenceSimulation member {}", item.name);
var historicState = PersistenceExtensions.historicState(item, ZonedDateTime.now().minusDays(presenceOffset),"rrd4j").state;
if (historicState != item.state) {
logger.debug("Pres_Sim {} set to {}", item.name, historicState);
ScriptExecution.createTimer(ZonedDateTime.now().plusNanos(index*presenceDelay), function(){
events.sendCommand(item.name, historicState)
})
}
});
type: script.ScriptAction
OK, if that’s the case it looks like your latest code looks reasonable. Another approach that could work, assuming that you don’t have too many Items that makes the rule run longer than an minute, is to use java.lang.Thread.sleep()
to pause inline instead of scheduling a timer. The problems with long running rules is way less pronounced in OH 3. You can still cause problems if your one rule takes too long but the problems will be limited to that one rule and no longer starve out all your rules. So the recommendations against using Thread.sleep in rules is relaxed somewhat.
Have you tried to use this only for a certain time of the day? How would this rule look like then? Because the only-if function of the “new” rule engine doesn’t seem to work…: [Rules] Issues regarding only-if and Dimmer-value (new OH3 Rule-Engine) · Issue #2124 · openhab/openhab-core · GitHub
That issue is specific to Dimmers. It does not mean that conditions in general do not work. I’ve successfully used them in many of my rules.
But if that doesn’t work for you, add an if condition to exit in your Script Action if it’s not the right time.
Okay great Thanks =)
what is “presence delay” for?
presenceDelay is actually misnamed. Meant is the delay between commands to avoid flooding interface with too many simultaneous sendCommands.
Ohhhh okay that’s nice! Thanks for the explanation
maybe could be renamed to smth lik ‘replayTimeShift’ or smth like that