Devices, units and capabilities
ALYT models the home around capabilities, logical devices, and ownership boundaries. A thing’s role is a set of capabilities, not a single fixed type. ALYT hardware and hub-acquired radio children are represented as devices, while connector-discovered LAN or cloud things are endpoints. As a developer, you work with capability-scoped settings, separate flows for adding ALYT hardware versus adding a child to a hub, and clients that render from reported capabilities rather than hardcoded device types.
Devices, units, and identities
Section titled “Devices, units, and identities”A device’s role is a set of capabilities, not a single kind. Today, the capability set is stored on Device.capabilities and can include values such as VOICE, HUB, and SENSOR.
That lets one physical product carry multiple roles at once. A voice device that is also a hub is represented by both capabilities rather than by choosing one exclusive type.
ALYT also separates the logical thing from the hardware currently serving it:
Deviceis the logical device in the roomDeviceUnitis the hardware unit currently serving that device
This matters for replacements. Room placement, settings, and history stay with the logical device instead of being tied to one piece of hardware.
Serial and protocol identity
Section titled “Serial and protocol identity”For ALYT hardware, identity is still the burned-in serial, but the serial belongs to DeviceUnit.serial, not to the logical device.
Two rules follow:
ALSAT1is a model code inside the serial- the serial grammar does not change
A child acquired over radio does not have an ALYT serial. Its identity comes from the protocol and the owning hub:
Device.protocolDevice.protocolId- the parent hub through
Device.parentDeviceId
The schema names MATTER, ZIGBEE, and THREAD as protocol values.
Capabilities drive settings and UI
Section titled “Capabilities drive settings and UI”Settings are grouped by capability in DeviceSettings.byCapability.
For example:
- voice settings such as announce volume, playback mode, and personas live under
voice - hub settings such as permit join, radio behavior, and hub preferences live under
hub
When you patch settings, each capability key in the patch must already be reported by that device. A patch that names a capability the device does not report returns 400. This is not a silent no-op.
Current shared settings shapes include these keys:
| Capability settings key | Purpose |
|---|---|
voice | voice preferences such as announce volume, playback mode, and persona mapping |
audio | audio output settings |
hub | hub preferences such as permit join, LED night mode, and wake chime |
sensor | sensor reporting settings |
The same capability-first rule applies in clients. A device page renders sections from the capabilities the thing reports. Adding a new capability adds a new section, not a new hardcoded device page type.
Hub-owned child devices
Section titled “Hub-owned child devices”A hub owns child devices acquired over radio. In the schema, that ownership is represented by Device.parentDeviceId.
Important consequences:
- Zigbee and Matter children are
Devicerows, not a separate table - they use the same room model and tenancy as other devices
- deleting the parent cascades to its children
- child identity is unique by parent and protocol id through
@@unique([parentDeviceId, protocolId])
This keeps room moves, household membership, and tenant scoping consistent across ALYT hardware and hub-acquired radio devices.
Endpoints are not devices
Section titled “Endpoints are not devices”Connector-discovered LAN and cloud things are endpoints, not devices.
Use endpoints for things such as WiZ, Tuya, Cync, ecobee, Sonos-style discovered targets, and cloud-connected third-party devices. Use devices for ALYT hardware and for children a hub acquires directly over radio.
This preserves one meaning for Device.parentDeviceId: a child acquired by a hub over radio.
For endpoints:
- capabilities are carried in
Endpoint.capabilitySet - household presentation can be overridden with
Endpoint.presentedAs PATCH /endpoints/:idupdates that presentation
Provisioning versus acquisition
Section titled “Provisioning versus acquisition”These are different flows and should be presented separately.
Add an ALYT device
Section titled “Add an ALYT device”A hub is provisioned the same way as a satellite:
- start with the burned-in serial
- a user mints a pairing token
- credentials are handed over over BLE or Improv
- the device calls
POST /devices/register
Add something to this hub
Section titled “Add something to this hub”A child device is added after the hub is already trusted.
- For Zigbee, the user opens permit-join on the hub.
- For Matter, the user starts commissioning with the device setup code and the selected Wi-Fi or Thread network.
- The Matter setup follows the hub-owned acquisition job and its readiness checks.
One is “add an ALYT device”. The other is “add something to this hub”. Those flows should not be conflated in the UI.
Presenting capabilities in clients
Section titled “Presenting capabilities in clients”Current clients use the reported capability set to decide both overview controls and detail screens.
Examples from current behavior:
- thermostats use the
thermostatcapability’s own target, mode, and reported bounds - lights only show color, warmth, brightness, or power when those controls are actually reported
- sensors render only the readings they report
- a room sensor that reports both
sensor.temperatureandsensor.motionpresents temperature as the primary reading, with motion shown as a secondary figure
A capability the thing does not report is not treated as available.
Command state is also surfaced in clients. When a command is not yet confirmed, users can see statuses such as pending, waiting, rejected, or not confirmed, instead of the UI pretending the final state is already known.
Light and switch presentation
Section titled “Light and switch presentation”A switch can be presented as a light or as a switch depending on household choice.
The override is stored in Endpoint.presentedAs:
lightswitchnullfor “as described”
When that changes, ALYT remaps both presentation and state. This affects:
- category
- icon
- which “all lights” actions reach it
- which state key clients read for power
Routine steps still survive that change for shared power control. A step written earlier against light or switch power still runs against the underlying thing.
Remote button bindings
Section titled “Remote button bindings”Remote button behavior belongs to the remote’s own record. It is not a routine.
Current behavior:
- read the configuration with
GET /endpoints/:id/buttons - save it with one whole-record
PUT - a cell can hold an ordered sequence of steps
- a wait step can be from 1 second to 3600 seconds
The configuration can include:
- stale cells the remote can no longer send
- configured cells the hub cannot currently be left to run, with a reason
If a save keeps any stale cell, the server refuses the write. Clients should show those stale cells and let the household remove them.
On phone and web, this is described as the remote’s own record: what each press runs. On TV, the remote is read-only and shows its reported facts, while setup stays in the phone app.
Access and runtime boundaries
Section titled “Access and runtime boundaries”A few limits matter when you build against the platform:
- household permissions are narrower than staff
- DEV credentials act in the developer sandbox
- LIVE credentials only for their own installed connector
Runtime behavior also depends on where the path runs:
- Local functions can keep working during a cloud outage.
- cloud-dependent connectors require the provider and network.
Never claim a cloud connector works when its cloud path is unavailable.