Skip to content

Commit

Permalink
1.0.5
Browse files Browse the repository at this point in the history
1.0.5
- Added new item function ``post_value_if`` and ``oh_post_update_if`` to conditionally update an item
- Added support for new alive event with openHAB 3.4
- Reworked file writer for textual thing config
- Added support for ThingConfigStatusInfoEvent
- MultiModeValue returns True/False if item value was changed
- Updated dependencies
  • Loading branch information
spacemanspiff2007 authored Oct 20, 2022
1 parent 2599822 commit b03de5a
Show file tree
Hide file tree
Showing 69 changed files with 1,335 additions and 390 deletions.
13 changes: 13 additions & 0 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,17 @@
add_module_names = False
python_use_unqualified_type_names = True

# -- nitpick configuration -------------------------------------------------
nitpick_ignore = [
('py:data', 'Ellipsis')
]

nitpick_ignore_regex = [
(re.compile(r'py:data|py:class'), re.compile(r'typing\..+')),
(re.compile(r'py:class'), re.compile(r'(?:datetime|pendulum|aiohttp|pathlib)\..+'))
]


# -- Extension configuration -------------------------------------------------
exec_code_working_dir = '../src'
exec_code_source_folders = ['../src', '../tests']
Expand All @@ -229,6 +240,8 @@
autodoc_pydantic_field_swap_name_and_alias = True




# ----------------------------------------------------------------------------------------------------------------------
# Post processing of default value

Expand Down
51 changes: 51 additions & 0 deletions docs/getting_started.rst
Original file line number Diff line number Diff line change
Expand Up @@ -303,3 +303,54 @@ Trigger an event when an item is constant
HABApp.core.EventBus.post_event('Item_Name', ItemNoChangeEvent('Item_Name', 10))
runner.tear_down()
# ------------ hide: stop -------------


Convenience functions
------------------------------------------

HABApp provides some convenience functions which make the rule creation easier and reduce boiler plate code.

post_value_if
""""""""""""""""""""""""""""""""""""""

``post_value_if`` will post a value to the item depending on its current state.
There are various comparisons available (see :meth:`documentation <HABApp.core.items.Item.post_value_if>`)
Something similar is available for openHAB items (``oh_post_update_if``)

.. exec_code::

# ------------ hide: start ------------
import time, HABApp
from rule_runner import SimpleRuleRunner
runner = SimpleRuleRunner()
runner.set_up()
HABApp.core.Items.add_item(HABApp.core.items.Item('Item_Name'))
# ------------ hide: stop -------------

import HABApp
from HABApp.core.items import Item

class MyFirstRule(HABApp.Rule):
def __init__(self):
super().__init__()
# Get the item or create it if it does not exist
self.my_item = Item.get_create_item('Item_Name')

self.run.soon(self.say_something)

def say_something(self):

# This construct
if self.my_item != 'overwrite value':
self.my_item.post_value('Test')

# ... is equivalent to
self.my_item.pos_value_if('Test', equal='overwrite value')



MyFirstRule()
# ------------ hide: start ------------
runner.process_events()
runner.tear_down()
# ------------ hide: stop -------------
40 changes: 39 additions & 1 deletion docs/installation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ Command line arguments
# ------------ hide: stop -------------


PyCharm
Usage with PyCharm
----------------------------------
It's recommended to use PyCharm as an IDE for writing rules. The IDE can provide auto complete and static checks
which will help write error free rules and vastly speed up development.
Expand Down Expand Up @@ -365,3 +365,41 @@ It's still necessary to supply a configuration file which can be done in the ``P

| After a click on "OK" HABApp can be run/debugged directly from pycharm.
| It's even possible to create breakpoints in rules and inspect all objects.

Install a development version of HABApp
---------------------------------------

To try out new features or test some functionality it's possible to install a branch directly from github.
Installation works only in a virtual environment.

New features are typically first available in the ``Develop`` branch.

#. Navigate to the folder where the virtual environment was created::

cd /opt/habapp


#. Activate the virtual environment

Linux::

source bin/activate

Windows::

Scripts\activate


#. Remove existing HABApp installation::

python3 -m pip uninstall habapp

#. Install HABApp from the github branch (here ``Develop``)::

python3 -m pip install git+https://github.com/spacemanspiff2007/HABApp.git@Develop


#. Run HABApp as usual (e.g. through ``systemctl``) or manually with::

habapp --config PATH_TO_CONFIGURATION_FOLDER
50 changes: 23 additions & 27 deletions docs/interface_openhab.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,16 @@
openHAB
######################################


**************************************
Additional configuration
**************************************

openHAB 2
======================================
For openHAB2 there is no additional configuration needed.

