Goby Underwater Autonomy Project
Series: 1.1, revision: 163, released on 2013-02-06 14:23:27 -0500
|
Table of contents for libdccl:
Return to goby-acomms: Overview of Acoustic Communications Libraries.
Scenario 1: Send a string command to a vehicle:
We need to send an ASCII string command to an underwater vehicle. We thus make the <layout> section of the message contain a single message variable, a <string>. We know that a string uses a byte for each character and DCCL uses six header bytes (CCL id, DCCL id, time, src, dest, flags), making the <max_length> of our string 26 (32-6). We need some sort of name for our string to use internally when encoding and decoding this message, so we'll use <name> of "s_key" to stand for "string key".
We want to have the ability to use the lowest rate WHOI Micro-Modem message size, so we pick <size> to be 32. We have no other DCCL messages currently in the system so we start with an <id> of 1. Since this is a simple case we choose a "Simple" for our <name>.
See dccl_simple.cpp for the final result (simple.xml) and for an example of how to use this message.
Scenario 2: Send a more realistic command and receive a status message from the vehicle:
We want to be able to command our vehicle (to which we have assigned an ID number of "2") to go to a specific point on a local XY grid (meters from some known latitude / longitude), but no more than 10 kilometers from the datum. We also want to be able to turn the lights on or off, and send a short string for other new instructions. Finally, we need to be able to command a speed. Our vehicle can move no faster than 3 m/s, but its control is precise enough to handle hundredths of a m/s (wow!). It's probably easiest to make a table with our conditions:
message variable name | description | type | bounds |
dest_id | id number of the vehicle we are commanding | integer | built into the header [0, 31] |
goto_x | meters east to transit from datum | integer | [0, 10000] |
goto_y | meters north to transit from datum | integer | [0, 10000] |
lights_on | turn on the lights? | boolean | |
new_instructions | string instructions | string | no longer than 10 characters |
goto_speed | transit speed (m/s) | float | [0.00, 3.00] |
Taking all this into account, we form the <layout> section of the first message (named GoToCommand) in the file two_message.xml (see two_message.cpp).
We choose <id> of 2 to avoid conflicting with the message from Scenario 1 (simple.xml) and a <size> of 32 bytes to again allow sending in the WHOI Micro-Modem rate 0 packet.
Now, for the second message in two_message.xml. We want to receive the vehicle's present position and its current health, which can either be "good", "low_battery" or "abort". We make a similar table to before:
message variable name | description | type | bounds |
nav_x | current vehicle position (meters east of the datum) | integer | [0, 10000] |
nav_y | current vehicle position (meters north of the datum) | integer | [0, 10000] |
health | vehicle state | enumeration | good, low_battery, or abort |
The resulting message, along with an example of how to use it, can be seen here: two_message.cpp.
You can run analyze_dccl_xml
to view more information on your messages:
> analyze_dccl_xml /path/to/two_message.xml
When I ran the above command I got (omitting parts of the header we're not using to save space):
creating DCCLCodec using xml file: [examples/two_message/two_message.xml] and schema: [../../message_schema.xsd] schema must be specified with an absolute path or a relative path to the xml file location (not pwd!) parsed file ok! ############################## detailed message summary: ############################## ******************** message 2: {GoToCommand} requested size {bytes} [bits]: {32} [256] actual size {bytes} [bits]: {21} [167] >>>> HEADER <<<< destination (int): size [bits]: [5] [min, max] = [0,31] >>>> LAYOUT (message_vars) <<<< type (static): size [bits]: [0] value: "goto" goto_x (int): size [bits]: [14] [min, max] = [0,10000] goto_y (int): size [bits]: [14] [min, max] = [0,10000] lights_on (bool): size [bits]: [2] new_instructions (string): size [bits]: [80] goto_speed (float): size [bits]: [9] [min, max] = [0,3] precision: {2} ******************** ******************** message 3: {VehicleStatus} requested size {bytes} [bits]: {32} [256] actual size {bytes} [bits]: {11} [84] >>>> LAYOUT (message_vars) <<<< nav_x (float): size [bits]: [17] [min, max] = [0,10000] precision: {1} nav_y (float): size [bits]: [17] [min, max] = [0,10000] precision: {1} health (enum): size [bits]: [2] values:{good,low_battery,abort} ********************
Besides validity checking, the most useful feature of analyze_dccl_xml
is the calculation of the size (in bits) of each message variable. This lets you see which fields in the message are too big. To make fields smaller, tighten up bounds (depending on the type, increase <min>, decrease <max>, decrease <precision>, decrease <max_length>, decrease <num_bytes>, or decrease the number of <enum> <value> options).
This section gives a brief outline of the tag structure of an XML file for defining a DCCL message. See DCCL XML Tags Reference for a full description of each tag.
DCCL root tags:
<?xml version="1.0" encoding="UTF-8"?>
: specifies that the file is XML; must be the first line of every message XML file. Children of <message> needed for normal goby::acomms::DCCLCodec::encode and goby::acomms::DCCLCodec::decode:
Children of <message> needed (in addition to those above) for publish/subscribe architecture methods goby::acomms::DCCLCodec::pubsub_encode and goby::acomms::DCCLCodec::pubsub_decode (these tags are ignored for calls to goby::acomms::DCCLCodec::encode and goby::acomms::DCCLCodec::decode):
Using the goby::acomms::DCCLCodec is a fairly straightforward endeavor. First you need to instantiate a copy of this object with the configuration you want (including the XML files you want to be able to use):
goby::acomms::DCCLCodec dccl(&std::clog); goby::acomms::protobuf::DCCLConfig cfg; cfg.add_message_file()->set_path("path/to/file.xml"); cfg.set_modem_id(1); // unique id 1-31 for each platform dccl.set_cfg(cfg);
Then, to encode a message, fill up std::maps of dccl::MessageVal where the key of the map (i.e. the it->first
if it
is the map iterator) is the <name> of each message variable, and the value (it->second
) is the quantity you wish to encode. All reasonable type conversions will be made by DCCL using dccl::MessageVal (doubles to <int>, for example), but the most predictable (and fastest) results will be gained by using the following mapping between DCCL message variable types and C++ types:
DCCL Message Variable Type | C++ Type | Example |
<int> | long | 421 |
<float> | double | 42.1 |
<hex> | std::string | "abc23" or "ABC23" (case does not matter) |
<enum> | std::string | "ON" (case matters, this will not match <value>on</value> , but will match <value>ON</value> ) |
<string> | std::string | "i am hungry" (case matters, string cannot contain any null characters in the middle, i.e. '\0') |
<bool> | bool | true |
After filling up the std::maps, pass pointers to the maps to goby::acomms::DCCLCodec::encode along with a reference to a string in which to store the result:
std::map<std::string, dccl::MessageVal> vals; // code to insert values into map // ... // // store the result here, using the string as a byte container std::string bytes; dccl.encode(id, bytes, vals);
bytes
will now contain the encoded message in the form of a byte string (each char will contain a single byte of the message).
You may now send this message through whatever channel you would like, or pass it to the goby::acomms::QueueManager to queue for sending later.
To decode a message (stored in bytes
as a byte string), simply pass hex as a reference along with pointers to the maps to store the results. Based on the maps you provide, values will be cast and stored as the best fit.
std::map<std::string, std::string> vals; dccl.decode(1, bytes, vals);
For line by line interaction with the goby::acomms::DCCLCodec and for advanced use, investigate the code examples given in the Examples column of this table.
Encryption of all messages can be enabled by providing a secret passphrase to the goby::acomms::protobuf::DCCLConfig object passed to goby::acomms::DCCLCodec::set_cfg(). All parties to the communication must have the same secret key.
DCCL provides AES (Rijndael) encryption for the body (<layout>) of the message. The header, which is sent in plain text, is hashed to form an initialization vector (IV), and the passphrase is hashed using SHA-256 to form the cipher key.
AES is considered secure and is used for United States top secret information.
We may want to know the actual layout of the binary/hex message. For the first of the two messages in two_message.xml, we can run analyze_dccl_xml
to find the sizes of each message variable. The calculated sizes are used to determine the boundaries (which are by bit, not by byte) when the message is packed. Each field is placed in the order it is declared in the XML file such that the message is as follows (where left to right is the same as reading the hex string from left to right):
[[header][0 {1}][goto_x {14}][goto_y {14}][lights_on {2}][new_instructions {80}][goto_speed {9}]]
where [0 {1}]
means zero fill the message to the closest whole byte (15 bytes = 120 bits minus 119 for other fields = 1). Byte boundaries are dissolved and encoded as a string "ABCDEF..." where the most significant byte (MSB, or leftmost 8 bits) is 0xAB, second MSB is 0xCD, etc. Encoding and decoding are done by functions available in tes_utils.h. You will notice that the resulting size is 15 bytes which is short of the 32 bytes specified for the <size>. This is because the <size> is a maximum size before a warning is generated, not the actual size always returned by the DCCLCodec. This allows libqueue to pack multiple messages together to form a modem message frame and thus fit a nearly optimal amount of data into each modem packet. For example, you could now fit one of the GoToCommand messages and another message up to 17 bytes in a single 32 byte WHOI Micro-Modem rate 0 frame.
The encoding of each message_var is done as an unsigned integer, with the exception of strings, which are store as ASCII. The value 0 (all bits zero) always indicates "not specified" or "Not a Number" (nan). This means that the user did not specify any value for this field, specified a value causing overflow (<int> or <float> greater than <max> or less than <min>), or provided a value for an <enum> that did not match any of the enumerate's <value> options. Along with this rule, the method for encoding and decoding is summarized below:
message_var | size (bits) | encode | decode |
static | 0 | not sent | not sent |
bool | 2 | == to_lower("true") OR != 0) ? 2 : 1 | ? true : false |
enum | = 1 + index to array of enum values based on order they were declared | = value at index | |
string | string is filled at end with zeros ('\0' ) to then encoded using ASCII byte values | ASCII, ignoring null termination chars (if any) | |
int | |||
float | |||
hex |
where is the original (and decoded) value, is the encoded value, , , , are the contents of the <min>, <max>, <max_length>, and <precision> tags, respectively, and round( ,0) means round to the nearest integer.
An example. Say you have the following XML file:
... <id>1</id> <header> <src_id> <name>Src</name> </src_id> <dest_id> <name>Dest</name> </dest_id> </header> <layout> <bool> <name>B</name> </bool> <enum> <name>E</name> <value>cat</value> <value>dog</value> <value>mouse</value> </enum> <string> <name>S</name> <max_length>4</max_length> </string> <int> <name>I</name> <max>100</max> <min>-50</min> </int> <float> <name>F</name> <max>100</max> <min>-50</min> <precision>2</precision> </float> </layout> ...
The header is always the same size and is given by (sizes shown in bits):
Next, the size of each message_var (in the <layout> section) and its encoded value in decimal and binary are calculated for an example set of inputs:
message_var | example | size (bits) | (decimal) | (binary) |
B | true | 2 | 2 | 10 |
E | cat | 2 | 1 | 01 |
S | FAT | 32 | 1178686464 | 01000110 01000001 01010100 00000000 |
I | 34 | 8 | 85 | 01010101 |
F | -22.49 | 14 | 2752 | 00101011000000 |
and thus the whole message (zero padded from the most significant bits to the closest byte) sent would be
00000010 01010001 10010000 01010101 00000000 00010101 01001010 11000000
or
0x0251905500154AC0
plus the header, which in this case is 0x2000AA300230, so the full message sent is
0x2000AA3002300251905500154AC0
Syntax:
<?xml version="1.0" encoding="UTF-8"?> <message_set> <message> <on_receipt> <publish> ... <all /> </publish> </on_receipt> </message> </message_set>
Description: Equivalent to <message_var> for all the message_vars in the message. This is a shortcut when you want to publish all the data in a human readable string. [optional, one allowed].
Syntax:
<?xml version="1.0" encoding="UTF-8"?> <message_set> <message> <layout> <int> <array_length>5</array_length> </int> <string> <array_length>5</array_length> </string> <float> <array_length>5</array_length> </float> <bool> <array_length>5</array_length> </bool> <hex> <array_length>5</array_length> </hex> <enum> <array_length>5</array_length> </enum> </layout> </message> </message_set>
Description: If larger than 1, this makes an array of values instead of a single value.
\b Syntax: <?xml version="1.0" encoding="UTF-8"?> <message_set> <message> <layout> ... <bool algorithm=""> <src_var></src_var> <name></name> </bool> </layout> </message> </message_set>
Description: a boolean (true or false) message_var The optional parameter algorithm
allows you to perform certain algorithms on the data before encoding. See libdccl/examples/test/test.cpp [optional, one or more allowed].
Syntax:
<?xml version="1.0" encoding="UTF-8"?> <message_set> <message> <header> <dest_id> <name></name> <src_var></src_var> <dest_id> </header> </message> </message_set>
Description: Allows setting a name other than the default ("_dest_id") and a <src_var> for the destination id field of the header.
Syntax:
<?xml version="1.0" encoding="UTF-8"?> <message_set> <message> ... <!-- OUT_MESSAGE: destination=abcd,... --> <destination_var key="destination">OUT_MESSAGE</destination_var> </message> </message_set>
Description: deprecated. Use <dest_id> instead.
architecture variable to find where this message should be sent. Specify attribute "key=" to specify a substring to look for within the value of this architecture variable. For example, if COMMAND
contained the string Destination=3
and you want this message sent to modem_id 3, then you should set key=Destination
to properly parse that string. [optional: default is 0 (broadcast), one allowed].
Syntax:
<?xml version="1.0" encoding="UTF-8"?> <message_set> <message> <layout> ... <enum algorithm=""> <src_var></src_var> <name></name> <value></value> <value></value> <value></value> </enum> </layout> </message> </message_set>
Description: an enumeration message_var [optional, one or more allowed].
Syntax:
<?xml version="1.0" encoding="UTF-8"?> <message_set> <message> <layout> ... <float algorithm=""> <src_var></src_var> <name></name> <max></max> <min></min> <precision></precision> </float> </layout> </message> </message_set>
Description: a decimal valued real number message_var [optional, one or more allowed].
Syntax:
<?xml version="1.0" encoding="UTF-8"?> <message_set> <message> <on_receipt> <publish> ... <format>A=%1%,B=%2%</format> </publish> </on_receipt> </message> </message_set>
Description: a string conforming to the format string syntax of the boost::format library. This field will specify the format of the string published to the architecture variable defined in <publish_var>. At its simplest, it is a string of incrementing numbers surrounded by %%. Or, instead, you may also use a printf style string, using %d for int message_var, %lf for floats, and %s for strings, bools, enums and hex. [optional: default is name1=%1%,name2=%2%,name3=%3%
, where name1
is the name of the first <message_var> field to follow, name2
is the second, etc. exception: default is %1%
if only a single <message_var> defined. one allowed].
Syntax:
<?xml version="1.0" encoding="UTF-8"?> <message_set> <message> <header> <time></time> <src_id></src_id> <dest_id></dest_id> </header> <layout> ... </layout> </message> </message_set>
Description: holds tags allowing some parts of the DCCL header to be referenced by a new name (other than the defaults: "_time", "_src_id", "_dest_id") at encode and decode time. See <src_id>, <dest_id>, <time>.
Syntax:
<?xml version="1.0" encoding="UTF-8"?> <message_set> <message> <layout> ... <hex algorithm=""> <src_var></src_var> <name></name> <num_bytes></num_bytes> </hex> </layout> </message> </message_set>
Description: a message variable represented pre-encoded hexadecimal to add to the message. This field is useful if another source is encoding part or all of a DCCL message. [optional, one or more allowed].
Syntax:
<?xml version="1.0" encoding="UTF-8"?> <message_set> <message> ... <id>23</id> </message> </message_set>
Description: an unsigned nine bit integer (0-511)g that identifies this message within a network. very similar to the CCL identifier, but for DCCL messages. The CCL identifier occupies the most significant byte (MSB) of the message followed by this id which takes the part of the second MSB (two flags, multimessage and broadcast, use the remainder of the second MSB). This must be unique within a network. [mandatory, one allowed]
Syntax:
<?xml version="1.0" encoding="UTF-8"?> <message_set> <message> <layout> ... <int algorithm=""> <src_var></src_var> <name></name> <max></max> <min></min> </int> </layout> </message> </message_set>
Description: an integer message_var [optional, one or more allowed].
Syntax:
<?xml version="1.0" encoding="UTF-8"?> <message_set> <message> ... <layout> <int></int> <string></string> <float></float> <bool></bool> <hex></hex> <static></static> <enum></enum> </layout> </message> </message_set>
Description: defines the message structure itself (what fields [the message variables or message_vars] the message contains and how they are to be encoded). [mandatory, one allowed].
Syntax:
<?xml version="1.0" encoding="UTF-8"?> <message_set> <message> <layout> <string> ... <max_length>10</max_length> </string> </layout> </message> </message_set>
Description: the length of the string value in this field. Longer strings are truncated. <max_length>4</max_length>
means "ABCDEFG" is sent as "ABCD". [mandatory, one allowed].
Syntax:
<?xml version="1.0" encoding="UTF-8"?> <message_set> <message> <layout> <int> <max>100</max> </int> <float> <max>100</max> </float> </layout> </message> </message_set>
Description: the maximum value this field can take. [mandatory, one allowed].
Syntax:
<?xml version="1.0" encoding="UTF-8"?> <message_set> <message> <layout> <int> <max_delta>10</max_delta> </int> <float> <max_delta>100</max_delta> </float> </layout> </message> </message_set>
Description: if specified, delta-difference encoding is done of the <repeat> ed message or the values in the array (for <array_length> > 1). The first value is used as a key for the remaining values which are sent as a difference to this key. The number specified here is the maximum expected difference between the first value (key) and any of the remaining values in the message. [optional, if omitted, delta-difference encoding is not performed].
Syntax:
<?xml version="1.0" encoding="UTF-8"?> <message_set> <message></message> <message></message> <message></message> </message_set>
Description: the root element. All XML files must have a single root element. Since we are define a set of messages (one or more per file), this is a logical choice of name for the root element. [mandatory, one allowed].
Syntax:
<?xml version="1.0" encoding="UTF-8"?> <message_set> <message> <on_receipt> <publish> ... <message_var></message_var> <message_var></message_var> </publish> </on_receipt> </message> </message_set>
Description: the name (<name> above) of a message_var contained in this message (i.e. an <int>, <bool>, etc.) the values of these fields upon receipt of a message will be used to populate the format string and the result will be published to <publish_var>. The optional parameter algorithm
allows you to perform certain algorithms on the data after receipt before publishing. [mandatory unless <all> used, one or more allowed].
Syntax:
<?xml version="1.0" encoding="UTF-8"?> <message_set> <message> <name></name> <id></id> <size></size> <layout></layout> <destination_var key=""></destination_var> <trigger>publish</trigger> <trigger_var mandatory_content=""></trigger_var> <!-- OR --> <trigger>time</trigger> <trigger_time></trigger_time> <on_receipt></on_receipt> <queuing></queuing> </message> <message> ... </message> </message_set>
Description: defines the start of a message. [mandatory, one or more allowed].
Syntax:
<?xml version="1.0" encoding="UTF-8"?> <message_set> <message> <layout> <int> <min>-100</min> </int> <float> <min>-100</min> </float> </layout> </message> </message_set>
Description: the minimum value this field can take. [mandatory, one allowed].
Syntax:
<message_set> <message> ... <name>STATUS_REPORT</name> </message> </message_set>
or
<?xml version="1.0" encoding="UTF-8"?> <message_set> <message> <layout> <int> <name>parameter1</name> </int> <string> <name>parameter2</name> </string> <float> <name>parameter3</name> </float> <bool> <name>parameter4</name> </bool> <hex> <name>parameter5</name> </hex> <static> <name>parameter6</name> </static> <enum> <name>parameter7</name> </enum> </layout> </message> </message_set>
Description: (as child of <message>): a human readable name for the message. [mandatory, one allowed]
(as child of <int>, <hex>, <string>, <float>, <enum>, or <bool>): the name of this message_var. [mandatory, one allowed].
the number of bytes for this field. The string provided should be twice as many characters as <num_bytes> since each character of a hexadecimal string is one nibble (4 bits or 1/2 byte). [mandatory, one allowed].
Syntax:
<?xml version="1.0" encoding="UTF-8"?>
Description: contains the various <publish> options for publishing parts of a message upon receipt when using the publish-subscribe architecture method (goby::acomms::DCCLCodec::encode_to_publish). [optional, one allowed].
Syntax:
<?xml version="1.0" encoding="UTF-8"?> <message_set> <message> <layout> <float> <precision>3</precision> </float> </layout> </message> </message_set>
Description: an integer that specifies the number of decimal digits to preserve. Negatives are allowed. For example, <precision>2</precision>
rounds 1042.1234 to 1042.12; <precision>-1</precision>
rounds 1042.1234 to 1.04e3. [mandatory, one allowed].
Syntax:
<?xml version="1.0" encoding="UTF-8"?> <message_set> <message> <on_receipt> <publish> <publish_var></publish_var> <format></format> <message_var></message_var> </publish> </on_receipt> </message> </message_set>
Description: defines a single output value upon receipt of a message. Any number of publishes containing any subset of the message_vars can be specified. [mandatory, one or more allowed].
Syntax:
<?xml version="1.0" encoding="UTF-8"?> <message_set> <message> <on_receipt> <publish> <publish_var type="string">OUT_STATUS_REPORT</publish_var> </publish> </on_receipt> </message> </message_set>
Description: the name of the architecture variable to publish to. If desired, a format string is allowed here as well (e.g. %1%_NAV_X
will fill %1%
with the first message_var). See the <format> tag description for more info. [mandatory, one allowed].
Syntax:
<?xml version="1.0" encoding="UTF-8"?> <message_set> <message> ... <repeat/> </message> </message_set>
Description: Including this empty tag tells DCCL to make as many copies of the message structure defined in <layout> as will fit in the message <size>. No message will be sent until the message is full. For example, if the message is 32 bytes and the layout is 8 bytes, three copies of the message will be stored before sending (32-6-3*8 = 0). That is, three messages will be triggered, packed and sent as a single DCCL message. [optional, if omitted only a single copy is made]. If <repeat> is specified, <array_length> must omitted for all message}. That is, you cannot have repeated messages that contain arrays.
Syntax:
<?xml version="1.0" encoding="UTF-8"?> <message_set> <message> <size>32</size> </message> </message_set>
Description: the size of the message in bytes. There are eight bits (binary digits) to a byte. Use N here for messages passed to the Micro-Modem where N is the desired Micro-Modem frame size (N=32, 64, or 256 depending on the rate). If the <layout> of the message exceeds this size, DCCL will exit on startup with information about sizes, from which you can remove or reduce the size of certain message_vars.
Syntax:
<?xml version="1.0" encoding="UTF-8"?> <message_set> <message> <header> <src_id> <name></name> <src_var></src_var> <src_id> </header> </message> </message_set>
Description: Allows setting a name other than the default ("_src_id") and a <src_var> for the source id field of the header.
Syntax:
<?xml version="1.0" encoding="UTF-8"?> <message_set> <message> <layout> <!-- OUT_MESSAGE: ...,parameter1=123,parameter2=abc,parameter3=3.42, parameter4=true,parameter5=ON SOME_OTHER_HEX: 24bbc231 --> <int> <src_var key="parameter1">OUT_MESSAGE</src_var> </int> <string> <src_var key="parameter2">OUT_MESSAGE</src_var> </string> <float> <src_var key="parameter3">OUT_MESSAGE</src_var> </float> <bool> <src_var key="parameter4">OUT_MESSAGE</src_var> </bool> <hex> <src_var>SOME_OTHER_HEX</src_var> </hex> <enum> <src_var key="parameter5>OUT_MESSAGE</src_var> </enum> </layout> </message> </message_set>
Description: the architecture variable from which to pull the value of this field. [optional if <trigger>publish</trigger>
: default is trigger_var; mandatory if <trigger>time</trigger>
, one allowed].
Syntax:
<?xml version="1.0" encoding="UTF-8"?> <message_set> <message> <layout> <static algorithm=""> <name></name> <value></value> </static> </layout> </message> </message_set>
Description: a message_var that is not actually sent with the message but can be used to include in received messages (publishes). [optional, one or more allowed].
Syntax:
<?xml version="1.0" encoding="UTF-8"?> <message_set> <message> <layout> <string algorithm=""> <src_var></src_var> <name></name> <max_length></max_length> </string> </layout> </message> </message_set>
Description: an ASCII string message_var [optional, one or more allowed].
Syntax:
<?xml version="1.0" encoding="UTF-8"?> <message_set> <message> <header> <time> <name></name> <src_var></src_var> </time> </header> </message> </message_set>
Description: Allows setting a name other than the default ("_time") and a <src_var> for the time field of the header. Note that the value of the <src_var> should be a UNIX timestamp (seconds since 1/1/1970 00:00:00). In the DCCL encoding, this reduced to seconds since the start of the day, with precision of one second. Upon decoding, assuming the message arrives within twelve hours of its creation, it is properly restored to a full UNIX time.
Syntax:
<?xml version="1.0" encoding="UTF-8"?> <message_set> <message> <trigger>publish</trigger> <trigger_var mandatory_content="">OUT_MESSAGE</trigger_var> </message> </message_set>
Description: used if <trigger>publish</trigger>
, this field gives the architecture variable that publishes to will trigger the creation of this message [mandatory if and only if <trigger>publish</trigger>
]. optional attribute mandatory_content
specifies a string that must be a substring of the contents of the trigger variable in order to trigger the creation of a message. For example, if you wanted to create a certain message every time COMMAND
contained the string CommandType=GoTo...
but no other time, you would specify mandatory_content="CommandType=GoTo"
within this tag.
Syntax:
<?xml version="1.0" encoding="UTF-8"?> <message_set> <message> <trigger>time</trigger> <trigger_time>60</trigger_time> </message> </message_set>
Description: used if <trigger>time</trigger>
, this field gives the time interval used to create this message. For example, a value of <trigger_time>10</trigger_time>
would mean a message should be created every ten seconds. [mandatory if and only if <trigger>time</trigger>
].
Syntax:
<?xml version="1.0" encoding="UTF-8"?> <message_set> <message> <trigger>publish</trigger> <trigger_var mandatory_content=""></trigger_var> <!-- OR --> <trigger>time</trigger> <trigger_time></trigger_time> </message> </message_set>
Description: how the message is created. Currently this field must take the value "publish" (meaning a message is created on a publish event to a certain architecture variable) or "time" (a message is created on a certain time interval). [mandatory, one allowed]
Syntax:
<?xml version="1.0" encoding="UTF-8"?> <message_set> <message> <layout> <static> <value>my static value</value> </static> </layout> </message> </message_set>
or
<?xml version="1.0" encoding="UTF-8"?> <message_set> <message> <layout> <enum> <value>ON</value> <value>OFF</value> <value>IN_BETWEEN</value> </enum> </layout> </message> </message_set>
Description: (as child of <static>): the value of this static variable. [mandatory, one allowed].
(as child of <enum>): a possible value (string) the enum can take. Any number of values can be specified. [mandatory, one or more allowed].