Status Reporter Module (ID 3)
Purpose
The StatusReporterModule with ModuleId 3 reports the node status in a configured interval. It provides methods for directly requesting different kinds of device info and status data.
Functionality
The StatusReporterModule can periodically send out different kinds of informational messages. It also feeds the watchdog when keep alive messages are received. It is responsible for sending out logged error codes and measuring the necessary data for its messages such as the battery power.
Terminal Commands
Device Information
Generic information about a node that never changes or only changes through enrollment or firmware updates can be requested via the get_device_info command.
//Request the full device info from some nodes
action [nodeId] status get_device_info
Status Information
Information that is bound to change from time to time can be requested using the get_status command.
//Request the status
action [nodeId] status get_status
Connection Information
Information about the mesh connections of a node can be requested with the get_connections or get_nearby commands.
//Retrieve the connections from all nodes in the network
action [nodeId] status get_connections
//Retrieve nearby nodes with the same network id
action [nodeId] status get_nearby
Information about all connections with a lot of detail can be requested with the get_connections_verbose command. In scenarios with limited queue sizes, only single connections can be requested via an optional index parameter, as returned by the GetConnections method of the ConnectionManager.
//Retrieve detailed connection information from the node with nodeId.
action [nodeId] status get_connections_verbose
//Same, but only for the connection with the given index.
action [nodeId] status get_connections_verbose {index}
Live Reports
Live reports are a way to send information about errors, connections, disconnections and other important events to the user through the mesh. Each live report has a unique ID according to its importance. Liver reports are activated by setting the livereports level to a value greater than 0. The different levels are:
-
Off (0)
-
Error (50)
-
Warn (100)
-
Info (150)
-
Debug (200)
Live reports can be generated in the firmware using the SendLiveReport
method. Two extra parameters can be given that can contain additional information for the specific report/error. The meaning of the extras is documented at the LiveReportType definition. LiveReports will of course only be received if the node is currently part of the mesh. If this is not the case, than it might be better to use the error log.
//Set the livereport level
action [nodeId] status livereports [liveReportLevel]
//Activate livereports for all errors on all nodes
action 0 status livereports 50
Live reports are printed on the terminal of a sink node and can be used to debug a problem in a running system:
{"type":"live_report","nodeId":123,"module":3,"code":1,"extra":2,"extra2":3}
Error Log
The error log stores metrics and errors that help monitoring the mesh. This information can be periodically queried e.g. by a gateway. More information is available on the dedicated error log page.
action [nodeId] status get_errors
The queried nodes will respond with their complete error log that they have stored in RAM. The error log is cleared on reboot as it is only stored in RAM and is also cleared after it was queried. The error log is printed on a sink node (or any other if json logging is active) as multiple json objects.
{"type":"error_log_entry","nodeId":2,"module":3,"errType":2,"code":22,"extra":59,"time":10000,"typeStr":"CUSTOM","codeStr":"COUNT_JOIN_ME_RECEIVED"}
{"type":"error_log_entry","nodeId":2,"module":3,"errType":2,"code":86,"extra":10030,"time":10030,"typeStr":"CUSTOM","codeStr":"INFO_UPTIME_ABSOLUTE"}
{"type":"error_log_entry","nodeId":2,"module":3,"errType":2,"code":20,"extra":6,"time":10030,"typeStr":"CUSTOM","codeStr":"INFO_ERRORS_REQUESTED"}
Component periodic timestamp sending
The StatusReporterModule includes functionality for periodically sending the nodes current timestamp. It has temporary and persistent time reporting functionality.
Temporary time reporting can be enabled and disabled via component_act. When enabled, it is automatically disabled after a few minutes to avoid unnecessary battery usage.
//Enables Periodic sending
component_act [nodeId] 3 2 0xABCD 0x1234 01 [requestHandle]
//Disabled Periodic sending
component_act [nodeId] 3 2 0xABCD 0x1234 00 [requestHandle]
Persistent time reporting is enabled with the terminal command:
action [nodeId] status set_time_reporting [intervalDs]
intervalDs .. Time reporting interval in deci seconds.
An interval of 0
means no time reporting.
The immediate confirmation message should look like this:
{"type":"time_reporting_state","intervalDs":10,"nodeId":2,"module":3,"code":0}
Upon activation, the time is reported with multiple component_sense messages that roughly look like this example:
{"nodeId":33011,"type":"component_sense","module":3,"requestHandle":13,"actionType":0,"component":43981,"register":4660,"payload":"AgAAAA=="}
The payload of the answer is the base 64 timestamp of the target node.
Gateway status for Sink Nodes with USB support
For nodes that use the ACTIVATE_ONLY_SINK_FUNCTIONALITY
and the ACTIVATE_VIRTUAL_COM_PORT
defines, the current USB serial Terminal and Gateway status can be retreived and updated.
This value is stored as a u8
in RAM only. It is updated
-
always when calling
set_gw_status
-
when calling
get_gw_status
to ensure that an up to date serial status is provided-
When USB is not initialized, it is set to
USB_PORT_NOT_CONNECTED(2)
-
When USB is initialized and wasn’t before, it is set to
USB_PORT_CONNECTED(1)
-
Set Gateway status
The gateway status can be set to any number from 10 to 255. However, only the following values are defined as an enum:
Enum
enum class GatewayStatus : u8 {
// 0..9 from firmware side
UNKNOWN = 0,
USB_PORT_CONNECTED = 1,
USB_PORT_NOT_CONNECTED = 2, // overwrites the other states
// 10.. set from outside, overwrites USB_PORT_CONNECTED
READY = 10, //Serial communication handshake done
USB_PORT_CONNECTED_BUT_UNKNOWN_STATUS = 11, // when the gateway failed to determine current state
READY_BUT_NO_BLUERANGE_CONNECTION = 12, // no server connection
READY_BUT_NOT_ENROLLED = 13, // edgerouter not enrolled
READY_BUT_NO_MESH_CONNECTION = 14, // enrolled but no other node is enrolled
READY_AND_DFU_IN_PROGRESS = 15, // dfu in progress, higher prio than NO_MESH_CONNECTION but lower prio than NOT_ENROLLED and NO_BLUERANGE_CONNECTION
EDGEROUTER_SHUTDOWN = 16, // edgerouter was shut down and _should_ be restarting
};
The response is the current Gateway status:
action [nodeId] status set_gw_status [status]
// Example
action this status set_gw_status 10
// Example response
{"type":"gw_status","nodeId":2,"module":3,"status":10}
Get Gateway status
As noted in the introduction, the Gateway status can be updated by the node when calling get_gw_status
.
action [nodeId] status get_gw_status
// Example
action this status get_gw_status
// Example response: node just started -> UNKNOWN
{"type":"gw_status","nodeId":2,"module":3,"status":0}
// ... USB plugged in
action this status get_gw_status
{"type":"gw_status","nodeId":2,"module":3,"status":1}
// ... Gateway sets the status
action this status set_gw_status
{"type":"gw_status","nodeId":2,"module":3,"status":10}
// ... USB unplugged
action this status get_gw_status
{"type":"gw_status","nodeId":2,"module":3,"status":2}
Messages
Device Info (v2)
Request
Bytes | Type | Name | Description |
---|---|---|---|
8 |
header |
messageType: MODULE_TRIGGER_ACTION(51), actionType: GET_DEVICE_INFO_V2(10) |
Response
The device info contains information about the device that is not changing often, e.g. only after a firmware update or an enrollment.
Bytes | Type | Name | Description |
---|---|---|---|
8 |
header |
messageType: MODULE_ACTION_RESPONSE(52), actionType: DEVICE_INFO_V2(10) |
|
2 |
u16 |
manufacturerId |
ID according to Bluetooth SIG Assigned numbers company identifiers |
4 |
u32 |
serialNumberIndex |
Index of the serial number, can be converted with alphabet |
8 |
u64 |
chipId |
A unique ID of the nRF chip |
7 |
gapAddress |
1 byte address type, 6 byte BLE address |
|
2 |
u16 |
networkid |
The network id |
4 |
u32 |
nodeVersion |
Version of the node (10000000 * MAJOR + 10000 * MINOR + PATCH) |
1 |
i8 |
dbmRx |
Receive power in dBm (signed) |
1 |
i8 |
dbmTx |
Transmit power in dBm (signed) |
1 |
u8 |
deviceType |
cf. Device Types |
1 |
i8 |
calibratedTx |
Calibrated TX power at 1m distance (signed) |
2 |
u16 |
chipGroupId |
Group ID for the chip (e.g. NRF52) |
2 |
u16 |
featuresetGroupId |
Group ID for the firmware featureset (used for firmware update). Matching groups are allowed to receive the firmware. |
2 |
u16 |
bootloaderVersion |
Version of the bootloader |
Status
Response
The device status contains information that is changing from time to time.
Bytes | Type | Description |
---|---|---|
8 |
messageType: MODULE_ACTION_RESPONSE(52), actionType: STATUS(1) |
|
2 |
clusterSize |
Size of the cluster that the node is connected to (current mesh size) |
2 |
inConnectionPartner |
NodeId of the node that is connected to the one and only peripheral connection with this node. |
1 |
inConnectionRssi |
RSSI of the incoming connection |
2 bit |
freeIn |
Number of free mesh connections as peripheral |
6 bit |
freeOut |
Number of free mesh connections as central |
1 |
batteryInfo |
Battery voltage |
1 |
connectionLossCounter |
Counter of how many mesh connections were dropped |
1 bit |
initializedByGateway |
If the gateway has initialized this beacon and sent the SET_INITIALIZED command, this bit will be 1 until a reboot is encountered |
7 bit |
reserved |
Connections
Query all nodeIDs that a node is connected to including the connection rssi. The first entry is the incoming connection, the others are outgoing.
Request
Bytes | Type | Description |
---|---|---|
8 |
messageType: MODULE_TRIGGER_ACTION(51), actionType: GET_ALL_CONNECTIONS(3) |
Nearby Nodes
Returns all nodes (limited to some maximum count) that are surrounding the node with the same networkId.
Request
Bytes | Type | Description |
---|---|---|
8 |
messageType: MODULE_TRIGGER_ACTION(51), actionType: GET_NEARBY_NODES(4) |
Live Reports
The statusReporterModule can send live reports that notify the user over various state changes and error conditions. A live report is generated for a node and then broadcast over the mesh. This allows live debugging of mesh errors, e.g. if two nodes are not connecting to each other. Live reports are also received over MeshAccessConnection, which means an error can be detected after connecting to the disconnected part of the mesh using a MeshAccessConnection.
enum LiveReportTypes {
LIVE_REPORT_TYPES_ERROR = 0,
LIVE_REPORT_TYPES_WARN = 50,
//========
LIVE_REPORT_TYPES_INFO = 100,
LIVE_REPORT_TYPE_GAP_CONNECTED_INCOMING, //extra is connHandle, extra2 is 4 bytes of gap addr
LIVE_REPORT_TYPE_GAP_TRYING_AS_MASTER, //extra is partnerId, extra2 is 4 bytes of gap addr
LIVE_REPORT_TYPE_GAP_CONNECTED_OUTGOING, //extra is connHandle, extra2 is 4 byte of gap addr
LIVE_REPORT_TYPE_GAP_DISCONNECTED, //extra is partnerid, extra2 is hci code
LIVE_REPORT_TYPE_HANDSHAKE_FAIL,
LIVE_REPORT_TYPE_MESH_CONNECTED, //extra is partnerid, extra2 is asWinner
LIVE_REPORT_TYPE_MESH_DISCONNECTED, //extra is partnerid, extra2 is appDisconnectReason
//========
LIVE_REPORT_TYPES_DEBUG = 150,
LIVE_REPORT_TYPE_DECISION_RESULT //extra is decision type, extra2 is preferedPartner
};
Event
Bytes | Type | Description |
---|---|---|
8 |
messageType: MODULE_GENERAL(53), actionType: LIVE_REPORT(1) |
|
1 |
reportType |
Of type LiveReportType |
4 |
extra |
Additional data regarding the event, depending on reportType |
4 |
extra2 |
Additional data regarding the event, depending on reportType |
Keep Alive
The SET_KEEP_ALIVE
message is used to validate the hopsToSink
field on nodes in the mesh network.
This feature is part of sink routing.
Bytes | Type | Description |
---|---|---|
8 |
messageType: MODULE_TRIGGER_ACTION(51), actionType: SET_KEEP_ALIVE(9) |
|
1 bit |
fromSink |
If the sender of the message is a sink |
7 bits |
reserved |
Reserved |
Get Gateway status
Request
Bytes | Type | Name | Description |
---|---|---|---|
8 |
header |
messageType: MODULE_TRIGGER_ACTION(51), actionType: GET_GATEWAY_STATUS(14) |
Response
Bytes | Type | Name | Description |
---|---|---|---|
8 |
header |
messageType: MODULE_ACTION_RESPONSE(52), actionType: GATEWAY_STATUS(14) |
|
1 |
u8 |
gatewayStatus |
see enum above |
Register Based Functionality
We offer a generic register based access to a number of values as well. Using this functionality makes it very easy to configure health / status reporting based on the use-case using AutoSense.
Register Mapping
Component | Register | Name | DataType (Length) | Min … Max (Default) | R/W | Description |
---|---|---|---|---|---|---|
Information Registers |
||||||
0 |
1000 |
GAP_ADDRESS_TYPE |
U8(1) |
- |
R |
The GAP address Type as FruityHal::BleGapAddrType |
0 |
1001 |
GAP_ADDRESS |
RAW(6) |
- |
R |
The current GAP address of the device, also known as MAC address |
0 |
1007 |
GAP_ZERO_PAD |
U8(1) |
0 … 0 (0) |
R |
Always set to 0 so that the Gap Address and Type can be read as a U64 |
0 |
1010 |
GAP_ADDR_STRING |
ASCII(18) |
- |
R |
The GAP address in its typical hex-string representation and zero terminated |
Configuration Registers |
||||||
0 |
10000 |
REFERENCE_MILLI_VOLT_AT_0_PERCENT |
U32(4) |
(1000) |
R |
Reference voltage (in millivolts) that represents the lowest level at which the device can still work correctly. (Currently only settable via board configuration) |
0 |
10004 |
REFERENCE_MILLI_VOLT_AT_100_PERCENT |
U32(4) |
(2500) |
R |
Reference voltage (in millivolts) that represents the level of factory new batteries where they are fully charged. (Currently only settable via board configuration) |
Data Registers |
||||||
0 |
30000 |
DEVICE_UPTIME |
U32(4) |
- |
R |
Contains the time since device reboot in deciseconds |
0 |
30004 |
ABSOLUTE_UTC_TIME |
U32(4) |
- |
R |
Contains the absolute UTC time in seconds that was synced to the device or 0 if not available. |
0 |
30008 |
ABSOLUTE_LOCAL_TIME |
U32(4) |
- |
R |
Contains the local time (UTC time including timezone offset) in seconds that was synced to the device or 0 if not available. |
0 |
30100 |
CLUSTER_SIZE |
U16(2) |
- |
R |
The amount of currently connected mesh nodes in the whole mesh, including the own node. |
0 |
30102 |
NUM_MESH_CONNECTIONS |
U8(1) |
- |
R |
The amount of opened mesh relay connections to other nodes |
0 |
30103 |
NUM_OTHER_CONNECTIONS |
U8(1) |
- |
R |
The amount of other BLE connections (e.g. MeshAccess) that are not used to form the mesh. |
0 |
30104 |
MESH_CONNECTIONS_DROPPED |
U16(2) |
- |
R |
The total amount of mesh connections that were dropped accidentially or on purpose. |
0 |
30106 |
PACKETS_SENT_RELIABLE |
U32(4) |
- |
R |
The number of packets that were sent through the mesh on all connections with ACK request. |
0 |
30110 |
PACKETS_SENT_UNRELIABLE |
U32(4) |
- |
R |
The number of packets that were sent through the mesh on all connections without ACK. |
0 |
30114 |
PACKETS_DROPPED |
U32(4) |
- |
R |
The total number of packets that had to be dropped due to peak traffic exceeding the queue size. |
0 |
30118 |
PACKETS_GENERATED |
U32(4) |
- |
R |
The amount of packets that this node has generated itself to be sent to the mesh or other partners. |
0 |
30200 |
BATTERY_PERCENTAGE |
U8(1) |
0 … 100 |
R |
The battery percentage, where 0% represents an empty battery and 0xFF an invalid measurement (e.g. connected to power supply). |
The reference voltagses are currently not writable as the generic register implementation does not yet have persistence included. It should therefore be set through the board configuration. |
Potential Use-Cases
-
Use AutoSense to periodically report the battery percentage to monitor the expected remaining device runtime.
-
Detect device reboots by monitoring the device uptime.
-
Monitor the mesh stability through the cluster size.
//Check the device uptime
component_act this 3 read 0 30000 04
//Check the battery level
component_act this 3 read 0 30200 01