HABApp - Easy automation with openHAB

Using Visual Studio Code with remote SSH and python extensin with Habapp

I am trying to use VSC on my windows laptop remotely connected to my raspberry pi v4 (but i would also like to use my pi 3b).
I always get the error

Import "HABApp.core.events" could not be resolvedPylancereportMissingImports

It may be obvious but I am unable to find the right setting of python or pylance extension
(python.venvFolders?)

Can someone point me in the right direction?
Thank you
EDIT: I figured out myself, and I post here the solution.
The point is to set in VSC the “version” of the python interpreter, as explained at this link.

Then, in order to have also files contained in the habapp/lib directory the pylint setting

"python.analysis.extraPaths": [ "/srv/openhab-conf/habapp/lib"]

should be set

Good news everyone! HABApp 1.0 is out!

1 Like

hello,
i have installed openhabian on a rpi4b an work on oh3.4.0.m3 with installed habapp 1.0.4
i suddenly realize lots of errors in the habapp.log that appear continuosly:

[2022-10-18 11:01:14,802] [                   HABApp]     INFO | HABApp Version 1.0.4
[2022-10-18 11:01:14,802] [            HABApp.Config]     WARN | Replaced class for handler "HABApp_default" with HABApp.config.logging.MidnightRotatingFileHandler
[2022-10-18 11:01:14,802] [            HABApp.Config]     WARN | Replaced class for handler "My_HABApp_default" with HABApp.config.logging.MidnightRotatingFileHandler
[2022-10-18 11:01:14,866] [   HABApp.mqtt.connection]     INFO | MQTT disabled
[2022-10-18 11:01:14,992] [HABApp.openhab.connection]     INFO | Connected to OpenHAB version 3.4.0.M3 (Milestone Build)
[2022-10-18 11:01:15,933] [     HABApp.openhab.items]     INFO | Updated 584 Items
[2022-10-18 11:01:16,241] [     HABApp.openhab.items]     INFO | Updated 257 Things
[2022-10-18 11:01:16,877] [          HABApp.EventBus]     INFO |              iSl_pac: <ItemStateEvent name: iSl_pac, value: 8560>
[2022-10-18 11:01:16,882] [          HABApp.EventBus]     INFO |              iSl_pac: <ItemStateChangedEvent name: iSl_pac, value: 8560, old_value: 8527>
[2022-10-18 11:01:16,885] [          HABApp.EventBus]     INFO |         iSl_yieldday: <ItemStateEvent name: iSl_yieldday, value: 11571>
[2022-10-18 11:01:16,887] [          HABApp.EventBus]     INFO |    solarlog:meter:pv: <ThingStatusInfoEvent name: solarlog:meter:pv, status: ONLINE, detail: None>
[2022-10-18 11:01:16,888] [          HABApp.EventBus]     INFO |         iSl_yieldday: <ItemStateChangedEvent name: iSl_yieldday, value: 11571, old_value: 11500>
[2022-10-18 11:01:23,654] [                   HABApp]    ERROR | Error 'topic' in on_sse_event:
[2022-10-18 11:01:23,654] [                   HABApp]    ERROR | File "/opt/habapp/lib/python3.9/site-packages/HABApp/openhab/connection_handler/sse_handler.py", line 31 in on_sse_event
[2022-10-18 11:01:23,654] [                   HABApp]    ERROR | --------------------------------------------------------------------------------
[2022-10-18 11:01:23,654] [                   HABApp]    ERROR |      28 | def on_sse_event(event_dict: dict):
[2022-10-18 11:01:23,654] [                   HABApp]    ERROR |      29 |     try:
[2022-10-18 11:01:23,655] [                   HABApp]    ERROR |      30 |         # Lookup corresponding OpenHAB event
[2022-10-18 11:01:23,655] [                   HABApp]    ERROR | -->  31 |         event = get_event(event_dict)
[2022-10-18 11:01:23,655] [                   HABApp]    ERROR |      33 |         # Update item in registry BEFORE posting to the event bus
[2022-10-18 11:01:23,655] [                   HABApp]    ERROR |      34 |         # so the items have the correct state when we process the event in a rule
[2022-10-18 11:01:23,655] [                   HABApp]    ERROR |    ------------------------------------------------------------
[2022-10-18 11:01:23,655] [                   HABApp]    ERROR |      (ItemAddedEvent, ItemUpdatedEvent) = (<class 'HABApp.openhab.events.item_events.ItemAddedEvent'>, <class 'HABApp.openhab.events.item_events.ItemUpdatedEvent'>)
[2022-10-18 11:01:23,655] [                   HABApp]    ERROR |      (ThingStatusInfoEvent, ThingUpdatedEvent) = (<class 'HABApp.openhab.events.thing_events.ThingStatusInfoEvent'>, <class 'HABApp.openhab.events.thing_events.ThingUpdatedEvent'>)
[2022-10-18 11:01:23,656] [                   HABApp]    ERROR |      e = KeyError('topic')
[2022-10-18 11:01:23,656] [                   HABApp]    ERROR |      event_dict = {'type': 'ALIVE', 'interval': 10}
[2022-10-18 11:01:23,656] [                   HABApp]    ERROR |      log = <Logger HABApp.openhab.connection (INFO)>
[2022-10-18 11:01:23,656] [                   HABApp]    ERROR |      TOPIC_ITEMS = 'openHAB.Items'
[2022-10-18 11:01:23,656] [                   HABApp]    ERROR |      TOPIC_THINGS = 'openHAB.Things'
[2022-10-18 11:01:23,656] [                   HABApp]    ERROR |    ------------------------------------------------------------
[2022-10-18 11:01:23,656] [                   HABApp]    ERROR | 
[2022-10-18 11:01:23,657] [                   HABApp]    ERROR | File "/opt/habapp/lib/python3.9/site-packages/HABApp/openhab/map_events.py", line 31 in get_event
[2022-10-18 11:01:23,657] [                   HABApp]    ERROR | --------------------------------------------------------------------------------
[2022-10-18 11:01:23,657] [                   HABApp]    ERROR |      29 | def get_event(_in_dict: dict) -> OpenhabEvent:
[2022-10-18 11:01:23,657] [                   HABApp]    ERROR |      30 |     event_type: str = _in_dict['type']
[2022-10-18 11:01:23,657] [                   HABApp]    ERROR | -->  31 |     topic: str = _in_dict['topic']
[2022-10-18 11:01:23,657] [                   HABApp]    ERROR |      33 |     # Workaround for None values in the payload str
[2022-10-18 11:01:23,658] [                   HABApp]    ERROR |    ------------------------------------------------------------
[2022-10-18 11:01:23,658] [                   HABApp]    ERROR |      _events = {'ItemStateEvent': <class 'HABApp.openhab.events.item_events.ItemStateEvent'>, 'ItemStateChangedEvent': <class 'HABApp.openhab.events.item_events.ItemStateChangedEvent'>, 'ItemCommandEvent': <class 'HABApp.openhab.events.item_events.ItemCommandEvent'>, 'ItemAddedEvent': <class 'HABApp.openhab.events.item_events.ItemAddedEvent'>, 'ItemUpdatedEvent': <class 'HABApp.openhab.events.item_events.ItemUpdatedEvent'>, 'ItemRemovedEvent': <class 'HABApp.openhab.events.item_events.ItemRemovedEvent'>, 'ItemStatePredictedEvent': <class 'HABApp.openhab.events.item_events.ItemStatePredictedEvent'>, 'GroupItemStateChangedEvent': <class 'HABApp.openhab.events.item_events.GroupItemStateChangedEvent'>, 'ChannelTriggeredEvent': <class 'HABApp.openhab.events.channel_events.ChannelTriggeredEvent'>, 'ChannelDescriptionChangedEvent': <class 'HABApp.openhab.events.channel_events.ChannelDescriptionChangedEvent'>, 'ThingAddedEvent': <class 'HABApp.openhab.events.thing_events.ThingAddedEvent'>, 'ThingRemovedEvent': <class 'HABApp.openhab.events.thing_events.ThingRemovedEvent'>, 'ThingUpdatedEvent': <class 'HABApp.openhab.events.thing_events.ThingUpdatedEvent'>, 'ThingStatusInfoEvent': <class 'HABApp.openhab.events.thing_events.ThingStatusInfoEvent'>, 'ThingStatusInfoChangedEvent': <class 'HABApp.openhab.events.thing_events.ThingStatusInfoChangedEvent'>, 'ThingFirmwareStatusInfoEvent': <class 'HABApp.openhab.events.thing_events.ThingFirmwareStatusInfoEvent'>, 'FirmwareStatusInfoEvent': <class 'HABApp.openhab.events.thing_events.ThingFirmwareStatusInfoEvent'>}
[2022-10-18 11:01:23,658] [                   HABApp]    ERROR |      _in_dict = {'type': 'ALIVE', 'interval': 10}
[2022-10-18 11:01:23,658] [                   HABApp]    ERROR |      _in_dict['type'] = 'ALIVE'
[2022-10-18 11:01:23,658] [                   HABApp]    ERROR |      event_type = 'ALIVE'
[2022-10-18 11:01:23,658] [                   HABApp]    ERROR |    ------------------------------------------------------------
[2022-10-18 11:01:23,659] [                   HABApp]    ERROR | 
[2022-10-18 11:01:23,659] [                   HABApp]    ERROR | --------------------------------------------------------------------------------
[2022-10-18 11:01:23,659] [                   HABApp]    ERROR | Traceback (most recent call last):
[2022-10-18 11:01:23,659] [                   HABApp]    ERROR |   File "/opt/habapp/lib/python3.9/site-packages/HABApp/openhab/connection_handler/sse_handler.py", line 31, in on_sse_event
[2022-10-18 11:01:23,659] [                   HABApp]    ERROR |     event = get_event(event_dict)
[2022-10-18 11:01:23,659] [                   HABApp]    ERROR |   File "/opt/habapp/lib/python3.9/site-packages/HABApp/openhab/map_events.py", line 31, in get_event
[2022-10-18 11:01:23,659] [                   HABApp]    ERROR |     topic: str = _in_dict['topic']
[2022-10-18 11:01:23,660] [                   HABApp]    ERROR | KeyError: 'topic'
[2022-10-18 11:01:23,660] [          HABApp.EventBus]     INFO |        HABApp.Errors: <HABAppException func_name: on_sse_event, exception: 'topic'>
[2022-10-18 11:01:33,536] [                   HABApp]    ERROR | Error 'topic' in on_sse_event:
[2022-10-18 11:01:33,536] [                   HABApp]    ERROR | File "/opt/habapp/lib/python3.9/site-packages/HABApp/openhab/connection_handler/sse_handler.py", line 31 in on_sse_event
[2022-10-18 11:01:33,536] [                   HABApp]    ERROR | --------------------------------------------------------------------------------
[2022-10-18 11:01:33,537] [                   HABApp]    ERROR |      28 | def on_sse_event(event_dict: dict):
[2022-10-18 11:01:33,537] [                   HABApp]    ERROR |      29 |     try:
[2022-10-18 11:01:33,537] [                   HABApp]    ERROR |      30 |         # Lookup corresponding OpenHAB event
[2022-10-18 11:01:33,537] [                   HABApp]    ERROR | -->  31 |         event = get_event(event_dict)
[2022-10-18 11:01:33,537] [                   HABApp]    ERROR |      33 |         # Update item in registry BEFORE posting to the event bus
[2022-10-18 11:01:33,537] [                   HABApp]    ERROR |      34 |         # so the items have the correct state when we process the event in a rule
[2022-10-18 11:01:33,538] [                   HABApp]    ERROR |    ------------------------------------------------------------
[2022-10-18 11:01:33,538] [                   HABApp]    ERROR |      (ItemAddedEvent, ItemUpdatedEvent) = (<class 'HABApp.openhab.events.item_events.ItemAddedEvent'>, <class 'HABApp.openhab.events.item_events.ItemUpdatedEvent'>)
[2022-10-18 11:01:33,538] [                   HABApp]    ERROR |      (ThingStatusInfoEvent, ThingUpdatedEvent) = (<class 'HABApp.openhab.events.thing_events.ThingStatusInfoEvent'>, <class 'HABApp.openhab.events.thing_events.ThingUpdatedEvent'>)
[2022-10-18 11:01:33,538] [                   HABApp]    ERROR |      e = KeyError('topic')
[2022-10-18 11:01:33,538] [                   HABApp]    ERROR |      event_dict = {'type': 'ALIVE', 'interval': 10}
[2022-10-18 11:01:33,538] [                   HABApp]    ERROR |      log = <Logger HABApp.openhab.connection (INFO)>
[2022-10-18 11:01:33,538] [                   HABApp]    ERROR |      TOPIC_ITEMS = 'openHAB.Items'
[2022-10-18 11:01:33,538] [                   HABApp]    ERROR |      TOPIC_THINGS = 'openHAB.Things'
[2022-10-18 11:01:33,539] [                   HABApp]    ERROR |    ------------------------------------------------------------
[2022-10-18 11:01:33,539] [                   HABApp]    ERROR | 
[2022-10-18 11:01:33,539] [                   HABApp]    ERROR | File "/opt/habapp/lib/python3.9/site-packages/HABApp/openhab/map_events.py", line 31 in get_event
[2022-10-18 11:01:33,539] [                   HABApp]    ERROR | --------------------------------------------------------------------------------
[2022-10-18 11:01:33,539] [                   HABApp]    ERROR |      29 | def get_event(_in_dict: dict) -> OpenhabEvent:
[2022-10-18 11:01:33,539] [                   HABApp]    ERROR |      30 |     event_type: str = _in_dict['type']
[2022-10-18 11:01:33,539] [                   HABApp]    ERROR | -->  31 |     topic: str = _in_dict['topic']
[2022-10-18 11:01:33,539] [                   HABApp]    ERROR |      33 |     # Workaround for None values in the payload str
[2022-10-18 11:01:33,540] [                   HABApp]    ERROR |    ------------------------------------------------------------
[2022-10-18 11:01:33,540] [                   HABApp]    ERROR |      _events = {'ItemStateEvent': <class 'HABApp.openhab.events.item_events.ItemStateEvent'>, 'ItemStateChangedEvent': <class 'HABApp.openhab.events.item_events.ItemStateChangedEvent'>, 'ItemCommandEvent': <class 'HABApp.openhab.events.item_events.ItemCommandEvent'>, 'ItemAddedEvent': <class 'HABApp.openhab.events.item_events.ItemAddedEvent'>, 'ItemUpdatedEvent': <class 'HABApp.openhab.events.item_events.ItemUpdatedEvent'>, 'ItemRemovedEvent': <class 'HABApp.openhab.events.item_events.ItemRemovedEvent'>, 'ItemStatePredictedEvent': <class 'HABApp.openhab.events.item_events.ItemStatePredictedEvent'>, 'GroupItemStateChangedEvent': <class 'HABApp.openhab.events.item_events.GroupItemStateChangedEvent'>, 'ChannelTriggeredEvent': <class 'HABApp.openhab.events.channel_events.ChannelTriggeredEvent'>, 'ChannelDescriptionChangedEvent': <class 'HABApp.openhab.events.channel_events.ChannelDescriptionChangedEvent'>, 'ThingAddedEvent': <class 'HABApp.openhab.events.thing_events.ThingAddedEvent'>, 'ThingRemovedEvent': <class 'HABApp.openhab.events.thing_events.ThingRemovedEvent'>, 'ThingUpdatedEvent': <class 'HABApp.openhab.events.thing_events.ThingUpdatedEvent'>, 'ThingStatusInfoEvent': <class 'HABApp.openhab.events.thing_events.ThingStatusInfoEvent'>, 'ThingStatusInfoChangedEvent': <class 'HABApp.openhab.events.thing_events.ThingStatusInfoChangedEvent'>, 'ThingFirmwareStatusInfoEvent': <class 'HABApp.openhab.events.thing_events.ThingFirmwareStatusInfoEvent'>, 'FirmwareStatusInfoEvent': <class 'HABApp.openhab.events.thing_events.ThingFirmwareStatusInfoEvent'>}
[2022-10-18 11:01:33,540] [                   HABApp]    ERROR |      _in_dict = {'type': 'ALIVE', 'interval': 10}
[2022-10-18 11:01:33,540] [                   HABApp]    ERROR |      _in_dict['type'] = 'ALIVE'
[2022-10-18 11:01:33,540] [                   HABApp]    ERROR |      event_type = 'ALIVE'
[2022-10-18 11:01:33,540] [                   HABApp]    ERROR |    ------------------------------------------------------------
[2022-10-18 11:01:33,540] [                   HABApp]    ERROR | 
[2022-10-18 11:01:33,541] [                   HABApp]    ERROR | --------------------------------------------------------------------------------
[2022-10-18 11:01:33,541] [                   HABApp]    ERROR | Traceback (most recent call last):
[2022-10-18 11:01:33,541] [                   HABApp]    ERROR |   File "/opt/habapp/lib/python3.9/site-packages/HABApp/openhab/connection_handler/sse_handler.py", line 31, in on_sse_event
[2022-10-18 11:01:33,541] [                   HABApp]    ERROR |     event = get_event(event_dict)
[2022-10-18 11:01:33,541] [                   HABApp]    ERROR |   File "/opt/habapp/lib/python3.9/site-packages/HABApp/openhab/map_events.py", line 31, in get_event
[2022-10-18 11:01:33,541] [                   HABApp]    ERROR |     topic: str = _in_dict['topic']
[2022-10-18 11:01:33,541] [                   HABApp]    ERROR | KeyError: 'topic'
[2022-10-18 11:01:33,541] [          HABApp.EventBus]     INFO |        HABApp.Errors: <HABAppException func_name: on_sse_event, exception: 'topic'>
[2022-10-18 11:01:43,535] [                   HABApp]    ERROR | Error 'topic' in on_sse_event:
[2022-10-18 11:01:43,535] [                   HABApp]    ERROR | File "/opt/habapp/lib/python3.9/site-packages/HABApp/openhab/connection_handler/sse_handler.py", line 31 in on_sse_event
[2022-10-18 11:01:43,535] [                   HABApp]    ERROR | --------------------------------------------------------------------------------
[2022-10-18 11:01:43,536] [                   HABApp]    ERROR |      28 | def on_sse_event(event_dict: dict):
[2022-10-18 11:01:43,536] [                   HABApp]    ERROR |      29 |     try:
[2022-10-18 11:01:43,536] [                   HABApp]    ERROR |      30 |         # Lookup corresponding OpenHAB event
[2022-10-18 11:01:43,536] [                   HABApp]    ERROR | -->  31 |         event = get_event(event_dict)
[2022-10-18 11:01:43,537] [                   HABApp]    ERROR |      33 |         # Update item in registry BEFORE posting to the event bus
[2022-10-18 11:01:43,537] [                   HABApp]    ERROR |      34 |         # so the items have the correct state when we process the event in a rule
[2022-10-18 11:01:43,537] [                   HABApp]    ERROR |    ------------------------------------------------------------
[2022-10-18 11:01:43,537] [                   HABApp]    ERROR |      (ItemAddedEvent, ItemUpdatedEvent) = (<class 'HABApp.openhab.events.item_events.ItemAddedEvent'>, <class 'HABApp.openhab.events.item_events.ItemUpdatedEvent'>)
[2022-10-18 11:01:43,537] [                   HABApp]    ERROR |      (ThingStatusInfoEvent, ThingUpdatedEvent) = (<class 'HABApp.openhab.events.thing_events.ThingStatusInfoEvent'>, <class 'HABApp.openhab.events.thing_events.ThingUpdatedEvent'>)
[2022-10-18 11:01:43,538] [                   HABApp]    ERROR |      e = KeyError('topic')
[2022-10-18 11:01:43,538] [                   HABApp]    ERROR |      event_dict = {'type': 'ALIVE', 'interval': 10}
[2022-10-18 11:01:43,538] [                   HABApp]    ERROR |      log = <Logger HABApp.openhab.connection (INFO)>
[2022-10-18 11:01:43,538] [                   HABApp]    ERROR |      TOPIC_ITEMS = 'openHAB.Items'
[2022-10-18 11:01:43,538] [                   HABApp]    ERROR |      TOPIC_THINGS = 'openHAB.Things'
[2022-10-18 11:01:43,538] [                   HABApp]    ERROR |    ------------------------------------------------------------
[2022-10-18 11:01:43,539] [                   HABApp]    ERROR | 
[2022-10-18 11:01:43,539] [                   HABApp]    ERROR | File "/opt/habapp/lib/python3.9/site-packages/HABApp/openhab/map_events.py", line 31 in get_event
[2022-10-18 11:01:43,539] [                   HABApp]    ERROR | --------------------------------------------------------------------------------
[2022-10-18 11:01:43,539] [                   HABApp]    ERROR |      29 | def get_event(_in_dict: dict) -> OpenhabEvent:
[2022-10-18 11:01:43,539] [                   HABApp]    ERROR |      30 |     event_type: str = _in_dict['type']
[2022-10-18 11:01:43,539] [                   HABApp]    ERROR | -->  31 |     topic: str = _in_dict['topic']
[2022-10-18 11:01:43,539] [                   HABApp]    ERROR |      33 |     # Workaround for None values in the payload str
[2022-10-18 11:01:43,540] [                   HABApp]    ERROR |    ------------------------------------------------------------
[2022-10-18 11:01:43,540] [                   HABApp]    ERROR |      _events = {'ItemStateEvent': <class 'HABApp.openhab.events.item_events.ItemStateEvent'>, 'ItemStateChangedEvent': <class 'HABApp.openhab.events.item_events.ItemStateChangedEvent'>, 'ItemCommandEvent': <class 'HABApp.openhab.events.item_events.ItemCommandEvent'>, 'ItemAddedEvent': <class 'HABApp.openhab.events.item_events.ItemAddedEvent'>, 'ItemUpdatedEvent': <class 'HABApp.openhab.events.item_events.ItemUpdatedEvent'>, 'ItemRemovedEvent': <class 'HABApp.openhab.events.item_events.ItemRemovedEvent'>, 'ItemStatePredictedEvent': <class 'HABApp.openhab.events.item_events.ItemStatePredictedEvent'>, 'GroupItemStateChangedEvent': <class 'HABApp.openhab.events.item_events.GroupItemStateChangedEvent'>, 'ChannelTriggeredEvent': <class 'HABApp.openhab.events.channel_events.ChannelTriggeredEvent'>, 'ChannelDescriptionChangedEvent': <class 'HABApp.openhab.events.channel_events.ChannelDescriptionChangedEvent'>, 'ThingAddedEvent': <class 'HABApp.openhab.events.thing_events.ThingAddedEvent'>, 'ThingRemovedEvent': <class 'HABApp.openhab.events.thing_events.ThingRemovedEvent'>, 'ThingUpdatedEvent': <class 'HABApp.openhab.events.thing_events.ThingUpdatedEvent'>, 'ThingStatusInfoEvent': <class 'HABApp.openhab.events.thing_events.ThingStatusInfoEvent'>, 'ThingStatusInfoChangedEvent': <class 'HABApp.openhab.events.thing_events.ThingStatusInfoChangedEvent'>, 'ThingFirmwareStatusInfoEvent': <class 'HABApp.openhab.events.thing_events.ThingFirmwareStatusInfoEvent'>, 'FirmwareStatusInfoEvent': <class 'HABApp.openhab.events.thing_events.ThingFirmwareStatusInfoEvent'>}
[2022-10-18 11:01:43,540] [                   HABApp]    ERROR |      _in_dict = {'type': 'ALIVE', 'interval': 10}
[2022-10-18 11:01:43,540] [                   HABApp]    ERROR |      _in_dict['type'] = 'ALIVE'
[2022-10-18 11:01:43,540] [                   HABApp]    ERROR |      event_type = 'ALIVE'
[2022-10-18 11:01:43,540] [                   HABApp]    ERROR |    ------------------------------------------------------------
[2022-10-18 11:01:43,541] [                   HABApp]    ERROR | 
[2022-10-18 11:01:43,541] [                   HABApp]    ERROR | --------------------------------------------------------------------------------
[2022-10-18 11:01:43,541] [                   HABApp]    ERROR | Traceback (most recent call last):
[2022-10-18 11:01:43,541] [                   HABApp]    ERROR |   File "/opt/habapp/lib/python3.9/site-packages/HABApp/openhab/connection_handler/sse_handler.py", line 31, in on_sse_event
[2022-10-18 11:01:43,541] [                   HABApp]    ERROR |     event = get_event(event_dict)
[2022-10-18 11:01:43,541] [                   HABApp]    ERROR |   File "/opt/habapp/lib/python3.9/site-packages/HABApp/openhab/map_events.py", line 31, in get_event
[2022-10-18 11:01:43,541] [                   HABApp]    ERROR |     topic: str = _in_dict['topic']
[2022-10-18 11:01:43,542] [                   HABApp]    ERROR | KeyError: 'topic'
[2022-10-18 11:01:43,542] [          HABApp.EventBus]     INFO |        HABApp.Errors: <HABAppException func_name: on_sse_event, exception: 'topic'>
[2022-10-18 11:01:46,946] [          HABApp.EventBus]     INFO |              iSl_pac: <ItemStateEvent name: iSl_pac, value: 8576>
[2022-10-18 11:01:46,951] [          HABApp.EventBus]     INFO |         iSl_yieldday: <ItemStateEvent name: iSl_yieldday, value: 11642>
[2022-10-18 11:01:46,953] [          HABApp.EventBus]     INFO |              iSl_pac: <ItemStateChangedEvent name: iSl_pac, value: 8576, old_value: 8560>
[2022-10-18 11:01:46,955] [          HABApp.EventBus]     INFO |    solarlog:meter:pv: <ThingStatusInfoEvent name: solarlog:meter:pv, status: ONLINE, detail: None>
[2022-10-18 11:01:46,956] [          HABApp.EventBus]     INFO |         iSl_yieldday: <ItemStateChangedEvent name: iSl_yieldday, value: 11642, old_value: 11571>
[2022-10-18 11:01:53,535] [                   HABApp]    ERROR | Error 'topic' in on_sse_event:
[2022-10-18 11:01:53,536] [                   HABApp]    ERROR | File "/opt/habapp/lib/python3.9/site-packages/HABApp/openhab/connection_handler/sse_handler.py", line 31 in on_sse_event
[2022-10-18 11:01:53,536] [                   HABApp]    ERROR | --------------------------------------------------------------------------------
[2022-10-18 11:01:53,536] [                   HABApp]    ERROR |      28 | def on_sse_event(event_dict: dict):
[2022-10-18 11:01:53,536] [                   HABApp]    ERROR |      29 |     try:
[2022-10-18 11:01:53,537] [                   HABApp]    ERROR |      30 |         # Lookup corresponding OpenHAB event
[2022-10-18 11:01:53,537] [                   HABApp]    ERROR | -->  31 |         event = get_event(event_dict)
[2022-10-18 11:01:53,537] [                   HABApp]    ERROR |      33 |         # Update item in registry BEFORE posting to the event bus
[2022-10-18 11:01:53,537] [                   HABApp]    ERROR |      34 |         # so the items have the correct state when we process the event in a rule
[2022-10-18 11:01:53,538] [                   HABApp]    ERROR |    ------------------------------------------------------------
[2022-10-18 11:01:53,538] [                   HABApp]    ERROR |      (ItemAddedEvent, ItemUpdatedEvent) = (<class 'HABApp.openhab.events.item_events.ItemAddedEvent'>, <class 'HABApp.openhab.events.item_events.ItemUpdatedEvent'>)
[2022-10-18 11:01:53,538] [                   HABApp]    ERROR |      (ThingStatusInfoEvent, ThingUpdatedEvent) = (<class 'HABApp.openhab.events.thing_events.ThingStatusInfoEvent'>, <class 'HABApp.openhab.events.thing_events.ThingUpdatedEvent'>)
[2022-10-18 11:01:53,538] [                   HABApp]    ERROR |      e = KeyError('topic')
[2022-10-18 11:01:53,539] [                   HABApp]    ERROR |      event_dict = {'type': 'ALIVE', 'interval': 10}
[2022-10-18 11:01:53,539] [                   HABApp]    ERROR |      log = <Logger HABApp.openhab.connection (INFO)>
[2022-10-18 11:01:53,539] [                   HABApp]    ERROR |      TOPIC_ITEMS = 'openHAB.Items'
[2022-10-18 11:01:53,539] [                   HABApp]    ERROR |      TOPIC_THINGS = 'openHAB.Things'
[2022-10-18 11:01:53,539] [                   HABApp]    ERROR |    ------------------------------------------------------------
[2022-10-18 11:01:53,540] [                   HABApp]    ERROR | 
[2022-10-18 11:01:53,540] [                   HABApp]    ERROR | File "/opt/habapp/lib/python3.9/site-packages/HABApp/openhab/map_events.py", line 31 in get_event
[2022-10-18 11:01:53,540] [                   HABApp]    ERROR | --------------------------------------------------------------------------------
[2022-10-18 11:01:53,540] [                   HABApp]    ERROR |      29 | def get_event(_in_dict: dict) -> OpenhabEvent:
[2022-10-18 11:01:53,541] [                   HABApp]    ERROR |      30 |     event_type: str = _in_dict['type']
[2022-10-18 11:01:53,541] [                   HABApp]    ERROR | -->  31 |     topic: str = _in_dict['topic']
[2022-10-18 11:01:53,541] [                   HABApp]    ERROR |      33 |     # Workaround for None values in the payload str
[2022-10-18 11:01:53,541] [                   HABApp]    ERROR |    ------------------------------------------------------------
[2022-10-18 11:01:53,542] [                   HABApp]    ERROR |      _events = {'ItemStateEvent': <class 'HABApp.openhab.events.item_events.ItemStateEvent'>, 'ItemStateChangedEvent': <class 'HABApp.openhab.events.item_events.ItemStateChangedEvent'>, 'ItemCommandEvent': <class 'HABApp.openhab.events.item_events.ItemCommandEvent'>, 'ItemAddedEvent': <class 'HABApp.openhab.events.item_events.ItemAddedEvent'>, 'ItemUpdatedEvent': <class 'HABApp.openhab.events.item_events.ItemUpdatedEvent'>, 'ItemRemovedEvent': <class 'HABApp.openhab.events.item_events.ItemRemovedEvent'>, 'ItemStatePredictedEvent': <class 'HABApp.openhab.events.item_events.ItemStatePredictedEvent'>, 'GroupItemStateChangedEvent': <class 'HABApp.openhab.events.item_events.GroupItemStateChangedEvent'>, 'ChannelTriggeredEvent': <class 'HABApp.openhab.events.channel_events.ChannelTriggeredEvent'>, 'ChannelDescriptionChangedEvent': <class 'HABApp.openhab.events.channel_events.ChannelDescriptionChangedEvent'>, 'ThingAddedEvent': <class 'HABApp.openhab.events.thing_events.ThingAddedEvent'>, 'ThingRemovedEvent': <class 'HABApp.openhab.events.thing_events.ThingRemovedEvent'>, 'ThingUpdatedEvent': <class 'HABApp.openhab.events.thing_events.ThingUpdatedEvent'>, 'ThingStatusInfoEvent': <class 'HABApp.openhab.events.thing_events.ThingStatusInfoEvent'>, 'ThingStatusInfoChangedEvent': <class 'HABApp.openhab.events.thing_events.ThingStatusInfoChangedEvent'>, 'ThingFirmwareStatusInfoEvent': <class 'HABApp.openhab.events.thing_events.ThingFirmwareStatusInfoEvent'>, 'FirmwareStatusInfoEvent': <class 'HABApp.openhab.events.thing_events.ThingFirmwareStatusInfoEvent'>}
[2022-10-18 11:01:53,542] [                   HABApp]    ERROR |      _in_dict = {'type': 'ALIVE', 'interval': 10}
[2022-10-18 11:01:53,542] [                   HABApp]    ERROR |      _in_dict['type'] = 'ALIVE'
[2022-10-18 11:01:53,542] [                   HABApp]    ERROR |      event_type = 'ALIVE'
[2022-10-18 11:01:53,543] [                   HABApp]    ERROR |    ------------------------------------------------------------
[2022-10-18 11:01:53,543] [                   HABApp]    ERROR | 
[2022-10-18 11:01:53,543] [                   HABApp]    ERROR | --------------------------------------------------------------------------------
[2022-10-18 11:01:53,543] [                   HABApp]    ERROR | Traceback (most recent call last):
[2022-10-18 11:01:53,544] [                   HABApp]    ERROR |   File "/opt/habapp/lib/python3.9/site-packages/HABApp/openhab/connection_handler/sse_handler.py", line 31, in on_sse_event
[2022-10-18 11:01:53,544] [                   HABApp]    ERROR |     event = get_event(event_dict)
[2022-10-18 11:01:53,544] [                   HABApp]    ERROR |   File "/opt/habapp/lib/python3.9/site-packages/HABApp/openhab/map_events.py", line 31, in get_event
[2022-10-18 11:01:53,544] [                   HABApp]    ERROR |     topic: str = _in_dict['topic']
[2022-10-18 11:01:53,544] [                   HABApp]    ERROR | KeyError: 'topic'

