Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 111 additions & 0 deletions include/zephyr/mgmt/homeassistant/homeassistant.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
/*
* Copyright (c) 2025 Benjamin Cabé
*
* SPDX-License-Identifier: Apache-2.0
*/

#ifndef ZEPHYR_INCLUDE_MGMT_HOMEASSISTANT_H_
#define ZEPHYR_INCLUDE_MGMT_HOMEASSISTANT_H_

#include <zephyr/kernel.h>
#include <zephyr/zbus/zbus.h>

#ifdef __cplusplus
extern "C" {
#endif

/**
* @brief Home Assistant Integration API
* @defgroup homeassistant_api Home Assistant Integration API
* @ingroup mgmt
* @{
*/

/**
* @brief Entity types supported by Home Assistant
*/
enum homeassistant_entity_type {
/** Sensor entity (read-only) */
HOMEASSISTANT_ENTITY_SENSOR,
/** Binary sensor entity (on/off) */
HOMEASSISTANT_ENTITY_BINARY_SENSOR,
/** Switch entity (controllable on/off) */
HOMEASSISTANT_ENTITY_SWITCH,
/** Number entity (numeric value) */
HOMEASSISTANT_ENTITY_NUMBER,
};

/**
* @brief Home Assistant entity configuration
*/
struct homeassistant_entity_config {
/** Name of the entity as it appears in Home Assistant */
const char *name;
/** Type of entity */
enum homeassistant_entity_type type;
/** Unit of measurement (for sensors, can be NULL) */
const char *unit;
/** Device class (e.g., "temperature", "humidity", can be NULL) */
const char *device_class;
/** Zbus channel associated with this entity */
const struct zbus_channel *channel;
};

/**
* @brief Register a Zbus channel with Home Assistant
*
* This function registers a Zbus channel to be automatically synchronized
* with Home Assistant. The channel data will be published to Home Assistant
* as the specified entity type.
*
* @param config Entity configuration
* @return 0 on success, negative errno on failure
*/
int homeassistant_register_entity(const struct homeassistant_entity_config *config);

/**
* @brief Initialize Home Assistant integration
*
* This function starts the Home Assistant integration service, which monitors
* registered Zbus channels and synchronizes them with Home Assistant.
*
* @return 0 on success, negative errno on failure
*/
int homeassistant_init(void);

/**
* @brief Macro to define and register a Home Assistant entity
*
* This macro creates a Home Assistant entity configuration and automatically
* registers it at initialization time.
*
* @param _var_name Variable name for the entity (used internally)
* @param _entity_name Name of the entity as a string (e.g., "temperature")
* @param _type Entity type (e.g., HOMEASSISTANT_ENTITY_SENSOR)
* @param _unit Unit of measurement (or NULL)
* @param _device_class Device class (or NULL)
* @param _channel Zbus channel to monitor
*/
#define HOMEASSISTANT_ENTITY_DEFINE(_var_name, _entity_name, _type, _unit, _device_class, _channel) \
static const struct homeassistant_entity_config _homeassistant_entity_##_var_name = { \
.name = _entity_name, \
.type = _type, \
.unit = _unit, \
.device_class = _device_class, \
.channel = &_channel, \
}; \
static int _homeassistant_entity_init_##_var_name(void) \
{ \
return homeassistant_register_entity(&_homeassistant_entity_##_var_name); \
} \
SYS_INIT(_homeassistant_entity_init_##_var_name, APPLICATION, 91)

/**
* @}
*/

#ifdef __cplusplus
}
#endif

#endif /* ZEPHYR_INCLUDE_MGMT_HOMEASSISTANT_H_ */
8 changes: 8 additions & 0 deletions samples/subsys/homeassistant/basic/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# SPDX-License-Identifier: Apache-2.0

cmake_minimum_required(VERSION 3.20.0)

find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(homeassistant_basic)

target_sources(app PRIVATE src/main.c)
145 changes: 145 additions & 0 deletions samples/subsys/homeassistant/basic/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
.. zephyr:code-sample:: homeassistant-basic
:name: Home Assistant Integration Basic
:relevant-api: homeassistant_api zbus_apis

Integrate Zephyr sensors with Home Assistant using Zbus channels.

Overview
********

This sample demonstrates how to integrate Zephyr-based IoT devices with Home Assistant
using the Home Assistant integration library. The library bridges Zbus channels to
Home Assistant, allowing developers to expose sensor data and control entities without
writing any networking code.

The sample creates three entities:

* **Temperature sensor** - Reports temperature in Celsius
* **Humidity sensor** - Reports humidity percentage
* **Light switch** - Binary switch that can be toggled

All sensor data is published through Zbus channels and automatically synchronized with
Home Assistant via the REST API.

Requirements
************

* Home Assistant instance running and accessible on the network
* Long-lived access token from Home Assistant (create from your profile)
* Network connectivity (Ethernet or Wi-Fi configured)

Configuration
*************

Before building, update the following configurations in ``prj.conf``:

.. code-block:: cfg

CONFIG_HOMEASSISTANT_SERVER_ADDR="192.168.1.100" # Your Home Assistant IP
CONFIG_HOMEASSISTANT_SERVER_PORT=8123 # Home Assistant port
CONFIG_HOMEASSISTANT_API_TOKEN="your_token_here" # Your API token
CONFIG_NET_CONFIG_MY_IPV4_ADDR="192.168.1.10" # Device IP address

To generate a Home Assistant API token:

1. Log into your Home Assistant web interface
2. Click on your profile (bottom left)
3. Scroll to "Long-Lived Access Tokens"
4. Click "Create Token"
5. Copy the token and update ``CONFIG_HOMEASSISTANT_API_TOKEN``

Building and Running
********************

This sample can be built for any board with networking support. Example for native_sim:

.. zephyr-app-commands::
:zephyr-app: samples/subsys/homeassistant/basic
:host-os: unix
:board: native_sim
:goals: build
:compact:

Or for a real board with Ethernet (e.g., STM32 Nucleo):

.. zephyr-app-commands::
:zephyr-app: samples/subsys/homeassistant/basic
:host-os: unix
:board: nucleo_f767zi
:goals: build flash
:compact:

Sample Output
=============

.. code-block:: console

*** Booting Zephyr OS build v3.x.x ***
[00:00:00.000,000] <inf> ha_sample: Home Assistant Integration Sample
[00:00:00.000,000] <inf> ha_sample: ===================================
[00:00:00.000,000] <inf> ha_sample: This sample demonstrates Zbus integration with Home Assistant
[00:00:00.000,000] <inf> ha_sample: Sensor data is automatically published to Home Assistant
[00:00:00.000,000] <inf> ha_sample:
[00:00:00.000,000] <inf> ha_sample: Configuration:
[00:00:00.000,000] <inf> ha_sample: Server: 192.168.1.100:8123
[00:00:00.000,000] <inf> ha_sample: Update interval: 5000 ms
[00:00:00.000,000] <inf> homeassistant: Registered entity: temperature (type=0)
[00:00:00.000,000] <inf> homeassistant: Registered entity: humidity (type=0)
[00:00:00.000,000] <inf> homeassistant: Registered entity: light (type=2)
[00:00:00.000,000] <inf> homeassistant: Home Assistant integration initialized
[00:00:00.000,000] <inf> homeassistant: Home Assistant integration started
[00:00:00.000,000] <inf> homeassistant: Server: 192.168.1.100:8123
[00:00:02.000,000] <inf> ha_sample: Starting sensor simulation...
[00:00:02.000,000] <inf> ha_sample: Temperature: 20°C
[00:00:02.000,000] <inf> ha_sample: Humidity: 40%
[00:00:02.000,000] <inf> ha_sample: Light switch: OFF

Home Assistant Integration
***************************

Once the sample is running, the entities will appear in Home Assistant:

* ``sensor.temperature`` - Temperature sensor with °C unit
* ``sensor.humidity`` - Humidity sensor with % unit
* ``sensor.light`` - Light switch control

You can view these entities in Home Assistant's Developer Tools > States page.

How It Works
************

The sample demonstrates the simplicity of the Home Assistant integration:

1. **Define Zbus channels** - Create channels for your sensor data:

.. code-block:: c

ZBUS_CHAN_DEFINE(temperature_chan, struct temperature_msg, ...);

2. **Register with Home Assistant** - Use the convenient macro:

.. code-block:: c

HOMEASSISTANT_ENTITY_DEFINE(temp_sensor,
"temperature",
HOMEASSISTANT_ENTITY_SENSOR,
"°C",
"temperature",
temperature_chan);

3. **Publish data to Zbus** - The library handles the rest:

.. code-block:: c

struct temperature_msg temp = { .value = 25 };
zbus_chan_pub(&temperature_chan, &temp, K_NO_WAIT);

The Home Assistant integration library automatically:

* Monitors registered Zbus channels for updates
* Formats data as JSON payloads
* Sends HTTP POST requests to Home Assistant REST API
* Handles authentication with your API token
* Updates entities at the configured interval

No networking code needed in your application!
40 changes: 40 additions & 0 deletions samples/subsys/homeassistant/basic/prj.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Logging
CONFIG_LOG=y
CONFIG_LOG_MODE_MINIMAL=y
CONFIG_BOOT_BANNER=n

# Zbus
CONFIG_ZBUS=y
CONFIG_ZBUS_LOG_LEVEL_INF=y
CONFIG_ZBUS_CHANNEL_NAME=y
CONFIG_ZBUS_OBSERVER_NAME=y

# Networking
CONFIG_NETWORKING=y
CONFIG_NET_IPV4=y
CONFIG_NET_TCP=y
CONFIG_NET_SOCKETS=y
CONFIG_NET_SOCKETS_POSIX_NAMES=y

# HTTP client
CONFIG_HTTP_CLIENT=y

# DNS resolver
CONFIG_DNS_RESOLVER=y
CONFIG_DNS_RESOLVER_ADDITIONAL_BUF_CTR=5
CONFIG_DNS_RESOLVER_ADDITIONAL_QUERIES=2

# Network configuration for testing
CONFIG_NET_CONFIG_SETTINGS=y
CONFIG_NET_CONFIG_MY_IPV4_ADDR="192.168.1.10"
CONFIG_NET_CONFIG_MY_IPV4_NETMASK="255.255.255.0"
CONFIG_NET_CONFIG_MY_IPV4_GW="192.168.1.1"

# Home Assistant
CONFIG_HOMEASSISTANT=y
CONFIG_HOMEASSISTANT_SERVER_ADDR="192.168.1.100"
CONFIG_HOMEASSISTANT_SERVER_PORT=8123
CONFIG_HOMEASSISTANT_API_TOKEN="your_token_here"
CONFIG_HOMEASSISTANT_DEVICE_NAME="Zephyr Sensor"
CONFIG_HOMEASSISTANT_UPDATE_INTERVAL=5000
CONFIG_HOMEASSISTANT_LOG_LEVEL_INF=y
21 changes: 21 additions & 0 deletions samples/subsys/homeassistant/basic/sample.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
sample:
name: Home Assistant Integration Basic
description: Demonstrates Zbus integration with Home Assistant
common:
tags:
- homeassistant
- zbus
- networking
- iot
harness: console
harness_config:
type: one_line
regex:
- "Home Assistant Integration Sample"
integration_platforms:
- native_sim
tests:
sample.subsys.homeassistant.basic:
platform_allow:
- native_sim
- qemu_x86
Loading