ESP Weaver

[中文]

Supported chips

ESP32

ESP32-C2

ESP32-C3

ESP32-C5

ESP32-C6

ESP32-C61

ESP32-S3

ESP Weaver is a device-side SDK for building smart home devices with Home Assistant local discovery and control support. Based on ESP-IDF’s esp_local_ctrl component and mDNS service discovery, it enables millisecond-level local network communication without relying on cloud services.

The SDK provides a simple device/parameter model, supporting device creation, parameter management, write callbacks, and real-time parameter push to connected clients. It supports Security1 protocol (Curve25519 + AES-CTR) with Proof of Possession (PoP) for secure communication.

Features

  • Low-latency local control via mDNS + esp_local_ctrl

  • Offline capable, no internet connection required

  • End-to-end encryption with Proof of Possession (PoP)

  • Zero-configuration device discovery

  • Simple device/parameter model for smart home integration

  • Compatible with ESP-Weaver Home Assistant custom integration

Architecture

+-------------------+    mDNS Discovery    +-------------------+
|                   | <------------------- |                   |
|  Home Assistant   |                      |    ESP Device     |
|  (ESP-Weaver)     | -------------------> |   (ESP Weaver)    |
|                   |    Local Control     |                   |
+-------------------+                      +-------------------+
         |                                          |
         |               Local Network              |
         +------------------------------------------+
  1. ESP device connects to WiFi and broadcasts service via mDNS

  2. ESP-Weaver integration in Home Assistant discovers the device

  3. User enters the device’s PoP code to complete pairing

  4. Bidirectional communication through Local Control protocol

Examples

  1. LED Light Example: weaver/led_light. RGB LED light control with power, brightness, HSV color, and color temperature support.

API Reference

Header File

Functions

esp_weaver_param_val_t esp_weaver_bool(bool bval)

Create a Weaver value with a boolean.

Parameters

bval[in] Boolean value to store

Returns

Weaver param value structure with type WEAVER_VAL_TYPE_BOOLEAN

esp_weaver_param_val_t esp_weaver_int(int ival)

Create a Weaver value with an integer.

Parameters

ival[in] Integer value to store (signed 32-bit)

Returns

Weaver param value structure with type WEAVER_VAL_TYPE_INTEGER

esp_weaver_param_val_t esp_weaver_float(float fval)

Create a Weaver value with a float.

Parameters

fval[in] Floating-point value to store (32-bit)

Returns

Weaver param value structure with type WEAVER_VAL_TYPE_FLOAT

esp_weaver_param_val_t esp_weaver_str(const char *sval)

Create a Weaver value with a string.

Parameters

sval[in] Pointer to a null-terminated string

Returns

Weaver param value structure with type WEAVER_VAL_TYPE_STRING

esp_weaver_param_val_t esp_weaver_obj(const char *val)

Create a Weaver value with a JSON object string.

Parameters