i tried without success:

  • uninstalled habapp, deleted folder /opt/habapp and installed again
  • disabled my mqtt-things and 1wire-things
  • removed all rule files from habapp folder /rules and /lib

sorry i am lost with this error messages and would be glad if somebody could help me to eliminate them. thanks in advance

It’s a modified event type that came with 3.4.0 M3. Downgrading to 3.4 M2 will solve the issue.
The fix is already available in the dev branch. If you want to try it out you can install the dev branch.
Installation instruction can be found here. I’ll release the dev branch in the next 5 to 10 days.

1 Like

this did the trick, thank you very much!

9 posts were split to a new topic: Dynamically create HABApp Rules with auto discovery

What would be the best way to get the dates of the (oldest/…/newest) min and max values?

And I (as in google) could not find any documentation for return type OpenhabPersistenceData as it seems there is also a .from_dict() method?

If there is only one maximum you can do this:

max_value = -999_999
max_time = None
min_value = 999_999
min_time = None

for timestamp, value in returned_obj.data.items():
    if value > max_value:
        max_value = value
        max_time = timestamp
    if value < min_value:
        min_value = value
        min_time = timestamp

Ah, I see, thx. This is even nicer than list comprehension and sorting. Takes only one pass.
Why I was asking was that in my OH1 xtext based rule I had

Min = (TempIn.minimumSince(now.minusHours(hoursBack), dataStore).state as DecimalType)

So I wondered, if there was something similar in HABApp.

If you create an issue where you properly describe what your goal is and what you like to achieve I might implement it in one of the upcoming versions.

If you are only interested in the value there is the .min(), .max(), and average() function on the OpenhabPersistenceData object.

If you want this value(s) to refresh automatically you can use the AggregationItem to do everything in memory.

Has anyone any experience using HABapp with openHAB 4.0.0.M1?

I ask in advance…

Nope - I am still on 3.4 and haven’t run any tests yet.
But for now I don’t expect any problems.
If you try it out it would be nice if you could let us know …

Hi all,
I am currently moving some of my rules to HABApp and it works great so far. Thank you very much for this!
The one thing I can not get my head around is testing my rules. Can someone share an example?

Can you post an example rule which you want to test via pytest / unittest?

Sure! I started with a very simple rule:

...
class ZigbeeRule(HABApp.Rule):
    def __init__(self, base_name: str):
        super().__init__()

        soc = NumberItem.get_item(base_name + "_SoC")
        available = SwitchItem.get_item(base_name + "_Available")

        soc.listen_event(self.handle_soc, ItemStateChangedEventFilter())
        available.listen_event(self.handle_available, ItemStateChangedEventFilter())

        self.gotify = StringItem.get_item("Gotify")

    def handle_soc(self, event: ItemStateChangedEvent):
        if event.value < SOC_THRESH and event.old_value >= SOC_THRESH:
            self.gotify.oh_send_command(
                f"{event.name} bald leer! (SoC = {event.value}%)"
            )

    def handle_available(self, event: ItemStateChangedEvent):
        if not event.value:
            self.gotify.oh_send_command(f"{event.name} nicht verfügbar!")
