All chapters
Devices and outputs
Huntress does not only listen. An output is a sensor it can also command: switch a light, release a door strike, sound a siren, open a gate, set a thermostat. Operators use buttons; rules use the Operate device action. Both go through one pipeline that checks, records, delivers and confirms every command.
Output types#
There are 13 kinds of output. Which commands each understands is fixed by its type; an individual output can narrow them.
| Output | Commands | Owner / Admin only |
|---|---|---|
| Switch / Relay | Turn on, Turn off, Toggle | No |
| Door Strike / Momentary | Pulse | Yes, by default |
| Dimmer | Turn on, Turn off, Toggle, Set level | No |
| Light (colour) | Turn on, Turn off, Toggle, Set level, Set colour temperature, Set colour | No |
| Door Lock | Lock, Unlock | Yes, by default |
| Blind / Shutter | Open, Close, Stop, Set position | No |
| Garage Door / Gate | Open, Close, Stop | Yes, by default |
| Shut-off Valve | Open, Close | Yes, by default |
| Thermostat | Set setpoint, Set mode | No |
| Fan / Ventilation | Set speed | No |
| Siren / Strobe | Sound siren, Stop, Squawk | Yes, by default |
| Number Output | Set value | No |
| Select Output | Select | No |
Locks, door strikes (momentary relays), garage doors, valves and sirens are sensitive: only an Owner or Admin may operate them by hand (rules may). You can change which outputs are sensitive per output.
The command pipeline#
A command is never sent straight to a device. Every command, from a button, a rule or a revert, goes through the same steps:
- Validated. The command and its arguments must be valid for the output's type and settings.
- Permitted. Ordinary outputs may be operated by any member; sensitive ones by Owners and Admins; rules are trusted. Per-user and per-rule rate limits and a guard against a rule commanding the same output in a loop apply.
- Recorded. A command row is stored with who or what issued it, the command, its arguments and its result, and a Command issued event is added to the timeline. This is the audit of device control.
- Delivered in order for each output through the output's protocol, and never after its 30-second time-to-live.
- Followed until the device reports back.
| State | Meaning |
|---|---|
| Pending, Sent | Queued and handed to the transport. |
| Acknowledged | The device accepted it (an MQTT ack, an HTTP 2xx). |
| Confirmed | The device then reported the state the command should produce. |
| Unconfirmed | Accepted, but the expected state never came back. |
| Failed, Expired, Rejected | Delivery failed, the time-to-live passed, or the command was refused (permissions, rate limit, validation). |
A button that sent a command watches it and raises an error toast if it ends Failed, Expired or Rejected, because transports report asynchronously. Revert: a rule's command can last “for N minutes”, after which the previous state is restored; reverts survive a restart and a newer command cancels pending ones.
Transports#
MQTT#
An MQTT output speaks to a device that connects to Huntress's built-in broker (port 1883), with the output's token as the MQTT user name. The device subscribes to its own command topic and publishes state and acknowledgements:
| Topic | Direction | Purpose |
|---|---|---|
hunt/out/{sensorId}/set | Huntress → device | Commands. QoS 1, never retained, with an expiry. |
hunt/out/{sensorId}/state | Device → Huntress | Reported state (a plain value, or structured JSON). |
hunt/out/{sensorId}/ack | Device → Huntress | {"id":…,"status":"ok|error","message":…} |
{sensorId}is the output's numeric id, not its token. An output can use its own topics instead, but they may not start withhunt/.- A connection may subscribe only to the command topics of its own sensor and of the other sensors of the same device. Wildcards are refused, and a client's publishes are never forwarded to other clients.
- Two payload formats exist: Huntress JSON (
{id, command, args, expiresAt}, with an acknowledgement) and Plain for firmware that expects bare values such as Tasmota, ESPHome or Shelly (ON,OFF,TOGGLE,LOCK,UNLOCK,OPEN,CLOSE,STOP,SQUAWK, or a number).
Zigbee#
Huntress talks to Zigbee devices directly through a coordinator dongle on a USB or serial port of the server, or of an edge. It supports Silicon Labs EFR32 coordinators running EZSP version 13 firmware, for example the Sonoff ZBDongle-E. There is no Zigbee2MQTT, ZHA, ConBee or Texas Instruments support.
- Add the coordinator on the Devices page, open the join window (up to 254 seconds) and pair devices. A joined device is Discovered and is not ingested until you add it to a place.
- Huntress reads each device's clusters and proposes sensor types: IAS zones become motion, door contact, smoke, water leak, carbon monoxide, vibration, glass break or panic button sensors (with alarm, tamper and low-battery status); temperature, humidity, pressure, illuminance, occupancy and power readings; and on/off, light, lock, cover, thermostat, fan and siren outputs. Buttons that send remote, level or scene commands become Scene button sensors.
- Battery and link quality are kept on the device. An unplugged dongle makes
/healthDegraded, never Unhealthy. - The network key is stored unencrypted in
<DataDir>/zigbee/, protected by file permissions (readable only by the service account). A dongle on an edge keeps working while the server is unreachable, but events during the outage are not replayed. - Not included: Zigbee groups, scenes and over-the-air updates.
HTTP#
An HTTP output is any device that takes a web request: Shelly relays, Tasmota and ESPHome switches, a smart plug, your own controller. Per command you set a URL, a method (GET, POST or PUT), a body and headers. These placeholders are filled in and escaped for where they land (URL, JSON, form or header): {{command}}, {{on}}, {{level}} and the like; an unknown placeholder is refused when you save.
- Presets fill the form for Shelly (Gen 1) relay, Shelly (Gen 2 / Plus / Pro) switch, Tasmota switch, ESPHome switch (web server) and a generic JSON endpoint.
- A 2xx answer means acknowledged. Anything else fails the command, and the log names the host only, since a path or query may hold a key.
- State. Without a status address the accepted command is taken as the new state and is flagged assumed until a real report replaces it. With a status address (read every 5 to 3,600 seconds, 30 by default, and right after each command) Huntress reads the real state, which confirms the command and also shows a change someone made by hand.
- Header values are secrets. They are shown only on the output's settings page and never logged.
- Network policy. Calls go through the outbound policy: public addresses by default, with no redirects and at most 16 KB of answer. To reach devices on a local network from the server, list them in
Outputs:AllowedHosts(or setOutputs:AllowPrivateAddresseson a server shared by organisations that trust each other).
HTTP relay#
A server in a data centre cannot reach a relay on your LAN. An HTTP relay is a Huntress Edge on that network that makes the calls for the server. Create the relay on the Devices page (HTTP relays), copy its token and secret into the edge's HuntressEdge:HttpRelays, and choose it in the output's HTTP settings. The edge allows local addresses but never loopback, link-local (including cloud metadata), multicast or reserved ones, checks every resolved address, and refuses a request past its expiry (its clock must be right).
AllowedHosts empty, any administrator of the relay's organisation can make the edge call any local address. Set AllowedHosts on the relay edge to the devices it should reach.Operating from the interface#
A place's Outputs tab lists its outputs as cards with a quick toggle and the output's recent commands; with zones the tab groups them by zone. A zone's heading and page carry All on / All off: only outputs that understand the command are sent it, sensitive ones only when an Owner or Admin is signed in and after a confirmation, and each one is a separate audited command. A command's failures are summarised.
Not included#
- No control from Pulse or the provisioning API.
- No TLS on the MQTT listener (see Security).
- Rules cannot arm or disarm an alarm panel directly; see Alarm panels.