Skip to content

Instantly share code, notes, and snippets.

@KlausStetter
Created February 7, 2016 12:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save KlausStetter/5103ca433459ba81aff3 to your computer and use it in GitHub Desktop.
Save KlausStetter/5103ca433459ba81aff3 to your computer and use it in GitHub Desktop.
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