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:

  1. 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)

  2. 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)

  3. 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) which acts as a translation layer.

  4. 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

5 Likes

Could Home Assistant be fully managed within the Nerves runtime with Pythonx?

Possibly if it can run as a single python instance. I think HA typically wants more. But that seems very separate from what Kevin wants to achieve. If it is something you are interested in exploring I’d love a separate topic for that :slight_smile: how I understand what you are saying is that you are talking about running HA itself from Nerves. Which is interesting but different from making a Nerves device integrate with HA.

*intermission *Home Assistant with High Availability is hilarious. One could say it is HA HA.

Moving on.

@kevinschweikert I guess the HA API and WebSocket are the most straightforward and capable for integrating really well. Also doesn’t need extra stuff.

This would be a neat thing to toolup. HA API and some nice config or DSL to declare how the device shows up.

3 Likes

Yes, i want to create an easy way to add your Nerves devices and their sensor data to Home Assistant. Home Assistant itself is better run in their own HA OS as a central server which scrapes/connects to all the IoT devices.

But that brings me to my next point. @lawik i’ve had a look at the REST API docs and i see no way to create devices/integrations/entities dynamically this way. The official supported way seems to be the MQTT route. Additionally with option 2 we would need to have the Nerves device connect to HA (Home Assistant) and this seems like the reversed way to organize this. HA should see and connect to devices not the other way round. I think that wipes 2 off the table.

That leaves us with 1 and 3 and i tend to the MQTT option (1) because we could develop this without writing a custom integration for HA. The library could be written in a way which let’s the user select the communication mechanism and we start with MQTT only and we can add a “native” way later.

We first focus on the abstraction to get the correct entity types for your sensors in HA and collect some basic system information to monitor the device with HA.

1 Like

I love this idea of a clean way of creating devices and entities for Home Assistant in Elixir and Nerves.

I’d be super keen to help any way I can.

2 Likes

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

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!

4 Likes