Keypad — keypad v1
A keypad, a remote or a dial — one device, however many keys are on it. A Pico, a Hue Dimmer and a wall module behind a rocker are all this. Not a load: a keypad drives nothing by itself, it only says a key was touched, and what happens next is a rule.
One binding for the whole device, not one per key. A Pico on the wall is one object somebody picks up, and splitting it into four would make it four tiles, four things that go offline separately, and four rows in a list where a person is looking for the remote they are holding.
Which key, and what was done to it, are parameters. That is only usable because a trigger can
match on them: pressed { key = 2, action = "held" } binds to one key of one keypad, and a click
and a hold are different rules rather than two values nothing can tell apart. Before triggers
could do that, this contract had to be one binding per key — the shape is a consequence of what
rules can express, and it changed when they got better.
Keys are numbered from 1, in the order the device itself reports them. A keypad that names them —
"On", "Favourite", a scene — carries those in key_labels, so a rule editor can offer "Off"
rather than "key 4".
Nothing here is gated on the device being able to do anything, because it cannot. A keypad resolves to no commands at all, and the tile drawn for one records what it last did rather than offering a control. What varies between them is which actions the hardware can distinguish, so that is what the capabilities describe.
Capabilities
Declared in the driver manifest under [[proxy]] capabilities. Anything not declared takes the default below.
| Capability | Type | Default | Meaning |
|---|---|---|---|
has_battery | bool | false | |
has_double | bool | false | Distinguishes a double press |
has_hold | bool | false | Tells a long press apart from a short one — see the held and released actions |
has_repeat | bool | false | Keeps reporting while the button is held down, rather than once |
has_triple | bool | false | Distinguishes a triple press |
is_rotary | bool | false | A dial rather than a button — reports rotation instead of, or as well as, presses |
key_count | u32 | 1 | How many keys. A rule editor offers this many; a keypad reporting a key beyond it is a driver bug worth seeing rather than hiding. |
key_labels | string | "" | What is printed on them, in order, comma separated — "On,Up,Down,Off". Empty where they are unmarked, and a rule editor falls back to numbers. |
Notifications
battery_changed
Only present when
has_batteryis declared true.
| Parameter | Type | Notes |
|---|---|---|
percent | u8 0–100 |
clicked
Pressed and let go, with no long press in between. The everyday one, and the only action every button has — a device that can tell nothing else apart still reports this.
| Parameter | Type | Notes |
|---|---|---|
key | u32 ≥1 | Which key, numbered from 1 as the device reports them. |
double_clicked
Only present when
has_doubleis declared true.
| Parameter | Type | Notes |
|---|---|---|
key | u32 ≥1 | Which key, numbered from 1 as the device reports them. |
held
Only present when
has_holdis declared true.
Crossed from a press into a long press. Sent once, when the threshold is passed — not repeatedly.
Pair it with released to bracket the hold, which is what a ramp needs: start on this, stop on that.
| Parameter | Type | Notes |
|---|---|---|
key | u32 ≥1 | Which key, numbered from 1 as the device reports them. |
online_changed
| Parameter | Type | Notes |
|---|---|---|
online | bool |
released
Only present when
has_holdis declared true.
A long press ended. Only meaningful where held was sent; a plain click reports clicked and nothing else.
| Parameter | Type | Notes |
|---|---|---|
key | u32 ≥1 | Which key, numbered from 1 as the device reports them. |
repeating
Only present when
has_repeatis declared true.
Sent over and over while the button stays down, at whatever rate the hardware chooses.
Distinct from held, and both exist because they answer different questions. A ramp wants held
once and then released, and would be fought by a stream of these. A step-per-tick — brightness up
one notch each time — wants exactly these and would never move on held alone.
| Parameter | Type | Notes |
|---|---|---|
key | u32 ≥1 | Which key, numbered from 1 as the device reports them. |
rotated_clockwise
Only present when
is_rotaryis declared true.
A dial moved. steps is how far since the last report, in whatever detent the hardware counts in —
relative, never an absolute position, because a dial has no end stops and no zero.
Clockwise and anticlockwise are separate notifications rather than a direction parameter, for the
reason given at the top: a rule triggers on a notification name, and "turn it right to brighten"
has to be able to bind to one way round.
| Parameter | Type | Notes |
|---|---|---|
key | u32 ≥1 | Which key, numbered from 1 as the device reports them. |
steps | u32 |
rotated_counter_clockwise
Only present when
is_rotaryis declared true.
| Parameter | Type | Notes |
|---|---|---|
key | u32 ≥1 | Which key, numbered from 1 as the device reports them. |
steps | u32 |
triple_clicked
Only present when
has_tripleis declared true.
| Parameter | Type | Notes |
|---|---|---|
key | u32 ≥1 | Which key, numbered from 1 as the device reports them. |
State
Last-known values core keeps for a binding of this proxy.
| Key | Type | Meaning |
|---|---|---|
battery | u8 | |
last_action | string | What the keypad last did, key included — "Up held". A tile saying only "held" on a four-key remote is a tile nobody can read. |
online | bool |