Blockly "Repeat" block not repeating

OH 3.4.4 on openHABian RPi4:

This is a rule I’m testing to repeat email alerts but I can’t seem to get the repeat function to work. If anyone can point me in the right direction I would appreciate it. I get just one email:

Given that Blockly has been completely rewritten for OH 4 the ability to help is going to be limited and if there is a bug here it’s not going to be fixed in 3.4.

With that caveat, show the code generated by the blocks.

The only thing that I can see which might be a problem is if the “after 1 minute do with timer” block cancels the existing timer before creating a new one. You are trying to create three Timers but all three have the same name and even in 3.4 Blockly tries to generate code that cleans up after itself rather than leave stuff like orphaned timers hanging about. Seeing the code generated by the blocks will; confirm.

If this is the problem, you need to create a new name for the Timer each time through the loop.

Thanks Rikoshak.

configuration: {}
triggers:
  - id: "1"
    configuration:
      itemName: Leak_Sensor_Dehu
    type: core.ItemStateChangeTrigger
conditions: []
actions:
  - inputs: {}
    id: "2"
    configuration:
      blockSource: <xml xmlns="https://developers.google.com/blockly/xml"><block
        type="controls_repeat_ext" id="EW#FI_OCO)-oc^D))+nO" x="72"
        y="-749"><value name="TIMES"><shadow type="math_number"
        id="QYNYOGz(olgCB(}`aJ6X"><field
        name="NUM">3</field></shadow></value><statement name="DO"><block
        type="controls_if" id="^YXST~::FT*1jN$3MN*m"><value name="IF0"><block
        type="logic_compare" id="pvK^H4{-S)DyayFkSD/-"><field
        name="OP">EQ</field><value name="A"><block type="oh_getitem_state"
        id="qlSvPDtWo@t=X@2}`zS("><value name="itemName"><shadow type="oh_item"
        id="2=AiITheg[=2}#zE|zit"><field
        name="itemName">Leak_Sensor_Dehu</field></shadow></value></block></value><value
        name="B"><block type="text" id="ME}:MZ*S,7k@aB*p2Av)"><field
        name="TEXT">ON</field></block></value></block></value><statement
        name="DO0"><block type="oh_timer" id="S{5_72pS_P:3.yeqp/Ko"><field
        name="delayUnits">plusMinutes</field><value name="delay"><shadow
        type="math_number" id="[,AIjn.pXaM|3s)3*OLL"><field
        name="NUM">1</field></shadow></value><value name="timerName"><shadow
        type="text" id="gt)2^m+V9C/+VI*3+70y"><field name="TEXT">Leak Alert
        Timer 1</field></shadow></value><statement name="timerCode"><block
        type="mherwege:blocky:mail_send_mail" id="{J!oFRIV$N7+N}zZ!Y5c"><field
        name="TYPE"></field><value name="SERVER"><shadow type="oh_thing"
        id="B=`k}}#@V[TVh7Mc}LC7"><field
        name="thingUid">mail:smtp:SMTP_Server</field></shadow></value><value
        name="RECIPIENTS"><shadow type="text" id=";zI,~FXGB#3]=[v:|#0u"><field
        name="TEXT">monitors@x.com</field></shadow></value><value
        name="SUBJECT"><shadow type="text" id="2J`5o}e::oIf]X|D9SmQ"><field
        name="TEXT">Leak Alert Test 2-4</field></shadow></value><value
        name="CONTENT"><shadow type="text" id="@!]L|@k76ri7SJlU2^P~"><field
        name="TEXT">The Dehumidifier leak sensor has triggered an alert. Please
        contact BPS at monitors@bpsgreenhomes.com or
        910-470-8203</field></shadow></value><next><block type="oh_log"
        id="6?PYoFi|UrB,6%dLNm$_"><field name="severity">info</field><value
        name="message"><shadow type="text" id="KndOjE`0`1x-Edp;=kf#"><field
        name="TEXT">Email Sent - Dehumidifier Leak
        Alert</field></shadow></value></block></next></block></statement></block></statement></block></statement></block></xml>
      type: application/javascript
      script: >
        var scriptExecution =
        Java.type('org.openhab.core.model.script.actions.ScriptExecution');


        var zdt = Java.type('java.time.ZonedDateTime');


        if (typeof this.timers === 'undefined') {
          this.timers = [];
        }


        var Things = Java.type('org.openhab.core.model.script.actions.Things');


        var logger = Java.type('org.slf4j.LoggerFactory').getLogger('org.openhab.rule.' + ctx.ruleUID);



        for (var count = 0; count < 3; count++) {
          if (itemRegistry.getItem('Leak_Sensor_Dehu').getState() == 'ON') {
            if (typeof this.timers['Leak Alert Timer 1'] === 'undefined' || this.timers['Leak Alert Timer 1'].hasTerminated()) {
              this.timers['Leak Alert Timer 1'] = scriptExecution.createTimer(zdt.now().plusMinutes(1), function () {
                Things.getActions('mail', 'mail:smtp:SMTP_Server').sendMail('monitors@x.com', 'Leak Alert Test 2-4', 'The Dehumidifier leak sensor has triggered an alert. Please contact BPS at monitors@bpsgreenhomes.com or 910-470-8203');
                logger.info('Email Sent - Dehumidifier Leak Alert');
                })
            }
          }
        }
    type: script.ScriptAction

There is an icon at the bottom right to show the code generated by the blocks. I don’t need the full rule’s code. But this works too.

OK, it’s not what I though was happening but it results in the same behavior. It only creates a new Timer if the old one doesn’t already exist or it exists but has terminated. So it creates the Timer named “Leak Alert Timer 1” on the first loop and skips the rest because a timer with that name already exists.

You need to use a unique name for the timers each time through the loop.

Also, even if three Timers are created, they are all going to go off at the same time. Do you really want to send three identical emails all at basically the same time? Wouldn’t it make more sense to spread the Timers out so you get one email perminute over the next three minutes?

Ah, didn’t know about the icon. Yes I want to send emails out on a timed basis. The final result will be a rule that sends an alert email every 30 minutes for 3 hrs., then backs down to every few hours until the leak sensor has cleared. Is there a way to do it without having to name a bunch of timers?

In OH 3.4, no. But keep in mind you can use a for loop block and get access to the i variable you can use to create the timer names.

In OH 4 there’s openHAB Rules Tools [4.1.0.0;4.9.9.9] which includes a looping timer. However, even then “backs down to every few hours” isn’t going to be supported by that block. To meet these requirements in Blockly you’ll have to do it all yourself I think.

You need to:

  1. create the timer (no repreat or for loop), we just need the one, set it to run immediately or in 0 seconds or what ever is supported
  2. the “do” part of the timer needs to see if the conditions are still such that the email needs to be sent. If so
    a. send the email
    b. see how long we’ve been sending alerts and based on that calculate when to send the next email
    c. use that calculated time from 2b to reschedule the timer created in 1

If the conditions are no longer such that alerts should be sent, do nothing and the Timer will stop rescheduling itself.

You might be able to use Open Reminder [3.3.0;3.4.9) or Threshold Alert [3.2.0;3.4.9) to handle this. Probably Open Reminder for this use case. Then all the looping and timers and stuff is handled for you and all you need to do is write some code that sends the email. However, I don’t think you can access the passed in values in Blockly in 3.4 so you’ll have to code it in JS.