HABApp: NumberItem and "received update"

Hi,

I’m trying to port my JSR223/Python rules to HABApp (because I’m missing some python packages running only with python 3.x). It is basically working and I like HABApp (thanks!), but now I’m stuck.

Background: when I dial a number on my old rotary phone, a Number item is updated with the value I dialed (e.g. 3 when I dial the number 3). Of course I can dial the same number multiple times in a row and want to trigger a rule every time (even if the number doesn’t change).

In my old Jython2.7 rules I have something like the following:

@rule("Handle dial codes", description="", tags=["DIAL"])
@when("Item wallPhone_dialPlate received update")
def processRuleDialCodes(event):
    if event.itemState.intValue() == 1:
       # do something
    # and so on...

In HABApp I tried the following. But the rule is not called.

import HABApp
from HABApp.openhab.items import SwitchItem, NumberItem
from HABApp.openhab.events import ItemStateUpdatedEventFilter, ItemStateChangedEventFilter


class DialCodes(HABApp.Rule):
    def __init__(self):
        super().__init__()

        self.alarmPhone = NumberItem.get_item('alarmPhone_dialPlate')
        self.alarmPhone.listen_event(self.handle_dial_code, ItemStateUpdatedEventFilter())

        self.wallPhone = NumberItem.get_item('wallPhone_dialPlate')
        self.wallPhone.listen_event(self.handle_dial_code, ItemStateUpdatedEventFilter())

        self.actions = {
            1: self.toggle_lights_in_living_room,
            2: DialCodes.none,
            3: self.toggle_power_of_espresso_machine,
            4: self.toggle_lights_in_bathroom,
            5: self.toggle_power_switch,
            6: self.toggle_surveillance_state,
            7: self.ring_bell,
            8: DialCodes.none,
            9: DialCodes.none,
            0: DialCodes.none
        }

    def handle_dial_code(self, event):
        print(f'Dial Code: {event.value}')
        self.actions[event.value]()

    @staticmethod
    def toggle_switch(switch_item_name):
        switch = SwitchItem.get_item(switch_item_name)
        if switch.is_on():
            switch.off()
        else:
            switch.on()

    @staticmethod
    def none():
        pass

    def toggle_lights_in_living_room(self):
        self.toggle_switch('hue_switch_livingroom_lights')

    def toggle_power_of_espresso_machine(self):
        self.toggle_switch('hm_powerSwitch_espressoMachine')

    def toggle_lights_in_bathroom(self):
        self.toggle_switch('hm_powerSwitch_light')

    def toggle_power_switch(self):
        self.toggle_switch('hm_powerSwitch')

    def toggle_surveillance_state(self):
        self.toggle_switch('surveillance_enabled')

    def ring_bell(self):
        self.mqtt.publish('wallPhone/bell', '2')


DialCodes()

If I use ItemStateChangedEventFilter (not …Updated…) and dial different numbers, it works. But I don’t want to get an event on changes only.

How do I have to use the ItemStateUpdatedEventFilter on a NumberItem?

Thanks!
Sebastian

I think, I found an even cleaner solution (for this case) by directly subscribing to the mqtt topics:

class DialCodes(HABApp.Rule):
    def __init__(self):
        super().__init__()

        self.alarm_phone = MqttItem.get_create_item('alarmPhone/dialPlate')
        self.wall_phone = MqttItem.get_create_item('wallPhone/dialPlate')

        self.listen_event('alarmPhone/dialPlate', self.handle_dial_code, ValueUpdateEventFilter())
        self.listen_event('wallPhone/dialPlate', self.handle_dial_code, ValueUpdateEventFilter())

But in general, it should be possible to react on updates of a Number item right?

Which openHAB version are you running?
Do you see the event in the HABApp event log?
Older versions issue another event when updating.

I typically trigger on ValueUpdateEvent and ValueChangeEvent from HABApp.core.event.

Edit:
I think you neet the ItemStateEventFilter if you are running an older version of openHAB.
In any case you can just look at the HABApp event log, you should see all events there.

I’m still using openHAB 3.3.0 (and HABApp 23.11.0). But will update to 4.x in the near future.

Thanks for the hint to log/events.log. I found this:

[          HABApp.EventBus]     INFO | alarmPhone/dialPlate: <MqttValueUpdateEvent name: alarmPhone/dialPlate, value: 8>
[          HABApp.EventBus]     INFO | alarmPhone_dialPlate: <ItemStateEvent name: alarmPhone_dialPlate, value: 8>
[          HABApp.EventBus]     INFO | alarmPhone_dialPlate: <ItemStateChangedEvent name: alarmPhone_dialPlate, value: 8, old_value: 7>

[          HABApp.EventBus]     INFO | alarmPhone/dialPlate: <MqttValueUpdateEvent name: alarmPhone/dialPlate, value: 8>
[          HABApp.EventBus]     INFO | alarmPhone_dialPlate: <ItemStateEvent name: alarmPhone_dialPlate, value: 8>

It works if I use ItemStateEventFilter on the NumberItem:

self.alarmPhone.listen_event(self.handle_dial_code, ItemStateEventFilter())

Not sure how to use ValueUpdateEvent and ValueChangeEvent. Is this possible with an openhab item?

Yes - you can use it instead of ItemState[Updated]EventFilter.
You already do this for mqtt where you use the ValueUpdateEventFilter ìnstead of MqttValueUpdateEventFilter

1 Like

Ah now I get it. I tried to use the Event, not the EventFilter…

This works too:

self.alarmPhone = NumberItem.get_item('alarmPhone_dialPlate')
self.alarmPhone.listen_event(self.handle_dial_code, ValueUpdateEventFilter())

Thanks for your help!

The ValueUpdateEvent is the parent of the ItemStateUpdatedEvent or the MqttValueUpdateEvent.
So filtering with the ValueUpdateEventFilter will pass both the events, but since the openHAB item will only receive the ItemStateUpdatedEvent you will get only that with the filter.

It’s a more easy way without having to remember all the item names.
You can also see the inheritance diagram in the docs.

1 Like

This topic was automatically closed 41 days after the last reply. New replies are no longer allowed.