openHAB 3
======================================
For optimal performance it is recommended to use Basic Auth (available from openHAB 3.1 M3 on).
It can be enabled through GUI or through textual configuration.

Textual configuration
--------------------------------------
======================================
The settings are in the ``runtime.cfg``.
Remove the ``#`` before the entry to activate it.

Expand All @@ -29,34 +24,17 @@ Remove the ``#`` before the entry to activate it.
GUI
--------------------------------------
======================================
It can be enabled through the gui in ``settings`` -> ``API Security`` -> ``Allow Basic Authentication``.

.. image:: /images/openhab_api_config.png



**************************************
Interaction with a openHAB
**************************************
All interaction with the openHAB is done through the ``self.oh`` or ``self.openhab`` object in the rule
or through an ``OpenhabItem``.

.. image:: /gifs/openhab.gif



Function parameters
======================================
.. automodule:: HABApp.openhab.interface
:members:
:imported-members:


.. _OPENHAB_ITEM_TYPES:


**************************************
openhab item types
openHAB item types
**************************************

Description and example
Expand Down Expand Up @@ -242,6 +220,24 @@ Thing
:member-order: groupwise



**************************************
Interaction with a openHAB
**************************************
All interaction with the openHAB is done through the ``self.oh`` or ``self.openhab`` object in the rule
or through an ``OpenhabItem``.

.. image:: /gifs/openhab.gif



Function parameters
======================================
.. automodule:: HABApp.openhab.interface
:members:
:imported-members:


.. _OPENHAB_EVENT_TYPES:

**************************************
Expand Down
4 changes: 2 additions & 2 deletions docs/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Packages required to build the documentation
sphinx >= 5.0, < 6.0
sphinx-autodoc-typehints >= 1.18, < 2
sphinx >= 5.2, < 6.0
sphinx-autodoc-typehints >= 1.19, < 2
sphinx_rtd_theme == 1.0.0
sphinx-exec-code == 0.8
autodoc_pydantic >= 1.7, < 1.8
Expand Down
2 changes: 1 addition & 1 deletion docs/rule.rst
Original file line number Diff line number Diff line change
Expand Up @@ -344,4 +344,4 @@ All available functions
:var async_http: :ref:`Async http connections <ref_async_io>`
:var mqtt: :ref:`MQTT interaction <ref_mqtt>`
:var openhab: :ref:`openhab interaction <ref_openhab>`
:var oh: short alias for :py:class:`openhab` openhab
:var oh: short alias for :ref:`openhab <ref_openhab>`
1 change: 1 addition & 0 deletions docs/util.rst
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,7 @@ Basic Example
# create two different modes which we will use and add them to the item
auto = ValueMode('Automatic', initial_value=5)
manu = ValueMode('Manual', initial_value=0)
# Add the auto mode with priority 0 and the manual mode with priority 10
item.add_mode(0, auto).add_mode(10, manu)