...

I found the concept of mock items in the docs but I am missing some kind of ‘test fixture’.
I could imagine something like the following:

# setup
gotify = StringItem("Gotify", "init")
soc = NumberItem("Test_SoC", 50)
available = SwitchItem("Test_Available", "ON")

Items.add_item(gotify)
Items.add_item(soc)
Items.add_item(available)

ZigbeeRule("Test")

# test
soc.set_value(4)

assert gotify.get_value() == "expected"

# tear down
Items.pop_item("Gotify")
Items.pop_item("Test_SoC")
Items.pop_item("Test_Available")

Currently we have a mixture of rule definition and rule creation.
E.g. in one file there is

class MyRule(Rule):
   ...

MyRule()

This makes it impossible to import the rule class (rule definition) without creating an instance.
But for testing the rule should only be created in the test case so it’s independent of other test cases which might have been running before.
This is something that has to be solved before it’s possible to write clean and easy to use tests.
I can think of two three ways:

  • Separate rule definition and rule creation in different files. However this creates much overhead and I think it’s not work the additional effort for the HABApp users. E.g.
class MyRule(Rule):
   ...
from file_a import MyRule
MyRule()
  • Write some kind of pre-processor that removes the rule creation statements and dynamically imports the rule module (difficult)
  • Patch the environment so the automatically created rules will automatically get unloaded again before the tests run (difficult, because rule creation can depend on existing items)

