diff --git a/src/ebusd/bushandler.cpp b/src/ebusd/bushandler.cpp index 602eca66..848d2974 100644 --- a/src/ebusd/bushandler.cpp +++ b/src/ebusd/bushandler.cpp @@ -951,7 +951,7 @@ void BusHandler::formatSeenInfo(ostringstream& output) if (message!=NULL && message->getLastUpdateTime()>0) { // add detailed scan info: Manufacturer ID SW HW output << " \""; - result_t result = message->decodeLastData(output, OF_VERBOSE); + result_t result = message->decodeLastData(output, OF_NAMES|OF_UNITS|OF_COMMENTS); if (result!=RESULT_OK) output << "\" error: " << getResultCode(result); else diff --git a/src/ebusd/mainloop.cpp b/src/ebusd/mainloop.cpp index 81d97d14..d427acbf 100644 --- a/src/ebusd/mainloop.cpp +++ b/src/ebusd/mainloop.cpp @@ -368,7 +368,8 @@ result_t MainLoop::readFromBus(Message* message, string inputStr, const unsigned string MainLoop::executeRead(vector &args) { size_t argPos = 1; - bool hex = false, verbose = false, numeric = false; + bool hex = false, numeric = false; + OutputFormat verbosity = 0; time_t maxAge = 5*60; string circuit, params; unsigned char dstAddress = SYN, pollPriority = 0; @@ -378,7 +379,21 @@ string MainLoop::executeRead(vector &args) } else if (args[argPos] == "-f") { maxAge = 0; } else if (args[argPos] == "-v") { - verbose = true; + switch (verbosity) { + case 0: + verbosity = OF_NAMES; + break; + case OF_NAMES: + verbosity |= OF_UNITS; + break; + case OF_NAMES|OF_UNITS: + verbosity |= OF_COMMENTS; + break; + } + } else if (args[argPos] == "-vv") { + verbosity |= OF_NAMES|OF_UNITS; + } else if (args[argPos] == "-vvv" || args[argPos] == "-V") { + verbosity |= OF_NAMES|OF_UNITS|OF_COMMENTS; } else if (args[argPos] == "-n") { numeric = true; } else if (args[argPos] == "-m") { @@ -435,7 +450,7 @@ string MainLoop::executeRead(vector &args) } argPos++; } - if (hex && (dstAddress != SYN || !circuit.empty() || verbose || numeric || pollPriority > 0 || args.size() < argPos + 1)) { + if (hex && (dstAddress != SYN || !circuit.empty() || verbosity != 0 || numeric || pollPriority > 0 || args.size() < argPos + 1)) { argPos = 0; // print usage } @@ -488,7 +503,7 @@ string MainLoop::executeRead(vector &args) return getResultCode(ret); } if (argPos == 0 || args.size() < argPos + 1 || args.size() > argPos + 2) - return "usage: read [-f] [-m SECONDS] [-c CIRCUIT] [-d ZZ] [-p PRIO] [-v] [-n] [-i VALUE[;VALUE]*] NAME [FIELD[.N]]\n" + return "usage: read [-f] [-m SECONDS] [-c CIRCUIT] [-d ZZ] [-p PRIO] [-v|-V] [-n] [-i VALUE[;VALUE]*] NAME [FIELD[.N]]\n" " or: read [-f] [-m SECONDS] [-c CIRCUIT] -h ZZPBSBNNDx\n" " Read value(s) or hex message.\n" " -f force reading from the bus (same as '-m 0')\n" @@ -496,7 +511,8 @@ string MainLoop::executeRead(vector &args) " -c CIRCUIT limit to messages of CIRCUIT\n" " -d ZZ override destination address ZZ\n" " -p PRIO set the message poll priority (1-9)\n" - " -v be verbose (include circuit, name, field names, units, and comments)\n" + " -v increase verbosity (include names/units/comments)\n" + " -V be very verbose (include names, units, and comments)\n" " -n use numeric value of value=name pairs\n" " -i VALUE read additional message parameters from VALUE\n" " NAME NAME of the message to send\n" @@ -533,13 +549,14 @@ string MainLoop::executeRead(vector &args) if (dstAddress == SYN && maxAge > 0 && params.length() == 0) { Message* cacheMessage = m_messages->find(circuit, args[argPos], false, true); bool hasCache = cacheMessage != NULL; - if (!hasCache || (message != NULL && message->getLastUpdateTime() > cacheMessage->getLastUpdateTime())) + if (!hasCache || (message != NULL && message->getLastUpdateTime() > cacheMessage->getLastUpdateTime())) { cacheMessage = message; // message is newer/better - + } if (cacheMessage != NULL && (cacheMessage->getLastUpdateTime() + maxAge > now || (cacheMessage->isPassive() && cacheMessage->getLastUpdateTime() != 0))) { - if (verbose) + if (verbosity & OF_NAMES) { result << cacheMessage->getCircuit() << " " << cacheMessage->getName() << " "; - result_t ret = cacheMessage->decodeLastData(result, (verbose?OF_VERBOSE:0)|(numeric?OF_NUMERIC:0), false, fieldIndex==-2 ? NULL : fieldName.c_str(), fieldIndex); + } + result_t ret = cacheMessage->decodeLastData(result, verbosity|(numeric?OF_NUMERIC:0), false, fieldIndex==-2 ? NULL : fieldName.c_str(), fieldIndex); if (ret != RESULT_OK) { if (ret < RESULT_OK) logError(lf_main, "read %s %s cached: %s", cacheMessage->getCircuit().c_str(), cacheMessage->getName().c_str(), getResultCode(ret)); @@ -564,9 +581,10 @@ string MainLoop::executeRead(vector &args) if (ret != RESULT_OK) return getResultCode(ret); - if (verbose) + if (verbosity & OF_NAMES) { result << message->getCircuit() << " " << message->getName() << " "; - ret = message->decodeLastData(pt_slaveData, result, (verbose?OF_VERBOSE:0)|(numeric?OF_NUMERIC:0), false, fieldIndex==-2 ? NULL : fieldName.c_str(), fieldIndex); + } + ret = message->decodeLastData(pt_slaveData, result, verbosity|(numeric?OF_NUMERIC:0), false, fieldIndex==-2 ? NULL : fieldName.c_str(), fieldIndex); if (ret < RESULT_OK) { logError(lf_main, "read %s %s: decode %s", message->getCircuit().c_str(), message->getName().c_str(), getResultCode(ret)); result.str(""); @@ -752,13 +770,28 @@ string MainLoop::executeHex(vector &args) string MainLoop::executeFind(vector &args) { size_t argPos = 1; - bool verbose = false, configFormat = false, exact = false, withRead = true, withWrite = false, withPassive = true, first = true, onlyWithData = false, hexFormat = false; + bool configFormat = false, exact = false, withRead = true, withWrite = false, withPassive = true, first = true, onlyWithData = false, hexFormat = false; + OutputFormat verbosity = 0; vector columns; string circuit; vector id; while (args.size() > argPos && args[argPos][0] == '-') { if (args[argPos] == "-v") { - verbose = true; + switch (verbosity) { + case 0: + verbosity |= OF_NAMES; + break; + case OF_NAMES: + verbosity |= OF_UNITS; + break; + case OF_NAMES|OF_UNITS: + verbosity |= OF_COMMENTS; + break; + } + } else if (args[argPos] == "-vv") { + verbosity |= OF_NAMES|OF_UNITS; + } else if (args[argPos] == "-vvv" || args[argPos] == "-V") { + verbosity |= OF_NAMES|OF_UNITS|OF_COMMENTS; } else if (args[argPos] == "-f") { configFormat = true; if (hexFormat) { @@ -847,9 +880,10 @@ string MainLoop::executeFind(vector &args) argPos++; } if (argPos == 0 || args.size() < argPos || args.size() > argPos + 1) - return "usage: find [-v] [-r] [-w] [-p] [-d] [-h] [-i ID] [-f] [-F COL[,COL]*] [-e] [-c CIRCUIT] [NAME]\n" + return "usage: find [-v|-V] [-r] [-w] [-p] [-d] [-h] [-i ID] [-f] [-F COL[,COL]*] [-e] [-c CIRCUIT] [NAME]\n" " Find message(s).\n" - " -v be verbose (append destination address and update time)\n" + " -v increase verbosity (include names/units/comments+destination address++update time)\n" + " -V be very verbose (include everything)\n" " -r limit to active read messages (default: read + passive)\n" " -w limit to active write messages (default: read + passive)\n" " -p limit to passive messages (default: read + passive)\n" @@ -896,14 +930,14 @@ string MainLoop::executeFind(vector &args) result << message->getLastMasterData().getDataStr() << " / " << message->getLastSlaveData().getDataStr(); } else { - result_t ret = message->decodeLastData(result, verbose?OF_VERBOSE:0); + result_t ret = message->decodeLastData(result, verbosity); if (ret!=RESULT_OK) { result << " (" << getResultCode(ret) << " for " << message->getLastMasterData().getDataStr() << " / " << message->getLastSlaveData().getDataStr() << ")"; } } - if (verbose) { + if (verbosity==(OF_NAMES|OF_UNITS|OF_COMMENTS)) { unsigned char dstAddress = message->getDstAddress(); if (dstAddress != SYN) sprintf(str, "%02x", dstAddress); @@ -1159,12 +1193,12 @@ string MainLoop::executeQuit(vector &args, bool& connected) string MainLoop::executeHelp() { return "usage:\n" - " read|r Read value(s): read [-f] [-m SECONDS] [-c CIRCUIT] [-d ZZ] [-p PRIO] [-v] [-n] [-i VALUE[;VALUE]*] NAME [FIELD[.N]]\n" + " read|r Read value(s): read [-f] [-m SECONDS] [-c CIRCUIT] [-d ZZ] [-p PRIO] [-v|-V] [-n] [-i VALUE[;VALUE]*] NAME [FIELD[.N]]\n" " Read hex message: read [-f] [-m SECONDS] [-c CIRCUIT] -h ZZPBSBNNDx\n" " write|w Write value(s): write [-d ZZ] -c CIRCUIT NAME [VALUE[;VALUE]*]\n" " Write hex message: write [-c CIRCUIT] -h ZZPBSBNNDx\n" " hex Send hex data: hex ZZPBSBNNDx\n" - " find|f Find message(s): find [-v] [-r] [-w] [-p] [-d] [-h] [-i ID] [-f] [-F COL[,COL]*] [-e] [-c CIRCUIT] [NAME]\n" + " find|f Find message(s): find [-v|-V] [-r] [-w] [-p] [-d] [-h] [-i ID] [-f] [-F COL[,COL]*] [-e] [-c CIRCUIT] [NAME]\n" " listen|l Listen for updates: listen [stop]\n" " state|s Report bus state\n" " info|i Report information about the daemon, the configuration, and seen devices.\n" @@ -1186,7 +1220,8 @@ string MainLoop::executeHelp() string MainLoop::executeGet(vector &args, bool& connected) { result_t ret = RESULT_OK; - bool verbose = false, numeric = false, required = false; + bool numeric = false, required = false; + OutputFormat verbosity = OF_NAMES; size_t argPos = 1; string uri = args[argPos++]; ostringstream result; @@ -1224,7 +1259,13 @@ string MainLoop::executeGet(vector &args, bool& connected) } else if (strcmp(qname.c_str(), "exact") == 0) { exact = value.length()==0 || strcmp(value.c_str(), "1") == 0; } else if (strcmp(qname.c_str(), "verbose") == 0) { - verbose = value.length()==0 || strcmp(value.c_str(), "1") == 0; + if (value.length()==0 || strcmp(value.c_str(), "1") == 0) { + verbosity |= OF_UNITS|OF_COMMENTS; + } + } else if (strcmp(qname.c_str(), "indexed") == 0) { + if (value.length()==0 || strcmp(value.c_str(), "1") == 0) { + verbosity &= ~OF_NAMES; + } } else if (strcmp(qname.c_str(), "numeric") == 0) { numeric = value.length()==0 || strcmp(value.c_str(), "1") == 0; } else if (strcmp(qname.c_str(), "required") == 0) { @@ -1278,7 +1319,7 @@ string MainLoop::executeGet(vector &args, bool& connected) result << ",\n \"zz\": \"" << setfill('0') << setw(2) << hex << static_cast(dstAddress) << "\""; size_t pos = (size_t)result.tellp(); result << ",\n \"fields\": {"; - result_t dret = message->decodeLastData(result, (verbose?OF_VERBOSE:0)|(numeric?OF_NUMERIC:0)|OF_JSON); + result_t dret = message->decodeLastData(result, verbosity|(numeric?OF_NUMERIC:0)|OF_JSON); if (dret==RESULT_OK) { result << "\n }"; } else { diff --git a/src/lib/ebus/data.cpp b/src/lib/ebus/data.cpp index 1c263c43..fea73f35 100644 --- a/src/lib/ebus/data.cpp +++ b/src/lib/ebus/data.cpp @@ -55,8 +55,8 @@ result_t DataField::create(vector::iterator& it, bool hasPartStr = false; string token; - // template: name,type[:len][,[divisor|values][,[unit][,[comment]]]] - // std: name,part,type[:len][,[divisor|values][,[unit][,[comment]]]] + // template: name,basetype[:len]|template[:name][,[divisor|values][,[unit][,[comment]]]] + // std: name,part,basetype[:len]|template[:name][,[divisor|values][,[unit][,[comment]]]] const string name = *it++; // name if (it == end) { if (!name.empty()) @@ -64,9 +64,9 @@ result_t DataField::create(vector::iterator& it, break; } - if (isTemplate) + if (isTemplate) { partType = pt_any; - else { + } else { const char* partStr = (*it++).c_str(); // part hasPartStr = partStr[0] != 0; if (it == end) { @@ -78,12 +78,10 @@ result_t DataField::create(vector::iterator& it, || (isWriteMessage && !hasPartStr) || strcasecmp(partStr, "M") == 0) { // master data partType = pt_masterData; - } - else if ((!isWriteMessage && !hasPartStr) + } else if ((!isWriteMessage && !hasPartStr) || strcasecmp(partStr, "S") == 0) { // slave data partType = pt_slaveData; - } - else { + } else { result = RESULT_ERR_INVALID_PART; break; } @@ -94,10 +92,11 @@ result_t DataField::create(vector::iterator& it, firstComment = comment; } - const string typeStr = *it++; // type[:len] + const string typeStr = *it++; // basetype[:len]|template[:name] if (typeStr.empty()) { - if (!name.empty() || hasPartStr) + if (!name.empty() || hasPartStr) { result = RESULT_ERR_MISSING_TYPE; + } break; } @@ -105,9 +104,9 @@ result_t DataField::create(vector::iterator& it, if (it != end) { const string divisorStr = *it++; // [divisor|values] if (!divisorStr.empty()) { - if (divisorStr.find('=') == string::npos) + if (divisorStr.find('=') == string::npos) { divisor = parseSignedInt(divisorStr.c_str(), 10, -MAX_DIVISOR, MAX_DIVISOR, result); - else { + } else { istringstream stream(divisorStr); while (getline(stream, token, VALUE_SEPARATOR)) { FileReader::trim(token); @@ -135,29 +134,32 @@ result_t DataField::create(vector::iterator& it, values[(unsigned int)id] = token; } } - if (result != RESULT_OK) + if (result != RESULT_OK) { break; + } } } - if (it == end) + if (it == end) { unit = ""; - else { + } else { const string str = *it++; // [unit] - if (strcasecmp(str.c_str(), NULL_VALUE) == 0) + if (strcasecmp(str.c_str(), NULL_VALUE) == 0) { unit = ""; - else + } else { unit = str; + } } - if (it == end) + if (it == end) { comment = ""; - else { + } else { const string str = *it++; // [comment] - if (strcasecmp(str.c_str(), NULL_VALUE) == 0) + if (strcasecmp(str.c_str(), NULL_VALUE) == 0) { comment = ""; - else + } else { comment = str; + } } bool firstType = true; @@ -165,29 +167,44 @@ result_t DataField::create(vector::iterator& it, while (result == RESULT_OK && getline(stream, token, VALUE_SEPARATOR)) { FileReader::trim(token); DataField* templ = templates->get(token); - unsigned char length; - if (templ == NULL) { - size_t pos = token.find(LENGTH_SEPARATOR); - if (pos == string::npos) + size_t pos = token.find(LENGTH_SEPARATOR); + if (templ == NULL && pos != string::npos) { + templ = templates->get(token.substr(0, pos)); + } + if (templ == NULL) { // basetype[:len] + unsigned char length; + string typeName; + if (pos == string::npos) { length = 0; // no length specified - else if (pos+2==token.length() && token[pos+1]=='*') { - length = REMAIN_LEN; + typeName = token; } else { - length = (unsigned char)parseInt(token.substr(pos+1).c_str(), 10, 1, maxFieldLength, result); - if (result != RESULT_OK) - break; + if (pos+2==token.length() && token[pos+1]=='*') { + length = REMAIN_LEN; + } else { + length = (unsigned char)parseInt(token.substr(pos+1).c_str(), 10, 1, maxFieldLength, result); + if (result != RESULT_OK) { + break; + } + } + typeName = token.substr(0, pos); } - transform(token.begin(), token.end(), token.begin(), ::toupper); - string typeName = token.substr(0, pos); + transform(typeName.begin(), typeName.end(), typeName.begin(), ::toupper); SingleDataField* add = NULL; result = SingleDataField::create(typeName, length, firstType ? name : "", firstType ? comment : "", firstType ? unit : "", partType, divisor, values, add); - if (add != NULL) + if (add != NULL) { fields.push_back(add); - else if (result == RESULT_OK) + } else if (result == RESULT_OK) { result = RESULT_ERR_NOTFOUND; // type not found - } else { + } + } else { // template[:name] + string fieldName; bool lastType = stream.eof(); - result = templ->derive((firstType && lastType) ? name : "", firstType ? comment : "", firstType ? unit : "", partType, divisor, values, fields); + if (pos != string::npos) { // replacement name specified + fieldName = token.substr(pos+1); + } else { + fieldName = (firstType && lastType) ? name : ""; + } + result = templ->derive(fieldName, firstType ? comment : "", firstType ? unit : "", partType, divisor, values, fields); } firstType = false; } @@ -201,9 +218,9 @@ result_t DataField::create(vector::iterator& it, return result; } - if (fields.size() == 1) + if (fields.size() == 1) { returnField = fields[0]; - else { + } else { returnField = new DataFieldSet(firstName, firstComment, fields); } return RESULT_OK; @@ -211,8 +228,9 @@ result_t DataField::create(vector::iterator& it, void DataField::dumpString(ostream& output, const string str, const bool prependFieldSeparator) { - if (prependFieldSeparator) + if (prependFieldSeparator) { output << FIELD_SEPARATOR; + } if (str.find_first_of(FIELD_SEPARATOR) == string::npos) { output << str; } else { @@ -326,9 +344,9 @@ result_t SingleDataField::read(const PartType partType, ostringstream& output, OutputFormat outputFormat, signed char outputIndex, bool leadingSeparator, const char* fieldName, signed char fieldIndex) { - if (partType != m_partType) + if (partType != m_partType) { return RESULT_OK; - + } switch (m_partType) { case pt_masterData: @@ -349,39 +367,44 @@ result_t SingleDataField::read(const PartType partType, } if (outputFormat & OF_JSON) { - if (leadingSeparator) + if (leadingSeparator) { output << ","; - if (outputIndex>=0 || m_name.empty()) + } + if (outputIndex>=0 || m_name.empty() || !(outputFormat & OF_NAMES)) { output << "\n \"" << static_cast(outputIndex<0?0:outputIndex) << "\": {\"name\": \"" << m_name << "\"" << ", \"value\": "; - else + } else { output << "\n \"" << m_name << "\": {\"value\": "; + } } else { - if (leadingSeparator) + if (leadingSeparator) { output << UI_FIELD_SEPARATOR; - if (outputFormat & OF_VERBOSE) + } + if (outputFormat & OF_NAMES) { output << m_name << "="; + } } result_t result = readSymbols(data, m_partType==pt_masterData, offset, output, outputFormat); - if (result != RESULT_OK) + if (result != RESULT_OK) { return result; - - if (outputFormat & OF_VERBOSE) { - if (m_unit.length() > 0) { - if (outputFormat & OF_JSON) - output << ", \"unit\": \"" << m_unit << '"'; - else - output << " " << m_unit; - } - if (m_comment.length() > 0) { - if (outputFormat & OF_JSON) - output << ", \"comment\": \"" << m_comment << '"'; - else - output << " [" << m_comment << "]"; + } + if ((outputFormat & OF_UNITS) && m_unit.length() > 0) { + if (outputFormat & OF_JSON) { + output << ", \"unit\": \"" << m_unit << '"'; + } else { + output << " " << m_unit; } } - if (outputFormat & OF_JSON) + if ((outputFormat & OF_COMMENTS) && m_comment.length() > 0) { + if (outputFormat & OF_JSON) { + output << ", \"comment\": \"" << m_comment << '"'; + } else { + output << " [" << m_comment << "]"; + } + } + if (outputFormat & OF_JSON) { output << "}"; + } return RESULT_OK; } @@ -389,9 +412,9 @@ result_t SingleDataField::write(istringstream& input, const PartType partType, SymbolString& data, unsigned char offset, char separator, unsigned char* length) { - if (partType != m_partType) + if (partType != m_partType) { return RESULT_OK; - + } switch (m_partType) { case pt_masterData: @@ -805,11 +828,12 @@ result_t DataFieldSet::read(const PartType partType, if (!found) { return RESULT_EMPTY; } - if (m_comment.length() > 0 && (outputFormat & OF_VERBOSE)) { - if (outputFormat & OF_JSON) + if ((outputFormat & OF_COMMENTS) && m_comment.length() > 0) { + if (outputFormat & OF_JSON) { output << ",\"comment\": \"" << m_comment << '"'; - else + } else { output << " [" << m_comment << "]"; + } } return RESULT_OK; diff --git a/src/lib/ebus/datatype.h b/src/lib/ebus/datatype.h index eca009ed..446ed650 100644 --- a/src/lib/ebus/datatype.h +++ b/src/lib/ebus/datatype.h @@ -77,9 +77,11 @@ using namespace std; typedef int OutputFormat; /* the bit flags for @a OutputFormat. */ -static const unsigned int OF_VERBOSE = 0x01; //!< verbose format (names, values, units, and comments). -static const unsigned int OF_NUMERIC = 0x02; //!< numeric format (keep numeric value of value=name pairs). -static const unsigned int OF_JSON = 0x04; //!< JSON format. +static const unsigned int OF_NAMES = 0x01; //!< include names. +static const unsigned int OF_UNITS = 0x02; //!< include units. +static const unsigned int OF_COMMENTS = 0x04; //!< include comments. +static const unsigned int OF_NUMERIC = 0x08; //!< numeric format (keep numeric value of value=name pairs). +static const unsigned int OF_JSON = 0x10; //!< JSON format. /** the message part in which a data field is stored. */ enum PartType { diff --git a/src/lib/ebus/test/test_data.cpp b/src/lib/ebus/test/test_data.cpp index 5de0a9cb..8fe03316 100644 --- a/src/lib/ebus/test/test_data.cpp +++ b/src/lib/ebus/test/test_data.cpp @@ -365,16 +365,18 @@ int main() {"x,,bi3:2,0=off;1=on","on", "10feffff0108", "00", ""}, {"x,,bi3:2,0=off;1=on","off","10feffff0100", "00", ""}, {"x,,bi3:2,0=off;1=on","1", "10feffff0108", "00", "n"}, - {"x,,bi3:2,0=off;1=on,ja/nein,Wahrheitswert","x=on ja/nein [Wahrheitswert]", "10feffff0108", "00", "v"}, - {"x,,bi3:2,0=off;1=on,ja/nein,Wahrheitswert","x=1 ja/nein [Wahrheitswert]", "10feffff0108", "00", "vn"}, - {"x,,bi3:2,0=off;1=on,ja/nein,Wahrheitswert","\n \"x\": {\"value\": \"on\"}", "10feffff0108", "00", "j"}, + {"x,,bi3:2,0=off;1=on,ja/nein,Wahrheitswert","x=on ja/nein [Wahrheitswert]", "10feffff0108", "00", "vvv"}, + {"x,,bi3:2,0=off;1=on,ja/nein,Wahrheitswert","x=1 ja/nein [Wahrheitswert]", "10feffff0108", "00", "vvvn"}, + {"x,,bi3:2,0=off;1=on,ja/nein,Wahrheitswert","\n \"x\": {\"value\": \"on\"}", "10feffff0108", "00", "vj"}, + {",,bi3:2,0=off;1=on,ja/nein,Wahrheitswert", "\n \"0\": {\"name\": \"\", \"value\": \"on\"}", "10feffff0108", "00", "vj"}, {",,bi3:2,0=off;1=on,ja/nein,Wahrheitswert", "\n \"0\": {\"name\": \"\", \"value\": \"on\"}", "10feffff0108", "00", "j"}, - {"x,,bi3:2,0=off;1=on,ja/nein,Wahrheitswert","\n \"x\": {\"value\": \"on\", \"unit\": \"ja/nein\", \"comment\": \"Wahrheitswert\"}", "10feffff0108", "00", "vj"}, - {"x,,bi3:2,0=off;1=on,ja/nein,Wahrheitswert","\n \"x\": {\"value\": 1}", "10feffff0108", "00", "nj"}, - {"x,,bi3:2,0=off;1=on,ja/nein,Wahrheitswert","\n \"x\": {\"value\": 1, \"unit\": \"ja/nein\", \"comment\": \"Wahrheitswert\"}", "10feffff0108", "00", "vnj"}, + {"x,,bi3:2,0=off;1=on,ja/nein,Wahrheitswert","\n \"x\": {\"value\": \"on\", \"unit\": \"ja/nein\", \"comment\": \"Wahrheitswert\"}", "10feffff0108", "00", "vvvj"}, + {"x,,bi3:2,0=off;1=on,ja/nein,Wahrheitswert","\n \"x\": {\"value\": 1}", "10feffff0108", "00", "vnj"}, + {"x,,bi3:2,0=off;1=on,ja/nein,Wahrheitswert","\n \"x\": {\"value\": 1, \"unit\": \"ja/nein\", \"comment\": \"Wahrheitswert\"}", "10feffff0108", "00", "vvvnj"}, + {"x,,bi3:2,0=off;1=on,ja/nein,Wahrheitswert","\n \"0\": {\"name\": \"x\", \"value\": 1}", "10feffff0108", "00", "nj"}, {"x,,uch,1=test;2=high;3=off;0x10=on","on","10feffff0110", "00", ""}, {"x,s,uch","3","1050ffff00", "0103", ""}, - {"x,,d2b,,°C,Aussentemperatur","x=18.004 °C [Aussentemperatur]","10fe0700090112", "00", "v"}, + {"x,,d2b,,°C,Aussentemperatur","x=18.004 °C [Aussentemperatur]","10fe0700090112", "00", "vvv"}, {"x,,bti,,,,y,,bda,,,,z,,bdy", "21:04:58;26.10.2014;Sun","10fe0700085804212610061406", "00", ""}, // combination {"x,,bi3,,,,y,,bi5", "1;0", "10feffff0108", "00", ""}, // bit combination {"x,,bi3,,,,y,,bi5", "1;1", "10feffff0128", "00", ""}, // bit combination @@ -393,6 +395,8 @@ int main() {"x,,trelrel","18.004;19.008","10fe07000401120213", "00", ""}, // reference to template struct {"x,,temp,,,,y,,d1c","18.004;9.5","10fe070003011213", "00", ""}, // reference to template, normal def {"x,,temp;HEX:2","18.004;13 14","10fe07000401121314", "00", ""}, // reference to template and base type + {"x,,temp;HEX:2","temp=18.004;=13 14","10fe07000401121314", "00", "v"}, // reference to template and base type + {"x,,temp:degrees;HEX:2","degrees=18.004;=13 14","10fe07000401121314", "00", "v"}, // reference to template and base type }; DataFieldTemplates* templates = new DataFieldTemplates(); DataField* fields = NULL; @@ -421,9 +425,20 @@ int main() bool failedReadMatch = flags.find('R') != string::npos; bool failedWrite = flags.find('w') != string::npos; bool failedWriteMatch = flags.find('W') != string::npos; - bool verbose = flags.find('v') != string::npos; + OutputFormat verbosity = 0; + if (flags.find("v") != string::npos) { + verbosity |= OF_NAMES; + } + if (flags.find("vv") != string::npos) { + verbosity |= OF_UNITS; + } + if (flags.find("vvv") != string::npos) { + verbosity |= OF_COMMENTS; + } + if (flags.find('j') != string::npos) { + verbosity |= OF_JSON; + } bool numeric = flags.find('n') != string::npos; - bool json = flags.find('j') != string::npos; bool isTemplate = flags.find('t') != string::npos; string item; vector entries; @@ -490,9 +505,9 @@ int main() cout << " parse \"" << sstr.getDataStr(true, false).substr(0, 2) << "\" error: " << getResultCode(result) << endl; error = true; } - result = fields->read(pt_masterData, mstr, 0, output, (verbose?OF_VERBOSE:0)|(numeric?OF_NUMERIC:0)|(json?OF_JSON:0), -1, false); + result = fields->read(pt_masterData, mstr, 0, output, verbosity|(numeric?OF_NUMERIC:0), -1, false); if (result >= RESULT_OK) { - result = fields->read(pt_slaveData, sstr, 0, output, (verbose?OF_VERBOSE:0)|(numeric?OF_NUMERIC:0)|(json?OF_JSON:0), -1, !output.str().empty()); + result = fields->read(pt_slaveData, sstr, 0, output, verbosity|(numeric?OF_NUMERIC:0), -1, !output.str().empty()); } if (failedRead) if (result >= RESULT_OK) { @@ -513,7 +528,7 @@ int main() verify(failedReadMatch, "read", check[2], match, expectStr, output.str()); } - if (!verbose && !json) { + if (verbosity==0) { istringstream input(expectStr); result = fields->write(input, pt_masterData, writeMstr, 0); if (result >= RESULT_OK) diff --git a/src/lib/ebus/test/test_message.cpp b/src/lib/ebus/test/test_message.cpp index ece2baf1..6b83f5de 100644 --- a/src/lib/ebus/test/test_message.cpp +++ b/src/lib/ebus/test/test_message.cpp @@ -337,7 +337,7 @@ int main() for (unsigned char index=0; indexgetCount(); index++) { message->storeLastData(*mstrs[index], *sstrs[index]); } - result = message->decodeLastData(output, (decodeVerbose?OF_VERBOSE:0)|(decodeJson?OF_JSON:0), false); + result = message->decodeLastData(output, (decodeVerbose?OF_NAMES|OF_UNITS|OF_COMMENTS:0)|(decodeJson?OF_NAMES|OF_JSON:0), false); if (result != RESULT_OK) { cout << " \"" << check[2] << "\" / \"" << check[3] << "\": decode error: " << getResultCode(result) << endl;