Skip to content

Device state

GET /api/v1/device tells you how AWTRIX is doing right now: firmware version, network, memory, display, sensors, battery and the indicators. The web UI dashboard reads it, and you can read it from your own automations.

All values are live. They are not stored and they reset when AWTRIX restarts.

Endpoint

Method GET only
Path /api/v1/device
Request body none
Response 200 application/json – a single object
Auth HTTP Basic, whenever authEnabled is set – in setup mode too. See Authentication
curl http://<awtrix-ip>/api/v1/device

With a password set:

curl -u admin:secret http://<awtrix-ip>/api/v1/device

Any method other than GET gets 405 methodNotAllowed:

curl -i -X POST http://<awtrix-ip>/api/v1/device
# HTTP/1.1 405 Method Not Allowed
# {"error":{"code":"methodNotAllowed","message":"allowed: GET"}}

Response shape

An example. The tables below explain every key.

{
  "version": "1.0.12",
  "uid": "a4cf12ab34cd",
  "boardType": "awtrixng",
  "soc": "esp32s3",
  "updateImage": "firmware-awtrix-ng-s3-octal.bin",
  "ipAddress": "192.168.1.42",
  "hostname": "awtrixng-ab34cd",
  "wifiRssi": -58,
  "uptimeSeconds": 4213,
  "freeHeapBytes": 118234,
  "minFreeHeapBytes": 91560,
  "largestFreeBlockBytes": 63488,
  "psramTotalBytes": 8388608,
  "psramFreeBytes": 8012345,
  "scriptingRunning": true,
  "scriptHeapPool": "psram",
  "scriptHeapBudgetBytes": 4006172,
  "resetReason": "software",
  "fps": 41,
  "brightness": 120,
  "lightLevel": 29.3,
  "ldrRaw": 1200,
  "batteryPercent": 88,
  "batteryVoltage": 4.1,
  "batteryPinMillivolts": 2290,
  "lowBattery": false,
  "temperature": 21.5,
  "humidity": 42,
  "pressureHpa": 1013.2,
  "matrixPower": true,
  "currentApp": "Time",
  "indicators": [
    {"on": false, "color": "#000000", "blinkMs": 0, "fadeMs": 0},
    {"on": false, "color": "#000000", "blinkMs": 0, "fadeMs": 0},
    {"on": false, "color": "#000000", "blinkMs": 0, "fadeMs": 0}
  ],
  "messageCount": 0,
  "wifi": {
    "enabled": true,
    "state": "connected",
    "host": "MyNetwork",
    "endpoint": "192.168.1.31",
    "attempts": 0,
    "retryInMs": 0,
    "connects": 1,
    "error": null,
    "lastError": null
  },
  "mqtt": {
    "enabled": true,
    "state": "connected",
    "host": "broker.local",
    "endpoint": "192.168.1.42:1883",
    "attempts": 0,
    "retryInMs": 0,
    "connects": 1,
    "error": null,
    "lastError": null
  },
  "mirror": {
    "sharing": false,
    "viewers": 0,
    "source": "kitchen.local",
    "state": "showing",
    "sourceWidth": 32,
    "sourceHeight": 8
  }
}

Check that a key exists before you read it

These keys are left out completely – not null, not 0 – when the hardware is missing: psramTotalBytes, psramFreeBytes, lightLevel, ldrRaw, batteryPercent, batteryVoltage, batteryPinMillivolts, lowBattery, temperature, humidity and pressureHpa.

Always-present fields

These keys are in every response.

Key Type Range / format Units Meaning
version string - - Firmware version. Same value as GET /api/v1/version.
uid string 12 lowercase hex chars - Device ID: the Wi-Fi MAC address in lowercase without colons. It never changes, not even after a new firmware install. Also the default MQTT topic prefix and MQTT client ID.
boardType string awtrixng - Which firmware this is. awtrixng on every board, whatever your pin map.
soc string esp32s3 - The chip the firmware is made for. Use it only to tell the firmware types apart; for pin rules read gpio in GET /api/v1/capabilities.
updateImage string firmware-awtrix-ng-s3-octal.bin, firmware-awtrix-ng-s3-quad.bin - The update file this device needs – the one POST /update accepts. It depends on the kind of PSRAM on your board. The web UI uses it to offer the right download.
ipAddress string dotted quad - The IP address in your home network. In setup mode this is not the address you used to reach AWTRIX.
macAddress string A4:CF:12:0B:3C:7D - The Wi-Fi MAC address the clock joins your network with, in upper case with colons. Networks that only admit known devices need it. The web UI shows it on the dashboard and in setup mode.
hostname string 1 … 32 chars - The name AWTRIX uses on the network and announces over mDNS (lets you open http://<hostname>.local). If you never set a name, it is awtrixng- plus the last six characters of uid. In that case hostname in GET /api/v1/system is empty, because it holds only a name you set yourself.
wifiRssi integer about −30 (excellent) to −90 (unusable) dBm Wi-Fi signal strength.
uptimeSeconds integer 0 … seconds Seconds since the last start. Starts at 0 after every restart, including after an update or a settings reset.
resetReason string poweron, external, software, panic, interruptWatchdog, taskWatchdog, watchdog, deepSleep, brownout, sdio, unknown - Why AWTRIX last started. poweron: switched on. software: AWTRIX restarted itself (update, restart from the web UI). panic or one of the watchdog values: AWTRIX crashed or hung and was restarted. brownout: the power supply voltage dropped too low. deepSleep: woke from sleep.
freeHeapBytes integer 0 … bytes Free memory right now. It changes all the time.
minFreeHeapBytes integer 0 … bytes The lowest free memory seen since the last start. It only goes down. A value that keeps dropping towards zero over days points to a problem; a stable value is fine.
largestFreeBlockBytes integer 0 … bytes The largest piece of free memory in one block. Installing a script or playing an HTTPS stream needs one large block. If AWTRIX says "not enough memory" although freeHeapBytes looks high, this value is the one that is too small.
scriptingRunning boolean - - Whether scripts run. false when scriptingEnabled is off – installed scripts stay listed and editable, but none of them runs.
scriptHeapPool string internal, psram - Which memory scripts use: internal (main memory) or psram (extra memory on boards that have it – installing a script then hardly changes freeHeapBytes).
scriptHeapBudgetBytes integer 0 … bytes How much memory all scripts together may use. When it is full, installing another script is refused. 98304 with internal; with psram about half the free PSRAM, so about 4 MB on an 8 MB board. Read the value instead of assuming it.
fps integer 0 … frames/second Frames actually shown per second, measured once per second. It moves around.
brightness integer 0 … 255 - The brightness the display uses right now. With autoBrightness off, or without a light sensor, it equals settings.brightness. With autoBrightness on and a light sensor, AWTRIX calculates it from lightLevel within minBrightness…maxBrightness, and settings.brightness is ignored. While the mood light is on, it is the mood light's brightness. Also shown as brightness in GET /api/v1/display. The value you set is in GET /api/v1/settings.
matrixPower boolean - - true when the display is on. Same as power in GET /api/v1/display. Change it with PATCH /api/v1/display.
currentApp string app name, or "" - The app currently selected in the rotation, for example "Time", "Date" or the name of one of your apps. Empty when no app is in the rotation. A notification shown does not change it. During a transition it still names the app that is leaving.
indicators array exactly 3 objects - The three indicators, in order 1, 2, 3. See Indicators.
messageCount integer 0 … count MQTT command messages received since the last start – everything that arrives under your AWTRIX's topic prefix, including a script's own subscription below that prefix. Messages AWTRIX sends (such as /result) and HTTP requests are not counted.
wifi object - - Whether AWTRIX is on your network, and if not, why. See Connection status.
mqtt object - - Whether AWTRIX is connected to your MQTT broker, and if not, why. See Connection status.

PSRAM fields (conditional)

Only on boards with PSRAM (extra memory). Both keys appear together or not at all.

Key Type Range Units Meaning
psramTotalBytes integer 0 … bytes Total PSRAM on the board.
psramFreeBytes integer 0 … bytes Free PSRAM. Do not add it to freeHeapBytes: PSRAM cannot replace main memory, and main memory runs out first.

Light sensor fields (conditional)

Only when the board has a light sensor pin – pinLdr in the system configuration is 0 or higher. The default is GPIO 2, so a stock clock has both keys. With pinLdr: -1 both keys disappear.

Key Type Range Units Meaning
lightLevel number 0.0 … 100.0, one decimal percent (relative) Ambient light as a relative percentage, not lux.
ldrRaw integer 0 … 4095 - The raw sensor reading: 0 in the dark, 4095 in bright light. Use this value to calibrate ldrFactor.

lightLevel follows ldrRaw in a straight line. ldrFactor sets what counts as full light, and ldrOnGround handles a sensor wired the other way round. ldrGamma changes only how lightLevel turns into brightness, never lightLevel itself. lightLevel is reported whether autoBrightness is on or off.

Battery fields (conditional)

Only when the board has a battery pin – pinBattery in the system configuration is 0 or higher. The default is GPIO 1, so a stock clock has all four keys. With pinBattery: -1 all four disappear.

Key Type Range Units Meaning
batteryPinMillivolts integer 0 … 65535 mV Voltage at the pin, after the resistor divider – not the battery voltage. Median of the last 5 readings. Use it to calibrate batteryDividerRatio.
batteryVoltage number 0.0 … , two decimals V The battery voltage: batteryPinMillivolts / 1000 × batteryDividerRatio. A ratio of 0 or less uses the default 1.79. Useful to watch a battery age, independent of the percentage.
batteryPercent integer 0 … 100 percent Charge level, estimated from batteryVoltage with a typical Li-Ion curve. 100 % at 4.20 V or more, 0 % at 3.27 V or less.
lowBattery boolean - - true when batteryPercent is below lowBatteryThreshold in the system configuration. Always false while lowBatteryThreshold is 0 (the default). Also shown as a Home Assistant "Low battery" binary sensor.

Calibrate the divider, not the percentage. If batteryVoltage looks wrong, read batteryPinMillivolts with a fully charged battery and set batteryDividerRatio = 4.2 / (batteryPinMillivolts / 1000). See Power & battery.

batteryPercent is only an estimate from the voltage. It cannot tell you the remaining runtime, and it drops a little under load.

Environment fields (conditional)

Only when a temperature sensor was found at startup. AWTRIX looks for BME280, then BMP280, then HTU21DF, then SHT31. If none answers – or if pinI2cSda / pinI2cScl is -1 – all three keys are left out. A sensor you connect later is found only after a restart.

Only the values the sensor can measure appear:

Sensor temperature humidity pressureHpa
BME280 ✓ ✓ ✓
BMP280 ✓ - ✓
HTU21DF ✓ ✓ -
SHT31 ✓ ✓ -
Key Type Range Units Meaning
temperature number sensor-dependent, one decimal °C Temperature plus tempOffset. Always Celsius, whatever useCelsius says – that setting changes only the display.
humidity number sensor-dependent, one decimal percent RH Relative humidity plus humOffset. Left out on temperature-only sensors.
pressureHpa number sensor-dependent, one decimal hPa Air pressure. Only with a BME280 or BMP280.

Indicators

indicators always holds 3 objects: index 0 is indicator 1, index 2 is indicator 3. It shows what was last set with PUT /api/v1/indicators/{id} (or over MQTT / Home Assistant), which is also what you see on the display: dots on the right edge, indicator 1 at the top, indicator 3 at the bottom.

Key Type Range Units Meaning
on boolean - - Whether the indicator is on.
color string "#RRGGBB" - Color, uppercase hex. Default #000000.
blinkMs integer 0 … 65535 milliseconds Blink interval. 0 = no blinking.
fadeMs integer 0 … 65535 milliseconds Fade interval. 0 = no fading.

Connection dots

The right edge of the display is for your indicators. The left edge is for AWTRIX: it shows a single pulsing dot there while a connection is missing.

Where Color Meaning
Top-left corner red AWTRIX is not on your Wi-Fi network.
Bottom-left corner yellow AWTRIX is on the network but not connected to your MQTT broker.

The dots appear by themselves, cannot be switched off, and go away as soon as the connection is back.

Only one dot shows at a time. Without Wi-Fi there is no MQTT either, so a network outage shows only the red dot. If no broker is set up, the yellow dot never shows.

You do not see the dots while the display is off, on the setup screen, in mood light, or while an Art-Net stream is running. To find out why a connection is down, read wifi and mqtt below.

Connection status

wifi and mqtt tell you whether AWTRIX reached your network and your broker, and if not, why. Both objects have the same keys. mqtt also feeds the Connection line on the web UI's MQTT tab. For the dots on the display see Connection dots.

"mqtt": {
  "enabled": true,
  "state": "offline",
  "host": "broker.local",
  "endpoint": "",
  "attempts": 4,
  "retryInMs": 40000,
  "connects": 0,
  "error": "hostNotFound",
  "lastError": "hostNotFound"
}
Key Type Meaning for wifi Meaning for mqtt
enabled boolean A network name is stored. Same as mqttEnabled.
state string disabled, offline, connecting or connected. Same four values.
host string The network name (SSID). The broker host as you entered it.
endpoint string AWTRIX's IP address on that network. Empty while not connected. The broker address and port in use, once the name is resolved. Empty before that – an empty endpoint with a broker name means the name was not found yet.
attempts integer Failed attempts in a row. 0 while connected. Same.
retryInMs integer Milliseconds until the next attempt. 0 while connected and during an attempt. Same.
connects integer Successful connections since the last start. A number that keeps rising means the connection keeps dropping – for wifi, usually the router or the range. Same.
error string / null Why it is not connected right now. null when connected. Same.
lastError string / null Why the connection last went down. Kept after it comes back. null until something goes wrong. Same.

Why wifi has a lastError

While Wi-Fi is down, you cannot reach this API – only the red dot tells you. lastError stays after the connection is back. So "lastError": "lost" together with "state": "connected" means the connection dropped and came back. connects tells you how often.

You can read wifi.error live in one case: when AWTRIX could not join your network at startup. It then opens its own setup hotspot, and the API is reachable there.

What each error means

error What it means What to do
noWifi (mqtt only) AWTRIX is not on the network. Fix Wi-Fi first; MQTT needs it. You see this only if you reach AWTRIX some other way.
hostNotFound For wifi: your network was not found. For mqtt: the broker name could not be resolved. For Wi-Fi, check the network name and that the router is on. For MQTT, check the spelling. A .local name only works if something on your network answers for it – if in doubt, enter the broker's IP address.
refused (mqtt only) Nothing accepted a connection at that address and port. Check the port, and that the broker runs and is reachable from AWTRIX's network.
badCredentials The password was rejected – by the router for wifi, by the broker for mqtt. Enter the Wi-Fi password again, or mqttUser and mqttPass.
rejected (mqtt only) The broker refused AWTRIX for another reason. Check the broker's log.
timeout For wifi: the network did not answer in time while AWTRIX was starting. For mqtt: something answered at that address but it did not speak MQTT. For Wi-Fi, usually range or a router that was still starting; AWTRIX keeps trying. For MQTT, usually the wrong port.
lost The connection was up and dropped. For Wi-Fi, usually range or a router restart. For MQTT, the same or a broker restart. AWTRIX reconnects by itself.

Retries back off

After a failed attempt AWTRIX waits 5 seconds, then 10, 20, 40, and then 60 seconds between attempts. Each wait is up to 20 % shorter at random, so many clocks do not all retry at the same moment. After a successful connection the waits start again at 5 seconds. retryInMs counts down to the next attempt.

AWTRIX looks up the broker's address once and keeps it while it works. It looks it up again after three failed attempts in a row, and after it rejoins Wi-Fi.

Mirroring status

mirror tells you what mirroring is doing. It feeds the State line in the web UI's Mirroring section.

Key Type Meaning
sharing boolean This clock shares its display and is on the network.
viewers integer How many clocks watch this display right now.
source string The clock this clock mirrors, as entered in mirrorFrom. Empty when it mirrors none.
state string What mirroring the source clock does right now; see below.
sourceWidth, sourceHeight integer The display size the source clock reported. Left out until it has answered.
state What it means
off mirrorFrom is empty.
offline This clock is not on the network.
resolving The host name is being looked up.
notFound The host name could not be found. It is looked up again every 10 seconds.
waiting No answer from that clock for more than 3 seconds, or none yet.
idle That clock answers but shows nothing it shares.
filtered That clock shows something mirrorFromApps or mirrorFromNotifications leaves out.
sizeMismatch The two displays differ in size.
noMemory There was no memory for the mirrored picture.
showing The mirrored picture is on the display.

Also published over MQTT

The same JSON is published, retained, to <prefix>/state/device. A subscriber gets the latest state as soon as it connects, so you do not need to poll over HTTP. See MQTT topics for how often it is sent and for the other state topics.

How often the values update

The values are updated on their own schedule, not when you ask. Asking more often than this returns the same values.

Field(s) Updated
ldrRaw, lightLevel every 100 ms, median of 5 readings
brightness every frame
batteryPinMillivolts, batteryVoltage, batteryPercent, lowBattery every 2 s, median of 5 readings
temperature, humidity, pressureHpa every 2 s
fps once per second
uptimeSeconds, freeHeapBytes, minFreeHeapBytes, largestFreeBlockBytes, ipAddress, wifiRssi when you ask
resetReason, hostname at startup

Platform capabilities

Tools that support several device types can read GET /api/v1/capabilities to find out what the device offers. Part of the answer describes the platform:

{
  "platform": { "id": "esp32s3" },
  "sensors": { "light": true },
  "display": { "width": 32, "height": 8, "configurable": true }
}
Key Meaning
platform.id esp32s3.
sensors.light true when there is a light sensor, that is when pinLdr is set (a pin change shows after a restart). Without a light sensor autoBrightness has no effect and the web UI hides the auto-brightness controls.
display.width / display.height Display size in pixels. The top-left pixel is (0, 0), so (31, 7) is the bottom-right pixel of a 32×8 display. Scripts, draw commands and /api/v1/display/screen use the same coordinates.
display.configurable true: the display size and wiring can be changed.
gpio The pin rules of the chip – see GPIO & boards.
  • HTTP API – conventions, auth, and the full route list
  • System configuration – pinBattery, pinLdr, batteryDividerRatio, lowBatteryThreshold, ldrFactor, ldrGamma, minBrightness, maxBrightness, tempOffset, humOffset
  • Settings – brightness, autoBrightness and the rest of the user settings
  • Brightness & sensors – calibrating the light sensor
  • Power & battery – calibrating the divider ratio
  • Errors – what a failing request answers