Temperature/Humidity and other postUpdate - rule Design Pattern

  • Platform information:
    • Hardware: Raspberry Pi 4 Model B Rev 1.1/4GB
    • OS: Raspbian GNU/Linux 10
  • Issue of the topic: Temperature/Humidity and other postUpdate Design Pattern

I have been an OH user for a long time, but recently I started to explore the secrets of this smart home software. While I like the multitude of possibilities in HABPanel, I like the ascetic BasicUI the most thanks to the simplicity and speed of operation in the Android application.
Unfortunately, it has its limitations in the form of 1 line of text + 1 datapoint, which with several sensors of the same type can take up three mobile screens.
To avoid this, I try to combine the data using a rule with the module .postUpdate () which saves me one line of data (although it does not allow me to use valuecolor or labelcolor).
I think that there are data that no loss of legibility can be combined in pairs before displaying eg temperature / humidity data sent / received, sunrise / sunset / moonlight, brightness / full moon.
Currently, I use 6 pairs of temperature / humidity even though I could do so for about 14 pairs.
Currently, the rule looks like this:

rule "merge czort"
when
Item MijiaTemp1 changed
then
SklejCzort.postUpdate(MijiaTemp1.state.toString + "°C / " + MijiaH1.state + "%")
end

and items looks like

Number   MijiaTemp1   "Temp wc"  (MijiaTG) {channel="mqtt:topic:ble:temp1", expire="5m,state=NULL"}
Number   MijiaTemp2   "Temp hall"  (MijiaTG) {channel="mqtt:topic:ble:temp2", expire="5m,state=NULL"}
Number   MijiaTemp3   "Temp sleep"  (MijiaTG) {channel="mqtt:topic:ble:temp3", expire="5m,state=NULL"}
Number   MijiaTemp4   "Temp base"  (MijiaTG) {channel="mqtt:topic:ble:temp4", expire="5m,state=NULL"}
Number   MijiaTemp5   "Temp nowhere"  (MijiaTG) {channel="mqtt:topic:ble:temp5", expire="5m,state=NULL"}
Number   MijiaTemp6   "Temp somewhere"  (MijiaTG) {channel="mqtt:topic:ble:temp6", expire="5m,state=NULL"}
Number   MijiaH1   "Hum wc"  (MijiaHG) {channel="mqtt:topic:ble:h1", expire="5m,state=NULL"}
Number   MijiaH2   "Hum hall"  (MijiaHG) {channel="mqtt:topic:ble:h2", expire="5m,state=NULL"}
Number   MijiaH3   "Hum sleep"  (MijiaHG) {channel="mqtt:topic:ble:h3", expire="5m,state=NULL"}
Number   MijiaH4   "Hum base"  (MijiaHG) {channel="mqtt:topic:ble:h4", expire="5m,state=NULL"}
Number   MijiaH5   "Hum nowhere"  (MijiaHG) {channel="mqtt:topic:ble:h5", expire="5m,state=NULL"}
Number   MijiaH6   "Hum somewhere"  (MijiaHG) {channel="mqtt:topic:ble:h6", expire="5m,state=NULL"}

