mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-23 18:56:38 +00:00
sml special options descriptor
This commit is contained in:
parent
79161d3c43
commit
de52580a18
@ -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--;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user