diff --git a/ChangeLog.md b/ChangeLog.md index cf59f2172..c7bc0a607 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -3,9 +3,10 @@ ## Bug Fixes * fix for escaping double quote in CSV format * adjusted helper shell scripts and Munin plugin to newer netcat +* fix for weekday in BDA data type (for sending only) ## Features -* added DTM data type +* added DTM and BDZ data types # 21.2 (2021-02-08) diff --git a/src/lib/ebus/datatype.cpp b/src/lib/ebus/datatype.cpp index ca4fec09f..4de68eaaf 100755 --- a/src/lib/ebus/datatype.cpp +++ b/src/lib/ebus/datatype.cpp @@ -69,12 +69,12 @@ bool DataType::dump(bool asJson, size_t length, bool appendDivisor, ostream* out result_t StringDataType::readRawValue(size_t offset, size_t length, const SymbolString& input, - unsigned int* value) const { + unsigned int* value) const { return RESULT_EMPTY; } result_t StringDataType::readSymbols(size_t offset, size_t length, const SymbolString& input, - OutputFormat outputFormat, ostream* output) const { + OutputFormat outputFormat, ostream* output) const { size_t start = 0, count = length; int incr = 1; symbol_t symbol; @@ -124,7 +124,7 @@ result_t StringDataType::readSymbols(size_t offset, size_t length, const SymbolS } result_t StringDataType::writeSymbols(size_t offset, size_t length, istringstream* input, - SymbolString* output, size_t* usedLength) const { + SymbolString* output, size_t* usedLength) const { size_t start = 0, count = length; bool remainder = count == REMAIN_LEN && hasFlag(ADJ); int incr = 1; @@ -205,12 +205,12 @@ result_t StringDataType::writeSymbols(size_t offset, size_t length, istringstrea result_t DateTimeDataType::readRawValue(size_t offset, size_t length, const SymbolString& input, - unsigned int* value) const { + unsigned int* value) const { return RESULT_EMPTY; } result_t DateTimeDataType::readSymbols(size_t offset, size_t length, const SymbolString& input, - OutputFormat outputFormat, ostream* output) const { + OutputFormat outputFormat, ostream* output) const { size_t start = 0, count = length; int incr = 1; symbol_t symbol, last = 0, hour = 0; @@ -241,44 +241,44 @@ result_t DateTimeDataType::readSymbols(size_t offset, size_t length, const Symbo symbol = (symbol_t)((symbol >> 4) * 10 + (symbol & 0x0f)); } switch (type) { - case 2: // date only - if (!hasFlag(REQ) && symbol == m_replacement) { - if (i + 1 != length) { - *output << NULL_VALUE << "."; - break; - } else if (last == m_replacement) { - if (length == 2) { // number of days since 01.01.1900 + case 2: // date only + if (!hasFlag(REQ) && symbol == m_replacement) { + if (i + 1 != length) { *output << NULL_VALUE << "."; + break; + } else if (last == m_replacement) { + if (length == 2) { // number of days since 01.01.1900 + *output << NULL_VALUE << "."; + } + *output << NULL_VALUE; + break; } - *output << NULL_VALUE; - break; } - } - if (length == 2) { // number of days since 01.01.1900 - if (i == 0) { + if (length == 2) { // number of days since 01.01.1900 + if (i == 0) { + break; + } + int mjd = last + symbol*256 + 15020; // 01.01.1900 + int y = static_cast((mjd-15078.2)/365.25); + int m = static_cast((mjd-14956.1-static_cast(y*365.25))/30.6001); + int d = mjd-14956-static_cast(y*365.25)-static_cast(m*30.6001); + m--; + if (m >= 13) { + y++; + m -= 12; + } + *output << dec << setfill('0') << setw(2) << static_cast(d) << "." + << setw(2) << static_cast(m) << "." << static_cast(y + 1900); break; } - int mjd = last + symbol*256 + 15020; // 01.01.1900 - int y = static_cast((mjd-15078.2)/365.25); - int m = static_cast((mjd-14956.1-static_cast(y*365.25))/30.6001); - int d = mjd-14956-static_cast(y*365.25)-static_cast(m*30.6001); - m--; - if (m >= 13) { - y++; - m -= 12; + if (i + 1 == length) { + *output << (2000 + symbol); + } else if (symbol < 1 || (i == 0 && symbol > 31) || (i == 1 && symbol > 12)) { + return RESULT_ERR_OUT_OF_RANGE; // invalid date + } else { + *output << setw(2) << dec << setfill('0') << static_cast(symbol) << "."; } - *output << dec << setfill('0') << setw(2) << static_cast(d) << "." - << setw(2) << static_cast(m) << "." << static_cast(y + 1900); break; - } - if (i + 1 == length) { - *output << (2000 + symbol); - } else if (symbol < 1 || (i == 0 && symbol > 31) || (i == 1 && symbol > 12)) { - return RESULT_ERR_OUT_OF_RANGE; // invalid date - } else { - *output << setw(2) << dec << setfill('0') << static_cast(symbol) << "."; - } - break; case 1: // time only if (!hasFlag(REQ) && symbol == m_replacement) { @@ -369,7 +369,7 @@ result_t DateTimeDataType::readSymbols(size_t offset, size_t length, const Symbo } result_t DateTimeDataType::writeSymbols(size_t offset, size_t length, istringstream* input, - SymbolString* output, size_t* usedLength) const { + SymbolString* output, size_t* usedLength) const { size_t start = 0, count = length; bool remainder = count == REMAIN_LEN && hasFlag(ADJ); int incr = 1; @@ -447,7 +447,7 @@ result_t DateTimeDataType::writeSymbols(size_t offset, size_t length, istringstr } else { // calculate local week day int daysSinceSunday = (mjd + 3) % 7; // Sun=0 - if (hasFlag(BCD)) { + if (hasFlag(SPE)) { output->dataAt(offset + index - incr) = (symbol_t) ((6 + daysSinceSunday) % 7); // Sun=0x06 } else { // Sun=0x07 @@ -638,17 +638,17 @@ result_t NumberDataType::derive(int divisor, size_t bitCount, const NumberDataTy } if (m_bitCount < 8) { *derived = new NumberDataType(m_id, bitCount, m_flags, m_replacement, - m_firstBit, divisor, m_baseType ? m_baseType : this); + m_firstBit, divisor, m_baseType ? m_baseType : this); } else { *derived = new NumberDataType(m_id, bitCount, m_flags, m_replacement, - m_minValue, m_maxValue, divisor, m_baseType ? m_baseType : this); + m_minValue, m_maxValue, divisor, m_baseType ? m_baseType : this); } DataTypeList::getInstance()->addCleanup(*derived); return RESULT_OK; } result_t NumberDataType::readRawValue(size_t offset, size_t length, const SymbolString& input, - unsigned int* value) const { + unsigned int* value) const { size_t start = 0, count = length; int incr = 1; symbol_t symbol; @@ -696,7 +696,7 @@ result_t NumberDataType::readRawValue(size_t offset, size_t length, const Symbol } result_t NumberDataType::readSymbols(size_t offset, size_t length, const SymbolString& input, - OutputFormat outputFormat, ostream* output) const { + OutputFormat outputFormat, ostream* output) const { unsigned int value = 0; int signedValue; @@ -794,7 +794,7 @@ result_t NumberDataType::readSymbols(size_t offset, size_t length, const SymbolS } if (m_divisor < 0) { *output << fixed << setprecision(0) - << (static_cast(signedValue) * static_cast(-m_divisor)); + << (static_cast(signedValue) * static_cast(-m_divisor)); } else if (m_divisor <= 1) { if (hasFlag(FIX) && hasFlag(BCD)) { if (outputFormat & OF_JSON) { @@ -813,7 +813,7 @@ result_t NumberDataType::readSymbols(size_t offset, size_t length, const SymbolS } result_t NumberDataType::writeRawValue(unsigned int value, size_t offset, size_t length, - SymbolString* output, size_t* usedLength) const { + SymbolString* output, size_t* usedLength) const { size_t start = 0, count = length; int incr = 1; symbol_t symbol; @@ -858,7 +858,7 @@ result_t NumberDataType::writeRawValue(unsigned int value, size_t offset, size_t } result_t NumberDataType::writeSymbols(size_t offset, size_t length, istringstream* input, - SymbolString* output, size_t* usedLength) const { + SymbolString* output, size_t* usedLength) const { unsigned int value; const string inputStr = input->str(); @@ -985,10 +985,13 @@ DataTypeList::DataTypeList() { // >= 1 byte hex digit string, usually separated by space, e.g. 0a 1b 2c 3d add(new StringDataType("HEX", MAX_LEN*8, ADJ, 0, true)); // date with weekday in BCD, 01.01.2000 - 31.12.2099 (0x01,0x01,WW,0x00 - 0x31,0x12,WW,0x99, - // WW is weekday Mon=0x00 - Sun=0x06, replacement 0xff) + // WW is weekday Mon=0x01 - Sun=0x07, replacement 0xff) add(new DateTimeDataType("BDA", 32, BCD, 0xff, true, false, 0)); // date in BCD, 01.01.2000 - 31.12.2099 (0x01,0x01,0x00 - 0x31,0x12,0x99, replacement 0xff) add(new DateTimeDataType("BDA", 24, BCD, 0xff, true, false, 0)); + // date with zero-based weekday in BCD, 01.01.2000 - 31.12.2099 (0x01,0x01,WZ,0x00 - 0x31,0x12,WZ,0x99, + // WZ is zero-based weekday Mon=0x00 - Sun=0x06, replacement 0xff) + add(new DateTimeDataType("BDZ", 32, BCD|SPE, 0xff, true, false, 0)); // date with weekday, 01.01.2000 - 31.12.2099 (0x01,0x01,WW,0x00 - 0x1f,0x0c,WW,0x63, // WW is weekday Mon=0x01 - Sun=0x07, replacement 0xff) add(new DateTimeDataType("HDA", 32, 0, 0xff, true, false, 0)); @@ -996,7 +999,7 @@ DataTypeList::DataTypeList() { add(new DateTimeDataType("HDA", 24, 0, 0xff, true, false, 0)); // date, days since 01.01.1900, 01.01.1900 - 06.06.2079 (0x00,0x00 - 0xff,0xff) add(new DateTimeDataType("DAY", 16, 0, 0xff, true, false, 0)); - // date+time in minutes since 01.01.2009, 01.01.2009 - 31.12.2099 + // date+time in minutes since 01.01.2009, 01.01.2009 - 31.12.2099 (0x00,0x00,0x00,0x00 - 0x02,0xda,0x4e,0x1f) add(new DateTimeDataType("DTM", 32, REQ, 0x100, true, true, 0)); // time in BCD, 00:00:00 - 23:59:59 (0x00,0x00,0x00 - 0x59,0x59,0x23) add(new DateTimeDataType("BTI", 24, BCD|REV, 0xff, false, true, 0)); diff --git a/src/lib/ebus/test/test_data.cpp b/src/lib/ebus/test/test_data.cpp index 5a3c7a719..3ebb2e4b7 100755 --- a/src/lib/ebus/test/test_data.cpp +++ b/src/lib/ebus/test/test_data.cpp @@ -129,9 +129,10 @@ int main() { {"x,,hex:5,==48 61 6c 6c 6f", "", "10fe070005ababababab", "00", "rW"}, {"x,,hex:5,=48 61 6c 6c 6f", "", "10fe07000548616c6c6f", "00", ""}, {"x,,hex:5,==48 61 6c 6c 6f", "", "10fe07000548616c6c6f", "00", ""}, - {"x,,bda", "26.10.2014", "10fe07000426100614", "00", ""}, // Sunday - {"x,,bda", "01.01.2000", "10fe07000401010500", "00", ""}, // Saturday - {"x,,bda", "31.12.2099", "10fe07000431120399", "00", ""}, // Thursday + {"x,,bda", "26.10.2014", "10fe07000426100714", "00", ""}, // Sunday + {"x,,bda", "01.01.2000", "10fe07000401010600", "00", ""}, // Saturday + {"x,,bda", "20.02.2021", "10fe07000420020621", "00", ""}, // Saturday + {"x,,bda", "31.12.2099", "10fe07000431120499", "00", ""}, // Thursday {"x,,bda", "-.-.-", "10fe070004ffff00ff", "00", ""}, {"x,,bda", "", "10fe07000432100014", "00", "rw"}, {"x,,bda:3", "26.10.2014", "10fe070003261014", "00", ""}, @@ -140,6 +141,12 @@ int main() { {"x,,bda:3", "-.-.-", "10fe070003ffffff", "00", ""}, {"x,,bda:3", "", "10fe070003321299", "00", "rw"}, {"x,,bda,2", "", "", "", "c"}, + {"x,,bdz", "26.10.2014", "10fe07000426100614", "00", ""}, // Sunday + {"x,,bdz", "01.01.2000", "10fe07000401010500", "00", ""}, // Saturday + {"x,,bdz", "20.02.2021", "10fe07000420020521", "00", ""}, // Saturday + {"x,,bdz", "31.12.2099", "10fe07000431120399", "00", ""}, // Thursday + {"x,,bdz", "-.-.-", "10fe070004ffff00ff", "00", ""}, + {"x,,bdz", "", "10fe07000432100014", "00", "rw"}, {"x,,hda", "26.10.2014", "10fe0700041a0a070e", "00", ""}, // Sunday {"x,,hda", "01.01.2000", "10fe07000401010600", "00", ""}, // Saturday {"x,,hda", "31.12.2099", "10fe0700041f0c0463", "00", ""}, // Thursday @@ -490,7 +497,7 @@ int main() { {"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", "vvv"}, - {"x,,bti,,,,y,,bda,,,,z,,bdy", "21:04:58;26.10.2014;Sun", "10fe0700085804212610061406", "00", ""}, // combination + {"x,,bti,,,,y,,bda,,,,z,,bdy", "21:04:58;26.10.2014;Sun", "10fe0700085804212610071406", "00", ""}, // combination {"x,,bi3,,,,y,,bi5", "1;0", "10feffff0108", "00", ""}, // bit combination {"x,,bi3,,,,y,,bi5", "1;1", "10feffff0128", "00", ""}, // bit combination {"x,,bi3,,,,y,,bi5", "0;1", "10feffff0120", "00", ""}, // bit combination diff --git a/src/lib/ebus/test/test_message.cpp b/src/lib/ebus/test/test_message.cpp index c9dc51a20..0ccc92789 100644 --- a/src/lib/ebus/test/test_message.cpp +++ b/src/lib/ebus/test/test_message.cpp @@ -112,11 +112,11 @@ int main() { {"r,message circuit,message name,message comment,,25,B509,0d2800,,,D2C,,°C,Temperatur,,,sensor", "\n \"0\": {\"name\": \"\", \"value\": -14.00},\n \"1\": {\"name\": \"sensor\", \"value\": \"ok\"}", "ff25b509030d2800", "0320ff00", "j"}, {"r,cir,name,,,25,B509,0d2800,,,tempsensorc", "-14.00", "ff25b509030d2800", "0320ff55", ""}, {"r,cir,name,,,25,B509,0d28,,m,sensorc,,,,,,temp", "-14.00", "ff25b509030d2855", "0220ff", ""}, - {"u,cir,first,,,fe,0700,,x,,bda", "26.10.2014", "fffe07000426100614", "00", "p"}, + {"u,cir,first,,,fe,0700,,x,,bda", "26.10.2014", "fffe07000426100714", "00", "p"}, {"u,broadcast,hwStatus,,,fe,b505,27,,,UCH,,,,,,UCH,,,,,,UCH,,,", "0;19;0", "10feb505042700130097", "00", ""}, - {"u,broadcast,datetime,Datum/Uhrzeit,,fe,0700,,outsidetemp,,temp2,,°C,Aussentemperatur,time,,btime,,,,date,,BDA,,,Datum", "outsidetemp=14.500 °C [Aussentemperatur];time=12:25:01 [Uhrzeit];date=01.05.2017 [Datum]", "10fe070009800e01251201050017", "", "D"}, - {"u,broadcast,datetime,Datum Uhrzeit,,fe,0700,,,,temp2;btime;bdate", "temp2=14.500 °C [Temperatur];time=12:25:01 [Uhrzeit];date=01.05.2017 [Datum]", "10fe070009800e01251201050017", "", "D"}, - {"w,cir,first,,,15,b509,0400,date,,bda", "26.10.2014", "ff15b50906040026100614", "00", ""}, + {"u,broadcast,datetime,Datum/Uhrzeit,,fe,0700,,outsidetemp,,temp2,,°C,Aussentemperatur,time,,btime,,,,date,,BDA,,,Datum", "outsidetemp=14.500 °C [Aussentemperatur];time=12:25:01 [Uhrzeit];date=01.05.2017 [Datum]", "10fe070009800e01251201050117", "", "D"}, + {"u,broadcast,datetime,Datum Uhrzeit,,fe,0700,,,,temp2;btime;bdate", "temp2=14.500 °C [Temperatur];time=12:25:01 [Uhrzeit];date=01.05.2017 [Datum]", "10fe070009800e01251201050117", "", "D"}, + {"w,cir,first,,,15,b509,0400,date,,bda", "26.10.2014", "ff15b50906040026100714", "00", ""}, {"w,cir,first,,,15,b509", "", "ff15b50900", "00", ""}, {"*w,,,,,,b505,2d", "", "", "", ""}, {"w,cir,offset,,,50,,,,,temp", "0.50", "ff50b505042d080000", "00", "kd"},