Matterlix

CIHex.pmHex DocsLicense

Elixir NIF bindings for the Matter (CHIP) smart home protocol. Build Matter-compatible devices on embedded Linux with Nerves.

Matter + Elixir = Matterlix

Overview

Matterlix is a reusable Elixir library that bridges the Matter C++ SDK with Elixir using NIFs. Your firmware project depends on matterlix and implements a Handler behaviour to react to Matter events.

┌─────────────────────────────────────────────────────┐
│                   Your Firmware                     │
│  ┌───────────────┐    ┌──────────────────────────┐  │
│  │   Your App    │───▶│ Matterlix.Handler        │  │
│  │  (Nerves)     │    │ (Your callbacks)         │  │
│  └───────────────┘    └──────────────────────────┘  │
│                              │                      │
│                              ▼                      │
│  ┌──────────────────────────────────────────────┐   │
│  │             Matterlix (library)              │   │
│  │  Matterlix.Matter (GenServer)                │   │
│  │  Matterlix.Matter.NIF (NIF bindings)         │   │
│  │  c_src/matter_nif.cpp (C++ NIF)              │   │
│  └──────────────────────────────────────────────┘   │
│                              │                      │
│                              ▼                      │
│  ┌──────────────────────────────────────────────┐   │
│  │            Matter SDK (libCHIP.a)            │   │
│  │  DeviceLayer │ Server │ Data Model (Clusters)│   │
│  └──────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────┘

Features

Prerequisites

Quick Start

1. Add Dependency

# In your firmware project's mix.exs
def deps do
  [{:matterlix, "~> 0.3"}]
end

2. Implement a Handler

defmodule MyApp.MatterHandler do
  @behaviour Matterlix.Handler

  @impl true
  def handle_attribute_change(1, 0x0006, 0x0000, _type, value) do
    # React to On/Off toggle from a Matter controller
    MyApp.LED.set(value)
    :ok
  end

  def handle_attribute_change(_ep, _cluster, _attr, _type, _value), do: :ok
end

3. Configure

# config/config.exs
config :matterlix,
  handler: MyApp.MatterHandler,
  device_profile: :light,
  setup_pin: 20202021,
  discriminator: 3840

4. Push Data to Matter

# Push a sensor reading — controllers get notified automatically
Matterlix.update_attribute(1, 0x0402, 0x0000, 2350)

# Toggle a light
Matterlix.update_attribute(1, 0x0006, 0x0000, true)

Building the Matter SDK

The library compiles in stub mode by default (no Matter SDK needed). For actual Matter functionality, build the SDK:

1. Clone Matter SDK

mkdir -p deps
git clone --depth 1 https://github.com/project-chip/connectedhomeip.git deps/connectedhomeip
cd deps/connectedhomeip
python3 scripts/checkout_submodules.py --shallow --platform linux

2. Build for a Device Profile

# List available profiles
mix matterlix.build_sdk --list

# Build for the default profile (light)
mix matterlix.build_sdk

# Build for a specific profile
mix matterlix.build_sdk --profile contact_sensor

This builds the Matter SDK in an arm64 Docker container and generates matter_sdk_includes.mk with the correct object files and libraries.

First build takes ~20-30 minutes.

3. Compile with Matter SDK

MATTER_SDK_ENABLED=1 mix compile

Device Profiles

Each profile maps to a Matter SDK example app with pre-configured clusters:

Profile Clusters Use Case
light (default) OnOff, LevelControl, ColorControl Dimmable color light
contact_sensor BooleanState Door/window sensor
lock DoorLock Smart lock
thermostat Thermostat HVAC control
air_quality_sensor AirQuality, Temperature, Humidity Environmental sensing
all_clusters All standard clusters Development/testing

System Requirements for Commissioning

Matter BLE commissioning requires BlueZ and D-Bus on Linux. Stock Nerves systems do not include Bluetooth support. You need a custom Nerves system with:

See the example/ directory for a working firmware project.

Testing

# Run tests (stub mode, no SDK needed)
mix test

# With AddressSanitizer (memory safety)
ASAN=1 mix test

# CI suite in Docker
docker build -f Dockerfile.ci -t matterlix-ci .
docker run --rm matterlix-ci

Complete Example

The example/ directory contains a fully working Matter light device with physical controls:

example/
├── lib/
│   ├── example/
│   │   ├── matter_light.ex   # Matter device logic & attribute handling
│   │   ├── pairing_button.ex # GPIO button with short/long press detection
│   │   └── status_led.ex     # LED patterns for device state feedback
│   └── example.ex            # Application supervisor
└── config/
    └── target.exs            # Raspberry Pi GPIO & commissioning config

See example/README.md for detailed documentation.

Configuration

Key Description Default
handler Module implementing Matterlix.HandlerMatterlix.Handler.Default
device_profile Matter device type :light
auto_supervise Auto-start GenServer in supervision tree true
setup_pin Commissioning PIN code (1-99999998) SDK default
discriminator 12-bit discriminator (0-4095) SDK default
debug Enable debug logging false

Environment Variables

Variable Description Default
MATTER_SDK_ENABLED Enable Matter SDK integration 0
MATTER_DEBUG Enable debug instrumentation in NIF 0
ASAN Enable AddressSanitizer 0
CROSSCOMPILE Enable cross-compilation auto

Verified Hardware

Resources

License

See LICENSE file.