Google Protocol Buffer message reference for the eDIDIO S10 controllers and the ADDICT V3 — Getting started (README) · Changelog · Repository
3030323 or TLS 4430xCD + 2-byte big-endian length + protobuf-encoded EdidioMessageAytMessage if nothing else - within 20 s to keep the connection0x010302; devices report theirs in diag_system.proto_versionNew here? Start with Requests and replies.
EdidioMessage with exactly one payload field set. On TCP (port 23) or TLS (443) it is framed as 0xCD, the protobuf length as two bytes (big-endian), then the protobuf bytes.message_id is yours: the device copies it into its reply, so you can match replies to requests and have several in flight.AckMessage: SUCCESS, or why not - INVALID_PARAMS (a value was refused), INDEX_OUT_OF_BOUNDS, UNEXPECTED_CASE / UNEXPECTED_TYPE (not supported by this device or firmware), UNAUTHORISED / FORBIDDEN (see roles). detail can carry a RejectReason.admin_message GETs come back as an admin_message with the value filled in; read_device, spektra_read and diag_message come back as the payload for what was asked for. The tables below list every reply.ayt_message if nothing else - within 20 seconds, or the device closes the connection.admin_message GET NONCE, then secure_login) and each request needs a role: NONE < CONTROL < CONFIG < ADMIN. Too low gives FORBIDDEN, not logged in UNAUTHORISED. With it off nothing is checked. The ADDICT has no login.WIFI_DIAGNOSTICS and DALI bus power 3.9.3). A device answers a message or property it does not have with UNEXPECTED_TYPE or UNEXPECTED_CASE, so check diag_system.firmware first if a feature matters.Each request with its frame as sent on the socket (start byte and length included).
The three you will use most - a DALI command, DMX levels and an external trigger - can be built in SpektraPlus: Device Tools → Message Generator. Fill in the fields and it gives the bytes, start byte and length included, as decimal or hex, ready to paste into another system.
A command: the device answers with an AckMessage.
EdidioMessage {
message_id: 1
dali_message {
line_mask: 0b0001 // line 1
address: 5 // short address
custom_command: DALI_ARC_LEVEL
arg: 200 // arc level 0-254
}
}cd 00 0e 08 01 92 01 09 08 01 10 05 30 00 48 c8 01
EdidioMessage {
message_id: 1
ack { payload: SUCCESS }
}cd 00 06 08 01 12 02 08 05
A field holding its default (0, false, "", the first enum value) is normally not sent at all. custom_command is the exception here: it is one choice of the action oneof, and a oneof field is always sent once chosen - so DALI_ARC_LEVEL (0) appears as 30 00.
A dmx_message sets consecutive channels on one or more universes, with an optional fade. channel is the first channel (1-512); level holds one value per channel and is repeated repeat times - here one RGB fixture set to red over 250 ms.
EdidioMessage {
message_id: 2
dmx_message {
universe_mask: 0b0001 // universe 1
channel: 1 // first channel, 1-based
repeat: 1 // one fixture
level: [255, 0, 0] // R, G, B
fade_time_by_10ms: 25 // 250 ms
}
}cd 00 13 08 02 a2 01 0e 10 01 18 01 20 01 2a 04 ff 01 00 00 30 19
EdidioMessage {
message_id: 2
ack { payload: SUCCESS }
}cd 00 06 08 02 12 02 08 05
An external_trigger runs any action a button or schedule could: the TriggerMessage names the TriggerType, and target_index / value / line_mask mean what that type says. Here it starts list 0 (lists count from 0).
EdidioMessage {
message_id: 3
external_trigger {
trigger {
type: LIST_START
target_index: 0 // list 0
}
}
}cd 00 09 08 03 aa 01 04 0a 02 08 09
EdidioMessage {
message_id: 3
ack { payload: SUCCESS }
}cd 00 06 08 03 12 02 08 05
An AdminMessage GET comes back as an AdminMessage with the value filled in - here the device name, in data.string_data (the admin property table says which field each property uses).
EdidioMessage {
message_id: 4
admin_message {
command: GET
target: DEVICE_NAME
}
}cd 00 07 08 04 8a 02 02 08 01
EdidioMessage {
message_id: 4
admin_message {
command: GET
target: DEVICE_NAME
data { string_data: "Lobby" }
}
}cd 00 10 08 04 8a 02 0b 08 01 1a 07 1a 05 4c 6f 62 62 79
A SET carries the new value in the same field and is answered with an AckMessage; INVALID_PARAMS if the value is refused.
EdidioMessage {
message_id: 5
admin_message {
command: SET
target: DEVICE_NAME
data { string_data: "Foyer" }
}
}cd 00 0e 08 05 8a 02 09 1a 07 1a 05 46 6f 79 65 72
EdidioMessage {
message_id: 5
ack { payload: SUCCESS }
}cd 00 06 08 05 12 02 08 05
A diag_message of type DIAGNOSTIC_SYSTEM_INFO returns diag_system: firmware and hardware versions, how many lists, alarms, sensors and so on it has, and proto_version - the protocol version it was built against.
EdidioMessage {
message_id: 6
diag_message {
type: DIAGNOSTIC_SYSTEM_INFO
}
}cd 00 05 08 06 82 02 00
EdidioMessage {
message_id: 6
diag_system {
firmware: "..."
proto_version: 0x010302 // 1.3.2
...
}
}Gate a feature on the protocol version: if (proto_version >= 0x010302) (1.3.2). Decode it as major = v >> 16 & 0xFF, minor = v >> 8 & 0xFF, patch = v & 0xFF. 0 means the firmware predates the field.
A read_device request comes back as the payload for the ReadType asked for - here the physical inputs of profile 0, as inputs.
EdidioMessage {
message_id: 7
read_device {
type: INPUTS
profile: 0
}
}cd 00 05 08 07 8a 01 00
EdidioMessage {
message_id: 7
inputs { ... } // InputMultiMessage
}Field number, the payload field to set, its message type, and what the device sends back.
| # | Field | Type | What it does | Reply | Role | Devices |
|---|---|---|---|---|---|---|
| 2 | ack | AckMessage | The answer to a request that returns no data: success, or why it was refused (type and detail). | sent by the device | eDIDIO, ADDICT | |
| 3 | inputs | InputMultiMessage | Configure the physical inputs of one profile; also the reply to read_device INPUTS. | AckMessage | CONFIG | eDIDIO |
| 4 | outputs | OutputMultiMessage | Configure the outputs of one profile; also the reply to read_device OUTPUTS. | AckMessage | CONFIG | eDIDIO |
| 5 | irs | IRMultiMessage | Configure the IR codes of one profile (deprecated); also the reply to read_device IR. | AckMessage | CONFIG | eDIDIO |
| 6 | sensor | SensorMessage | Configure one DALI-2 sensor; also the reply to read_device SENSOR. | AckMessage | CONFIG | eDIDIO |
| 8 | list | ListMessage | Configure a list - up to 32 steps, the rest follow in list_extended; also the reply to read_device LIST. | AckMessage | CONFIG | eDIDIO |
| 10 | alarm | AlarmMessage | Configure one alarm (a scheduled action). | AckMessage | CONFIG | eDIDIO |
| 11 | alarms | AlarmMultiMessage | Configure every alarm at once; also the reply to read_device ALARMS. | AckMessage | CONFIG | eDIDIO |
| 12 | burn_ins | BurnInMultiMessage | Configure the burn-ins; also the reply to read_device BURN_IN. | AckMessage | CONFIG | eDIDIO |
| 13 | sensor_command | SensorCommandMessage | Mute, unmute or override a sensor. | AckMessage | CONTROL | eDIDIO |
| 14 | change_profile | ChangeProfileMessage | Change the active profile (this resets the sensors). | AckMessage | CONTROL | eDIDIO |
| 15 | identify_message | IdentifyMessage | Show information on the device's screen to help find it. | AckMessage | CONTROL | eDIDIO |
| 16 | update_time | UpdateTimeMessage | Set the device clock. | AckMessage | CONFIG | eDIDIO |
| 17 | read_device | ReadDeviceMessage | Read configuration back; the reply is the payload for the ReadType asked for. | see ReadType | CONTROL | eDIDIO |
| 18 | dali_message | DALIMessage | Send a DALI command or query on one or more lines. | AckMessage for a command, dali_query for a query | CONTROL | eDIDIO, ADDICT |
| 19 | dali_query | DALIQueryResponse | A DALI query's answer, tagged with the line and address. | sent by the device | eDIDIO, ADDICT | |
| 20 | dmx_message | DMXMessage | Set DMX levels on one or more universes, with an optional fade. | AckMessage | CONTROL | eDIDIO, ADDICT |
| 21 | external_trigger | ExternalTriggerMessage | Fire a trigger action from another system. | AckMessage | CONTROL | eDIDIO |
| 22 | spektra_settings | SpektraSettingMessage | Configure a Spektra zone; also the reply to spektra_read SETTINGS. | AckMessage | CONTROL | eDIDIO |
| 23 | spektra_sequence | SpektraSequenceConfigMessage | Store a Spektra sequence; also the reply to spektra_read SEQUENCE. | AckMessage | CONTROL | eDIDIO |
| 24 | spektra_calendar | SpektraCalendarMessage | Assign a sequence or theme to calendar days. | AckMessage | CONFIG | eDIDIO |
| 25 | spektra_theme | SpektraThemeConfigMessage | Store a Spektra theme; also the reply to spektra_read THEME. | AckMessage | CONTROL | eDIDIO |
| 26 | spektra_read | SpektraReadMessage | Read Spektra data: SETTINGS gives spektra_settings, SEQUENCE spektra_sequence, THEME spektra_theme, CALENDAR spektra_calendar_overview, LIVE spektra_live, and with manifest set spektra_manifest. | see the type asked for | CONTROL | eDIDIO |
| 27 | spektra_control | SpektraControlMessage | Start, stop or pause a sequence or theme, or save the Spektra settings. | AckMessage | CONTROL | eDIDIO |
| 28 | dmx_translator | DMXProtocolTranslation | Configure the DMX to DALI translation objects; also the reply to read_device DMX_TRANSLATIONS. | AckMessage | ADMIN | eDIDIO |
| 29 | input_request | InputStateMessage | Ask for the live state of the physical inputs. | input_response | CONTROL | eDIDIO |
| 30 | input_response | InputStateResponse | The live input state mask. | sent by the device | eDIDIO | |
| 31 | diag_system | DiagnosticSystemInfoResponse | The device's capabilities, firmware, hardware and protocol version (proto_version): the reply to diag_message DIAGNOSTIC_SYSTEM_INFO. | sent by the device | eDIDIO, ADDICT | |
| 32 | diag_message | DiagnosticMessage | Ask for a diagnostic report; the reply depends on the type asked for. | see DiagnosticMessageType | CONTROL | eDIDIO, ADDICT |
| 33 | admin_message | AdminMessage | Get, set or run a device property. | admin_message for a GET, else AckMessage | see AdminPropertyType | eDIDIO, ADDICT |
| 34 | event | EventMessage | ADDICT: a filter starts or stops DALI bus monitoring, and each frame seen arrives as an event. On an eDIDIO, live events are event_stream (77). | AckMessage | NONE | ADDICT |
| 35 | secure_device_settings | SecureDeviceSettingsMessage | Change the secure-login settings (AES encrypted). | AckMessage | ADMIN | eDIDIO |
| 36 | firmware_new | FirmwareMetaMessage | Start a firmware update: describes the image, and erases the one stored. | AckMessage | ADMIN | eDIDIO, ADDICT |
| 37 | firmware_control | FirmwareControlMessage | Firmware update control (verify, apply, ...) from the client, and the device's verify result. | firmware_control or AckMessage | ADMIN | eDIDIO, ADDICT |
| 38 | firmware_chunk | FirmwareChunkMessage | One chunk of the firmware image. | AckMessage | ADMIN | eDIDIO, ADDICT |
| 39 | level_cache_response | LevelCacheResponse | A page of 64 cached DALI or DMX levels: the reply to a diag_message level-cache request. | sent by the device | eDIDIO, ADDICT | |
| 41 | list_extended | ExtendedListMessage | The steps of a list beyond the first 32; also the reply to read_device LIST_EXTENDED. | AckMessage | CONFIG | eDIDIO |
| 42 | ayt_message | AytMessage | "Are you there?" keep-alive: send one within 20 s or the connection is closed. | ayt_message | CONTROL | eDIDIO, ADDICT |
| 43 | rdm_message | RDMMessage | Send an RDM GET or SET to a fixture. | AckMessage, then rdm_response_message | CONTROL | eDIDIO, ADDICT |
| 44 | rdm_response_message | RDMResponseMessage | A fixture's RDM response. | sent by the device | eDIDIO, ADDICT | |
| 45 | logic_message | LogicMultiMessage | Configure the logic rules; also the reply to read_device LOGIC. | AckMessage | CONFIG | eDIDIO |
| 46 | secure_login | AdminSecureLoginMessage | Log in to a role, answering the nonce from AdminMessage NONCE. | AckMessage (detail = the role granted) | NONE | eDIDIO |
| 47 | device_state_message | DeviceStateMessage | Ask for the live state: uptime, clock, next alarm, inputs, lists and burn-ins. | device_state_message | CONTROL | eDIDIO, ADDICT |
| 48 | spektra_calendar_day | SpektraCalendarDayMessage | Not sent on its own: a calendar's days arrive inside spektra_calendar_overview. | unused | eDIDIO | |
| 49 | spektra_calendar_overview | SpektraCalendarOverviewMessage | The calendar: the reply to spektra_read CALENDAR. | sent by the device | eDIDIO | |
| 50 | inputs_dali | DALIInputMultiMessage | Configure the DALI inputs of one profile; also the reply to read_device DALI_INPUTS. | AckMessage | CONFIG | eDIDIO |
| 51 | logs_read | SystemLogReadMessage | Read up to 32 system log entries from a start index. | logs_read | CONFIG | eDIDIO |
| 52 | metadata_read | SystemMetaDataReadMessage | Read system metadata for debugging. | metadata_read | CONTROL | eDIDIO |
| 53 | dali_addressing_message | DALIAddressingMessage | Run DALI addressing on a line. | dali_addressing_message | CONFIG | eDIDIO, ADDICT |
| 54 | dali_remapping_message | DALIRemappingMessage | Move DALI devices to other short addresses. | AckMessage | CONFIG | eDIDIO, ADDICT |
| 58 | rdm_discovery | RDMDiscoveryMessage | Discover the RDM fixtures on a universe. | rdm_discovery_reply | CONFIG | eDIDIO, ADDICT |
| 59 | rdm_discovery_reply | RDMDiscoveryReplyMessage | Up to 128 discovered RDM fixtures; isNext asks for more. | sent by the device | eDIDIO, ADDICT | |
| 60 | dali_identify_duplicates | DALIIdentifyDuplicatesMessage | Find DALI devices sharing a short address. | dali_identify_duplicates | CONFIG | eDIDIO, ADDICT |
| 61 | spektra_live | SpektraLiveMessage | What Spektra is playing now, per zone: the reply to spektra_read LIVE. | sent by the device | eDIDIO | |
| 62 | sensor_query | SensorsQuery | Read the sensors' live state, up to 20 per request (page with offset). | sensor_query | CONTROL | eDIDIO |
| 63 | data_aliases | DataAliases | Get or set the names of profiles, inputs, lists, sensors and so on. | data_aliases for a get, AckMessage for a set | CONFIG | eDIDIO |
| 64 | sd_dir_list | SdDirListMessage | List an SD card directory, a page at a time (6-pole). | sd_dir_list | CONFIG | eDIDIO |
| 65 | sd_file_read | SdFileReadMessage | Read a chunk of a file on the SD card (6-pole). | sd_file_read | CONFIG | eDIDIO |
| 66 | sd_file_write | SdFileWriteMessage | Write a chunk of an upload to the SD card (6-pole). | sd_file_write | CONFIG | eDIDIO |
| 67 | sd_file_control | SdFileControlMessage | SD card file operations: stat, free space, delete, upload begin / end / abort / resume (6-pole). | sd_file_control | CONFIG | eDIDIO |
| 68 | sd_log_config | SdLogConfigMessage | Enable or disable log categories (6-pole). | sd_log_config | CONFIG | eDIDIO |
| 69 | sd_log_stream | SdLogStreamMessage | Deprecated: the v1 event stream, replaced by event_stream (77). Tag 69 stays reserved. | unused | eDIDIO | |
| 70 | crash_log | CrashLogMessage | Read the crash / reset record captured in backup RAM at boot. | crash_log | ADMIN | eDIDIO, ADDICT |
| 71 | sd_log_policy | SdLogPolicyMessage | Get or set the SD log rotation policy (6-pole). | sd_log_policy | CONFIG | eDIDIO |
| 72 | connection_status | ConnectionStatusMessage | The device's client connections: slot counts and per-connection details. | connection_status | ADMIN | eDIDIO, ADDICT |
| 73 | provision_get_state | ProvisionGetStateMessage | Read the device identity state (all public). | provision_get_state | ADMIN | eDIDIO |
| 74 | provision_install_identity | ProvisionInstallIdentityMessage | Install the device identity, in chunks; accepted only while unprovisioned. | provision_install_identity | ADMIN | eDIDIO |
| 75 | provision_pop | ProvisionProofOfPossessionMessage | Prove the device holds its key: it signs the nonce sent. | provision_pop | ADMIN | eDIDIO |
| 76 | provision_decommission | ProvisionDecommissionMessage | Return the device to unprovisioned. | provision_decommission | ADMIN | eDIDIO |
| 77 | event_stream | EventStreamMessage | Subscribe to the live event / log stream; events then arrive as event_stream. | event_stream | CONFIG | eDIDIO, ADDICT |
| 78 | spektra_manifest | SpektraManifestMessage | Which Spektra slots hold data, with a CRC for each: the reply to spektra_read with manifest set. | sent by the device | eDIDIO |
An admin_message names a target property and a command. Payload is the AdminMessage field the value travels in, both ways; for data it is the PayloadMessage field used. Actions (RUN, RESET, ADD, REMOVE) carry none and are answered with an AckMessage.
| # | Property | Commands | Payload | Role | Devices | Description |
|---|---|---|---|---|---|---|
| 0 | DEVICE_NAME | GET, SET | data.string_data | CONFIG | eDIDIO, ADDICT | The device name that appears on the network. Limited to 16 characters.string_data. |
| 1 | PROJECT_NAME | GET, SET | data.string_data | CONFIG | eDIDIO | Used for documentation. Limited to 32 characters.string_data. |
| 2 | LONGITUDE | GET, SET | data.float_data | CONFIG | eDIDIO | Used for calculating astronomical sunrise / sunset.float_data. |
| 3 | LATITUDE | GET, SET | data.float_data | CONFIG | eDIDIO | Used for calculating astronomical sunrise / sunset.float_data. |
| 4 | LOCAL_UTC_OFFSET | GET, SET | data.float_data | CONFIG | eDIDIO | Used for calculating astronomical sunrise / sunset.float_data. |
| 5 | DAYLIGHT_SAVINGS | GET, SET | data.uint_data | CONFIG | eDIDIO | Used for calculating astronomical sunrise / sunset.uint_data. |
| 6 | POLL_ACTIVE | GET, SET | data.uint_data | CONFIG | eDIDIO | Whether or not to poll the current level of DALI devices to keep an in-memory cache up-to-date.uint_data. |
| 7 | DHCP_ENABLED | GET, SET | data.uint_data | ADMIN | eDIDIO | Whether or not the device should use a static IP or expect a DHCP server to provide it with an IP.uint_data. |
| 8 | IP_ADDR | GET, SET | data.string_data | ADMIN | eDIDIO | The static IP address to use if DHCP_ENABLED is FALSE.string_data. |
| 9 | MAC_ADDR | GET, SET | data.string_data | ADMIN | eDIDIO | The MAC Address of the device. Expected format: [40:D8:55:1B:XX:XX].string_data. |
| 10 | GATEWAY_IP | GET, SET | data.string_data | ADMIN | eDIDIO | The IP address of the gateway for the network this device will be installed on.string_data. |
| 11 | NETWORK_PROPERTIES | GET, SET | network_properties | ADMIN | eDIDIO, ADDICT | Contains numerous properties such as DHCP, NTP, Gateway, IP, MAC. |
| 12 | SYSTEM_PROPERTIES | GET, SET | project_properties | CONFIG | eDIDIO | Contains numerous properties such as Device Name (documentation only; not network hostname), Project Name, Latitude, Longitude, UTC Offset, DLS, Polling. |
| 13 | CONTROLLER_LINES | GET, SET | controller_lines | CONFIG | eDIDIO | Allows you to specify the daughterboards installed in the device [NONE, DALI, DMX, DMX_IN]. |
| 14 | EEPROM_FULL_CHIP | RESET | none | ADMIN | eDIDIO | Allows you to request a reset to default values for all data stored in EEPROM. |
| 15 | CONFIG_DATA | RESET | none | ADMIN | eDIDIO | Allows you to request a reset to default values for the Config Data stored in EEPROM. |
| 16 | SPEKTRA_DATA | RESET | none | ADMIN | eDIDIO | Allows you to request a reset to default values for the Spektra Data stored in EEPROM. |
| 17 | DEVICE_STATUS | GET | device_status | CONTROL | eDIDIO, ADDICT | Can be used to request the Device Status: Temperature and Battery Voltage. |
| 18 | CONFIG_STATUS | GET | config_status | CONTROL | eDIDIO | Can be used to request the Config Status: Active Alarm, List States, Sensor States, Burn-in States. |
| 19 | DEVICE_TIME | GET, SET | device_time | CONTROL for GET, CONFIG for SET | eDIDIO | Get or Set the RTC time on the device. |
| 20 | NTP_DETAILS | GET, SET | network_properties | CONFIG | eDIDIO | Allows you to Get or Set the NTP parameters (i.e. NTP Server) used for maintaining the RTC via NTP updates. |
| 21 | DALI_SENSORS | ADD, REMOVE, RESET | none | CONFIG | eDIDIO | Provides actions for DALI Sensor control: "ADD" to un-mute all. "REMOVE" to mute all. "RESET" to clear all (unprogram). |
| 22 | SECURE_SESSION | GET, SET | data.uint_data | CONTROL for GET, ADMIN for SET | eDIDIO | Allows you to Get or Set the "Secure Session" status of the device.uint_data. |
| 23 | NONCE | GET | data.string_data | NONE | eDIDIO | Allows you to request a Nonce to perform a Secure Login.string_data. |
| 24 | DALI_SENSOR_TYPE | GET | dali_sensor_type | CONFIG | eDIDIO | The type of DALI frame (24 or 25-bit) for eDALI packets to/from motion sensors. |
| 25 | DEVICE_REBOOT | RUN | none | ADMIN | eDIDIO, ADDICT | Will reboot the device when used with the 'RUN' AdminCommandType. |
| 26 | SYSTEM_LOGGING | GET, RESET | data.uint_data | CONFIG | eDIDIO | Will reset the system logs when used with a 'RESET' AdminCommandType.uint_data. |
| 27 | SUBNET | GET, SET | data.string_data | ADMIN | eDIDIO | The Subnet of the Device.string_data. |
| 28 | DNS | GET, SET | dns_servers | ADMIN | eDIDIO | The Primary and Secondary DNS, both ways in dns_servers. eDIDIO firmware before 1.6.3 refused a SET with INVALID_PARAMS and answered a GET in the wrong arm - use NETWORK_PROPERTIES (DNS_Primary / DNS_Secondary) for those. |
| 29 | LINK | GET, SET | data.uint_data | ADMIN | eDIDIO | Whether or not the UDP Link state is active.uint_data. |
| 30 | LINK_TYPE | GET, SET | data.uint_data | ADMIN | eDIDIO | Type of Link to enable, based on ReadType.uint_data. |
| 31 | LINK_MASK | GET, SET | data.uint_data | ADMIN | eDIDIO | Link Index Mask for above.uint_data. |
| 32 | LINK_NETMASK | GET, SET | data.uint_data | ADMIN | eDIDIO | Netmask for Link to create Network groups for UDP messaging.uint_data. |
| 33 | DALI_RX_TOLERANCE | GET, SET | data.uint_data | CONFIG | eDIDIO | The tolerance for DALI RX (where 10 is 10% above and below nominal half bit time of 416us).uint_data. |
| 34 | DALI_TX_HALF_BIT_TIME | GET, SET | data.uint_data | CONFIG | eDIDIO | Default value is 416us.uint_data. |
| 35 | DMX_TIMING | GET, SET | dmx_timing_mode | CONFIG | eDIDIO, ADDICT | DMX Timing (I.e. 44Hz). |
| 36 | DMX_PROPERTIES | GET, SET | dmx_line_props | CONFIG | eDIDIO, ADDICT | DMX Line Properties. Channel Mapping, 16 bit, slot count. |
| 37 | MEMORY_DIAGNOSTICS | GET | memory_diagnostics | CONTROL | eDIDIO, ADDICT | GET-only. Returns per-task stack high-water-marks, system-stack HWM, and SRAM/CCMRAM static-section usage. Use with the 'GET' AdminCommandType. Used for tuning FreeRTOS task stack sizes and monitoring runtime RAM headroom. |
| 38 | ETHERNET_DIAGNOSTICS | GET | ethernet_diagnostics | CONTROL | eDIDIO | GET-only. Returns Ethernet PHY register snapshot, Ethernet MAC counters, resolved link state, and a ring buffer of recent link-state transitions. Use with the 'GET' AdminCommandType. Used to diagnose link/auto-negotiation/duplex-mismatch issues without an SD card. |
| 39 | LINE_DIAGNOSTICS | GET | line_diagnostics | CONTROL | eDIDIO | GET-only. Per-line readout of configured-vs-probed daughterboard type plus a coarse OK/FAULTY/EMPTY/MISCONFIGURED verdict. Briefly perturbs each line (a DALI half-bit pulse and/or a DMX RX-mode window) — fire on demand, not on a hot loop. Use with the 'GET' AdminCommandType. |
| 40 | TIME_DIAGNOSTICS | GET | time_diagnostics | CONTROL | eDIDIO | GET-only. RTC/NTP/DST observability: LSE crystal ppm measurement, lifetime NTP success/failure counts, last sync details, time-set audit trail, backup-domain boot counter, DST visibility. Use with the 'GET' AdminCommandType. |
| 41 | RTC_TEMP_COMP_ENABLED | GET, SET | data.uint_data | CONFIG | eDIDIO | GET/SET. Enable/disable the temperature-driven smooth calibration of the RTC. Persisted in BKPSRAM (reset on battery loss). Default 1.uint_data. |
| 42 | RTC_PPM_MANUAL_OVERRIDE | GET, SET | data.float_data | CONFIG | eDIDIO | GET/SET. When enabled (override flag in PayloadMessage), the RTC smooth calibration is set to a fixed signed ppm value at every hour boundary, bypassing temp comp. Persisted in BKPSRAM.float_data. |
| 43 | NTP_FORCE_SYNC | RUN | none | CONTROL | eDIDIO | RUN. Triggers an immediate NTP sync attempt. |
| 44 | NTP_POLL_PERIOD_SECONDS | GET, SET | data.uint_data | CONFIG | eDIDIO | GET/SET. Override the NTP poll period. 0 means use the existing NTP_DETAILS.NTPTimeout from config. Non-zero is persisted in BKPSRAM.uint_data. |
| 45 | NTP_MAX_ACCEPTABLE_DELTA_SECONDS | GET, SET | data.uint_data | CONFIG | eDIDIO | GET/SET. NTP corrections whose |delta| exceeds this value are rejected (treated as a sanity-check failure). Default 3600 (1 hour). Persisted in BKPSRAM.uint_data. |
| 46 | TIME_DIAG_MEASURE_LSE | RUN | none | CONTROL | eDIDIO | RUN. Triggers an on-demand LSE-vs-HSE ppm measurement (~250 ms). Result is cached and returned on the next GET TIME_DIAGNOSTICS. |
| 47 | BACKUP_DOMAIN_RESET_CANARY | RUN | none | CONFIG | eDIDIO | RUN. Resets the boots_since_last_backup_loss counter to 0. Use after a deliberate battery replacement so the counter reflects only post-replacement boots. |
| 48 | DALI_STATUS | GET | dali_status | CONTROL | eDIDIO, ADDICT | GET-only. Returns the DALI system status summary (per-line online/fault device counts, bus-power errors, lowest faulting address, and missing/comms-error device bitmaps) — the same data the on-device Logic system evaluates for "any DALI error" actions. Use with the 'GET' AdminCommandType. |
| 49 | USER_ACCOUNT | SET | user_account | ADMIN | eDIDIO | SET-only (ADMIN clearance). Provisions a role's login secret (see AdminUserAccountMessage). Write-only — secrets are never returned by a GET. |
| 50 | STORAGE_DIAGNOSTICS | GET | storage_diagnostics | CONTROL | eDIDIO | GET-only. Health of the shared SPI storage bus and everything on it: bus stall/reset counters, NOR flash program/erase fault state and presence/identity verdict, and — on variants fitted with an SD card — mount state, probe response, deadline-abort counters and the removal/power-cycle escalation state. Side-effect-free: every value is read from a RAM latch, nothing is probed. Use with the 'GET' AdminCommandType. Not in eDIDIO firmware 1.6.3, which answers UNEXPECTED_TYPE. |
| 51 | WIFI_SETTINGS | GET, SET | wifi_settings | NONE | ADDICT | GET/SET. Wi-Fi of a device with an ESP32 co-processor (ADDICT V3): access point only or access point + station, the station network and the access point channel. The station password is write-only - a GET never returns it. A SET replies before the device reconnects its Wi-Fi. See AdminWifiSettingsMessage. |
| 52 | WIFI_STATUS | GET | wifi_status | NONE | ADDICT | GET-only. Live Wi-Fi state: station link and IP, the device's own access point (SSID, IP, connected clients) and both MACs. See AdminWifiStatusMessage. |
| 53 | WIFI_DIAGNOSTICS | GET | wifi_diagnostics | NONE | ADDICT | GET-only. Wi-Fi link quality (station RSSI, channel, BSSID), co-processor version and restart counters, and command-pipeline health counters. Side-effect-free: every value is cached. See AdminWifiDiagnosticsMessage. |
read_device)| # | ReadType | Reply | Devices | Description |
|---|---|---|---|---|
| 0 | INPUTS | inputs | eDIDIO | The physical inputs of one profile (profile). |
| 1 | OUTPUTS | outputs | eDIDIO | The outputs of one profile (profile). |
| 2 | IR | irs | eDIDIO | The IR codes of one profile (profile; deprecated). |
| 3 | SENSOR | sensor | eDIDIO | One sensor (index) of one profile (profile). |
| 5 | LIST | list | eDIDIO | One list (index): its first 32 steps. |
| 7 | ALARMS | alarms | eDIDIO | Every alarm. |
| 8 | BURN_IN | burn_ins | eDIDIO | Every burn-in. |
| 9 | PROJECT | AckMessage (INDEX_OUT_OF_BOUNDS) | eDIDIO | Not supported - use AdminMessage SYSTEM_PROPERTIES. |
| 10 | NETWORK | AckMessage (INDEX_OUT_OF_BOUNDS) | eDIDIO | Not supported - use AdminMessage NETWORK_PROPERTIES. |
| 11 | DEVICE | AckMessage (INDEX_OUT_OF_BOUNDS) | eDIDIO | Not supported - use diag_message DIAGNOSTIC_SYSTEM_INFO. |
| 12 | POLL_DATA | AckMessage (INDEX_OUT_OF_BOUNDS) | eDIDIO | Not supported - use diag_message DALI_LEVEL_CACHE. |
| 13 | LIST_EXTENDED | list_extended | eDIDIO | Steps beyond the first 32 of one list (index), from block secondary_index. |
| 14 | LOGIC | logic_message | eDIDIO | Every logic rule. |
| 15 | DALI_INPUTS | inputs_dali | eDIDIO | The DALI inputs of one profile (profile). |
| 16 | DMX_TRANSLATIONS | dmx_translator | eDIDIO | Every DMX to DALI translation object. |
diag_message)| # | DiagnosticMessageType | Reply | Devices | Description |
|---|---|---|---|---|
| 0 | DIAGNOSTIC_SYSTEM_INFO | diag_system | eDIDIO, ADDICT | Can be used to retrieve a large number of properties that describe the capabilities of the device. (Number of supported Lists, Alarms, etc.). |
| 1 | DIAGNOSTIC_INPUT_STATUS | diag_system | eDIDIO, ADDICT | Not currently supported (will default to SYSTEM_INFO). |
| 2 | DALI_LEVEL_CACHE | level_cache_response (64 levels of line) | eDIDIO | Can be used to retrieve the current entries of the in-memory DALI values cache. |
| 3 | DMX_LEVEL_CACHE | level_cache_response (64 levels of line, from page x 64) | eDIDIO, ADDICT | Can be used to retrieve the current entries of the in-memory DMX levels cache. Results must be paginated due to size of DMX universe (512). |
| 4 | ROOM_JOINS | AckMessage (INDEX_OUT_OF_BOUNDS) | eDIDIO | Removed: the "Joined Rooms" state no longer exists. |
| 5 | DALI_STATUS_CACHE | level_cache_response (64 status bytes of line) | eDIDIO | Can be used to retrieve the current entries of the in-memory DALI status cache. |
Every message to and from a device is one EdidioMessage carrying exactly one payload. On TCP it is
framed as [0xCD, length MSB, length LSB, protobuf bytes] - the length counts the protobuf bytes only.
Each payload field below says what the device replies ("Reply:"), or that only the device sends it,
and the login role it needs when the device's secure session is on ("Role:"; with it off nothing is
checked). "Devices:" lists the products that handle it; without one it is eDIDIO only.
Retired payload numbers - never reuse: 7 (SensorMultiMessage), 9 (ListMultiMessage),
40 (JoinedRoomsMessage), 55-57 (Spektra show messages).
| Field | Type | Label | Description |
| message_id | uint32 | Chosen by the client and echoed in the reply, so replies can be matched to requests. Not unique across clients. |
|
| ack | AckMessage | The answer to a request that returns no data: success, or why it was refused (type and detail). Sent by the device. Devices: eDIDIO, ADDICT. |
|
| inputs | InputMultiMessage | Configure the physical inputs of one profile; also the reply to read_device INPUTS. Reply: AckMessage. Role: CONFIG. |
|
| outputs | OutputMultiMessage | Configure the outputs of one profile; also the reply to read_device OUTPUTS. Reply: AckMessage. Role: CONFIG. |
|
| irs | IRMultiMessage | Configure the IR codes of one profile (deprecated); also the reply to read_device IR. Reply: AckMessage. Role: CONFIG. |
|
| sensor | SensorMessage | Configure one DALI-2 sensor; also the reply to read_device SENSOR. Reply: AckMessage. Role: CONFIG. |
|
| list | ListMessage | Configure a list - up to 32 steps, the rest follow in list_extended; also the reply to read_device LIST. Reply: AckMessage. Role: CONFIG. |
|
| alarm | AlarmMessage | Configure one alarm (a scheduled action). Reply: AckMessage. Role: CONFIG. |
|
| alarms | AlarmMultiMessage | Configure every alarm at once; also the reply to read_device ALARMS. Reply: AckMessage. Role: CONFIG. |
|
| burn_ins | BurnInMultiMessage | Configure the burn-ins; also the reply to read_device BURN_IN. Reply: AckMessage. Role: CONFIG. |
|
| sensor_command | SensorCommandMessage | Mute, unmute or override a sensor. Reply: AckMessage. Role: CONTROL. |
|
| change_profile | ChangeProfileMessage | Change the active profile (this resets the sensors). Reply: AckMessage. Role: CONTROL. |
|
| identify_message | IdentifyMessage | Show information on the device's screen to help find it. Reply: AckMessage. Role: CONTROL. |
|
| update_time | UpdateTimeMessage | Set the device clock. Reply: AckMessage. Role: CONFIG. |
|
| read_device | ReadDeviceMessage | Read configuration back; the reply is the payload for the ReadType asked for. Reply: see ReadType. Role: CONTROL. |
|
| dali_message | DALIMessage | Send a DALI command or query on one or more lines. Reply: AckMessage for a command, dali_query for a query. Role: CONTROL. Devices: eDIDIO, ADDICT. |
|
| dali_query | DALIQueryResponse | A DALI query's answer, tagged with the line and address. Sent by the device. Devices: eDIDIO, ADDICT. |
|
| dmx_message | DMXMessage | Set DMX levels on one or more universes, with an optional fade. Reply: AckMessage. Role: CONTROL. Devices: eDIDIO, ADDICT. |
|
| external_trigger | ExternalTriggerMessage | Fire a trigger action from another system. Reply: AckMessage. Role: CONTROL. |
|
| spektra_settings | SpektraSettingMessage | Configure a Spektra zone; also the reply to spektra_read SETTINGS. Reply: AckMessage. Role: CONTROL. |
|
| spektra_sequence | SpektraSequenceConfigMessage | Store a Spektra sequence; also the reply to spektra_read SEQUENCE. Reply: AckMessage. Role: CONTROL. |
|
| spektra_calendar | SpektraCalendarMessage | Assign a sequence or theme to calendar days. Reply: AckMessage. Role: CONFIG. |
|
| spektra_theme | SpektraThemeConfigMessage | Store a Spektra theme; also the reply to spektra_read THEME. Reply: AckMessage. Role: CONTROL. |
|
| spektra_read | SpektraReadMessage | Read Spektra data: SETTINGS gives spektra_settings, SEQUENCE spektra_sequence, THEME spektra_theme, CALENDAR spektra_calendar_overview, LIVE spektra_live, and with manifest set spektra_manifest. Reply: see the type asked for. Role: CONTROL. |
|
| spektra_control | SpektraControlMessage | Start, stop or pause a sequence or theme, or save the Spektra settings. Reply: AckMessage. Role: CONTROL. |
|
| dmx_translator | DMXProtocolTranslation | Configure the DMX to DALI translation objects; also the reply to read_device DMX_TRANSLATIONS. Reply: AckMessage. Role: ADMIN. |
|
| input_request | InputStateMessage | Ask for the live state of the physical inputs. Reply: input_response. Role: CONTROL. |
|
| input_response | InputStateResponse | The live input state mask. Sent by the device. |
|
| diag_system | DiagnosticSystemInfoResponse | The device's capabilities, firmware, hardware and protocol version (proto_version): the reply to diag_message DIAGNOSTIC_SYSTEM_INFO. Sent by the device. Devices: eDIDIO, ADDICT. |
|
| diag_message | DiagnosticMessage | Ask for a diagnostic report; the reply depends on the type asked for. Reply: see DiagnosticMessageType. Role: CONTROL. Devices: eDIDIO, ADDICT. |
|
| admin_message | AdminMessage | Get, set or run a device property. Reply: admin_message for a GET, else AckMessage. Role: see AdminPropertyType. Devices: eDIDIO, ADDICT. |
|
| event | EventMessage | ADDICT: a filter starts or stops DALI bus monitoring, and each frame seen arrives as an event. On an eDIDIO, live events are event_stream (77). Reply: AckMessage. Role: NONE. Devices: ADDICT. |
|
| secure_device_settings | SecureDeviceSettingsMessage | Change the secure-login settings (AES encrypted). Reply: AckMessage. Role: ADMIN. |
|
| firmware_new | FirmwareMetaMessage | Start a firmware update: describes the image, and erases the one stored. Reply: AckMessage. Role: ADMIN. Devices: eDIDIO, ADDICT. |
|
| firmware_control | FirmwareControlMessage | Firmware update control (verify, apply, ...) from the client, and the device's verify result. Reply: firmware_control or AckMessage. Role: ADMIN. Devices: eDIDIO, ADDICT. |
|
| firmware_chunk | FirmwareChunkMessage | One chunk of the firmware image. Reply: AckMessage. Role: ADMIN. Devices: eDIDIO, ADDICT. |
|
| level_cache_response | LevelCacheResponse | A page of 64 cached DALI or DMX levels: the reply to a diag_message level-cache request. Sent by the device. Devices: eDIDIO, ADDICT. |
|
| list_extended | ExtendedListMessage | The steps of a list beyond the first 32; also the reply to read_device LIST_EXTENDED. Reply: AckMessage. Role: CONFIG. |
|
| ayt_message | AytMessage | "Are you there?" keep-alive: send one within 20 s or the connection is closed. Reply: ayt_message. Role: CONTROL. Devices: eDIDIO, ADDICT. |
|
| rdm_message | RDMMessage | Send an RDM GET or SET to a fixture. Reply: AckMessage, then rdm_response_message. Role: CONTROL. Devices: eDIDIO, ADDICT. |
|
| rdm_response_message | RDMResponseMessage | A fixture's RDM response. Sent by the device. Devices: eDIDIO, ADDICT. |
|
| logic_message | LogicMultiMessage | Configure the logic rules; also the reply to read_device LOGIC. Reply: AckMessage. Role: CONFIG. |
|
| secure_login | AdminSecureLoginMessage | Log in to a role, answering the nonce from AdminMessage NONCE. Reply: AckMessage (detail = the role granted). Role: NONE. |
|
| device_state_message | DeviceStateMessage | Ask for the live state: uptime, clock, next alarm, inputs, lists and burn-ins. Reply: device_state_message. Role: CONTROL. Devices: eDIDIO, ADDICT. |
|
| spektra_calendar_day | SpektraCalendarDayMessage | Not sent on its own: a calendar's days arrive inside spektra_calendar_overview. Unused. |
|
| spektra_calendar_overview | SpektraCalendarOverviewMessage | The calendar: the reply to spektra_read CALENDAR. Sent by the device. |
|
| inputs_dali | DALIInputMultiMessage | Configure the DALI inputs of one profile; also the reply to read_device DALI_INPUTS. Reply: AckMessage. Role: CONFIG. |
|
| logs_read | SystemLogReadMessage | Read up to 32 system log entries from a start index. Reply: logs_read. Role: CONFIG. |
|
| metadata_read | SystemMetaDataReadMessage | Read system metadata for debugging. Reply: metadata_read. Role: CONTROL. |
|
| dali_addressing_message | DALIAddressingMessage | Run DALI addressing on a line. Reply: dali_addressing_message. Role: CONFIG. Devices: eDIDIO, ADDICT. |
|
| dali_remapping_message | DALIRemappingMessage | Move DALI devices to other short addresses. Reply: AckMessage. Role: CONFIG. Devices: eDIDIO, ADDICT. |
|
| rdm_discovery | RDMDiscoveryMessage | Discover the RDM fixtures on a universe. Reply: rdm_discovery_reply. Role: CONFIG. Devices: eDIDIO, ADDICT. |
|
| rdm_discovery_reply | RDMDiscoveryReplyMessage | Up to 128 discovered RDM fixtures; isNext asks for more. Sent by the device. Devices: eDIDIO, ADDICT. |
|
| dali_identify_duplicates | DALIIdentifyDuplicatesMessage | Find DALI devices sharing a short address. Reply: dali_identify_duplicates. Role: CONFIG. Devices: eDIDIO, ADDICT. |
|
| spektra_live | SpektraLiveMessage | What Spektra is playing now, per zone: the reply to spektra_read LIVE. Sent by the device. |
|
| sensor_query | SensorsQuery | Read the sensors' live state, up to 20 per request (page with offset). Reply: sensor_query. Role: CONTROL. |
|
| data_aliases | DataAliases | Get or set the names of profiles, inputs, lists, sensors and so on. Reply: data_aliases for a get, AckMessage for a set. Role: CONFIG. |
|
| sd_dir_list | SdDirListMessage | List an SD card directory, a page at a time (6-pole). Reply: sd_dir_list. Role: CONFIG. |
|
| sd_file_read | SdFileReadMessage | Read a chunk of a file on the SD card (6-pole). Reply: sd_file_read. Role: CONFIG. |
|
| sd_file_write | SdFileWriteMessage | Write a chunk of an upload to the SD card (6-pole). Reply: sd_file_write. Role: CONFIG. |
|
| sd_file_control | SdFileControlMessage | SD card file operations: stat, free space, delete, upload begin / end / abort / resume (6-pole). Reply: sd_file_control. Role: CONFIG. |
|
| sd_log_config | SdLogConfigMessage | Enable or disable log categories (6-pole). Reply: sd_log_config. Role: CONFIG. |
|
| sd_log_stream | SdLogStreamMessage | Deprecated. Deprecated: the v1 event stream, replaced by event_stream (77). Tag 69 stays reserved. Unused. |
|
| crash_log | CrashLogMessage | Read the crash / reset record captured in backup RAM at boot. Reply: crash_log. Role: ADMIN. Devices: eDIDIO, ADDICT. |
|
| sd_log_policy | SdLogPolicyMessage | Get or set the SD log rotation policy (6-pole). Reply: sd_log_policy. Role: CONFIG. |
|
| connection_status | ConnectionStatusMessage | The device's client connections: slot counts and per-connection details. Reply: connection_status. Role: ADMIN. Devices: eDIDIO, ADDICT. |
|
| provision_get_state | ProvisionGetStateMessage | Read the device identity state (all public). Reply: provision_get_state. Role: ADMIN. |
|
| provision_install_identity | ProvisionInstallIdentityMessage | Install the device identity, in chunks; accepted only while unprovisioned. Reply: provision_install_identity. Role: ADMIN. |
|
| provision_pop | ProvisionProofOfPossessionMessage | Prove the device holds its key: it signs the nonce sent. Reply: provision_pop. Role: ADMIN. |
|
| provision_decommission | ProvisionDecommissionMessage | Return the device to unprovisioned. Reply: provision_decommission. Role: ADMIN. |
|
| event_stream | EventStreamMessage | Subscribe to the live event / log stream; events then arrive as event_stream. Reply: event_stream. Role: CONFIG. Devices: eDIDIO, ADDICT. |
|
| spektra_manifest | SpektraManifestMessage | Which Spektra slots hold data, with a CRC for each: the reply to spektra_read with manifest set. Sent by the device. |
| Name | Option |
| sd_log_stream | true |
The result in an AckMessage: SUCCESS, or why the request was not done.
| Name | Number | Description |
| DECODE_FAILED | 0 | May indicate an issue with the protocol (e.g. a mismatch in expected fields between clients). Ensure both parties are using the latest version. |
| INDEX_OUT_OF_BOUNDS | 1 | A resource was requested beyond the amount available. |
| UNEXPECTED_TYPE | 2 | The provided message was not able to be handled or processed (likely due to a lack of enough information or incorrect values). |
| ENCODE_FAILED | 3 | Not currently in use. |
| KEY_MISMATCH | 4 | Not currently in use. |
| SUCCESS | 5 | The message was decoded and handled successfully. |
| INVALID_PARAMS | 6 | The message was decoded but had invalid data for the intended outcome. |
| UNEXPECTED_COMMAND | 7 | The message was decoded but the requested action was not valid for current the state of the device. |
| COMMUNICATION_FAILED | 8 | The message could not be received or sent due to an internal issue. |
| COMMUNICATION_TIMEOUT | 9 | May indicate contention for a shared resource or that an existing task is taking longer than expected and the latest request has timed-out. |
| DATA_TOO_LONG | 10 | May indicate too much data was in the request or the required reply would be too big to handle. |
| UNEXPECTED_CASE | 11 | May indicate that the message is out of context (e.g. an "end" command for a process that is not running) or that the message requests a feature that is not yet implemented. |
| SLOTS_FULL | 12 | Typically indicates that a request was valid, but the relevant content is "full" and thus elements must be removed before continuing. |
| UNAUTHORISED | 13 | The message could not be actioned because the connection has not been authorised. |
| PARTIAL_SUCCESS | 14 | Can be returned in the case where some but not all Lines in a line_mask successfully sent |
| COMMAND_FAILED | 15 | For whatever reason, the intended command did not complete |
| DEPRECATED | 16 | For message which is no longer supported by this Firmware |
| FORBIDDEN | 17 | The connection is authenticated but its role lacks the clearance required for this operation (distinct from UNAUTHORISED, which means not authenticated at all). |
Sent in Response to another message.
| Field | Type | Label | Description |
| payload | AckMessageType | Will either indicate 'Success' or a particular Error as specified by "AckMessageType" |
|
| detail | uint32 | Optional context. Interpretation depends on payload type: for PARTIAL_SUCCESS on a DALI multi-line command it is the bitmask of lines that succeeded; for an ERROR payload (e.g. INVALID_PARAMS) it is a RejectReason code naming the specific reason (0 = unspecified); for a SUCCESS ack to a secure login it is the granted clearance level (0=NONE, 1=CONTROL, 2=CONFIG, 3=ADMIN). |
Refines an ERROR AckMessageType with a specific, machine-readable reason, carried in AckMessage.detail
(detail stays a uint32 - for SUCCESS / PARTIAL_SUCCESS it keeps its existing meaning, e.g. a line bitmask).
0 = unspecified so older firmware (detail defaults to 0) gracefully degrades to the generic ack message.
The CLIENT owns the human-readable strings; this enum is the shared code<->meaning contract so firmware and
app never drift. Values are allocated in 1000-wide blocks per subsystem - add new reasons to the owning
block, never renumber (gaps are free). uint32/varint: a value stays 2 wire-bytes up to 16383, and the field
itself reaches ~4.29e9, so the block scheme is effectively open-ended.
1-999 general / protocol (cross-cutting)
1000-1999 sensors
2000-2999 inputs
3000-3999 outputs
4000-4999 lists
5000-5999 schedules / alarms
6000-6999 zones
7000-7999 sequences / themes / colour
8000-8999 DALI commissioning / addressing
9000-9999 network / config
10000-10999 admin
11000-11999 firmware update / apply
| Name | Number | Description |
| REJECT_UNSPECIFIED | 0 | No specific reason (older firmware, or a generic reject) |
| GENERAL_REQUIRES_NEWER_FIRMWARE | 1 | The controller firmware is older than the requested feature needs |
| GENERAL_UNSUPPORTED_ON_VARIANT | 2 | Not supported on this hardware variant |
| SENSOR_BAD_LINE | 1000 | V4: a sensor must sit on exactly one valid DALI line |
| SENSOR_ADDRESS_OUT_OF_RANGE | 1001 | V4: sensor short address must be 0-63 |
| SENSOR_CONTROL_LINE_INVALID | 1002 | V4: control line mask falls outside the available lines |
| SENSOR_CONTROL_TARGET_INVALID | 1003 | V4: control group/address is out of range |
| SENSOR_TIMER_OUT_OF_RANGE | 1004 | V8: a timer value would overflow once stored/scaled |
| SENSOR_LEGACY_GROUPING | 1005 | V7': non-zero legacy motion_sensors (an OLD client) - update the app |
| SENSOR_LEADER_WITHOUT_GROUP | 1006 | V9: Leader role set without a cooperation group |
| SENSOR_GROUP_ID_INVALID | 1007 | V9: cooperation group id is too large |
| SENSOR_HARVEST_NO_CONTROL_LINE | 1008 | V1: a daylight-harvesting sensor must drive at least one line |
| SENSOR_HARVEST_QUERY_ADDR_INVALID | 1009 | V1: the harvesting seed query address must be a single 0-63 device |
| SENSOR_HARVEST_NO_SETPOINT | 1010 | V1: the harvesting setpoint must be greater than 0 |
| SENSOR_GROUP_MIXED_TARGET | 1011 | V2': ACTIVE members of one group must share the control target |
| SENSOR_DUPLICATE_ADDRESS | 1012 | V10: another programmed sensor already uses this (short address, DALI line) - one physical sensor's events would drive multiple slots |
| FIRMWARE_APPLY_NO_IMAGE | 11000 | No firmware image is staged in the target slot |
| FIRMWARE_APPLY_CHECKSUM_FAILED | 11001 | Staged image failed the XOR checksum verify (corrupt or incomplete upload) |
| FIRMWARE_APPLY_BAD_STRUCTURE | 11002 | Staged image geometry is not cleanly flashable (bad/misaligned chunk addressing) - would brick on handoff |
| FIRMWARE_APPLY_UNSIGNED | 11003 | No image signature was present - device rejects as unsigned |
| FIRMWARE_APPLY_SIGNATURE_INVALID | 11004 | Image signature present but did not verify (wrong key, tampered, or content mismatch) |
| FIRMWARE_APPLY_INCOMPLETE | 11005 | A staged chunk could not be read back (blank/unreadable page) even after retries - the staged image is incomplete/corrupt in flash, NOT a geometry problem. Re-upload. |
| FIRMWARE_UPLOAD_SLOT_NOT_ERASED | 11006 | Upload: the target page already held DIFFERENT data (the slot was not cleanly erased) - abort and restart the upload |
| FIRMWARE_UPLOAD_WRITE_FAILED | 11007 | Upload: the post-write read-back did not match what was sent (flash write did not take) - retry the chunk / upload |
| FIRMWARE_SESSION_BUSY | 11008 | Another connection already owns the firmware update session (single-owner) - wait for it to finish or disconnect, then retry |
| FIRMWARE_APPLY_NO_CONF_KEY | 11009 | V3: the image is encrypted but the device has no key to decrypt it - provision the device first |
| FIRMWARE_APPLY_DECRYPT_FAILED | 11010 | V3: image decryption failed - image not applied |
| FIRMWARE_APPLY_BOOTLOADER_INCOMPATIBLE | 11011 | The staged image needs a firmware format this device's bootloader cannot decode - provide a compatible image |
Contains a payload. Used in multiple message types. Incorrect payload type will result in AckMessage Unexpected Type.
| Field | Type | Label | Description |
| uint_data | uint32 | Binary Flags set with 0 (FALSE) and 1 (TRUE) |
|
| float_data | float | Decimal values (latitude, longitude, UTC offset, ppm) |
|
| string_data | string | Every PayloadMessage will contain String data, with optional uint or float data |
"Are You There" Message with some supplementary values for debugging. "Are you there?" messages should be sent within 20 seconds to maintain a connection. However, any received message will reset this timer.
| Field | Type | Label | Description |
| timesinceboot | uint32 | Device uptime in seconds |
|
| temperature | float | Current Temp on the device internals |
|
| time | TimeClockMessage | Current Time of the RTC |
This message contains the 'variable state' for the Device
| Field | Type | Label | Description |
| uptime | uint32 | Uptime (seconds since boot) |
|
| temp | float | Temperature |
|
| vbat | float | Battery voltage |
|
| clock | TimeClockMessage | RTC Time on device |
|
| next_alarm | uint32 | Index of next alarm |
|
| next_alarm_time | TimeClockMessage | Time of next alarm |
|
| input_state | uint32 | Input state mask |
|
| list_states | uint32 | repeated | State of each List (DISABLED / ENABLED / LOOPING) |
| burn_in_states | uint32 | repeated | State of each Burn-in (RUNNING / NOT RUNNING) |
| sensor_states | uint32 | repeated | State of each DALI Sensor (IDLE / DISABLED / WARNING / OCCUPANCY) |
| zone_states | uint32 | repeated | State of each Spektra Zone (OFF / SEQUENCE / THEME / STATIC) |
| zone_sleep_states | uint32 | repeated | Sleep State of each Spektra Zone (TRUE / FALSE) |
| zone_indexes | uint32 | repeated | Index of the selected Sequence, Theme, or Static colour for each Zone |
| dali_input_state | uint64 | DALI Input state mask |
|
| output_state | uint32 | Output state mask |
How an input or output behaves: momentary or latching, and whether it is enabled.
| Name | Number | Description |
| MOMENTARY | 0 | A Short Press occurs when a button is pressed for less than 250ms (and at least 50ms). A Long Press occurs when a button is pressed for longer than 650ms. Holding the button down will repeat the Long Press action every 400ms. |
| LATCHING | 1 | Instantaneous on short to ground (debounced to 50ms). Trigger occurs once upon entering this state (LOW) and once upon leaving this state (HIGH). |
| MOMENTARY_OUTPUT | 2 | A temporary output signal |
| LATCHING_OUTPUT | 3 | A continuous output signal |
| ROTARY | 4 | Rotary device, DALI input device |
| MOMENTARY_DISABLED | 128 | Used to track the enabled/disabled state of an I/O |
| LATCHING_DISABLED | 129 | Used to track the enabled/disabled state of an I/O |
What a trigger does (TriggerMessage.type): set DALI or DMX levels, start or stop lists, sequences and themes, change profiles, control sensors, and so on. target_index and value mean what each type says.
| Name | Number | Description |
| DALI_ARC | 0 | For controlling DALI Arc Levels (0 to 254) and 255 for MASK |
| DALI_COMMAND | 1 | See (https://en.wikipedia.org/wiki/Digital_Addressable_Lighting_Interface#Commands_for_control_gear) for a list of common DALI commands |
| DMX_CHANNELS_SPLIT_LOW | 2 | Sets DMX channel directly. Expects 1-based channel number (1-512) |
| DMX_CHANNELS_SPLIT_HIGH | 3 | Sets DMX channel directly. Expects 1-based channel number (1-512) |
| DMX_MULTICAST_CHANNELS_SPLIT_LOW | 4 | Sets DMX channel relative to the Zone's configured start address. Expects 0-based offset index |
| DMX_MULTICAST_CHANNELS_SPLIT_HIGH | 5 | Sets DMX channel relative to the Zone's configured start address. Expects 0-based offset index |
| DMX_BROADCAST | 6 | Affects all DMX lights as per the Spektra Settings (number of lights and channels per light) |
| DIDIO | 7 | DEPRECATED |
| FADE_UP_WITH_MIN | 8 | DALI Fade Up Command - Query level and set Minimum if Off |
| LIST_START | 9 | Start a List action once |
| LIST_START_CONTINUOUS | 10 | Start a List action with repeat |
| LIST_STOP | 11 | Stop a List |
| SPEKTRA_START_SEQ | 12 | Start a Spektra Sequence |
| SPEKTRA_STOP_SEQ | 13 | Stop a playing Spektra Sequence |
| SPEKTRA_THEME | 14 | Apply a Spektra Theme |
| SPEKTRA_STATIC | 15 | DEPRECATED |
| SPEKTRA_SCHEDULE | 16 | Start the scheduled Spektra item |
| LINK_START | 17 | Enables the UDP Link State - If Configured |
| LINK_STOP | 18 | Temporarily disables the UDP Link State |
| STOP_BURN_IN | 19 | Stop a Burn-In |
| START_BURN_IN | 20 | Start a Burn-In |
| ON_OFF_TOG | 21 | Turn a Group/Address On/Off based on queried arc level. For DALI_GROUP_ALL (broadcast), uses internal toggle state flag |
| MIN_MAX_TOG | 22 | On/Off Toggle replaced by Min/Max |
| ENABLE_INPUT | 23 | Enable Input - If latching, Input will trigger immediately based on current state |
| DISABLE_INPUT | 24 | Disable Input |
| ENABLE_TOG_INPUT | 25 | Toggle Enable/Disable Input |
| OUTPUT_TOG | 26 | Toggle Output State between High (~22Vdc) and Low (0Vdc) |
| OUTPUT_HIGH | 27 | Set Output HIGH |
| OUTPUT_LOW | 28 | Set Output LOW |
| OUTPUT_TRIG | 29 | Set Output to trigger momentarily based on configuration |
| PROFILE_CHANGE | 30 | Change Profile - This action will reset sensor state |
| FADE_LONG_PRESS | 31 | Long Press Fade based on Toggle Flag |
| SYNCRO | 32 | Command sets clock to 11:59PM. Used for hardware time update by external Timeclock |
| PRESET_CODE | 33 | Preset Code - Executes a predefined action sequence stored on the device (index 0-N based on preset_code_count) |
| CUSTOM_CODE | 34 | Project Specific Custom Code - Contact Control Freak for support |
| SPEKTRA_SLEEP | 35 | Pause Spektra sequence |
| SPEKTRA_RESUME | 36 | Resume Spektra sequence |
| DEVICE_RESET | 37 | Admin Command for Hardware Reset |
| DEVICE_SAVE | 38 | Admin Command for manual device memory save |
| USER_LEVEL_STORE_NEW | 39 | Store Current Level to Variable |
| USER_LEVEL_SET_DEFAULT | 40 | Reset User Level Variable |
| USER_LEVEL_RECALL | 41 | Recall User Level Variable |
| ROOM_JOIN | 43 | DEPRECATED |
| ROOM_UNJOIN | 44 | DEPRECATED |
| TYPE8_TC_WARMER | 45 | DALI Type 8 Warmer Command. 1 Mirek increments |
| TYPE8_TC_COOLER | 46 | DALI Type 8 Cooler Command. 1 Mirek increments |
| TYPE8_TC_ACTUAL | 47 | DALI Type 8 Set Colour to Mirek value |
| LOGIC_OPERATION | 48 | Execute a conditional logic rule (see LogicMessage) |
| ALARM_ENABLE | 49 | Enable Alarm at Index |
| ALARM_DISABLE | 50 | Disable Alarm at Index |
| DALI_CONTROL_SENSOR_OVERRIDE | 51 | Puts the DALI Sensor in 'override mode', which means it will no longer control the lighting until occupancy has timed-out or control is manually resumed |
| DALI_CONTROL_SENSOR_TEMP_DISABLE | 52 | Sets the occupancy timer to zero and puts the DALI Sensor in a temporary 'disable mode' (duration depends on Sensor configuration: 'Disable Period') |
| DALI_CONTROL_SENSOR_RESUME | 53 | Takes the DALI Sensor out of 'override mode' |
| DALI_ARC_OVERRIDE | 54 | For controlling DALI Arc Levels (0 to 254) and 255 for MASK - Sets associated group to override mode |
| DALI_COMMAND_OVERRIDE | 55 | For sending DALI commands - Sets associated group to override mode |
| FADE_UP_WITH_MIN_OVERRIDE | 56 | Non-native DALI command override (sets associated group to override mode) |
| ON_OFF_TOG_OVERRIDE | 57 | Non-native DALI command override (sets associated group to override mode) |
| MIN_MAX_TOG_OVERRIDE | 58 | Non-native DALI command override (sets associated group to override mode) |
| MAX_OFF_TOG | 59 | Reserved - Toggle between MAX level and OFF |
| MAX_OFF_TOG_OVERRIDE | 60 | Reserved - Toggle between MAX level and OFF with sensor override |
| FADE_LONG_PRESS_OVERRIDE | 61 | Non-native DALI command override (sets associated group to override mode) |
| USER_LEVEL_RECALL_OVERRIDE | 62 | Non-native DALI command override (sets associated group to override mode) |
| DMX_ZONE_FADE_UP | 63 | DMX Spektra Zone Fade UP |
| DMX_ZONE_FADE_DOWN | 64 | DMX Spektra Zone Fade DOWN |
| LOGGING_LEVEL | 65 | Enable Logging to EEPROM to be read by configurator |
| SPEKTRA_SHOW_CONTROL | 66 | DEPRECATED |
| CIRCADIAN_TEMPERATURE | 67 | Automatically adjusts DALI Type 8 colour temperature based on time of day (warmer in morning/evening, cooler midday) |
| DALI_CONTROL_SENSOR_MUTE | 68 | Mute Sensor at Index (or all with Index 255) |
| DALI_CONTROL_SENSOR_UNMUTE | 69 | Unmute to Sensor at Index (or all with Index 255) |
| SPEKTRA_INTENSITY | 70 | Allow you to specify the maximum Spektra Sequence or Theme output intensity (10 to 100)% |
| ENABLE_INPUT_NO_ACTION | 71 | Allow you to enable an input (Latching), but not trigger the action. |
| SET_DALI_FADE_TIME | 72 | Sets the DALI Fade Time |
| NO_COMMAND | 254 | This TriggerType should always be at the bottom of the list. Add any new TriggerTypes above it (up to 253). |
Whether an alarm repeats. Which days it runs on comes from repeat_day_bitmask and repeat_month_bitmask.
| Name | Number | Description |
| ALARM_NO_REPEAT | 0 | Once, on the date in start_time |
| ALARM_REPEAT_DAILY | 1 | Repeats - on the weekdays in repeat_day_bitmask and months in repeat_month_bitmask (set all days) |
| ALARM_REPEAT_WORK_DAY | 2 | Repeats - on the weekdays in repeat_day_bitmask (set Monday to Friday) |
| ALARM_REPEAT_WEEKLY | 3 | Repeats - on the weekday(s) in repeat_day_bitmask |
| ALARM_REPEAT_MONTHLY | 4 | Repeats - in the months in repeat_month_bitmask. The firmware treats every type but NO_REPEAT alike: the bitmasks decide |
Whether an alarm's start or end is a clock time, or sunrise / sunset with the time as an offset.
| Name | Number | Description |
| ALARM_NO_ASTRO | 0 | At the clock time given |
| ALARM_SUNRISE | 1 | At sunrise (from LATITUDE / LONGITUDE), moved by the time given as an offset |
| ALARM_SUNSET | 2 | At sunset, moved by the time given as an offset |
How a logic rule compares its variable with comparison_value. It runs trigger A when the comparison holds, else trigger B.
| Name | Number | Description |
| LESS_THAN | 0 | A runs if the variable < comparison_value, else B |
| LESS_THAN_OR_EQUALS | 1 | A runs if the variable <= comparison_value, else B |
| EQUALS | 2 | A runs if the variable == comparison_value, else B |
| MORE_THAN | 3 | A runs if the variable > comparison_value, else B |
| MORE_THAN_OR_EQUALS | 4 | A runs if the variable >= comparison_value, else B |
| NOT_EQUAL | 5 | A runs if the variable != comparison_value, else B |
| BIT_OR | 6 | A runs if (variable | comparison_value) is non-zero, else B |
| BIT_AND | 7 | A runs if (variable & comparison_value) is non-zero - any of the masked bits set - else B |
| BIT_XOR | 8 | A runs if (variable ^ comparison_value) is non-zero - they differ - else B |
Trigger Message Structure. Stores all information for Trigger Type Actions
| Field | Type | Label | Description |
| type | TriggerType | The type of Trigger |
|
| zone | uint32 | Which Zone (Spektra) |
|
| line_mask | uint32 | Which Line(s) to perform this trigger on (if applicable) |
|
| target_index | uint32 | Index to target (context depends on TriggerType) |
|
| value | uint32 | Value for this trigger (if applicable) |
|
| query_index | uint32 | Index to query (if applicable) |
Date/Time Message Structure. Year is 0-99. Month is 1 (Jan) - 12 (Dec), Date is day of the month, Day is Weekday with 1 (Monday) - 7 (Sunday)
| Field | Type | Label | Description |
| date | uint32 | Year | Month | Date | Day |
|
| time | uint32 | <Empty> | Hour | Minute | Second |
Message to describe the two Burn-In objects
| Field | Type | Label | Description |
| light_state | uint32 | Tracks when a Light is 'On' and "burning in" |
|
| running_flag | uint32 | Whether or not the burn-in is currently counting down |
|
| enable_flag | uint32 | Whether or not the burn-in should count down |
Message to describe the 12 or 24 Physical Inputs. Not sent natively, see InputMultiMessage
| Field | Type | Label | Description |
| index | uint32 | Which Input is this (0 - 11) on 4 Pole and (0 - 23) on 9 Pole |
|
| button_state | TriggerOperationType | How will this Input be triggered? Momentary (short/long press) or Latching (low/high) |
|
| short_press | TriggerMessage | What action should occur on short/low |
|
| long_press | TriggerMessage | What action should occur on long/high |
Message to describe the 4 or 8 Physical Outputs. Not sent natively, see OutputMultiMessage
| Field | Type | Label | Description |
| index | uint32 | Which Output is this? (0 - 3) on 4 Pole and (0 - 7) on 9 Pole. Note: Actual Pin numbers are (9 - 12) and (21 - 24) respectively. |
|
| initial_level | uint32 | Will the Output be Low or High at startup? |
|
| time_trigger_is_active | uint32 | How long should a 'Trigger Output' command last? |
|
| type | TriggerOperationType | Is this a continuous (latching) trigger or momentary output? |
Message to describe the (Up to) 40 DALI 2 Input Devices. Not sent natively, see DALIInputMultiMessage
| Field | Type | Label | Description |
| index | uint32 | Which index for this Input |
|
| address | uint32 | The eDALI Address of this Input |
|
| dali_line | uint32 | The DALI Line this Input is on |
|
| button_state | TriggerOperationType | How will this Input be triggered? Momentary (short/long press) or Latching (low/high) |
|
| short_press | TriggerMessage | What action should occur on short/low |
|
| long_press | TriggerMessage | What action should occur on long/high |
|
| instance | uint32 | What instance of the device? If it has multiple inputs |
Message to describe the Infrared Input (DEPRECATED)
| Field | Type | Label | Description |
| index | uint32 | IR slot, 0-based |
|
| action | TriggerMessage | The trigger the code fires |
|
| codes | uint32 | The IR code to match |
Message to describe the (Up to) 40 DALI 2 Sensors. Not sent natively, see SensorMultiMessage
| Field | Type | Label | Description |
| profile | uint32 | Under which Profile is this Sensor active? |
|
| index | uint32 | The index for this Sensor |
|
| sensor_address | uint32 | The eDALI Address of this Sensor (assumes address of "L" (Light) component with "M" (Motion) at L + 1) |
|
| sensor_dali_line | uint32 | The DALI Line this Sensor is on |
|
| address_query | uint32 | The DALI Address to query for Group-based control |
|
| control_dali_line | uint32 | The DALI Line (mask) to control |
|
| control_group | uint32 | The DALI Group Address to control |
|
| light_setpoint | uint32 | The Lux level to maintain during Daylight Harvesting |
|
| warning_setpoint | uint32 | DEPRECATED (superseded by warning_trigger) - The Arc level to set during the Warning Period |
|
| motion_only | uint32 | Is this Sensor used for motion detection only? If False, Daylight Harvesting will be in effect |
|
| timeout_values | uint32 | Occupancy hold time in MINUTES (firmware multiplies by 60 internally) - duration after last motion detection before entering Warning Period |
|
| warning_values | uint32 | Warning period duration in seconds - time spent in dimmed state before transitioning to Idle/Off |
|
| disable_values | uint32 | Deadtime period in seconds - delay after timeout before the Sensor resumes motion detection |
|
| input_1_pm | uint32 | DEPRECATED - The first Input button used for Two-Button Programming |
|
| input_2_pm | uint32 | DEPRECATED - The second Input button used for Two-Button Programming |
|
| sensor_states | uint32 | DEPRECATED (firmware-internal, not configuration) - Used to keep track of the Motion Sensor state |
|
| motion_sensors | uint32 | DEPRECATED since FW 1.3.0 (Phase 3): legacy 32-bit grouping bitmask. New firmware REJECTS a non-zero value here with INVALID_PARAMS - re-push from an updated SpektraPlus. See coop_group/coop_leader. |
|
| lux_sensors | uint32 | DEPRECATED (firmware-internal, not configuration) - Used to keep track of the Light (Lux) Sensor state |
|
| off_flag | uint32 | DEPRECATED (firmware-internal, not configuration) - Used to keep track of the Control Group's state |
|
| is_programmed | bool | Set to 'True' when the Firmware receives a SensorMessage with this Index |
|
| detection_trigger | TriggerMessage | The action to perform upon initial detection |
|
| warning_trigger | TriggerMessage | The action to perform upon transitioning to the Warning Period |
|
| idle_trigger | TriggerMessage | The action to perform upon transitioning to the Idle (disable) Period |
|
| coop_group | uint32 | Cooperative directional group ID (1..0x7FFFFFFF; 0 = standalone). Replaces motion_sensors. Members of the same non-zero group cooperate; Leader members propagate occupancy & share lux. |
|
| coop_leader | uint32 | 1 = Leader member (its motion keeps the group on; shares the daylight-harvest mean with other Leader members). 0 = Follower (kept on by Leader members; fires its own triggers; harvests its own zone). |
Message to Query running sensor data
| Field | Type | Label | Description |
| timer | uint32 | Time Remaining in seconds |
|
| light_state | uint32 | Light Group State |
|
| motion_sensor_state | uint32 | Motion Sensor State |
|
| lux_sensor_state | uint32 | Lux Sensor State |
|
| last_lux | uint32 | Last reported lux (sensor device-relative units, not absolute lux) |
|
| last_commanded_arc | uint32 | Last DALI arc level (0-254) commanded by daylight harvesting |
|
| is_group_master | bool | TRUE when this sensor is the active controller of its cooperative harvesting group |
|
| control_group | uint32 | Effective control target: group/address the sensor maintains |
|
| control_dali_line | uint32 | Effective control target: DALI line mask the sensor controls |
|
| lux_seeded | bool | FALSE while the harvest loop is awaiting its first real 304 reading after occupancy (last_lux / last_commanded_arc are still the previous occupancy's values until TRUE) |
|
| light_setpoint | uint32 | The DEVICE-resident daylight-harvest setpoint the loop actually regulates against (active profile). Lets the app draw the set-point line from the device, not its own config, so a device/app divergence is visible. |
|
| group_mean_lux | uint32 | The blended lux the harvest master regulates on (mean of active Leader members of this sensor's cooperative group). Equals last_lux for a standalone/Follower sensor. |
The sensors' live state, a page of up to 20 at a time: send offset, read sensors and total_count, then ask for the next page.
| Field | Type | Label | Description |
| sensors | SensorQuery | repeated | A page of up to 20 SensorQuery entries starting at 'offset' (device holds 40; see nanopb max_count) |
| offset | uint32 | Request: absolute index of the first sensor to return (0-based; 0 = first page). Response: echoes the offset of this page so the client can place the entries at absolute slots. |
|
| total_count | uint32 | Response only: total number of sensors on the device. Lets the client page until offset + sensors.length >= total_count. Omitted (0) on older firmware, which returns every sensor in one page. |
List Step Structure for List Actions
| Field | Type | Label | Description |
| step_index | uint32 | Index of Step in List |
|
| action | TriggerMessage | Action to perform |
|
| time_seconds | uint32 | Time in seconds between steps, uint16_t value |
Message to describe Scheduled Actions. Not sent natively, see AlarmMultiMessage
| Field | Type | Label | Description |
| index | uint32 | Alarm Index from 0 - 9 |
|
| enabled | bool | Enabled Flag - FALSE (0) or TRUE (1) |
|
| start_time | TimeClockMessage | Time to Start Action, or Astro Offset |
|
| end_time | TimeClockMessage | Time to Stop Action, or Astro Offset |
|
| start_trigger | TriggerMessage | Trigger Action to perform at start time |
|
| end_trigger | TriggerMessage | Trigger Action to perform at end time |
|
| astro_start | AlarmAstroType | Start Time Type |
|
| astro_end | AlarmAstroType | End Time Type |
|
| repeat | AlarmRepeatType | Alarm Repeat Type |
|
| repeat_day_bitmask | uint32 | 1 to trigger on this day. LSB (0) = Monday, MSB (6) = Sunday |
|
| repeat_month_bitmask | uint32 | 1 to trigger during this month. LSB (0) = January, MSB (11) = December |
|
| yearly | bool | Should this Alarm happen each year? |
|
| start_offset_is_before | bool | E.g. 10 minutes BEFORE or AFTER the start astro event? |
|
| end_offset_is_before | bool | E.g. 10 minutes BEFORE or AFTER the end astro event? |
Message to describe the two Burn-In Actions. While Burn-In is active, the system will check associated DALI line and group and prevent any action other than 100% or 0%. Any value set over 1% will be forced to 100%. Not sent natively, see BurnInMultiMessage
| Field | Type | Label | Description |
| index | uint32 | Burn-in, 0-based |
|
| line | uint32 | DALI line mask the burn-in drives |
|
| address | uint32 | DALI address held at full while burning in (RECALL MAX LEVEL) |
|
| query_address | uint32 | DALI address queried to see whether the lights are on (the timer only runs while they are) |
|
| time | uint32 | Burn-in duration, minutes. Setting it restarts the countdown |
|
| remaining | uint32 | Minutes left (read only) |
|
| states | BurnInBitsMessage | Its live state |
This message will allow an externally connected device to send a Trigger action
| Field | Type | Label | Description |
| trigger | TriggerMessage | Can be used to action Triggers via the network instead of via a hardware input or on-board alarm |
Message used to send all Physical Inputs, for a specific profile
| Field | Type | Label | Description |
| profile | uint32 | The profile these inputs belong to, 0-based |
|
| inputs | IOInputMessage | repeated | Every physical input, in index order |
Message used to send all Outputs, for a specific profile
| Field | Type | Label | Description |
| profile | uint32 | The profile these outputs belong to, 0-based |
|
| outputs | IOOutputMessage | repeated | Every output, in index order |
Message used to send all DALI Inputs, for a specific profile
| Field | Type | Label | Description |
| profile | uint32 | The profile these DALI inputs belong to, 0-based |
|
| input_index_offset | uint32 | To support paginated results (0-9, 10-19, 20-29, 30-39) |
|
| inputs | DALIInputMessage | repeated | Every DALI input, in index order |
DEPRECATED
| Field | Type | Label | Description |
| profile | uint32 | The profile these IR codes belong to, 0-based |
|
| irs | IOIRMessage | repeated | Every IR slot, in index order |
Message used to send a List. If more than 32 steps in the list, the ExtendedListMessage is used repeatedly to send the remainder.
| Field | Type | Label | Description |
| list_index | uint32 | Which list, 0-based |
|
| step | ListStepMessage | repeated | Limited to 32 for this Message Type; you must use ExtendedListMessage to configure more than 32 steps per List |
| list_state | uint32 | Typically will be 'DISABLED' to start with (requires a 'START LIST' trigger to begin) |
|
| total_step_count | uint32 | Can be greater than 32, but you must use ExtendedListMessage to send the rest |
This Message must be used when the List has more than 32 steps
| Field | Type | Label | Description |
| list_index | uint32 | Which List do these steps belong to? |
|
| step_index_offset | uint32 | 0 for the first ExtendedListMessage; offset by 32 for every ExtendedListMessage beyond the first |
|
| step | ListStepMessage | repeated | Up to 32 steps, from step_index_offset |
Message used to send the Alarms
| Field | Type | Label | Description |
| alarm | AlarmMessage | repeated | Every alarm, in index order |
Message used to send the Burn-Ins
| Field | Type | Label | Description |
| burnin | BurnInMessage | repeated | Every burn-in, in index order |
Defines a conditional logic rule that evaluates a condition and executes an action based on the result
| Field | Type | Label | Description |
| index | uint32 | Index of this logic rule (0 to logic_count-1) |
|
| enabled | bool | Whether this logic rule is active |
|
| comparison_object | TriggerMessage | The source value to evaluate (e.g., DALI level, input state) |
|
| comparison_value | uint32 | The threshold/setpoint value to compare against |
|
| comparison_type | LogicComparisonType | How to compare: equals, less than, greater than, etc. |
|
| actionA | TriggerMessage | Action to execute if comparison evaluates to TRUE |
|
| actionB | TriggerMessage | Action to execute if comparison evaluates to FALSE |
Container for multiple logic rules (used when reading/writing all logic rules at once)
| Field | Type | Label | Description |
| logic | LogicMessage | repeated | Array of logic rules (max logic_count entries) |
What a read_device request reads. Each value says which EdidioMessage payload comes back. Also used to say where an event came from.
| Name | Number | Description |
| INPUTS | 0 | The physical inputs of one profile (profile). Reply: inputs. |
| OUTPUTS | 1 | The outputs of one profile (profile). Reply: outputs. |
| IR | 2 | The IR codes of one profile (profile; deprecated). Reply: irs. |
| SENSOR | 3 | One sensor (index) of one profile (profile). Reply: sensor. |
| LIST | 5 | One list (index): its first 32 steps. Reply: list. |
| ALARMS | 7 | Every alarm. Reply: alarms. |
| BURN_IN | 8 | Every burn-in. Reply: burn_ins. |
| PROJECT | 9 | Not supported - use AdminMessage SYSTEM_PROPERTIES. Reply: AckMessage (INDEX_OUT_OF_BOUNDS). |
| NETWORK | 10 | Not supported - use AdminMessage NETWORK_PROPERTIES. Reply: AckMessage (INDEX_OUT_OF_BOUNDS). |
| DEVICE | 11 | Not supported - use diag_message DIAGNOSTIC_SYSTEM_INFO. Reply: AckMessage (INDEX_OUT_OF_BOUNDS). |
| POLL_DATA | 12 | Not supported - use diag_message DALI_LEVEL_CACHE. Reply: AckMessage (INDEX_OUT_OF_BOUNDS). |
| LIST_EXTENDED | 13 | Steps beyond the first 32 of one list (index), from block secondary_index. Reply: list_extended. |
| LOGIC | 14 | Every logic rule. Reply: logic_message. |
| DALI_INPUTS | 15 | The DALI inputs of one profile (profile). Reply: inputs_dali. |
| DMX_TRANSLATIONS | 16 | Every DMX to DALI translation object. Reply: dmx_translator. |
What a SensorCommandMessage does.
| Name | Number | Description |
| INITIALISE | 0 | Applies default settings to all Sensors (broadcast) and resets their detection state |
| MUTE | 1 | Stops a Sensor from sending DALI packets |
| UNMUTE | 2 | Allows a Sensor to send DALI packets |
| OVERRIDE | 3 | Puts a Sensor in 'Override Mode' which prevents it from adjusting the Light Level (until after the occupancy timeout occurs) |
| IDENTIFY | 4 | Starts the 'Identify' behaviour of a Sensor (typically this involves rapid flashing of the status LED for several seconds) |
Message used to send specific sensor commands, such as Mute, Unmute and Override. Mute will stop the sensor from talking until; Unmute, Profile Change, or Program. Override will prevent the sensor from changing the currently selected level until it has timed-out
| Field | Type | Label | Description |
| command | uint32 | DEPRECATED: Use 'type' instead |
|
| index | uint32 | Which sensor, 0-based (INITIALISE ignores it: it is broadcast) |
|
| type | SensorCommandType | What to do |
Message used to change Profiles. Note that changing the profile will cause the sensors to reset
| Field | Type | Label | Description |
| profile | uint32 | The profile to make active, 0-based |
Message used to show information on screen to aid with physical identification
| Field | Type | Label | Description |
| MAC | uint64 | Not used: the device shows its own name, IP and MAC |
|
| IP | uint64 | Not used: the device shows its own name, IP and MAC |
Message to update the device time. Message will be affected by Day Light Savings (If selected) and will refresh currently selected schedules
| Field | Type | Label | Description |
| time | TimeClockMessage | The new date and time (local time) |
Message used to request device information, such as inputs, lists, sensors, etc
| Field | Type | Label | Description |
| profile | uint32 | Profile to read, for INPUTS, DALI_INPUTS, OUTPUTS, IR and SENSOR |
|
| type | ReadType | What to read - each ReadType says which payload comes back |
|
| index | uint32 | Which item, for SENSOR, LIST and LIST_EXTENDED |
|
| secondary_index | uint32 | For LIST_EXTENDED: which block of steps after the first 32 |
Message used to send a secure login settings message. AES Encryption Required
| Field | Type | Label | Description |
| payload | string | Encrypted payload of a PB message. |
Standard DALI Type 8 Commands - See DALI Standard
| Name | Number | Description |
| SET_TEMP_X_COORD | 0 | IEC 62386-209 command 224: SET TEMPORARY X-COORDINATE (DTR1:DTR0) |
| SET_TEMP_Y_COORD | 1 | IEC 62386-209 command 225: SET TEMPORARY Y-COORDINATE (DTR1:DTR0) |
| ACTIVATE | 2 | IEC 62386-209 command 226: ACTIVATE - apply the temporary colour |
| X_COORD_STEP_UP | 3 | Activate Not Required |
| X_COORD_STEP_DOWN | 4 | Activate Not Required |
| Y_COORD_STEP_UP | 5 | Activate Not Required |
| Y_COORD_STEP_DOWN | 6 | Activate Not Required |
| SET_TEMP_COLOUR_TEMPERATURE | 7 | DTR1 | DTR as Mirek Value |
| COLOUR_TEMPERATURE_STEP_COOLER | 8 | Activate Not Required |
| COLOUR_TEMPERATURE_STEP_WARMER | 9 | Activate Not Required |
| SET_TEMP_PRI_N_DIMLEVEL | 10 | IEC 62386-209 command 234: SET TEMPORARY PRIMARY N DIMLEVEL (DTR1:DTR0, primary N in DTR2) |
| SET_TEMP_RGB_DIMLEVEL | 11 | IEC 62386-209 command 235: SET TEMPORARY RGB DIMLEVEL (DTR0, DTR1, DTR2) |
| SET_TEMP_WAF_DIMLEVEL | 12 | IEC 62386-209 command 236: SET TEMPORARY WAF DIMLEVEL (DTR0, DTR1, DTR2) |
| SET_TEMP_RGBWAF_CONTROL | 13 | IEC 62386-209 command 237: SET TEMPORARY RGBWAF CONTROL (DTR0) |
| COPY_REPORT_TEMPORARY | 14 | IEC 62386-209 command 238: COPY REPORT TO TEMPORARY |
| STORE_TY_PRI_N | 16 | IEC 62386-209 command 240: STORE TY PRIMARY N (DTR1:DTR0, N in DTR2) |
| STORE_XY_COORD_PRI_N | 17 | IEC 62386-209 command 241: STORE XY-COORDINATE PRIMARY N (N in DTR2) |
| STORE_COLOUR_TEMPERATURE_LIMIT | 18 | IEC 62386-209 command 242: STORE COLOUR TEMPERATURE TC LIMIT (DTR1:DTR0, which limit in DTR2) |
| STORE_GEAR_FEATURES_STATUS | 19 | IEC 62386-209 command 243: STORE GEAR FEATURES / STATUS (DTR0) |
| ASSIGN_COLOR_LINKED_CH | 21 | IEC 62386-209 command 245: ASSIGN COLOUR TO LINKED CHANNEL (DTR0) |
| START_AUTO_CAL | 22 | IEC 62386-209 command 246: START AUTO CALIBRATION |
| ENABLE_DEVICE_TYPE8 | 48 | ENABLE DEVICE TYPE 8 (special command C1 08) - sent before each DT8 command |
| SET_XY_COORDINATE | 50 | Manufacturer Specific combined XY command |
Standard DALI Type 8 Queries - See DALI Standard
| Name | Number | Description |
| TYPE8_QUERY_NULL | 0 | Required as the first "default" element for the Protocol. Will not perform any action. |
| TYPE8_QUERY_GEAR_FEATURES_STATUS | 1 | 247 |
| TYPE8_QUERY_COLOUR_STATUS | 2 | 248 |
| TYPE8_QUERY_COLOUR_TYPE_FEATURES | 3 | 249 |
| TYPE8_QUERY_COLOUR_VALUE | 4 | 250 |
| TYPE8_QUERY_RGBWAF_CONTROL | 5 | 251 |
| TYPE8_QUERY_ASSIGNED_COLOUR | 6 | 252 |
| TYPE8_QUERY_EXT_VERSION_NUM | 8 | 254 |
Standard DALI 24 Bit Commands - See DALI Standard
| Name | Number | Description |
| COMMAND_IDENTIFY | 0 | IEC 62386-103 opcode 0x00: IDENTIFY DEVICE |
| COMMAND_RESET_POWER_CYCLE_SEEN | 1 | IEC 62386-103 opcode 0x01: RESET POWER CYCLE SEEN |
| COMMAND_RESET | 16 | IEC 62386-103 opcode 0x10: RESET |
| COMMAND_RESET_MEMORY_BANK | 17 | IEC 62386-103 opcode 0x11: RESET MEMORY BANK (DTR0) |
| COMMAND_SET_SHORT_ADDRESS | 20 | IEC 62386-103 opcode 0x14: SET SHORT ADDRESS (DTR0) |
| COMMAND_ENABLE_WRITE_MEMORY | 21 | IEC 62386-103 opcode 0x15: ENABLE WRITE MEMORY |
| COMMAND_ENABLE_APP_CONTROLLER | 22 | IEC 62386-103 opcode 0x16: ENABLE APPLICATION CONTROLLER |
| COMMAND_DISABLE_APP_CONTROLLER | 23 | IEC 62386-103 opcode 0x17: DISABLE APPLICATION CONTROLLER |
| COMMAND_SET_OPERATING_MODE | 24 | IEC 62386-103 opcode 0x18: SET OPERATING MODE (DTR0) |
| COMMAND_ADD_TO_DEVICE_GROUPS_0_15 | 25 | IEC 62386-103 opcode 0x19: ADD TO DEVICE GROUPS 0-15 (DTR2:DTR1) |
| COMMAND_ADD_TO_DEVICE_GROUPS_15_32 | 26 | IEC 62386-103 opcode 0x1A: ADD TO DEVICE GROUPS 16-31 (DTR2:DTR1) |
| COMMAND_REMOVE_FROM_GROUPS_0_15 | 27 | IEC 62386-103 opcode 0x1B: REMOVE FROM DEVICE GROUPS 0-15 (DTR2:DTR1) |
| COMMAND_REMOVE_FROM_GROUPS_16_32 | 28 | IEC 62386-103 opcode 0x1C: REMOVE FROM DEVICE GROUPS 16-31 (DTR2:DTR1) |
| COMMAND_START_QUIESCENT_MODE | 29 | IEC 62386-103 opcode 0x1D: START QUIESCENT MODE |
| COMMAND_STOP_QUIESCENT_MODE | 30 | IEC 62386-103 opcode 0x1E: STOP QUIESCENT MODE |
| COMMAND_ENABLE_POWER_CYCLE_NOTIF | 31 | IEC 62386-103 opcode 0x1F: ENABLE POWER CYCLE NOTIFICATION |
| COMMAND_DISABLE_POWER_CYCLE_NOTIF | 32 | IEC 62386-103 opcode 0x20: DISABLE POWER CYCLE NOTIFICATION |
| COMMAND_SAVE_PERSISTENT_VARIABLES | 33 | IEC 62386-103 opcode 0x21: SAVE PERSISTENT VARIABLES |
| SET_EVENT_PRIORITY | 97 | IEC 62386-103 opcode 0x61: instance command SET EVENT PRIORITY (DTR0) |
| ENABLE_INSTANCE | 98 | IEC 62386-103 opcode 0x62: instance command ENABLE INSTANCE |
| DISABLE_INSTANCE | 99 | IEC 62386-103 opcode 0x63: instance command DISABLE INSTANCE |
| SET_PRIMARY_INSTANCE_GROUP | 100 | IEC 62386-103 opcode 0x64: instance command SET PRIMARY INSTANCE GROUP (DTR0) |
| SET_INSTANCE_GROUP_1 | 101 | IEC 62386-103 opcode 0x65: instance command SET INSTANCE GROUP 1 (DTR0) |
| SET_INSTANCE_GROUP_2 | 102 | IEC 62386-103 opcode 0x66: instance command SET INSTANCE GROUP 2 (DTR0) |
| SET_EVENT_SCHEME | 103 | IEC 62386-103 opcode 0x67: instance command SET EVENT SCHEME (DTR0) |
| SET_EVENT_FILTER | 104 | IEC 62386-103 opcode 0x68: instance command SET EVENT FILTER (DTR2:DTR1:DTR0) |
Standard DALI 24 Bit Instance Types - See DALI Standard
| Name | Number | Description |
| DEFAULT | 0 | Not an instance type: no instance selected |
| INPUT | 1 | IEC 62386-301 push button |
| ROTARY_INPUT | 2 | IEC 62386-302 absolute input (slider, rotary, switch) |
| MOTION_SENSOR | 3 | IEC 62386-303 occupancy sensor |
| LIGHT_SENSOR | 4 | IEC 62386-304 light sensor |
Standard DALI 24 Bit Device Op Codes - See DALI Standard
| Name | Number | Description |
| OPCODE_NULL | 0 | No Action |
| SENSOR_MOTION_SET_HOLD_TIMER | 33 | Motion Sensor |
| SENSOR_MOTION_SET_REPORT_TIMER | 34 | IEC 62386-303 SET REPORT TIMER (DTR0) |
| SENSOR_MOTION_SET_DEADTIME_TIMER | 35 | IEC 62386-303 SET DEADTIME TIMER (DTR0) |
| SENSOR_MOTION_CANCEL_HOLD_TIMER | 36 | IEC 62386-303 CANCEL HOLD TIMER |
| SENSOR_LIGHT_SET_REPORT_TIMER | 48 | Light Sensor |
| SENSOR_LIGHT_SET_HYSTERESIS | 49 | IEC 62386-304 SET HYSTERESIS (DTR0) |
| SENSOR_LIGHT_SET_DEADTIME_TIMER | 50 | IEC 62386-304 SET DEADTIME TIMER (DTR0) |
| SENSOR_LIGHT_SET_HYSTERESIS_MIN | 51 | IEC 62386-304 SET HYSTERESIS MIN (DTR0) |
Standard DALI Queries - See DALI Standard
| Name | Number | Description |
| DALI_QUERY_NULL | 0 | Required as the first "default" element for the Protocol. Will not perform any action. |
| DALI_QUERY_STATUS | 144 | IEC 62386-102 command 144: QUERY STATUS (see DALIStatusType) |
| DALI_QUERY_BALLAST | 145 | IEC 62386-102 command 145: QUERY CONTROL GEAR PRESENT |
| DALI_QUERY_LAMP_FAILURE | 146 | IEC 62386-102 command 146: QUERY LAMP FAILURE |
| DALI_QUERY_LAMP_POWER_ON | 147 | IEC 62386-102 command 147: QUERY LAMP POWER ON |
| DALI_QUERY_LIMIT_ERROR | 148 | IEC 62386-102 command 148: QUERY LIMIT ERROR |
| DALI_QUERY_RESET_STATE | 149 | IEC 62386-102 command 149: QUERY RESET STATE |
| DALI_QUERY_MISSING_SHORT_ADDRESS | 150 | IEC 62386-102 command 150: QUERY MISSING SHORT ADDRESS |
| DALI_QUERY_VERSION_NUMBER | 151 | IEC 62386-102 command 151: QUERY VERSION NUMBER |
| DALI_QUERY_DTR0 | 152 | IEC 62386-102 command 152: QUERY CONTENT DTR0 |
| DALI_QUERY_DEVICE_TYPE | 153 | IEC 62386-102 command 153: QUERY DEVICE TYPE |
| DALI_QUERY_PHYSICAL_MIN | 154 | IEC 62386-102 command 154: QUERY PHYSICAL MINIMUM |
| DALI_QUERY_POWER_FAILURE | 155 | IEC 62386-102 command 155: QUERY POWER FAILURE |
| DALI_QUERY_DTR1 | 156 | IEC 62386-102 command 156: QUERY CONTENT DTR1 |
| DALI_QUERY_DTR2 | 157 | IEC 62386-102 command 157: QUERY CONTENT DTR2 |
| DALI_QUERY_OPERATING_MODE | 158 | IEC 62386-102 command 158: QUERY OPERATING MODE |
| DALI_QUERY_LIGHTSOURCE_TYPE | 159 | IEC 62386-102 command 159: QUERY LIGHT SOURCE TYPE |
| DALI_QUERY_ACTUAL_LEVEL | 160 | IEC 62386-102 command 160: QUERY ACTUAL LEVEL |
| DALI_QUERY_MAX_LEVEL | 161 | IEC 62386-102 command 161: QUERY MAX LEVEL |
| DALI_QUERY_MIN_LEVEL | 162 | IEC 62386-102 command 162: QUERY MIN LEVEL |
| DALI_QUERY_POWER_ON_LEVEL | 163 | IEC 62386-102 command 163: QUERY POWER ON LEVEL |
| DALI_QUERY_SYSTEM_FAILURE_LEVEL | 164 | IEC 62386-102 command 164: QUERY SYSTEM FAILURE LEVEL |
| DALI_QUERY_FADETIME_FADERATE | 165 | IEC 62386-102 command 165: QUERY FADE TIME / FADE RATE |
| DALI_QUERY_MANUFACTURER_SPECIFIC_MODE | 166 | IEC 62386-102 command 166: QUERY MANUFACTURER SPECIFIC MODE |
| DALI_QUERY_NEXT_DEVICE_TYPE | 167 | IEC 62386-102 command 167: QUERY NEXT DEVICE TYPE |
| DALI_QUERY_EXTENDED_FADE_TIME | 168 | IEC 62386-102 command 168: QUERY EXTENDED FADE TIME |
| DALI_QUERY_CONTROL_GEAR_FAILURE | 170 | IEC 62386-102 command 170: QUERY CONTROL GEAR FAILURE |
| DALI_QUERY_SCENE_X_LEVEL | 176 | IEC 62386-102 command 176: QUERY SCENE LEVEL 0 (add the scene number for scenes 1-15) |
| DALI_QUERY_GROUPS_0_7 | 192 | IEC 62386-102 command 192: QUERY GROUPS 0-7 |
| DALI_QUERY_GROUPS_8_15 | 193 | IEC 62386-102 command 193: QUERY GROUPS 8-15 |
| DALI_QUERY_RANDOM_ADDRESS_H | 194 | IEC 62386-102 command 194: QUERY RANDOM ADDRESS (H) |
| DALI_QUERY_RANDOM_ADDRESS_M | 195 | IEC 62386-102 command 195: QUERY RANDOM ADDRESS (M) |
| DALI_QUERY_RANDOM_ADDRESS_L | 196 | IEC 62386-102 command 196: QUERY RANDOM ADDRESS (L) |
| DALI_QUERY_READ_DTR_0_1 | 197 | IEC 62386-102 command 197: READ MEMORY LOCATION (DTR1 bank, DTR0 location) |
| DALI_QUERY_APP_EXT_COMMANDS | 224 | IEC 62386-102 command 224: the first application extended command (device-type specific; DT8 queries are DALIMessage.type8_reply) |
| DALI_QUERY_EXT_VERSION_NUMBER | 255 | IEC 62386-102 command 255: QUERY EXTENDED VERSION NUMBER (of the device type selected with ENABLE DEVICE TYPE). An ordinary query, not a special command |
| DALI_QUERY_COMPARE | 260 | IEC 62386-102 special command COMPARE (frame A9 00). The device sends it as that frame, with arg as the data byte (eDIDIO 1.6.3, ADDICT 3.9.3). Earlier firmware sent only the value's low byte - for those, send the frame with frame_16_bit_reply. |
| DALI_QUERY_VERIFY_SHORT_ADDRESS | 268 | IEC 62386-102 special command VERIFY SHORT ADDRESS (frame B9 xx). The device sends it as that frame, with arg as the data byte (eDIDIO 1.6.3, ADDICT 3.9.3). Earlier firmware sent only the value's low byte - for those, send the frame with frame_16_bit_reply. |
| DALI_QUERY_SHORT_ADDRESS | 269 | IEC 62386-102 special command QUERY SHORT ADDRESS (frame BB 00). The device sends it as that frame, with arg as the data byte (eDIDIO 1.6.3, ADDICT 3.9.3). Earlier firmware sent only the value's low byte - for those, send the frame with frame_16_bit_reply. |
Standard DALI Commands - See DALI Standard
| Name | Number | Description |
| DALI_OFF | 0 | IEC 62386-102 command 0: OFF |
| DALI_FADE_UP | 1 | IEC 62386-102 command 1: UP - fade up for 200 ms at the fade rate |
| DALI_FADE_DOWN | 2 | IEC 62386-102 command 2: DOWN - fade down for 200 ms at the fade rate |
| DALI_STEP_UP | 3 | IEC 62386-102 command 3: STEP UP |
| DALI_STEP_DOWN | 4 | IEC 62386-102 command 4: STEP DOWN |
| DALI_MAX_LEVEL | 5 | IEC 62386-102 command 5: RECALL MAX LEVEL |
| DALI_MIN_LEVEL | 6 | IEC 62386-102 command 6: RECALL MIN LEVEL |
| DALI_STEP_DOWN_OFF | 7 | IEC 62386-102 command 7: STEP DOWN AND OFF |
| DALI_ON_STEP_UP | 8 | IEC 62386-102 command 8: ON AND STEP UP |
| DALI_ENABLE_DAPC_SEQ | 9 | IEC 62386-102 command 9: ENABLE DAPC SEQUENCE |
| DALI_RECALL_LAST_ACTIVE_LEVEL | 10 | IEC 62386-102 command 10: GO TO LAST ACTIVE LEVEL |
| DALI_CONTINUOUS_UP | 11 | IEC 62386-102 command 11: CONTINUOUS UP |
| DALI_CONTINUOUS_DOWN | 12 | IEC 62386-102 command 12: CONTINUOUS DOWN |
| DALI_RECALL_SCENE_0 | 16 | IEC 62386-102 command 16: GO TO SCENE 0 |
| DALI_RECALL_SCENE_1 | 17 | IEC 62386-102 command 17: GO TO SCENE 1 |
| DALI_RECALL_SCENE_2 | 18 | IEC 62386-102 command 18: GO TO SCENE 2 |
| DALI_RECALL_SCENE_3 | 19 | IEC 62386-102 command 19: GO TO SCENE 3 |
| DALI_RECALL_SCENE_4 | 20 | IEC 62386-102 command 20: GO TO SCENE 4 |
| DALI_RECALL_SCENE_5 | 21 | IEC 62386-102 command 21: GO TO SCENE 5 |
| DALI_RECALL_SCENE_6 | 22 | IEC 62386-102 command 22: GO TO SCENE 6 |
| DALI_RECALL_SCENE_7 | 23 | IEC 62386-102 command 23: GO TO SCENE 7 |
| DALI_RECALL_SCENE_8 | 24 | IEC 62386-102 command 24: GO TO SCENE 8 |
| DALI_RECALL_SCENE_9 | 25 | IEC 62386-102 command 25: GO TO SCENE 9 |
| DALI_RECALL_SCENE_10 | 26 | IEC 62386-102 command 26: GO TO SCENE 10 |
| DALI_RECALL_SCENE_11 | 27 | IEC 62386-102 command 27: GO TO SCENE 11 |
| DALI_RECALL_SCENE_12 | 28 | IEC 62386-102 command 28: GO TO SCENE 12 |
| DALI_RECALL_SCENE_13 | 29 | IEC 62386-102 command 29: GO TO SCENE 13 |
| DALI_RECALL_SCENE_14 | 30 | IEC 62386-102 command 30: GO TO SCENE 14 |
| DALI_RECALL_SCENE_15 | 31 | IEC 62386-102 command 31: GO TO SCENE 15 |
| DALI_RESET | 32 | IEC 62386-102 command 32: RESET |
| DALI_STORE_ACTUAL_LEVEL_DTR0 | 33 | IEC 62386-102 command 33: STORE ACTUAL LEVEL IN DTR0 |
| DALI_SAVE_PERSISTENT_VARS | 34 | IEC 62386-102 command 34: SAVE PERSISTENT VARIABLES |
| DALI_SET_OPERATING_MODE | 35 | IEC 62386-102 command 35: SET OPERATING MODE (DTR0) |
| DALI_RESET_MEMORY_BANK | 36 | IEC 62386-102 command 36: RESET MEMORY BANK (DTR0) |
| DALI_IDENTIFY_DEVICE | 37 | IEC 62386-102 command 37: IDENTIFY DEVICE |
| DALI_SET_MAX_LEVEL | 42 | IEC 62386-102 command 42: SET MAX LEVEL (DTR0) |
| DALI_SET_MIN_LEVEL | 43 | IEC 62386-102 command 43: SET MIN LEVEL (DTR0) |
| DALI_SET_SYSTEM_FAILURE_LEVEL | 44 | IEC 62386-102 command 44: SET SYSTEM FAILURE LEVEL (DTR0) |
| DALI_SET_POWER_ON_LEVEL | 45 | IEC 62386-102 command 45: SET POWER ON LEVEL (DTR0) |
| DALI_SET_FADE_TIME | 46 | IEC 62386-102 command 46: SET FADE TIME (DTR0) |
| DALI_SET_FADE_RATE | 47 | IEC 62386-102 command 47: SET FADE RATE (DTR0) |
| DALI_SET_EXT_FADE_TIME | 48 | IEC 62386-102 command 48: SET EXTENDED FADE TIME (DTR0) |
| DALI_SET_SCENE_0 | 64 | IEC 62386-102 command 64: SET SCENE 0 (DTR0) |
| DALI_SET_SCENE_1 | 65 | IEC 62386-102 command 65: SET SCENE 1 (DTR0) |
| DALI_SET_SCENE_2 | 66 | IEC 62386-102 command 66: SET SCENE 2 (DTR0) |
| DALI_SET_SCENE_3 | 67 | IEC 62386-102 command 67: SET SCENE 3 (DTR0) |
| DALI_SET_SCENE_4 | 68 | IEC 62386-102 command 68: SET SCENE 4 (DTR0) |
| DALI_SET_SCENE_5 | 69 | IEC 62386-102 command 69: SET SCENE 5 (DTR0) |
| DALI_SET_SCENE_6 | 70 | IEC 62386-102 command 70: SET SCENE 6 (DTR0) |
| DALI_SET_SCENE_7 | 71 | IEC 62386-102 command 71: SET SCENE 7 (DTR0) |
| DALI_SET_SCENE_8 | 72 | IEC 62386-102 command 72: SET SCENE 8 (DTR0) |
| DALI_SET_SCENE_9 | 73 | IEC 62386-102 command 73: SET SCENE 9 (DTR0) |
| DALI_SET_SCENE_10 | 74 | IEC 62386-102 command 74: SET SCENE 10 (DTR0) |
| DALI_SET_SCENE_11 | 75 | IEC 62386-102 command 75: SET SCENE 11 (DTR0) |
| DALI_SET_SCENE_12 | 76 | IEC 62386-102 command 76: SET SCENE 12 (DTR0) |
| DALI_SET_SCENE_13 | 77 | IEC 62386-102 command 77: SET SCENE 13 (DTR0) |
| DALI_SET_SCENE_14 | 78 | IEC 62386-102 command 78: SET SCENE 14 (DTR0) |
| DALI_SET_SCENE_15 | 79 | IEC 62386-102 command 79: SET SCENE 15 (DTR0) |
| DALI_REMOVE_FROM_SCENE_0 | 80 | IEC 62386-102 command 80: REMOVE FROM SCENE 0 |
| DALI_REMOVE_FROM_SCENE_1 | 81 | IEC 62386-102 command 81: REMOVE FROM SCENE 1 |
| DALI_REMOVE_FROM_SCENE_2 | 82 | IEC 62386-102 command 82: REMOVE FROM SCENE 2 |
| DALI_REMOVE_FROM_SCENE_3 | 83 | IEC 62386-102 command 83: REMOVE FROM SCENE 3 |
| DALI_REMOVE_FROM_SCENE_4 | 84 | IEC 62386-102 command 84: REMOVE FROM SCENE 4 |
| DALI_REMOVE_FROM_SCENE_5 | 85 | IEC 62386-102 command 85: REMOVE FROM SCENE 5 |
| DALI_REMOVE_FROM_SCENE_6 | 86 | IEC 62386-102 command 86: REMOVE FROM SCENE 6 |
| DALI_REMOVE_FROM_SCENE_7 | 87 | IEC 62386-102 command 87: REMOVE FROM SCENE 7 |
| DALI_REMOVE_FROM_SCENE_8 | 88 | IEC 62386-102 command 88: REMOVE FROM SCENE 8 |
| DALI_REMOVE_FROM_SCENE_9 | 89 | IEC 62386-102 command 89: REMOVE FROM SCENE 9 |
| DALI_REMOVE_FROM_SCENE_10 | 90 | IEC 62386-102 command 90: REMOVE FROM SCENE 10 |
| DALI_REMOVE_FROM_SCENE_11 | 91 | IEC 62386-102 command 91: REMOVE FROM SCENE 11 |
| DALI_REMOVE_FROM_SCENE_12 | 92 | IEC 62386-102 command 92: REMOVE FROM SCENE 12 |
| DALI_REMOVE_FROM_SCENE_13 | 93 | IEC 62386-102 command 93: REMOVE FROM SCENE 13 |
| DALI_REMOVE_FROM_SCENE_14 | 94 | IEC 62386-102 command 94: REMOVE FROM SCENE 14 |
| DALI_REMOVE_FROM_SCENE_15 | 95 | IEC 62386-102 command 95: REMOVE FROM SCENE 15 |
| DALI_ADD_TO_GROUP_0 | 96 | IEC 62386-102 command 96: ADD TO GROUP 0 |
| DALI_ADD_TO_GROUP_1 | 97 | IEC 62386-102 command 97: ADD TO GROUP 1 |
| DALI_ADD_TO_GROUP_2 | 98 | IEC 62386-102 command 98: ADD TO GROUP 2 |
| DALI_ADD_TO_GROUP_3 | 99 | IEC 62386-102 command 99: ADD TO GROUP 3 |
| DALI_ADD_TO_GROUP_4 | 100 | IEC 62386-102 command 100: ADD TO GROUP 4 |
| DALI_ADD_TO_GROUP_5 | 101 | IEC 62386-102 command 101: ADD TO GROUP 5 |
| DALI_ADD_TO_GROUP_6 | 102 | IEC 62386-102 command 102: ADD TO GROUP 6 |
| DALI_ADD_TO_GROUP_7 | 103 | IEC 62386-102 command 103: ADD TO GROUP 7 |
| DALI_ADD_TO_GROUP_8 | 104 | IEC 62386-102 command 104: ADD TO GROUP 8 |
| DALI_ADD_TO_GROUP_9 | 105 | IEC 62386-102 command 105: ADD TO GROUP 9 |
| DALI_ADD_TO_GROUP_10 | 106 | IEC 62386-102 command 106: ADD TO GROUP 10 |
| DALI_ADD_TO_GROUP_11 | 107 | IEC 62386-102 command 107: ADD TO GROUP 11 |
| DALI_ADD_TO_GROUP_12 | 108 | IEC 62386-102 command 108: ADD TO GROUP 12 |
| DALI_ADD_TO_GROUP_13 | 109 | IEC 62386-102 command 109: ADD TO GROUP 13 |
| DALI_ADD_TO_GROUP_14 | 110 | IEC 62386-102 command 110: ADD TO GROUP 14 |
| DALI_ADD_TO_GROUP_15 | 111 | IEC 62386-102 command 111: ADD TO GROUP 15 |
| DALI_REMOVE_FROM_GROUP_0 | 112 | IEC 62386-102 command 112: REMOVE FROM GROUP 0 |
| DALI_REMOVE_FROM_GROUP_1 | 113 | IEC 62386-102 command 113: REMOVE FROM GROUP 1 |
| DALI_REMOVE_FROM_GROUP_2 | 114 | IEC 62386-102 command 114: REMOVE FROM GROUP 2 |
| DALI_REMOVE_FROM_GROUP_3 | 115 | IEC 62386-102 command 115: REMOVE FROM GROUP 3 |
| DALI_REMOVE_FROM_GROUP_4 | 116 | IEC 62386-102 command 116: REMOVE FROM GROUP 4 |
| DALI_REMOVE_FROM_GROUP_5 | 117 | IEC 62386-102 command 117: REMOVE FROM GROUP 5 |
| DALI_REMOVE_FROM_GROUP_6 | 118 | IEC 62386-102 command 118: REMOVE FROM GROUP 6 |
| DALI_REMOVE_FROM_GROUP_7 | 119 | IEC 62386-102 command 119: REMOVE FROM GROUP 7 |
| DALI_REMOVE_FROM_GROUP_8 | 120 | IEC 62386-102 command 120: REMOVE FROM GROUP 8 |
| DALI_REMOVE_FROM_GROUP_9 | 121 | IEC 62386-102 command 121: REMOVE FROM GROUP 9 |
| DALI_REMOVE_FROM_GROUP_10 | 122 | IEC 62386-102 command 122: REMOVE FROM GROUP 10 |
| DALI_REMOVE_FROM_GROUP_11 | 123 | IEC 62386-102 command 123: REMOVE FROM GROUP 11 |
| DALI_REMOVE_FROM_GROUP_12 | 124 | IEC 62386-102 command 124: REMOVE FROM GROUP 12 |
| DALI_REMOVE_FROM_GROUP_13 | 125 | IEC 62386-102 command 125: REMOVE FROM GROUP 13 |
| DALI_REMOVE_FROM_GROUP_14 | 126 | IEC 62386-102 command 126: REMOVE FROM GROUP 14 |
| DALI_REMOVE_FROM_GROUP_15 | 127 | IEC 62386-102 command 127: REMOVE FROM GROUP 15 |
| DALI_SET_SHORT_ADDRESS | 128 | IEC 62386-102 command 128: SET SHORT ADDRESS (DTR0) |
| DALI_ENABLE_WRITE_MEMORY | 129 | IEC 62386-102 command 129: ENABLE WRITE MEMORY |
| DALI_TERMINATE | 255 | IEC 62386-102 special command TERMINATE (frame A1 00). The device sends it as that frame, with arg as the data byte (eDIDIO 1.6.3, ADDICT 3.9.3). Earlier firmware sent only the value's low byte - for those, send the frame with frame_16_bit. |
| DALI_INITIALISE | 258 | IEC 62386-102 special command INITIALISE (frame A5 xx). The device sends it as that frame, with arg as the data byte (eDIDIO 1.6.3, ADDICT 3.9.3). Earlier firmware sent only the value's low byte - for those, send the frame with frame_16_bit. |
| DALI_RANDOMISE | 259 | IEC 62386-102 special command RANDOMISE (frame A7 00). The device sends it as that frame, with arg as the data byte (eDIDIO 1.6.3, ADDICT 3.9.3). Earlier firmware sent only the value's low byte - for those, send the frame with frame_16_bit. |
| DALI_WITHDRAW | 261 | IEC 62386-102 special command WITHDRAW (frame AB 00). The device sends it as that frame, with arg as the data byte (eDIDIO 1.6.3, ADDICT 3.9.3). Earlier firmware sent only the value's low byte - for those, send the frame with frame_16_bit. |
| DALI_SEARCH_ADDR_H | 264 | IEC 62386-102 special command SEARCHADDRH (frame B1 xx). The device sends it as that frame, with arg as the data byte (eDIDIO 1.6.3, ADDICT 3.9.3). Earlier firmware sent only the value's low byte - for those, send the frame with frame_16_bit. |
| DALI_SEARCH_ADDR_M | 265 | IEC 62386-102 special command SEARCHADDRM (frame B3 xx). The device sends it as that frame, with arg as the data byte (eDIDIO 1.6.3, ADDICT 3.9.3). Earlier firmware sent only the value's low byte - for those, send the frame with frame_16_bit. |
| DALI_SEARCH_ADDR_L | 266 | IEC 62386-102 special command SEARCHADDRL (frame B5 xx). The device sends it as that frame, with arg as the data byte (eDIDIO 1.6.3, ADDICT 3.9.3). Earlier firmware sent only the value's low byte - for those, send the frame with frame_16_bit. |
| DALI_PROGRAM_SHORT_ADDRESS | 267 | IEC 62386-102 special command PROGRAM SHORT ADDRESS (frame B7 xx). The device sends it as that frame, with arg as the data byte (eDIDIO 1.6.3, ADDICT 3.9.3). Earlier firmware sent only the value's low byte - for those, send the frame with frame_16_bit. |
Non-native DALI Commands provided as quality-of-life functions.
| Name | Number | Description |
| DALI_ARC_LEVEL | 0 | DALI Arc level (0 - 254) |
| DALI_DAPC_LEVEL | 1 | Runs a DALI_ENABLE_DAPC_SEQUENCE if needed. // DEPRECATED |
| DALI_GROUP_ARC_LEVEL | 2 | Specified by Group ID (0 - 15) // DEPRECATED |
| DALI_BROADCAST_SCENE | 3 | No specific Address required, sent to all Devices // DEPRECATED |
| DALI_SCENE_ON_GROUP | 4 | Specified by Group ID (0 - 15) // DEPRECATED |
| DALI_SCENE_ON_ADDRESS | 5 | Specified by Address (0 - 63) // DEPRECATED |
| DALI_QUERY_MULTI_TYPES | 6 | Query multi-device types, returned as a bitmask |
DALI status query response bitmask values - See DALI Standard
IEC 62386-102 control-GEAR status byte (reply to the 16-bit QUERY STATUS, for lamps/drivers).
NOTE: this is NOT the IEC 62386-103 control-DEVICE deviceStatus (reply to the 24-bit QUERY DEVICE STATUS
used for input devices/sensors). For a SENSOR power cycle, powerCycleSeen is deviceStatus bit5 (0x20), not
the bit7 (=128) below.
| Name | Number | Description |
| LAMP_OFF | 0 | Not technically in DALI. But this is the default when mask = 0b00000000 |
| CONTROL_GEAR_FAILURE | 1 | Bit 0: control gear failure |
| LAMP_FAILURE | 2 | Bit 1: lamp failure |
| LAMP_ON | 4 | Bit 2: lamp on (arc power above 0) |
| LIMIT_ERROR | 8 | Bit 3: limit error - the last level asked for was outside min / max |
| FADE_RUNNING | 16 | Bit 4: a fade is running |
| RESET_STATE | 32 | Bit 5: in the reset state |
| SHORT_ADDRESS | 64 | Bit 6: short address is MASK (no short address) |
| POWER_CYCLE_SEEN | 128 | Bit 7: power cycle seen since the last reset |
DALI Receive Flag
| Name | Number | Description |
| WAITING | 0 | Internal Idle State - Should not be received |
| RECEIVING_FRAME | 1 | DALI Frame being Received |
| NO_RECEIVED_FRAME | 2 | Frame was recorded - Empty Data |
| RECEIVED_8_BIT_FRAME | 3 | Frame was recorded - 8 Bit Reply |
| RECEIVED_16_BIT_FRAME | 4 | Frame was recorded - 16 Bit - Standard Message |
| RECEIVED_24_BIT_FRAME | 5 | Frame was recorded - 24 Bit - eDALI Message |
| RECEIVED_PARTIAL_FRAME | 6 | Frame was recorded - Unusual Bit count |
| IDLE | 7 | DALI System Idle |
| CALIBRATION | 8 | Inhouse DALI Calibration |
| ERROR_WHILE_SENDING | 254 | Error while trying to Transmit DALI - Possibly no Bus Power |
| ERROR_WHILE_RECEIVING | 255 | Error while trying to Receive - Invalid Frame Data, or no response |
DALI DTR Message structure.
| Field | Type | Label | Description |
| dtr | uint32 | repeated | For DALI, you can use 2 bytes, for eDALI 3. Format - DTR0 | DTR1 << 8 | DTR2 << 16 |
Message to send a DALI command using various DALI frame types.
| Field | Type | Label | Description |
| line_mask | uint32 | Binary mask; e.g. selecting line 1 out of 4 looks like 0b0001. For non queries, line_mask can contain multiple valid lines |
|
| address | uint32 | DALI Address |
|
| frame_25_bit | uint32 | Older eDALI commands are manufacturer specific, so we have to take a raw value. |
|
| frame_25_bit_reply | uint32 | Older eDALI commands can have a reply. |
|
| command | DALICommandType | A standard DALI command (IEC 62386-102) to address. From DALI_TERMINATE (255) up the values are special commands, sent without an address; a value there that is not one is refused with INVALID_PARAMS (eDIDIO 1.6.3, ADDICT 3.9.3) |
|
| custom_command | CustomDALICommandType | A command the device builds itself (arc level, fade, ...), with arg |
|
| query | DALIQueryType | A standard DALI query to address; the reply is dali_query. Above DALI_QUERY_EXT_VERSION_NUMBER (255) the values are special queries, sent without an address; a value there that is not one is refused with INVALID_PARAMS (eDIDIO 1.6.3, ADDICT 3.9.3) |
|
| type8 | Type8CommandType | A DT8 colour command; the device sends ENABLE DEVICE TYPE 8 and the DTRs first |
|
| frame_16_bit | uint32 | Standard DALI Frame data - Don't use arg |
|
| frame_16_bit_reply | uint32 | Standard DALI Frame data with reply - Don't use arg |
|
| frame_24_bit | uint32 | Standard 24 Bit DALI Frame data - Don't use arg |
|
| frame_24_bit_reply | uint32 | Standard 24 Bit DALI Frame data with reply - Don't use arg |
|
| type8_reply | Type8QueryType | A DT8 colour query; the reply is dali_query |
|
| device24_setting | DALI24DeviceSetting | Settings for DALI 24 Bit Devices |
|
| arg | uint32 | Context-dependent value: scene number (0-15), arc level (0-254), XY coordinates packed as (X << 16) | Y, or a special command's data byte as sent on the bus (INITIALISE: 0x00 all, 0xFF unaddressed, 0AAAAAA1 one device; SEARCHADDR H / M / L: the byte; PROGRAM / VERIFY SHORT ADDRESS: 0AAAAAA1, 0xFF to delete) |
|
| dtr | DTRPayloadMessage | DTR0 / DTR1 / DTR2 values written before the command |
|
| instance_type | DALI24InstanceType | Instance for 24 bit device - Commands are sent via Type |
|
| op_code | DALI24OpCode | OpCode for 24 bit device |
|
| send_twice | bool | Should this command be sent twice on the DALI Line(s)? |
Message reply for DALI Status Flag
| Field | Type | Label | Description |
| flags | DALIStatusType | repeated | The status bits that are set |
DALI Response is tagged with the line and DALI address.
| Field | Type | Label | Description |
| status_flags | DALIStatusFlagMessage | Deprecated: the answer to QUERY STATUS as flags |
|
| data | PayloadMessage | Deprecated: the answer byte in data.uint_data |
|
| dali_flag | DALIRXStatusFlag | New Query Method |
|
| response_data | PayloadMessage | The answer byte in response_data.uint_data, when dali_flag says one was received |
DALI Response for Addressing Error
| Name | Number | Description |
| NO_ERROR | 0 | Device found and Addressed |
| VERIFY | 1 | Device was found, address was set, but verification failed |
| SEARCH | 2 | Device was found, issue with long address |
| NO_NEW_DEVICE | 3 | No device found |
DALI Addressing Type
| Name | Number | Description |
| ADDRESS_NEW | 0 | Only Address New devices which have their address set to MASK (255) |
| READDRESS_ALL | 1 | Address everything on the line (Standard or 24 bit) - USE CAREFULLY |
Message to invoke DALI Addressing
| Field | Type | Label | Description |
| type | DALIAddressingType | New or All |
|
| initialisation | bool | First Address (TRUE) or Next Address (FALSE) |
|
| line_mask | uint32 | Line to Address - Must be singular |
|
| is24Bit | bool | 24 Bit DALI (TRUE) or Standard (FALSE) |
|
| error | DALIAddressingError | Response -> Error while Addressing |
|
| index | uint32 | Response -> Index of Set Address |
Message to invoke DALI remapping
| Field | Type | Label | Description |
| from_address | uint32 | DALI Address to change |
|
| to_address | uint32 | New address for device. If populated, this address will change to the from_address |
|
| line_mask | uint32 | Affected DALI Line |
|
| is24Bit | bool | 24 bit DALI (TRUE) or Standard (FALSE) |
A DALI device: its line and short address.
| Field | Type | Label | Description |
| line | uint32 | Which DALI Line is this Device on? |
|
| address | uint32 | What is the Short Address of this Device? |
Find DALI devices that may share a short address. Send line_mask (and is24Bit); the reply lists the suspects.
| Field | Type | Label | Description |
| line_mask | uint32 | Which DALI Line(s) to check |
|
| is24Bit | bool | Use 24-bit DALI (DALI v2) or standard 16-bit DALI if FALSE |
|
| possible_duplicates | DALIAddressableObject | repeated | A collection of DALI Devices which *may* be using duplicated Short Addresses |
Message to send DMX on requested DMX line(s)
| Field | Type | Label | Description |
| zone | uint32 | For Spektra (default of 0 is fine if not applicable) |
|
| universe_mask | uint32 | Which DMX Universes to apply the values to. Specified as a binary mask. Can be sent to multiple. |
|
| channel | uint32 | The actual channel number (not zero-based index) |
|
| repeat | uint32 | The number of times to repeat the data given (e.g. start from DMX channel 30 and set the RGB channel values (levels) of the next 3 lights, so repeat would be 3 with 3 levels provided) |
|
| level | uint32 | repeated | The actual channel values/levels to send |
| fade_time_by_10ms | uint32 | The DMX Fade Task runs every 10ms, so a value of 25 will fade over 250ms |
Message to send a DMX command with/without a response (Getset)
| Field | Type | Label | Description |
| universe_mask | uint32 | Universe Mask - Must be a single universe. |
|
| uid | uint64 | UID of device to send the message to. Can be Multi/Broadcast |
|
| pid | uint32 | RDM PID - See Standard |
|
| getset | uint32 | Expects [DMX_RDM_GET_COMMAND = 0x20] or [DMX_RDM_SET_COMMAND = 0x30] |
|
| datalength | uint32 | Length of Data to send |
|
| data | uint32 | repeated | Data |
RDM Response message - source UID, PID, datalength and data
| Field | Type | Label | Description |
| uid | uint64 | UID of requested device |
|
| pid | uint32 | Message PID |
|
| datalength | uint32 | Length of Data to receive |
|
| data | uint32 | repeated | Data |
RDM Discovery Message - Invokes Discovery with reply as RDMDiscoveryReplyMessage. isNext flag allows for more than 128 devices to be discovered in additional messages.
| Field | Type | Label | Description |
| universe_mask | uint32 | Universe Mask - Must be a single universe |
|
| isNext | bool | If true, RDM module will search for additional or 'next' 128 RDM devices. If false (empty), RDM module will re-init search for up to 128 devices |
RDM Discovery Reply with up to 128 devices
| Field | Type | Label | Description |
| discovery_count | uint32 | How many UIDs were found in total |
|
| uid | uint64 | repeated | The RDM UIDs (48-bit) found, up to 128 per reply |
| error_code | uint32 | Non-zero if discovery failed |
Which kind of Spektra data a request or action is about.
| Name | Number | Description |
| SETTINGS | 0 | A zone's settings (SpektraSettingMessage) |
| SEQUENCE | 1 | A stored sequence |
| THEME | 2 | A stored theme |
| STATIC | 3 | DEPRECATED |
| CALENDAR | 4 | The calendar |
| SHOW | 5 | DEPRECATED |
| LIVE | 6 | Live Update of the Spektra settings |
What to do with a sequence or theme (SpektraControlMessage).
| Name | Number | Description |
| START | 0 | Start playing |
| STOP | 1 | Stop |
| PAUSE | 2 | Pause, keeping the current colours |
| SAVE | 3 | Save the Spektra data (settings, calendar) to non-volatile memory |
What a Spektra zone does on a day the calendar gives it nothing.
| Name | Number | Description |
| RUN_RANDOM_COLOURED_SEQUENCE | 0 | Unless otherwise specified, this is a rotate sequence with random colours rotating every 5 seconds |
| RUN_SEQUENCE_1 | 1 | Can be used to set a 'Default Sequence' with a known pattern and colour combination |
| RESUME_PREVIOUS | 2 | Resume the last Sequence or Theme that Spektra had active |
| RUN_THEME_1 | 3 | Resume to Theme 1 |
| RUN_SHOW_1 | 4 | Resume to Show 1 |
| DO_NOTHING | 254 | Left as the last possible type, fill between 0 and 253 as necessary |
How DMX addresses count across lines.
| Name | Number | Description |
| INDEPENDENT | 0 | Control Lines are independently addressed (e.g. DMX 1 to 512 per line) |
| CONSECUTIVE | 1 | Control Lines are consecutively addressed (e.g. DMX 1 to 512 on the first line, 513 to 1024 on the next, etc.) |
How a sequence moves from one colour to the next.
| Name | Number | Description |
| BLEND | 0 | Blended colour transitions. Example: Transition between red and green will go through yellow. |
| SNAP | 1 | Instant colour transitions. |
| FADE_TO_BLACK | 2 | Example: Transition between red and green will fade the light off then on between colours. Not currently supported. |
Message for Spektra Setting Information
| Field | Type | Label | Description |
| zone | uint32 | Determine Spektra zone from 0-9 |
|
| start_address | uint32 | DMX or DALI Start Address. Typically RED on the first fixture. |
|
| line_or_universe_mask | uint32 | Which DALI Line(s) or DMX Universe(s) to control |
|
| protocol | uint32 | E.g. DMX or DALI |
|
| number_of_lights | uint32 | Number of DALI or DMX fixtures connected. If more than available channels, the 'consecutive' option can be selected which will use multiple lines, starting from the first line specified above |
|
| channels_per_light | uint32 | E.g. 4 for RGBW |
|
| channel_colours | uint32 | repeated | What colour is assigned to each channel (e.g. Red, Green, etc.) |
| unscheduled_behaviour | SpektraUnscheduledBehaviourType | 0 = Random colours rotate sequence, 1 = Run default sequence (seq 1) |
|
| channel_mapping | uint32 | repeated | Channel mapping for DALI or future DMX virtual 'grouping' |
| line_addressing | LineAddressingType | Independent or Consecutive |
|
| zone_scale_factor | float | Zone Scale Factor - Float 0 to 1.0f |
Spektra Colour Channel Config Structure
| Field | Type | Label | Description |
| channel_value | uint32 | repeated | Include as many values as there are channels, e.g. [0, 255, 0] would be Green for an RGB light (3 channel values) |
Spektra Sequence Configuration Message. Up to 144 sequences can be stored
| Field | Type | Label | Description |
| index | uint32 | Index of sequence - 0 to 143 |
|
| type | uint32 | BLEND / SIMPLE CHASE / SHADOW CHASE / COMET / ROTATE / TWINKLE / BUILD-UP / CRASH / FIREWORKS |
|
| transition | SpektraTransitionType | BLEND / SNAP / FADE_TO_BLACK |
|
| fade_time_by_10ms | uint32 | Correlates to blend transitions |
|
| time_per_colour | uint32 | How long each colour should be shown |
|
| time_per_colour_unit | uint32 | MILLISECONDS / SECONDS / MINUTES / HOURS |
|
| time_per_step | uint32 | How long each sequence type 'animation' takes (e.g. speed of the chase) |
|
| time_per_step_unit | uint32 | MILLISECONDS / SECONDS / MINUTES / HOURS |
|
| range | uint32 | Number of lights per repeating segment. 0 = no segmentation (all lights as one group). Values > 0 divide lights into groups of this size for pattern repetition |
|
| colour | uint64 | repeated | DEPRECATED - Use the 'colours' field (SpektraColourConfigMessage array) instead |
| is_randomised_type | uint32 | Will randomly select (from random_types_mask) one of the Sequence Types |
|
| random_types_mask | uint32 | A bitmask of Sequence Types |
|
| is_reverse_direction | uint32 | Animate the sequence in reverse light order |
|
| is_cycle_direction | uint32 | Animate the sequence in alternating light order from forward to reverse |
|
| title | string | The name of the Sequence |
|
| has_random_colour_order | bool | Randomly pick the next colour out of the chosen colours |
|
| colours | SpektraColourConfigMessage | repeated | The colours used in the Sequence |
| args | uint32 | repeated | Function specific arguments * 5 |
Message to define Spektra Calendar message. Zone options available in SpektraSettingsMessage to define what will happen if no action is scheduled on a calendar day.
| Field | Type | Label | Description |
| type | SpektraTargetType | Spektra Type (e.g. Sequence or Theme) |
|
| index | uint32 | Index (i.e. which Sequence or Theme) |
|
| days | bool | repeated | Boolean array to specify when this Target Index is active (up to the number of days in a year) |
| isOverride | bool | Boolean isOverride. If override, only run once |
Spektra Calendar Day Structure
| Field | Type | Label | Description |
| day_index | uint32 | Index of this day (0 to 365, 366 days total) |
|
| type | SpektraTargetType | Spektra Type for this day (e.g. Sequence or Theme) |
|
| target_index | uint32 | Index of the specified Type (i.e. which Sequence or Theme) |
|
| isOverride | bool | Boolean isOverride. If override, only run once |
Message to handle Spektra Calendar Read - This is the reply message to the read request
| Field | Type | Label | Description |
| day_offset | uint32 | Offset to start counting days from (0 is the first day of the year) |
|
| days | SpektraCalendarDayMessage | repeated | Schedule information for each day; supports up to 90 days per Message |
Message to define Spektra Theme. Up to 16 Themes
| Field | Type | Label | Description |
| index | uint32 | Theme slot, 0-based |
|
| colour | uint64 | repeated | DEPRECATED - Use the 'colours' field (SpektraColourConfigMessage array) instead |
| title | string | The name of the Theme |
|
| colours | SpektraColourConfigMessage | repeated | The colours used in the Theme (will repeat colours if less colours than lights) |
Message to request Spektra Data
| Field | Type | Label | Description |
| type | SpektraTargetType | What to read; with manifest set, SEQUENCE or THEME |
|
| index | uint32 | Slot index; when manifest = true, the manifest page number |
|
| manifest | bool | TRUE = reply with a SpektraManifestMessage for 'type' instead of one slot. Additive: firmware below the manifest floor ignores this field and replies with slot 'index', so a client MUST gate on firmware version AND check that the reply actually carries spektra_manifest. |
Compact summary of which slots of a Spektra slot table hold data, and a change
token for each. Reply to a SpektraReadMessage with manifest = true.
Lets a client read only the slots that exist instead of polling every slot: a
site with 8 sequences goes from 143 round trips to 1 + 8. That matters most on
the transports where it hurts most - mobile/VPN links, and TLS.
NOT an atomic snapshot: the device reads the slot table a sector at a time and
releases its flash lock between sectors, so a write that lands mid-scan may or
may not be reflected. That is correct for a change detector; do not treat the
manifest as a transactional view.
| Field | Type | Label | Description |
| type | SpektraTargetType | SEQUENCE or THEME - which slot table this describes |
|
| slot_offset | uint32 | First slot index this page covers |
|
| slot_count | uint32 | Slots this page covers, occupied or not |
|
| is_last_page | bool | TRUE on the final page of the table |
|
| index | uint32 | repeated | Occupied slot indices, ascending |
| crc | fixed32 | repeated | CRC-32 of each slot's stored page, aligned 1:1 with 'index'. Opaque change token: equal CRC means the stored bytes did not change. WIRE INVARIANT: index count == crc count; a receiver that sees otherwise must discard the message. |
Message to control the Spektra Module
| Field | Type | Label | Description |
| type | SpektraTargetType | Spektra Target Type - Sequence/Theme |
|
| zone | uint32 | Zone (0 to 9) or Zones (255) to control |
|
| index | uint32 | Index of Action. I.e. Sequence 5 |
|
| action | SpektraActionType | Type of Action. Start/Resume/Stop |
What Spektra is doing right now, one entry per zone in every repeated field: the reply to spektra_read LIVE.
| Field | Type | Label | Description |
| type | SpektraTargetType | repeated | Target Type Per Zone (Sequence/Theme etc) |
| index | uint32 | repeated | Target Index Per Zone |
| action | SpektraActionType | repeated | Target Action Per Zone |
| step_index | uint32 | repeated | Current Step |
| step_index_direction | uint32 | repeated | Forwards/Backwards (If Cycling) |
| colour_index | uint32 | repeated | Current State of Colour Index (Changes over time) |
| colour_range | uint32 | repeated | Current State of Colour Range (Changes based on Sequence Step) |
| random_seq_type | uint32 | repeated | Currently Active Random Sequence Type |
| zone_active | bool | repeated | Flag to show if any channel in this zone is active |
Structure to describe the DMX to DALI translation
| Field | Type | Label | Description |
| line_in | uint32 | DMX IN - Must configure line as DMX IN |
|
| line_out | uint32 | DALI OUT |
|
| dmx_start_address | uint32 | DMX Start Address |
|
| channel_count | uint32 | DMX Count |
|
| dali_array | uint32 | repeated | DALI Addresses |
| affected_input | uint32 | Bitmask of affected inputs |
|
| blocking | bool | If TRUE (1), the inputs will be ignored if the internal DMX receiving flag is TRUE |
|
| enabled | bool | Translation object is enabled (1) or disabled (0) |
|
| index | uint32 | Index of Translation Object |
Message to describe the DMX to DALI translation objects. For a 4 line controller, up to 3 objects can be created allowing for single/multi line translation to single/multi line out.
| Field | Type | Label | Description |
| object | DMXTranslationObject | repeated | Typically 1 for a 4 Pole device but can be more for 9 Pole eDIDIO |
What is fitted on a control line (a daughterboard slot).
| Name | Number | Description |
| LINE_EMPTY | 0 | No Hardware in this slot |
| LINE_DALI | 1 | Physical DALI Board in this slot |
| LINE_DMX | 2 | Physical DMX Board in this slot |
| LINE_DMX_IN | 3 | Physical DMX Board in this slot - Must be set in the case of DMX to DALI Translation. |
| LINE_AUTO | 4 | Line will be determined from physical hardware - Do not use for DMX to DALI Translation |
Which report a diag_message asks for. Each value says what comes back.
| Name | Number | Description |
| DIAGNOSTIC_SYSTEM_INFO | 0 | Can be used to retrieve a large number of properties that describe the capabilities of the device. (Number of supported Lists, Alarms, etc.). Reply: diag_system. Devices: eDIDIO, ADDICT. |
| DIAGNOSTIC_INPUT_STATUS | 1 | Not currently supported (will default to SYSTEM_INFO). Reply: diag_system. Devices: eDIDIO, ADDICT. |
| DALI_LEVEL_CACHE | 2 | Can be used to retrieve the current entries of the in-memory DALI values cache. Reply: level_cache_response (64 levels of line). |
| DMX_LEVEL_CACHE | 3 | Can be used to retrieve the current entries of the in-memory DMX levels cache. Results must be paginated due to size of DMX universe (512). Reply: level_cache_response (64 levels of line, from page x 64). Devices: eDIDIO, ADDICT. |
| ROOM_JOINS | 4 | Removed: the "Joined Rooms" state no longer exists. Reply: AckMessage (INDEX_OUT_OF_BOUNDS). |
| DALI_STATUS_CACHE | 5 | Can be used to retrieve the current entries of the in-memory DALI status cache. Reply: level_cache_response (64 status bytes of line). |
Structure of Input state mask when InputStateResponse message is sent. 1 is HIGH, 0 is LOW. GPIO are configured as default HIGH. If not connected, a momentary input will return TRUE (1)
| Field | Type | Label | Description |
| use_mask | bool | Reply with a mask rather than a list of active inputs. |
Message containing the InputStateMessage mask
| Field | Type | Label | Description |
| inputs | uint32 | repeated | Contains Inputs that are Low (i.e. currently active) |
| input_mask | uint32 | Usage is determined by "InputStateMessage: use_mask" |
Message that contains DALI polled levels. Levels are split into pages of 64 values
DALI/DMX agnostic.
| Field | Type | Label | Description |
| levels | uint32 | repeated | Repeated Level array |
| line | uint32 | Requested Line |
|
| page | uint32 | Page of requested information |
Command type for reading or writing user-defined names (aliases) for device elements
| Name | Number | Description |
| GET_ALIASES | 0 | Retrieve stored aliases from the device |
| SET_ALIASES | 1 | Save new aliases to the device |
User-defined names for profiles (max profile_count entries)
| Field | Type | Label | Description |
| profiles | string | repeated | One name per profile, in index order |
User-defined names for physical inputs (max input_count entries)
| Field | Type | Label | Description |
| inputs | string | repeated | One name per physical input, in index order |
User-defined names for physical outputs (max output_count entries)
| Field | Type | Label | Description |
| outputs | string | repeated | One name per output, in index order |
User-defined names for lists (max list_count entries)
| Field | Type | Label | Description |
| lists | string | repeated | One name per list, in index order |
User-defined names for sensors (max 40 entries)
| Field | Type | Label | Description |
| sensors | string | repeated | One name per sensor, in index order |
User-defined names for DALI input devices (max input_dali_count entries)
| Field | Type | Label | Description |
| dali_inputs | string | repeated | One name per DALI input, in index order |
User-defined names for schedules/alarms (max alarm_count entries)
| Field | Type | Label | Description |
| schedules | string | repeated | One name per alarm (schedule), in index order |
Container for getting or setting user-defined aliases. Only one alias type can be sent per message.
| Field | Type | Label | Description |
| command | AliasCommandType | GET_ALIASES to read, SET_ALIASES to write |
|
| profiles | ProfileAliases | Profile names |
|
| inputs | InputAliases | Physical input names |
|
| outputs | OutputAliases | Output names |
|
| lists | ListAliases | List names |
|
| sensors | SensorAliases | Sensor names |
|
| dali_inputs | DaliInputAliases | DALI input names |
|
| schedules | ScheduleAliases | Alarm (schedule) names |
Message to request system information. Contains vital information about connected devices configuration capabilities, as well as firmware and hardware version.
| Field | Type | Label | Description |
| firmware | string | Firmware Version number |
|
| hardware | string | Hardware Version number |
|
| error | string | Any populated Error message |
|
| input_count | uint32 | Number of supported Inputs |
|
| output_count | uint32 | Number of supported Outputs |
|
| ir_count | uint32 | Number of supported IR codes |
|
| list_step_count | uint32 | Number of supported List Steps |
|
| list_count | uint32 | Number of supported Lists |
|
| alarm_count | uint32 | Number of supported Alarms (Schedules) |
|
| burnin_count | uint32 | Number of supported Burn-ins |
|
| spektra_seq_count | uint32 | Number of supported Spektra Sequences |
|
| spektra_seq_step_count | uint32 | Number of supported Spektra Sequence Steps |
|
| spektra_theme_count | uint32 | Number of supported Spektra Themes |
|
| spektra_static_count | uint32 | Number of supported Spektra Static Colours |
|
| proto_version | uint32 | Protocol version = ProtocolVersion_PROTOCOL_VERSION_CURRENT, byte-packed 0x00_MM_mm_PP (e.g. 0x010301 = 1.3.1) |
|
| line_count | uint32 | Number of supported Control Lines (for DMX, DALI) |
|
| lines | LineType | repeated | Denotes what control type is assigned to each line (e.g. DMX, DALI) |
| profile_count | uint32 | Number of supported Profiles |
|
| preset_code_count | uint32 | Number of supported Preset Codes |
|
| user_level_count | uint32 | Number of supported User Levels |
|
| dmx_to_dali_count | uint32 | Number of supported DMX to DALI Translations |
|
| spektra_zone_count | uint32 | Number of supported Spektra Zones |
|
| logic_count | uint32 | Number of supported Logic Mappings |
|
| input_dali_count | uint32 | Number of supported DALI Inputs |
|
| vendor_id | string | Vendor ID - "Control Freak" |
|
| selected_profile | uint32 | Currently Selected Profile |
|
| bootloader | string | Bootloader Version number (if applicable) |
|
| commit_hash | string | Git commit hash from the build system |
|
| build_date | string | Build date/time string (e.g. "Apr 8 2026 14:30:00") |
|
| has_confidentiality_key | bool | TRUE if the device can accept an encrypted (V3) firmware image. Lets the updater gate the V3 option. Older firmware omits it -> decodes as false. |
Request a diagnostic response message of a given type.
| Field | Type | Label | Description |
| type | DiagnosticMessageType | Which report; each DiagnosticMessageType says what comes back |
|
| page | uint32 | Allow paging of results, eg. 32 DMX levels per page, 16 pages. |
|
| line | uint32 | If a line/DMX universe needs to be indicated it can go here. |
Which frames the device uses to talk to its DALI sensors.
| Name | Number | Description |
| EDALI_25_BIT | 0 | 25-bit frame type for a vendor-specific pre-configured sensor |
| DEFAULT_DALI_2 | 1 | The default 24-bit DALI 2 frames |
Message to get or set Admin Properties in reference to project information.
| Field | Type | Label | Description |
| device_name | string | As shown on the Network (in Spektra/Configurator Discovery) |
|
| project_name | string | For project documentation |
|
| longitude | float | For astronomical calculations (e.g. sunrise/sunset) |
|
| latitude | float | For astronomical calculations (e.g. sunrise/sunset) |
|
| local_offset | float | For astronomical calculations (e.g. sunrise/sunset) |
|
| daylight_savings | bool | For astronomical calculations (e.g. sunrise/sunset) |
|
| daylight_savings_start | uint32 | Can be used to state when DST is active from |
|
| daylight_savings_end | uint32 | Can be used to state when DST is active to |
|
| poll_active | uint32 | Should the device be polling the DALI line to cache arc levels. If not 0, it is the polling interval in seconds |
Message to get or set Admin Properties in reference to the device configuration
| Field | Type | Label | Description |
| list_status | uint32 | repeated | State of each List (DISABLED / ENABLED / LOOPING) |
| burn_in_status | uint32 | repeated | State of each Burn-in (RUNNING / NOT RUNNING) |
| alarm_status | uint32 | Currently Selected Alarm (i.e. 'next Alarm') |
|
| alarm_time_from_reg | TimeClockMessage | Time for next Alarm as per RTC Register |
|
| sensor_status | uint32 | repeated | State of each DALI Sensor (IDLE / DISABLED / WARNING / OCCUPANCY) |
Message to get or set Admin Properties in reference to the network connection. Will require a device reboot to update - Used with AdminMessage
| Field | Type | Label | Description |
| DHCP | bool | Should DHCP be used? If False, the static IP will be used instead |
|
| IP | string | A static IP to use if DHCP is False |
|
| MAC | string | The MAC Address of this Device |
|
| gateway | string | The Gateway IP for the network this Device is on |
|
| NTPServer | string | The NTP Server address from RTC updates over the network |
|
| NTP | bool | Should NTP be used to keep the RTC up-to-date via network requests |
|
| error | string | Error or Status Message 32 char |
|
| NTPTimeout | uint32 | Timeout in seconds for NTP Retry |
|
| subnet | string | The Subnet if set by Static IP |
|
| DNS_Primary | string | Primary DNS |
|
| DNS_Secondary | string | Secondary DNS |
Message to set the DNS Server - Used with AdminMessage
| Field | Type | Label | Description |
| DNS_Primary | string | Primary DNS |
|
| DNS_Secondary | string | Secondary DNS |
Message to set the Type of Controller lines - Used with AdminMessage
| Field | Type | Label | Description |
| lines | LineType | repeated | Used to set the control type on each control line (e.g. DMX / DALI) |
Message to get device temperature and battery - Used with AdminMessage
| Field | Type | Label | Description |
| temperature | float | The current device chip temperature |
|
| battery | float | The current battery voltage (3.3V battery) |
Message to enable/disable the Secure Login functionality
| Field | Type | Label | Description |
| username | string | Which username to login as ("control" / "config" / "admin"; 3rd party vendors may have a built-in alias for the admin role) |
|
| cnonce | string | The nonce generated by the client attempting to login |
|
| hash | uint32 | repeated | The login response digest, as 32 repeated byte (0-255) elements (decoded as raw bytes). |
Which role a per-role login secret belongs to. Hierarchical clearance: ADMIN includes CONFIG includes CONTROL.
| Name | Number | Description |
| ROLE_CONTROL | 0 | Drive outputs, run sequences/scenes, read state/diagnostics |
| ROLE_CONFIG | 1 | + edit inputs/schedules/sensors/lists/logic/alarms/addressing |
| ROLE_ADMIN | 2 | + network/firmware/provisioning/secure-session/resets/accounts |
Provisions a role's login secret. Used with AdminMessage (USER_ACCOUNT, SET, ADMIN clearance).
Write-only: the device never returns a secret. An all-zero secret clears (un-provisions) that role.
| Field | Type | Label | Description |
| role | AuthRole | Which role's secret to set |
|
| secret | bytes | 32-byte login secret (all-zero = clear/UNSET) |
Message to set the DALI sensor messaging type (24 or 25 bit DALI) - Used with AdminMessage
| Field | Type | Label | Description |
| type | DALISensorType | Which type of eDALI will the eDIDIO use to decode & encode Sensor packets? |
DMX512 timing modes as defined by ESTA for Relaxed DMX Timing. Affects refresh rate and compatibility with fixtures
| Name | Number | Description |
| DMX_TIMING_FAST | 0 | Fastest refresh rate, may have compatibility issues with some fixtures |
| DMX_TIMING_MEDIUM | 1 | Balanced timing for most fixtures |
| DMX_TIMING_SLOW | 2 | Slower timing for maximum fixture compatibility |
| DMX_TIMING_NORMAL | 3 | Standard DMX512 timing per ESTA specification |
Global DMX Timing
| Field | Type | Label | Description |
| mode | DMXTimingMode | Applies to all lines |
Per-line DMX output configuration
| Field | Type | Label | Description |
| line_index | uint32 | DMX line / universe index (0-based) |
|
| output_slot_count | uint32 | Number of DMX slots to transmit (1-512) |
|
| use_16bit_output | bool | If true, use 16-bit resolution (pairs adjacent slots for fine/coarse control) |
|
| dmx_slot_mapping_raw | bytes | Optional: Custom fixture slot remapping. Value of 513 indicates unused slot |
Per-task stack accounting. One entry per FreeRTOS task currently running.
stack_hwm_bytes is the canonical "free bytes at worst since the task started"
reported by uxTaskGetStackHighWaterMark(); on Cortex-M the underlying counter
is words (4-byte), already multiplied here for client convenience.
| Field | Type | Label | Description |
| name | string | FreeRTOS task name (configMAX_TASK_NAME_LEN-1 chars max) |
|
| stack_size_bytes | uint32 | Allocated stack region in bytes |
|
| stack_hwm_bytes | uint32 | Free bytes at worst since task start (lower = more used) |
|
| stack_used_peak_bytes | uint32 | Convenience: stack_size_bytes - stack_hwm_bytes |
|
| stack_min_hwm_bytes | uint32 | Lowest HWM ever observed by the firmware's own periodic sampler (0 if not separately tracked for this task) |
|
| instance_index | uint32 | Disambiguator for dynamic-instance tasks (TCP/TLS clients); 0 for singletons |
|
| priority | uint32 | Current FreeRTOS priority |
Memory diagnostics snapshot. Returned in response to AdminMessage{GET, MEMORY_DIAGNOSTICS}.
All byte counts are bytes (not FreeRTOS "words"). uptime_seconds is included so
the client can judge whether HWMs have had enough wall time to converge.
| Field | Type | Label | Description |
| tasks | TaskMemoryInfo | repeated | Live tasks only (NULL handles skipped) |
| task_count | uint32 | Length of tasks (mirror for clients that don't auto-count) |
|
| sys_stack_size_bytes | uint32 | System/MSP stack (the stack used before scheduler start + by ISRs). HWM derived from a stack-painting scan. |
|
| sys_stack_hwm_bytes | uint32 | Free bytes at worst this run |
|
| sys_stack_hwm_prev_bytes | uint32 | Free bytes captured before this reboot |
|
| sram_total_bytes | uint32 | Linker-section static usage (computed from _sdata/_edata/_sbss/_ebss/_enoinit/_sccmram/_eccmram/_estack). 128 KB total |
|
| sram_static_bytes | uint32 | .data + .bss + .noinit |
|
| ccmram_total_bytes | uint32 | 64 KB total |
|
| ccmram_static_bytes | uint32 | Sections marked CCMRAM |
|
| uptime_seconds | uint32 | Seconds since boot |
|
| boot_sys_stack_hwm_bytes | uint32 | System-stack peak captured immediately before vTaskStartScheduler(). Compare against sys_stack_hwm_bytes to disambiguate pre-scheduler boot-init depth vs. post-boot ISR growth: equal => boot was the peak. Free bytes at scheduler start (lower = more used) |
|
| tls_pool_size_bytes | uint32 | TLS static memory pool. 0 in builds without TLS support. tls_pool_hwm_bytes is the peak first-fit allocation offset, NOT peak concurrent in-use bytes — fragmentation can push real-world need higher. total TLS pool size (24576 bytes when enabled) |
|
| tls_pool_hwm_bytes | uint32 | Peak byte offset ever allocated |
Resolved link state. UNKNOWN until the first link-up after boot.
| Name | Number | Description |
| ETH_LINK_UNKNOWN | 0 | Not reported (older firmware, or not measured yet) |
| ETH_LINK_DOWN | 1 | No Ethernet link |
| ETH_LINK_UP | 2 | Ethernet link up |
Resolved duplex. UNKNOWN means the PHY has not yet published a valid
HCDSPEED (auto-neg in progress, or AN disabled + no link, or AUTODONE
timeout occurred).
| Name | Number | Description |
| ETH_DUPLEX_UNKNOWN | 0 | Not reported (older firmware, or not measured yet) |
| ETH_DUPLEX_HALF | 1 | Half duplex |
| ETH_DUPLEX_FULL | 2 | Full duplex |
How the current link speed/duplex was decided. PARALLEL_DETECTED is the
duplex-mismatch smoking gun: it means the link partner did not transmit
FLP bursts, so the PHY had to detect speed only and (per IEEE 802.3)
pick half-duplex. If the partner is actually configured full-duplex,
every collision they see is "late" and TCP loses retransmits.
| Name | Number | Description |
| ETH_NEG_UNKNOWN | 0 | Not yet determined (no link, fill-time read happened pre-link) |
| ETH_NEG_AN_DISABLED | 1 | BMCR.AN_EN == 0 (forced speed/duplex) |
| ETH_NEG_AN_IN_PROGRESS | 2 | AN_EN set but BMSR.AN_COMPLETE not yet |
| ETH_NEG_AN_COMPLETED | 3 | Clean auto-negotiation with a peer that also auto-negotiates |
| ETH_NEG_PARALLEL_DETECT | 4 | ANER.PAR_DETECT_FAULT set OR LP_AN_ABLE==0 with link up |
Reason a record was appended to the ring buffer.
| Name | Number | Description |
| ETH_EVT_BOOT_INIT | 0 | Snapshot taken at end of lan8720Init() |
| ETH_EVT_LINK_UP | 1 | Edge: link came up |
| ETH_EVT_LINK_DOWN | 2 | Edge: link went down |
| ETH_EVT_AN_COMPLETE | 3 | BMSR.AN_COMPLETE latched in ISR |
| ETH_EVT_PAR_DETECT_FAULT | 4 | ANER.PAR_DETECT_FAULT observed |
| ETH_EVT_AUTODONE_TIMEOUT | 5 | Reserved for future bounded-poll fix; not emitted yet |
| ETH_EVT_INVALID_HCDSPEED | 6 | PSCSR.HCDSPEED resolved to a reserved value |
One slot of the per-minute error histogram. Counters are deltas for the
minute identified by minute_index (uptime_seconds / 60). The bucket
labelled "current_minute_index" in the parent message is still
accumulating; older buckets are closed and frozen.
| Field | Type | Label | Description |
| minute_index | uint32 | Uptime-minute when this bucket was opened |
|
| secr_count | uint32 | PHY SECR ticks during this minute |
|
| crc_count | uint32 | MAC RX CRC errors during this minute |
|
| miss_count | uint32 | DMA controller-side missed frames during this minute |
|
| rx_good_count | uint32 | MAC RX good frames during this minute — context for the error rates |
|
| tx_good_count | uint32 | MAC TX good frames during this minute — context for the error rates |
One row of the link-event ring buffer. Fixed-stride for simple parsing.
PHY register fields are uint32 only to widen nanopb varint encoding —
real values fit in 16 bits.
| Field | Type | Label | Description |
| uptime_seconds | uint32 | When the event was recorded (xTaskGetTickCount / configTICK_RATE_HZ) |
|
| kind | EthLinkEventKind | What happened |
|
| resolved_speed_mbps | uint32 | 0 / 10 / 100 — 0 means UNKNOWN at the time of the event |
|
| resolved_duplex | EthDuplexMode | Duplex resolved at the time |
|
| bmsr | uint32 | BMSR (PHY reg 0x01) at event time |
|
| anlpar | uint32 | ANLPAR(PHY reg 0x05) — what link partner advertised; 0x0000 => partner did not AN |
|
| aner | uint32 | ANER (PHY reg 0x06) — bit 4 PAR_DETECT_FAULT, bit 0 LP_AN_ABLE |
|
| pscsr | uint32 | PSCSR (PHY reg 0x1F) — bit 12 AUTODONE, bits 4:2 HCDSPEED |
Returned in response to AdminMessage{GET, ETHERNET_DIAGNOSTICS}.
All PHY register fields are live reads via MDIO at the moment of the
request (except SECR — symbol error count is self-clearing on read and
is accumulated in phy_symbol_errors_total).
MAC counters are the Ethernet MAC's MMC registers (32-bit, not self-clearing by
default on this build). They are absolute since power-on; clients should
take two snapshots and diff to get a rate. They WILL wrap eventually
(~8 hours at 100 Mbps line-rate of 64-byte frames).
| Field | Type | Label | Description |
| link_state | EthLinkState | ===== Resolved live link state ===== |
|
| link_speed_mbps | uint32 | 0 / 10 / 100 |
|
| duplex_mode | EthDuplexMode | Duplex mode now |
|
| neg_method | EthNegotiationMethod | Derived from BMCR/BMSR/ANER at fill-time |
|
| partner_an_capable | bool | ANER.LP_AN_ABLE |
|
| partner_adv_full_duplex | bool | ANLPAR.100BTX_FD || ANLPAR.10BT_FD |
|
| partner_adv_100mbps | bool | ANLPAR.100BTX_FD || ANLPAR.100BTX_HD |
|
| autodone | bool | PSCSR.AUTODONE |
|
| use_auto_negotiation_setting | bool | the user's auto-negotiation setting (what the user toggled) |
|
| bmcr | uint32 | 0x00 — AN_EN, SPEED_SEL, DUPLEX, RESTART_AN |
|
| bmsr | uint32 | 0x01 — LINK_STATUS, AN_COMPLETE, capabilities |
|
| phyid1 | uint32 | 0x02 — PHY ID 1 (identity high) |
|
| phyid2 | uint32 | 0x03 — PHY ID 2 (identity low) |
|
| anar | uint32 | 0x04 — what WE advertised |
|
| anlpar | uint32 | 0x05 — what PARTNER advertised |
|
| aner | uint32 | 0x06 — PAR_DETECT_FAULT, LP_AN_ABLE |
|
| mcsr | uint32 | 0x11 — EDPWRDOWN, ENERGYON |
|
| scsir | uint32 | 0x1B — AMDIX, polarity |
|
| pscsr | uint32 | 0x1F — AUTODONE, HCDSPEED |
|
| mac_tx_good_frames | uint32 | ETH_MMCTGFCR — successfully transmitted frames |
|
| mac_tx_single_collision | uint32 | ETH_MMCTGFSCCR — transmitted after one collision (HD only; non-zero on HD link is normal, non-zero on FD link => mismatch) |
|
| mac_tx_multi_collision | uint32 | ETH_MMCTGFMSCCR — transmitted after >1 collisions (HD only; very strong mismatch indicator on a FD partner) |
|
| mac_rx_good_frames | uint32 | ETH_MMCRGUFCR — received good unicast frames |
|
| mac_rx_crc_errors | uint32 | ETH_MMCRFCECR — CRC errors (cable, EMI, or duplex mismatch on FD side) |
|
| mac_rx_alignment_errors | uint32 | ETH_MMCRFAECR — frame alignment / dribble errors |
|
| dma_missed_frames_app | uint32 | ETH_DMAMFBOCR.MFA[27:17] — drops because the descriptor list was full (RX backlog) |
|
| dma_missed_frames_controller | uint32 | ETH_DMAMFBOCR.MFC[15:0] — drops because the RX FIFO was full |
|
| phy_symbol_errors_total | uint64 | Sum of PHY SECR (reg 0x1A) reads |
|
| link_up_count | uint32 | How many times the link came up since boot |
|
| link_down_count | uint32 | How many times the link dropped |
|
| par_detect_count | uint32 | Times ANER.PAR_DETECT_FAULT was latched |
|
| invalid_hcdspeed_count | uint32 | Times PSCSR.HCDSPEED came back as a reserved value (the invalid-operation-mode warning path) |
|
| autodone_timeout_count | uint32 | Times the post-link-event AUTODONE wait expired (currently a 2.5 s budget) |
|
| secr_saturation_count | uint32 | SECR (PHY reg 0x1A) is a 16-bit self-clearing counter. If the symbol error rate exceeds 65535 between successive drains, the register saturates at 0xFFFF and we lose count fidelity for the overflow. This counter increments every time we drain SECR and find exactly 0xFFFF — i.e. every time we know we under-counted. A non-zero value means the phy_symbol_errors_total / per-minute histogram are LOWER BOUNDS only. |
|
| uptime_seconds | uint32 | Seconds since boot, when this was read |
|
| peak_secr_per_tick | uint32 | ===== Burst tracking ===== Largest single-drain SECR value ever observed since boot. The diagnostics module drains SECR on a periodic timer (~4 Hz / 250 ms by default) AND on every PHY poll tick (~1 Hz). The field name is kept for wire compatibility; treat it as "peak_secr_per_drain". If this approaches 0xFFFF (= 65535) the chip saturated the counter and we lost precision — see secr_saturation_count. |
|
| current_minute_secr | uint32 | SECR count accumulated in the CURRENTLY-OPEN minute bucket (i.e. the bucket that will eventually be appended to `buckets` when the minute rolls). 0 to ~10s for a brand-new minute, up to ~1.8M/min at observed peak rates. |
|
| current_minute_index | uint32 | Uptime-minute index of the currently-open bucket — clients use this to know which minute the partial `current_minute_secr` belongs to. |
|
| events | EthLinkEventRecord | repeated | ===== Ring buffer of recent link-state transitions, oldest -> newest ===== |
| buckets | EthErrorHistogramBucket | repeated | ===== Per-minute error histogram, oldest -> newest ===== Each bucket is a closed (finalised) 1-minute window. The currently accumulating minute is exposed via current_minute_* above. Up to 30 minutes of history so you can leave the device running and see patterns (thermal drift, time-of-day EMI, traffic correlation). |
| phy_regs_all | uint32 | repeated | ===== Full Ethernet PHY register dump (live MDIO sweep) ===== 32 entries indexed by PHY register address (0..31). Reserved/unused registers will read back as 0 (or whatever the chip drives onto MDIO for those addresses). Included primarily for forensic comparison against the PHY datasheet when needed. |
Raw Phase-1 GPIO classification — TX/RX as input with internal pull-down, EN as
output low (DMX transceiver receive mode), 16 samples OR-folded over ~8 ms.
Multi-sampling matters: a single read of RX on a line being actively driven by an
external DMX master can land inside a BREAK or 0-bit and falsely report EMPTY.
OR-folding 16 samples across one DMX frame's worth of time guarantees we observe
at least one MARK state if the line is active.
Why each pattern occurs:
EMPTY: nothing fitted, internal pull-downs win on both pins
DALI_LIKE: TX pulled to ~2 V by the on-board 3V3 → opto-LED → R4 (390R) bleed-through
regardless of DALI bus state. RX may be 0 or 1 depending on whether the
DALI bus is energised — TX HIGH alone is enough to classify.
DMX_LIKE: DMX line transceiver receiver enabled (EN=LOW) drives R output push-pull HIGH via the
transceiver's internal fail-safe biasing on undriven A/B. TX stays LOW
because the D input is high-Z CMOS.
CAUTION: this pattern is ALSO matched by a DALI daughterboard whose TX
bleed-through path is broken (R4 open, TX-opto LED open, daughterboard
3V3 lost on the TX-side feed) while R2's RX pull-up is still alive — that
case is what `dmx_toggle` exists to disambiguate.
| Name | Number | Description |
| GPIO_PHASE1_UNKNOWN | 0 | Not run |
| GPIO_PHASE1_EMPTY | 1 | (TX, RX) = (0, 0) |
| GPIO_PHASE1_DALI_LIKE | 2 | (TX, RX) = (1, X) |
| GPIO_PHASE1_DMX_LIKE | 3 | (TX, RX) = (0, 1) |
DALI active self-echo probe (~13 ms total, GPIO-only). Drives TX HIGH (DALI idle),
settles 10 ms (covers worst-case ~9 ms DALI bus rise time on fully-loaded buses),
reads RX. Then TX LOW for ~200 µs (active sink — well below any DALI receiver's
frame-start threshold so no devices misinterpret it) and reads RX. Then TX HIGH
again and reads RX. A healthy DALI board on a powered (~16 V) bus shows the
sequence (rx_idle=0, rx_during=1, rx_after=0) because the receive opto's
conduction tracks bus voltage.
PASS is a UNIQUELY POSITIVE identification of a healthy DALI loop on a powered bus
— no other fitted hardware can produce this echo pattern. Always run regardless of
Phase 1's classification so cross-checking can catch P1 misclassifications.
FAIL does NOT localise to a specific failure — could be a damaged DALI board, an
unpowered/disconnected DALI bus, a shorted bus, or a non-DALI daughterboard.
SKIPPED means the echo did not run. Two causes, distinguishable by the rest of the
entry:
- RX was observed toggling in the ~1 ms pre-check immediately before this phase,
i.e. an external DMX master is transmitting. Driving TX into a line another
transmitter owns is unsafe, and the result would be meaningless anyway: a BREAK
sampled as rx_idle followed by a data MARK can forge the (0, 1, 0) signature.
Here gpio_phase1 and verdict still carry real results.
- The whole probe was skipped because the line was locked by DALI or RDM traffic.
Here gpio_phase1 and verdict are both UNKNOWN and every phase reads SKIPPED.
To rule out the forged-signature case the echo is repeated three times back-to-back
and only reports PASS when all three agree.
| Name | Number | Description |
| DALI_ECHO_UNKNOWN | 0 | Not run |
| DALI_ECHO_PASS | 1 | The frame sent came back on RX: a working DALI interface |
| DALI_ECHO_FAIL | 2 | Nothing came back |
| DALI_ECHO_SKIPPED | 3 | External transmitter seen on RX, or the whole probe was skipped (line busy) |
DMX EN-toggle probe (~7 ms total, GPIO-only). Holds TX OUTPUT HIGH (so if the driver
were enabled it would output DMX idle A=HIGH/B=LOW — minimally disruptive), RX as
input pull-down. EN goes LOW (receiver enabled) then HIGH (receiver disabled, driver
briefly enabled for ~10 µs) then back LOW. Only a real DMX transceiver R output transitions
from push-pull HIGH → high-Z in this sequence. A DALI board's RX is held HIGH by R2
(4k7 to on-board 3V3) regardless of EN, so it gets stuck HIGH on both reads. Empty
slot reads (0, 0).
PASS is a UNIQUELY POSITIVE identification of a working DMX receiver — no other
fitted hardware can produce the high→high-Z transition. Always run regardless of
Phase 1's classification so cross-checking can catch P1 misclassifications.
SKIPPED has three causes:
- dali_echo already returned PASS. The board is positively identified as DALI and
the verdict no longer depends on this phase, so it is not run.
- RX was observed toggling (active external master) during the ~1 ms pre-check run
immediately before this phase. Skipping protects against driving the line into
contention with an external master mid-frame.
- The whole probe was skipped because the line was locked by DALI or RDM traffic,
in which case verdict is UNKNOWN and every phase reads SKIPPED.
| Name | Number | Description |
| DMX_TOGGLE_UNKNOWN | 0 | Not run |
| DMX_TOGGLE_SKIPPED | 1 | DALI already confirmed, external transmitter on RX, or whole probe skipped (line busy) |
| DMX_TOGGLE_PASS | 2 | (rx_low=1, rx_high=0) — confirmed DMX receiver |
| DMX_TOGGLE_FAIL_STUCK_HIGH | 3 | (rx_low=1, rx_high=1) — something pulls RX HIGH regardless of EN (most-likely DALI R2) |
| DMX_TOGGLE_FAIL_STUCK_LOW | 4 | (rx_low=0, rx_high=0) — no driver on RX |
| DMX_TOGGLE_FAIL_INVERTED | 5 | (rx_low=0, rx_high=1) — unexpected; investigate hardware |
DMX passive listen (~50 ms). Decodes the USART RXNE/FE/ORE stream while EN=LOW, looking
for the DMX512 framing signature — a BREAK (which surfaces as a single framing error)
followed by a 0x00 NULL start code and slot data. Only runs
when the line's USART is already enabled (i.e. configured DMX or DMX_IN) — for other
configurations the USART for that slot is not clocked, and reconfiguring it from a
diagnostic call would be invasive. Also skipped once dali_echo has returned PASS:
the board is identified and this window would only delay the response.
| Name | Number | Description |
| DMX_LISTEN_UNKNOWN | 0 | Not run |
| DMX_LISTEN_SKIPPED | 1 | USART not configured for this line, DALI already confirmed, or whole probe skipped (line busy) |
| DMX_LISTEN_QUIET | 2 | Zero events in window — line is electrically clean |
| DMX_LISTEN_ACTIVE | 3 | Events seen but not validated as DMX — could be an external master we did not catch a BREAK from, or a transceiver fault |
| DMX_LISTEN_DMX_VALID | 4 | Coherent DMX512 stream validated: BREAK -> 0x00 start code -> slots |
Synthesized verdict from (configured_as, gpio_phase1, dali_echo, dmx_toggle, dmx_listen).
Verdict logic prefers the strongest positive signal:
1. dali_echo == PASS → DALI confirmed (regardless of P1)
2. dmx_toggle == PASS → DMX confirmed (regardless of P1)
3. dmx_listen == DMX_VALID → a coherent DMX512 stream is positive proof of a working
receive path, obtained passively. Ranks below the EN-toggle, which proves the
control path as well, but above any P1 inference.
4. none of those → fall back to P1 + the FAIL/SKIPPED context
This protects against P1 misclassifications — e.g. a damaged DMX board whose TX pin
leaks high reads as DALI_LIKE under P1, but the EN-toggle correctly identifies it.
Failure modes deliberately NOT distinguished by this verdict (firmware can't see them
from the three pins available): DALI bus open vs. shorted; DALI cable mis-wired into
a DMX board (looks like quiet DMX); DMX cable mis-wired into a DALI board (looks
like unpowered DALI bus); DMX board with lost on-board 3V3 (looks like EMPTY unless
the operator configured the slot as DMX, in which case EMPTY_OR_UNPOWERED_BOARD).
| Name | Number | Description |
| LINE_VERDICT_UNKNOWN | 0 | No verdict (probe not run) |
| LINE_VERDICT_EMPTY | 1 | Slot empty; matches configured EMPTY/AUTO. Nothing to investigate. |
| LINE_VERDICT_EMPTY_OR_UNPOWERED_BOARD | 2 | Operator configured DALI/DMX but all probes returned negative. Either no board fitted, on-board 3V3 lost, or transceiver IC dead. |
| LINE_VERDICT_DALI_OK_BUS_POWERED | 3 | DALI board + DALI bus both verified healthy by echo. |
| LINE_VERDICT_DALI_PRESENT_BUS_UNVERIFIED | 4 | Phase 1 saw DALI TX bleed-through but the echo failed. Bus is open / shorted / not energised — connect a DALI PSU and retry. |
| LINE_VERDICT_DMX_OK | 5 | DMX board confirmed via EN-toggle, line quiet (or USART not yet running). |
| LINE_VERDICT_DMX_PRESENT_ACTIVE_TRAFFIC | 6 | DMX board confirmed via EN-toggle, external traffic seen on bus. |
| LINE_VERDICT_BOARD_PRESENT_TYPE_AMBIGUOUS | 7 | Phase 1 looked DMX-like but the EN-toggle said NOT a DMX receiver and the DALI echo also failed. Most-likely a TX-broken DALI board (R4 / TX opto LED open) with R2 still pulling RX up. Replace daughterboard. |
| LINE_VERDICT_MISCONFIGURED_LIKELY_DMX | 8 | Configured type ≠ DMX, but EN-toggle confirms a DMX board is fitted. Reconfigure to DMX. |
| LINE_VERDICT_MISCONFIGURED_LIKELY_DALI | 9 | Configured type ≠ DALI, but DALI echo confirms a healthy DALI board on a powered bus. Reconfigure to DALI. |
| LINE_VERDICT_MISCONFIGURED_OTHER | 10 | Configured ≠ probed and no active probe gave a confident positive identification. Investigate cabling + board fit. |
| LINE_VERDICT_FAULT | 11 | Probes returned a pattern that does not match any healthy configuration (e.g. P1 says DALI_LIKE but every other probe disagrees). Likely a damaged daughterboard. |
How sure a line diagnostic verdict is.
| Name | Number | Description |
| LINE_CONFIDENCE_UNKNOWN | 0 | No verdict, so no confidence |
| LINE_CONFIDENCE_LOW | 1 | Verdict relies on inference the firmware cannot directly verify (e.g. EMPTY vs unpowered board) |
| LINE_CONFIDENCE_MEDIUM | 2 | Verdict is consistent with the probes but one or more came back SKIPPED / ambiguous |
| LINE_CONFIDENCE_HIGH | 3 | All probes that ran agree, in a pattern that uniquely identifies the verdict |
One per physical line slot. All four raw probe results are reported alongside the
synthesized verdict so a UI can show "why" the verdict was reached.
| Field | Type | Label | Description |
| line_index | uint32 | 0-based; 0..LINE_COUNT-1 for the current hardware variant |
|
| configured_as | LineType | The configured type for this line |
|
| gpio_phase1 | GpioPhase1Result | Phase-1 (TX, RX) classification after multi-sample OR-fold |
|
| dali_echo | DaliEchoResult | Active DALI self-echo (always run) |
|
| dmx_toggle | DmxToggleResult | EN-toggle DMX-receiver presence test (always run unless RDM busy or external traffic observed) |
|
| dmx_listen | DmxListenResult | Passive ~50 ms USART listen, validated against DMX512 framing (only when line's USART is enabled) |
|
| verdict | LineDiagnosticVerdict | Highest-information verdict; see enum comment |
|
| confidence | LineDiagnosticConfidence | How much to trust `verdict` |
Per-line diagnostic snapshot. Returned in response to AdminMessage{GET, LINE_DIAGNOSTICS}.
All four probes run on every line (with safety-skip on P3/P4 if RDM is active or
external traffic is detected). Per-line wall time: ~33 ms typical, ~88 ms when P4
runs. Total message wall time: bounded under 400 ms on any hardware variant. Not
safe to spam from a hot loop.
| Field | Type | Label | Description |
| lines | LineDiagnosticEntry | repeated | One entry per physical line slot, in line-index order |
| uptime_seconds | uint32 | Seconds since boot — context for the probe (e.g. very-recent boot may not have stable bus state yet) |
Which clock drives the RTC. UNKNOWN should not appear in a healthy device.
| Name | Number | Description |
| CLOCK_SOURCE_UNKNOWN | 0 | Not reported (older firmware, or not measured yet) |
| CLOCK_SOURCE_LSE | 1 | 32.768 kHz external crystal (default) |
| CLOCK_SOURCE_LSI | 2 | Internal RC oscillator (less accurate fallback) |
Outcome of the software LSE-vs-HSE ppm measurement.
| Name | Number | Description |
| LSE_MEAS_NOT_RUN | 0 | Never measured (default after boot, before first probe) |
| LSE_MEAS_OK | 1 | Window completed cleanly |
| LSE_MEAS_LSE_DEAD | 2 | SSR never advanced — crystal silent |
| LSE_MEAS_HSE_UNSTABLE | 3 | HSE drifted during the window — measurement invalid |
| LSE_MEAS_INSUFFICIENT_TIME | 4 | dwt_delta too small to resolve |
Origin of the most-recent RTC write. Used by clients to distinguish drift
(no recent write) from operator action (recent NETWORK_ADMIN / MENU write).
| Name | Number | Description |
| TIME_SET_NEVER | 0 | Clock has never been set since the last battery loss |
| TIME_SET_FACTORY | 1 | Reserved — not currently emitted |
| TIME_SET_MENU | 2 | Set via the on-device menu / debug helper |
| TIME_SET_NETWORK_LEGACY | 3 | UpdateTimeMessage (top-level update_time) |
| TIME_SET_NETWORK_ADMIN | 4 | AdminPropertyType DEVICE_TIME SET |
| TIME_SET_NTP | 5 | NTP success path |
| TIME_SET_BACNET | 6 | BACnet TimeSync (local or UTC) |
| TIME_SET_DST_ADJUST | 7 | Automatic DST hour-boundary fixup |
Inferred from start_day / end_day of the configured DST window.
| Name | Number | Description |
| DST_HEMISPHERE_UNKNOWN | 0 | DST disabled in config |
| DST_HEMISPHERE_NORTHERN | 1 | start_day < end_day (DST contained within one calendar year) |
| DST_HEMISPHERE_SOUTHERN | 2 | start_day > end_day (DST wraps across the new year) |
What the next DST transition will do.
| Name | Number | Description |
| DST_TRANSITION_NONE | 0 | DST disabled or no transition scheduled |
| DST_TRANSITION_ENTER | 1 | Spring forward (gain an hour) |
| DST_TRANSITION_LEAVE | 2 | Fall back (lose an hour) |
Single entry in the recent-NTP-sync ring buffer. RAM-only on the device
(lost on reboot), populated in chronological order: oldest → newest.
| Field | Type | Label | Description |
| unix_time | uint32 | Y2K-relative seconds at the moment of acceptance |
|
| correction_seconds | sint32 | server - rtc, before stepping (signed) |
|
| rtt_ms | uint32 | Request → response round-trip |
|
| stratum | uint32 | From NTP packet[1] (1-15 valid) |
Returned in response to AdminMessage{GET, TIME_DIAGNOSTICS}.
Performs a fresh ~250 ms LSE-vs-HSE ppm measurement on every call unless
the caller recently issued AdminPropertyType_TIME_DIAG_MEASURE_LSE (RUN),
in which case the cached result is returned. Otherwise side-effect-free.
===== Clock source identity & health =====
| Field | Type | Label | Description |
| rtc_clock_source | ClockSource | LSE / LSI / UNKNOWN |
|
| lse_ready_now | bool | RCC->BDCR.LSERDY at read time |
|
| lse_css_enabled | bool | RCC->BDCR.LSECSSON |
|
| lse_css_fault_latched | bool | RCC->BDCR.LSECSSD — sticky once tripped |
|
| nominal_lse_hz | uint32 | 32768 |
|
| hse_hz | uint32 | SystemCoreClock (reference rate) |
|
| measurement_status | ClockMeasurementStatus | ===== Independent frequency measurement ===== |
|
| measured_lse_ppm_error | sint32 | (measured - 32768) ppm |
|
| measurement_window_us | uint32 | Actual elapsed window |
|
| measurement_dwt_delta | uint32 | Raw HCLK cycles in the window |
|
| measurement_rtc_subsec_delta | uint32 | Raw SSR ticks in the window |
|
| applied_ppm_correction | float | Active RTC ppm calibration value at read time |
|
| temperature_at_last_calibration | float | Internal MCU temp °C at last hour-boundary call |
|
| smooth_calib_period_seconds | uint32 | 32 seconds |
|
| rtc_temp_comp_enabled | bool | Persisted action-knob state |
|
| rtc_ppm_manual_override_enabled | bool | Persisted action-knob state |
|
| rtc_ppm_manual_override_value | sint32 | Persisted action-knob state |
|
| ntp_enabled_in_config | bool | NTP enabled in config |
|
| ntp_server_hostname | string | From config (max_size enforced in .options) |
|
| ntp_sync_success_count | uint32 | Lifetime, persisted |
|
| ntp_sync_failure_count | uint32 | Lifetime, persisted |
|
| last_ntp_success_unix | uint32 | 0xFFFFFFFF means never (Y2K epoch) |
|
| last_ntp_attempt_unix | uint32 | Either success or failure (Y2K epoch) |
|
| last_ntp_correction_seconds | sint32 | Signed: server - rtc at last success |
|
| last_ntp_rtt_ms | uint32 | Round-trip of last attempt |
|
| last_ntp_stratum | uint32 | Stratum of last successful response |
|
| effective_ntp_poll_period_seconds | uint32 | ntp_poll_period_seconds override if set, else config NTPTimeout |
|
| ntp_max_acceptable_delta_seconds | uint32 | The rejection threshold currently in force |
|
| last_ntp_error | string | Last NTP error string (max 32 chars) |
|
| ntp_history | NtpSyncRecord | repeated | Oldest → newest, RAM only |
| rtc_unix_epoch_now | uint32 | Y2K seconds at read time |
|
| rtc_subseconds_now | uint32 | RTC->SSR snapshot |
|
| rtc_advancing | bool | SSR observed to change during a 200 µs probe |
|
| last_boot_lost_backup | bool | backup-domain canary was clear at this boot's start |
|
| boots_since_last_backup_loss | uint32 | Persisted, bumped each boot when canary valid |
|
| rtc_ever_been_set | bool | True once any non-DST set has occurred since loss |
|
| vbat_voltage | float | Backup battery voltage |
|
| vbat_low | bool | backup battery voltage below the low-battery threshold |
|
| dst_enabled_in_config | bool | ===== DST visibility ===== |
|
| dst_currently_active | bool | DST store flag active |
|
| dst_offset_seconds | sint32 | -3600 / 0 / +3600 |
|
| dst_last_transition_unix | uint32 | 0 until first observed transition (Y2K epoch) |
|
| dst_next_transition_unix | uint32 | Computed forward from current date |
|
| dst_next_transition_type | DstTransitionType | Whether the next daylight-saving change starts or ends DST |
|
| dst_hemisphere | DstHemisphere | Hemisphere the DST rules were worked out for |
|
| total_time_set_count | uint32 | Lifetime, persisted |
|
| last_time_set_unix | uint32 | Y2K seconds of the last set |
|
| last_time_set_source | TimeSetSource | What set the clock last |
|
| last_manual_set_delta_seconds | sint32 | (new - old) at the last non-NTP, non-DST set |
|
| uptime_seconds | uint32 | Seconds since boot, when this was read |
Which flag of the storage SPI bus stalled. The
distinction matters: on a TXE stall nothing was clocked out (a resend would
have been safe), whereas on BSY or RXNE the byte was already sent (a resend
would have corrupted the frame). The firmware discards in both cases.
| Name | Number | Description |
| SPI2_STALL_NONE | 0 | No stall has occurred since boot |
| SPI2_STALL_TXE | 1 | TX buffer never emptied - byte not sent |
| SPI2_STALL_BSY | 2 | Peripheral stayed busy - byte was sent |
| SPI2_STALL_RXNE | 3 | RX buffer never filled - byte was sent |
Storage subsystem health. Returned for AdminMessage{GET, STORAGE_DIAGNOSTICS}.
Scope is the storage SPI bus and every device on it - the SD card, the NOR
flash and the IO expander share the bus, so one device wedging it takes the
others down. The bus fields come first because they are the context the device
fields are read in.
All counters are absolute since boot, never cleared; diff successive GETs for
a rate. Only the four sd_*_abort_* counters saturate at 0xFFFFFFFF (a value
there is a lower bound); the rest are plain 2^32 wraps.
Side-effect-free: every field is a RAM latch, nothing probes the bus, so this
is safe to poll.
===== Roll-up =====
| Field | Type | Label | Description |
| storage_healthy | bool | False if the bus is suppressed, the NOR has a latched or presence fault, or a fitted SD card is failing health checks. A convenience only - every input is also present below. The mount-cycle counters and sd_cd_hint do not feed it: they are history and pin state, not present health. |
|
| spi2_suppressed | bool | True while the bus is suppressed after a stall the driver could not clear. Read before any nor_* field: while suppressed, transfers return 0x00 instead of failing, so every nor_* value below is stale (the last latched before suppression) and should be shown as unknown, not healthy. The spi2_* counters stay valid - they are what suppressed the bus. |
|
| spi2_stall_txe_count | uint32 | Stalls where TXE never set |
|
| spi2_stall_bsy_count | uint32 | Stalls where BSY never cleared |
|
| spi2_stall_rxne_count | uint32 | Stalls where RXNE never set |
|
| spi2_last_stall | Spi2StallType | Kind of the most recent stall |
|
| spi2_reset_count | uint32 | Times the driver reset the SPI peripheral |
|
| nor_fault_active | bool | Sticky since boot: the part latched a program/erase error or the boot presence probe rejected it - the NOR itself is suspect. Not set by a suppressed bus (that is a bus property, reported by spi2_suppressed); stays valid as history while suppressed, just stops updating. |
|
| nor_fault_count | uint32 | Program/erase operations that did not complete cleanly. Two causes: the part latched E_ERR/P_ERR, or the operation was attempted while the bus was suppressed and the bytes never left the MCU. Only the first sets nor_fault_active/nor_fault_last_status, so a non-zero count with both of those clear means "attempted while the bus was down", not a failing part. |
|
| nor_fault_last_status | uint32 | The NOR's status register 1 byte that carried the error bits (0 if none): bit5 (0x20) = E_ERR erase failed, bit6 (0x40) = P_ERR program failed. |
|
| nor_presence_fault | uint32 | Boot probe cause bitmask, latched once and never re-probed. 0 healthy, bit0 (0x01) RDID absent or wrong part, bit1 (0x02) CR1 TBPARM set (parameter block not at the bottom). Mutually exclusive - CR1 is trusted only once the part identifies as ours - so 0x03 cannot occur. |
|
| sd_supported | bool | False on variants with no SD socket. Without it, every field below reads 0 and is indistinguishable from a fitted card sitting idle. |
|
| sd_mounted | bool | The SD card is mounted and usable |
|
| sd_last_probe_r1 | uint32 | Raw R1 from the last CMD0 probe - keeps the absent vs present-and-faulty distinction the mount result loses. 0xFF nothing answered: no card fitted, no probe run yet, or the bus suppressed (check spi2_suppressed before wording this one). 0x01 a card in idle state. Healthy. bit7 set but not 0xFF: no valid R1 received; the low bits are bus noise. otherwise a present card that answered with error bits set. SD spec 7.3.2.1: bit6 erase reset, bit5 illegal command, bit4 CRC error, bit3 erase sequence error, bit2 address error, bit1 parameter error. |
|
| sd_block_abort_rx | uint32 | Blocks abandoned by the per-block deadline, and operations abandoned by the per-operation deadline (refused at entry, or cut short mid-transfer). All four are deadline aborts, not media errors; FatFs reports both as FR_DISK_ERR and these counters are the only thing that tells them apart. |
|
| sd_block_abort_tx | uint32 | Blocks abandoned while writing (see sd_block_abort_rx) |
|
| sd_op_abort_entry | uint32 | Operations refused at entry by the per-operation deadline |
|
| sd_op_abort_mid | uint32 | Operations cut short mid-transfer by the per-operation deadline |
|
| sd_unsafe_delete_count | uint32 | Deletions that proceeded without the guarantee the safe path provides. |
|
| sd_consecutive_health_failures | uint32 | Consecutive failed CMD13 health checks on the mounted card. Reaching the firmware's threshold unmounts the volume, so a persistently non-zero value below it means a card answering intermittently - the state that precedes an unexplained unmount. |
|
| sd_recovery_consecutive_failures | uint32 | Power-cycle escalation while the card is unmounted: consecutive failed SPI probes, and the count the next rail drop needs. The threshold doubles after every drop, so it also reports how many have happened (first-rung = none). |
|
| sd_recovery_failures_needed | uint32 | Failed probes the next power cycle of the card needs (see sd_recovery_consecutive_failures) |
|
| sd_total_bytes | uint64 | Volume capacity as last measured by f_getfree(). total_bytes = 0 on a mounted card means capacity has never been measured (every f_getfree() since the mount failed), not that the card is empty - the same condition SD_CAPACITY_UNKNOWN reports, and while it holds size-based log retention cannot run. |
|
| sd_free_bytes | uint64 | Free space, as last measured (see sd_total_bytes) |
|
| sd_mount_attempts | uint32 | ===== Mount cycle history - monotonic since boot, never reset ===== Counted at the sole f_mount site, so the boot mount is included. Read attempts and successes as a pair: alone they cannot be interpreted (a card reinserted often and one that never mounts both climb). Attempts rising with successes stuck at zero is a card that answers CMD0 but whose filesystem will not mount - no other field moves, because the probe is succeeding and the power-cycle escalation never arms. |
|
| sd_mount_successes | uint32 | Mounts that succeeded (read with sd_mount_attempts) |
|
| sd_unmount_count | uint32 | Confirmed removals (enough consecutive CMD13 failures for the firmware to unmount). The only durable record that a removal happened: sd_consecutive_health_failures resets on the unmount it triggers, so a client polling slower than the health check would miss it. A non-zero value with sd_mounted true means the card is up now but has been up and down. |
|
| sd_mount_deferred_lock_busy | uint32 | Mounts abandoned before f_mount because the volume lock was still held. Not a media fault, and not counted as an attempt: another task held the filesystem longer than the firmware would wait, usually the NOR on the shared SPI bus. Expected near zero; a large value points at bus contention, so read it against the spi2_* counters. |
|
| sd_cd_hint | bool | ===== Card detect pin ===== The debounced CD switch, sampled every 10 ms. Advisory only - it is a mechanical switch, not a presence answer; mount authority rests entirely on whether the card answers CMD0. Never label it "card present" in a UI. These switches fail in both directions on this hardware, so the value is only useful cross-checked against the authoritative fields: true + sd_last_probe_r1 == 0xFF -> switch stuck closed, or an empty socket reading as occupied (check spi2_suppressed, also 0xFF). false + sd_mounted true -> switch stuck open. The card works only because the firmware probes on a timer; insertion is detected late (~1 s) in this state. False before the debounce settles (30 ms from boot), long resolved by the time any client can ask - no "never sampled" ambiguity to allow for. |
|
| sd_cid_valid | bool | ===== Card identity (CID register, SD spec 5.2) ===== Read once per mount by a single CMD10, then cached (this message never touches the bus); cleared on unmount, so the identity always belongs to the mounted card. Check sd_cid_valid first - every field below is meaningless without it, and an unvalidated identity is worse than none: the read discards the CRC16, so a marginal SPI joint yields a plausible-looking name rather than an obvious failure. The flag covers CRC7 plus the all-zero/all-ones idle-bus patterns (CRC7 has a fixed point at zero, so a blank register passes its checksum). |
|
| sd_cid_manufacturer_id | uint32 | Manufacturer ID. Raw on purpose: MIDs are allocated privately by SD-3C LLC with no public registry, so every MID-to-name table is guesswork. Display as hex; use oid/pnm for the readable identity. |
|
| sd_cid_oem_id | string | OID, 2 ASCII chars |
|
| sd_cid_product_name | string | PNM, 5 ASCII chars |
|
| sd_cid_revision_major | uint32 | PRV, two BCD nibbles. Present as "major.minor", not a single number. |
|
| sd_cid_revision_minor | uint32 | Product revision, minor part (see sd_cid_revision_major) |
|
| sd_cid_serial | uint32 | PSN, 32-bit binary. Display as hex. |
|
| sd_cid_mdt_year | uint32 | MDT. Year is absolute (the device already applied the spec's 2000 offset). Month is 1-based; 0 or >12 means the card encoded an out-of-spec value, passed through rather than clamped. |
|
| sd_cid_mdt_month | uint32 | Manufacturing month, 1-12 (see sd_cid_mdt_year) |
|
| uptime_seconds | uint32 | Seconds since boot, when this was read |
What is powering a DALI line's bus. Used with DaliLineStatus
| Name | Number | Description |
| DALI_BUS_POWER_UNKNOWN | 0 | Not reported by this firmware |
| DALI_BUS_POWER_NONE | 1 | No supply on the bus |
| DALI_BUS_POWER_EXTERNAL | 2 | An external DALI bus supply |
| DALI_BUS_POWER_INTERNAL | 3 | The device's own bus supply for this line |
| DALI_BUS_POWER_SHORT | 4 | Bus held low while powered: own supply removed. Latched until the bus is seen high again or the supply is re-enabled |
Per-line DALI health snapshot. Mirrors one line of the device's
DALI status structure. Short-address bitmaps use bit n = DALI short address n.
| Field | Type | Label | Description |
| line_index | uint32 | 0-based physical DALI line index |
|
| device_count | uint32 | Devices currently online (popcount of the poll mask) |
|
| fault_count | uint32 | Devices on this line reporting a lamp or gear fault |
|
| bus_power_error | bool | TRUE if the DALI bus itself is down (debounced) |
|
| lowest_fault_address | uint32 | Lowest DALI short address with a fault (0xFF = none) |
|
| missing_devices_mask | uint64 | Latching bitmap of devices that failed retries (gone silent). JS_STRING so JS clients keep full 64-bit precision (a JS number loses bits above 2^53). |
|
| comms_error_mask | uint64 | Bitmap of devices present but returning corrupted responses. JS_STRING so JS clients keep full 64-bit precision (a JS number loses bits above 2^53). |
|
| bus_power | DaliBusPower | What is powering the bus. Live, whatever polling_active says |
|
| short_count | uint32 | Shorts detected on this line since boot |
|
| dual_supply_count | uint32 | Own and external supply found together (own one then removed), since boot |
DALI system status summary. Returned in response to AdminMessage{GET, DALI_STATUS}.
Read-only mirror of the device's DALI system status — the
same structure the on-device Logic system evaluates for "any DALI error" actions.
| Field | Type | Label | Description |
| lines | DaliLineStatus | repeated | One entry per configured DALI line, in line-index order |
| any_system_fault | bool | Global flag: TRUE if any line has any fault |
|
| polling_active | bool | FALSE if DALI polling is disabled (dali_polling_interval == 0). When FALSE the per-line data is NOT live — a clean report means "not being monitored", not "no faults". Clients (e.g. a BMS) must check this before trusting any_system_fault. Each line's bus_power, short_count and dual_supply_count are live even when FALSE. |
The property an AdminMessage targets. Each value lists its commands, the AdminMessage field its value travels in (Payload), and the login role it needs.
| Name | Number | Description |
| DEVICE_NAME | 0 | The device name that appears on the network. Limited to 16 characters. Commands: GET, SET. Payload: data.string_data. Role: CONFIG. Devices: eDIDIO, ADDICT. |
| PROJECT_NAME | 1 | Used for documentation. Limited to 32 characters. Commands: GET, SET. Payload: data.string_data. Role: CONFIG. |
| LONGITUDE | 2 | Used for calculating astronomical sunrise / sunset. Commands: GET, SET. Payload: data.float_data. Role: CONFIG. |
| LATITUDE | 3 | Used for calculating astronomical sunrise / sunset. Commands: GET, SET. Payload: data.float_data. Role: CONFIG. |
| LOCAL_UTC_OFFSET | 4 | Used for calculating astronomical sunrise / sunset. Commands: GET, SET. Payload: data.float_data. Role: CONFIG. |
| DAYLIGHT_SAVINGS | 5 | Used for calculating astronomical sunrise / sunset. Commands: GET, SET. Payload: data.uint_data. Role: CONFIG. |
| POLL_ACTIVE | 6 | Whether or not to poll the current level of DALI devices to keep an in-memory cache up-to-date. Commands: GET, SET. Payload: data.uint_data. Role: CONFIG. |
| DHCP_ENABLED | 7 | Whether or not the device should use a static IP or expect a DHCP server to provide it with an IP. Commands: GET, SET. Payload: data.uint_data. Role: ADMIN. |
| IP_ADDR | 8 | The static IP address to use if DHCP_ENABLED is FALSE. Commands: GET, SET. Payload: data.string_data. Role: ADMIN. |
| MAC_ADDR | 9 | The MAC Address of the device. Expected format: [40:D8:55:1B:XX:XX]. Commands: GET, SET. Payload: data.string_data. Role: ADMIN. |
| GATEWAY_IP | 10 | The IP address of the gateway for the network this device will be installed on. Commands: GET, SET. Payload: data.string_data. Role: ADMIN. |
| NETWORK_PROPERTIES | 11 | Contains numerous properties such as DHCP, NTP, Gateway, IP, MAC. Commands: GET, SET. Payload: network_properties. Role: ADMIN. Devices: eDIDIO, ADDICT. |
| SYSTEM_PROPERTIES | 12 | Contains numerous properties such as Device Name (documentation only; not network hostname), Project Name, Latitude, Longitude, UTC Offset, DLS, Polling. Commands: GET, SET. Payload: project_properties. Role: CONFIG. |
| CONTROLLER_LINES | 13 | Allows you to specify the daughterboards installed in the device [NONE, DALI, DMX, DMX_IN]. Commands: GET, SET. Payload: controller_lines. Role: CONFIG. |
| EEPROM_FULL_CHIP | 14 | Allows you to request a reset to default values for all data stored in EEPROM. Commands: RESET. Payload: none. Role: ADMIN. |
| CONFIG_DATA | 15 | Allows you to request a reset to default values for the Config Data stored in EEPROM. Commands: RESET. Payload: none. Role: ADMIN. |
| SPEKTRA_DATA | 16 | Allows you to request a reset to default values for the Spektra Data stored in EEPROM. Commands: RESET. Payload: none. Role: ADMIN. |
| DEVICE_STATUS | 17 | Can be used to request the Device Status: Temperature and Battery Voltage. Commands: GET. Payload: device_status. Role: CONTROL. Devices: eDIDIO, ADDICT. |
| CONFIG_STATUS | 18 | Can be used to request the Config Status: Active Alarm, List States, Sensor States, Burn-in States. Commands: GET. Payload: config_status. Role: CONTROL. |
| DEVICE_TIME | 19 | Get or Set the RTC time on the device. Commands: GET, SET. Payload: device_time. Role: CONTROL for GET, CONFIG for SET. |
| NTP_DETAILS | 20 | Allows you to Get or Set the NTP parameters (i.e. NTP Server) used for maintaining the RTC via NTP updates. Commands: GET, SET. Payload: network_properties. Role: CONFIG. |
| DALI_SENSORS | 21 | Provides actions for DALI Sensor control: "ADD" to un-mute all. "REMOVE" to mute all. "RESET" to clear all (unprogram). Commands: ADD, REMOVE, RESET. Payload: none. Role: CONFIG. |
| SECURE_SESSION | 22 | Allows you to Get or Set the "Secure Session" status of the device. Commands: GET, SET. Payload: data.uint_data. Role: CONTROL for GET, ADMIN for SET. |
| NONCE | 23 | Allows you to request a Nonce to perform a Secure Login. Commands: GET. Payload: data.string_data. Role: NONE. |
| DALI_SENSOR_TYPE | 24 | The type of DALI frame (24 or 25-bit) for eDALI packets to/from motion sensors. Commands: GET. Payload: dali_sensor_type. Role: CONFIG. |
| DEVICE_REBOOT | 25 | Will reboot the device when used with the 'RUN' AdminCommandType. Commands: RUN. Payload: none. Role: ADMIN. Devices: eDIDIO, ADDICT. |
| SYSTEM_LOGGING | 26 | Will reset the system logs when used with a 'RESET' AdminCommandType. Commands: GET, RESET. Payload: data.uint_data. Role: CONFIG. |
| SUBNET | 27 | The Subnet of the Device. Commands: GET, SET. Payload: data.string_data. Role: ADMIN. |
| DNS | 28 | The Primary and Secondary DNS, both ways in dns_servers. eDIDIO firmware before 1.6.3 refused a SET with INVALID_PARAMS and answered a GET in the wrong arm - use NETWORK_PROPERTIES (DNS_Primary / DNS_Secondary) for those. Commands: GET, SET. Payload: dns_servers. Role: ADMIN. |
| LINK | 29 | Whether or not the UDP Link state is active. Commands: GET, SET. Payload: data.uint_data. Role: ADMIN. |
| LINK_TYPE | 30 | Type of Link to enable, based on ReadType. Commands: GET, SET. Payload: data.uint_data. Role: ADMIN. |
| LINK_MASK | 31 | Link Index Mask for above. Commands: GET, SET. Payload: data.uint_data. Role: ADMIN. |
| LINK_NETMASK | 32 | Netmask for Link to create Network groups for UDP messaging. Commands: GET, SET. Payload: data.uint_data. Role: ADMIN. |
| DALI_RX_TOLERANCE | 33 | The tolerance for DALI RX (where 10 is 10% above and below nominal half bit time of 416us). Commands: GET, SET. Payload: data.uint_data. Role: CONFIG. |
| DALI_TX_HALF_BIT_TIME | 34 | Default value is 416us. Commands: GET, SET. Payload: data.uint_data. Role: CONFIG. |
| DMX_TIMING | 35 | DMX Timing (I.e. 44Hz). Commands: GET, SET. Payload: dmx_timing_mode. Role: CONFIG. Devices: eDIDIO, ADDICT. |
| DMX_PROPERTIES | 36 | DMX Line Properties. Channel Mapping, 16 bit, slot count. Commands: GET, SET. Payload: dmx_line_props. Role: CONFIG. Devices: eDIDIO, ADDICT. |
| MEMORY_DIAGNOSTICS | 37 | GET-only. Returns per-task stack high-water-marks, system-stack HWM, and SRAM/CCMRAM static-section usage. Use with the 'GET' AdminCommandType. Used for tuning FreeRTOS task stack sizes and monitoring runtime RAM headroom. Commands: GET. Payload: memory_diagnostics. Role: CONTROL. Devices: eDIDIO, ADDICT. |
| ETHERNET_DIAGNOSTICS | 38 | GET-only. Returns Ethernet PHY register snapshot, Ethernet MAC counters, resolved link state, and a ring buffer of recent link-state transitions. Use with the 'GET' AdminCommandType. Used to diagnose link/auto-negotiation/duplex-mismatch issues without an SD card. Commands: GET. Payload: ethernet_diagnostics. Role: CONTROL. |
| LINE_DIAGNOSTICS | 39 | GET-only. Per-line readout of configured-vs-probed daughterboard type plus a coarse OK/FAULTY/EMPTY/MISCONFIGURED verdict. Briefly perturbs each line (a DALI half-bit pulse and/or a DMX RX-mode window) — fire on demand, not on a hot loop. Use with the 'GET' AdminCommandType. Commands: GET. Payload: line_diagnostics. Role: CONTROL. |
| TIME_DIAGNOSTICS | 40 | GET-only. RTC/NTP/DST observability: LSE crystal ppm measurement, lifetime NTP success/failure counts, last sync details, time-set audit trail, backup-domain boot counter, DST visibility. Use with the 'GET' AdminCommandType. Commands: GET. Payload: time_diagnostics. Role: CONTROL. |
| RTC_TEMP_COMP_ENABLED | 41 | GET/SET. Enable/disable the temperature-driven smooth calibration of the RTC. Persisted in BKPSRAM (reset on battery loss). Default 1. Commands: GET, SET. Payload: data.uint_data. Role: CONFIG. |
| RTC_PPM_MANUAL_OVERRIDE | 42 | GET/SET. When enabled (override flag in PayloadMessage), the RTC smooth calibration is set to a fixed signed ppm value at every hour boundary, bypassing temp comp. Persisted in BKPSRAM. Commands: GET, SET. Payload: data.float_data. Role: CONFIG. |
| NTP_FORCE_SYNC | 43 | RUN. Triggers an immediate NTP sync attempt. Commands: RUN. Payload: none. Role: CONTROL. |
| NTP_POLL_PERIOD_SECONDS | 44 | GET/SET. Override the NTP poll period. 0 means use the existing NTP_DETAILS.NTPTimeout from config. Non-zero is persisted in BKPSRAM. Commands: GET, SET. Payload: data.uint_data. Role: CONFIG. |
| NTP_MAX_ACCEPTABLE_DELTA_SECONDS | 45 | GET/SET. NTP corrections whose |delta| exceeds this value are rejected (treated as a sanity-check failure). Default 3600 (1 hour). Persisted in BKPSRAM. Commands: GET, SET. Payload: data.uint_data. Role: CONFIG. |
| TIME_DIAG_MEASURE_LSE | 46 | RUN. Triggers an on-demand LSE-vs-HSE ppm measurement (~250 ms). Result is cached and returned on the next GET TIME_DIAGNOSTICS. Commands: RUN. Payload: none. Role: CONTROL. |
| BACKUP_DOMAIN_RESET_CANARY | 47 | RUN. Resets the boots_since_last_backup_loss counter to 0. Use after a deliberate battery replacement so the counter reflects only post-replacement boots. Commands: RUN. Payload: none. Role: CONFIG. |
| DALI_STATUS | 48 | GET-only. Returns the DALI system status summary (per-line online/fault device counts, bus-power errors, lowest faulting address, and missing/comms-error device bitmaps) — the same data the on-device Logic system evaluates for "any DALI error" actions. Use with the 'GET' AdminCommandType. Commands: GET. Payload: dali_status. Role: CONTROL. Devices: eDIDIO, ADDICT. |
| USER_ACCOUNT | 49 | SET-only (ADMIN clearance). Provisions a role's login secret (see AdminUserAccountMessage). Write-only — secrets are never returned by a GET. Commands: SET. Payload: user_account. Role: ADMIN. |
| STORAGE_DIAGNOSTICS | 50 | GET-only. Health of the shared SPI storage bus and everything on it: bus stall/reset counters, NOR flash program/erase fault state and presence/identity verdict, and — on variants fitted with an SD card — mount state, probe response, deadline-abort counters and the removal/power-cycle escalation state. Side-effect-free: every value is read from a RAM latch, nothing is probed. Use with the 'GET' AdminCommandType. Not in eDIDIO firmware 1.6.3, which answers UNEXPECTED_TYPE. Commands: GET. Payload: storage_diagnostics. Role: CONTROL. |
| WIFI_SETTINGS | 51 | GET/SET. Wi-Fi of a device with an ESP32 co-processor (ADDICT V3): access point only or access point + station, the station network and the access point channel. The station password is write-only - a GET never returns it. A SET replies before the device reconnects its Wi-Fi. See AdminWifiSettingsMessage. Commands: GET, SET. Payload: wifi_settings. Role: NONE. Devices: ADDICT. |
| WIFI_STATUS | 52 | GET-only. Live Wi-Fi state: station link and IP, the device's own access point (SSID, IP, connected clients) and both MACs. See AdminWifiStatusMessage. Commands: GET. Payload: wifi_status. Role: NONE. Devices: ADDICT. |
| WIFI_DIAGNOSTICS | 53 | GET-only. Wi-Fi link quality (station RSSI, channel, BSSID), co-processor version and restart counters, and command-pipeline health counters. Side-effect-free: every value is cached. See AdminWifiDiagnosticsMessage. Commands: GET. Payload: wifi_diagnostics. Role: NONE. Devices: ADDICT. |
Used with AdminPropertyType
| Name | Number | Description |
| SET | 0 | Set property |
| GET | 1 | Get property |
| ADD | 2 | Add property |
| REMOVE | 3 | Remove property |
| RESET | 4 | Reset property |
| RUN | 5 | Run property |
Used with AdminWifiSettingsMessage / AdminWifiStatusMessage
| Name | Number | Description |
| WIFI_MODE_AP | 0 | The device's own access point only |
| WIFI_MODE_AP_STATION | 1 | Its own access point, and it joins the station network as well |
Used with AdminWifiStatusMessage
| Name | Number | Description |
| WIFI_STATION_DISCONNECTED | 0 | Not associated with the station network (or station mode is off) |
| WIFI_STATION_CONNECTED | 1 | Associated, no IP address yet |
| WIFI_STATION_GOT_IP | 2 | Associated, with an IP address |
AdminMessage{GET / SET, WIFI_SETTINGS}. The access point is always the
device's own (on an ADDICT: "ADDICT_
on the unit) and is not configurable here. Station IP settings (DHCP / static)
are AdminNetworkPropertiesMessage; the hostname is DEVICE_NAME.
| Field | Type | Label | Description |
| mode | WifiMode | GET/SET |
|
| station_ssid | string | GET/SET. Up to 32 printable ASCII characters, not " \ or a comma |
|
| station_password | string | SET only, never returned. "" = an open network, else 8-32 printable ASCII characters (not " \ or a comma). Ignored when keep_station_password is set |
|
| keep_station_password | bool | SET: true = keep the stored password (station_password ignored). GET: true = a station password is stored |
|
| ap_channel | uint32 | GET/SET. 2.4 GHz channel of the access point, 1-13. On a SET, 0 = keep |
AdminMessage{GET, WIFI_STATUS}
| Field | Type | Label | Description |
| running | bool | The Wi-Fi co-processor is up (false: Wi-Fi switched off, or the unit started on battery) |
|
| mode | WifiMode | Access point only, or access point + station |
|
| station_state | WifiStationState | How far the station has got joining its network |
|
| station_ssid | string | The network it joins (station mode) |
|
| station_ip | string | Its address there; "" until it has one |
|
| ap_ssid | string | Its own access point, e.g. "ADDICT_23" |
|
| ap_ip | string | e.g. "192.168.8.1" |
|
| ap_clients | uint32 | Stations connected to its access point |
|
| station_mac | string | Expected format: [40:D8:55:1B:XX:XX] |
|
| ap_mac | string | MAC address of its own access point, "XX:XX:XX:XX:XX:XX" |
AdminMessage{GET, WIFI_DIAGNOSTICS}. Counters are since boot (uptime_seconds); diff two snapshots for a rate.
---- Station link (0 / "" while not associated) ----
| Field | Type | Label | Description |
| station_rssi | sint32 | dBm, e.g. -58 |
|
| station_channel | uint32 | 2.4 GHz channel of the station network |
|
| station_bssid | string | The access point it is associated with, "XX:XX:XX:XX:XX:XX" |
|
| ap_channel | uint32 | Channel its own access point is actually on (in AP + station mode it follows the station's) |
|
| rssi_age_seconds | uint32 | How old station_rssi / station_channel / station_bssid are |
|
| coprocessor_version | string | e.g. the ESP-AT "AT version:" line |
|
| uart_baud | uint32 | UART rate to the co-processor (921600, or 115200 if the handover fell back) |
|
| uptime_seconds | uint32 | Seconds since boot |
|
| coprocessor_restarts | uint32 | Co-processor reboots seen (each one re-initialised) |
|
| coprocessor_resets | uint32 | Hard resets after it stopped answering |
|
| station_disconnects | uint32 | Station links lost |
|
| station_join_failures | uint32 | Station joins that failed or timed out |
|
| tcp_clients | uint32 | TCP clients connected now |
|
| tcp_clients_max | uint32 | TCP client slots (4, or 3 while Art-Net / sACN holds one) |
|
| rx_overruns | uint32 | Receive bursts dropped: the staging buffers were full |
|
| at_retries | uint32 | Reads and sends the co-processor refused ("busy") and were retried |
|
| reply_timeouts | uint32 | Replies abandoned: the co-processor never asked for the data |
|
| replies_dropped | uint32 | Keep-alive / discovery replies skipped while another reply was in flight |
|
| reads_recovered | uint32 | Received data found unread that was never announced |
|
| rx_bytes_discarded | uint32 | Received bytes discarded: overflow, lost framing or an incomplete frame |
The Main AdminMessage used with the specific oneof message type.
| Field | Type | Label | Description |
| command | AdminCommandType | What type of Command to run (GET / SET / etc.) |
|
| target | AdminPropertyType | Which property to run the Command on |
|
| data | PayloadMessage | A single value - the properties that use it say which PayloadMessage field |
|
| network_properties | AdminNetworkPropertiesMessage | NETWORK_PROPERTIES and NTP_DETAILS |
|
| project_properties | AdminProjectPropertiesMessage | SYSTEM_PROPERTIES |
|
| controller_lines | AdminControllerLinesMessage | CONTROLLER_LINES |
|
| device_status | AdminDeviceStatusMessage | DEVICE_STATUS |
|
| config_status | AdminConfigStatusMessage | CONFIG_STATUS |
|
| device_time | UpdateTimeMessage | DEVICE_TIME |
|
| dali_sensor_type | AdminDALISensorTypeMessage | DALI_SENSOR_TYPE |
|
| dns_servers | AdminDNSServersMessage | DNS |
|
| dmx_timing_mode | AdminDMXGlobalTimingConfig | Applies to all lines |
|
| dmx_line_props | AdminDMXLineParameters | One entry per active DMX line |
|
| memory_diagnostics | AdminMemoryDiagnosticsMessage | Per-task stack HWMs + system/section memory usage |
|
| ethernet_diagnostics | AdminEthernetDiagnosticsMessage | Ethernet PHY regs, Ethernet MAC counters, link-event ring buffer |
|
| line_diagnostics | AdminLineDiagnosticsMessage | Per-line configured-vs-probed daughterboard type + coarse OK/FAULTY/EMPTY/MISCONFIGURED verdict |
|
| time_diagnostics | AdminTimeDiagnosticsMessage | RTC/NTP/DST observability snapshot |
|
| dali_status | AdminDaliStatusMessage | DALI system status summary (per-line device/fault counts + missing/comms-error bitmaps) |
|
| user_account | AdminUserAccountMessage | Provision a role's login secret (USER_ACCOUNT, SET, ADMIN) |
|
| storage_diagnostics | AdminStorageDiagnosticsMessage | Storage bus stalls/resets, NOR flash fault + presence state, SD mount/probe/deadline-abort counters |
|
| wifi_settings | AdminWifiSettingsMessage | Wi-Fi mode, station network, AP channel (WIFI_SETTINGS, GET/SET) |
|
| wifi_status | AdminWifiStatusMessage | Live Wi-Fi state (WIFI_STATUS, GET) |
|
| wifi_diagnostics | AdminWifiDiagnosticsMessage | Wi-Fi link quality and health counters (WIFI_DIAGNOSTICS, GET) |
The steps of a firmware update (FirmwareControlMessage), both directions.
| Name | Number | Description |
| FW_READY | 0 | System Ready for Firmware Message |
| FW_APPLY | 1 | Sent to controller to initiate a Firmware update |
| FW_VERIFY | 2 | Sent to controller to initiate stored Firmware verification - This will complete the firmware upload mode and unlock normal functionality. |
| FW_VERIFY_FAILED | 3 | Received from controller - Issue with stored Firmware |
| FW_VERIFY_SUCCESS | 4 | Received from controller - Stored Firmware is Valid |
| FW_READ | 5 | Sent to controller to request information for currently stored Firmware |
| FW_CLONE | 6 | Command to Clone Main FW to Backup. Using the firmware_is_backup flag will clone Backup to Main |
Simple free-form binary data blob that can be used for chunk transfer.
| Field | Type | Label | Description |
| identifier | uint32 | A free-form number that indicates exactly what type of data is being dealt with. Eg. 0x99 may indicate a firmware flash. |
|
| seq | uint32 | The message position in the sequence. |
|
| count | uint32 | The expected total number of DataMessages to be sent. When seq == count, you know you've got the last chunk and can go ahead and process the data (eg. flash firmware). |
|
| data | uint32 | repeated | The data, one byte (0-255) per element |
Firmware Update Meta Message. Contains information on new incoming firmware. Sending this message begins the update process and will ERASE the currently stored firmware
| Field | Type | Label | Description |
| firmware_version | uint32 | MSB.XXX.LSB |
|
| firmware_date | uint32 | Day/Month/Year Compiled - Deprecated, use tag = 10, 11, 12 |
|
| firmware_date_upload | uint32 | Day/Month/Year Uploaded - Deprecated, uses controller time |
|
| firmware_checksum | uint32 | Checksum to verify data |
|
| firmware_chunk_count | uint32 | Number of stored chunks |
|
| firmware_base_address | uint32 | Base Address of the Firmware |
|
| firmware_end_address | uint32 | End Address - For sector erases |
|
| firmware_is_backup | bool | Flag to send Firmware to 'Backup' Location |
|
| nonce | uint32 | repeated | Decryption Nonce |
| firmware_date_day | uint32 | Day in Firmware File |
|
| firmware_date_month | uint32 | Month in Firmware File |
|
| firmware_date_year | uint32 | Year in Firmware File |
|
| signature | bytes | Optional image signature over the staged chunk stream (raw bytes). Absent => unsigned image. |
|
| firmware_format | uint32 | Optional encrypted-firmware (V3) fields. Absent, or firmware_format==0, means a classic image. 0 = classic, 3 = encrypted (V3) |
|
| kem_alg | uint32 | Content-key wrap algorithm identifier |
|
| content_alg | uint32 | Chunk-payload cipher identifier |
|
| content_iv | bytes | 16-byte base initialisation vector |
|
| wrapped_content_key | bytes | Wrapped content key (raw bytes) |
Reply from eDIDIO, or command from program. eDIDIO will check firmware before 'Apply'
| Field | Type | Label | Description |
| cmd | FirmwareCommandType | The step: from the client READY / APPLY / VERIFY / READ / CLONE, from the device the verify result |
|
| firmware_is_backup | bool | Flag used for FW_READ, FW_VERIFY, and FW_CLONE. Does not work for FW_APPLY |
Chunk of firmware to be sent via a 256 byte payload
| Field | Type | Label | Description |
| firmware_address | uint32 | Offset of this chunk in the image, bytes |
|
| total_bytes | uint32 | Size of the whole image, bytes |
|
| payload | DataMessage | The chunk (up to 256 bytes) |
Message sent to read the logs. The start address is offset for how many logs are requested. Up to 32 logs are sent in one message.
| Field | Type | Label | Description |
| log_start_address | uint32 | Which log to start from |
|
| logs_requested | uint32 | How many logs requested? Max of 32 |
|
| logs | SystemLogMessage | repeated | Array of requested logs |
Individual Log packet containing oneof log type of information. Logs are timestamped using the timesinceboot parameter. The boot packet will provide the time of boot, so exact times can be extracted
| Field | Type | Label | Description |
| time_since_boot | uint32 | Time since boot (From latest power message) |
|
| boot | SystemLogBoot | The device started |
|
| netlink | SystemLogNetLink | The Ethernet link went up or down |
|
| ntp | SystemLogNTP | The clock was set from NTP |
|
| trigger | SystemLogTrigger | A trigger ran |
|
| spektra | SystemLogSpektra | Spektra started, stopped or paused something |
|
| schedule | SystemLogSchedule | An alarm fired |
|
| userstart | SystemLogUserStart | The logs were started or reset by a user |
Message for Log Boot Type
| Field | Type | Label | Description |
| timeclock | TimeClockMessage | The clock at boot |
|
| flags | uint32 | Boot flags (bitmask) |
Message for Log Netlink Type
| Field | Type | Label | Description |
| is_linked | bool | true: link up; false: link down |
Message for Log NTP Type
| Field | Type | Label | Description |
| timeclock | TimeClockMessage | The time set |
Message for Log Trigger Type
| Field | Type | Label | Description |
| trigger | TriggerMessage | The trigger that ran |
|
| source | ReadType | What fired it, as a ReadType (INPUTS, SENSOR, LIST, ...) |
Message for Log Spektra Type
| Field | Type | Label | Description |
| action | SpektraActionType | Start, stop or pause |
|
| type | SpektraTargetType | Sequence or theme |
|
| index | uint32 | Which one, 0-based |
Message for Log Schedule Type
| Field | Type | Label | Description |
| index | uint32 | Which alarm, 0-based |
|
| isStart | uint32 | 1: its start trigger; 0: its end trigger |
|
| second | uint32 | Time it fired: seconds |
|
| minute | uint32 | Time it fired: minutes |
|
| hour | uint32 | Time it fired: hours |
Message for Log User Start Type
| Field | Type | Label | Description |
| timeclock | TimeClockMessage | When |
|
| flags | uint32 | Which logs were reset (bitmask) |
Message to contain system metadata for debugging purposes
| Field | Type | Label | Description |
| input_press_counter | uint32 | repeated | Max 24 Inputs |
| list_start_counter | uint32 | repeated | Max 32 Lists |
| schedules_counter | uint32 | repeated | Max 10 Alarms |
| screen_on_time | uint32 | Time in seconds |
|
| screen_dim_time | uint32 | Time in seconds |
|
| screen_saver_time | uint32 | Time in seconds |
|
| reboot_counter | uint32 | Number of reboots since Data erased |
What an EventMessage reports. On an eDIDIO, live events are EventStreamMessage (event_stream).
| Name | Number | Description |
| REGISTER | 0 | Sent by the client to register for events. |
| TRIGGER_EVENT | 1 | Emitted when trigger runs an action listed in TriggerType. |
| INPUT_EVENT | 2 | Emitted when a physical Input is triggered. |
| SENSOR_EVENT | 3 | Emitted when a Sensor (24-bit DALI or 25-bit) is triggered. |
| CONTROL_EVENT | 4 | Emitted when a DALI/DMX/physical output type event is done. References an action in TriggerType. |
| ROOM_JOIN_EVENT | 5 | Emitted when rooms are joined/unjoined. |
| DALI_24_INPUT_EVENT | 6 | Emitted when a 24-bit DALI Input Device is triggered. |
| DALI_24_FRAME_EVENT | 7 | Emitted when a 24-bit DALI Frame is received. |
Input event types from DALI-2 (24-bit) input devices
| Name | Number | Description |
| MOMENTARY_SHORT | 0 | Short button press (< 250ms) |
| MOMENTARY_LONG | 1 | Long button press (> 650ms) |
| LATCHED_LOW | 2 | Switch transitioned to closed/low state |
| LATCHED_HIGH | 3 | Switch transitioned to open/high state |
| POSITIONAL | 4 | Rotary encoder or slider position value |
State machine for DALI motion sensor occupancy detection
| Name | Number | Description |
| MOTION_IDLE | 0 | No occupancy detected, lights at idle/off level |
| MOTION_DISABLED | 1 | Sensor is muted or in deadtime period |
| MOTION_WARNING | 2 | Occupancy timeout reached, lights dimmed to warning level |
| MOTION_OCCUPANCY | 3 | Active occupancy detected, lights at occupied level |
State machine for DALI light level (lux) sensor daylight harvesting
| Name | Number | Description |
| LUX_DISABLED | 0 | Daylight harvesting is inactive |
| LUX_ENABLED | 1 | Actively regulating to maintain target lux setpoint |
| LUX_DEVIATE | 2 | Light level has deviated significantly from setpoint |
Message to set Event Filter Mask
| Field | Type | Label | Description |
| input | bool | eDIDIO physical inputs |
|
| dali_arc_level | bool | 16-bit DALI Arc Level Commands |
|
| dali_command | bool | 16-bit DALI Commands |
|
| dali_sensor | bool | DALI Sensors (24-bit and 25-bit) |
|
| dali_input | bool | 24-bit DALI Inputs |
|
| dmx_stream_changed | bool | DMX output stream changes |
|
| dali_24_frame | bool | Raw 24-bit DALI frames |
|
| trigger_message | bool | High Level Trigger from Input/List/Sensor/Schedule |
Message Response for Trigger Event
| Field | Type | Label | Description |
| type | TriggerType | What type of Trigger occurred |
|
| level | uint32 | Associated level (if applicable) |
|
| dali_command | DALICommandType | Associated DALI Command (if applicable) |
|
| target_address | uint32 | The target address for the TriggerType (if applicable) |
|
| line_mask | uint32 | The Line(s) on which the Trigger occurred (if applicable) |
|
| zone | uint32 | The zone of the Trigger (if applicable) |
|
| value | uint32 | The value of the Trigger (if applicable) |
|
| query_index | uint32 | The query_index of the Trigger (if applicable) |
|
| source | uint32 | The source of the trigger (input/list/sensor) (if applicable) |
Message Response for DALI 24 Input Event
| Field | Type | Label | Description |
| index | uint32 | DALI input, 0-based |
|
| line | uint32 | DALI line it is on |
|
| address | uint32 | Its short address |
|
| type | DALI24InputType | Momentary Short / Momentary Long / Latch Low / Latch High / Positional |
|
| arg | uint32 | Relevant information for the DALI24InputType |
Message Response for DALI 24 Frame Event
| Field | Type | Label | Description |
| line | uint32 | Which DALI Line within the eDIDIO (left -> right): 1, 2, 3, 4 |
|
| frame | uint32 | The 24-bit Frame |
Message Response for DALI Sensor Event
| Field | Type | Label | Description |
| index | uint32 | Sensor, 0-based |
|
| line | uint32 | DALI line it is on |
|
| address | uint32 | Its short address |
|
| motion_state | DALIMotionSensorStates | Idle / Disabled / Warning / Occupancy |
|
| lux_state | DALILuxSensorStates | Disabled / Enabled / Deviate |
|
| lux_level | uint32 | Light level reported, lux |
A message sent to a client when an event occurs. Depending on the event type (Trigger, Input or Sensor) different data is supplied with the event.
If a client sends an EventMessage with EventType of REGISTER then broadcast events out to the client.
| Field | Type | Label | Description |
| event | EventType | What happened; sent by the client as REGISTER (ADDICT: to start or stop monitoring) |
|
| trigger | TriggerEvent | TRIGGER_EVENT / CONTROL_EVENT: the trigger that ran |
|
| inputs | InputStateResponse | INPUT_EVENT: the input state |
|
| payload | PayloadMessage | A plain value, for events that carry one |
|
| sensor | DALISensorEvent | OBSOLETE: JoinedRoomsMessage joined_rooms (5) --> No longer used |
|
| dali_24_input | DALI24InputEvent | DALI_24_INPUT_EVENT: the input that fired |
|
| filter | EventFilter | From the client: what to monitor (ADDICT: which 24-bit frames) |
|
| dali_24_frame | DALI24FrameEvent | DALI_24_FRAME_EVENT: a 24-bit frame seen on the bus |
SD card file operations (SdFileControlMessage).
| Name | Number | Description |
| SD_STAT | 0 | Get file info (size, date, time) |
| SD_GET_SPACE | 1 | Get free/total bytes on card |
| SD_DELETE | 2 | Delete a file (stub: returns ACCESS_DENIED until approved) |
| SD_WRITE_BEGIN | 3 | Begin upload session (creates temp file) |
| SD_WRITE_END | 4 | Finalize upload (rename temp -> target) |
| SD_WRITE_ABORT | 5 | Cancel upload (delete temp file) |
| SD_WRITE_RESUME | 6 | Resume interrupted upload (returns bytes already written to temp) |
The result of an SD card operation.
| Name | Number | Description |
| SD_OK | 0 | Success |
| SD_NOT_MOUNTED | 1 | No card, or it is not mounted |
| SD_FILE_NOT_FOUND | 2 | No such file |
| SD_ACCESS_DENIED | 3 | Not allowed (e.g. delete, until enabled) |
| SD_DISK_FULL | 4 | The card is full |
| SD_IO_ERROR | 5 | The card returned an error |
| SD_INVALID_PATH | 6 | The path is not valid |
| SD_BUSY | 7 | The card is in use - retry |
| SD_TIMEOUT | 8 | The card did not answer in time |
| SD_WRITE_ERROR | 9 | A write failed |
| SD_CAPACITY_UNKNOWN | 10 | The volume is mounted but its capacity has never been measured: every f_getfree() since the mount failed. Returned by SD_GET_SPACE instead of an SD_OK carrying free_bytes = total_bytes = 0, which is indistinguishable from a card with nothing left on it. A client seeing this should treat free space as unknown, not as zero. |
| SD_DEADLINE_ABORT | 11 | The operation was abandoned by the device's own per-operation deadline rather than failing on the media. Distinguishes a card that is too slow (or a bus that stalled) from one that is returning errors: the request may well succeed on a retry, where SD_IO_ERROR usually will not. |
A single directory entry returned in SdDirListMessage
| Field | Type | Label | Description |
| name | string | 8.3 filename (max 12 chars + null) |
|
| size | uint32 | File size in bytes |
|
| date | uint32 | FAT date: ((year-1980)<<9)|(month<<5)|day |
|
| time | uint32 | FAT time: (hour<<11)|(min<<5)|(sec/2) |
|
| is_directory | bool | true for a folder |
Browse SD card directory contents (paginated)
Request fields
| Field | Type | Label | Description |
| path | string | Directory path, e.g. "logs/dali" |
|
| offset | uint32 | Skip this many entries (for pagination) |
|
| max_entries | uint32 | Max entries to return (device caps at 16) |
|
| status | SdStatusCode | Response fields |
|
| entries | SdDirEntry | repeated | Directory entries |
| has_more | bool | True if more entries available |
Read a chunk of a file from the SD card
Request fields
| Field | Type | Label | Description |
| path | string | File path, e.g. "logs/sys/SYS_0001.LOG" |
|
| offset | uint32 | Byte offset to start reading from |
|
| length | uint32 | Bytes requested (device caps at 512) |
|
| status | SdStatusCode | Response fields |
|
| file_size | uint32 | Total file size (from f_stat at read time) |
|
| bytes_read | uint32 | Actual bytes returned in data |
|
| data | bytes | File content chunk (max 512 bytes) |
Write a chunk of data to the SD card (during an upload session)
Request fields
| Field | Type | Label | Description |
| offset | uint32 | Byte offset for this chunk |
|
| data | bytes | Data to write (max 512 bytes) |
|
| status | SdStatusCode | Response fields |
|
| bytes_written | uint32 | Actual bytes written |
File control operations (stat, delete, space, upload begin/end/resume)
| Field | Type | Label | Description |
| command | SdFileControlType | Request fields |
|
| path | string | File or directory path |
|
| expected_size | uint32 | For WRITE_BEGIN: expected total size (advisory) |
|
| status | SdStatusCode | Response fields |
|
| file_size | uint32 | For STAT/WRITE_RESUME: file size in bytes |
|
| file_date | uint32 | For STAT: FAT date |
|
| file_time | uint32 | For STAT: FAT time |
|
| free_bytes | uint64 | For GET_SPACE |
|
| total_bytes | uint64 | For GET_SPACE |
Log category enable/disable configuration
| Field | Type | Label | Description |
| is_write | bool | false=read config, true=write config |
|
| enabled_mask | uint32 | Bitmask: bit N = log category N enabled |
|
| api_version | uint32 | Client's API version |
|
| status | SdStatusCode | Response fields |
|
| current_mask | uint32 | Current enabled mask after operation |
|
| category_count | uint32 | Number of log categories (11) |
|
| device_api_version | uint32 | Device's API version |
Live log streaming - subscribe to real-time log entries pushed by the device
Request fields (client -> device: subscribe/unsubscribe)
| Field | Type | Label | Description |
| subscribe | bool | true=subscribe, false=unsubscribe |
|
| category_mask | uint32 | Bitmask of categories to stream |
|
| category | uint32 | log category value |
|
| timestamp_ms | uint32 | FreeRTOS tick count (milliseconds since boot) |
|
| rtc_time | uint32 | RTC seconds since 2000-01-01 |
|
| payload | bytes | Text log line or binary entry (DALI 12B / EVENT 35B) |
|
| sequence | uint32 | Monotonic sequence number (detects missed entries) |
|
| level | uint32 | Log level: 0=ERROR, 1=WARN, 2=INFO. Push only; binary categories write 0. |
===== Event Stream v2 (tag 77) — typed live event/log stream =====
Replaces SdLogStreamMessage (tag 69, deprecated) on the wire. Same transport,
sequence/timestamp/level observability and ISR-safe SD-independent producers,
but a TYPED, endian-safe, forward-compatible payload instead of raw C structs
memcpy'd into a bytes field. Runs on ALL hardware variants (not SD-specific).
Enum-valued fields are carried as uint32 (values documented inline) rather than
proto enums, for forward-compatibility (new firmware values decode as numbers on
old clients) and consistency across every discriminator in this family.
| Field | Type | Label | Description |
| subscribe | bool | ---- request (client -> device) ---- |
|
| category_mask | uint32 | bit N = category N |
|
| level_threshold | uint32 | push text iff level <= threshold (0=ERR,1=WARN,2=INFO) |
|
| ack | bool | true only on the subscribe/unsubscribe reply |
|
| sequence | uint32 | monotonic per-connection; gaps => dropped entries |
|
| timestamp_ms | uint32 | authoritative: producer tick, ms since boot |
|
| rtc_time | uint32 | seconds since 2000-01-01 (0 if RTC unset) |
|
| category | uint32 | log category value |
|
| level | uint32 | text severity; 0 for binary/structured categories |
|
| text | string | text categories (0,2,4,5,6,7,8,9) |
|
| input | InputEvent | An input was pressed |
|
| sensor | SensorEvent | A sensor changed state |
|
| list | ListEvent | A list ran a step |
|
| schedule | ScheduleEvent | An alarm fired |
|
| config | ConfigEvent | Configuration changed |
|
| boot | BootEvent | The device started |
|
| net | NetEvent | A link or connection changed |
|
| dali | DaliFrame | raw frame + decoded envelope |
|
| raw | bytes | forward-safe fallback: META/unknown types |
|
| spektra | SpektraEvent | sequence/theme playback (EVT_TYPE_SPEKTRA) |
|
| command | CommandEvent | standalone trigger/command (network, logic, IR, device, iRAD) |
Trigger action embedded in Input/Schedule/List (matches what producers hold).
| Field | Type | Label | Description |
| trigger_type | uint32 | TriggerType enum |
|
| target_index | uint32 | Its target (address, group, list, sequence ...), as for TriggerMessage |
|
| value | uint32 | Its value (level, scene ...), as for TriggerMessage |
|
| line_mask | uint32 | The lines it acts on |
An input was pressed (category: inputs). press_type means what source says: for physical inputs 0 short, 1 long, 2 latch low, 3 latch high; for DALI inputs 0 short, 1 long, 2 pressed, 3 released, 4 rotary.
| Field | Type | Label | Description |
| input_index | uint32 | Which input, 0-based |
|
| source | uint32 | ReadType: 0=GPIO, 15=DALI |
|
| press_type | uint32 | GPIO or DALI press type (per source) |
|
| action | TriggerInfo | The trigger it ran |
|
| dali_line | uint32 | reclaimed (DALI inputs only; 0/absent for GPIO) |
|
| dali_address | uint32 | DALI inputs: the input device's short address (0 for physical inputs) |
|
| raw_arg | uint32 | raw rotary/positional value pre-transform |
A sensor changed state (category: sensors). transition: 1 occupancy, 2 warning, 3 off, 4 re-enabled after its deadtime, 5 light level, 6 override.
| Field | Type | Label | Description |
| sensor_index | uint32 | Which sensor, 0-based |
|
| transition | uint32 | sensor transition type |
|
| light_state | uint32 | The lights it controls: 0 off, 1 warning, 2 occupancy, 3 override |
|
| motion_state | uint32 | The motion detector: 0 idle, 1 disabled (deadtime), 2 warning, 3 occupancy |
|
| lux_value | uint32 | Light level, lux (0 if not reported) |
|
| dali_line | uint32 | reclaimed (available in the sensor struct) |
|
| dali_address | uint32 | The sensor's short address |
A list ran a step (category: lists).
| Field | Type | Label | Description |
| list_index | uint32 | Which list, 0-based |
|
| step_index | uint32 | The step it ran |
|
| list_state | uint32 | 0 disabled, 1 enabled, 2 looping, 3 random loop, 4 random withdrawn, 5 random withdrawn loop |
|
| action | TriggerInfo | The step's action (line_mask is 0: list steps carry none) |
An alarm (schedule) fired (category: schedules).
| Field | Type | Label | Description |
| alarm_index | uint32 | Which alarm, 0-based |
|
| is_end | bool | false: its start trigger ran; true: its end trigger |
|
| action | TriggerInfo | The trigger that ran |
Configuration was changed (category: config).
| Field | Type | Label | Description |
| read_type | uint32 | What changed, as a ReadType; 17 Spektra sequence, 18 theme, 19 zone settings, 20 calendar |
|
| item_index | uint32 | Which item, 0-based; 0xFF = all of them |
|
| source | uint32 | Who changed it: 0 network (a client), 1 BACnet, 2 the device's menu, 3 a profile change, 4 the firmware itself |
|
| profile_index | uint32 | The active profile at the time |
|
| ip | bytes | The client's IPv4 address (4 bytes) when source is 0; zero otherwise |
|
| port | uint32 | The client's TCP port when source is 0; 0 otherwise |
|
| mac | bytes | The client's MAC address (6 bytes) when source is 0; zero otherwise |
The device started (category: boot).
| Field | Type | Label | Description |
| reset_cause | uint32 | Why it reset, a bitmask: bit0 power-on, bit1 software, bit2 independent watchdog, bit3 window watchdog, bit4 low power, bit5 reset pin |
|
| profile_index | uint32 | The profile active at boot |
A network link or client connection changed (category: network).
| Field | Type | Label | Description |
| event | uint32 | 0 link up, 1 link down, 2 TCP connect, 3 TCP disconnect, 4 TLS connect, 5 TLS disconnect, 6 / 7 keep-alive (AytMessage) on TCP / TLS, 8 / 9 legacy raw keep-alive (0xFF 0xF6) on TCP / TLS |
|
| ip | bytes | The client's IPv4 address (4 bytes); zero for link events |
|
| port | uint32 | The client's port; 0 for link events |
|
| mac | bytes | The client's MAC address (6 bytes); zero for link events |
|
| reason | uint32 | For a disconnect: 0 graceful, 1 idle timeout, 2 reset by peer, 3 closed by peer, 4 end of stream, 5 send failed, 6 TLS handshake failed, 7 TLS init failed, 8 socket setup failed, 9 link down, 10 no route, 11 not connected, 12 no free connection slot, 13 task creation failed, 255 other |
Spektra sequence/theme playback event (EVT_TYPE_SPEKTRA).
| Field | Type | Label | Description |
| zone | uint32 | The Spektra zone, 0-based |
|
| action | uint32 | Spektra action: 1=START,2=STOP,3=PAUSE |
|
| target | uint32 | Spektra target: 1=SEQUENCE,2=THEME |
|
| index | uint32 | sequence/theme index |
One DALI frame seen or sent on a line (category: DALI bus).
| Field | Type | Label | Description |
| line | uint32 | 0-3, 0xFF=META |
|
| direction | uint32 | 0=TX,1=RX,0xFF=META |
|
| frame_type | uint32 | 0=8b,1=16b,2=24b (or META subtype) |
|
| status | uint32 | TX: the send result (success, collision, timeout or error); RX: for an incomplete frame, how many bits were decoded; 0 for META entries |
|
| frame | uint32 | RAW frame bits (up to 24) — the deliberate raw payload |
A trigger/command executed by a non-input origin (network, logic, IR, device, iRAD).
The action is a plain TriggerInfo; `source` says where it came from. Reuses the
ConfigEvent precedent of discriminating origin with a field, not a message type.
The successor to legacy TRIGGER_EVENT / CONTROL_EVENT.
| Field | Type | Label | Description |
| source | uint32 | ReadType_*: 2=IR, 10=NETWORK, 11=DEVICE, 14=LOGIC, 255=iRAD/internal |
|
| action | TriggerInfo | trigger_type, target_index, value, line_mask |
|
| zone | uint32 | trigger zone (0 if unused by this command) |
|
| query_index | uint32 | trigger query_index (0 if unused by this command) |
|
| ip | bytes | Network-origin identity (source==NETWORK only; 0-len / 0 otherwise). Mirrors ConfigEvent. |
|
| port | uint32 | The client's TCP port when source is NETWORK; 0 otherwise |
|
| mac | bytes | The client's MAC address (6 bytes) when source is NETWORK; empty otherwise |
What an SdLogPolicyMessage request does.
| Name | Number | Description |
| SD_LOG_POLICY_GET | 0 | Read current policy table |
| SD_LOG_POLICY_SET | 1 | Validate + commit new policy table |
| SD_LOG_POLICY_RESET | 2 | Restore flash factory defaults |
Identifies which field in a SET request failed validation. Returned in
SdLogPolicyMessage.invalid_field when status != SD_OK.
| Name | Number | Description |
| SD_LOG_POLICY_FIELD_NONE | 0 | No field (the table is valid) |
| SD_LOG_POLICY_FIELD_CATEGORY | 1 | category index out of range or missing |
| SD_LOG_POLICY_FIELD_BUDGET_PERMILLE | 2 | budget_permille is out of range (0-1000) |
| SD_LOG_POLICY_FIELD_MAX_FILE_SIZE_KB | 3 | max_file_size_kb is out of range (32-32768) |
| SD_LOG_POLICY_FIELD_PRIORITY | 4 | priority is out of range (0-255) |
| SD_LOG_POLICY_FIELD_DUPLICATE | 5 | same category appears twice in a SET |
| SD_LOG_POLICY_FIELD_COUNT | 6 | wrong number of entries in a SET |
The rotation policy for one log category.
| Field | Type | Label | Description |
| category | uint32 | log category value (0..category_count-1) |
|
| directory | string | read-only (response) |
|
| prefix | string | read-only (response) |
|
| extension | string | read-only (response) |
|
| budget_permille | uint32 | 0..1000 |
|
| max_file_size_kb | uint32 | 32..32768 |
|
| priority | uint32 | 0..255 |
|
| current_disk_bytes | uint32 | read-only (response): bytes currently on disk for this category |
Read, change or reset the SD card log rotation policy: how much of the card each log category may use, how big its files grow, and which is pruned first.
| Field | Type | Label | Description |
| op | SdLogPolicyOp | Request fields |
|
| entries | SdLogPolicyEntry | repeated | For SET: full table (one per category) |
| status | SdStatusCode | SD_OK or rejection reason |
|
| invalid_field | SdLogPolicyField | Which field tripped validation (0 if ok) |
|
| invalid_category | uint32 | Which category's entry failed (0 if ok) |
|
| category_count | uint32 | Number of categories on the device |
|
| device_api_version | uint32 | 1 = initial release |
Per-connection details returned in ConnectionStatusMessage.
| Field | Type | Label | Description |
| ip_bytes | bytes | 4-byte IPv4 address of the connected client |
|
| port | uint32 | TCP source port of the connected client |
|
| mac_bytes | bytes | 6-byte MAC address; all-zero if ARP resolution failed |
|
| is_tls | bool | True if this connection is TLS, false if plain TCP |
Query active client connections.
Send with no fields populated to request current status.
The device responds with slot counts and per-connection details.
| Field | Type | Label | Description |
| max_connections | uint32 | Maximum simultaneous connections this device supports |
|
| active_count | uint32 | Number of currently active connections |
|
| connections | ConnectionInfo | repeated | Details for each active connection (active_count entries) |
Read the crash/reset record captured from backup SRAM at boot.
The device captures a 128-byte crash record into battery-backed SRAM on
HardFault/MemManage/BusFault/UsageFault/stack overflow/watchdog/assert.
On the next boot, the record is held in RAM for network retrieval.
Request fields
| Field | Type | Label | Description |
| clear | bool | If true, acknowledge/clear the pending crash record |
|
| has_crash | bool | True if a crash was recorded before this boot |
|
| crash_type | uint32 | Crash type: 0=none,1=hardfault,2=memmanage,3=busfault, 4=usagefault,5=stack_overflow,6=watchdog,7=assert |
|
| reset_cause | uint32 | Reset cause, packed as a bitmask: bit0=POR, bit1=software, bit2=IWDG, bit3=WWDG, bit4=low_power, bit5=pin_reset |
|
| crash_data | bytes | Full 128-byte crash record (binary, for detailed analysis — client decodes per struct layout) |
|
| task_name | string | FreeRTOS task name at fault (convenience, max 7 chars) |
|
| pc | uint32 | Program counter at fault (convenience) |
|
| lr | uint32 | Link register at fault (convenience) |
|
| time_since_boot | uint32 | Uptime in seconds before crash |
|
| cfsr | uint32 | Cortex-M Configurable Fault Status Register (convenience) |
|
| boot_watchdog_flags | uint32 | Watchdog status captured from .noinit RAM at boot (only valid on IWDG resets). Bitmask of tasks that fed the watchdog before reset. Missing bits indicate which tasks stalled. 0 if the reset was not caused by IWDG. |
|
| firmware_version | string | Running firmware version (e.g. "1.2.3") |
|
| commit_hash | string | Git commit hash from the build system |
|
| build_date | string | Build date/time string (e.g. "Apr 8 2026 14:30:00") |
|
| boot_rtc_timestamp | uint32 | RTC wall-clock time of the boot after the crash (same as the SD crash.log header timestamp). Combined with time_since_boot, the client can estimate when the crash actually occurred. RTC seconds since 2000-01-01 at this boot |
|
| task_hwm_data | bytes | Per-task stack high-water-mark snapshot captured at boot from .noinit stacks. Binary per-task stack-HWM snapshot (up to 200 bytes). Always populated when available, regardless of whether a crash was recorded. Reflects the *previous* boot's stack usage. |
Whether the device has a provisioned identity.
| Name | Number | Description |
| PROVISION_STATE_UNPROVISIONED | 0 | Default: no identity; accepts InstallIdentity |
| PROVISION_STATE_PROVISIONED | 1 | Identity in flash; refuses re-provision (Decommission first) |
The result of a provisioning request.
| Name | Number | Description |
| PROVISION_RESULT_OK | 0 | Success |
| PROVISION_RESULT_ERR_PARSE | 1 | supplied identity failed to parse |
| PROVISION_RESULT_ERR_CHAIN | 2 | certificate chain did not validate |
| PROVISION_RESULT_ERR_UID_MISMATCH | 3 | certificate does not match this device's unique ID |
| PROVISION_RESULT_ERR_POP | 4 | key consistency check failed |
| PROVISION_RESULT_ERR_FLASH | 5 | identity store failed |
| PROVISION_RESULT_ERR_ALREADY_DONE | 6 | already PROVISIONED; Decommission first |
Tag 73: read identity state. Request is empty; response carries state/uid/fingerprint (all public).
| Field | Type | Label | Description |
| state | ProvisionState | Response |
|
| uid | bytes | Response: 96-bit unique device ID (12 bytes) |
|
| fingerprint | bytes | Response: certificate fingerprint (32 bytes; empty if UNPROVISIONED) |
Tag 74: install identity, uploaded as a CHUNKED stream (mirrors FirmwareChunkMessage). The host
sends a self-describing identity blob in <=256 B chunks; the device reassembles it and, on the
final chunk, validates the certificate chain, binds it to the device ID, and stores the identity.
| Field | Type | Label | Description |
| total_length | uint32 | Request: total identity-blob length (sent on every chunk) |
|
| offset | uint32 | Request: byte offset of this chunk within the blob |
|
| data | bytes | Request: chunk payload (<=256 B) |
|
| last | bool | Request: true on the final chunk -> validate + store |
|
| ok | bool | Response |
|
| result | ProvisionResult | Response |
|
| received | uint32 | Response: bytes accepted so far (resume/diagnostics) |
Tag 75: proof of possession. Request = {nonce}; response = {signature} (device signs the nonce).
| Field | Type | Label | Description |
| nonce | bytes | Request: tool-supplied challenge |
|
| signature | bytes | Response: signature over the nonce using the device's private key |
Tag 76: decommission back to UNPROVISIONED (phase 2: authenticated). Response = {ok, result}.
| Field | Type | Label | Description |
| ok | bool | Response |
|
| result | ProvisionResult | Response |
What a Spektra step does.
| Name | Number | Description |
| RUN_SEQUENCE | 0 | Run a sequence |
| SHOW_THEME | 1 | Show a theme |
| START_LIST | 2 | Start a list |
| PAUSE_PREVIOUS | 3 | Pause what the previous step started |
| STOP_PREVIOUS | 4 | Stop what the previous step started |
Types of conditions that can be evaluated in Logic rules
| Name | Number | Description |
| DALI_LEVEL | 0 | Compare against a DALI device's arc level (0-254) |
| INPUT_STATE | 1 | Compare against a physical input's current state (HIGH/LOW) |
| LIST_RUNNING | 2 | Check if a specific List is currently running |
| OCCUPANCY_DETECTED | 3 | Check if a sensor has detected occupancy |
| DMX_PRESENT | 4 | Check if DMX input signal is being received |
| CAL_WEEKDAY | 5 | Compare against current day of week (1=Monday to 7=Sunday) |
| CAL_MONTH | 6 | Compare against current month (1=January to 12=December) |
| ALARM_SCHEDULED | 7 | Check if a specific alarm/schedule is active |
| DALI_CACHE_STATUS | 8 | Checks if any DALI device in the cache has an error status |
| HAS_ERROR | 9 | Check device error flags. target_index is bitmask: [bit0=DALI Poll Error, bit1=DALI Line Error, bit2=Ethernet Link Dropped, bit3=Over Temperature, bit4=OLED Error, bits5-7=Reserved] |
Categories of events recorded in the system log
| Name | Number | Description |
| BOOT | 0 | Device power-on or reboot event |
| NET_LINK | 1 | Ethernet link state change (connected/disconnected) |
| NTP | 2 | NTP time synchronization event |
| TRIGGER | 3 | Trigger action executed (input, schedule, or external) |
| SPEKTRA | 4 | Spektra sequence/theme state change |
| SCHEDULE | 5 | Scheduled alarm triggered |
| USER | 6 | User changed logging level configuration |
| CRASH | 7 | Crash record summary (crash_type, PC, CFSR, LR low-16) |
| WATCHDOG_RESET | 8 | Watchdog-triggered reset |
| CRASH_EXT | 9 | Extended crash data (SP, watchdog_flags, task_name) |
| .proto Type | Notes | C++ | Java | Python | Go | C# | PHP | Ruby |
| double | double | double | float | float64 | double | float | Float | |
| float | float | float | float | float32 | float | float | Float | |
| int32 | Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint32 instead. | int32 | int | int | int32 | int | integer | Bignum or Fixnum (as required) |
| int64 | Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint64 instead. | int64 | long | int/long | int64 | long | integer/string | Bignum |
| uint32 | Uses variable-length encoding. | uint32 | int | int/long | uint32 | uint | integer | Bignum or Fixnum (as required) |
| uint64 | Uses variable-length encoding. | uint64 | long | int/long | uint64 | ulong | integer/string | Bignum or Fixnum (as required) |
| sint32 | Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int32s. | int32 | int | int | int32 | int | integer | Bignum or Fixnum (as required) |
| sint64 | Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int64s. | int64 | long | int/long | int64 | long | integer/string | Bignum |
| fixed32 | Always four bytes. More efficient than uint32 if values are often greater than 2^28. | uint32 | int | int | uint32 | uint | integer | Bignum or Fixnum (as required) |
| fixed64 | Always eight bytes. More efficient than uint64 if values are often greater than 2^56. | uint64 | long | int/long | uint64 | ulong | integer/string | Bignum |
| sfixed32 | Always four bytes. | int32 | int | int | int32 | int | integer | Bignum or Fixnum (as required) |
| sfixed64 | Always eight bytes. | int64 | long | int/long | int64 | long | integer/string | Bignum |
| bool | bool | boolean | boolean | bool | bool | boolean | TrueClass/FalseClass | |
| string | A string must always contain UTF-8 encoded or 7-bit ASCII text. | string | String | str/unicode | string | string | string | String (UTF-8) |
| bytes | May contain any arbitrary sequence of bytes. | string | ByteString | str | []byte | ByteString | string | String (ASCII-8BIT) |