val[in] Pointer to a null-terminated JSON object string (e.g. “{"name”:”value”}”)

Returns

Weaver param value structure with type WEAVER_VAL_TYPE_OBJECT

esp_weaver_param_val_t esp_weaver_array(const char *val)

Create a Weaver value with a JSON array string.

Parameters

val[in] Pointer to a null-terminated JSON array string (e.g. “[1,2,3]”)

Returns

Weaver param value structure with type WEAVER_VAL_TYPE_ARRAY

esp_weaver_node_t *esp_weaver_node_init(const esp_weaver_config_t *config, const char *name, const char *type)

Initialize the Weaver node (singleton)

Only one node may exist at a time. Calling this again without esp_weaver_node_deinit() will return NULL.

Parameters
  • config[in] Pointer to configuration structure (must not be NULL, use ESP_WEAVER_CONFIG_DEFAULT())

  • name[in] Node name (must not be NULL)

  • type[in] Node type (must not be NULL)

Returns

Node handle on success, or NULL on failure

esp_err_t esp_weaver_node_deinit(const esp_weaver_node_t *node)

Deinitialize the Weaver node and free all resources.

This function frees all devices, parameters, and node resources. After calling this, esp_weaver_node_init() can be called again.

Parameters

node[in] Node handle returned by esp_weaver_node_init() (must not be NULL)

Returns

  • ESP_OK: Node deinitialized successfully

  • ESP_ERR_INVALID_STATE: Node not initialized

  • ESP_ERR_INVALID_ARG: Invalid parameter

const char *esp_weaver_get_node_id(void)

Get Node ID.

Returns pointer to the NULL terminated Node ID string.

Returns

Pointer to a NULL terminated Node ID string, or NULL if not initialized

esp_err_t esp_weaver_node_add_device(const esp_weaver_node_t *node, esp_weaver_device_t *device)

Add a device to a node.

Parameters
  • node[in] Node handle (must not be NULL)

  • device[in] Device handle (must not be NULL)

Returns

  • ESP_OK: Device added successfully

  • ESP_ERR_INVALID_ARG: Invalid parameter or duplicate device name

esp_err_t esp_weaver_node_remove_device(const esp_weaver_node_t *node, esp_weaver_device_t *device)

Remove a device from a node.

Note

The device should be removed before deleting it with esp_weaver_device_delete().

Parameters
  • node[in] Node handle (must not be NULL)

  • device[in] Device handle (must not be NULL)

Returns

  • ESP_OK: Device removed successfully

  • ESP_ERR_INVALID_ARG: Invalid parameter

  • ESP_ERR_NOT_FOUND: Device not found in node

esp_weaver_device_t *esp_weaver_device_create(const char *dev_name, const char *type, void *priv_data)

Create a Device.

Note

The device created needs to be added to a node using esp_weaver_node_add_device().

Parameters
  • dev_name[in] The unique device name (must not be NULL)

  • type[in] Device type (must not be NULL, e.g., “esp.device.lightbulb”)

  • priv_data[in] Private data associated with the device (can be NULL). This will be passed to callbacks

Returns

Pointer to the created device, or NULL on failure

esp_err_t esp_weaver_device_delete(esp_weaver_device_t *device)

Delete a Device.

This API will delete a device created using esp_weaver_device_create(). All parameters associated with the device are also freed.

Note

The device should first be removed from the node using esp_weaver_node_remove_device() before deleting.

Parameters

device[in] Device handle (must not be NULL)

Returns

  • ESP_OK: Device deleted successfully

  • ESP_ERR_INVALID_ARG: Invalid parameter

esp_err_t esp_weaver_device_add_param(esp_weaver_device_t *device, esp_weaver_param_t *param)

Add a parameter to a device.

Note

A device supports up to 255 parameters.

Parameters
  • device[in] Device handle (must not be NULL)

  • param[in] Parameter handle (must not be NULL)

Returns

  • ESP_OK: Parameter added successfully

  • ESP_ERR_INVALID_ARG: Invalid parameter or duplicate parameter name

  • ESP_ERR_NO_MEM: Maximum number of parameters reached

esp_err_t esp_weaver_device_add_bulk_cb(esp_weaver_device_t *device, esp_weaver_device_bulk_write_cb_t write_cb)

Add bulk write callback for a device.

Parameters
  • device[in] Device handle (must not be NULL)

  • write_cb[in] Bulk write callback function (must not be NULL)

Returns

  • ESP_OK: Callback set successfully

  • ESP_ERR_INVALID_ARG: Invalid parameter

esp_err_t esp_weaver_device_assign_primary_param(esp_weaver_device_t *device, esp_weaver_param_t *param)

Assign a primary parameter.

Assign a parameter (already added using esp_weaver_device_add_param()) as a primary parameter, which can be used by clients to give prominence to it.

Parameters
  • device[in] Device handle (must not be NULL)

  • param[in] Parameter handle (must not be NULL)

Returns

  • ESP_OK: Primary parameter assigned successfully

  • ESP_ERR_INVALID_ARG: Invalid parameter

  • ESP_ERR_NOT_FOUND: Parameter not found in device

const char *esp_weaver_device_get_name(const esp_weaver_device_t *device)

Get device name from handle.

Parameters

device[in] Device handle (must not be NULL)

Returns

NULL terminated device name string, or NULL on failure

void *esp_weaver_device_get_priv_data(const esp_weaver_device_t *device)

Get device private data from handle.

Parameters

device[in] Device handle (must not be NULL)

Returns

Pointer to the private data, or NULL if no private data found

esp_weaver_param_t *esp_weaver_device_get_param_by_name(const esp_weaver_device_t *device, const char *param_name)

Get parameter by name.

Get handle for a parameter based on the name.

Parameters
  • device[in] Device handle (must not be NULL)

  • param_name[in] Parameter name to search (must not be NULL)

Returns

Parameter handle on success, or NULL on failure

esp_weaver_param_t *esp_weaver_device_get_param_by_type(const esp_weaver_device_t *device, const char *param_type)

Get parameter by type.

Get handle for a parameter based on the type.

Parameters
  • device[in] Device handle (must not be NULL)

  • param_type[in] Parameter type to search (must not be NULL, e.g., “esp.param.power”)

Returns

Parameter handle on success, or NULL on failure

esp_weaver_param_t *esp_weaver_param_create(const char *param_name, const char *type, esp_weaver_param_val_t val, uint8_t properties)

Create a Parameter.

Note

The parameter created needs to be added to a device using esp_weaver_device_add_param(). Parameter name should be unique in a given device.

Parameters
  • param_name[in] Name of the parameter (must not be NULL)

  • type[in] Parameter type (must not be NULL, e.g., “esp.param.power”)

  • val[in] Value of the parameter. This also specifies the type that will be assigned to this parameter. You can use esp_weaver_bool(), esp_weaver_int(), esp_weaver_float() or esp_weaver_str() functions as the argument here. Eg, esp_weaver_bool(true)

  • properties[in] Properties of the parameter, which will be a logical OR of flags in esp_weaver_param_property_flags_t

Returns

Pointer to the created parameter, or NULL on failure

esp_err_t esp_weaver_param_delete(esp_weaver_param_t *param)

Delete a Parameter.

Use this to clean up a parameter that was created with esp_weaver_param_create() but not added to a device (e.g., if esp_weaver_device_add_param() failed).

Note

Parameters that have been added to a device are automatically freed when the device is deleted with esp_weaver_device_delete().

Parameters

param[in] Parameter handle (must not be NULL)

Returns

  • ESP_OK: Parameter deleted successfully

  • ESP_ERR_INVALID_ARG: Invalid parameter

esp_err_t esp_weaver_param_add_ui_type(esp_weaver_param_t *param, const char *ui_type)

Add a UI Type to a parameter.

Parameters
  • param[in] Parameter handle (must not be NULL)

  • ui_type[in] String describing the UI Type (must not be NULL, e.g., “esp.ui.toggle”)

Returns

  • ESP_OK: UI type added successfully

  • ESP_ERR_INVALID_ARG: Invalid parameter

  • ESP_ERR_NO_MEM: Memory allocation failed

esp_err_t esp_weaver_param_add_bounds(esp_weaver_param_t *param, esp_weaver_param_val_t min, esp_weaver_param_val_t max, esp_weaver_param_val_t step)

Add bounds for an integer/float parameter.

Eg. esp_weaver_param_add_bounds(brightness_param, esp_weaver_int(0), esp_weaver_int(100), esp_weaver_int(5));

Parameters
  • param[in] Parameter handle (must not be NULL)

  • min[in] Minimum allowed value

  • max[in] Maximum allowed value (must be >= min)

  • step[in] Minimum stepping (set to 0 if no specific value is desired)

Returns

  • ESP_OK: Bounds added successfully

  • ESP_ERR_INVALID_ARG: Invalid parameter

  • ESP_ERR_NO_MEM: Memory allocation failed

const char *esp_weaver_param_get_name(const esp_weaver_param_t *param)

Get parameter name from handle.

Parameters

param[in] Parameter handle (must not be NULL)

Returns

NULL terminated parameter name string, or NULL on failure

const esp_weaver_param_val_t *esp_weaver_param_get_val(const esp_weaver_param_t *param)

Get parameter value.

Note

This does not call any explicit functions to read value from hardware/driver.

Parameters

param[in] Parameter handle (must not be NULL)

Returns

Pointer to parameter value, or NULL on failure

esp_err_t esp_weaver_param_update(esp_weaver_param_t *param, esp_weaver_param_val_t val)

Update a parameter.

This will just update the value of a parameter without actually reporting it. This can be used when multiple parameters need to be reported together. Eg. If x parameters are to be reported, this API can be used for the first x - 1 parameters and the last one can be updated using esp_weaver_param_update_and_report(). This will report all parameters which were updated prior to this call.

Sample:

esp_weaver_param_update(param1, esp_weaver_int(180)); esp_weaver_param_update(param2, esp_weaver_int(80)); esp_weaver_param_update_and_report(param3, esp_weaver_int(50));

Parameters
  • param[in] Parameter handle (must not be NULL)

  • val[in] New value of the parameter

Returns

  • ESP_OK: Parameter updated successfully

  • ESP_ERR_INVALID_ARG: Invalid parameter or type mismatch

  • ESP_ERR_NO_MEM: Memory allocation failed (for string/object/array types)

esp_err_t esp_weaver_param_update_and_report(esp_weaver_param_t *param, esp_weaver_param_val_t val)

Update and report a parameter.

Calling this API will update the parameter and report it to connected clients. This should be used whenever there is any local change.

Parameters
  • param[in] Parameter handle (must not be NULL)

  • val[in] New value of the parameter

Returns

  • ESP_OK: Parameter updated and reported successfully

  • ESP_ERR_INVALID_ARG: Invalid parameter or type mismatch

  • ESP_ERR_NO_MEM: Memory allocation failed (for string/object/array types)

esp_err_t esp_weaver_local_ctrl_set_pop(const char *pop)

Set Proof of Possession (PoP) for local control security.

Note

This must be called before esp_weaver_local_ctrl_start() for it to take effect. If not called, a random PoP will be generated and stored in NVS.

Parameters

pop[in] NULL terminated PoP string. Pass NULL to clear any previously set custom PoP.

Returns

  • ESP_OK: PoP set successfully

  • ESP_ERR_INVALID_ARG: Empty PoP string

  • ESP_ERR_NO_MEM: Memory allocation failed

const char *esp_weaver_local_ctrl_get_pop(void)

Get the Proof of Possession (PoP) for local control.

Returns the current PoP string. The PoP is resolved in this order:

  1. User-set PoP (via esp_weaver_local_ctrl_set_pop())

  2. PoP stored in NVS (from a previous boot)

  3. Auto-generated random PoP (saved to NVS for persistence)

Note

This should be called after esp_weaver_local_ctrl_start() to ensure the PoP has been resolved.

Returns

PoP string on success, or NULL on failure

esp_err_t esp_weaver_local_ctrl_start(void)

Start local control service (HTTP + mDNS)

All configuration (HTTP port, security version, etc.) is read from Kconfig.

Returns

  • ESP_OK: Local control started successfully

  • ESP_ERR_INVALID_STATE: Weaver not initialized or already started

  • ESP_ERR_NO_MEM: Memory allocation failed

esp_err_t esp_weaver_local_ctrl_set_txt(const char *key, const char *value)

Set a custom mDNS TXT record for the local control service.

Must be called after esp_weaver_local_ctrl_start().

Parameters
  • key[in] TXT record key (must not be NULL)

  • value[in] TXT record value (must not be NULL)

Returns

  • ESP_OK: TXT record set successfully

  • ESP_ERR_INVALID_STATE: Local control not started

  • ESP_ERR_INVALID_ARG: Invalid parameter

esp_err_t esp_weaver_local_ctrl_stop(void)

Stop local control service.

Returns

  • ESP_OK: Local control stopped successfully

  • ESP_ERR_INVALID_STATE: Local control not started

esp_err_t esp_weaver_local_ctrl_send_params(void)

Push current parameter values to local control clients.

Call this after updating parameters with esp_weaver_param_update() to push the changes to connected clients. Not needed after esp_weaver_param_update_and_report() which sends automatically.

Returns

  • ESP_OK: Parameters sent successfully

  • ESP_ERR_INVALID_STATE: Local control not started

  • ESP_FAIL: Failed to generate or send parameters

Unions

union esp_weaver_val_t
#include <esp_weaver.h>

ESP Weaver Value data union.

Union containing the actual data for Weaver values. The active member is determined by the type field in the parent esp_weaver_param_val_t structure.

Note

Only access the member corresponding to the value type.

Public Members

bool b

Boolean data value

int i

Integer data value (signed 32-bit)

float f

Floating-point data value (32-bit)

char *s

String data value (pointer to null-terminated string)

Structures

struct esp_weaver_param_val_t

ESP Weaver Parameter Value.

Complete Weaver value with its type and associated data. Provides a unified way to handle different data types in the Weaver protocol.

Note

The type field determines which member of the val union is valid.

Note

For STRING type, val.s points to dynamically allocated memory.

Public Members

esp_weaver_val_type_t type

Type of the value (boolean, integer, float, or string)

esp_weaver_val_t val

Union containing the actual value data

struct esp_weaver_write_ctx_t

Write request Context.

Public Members

esp_weaver_req_src_t src

Source of the write request

struct esp_weaver_param_write_req_t

Parameter write request payload.

Public Members

esp_weaver_param_t *param

Parameter handle

esp_weaver_param_val_t val

Value to write

struct esp_weaver_config_t

ESP Weaver Configuration.

Public Members

const char *node_id

Custom node ID (max 32 chars). NULL to auto-generate from MAC address

Macros

ESP_WEAVER_CONFIG_DEFAULT()

Default Weaver configuration (auto-generated node ID)

Type Definitions

typedef struct esp_weaver_node esp_weaver_node_t

ESP Weaver Node handle.

Opaque structure representing a Weaver node instance.

typedef struct esp_weaver_device esp_weaver_device_t

ESP Weaver Device handle.

Opaque structure representing a device attached to a Weaver node.

typedef struct esp_weaver_param esp_weaver_param_t

ESP Weaver Parameter handle.

Opaque structure representing a single parameter within a device.

typedef esp_err_t (*esp_weaver_device_bulk_write_cb_t)(const esp_weaver_device_t *device, const esp_weaver_param_write_req_t write_req[], uint8_t count, void *priv_data, esp_weaver_write_ctx_t *ctx)

Callback for bulk parameter value write requests.

This callback is invoked when multiple parameters are received in a single request.

Note

This callback may execute in a transport-specific task context (e.g., HTTPD task), not the main task. Avoid blocking operations and ensure any shared state access is properly synchronized.

Param device

[in] Device handle (must not be NULL)

Param write_req

[in] Array of write requests (must not be NULL)

Param count

[in] Number of write requests in the array

Param priv_data

[in] Pointer to the private data passed while creating the device

Param ctx

[in] Context associated with the request

Return

  • ESP_OK: Success

  • ESP_ERR_INVALID_ARG: Invalid parameter

  • ESP_FAIL: Error

Enumerations

enum esp_weaver_val_type_t

ESP Weaver Value type.

Supported data types for Weaver parameter values.

Values:

enumerator WEAVER_VAL_TYPE_INVALID

Invalid

enumerator WEAVER_VAL_TYPE_BOOLEAN

Boolean

enumerator WEAVER_VAL_TYPE_INTEGER

Integer. Mapped to a 32 bit signed integer

enumerator WEAVER_VAL_TYPE_FLOAT

Floating point number

enumerator WEAVER_VAL_TYPE_STRING

NULL terminated string

enumerator WEAVER_VAL_TYPE_OBJECT

NULL terminated JSON Object string Eg. {“name”:”value”}

enumerator WEAVER_VAL_TYPE_ARRAY

NULL terminated JSON Array string Eg. [1,2,3]

enum esp_weaver_param_property_flags_t

Param property flags.

Values:

enumerator PROP_FLAG_WRITE

Parameter is writable

enumerator PROP_FLAG_READ

Parameter is readable

enumerator PROP_FLAG_PERSIST

Parameter value is persisted in NVS

enum esp_weaver_req_src_t

Parameter read/write request source.

Values:

enumerator ESP_WEAVER_REQ_SRC_INIT

Request triggered in the init sequence i.e. when a value is found in persistent memory for parameters with PROP_FLAG_PERSIST

enumerator ESP_WEAVER_REQ_SRC_LOCAL

Request from local control (HTTP)

enumerator ESP_WEAVER_REQ_SRC_MAX

This will always be the last value. Any value equal to or greater than this should be considered invalid