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:
Sat May 19 17:35:20 2018 +0000
Revision:
0:a9259748d982
first commit

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 * record base class
kpniot 0:a9259748d982 12 */
kpniot 0:a9259748d982 13
kpniot 0:a9259748d982 14 #ifndef SENMLTIMED
kpniot 0:a9259748d982 15 #define SENMLTIMED
kpniot 0:a9259748d982 16
kpniot 0:a9259748d982 17 #include <senml_base.h>
kpniot 0:a9259748d982 18 #include <senml_enums.h>
kpniot 0:a9259748d982 19
kpniot 0:a9259748d982 20 #ifdef __MBED__
kpniot 0:a9259748d982 21 #include "mbed.h"
kpniot 0:a9259748d982 22 #include <string>
kpniot 0:a9259748d982 23 using namespace std;
kpniot 0:a9259748d982 24 #define String string
kpniot 0:a9259748d982 25 #endif
kpniot 0:a9259748d982 26
kpniot 0:a9259748d982 27 /**
kpniot 0:a9259748d982 28 * SenMLRecord represents a single measurement. Besides the value, it also stores the name,
kpniot 0:a9259748d982 29 * optional unit, timestamp and update time.
kpniot 0:a9259748d982 30 *
kpniot 0:a9259748d982 31 * This is the base class for all record types, you can not work directly with this class.
kpniot 0:a9259748d982 32 * Instead, use one of it's derivatives such as SenMLBinaryRecord, SenMLBoolRecord, SenMLFloatRecord,
kpniot 0:a9259748d982 33 * SenMLIntRecord or SenMLStringRecord. Alternatively, you can create your own records by inheriting from
kpniot 0:a9259748d982 34 * this class, or SenMLRecordTemplate, a convenience template which allows you to create records for
kpniot 0:a9259748d982 35 * different data types.
kpniot 0:a9259748d982 36 *
kpniot 0:a9259748d982 37 * Although a record object can be used by itself, usually record objects are added to SenMLPack objects.
kpniot 0:a9259748d982 38 */
kpniot 0:a9259748d982 39 class SenMLRecord: public SenMLBase
kpniot 0:a9259748d982 40 {
kpniot 0:a9259748d982 41 friend class SenMLCborParser;
kpniot 0:a9259748d982 42 friend class SenMLJsonListener;
kpniot 0:a9259748d982 43 public:
kpniot 0:a9259748d982 44
kpniot 0:a9259748d982 45 /**
kpniot 0:a9259748d982 46 * create a SenMLRecord object.
kpniot 0:a9259748d982 47 */
kpniot 0:a9259748d982 48 SenMLRecord(): _unit(SENML_UNIT_NONE), _time(NAN), _updateTime(0){};
kpniot 0:a9259748d982 49
kpniot 0:a9259748d982 50 /**
kpniot 0:a9259748d982 51 * create a SenMLRecord object.
kpniot 0:a9259748d982 52 * @param name the identifier for this record. This is a free-form string, but a set of
kpniot 0:a9259748d982 53 * predefined names, supported by the KPN network can be found in senml_enums.h
kpniot 0:a9259748d982 54 */
kpniot 0:a9259748d982 55 SenMLRecord(const char* name);
kpniot 0:a9259748d982 56
kpniot 0:a9259748d982 57 /**
kpniot 0:a9259748d982 58 * create a SenMLRecord object.
kpniot 0:a9259748d982 59 * @param name the string that will be prepended to all records in this pack.
kpniot 0:a9259748d982 60 * Is used to represent the name of the device.
kpniot 0:a9259748d982 61 * @param unit the unit that should be included in the output. See the SenMLUnit enum for
kpniot 0:a9259748d982 62 * supported unit types.
kpniot 0:a9259748d982 63 */
kpniot 0:a9259748d982 64 SenMLRecord(const char* name, SenMLUnit unit);
kpniot 0:a9259748d982 65
kpniot 0:a9259748d982 66
kpniot 0:a9259748d982 67 /**
kpniot 0:a9259748d982 68 * returns the time assigned to this record. NaN represents 'no time assigned'.
kpniot 0:a9259748d982 69 * See [base fields](https://tools.ietf.org/html/draft-ietf-core-senml-13#section-4.1) for more info on the time value.
kpniot 0:a9259748d982 70 * @returns the timestamp assigned to the record, expressed in unix epoch, relative to the
kpniot 0:a9259748d982 71 * parent SenMLPack object's base time (if any).
kpniot 0:a9259748d982 72 */
kpniot 0:a9259748d982 73 double getTime() {return this->_time;};
kpniot 0:a9259748d982 74
kpniot 0:a9259748d982 75 /**
kpniot 0:a9259748d982 76 * set the time, expressed as a unix epoch time, absolute or relative to the base time of the
kpniot 0:a9259748d982 77 * parent SenMLPack object..
kpniot 0:a9259748d982 78 * when absolute is true (default behaviour), the time value will be made relative to the
kpniot 0:a9259748d982 79 * base time of the pack object, if it has a base time.
kpniot 0:a9259748d982 80 * See [base fields](https://tools.ietf.org/html/draft-ietf-core-senml-13#section-4.1) for more info on the time value.
kpniot 0:a9259748d982 81 * Possible reasons for failure:
kpniot 0:a9259748d982 82 * - if there is a root object, but it is not a SenMLPack
kpniot 0:a9259748d982 83 * - if absolute is false, but there is no parent SenMLPack object.
kpniot 0:a9259748d982 84 * @param value the unix epoch time value to assign to the record
kpniot 0:a9259748d982 85 * @param absolute When true (default), the value will be interpreted as an absolute time stamp. If there
kpniot 0:a9259748d982 86 * is a parent SenMLPack, the value will be made relative to the pack's base time, if there is any.
kpniot 0:a9259748d982 87 * When false, no conversion is done, but a parent SenMLPack has to be present.
kpniot 0:a9259748d982 88 * @returns true upon success, otherwise false.
kpniot 0:a9259748d982 89 */
kpniot 0:a9259748d982 90 bool setTime(double value, bool absolute = true);
kpniot 0:a9259748d982 91
kpniot 0:a9259748d982 92
kpniot 0:a9259748d982 93 /**
kpniot 0:a9259748d982 94 * Get the name of the record.
kpniot 0:a9259748d982 95 * @returns the name of the record as an immutable string. Don't delete this pointer, it refers to the
kpniot 0:a9259748d982 96 * internal buffer of the object and is managed by the record.
kpniot 0:a9259748d982 97 */
kpniot 0:a9259748d982 98 inline const char* getName(){ return this->_name.c_str();}
kpniot 0:a9259748d982 99
kpniot 0:a9259748d982 100 /**
kpniot 0:a9259748d982 101 * Assign an identifier to the record. This is a free-form string, but a set of
kpniot 0:a9259748d982 102 * predefined names, supported by the KPN network can be found in senml_enums.h
kpniot 0:a9259748d982 103 * @param name a string that represents the identifier for the record. A copy of the value
kpniot 0:a9259748d982 104 * is made.
kpniot 0:a9259748d982 105 * @returns none
kpniot 0:a9259748d982 106 */
kpniot 0:a9259748d982 107 inline void setName(const char* name){ this->_name = name; }
kpniot 0:a9259748d982 108
kpniot 0:a9259748d982 109
kpniot 0:a9259748d982 110 /**
kpniot 0:a9259748d982 111 * Get the expected timestamp at which this record will be updated again. NaN represents 'no time assigned'.
kpniot 0:a9259748d982 112 * @returns a unix epoch time, relative to the parent SenMLPack object's base time (if any).
kpniot 0:a9259748d982 113 */
kpniot 0:a9259748d982 114 inline int getUpdateTime(){ return this->_updateTime;}
kpniot 0:a9259748d982 115
kpniot 0:a9259748d982 116 /**
kpniot 0:a9259748d982 117 * Assign a timestamp to the record at which it is expected to update the value.
kpniot 0:a9259748d982 118 * when absolute is true (default behaviour), the time value will be made relative to the
kpniot 0:a9259748d982 119 * base time of the pack object, if it has a base time.
kpniot 0:a9259748d982 120 * See [base fields](https://tools.ietf.org/html/draft-ietf-core-senml-13#section-4.1) for more info on the time value.
kpniot 0:a9259748d982 121 * Possible reasons for failure:
kpniot 0:a9259748d982 122 * - if there is a root object, but it is not a SenMLPack
kpniot 0:a9259748d982 123 * - if absolute is false, but there is no parent SenMLPack object.
kpniot 0:a9259748d982 124 * @param value the unix epoch update time value to assign to the record
kpniot 0:a9259748d982 125 * @param absolute When true (default), the value will be interpreted as an absolute time stamp. If there
kpniot 0:a9259748d982 126 * is a parent SenMLPack, the value will be made relative to the pack's base time, if there is any.
kpniot 0:a9259748d982 127 * When false, no conversion is done, but a parent SenMLPack has to be present.
kpniot 0:a9259748d982 128 * @returns true upon success, otherwise false.
kpniot 0:a9259748d982 129 */
kpniot 0:a9259748d982 130 bool setUpdateTime(double value, bool absolute=true);
kpniot 0:a9259748d982 131
kpniot 0:a9259748d982 132
kpniot 0:a9259748d982 133 /**
kpniot 0:a9259748d982 134 * Get the enum that identifies the unit name assigned to the record.
kpniot 0:a9259748d982 135 * The value SENML_UNIT_NONE means that no unit will be generated in the output.
kpniot 0:a9259748d982 136 * Senml defines a fixed set of supported [unit names](https://tools.ietf.org/html/draft-ietf-core-senml-13#section-12.1).
kpniot 0:a9259748d982 137 * @returns a SenMLUnit enum value representing the unit name.
kpniot 0:a9259748d982 138 */
kpniot 0:a9259748d982 139 SenMLUnit getUnit(){ return this->_unit;}
kpniot 0:a9259748d982 140
kpniot 0:a9259748d982 141 /**
kpniot 0:a9259748d982 142 * Assigns a unit value to the record.
kpniot 0:a9259748d982 143 * The value SENML_UNIT_NONE means that no unit will be generated in the output.
kpniot 0:a9259748d982 144 * Senml defines a fixed set of supported [unit names](https://tools.ietf.org/html/draft-ietf-core-senml-13#section-12.1).
kpniot 0:a9259748d982 145 * @param value a SenMLUnit enum value representing the unit name.
kpniot 0:a9259748d982 146 * @returns none
kpniot 0:a9259748d982 147 */
kpniot 0:a9259748d982 148 void setUnit(SenMLUnit value){ this->_unit = value; }
kpniot 0:a9259748d982 149
kpniot 0:a9259748d982 150
kpniot 0:a9259748d982 151 /**
kpniot 0:a9259748d982 152 * renders all the fields to json, without the starting and ending brackets.
kpniot 0:a9259748d982 153 * Inheriters can extend this function if they want to add extra fields to the json output
kpniot 0:a9259748d982 154 * note: this is public so that custom implementations for the record object can use other objects
kpniot 0:a9259748d982 155 * internally and render to json using this function (ex: coordinatesRecord using 3 floatRecrods for lat, lon & alt.
kpniot 0:a9259748d982 156 * @returns: None
kpniot 0:a9259748d982 157 */
kpniot 0:a9259748d982 158 virtual void fieldsToJson();
kpniot 0:a9259748d982 159
kpniot 0:a9259748d982 160 /**
kpniot 0:a9259748d982 161 * renders all the fields to cbor format. renders all the fields of the object without the length info
kpniot 0:a9259748d982 162 * at the beginning
kpniot 0:a9259748d982 163 * note: this is public so that custom implementations for the record object can use other objects
kpniot 0:a9259748d982 164 * internally and render to json using this function (ex: coordinatesRecord using 3 floatRecrods for
kpniot 0:a9259748d982 165 * lat, lon & alt.
kpniot 0:a9259748d982 166 * @returns: The number of bytes that were written.
kpniot 0:a9259748d982 167 */
kpniot 0:a9259748d982 168 virtual int fieldsToCbor();
kpniot 0:a9259748d982 169
kpniot 0:a9259748d982 170 protected:
kpniot 0:a9259748d982 171
kpniot 0:a9259748d982 172
kpniot 0:a9259748d982 173 /*
kpniot 0:a9259748d982 174 renders all the fields to json, including the starting and ending brackets.
kpniot 0:a9259748d982 175 Inheriters can extend this function if they want to add extra fields to the json output
kpniot 0:a9259748d982 176 */
kpniot 0:a9259748d982 177 virtual void contentToJson();
kpniot 0:a9259748d982 178
kpniot 0:a9259748d982 179
kpniot 0:a9259748d982 180
kpniot 0:a9259748d982 181 //renders all the fields to cbor format. renders all the fields of the object including the
kpniot 0:a9259748d982 182 //length info at the beginning
kpniot 0:a9259748d982 183 virtual int contentToCbor();
kpniot 0:a9259748d982 184
kpniot 0:a9259748d982 185
kpniot 0:a9259748d982 186
kpniot 0:a9259748d982 187
kpniot 0:a9259748d982 188 //This function is called by the root SenMLPack object to indicate that the object
kpniot 0:a9259748d982 189 //should adjust it's time info relative to the new base time (if applicable)
kpniot 0:a9259748d982 190 //doesn't do anything by default
kpniot 0:a9259748d982 191 virtual void adjustToBaseTime(double prev, double time);
kpniot 0:a9259748d982 192
kpniot 0:a9259748d982 193
kpniot 0:a9259748d982 194 //called while parsing a senml message, when the parser found the value for an SenMLJsonListener
kpniot 0:a9259748d982 195 virtual void actuate(const void* value, int dataLength, SenMLDataType dataType);
kpniot 0:a9259748d982 196
kpniot 0:a9259748d982 197 //calculates the nr of fields that this record will produce.
kpniot 0:a9259748d982 198 //The default implementation already adds 1 field for the value.
kpniot 0:a9259748d982 199 int getFieldLength();
kpniot 0:a9259748d982 200
kpniot 0:a9259748d982 201 private:
kpniot 0:a9259748d982 202 double _time;
kpniot 0:a9259748d982 203 int _updateTime;
kpniot 0:a9259748d982 204 String _name;
kpniot 0:a9259748d982 205 SenMLUnit _unit;
kpniot 0:a9259748d982 206 };
kpniot 0:a9259748d982 207
kpniot 0:a9259748d982 208 #endif // SENMLRECORD
kpniot 0:a9259748d982 209
kpniot 0:a9259748d982 210
kpniot 0:a9259748d982 211
kpniot 0:a9259748d982 212
kpniot 0:a9259748d982 213
kpniot 0:a9259748d982 214
kpniot 0:a9259748d982 215