diff --git a/src/libebus/data.cpp b/src/libebus/data.cpp index a23a1be6..c2065727 100644 --- a/src/libebus/data.cpp +++ b/src/libebus/data.cpp @@ -36,12 +36,12 @@ static const dataType_t dataTypes[] = { {"HEX",16, bt_hexstr,ADJ, 0, 2, 47, 0}, // >= 1 byte hex digit string, usually separated by space, e.g. 0a 1b 2c 3d {"BDA", 4, bt_date, BCD, 0, 10, 10, 0}, // date in BCD, 01.01.2000 - 31.12.2099 (0x01,0x01,WW,0x00 - 0x31,0x12,WW,0x99, WW is ignored weekday) {"BDA", 3, bt_date, BCD, 0, 10, 10, 0}, // date in BCD, 01.01.2000 - 31.12.2099 (0x01,0x01,0x00 - 0x31,0x12,0x99) - //{"HDA", 3, bt_date, 0, 0, 10, 10, 0}, // date, 01.01.2000 - 31.12.2099 (0x01,0x01,0x00 - 0x31,0x12,0x99) - //{"HDA", 4, bt_date, 0, 0, 10, 10, 0}, // date, 01.01.2000 - 31.12.2099 (0x0101WW00 - 0x3112WW99, WW is ignored weekday) + {"HDA", 4, bt_date, 0, 0, 10, 10, 0}, // date, 01.01.2000 - 31.12.2099 (0x01,0x01,WW,0x00 - 0x31,0x12,WW,0x99, WW is ignored weekday) // TODO remove duplicate of BDA + {"HDA", 3, bt_date, 0, 0, 10, 10, 0}, // date, 01.01.2000 - 31.12.2099 (0x01,0x01,0x00 - 0x31,0x12,0x99) // TODO remove duplicate of BDA {"BTI", 3, bt_time,BCD|REV,0, 8, 8, 0}, // time in BCD, 00:00:00 - 23:59:59 (0x00,0x00,0x00 - 0x59,0x59,0x23) {"TTM", 1, bt_time, 0, 0, 5, 5, 0}, // truncated time (only multiple of 10 minutes), 00:00 - 24:00 (minutes div 10 + hour * 6 as integer) {"BDY", 1, bt_list,BCD|DAY,0, 0, 6, 0}, // weekday, "Mon" - "Sun" - {"HDY", 1, bt_list,BCD|DAY,0, 1, 7, 0}, // weekday, "Mon" - "Sun" // TODO different range + {"HDY", 1, bt_list,BCD|DAY,0, 1, 7, 0}, // weekday, "Mon" - "Sun" {"BCD", 1, bt_number,BCD|LST,0xff, 0, 0x99, 1}, // unsigned decimal in BCD, 0 - 99 {"UCH", 1, bt_number, LST, 0xff, 0, 0xff, 1}, // unsigned integer, 0 - 255 {"SCH", 1, bt_number, SIG, 0x80, 0x80, 0x7f, 1}, // signed integer, -128 - +127 @@ -54,7 +54,7 @@ static const dataType_t dataTypes[] = { {"D2C", 2, bt_number, SIG, 0x8000, 0x8001, 0x7fff, 16}, // signed number (fraction 1/16), -2047.9 - +2047.9 {"ULG", 4, bt_number, LST, 0xffffffff, 0, 0xffffffff, 1}, // unsigned integer, 0 - 4294967295 {"SLG", 4, bt_number, SIG, 0x80000000, 0x80000000, 0xffffffff, 1}, // signed integer, -2147483648 - +2147483647 -}; +}; // TODO check value range for numberdf /** the week day names. */ static const char* dayNames[] = {"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"}; @@ -118,14 +118,27 @@ DataField* DataField::create(const unsigned char dstAddress, const bool isSetMes const char* typeStr = (*it++).c_str(); + std::map values; if (it == end) factor = 1.0; else { std::string factorStr = *it++; - if (factorStr.length() > 0 && factorStr.find_first_not_of("0123456789.") == std::string::npos) - factor = static_cast(strtod(factorStr.c_str(), NULL)); - else + if (factorStr.empty()) factor = 1.0; + else if (factorStr.find_first_not_of("0123456789.") == std::string::npos) + factor = static_cast(strtod(factorStr.c_str(), NULL)); + else { + factor = 1.0; + std::istringstream stream(factorStr); + while (std::getline(stream, token, ',') != 0) { + const char* start = token.c_str(); + char* end = NULL; + unsigned int id = strtoul(start, &end, 10); + if (end == NULL || end == start || *end != '=') + return NULL; // TODO error code: invalid values definition + values[id] = std::string(end+1); + } + } } if (it == end) @@ -145,19 +158,6 @@ DataField* DataField::create(const unsigned char dstAddress, const bool isSetMes comment.clear(); } - std::map values; - if (it != end) { - std::istringstream stream(*it++); - while (std::getline(stream, token, ',') != 0) { - const char* start = token.c_str(); - char* end = NULL; - unsigned int id = strtoul(start, &end, 10)-1; // 1-based - if (end == NULL || end == start || *end != '=') - return NULL; // TODO error code: invalid values definition - values[id] = std::string(end+1); - } - } - for (size_t i = 0; i < sizeof(dataTypes)/sizeof(dataTypes[0]); i++) { dataType_t dataType = dataTypes[i]; if (strcasecmp(typeStr, dataType.name) == 0) { @@ -541,7 +541,7 @@ bool NumberDataField::writeSymbols(std::istringstream& input, SymbolString& outp double dvalue = strtod(str, &strEnd); if (strEnd != str+strlen(str)) return false; // TODO error code: invalid value - dvalue /= m_factor; + dvalue = dvalue / m_factor + 0.5; // round if ((m_dataType.flags&SIG) != 0) { if (dvalue < -(1LL<<(8*m_length)) || dvalue >= (1LL<<(8*m_length))) return false; // TODO error code: invalid value diff --git a/src/test/test_data.cpp b/src/test/test_data.cpp index 8c8cfae4..19310cc2 100644 --- a/src/test/test_data.cpp +++ b/src/test/test_data.cpp @@ -25,9 +25,6 @@ using namespace libebus; int main () { - //TODO dt_d1b, - //TODO dt_d1c, - //TODO dt_d2c, std::string checks[][4] = { //name;position(s);type;factor;unit;comment // {"temp;1;d2b;;°C;Aussentemperatur","temp=18.004 °C [Aussentemperatur]","10fe070009019258042126100714cc", "00"}, @@ -39,12 +36,14 @@ int main () {"x;1;hdy","Sun","10fe07000307", "00"}, {"x;1;bdy","Sun","10fe07000306", "00"}, {"x;1;d2b","18.004","10fe0700090112", "00"}, + {"x;1;d2c","288.062","10fe0700090112", "00"}, {"x;1;ttm","22:40","10feffff0188", "00"}, {"x;1;bcd","26","10feffff0126", "00"}, {"x;1;bcd","-","10feffff01ff", "00"}, {"x;1;uch","38","10feffff0126", "00"}, {"x;1;sch","-90","10feffff01a6", "00"}, {"x;1;d1b","-90","10feffff01a6", "00"}, + {"x;1;d1c","19.500","10feffff0127", "00"}, {"x;1;uin","38","10feffff022600", "00"}, {"x;1;sin","-90","10feffff02a6ff", "00"}, {"x;1;ulg","38","10feffff0426000000", "00"}, @@ -52,6 +51,7 @@ int main () {"x;1;flt","-0.090","10feffff02a6ff", "00"}, {"x;1-9;str","hallo Du!","10feffff0868616c6c6f20447521", "00"}, {"x;1-9;str","hallo Du ","10feffff0868616c6c6f20447520", "00"}, + {"new;1;uch;1=test,2=high,3=off,4=on","on","10feffff0104", "00"}, }; for (size_t i = 0; i < sizeof(checks)/sizeof(checks[0]); i++) { std::istringstream isstr(checks[i][0]); @@ -77,20 +77,20 @@ int main () std::string gotStr = field->read(mstr, sstr); if (strcasecmp(gotStr.c_str(), expectStr.c_str()) == 0) - std::cout << "parse successful: " << gotStr << std::endl; + std::cout << "read successful: " << gotStr << std::endl; else - std::cout << "parse invalid: got " << gotStr + std::cout << "read invalid: got " << gotStr << ", expected " << expectStr << std::endl; SymbolString writeMstr = SymbolString(mstr.getDataStr().substr(0, 10), false); SymbolString writeSstr = SymbolString(sstr.getDataStr().substr(0, 2), false); if (field->write(gotStr, writeMstr, writeSstr) == false) - std::cout << "format failed" << std::endl; + std::cout << "write failed" << std::endl; else { if (mstr == writeMstr && sstr == writeSstr) - std::cout << "format successful" << std::endl; + std::cout << "write successful" << std::endl; else { - std::cout << "format invalid: "; + std::cout << "write invalid: "; if (mstr == writeMstr) std::cout << "master OK"; else