hass
is an Emacs package that enables integration with Home Assistant. Call Home Assistant services, hook into Home Assistant events, and create convenient dashboards!
This package is available on MELPA.
(use-package hass
:ensure t
:init
;; -- Configuration goes here --
)
(straight-use-package 'hass)
;; -- Configuration goes here --
Place in your packages.el
then run doom sync
to pull the repository:
(package! hass)
Then load the package in your main config file.
(use-package! hass
:init
;; -- Configuration goes here --
)
Thanks to cprussin, the dashboards have been completely overhauled. They’re much more flexible by more cleanly utilizing the built-in widget framework. Additionally, you can have multiple dashboards configured.
Calling hass-setup
is no longer required. It has been renamed hass-ensure
. It can still be useful if you want to ‘ensure’ an API connection has already been established and entity information is already up to date before you open a dashboard.
Didn’t seem useful.
Both hass-host
and hass-apikey
must be set to use this package. Set hass-host
to the hostname or IP of Home Assistant instance. If you are not using SSL/TLS to connect to your Home Assistance instance, set hass-insecure
to t
. If you are using a port number other than the default 8123
,
specify the port number with hass-port
.
(setq hass-host "homeassistant")
(setq hass-apikey "APIKEY-GOES-IN-HERE")
(setq hass-port 8123)
Alternatively, you can store a function inside hass-apikey
. This will be executed on every query. In turn, this approach requires the token to be stored in your gpg store e.g. ~/.password-store/emacs-apikey.gpg
(setq hass-host "homeassistant")
(setq hass-apikey (lambda () (auth-source-pass-get 'secret "emacs-apikey")))
Once those variables are set, you can call (hass-ensure)
to query the Home Assistance instance and populate available entities and services. Otherwise, this will be done when it is needed.
Ensure that your Home Assistant instance is configured to support API calls by following the instructions here.
Retrieve your API key a.k.a. Long-Lived Access Token by logging into your Home Assistant instance and going to your profile by selecting your username in the lower-left corner or going to this URL: http://HOME-ASSISTANT-URL:8123/profile
. You can generate an API token at the very bottom of this page.
(setq hass-dash-layouts
'((default . ; Key for dashboard. Shows up with completing-read when calling `hass-dash-open'.
((hass-dash-group ; Create a widget group.
:title "Home Assistant" ; Give the group a title at the top.
:format "%t\n\n%v" ; %t is where the title goes and %v is the widget it owns.
(hass-dash-group ; Create a subgroup of widgets.
:title "Kitchen"
:title-face outline-2 ; Give it a unique face to make it stand out.
(hass-dash-toggle :entity-id "light.kitchen_lights")
(hass-dash-toggle :entity-id "light.master_bedroom_lights")
(hass-dash-toggle :entity-id "switch.entry_light"
:label "Hallway" ; Override the widgets friendly name
:confirm t))) ; Require a y/n confirmation when toggling this entity.
(hass-dash-group :title "Group 2" :format "\n\n%t\n\n%v"
(hass-dash-toggle :entity-id "light.master_bedroom_fan_light"))))
(simple . ; Declaring a top-level group is optional and implied.
((hass-dash-toggle :entity-id "light.kitchen_lights")
(hass-dash-toggle :entity-id "switch.entry_lights")))))
To use the dashboard feature, hass-dash-layouts
must be configure to tell hass
what the layout should look like. The layout is constructed with three components: groups, widgets, and properties.
- Each element in
hass-dash-layouts
is a dashboard. - A dashboard is a cons of its key/id and the widgets it contains.
- A widget is an Emacs widget, probably one from this package.
Any widgets defined in hass-dash-layouts
are automatically inserted into the hass-tracked-entities
list in order to receive state updates.
All widgets contain at least the following properties:
Widget Property | Description |
---|---|
:label | The human readable label of the widget to be shown on the dashboard. |
:service | The service to be called when the widget is selected. |
:icon | The icon to be shown prefixed to the widget. |
:confirm | When t or a string, ask for confirmation before calling the service. |
A ‘state’ widget is a read-only widget to simply display the state of some entity. I typically like to use this as the very first widget in a group to show the overall status of the group. For example, a vacuum:
(hass-dash-group :title "Vacuum"
(hass-dash-state :entity-id "vacuum.valetudo_vacuum" :format "%v\n")
; Vacuum related widgets
; ...
)
A ‘button’ widget is a push-button widget to call a service.
(hass-dash-button :entity-id "vacuum.valetudo_vacuum"
:service "vacuum.start"
:format "%[%t: %v%]\n"
:label "Clean")
A ‘toggle’ widget is similar to a button, except it’ll only show on or off. If the state is anything other than “on”, then it will show “off”.
(hass-dash-toggle :entity-id "light.kitchen")
To call a service on Home Assistant, use the hass-call-service
function which has two required arguments: entity-id
and service
.
(hass-call-service "switch.bedroom_light" "switch.toggle")
If you call hass-call-service
interactively, it will prompt you for an entity ID and then the respective service you want to call.
After configuring the hass-dash-layouts
, use the function hass-dash-open
to pop open a dashboard. This can be enhanced with standard buffer management configuration or packages like popper
and/or shackle
.
For services that require additional data use the hass-call-service-with-payload
function. The second argument, payload
, requires an JSON encoded string.
This example publishes to an MQTT topic:
(hass-call-service-with-payload
"mqtt.publish"
(json-encode '(("payload" . "PERFORM")
("topic" . "valetudo/vacuum/LocateCapability/locate/set"))))
You could pass a JSON string directly, but that would require escaping every quote which can be cumbersome. Here’s what the encoded list above looks like in JSON:
{
"payload": "PERFORM",
"topic": "valetudo/vacuum/LocateCapability/locate/set"
}
The most useful hook is a function list named hass-entity-state-changed-functions
. Functions in this list are passed a single argument entity-id
which is the entity id of the entity whose state has changed since it was last updated. Using this function hook along side tracking entities enables Emacs to react to changes to Home Assistant entities.
This example will display the state of an entity when it changes:
(add-hook 'hass-entity-state-changed-functions
(lambda (entity-id)
(message "The entity %s state has changed to %s." entity-id (hass-state-of entity-id))))
The other two hooks available are hass-entity-updated-hook
and hass-service-called-hook
. hass-entity-updated-hook
is called when the state of an entity is updated, regardless of if it changed or not. hass-service-called-hook
is called when a service
is called.
(add-hook 'hass-service-called-hook (lambda () (message "A service was called.")))
(add-hook 'hass-entity-updated-hook (lambda () (message "An entitys' state was updated.")))
MIT