HABApp - Easy automation with openHAB

This is a very small release

0.13.2

  • Changed default value in HABApp configuration for “wait_for_openhab” to “True”
  • Improved readability of exceptions in the logs
  • Updated packages astral, pytz, tzlocal, stackprinter and ujson

0.14.0

  • completely reworked openhab connection (necessary for new features)
  • updated docs
  • added plugin that shows an overview for Things and Z-Wave

Some time after the first connect a small overview over Things and Z-Wave specific Things will be shown:

+--------+---------------------------+------------+---------------------------------+------------------------------------------------------+
| Status |           Label           |  Location  |           Thing type            |                      Thing UID                       |
+--------+---------------------------+------------+---------------------------------+------------------------------------------------------+
| ONLINE | Astronomische Sonnendaten |            | astro:sun                       | astro:sun:home                                       |
| ONLINE | TV                        | TV Room    | network:pingdevice              | network:pingdevice:TV                                |
| ONLINE | Squeezebox Player 1       | Room 1     | squeezebox:squeezeboxplayer     | squeezebox:squeezeboxplayer:myServer:room_1          |
| ONLINE | Squeezebox Player 2       | Room 2     | squeezebox:squeezeboxplayer     | squeezebox:squeezeboxplayer:myServer:room_2          |
| ONLINE | SqueezeBox Server         |            | squeezebox:squeezeboxserver     | squeezebox:squeezeboxserver:myServer                 |
+--------+---------------------------+------------+---------------------------------+------------------------------------------------------+
+------+--------+---------------------------------------------------+------------+---------+----------+-----------------------------+--------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+
| Node | Status |                       Label                       |  Location  |  Model  | Firmware |         Thing type          |           Thing UID            |                                                              Linked channel types                                                               |                                                               Unlinked channel types                                                               |
+------+--------+---------------------------------------------------+------------+---------+----------+-----------------------------+--------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+
|  31  | ONLINE | Z-Wave Node 031: ZW096 Smart Switch 6             |            |  ZW096  |   1.0    | zwave:aeon_zw096_00_000     | zwave:device:controller:node31 | zwave:switch_binary, zwave:meter_kwh, zwave:meter_current, zwave:meter_voltage, zwave:meter_watts, zwave:meter_reset                            | zwave:color_color                                                                                                                                  |
|  30  | ONLINE | Z-Wave Node 030: ZW100 MultiSensor 6              |            |  ZW100  |   1.4    | zwave:aeon_zw100_00_000     | zwave:device:controller:node30 | zwave:sensor_binary, zwave:sensor_relhumidity, zwave:sensor_ultraviolet, zwave:sensor_temperature, zwave:sensor_luminance, system:battery-level | zwave:alarm_general                                                                                                                                |
|  22  | ONLINE | Z-Wave Node 022                                   |            |         |   0.0    | zwave:device                | zwave:device:controller:node22 |                                                                                                                                                 |                                                                                                                                                    |
|  2   | ONLINE | Z-Wave Node 002: FGWP101 Metered Wall Plug Switch |            | FGWP101 |  25.25   | zwave:fibaro_fgwp101_00_000 | zwave:device:controller:node2  | zwave:switch_binary, zwave:sensor_power, zwave:meter_kwh, zwave:meter_reset                                                                     | zwave:meter_watts, zwave:fibaro_fgwp101_00_000_config_decimal_param61, zwave:fibaro_fgwp101_00_000_config_decimal_param62, zwave:notification_send |
|  40  | ONLINE | Z-Wave Node 040: FGWP102 Metered Wall Plug Switch |            | FGWP102 |   3.2    | zwave:fibaro_fgwp102_03_002 | zwave:device:controller:node40 | zwave:switch_binary, zwave:sensor_power, zwave:meter_kwh, zwave:meter_reset                                                                     | zwave:meter_watts, zwave:fibaro_fgwp102_03_002_config_decimal_param41, zwave:fibaro_fgwp102_03_002_config_decimal_param42, zwave:alarm_power       |
|  33  | ONLINE | Z-Wave Node 033: PSR04 Smart Color Button         |            |  PSR04  |   1.7    | zwave:philio_psr04_00_000   | zwave:device:controller:node33 | zwave:switch_dimmer, zwave:scene_number, system:battery-level                                                                                   |                                                                                                                                                    |
|  1   | ONLINE | ZWave Controller                                  |            |         |          | zwave:serial_zstick         | zwave:serial_zstick:controller |                                                                                                                                                 | zwave:serial_sof, zwave:serial_ack, zwave:serial_nak, zwave:serial_can, zwave:serial_oof, zwave:serial_cse                                         |
|  11  | ONLINE | Z-Wave Node 011: WPS104 Energy Driven Switch      | Room 1     | WPS104  |   1.31   | zwave:widom_wps104_00_000   | zwave:device:controller:node11 | zwave:switch_binary, zwave:meter_voltage, zwave:meter_current, zwave:meter_watts, zwave:meter_kwh, zwave:meter_reset                            | zwave:sensor_power, zwave:meter_powerfactor                                                                                                        |
+------+--------+---------------------------------------------------+------------+---------+----------+-----------------------------+--------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+

Hi, found this app the other day and I’m starting to play with it. Somewhere in the thread I saw that channel events e.g. Astro sunrise start, Civil dusk end aren’t currently supported.

Is this still true? If so, how do I fire a rule at some of the more obscure astro events - e.g. civil dusk start.

How do I trigger a rule at a specific time or interval (cron equivalent)

TIA

Nick

Just add a Switch to the channel, it will flip on and off when the event starts

With the scheduler

Good news everyone!
I’ve published a small bugfix release:

0.14.1

  • Added Number:Dimensionless as a unit of measurement
  • made z-wave table more robust

Lately I had to create multiple proxy items for every thing which has an energy_meter channel.
This took quite some time and was very annoying.
So this release contains a very powerful plugin which can filter existing things and then for each thing

  • modify/check the thing configuration
  • create items
  • filter the channels of the thing and then for each channel create items and link them to the channel

It has a test mode and prints very nice overviews in the log files.
Additionally it creates an .items file with the created items.

Example for the configuration overview for my Philio PST02A sensors:

# Test mode: will not do anything but instead print out information
test: True

# Define filters which will reduce the number of things,
# all defined filters have to match for further processing
filter:
  thing_type: zwave:philio_pst02a_00_000

# Set this configuration for all things.
# Here it is the z-wave parameters which are responsible for the device behaviour
thing config:
  4: 99     # Light Threshold
  5: 8      # Operation Mode
  6: 4      # MultiSensor Function Switch
  7: 20     # Customer Function

# Create items for every matching thing
create items:
 - type: Number
   name: '{thing_label, :(.+)$}_MyNumber'          # Use the label from the thing as an input for the name,
   label: '{thing_label, :(.+)$} MyNumber [%d]'    # the regex will take everything from the ':' on until the end
   icon: battery

channels:
  # reduce the channels of the thing with these filters
  # and link items to it
  - filter:
      channel_type: zwave:alarm_motion
    link items:
      - type: Number
        name: '{thing_label, :(.+)$}_Movement'           # Use the label from the thing as an input for the name,
        label: '{thing_label, :(.+)$} Movement [%d %%]'  # the regex will take everything from the ':' on until the end
        icon: battery
        groups: ['group1', 'group2']
        tags: ['tag1']

  - filter:
      channel_type: zwave:sensor_temperature
    link items:
      - type: Number
        name: '{thing_label, :(.+)$}_Temperature'
        label: '{thing_label, :(.+)$} Temperature [%d %%]'
        icon: battery

The thing config, create items and the channels part is optional so you can combine them as you like.

Loading /config/thing_philio.yml!
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|                                                                                   Thing overview                                                                                 |
+---------------------------------+----------------------------+----------------+----------------------------------------+----------------------------------------------+----------+
|           thing_uid             |         thing_type         | thing_location |            thing_label                 |                  bridge_uid                  | editable |
+---------------------------------+----------------------------+----------------+----------------------------------------+----------------------------------------------+----------+
| zwave:device:controller:node32  | zwave:fibaro_fgrgbw_00_000 | Room1          | Fibaro RGBW (Node 32): Room1 RGBW      | zwave:serial_zstick:controller               | True     |
| zwave:device:controller:node7   | zwave:fibaro_fgrgbw_00_000 | Room2          | Fibaro RGBW (Node 07): Room2 RGBW      | zwave:serial_zstick:controller               | True     |
| zwave:device:controller:node23  | zwave:fibaro_fgrgbw_00_000 | Room3          | Fibaro RGBW (Node 23): Room3 RGBW      | zwave:serial_zstick:controller               | True     |
| zwave:device:controller:node35  | zwave:philio_pst02a_00_000 | Room1          | Philio PST02A (Node 35): Room1 Door    | zwave:serial_zstick:controller               | True     |
| zwave:device:controller:node15  | zwave:philio_pst02a_00_000 | Room2          | Philio PST02A (Node 15): Room2 Window  | zwave:serial_zstick:controller               | True     |
| zwave:device:controller:node17  | zwave:philio_pst02a_00_000 | Room3          | Philio PST02A (Node 17): Room3 Window  | zwave:serial_zstick:controller               | True     |
| zwave:device:controller:node3   | zwave:philio_pst02a_00_000 | Room1          | Philio PST02A (Node 03): Room1 Window  | zwave:serial_zstick:controller               | True     |
| zwave:device:controller:node5   | zwave:philio_pst02a_00_000 | Room4          | Philio PST02A (Node 05): FrontDoor     | zwave:serial_zstick:controller               | True     |
| zwave:serial_zstick:controller  | zwave:serial_zstick        |                | ZWave Controller                       |                                              | False    |
+---------------------------------+----------------------------+----------------+----------------------------------------+----------------------------------------------+----------+
thing_type "zwave:philio_pst02a_00_000" matches for zwave:device:controller:node35!
thing_type "zwave:philio_pst02a_00_000" matches for zwave:device:controller:node15!
thing_type "zwave:philio_pst02a_00_000" matches for zwave:device:controller:node17!
thing_type "zwave:philio_pst02a_00_000" matches for zwave:device:controller:node3!
thing_type "zwave:philio_pst02a_00_000" matches for zwave:device:controller:node5!
+---------------------------------------------------------------------------------------------------------------------------+
|                                                   Current configuration                                                   |
+-------------------------+-------------------+-------------------+-------------------+------------------+------------------+
|        Parameter        | controller:node35 | controller:node15 | controller:node17 | controller:node3 | controller:node5 |
+-------------------------+-------------------+-------------------+-------------------+------------------+------------------+
| 2                       | -1                | -1                | -1                | -1               | -1               |
| 3                       | 80                | 80                | 80                | 80               | 80               |
| 4                       | 99                | 99                | 99                | 99               | 99               |
| 5                       | 0                 | 8                 | 8                 | 8                | 8                |
| 6                       | 4                 | 0                 | 0                 | 0                | 0                |
| 7                       | 22                | 20                | 20                | 20               | 20               |
| 8                       | 3                 | 3                 | 3                 | 3                | 3                |
| 9                       | 4                 | 0                 | 4                 | 4                | 4                |
| 10                      | 12                | 12                | 12                | 12               | 12               |
| 11                      | 12                | 12                | 12                | 12               | 12               |
| 12                      | 12                | 12                | 2                 | 12               | 4                |
| 13                      | 12                | 12                | 2                 | 12               | 4                |
| 20                      | 30                | 30                | 30                | 30               | 30               |
| 21                      | 1                 | 0                 | 0                 | 0                | 0                |
| 22                      | 0                 | 0                 | 0                 | 0                | 0                |
| Group1                  | ['controller']    | ['controller']    | ['controller']    | ['controller']   | ['controller']   |
| Group2                  | []                | []                | []                | []               | []               |
| binding_cmdrepollperiod | 1500              | 1500              | 1500              | 1500             | 1500             |
| binding_pollperiod      | 86400             | 86400             | 86400             | 86400            | 86400            |
| wakeup_interval         | 86400             | 86400             | 86400             | 86400            | 86400            |
+-------------------------+-------------------+-------------------+-------------------+------------------+------------------+
Would set {5: 8, 7: 20} for zwave:device:controller:node35
Would set {6: 4} for zwave:device:controller:node15
Would set {6: 4} for zwave:device:controller:node17
Would set {6: 4} for zwave:device:controller:node3
Would set {6: 4} for zwave:device:controller:node5
+----------------------------------------------------------------------------------------------------------------------+
|                                       Channels for zwave:philio_pst02a_00_000                                        |
+---------------------------------------------------+--------------------------+------------------------+--------------+
|                    channel_uid                    |       channel_type       |     channel_label      | channel_kind |
+---------------------------------------------------+--------------------------+------------------------+--------------+
| zwave:device:controller:node35:sensor_door        | zwave:sensor_door        | Door/Window Sensor     | STATE        |
| zwave:device:controller:node35:alarm_motion       | zwave:alarm_motion       | Motion Sensor          | STATE        |
| zwave:device:controller:node35:alarm_tamper       | zwave:alarm_tamper       | Tamper Alarm           | STATE        |
| zwave:device:controller:node35:sensor_luminance   | zwave:sensor_luminance   | Sensor (luminance)     | STATE        |
| zwave:device:controller:node35:sensor_temperature | zwave:sensor_temperature | Sensor (temperature)   | STATE        |
| zwave:device:controller:node35:alarm_access       | zwave:alarm_access       | Alarm (Access Control) | STATE        |
| zwave:device:controller:node35:alarm_burglar      | zwave:alarm_burglar      | Alarm (Burglar)        | STATE        |
| zwave:device:controller:node35:battery-level      | system:battery-level     | Batterieladung         | STATE        |
+---------------------------------------------------+--------------------------+------------------------+--------------+
channel_type "zwave:alarm_motion" matches for zwave:device:controller:node35:alarm_motion!
channel_type "zwave:sensor_temperature" matches for zwave:device:controller:node35:sensor_temperature!

channel_type "zwave:alarm_motion" matches for zwave:device:controller:node15:alarm_motion!
channel_type "zwave:sensor_temperature" matches for zwave:device:controller:node15:sensor_temperature!

channel_type "zwave:alarm_motion" matches for zwave:device:controller:node17:alarm_motion!
channel_type "zwave:sensor_temperature" matches for zwave:device:controller:node17:sensor_temperature!

channel_type "zwave:alarm_motion" matches for zwave:device:controller:node3:alarm_motion!
channel_type "zwave:sensor_temperature" matches for zwave:device:controller:node3:sensor_temperature!

channel_type "zwave:alarm_motion" matches for zwave:device:controller:node5:alarm_motion!
channel_type "zwave:sensor_temperature" matches for zwave:device:controller:node5:sensor_temperature!

Would create Item(type='Number', name='Room1_Door_MyNumber', label='Room1 Door MyNumber [%d]', icon='battery', groups=[], tags=[], link=None)
Would create Item(type='Number', name='Room1_Door_Movement', label='Room1 Door Movement [%d %%]', icon='battery', groups=['group1', 'group2'], tags=['tag1'], link='zwave:device:controller:node35:alarm_motion')
Would create Item(type='Number', name='Room1_Door_Temperature', label='Room1 Door Temperature [%d %%]', icon='battery', groups=[], tags=[], link='zwave:device:controller:node35:sensor_temperature')
Would create Item(type='Number', name='Room2_Window_MyNumber', label='Room2 Window MyNumber [%d]', icon='battery', groups=[], tags=[], link=None)
Would create Item(type='Number', name='Room2_Window_Movement', label='Room2 Window Movement [%d %%]', icon='battery', groups=['group1', 'group2'], tags=['tag1'], link='zwave:device:controller:node15:alarm_motion')
Would create Item(type='Number', name='Room2_Window_Temperature', label='Room2 Window Temperature [%d %%]', icon='battery', groups=[], tags=[], link='zwave:device:controller:node15:sensor_temperature')
Would create Item(type='Number', name='Room3_Window_MyNumber', label='Room3 Window MyNumber [%d]', icon='battery', groups=[], tags=[], link=None)
Would create Item(type='Number', name='Room3_Window_Movement', label='Room3 Window Movement [%d %%]', icon='battery', groups=['group1', 'group2'], tags=['tag1'], link='zwave:device:controller:node17:alarm_motion')
Would create Item(type='Number', name='Room3_Window_Temperature', label='Room3 Window Temperature [%d %%]', icon='battery', groups=[], tags=[], link='zwave:device:controller:node17:sensor_temperature')
Would create Item(type='Number', name='Room1_Window_MyNumber', label='Room1 Window MyNumber [%d]', icon='battery', groups=[], tags=[], link=None)
Would create Item(type='Number', name='Room1_Window_Movement', label='Room1 Window Movement [%d %%]', icon='battery', groups=['group1', 'group2'], tags=['tag1'], link='zwave:device:controller:node3:alarm_motion')
Would create Item(type='Number', name='Room1_Window_Temperature', label='Room1 Window Temperature [%d %%]', icon='battery', groups=[], tags=[], link='zwave:device:controller:node3:sensor_temperature')
Would create Item(type='Number', name='FrontDoor_MyNumber', label='FrontDoor MyNumber [%d]', icon='battery', groups=[], tags=[], link=None)
Would create Item(type='Number', name='FrontDoor_Movement', label='FrontDoor Movement [%d %%]', icon='battery', groups=['group1', 'group2'], tags=['tag1'], link='zwave:device:controller:node5:alarm_motion')
Would create Item(type='Number', name='FrontDoor_Temperature', label='FrontDoor Temperature [%d %%]', icon='battery', groups=[], tags=[], link='zwave:device:controller:node5:sensor_temperature')

Created *.items file (next to the yml, not in the items directory).
This is just to quickly check which items will/have been created.

Number   Room1_Door_MyNumber         "Room1 Door MyNumber [%d]"             <battery>
Number   Room1_Door_Movement         "Room1 Door Movement [%d %%]"          <battery>    (group1, group2)     [tag1]   {channel = "zwave:device:controller:node35:alarm_motion"}
Number   Room1_Door_Temperature      "Room1 Door Temperature [%d %%]"       <battery>                                  {channel = "zwave:device:controller:node35:sensor_temperature"}
Number   Room2_Window_MyNumber       "Room2 Window MyNumber [%d]"           <battery>
Number   Room2_Window_Movement       "Room2 Window Movement [%d %%]"        <battery>    (group1, group2)     [tag1]   {channel = "zwave:device:controller:node15:alarm_motion"}
Number   Room2_Window_Temperature    "Room2 Window Temperature [%d %%]"     <battery>                                  {channel = "zwave:device:controller:node15:sensor_temperature"}
Number   Room3_Window_MyNumber       "Room3 Window MyNumber [%d]"           <battery>
Number   Room3_Window_Movement       "Room3 Window Movement [%d %%]"        <battery>    (group1, group2)     [tag1]   {channel = "zwave:device:controller:node17:alarm_motion"}
Number   Room3_Window_Temperature    "Room3 Window Temperature [%d %%]"     <battery>                                  {channel = "zwave:device:controller:node17:sensor_temperature"}
Number   Room1_Window_MyNumber       "Room1 Window MyNumber [%d]"           <battery>
Number   Room1_Window_Movement       "Room1 Window Movement [%d %%]"        <battery>    (group1, group2)     [tag1]   {channel = "zwave:device:controller:node3:alarm_motion"}
Number   Room1_Window_Temperature    "Room1 Window Temperature [%d %%]"     <battery>                                  {channel = "zwave:device:controller:node3:sensor_temperature"}
Number   FrontDoor_MyNumber          "FrontDoor MyNumber [%d]"              <battery>
Number   FrontDoor_Movement          "FrontDoor Movement [%d %%]"           <battery>    (group1, group2)     [tag1]   {channel = "zwave:device:controller:node5:alarm_motion"}
Number   FrontDoor_Temperature       "FrontDoor Temperature [%d %%]"        <battery>                                  {channel = "zwave:device:controller:node5:sensor_temperature"}

Since this is quite a complex feature I’d gladly take some hints on how to improve the documentation. :slight_smile:


Release 0.15.0

  • removed the plugin for thing configuration (!! BREAKING CHANGE !!)
  • created a plugin which can automatically do thing configuration, create things and link them to channels
  • created pending future class and made the item_watch use it
  • better logging of the event bus for str values
  • added INFO to HABApp topics
  • fixed #159
  • added tests and docs
  • Automatic unloading for MultiMode which are added in rules

0.15.1

  • Parameters can be used in operations without having to access the value property
  • Log info gets printed properly when changing thing parameters
  • Changed example and readme (fixes #161)

0.15.2

This is mostly a bugfix release.

  • Both values for ValueChangeEvent are properly unpacked
  • Fixed a bug where the configuration for a link was not set properly
  • Bumped used library versions
  • The test client does log all rest communication in the testcase

Has anybody tried HABApp with openHAB 3?

I haven’t tried it (yet) but most if not all of it should work because there haven’t been fundamental changes to the rest api.

I am currently unsure when it’ll be a good time to shift development efforts to oh3.

I believe the REST API has expanded but I think things are still quite fluid. I am sure there will be some sort of release this year but I personally am not confident on its usability for many users.

My first try says it is currently not compatible with OH3.

HABApp tries to access http://localhost:8080/rest/uuid/ This is what is returned, by default.

{"error":{"message":"User is not authenticated","http-code":401}}

Some parts of the API seem to be protected by user/password.
In the openhab config there is a possibility to specify user and password.
Have you entered the correct “admin” credentials there?

Edit:
Where do you download oh3? I can’t seem to find a link so I can test myself.

I think this is the guide most are using:

I used apt to install. The official download is here for other methods.

I have not tried that but it appears the API is using some sort of OAuth2 token based authentication.

"/auth/token":{"post":{
        "tags":["auth"],
	"summary":"Get access and refresh tokens.",
	"operationId":"getToken",
	"parameters":[{"name":"useCookie","in":"query","schema":{"type":"boolean"}}],
	"requestBody":{"content":{
		"application/x-www-form-urlencoded":{"schema":{
			"type":"object",
			"properties":{
				"grant_type":{"type":"string"},
				"code":{"type":"string"},
				"redirect_uri":{"type":"string"},
				"client_id":{"type":"string"},
				"refresh_token":{"type":"string"},
				"code_verifier":{"type":"string"}
		}}}
	}},
	"responses":{"200":{"description":"OK"}}
}},

@Spaceman_Spiff

I just started testing with a clean OH 2.5.9 install on my test Pi with HABApp 0.15.2 & Python 3.7.3. The first simple rule in the docs gives an error.

(habapp) root@raspberrypi:/opt/habapp/config/rules# python first.py
Traceback (most recent call last):
  File "first.py", line 16, in <module>
    MyFirstRule()
  File "first.py", line 6, in __init__
    super().__init__()
  File "/opt/habapp/lib/python3.7/site-packages/HABApp/rule/rule.py", line 43, in __init__
    __vars = sys._getframe(depth).f_globals
ValueError: call stack is not deep enough
(habapp) root@raspberrypi:/opt/habapp/config/rules#

If you have made the installation you have to start HABApp, not execute the rule directly.
HABApp will automatically load the rule.
You can observe this in the logs accordingly.

HABApp was running. Does it need to be restarted to pick up new rules?

Is this primarily for rules or to replace other text files such as Items and sitemaps?

If HABApp is started it will automatically load and execute the rules located in the rules folder (which is configured in the config.yml and typically a different folder than the rules folder from openhab) You just drop or edit the files in the folder - that’s it.
In the HABApp.log you can observe how things are loaded/unloaded.

There is no possibility to create sitemaps, but you can replace many *.items files and definitely all rule files with it.
It is mainly intended as a python rule engine, item and thing interaction is just a bonus.

Example with default configuration:
I started HABApp with /opt/habapp/bin/habapp -c /opt/openhab/conf/habapp.
Now my rules are in /opt/openhab/conf/habapp/rules (and subfolders).
I just edit or copy them into the folder and they get picked up automatically as soon as they are changed.
In /opt/openhab/conf/habapp/log I can find all relevant log files and observe what is happening.

1 Like