Created
February 7, 2016 12:15
-
-
Save KlausStetter/5103ca433459ba81aff3 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/include/protocols/MeterOMS.hpp b/include/protocols/MeterOMS.hpp | |
index 942357b..e0f59e5 100644 | |
--- a/include/protocols/MeterOMS.hpp | |
+++ b/include/protocols/MeterOMS.hpp | |
@@ -66,6 +66,7 @@ protected: | |
std::string _device; | |
bool _mbus_debug; | |
double _last_timestamp; | |
+ int no_frame_count; | |
}; | |
#endif | |
diff --git a/src/protocols/MeterOMS.cpp b/src/protocols/MeterOMS.cpp | |
index f0a92e8..0c74ed3 100644 | |
--- a/src/protocols/MeterOMS.cpp | |
+++ b/src/protocols/MeterOMS.cpp | |
@@ -252,22 +252,191 @@ ssize_t MeterOMS::read(std::vector<Reading> &rds, size_t n) | |
if (MBUS_RECV_RESULT_OK == _hwif->receive_frame(&frame)) { | |
--expect_frame; | |
print(log_debug, "got valid mbus frame with len=%d, type=%x control=%x controlinfo=%x address=%x", name().c_str(), frame.length1, frame.type, frame.control, frame.control_information, frame.address); | |
- if ((frame.control & MBUS_CONTROL_MASK_SND_UD) == MBUS_CONTROL_MASK_SND_UD) { | |
+ no_frame_count=0; | |
+ if ((frame.control & MBUS_CONTROL_MASK_RSP_UD) == MBUS_CONTROL_MASK_RSP_UD) { | |
+ print(log_debug, "got RSP_UD", name().c_str()); | |
+ /* for slave to master messages:*/ | |
+ mbus_frame_data reply_data; | |
+ if (mbus_frame_data_parse(&frame, &reply_data) == -1) { | |
+ print(log_error, "m-bus data parse error: %s", name().c_str(), mbus_error_str()); | |
+ } else { | |
+ char *xml_res; | |
+ if ((xml_res = mbus_frame_data_xml(&reply_data)) == NULL) { | |
+ print(log_error, "failed to generate xml: %s", name().c_str(), mbus_error_str()); | |
+ } else { | |
+ print(log_debug, "%s", name().c_str(), xml_res); | |
+ mbus_frame_data frame_data; | |
+ memset(&frame_data, 0, sizeof(frame_data)); | |
+ frame_data.type = MBUS_DATA_TYPE_VARIABLE; | |
+ mbus_data_variable_parse(&frame, &(frame_data.data_var)); | |
+ print(log_debug, "got %d data records: %s", name().c_str(), frame_data.data_var.nrecords, _mbus_debug ? mbus_data_variable_xml(&(frame_data.data_var)) : "active mbus_debug for detail infos"); | |
+ double timeFromMeter = 0.0; | |
+ // go through each record: | |
+ bool ignore_telegram = false; | |
+ for (mbus_data_record *record = (mbus_data_record*)frame_data.data_var.record; record && !ignore_telegram; record=(mbus_data_record*)(record->next)) { | |
+ print(log_debug, "DIF=%.2x, NDIFE=%.2x, DIFE1=%.2x, VIF=%.2x, NVIFE=%.2x VIFE1=%.2x VIFE2=%.2x", name().c_str(), | |
+ record->drh.dib.dif, | |
+ record->drh.dib.ndife, | |
+ record->drh.dib.dife[0], | |
+ record->drh.vib.vif, | |
+ record->drh.vib.nvife, | |
+ record->drh.vib.vife[0], | |
+ record->drh.vib.vife[1]); | |
+ const unsigned char &dif = record->drh.dib.dif; | |
+ const unsigned char &nvife = record->drh.vib.nvife; | |
+ const unsigned char &vife1 = record->drh.vib.vife[0]; | |
+ | |
+ switch (record->drh.vib.vif) { | |
+ case 0x6d: // time | |
+ timeFromMeter = get_record_value(record); | |
+ if (timeFromMeter > 1.0 && (timeFromMeter == _last_timestamp)) { | |
+ // duplicated timestamp received. ignore the remaining telegram as by spec | |
+ ignore_telegram = true; | |
+ print(log_finest, "Ignoring telegram due to duplicated timestamp %f", name().c_str(), timeFromMeter); | |
+ } else { | |
+ if (timeFromMeter > 1.0) | |
+ _last_timestamp = timeFromMeter; | |
+ } | |
+ break; | |
+ case 0x06: | |
+ //if (dif == 0x0c) { // Obis 1.8.0 Zaehlerstand Energie A+ Wh | |
+ print(log_debug, "Zählerstand %f %s", name().c_str(), | |
+ get_record_value(record), | |
+ mbus_vib_unit_lookup(&(record->drh.vib))); | |
+ if (ret<n) { | |
+ rds[ret].identifier(new ObisIdentifier("1.8.0")); | |
+ rds[ret].value(get_record_value(record)); | |
+ if (timeFromMeter>1.0) | |
+ rds[ret].time_from_double(timeFromMeter); | |
+ else | |
+ rds[ret].time(); | |
+ ++ret; | |
+ } | |
+ //} | |
+ break; | |
+ case 0x83: | |
+ if (dif == 0x04 && nvife == 1 && vife1 == 0x3c) { | |
+ print(log_debug, "Obis 2.8.0 %f %s", name().c_str(), | |
+ get_record_value(record), | |
+ mbus_vib_unit_lookup(&(record->drh.vib))); | |
+ if (ret < n) { | |
+ rds[ret].identifier(new ObisIdentifier("2.8.0")); | |
+ rds[ret].value(get_record_value(record)); | |
+ if (timeFromMeter>1.0) | |
+ rds[ret].time_from_double(timeFromMeter); | |
+ else | |
+ rds[ret].time(); | |
+ ++ret; | |
+ } | |
+ } | |
+ break; | |
+ case 0x2b: | |
+ //if (dif == 0x04) { | |
+ print(log_debug, "Leistung %f %s", name().c_str(), | |
+ get_record_value(record), | |
+ mbus_vib_unit_lookup(&(record->drh.vib))); | |
+ if (ret < n) { | |
+ rds[ret].identifier(new ObisIdentifier("1.7.0")); | |
+ rds[ret].value(get_record_value(record)); | |
+ if (timeFromMeter>1.0) | |
+ rds[ret].time_from_double(timeFromMeter); | |
+ else | |
+ rds[ret].time(); | |
+ ++ret; | |
+ } | |
+ //} | |
+ break; | |
+ case 0xab: | |
+ if (dif == 0x04 && nvife == 1 && vife1 == 0x3c) { | |
+ print(log_debug, "Obis 2.7.0 %f %s", name().c_str(), | |
+ get_record_value(record), | |
+ mbus_vib_unit_lookup(&(record->drh.vib))); | |
+ if (ret < n) { | |
+ rds[ret].identifier(new ObisIdentifier("2.7.0")); | |
+ rds[ret].value(get_record_value(record)); | |
+ if (timeFromMeter>1.0) | |
+ rds[ret].time_from_double(timeFromMeter); | |
+ else | |
+ rds[ret].time(); | |
+ ++ret; | |
+ } | |
+ } | |
+ break; | |
+ case 0x5a: | |
+ //if (dif == 0x04 && nvife == 1 && vife1 == 0x3c) { | |
+ print(log_debug, "Vorlauftemperatur %f %s", name().c_str(), | |
+ get_record_value(record), | |
+ mbus_vib_unit_lookup(&(record->drh.vib))); | |
+ if (ret < n) { | |
+ rds[ret].identifier(new ObisIdentifier("2.7.0")); | |
+ rds[ret].value(get_record_value(record)/10); | |
+ if (timeFromMeter>1.0) | |
+ rds[ret].time_from_double(timeFromMeter); | |
+ else | |
+ rds[ret].time(); | |
+ ++ret; | |
+ } | |
+ //} | |
+ break; | |
+ case 0x5e: | |
+ //if (dif == 0x04 && nvife == 1 && vife1 == 0x3c) { | |
+ print(log_debug, "Rücklauftemperatur %f %s", name().c_str(), | |
+ get_record_value(record), | |
+ mbus_vib_unit_lookup(&(record->drh.vib))); | |
+ if (ret < n) { | |
+ rds[ret].identifier(new ObisIdentifier("2.7.1")); | |
+ rds[ret].value(get_record_value(record)/10); | |
+ if (timeFromMeter>1.0) | |
+ rds[ret].time_from_double(timeFromMeter); | |
+ else | |
+ rds[ret].time(); | |
+ ++ret; | |
+ } | |
+ //} | |
+ break; | |
+ case 0x60: | |
+ //if (dif == 0x04 && nvife == 1 && vife1 == 0x3c) { | |
+ print(log_debug, "Spreizung %f %s", name().c_str(), | |
+ get_record_value(record), | |
+ mbus_vib_unit_lookup(&(record->drh.vib))); | |
+ if (ret < n) { | |
+ rds[ret].identifier(new ObisIdentifier("2.7.2")); | |
+ rds[ret].value(get_record_value(record)/1000); | |
+ if (timeFromMeter>1.0) | |
+ rds[ret].time_from_double(timeFromMeter); | |
+ else | |
+ rds[ret].time(); | |
+ ++ret; | |
+ } | |
+ //} | |
+ break; | |
+ case 0x3b: | |
+ //if (dif == 0x04 && nvife == 1 && vife1 == 0x3c) { | |
+ print(log_debug, "Durchfluss %f %s", name().c_str(), | |
+ get_record_value(record), | |
+ mbus_vib_unit_lookup(&(record->drh.vib))); | |
+ if (ret < n) { | |
+ rds[ret].identifier(new ObisIdentifier("2.7.3")); | |
+ rds[ret].value(get_record_value(record)/1000); | |
+ if (timeFromMeter>1.0) | |
+ rds[ret].time_from_double(timeFromMeter); | |
+ else | |
+ rds[ret].time(); | |
+ ++ret; | |
+ } | |
+ //} | |
+ break; | |
+ } | |
+ } | |
+ mbus_data_record_free((mbus_data_record*)frame_data.data_var.record); | |
+ } | |
+ } | |
+ } | |
+ | |
+ else if ((frame.control & MBUS_CONTROL_MASK_SND_UD) == MBUS_CONTROL_MASK_SND_UD) { | |
if (_mbus_debug) mbus_frame_print(&frame); | |
if (!got_SND_NKE) | |
print(log_finest, "got SND_UD without SND_NKE", name().c_str()); | |
- /* for slave to master messages: | |
- mbus_frame_data reply_data; | |
- if (mbus_frame_data_parse(&frame2, &reply_data) == -1) { | |
- print(log_error, "m-bus data parse error: %s", name().c_str(), mbus_error_str()); | |
- } else { | |
- char *xml_res; | |
- if ((xml_res = mbus_frame_data_xml(&reply_data)) == NULL) { | |
- print(log_error, "failed to generate xml: %s", name().c_str(), mbus_error_str()); | |
- } else { | |
- print(log_finest, "%s", name().c_str(), xml_res); | |
- } | |
- } */ | |
print(log_finest, "got SND_UD packet", name().c_str()); | |
// analyse first and ACK only if correct: | |
@@ -440,14 +609,22 @@ ssize_t MeterOMS::read(std::vector<Reading> &rds, size_t n) | |
} | |
} else | |
{ | |
- print(log_debug, "wrong frame received. waiting for SND_NKE or SND_UD!", name().c_str()); | |
+ print(log_error, "wrong frame received. waiting for SND_NKE or SND_UD!", name().c_str()); | |
expect_frame = 0; | |
} | |
} else { | |
expect_frame = 0; | |
+ if (++no_frame_count > 240) | |
+ { | |
+ print(log_error, "no_frame_count=%d! reopen device....", name().c_str(), no_frame_count); | |
+ close(); | |
+ open(); | |
+ no_frame_count = 0; | |
+ } | |
} | |
} // while expect_frame>0 | |
+ | |
mbus_frame_free(frame_ack); | |
return ret; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment