No description
  • Rust 92.2%
  • Nix 7.8%
Find a file
2026-06-19 23:54:40 +02:00
bin/ecd initial commit 2026-06-19 23:52:00 +02:00
crates add GUI directory listing: root redirects to single thing or shows device list 2026-06-19 23:52:43 +02:00
docs initial commit 2026-06-19 23:52:00 +02:00
examples initial commit 2026-06-19 23:52:00 +02:00
nix/modules initial commit 2026-06-19 23:52:00 +02:00
.gitignore initial commit 2026-06-19 23:52:00 +02:00
Cargo.lock initial commit 2026-06-19 23:52:00 +02:00
Cargo.toml initial commit 2026-06-19 23:52:00 +02:00
flake.lock initial commit 2026-06-19 23:52:00 +02:00
flake.nix initial commit 2026-06-19 23:52:00 +02:00
README.md add 💠 emoji to project header 2026-06-19 23:54:40 +02:00
rust-toolchain.toml initial commit 2026-06-19 23:52:00 +02:00

💠 edgecore

A lean, declarative agent that turns a physical device into a discoverable,
composable capability surface — speaking W3C Web of Things.

edgecore is a framework for special devices and a control daemon, ecd,
that exposes a device's capabilities and values. You describe a device once, in a
single declarative TOML manifest; ecd then:

  • generates a conformant WoT Thing Description (TD 1.1),
  • serves a WoT HTTP API plus a small built-in web GUI,
  • routes each interaction to its backing (a command, file, HTTP endpoint, …),
  • announces the device on the LAN over DNS-SD/mDNS (_wot._tcp).

Any WoT consumer can drive the device with zero edgecore-specific knowledge.

edgecore is a subproject of git.hydrar.de/jmarya/myverse.

Quick start

With Nix (flakes enabled):

nix develop          # dev shell with the pinned Rust toolchain
nix build .#ecd      # build the daemon
nix flake check      # build + clippy + rustfmt + tests

Run the daemon against a manifest:

ecd path/to/device.toml      # serve the device
ecd --check device.toml      # validate the manifest and exit
ecd --td    device.toml      # print the generated Thing Description

One process can host several Things (a WoT Servient) — pass multiple manifests
or a directory of them. They share one port; each keeps its own base path, and
GET /things lists every hosted Thing Description:

ecd things.d/                        # every *.toml in the directory
ecd lobby-01.toml door-02.toml       # or an explicit list

Then visit http://<host>:<port><base> for the GUI, or fetch the TD at
<base>/.well-known/wot.

A minimal manifest

[device]
id    = "urn:edgecore:kiosk:lobby-01"
title = "Lobby Kiosk"
class = "kiosk"

[property.brightness]
type    = "integer"
unit    = "percent"
minimum = 0
maximum = 100
source  = { exec = "backlight-get" }
sink    = { exec = "backlight-set {value}" }

[action.reload]
run = { exec = "kiosk-reload {hard}" }
  [action.reload.input.properties.hard]
  type = "boolean"

[expose]
bind = ["http"]
gui  = true
  [expose.http]
  port = 8080
  base = "/things/lobby-01"
  [expose.discovery]
  mdns = true

See the examples/ directory for full manifests:
lobby-01.toml (kiosk),
camera-01.toml (camera),
env-sensor-01.toml (sensor),
light-01.toml (smart light).
See docs/manifest.md for the complete schema.

HTTP surface

Route WoT operation
GET /.well-known/wot fetch the Thing Description
GET /properties/{name} read a property (SSE observe with Accept: text/event-stream)
PUT /properties/{name} write a property
POST /actions/{name} invoke an action (JSON body → backing)
GET /events/{name} subscribe to an event (SSE)
GET / the web GUI (when expose.gui = true)

All routes are mounted under the device's expose.http.base.

Documentation

Repository layout

crates/manifest    manifest types · parse · validate
crates/td          Thing Description model · generation
crates/backing     the Backing trait + exec/file/http/const/journal
crates/server      axum WoT HTTP surface + web GUI + auth
crates/discovery   mDNS / DNS-SD advertisement
bin/ecd            the daemon
nix/modules        NixOS modules: ecd, kiosk, camera
examples           example manifests

Status

v0 is HTTP-only, uses SSE for property observation and events, and a
single device-wide security scheme. Implemented backings: exec, file,
http, const, journal. See
docs/architecture.md for the current state of each crate.