I think it would be nice to have an easy way to test the rules but while it sounds easy at first when done properly an implementation is quite hard.
With a static code checker you can already catch many issues now so I didn’t think that an easy way to test was that important.

@nobbi123 I know you already do some testing, how have you solved these issues?

1 Like

Sorry, my time is very limited, these days :frowning:
I will try to post an example on weekend.

Short: I have separate files for rule creation and definition.

If I create a module, lets say mymodule.py with the following code:

def greeting(name):
  return ("Hello, " + name)

And then I use the module in a HABApp rules file by using the import statement:

import mymodule

mymodule.greeting("Adam")

I can now use that mode from several HABApp rules file. However if I’d like to allow that module to use the openhab object I could probably use a class like this in my module file:

import HABApp
class MyClass(HABApp.Rule):
    def __init__(self):
        super().__init__()
    def greeting(name):
        self.log.debug("Hello, " + name)
        self.openhab.post_update('MySwitch', OFF)
        return ("Hello, " + name)

I’m not sure but it feels wrong to create a HABApp.Rule instance for this because it’s not really a HABApp.Rule. Would there be any other way to access the openhab object that I get access to by using the HABApp.Rule? Small code example would be really helpful. Thanks in advance!

In modules I use

import HABApp.openhab.interface as interface
...
in code:
    interface.post_update( item_name, value )
    interface.send_command ( item_name, cmd )

To be warned, at least today it is not officially documented.

If you are worried about it, you could pass self.openhab as parameter to greeting().

1 Like

Be aware that you should put the file mymodule.py in the lib folder.
Have you done that?

It’s not officially documented because it’s not officially supported. :wink:
There are so many things that can actually go wrong and so many things that you have to ensure.
It’s easy to build something that works sometimes but also breaks sometimes and error search can be very very hard.

There is almost always a more elegant option to achieve the same, e.g.

  • using the HABApp event bus to pass data between rule instances where one rule instance acts as e.g. a worker
  • self.get_rule()

@RRoe What are you actually trying to do? Maybe there is an easier way … .