Why is HABapp with a config.yml "listen_only: True" not so listen only?

I was testing code to drive my screens (digitalSTROM). The rule file was placed in de rules folder of my second openhab raspi that has a “listen only” config for mqtt and openhab. But the screens are moving none the less. Cross referencing the log files shows the production instance of HABapp was not driving the screens at the time.

HABapp.log shows:

[2026-07-04 17:40:16,168\] [HABApp.connection.openhab] INFO | Connected read only to OpenHAB version 5.1.4 (Release Build)

Why is HABapp not listening only? Does it have something tot do with my code, the RollerShutterItems that are digitalSTROM items and things? Or have I stumbled across a bug in HABapp?

This is my config.yml:

directories:
logging: log # Folder where the logs will be written to
rules: rules # Folder from which the rule files will be loaded
params: params # Folder from which the parameter files will be loaded
config: config # Folder from which configuration files (e.g. for textual thing configuration) will be loaded
lib: lib # Folder where additional libraries can be placed
location:
latitude: xxxx
longitude: xxxx
elevation: xxxx
country: ‘NL’ # ISO 3166-1 Alpha-2 country code
subdivision: ‘’ # The subdivision (e.g. state or province) as a ISO 3166-2 code or its alias
mqtt:
connection:
identifier: HABApp # Identifier that is used to uniquely identify this client on the mqtt broker.
host: ‘xxx.xxx.xxx’ # Connect to this host. Empty string (“”) disables the connection.
port: 1883
user: ‘xxxxx’
password: ‘xxxxx’
tls:
enabled: False # Enable TLS for the connection
ca cert: . # Path to a CA certificate that will be treated as trusted
insecure: False # Validate server hostname in server certificate
subscribe:
qos: 0 # Default QoS for subscribing
topics:
- ‘#’
- topic/with/default/qos
- - topic/with/qos
- 1
publish:
qos: 0 # Default QoS when publishing values
retain: False # Default retain flag when publishing values
general:
listen_only: True # If True HABApp does not publish any value to the broker
openhab:
connection:
url: ``http://xxx.xxx.xxx:8080`` # Connect to this url. Empty string (“”) disables the connection.
user: ‘xxxxx’
password: ‘xxxxx’
verify_ssl: True # Check certificates when using https
general:
listen_only: True # If True HABApp does not change anything on the openHAB instance.
wait_for_openhab: True # If True HABApp will wait for a successful openHAB connection before loading any rules on startup
ping:
enabled: False # If enabled the configured item will show how long it takes to send an update from HABApp and get the updated value back from openHAB in milliseconds
item: HABApp_Ping # Name of the Numberitem
interval: 10 # Seconds between two pings

My script is as follows:

from typing import List




import HABApp

from HABApp.core.events import ValueUpdateEventFilter, ValueUpdateEvent

from HABApp.core.items import Item

from HABApp.openhab.items import SwitchItem, NumberItem, GroupItem, RollershutterItem

from HABApp.openhab.items import OpenhabItem

from datetime import datetime, timedelta

import logging




log = logging.getLogger("TestLog")




class ScreenTesting(HABApp.Rule):

    def __init__(self):

        super().__init__()




        self.screenPositionZuid = GroupItem.get_item('alleZuidScreens')

        self.screenPositionWest = GroupItem.get_item('alleWestScreens')

        self.screenPositionParents = RollershutterItem.get_item('Screen_Ouderslaapkamer')

        self.screenPositionNoord = RollershutterItem.get_item('Screen_Woonkamer_Noord_Position_control')

        self.screenSceneZuidNeer = SwitchItem.get_item('dsS_Scene_ScreensZuid_Neer')

        self.screenSceneZuidOp = SwitchItem.get_item('dsS_Scene_ScreensZuid_Op')




        self.run.soon(self.test)




        self.screens_to_command = [self.screenPositionZuid, self.screenPositionWest, self.screenPositionParents, self.screenPositionNoord]

        self.zonhoek: List[int] = [90,120,240,260]

        self.zuid_omlaag = False

        self.west_omlaag = False

        self.noord_omlaag = False




    def command_screens(self, screen, direction):

        movescreen = screen

        if direction == 0 and movescreen.value >= 95:

            log.info(f'{screen.name} must be up and is down, up command sent.')

            movescreen.command_value(direction)

        elif direction == 0:

            log.info(f'{screen.name} must be up and is already up, no command sent.')

        elif direction == 100 and movescreen.value <= 5:

            log.info(f'{screen.name} must be down and is up, down command sent.')

            movescreen.command_value(direction)

        elif direction == 100:

            log.info(f'{screen.name} must be down and is already down, no command sent.')




    def _val(self, item: OpenhabItem) -> float:

        """Helper function to get the value of an item as a float."""

        return float(item.value)




    def test(self):

        global_index = 0

        for i, hoek in enumerate(self.zonhoek):

            log.info("\n\n\n")

            log.info(f"Test {i+1}:")

            log.info(f"Sun angle of {hoek} degrees.")




            if hoek >= 90 and hoek < 120:

                self.zuid_omlaag = True

            if hoek >= 120 and hoek < 240:

                self.west_omlaag = True

            if hoek >= 240 and hoek < 260:

                self.zuid_omlaag = False

            if hoek >= 260:

                self.west_omlaag = False

                self.noord_omlaag = True




            lijst_op = []

            lijst_neer = []




            if self.zuid_omlaag:

                lijst_op = list(self.screenPositionZuid.members)

                lijst_op += [self.screenPositionParents]

            if self.west_omlaag:

                lijst_op += list(self.screenPositionWest.members)

            if self.noord_omlaag:

                lijst_op += [self.screenPositionNoord]




            if not self.zuid_omlaag:

                lijst_neer = list(self.screenPositionZuid.members)

                lijst_neer += [self.screenPositionParents]

            if not self.west_omlaag:

                lijst_neer += list(self.screenPositionWest.members)

            if not self.noord_omlaag:

                lijst_neer += [self.screenPositionNoord]




            alle_commandos = [(screen, 0) for screen in lijst_op] + [(screen, 100) for screen in lijst_neer]

            for screen, direction in alle_commandos:

                self.run.once(global_index * 2, self.command_screens, screen, direction)

                global_index += 1                            




ScreenTesting()

Could definately be the case. I reworked the connection handling in the last releases so it’s quite possible I broke the listen_only flag.
I’ll investigate next week - sorry for your inconvenience.

No inconvenience, I’ll just wait with further testing a bit :slightly_smiling_face: