spacemanspiff2007 / HABApp

Easy home automation with MQTT and/or openHAB
Apache License 2.0
54 stars 23 forks source link
home-automation mqtt openhab pypi python

HABApp

Tests Status Documentation Status Updates PyPI - Python Version

PyPI Downloads Docker Image Version (latest by date) Docker Pulls

Easy automation with MQTT and/or openHAB

HABApp is a asyncio/multithread application that connects to an openHAB instance and/or a MQTT broker. It is possible to create rules that listen to events from these instances and then react accordingly.

Goals

The goal of this application is to provide a simple way to create home automation rules in python. With full syntax highlighting and descriptive names it should almost never be required to look something up in the documentation

Documentation

The documentation can be found at here

Help out

HABApp was created for my own use, but I wanted others to profit from it, too. Creating, maintaining and developing it takes a lot of time. If you think this is a great tool and want to support it you can donate, so I can buy some more coffee to keep development going. :wink:

Donate with PayPal

All donations are greatly appreciated!

Examples

MQTT Rule example

import datetime
import random

import HABApp
from HABApp.mqtt.items import MqttItem
from HABApp.core.events import ValueChangeEvent, ValueChangeEventFilter, ValueUpdateEvent, ValueUpdateEventFilter

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

        self.run.every(
            start_time=datetime.timedelta(seconds=60),
            interval=datetime.timedelta(seconds=30),
            callback=self.publish_rand_value
        )

        # this will trigger every time a message is received under "test/test"
        self.listen_event('test/test', self.topic_updated, ValueUpdateEventFilter())

        # This will create an item which will store the payload of the topic so it can be accessed later.
        self.item = MqttItem.get_create_item('test/value_stored')
        # Since the payload is now stored we can trigger only if the value has changed
        self.item.listen_event(self.item_topic_updated, ValueChangeEventFilter())

    def publish_rand_value(self):
        print('test mqtt_publish')
        self.mqtt.publish('test/test', str(random.randint(0, 1000)))

    def topic_updated(self, event: ValueUpdateEvent):
        assert isinstance(event, ValueUpdateEvent), type(event)
        print( f'mqtt topic "test/test" updated to {event.value}')

    def item_topic_updated(self, event: ValueChangeEvent):
        print(self.item.value)  # will output the current item value
        print( f'mqtt topic "test/value_stored" changed from {event.old_value} to {event.value}')

ExampleMqttTestRule()

openHAB rule example

import HABApp
from HABApp.core.events import ValueUpdateEvent, ValueChangeEvent, ValueChangeEventFilter, ValueUpdateEventFilter
from HABApp.openhab.events import ItemCommandEvent, ItemStateUpdatedEventFilter, ItemCommandEventFilter, \
  ItemStateChangedEventFilter

class MyOpenhabRule(HABApp.Rule):

  def __init__(self):
    super().__init__()

    # Trigger on item updates
    self.listen_event('TestContact', self.item_state_update, ItemStateUpdatedEventFilter())
    self.listen_event('TestDateTime', self.item_state_update, ValueUpdateEventFilter())

    # Trigger on item changes
    self.listen_event('TestDateTime', self.item_state_change, ItemStateChangedEventFilter())
    self.listen_event('TestSwitch', self.item_state_change, ValueChangeEventFilter())

    # Trigger on item commands
    self.listen_event('TestSwitch', self.item_command, ItemCommandEventFilter())

  def item_state_update(self, event: ValueUpdateEvent):
    assert isinstance(event, ValueUpdateEvent)
    print(f'{event}')

  def item_state_change(self, event: ValueChangeEvent):
    assert isinstance(event, ValueChangeEvent)
    print(f'{event}')

    # interaction is available through self.openHAB or self.oh
    self.openhab.send_command('TestItemCommand', 'ON')

  def item_command(self, event: ItemCommandEvent):
    assert isinstance(event, ItemCommandEvent)
    print(f'{event}')

    # interaction is available through self.openhab or self.oh
    self.oh.post_update('TestItemUpdate', 123)

MyOpenhabRule()

Changelog

24.02.0 (2024-02-14)

24.01.0 (2024-01-08)

23.11.0 (2023-11-23)

23.09.2 (2023-09-24)

23.09.1 (2023-09-18)

23.09.0 (2023-09-12)

1.1.2 (2023-06-19)

1.1.1 (2023-06-16)

1.1.0 (2023-06-15)

This is a breaking change!

1.0.8 (2023-02-09)

1.0.7 (2023-02-09)

1.0.6 (2022-11-08)

1.0.5 (2022-10-20)

1.0.4 (2022-08-25)

1.0.3 (2022-08-09)

1.0.2 (2022-07-29)

1.0.1 (2022-07-25)

1.0.0 (2022-07-25)

Migration to new version

self.listen_event now requires an instance of EventFilter.

Old:

from HABApp.core.events import ValueUpdateEvent
...
self.my_sensor = Item.get_item('my_sensor')
self.my_sensor.listen_event(self.movement, ValueUpdateEvent)

New:

from HABApp.core.events import ValueUpdateEventFilter
...
self.my_sensor = Item.get_item('my_sensor')
self.my_sensor.listen_event(self.movement, ValueUpdateEventFilter())   # <-- Instance of EventFilter
HABApp:
  ValueUpdateEvent -> ValueUpdateEventFilter()
  ValueChangeEvent -> ValueChangeEventFilter()

Openhab:
  ItemStateEvent        -> ItemStateEventFilter()
  ItemStateChangedEvent -> ItemStateChangedEventFilter()
  ItemCommandEvent      -> ItemCommandEventFilter()

MQTT:
  MqttValueUpdateEvent -> MqttValueUpdateEventFilter()
  MqttValueChangeEvent -> MqttValueChangeEventFilter()

Migration to new docker image


0.31.2 (2021-12-17)

0.31.1 (2021-10-29)

0.31.0 (2021-10-08)

0.30.3 (2021-06-17)

0.30.3 (2021-06-01)

0.30.2 (2021-05-26)

0.30.1 (2021-05-07)

0.30.0 (2021-05-02)

Attention:

Changelog

Migration of rules:

0.20.2 (2021-04-07)