# This shows how to enable/disable a mode and how to get a mode from the item
Expand Down
3 changes: 3 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,9 @@ MyOpenhabRule()
```

# Changelog
#### 1.0.5 (20.10.2022)
- Added new item function ``post_value_if`` and ``oh_post_update_if`` to conditionally update an item

#### 1.0.4 (25.08.2022)
- New RGB & HSB datatype for simpler color handling
- Fixed Docker build
Expand Down
8 changes: 4 additions & 4 deletions requirements_setup.txt
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
aiohttp >= 3.8, < 3.9
pydantic >= 1.9, < 1.10
pydantic >= 1.10, < 1.11
pendulum >= 2.1.2, < 2.2
bidict >= 0.22, < 0.23
watchdog >= 2.1.7, < 2.2
ujson >= 5.4, < 5.5
ujson >= 5.5, < 5.6
paho-mqtt >= 1.6, < 1.7

immutables == 0.18
immutables == 0.19
eascheduler == 0.1.7
easyconfig == 0.2.4
stack_data == 0.4.0
stack_data == 0.5.1

voluptuous == 0.13.1

Expand Down
2 changes: 1 addition & 1 deletion run/conf_testing/config/thing_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ channels:
- channel_uid: .+rise#start
link items:
- type: Number
name: '{thing_uid, :([^:]+?)$}_Temperature_1'
name: 'Item_{thing_uid, :([^:]+?)$}_Temperature_1'
label: '{thing_uid, :([^:]+)$} Temperature [%d %%]'
icon: battery
metadata:
Expand Down
24 changes: 11 additions & 13 deletions run/conf_testing/rules/openhab/test_event_types.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from HABApp.core.events import ValueUpdateEventFilter
from HABApp.openhab.definitions.definitions import ITEM_DIMENSIONS

from HABAppTests import TestBaseRule, EventWaiter, OpenhabTmpItem, get_openhab_test_events, \
get_openhab_test_types, get_openhab_test_states, ItemWaiter
Expand All @@ -15,8 +14,13 @@ def __init__(self):
for oh_type in get_openhab_test_types():
self.add_test(f'{oh_type} events', self.test_events, oh_type, get_openhab_test_events(oh_type))

for dimension in ITEM_DIMENSIONS:
self.add_test(f'Quantity {dimension} events', self.test_quantity_type_events, dimension)
dimensions = {
'Length': 'm', 'Temperature': '°C', 'Pressure': 'hPa', 'Speed': 'km/h', 'Intensity': 'W/m²', 'Angle': '°',
'Dimensionless': '',
}

for name, unit in dimensions.items():
self.add_test(f'Quantity {name} events', self.test_quantity_type_events, name, unit)

def test_events(self, item_type, test_values):
item_name = f'{item_type}_value_test'
Expand All @@ -32,21 +36,15 @@ def test_events(self, item_type, test_values):
self.openhab.send_command(item_name, value)
waiter.wait_for_event(value=value)

def test_quantity_type_events(self, dimension):

unit_of_dimension = {
'Length': 'm', 'Temperature': '°C', 'Pressure': 'hPa', 'Speed': 'km/h', 'Intensity': 'W/m²', 'Angle': '°',
'Dimensionless': '',
}

def test_quantity_type_events(self, dimension, unit):
item_name = f'{dimension}_event_test'
with OpenhabTmpItem(f'Number:{dimension}', item_name) as item, \
EventWaiter(item_name, ValueUpdateEventFilter()) as event_watier, \
EventWaiter(item_name, ValueUpdateEventFilter()) as event_waiter, \
ItemWaiter(item) as item_waiter:

for state in get_openhab_test_states('Number'):
self.openhab.post_update(item_name, f'{state} {unit_of_dimension[dimension]}'.strip())
event_watier.wait_for_event(value=state)
self.openhab.post_update(item_name, f'{state} {unit}'.strip())
event_waiter.wait_for_event(value=state)
item_waiter.wait_for_state(state)


Expand Down
20 changes: 18 additions & 2 deletions run/conf_testing/rules/openhab/test_item_funcs.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import logging
import typing

from HABApp.openhab.items import OpenhabItem
from HABApp.openhab.items import OpenhabItem, NumberItem
from HABApp.openhab.items import SwitchItem, RollershutterItem, DimmerItem, ColorItem, ImageItem
from HABAppTests import TestBaseRule, ItemWaiter, OpenhabTmpItem, get_openhab_test_states, get_openhab_test_types

Expand Down Expand Up @@ -55,7 +55,7 @@ def __init__(self):

def add_func_test(self, cls, params: set):
# <class 'HABApp.openhab.items.switch_item.SwitchItem'> -> SwitchItem
self.add_test(str(cls).split('.')[-1][:-2], self.test_func, cls, params)
self.add_test(cls.__name__, self.test_func, cls, params)

def test_func(self, item_type, test_params):

Expand Down Expand Up @@ -103,6 +103,8 @@ def __init__(self):
continue
self.add_test(f'{k}.{name}', self.test_func, k, name, get_openhab_test_states(k))

self.add_test('post_value_if', self.test_post_update_if)

def test_func(self, item_type, func_name, test_vals):

with OpenhabTmpItem(item_type) as tmpitem, ItemWaiter(OpenhabItem.get_item(tmpitem.name)) as waiter:
Expand All @@ -115,5 +117,19 @@ def test_func(self, item_type, func_name, test_vals):
getattr(tmpitem, func_name)()
waiter.wait_for_state(val)

@OpenhabTmpItem.create('Number', arg_name='oh_item')
def test_post_update_if(self, oh_item: OpenhabTmpItem):
item = NumberItem.get_item(oh_item.name)

with ItemWaiter(OpenhabItem.get_item(item.name)) as waiter:
item.post_value_if(0, is_=None)
waiter.wait_for_state(0)

item.post_value_if(1, eq=0)
waiter.wait_for_state(1)

item.post_value_if(5, lower_equal=1)
waiter.wait_for_state(5)


TestOpenhabItemConvenience()
2 changes: 1 addition & 1 deletion src/HABApp/__version__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '1.0.4'
__version__ = '1.0.5'
2 changes: 1 addition & 1 deletion src/HABApp/core/const/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def __repr__(self):


MISSING: Final = _MissingType.MISSING
STARTUP = time.time()
STARTUP: Final = time.monotonic()

# Python Versions for feature control
PYTHON_38: Final = sys.version_info >= (3, 8)
Expand Down
Loading

0 comments on commit b03de5a

Please sign in to comment.