I`ve read a lecture on Design Rich Koshak pattern but probably still do not feel it and examples contained therein does not apply Number item so I wonder:
Is it possible to create such a rule, design pattern, that one would suffice instead of 14?
I consider only the temperature / humidity pairs because they are the most numerous and repeatable.

What would you recommend? How do you manage overflow of data in BasicUI?

To deal with that boils down to “if sensor X changes I need to find its partner Y so I can use both values for my purpose”.
A start might be looking at the “Associated Items” design pattern.
Essentially, adopting an Item naming scheme like XX_temp and XX_humid allows a rule to identify the partner given only one Item.

You could actually do that with some of the names you have, the rule would be just a little more fiddly in manipulating name strings.
Because you then update another Item, you’ll need to incorporate that in the naming scheme as well so that the rule can find that.
“SklejCzort1” say, to partner MijiaTemp1 and MijiaH1

That still leaves how to get all these Items to trigger a rule without keeping a long list. This is where “Working with Groups” design pattern comes in,putting similar Items in a Group and using “Member of (group)” rule triggers.

I keep it to one screen at a time, and use click-for-more features to get more detail on a selection of Items…

1 Like

rossko57 describes it perfectly.

Add all your Items to a Group.

Trigger the rule using a Member of changes trigger on that Group. When any member of the Group changes the rule will run and triggeringItem will be the Item that caused the rule to trigger.

With the triggeringItem.name, do some string manipulation to build the names of the other two Items (for example if the humidity changed you need to generate the corresponding name for the temp Item and the combined Item). This is where you’ll need to rethink the names of your combined Items to make it easier to create it’s name, for example, SkeljCzort1 for MijiaTemp1 and MijiaH1.

    var tempItemName = triggeringItem.name.replace("H", "Temp") // if this is a Temp Item there is no H so nothing happens
    var hItemName = triggeringItem.name.replace("Temp", "H") // if this is an H Item there is no Temp so nothing happens
    var combinedName = "SklejCzort"+triggeringItem.name.substring(striggeringItem.name.length() - 1)); 

Armed with the associated Item’s names you can pull the temp and humidity Items from the Group. We don’t actually need the combined Item itself, just it’s name.

    var tempItem = AllTempHItems.members.findFirst[ i | i.name == tempItemName ]
    var hItem = AllTempHItems.members.findFirst[ i | i.name == hItemName ]

Finally post update the combined string to the combined Item.

    postUpdate(combinedName, tempItem.state + "°C / " + hItem.state)

The complete rule would look something like:

rule "Combine T/H Rule"
when
    Member of AllTempHItems changed
then
    var tempItemName = triggeringItem.name.replace("H", "Temp") // if triggeringItem is a Temp Item there is no H so nothing happens
    var hItemName = triggeringItem.name.replace("Temp", "H") // if triggeringItem is an H Item there is no Temp so nothing happens
    var combinedName = "SklejCzort"+triggeringItem.name.substring(striggeringItem.name.length() - 1)); 

    var tempItem = AllTempHItems.members.findFirst[ i | i.name == tempItemName ]
    var hItem = AllTempHItems.members.findFirst[ i | i.name == hItemName ]

    postUpdate(combinedName, tempItem.state + "°C / " + hItem.state)
end

If you rename your Items using the pattern described in the Associated Items DP the above could be a bit simpler. For example, if they follow the pattern <Unique name>_Temp, <Unique name>_H, <Unique name>_Combined the rule would become

rule "Combine T/H Rule"
when
    Member of AllTempHItems changed
then
    var name = triggeringItem.name.split("_").get(0)
    var tempItem = AllTempHItems.members.findFirst[ i | i.name == name+"_Temp" ]
    var hItem = AllTempHItems.members.findFirst[ i | i.name == name+"_H" ]

    postUpdate(name+"_Combined", tempItem.state + "°C / " + hItem.state)
end

I’ve left sitemaps behind and use MainUI exclusively now that I’ve moved to OH 3 (note, you don’t need a rule like this and extra Items to achieve combining these two Items into one element in MainUI).

When I did use BasicUI I kept them in two separate elements and ordered them such that the temp and humidity were across from each other or next to each other on my phone. But the OH UI has always been secondary. Most of the controlling in this house is done using the traditional wall switches and such or using Google Assistant voice controls. OH is mostly set up for automation, not control.

I am pleased to announce that it works :slight_smile:
I opted for the second, simpler option, and even though VisualStudioCode screams on the snippet

  i.name == name+ "_ Temp"
  i.name == name+ "_ H"
 Cannot refer to the non-final variable name inside a lambda expression

This rule works like the dream one :slight_smile:
Thanks to both of you. Now I can plan my MainUI transfer without hurry

You can declare name as a val instead of a var, as you never change it.

1 Like