Skip to content

Commit

Permalink
corrected BDA type according to eBUS spec (fixes #382), added BDZ
Browse files Browse the repository at this point in the history
  • Loading branch information
john30 committed Feb 20, 2021
1 parent e3fb45b commit 3e81e4a
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 56 deletions.
3 changes: 2 additions & 1 deletion ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
97 changes: 50 additions & 47 deletions src/lib/ebus/datatype.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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<int>((mjd-15078.2)/365.25);
int m = static_cast<int>((mjd-14956.1-static_cast<int>(y*365.25))/30.6001);
int d = mjd-14956-static_cast<int>(y*365.25)-static_cast<int>(m*30.6001);
m--;
if (m >= 13) {
y++;
m -= 12;
}
*output << dec << setfill('0') << setw(2) << static_cast<unsigned>(d) << "."
<< setw(2) << static_cast<unsigned>(m) << "." << static_cast<unsigned>(y + 1900);
break;
}
int mjd = last + symbol*256 + 15020; // 01.01.1900
int y = static_cast<int>((mjd-15078.2)/365.25);
int m = static_cast<int>((mjd-14956.1-static_cast<int>(y*365.25))/30.6001);
int d = mjd-14956-static_cast<int>(y*365.25)-static_cast<int>(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<unsigned>(symbol) << ".";
}
*output << dec << setfill('0') << setw(2) << static_cast<unsigned>(d) << "."
<< setw(2) << static_cast<unsigned>(m) << "." << static_cast<unsigned>(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<unsigned>(symbol) << ".";
}
break;

case 1: // time only
if (!hasFlag(REQ) && symbol == m_replacement) {
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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<float>(signedValue) * static_cast<float>(-m_divisor));
<< (static_cast<float>(signedValue) * static_cast<float>(-m_divisor));
} else if (m_divisor <= 1) {
if (hasFlag(FIX) && hasFlag(BCD)) {
if (outputFormat & OF_JSON) {
Expand All @@ -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;
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -985,18 +985,21 @@ 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));
// date, 01.01.2000 - 31.12.2099 (0x01,0x01,0x00 - 0x1f,0x0c,0x63, replacement 0xff)
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));
Expand Down
15 changes: 11 additions & 4 deletions src/lib/ebus/test/test_data.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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", ""},
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down
8 changes: 4 additions & 4 deletions src/lib/ebus/test/test_message.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"},
Expand Down

0 comments on commit 3e81e4a

Please sign in to comment.