Parameters

Parameters

Parameters are values which can easily be changed without having to reload the rules. Values will be picked up during runtime as soon as they get edited in the corresponding file. If the file doesn’t exist yet it will automatically be generated in the configured param folder. Parameters are perfect for boundaries (e.g. if value is below param switch something on).

Available parameter classes:
from HABApp import Rule
from HABApp.parameters import Parameter
from HABApp.core.events import ValueChangeEventFilter

class MyRuleWithParameters(Rule):
    def __init__(self):
        super().__init__()

        # construct parameter once, default_value can be anything
        self.min_value = Parameter( 'param_file_testrule', 'min_value', default_value=10)

        # deeper structuring is possible through specifying multiple keys
        self.min_value_nested = Parameter(
            'param_file_testrule',
            'Rule A', 'subkey1', 'subkey2',
            default_value=['a', 'b', 'c'] # defaults can also be dicts or lists
        )

        self.listen_event('test_item', self.on_change_event, ValueChangeEventFilter())

    def on_change_event(self, event):

        # the parameter can be used like a normal variable, comparison works as expected
        if self.min_value < event.value:
            pass

        # The current value can be accessed through the value-property, but don't cache it!
        current_value = self.min_value.value


MyRuleWithParameters()

Created file:

min_value: 10
Rule A:
    subkey1:
        subkey2:
            - a
            - b
            - c

Changes in the file will be automatically picked up through Parameter.

Create rules from Parameters

Parameteres are not bound to rule instance and thus work everywhere in the rule file. It is possible to dynamically create rules from the contents of the parameter file.

It’s even possible to automatically reload rules if the parameter file has changed: Just add the “reloads on” entry to the file.

my_param.yml
 key1:
   v: 10
 key2:
   v: 12
rule
import HABApp

class MyRule(HABApp.Rule):
    def __init__(self, k, v):
        super().__init__()

        print(f'{k}: {v}')


cfg = HABApp.parameters.DictParameter('my_param')    # this will get the file content
for k, v in cfg.items():
    MyRule(k, v)
key1: {'v': 10}
key2: {'v': 12}
/home/docs/.asdf/installs/python/3.13.14/lib/python3.13/asyncio/base_events.py:569: ResourceWarning: asynchronous generator <async_generator object HabAppObjProvider._reentrant_lock at 0x7d7de95eaf20> was scheduled after loop.shutdown_asyncgens() call

Typed parameters

Parameter accepts any value type. If the value in the file has to be of a specific type use one of the typed subclasses instead - they raise a TypeError on access if the value in the file does not match:

from HABApp.parameters import StrParameter, IntParameter, FloatParameter, NumberParameter

name = StrParameter('my_param', 'name', default_value='Bob')      # only accepts str
count = IntParameter('my_param', 'count', default_value=1)        # only accepts int
ratio = FloatParameter('my_param', 'ratio', default_value=0.5)    # only accepts float
limit = NumberParameter('my_param', 'limit', default_value=10)    # accepts int or float

Validating parameter files

The complete content of a parameter file can be validated against a pydantic model with set_file_validator(). The file is (re-)validated every time it is loaded - if the validation fails the file will not be loaded and the error is logged.

from pydantic import BaseModel
from HABApp.parameters import set_file_validator

class MyParamModel(BaseModel):
    min_value: int = 10

# set the file validator
set_file_validator('param_file_testrule', MyParamModel)

# remove the validator again
set_file_validator('param_file_testrule', None)

Validating individual parameters

If only a part of a file should be validated use BaseModelParameter instead. The value is validated against the model on every access, so it also works if the value of a single key changes independently of the rest of the file.

from pydantic import BaseModel
from HABApp.parameters import BaseModelParameter

class SubModel(BaseModel):
    subkey2: list[str]

param = BaseModelParameter('param_file_testrule', 'Rule A', 'subkey1', model=SubModel)
param.value.subkey2  # -> ['a', 'b', 'c'], validated & parsed as SubModel

Parameter classes

class Parameter[T](filename, *keys, value_type=<class 'object'>, default_value='ToDo')
property value: T

Return the current value. This will do the lookup so make sure to not cache this value, otherwise the parameter might not work as expected.

class StrParameter(filename, *keys, default_value='ToDo')

Parameter that is typed to always return a str value.

class IntParameter(filename, *keys, default_value='ToDo')

Parameter that is typed to always return an int value.

class FloatParameter(filename, *keys, default_value='ToDo')

Parameter that is typed to always return a float value.

class NumberParameter(filename, *keys, default_value='ToDo')

Parameter that is typed to always return an int or float value. The value is returned as-is, i.e. it is not converted to a common type.

class DictParameter(filename, *keys, default_value='ToDo')

Implements a dict interface

property value: dict

Return the current value. This will do the lookup so make sure to not cache this value, otherwise the parameter might not work as expected.

class BaseModelParameter[T: BaseModel](filename, *keys, model, default_value=None)

Parameter that validates the value at the given path against a pydantic model and returns a validated model instance.

Unlike set_file_validator (which validates the whole file once, when it is loaded) this validates only the value found at keys - and does so on every access. This makes it possible to use different (sub-)models for different parts of the same file, independent of (and in addition to) a whole-file validator.

property value: T

Validate the current raw value against the configured model and return the resulting model instance. This will do the lookup (and validation) so make sure to not cache this value, otherwise the parameter might not work as expected.

set_file_validator(filename, model)

Add a validator for the parameter file. If the file is already loaded this will reload the file.

Parameters:
  • filename (str) – filename which shall be validated (without extension)

  • model (type[BaseModel] | None) – Pydantic model class describing the file content. Use None to remove the validator.

Return type:

None