Add meter Sekundenindex anchoring for epoch timestamps
Parse 0-0:96.8.0*255 meter seconds, derive sample epoch from anchored offset, and detect meter-time jumps via monotonic/delta checks.
This commit is contained in:
@@ -100,6 +100,52 @@ static bool parse_obis_ascii_unit_scale(const char *line, const char *obis, floa
|
||||
return false;
|
||||
}
|
||||
|
||||
static int8_t hex_nibble(char c) {
|
||||
if (c >= '0' && c <= '9') {
|
||||
return static_cast<int8_t>(c - '0');
|
||||
}
|
||||
if (c >= 'A' && c <= 'F') {
|
||||
return static_cast<int8_t>(10 + (c - 'A'));
|
||||
}
|
||||
if (c >= 'a' && c <= 'f') {
|
||||
return static_cast<int8_t>(10 + (c - 'a'));
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static bool parse_obis_hex_u32(const char *line, const char *obis, uint32_t &out_value) {
|
||||
const char *p = strstr(line, obis);
|
||||
if (!p) {
|
||||
return false;
|
||||
}
|
||||
const char *lparen = strchr(p, '(');
|
||||
if (!lparen) {
|
||||
return false;
|
||||
}
|
||||
const char *cur = lparen + 1;
|
||||
uint32_t value = 0;
|
||||
size_t n = 0;
|
||||
while (*cur && *cur != ')' && *cur != '*') {
|
||||
int8_t nib = hex_nibble(*cur++);
|
||||
if (nib < 0) {
|
||||
if (n == 0) {
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (n >= 8) {
|
||||
return false;
|
||||
}
|
||||
value = (value << 4) | static_cast<uint32_t>(nib);
|
||||
n++;
|
||||
}
|
||||
if (n == 0) {
|
||||
return false;
|
||||
}
|
||||
out_value = value;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void meter_debug_log() {
|
||||
if (!SERIAL_DEBUG_MODE) {
|
||||
return;
|
||||
@@ -242,6 +288,11 @@ bool meter_parse_frame(const char *frame, size_t len, MeterData &data) {
|
||||
p3_ok = true;
|
||||
got_any = true;
|
||||
}
|
||||
uint32_t meter_seconds = 0;
|
||||
if (parse_obis_hex_u32(line, "0-0:96.8.0*255", meter_seconds)) {
|
||||
data.meter_seconds = meter_seconds;
|
||||
data.meter_seconds_valid = true;
|
||||
}
|
||||
|
||||
line_len = 0;
|
||||
continue;
|
||||
@@ -261,6 +312,8 @@ bool meter_parse_frame(const char *frame, size_t len, MeterData &data) {
|
||||
}
|
||||
|
||||
bool meter_read(MeterData &data) {
|
||||
data.meter_seconds = 0;
|
||||
data.meter_seconds_valid = false;
|
||||
data.energy_total_kwh = NAN;
|
||||
data.total_power_w = NAN;
|
||||
data.phase_power_w[0] = NAN;
|
||||
|
||||
Reference in New Issue
Block a user