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.

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 #include <senml_record.h>
kpniot 0:a9259748d982 15 #include <senml_helpers.h>
kpniot 0:a9259748d982 16 #include <senml_pack.h>
kpniot 0:a9259748d982 17 #include <cbor.h>
kpniot 0:a9259748d982 18 #include <senml_logging.h>
kpniot 0:a9259748d982 19
kpniot 0:a9259748d982 20 SenMLRecord::SenMLRecord(const char* name): _name(name), _unit(SENML_UNIT_NONE), _time(NAN), _updateTime(0)
kpniot 0:a9259748d982 21 {
kpniot 0:a9259748d982 22 }
kpniot 0:a9259748d982 23
kpniot 0:a9259748d982 24 SenMLRecord::SenMLRecord(const char* name, SenMLUnit unit): _name(name), _unit(unit), _time(NAN), _updateTime(0)
kpniot 0:a9259748d982 25 {
kpniot 0:a9259748d982 26 }
kpniot 0:a9259748d982 27
kpniot 0:a9259748d982 28 bool SenMLRecord::setTime(double value, bool absolute)
kpniot 0:a9259748d982 29 {
kpniot 0:a9259748d982 30 SenMLBase* root = this->getRoot();
kpniot 0:a9259748d982 31 if(absolute){
kpniot 0:a9259748d982 32 if(root){
kpniot 0:a9259748d982 33 if(root->isPack()){
kpniot 0:a9259748d982 34 double baseTime = ((SenMLPack*)root)->getBaseTime();
kpniot 0:a9259748d982 35 if(!isnan(baseTime))
kpniot 0:a9259748d982 36 value -= baseTime;
kpniot 0:a9259748d982 37 }
kpniot 0:a9259748d982 38 else{
kpniot 0:a9259748d982 39 return false;
kpniot 0:a9259748d982 40 }
kpniot 0:a9259748d982 41 }
kpniot 0:a9259748d982 42 }
kpniot 0:a9259748d982 43 else if(root == NULL){
kpniot 0:a9259748d982 44 return false;
kpniot 0:a9259748d982 45 }
kpniot 0:a9259748d982 46 this->_time = value;
kpniot 0:a9259748d982 47 return true;
kpniot 0:a9259748d982 48 }
kpniot 0:a9259748d982 49
kpniot 0:a9259748d982 50 bool SenMLRecord::setUpdateTime(double value, bool absolute)
kpniot 0:a9259748d982 51 {
kpniot 0:a9259748d982 52 SenMLBase* root = this->getRoot();
kpniot 0:a9259748d982 53 if(absolute){
kpniot 0:a9259748d982 54 if(root){
kpniot 0:a9259748d982 55 if(root->isPack()){
kpniot 0:a9259748d982 56 double baseTime = ((SenMLPack*)root)->getBaseTime();
kpniot 0:a9259748d982 57 if(!isnan(baseTime))
kpniot 0:a9259748d982 58 value -= baseTime;
kpniot 0:a9259748d982 59 }
kpniot 0:a9259748d982 60 else{
kpniot 0:a9259748d982 61 return false;
kpniot 0:a9259748d982 62 }
kpniot 0:a9259748d982 63 }
kpniot 0:a9259748d982 64 }
kpniot 0:a9259748d982 65 else if(root == NULL){
kpniot 0:a9259748d982 66 return false;
kpniot 0:a9259748d982 67 }
kpniot 0:a9259748d982 68 this->_updateTime = value;
kpniot 0:a9259748d982 69 return true;
kpniot 0:a9259748d982 70 }
kpniot 0:a9259748d982 71
kpniot 0:a9259748d982 72 void SenMLRecord::contentToJson()
kpniot 0:a9259748d982 73 {
kpniot 0:a9259748d982 74 printText("{", 1);
kpniot 0:a9259748d982 75 this->fieldsToJson();
kpniot 0:a9259748d982 76 printText("}", 1);
kpniot 0:a9259748d982 77 }
kpniot 0:a9259748d982 78
kpniot 0:a9259748d982 79 void SenMLRecord::adjustToBaseTime(double prev, double time)
kpniot 0:a9259748d982 80 {
kpniot 0:a9259748d982 81 if(!isnan(this->_time)){
kpniot 0:a9259748d982 82 if(!isnan(prev))
kpniot 0:a9259748d982 83 this->_time += prev;
kpniot 0:a9259748d982 84 if(!isnan(time))
kpniot 0:a9259748d982 85 this->_time -= time;
kpniot 0:a9259748d982 86 }
kpniot 0:a9259748d982 87 if(!isnan(this->_updateTime)){
kpniot 0:a9259748d982 88 if(!isnan(prev))
kpniot 0:a9259748d982 89 this->_updateTime += prev;
kpniot 0:a9259748d982 90 if(!isnan(time))
kpniot 0:a9259748d982 91 this->_updateTime -= time;
kpniot 0:a9259748d982 92 }
kpniot 0:a9259748d982 93 }
kpniot 0:a9259748d982 94
kpniot 0:a9259748d982 95 void SenMLRecord::fieldsToJson()
kpniot 0:a9259748d982 96 {
kpniot 0:a9259748d982 97 int bnLength = this->_name.length();
kpniot 0:a9259748d982 98 if(bnLength){
kpniot 0:a9259748d982 99 printText("\"n\":\"", 5);
kpniot 0:a9259748d982 100 printText(this->_name.c_str(), bnLength);
kpniot 0:a9259748d982 101 printText("\"", 1);
kpniot 0:a9259748d982 102 }
kpniot 0:a9259748d982 103 if(!isnan(this->_time)){
kpniot 0:a9259748d982 104 printText(",\"t\":", 5);
kpniot 0:a9259748d982 105 printDouble(this->_time, SENML_MAX_DOUBLE_PRECISION);
kpniot 0:a9259748d982 106 }
kpniot 0:a9259748d982 107 if(this->_unit != SENML_UNIT_NONE){
kpniot 0:a9259748d982 108 printText(",\"u\":\"", 6);
kpniot 0:a9259748d982 109 printUnit(this->_unit);
kpniot 0:a9259748d982 110 printText("\"", 1);
kpniot 0:a9259748d982 111 }
kpniot 0:a9259748d982 112 if(this->_updateTime != 0){
kpniot 0:a9259748d982 113 printText(",\"ut\":", 5);
kpniot 0:a9259748d982 114 #ifdef __MBED__
kpniot 0:a9259748d982 115 char buf[10];
kpniot 0:a9259748d982 116 sprintf(buf, "%d", this->_updateTime);
kpniot 0:a9259748d982 117 String val = buf;
kpniot 0:a9259748d982 118 #else
kpniot 0:a9259748d982 119 String val(this->_updateTime);
kpniot 0:a9259748d982 120 #endif
kpniot 0:a9259748d982 121 printText(val.c_str(), val.length());
kpniot 0:a9259748d982 122 }
kpniot 0:a9259748d982 123 }
kpniot 0:a9259748d982 124
kpniot 0:a9259748d982 125 void SenMLRecord::actuate(const void* value, int dataLength, SenMLDataType dataType)
kpniot 0:a9259748d982 126 {
kpniot 0:a9259748d982 127 log_debug(this->getName());
kpniot 0:a9259748d982 128 log_debug("no actuator");
kpniot 0:a9259748d982 129 }
kpniot 0:a9259748d982 130
kpniot 0:a9259748d982 131 int SenMLRecord::contentToCbor()
kpniot 0:a9259748d982 132 {
kpniot 0:a9259748d982 133 int res = cbor_serialize_map(this->getFieldLength());
kpniot 0:a9259748d982 134 res += this->fieldsToCbor();
kpniot 0:a9259748d982 135 return res;
kpniot 0:a9259748d982 136 }
kpniot 0:a9259748d982 137
kpniot 0:a9259748d982 138 int SenMLRecord::getFieldLength()
kpniot 0:a9259748d982 139 {
kpniot 0:a9259748d982 140 int result = 1; //always have 1 item for the value
kpniot 0:a9259748d982 141 if(this->_name.length() > 0) result++;
kpniot 0:a9259748d982 142 if(!isnan(this->_time)) result++;
kpniot 0:a9259748d982 143 if(this->_unit != SENML_UNIT_NONE) result++;
kpniot 0:a9259748d982 144 if(this->_updateTime != 0) result ++;
kpniot 0:a9259748d982 145 return result;
kpniot 0:a9259748d982 146 }
kpniot 0:a9259748d982 147
kpniot 0:a9259748d982 148 int SenMLRecord::fieldsToCbor()
kpniot 0:a9259748d982 149 {
kpniot 0:a9259748d982 150 int res = 0;
kpniot 0:a9259748d982 151 if(this->_name.length() > 0){
kpniot 0:a9259748d982 152 res += cbor_serialize_int(SENML_CBOR_N_LABEL);
kpniot 0:a9259748d982 153 res += cbor_serialize_unicode_string(this->_name.c_str());
kpniot 0:a9259748d982 154 }
kpniot 0:a9259748d982 155 if(!isnan(this->_time)){
kpniot 0:a9259748d982 156 res += cbor_serialize_int(SENML_CBOR_T_LABEL);
kpniot 0:a9259748d982 157 res += cbor_serialize_double(this->_time);
kpniot 0:a9259748d982 158 }
kpniot 0:a9259748d982 159 if(this->_unit != SENML_UNIT_NONE){
kpniot 0:a9259748d982 160 res += cbor_serialize_int(SENML_CBOR_U_LABEL);
kpniot 0:a9259748d982 161 res += cbor_serialize_unicode_string(senml_units_names[this->_unit]);
kpniot 0:a9259748d982 162 }
kpniot 0:a9259748d982 163 if(this->_updateTime != 0){
kpniot 0:a9259748d982 164 res += cbor_serialize_int(SENML_CBOR_UT_LABEL);
kpniot 0:a9259748d982 165 res += cbor_serialize_int(this->_updateTime);
kpniot 0:a9259748d982 166 }
kpniot 0:a9259748d982 167 return res;
kpniot 0:a9259748d982 168 }
kpniot 0:a9259748d982 169
kpniot 0:a9259748d982 170
kpniot 0:a9259748d982 171
kpniot 0:a9259748d982 172
kpniot 0:a9259748d982 173
kpniot 0:a9259748d982 174
kpniot 0:a9259748d982 175