sml special options descriptor

This commit is contained in:
gemu2015 2022-07-20 14:25:40 +02:00
parent 79161d3c43
commit de52580a18

View File

@ -78,6 +78,7 @@
#define DJ_VAVG "Volt_avg" #define DJ_VAVG "Volt_avg"
#define DJ_COUNTER "Count" #define DJ_COUNTER "Count"
struct METER_DESC { struct METER_DESC {
int8_t srcpin; int8_t srcpin;
uint8_t type; uint8_t type;
@ -91,8 +92,28 @@ struct METER_DESC {
uint8_t max_index; uint8_t max_index;
char *script_str; char *script_str;
uint8_t sopt; uint8_t sopt;
#ifdef USE_SML_SPECOPT
uint32_t so_obis1;
uint32_t so_obis2;
uint8_t so_fcode1;
uint8_t so_bpos1;
uint8_t so_fcode2;
uint8_t so_bpos2;
#endif
}; };
// max number of meters , may be adjusted
#ifndef MAX_METERS
#define MAX_METERS 5
#endif
#ifdef USE_SCRIPT
struct METER_DESC script_meter_desc[MAX_METERS];
uint8_t *script_meter;
#endif
// this descriptor method is no longer supported // this descriptor method is no longer supported
// but still functional for simple meters // but still functional for simple meters
// use scripting method instead // use scripting method instead
@ -480,10 +501,7 @@ const uint8_t meter[]=
#define SML_MAX_VARS 20 #define SML_MAX_VARS 20
#endif #endif
// max number of meters , may be adjusted
#ifndef MAX_METERS
#define MAX_METERS 5
#endif
double meter_vars[SML_MAX_VARS]; double meter_vars[SML_MAX_VARS];
// calulate deltas // calulate deltas
#define MAX_DVARS MAX_METERS*2 #define MAX_DVARS MAX_METERS*2
@ -1236,7 +1254,7 @@ void Hexdump(uint8_t *sbuff, uint32_t slen) {
AddLogData(LOG_LEVEL_INFO, cbuff); AddLogData(LOG_LEVEL_INFO, cbuff);
} }
#if defined(ED300L) || defined(AS2020) #if defined(ED300L) || defined(AS2020) || defined(DTZ541) || defined(USE_SML_SPECOPT)
uint8_t sml_status[MAX_METERS]; uint8_t sml_status[MAX_METERS];
uint8_t g_mindex; uint8_t g_mindex;
#endif #endif
@ -1293,6 +1311,46 @@ double dval;
sml_status[g_mindex]=*(cp+1); sml_status[g_mindex]=*(cp+1);
} }
#endif #endif
#ifdef DTZ541
unsigned char *cpx=cp-5;
// decode OBIS 0180 amd extract direction info
if (*cp==0x65 && *cpx==0 && *(cpx+1)==0x01 && *(cpx+2)==0x08 && *(cpx+3)==0) {
sml_status[g_mindex]=*(cp+3);
}
#endif
#ifdef USE_SML_SPECOPT
unsigned char *cpx = cp - 5;
uint32_t ocode = (*(cpx+0)<<24) | (*(cpx+1)<<16) | (*(cpx+2)<<8) | (*(cpx+3)<<0);
if (ocode == script_meter_desc[g_mindex].so_obis1) {
sml_status[g_mindex]&=0xfe;
uint32_t flag = 0;
uint16_t bytes = 0;
if (*cp == script_meter_desc[g_mindex].so_fcode1) {
cpx = cp + 1;
bytes = (script_meter_desc[g_mindex].so_fcode1 & 0xf) - 1;
for (uint16_t cnt = 0; cnt < bytes; cnt++) {
flag <<= 8;
flag |= *cpx++;
}
if (flag & (1 << script_meter_desc[g_mindex].so_bpos1)) {
sml_status[g_mindex]|=1;
}
}
if (*cp == script_meter_desc[g_mindex].so_fcode2) {
cpx = cp + 1;
bytes = (script_meter_desc[g_mindex].so_fcode2 & 0xf) - 1;
for (uint16_t cnt = 0; cnt < bytes; cnt++) {
flag <<= 8;
flag |= *cpx++;
}
if (flag & (1 << script_meter_desc[g_mindex].so_bpos1)) {
sml_status[g_mindex]|=1;
}
}
}
#endif
cp=skip_sml(cp,&result); cp=skip_sml(cp,&result);
// check time // check time
@ -1418,6 +1476,25 @@ double dval;
} }
} }
#endif #endif
#ifdef DTZ541
// decode current power OBIS 00 10 07 00
if (*cpx==0x00 && *(cpx+1)==0x10 && *(cpx+2)==0x07 && *(cpx+3)==0) {
if (sml_status[g_mindex]&0x08) {
// and invert sign on solar feed
dval*=-1;
}
}
#endif
#ifdef USE_SML_SPECOPT
ocode = (*(cpx+0)<<24) | (*(cpx+1)<<16) | (*(cpx+2)<<8) | (*(cpx+3)<<0);
if (ocode == script_meter_desc[g_mindex].so_obis2) {
if (sml_status[g_mindex] & 1) {
// and invert sign on solar feed
dval*=-1;
}
}
#endif
return dval; return dval;
} }
@ -1723,6 +1800,12 @@ void SML_Decode(uint8_t index) {
continue; continue;
} }
if (*mp == '=' && *(mp+1) == 's') {
mp = strchr(mp, '|');
if (mp) mp++;
continue;
}
// =d must handle dindex // =d must handle dindex
if (*mp == '=' && *(mp + 1) == 'd') { if (*mp == '=' && *(mp + 1) == 'd') {
if (index != mindex) { if (index != mindex) {
@ -1851,6 +1934,11 @@ void SML_Decode(uint8_t index) {
mp = strchr(mp, '|'); mp = strchr(mp, '|');
if (mp) mp++; if (mp) mp++;
continue; continue;
} else if (*mp == 's') {
// skip spec option tag line
mp = strchr(mp, '|');
if (mp) mp++;
continue;
} }
} else { } else {
// compare value // compare value
@ -2118,8 +2206,8 @@ void SML_Decode(uint8_t index) {
// matches, get value // matches, get value
dvalid[vindex] = 1; dvalid[vindex] = 1;
mp++; mp++;
#if defined(ED300L) || defined(AS2020) #if defined(ED300L) || defined(AS2020) || defined(DTZ541) || defined(USE_SML_SPECOPT)
g_mindex=mindex; g_mindex = mindex;
#endif #endif
if (*mp == '#') { if (*mp == '#') {
// get string value // get string value
@ -2333,6 +2421,11 @@ void SML_Show(boolean json) {
if (mp) mp++; if (mp) mp++;
continue; continue;
} }
if (*mp=='=' && *(mp+1)=='s') {
mp = strchr(mp, '|');
if (mp) mp++;
continue;
}
// skip compare section // skip compare section
cp=strchr(mp,'@'); cp=strchr(mp,'@');
if (cp) { if (cp) {
@ -2519,11 +2612,6 @@ uint32_t debounce_time;
} }
#ifdef USE_SCRIPT
struct METER_DESC script_meter_desc[MAX_METERS];
uint8_t *script_meter;
#endif
#ifndef METER_DEF_SIZE #ifndef METER_DEF_SIZE
#define METER_DEF_SIZE 3000 #define METER_DEF_SIZE 3000
#endif #endif
@ -2583,6 +2671,40 @@ bool Gpio_used(uint8_t gpiopin) {
return false; return false;
} }
#ifdef USE_SML_SPECOPT
void SML_GetSpecOpt(char *cp, uint32_t mnum) {
// special option 1
// we need 2 obis codes
// 2 flag codes + bit positions
// 1,=so1,00010800,63,7,64,11,00100700
if (*cp == ',') {
cp++;
script_meter_desc[mnum].so_obis1 = strtol(cp, &cp, 16);
}
if (*cp == ',') {
cp++;
script_meter_desc[mnum].so_fcode1 = strtol(cp, &cp, 16);
}
if (*cp == ',') {
cp++;
script_meter_desc[mnum].so_bpos1 = strtol(cp, &cp, 10);
}
if (*cp == ',') {
cp++;
script_meter_desc[mnum].so_fcode2 = strtol(cp, &cp, 16);
}
if (*cp == ',') {
cp++;
script_meter_desc[mnum].so_bpos2 = strtol(cp, &cp, 10);
}
if (*cp == ',') {
cp++;
script_meter_desc[mnum].so_obis2 = strtol(cp, &cp, 16);
}
}
#endif
void SML_Init(void) { void SML_Init(void) {
meters_used=METERS_USED; meters_used=METERS_USED;
meter_desc_p=meter_desc; meter_desc_p=meter_desc;
@ -2599,6 +2721,13 @@ void SML_Init(void) {
meter_spos[cnt]=0; meter_spos[cnt]=0;
} }
#ifdef USE_SML_SPECOPT
for (uint32_t cnt = 0; cnt < MAX_METERS; cnt++) {
script_meter_desc[cnt].so_obis1 = 0;
script_meter_desc[cnt].so_obis2 = 0;
}
#endif
#ifdef USE_SCRIPT #ifdef USE_SCRIPT
for (uint32_t cnt=0;cnt<MAX_METERS;cnt++) { for (uint32_t cnt=0;cnt<MAX_METERS;cnt++) {
@ -2818,6 +2947,16 @@ dddef_exit:
goto next_line; goto next_line;
} }
} }
#ifdef USE_SML_SPECOPT
if (!strncmp(lp1 + 1, ",=so", 4)) {
// special option
char *cp = lp1 + 5;
if (*cp == '1') {
cp++;
SML_GetSpecOpt(cp, mnum - 1);
}
}
#endif
while (1) { while (1) {
if (*lp1 == 0) { if (*lp1 == 0) {
*tp++ = '|'; *tp++ = '|';
@ -2846,7 +2985,16 @@ dddef_exit:
goto next_line; goto next_line;
} }
} }
#ifdef USE_SML_SPECOPT
if (!strncmp(lp + 1, ",=so", 4)) {
// special option
char *cp = lp + 5;
if (*cp == '1') {
cp++;
SML_GetSpecOpt(cp, mnum - 1);
}
}
#endif
while (1) { while (1) {
if (*lp == SCRIPT_EOL) { if (*lp == SCRIPT_EOL) {
if (*(tp-1) != '|') *tp++ = '|'; if (*(tp-1) != '|') *tp++ = '|';
@ -3047,7 +3195,7 @@ uint32_t SML_SetBaud(uint32_t meter, uint32_t br) {
uint32_t SML_Status(uint32_t meter) { uint32_t SML_Status(uint32_t meter) {
if (meter<1 || meter>meters_used) return 0; if (meter<1 || meter>meters_used) return 0;
meter--; meter--;
#if defined(ED300L) || defined(AS2020) #if defined(ED300L) || defined(AS2020) || defined(DTZ541) || defined(USE_SML_SPECOPT)
return sml_status[meter]; return sml_status[meter];
#else #else
return 0; return 0;
@ -3055,6 +3203,7 @@ uint32_t SML_Status(uint32_t meter) {
} }
uint32_t SML_Write(uint32_t meter,char *hstr) { uint32_t SML_Write(uint32_t meter,char *hstr) {
if (meter<1 || meter>meters_used) return 0; if (meter<1 || meter>meters_used) return 0;
meter--; meter--;