util - helpers and utilities

The util package contains useful classes which make rule creation easier.

CounterItem

Example

from HABApp.util import CounterItem
c = CounterItem.get_create_item('MyCounter', initial_value=5)
print(c.increase())
print(c.decrease())
print(c.reset())
6
5
5

Documentation

class HABApp.util.CounterItem(name, initial_value=0)

Implements a simple thread safe counter

__init__(name, initial_value=0)
Parameters

initial_value (int) – Initial value of the counter

reset()

Reset value to initial value

increase(step=1)

Increase value

Parameters

step – increase by this value, default = 1

Return type

int

Returns

value of the counter

decrease(step=1)

Decrease value

Parameters

step – decrease by this value, default = 1

Return type

int

Returns

value of the counter

Statistics

Example

s = Statistics(max_samples=4)
for i in range(1,4):
    s.add_value(i)
    print(s)
<Statistics sum: 1.0, min: 1.00, max: 1.00, mean: 1.00, median: 1.00>
<Statistics sum: 3.0, min: 1.00, max: 2.00, mean: 1.50, median: 1.50>
<Statistics sum: 6.0, min: 1.00, max: 3.00, mean: 2.00, median: 2.00>

Documentation

class HABApp.util.Statistics(max_age=None, max_samples=None)

Calculate mathematical statistics of numerical values.

Variables
  • sum – sum of all values

  • min – minimum of all values

  • max – maximum of all values

  • mean – mean of all values

  • median – median of all values

  • last_value – last added value

  • last_change – timestamp the last time a value was added

__init__(max_age=None, max_samples=None)
Parameters
  • max_age – Maximum age of values in seconds

  • max_samples – Maximum amount of samples which will be kept

update()

update values without adding a new value

add_value(value)

Add a new value and recalculate statistical values

Parameters

value – new value

MultiModeItem

Prioritizer item which automatically switches between values with different priorities. Very useful when different states or modes overlap, e.g. automatic and manual mode. etc.

Basic Example

import HABApp
from HABApp.core.events import ValueUpdateEvent
from HABApp.util import MultiModeItem

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

        # create a new MultiModeItem
        item = MultiModeItem.get_create_item('MultiModeTestItem')
        self.listen_event(item, self.item_update, ValueUpdateEvent)

        # create two different modes which we will use
        item.create_mode('Automatic', 0, initial_value=5)
        item.create_mode('Manual', 10, initial_value=0)

        # This shows how to enable/disable a mode
        print('disable/enable the higher priority mode')
        item.get_mode('manual').set_enabled(False)
        item.get_mode('manual').set_value(11)

        # This shows that changes of the lower priority only show when
        # the mode with the higher priority gets disabled
        print('')
        print('Set value of lower priority')
        item.get_mode('automatic').set_value(55)
        print('Disable higher priority')
        item.get_mode('manual').set_enabled(False)

    def item_update(self, event):
        print(f'State: {event.value}')

MyMultiModeItemTestRule()
disable/enable the higher priority mode
State: 5
State: 11

Set value of lower priority
State: 11
Disable higher priority
State: 55

Advanced Example

import logging
import HABApp
from HABApp.core.events import ValueUpdateEvent
from HABApp.util import MultiModeItem

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

        # create a new MultiModeItem and assign logger
        log = logging.getLogger('AdvancedMultiMode')
        item = MultiModeItem.get_create_item('MultiModeTestItem', log)
        self.listen_event(item, self.item_update, ValueUpdateEvent)

        # create two different modes which we will use
        item.create_mode('Automatic', 2, initial_value=5)
        item.create_mode('Manual', 10).set_value(10)
        print(f'{repr(item.get_mode("Automatic"))}')
        print(f'{repr(item.get_mode("Manual"))}')


        # it is possible to automatically disable a mode
        # this will disable the manual mode if the automatic mode
        # sets a value greater equal manual mode
        print('')
        print('-' * 80)
        print('Automatically disable mode')
        print('-' * 80)
        item.get_mode('manual').auto_disable_on = '>='  # disable when low priority value >= mode value

        item.get_mode('Automatic').set_value(11)    # <-- manual now gets disabled because
        item.get_mode('Automatic').set_value(4)     #     the lower priority value is >= itself


        # It is possible to use functions to calculate the new value for a mode.
        # E.g. shutter control and the manual mode moves the shades. If it's dark the automatic
        # mode closes the shutter again. This could be achievied by automatically disable the
        # manual mode or if the state should be remembered then the max function should be used
        print('')
        print('-' * 80)
        print('Use of functions')
        print('-' * 80)
        item.create_mode('Manual', 10, initial_value=5, calc_value_func=max)    # overwrite the earlier declaration
        item.get_mode('Automatic').set_value(7)
        item.get_mode('Automatic').set_value(3)

    def item_update(self, event):
        print(f'State: {event.value}')

