Skip to content

HassController

HassController is the interface to Home Assistant systems. It uses Home Assistant's WebSocket API to implement the communications layer. This approach significantly reduces the load of communication on both systems, even in periods of high activity when a lot of data is being exchanged. You will need to make sure that the WebSocket API is enabled in your HomeAssistant configuration. See their documentation for that.

Because Home Assistant sometimes makes breaking changes to its API, only specific version of Home Assistant are supported by this interface. Currently, only Home Assistant versions 2021.1.5 through 2021.12.7 supported. Versions outside this range may not work at all, or exhibit errant behaviors that are not immediately obvious. Bug reports and fixes for versions outside this range are not accepted/handled.

The only required fields for HassController are source and access_token:

reactor:
  # reactor configuration section not shown

controllers:
- id: hass
  enabled: true
  implementation: HassController
  name: Home Assistant
  config:
    source: "ws://192.168.0.10:8123"
    access_token: "place long-lived access token within"

Note that the source field must contain a URI in the form ws://ip-address:port. The access_token value is a "long-lived access token" from Home Assistant. To get a LLAT, log in to the Home Assistant UI and click on your username in the bottom-left corner. Then scoll down your profile until you find the "Long-Lived Access Tokens" section. Create a new token there, and copy/paste it into your Reactor controller configuration, keeping it surrounded in quotes as shown above.

Mapping Home Assistant Entities to Reactor Entities

HassController tries to do as much of the work of mapping between Home Assistant entities and Reactor entities as possible through configuration files. However, there is some data that is not available through the Home Assistant APIs, so there is a mechanism by which you can either override or enhance HassController's default mapping strategy.

Your overrides and enhancements can be specified in a configuration file you create and manage called local_hass_devices.yaml. This file must be located in your config subdirectory (where reactor.yaml also resides).

Overriding Entity Name, Capabilities, etc.

To override the name of an entity, or to add a capability that an entity may have that does not register automatically, add the entity to an entities section of local_hass_devices.yaml, like this:

entities:
  "hass>switch_power_switch":
    name: "My Override Name"
    capabilities:
      - temperature_sensor
    primary_attribute: temperature_sensor.value

In the example above, the entity with the (Reactor) canonical ID hass>switch_power_switch will get given the name shown, and in addition to the automatically-determined capabilities, will also implement the temperature_sensor capability (imagining there is such a device). Finally, it makes the temperature sensor value the default (primary) value for the device.

Handling Home Assistant Events

Some Home Assistant devices send events, and these events are not mapped in Home Assistant to a Home Assistant Entity. Since the Home Assistant API does not enumerate these events or the devices that may send them, it is up the user (you) to add event handling for any such events.

For example, let's say you have an Amcrest camera that can do motion detection and sends motion events, but the HA integration does not create a virtual motion sensor entity to reflect the state of that capability, it only sends events. Here's a typical motion-start event for the camera:

{
    "event_type": "amcrest",
    "data": {
        "camera": "Cam2",
        "event": "VideoMotion",
        "payload": {
            "Code": "VideoMotion",
            "action": "Start",
            "index": "0"
        }
    },
    "origin": "LOCAL",
    "time_fired": "2021-11-16T19:25:10.223198+00:00",
    "context": {
        "id": "9ec3cdea4a733798660e23e2f59b3a2e",
        "parent_id": null,
        "user_id": null
    }
}

To handle this event, we add the following configuration to our HassController's config section of reactor.yaml:

  config:
    # Additions to config section for Amcrest camera motion:
    event_targets:
     cam2_motion:
        capabilities:
        - motion_sensor
        events:
        - event:
            event_type: amcrest
            data:
              camera: "Cam2"
              event: "VideoMotion"
          response:
            "motion_sensor.state":
              from: "lower(event.data.payload.action)"
              map:
                start: true
                stop: false

This will create a (Reactor) entity with ID cam2_motion, having the single capability motion_sensor, that responds to amcrest HA events. If an amcrest event is received that also matches the given data filters, the attributes enumerated in response will be updated in accordance with their configuration. In this case, that takes the value from the event's data and maps it to a boolean value as required for the attribute.

Note that the event_type and data values are dependent entirely on the event data for the device and integration in Hass, and they will vary. You can add log_events: true to the config section of your HassController instance to capture events to a file in your logs directory, to help you determine what data Hass is sending with the event and what the filter values and expressions should be.

The generalized form of the event_targets section is:

      event_targets:    # this section starts the event-receiving entities
        "my_virtual_entity_id":     # Assign an ID to your entity; each entity must have a unique ID
          name: "My Entity Name"   # This is optional but recommended, so you have a friendly name
          capabilities:  # define an array of capabilities to be modified by the event
          - capability_name    # first capability
          - capability_name    # second, etc., as many as you need, but always at least ONE
          events:  # define an array of events that modify capability attributes on the entity
          - event:  # start of an event; each element of the events array begins this way
              event_type: "type of HomeAssistant event"
              data:  # optional section, if further matching to the event data is required
                data_field: "data_value"    # data field to be checked/matched to data_value
                data_field: "data_value"    # as many as you need, but each data_field must be unique
            response:  # begin the (required) response section for handling the event
              "capability.attribute":  # an attribute that the event modifies.
                expr: "expression"   # expression to get attribute value from event data
              "capability.attribute":
                # This shows an alternative to using "expr"/expressions for value handling
                from: "event.data...."  # dot-reference expression to pull value from event message
                map:                    # optional, map to modify value
                  value_in: new_value   # if value is value_in, it is mapped to new_value
                  value_in: new_value   # repeat this as needed, but each value_in must be unique
              # repeat "capability.attribute" section for all attributes modified by the event
          - event:  # start of next event for this entity, same form as above
        "my_second_entity":  # ID of next entity to create/handle events
          events:
            # etc...

Other Special Configuration for HassController

This section is informational only. It is not usually necessary to specify these values or modify their defaults.

  • Timeout — this value sets the length of time HassController will wait for a successful connection to Home Assistant before throwing an error. The default is 15000 (milliseconds, 15 seconds).

Updated: 2021-Nov-22