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
senml_record.cpp@0:a9259748d982, 2018-05-19 (annotated)
- Committer:
- kpniot
- Date:
- Sat May 19 17:35:20 2018 +0000
- Revision:
- 0:a9259748d982
first commit
Who changed what in which revision?
User | Revision | Line number | New 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 |