MyMultiModeItemTestRule()
[AdvancedMultiMode]     INFO | MultiModeTestItem: Manual set value to 10
State: 10
<MultiModeValue Automatic enabled: True, value: 5>
<MultiModeValue Manual enabled: True, value: 10>

--------------------------------------------------------------------------------
Automatically disable mode
--------------------------------------------------------------------------------
[AdvancedMultiMode]     INFO | MultiModeTestItem: Automatic set value to 11
[AdvancedMultiMode]     INFO | MultiModeTestItem: Manual disabled (11>=10)!
State: 11
[AdvancedMultiMode]     INFO | MultiModeTestItem: Automatic set value to 4
State: 4

--------------------------------------------------------------------------------
Use of functions
--------------------------------------------------------------------------------
[AdvancedMultiMode]     INFO | MultiModeTestItem: Automatic set value to 7
State: 7
[AdvancedMultiMode]     INFO | MultiModeTestItem: Automatic set value to 3
State: 5

Documentation

class HABApp.util.MultiModeItem(name, initial_value=None)

Thread safe value prioritizer Item

Variables

logger – Assign a logger to get log messages about the different modes

classmethod get_create_item(name, logger=None)

Creates a new item in HABApp and returns it or returns the already existing one with the given name

Parameters
  • name (str) – item name

  • initial_value – state the item will have if it gets created

Returns

item

create_mode(name, priority, initial_value=None, auto_disable_on=None, auto_disable_after=None, calc_value_func=None)

Create a new mode with priority

Parameters
  • name (str) – Name of the new mode

  • priority (int) – Priority of the mode

  • initial_value (Optional[Any]) – Initial value, will also enable the mode

  • auto_disable_on (Optional[str]) – Automatically disable the mode if the lower priority state is > or < the value. See MultiModeValue

  • auto_disable_after (Optional[timedelta]) – Automatically disable the mode after a timedelta if a recalculate is done See MultiModeValue

  • calc_value_func (Optional[Callable[[Any, Any], Any]]) – See MultiModeValue

Return type

MultiModeValue

Returns

The newly created MultiModeValue

get_mode(name)

Returns a created mode

Parameters

name (str) – name of the mode (case insensitive)

Return type

MultiModeValue

Returns

The requested MultiModeValue

calculate_value()

Recalculate the output value and post the state to the event bus (if it is not None)

Return type

Any

Returns

new value

class HABApp.util.multimode_item.MultiModeValue(parent, name, initial_value=None, auto_disable_on=None, auto_disable_after=None, calc_value_func=None)
Variables
  • last_update (datetime.datetime) – Timestamp of the last update/enable of this value

  • auto_disable_after (typing.Optional[datetime.timedelta]) – Automatically disable this mode after a given timedelta on the next recalculation

  • auto_disable_on (typing.Optional[str]) – Automatically disable this mode if the state with lower priority is >, >=, <, <=, == or != than the own value

  • calc_value_func (typing.Optional[typing.Callable[[typing.Any, typing.Any], typing.Any]]) – Function to calculate the new value (e.g. min or max). Any function that accepts two Arguments can be used. First arg is value with lower priority, second argument is own value.

property value

Returns the current value

property enabled

Returns if the value is enabled

Return type

bool

set_value(value)

Set new value and recalculate overall value

Parameters

value – new value

set_enabled(value)

Enable or disable this value and recalculate overall value

Parameters

value (bool) – True/False