kevinschweikert
Nerves Home Assistant integration
I’ve had the idea to integrate Nerves devices into Home Assistant. The idea would be to communicate with Home Assistant which autodiscovers new devices and creates entities in Home Assistant to get all the wonderful features like a nice UI, historical data, automations, backup, interop with other devices and more for free.
My vision is to make device smart and integrate them easily into Home Assistant.
Some pseudo code could look like this:
defmodule MyNervesProject do
use HomeAssistantNerves
entity :sensor, :temperature do
name "Living Room Temperature"
unit_of_measurement "°C"
device_class :temperature
state_class :measurement
state_fn fn ->
{:ok, temp} = YourTempSensor.read()
temp
end
update_interval 60_000
end
entity :switch, :relay do
name "Garage Light"
state_fn fn ->
GPIO.read(pin)
end
on_command fn state ->
GPIO.write(pin, state)
end
end
end
This could be a nice use case for Build a Weather Station with Elixir and Nerves (PragProg)
But i’m still not a 100% sure on how to implement the communication layer between Nerves and Homeassistant. I see three options:
-
MQTT
Homeassistant offers a automatic device discovery with MQTT. This is very nice, because we wouldn’t have to create a custom integration and using native mechanics. The downside would be, that the user has to configure MQTT and run a broker (which should be already pretty common in a smart home but still) -
Native API
Another option would be to directly hook in to the native APIs from Home Asssistant. This would had the same benefit of not writing a custom integration and also not having to use a MQTT broker but we would have to maintain the calls to the REST API (entity creation) and WebSocket API (realtime updates) -
Custom Integration
This would be the most complex solution but also the most flexible. We could decide ourselves on how to communicate with the device (SSH, gRPC, WebSocket, TCP, HTTP) and implement Nerves only functionality into Home Assistant if there is a need for it. This would involve writing a custom integration in Home Assistant (which i’ve done for other devices, e.g. GitHub - kevinschweikert/ha-mahlkoenig: A homeassistant integration for the Mahlkönig X54 coffee grinder · GitHub) which acts as a translation layer. -
Any other ideas?
Before starting this adventure, is there anything you would wish for? Any ideas for improvements? Is there a need/interest in the community?
I’ve looked at other topics but they wanted to write a standalone smart home solution or just connect to the existing information in Home Assistant
Most Liked
kevinschweikert
Just a quick update:
The project is called homex and can be found at GitHub - kevinschweikert/homex: A bridge between Elixir and Home Assistant · GitHub .
There is a nerves example project at GitHub - kevinschweikert/Homex-Nerves-Example: An example project using Homex in Nerves · GitHub
I’m currenlty waiting on a new Hex release of the emqtt library which i am using as the MQTT client.
Some sample code:
defmodule HomexDemo.TemperatureSensor do
@moduledoc """
A Homex.Entity for the BME680 sensors temperature values
"""
use Homex.Entity.Sensor,
name: "bme680 temp",
device_class: "temperature",
unit_of_measurement: "°C"
def handle_timer(entity) do
{:ok, measurements} = BMP280.measure(BME680)
entity |> set_value(Float.round(measurements.temperature_c, 2))
end
end
defmodule HomexDemo.Relay do
@moduledoc """
A Homex.Entity for a relay.
Uses `put_private/3` and `get_private/2` to keep the i2c bus handle in state and reference it
"""
use Homex.Entity.Switch, name: "quiick_relay"
def handle_init(entity) do
{:ok, bus} = Circuits.I2C.open("i2c-1")
entity |> put_private(:bus, bus) |> set_off()
end
def handle_on(entity) do
bus = entity |> get_private(:bus)
Circuits.I2C.write!(bus, 0x18, <<0x01>>)
entity
end
def handle_off(entity) do
bus = entity |> get_private(:bus)
Circuits.I2C.write!(bus, 0x18, <<0x00>>)
entity
end
end
and some pictures
i will write an announcement post when the hex version is published. But in the meantime feel free to play around with it and give feedback!
kevinschweikert
After a bit of back and forth with @joshknz we came to the conclusion that the MQTT route would be the best to start from and see from there how the project evolves. Josh also made the point to look at Matter and see if that could be a more generic solution to make Nerves devices compatible with ecosystems like Apple HomeKit and Google Home instead of only Home Assistant. Home Assistant already supports Matter so that way would still be possible.
Inspiration came from GitHub - mtrudel/hap: A HomeKit Accessory Protocol (HAP) Implementation for Elixir · GitHub
We also talked about a more GenServer-ish implementation which could look like this:
defmodule LivingRoomTemo do
use HomeAssistantNerves.Sensor,
name: "Living Room Temperature",
unit_of_measurement: "°C",
device_class: :temperature,
update_interval: Duration.new(seconds: 60)
def handle_state(_temp) do
YourTempSensor.read()
end
end
defmodule Garage do
use HomeAssistantNerves.Switch,
name: "Garage Light"
def handle_state(_state) do
GPIO.read(pin)
end
def handle_command(:toggle, _state) do
GPIO.write(pin, !state)
end
end
The plan is to create a Repo and go from there and explore ideas. Will post the link here as soon as we have something to show!
kevinschweikert
Popular in Discussions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #elixirconf-us
- #advent-of-code
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #hex











