[Solved] OH2: simplifying my rules...?

I have a bunch of rules which are very similar (see below).
May I kindly ask for what would you’d suggest on how to simplify these rules, maybe and ideally with one rule.

I thought of using the overarching group to the iterate through the members of for the last updated OFF state… but could not get this to work.

rule "Irrigation1 valve 1 OFF"
    when
        Item Irrigation1_1 received command OFF
    then
        var int valveFlow = (PumpStation1_Flow.state as Number).intValue
        publish("mymosquitto", "ArgyleCourt/Property/PumpStation1/Flow1", valveFlow.toString)
        var int valveVolume = (PumpStation1_Meter.state as Number).intValue
        valveVolume = valveVolume - PumpStation1_MemoriseMeterRead
        publish("mymosquitto", "ArgyleCourt/Property/PumpStation1/Volume1", valveVolume.toString)
        PumpStation1_LastSessionMemory.postUpdate((PumpStation1_LastSessionMemory.state as Number).intValue + valveVolume)
end


rule "Irrigation1 valve 2 OFF"
    when
        Item Irrigation1_2 received command OFF
    then
        var int valveFlow = (PumpStation1_Flow.state as Number).intValue
        publish("mymosquitto", "ArgyleCourt/Property/PumpStation1/Flow2", valveFlow.toString)
        var int valveVolume = (PumpStation1_Meter.state as DecimalType).intValue
        valveVolume = valveVolume - PumpStation1_MemoriseMeterRead
        publish("mymosquitto", "ArgyleCourt/Property/PumpStation1/Volume2", valveVolume.toString)
        PumpStation1_LastSessionMemory.postUpdate((PumpStation1_LastSessionMemory.state as Number).intValue + valveVolume)
end


rule "Irrigation1 valve 3 OFF"
    when
        Item Irrigation1_3 received command OFF
    then
        var int valveFlow = (PumpStation1_Flow.state as Number).intValue
        publish("mymosquitto", "ArgyleCourt/Property/PumpStation1/Flow3", valveFlow.toString)
        var int valveVolume = (PumpStation1_Meter.state as DecimalType).intValue
        valveVolume = valveVolume - PumpStation1_MemoriseMeterRead
        publish("mymosquitto", "ArgyleCourt/Property/PumpStation1/Volume3", valveVolume.toString)
        PumpStation1_LastSessionMemory.postUpdate((PumpStation1_LastSessionMemory.state as Number).intValue + valveVolume)
end

You could do something similar in rules DSL, but here is a condensed solution in Jython. To use it, you would need to:

  • add in your broker ThingID
  • create a gIrrigation1 group with members of Irrigation1_1, 2, and 3
  • define PumpStation1_MemoriseMeterRead (is it a global variable?)
from core.rules import rule
from core.triggers import when
from core.actions import MQTTActions

@rule("Irrigation valve OFF")
@when("Member of gIrrigation1 received command OFF")
def irrigation_off(event):
    valve_number = event.itemName.split("_")[1]
    MQTTActions.publish("mymosquitto", "ArgyleCourt/Property/PumpStation1/Flow{}".format(valve_number), items["PumpStation{}_Flow".format(valve_number)].toString())
    valve_volume = items["PumpStation{}_Meter".format(valve_number)).intValue() - PumpStation1_MemoriseMeterRead
    MQTTActions.publish("mymosquitto", "ArgyleCourt/Property/PumpStation1/Volume{}".format(valve_number), items["PumpStation{}_Volume".format(valve_number)].toString())
    events.postUpdate("PumpStation1_LastSessionMemory", str(items["PumpStation1_LastSessionMemory"].intValue() + valve_volume))

Appreciate the response, though
a) I a neither running OH3 nor the new rule engine :slight_smile:
b) have no things
c) is a global int

However, I have plans to eventually move to OH3 and the new rule engine… as the existing DSL still does my head in. :slight_smile:

1 Like

