HABridge

Published on Jan 6, 2024


bridge!

Create a Home Assistant sensor from any hardware and send measurements with ESPNow or LoRa

Building from our ESPNow and LoRa components for Home Assistant/ESPHome, we’ve added a way to do the same thing with any Arduino-compatible board with a radio.

To recap, there’s not an easy way to send messages with ESPNow or LoRa within ESPHome/Home Assistant. There are a handful of reasons why you might want to.

  • speed there’s no need to negotiate a connection to any servers, messages can be sent in milliseconds from waking up
  • battery-friendly WiFi is not ideal for battery-powered devices, it can take several seconds to start a connection
  • range ESPNow has a long-range option, and LoRa can go several kilometers under the right circumstances

The components allow you to create sensors (regular measurements, binary, text) using ESPHome, but sometimes you want to use something other than an ESP32 and Home Assistant. That’s where this library comes in. You could use something like this RAK3172 which is a LoRa radio and processor combined. It has Arduino support, but wouldn’t have been able to be used within Home Assistant.

Use

HABridge is on GitHub, listed in the Arduino Library Manager, and PlatformIO. Any Arduino-compatible hardware can be used, but you will need a LoRa radio that is usable with the arduino-LoRa library for LoRa, or an ESP32 to use ESPNow.

The API is simple, there are only two methods: ::line and ::send. There are two example projects that come with the library, one to use ESPNow and the other for LoRa.

#include <Arduino.h>
#include <HABridge.h>
#include <ESPNowBridge.h>
#define DEVICE_NAME "test_device"

HABridgeSensor sensor(DEVICE_NAME, "temperature_sensor", HABridge::SensorClass::TEMPERATURE,\
                      HABridge::SensorState::MEASUREMENT, "C", "mdi:temperature-celsius");
                      
HABridgeBinary binary(DEVICE_NAME, "binary_sensor");
HABridgeText text(DEVICE_NAME, "text_sensor", "mdi:text");
ESPNowBridge now;

void setup() {
  now.begin();
}

void loop() {
  now.send(sensor.line(rand() % 20, 2));
  now.send(binary.line(rand() % 2));
  now.send(text.line(rand() % 2 ? "charging" : "discharging"));

  delay(5000);
}

This example just uses rand() to simulate sensor measurements.