Octave Resource Protocol
This topic describes the Octave Resource Protocol, which is the protocol that facilitates communications between your assets, Octave edge device, and the cloud.
What is the Octave Resource Protocol?
Octave Resource Protocol (ORP) is a simple ASCII-based protocol that is built on top of HDLC-framed data sent via UART. Using ORP, a customer asset (asset) can interact with Octave by sending and receiving ASCII-based messages with an Octave edge device.
This page provides the specification of this protocol:
- ORP Versions: provides information about specific changes in different versions of ORP
- Packet Structure: describes ORP's packet structure.
- Operations: describes ORP's available commands.
ORP Version Updates
ORP Version 2
ORP version 2 is supported by Octave edge firmware, version 3.0.0, released in June 2020. There is no change in the protocol itself and it is backward compatible with version 1. Version 2 does however provide the following changes/enhancements:
- The fields of the general packet description have been updated to support sequence numbers.
- A "hello message" was added (SYNC). This includes a version number and sent/received packet counts. This message can be ignored by assets which do not wish to support it. The hello message is sent by the module when the ORP service starts and may be used by the asset to decide when to create or recreate the Resources.
- The path of ORP Resources has changed:
- All ORP Resources are under a node named
orp
. - Customer-defined Resources are under a node named
orp/asset
. - An asset has read/write access only to
orp/asset
. Other paths underorp
are read-only. - A read-only status Resource is available under
orp/status
to report the connection state as well as packet statistics and errors
- All ORP Resources are under a node named
Packet Structure
Packets must adhere to the following:
- Packets contain fixed-length and variable-length fields.
- Fixed-length fields are located at the beginning of the packet, followed by any variable-length ones.
- Fixed-length fields are mandatory. Their contents may be ignored when not needed for a given packet.
- Variable-length fields begin with a 1-byte identifier and end with a separator. The final variable-length field does not end with a separator.
- Data values may contain the separator. Therefore, data must appear as the last field in any packet.
- Most fields are ASCII characters but are not null-terminated strings.
Request and Notification Structure
Protocol Version 1 - ASCII
The first 4 bytes of a request packet must be present, even if not all are applicable to the specific request.
<packet type[1]><data type[1]><segment[2]><contents[variable]>
Fields:
packet type : Identifies request or notification, 1-byte
data type : Identifies data type of request or notification, if needed. Ignored for some types. 1-byte
segment : Count allowing a request or notification to span multiple packets. 2-bytes
contents : Packet dependent, variable length
Protocol Version 2 - ASCII
Version 2 introduces a message for synchonization between the Octave edge device and the asset. Protocol Version 2 is backward compatible with Version 1. Devices which do not
reply to the synchronization message or which report version 1 in the reply, can continue to follow version 1 of the protocol. Devices which report version 2 in the synchonization messages must use and increment the sequence field in any packet which specifies it. The packet sizes are unchanged but the use of some fields has been updated.
<packet type[1]><data type|version[1]><sequence[2]><contents[variable]>
Fields:
packet type : Identifies request or notification, 1-byte
data type/version : Identifies data type or protocol version, if needed. Ignored for some types. 1-byte
sequence : Packet number - count of packets sent by the sender since restart, including the current. 2-bytes, binary
contents : Packet dependent, variable length
Request and Notification Packet Structure
Packet Type | Request (asset to Octave edge device) | Response (Octave edge device to asset) | Version |
---|---|---|---|
Create Resource (input) | I (49h) | i (69h) | 1 |
Create Resource (output) | O (4Fh) | o (6Fh) | 1 |
Delete Resource | D (44h) | d (64h) | 1 |
Add Push Handler | H (48h) | h (68h) | 1 |
Remove Push Handler | K (4Bh) | k (6Bh) | 1 |
Push to Resource | P (50h) | p (70h) | 1 |
Get from Resource | G (47h) | g (67h) | 1 |
Create Sensor | S (53h) | s (73h) | 1 |
Remove Sensor | R (52h) | r (72h) | 1 |
Set JSON Example | E (45h) | e (65h) | 1 |
Push Handler Call | c (63h) | C (43h) | 1 |
Sensor Handler Call | b (62h) | B (42h) | 1 |
Sync | Y (59h) | y (79h) | 2 |
Unknown Request | ? (3Fh) | 1 |
Response Structure
Protocol Version 1 - ASCII
The first 4 bytes of a response packet must be present, even if not all are applicable to the specific response.
<packet type[1]><status[1]><segment[2]><contents[variable]>
Fields:
packet type : Identifies response, 1-byte
status : Identifies status of response. 1-byte
segment : Count allowing a responses to span multiple packets. 2-bytes
contents : Packet dependent, variable length
Protocol Version 2 - ASCII
<packet type[1]><status[1]><sequence[2]><contents[variable]>
Fields:
packet type : Identifies response, 1-byte
status : Identifies status of response. 1-byte
sequence : Packet number - count of packets sent by the sender since restart, including the current. 2-bytes, binary
contents : Packet dependent, variable length
Data Types
Type | Value |
---|---|
Trigger | T (54h) |
Boolean | B (42h) |
Numeric | N (4Eh) |
String | S (53h) |
JSON | J (4Ah) |
Note
When the data type field is ignored, any character may be used.
Version
The version byte is encoded in ASCII hex, beginning with '0'. The version number is calculated as follows:
version number = version byte + 0x01
For example, a version byte of 0x31 equates to version 2.
Sequence
The number of the current packet (i.e., count of the number of packets sent by the sender since restart, including the current one). This field is available in ORP versions 2.x and up.
Status
Octave edge devices provide a Resource with sub Resources under the node: orp/status. This status Resource provides the connection state as well as statistics and error reporting.
The status byte is encoded beginning with '@' (hex 40), which represents success. The status value can be calculated from this byte as:
status value = -1 * (<status byte> - 0x40)
where the status value is interpreted as:
Code | Description |
---|---|
0 | OK |
-1 | NOT FOUND |
-3 | OUT OF RANGE |
-4 | NO MEMORY |
-5 | NOT PERMITTED |
-6 | FAULT |
-7 | COMM ERROR |
-8 | TIMEOUT |
-9 | OVERFLOW |
-10 | UNDERFLOW |
-11 | WOULD BLOCK |
-12 | DEADLOCK |
-13 | FORMAT ERROR |
-14 | DUPLICATE |
-15 | BAD PARAMETER |
-16 | CLOSED |
-17 | BUSY |
-18 | UNSUPPORTED |
-19 | IO ERROR |
-20 | NOT IMPLEMENTED |
-21 | UNAVAILABLE |
-22 | TERMINATED |
Timestamps
The timestamp is encoded as a whole number, representing seconds since the UNIX epoch. Digits are encoded as ASCII decimal and are preceded by the character 'T'.
For example: T946684799 = December 31, 1999 23:59:59 GMT
The maximum length of a timestamp is 11 ASCII digits.
Paths
The path is encoded as ASCII text string with no null terminator.. The path field is preceded by the character 'P'. (e.g., Pinput/button_01
).
Allowable characters are: a-z A-Z 0-9 / _ -
The maximum length of a path depends on the type of Resource being created or accessed. A Sensor Resource includes auto-generated sub-nodes which reduce the allowable path length during the create request to 32 characters.
Paths which do not begin with a slash ‘/’ are treated as being relative to orp/asset
. In order to access other Resources, such as those under orp/status
, a full path must be provided that includes a beginning ‘/’ character (e.g., /orp/status/UART1/value
).
Field | Bytes | Comment |
---|---|---|
Path, Resource | 65 | Data Hub MAX_RESOURCE_PATH_LEN - "/app/orp/asset" |
Path, Sensor | 57 | Resource path max len - "/trigger" |
Data
Data is prepended with the character 'D' and there is no encoding of the contents. The data field must occur last in a packet. The maximum data length (payload) is 50,000 bytes.
For example: D0123456789,abc*
For some data types, the ORP service will transform the data it receives into the correct internal type. A failure to convert the data will result in an error being returned.
Data Type | Conversion |
---|---|
trigger | Not applicable |
boolean | Case insensitive comparison with "false" -> false Case insensitive comparison with "true" ‐> true "0" -> false "1" -> true Otherwise an error is returned |
numeric | Interpreted as double-precision real |
string | No conversion |
JSON | No conversion |
Packet Counts
Sync packets (version 2 and later) contain fields to report packets sent and received. These are whole numbers, encoded as ASCII decimal, and are preceded by an 'R' for received count and an 'S' for sent count (e.g., R251,S305).
Operations
Asset to Octave Edge Device
CreateResource
Request to create a Resource in the Data Hub. If a CreateResource
request is received for a Resource which already exists, the request will succeed only if all requested parameters match those of the existing Resource. In this case, no changes are actually applied. If one or more parameters differs from the existing Resource, the request will fail.
Request: <packet type[1]><data type[1]><sequence[2]><path>[,<units>]
packet type: 'I' || 'O'
data type: 'T' || 'B' || 'N' || 'S' || 'J' (Trigger || Boolean || Numeric || String || Json)
sequence: Version 1: ignored. Version 2: packet number
path: 'P'<path of the Resource>
units: 'U'<units> (optional)
Response: <packet type[1]><status[1]><sequence[2]>
packet type: 'i' || 'o'
status: see above
sequence: Version 1: ignored. Version 2: packet number
DeleteResource
Request to remove a Resource from the Data Hub. When a Resource is deleted, any associated handlers are also de-registered.
Request: <packet type[1]><data type[1]><sequence[2]><path>
packet type: 'D'
data type: ignored
sequence: Version 1: ignored. Version 2: packet number
path: 'P'<path of the Resource>
Response: <packet type[1]><status[1]><sequence[2]>
packet type: 'd'
status: see above
sequence: Version 1: ignored. Version 2: packet number
AddPushHandler
Asset request to be notified when data is written to a path. Once an asset successfully registers a handler, notification packets will be sent by the ORP service whenever there is a change in the associated Resource (path).
Request: <packet type[1]><data type[1]><sequence[2]><path>
packet type: 'H'
data type: ignored
sequence: Version 1: ignored. Version 2: packet number
path: 'P'<path of the Resource>
Response: <packet type[1]><status[1]><sequence[2]>
packet type: 'h'
status: see above
sequence: Version 1: ignored. Version 2: packet number
RemovePushHandler
Asset request to cease notifications for a particular path.
Request: <packet type[1]><data type[1]><sequence[2]><path>
packet type: 'K'
data type: ignored
sequence: Version 1: ignored. Version 2: packet number
path: 'P'<path of the Resource>
Response: <packet type[1]><status[1]><sequence[2]>
packet type: 'k'
status: see above
sequence: Version 1: ignored. Version 2: packet number
Push
Asset request to push data to a Resource.
Request: <packet type[1]><data type[1]><sequence[2]><path>[,<timestamp>][,<data>]
packet type: 'P'
data type: 'T' || 'B' || 'N' || 'S' || 'J' (Trigger || Boolean || Numeric || String || Json)
sequence: Version 1: ignored. Version 2: packet number
path: 'P'<path of the Resource>
timestamp: 'T'<time in seconds> (optional - omit to use current data hub timestamp)
data: 'D'<data> (optional)
Response: <packet type[1]><status[1]><sequence[2]>
packet type: 'p'
status: see above
sequence: Version 1: ignored. Version 2: packet number
Get
Asset request to read data from a Resource.
Request: <packet type[1]><data type[1]><sequence[2]><path>
packet type: 'G'
data type: ignored
sequence: Version 1: ignored. Version 2: packet number
path: 'P'<path of the Resource>
Response: <packet type[1]><status[1]><sequence[2]><timestamp>,<data>
packet type: 'g'
status: see above
sequence: Version 1: ignored. Version 2: packet number
timestamp: 'T'<time in seconds>
data: 'D'<data> (represented as ASCII, NOT null terminated)
CreateSensor
Asset request to create a sensor type in the Data Hub. If a CreateSensor
request is received for a sensor which already exists, the request will succeed only if all requested parameters match those of the existing Resource. In this case, no changes are actually applied. If one or more parameters differs from the existing Resource, the request fails.
Request: <packet type[1]><data type[1]><sequence[2]><path>[,<units>]
packet type: 'S'
data type: 'B' || 'N' || 'S' || 'J' (Boolean || Numeric || String || Json)
sequence: Version 1: ignored. Version 2: packet number
path: 'P'<path of the Resource>
units: 'U'<units> (optional)
Response: <packet type[1]><status[1]><sequence[2]>
packet type: 's'
status: see above
sequence: Version 1: ignored. Version 2: packet number
DestroySensor
Asset request to delete a sensor from the Data Hub.
Request: <packet type[1]><data type[1]><sequence[2]><path>
packet type: 'R'
data type: ignored
sequence: Version 1: ignored. Version 2: packet number
path: 'P'<path of the sensor>
Response: <packet type[1]><status[1]><sequence[2]>
packet type: 'r'
status: see above
sequence: Version 1: ignored. Version 2: packet number
SetJsonExample
Asset request to populate the JSON example node of a Resource.
Request: <packet type[1]><data type[1]><sequence[2]><path>,<data>
packet type: 'E'
data type: 'J' (Json)
sequence: Version 1: ignored. Version 2: packet number
path: 'P'<path of the Resource>
data: 'D'<data>
Response: <packet type[1]><status[1]><sequence[2]>
packet type: 'e'
status: see above
sequence: Version 1: ignored. Version 2: packet number
Octave Edge Device to Asset
PushHandler
Notification that data has changed on a Resource.
Notification: <packet type[1]><unused[1]><sequence[2]><timestamp>,<path>[,<data>]
packet type: 'c'
unused: not applicable - ignore
sequence: Version 1: ignored. Version 2: packet number
timestamp: 'T'<time in seconds>
path: 'P'<path of the Resource>
data: 'D'<data> (optional)
Response: <packet type[1]><status[1]><sequence[2]>
packet type: 'C'
status: see above
sequence: Version 1: ignored. Version 2: packet number
SensorCall
Notification that a sensor is requesting a push. A SensorCall
notification is to inform the owner of a sensor (the asset) that the Data Hub is requesting that data be pushed to the sensor value node. The asset should follow this notification with a Push
to the sensor value Resource.
Notification: <packet type[1]><unused[1]><sequence[2]><path>
packet type: 'b'
unused: not applicable - ignore
sequence: Version 1: ignored. Version 2: packet number
path: 'P'<path of the Resource>
Response: <packet type[1]><status[1]><sequence[2]>
packet type: 'B'
status: see above
sequence: Version 1: ignored. Version 2: packet number
Sync (Version 2 and up)
An unsolicited notification sent from the ORP service to the asset to indicate that the service has restarted.
After a restart of the ORP Service, the service will periodically send this message until either a direct response is received from the asset, or the asset sends any other valid packet. Once a response has been received, the ORP service will update its status to "connected".
The response packet must contain the protocol version which the remote device will use. The version byte is calculated as: version byte = version number - 0x01
. If the remote device does not explicitly respond to the sync packet with a sync response but instead sends any other valid packet, the ORP service assumes that the remote is using protocol version 1.
Note
The sequence numbers are not used in the sync and sync response packets. The sequence count must not be incremented when sending a sync or sync response.
Notification: <packet type[1]><version[1]><sequence[2]><timestamp><received><sent>
packet type: 'Y'
version: Maximum ORP version supported
sequence: unused
timestamp: 'T'<time in seconds>
received: 'R'<received count>. Packets received since restart, equal to zero (ASCII decimal, NOT null terminated)
sent: 'S'<sent count>. Packets sent since restart, equal to zero (ASCII decimal, NOT null terminated)
Response: <packet type[1]><version[1]><sequence[2]>
packet type: 'y'
version: ORP version supported
sequence: unused
Updated over 4 years ago