Detecting changed value in volume of beer keg when poured

Hi,

I’ve picked my OH deployment back up after moving house, I am playing around with my kegbot installation to play TTS over alexa when I pour a beer.

I am picking up the volume of keg remaining into an item. I basically want to play a TTS when the volume changes.

From what I understand I need to setup persistance and use previous state. The item is a number but I am having trouble with persistance and how to get the number value and previous number value. One of them is NULL.

Not sure which code to paste or how to troubleshoot!

rule “Tap 3 pour”
when
Item tap3_vol_remaining received update
then
if (tap3_vol_remaining.state.toString != tap3_vol_remaining.previousState.state.toString) {
Garage_Speak.sendCommand('Enjoy '+ tap3_name.state)
}
end

Cheers,

Moad.

Did you install and setup a persistence service? I would use rrd4j.
I would cast the state to a number type.
For debugging insert logInfo lines, the will show in the logs.
Example
logInfo("MyRule","Value of tap3_vol_remaining: {}", tap3_vol_remaining.state)

No, you don’t need persistence :slight_smile: Instead you need another trigger:

rule "Tap 3 pour"
when
    Item tap3_vol_remaining changed
then
    if (previousState !== null) {
        Garage_Speak.sendCommand('Enjoy '+ tap3_name.state)
    }
end

When using changed as trigger, there is a implicit variable previousState without an installed persistence service. Because the first status (when openHAB ist starting up) is null, we have to prevent a false positive :wink:
Another false positive will be if the volume changes in the wrong direction, you could prevent this by comparison…

rule "Tap 3 pour"
when
    Item tap3_vol_remaining changed
then
    if (previousState !== null) {
        if ((previousState as Number) > (tap3_vol_remaining.state as Number)) {
            Garage_Speak.sendCommand('Enjoy '+ tap3_name.state)
        }
    }
end

However, this will only work if it’s a number item.

As the Item is named tap3… are there other tapX which shall also trigger a message?

2 Likes

Ups, I should have known that. Thanks for correcting me.

1 Like

:blush:

Great thanks so much!

I will try this tonight and report back.

Yep 3 taps to set this up on. I can create 3 rules or can you have multiple when triggers in a rule to tidy it up?

You can use a group for this:

Group gAllTapRemain
Group gAllTapName
Number tap1_vol_remaining "Tap1 [%d]" (gAllTapRemain) {...}
Number tap2_vol_remaining "Tap2 [%d]" (gAllTapRemain) {...}
Number tap3_vol_remaining "Tap3 [%d]" (gAllTapRemain) {...}
String tap1_name "Tap1 [%s]" (gAllTapName)
String tap2_name "Tap1 [%s]" (gAllTapName)
String tap3_name "Tap1 [%s]" (gAllTapName)

rule:

rule "Tap pour"
when
    Member of gAllTapRemain changed                                              // one Tap was changed
then
    if(previousState === null) return;                                           // startup, so stop rule
    var String strTap = triggeringItem.name.split("_").get(0)                    // get Index
    var iTapName = gAllTapName.members.filter[i | i.name.contains(strTap)].head  // get Name as Item
    if ((previousState as Number) > (triggeringItem.state as Number)) {          // if level has fallen
        Garage_Speak.sendCommand('Enjoy '+ iTapName.state)                       // say the Name...
    }
end

As you can see, I changed the rule slightly, the rule now will return if changing from null.

1 Like

Thanks!

I got this error in the log

Rule ‘Tap pour’: Could not cast NULL to java.lang.Number; line 57, column 10, length 23

That line is

var iTapName = gAllTapName.members.filter[i | i.name.contains(strTap)].head

It triggered the rule but said “enjoy num”
Actually that was an issue with my “thing” that hits the kegbot API to get the name.

I think we are good

edit: oops I didn’t notice the tap names were the same in your sample code, fixed that up and it is working!

Thanks so much :slight_smile:

1 Like