Collection of Strings item

What i am trying to do is add errorMessages or eventMessages (Strings) to a collection as they happen (from different rules) while i am away to read them out to me when i come home.

So different rules would need to be able to add to this variable.

An item that could hold this collection would be nice, but i don’t know if they exist.
A dirty workaround would be a String item with some delimiter on which i could split when i need to go over the list or sort it. But i wonder if there would be a cleaner way to do it.

You can create a set of string Items, and a “stack push” rule that copies from each to an ‘older’ one, discarding the oldest as a new message arrives. If you want, you can add timestamp text to the message.
All other rules post to the same Item.

Using the new rule engine, scripted automation, and the helper libraries, I use a Python Queue object stored in a module to hold notification messages.

In Rules DSL you can use Design Pattern: Separation of Behaviors and keep the collection in the one place. The Rule that triggers when you return to read out the messages will need to be in the same .rules file.

Indeed, there is no Collections type Item. You’d have to encode and parse the messages into a single String Item.

Ok thanks. That confirms my “dirty workaround” idea.

Hi Scott,
your approach sounds very interesting to me.
At the moment I use a proxy item which gets a message via sendCommand. And a rule triggers the state-update of this proxy item. But in case that there are a few messages getting fired in a very short period of time, some of these messages just don’t get sent by this rule since the proxy item gets its updates too quickly.
So I’m looking for a kind of message queue or stack.
I’m not familiar with Python (just Java and a bit of Kotlin) and would ask you if
1.) your solution would fit to my problem
2.) you could provide my with further information / example code how to get things done.

Thank you in advance and best regards,
Michel

This is a really old thread and several of the people on this thread are not around any more. A lot has changed in OH in the three and a half years since this was published. In particular, in OH 2 for the Experimental Rule Engine, in OH 3 and OH 4 for the all rules languages/add-ons, rule triggers are queued. Any rule can have only one instance running at a time with subsequent rules queued up automatically.

There really isn’t even a need for a queue for your use case anymore (the original post would still need to use a queue though as it want to collect the messages over a time and then read them off which is a different use case).

Why not trigger the rule with received command?

You’d need to show the rule because what you are seeing might be a result of something else (e.g. a TOCTOU where the Item state changes between the time where the rule was triggered and you attempt to use the Item’s state, in which case you should use the newState implicit variable instead which has the state of the Item that triggered the rule regardless of what state the Item is currently in.

Given the state of the upstream Jython library and the fact that there’s no one left supporting the Jython add-on in OH, I cannot recommend starting any new rules development using Jython. Anything else will be a better choice right now.

I don’t think so because the way that OH 3+ works you shouldn’t be seeing this behavior. But it could be related to how you’ve implemented it. Even with a received update trigger, you should not be losing any of the messages.

If you did need a queue for other reasons, pretty much all of the rules languages have one built in. JavaScript does not but you can use my Gatekeeper as a queue if you use 0 as the delay between commands. You could even use that from Blockly but you’ll have to use an inline block to do it.

Thank you, Rich, for your help!
To be honest I wasn’t aware that this thread was that old. I haven’t checked it before.
I’m running OH 3.4.4 in a docker container on my Syology NAS.
The rule indeed triggers a received command of my proxy item. So I just explained it not correctly. Maybe related to the fact that I am not native english speaking.
Here’s my rule…

configuration: {}
triggers:

  • id: “2”
    configuration:
    itemName: notifyMichel
    type: core.ItemCommandTrigger
    conditions:
    actions:

  • inputs: {}
    id: “1”
    configuration:
    type: application/javascript
    script: >
    var things = Java.type(‘org.openhab.core.model.script.actions.Things’);

    things.getActions('telegram', 'telegram:telegramBot:xxxxxxxxxx').sendTelegram(itemRegistry.getItem('notifyMichel').getState());
    

    type: script.ScriptAction

I guess your second hint points to the

I guess this exactly describes what I have done wrong. I’m going to change it and will give you an update in a couple of days since I’m away from home.

The upper right if each post has the month and year it was made. The last post before you reopened it was Feb '20. You’ll also see right above your post “3 years later”. Given OH is on an every six months release cycle, anything older than six months should be treated as old. That doesn’t necessarily mean the information is incorrect, just that it needs to be verified.

As a general rule, we prefer forum users open new threads to replying to really old threads. It makes it easier for other users to find relevant and recent information when they search that way.

Replace that with event.itemCommand.

There are two potential problems here. The first is that the Item doesn’t change state on the command. So while the rule triggers and runs the Item is updating as a response of the command in parallel. It’s only a trick of timing whether the Item’s state reflects the command or not. The second problem is related where a subsequent command that occurs after the rule triggered might update the Item’s state before the rule pulls it.

So it’s almost always better to use the event data in the rule because that reflects the Item command or state that actually triggered the rule regardless of what the Item state is doing.

I switched back to RuleDSL and it looks now like this.

getActions(“telegram”,“telegram:telegramBot:xxxxxxxxxx”).sendTelegram(newState.toString)
Seems to work perfectly now.
Thank you very much for your support and always good explanations, even for rookies like me.