Browse Source

Add files via upload

pull/1080/head
oberfritze 2 years ago
committed by GitHub
parent
commit
870f8c5a37
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 191
      src/plugins/SML_OBIS_Parser.cpp

191
src/plugins/SML_OBIS_Parser.cpp

@ -86,11 +86,12 @@ static unsigned char sml_serial_buf[SML_MAX_SERIAL_BUF];
static unsigned char *cur_serial_buf = sml_serial_buf; static unsigned char *cur_serial_buf = sml_serial_buf;
static uint16 sml_serial_len = 0; static uint16 sml_serial_len = 0;
static uint16 sml_skip_len = 0; static uint16 sml_skip_len = 0;
static uint32 sml_message = 0;
static obis_state_t obis_state = OBIS_ST_NONE; static obis_state_t obis_state = OBIS_ST_NONE;
static int obis_power_all_scale, obis_power_all_value; static int obis_power_all_scale, obis_power_all_value;
/* design: max 16 bit fuer aktuelle Powerwerte */ /* design: max 16 bit fuer aktuelle Powerwerte */
static int16_t obis_cur_pac; static int16_t obis_cur_pac;
static uint16_t obis_crc; static uint16_t sml_telegram_crc;
static uint16_t obis_cur_pac_cnt; static uint16_t obis_cur_pac_cnt;
static uint16_t obis_cur_pac_index; static uint16_t obis_cur_pac_index;
static int32_t obis_pac_sum; static int32_t obis_pac_sum;
@ -106,14 +107,14 @@ const unsigned char esc_seq[] = {SML_ESCAPE_CHAR, SML_ESCAPE_CHAR, SML_ESCAPE_CH
#ifdef SML_OBIS_TEST #ifdef SML_OBIS_TEST
static size_t sml_test_telegram_offset; static size_t sml_test_telegram_offset;
const unsigned char sml_test_telegram[] = { const unsigned char sml_test_telegram[] = {
0x1b, 0x1b, 0x1b, 0x1b, // Escapesequenz 0x1b, 0x1b, 0x1b, 0x1b, // Escape sequence
0x01, 0x01, 0x01, 0x01, // Version 1 0x01, 0x01, 0x01, 0x01, // Version 1
0x76, // Liste mit 6 Eintraegen (1. SML Nachricht dieses Telegramms) 0x76, // List with 6 enties (1st SML message of this telegram)
0x05, 0x03, 0x2b, 0x18, 0x20, 0x05, 0x03, 0x2b, 0x18, 0x20,
0x62, 0x00, 0x62, 0x00,
0x62, 0x00, 0x62, 0x00,
0x72, 0x72,
0x63, 0x01, 0x01, // Messagetyp: OpenResponse 0x63, 0x01, 0x01, // Message type: OpenResponse
0x76, 0x76,
0x01, 0x01,
0x01, 0x01,
@ -123,12 +124,12 @@ const unsigned char sml_test_telegram[] = {
0x01, 0x01,
0x63, 0x53, 0x34, 0x63, 0x53, 0x34,
0x00, 0x00,
0x76, // Liste mit 6 Eintraegen (2. SML Nachricht dieses Telegramms) 0x76, // List with 6 entries (2. SML mesaage of this telegram)
0x05, 0x03, 0x2b, 0x18, 0x21, 0x05, 0x03, 0x2b, 0x18, 0x21,
0x62, 0x00, 0x62, 0x00,
0x62, 0x00, 0x62, 0x00,
0x72, 0x72,
0x63, 0x07, 0x01, // Messagetyp: GetListResponse 0x63, 0x07, 0x01, // Message type: GetListResponse
0x77, 0x77,
0x01, 0x01,
0x0b, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x0b, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
@ -138,107 +139,107 @@ const unsigned char sml_test_telegram[] = {
0x65, 0x02, 0x1a, 0x58, 0x7f, 0x65, 0x02, 0x1a, 0x58, 0x7f,
0x7a, 0x7a,
0x77, 0x77,
0x07, 0x01, 0x00, 0x01, 0x08, 0x00, 0xff, // OBIS Kennzahl fuer Wirkenergie Bezug gesamt tariflos 0x07, 0x01, 0x00, 0x01, 0x08, 0x00, 0xff, // OBIS: Energy in overall - no tarif
0x65, 0x00, 0x01, 0x01, 0x80, 0x65, 0x00, 0x01, 0x01, 0x80,
0x01, 0x01,
0x62, 0x1e, // Einheit "Wh" 0x62, 0x1e, // Einheit "Wh"
0x52, 0xff, // Skalierung 0.1 0x52, 0xff, // Skalierung 0.1
0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0xc3, 0x05, // Wert fuer Wirkenergie Bezug gesamt tariflos 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0xc3, 0x05, // value
0x01, 0x01,
0x77, 0x77,
0x07, 0x01, 0x00, 0x01, 0x08, 0x01, 0xff, // OBIS-Kennzahl fuer Wirkenergie Bezug Tarif 1 0x07, 0x01, 0x00, 0x01, 0x08, 0x01, 0xff, // OBIS: Energy in - tarif 1
0x01, 0x01,
0x01, 0x01,
0x62, 0x1e, // Einheit "Wh" 0x62, 0x1e, // "Wh"
0x52, 0xff, // Skalierung 0.1 0x52, 0xff, // scaler 0.1
0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0xc3, 0x05, // Wert fuer Wirkenergie Bezug Tarif 1 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0xc3, 0x05, // value
0x01, 0x01,
0x77, 0x77,
0x07, 0x01, 0x00, 0x01, 0x08, 0x02, 0xff, // OBIS-Kennzahl fuer Wirkenergie Bezug Tarif 2 0x07, 0x01, 0x00, 0x01, 0x08, 0x02, 0xff, // OBIS: Energy in - tarif 2
0x01, 0x01,
0x01, 0x01,
0x62, 0x1e, // Einheit "Wh" 0x62, 0x1e, // "Wh"
0x52, 0xff, // Skalierung 0.1 0x52, 0xff, // scaler 0.1
0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Wert fuer Wirkenergie Bezug Tarif 2 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // value
0x01, 0x01,
0x77, 0x77,
0x07, 0x01, 0x00, 0x02, 0x08, 0x00, 0xff, // OBIS-Kennzahl für Wirkenergie Einspeisung gesamt tariflos 0x07, 0x01, 0x00, 0x02, 0x08, 0x00, 0xff, // OBIS: energy out overall - no tarif
0x01, 0x01,
0x01, 0x01,
0x62, 0x1e, // Einheit "Wh" 0x62, 0x1e, // "Wh"
0x52, 0xff, // Skalierung 0.1 0x52, 0xff, // scaler 0.1
0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Wert für Wirkenergie Einspeisung gesamt tariflos 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // value
0x01, 0x01,
0x77, 0x77,
0x07, 0x01, 0x00, 0x02, 0x08, 0x01, 0xff, // OBIS-Kennzahl für Wirkenergie Einspeisung Tarif1 0x07, 0x01, 0x00, 0x02, 0x08, 0x01, 0xff, // OBIS: energy out - tarif 1
0x01, 0x01,
0x01, 0x01,
0x62, 0x1e, // Einheit "Wh" 0x62, 0x1e, // "Wh"
0x52, 0xff, // Skalierung 0.1 0x52, 0xff, // scaler 0.1
0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Wert fuer Wirkenergie Einspeisung Tarif 1 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // value
0x01, 0x01,
0x77, 0x77,
0x07, 0x01, 0x00, 0x02, 0x08, 0x02, 0xff, // OBIS-Kennzahl für Wirkenergie Einspeisung Tarif 2 0x07, 0x01, 0x00, 0x02, 0x08, 0x02, 0xff, // OBIS: energy out - tarif 2
0x01, 0x01,
0x01, 0x01,
0x62, 0x1e, // Einheit "Wh" 0x62, 0x1e, // "Wh"
0x52, 0xff, // Skalierung 0.1 0x52, 0xff, // scaler 0.1
0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Wert für Wirkenergie Einspeisung Tarif 2 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // value
0x01, 0x01,
0x77, 0x77,
0x07, 0x01, 0x00, 0x10, 0x07, 0x00, 0xff, // OBIS-Kennzahl fuer momentane Gesamtwirkleistung 0x07, 0x01, 0x00, 0x10, 0x07, 0x00, 0xff, // OBIS: power overall
0x01, 0x01,
0x01, 0x01,
0x62, 0x1b, // Einheit "W" 0x62, 0x1b, // "W"
0x52, 0x00, // Skalierung 1 0x52, 0x00, // scaler 1
0x55, 0x00, 0x00, 0x00, 0x2a, // Wert fuer momentane Gesamtwirkleistung 0x55, 0x00, 0x00, 0x00, 0x2a, // value
0x01, 0x01,
0x77, 0x77,
0x07, 0x01, 0x00, 0x24, 0x07, 0x00, 0xff, // OBIS-Kennzahl fuer momentane Wirkleistung L1 0x07, 0x01, 0x00, 0x24, 0x07, 0x00, 0xff, // OBIS: power L1
0x01, 0x01,
0x01, 0x01,
0x62, 0x1b, // Einheit "W" 0x62, 0x1b, // "W"
0x52, 0x00, // Skalierung 1 0x52, 0x00, // scaler 1
0x55, 0x00, 0x00, 0x00, 0x2a, // Wert fuer momentane Wirkleistung L1 0x55, 0x00, 0x00, 0x00, 0x2a, // value
0x01, 0x01,
0x77, 0x77,
0x07, 0x01, 0x00, 0x38, 0x07, 0x00, 0xff, // OBIS-Kennzahl fuer momentane Wirkleistung L2 0x07, 0x01, 0x00, 0x38, 0x07, 0x00, 0xff, // OBIS: power L2
0x01, 0x01,
0x01, 0x01,
0x62, 0x1b, // Einheit "W" 0x62, 0x1b, // "W"
0x52, 0x00, // Skalierung 1 0x52, 0x00, // scaler 1
0x55, 0x00, 0x00, 0x00, 0x00, // Wert für momentane Wirkleistung L2 0x55, 0x00, 0x00, 0x00, 0x00, // value
0x01, 0x01,
0x77, 0x77,
0x07, 0x01, 0x00, 0x4c, 0x07, 0x00, 0xff, // OBIS-Kennzahl fuer momentane Wirkleistung L3 0x07, 0x01, 0x00, 0x4c, 0x07, 0x00, 0xff, // OBIS: power L3
0x01, 0x01,
0x01, 0x01,
0x62, 0x1b, // Einheit "W" 0x62, 0x1b, // "W"
0x52, 0x00, // Skalierung 1 0x52, 0x00, // scaler 1
0x55, 0x00, 0x00, 0x00, 0x00, // Wert fuer momentane Wirkleistung L3 0x55, 0x00, 0x00, 0x00, 0x00, // value
0x01, 0x01,
0x01, 0x01,
0x01, 0x01,
0x63, 0x23, 0x59, 0x63, 0x23, 0x59,
0x00, 0x00,
0x76, // Liste mit 6 Eintraegen (3. SML Nachricht dieses Telegramms) 0x76, // List with 6 entries (3rd SML message of this telegram)
0x05, 0x03, 0x2b, 0x18, 0x22, 0x05, 0x03, 0x2b, 0x18, 0x22,
0x62, 0x00, 0x62, 0x00,
0x62, 0x00, 0x62, 0x00,
0x72, 0x72,
0x63, 0x02, 0x01, // Messagetyp: CloseResponse 0x63, 0x02, 0x01, // Message type: CloseResponse
0x71, 0x71,
0x01, 0x01,
0x63, 0x91, 0x26, 0x63, 0x91, 0x26,
0x00, 0x00,
0x1b, 0x1b, 0x1b, 0x1b, // Escapesequenz 0x1b, 0x1b, 0x1b, 0x1b, // Escape sequence
0x1a, 0x00, 0xbf, 0xd7 // 1a + Fuellbyte + CRC16 des gesamten Telegrammes (ggf. passend eintragen) 0x1a, 0x00, 0xbf, 0xd7 // 1a + number of fill bytes + CRC16 of telegram (change this to your needs)
}; };
#endif #endif
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// DIN EN 62056-46, Polynom 0x1021 // DIN EN 62056-46, Polynom 0x1021
static const uint16_t obis_crctab[256] = { static const uint16_t sml_crctab[256] = {
0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, 0x8c48, 0x9dc1, 0xaf5a, 0xbed3,
0xca6c, 0xdbe5, 0xe97e, 0xf8f7, 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, 0x2102, 0x308b, 0x0210, 0x1399, 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, 0x2102, 0x308b, 0x0210, 0x1399,
@ -263,25 +264,26 @@ static const uint16_t obis_crctab[256] = {
0x3de3, 0x2c6a, 0x1ef1, 0x0f78}; 0x3de3, 0x2c6a, 0x1ef1, 0x0f78};
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void sml_init_obis_crc () uint16_t sml_init_crc ()
{ {
obis_crc = 0xffff; return 0xffff;
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void sml_calc_obis_crc (unsigned int len, unsigned char *data) uint16_t sml_calc_crc (uint16_t crc, unsigned int len, unsigned char *data)
{ {
while (len--) { while (len--) {
obis_crc = (obis_crc >> 8) ^ obis_crctab[(obis_crc ^ *data++) & 0xff]; crc = (crc >> 8) ^ sml_crctab[(crc ^ *data++) & 0xff];
} }
return crc;
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
uint16_t sml_finit_obis_crc () uint16_t sml_finit_crc (uint16_t crc)
{ {
obis_crc ^= 0xffff; crc ^= 0xffff;
obis_crc = (obis_crc << 8) | (obis_crc >> 8); crc = (crc << 8) | (crc >> 8);
return obis_crc; return crc;
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -295,20 +297,17 @@ void sml_cleanup_history ()
{ {
time_t time_today; time_t time_today;
time_today = *obis_timestamp;
obis_cur_pac = 0; obis_cur_pac = 0;
obis_cur_pac_cnt = 0; obis_cur_pac_cnt = 0;
obis_cur_pac_index = 0; obis_cur_pac_index = 0;
obis_pac_sum = 0; obis_pac_sum = 0;
if (time_today) { if ((time_today = *obis_timestamp)) {
Dir grid_power_dir; Dir grid_power_dir;
struct tm tm_today;
char cur_file_name[sizeof (SML_OBIS_FORMAT_FILE_NAME)]; char cur_file_name[sizeof (SML_OBIS_FORMAT_FILE_NAME)];
localtime_r (&time_today, &tm_today); time_today = gTimezone.toLocal (time_today);
snprintf (cur_file_name, sizeof (cur_file_name), SML_OBIS_FORMAT_FILE_NAME, snprintf (cur_file_name, sizeof (cur_file_name), SML_OBIS_FORMAT_FILE_NAME,
tm_today.tm_mday, tm_today.tm_mon+1, tm_today.tm_year + 1900); day(time_today), month (time_today), year (time_today));
grid_power_dir = LittleFS.openDir (SML_OBIS_GRID_POWER_PATH); grid_power_dir = LittleFS.openDir (SML_OBIS_GRID_POWER_PATH);
/* design: no dataserver, cleanup old history */ /* design: no dataserver, cleanup old history */
@ -327,16 +326,15 @@ void sml_cleanup_history ()
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
File sml_open_hist () File sml_open_hist ()
{ {
time_t time_today;
File file = (File) NULL; File file = (File) NULL;
if (*obis_timestamp) { if ((time_today = *obis_timestamp)) {
char file_name[sizeof (SML_OBIS_GRID_POWER_PATH) + sizeof (SML_OBIS_FORMAT_FILE_NAME)]; char file_name[sizeof (SML_OBIS_GRID_POWER_PATH) + sizeof (SML_OBIS_FORMAT_FILE_NAME)];
time_t time_today = *obis_timestamp;
struct tm tm_today;
localtime_r (&time_today, &tm_today); time_today = gTimezone.toLocal(time_today);
snprintf (file_name, sizeof (file_name), SML_OBIS_GRID_POWER_PATH "/" SML_OBIS_FORMAT_FILE_NAME, snprintf (file_name, sizeof (file_name), SML_OBIS_GRID_POWER_PATH "/" SML_OBIS_FORMAT_FILE_NAME,
tm_today.tm_mday, tm_today.tm_mon+1, tm_today.tm_year + 1900); day(time_today), month(time_today), year(time_today));
file = LittleFS.open (file_name, "r"); file = LittleFS.open (file_name, "r");
if (!file) { if (!file) {
DPRINT (DBG_WARN, "sml_open_hist, failed to open "); DPRINT (DBG_WARN, "sml_open_hist, failed to open ");
@ -411,7 +409,7 @@ void sml_handle_obis_state (unsigned char *buf)
"." + String (buf[3], HEX) + "." + String(buf[4], HEX) + "*" + String(buf[5], HEX)); "." + String (buf[3], HEX) + "." + String(buf[4], HEX) + "*" + String(buf[5], HEX));
} }
#endif #endif
if (obis_state != OBIS_ST_NONE) { if (sml_message == SML_MSG_GET_LIST_RSP) {
if (buf[0] == 1) { if (buf[0] == 1) {
if (!memcmp (&buf[2], OBIS_SIG_YIELD_IN_ALL, 3)) { if (!memcmp (&buf[2], OBIS_SIG_YIELD_IN_ALL, 3)) {
obis_state = OBIS_ST_YIELD_IN_ALL; obis_state = OBIS_ST_YIELD_IN_ALL;
@ -533,12 +531,15 @@ int16_t sml_get_obis_pac_average ()
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void sml_handle_obis_pac (int16_t pac) void sml_handle_obis_pac (int16_t pac)
{ {
time_t time_today;
obis_cur_pac = pac; obis_cur_pac = pac;
if (*obis_timestamp) { if ((time_today = *obis_timestamp)) {
uint32_t pac_index = gTimezone.toLocal (*obis_timestamp); uint32_t pac_index;
time_today = gTimezone.toLocal (time_today);
pac_index = hour(pac_index) * 60 + minute(pac_index); pac_index = hour(time_today) * 60 + minute(time_today);
pac_index /= AHOY_PAC_INTERVAL; pac_index /= AHOY_PAC_INTERVAL;
if (pac_index != obis_cur_pac_index) { if (pac_index != obis_cur_pac_index) {
@ -547,12 +548,9 @@ void sml_handle_obis_pac (int16_t pac)
int16_t pac_average = sml_get_obis_pac_average(); int16_t pac_average = sml_get_obis_pac_average();
File file; File file;
char file_name[sizeof (SML_OBIS_GRID_POWER_PATH) + sizeof (SML_OBIS_FORMAT_FILE_NAME)]; char file_name[sizeof (SML_OBIS_GRID_POWER_PATH) + sizeof (SML_OBIS_FORMAT_FILE_NAME)];
time_t time_today = *obis_timestamp;
struct tm tm_today;
localtime_r (&time_today, &tm_today);
snprintf (file_name, sizeof (file_name), SML_OBIS_GRID_POWER_PATH "/" SML_OBIS_FORMAT_FILE_NAME, snprintf (file_name, sizeof (file_name), SML_OBIS_GRID_POWER_PATH "/" SML_OBIS_FORMAT_FILE_NAME,
tm_today.tm_mday, tm_today.tm_mon+1, tm_today.tm_year + 1900); day(time_today), month(time_today), year(time_today));
// append last average // append last average
if ((file = LittleFS.open (file_name, "a"))) { if ((file = LittleFS.open (file_name, "a"))) {
unsigned char buf[4]; unsigned char buf[4];
@ -579,7 +577,7 @@ void sml_handle_obis_pac (int16_t pac)
obis_pac_sum += pac; obis_pac_sum += pac;
obis_cur_pac_cnt++; obis_cur_pac_cnt++;
} else { } else {
DPRINTLN (DBG_INFO, "sml_handle_obis_pac, outside daylight, minutes: " + String (pac_index * AHOY_PAC_INTERVAL)); DPRINTLN (DBG_DEBUG, "sml_handle_obis_pac, outside daylight, minutes: " + String (pac_index * AHOY_PAC_INTERVAL));
} }
} else { } else {
DPRINTLN (DBG_INFO, "sml_handle_obis_pac, no time2"); DPRINTLN (DBG_INFO, "sml_handle_obis_pac, no time2");
@ -624,6 +622,7 @@ bool sml_get_list_entries (uint16_t layer)
sml_list_entry_type_t type = (sml_list_entry_type_t)(*cur_serial_buf & 0x70); sml_list_entry_type_t type = (sml_list_entry_type_t)(*cur_serial_buf & 0x70);
unsigned char entry_len; unsigned char entry_len;
// Acc. to Spec there might be len_info > 2. But does this happen in real life? // Acc. to Spec there might be len_info > 2. But does this happen in real life?
// Also: an info_len > 2 could be due to corrupt data. So better break.
uint16 len_info = (*cur_serial_buf & SML_EXT_LENGTH) ? 2 : 1; uint16 len_info = (*cur_serial_buf & SML_EXT_LENGTH) ? 2 : 1;
#ifdef undef #ifdef undef
@ -648,7 +647,7 @@ bool sml_get_list_entries (uint16_t layer)
entry_len = *cur_serial_buf & 0x0f; /* bei Listen andere Bedeutung */ entry_len = *cur_serial_buf & 0x0f; /* bei Listen andere Bedeutung */
} }
if ((type == SML_TYPE_LIST) || (sml_serial_len >= entry_len)) { if ((type == SML_TYPE_LIST) || (sml_serial_len >= entry_len)) {
sml_calc_obis_crc (len_info, cur_serial_buf); sml_telegram_crc = sml_calc_crc (sml_telegram_crc, len_info, cur_serial_buf);
sml_serial_len -= len_info; sml_serial_len -= len_info;
if (entry_len && (type != SML_TYPE_LIST)) { if (entry_len && (type != SML_TYPE_LIST)) {
entry_len -= len_info; entry_len -= len_info;
@ -669,10 +668,8 @@ bool sml_get_list_entries (uint16_t layer)
break; break;
case SML_TYPE_INT: case SML_TYPE_INT:
if (layer == 1) { if (layer == 1) {
if ((obis_state == OBIS_ST_NONE) && if (!sml_message && (sml_list_layer_entries[layer] == 2)) {
(sml_list_layer_entries[layer] == 2) && sml_message = sml_obis_get_int (cur_serial_buf, entry_len);
(sml_obis_get_int (cur_serial_buf, entry_len) == SML_MSG_GET_LIST_RSP)) {
obis_state = OBIS_ST_UNKNOWN;
} }
} else if (layer == 4) { } else if (layer == 4) {
if (obis_state == OBIS_ST_POWER_ALL) { if (obis_state == OBIS_ST_POWER_ALL) {
@ -698,10 +695,8 @@ bool sml_get_list_entries (uint16_t layer)
break; break;
case SML_TYPE_UINT: case SML_TYPE_UINT:
if (layer == 1) { if (layer == 1) {
if ((obis_state == OBIS_ST_NONE) && if (!sml_message && (sml_list_layer_entries[layer] == 2)) {
(sml_list_layer_entries[layer] == 2) && sml_message = sml_obis_get_uint (cur_serial_buf, entry_len);
(sml_obis_get_uint (cur_serial_buf, entry_len) == SML_MSG_GET_LIST_RSP)) {
obis_state = OBIS_ST_UNKNOWN;
} }
} else if (layer == 4) { } else if (layer == 4) {
if (obis_state == OBIS_ST_YIELD_IN_ALL) { if (obis_state == OBIS_ST_YIELD_IN_ALL) {
@ -740,7 +735,7 @@ bool sml_get_list_entries (uint16_t layer)
return sml_serial_len ? false : true; return sml_serial_len ? false : true;
} }
if (type != SML_TYPE_LIST) { if (type != SML_TYPE_LIST) {
sml_calc_obis_crc (entry_len, cur_serial_buf); sml_telegram_crc = sml_calc_crc (sml_telegram_crc, entry_len, cur_serial_buf);
sml_serial_len -= entry_len; sml_serial_len -= entry_len;
if (sml_serial_len) { if (sml_serial_len) {
cur_serial_buf += entry_len; cur_serial_buf += entry_len;
@ -796,8 +791,8 @@ uint16_t sml_parse_stream (uint16 len)
unsigned char *last_serial_buf = cur_serial_buf; unsigned char *last_serial_buf = cur_serial_buf;
if ((cur_serial_buf = (unsigned char *)memmem (cur_serial_buf, sml_serial_len, esc_seq, sizeof (esc_seq)))) { if ((cur_serial_buf = (unsigned char *)memmem (cur_serial_buf, sml_serial_len, esc_seq, sizeof (esc_seq)))) {
sml_init_obis_crc (); sml_telegram_crc = sml_init_crc ();
sml_calc_obis_crc (sizeof (esc_seq), cur_serial_buf); sml_telegram_crc = sml_calc_crc (sml_telegram_crc, sizeof (esc_seq), cur_serial_buf);
sml_serial_len -= cur_serial_buf - last_serial_buf; sml_serial_len -= cur_serial_buf - last_serial_buf;
sml_serial_len -= sizeof (esc_seq); sml_serial_len -= sizeof (esc_seq);
if (sml_serial_len) { if (sml_serial_len) {
@ -831,7 +826,7 @@ uint16_t sml_parse_stream (uint16 len)
case SML_ST_FIND_VERSION: case SML_ST_FIND_VERSION:
if (sml_serial_len >=sizeof (version_seq)) { if (sml_serial_len >=sizeof (version_seq)) {
if (!memcmp (cur_serial_buf, version_seq, sizeof (version_seq))) { if (!memcmp (cur_serial_buf, version_seq, sizeof (version_seq))) {
sml_calc_obis_crc (sizeof (version_seq), cur_serial_buf); sml_telegram_crc = sml_calc_crc (sml_telegram_crc, sizeof (version_seq), cur_serial_buf);
sml_state = SML_ST_FIND_MSG; sml_state = SML_ST_FIND_MSG;
#ifdef undef #ifdef undef
DPRINTLN(DBG_INFO, "VERSION, rest " + String (sml_serial_len - sizeof (version_seq))); DPRINTLN(DBG_INFO, "VERSION, rest " + String (sml_serial_len - sizeof (version_seq)));
@ -860,13 +855,14 @@ uint16_t sml_parse_stream (uint16 len)
sml_state = SML_ST_FIND_END_TAG; sml_state = SML_ST_FIND_END_TAG;
parse_continue = true; parse_continue = true;
} else if ((*cur_serial_buf & 0x70) == 0x70) { } else if ((*cur_serial_buf & 0x70) == 0x70) {
/* todo: extended list on 1st level */ /* todo: extended list on 1st level (does this happen in real life?) */
sml_calc_obis_crc (1, cur_serial_buf); sml_telegram_crc = sml_calc_crc (sml_telegram_crc, 1, cur_serial_buf);
#ifdef undef #ifdef undef
DPRINTLN (DBG_INFO, "TOPLIST 0x" + String(*cur_serial_buf, HEX) + ", rest " + String (sml_serial_len - 1)); DPRINTLN (DBG_INFO, "TOPLIST 0x" + String(*cur_serial_buf, HEX) + ", rest " + String (sml_serial_len - 1));
#endif #endif
sml_state = SML_ST_FIND_LIST_ENTRIES; sml_state = SML_ST_FIND_LIST_ENTRIES;
cur_sml_list_layer = 0; cur_sml_list_layer = 0;
sml_message = 0;
obis_state = OBIS_ST_NONE; obis_state = OBIS_ST_NONE;
sml_list_layer_entries[0] = *cur_serial_buf & 0xf; sml_list_layer_entries[0] = *cur_serial_buf & 0xf;
sml_serial_len--; sml_serial_len--;
@ -878,7 +874,7 @@ uint16_t sml_parse_stream (uint16 len)
} }
} else if (*cur_serial_buf == 0x00) { } else if (*cur_serial_buf == 0x00) {
/* fill byte (depends on the size of the telegram) */ /* fill byte (depends on the size of the telegram) */
sml_calc_obis_crc (1, cur_serial_buf); sml_telegram_crc = sml_calc_crc (sml_telegram_crc, 1, cur_serial_buf);
sml_serial_len--; sml_serial_len--;
if (sml_serial_len) { if (sml_serial_len) {
cur_serial_buf++; cur_serial_buf++;
@ -900,7 +896,7 @@ uint16_t sml_parse_stream (uint16 len)
if (sml_serial_len) { /* design: keep rcv buf small and skip irrelevant long list entries */ if (sml_serial_len) { /* design: keep rcv buf small and skip irrelevant long list entries */
size_t len = min (sml_serial_len, sml_skip_len); size_t len = min (sml_serial_len, sml_skip_len);
sml_calc_obis_crc (len, cur_serial_buf); sml_telegram_crc = sml_calc_crc (sml_telegram_crc, len, cur_serial_buf);
sml_serial_len -= len; sml_serial_len -= len;
if (sml_serial_len) { if (sml_serial_len) {
cur_serial_buf += len; cur_serial_buf += len;
@ -929,7 +925,7 @@ uint16_t sml_parse_stream (uint16 len)
case SML_ST_FIND_END_TAG: case SML_ST_FIND_END_TAG:
if (sml_serial_len >= sizeof (esc_seq)) { if (sml_serial_len >= sizeof (esc_seq)) {
if (!memcmp (cur_serial_buf, esc_seq, sizeof (esc_seq))) { if (!memcmp (cur_serial_buf, esc_seq, sizeof (esc_seq))) {
sml_calc_obis_crc (sizeof (esc_seq), cur_serial_buf); sml_telegram_crc = sml_calc_crc (sml_telegram_crc, sizeof (esc_seq), cur_serial_buf);
sml_state = SML_ST_CHECK_CRC; sml_state = SML_ST_CHECK_CRC;
} else { } else {
DPRINTLN(DBG_WARN, "Missing END_TAG, found 0x" + String (*cur_serial_buf) + DPRINTLN(DBG_WARN, "Missing END_TAG, found 0x" + String (*cur_serial_buf) +
@ -955,12 +951,13 @@ uint16_t sml_parse_stream (uint16 len)
if (*cur_serial_buf == 0x1a) { if (*cur_serial_buf == 0x1a) {
uint16_t calc_crc16, rcv_crc16; uint16_t calc_crc16, rcv_crc16;
sml_calc_obis_crc (2, cur_serial_buf); sml_telegram_crc = sml_calc_crc (sml_telegram_crc, 2, cur_serial_buf);
calc_crc16 = sml_finit_obis_crc (); calc_crc16 = sml_finit_crc (sml_telegram_crc);
rcv_crc16 = (*(cur_serial_buf+2) << 8) + *(cur_serial_buf+3); rcv_crc16 = (*(cur_serial_buf+2) << 8) + *(cur_serial_buf+3);
if (calc_crc16 == rcv_crc16) { if (calc_crc16 == rcv_crc16) {
obis_power_all_value = sml_obis_scale_int (obis_power_all_value, obis_power_all_scale); obis_power_all_value = sml_obis_scale_int (obis_power_all_value, obis_power_all_scale);
#ifdef undef #ifdef undef
// a bit more verbose info
obis_yield_in_all_value = sml_obis_scale_uint (obis_yield_in_all_value, obis_yield_in_all_scale); obis_yield_in_all_value = sml_obis_scale_uint (obis_yield_in_all_value, obis_yield_in_all_scale);
obis_yield_out_all_value = sml_obis_scale_uint (obis_yield_out_all_value, obis_yield_out_all_scale); obis_yield_out_all_value = sml_obis_scale_uint (obis_yield_out_all_value, obis_yield_out_all_scale);
DPRINTLN(DBG_INFO, "Power " + String (obis_power_all_value) + DPRINTLN(DBG_INFO, "Power " + String (obis_power_all_value) +

Loading…
Cancel
Save