How to write rules for multiple/loop items

i need help with rules in a loop aproach. I want to simplife rules code - below just a short example based on irrigation and many valves - right now i have duplicated code for every valve 1-4 and i want to achieve sth like this:

split code into 2 sections :

a) configuration


var int numberOfValves = 4

b) rules

for each … 4 do :

// watering timers

var Timer WtrValve1StartTimer = null
var Timer WtrValve1StopTimer  = null
var Timer WtrValve2StartTimer  = null
var Timer WtrValve2StopTimer   = null
var Timer WtrValve3StartTimer  = null
var Timer WtrValve3StopTimer   = null
var Timer WtrValve4StartTimer  = null
var Timer WtrValve4StopTimer   = null

additional code which should be multiplicated for4 valves

  // starting watering - 1
            if (wtr1Time > 0) {
                endTime = startTime.plusMinutes(wtr1Time)
                logInfo( "FILE", "Watering_starting/stoping: Watering 1 starts [" + startTime + "] finish [" + endTime + "]")
                WtrValve1StartTimer  = createTimer(startTime) [|
                    logInfo( "FILE", "Watering_starting/stoping: Lawn1[on]")
                    Lawn1.sendCommand(ON)
                ]
                WtrValve1StopTimer   = createTimer(endTime) [|
                    logInfo( "FILE", "Watering_starting/stoping:  Lawn1[off]")
                     Lawn1.sendCommand(OFF)
                ]
                startTime = endTime.plusMinutes(1)
            }

if there is existing example just give me a link to a thread or write a short code with some directions :slight_smile: Thank you!

There really isn’t enough here to provide concrete advice. It’s not even clear what language you are using and whether this is in a text file or in the UI.

There are several irrigation tutorials on the forum including Design Pattern: Cascading Timers. Additional useful tutorials include Design Pattern: Associated Items and Design Pattern: Gate Keeper.

If you use JS Scripting, there’s a library you can install for Gatekeeper which makes implementing this really simple.

1 Like

Thanks it’s only an example - this code is based od DSL rules (text). I think this is a good place to start:

val nextValve = gIrrigation.members.findFirst[ valve | valve.name == nextValveName]
gIrrigation.members.filter[ valve | valve.state != OFF ].forEach[ valve | valve.sendCommand(OFF) ]

Yes, good start. So the hard part is to choose what list of things to for-each through.

ok i used jsr223 to auto create some rules in a while (10 PWM+PID controller rules).
Do you know if this is possible to see the rule in GUI now its treated as a rule created from text definition = don;t wannt to edit them, just to see te created config - now i see:

===========
// Triggers:
// - PWM triggers

============

You can’t see the actual code of file-based rules on the UI. I am 100% file-based for rules and items, and don’t use the UI at all for rule-related stuff.

ok, is there a smart way to generate a test.items file from /jsr322 script? i need to create some items and rules within one “master file”. .js will be fine for that. I didn’t find the solution how to add items from js… i can do rules with:

scriptExtension.importPreset("RuleSupport");
scriptExtension.importPreset("RuleSimple");
+ 
var sRule = new SimpleRule()

is there a way to handle items ?

Definitely refer back to the reference docs when you have questions like these. Looking at the reference for items we see

  • .createItem(itemName, [itemType], [category], [groups], [label], [tags], [giBaseType], [groupFunction], [itemMetadata])
  • .addItem(itemName, [itemType], [category], [groups], [label], [tags], [giBaseType], [groupFunction])
  • .removeItem(itemOrItemName) ⇒ Boolean
  • .replaceItem(itemName, [itemType], [category], [groups], [label], [tags], [giBaseType], [groupFunction])

To get more detail, click on that “See openhab-js : items (opens new window)for full API documentation” link where you’ll get a pretty good description on what each of these do.

ok thank you. tried to create some items from js but with no luck. Don’t know where to start:

/automation/PWM.js →

items.createItem("testowyitem","String","","","Testowy item label"); 

Error during evaluation of script 'file:/etc/openhab/automation/jsr223/PWM.js': TypeError: items.createItem is not a function in /etc/openhab/automation/jsr223/PWM.js at line number 22

cant find a reference on community how to use .createItem, i cant even use .getItem


item = items.getItem("testowyitem");

