The KPN SenML library helps you create and parse senml documents in both json and cbor format. The library can be used for sending sensor data and receiving actuator commands.

Fork of kpn_senml by KPN IoT

Committer:
kpniot
Date:
Sun May 27 14:31:44 2018 +0000
Revision:
2:9b44be6e79ac
Parent:
0:a9259748d982
try to fix repo

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kpniot 0:a9259748d982 1 /* _ __ ____ _ _
kpniot 0:a9259748d982 2 * | |/ / | _ \ | \ | |
kpniot 0:a9259748d982 3 * | ' / | |_) | | \| |
kpniot 0:a9259748d982 4 * | . \ | __/ | |\ |
kpniot 0:a9259748d982 5 * |_|\_\ |_| |_| \_|
kpniot 0:a9259748d982 6 *
kpniot 0:a9259748d982 7 * (c) 2018 KPN
kpniot 0:a9259748d982 8 * License: MIT License.
kpniot 0:a9259748d982 9 * Author: Jan Bogaerts
kpniot 0:a9259748d982 10 *
kpniot 0:a9259748d982 11 * pack (document) without base values headers
kpniot 0:a9259748d982 12 */
kpniot 0:a9259748d982 13
kpniot 0:a9259748d982 14 #ifndef SENMLPACK
kpniot 0:a9259748d982 15 #define SENMLPACK
kpniot 0:a9259748d982 16
kpniot 0:a9259748d982 17 #ifdef __MBED__
kpniot 0:a9259748d982 18 #include "mbed.h"
kpniot 0:a9259748d982 19 #include <string>
kpniot 0:a9259748d982 20 using namespace std;
kpniot 0:a9259748d982 21 #define String string
kpniot 0:a9259748d982 22 #endif
kpniot 0:a9259748d982 23
kpniot 0:a9259748d982 24 #include <senml_base.h>
kpniot 0:a9259748d982 25
kpniot 0:a9259748d982 26
kpniot 0:a9259748d982 27 #define PACK_ACTUATOR_SIGNATURE void (*callback)(const char*, const char*, const void*, int, SenMLDataType)
kpniot 0:a9259748d982 28
kpniot 0:a9259748d982 29 /**
kpniot 0:a9259748d982 30 * SenMLPack represents a single senml document that can be sent or received.
kpniot 0:a9259748d982 31 *
kpniot 0:a9259748d982 32 * A senmlPack object has SenMLRecords and/or other SenMLPack objects as children. These
kpniot 0:a9259748d982 33 * represent the data that the object contains.
kpniot 0:a9259748d982 34 * A SenMLRecord represents a single value, while child SenMLPacks represent data of other
kpniot 0:a9259748d982 35 * devices. When a SenMLPack contains other SenMLPack objects, the root object represents a
kpniot 0:a9259748d982 36 * gateway.
kpniot 0:a9259748d982 37 *
kpniot 0:a9259748d982 38 * A SenMLPack object is able to render and parse the data to/from a json string or to/from binary
kpniot 0:a9259748d982 39 * CBOR data. Both rendering and parsing can be done either directly from a stream (like an UART
kpniot 0:a9259748d982 40 * connected to a modem), or from a memory buffer.
kpniot 0:a9259748d982 41 * Rendering to and parsing from a stream is useful for devices that have extreme low memory available.
kpniot 0:a9259748d982 42 * Almost no buffers are used in this case. Error handling is limited in this case though.
kpniot 0:a9259748d982 43 * The parser and generator are able to render in the native format (strings for json, binary data for
kpniot 0:a9259748d982 44 * cbor) and as a hex string. This is especially useful when directly working on a stream: some modems
kpniot 0:a9259748d982 45 * (ex lora) accept instructions with data in HEX format.
kpniot 0:a9259748d982 46 *
kpniot 0:a9259748d982 47 * example:
kpniot 0:a9259748d982 48 *
kpniot 0:a9259748d982 49 * @code
kpniot 0:a9259748d982 50 * #include <kpn_senml.h>
kpniot 0:a9259748d982 51 *
kpniot 0:a9259748d982 52 * SenMLPack doc("device_name");
kpniot 0:a9259748d982 53 *
kpniot 0:a9259748d982 54 * void setup(){
kpniot 0:a9259748d982 55 * Serial.begin(57600);
kpniot 0:a9259748d982 56 * senMLSetLogger(&Serial);
kpniot 0:a9259748d982 57 * delay(1000);
kpniot 0:a9259748d982 58 * Serial.println("start");
kpniot 0:a9259748d982 59 * }
kpniot 0:a9259748d982 60
kpniot 0:a9259748d982 61 * void loop(){
kpniot 0:a9259748d982 62 * int val = 10; //just give it some value
kpniot 0:a9259748d982 63 * SenMLFloatRecord rec("temp", SENML_UNIT_DEGREES_CELSIUS, val);
kpniot 0:a9259748d982 64 * doc.add(&rec);
kpniot 0:a9259748d982 65 * doc.toJson(&Serial); //as text
kpniot 0:a9259748d982 66 * Serial.println();
kpniot 0:a9259748d982 67 * doc.toJson(&Serial, SENML_HEX); //in hex format (often used in communication with lora modems)
kpniot 0:a9259748d982 68 * Serial.println();
kpniot 0:a9259748d982 69 * delay(1000);
kpniot 0:a9259748d982 70 * }
kpniot 0:a9259748d982 71
kpniot 0:a9259748d982 72 * @endcode
kpniot 0:a9259748d982 73 *
kpniot 0:a9259748d982 74 */
kpniot 0:a9259748d982 75 class SenMLPack: public SenMLBase
kpniot 0:a9259748d982 76 {
kpniot 0:a9259748d982 77 friend class SenMLJsonListener;
kpniot 0:a9259748d982 78 friend class SenMLCborParser;
kpniot 0:a9259748d982 79 friend class SenMLBase;
kpniot 0:a9259748d982 80 public:
kpniot 0:a9259748d982 81
kpniot 0:a9259748d982 82 /**
kpniot 0:a9259748d982 83 * create a SenMLPack object.
kpniot 0:a9259748d982 84 */
kpniot 0:a9259748d982 85 SenMLPack(): _bu(SENML_UNIT_NONE),
kpniot 0:a9259748d982 86 _bt(NAN),
kpniot 0:a9259748d982 87 _end(NULL) {};
kpniot 0:a9259748d982 88
kpniot 0:a9259748d982 89 /**
kpniot 0:a9259748d982 90 * create a SenMLPack object.
kpniot 0:a9259748d982 91 * @param baseName the string that will be prepended to all records in this pack.
kpniot 0:a9259748d982 92 * Is used to represent the name of the device.
kpniot 0:a9259748d982 93 */
kpniot 0:a9259748d982 94 SenMLPack(const char* baseName): _bn(baseName), //mbed compiler doesnt support delegating constructors
kpniot 0:a9259748d982 95 _bu(SENML_UNIT_NONE),
kpniot 0:a9259748d982 96 _bt(NAN),
kpniot 0:a9259748d982 97 _end(NULL) {};
kpniot 0:a9259748d982 98
kpniot 0:a9259748d982 99 /**
kpniot 0:a9259748d982 100 * create a SenMLPack object.
kpniot 0:a9259748d982 101 * @param baseName the string that will be prepended to all records in this pack.
kpniot 0:a9259748d982 102 * Is used to represent the name of the device.
kpniot 0:a9259748d982 103 * @param baseUnit the unit name that will be used by default if the record doesnt
kpniot 0:a9259748d982 104 * not define one.
kpniot 0:a9259748d982 105 */
kpniot 0:a9259748d982 106 SenMLPack(const char* baseName, SenMLUnit baseUnit): _bn(baseName),
kpniot 0:a9259748d982 107 _bu(baseUnit),
kpniot 0:a9259748d982 108 _bt(NAN),
kpniot 0:a9259748d982 109 _end(NULL) {};
kpniot 0:a9259748d982 110
kpniot 0:a9259748d982 111 /**
kpniot 0:a9259748d982 112 * create a SenMLPack object.
kpniot 0:a9259748d982 113 * @param baseName the string that will be prepended to all records in this pack.
kpniot 0:a9259748d982 114 * Is used to represent the name of the device.
kpniot 0:a9259748d982 115 * @param baseUnit the unit name that will be used by default if the record doesnt
kpniot 0:a9259748d982 116 * not define one.
kpniot 0:a9259748d982 117 * @param baseTime the time that will be added to each record. When specified, each
kpniot 0:a9259748d982 118 * record that does not specify a time, will receive this time. When
kpniot 0:a9259748d982 119 * the record does have a time, the baseTime of the pack is added to it,
kpniot 0:a9259748d982 120 * so the time of the record becomes relative to that of the pack.
kpniot 0:a9259748d982 121 */
kpniot 0:a9259748d982 122 SenMLPack(const char* baseName, SenMLUnit baseUnit, double baseTime): _bn(baseName),
kpniot 0:a9259748d982 123 _bu(baseUnit),
kpniot 0:a9259748d982 124 _bt(baseTime),
kpniot 0:a9259748d982 125 _end(NULL) {};
kpniot 0:a9259748d982 126
kpniot 0:a9259748d982 127 /**
kpniot 0:a9259748d982 128 * create a SenMLPack object.
kpniot 0:a9259748d982 129 * @param callback a function that will be called while parsing incomming data, when no
kpniot 0:a9259748d982 130 * record can be found that matches any of the defined ones in the object.
kpniot 0:a9259748d982 131 * The parameters of the callback must be:
kpniot 0:a9259748d982 132 * const char* packName the name of the pack that the record belongs to.
kpniot 0:a9259748d982 133 * The data is for a child SenMLPack when this
kpniot 0:a9259748d982 134 * field is different then the name of the root pack.
kpniot 0:a9259748d982 135 * const char* recordName the name of the record
kpniot 0:a9259748d982 136 * const void* value a pointer to the memory blob that contains the actual value.
kpniot 0:a9259748d982 137 * int size the size of the memory blobl
kpniot 0:a9259748d982 138 * SenMLDataType dataType: defines how to interprete the memory blob (ex: pointer to integer,..)
kpniot 0:a9259748d982 139 */
kpniot 0:a9259748d982 140 SenMLPack(PACK_ACTUATOR_SIGNATURE): _bn(""),
kpniot 0:a9259748d982 141 _bu(SENML_UNIT_NONE),
kpniot 0:a9259748d982 142 _bt(NAN),
kpniot 0:a9259748d982 143 _end(NULL),
kpniot 0:a9259748d982 144 callback(callback) {};
kpniot 0:a9259748d982 145
kpniot 0:a9259748d982 146 /**
kpniot 0:a9259748d982 147 * create a SenMLPack object.
kpniot 0:a9259748d982 148 * @param baseName the string that will be prepended to all records in this pack.
kpniot 0:a9259748d982 149 * Is used to represent the name of the device.
kpniot 0:a9259748d982 150 * @param callback a function that will be called while parsing incomming data, when no
kpniot 0:a9259748d982 151 * record can be found that matches any of the defined ones in the object.
kpniot 0:a9259748d982 152 * The parameters of the callback must be:
kpniot 0:a9259748d982 153 * const char* packName the name of the pack that the record belongs to.
kpniot 0:a9259748d982 154 * The data is for a child SenMLPack when this
kpniot 0:a9259748d982 155 * field is different then the name of the root pack.
kpniot 0:a9259748d982 156 * const char* recordName the name of the record
kpniot 0:a9259748d982 157 * const void* value a pointer to the memory blob that contains the actual value.
kpniot 0:a9259748d982 158 * int size the size of the memory blobl
kpniot 0:a9259748d982 159 * SenMLDataType dataType: defines how to interprete the memory blob (ex: pointer to integer,..)
kpniot 0:a9259748d982 160 */
kpniot 0:a9259748d982 161 SenMLPack(const char* baseName, PACK_ACTUATOR_SIGNATURE): _bn(baseName),
kpniot 0:a9259748d982 162 _bu(SENML_UNIT_NONE),
kpniot 0:a9259748d982 163 _bt(NAN),
kpniot 0:a9259748d982 164 _end(NULL),
kpniot 0:a9259748d982 165 callback(callback) {};
kpniot 0:a9259748d982 166
kpniot 0:a9259748d982 167 /**
kpniot 0:a9259748d982 168 * create a SenMLPack object.
kpniot 0:a9259748d982 169 * @param baseName the string that will be prepended to all records in this pack.
kpniot 0:a9259748d982 170 * Is used to represent the name of the device.
kpniot 0:a9259748d982 171 * @param baseUnit the unit name that will be used by default if the record doesnt
kpniot 0:a9259748d982 172 * not define one.
kpniot 0:a9259748d982 173 * @param callback a function that will be called while parsing incomming data, when no
kpniot 0:a9259748d982 174 * record can be found that matches any of the defined ones in the object.
kpniot 0:a9259748d982 175 * The parameters of the callback must be:
kpniot 0:a9259748d982 176 * const char* packName the name of the pack that the record belongs to.
kpniot 0:a9259748d982 177 * The data is for a child SenMLPack when this
kpniot 0:a9259748d982 178 * field is different then the name of the root pack.
kpniot 0:a9259748d982 179 * const char* recordName the name of the record
kpniot 0:a9259748d982 180 * const void* value a pointer to the memory blob that contains the actual value.
kpniot 0:a9259748d982 181 * int size the size of the memory blobl
kpniot 0:a9259748d982 182 * SenMLDataType dataType: defines how to interprete the memory blob (ex: pointer to integer,..)
kpniot 0:a9259748d982 183 */
kpniot 0:a9259748d982 184 SenMLPack(const char* baseName, SenMLUnit baseUnit, PACK_ACTUATOR_SIGNATURE): _bn(baseName),
kpniot 0:a9259748d982 185 _bu(baseUnit),
kpniot 0:a9259748d982 186 _bt(NAN),
kpniot 0:a9259748d982 187 _end(NULL),
kpniot 0:a9259748d982 188 callback(callback) {};
kpniot 0:a9259748d982 189
kpniot 0:a9259748d982 190 /**
kpniot 0:a9259748d982 191 * create a SenMLPack object.
kpniot 0:a9259748d982 192 * @param baseName the string that will be prepended to all records in this pack.
kpniot 0:a9259748d982 193 * Is used to represent the name of the device.
kpniot 0:a9259748d982 194 * @param baseUnit the unit name that will be used by default if the record doesnt
kpniot 0:a9259748d982 195 * not define one.
kpniot 0:a9259748d982 196 * @param baseTime the time that will be added to each record. When specified, each
kpniot 0:a9259748d982 197 * record that does not specify a time, will receive this time. When
kpniot 0:a9259748d982 198 * the record does have a time, the baseTime of the pack is added to it,
kpniot 0:a9259748d982 199 * so the time of the record becomes relative to that of the pack.
kpniot 0:a9259748d982 200 * @param callback a function that will be called while parsing incomming data, when no
kpniot 0:a9259748d982 201 * record can be found that matches any of the defined ones in the object.
kpniot 0:a9259748d982 202 * The parameters of the callback must be:
kpniot 0:a9259748d982 203 * const char* packName the name of the pack that the record belongs to.
kpniot 0:a9259748d982 204 * The data is for a child SenMLPack when this
kpniot 0:a9259748d982 205 * field is different then the name of the root pack.
kpniot 0:a9259748d982 206 * const char* recordName the name of the record
kpniot 0:a9259748d982 207 * const void* value a pointer to the memory blob that contains the actual value.
kpniot 0:a9259748d982 208 * int size the size of the memory blobl
kpniot 0:a9259748d982 209 * SenMLDataType dataType: defines how to interprete the memory blob (ex: pointer to integer,..)
kpniot 0:a9259748d982 210 */
kpniot 0:a9259748d982 211 SenMLPack(const char* baseName, SenMLUnit baseUnit, double baseTime, PACK_ACTUATOR_SIGNATURE): _bn(baseName),
kpniot 0:a9259748d982 212 _bu(baseUnit),
kpniot 0:a9259748d982 213 _bt(baseTime),
kpniot 0:a9259748d982 214 _end(NULL),
kpniot 0:a9259748d982 215 callback(callback) {};
kpniot 0:a9259748d982 216
kpniot 0:a9259748d982 217 /**
kpniot 0:a9259748d982 218 * destroys the SenMLPack object.
kpniot 0:a9259748d982 219 */
kpniot 0:a9259748d982 220 ~SenMLPack(){};
kpniot 0:a9259748d982 221
kpniot 0:a9259748d982 222 /**
kpniot 0:a9259748d982 223 * render the content of the current object to json data (string).
kpniot 0:a9259748d982 224 * This function is ideal for devices with low memory usage but offers less control over the rendering process.
kpniot 0:a9259748d982 225 * @param dest the destination stream to where the data will be rendered without buffering it in memory
kpniot 0:a9259748d982 226 * @param format determins how the data will be rendered. See SenMLStreamMethod for possible methods.
kpniot 0:a9259748d982 227 * @returns none
kpniot 0:a9259748d982 228 */
kpniot 0:a9259748d982 229 void toJson(Stream* dest, SenMLStreamMethod format=SENML_RAW);
kpniot 0:a9259748d982 230
kpniot 0:a9259748d982 231 /**
kpniot 0:a9259748d982 232 * render the content of the current object to json data (string).
kpniot 0:a9259748d982 233 * This function renders the data to a memory buffer. If the buffer is full before the entire object is
kpniot 0:a9259748d982 234 * rendered, an error will be written to the debug stream.
kpniot 0:a9259748d982 235 * @param dest a memory buffer to which the data will be rendred.
kpniot 0:a9259748d982 236 * @param length the length of the memory buffer.
kpniot 0:a9259748d982 237 * @param format determins how the data will be rendered. See SenMLStreamMethod for possible methods.
kpniot 0:a9259748d982 238 * @returns none
kpniot 0:a9259748d982 239 */
kpniot 0:a9259748d982 240 void toJson(char *dest, int length, SenMLStreamMethod format=SENML_RAW);
kpniot 0:a9259748d982 241
kpniot 0:a9259748d982 242 /**
kpniot 0:a9259748d982 243 * render the content of the current object to cbor data (binary).
kpniot 0:a9259748d982 244 * This function is ideal for devices with low memory usage but offers less control over the rendering process.
kpniot 0:a9259748d982 245 * @param dest the destination stream to where the data will be rendered without buffering it in memory
kpniot 0:a9259748d982 246 * @param format determins how the data will be rendered. See SenMLStreamMethod for possible methods.
kpniot 0:a9259748d982 247 * @returns nr of bytes that were rendered
kpniot 0:a9259748d982 248 */
kpniot 0:a9259748d982 249 int toCbor(Stream* dest, SenMLStreamMethod format=SENML_RAW);
kpniot 0:a9259748d982 250
kpniot 0:a9259748d982 251 /**
kpniot 0:a9259748d982 252 * render the content of the current object to cbor data (binary).
kpniot 0:a9259748d982 253 * This function renders the data to a memory buffer. If the buffer is full before the entire object is
kpniot 0:a9259748d982 254 * rendered, an error will be written to the debug stream.
kpniot 0:a9259748d982 255 * @param dest a memory buffer to which the data will be rendred.
kpniot 0:a9259748d982 256 * @param length the length of the memory buffer.
kpniot 0:a9259748d982 257 * @param format determins how the data will be rendered. See SenMLStreamMethod for possible methods.
kpniot 0:a9259748d982 258 * @returns nr of bytes that were rendered
kpniot 0:a9259748d982 259 */
kpniot 0:a9259748d982 260 int toCbor(char *dest, int length, SenMLStreamMethod format=SENML_RAW);
kpniot 0:a9259748d982 261
kpniot 0:a9259748d982 262 /**
kpniot 0:a9259748d982 263 * read and parse a senml json string from the specified source and, for each registered actuator, call the
kpniot 0:a9259748d982 264 * appropriate event on the actuator itself, for others, the callback function PACK_ACTUATOR_SIGNATURE
kpniot 0:a9259748d982 265 * will be called, if present.
kpniot 0:a9259748d982 266 * This method is ideal for devices with very littel ram memory. It will block on most devices if there is
kpniot 0:a9259748d982 267 * no more input to be read from the stream and the end of the json structure is not yet reached.
kpniot 0:a9259748d982 268 * Note: on mbed systems, the blocking nature is not garanteed. Instead, if no more data is available before
kpniot 0:a9259748d982 269 * the end is reached, parsing will fail.
kpniot 0:a9259748d982 270 * @param source the source stream to read the data from.
kpniot 0:a9259748d982 271 * @param format determins how the data will be read (ex: as normal text or in HEX format).
kpniot 0:a9259748d982 272 * See SenMLStreamMethod for possible methods.
kpniot 0:a9259748d982 273 * @returns none
kpniot 0:a9259748d982 274 */
kpniot 0:a9259748d982 275 void fromJson(Stream* source, SenMLStreamMethod format=SENML_RAW);
kpniot 0:a9259748d982 276
kpniot 0:a9259748d982 277 /**
kpniot 0:a9259748d982 278 * parse a senml json string from the specified source and, for each registered actuator, call the
kpniot 0:a9259748d982 279 * appropriate event on the actuator itself, for others, the callback function PACK_ACTUATOR_SIGNATURE
kpniot 0:a9259748d982 280 * will be called, if present.
kpniot 0:a9259748d982 281 * This method takes a string stored in memory as input. The json must be fully defined. It is up to the
kpniot 0:a9259748d982 282 * caller to transform it to a regular text string, if needed (ex: lora devices might send it in hex format).
kpniot 0:a9259748d982 283 * @param source the source string to use as input. This must be null terminated.
kpniot 0:a9259748d982 284 * @returns none
kpniot 0:a9259748d982 285 */
kpniot 0:a9259748d982 286 void fromJson(const char* source);
kpniot 0:a9259748d982 287
kpniot 0:a9259748d982 288 /**
kpniot 0:a9259748d982 289 * read and parse senml cbor from the specified source and, for each registered actuator, call the
kpniot 0:a9259748d982 290 * appropriate event on the actuator itself, for others, the callback function PACK_ACTUATOR_SIGNATURE
kpniot 0:a9259748d982 291 * will be called, if present.
kpniot 0:a9259748d982 292 * This method is ideal for devices with very littel ram memory. It will block on most decices if there is no
kpniot 0:a9259748d982 293 * more input to be read from the stream and the end of the cbor structure is not yet reached.
kpniot 0:a9259748d982 294 * Note: on mbed systems, the blocking nature is not garanteed. Instead, if no more data is available before
kpniot 0:a9259748d982 295 * the end is reached, parsing will fail.
kpniot 0:a9259748d982 296 * @param source the source stream to read the data from.
kpniot 0:a9259748d982 297 * @param format determins how the data will be read (ex: as normal binary or in HEX format).
kpniot 0:a9259748d982 298 * See SenMLStreamMethod for possible methods.
kpniot 0:a9259748d982 299 * @returns none
kpniot 0:a9259748d982 300 */
kpniot 0:a9259748d982 301 void fromCbor(Stream* source, SenMLStreamMethod format=SENML_RAW);
kpniot 0:a9259748d982 302
kpniot 0:a9259748d982 303 /**
kpniot 0:a9259748d982 304 * parse senml cbor from the specified memory and, for each registered actuator, call the
kpniot 0:a9259748d982 305 * appropriate event on the actuator itself, for others, the callback function PACK_ACTUATOR_SIGNATURE
kpniot 0:a9259748d982 306 * will be called, if present.
kpniot 0:a9259748d982 307 * This method takes a memory blob as input. The data must be fully defined.
kpniot 0:a9259748d982 308 * @param source the source data to use as input.
kpniot 0:a9259748d982 309 * @param length the length of the source data.
kpniot 0:a9259748d982 310 * @param format determins how the data will be read (ex: as normal binary or in HEX format).
kpniot 0:a9259748d982 311 * See SenMLStreamMethod for possible methods.
kpniot 0:a9259748d982 312 * @returns none
kpniot 0:a9259748d982 313 */
kpniot 0:a9259748d982 314 void fromCbor(char* source, int length, SenMLStreamMethod format);
kpniot 0:a9259748d982 315
kpniot 0:a9259748d982 316 /**
kpniot 0:a9259748d982 317 * assign a basename to the SenMLPack object. This represents the name of the device.
kpniot 0:a9259748d982 318 * see the spec on [base fields](https://tools.ietf.org/html/draft-ietf-core-senml-13#section-4.1) for more info.
kpniot 0:a9259748d982 319 * Every SenMLPack object must have a basename. This field will always be rendered in the output, even if the
kpniot 0:a9259748d982 320 * string is empty.
kpniot 0:a9259748d982 321 * @param name an immutable string that will be used to represent the name of the device. An internal
kpniot 0:a9259748d982 322 * copy of the value will be made.
kpniot 0:a9259748d982 323 * @returns none
kpniot 0:a9259748d982 324 */
kpniot 0:a9259748d982 325 void setBaseName(const char* name);
kpniot 0:a9259748d982 326
kpniot 0:a9259748d982 327 /**
kpniot 0:a9259748d982 328 * Get the base name. see the spec on [base fields](https://tools.ietf.org/html/draft-ietf-core-senml-13#section-4.1) for more info.
kpniot 0:a9259748d982 329 * @returns the name of the device as an immutable string.
kpniot 0:a9259748d982 330 */
kpniot 0:a9259748d982 331 const char* getBaseName();
kpniot 0:a9259748d982 332
kpniot 0:a9259748d982 333 /**
kpniot 0:a9259748d982 334 * Set the base unit that will be used as the default unit for all records that don't define their own unit.
kpniot 0:a9259748d982 335 * see the spec on [base fields](https://tools.ietf.org/html/draft-ietf-core-senml-13#section-4.1) for more info.
kpniot 0:a9259748d982 336 * Set to SENML_UNIT_NONE for ommiting the base unit from the output (default).
kpniot 0:a9259748d982 337 * @param unit the unit to use as default. See SenMLUnit for all supported unit names.
kpniot 0:a9259748d982 338 * @returns none
kpniot 0:a9259748d982 339 */
kpniot 0:a9259748d982 340 void setBaseUnit(SenMLUnit unit);
kpniot 0:a9259748d982 341
kpniot 0:a9259748d982 342 /**
kpniot 0:a9259748d982 343 * Get the base unit. see the spec on [base fields](https://tools.ietf.org/html/draft-ietf-core-senml-13#section-4.1) for more info.
kpniot 0:a9259748d982 344 * @returns a SenMLUnit enum value that is used as the default unit for records that don't define a unit of their own.
kpniot 0:a9259748d982 345 */
kpniot 0:a9259748d982 346 inline SenMLUnit getBaseUnit() { return this->_bu; };
kpniot 0:a9259748d982 347
kpniot 0:a9259748d982 348
kpniot 0:a9259748d982 349 /**
kpniot 0:a9259748d982 350 * Set the base time. see the spec on [base fields](https://tools.ietf.org/html/draft-ietf-core-senml-13#section-4.1) for more info.
kpniot 0:a9259748d982 351 * @param time the value to use as base time. set bt to NaN if the field should not be included in the output.
kpniot 0:a9259748d982 352 * @returns none
kpniot 0:a9259748d982 353 */
kpniot 0:a9259748d982 354 void setBaseTime(double time);
kpniot 0:a9259748d982 355
kpniot 0:a9259748d982 356 /**
kpniot 0:a9259748d982 357 * Get the base time. see the spec on [base fields](https://tools.ietf.org/html/draft-ietf-core-senml-13#section-4.1) for more info.
kpniot 0:a9259748d982 358 * @returns a double value that is used as the default unit for records that don't define a unit of their own.
kpniot 0:a9259748d982 359 * if no base time is set, NaN will be returned.
kpniot 0:a9259748d982 360 */
kpniot 0:a9259748d982 361 inline double getBaseTime() { return this->_bt; };
kpniot 0:a9259748d982 362
kpniot 0:a9259748d982 363 /**
kpniot 0:a9259748d982 364 * Adds the specified SenML object to the document. The item will be appended to the end of the linked list.
kpniot 0:a9259748d982 365 * The item being added, can be a regular SenMLRecord or another SenMLPack object if you want to send data
kpniot 0:a9259748d982 366 * for multiple devices in 1 SenML message.
kpniot 0:a9259748d982 367 * Check the result of the function to see if the operation was successful or not. Possible reasons for failure:
kpniot 0:a9259748d982 368 * - if the item being added is already part of a document.
kpniot 0:a9259748d982 369 * @param item a pointer to a SenMlRecord or SenMLPack that needs to be added to the document.
kpniot 0:a9259748d982 370 * @returns true upon success, otherwise false.
kpniot 0:a9259748d982 371 */
kpniot 0:a9259748d982 372 bool add(SenMLBase* item);
kpniot 0:a9259748d982 373
kpniot 0:a9259748d982 374 /**
kpniot 0:a9259748d982 375 * Clear out the document and remove all the children. Children aren't destroyed, this is up to the developer.
kpniot 0:a9259748d982 376 * @returns true (at the moment, the function does not yet return false as it doesn't detect any errors)
kpniot 0:a9259748d982 377 */
kpniot 0:a9259748d982 378 bool clear();
kpniot 0:a9259748d982 379
kpniot 0:a9259748d982 380 /**
kpniot 0:a9259748d982 381 * get the first recrod of in this pack element.
kpniot 0:a9259748d982 382 * @returns null when this object is empty (has no children), otherwise, the first item (SenMLRecord or SenMLPack)
kpniot 0:a9259748d982 383 * of the list.
kpniot 0:a9259748d982 384 */
kpniot 0:a9259748d982 385 inline SenMLBase* getFirst() { return this->_start; };
kpniot 0:a9259748d982 386
kpniot 0:a9259748d982 387
kpniot 0:a9259748d982 388 /**
kpniot 0:a9259748d982 389 * renders all the fields to json, without the starting and ending brackets.
kpniot 0:a9259748d982 390 * Inheriters can extend this function if they want to add extra fields to the json output
kpniot 0:a9259748d982 391 * note: this is public so that custom implementations for the record object can use other objects
kpniot 0:a9259748d982 392 * internally and render to json using this function (ex: coordinatesRecord using 3 floatRecrods for lat, lon & alt.
kpniot 0:a9259748d982 393 * @returns: None
kpniot 0:a9259748d982 394 */
kpniot 0:a9259748d982 395 virtual void fieldsToJson();
kpniot 0:a9259748d982 396
kpniot 0:a9259748d982 397 /**
kpniot 0:a9259748d982 398 * renders all the fields to cbor format. renders all the fields of the object without the length info
kpniot 0:a9259748d982 399 * at the beginning
kpniot 0:a9259748d982 400 * note: this is public so that custom implementations for the record object can use other objects
kpniot 0:a9259748d982 401 * internally and render to json using this function (ex: coordinatesRecord using 3 floatRecrods for
kpniot 0:a9259748d982 402 * lat, lon & alt.
kpniot 0:a9259748d982 403 * @returns: The number of bytes that were written.
kpniot 0:a9259748d982 404 */
kpniot 0:a9259748d982 405 virtual int fieldsToCbor();
kpniot 0:a9259748d982 406
kpniot 0:a9259748d982 407 protected:
kpniot 0:a9259748d982 408
kpniot 0:a9259748d982 409
kpniot 0:a9259748d982 410 //derived classes can use this function to see if the root object (getRoot) is a SenMLPack
kpniot 0:a9259748d982 411 //class or not.
kpniot 0:a9259748d982 412 virtual bool isPack() { return true; }
kpniot 0:a9259748d982 413
kpniot 0:a9259748d982 414 //when the user did not register a specific record actuator, this will be called.
kpniot 0:a9259748d982 415 inline void actuate(const char* pack, const char* record, const void* value, int valueLength, SenMLDataType dataType)
kpniot 0:a9259748d982 416 {
kpniot 0:a9259748d982 417 if(this->callback)
kpniot 0:a9259748d982 418 this->callback(pack, record, value, valueLength, dataType);
kpniot 0:a9259748d982 419 };
kpniot 0:a9259748d982 420
kpniot 0:a9259748d982 421 //store a ref to the last item in the list for quick link operations
kpniot 0:a9259748d982 422 void setLast(SenMLBase* value);
kpniot 0:a9259748d982 423
kpniot 0:a9259748d982 424 //renders the content of the pack object without []
kpniot 0:a9259748d982 425 virtual int contentToCbor();
kpniot 0:a9259748d982 426
kpniot 0:a9259748d982 427
kpniot 0:a9259748d982 428 //calculates the nr of items that there will be in the json array in senml representation
kpniot 0:a9259748d982 429 //this is used for rendering cbor which needs to declare the nr of elements in an array.
kpniot 0:a9259748d982 430 virtual int getArrayLength();
kpniot 0:a9259748d982 431
kpniot 0:a9259748d982 432 virtual void setupStreamCtx(char *dest, int length, SenMLStreamMethod format);
kpniot 0:a9259748d982 433
kpniot 0:a9259748d982 434 virtual void setupStreamCtx(Stream *dest, SenMLStreamMethod format);
kpniot 0:a9259748d982 435
kpniot 0:a9259748d982 436 private:
kpniot 0:a9259748d982 437 String _bn;
kpniot 0:a9259748d982 438 SenMLUnit _bu;
kpniot 0:a9259748d982 439 double _bt;
kpniot 0:a9259748d982 440 SenMLBase *_end; //keeps track of the end of the list
kpniot 0:a9259748d982 441 SenMLBase *_start; //keeps track of the start of the list
kpniot 0:a9259748d982 442 PACK_ACTUATOR_SIGNATURE; //for registering actuator callbacks.
kpniot 0:a9259748d982 443
kpniot 0:a9259748d982 444
kpniot 0:a9259748d982 445 //renders the content of the pack object without []
kpniot 0:a9259748d982 446 virtual void contentToJson();
kpniot 0:a9259748d982 447
kpniot 0:a9259748d982 448 //calculates the nr of json fields that this object uses in a senml structure
kpniot 0:a9259748d982 449 virtual int getFieldLength();
kpniot 0:a9259748d982 450
kpniot 0:a9259748d982 451
kpniot 0:a9259748d982 452 void internalToJson();
kpniot 0:a9259748d982 453
kpniot 0:a9259748d982 454 inline char readHexChar(Stream *source){
kpniot 0:a9259748d982 455 #ifdef __MBED__
kpniot 0:a9259748d982 456 unsigned char first = source->getc();
kpniot 0:a9259748d982 457 unsigned char second = source->getc();
kpniot 0:a9259748d982 458 #else
kpniot 0:a9259748d982 459 unsigned char first = source->read();
kpniot 0:a9259748d982 460 unsigned char second = source->read();
kpniot 0:a9259748d982 461 #endif
kpniot 0:a9259748d982 462 first = (first < '9') ? first - '0' : first - '7';
kpniot 0:a9259748d982 463 second = (second < '9') ? second - '0' : second - '7';
kpniot 0:a9259748d982 464 return (16 * first) + second;
kpniot 0:a9259748d982 465 };
kpniot 0:a9259748d982 466 };
kpniot 0:a9259748d982 467
kpniot 0:a9259748d982 468
kpniot 0:a9259748d982 469 #endif // SENMLPACK
kpniot 0:a9259748d982 470
kpniot 0:a9259748d982 471
kpniot 0:a9259748d982 472
kpniot 0:a9259748d982 473
kpniot 0:a9259748d982 474
kpniot 0:a9259748d982 475
kpniot 0:a9259748d982 476
kpniot 0:a9259748d982 477