Holiday simulation

I am going to write an easy holiday simulation script (JS) and like to hear some experts’ opinions/comments on the concept before starting to write the script.

As I do not want to make it too complicated, I have some personal prerequisites/preferences:

  • maintan the whole simulation in one script
  • define for a subset of my lights and rollershutters items a static plan as an array (one plan each for every third day) when to switch them on/off.

I am thinking about realizing in one of the two ways:

  1. The script will be triggered every 30 minutes and loops through the array. If it matches the correct name of day and the time to switch on/off a device is within the next 30 minutes, then `createTimer’
  2. run the script once per day and create all timers for the whole day

In total I will be switching on/off 5-10 devices per day (and only in the evening between 4-12 pm).
Number one is a bit more of work but I guess it is more “stable”, in case OH is restarting. Not sure if a timer “survives” a restart.
Anyway, that’s why I am asking for some general feedback from professionals.
Thanks in advance.

To give you some ideas:

1 Like

Thanks, Jim.
Forgotten to search in the Tutorials subforum also. :man_facepalming:

My implementation that @JimT kindly linked to works more like 1 than 2. How often it runs is a configurable property so you could go as little as one minute or as long as you want between runs. The lower the time between runs, the more fidelity the simulation will be. It’s kind of a dead giveaway if a bunch of lights all turn on or off all at once in different parts of the house.

I don’t think there is anything wrong with 2 though. That’s how Time Based State Machine [4.0.0.0;4.9.9.9] works. I think 1 results in a simpler implementation for this use case though.

That’s an interesting use case that I’ve not considered. I may add that to my rule template. My Threshold Alert template already has the code for a do not disturb period so I’d just need to move that to a library and call it from both.

In the mean time, my template runs based on the state of a Switch Item. You can create another rule to turn on the Switch at 4 and turn it off at 12 and get that use case covered.

Thanks Rich,
I ended up with a cron-based rule which runs every day at 4pm (and only if a managing item (isHoliday) is set to ON). The rule creates a number of timers for the whole day. If I read the docs correctly, a timer set via a UI based rule re-schedules itself, is that correct?

This is the code so far. If you have suggestions to improve, I’ll be happy to include them so that you can copy/paste the code to your existing rule template.

As a next step I plan to include a function to delete all existing timers when coming home (isHoliday=OFF) and build a widget which populates the schedule array (“plan”).

var debug = true;
var rule = "Urlaub";
console.log("Info: Rule",rule,"gestartet. Trigger: cron");
var plan = [];
var iDay = time.ZonedDateTime.now().dayOfWeek().value();
switch (iDay) {
  case 1:
  case 4:
  case 7:
    plan.push(["22:15","item1","70"]);
    plan.push(["22:28","item1","0"]);
    plan.push(["22:13","item2","ON"]);
    plan.push(["22:23","item2","OFF"]);
    ...
  case 2:
  case 5:
    plan.push(["22:41","item1","70"]);
    plan.push(["22:55","item1","0"]);
    plan.push(["22:53","item2","ON"]);
    plan.push(["23:05","item2","OFF"]);
    ...
  case 3:
  case 6:
    plan.push(["21:56","item1","70"]);
    plan.push(["22:17","item1","0"]);
    plan.push(["23:17","item2","ON"]);
    plan.push(["23:24","item2","OFF"]);
    ...
}
Object.keys(plan).forEach(function(i) {
  if (debug) console.log(i, plan[i]);
  strTimer = "HolidayTimer" + iDay.toString() + i.toString();
  cache.private.put(strTimer, actions.ScriptExecution.createTimer(strTimer, time.toZDT(plan[i][0]), function () {
    items.getItem(plan[i][1]).sendCommand(plan[i][2]);
    cache.private.remove(strTimer);
  }));
});

No. I’m not sure where you read that but a Timer in a UI rule behaves the same as a timer in a file based rule. No difference. If it says that somewhere in the docs it is incorrect and needs to be fixed.

I do have a loopingTimer in my openhab_rules_tools library and there is a setInterval function to create a JavaScript looping timer, but openHAB timers do not reschedule themselves so you’ll need to reschedule these inside the timer function if you want them to run more than once.

I believe this is a completely different approach compared to either of the approaches linked to above.

In my rule template, the overall idea is that the best simulation of presence is to play back the events that happened when you were actually present. If there is any pattern to that, it matches the pattern set when you are home. I recommend playing back events from 7 days ago so the events even match the day of the week.

@JimT’s approach is more stochastic, deciding when to turn something on or off based on weighted randomization. With that approach you’ll never have the same simulation run twice but the overall events look natural (e.g. when a certain lamp is often turned on, the simulation is likely to turn on the lamp).

Your approach is more of a special case of scheduling. There isn’t anything wrong with that approach at all, but it’s a more generic problem than presence simulation because you’ll want to schedule things to happen when you are home too and there are lots of tools on the forum (e.g. time based state machine) and built into openHAB (e.g. Time is <item> rule triggers) to address that.

If you step back and approach this from a scheduling perspective I wonder if a better approach would be to instead create Scenes and rules to trigger the scenes based on your schedule. Then you don’t really have to write any logic at all. Of if you want to add some randomness you only have very little logic to write.

Time based state machine could be used to drive the times and then all you’d have to do is choose the Items and states based on the time of day state. You can add a little randomness by updating the DateTime Items that drive the state machine from another rule.

Also look to the timeline widget/system which lets you create a schedule for things in MainUI or Sitemaps (I think they still support sitemaps).

Scheduling is a problem that has been well covered in the past with lots of tools you can use off the shelf to solve this problem.

The rule is meant to run only when I am on holiday. Misunderstanding…

Good idea. Haven’t thought about this. I look into that.

I’m not misunderstanding. Whether it’s supposed to run when you are on holiday or when you are away or on the third Thursday of the month, it’ll be implemented the same. That’s my point. Your approach is a generic scheduling problem and there are lots of tools to help solve that problem available to you. You don’t need to code this from scratch.