Error during evaluation of script 'file:/etc/openhab/automation/jsr223/PWM.js': TypeError: items.getItem is not a function in /etc/openhab/automation/jsr223/PWM.js at line number 23

Please help to understand js rules approach:

i want to use jsr223 rules to manipulate openhab items. There is no items. namespace available by default. i installed Home - Documentation - how to use it in jsr223 ?

I was under the incorrect assumption that you were using the JS Scripting addon with ECMAScript 2021 instead of the very old and soon to be deprecated built in JavaScript with ECMAScript 5.1.

openhab-js only works in the new JavaScript add-on and it comes with that add-on by default. You don’t have to install anything extra.

I don’t know how to do it in the old one and would strongly suggest, if you do what to use JavaScript, to use the new add-on. Not only is it well supported, but it is much better documented and much easier to do just about everything in.

In the old JavaScript you’d have to use the raw Java ItemRegistry and import a lot of extra classes instead of it being just that one liner function call.

ok, so i will use ECMAScript 2021 and put my scripts to /js. How to move my :

scriptExtension.importPreset("RuleSupport");
scriptExtension.importPreset("RuleSimple");

which gives me
var sRule = **new SimpleRule()**

to ECMAScript 2021 ?

You don’t need those lines. The openhab.js rule does it all for you.

var sRule = new SimpleRule() {

    execute: function(module, input) {

        print("input:" + input); // input contains all the output values

    }

};

Loading script ‘/etc/openhab/automation/js/ItemCreator.js’
21:57:38.563 [ERROR] [ab.automation.script.javascript.stack] - Failed to execute script:
org.graalvm.polyglot.PolyglotException: ReferenceError: “SimpleRule” is not defined

You’ve installed the JS Scripting add-on and reviewed the docs for how to build a rule? https://www.openhab.org/addons/automation/jsscripting/#file-based-rules

So i need to rewrite my rule to this format. My old rule was created using SimpleRule builder - i red the docs and not sure how to re-write such PWM rule using rules.JSRule.


var sRule = new SimpleRule() {

        execute: function(module, input) {

            print("input:" + input); // input contains all the output values

        }

    };

    sRule.setName('PWM' + RadiatorACn);

    sRule.setTags(java.util.Set.of("PWM"));

    sRule.setTriggers([

        TriggerBuilder.create()

            .withId(RadiatorACn)

            .withLabel(RadiatorACn)

            .withTypeUID("pwm.trigger")

            .withConfiguration(

                new Configuration({

                "deadManSwitch" : RadiatorACn + '_PWM_deadManSwitch',

                "minDutycycle"  : RadiatorACn + '_PWM_minDutycycle',

                "dutycycleItem" : RadiatorACn + '_PWM_dutycycleItem',

                "interval"      : RadiatorACn + '_PWM_interval',

                "maxDutycycle"  : RadiatorACn + '_PWM_maxDutycycle'

                })).build()

        ]);

    sRule.setActions([

        ActionBuilder.create()

        .withId("1")

        .withTypeUID("core.ItemCommandAction")

        .withConfiguration(

                new Configuration({

            "itemName" : RadiatorACn + '_Relay'

                })).build()

        ]);

    automationManager.addRule(sRule);

also no luck with using .createItem - i cant even find one example of usage in whole documentation and community :frowning:


const item = items.createItem("test", "Switch","","", "label test");

console.log("nowy item", items.getItem("test"));

 Error during evaluation of script 'file:/etc/openhab/automation/js/ItemCreator.js': org.openhab.core.items.ItemNotFoundException: Item 'test' could not be found in the item registry

That might be a timing thing - I wouldn’t expect the new Item to be available within milliseconds. Have you checked via UI whether the Item got created?

I don’t do text based rules but based on the docs it should be something like:

rules.JSRule({
  name: "PWM" + RadiatorACn,
  tags: ["PWM"],
  description: "Put something meaningful here",
  triggers: [???],
  execute: input => {
    print("input:" + input); // input contains all the output values
  }
});

I don’t know where RadiatorACn comes from and what that trigger configuration does is inscrutable to me. If it’s supposed to be an Item received update replace the ??? above with [triggers.ItemStateUpdateEvent('my_item')]. It’s an array so if you’ve more than one separate them by commas.

sure. it was not created