Added the zig_main project to software for zig based implementation of code for robot

This commit is contained in:
2026-05-05 20:14:04 +12:00
parent 7d752f2534
commit f21f909a71
83 changed files with 13631 additions and 0 deletions

View File

@@ -0,0 +1,252 @@
//! ESP Matter wrapper — Zig interface to the CHIP/Matter C++ SDK via matter_stubs.h.
//!
//! Requires the `espressif/esp_matter` managed component.
//! To add it: `idf.py add-dependency espressif/esp_matter`
const sys = @import("sys");
const errors = @import("error");
// ── Re-export core types ─────────────────────────────────────────────────────
pub const Node = sys.esp_matter_node_t;
pub const Endpoint = sys.esp_matter_endpoint_t;
pub const Cluster = sys.esp_matter_cluster_t;
pub const Attribute = sys.esp_matter_attribute_t;
/// Endpoint creation flags.
pub const EpFlags = enum(u8) {
none = sys.ESP_MATTER_EP_FLAG_NONE,
destroyable = sys.ESP_MATTER_EP_FLAG_DESTROYABLE,
bridge = sys.ESP_MATTER_EP_FLAG_BRIDGE,
};
/// Attribute value types (Zig enum wrapping the C enum constants).
pub const ValType = enum(c_uint) {
invalid = sys.ESP_MATTER_VAL_TYPE_INVALID,
boolean = sys.ESP_MATTER_VAL_TYPE_BOOLEAN,
integer = sys.ESP_MATTER_VAL_TYPE_INTEGER,
float_ = sys.ESP_MATTER_VAL_TYPE_FLOAT,
array = sys.ESP_MATTER_VAL_TYPE_ARRAY,
char_string = sys.ESP_MATTER_VAL_TYPE_CHAR_STRING,
octet_string = sys.ESP_MATTER_VAL_TYPE_OCTET_STRING,
int8 = sys.ESP_MATTER_VAL_TYPE_INT8,
uint8 = sys.ESP_MATTER_VAL_TYPE_UINT8,
int16 = sys.ESP_MATTER_VAL_TYPE_INT16,
uint16 = sys.ESP_MATTER_VAL_TYPE_UINT16,
int32 = sys.ESP_MATTER_VAL_TYPE_INT32,
uint32 = sys.ESP_MATTER_VAL_TYPE_UINT32,
int64 = sys.ESP_MATTER_VAL_TYPE_INT64,
uint64 = sys.ESP_MATTER_VAL_TYPE_UINT64,
enum8 = sys.ESP_MATTER_VAL_TYPE_ENUM8,
bitmap8 = sys.ESP_MATTER_VAL_TYPE_BITMAP8,
bitmap16 = sys.ESP_MATTER_VAL_TYPE_BITMAP16,
bitmap32 = sys.ESP_MATTER_VAL_TYPE_BITMAP32,
enum16 = sys.ESP_MATTER_VAL_TYPE_ENUM16,
long_char_string = sys.ESP_MATTER_VAL_TYPE_LONG_CHAR_STRING,
long_octet_string = sys.ESP_MATTER_VAL_TYPE_LONG_OCTET_STRING,
_,
};
/// Attribute value (union mirroring esp_matter_val_t).
pub const Val = sys.esp_matter_val_t;
/// Attribute value with type tag.
pub const AttrVal = sys.esp_matter_attr_val_t;
/// Attribute update callback type (Zig enum with named members).
/// Use e.g. `matter.AttrCbType.ESP_MATTER_ATTR_CB_POST_UPDATE`.
pub const AttrCbType = enum(c_uint) {
ESP_MATTER_ATTR_CB_PRE_UPDATE = sys.ESP_MATTER_ATTR_CB_PRE_UPDATE,
ESP_MATTER_ATTR_CB_POST_UPDATE = sys.ESP_MATTER_ATTR_CB_POST_UPDATE,
ESP_MATTER_ATTR_CB_READ = sys.ESP_MATTER_ATTR_CB_READ,
ESP_MATTER_ATTR_CB_WRITE = sys.ESP_MATTER_ATTR_CB_WRITE,
_,
};
/// Attribute update callback function pointer type.
/// The callback receives a `?*AttrVal` which at the C ABI boundary is `[*c]AttrVal`.
/// Return 0 (ESP_OK) to allow, non-zero from PRE_UPDATE to block.
pub const AttrCallback = ?*const fn (
AttrCbType,
u16,
u32,
u32,
?*AttrVal,
?*anyopaque,
) callconv(.c) c_int;
/// Identify cluster callback type.
pub const IdentifyCbType = enum(c_uint) {
ESP_MATTER_IDENTIFY_CB_START = sys.ESP_MATTER_IDENTIFY_CB_START,
ESP_MATTER_IDENTIFY_CB_STOP = sys.ESP_MATTER_IDENTIFY_CB_STOP,
ESP_MATTER_IDENTIFY_CB_EFFECT = sys.ESP_MATTER_IDENTIFY_CB_EFFECT,
_,
};
/// Identify cluster callback function pointer type.
pub const IdentifyCallback = ?*const fn (IdentifyCbType, u16, u8, u8, ?*anyopaque) callconv(.c) c_int;
// ── Attribute value helpers ──────────────────────────────────────────────────
/// Convenience wrappers matching esp_matter_val_bool(), esp_matter_uint8(), etc.
pub const val = struct {
pub fn boolean(b: bool) AttrVal {
return sys.esp_matter_val_bool(b);
}
pub fn uint8(v: u8) AttrVal {
return sys.esp_matter_val_uint8(v);
}
pub fn uint16(v: u16) AttrVal {
return sys.esp_matter_val_uint16(v);
}
pub fn uint32(v: u32) AttrVal {
return sys.esp_matter_val_uint32(v);
}
pub fn int16(v: i16) AttrVal {
return sys.esp_matter_val_int16(v);
}
pub fn nullable() AttrVal {
return sys.esp_matter_val_nullable();
}
};
// ── Core ─────────────────────────────────────────────────────────────────────
/// Start the Matter stack (non-blocking; spawns Matter OS task).
/// Call after building the node + endpoint + cluster data model.
pub fn start(attr_cb: AttrCallback, identify_cb: IdentifyCallback) !void {
// @ptrCast converts our typed function pointer to the raw sys type.
// The types are ABI-compatible: enum(c_uint)↔c_uint, ?*T↔[*c]T.
try errors.espCheckError(sys.esp_matter_wrapper_start(@ptrCast(attr_cb), @ptrCast(identify_cb)));
}
/// Erase Matter NVS data and reboot. Non-recoverable.
pub fn factoryReset() !void {
try errors.espCheckError(sys.esp_matter_wrapper_factory_reset());
}
/// Return true if Matter has been started.
pub fn isStarted() bool {
return sys.esp_matter_wrapper_is_started();
}
// ── Node ─────────────────────────────────────────────────────────────────────
/// Create the root Matter node (endpoint 0, Root Node device type).
/// attr_cb fires on every attribute read/write; identify_cb fires on Identify requests.
/// priv_data is forwarded to both callbacks.
pub fn nodeCreate(attr_cb: AttrCallback, identify_cb: IdentifyCallback, priv_data: ?*anyopaque) !*Node {
const n = sys.esp_matter_wrapper_node_create(@ptrCast(attr_cb), @ptrCast(identify_cb), priv_data);
if (n == null) return error.MatterNodeCreateFailed;
return @ptrCast(n);
}
// ── Endpoint ─────────────────────────────────────────────────────────────────
/// Endpoint operations.
pub const endpoint = struct {
/// Create a generic endpoint on the node.
pub fn create(node: *Node, flags: EpFlags, priv_data: ?*anyopaque) !*Endpoint {
const ep = sys.esp_matter_wrapper_endpoint_create(node, @intFromEnum(flags), priv_data);
if (ep == null) return error.MatterEndpointCreateFailed;
return @ptrCast(ep);
}
/// Destroy a destroyable endpoint.
pub fn destroy(node: *Node, ep: *Endpoint) !void {
try errors.espCheckError(sys.esp_matter_wrapper_endpoint_destroy(node, ep));
}
/// Return the endpoint's numeric ID.
pub fn getId(ep: *Endpoint) u16 {
return sys.esp_matter_wrapper_endpoint_get_id(ep);
}
/// Associate a Matter device type with this endpoint.
pub fn addDeviceType(ep: *Endpoint, device_type_id: u32, version: u8) !void {
try errors.espCheckError(
sys.esp_matter_wrapper_endpoint_add_device_type(ep, device_type_id, version),
);
}
/// Enable a dynamically-created endpoint (only after Matter is started).
pub fn enable(ep: *Endpoint) !void {
try errors.espCheckError(sys.esp_matter_wrapper_endpoint_enable(ep));
}
// ── Pre-built device-type helpers ─────────────────────────────────────
/// Add an On/Off Light endpoint (device type 0x0100).
pub fn addOnOffLight(node: *Node, flags: EpFlags, priv_data: ?*anyopaque) !*Endpoint {
const ep = sys.esp_matter_wrapper_add_on_off_light(node, @intFromEnum(flags), priv_data);
if (ep == null) return error.MatterEndpointCreateFailed;
return @ptrCast(ep);
}
/// Add an On/Off Switch endpoint (device type 0x0103).
pub fn addOnOffSwitch(node: *Node, flags: EpFlags, priv_data: ?*anyopaque) !*Endpoint {
const ep = sys.esp_matter_wrapper_add_on_off_switch(node, @intFromEnum(flags), priv_data);
if (ep == null) return error.MatterEndpointCreateFailed;
return @ptrCast(ep);
}
/// Add a Dimmable Light endpoint (device type 0x0101).
pub fn addDimmableLight(node: *Node, flags: EpFlags, priv_data: ?*anyopaque) !*Endpoint {
const ep = sys.esp_matter_wrapper_add_dimmable_light(node, @intFromEnum(flags), priv_data);
if (ep == null) return error.MatterEndpointCreateFailed;
return @ptrCast(ep);
}
/// Add a Color Temperature Light endpoint (device type 0x010C).
pub fn addColorTemperatureLight(node: *Node, flags: EpFlags, priv_data: ?*anyopaque) !*Endpoint {
const ep = sys.esp_matter_wrapper_add_color_temperature_light(node, @intFromEnum(flags), priv_data);
if (ep == null) return error.MatterEndpointCreateFailed;
return @ptrCast(ep);
}
};
// ── Cluster ───────────────────────────────────────────────────────────────────
/// Cluster operations.
pub const cluster = struct {
/// Cluster flag: server cluster.
pub const FLAG_SERVER: u8 = 0x40;
/// Cluster flag: client cluster.
pub const FLAG_CLIENT: u8 = 0x80;
/// Create a cluster on an endpoint.
pub fn create(ep: *Endpoint, cluster_id: u32, flags: u8) !*Cluster {
const cl = sys.esp_matter_wrapper_cluster_create(ep, cluster_id, flags);
if (cl == null) return error.MatterClusterCreateFailed;
return @ptrCast(cl);
}
};
// ── Attribute ─────────────────────────────────────────────────────────────────
/// Attribute operations.
pub const attribute = struct {
/// Create an attribute on a cluster with a default value.
pub fn create(cl: *Cluster, attribute_id: u32, flags: u16, default_val: AttrVal) !*Attribute {
const attr = sys.esp_matter_wrapper_attribute_create(cl, attribute_id, flags, default_val);
if (attr == null) return error.MatterAttributeCreateFailed;
return @ptrCast(attr);
}
/// Update an attribute value (use after Matter is started).
pub fn update(endpoint_id: u16, cluster_id: u32, attribute_id: u32, v: *AttrVal) !void {
try errors.espCheckError(
sys.esp_matter_wrapper_attribute_update(endpoint_id, cluster_id, attribute_id, v),
);
}
/// Get the current value of an attribute.
pub fn getVal(attr: *Attribute, v: *AttrVal) !void {
try errors.espCheckError(sys.esp_matter_wrapper_attribute_get_val(attr, v));
}
/// Set an attribute value (use before Matter is started).
pub fn setVal(attr: *Attribute, v: *AttrVal) !void {
try errors.espCheckError(sys.esp_matter_wrapper_attribute_set_val(attr, v));
}
};