diff --git a/include/Reading.hpp b/include/Reading.hpp index 7e88e163..0e17853b 100644 --- a/include/Reading.hpp +++ b/include/Reading.hpp @@ -180,6 +180,10 @@ class Reading { int64_t time_ms() const { return ((int64_t)_time.tv_sec) * 1e3 + (_time.tv_usec / 1e3); }; long time_s() const { return _time.tv_sec; }; // return only the seconds (always rounding down) void time() { gettimeofday(&_time, NULL); } + void time(time_t v) { + _time.tv_sec = v; + _time.tv_usec = 0; + } void time(struct timeval const &v) { _time = v; } void time(struct timespec const &v) { _time.tv_sec = v.tv_sec; diff --git a/src/protocols/MeterD0.cpp b/src/protocols/MeterD0.cpp index f2f0faa4..8f33f641 100644 --- a/src/protocols/MeterD0.cpp +++ b/src/protocols/MeterD0.cpp @@ -416,7 +416,7 @@ ssize_t MeterD0::read(std::vector &rds, size_t max_readings) { char endseq[2 + 1]; // Endsequence ! not ?! size_t number_of_tuples; int bytes_read; - time_t start_time, end_time; + time_t start_time, act_time, cur_time; struct termios tio; int baudrate_connect, baudrate_read; // Baudrates for switching @@ -442,7 +442,7 @@ ssize_t MeterD0::read(std::vector &rds, size_t max_readings) { wlen); } - time(&start_time); + time(&act_time); byte_iterator = number_of_tuples = baudrate = 0; byte = lastbyte = 0; @@ -474,8 +474,8 @@ ssize_t MeterD0::read(std::vector &rds, size_t max_readings) { while (1) { _safe_to_cancel(); // check for timeout - time(&end_time); - if (difftime(end_time, start_time) > _read_timeout_s) { + time(&cur_time); + if (difftime(cur_time, act_time) > _read_timeout_s) { print(log_error, "nothing received for more than %d seconds", name().c_str(), _read_timeout_s); dump_file(CTRL, "timeout!"); @@ -496,7 +496,7 @@ ssize_t MeterD0::read(std::vector &rds, size_t max_readings) { // reset timeout if we are making progress if (context != START) { - time(&start_time); + time(&act_time); } lastbyte = byte; @@ -513,6 +513,7 @@ ssize_t MeterD0::read(std::vector &rds, size_t max_readings) { case START: // strip the initial "/" if (byte == '/') { // if ((byte != '\r') && (byte != '\n')) { // allow extra new line // at the start + time(&start_time); // remember time of start of transmission byte_iterator = number_of_tuples = 0; // start context = VENDOR; // set new context: START -> VENDOR } // else ignore the other chars. -> Wait for / (!? is checked above already) @@ -794,7 +795,7 @@ ssize_t MeterD0::read(std::vector &rds, size_t max_readings) { Obis obis(obis_code); ReadingIdentifier *rid(new ObisIdentifier(obis)); rds[number_of_tuples].identifier(rid); - rds[number_of_tuples].time(); + rds[number_of_tuples].time(start_time); number_of_tuples++; } catch (vz::VZException &e) { print(log_alert, "Failed to parse obis code (%s)", name().c_str(), diff --git a/src/protocols/MeterSML.cpp b/src/protocols/MeterSML.cpp index 5bdaf33e..06ba25d8 100644 --- a/src/protocols/MeterSML.cpp +++ b/src/protocols/MeterSML.cpp @@ -242,6 +242,7 @@ ssize_t MeterSML::read(std::vector &rds, size_t n) { unsigned char buffer[SML_BUFFER_LEN]; size_t bytes, m = 0; + struct timeval tv; sml_file *file; sml_get_list_response *body; @@ -263,6 +264,7 @@ ssize_t MeterSML::read(std::vector &rds, size_t n) { /* wait until we receive a new datagram from the meter (blocking read) */ CANCELLABLE(bytes = sml_transport_read(_fd, buffer, SML_BUFFER_LEN)); + gettimeofday(&tv, NULL); if (0 == bytes) { // try to reopen. see issue #362 @@ -291,8 +293,11 @@ ssize_t MeterSML::read(std::vector &rds, size_t n) { /* iterating through linked list */ for (; m < n && entry != NULL;) { - if (_parse(entry, &rds[m])) + if (_parse(entry, &rds[m])) { + if (_use_local_time || !rds[m].time_s()) + rds[m].time(tv); m++; + } entry = entry->next; } } @@ -326,15 +331,12 @@ bool MeterSML::_parse(sml_list *entry, Reading *rd) { ReadingIdentifier *rid(new ObisIdentifier(obis)); rd->identifier(rid); - // TODO handle SML_TIME_SEC_INDEX or time by SML File/Message - struct timeval tv; - if (!_use_local_time && entry->val_time) { /* use time from meter */ + // TODO handle SML_TIME_SEC_INDEX + if (entry->val_time) { /* use time from meter */ + struct timeval tv = {0, 0}; tv.tv_sec = *entry->val_time->data.timestamp; - tv.tv_usec = 0; - } else { - gettimeofday(&tv, NULL); /* use local time */ + rd->time(tv); } - rd->time(tv); return true; } return false;