Fixed conversion of date and time from meter to account for CET/CEST

This commit is contained in:
Gunnar Skjold 2020-03-08 18:37:10 +01:00
parent 30d73c3a6e
commit 9b70802450
4 changed files with 26 additions and 37 deletions

View File

@ -2,7 +2,6 @@
HanReader::HanReader()
{
}
void HanReader::setup(Stream *hanPort, Stream *debugPort)
@ -10,6 +9,12 @@ void HanReader::setup(Stream *hanPort, Stream *debugPort)
han = hanPort;
bytesRead = 0;
debug = debugPort;
// Central European Time (Frankfurt, Paris)
TimeChangeRule CEST = {"CEST", Last, Sun, Mar, 2, 120}; // Central European Summer Time
TimeChangeRule CET = {"CET ", Last, Sun, Oct, 3, 60}; // Central European Standard Time
localZone = new Timezone(CEST, CET);
if (debug) debug->println("MBUS serial setup complete");
}
@ -182,8 +187,7 @@ time_t HanReader::getTime(byte *buffer, int start, int length)
int pos = start;
int dataLength = buffer[pos++];
if (dataLength == 0x0C)
{
if (dataLength == 0x0C) {
int year = buffer[pos] << 8 |
buffer[pos + 1];
@ -193,10 +197,21 @@ time_t HanReader::getTime(byte *buffer, int start, int length)
int minute = buffer[pos + 6];
int second = buffer[pos + 7];
return toUnixTime(year, month, day, hour, minute, second);
}
else
{
tmElements_t tm;
tm.Year = year - 1970;
tm.Month = month;
tm.Day = day;
tm.Hour = hour;
tm.Minute = minute;
tm.Second = second;
return localZone->toUTC(makeTime(tm));
} else if(dataLength == 0) {
return (time_t)0L;
} else {
if(debug) {
debug->print("Unknown time length: ");
debug->println(dataLength);
}
// Date format not supported
return (time_t)0L;
}
@ -259,30 +274,3 @@ String HanReader::getString(int dataPosition, byte *buffer, int start, int lengt
}
return String("");
}
time_t HanReader::toUnixTime(int year, int month, int day, int hour, int minute, int second)
{
byte daysInMonth[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
long secondsPerMinute = 60;
long secondsPerHour = secondsPerMinute * 60;
long secondsPerDay = secondsPerHour * 24;
long time = (year - 1970) * secondsPerDay * 365L;
for (int yearCounter = 1970; yearCounter<year; yearCounter++)
if ((yearCounter % 4 == 0) && ((yearCounter % 100 != 0) || (yearCounter % 400 == 0)))
time += secondsPerDay;
if (month > 2 && (year % 4 == 0) && ((year % 100 != 0) || (year % 400 == 0)))
time += secondsPerDay;
for (int monthCounter = 1; monthCounter<month; monthCounter++)
time += daysInMonth[monthCounter - 1] * secondsPerDay;
time += (day - 1) * secondsPerDay;
time += hour * secondsPerHour;
time += minute * secondsPerMinute;
time += second;
return (time_t)time;
}

View File

@ -9,7 +9,7 @@
#include "DlmsReader.h"
#include <Timezone.h>
class HanReader
{
@ -35,6 +35,7 @@ private:
int bytesRead;
DlmsReader reader;
int listSize;
Timezone *localZone;
int findValuePosition(int dataPosition, byte *buffer, int start, int length);

View File

@ -4,7 +4,7 @@ extra_configs = platformio-user.ini
[common]
framework = arduino
lib_deps = HanReader@1.0.0, ArduinoJson@6.14.1, MQTT@2.4.7, DallasTemperature@3.8.1, EspSoftwareSerial@6.7.1, Base64@1.0.0
lib_deps = HanReader@1.0.0, ArduinoJson@6.14.1, MQTT@2.4.7, DallasTemperature@3.8.1, EspSoftwareSerial@6.7.1, Base64@1.0.0, Time@1.6, Timezone@1.2.4
[env:hw1esp12e]
platform = espressif8266@2.3.3

View File

@ -143,7 +143,7 @@ void setup() {
#endif
#endif
hanReader.setup(hanSerial, 0);
hanReader.setup(hanSerial, debugger);
// Compensate for the known Kaifa bug
hanReader.compensateFor09HeaderBug = (config.getMeterType() == 1);