Sensors and Actuators (Firmware)

Purpose

As a generic way to send sensor measurements and to send commands to actuators, it is possible to use the component_act and component_sense messages. These messages contain a moduleId that is controlled by a vendor. Next, they contain a 2 byte component that can be used to specify a device that is somehow attached to a BlueRange Mesh node. The registerAddress is then used to specify a handle for this value, e.g. a Modbus holding register or a characteristic. The payload is transmitted over the terminal by using base64 or hex-string encoded binary data.

The names of these messages is a combination of two things: A BlueRange device can be a conglomerate of different sub-devices that are attached to each other via a bus system or different means of communication. We call these sub-devices components and offer the possibility for each component to report its individual sensor data, we also offer the possibility to implement a DFU process for each of these components. The second part of the name is either sense for everything that was read or sensed by the device and act for everything on the device that you could potentially control, write to or trigger.

Make sure to have a look at our tutorial for implementing sensor and actor messages for more information.

Messages

Message Types

#define MESSAGE_TYPE_COMPONENT_ACT 58 //Actuator message
#define MESSAGE_TYPE_COMPONENT_SENSE 59 //Sensor message

Actuator message (component_act)

// Instruct device to write data into a register address
component_act [nodeId] [moduleId] [actionType] [component] [registerAddress] [hexString | base64String] {requestHandle=0}

The following message is used to transport write or read requests through the mesh.

enum actionType {
    RESERVED = 0, // Unused
    WRITE = 1, // Write without acknowledgement, also used to send commands, will not generate any response
    READ = 2, // A request to read a value
    WRITE_ACK = 3, // Write with acknowledgement, same as write but will trigger a response
}
Bytes Type Name Description

5

connPacketHeader

header

1

u8

moduleId

The module that should act on the message

1

u8

requestHandle

Optional request handle, otherwise 0

1

u8

actionType

One of the above actionTypes

2

u16

component

Some number identifying the destination for the action (vendor specific)

2

u16

registerAddress

An address, e.g. hardware register number or a message profile id where the data should be written (vendor specific)

1-..

u8[]

payload

For READ, this must be a singly byte that represents the number of bytes to read. For WRITE and WRITE_ACK, the payload is the bytes that should be written.

No JSON representation is necessary for the moment as the mesh gateway will not react on component_act messages.

Sensor Message (component_sense)

The component_sense message is used to transport the result of reads or writes or other sensor values generated by the node.

// Generate a sensor event and send through mesh
// (Only used for debugging)
component_sense [nodeId] [moduleId] [actionType] [component] [registerAddress] [hexString | base64String] {requestHandle=0}

//E.g. broadcast sensor event for module 123 from component 7 and registerAddress 77
component_sense 0 123 0 7 77 AA:BB

Following message is used to transport the sensor measurement values across the mesh.

enum actionType {
    UNSPECIFIED = 0, // Generated by sensor itself, e.g. an event
    ERROR_RSP = 1, // Error during READ or WRITE_ACK with an error code
    READ_RSP = 2, // Response following a READ which contains the data that was read
    WRITE_RSP = 3, // Response following a WRITE_ACK which contains the data that was actually written
    RESULT_RSP = 4 // Response following a READ or WRITE_ACK that contains a result code of the operation
};
A protocol will usually use either a combination of ERROR_RSP + WRITE_RSP or will only return RESULT_RSP in all cases.
Bytes Type Name Description

5

connPacketHeader

header

1

u8

moduleId

The module that generated this value

1

u8

requestHandle

Optional request handle, otherwise 0

1

u8

actionType

One of the above actionTypes

2

u16

component

Some number identifying the source of the measurements such as a lamp head (vendor specific)

2

u16

registerAddress

An address used to differentiate data transported such as a hardware register number or a message profile ID (vendor specific)

1-…​

u8[]

payload

Actual binary data that represents a sensor reading or multiple.

The packet header consumes 12 bytes, which allows for 8 bytes of payload in a single packet and should be enough for most sensor values. For bigger payloads, it will be split.

The output on a sink will be:

{
	"nodeId": 5,                // sender
	"type": "component_sense",  // discriminator
	"module": 123,              // moduleId
	"requestHandle": 0,
	"actionType" : 0,
	"component" : 7,
	"register" : 77,
    "payload": "abcdeQ=="       // base64 encoded
}
component and register can also be represented as a string that contains the number in hex representation. The implementation must be able to support both an integer or a string representation of an unsigned hex number. For example: "component":"0x1234" and "register":"0xABCD".