mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-24 19:26:37 +00:00
support for vbus
This commit is contained in:
parent
0855169c54
commit
16a30bd12e
@ -1208,7 +1208,7 @@ void sml_empty_receiver(uint32_t meters) {
|
|||||||
|
|
||||||
void sml_shift_in(uint32_t meters,uint32_t shard) {
|
void sml_shift_in(uint32_t meters,uint32_t shard) {
|
||||||
uint32_t count;
|
uint32_t count;
|
||||||
if (meter_desc_p[meters].type!='e' && meter_desc_p[meters].type!='m' && meter_desc_p[meters].type!='M' && meter_desc_p[meters].type!='p' && meter_desc_p[meters].type!='R') {
|
if (meter_desc_p[meters].type!='e' && meter_desc_p[meters].type!='m' && meter_desc_p[meters].type!='M' && meter_desc_p[meters].type!='p' && meter_desc_p[meters].type!='R' && meter_desc_p[meters].type!='v') {
|
||||||
// shift in
|
// shift in
|
||||||
for (count=0; count<SML_BSIZ-1; count++) {
|
for (count=0; count<SML_BSIZ-1; count++) {
|
||||||
smltbuf[meters][count]=smltbuf[meters][count+1];
|
smltbuf[meters][count]=smltbuf[meters][count+1];
|
||||||
@ -1251,6 +1251,17 @@ void sml_shift_in(uint32_t meters,uint32_t shard) {
|
|||||||
if (meter_spos[meters]>=SML_BSIZ) {
|
if (meter_spos[meters]>=SML_BSIZ) {
|
||||||
meter_spos[meters]=0;
|
meter_spos[meters]=0;
|
||||||
}
|
}
|
||||||
|
} else if (meter_desc_p[meters].type=='v') {
|
||||||
|
if (iob==EBUS_SYNC) {
|
||||||
|
SML_Decode(meters);
|
||||||
|
smltbuf[meters][0] = iob;
|
||||||
|
meter_spos[meters] = 1;
|
||||||
|
} else {
|
||||||
|
if (meter_spos[meters] < SML_BSIZ) {
|
||||||
|
smltbuf[meters][meter_spos[meters]] = iob;
|
||||||
|
meter_spos[meters]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (iob==EBUS_SYNC) {
|
if (iob==EBUS_SYNC) {
|
||||||
@ -1278,7 +1289,7 @@ void sml_shift_in(uint32_t meters,uint32_t shard) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
sb_counter++;
|
sb_counter++;
|
||||||
if (meter_desc_p[meters].type!='e' && meter_desc_p[meters].type!='m' && meter_desc_p[meters].type!='M' && meter_desc_p[meters].type!='p' && meter_desc_p[meters].type!='R') SML_Decode(meters);
|
if (meter_desc_p[meters].type!='e' && meter_desc_p[meters].type!='m' && meter_desc_p[meters].type!='M' && meter_desc_p[meters].type!='p' && meter_desc_p[meters].type!='R' && meter_desc_p[meters].type!='v') SML_Decode(meters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1297,6 +1308,33 @@ uint32_t meters;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define VBUS_BAD_CRC 0
|
||||||
|
// get vbus septet with 6 bytes
|
||||||
|
uint32_t vbus_get_septet(uint8_t *cp) {
|
||||||
|
uint32_t result = 0;
|
||||||
|
|
||||||
|
//AddLog(LOG_LEVEL_INFO,PSTR("septet: %02x %02x %02x %02x %02x %02x"),cp[0] ,cp[1],cp[2],cp[3],cp[4],cp[5]);
|
||||||
|
|
||||||
|
uint8_t Crc = 0x7F;
|
||||||
|
for (uint32_t i = 0; i < 5; i++) {
|
||||||
|
Crc = (Crc - cp[i]) & 0x7f;
|
||||||
|
}
|
||||||
|
if (Crc != cp[5]) {
|
||||||
|
result = VBUS_BAD_CRC;
|
||||||
|
} else {
|
||||||
|
result = (cp[3] | ((cp[4]&8)<<4));
|
||||||
|
result <<= 8;
|
||||||
|
result |= (cp[2] | ((cp[4]&4)<<5));
|
||||||
|
result <<= 8;
|
||||||
|
result |= (cp[1] | ((cp[4]&2)<<6));
|
||||||
|
result <<= 8;
|
||||||
|
result |= (cp[0] | ((cp[4]&1)<<7));
|
||||||
|
}
|
||||||
|
|
||||||
|
//AddLog(LOG_LEVEL_INFO,PSTR("septet r: %d"),result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void SML_Decode(uint8_t index) {
|
void SML_Decode(uint8_t index) {
|
||||||
const char *mp=(const char*)meter_p;
|
const char *mp=(const char*)meter_p;
|
||||||
@ -1342,7 +1380,7 @@ void SML_Decode(uint8_t index) {
|
|||||||
while (*mp>='0' && *mp<='9') mp++;
|
while (*mp>='0' && *mp<='9') mp++;
|
||||||
if (ind<1 || ind>SML_MAX_VARS) ind=1;
|
if (ind<1 || ind>SML_MAX_VARS) ind=1;
|
||||||
dvar=meter_vars[ind-1];
|
dvar=meter_vars[ind-1];
|
||||||
for (uint8_t p=0;p<5;p++) {
|
for (uint8_t p = 0; p < 5; p++) {
|
||||||
if (*mp=='@') {
|
if (*mp=='@') {
|
||||||
// store result
|
// store result
|
||||||
meter_vars[vindex]=dvar;
|
meter_vars[vindex]=dvar;
|
||||||
@ -1438,12 +1476,20 @@ void SML_Decode(uint8_t index) {
|
|||||||
found=0;
|
found=0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// ebus mbus pzem or raw
|
// ebus mbus pzem vbus or raw
|
||||||
// XXHHHHSSUU
|
// XXHHHHSSUU
|
||||||
if (*mp=='x' && *(mp+1)=='x') {
|
if (*mp=='x') {
|
||||||
//ignore
|
if (*(mp+1)=='x') {
|
||||||
mp+=2;
|
//ignore one byte
|
||||||
cp++;
|
mp += 2;
|
||||||
|
cp++;
|
||||||
|
} else {
|
||||||
|
mp++;
|
||||||
|
if (isdigit(*mp)) {
|
||||||
|
uint8_t skip = strtol((char*)mp, (char**)&mp, 10);
|
||||||
|
cp += skip;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else if (!strncmp(mp,"UUuuUUuu",8)) {
|
} else if (!strncmp(mp,"UUuuUUuu",8)) {
|
||||||
uint32_t val= (cp[0]<<24)|(cp[1]<<16)|(cp[2]<<8)|(cp[3]<<0);
|
uint32_t val= (cp[0]<<24)|(cp[1]<<16)|(cp[2]<<8)|(cp[3]<<0);
|
||||||
ebus_dval=val;
|
ebus_dval=val;
|
||||||
@ -1530,6 +1576,99 @@ void SML_Decode(uint8_t index) {
|
|||||||
mp+=4;
|
mp+=4;
|
||||||
cp+=2;
|
cp+=2;
|
||||||
}
|
}
|
||||||
|
else if (*mp == 'v') {
|
||||||
|
// vbus values vul, vsl, vuwh, vuwl, wswh, vswl, vswh
|
||||||
|
// vub3, vsb3 etc
|
||||||
|
mp++;
|
||||||
|
int16_t offset = -1;
|
||||||
|
if (*mp == 'o') {
|
||||||
|
mp++;
|
||||||
|
offset = strtol((char*)mp, (char**)&mp, 10);
|
||||||
|
cp += (offset / 4) * 6;
|
||||||
|
}
|
||||||
|
uint8_t usign;
|
||||||
|
if (*mp == 'u') {
|
||||||
|
usign = 1;
|
||||||
|
} else if (*mp == 's') {
|
||||||
|
usign = 0;
|
||||||
|
}
|
||||||
|
mp++;
|
||||||
|
switch (*mp) {
|
||||||
|
case 'l':
|
||||||
|
mp++;
|
||||||
|
// get long value
|
||||||
|
if (usign) {
|
||||||
|
ebus_dval = vbus_get_septet(cp);
|
||||||
|
} else {
|
||||||
|
ebus_dval = (int32_t)vbus_get_septet(cp);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'w':
|
||||||
|
mp++;
|
||||||
|
char wflg;
|
||||||
|
if (offset >= 0) {
|
||||||
|
if (offset % 4) {
|
||||||
|
wflg = 'h';
|
||||||
|
} else {
|
||||||
|
wflg = 'l';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
wflg = *mp;
|
||||||
|
mp++;
|
||||||
|
}
|
||||||
|
// get word value
|
||||||
|
if (wflg == 'h') {
|
||||||
|
// high word
|
||||||
|
if (usign) ebus_dval = (vbus_get_septet(cp) >> 16) & 0xffff;
|
||||||
|
else ebus_dval = (int16_t)((vbus_get_septet(cp) >> 16) & 0xffff);
|
||||||
|
} else {
|
||||||
|
// low word
|
||||||
|
if (usign) ebus_dval = vbus_get_septet(cp) & 0xffff;
|
||||||
|
else (int16_t)(vbus_get_septet(cp) & 0xffff);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'b':
|
||||||
|
mp++;
|
||||||
|
char bflg;
|
||||||
|
if (offset >= 0) {
|
||||||
|
bflg = 0x30 | (offset % 4);
|
||||||
|
} else {
|
||||||
|
bflg = *mp;
|
||||||
|
mp++;
|
||||||
|
}
|
||||||
|
switch (bflg) {
|
||||||
|
case '3':
|
||||||
|
if (usign) ebus_dval = vbus_get_septet(cp) >> 24;
|
||||||
|
else ebus_dval = (int8_t)(vbus_get_septet(cp) >> 24);
|
||||||
|
break;
|
||||||
|
case '2':
|
||||||
|
if (usign) ebus_dval = (vbus_get_septet(cp) >> 16) & 0xff;
|
||||||
|
else ebus_dval = (int8_t)((vbus_get_septet(cp) >> 16) & 0xff);
|
||||||
|
break;
|
||||||
|
case '1':
|
||||||
|
if (usign) ebus_dval = (vbus_get_septet(cp) >> 8) & 0xff;
|
||||||
|
else ebus_dval = (int8_t)((vbus_get_septet(cp) >> 8) & 0xff);
|
||||||
|
break;
|
||||||
|
case '0':
|
||||||
|
if (usign) ebus_dval = vbus_get_septet(cp) & 0xff;
|
||||||
|
else ebus_dval = (int8_t)(vbus_get_septet(cp) & 0xff);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
mp++;
|
||||||
|
{ uint16_t time;
|
||||||
|
if (offset % 4) {
|
||||||
|
time = (vbus_get_septet(cp) >> 16) & 0xffff;
|
||||||
|
} else {
|
||||||
|
time = vbus_get_septet(cp) & 0xffff;
|
||||||
|
}
|
||||||
|
sprintf(&meter_id[mindex][0], "%02d:%02d", time / 60, time % 60);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
cp += 6;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
uint8_t val = hexnibble(*mp++) << 4;
|
uint8_t val = hexnibble(*mp++) << 4;
|
||||||
val |= hexnibble(*mp++);
|
val |= hexnibble(*mp++);
|
||||||
@ -1550,21 +1689,23 @@ void SML_Decode(uint8_t index) {
|
|||||||
// get string value
|
// get string value
|
||||||
getstr:
|
getstr:
|
||||||
mp++;
|
mp++;
|
||||||
if (meter_desc_p[mindex].type == 'o') {
|
if (meter_desc_p[mindex].type != 'v') {
|
||||||
uint32_t p;
|
if (meter_desc_p[mindex].type == 'o') {
|
||||||
for (p = 0; p < METER_ID_SIZE - 2; p++) {
|
uint32_t p;
|
||||||
if (*cp == *mp) {
|
for (p = 0; p < METER_ID_SIZE - 2; p++) {
|
||||||
break;
|
if (*cp == *mp) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
meter_id[mindex][p] = *cp++;
|
||||||
}
|
}
|
||||||
meter_id[mindex][p] = *cp++;
|
meter_id[mindex][p] = 0;
|
||||||
|
} else {
|
||||||
|
sml_getvalue(cp,mindex);
|
||||||
}
|
}
|
||||||
meter_id[mindex][p] = 0;
|
|
||||||
} else {
|
|
||||||
sml_getvalue(cp,mindex);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
double dval;
|
double dval;
|
||||||
if (meter_desc_p[mindex].type!='e' && meter_desc_p[mindex].type!='r' && meter_desc_p[mindex].type!='m' && meter_desc_p[mindex].type!='M' && meter_desc_p[mindex].type!='p') {
|
if (meter_desc_p[mindex].type!='e' && meter_desc_p[mindex].type!='r' && meter_desc_p[mindex].type!='m' && meter_desc_p[mindex].type!='M' && meter_desc_p[mindex].type!='p' && meter_desc_p[mindex].type!='v') {
|
||||||
// get numeric values
|
// get numeric values
|
||||||
if (meter_desc_p[mindex].type=='o' || meter_desc_p[mindex].type=='c') {
|
if (meter_desc_p[mindex].type=='o' || meter_desc_p[mindex].type=='c') {
|
||||||
if (*mp == '(') {
|
if (*mp == '(') {
|
||||||
@ -1596,7 +1737,7 @@ void SML_Decode(uint8_t index) {
|
|||||||
dval = sml_getvalue(cp,mindex);
|
dval = sml_getvalue(cp,mindex);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// ebus pzem or mbus or raw
|
// ebus pzem vbus or mbus or raw
|
||||||
if (*mp=='b') {
|
if (*mp=='b') {
|
||||||
mp++;
|
mp++;
|
||||||
uint8_t shift = *mp&7;
|
uint8_t shift = *mp&7;
|
||||||
@ -1639,15 +1780,16 @@ void SML_Decode(uint8_t index) {
|
|||||||
#else
|
#else
|
||||||
meter_vars[vindex]=dval;
|
meter_vars[vindex]=dval;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//AddLog_P(LOG_LEVEL_INFO, PSTR(">> %s"),mp);
|
//AddLog_P(LOG_LEVEL_INFO, PSTR(">> %s"),mp);
|
||||||
// get scaling factor
|
// get scaling factor
|
||||||
double fac=CharToDouble((char*)mp);
|
double fac=CharToDouble((char*)mp);
|
||||||
meter_vars[vindex]/=fac;
|
meter_vars[vindex]/=fac;
|
||||||
SML_Immediate_MQTT((const char*)mp,vindex,mindex);
|
SML_Immediate_MQTT((const char*)mp,vindex,mindex);
|
||||||
}
|
}
|
||||||
dvalid[vindex] = 1;
|
|
||||||
}
|
}
|
||||||
|
dvalid[vindex] = 1;
|
||||||
|
//AddLog(LOG_LEVEL_INFO, PSTR("set valid in line %d"), vindex);
|
||||||
}
|
}
|
||||||
nextsect:
|
nextsect:
|
||||||
// next section
|
// next section
|
||||||
@ -1809,9 +1951,11 @@ void SML_Show(boolean json) {
|
|||||||
dtostrfd(meter_vars[index],dp,tpowstr);
|
dtostrfd(meter_vars[index],dp,tpowstr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!dvalid[index]) nojson = 1;
|
|
||||||
|
|
||||||
if (json) {
|
if (json) {
|
||||||
|
if (!dvalid[index]) {
|
||||||
|
nojson = 1;
|
||||||
|
//AddLog(LOG_LEVEL_INFO, PSTR("not yet valid line %d"), index);
|
||||||
|
}
|
||||||
// json export
|
// json export
|
||||||
if (index==0) {
|
if (index==0) {
|
||||||
//snprintf_P(b_mqtt_data, sizeof(b_mqtt_data), "%s,\"%s\":{\"%s\":%s", b_mqtt_data,meter_desc_p[mindex].prefix,jname,tpowstr);
|
//snprintf_P(b_mqtt_data, sizeof(b_mqtt_data), "%s,\"%s\":{\"%s\":%s", b_mqtt_data,meter_desc_p[mindex].prefix,jname,tpowstr);
|
||||||
@ -2248,7 +2392,7 @@ init10:
|
|||||||
} else {
|
} else {
|
||||||
// serial input, init
|
// serial input, init
|
||||||
#ifdef SPECIAL_SS
|
#ifdef SPECIAL_SS
|
||||||
if (meter_desc_p[meters].type=='m' || meter_desc_p[meters].type=='M' || meter_desc_p[meters].type=='p' || meter_desc_p[meters].type=='R') {
|
if (meter_desc_p[meters].type=='m' || meter_desc_p[meters].type=='M' || meter_desc_p[meters].type=='p' || meter_desc_p[meters].type=='R' || meter_desc_p[meters].type=='v') {
|
||||||
meter_ss[meters] = new TasmotaSerial(meter_desc_p[meters].srcpin,meter_desc_p[meters].trxpin,1,0,TMSBSIZ);
|
meter_ss[meters] = new TasmotaSerial(meter_desc_p[meters].srcpin,meter_desc_p[meters].trxpin,1,0,TMSBSIZ);
|
||||||
} else {
|
} else {
|
||||||
meter_ss[meters] = new TasmotaSerial(meter_desc_p[meters].srcpin,meter_desc_p[meters].trxpin,1,1,TMSBSIZ);
|
meter_ss[meters] = new TasmotaSerial(meter_desc_p[meters].srcpin,meter_desc_p[meters].trxpin,1,1,TMSBSIZ);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user