The new rule engine has been available for several years and can be installed through Paper UI in OH2. Here is an easy way to install Jython and the helper libraries…

If you have OH2, then you have Things. Your Items are linked to Channels inside of the Things.

If you are interested in moving forward with Jython, let me know and I will help out! If not, everything I did in my example can be done in the rules DSL… just not as easily.

OK, you’ve convinced me; I’ll move quicker to Jython than envisaged.

While Things certainly exist, I am not using them.
I am not using PaperUI either.
… I am a OH1 (pure) textural guy (or old fart) :slight_smile:

But you are using a recent version of OH2? Hopefully 2.5? You still should use Paper UI to configure some stuff, even if you have everything configured in text files. I have my Items in files, but I use managed Things (created by the system and not in files except for the jsondb text files).

Hmmm… are you not using the OH2 MQTT binding? Then IIRC there is an MQTT action that you can access through core.actions.py.

I am using 2.5.6 (Build).

I had no need for PaperUI; so why use it?
I also stay corrected: I just checked, and see that I have one .things file for astro, network and logreader (set up once and forgotten about.)
I did not use the QH2 MQTT broker due to performance/drop-out issues, and stayed with mosquitto, also due to using Owntracks.

I will migrate to OH3 and explore different ways of working after having set-up the environment on a rPi4.

As do I :smile:, but I use the OH2 MQTT binding. You are using the OH1 version of the MQTT binding, so you can use the OH1 MQTT Action with…

from core.actions import MQTTActions
...
MQTTActions.publish("mymosquitto", "ArgyleCourt/Property/PumpStation1/Flow{}".format(valve_number), items["PumpStation{}_Flow".format(valve_number)].toString())

I’ll update my example rule.

If you want to use Jython, you will want to wait…

See Design Pattern: Cascading Timers for one such approach. Essentially what you need to do is parse out the pump station number valve number from the Item name that triggers the Rule. That tells you the valve that turned off. Then you can use those numbers to build the Item names and MQTT Topic names to send the messages to.

Put all the Irrigation Items into a Group, I’ll call it PumpStation1. If you have more than one PumpStations you might consider similarly parsing the pumpstation number out of the Item name.

import org.eclipse.smarthome.model.script.ScriptServiceUtil

rule "PumpStation1 Irrigation Item received command OFF"
when
    Member of PumpStation1 received command OFF
then
    val parts = triggeringItem.name.split('_')
    val valve = parts.get(1)
    val valveFlow = PumpStation1_Flow.state as Number
    val valveVolume = (PumpStation1_Meter.state as Number) - PumpStation1_MemoriseMeterRead // gloval variable?
    val topicRoot = "ArgyleCourt/Property/PumpStation1/"

    // MQTT 1.x version
    publish("mymosquitto", topicRoot+"Flow"+valve, valveFlow.toString)
    publish("mymosquitto", topicRoot+"Volume"+valve, valveVolume.toString)

    // MQTT 2.x version
    // val mqttActions = getActions("mqtt","mqtt:broker:mymosquitto") // use Thing ID for broker Thing
    // mqttActions.publishMQTT(topicRoot+"Flow"+valve, valveFlow.toString)
    // mqttActions.publishMQTT(TopicRoot+"Volvume"+valve, valveVolume.toString)

    PumpStation1_LastSessionMemory.postUpdate((PumpStation1_LastSessionMemory.state as Number) + valveVolume)
end

The above is a pretty straight forward application of Design Pattern: Associated Items and Design Pattern: How to Structure a Rule.

Note I just typed in the above. There are surely errors.

Note that 1.x bindings (i.e. those that do not use Things) are not and will not be supported on OH 3.

1 Like

As always, a big thank you for your post/reply…

I am in the process of reviewing my current OH set-up and what needs changing / simplifying to prepare and then move to OH3.

I haven’t used ‘things’ so far, as I never grasped the concept… and am reading up on the topic in the docs.

And yes, my timer ‘cascade’ is based on your design pattern you’ve published yonks ago. :slight_smile: