Blockly loop and timer behavior changed from 3.4 ot 4.0? Loops do not work anymore

Yes, it has been fixed but waits for the “merge”:

Update: Merged finally

1 Like

I see the fix did not make it to 4.0.3 :worried:

I am sorry to hear that. @florian-h05 , any idea why?

I did not backport the PR in time for the release because I was away from home. It is now backported, so it at least will be in the next release.

1 Like

Is this fix now in 4.0.4?

Yes, the fix has been backported and is in 4.0.4.

It was just missing in the release notes, but meanwhile release notes were corrected.

Blockly loops still don’t work :worried:

Have you opened the Blocklies and saved them? Blockly needs to regenerate the code.

1 Like

I did open and save, still no success. The script worked in 3.4, but no more.

To test, I wrote the script below. It never exits.

Is the problem in my code or is this a bug?

Some questions and a proposal:

Why do you do a repeat loop around a timer??? What is the intent here?
This creates the same time three times which may have unexpected results.

Can we simplify the topic and just create the one timer only and remove the repeat loop?

What code is it creating?

if (cache.private.exists('MyTimer') === false || cache.private.get('MyTimer').hasTerminated()) {
  cache.private.put('MyTimer', actions.ScriptExecution.createTimer('MyTimer', time.ZonedDateTime.now().plusSeconds(2), function () {
    console.info('abc');
    }));
};

Do you want the timer to run only three times and then stop? Because then the right way to do it is as follows:

Update note: As mentioned by Rich, there is a small mistake in the above image as it needs to be “cnt >=0”. Sorry for the confusion.

1 Like

Hello, thanks for the answer.

The idea is to test and confirm that loops work as they should in OpenHAB 4.0.4. Blockly loops stopped working with the 4.0.0. release and should now work again. Hence, I wrote a short code just to confirm that the loops now work.

Understood, thanks, though the use with the repeat does not make sense for me as a legit usecase as it recreates the timer several times. So, if the one I posted works for you, I would say we are good. agreed?

Absolutely.

I tried this, the loop executes 2 times and exits regardless of the value of cnt.

Can you confirm this behavior?

There’s an off by one error in @stefan.hoehn’s code. It should be “if cnt >= 0”. With just > the timer will only reschedule itself twice instead of three times.

30 years of programming and I still don’t get loops right :rofl: Thanks Rich.

1 Like

This is the whole wakeup light blockly code, after I changed the loop. For some reason the second loop, that should start with the “Dawn ended, sunrise starts” log info is never reached. It seems the code never exits the previous loop.

Please pray the full rule by clicking the code grab and pasting the YAML you find there into a reply. Use code fences.

```
code goes here
```

The idea is to slowly increase the brightness of the lamp over a period of 30 minutes. My original code, that worked in OH 3.x, was based upon a “Repeat-while” loop that would have delay of few seconds between each repeat. I read somewhere that using “wait” inside the loop is not recommended. Therefore I ended up with this structure whre the “repeat while” loop wraps around a delay timer.

I am not a coder so I do not quite understand what “this creates the same time three times” means in this context. Please explain.

Ok, understood. What you must not do is to stay in a rule for 30min. Therefore you need to increase the value via a timer, which is the reoccurring way that replaces you loop. In that timer you use a value that is stored in a shared rule cache variable:

Retrieve it, increase it, use and then save it again in that “stored value”.

Here is an example that use it to remember the last color that was set

In you example you can use it similarly only that additionally also increase the value.

1 Like

Thanks for the help. I ditched the loops totally and rewrote the wakeuplight. Now it runs once, stores its states in value storages and exits. The script is run once a minute until it has completed the wakeup cycle.

var comma, hsb, brightness, shutdown_timer, hue, saturation;


comma = ',';
if ((cache.shared.exists('hue_storage') === false) == true) {
  hsb = ' ';
  hue = 1;
  cache.shared.put('hue_storage', hue);
  console.info(hue);
  saturation = 100;
  cache.shared.put('saturation_storage', saturation);
  brightness = 0;
  cache.shared.put('brightness_storage', brightness);
  hsb += String(hue);
  hsb += String(comma);
  hsb += String(saturation);
  hsb += String(comma);
  hsb += String(brightness);
  items.getItem('Timon_yovalo_colour_data').sendCommand(hsb);
  console.info('Dawn started, H, S and B reset to default values');
} else if (hue < 40) {
  hsb = ' ';
  hue = (cache.shared.get('hue_storage'));
  hue = (typeof hue === 'number' ? hue : 0) + 1;
  cache.shared.put('hue_storage', hue);
  saturation = (cache.shared.get('saturation_storage'));
  saturation = (typeof saturation === 'number' ? saturation : 0) + -1;
  cache.shared.put('saturation_storage', saturation);
  brightness = (cache.shared.get('brightness_storage'));
  brightness = (typeof brightness === 'number' ? brightness : 0) + 2;
  cache.shared.put('brightness_storage', brightness);
  hsb += String(hue);
  hsb += String(comma);
  hsb += String(saturation);
  hsb += String(comma);
  hsb += String(brightness);
  items.getItem('Timon_yovalo_colour_data').sendCommand(hsb);
} else if (hue == 40 && brightness >= 58) {
  brightness = 1;
  hue = 50;
  cache.shared.put('hue_storage', hue);
  items.getItem('Timon_yovalo_temp_value').sendCommand(brightness);
  items.getItem('Timon_yovalo_bright_value').sendCommand(brightness);
  cache.shared.put('brightness_storage', brightness);
} else if (hue >= 40 && brightness < 100) {
  brightness = (cache.shared.get('brightness_storage'));
  brightness = (typeof brightness === 'number' ? brightness : 0) + 4;
  items.getItem('Timon_yovalo_bright_value').sendCommand(brightness);
  cache.shared.put('brightness_storage', brightness);
} else if (brightness >= 100 && (cache.shared.exists('shutdown_timer_storage') === false) == true) {
  shutdown_timer = 30;
  cache.shared.put('shutdown_timer_storage', shutdown_timer);
} else if (brightness >= 100 && (cache.shared.get('shutdown_timer_storage')) > 0) {
  shutdown_timer = (cache.shared.get('shutdown_timer_storage'));
  shutdown_timer = (typeof shutdown_timer === 'number' ? shutdown_timer : 0) + -1;
  cache.shared.put('shutdown_timer_storage', shutdown_timer);
  cache.shared.put('brightness_storage', brightness);
} else {
  hsb = ' ';
  hue = 1;
  saturation = 100;
  brightness = 0;
  items.getItem('Timon_yovalo_bright_value').sendCommand(brightness);
  cache.shared.put('hue_storage', hue);
  cache.shared.put('saturation_storage', saturation);
  cache.shared.put('brightness_storage', brightness);
  hsb += String(hue);
  hsb += String(comma);
  hsb += String(saturation);
  hsb += String(comma);
  hsb += String(brightness);
  console.info('Suhrise is over, H, S  and B reset');
}

1 Like