mirror of https://github.com/arendst/Tasmota.git
commit
3470e458cd
|
@ -140,6 +140,11 @@ struct METER_DESC {
|
||||||
uint16_t flag;
|
uint16_t flag;
|
||||||
int32_t params;
|
int32_t params;
|
||||||
char prefix[8];
|
char prefix[8];
|
||||||
|
int8_t trxpin;
|
||||||
|
uint8_t tsecs;
|
||||||
|
char *txmem;
|
||||||
|
uint8_t index;
|
||||||
|
uint8_t max_index;
|
||||||
};
|
};
|
||||||
|
|
||||||
// meter list , enter new meters here
|
// meter list , enter new meters here
|
||||||
|
@ -167,7 +172,7 @@ struct METER_DESC {
|
||||||
#undef METERS_USED
|
#undef METERS_USED
|
||||||
#define METERS_USED 1
|
#define METERS_USED 1
|
||||||
struct METER_DESC const meter_desc[METERS_USED]={
|
struct METER_DESC const meter_desc[METERS_USED]={
|
||||||
[0]={3,'o',0,SML_BAUDRATE,"OBIS"}};
|
[0]={3,'o',0,SML_BAUDRATE,"OBIS",-1,1,0}};
|
||||||
const uint8_t meter[]=
|
const uint8_t meter[]=
|
||||||
"1,1-0:1.8.0*255(@1," D_TPWRIN ",KWh," DJ_TPWRIN ",4|"
|
"1,1-0:1.8.0*255(@1," D_TPWRIN ",KWh," DJ_TPWRIN ",4|"
|
||||||
"1,1-0:2.8.0*255(@1," D_TPWROUT ",KWh," DJ_TPWROUT ",4|"
|
"1,1-0:2.8.0*255(@1," D_TPWROUT ",KWh," DJ_TPWROUT ",4|"
|
||||||
|
@ -185,7 +190,7 @@ const uint8_t meter[]=
|
||||||
#undef METERS_USED
|
#undef METERS_USED
|
||||||
#define METERS_USED 1
|
#define METERS_USED 1
|
||||||
struct METER_DESC const meter_desc[METERS_USED]={
|
struct METER_DESC const meter_desc[METERS_USED]={
|
||||||
[0]={3,'o',0,SML_BAUDRATE,"OBIS"}};
|
[0]={3,'o',0,SML_BAUDRATE,"OBIS",-1,1,0}};
|
||||||
const uint8_t meter[]=
|
const uint8_t meter[]=
|
||||||
"1,1-0:1.8.1*255(@1," D_TPWRIN ",KWh," DJ_TPWRIN ",4|"
|
"1,1-0:1.8.1*255(@1," D_TPWRIN ",KWh," DJ_TPWRIN ",4|"
|
||||||
"1,1-0:2.8.1*255(@1," D_TPWROUT ",KWh," DJ_TPWROUT ",4|"
|
"1,1-0:2.8.1*255(@1," D_TPWROUT ",KWh," DJ_TPWROUT ",4|"
|
||||||
|
@ -199,7 +204,7 @@ const uint8_t meter[]=
|
||||||
#undef METERS_USED
|
#undef METERS_USED
|
||||||
#define METERS_USED 1
|
#define METERS_USED 1
|
||||||
struct METER_DESC const meter_desc[METERS_USED]={
|
struct METER_DESC const meter_desc[METERS_USED]={
|
||||||
[0]={3,'s',0,SML_BAUDRATE,"SML"}};
|
[0]={3,'s',0,SML_BAUDRATE,"SML",-1,1,0}};
|
||||||
// 2 Richtungszähler EHZ SML 8 bit 9600 baud, binär
|
// 2 Richtungszähler EHZ SML 8 bit 9600 baud, binär
|
||||||
const uint8_t meter[]=
|
const uint8_t meter[]=
|
||||||
//0x77,0x07,0x01,0x00,0x01,0x08,0x00,0xff
|
//0x77,0x07,0x01,0x00,0x01,0x08,0x00,0xff
|
||||||
|
@ -218,7 +223,7 @@ const uint8_t meter[]=
|
||||||
#undef METERS_USED
|
#undef METERS_USED
|
||||||
#define METERS_USED 1
|
#define METERS_USED 1
|
||||||
struct METER_DESC const meter_desc[METERS_USED]={
|
struct METER_DESC const meter_desc[METERS_USED]={
|
||||||
[0]={3,'s',0,SML_BAUDRATE,"SML"}};
|
[0]={3,'s',0,SML_BAUDRATE,"SML",-1,1,0}};
|
||||||
// 2 Richtungszähler EHZ SML 8 bit 9600 baud, binär
|
// 2 Richtungszähler EHZ SML 8 bit 9600 baud, binär
|
||||||
// verbrauch total
|
// verbrauch total
|
||||||
const uint8_t meter[]=
|
const uint8_t meter[]=
|
||||||
|
@ -236,7 +241,7 @@ const uint8_t meter[]=
|
||||||
#undef METERS_USED
|
#undef METERS_USED
|
||||||
#define METERS_USED 1
|
#define METERS_USED 1
|
||||||
struct METER_DESC const meter_desc[METERS_USED]={
|
struct METER_DESC const meter_desc[METERS_USED]={
|
||||||
[0]={3,'s',0,SML_BAUDRATE,"SML"}};
|
[0]={3,'s',0,SML_BAUDRATE,"SML",-1,1,0}};
|
||||||
// 2 Richtungszähler EHZ SML 8 bit 9600 baud, binär
|
// 2 Richtungszähler EHZ SML 8 bit 9600 baud, binär
|
||||||
// verbrauch total
|
// verbrauch total
|
||||||
const uint8_t meter[]=
|
const uint8_t meter[]=
|
||||||
|
@ -252,7 +257,7 @@ const uint8_t meter[]=
|
||||||
#undef METERS_USED
|
#undef METERS_USED
|
||||||
#define METERS_USED 1
|
#define METERS_USED 1
|
||||||
struct METER_DESC const meter_desc[METERS_USED]={
|
struct METER_DESC const meter_desc[METERS_USED]={
|
||||||
[0]={3,'s',0,SML_BAUDRATE,"strom"}};
|
[0]={3,'s',0,SML_BAUDRATE,"strom",-1,1,0}};
|
||||||
const uint8_t meter[]=
|
const uint8_t meter[]=
|
||||||
//0x77,0x07,0x01,0x00,0x01,0x08,0x00,0xff
|
//0x77,0x07,0x01,0x00,0x01,0x08,0x00,0xff
|
||||||
"1,77070100010800ff@1000," D_TPWRIN ",KWh," DJ_TPWRIN ",4|"
|
"1,77070100010800ff@1000," D_TPWRIN ",KWh," DJ_TPWRIN ",4|"
|
||||||
|
@ -275,7 +280,7 @@ const uint8_t meter[]=
|
||||||
#undef METERS_USED
|
#undef METERS_USED
|
||||||
#define METERS_USED 1
|
#define METERS_USED 1
|
||||||
struct METER_DESC const meter_desc[METERS_USED]={
|
struct METER_DESC const meter_desc[METERS_USED]={
|
||||||
[0]={3,'s',0,SML_BAUDRATE,"SML"}};
|
[0]={3,'s',0,SML_BAUDRATE,"SML",-1,1,0}};
|
||||||
const uint8_t meter[]=
|
const uint8_t meter[]=
|
||||||
//0x77,0x07,0x01,0x00,0x01,0x08,0x01,0xff
|
//0x77,0x07,0x01,0x00,0x01,0x08,0x01,0xff
|
||||||
"1,77070100010800ff@1000," D_TPWRIN ",KWh," DJ_TPWRIN ",4|"
|
"1,77070100010800ff@1000," D_TPWRIN ",KWh," DJ_TPWRIN ",4|"
|
||||||
|
@ -291,9 +296,9 @@ const uint8_t meter[]=
|
||||||
#define METERS_USED 3
|
#define METERS_USED 3
|
||||||
|
|
||||||
struct METER_DESC const meter_desc[METERS_USED]={
|
struct METER_DESC const meter_desc[METERS_USED]={
|
||||||
[0]={3,'o',0,SML_BAUDRATE,"OBIS"}, // harware serial RX pin
|
[0]={3,'o',0,SML_BAUDRATE,"OBIS",-1,1,0}, // harware serial RX pin
|
||||||
[1]={14,'s',0,SML_BAUDRATE,"SML"}, // GPIO14 software serial
|
[1]={14,'s',0,SML_BAUDRATE,"SML",-1,1,0}, // GPIO14 software serial
|
||||||
[2]={4,'o',0,SML_BAUDRATE,"OBIS2"}}; // GPIO4 software serial
|
[2]={4,'o',0,SML_BAUDRATE,"OBIS2",-1,1,0}}; // GPIO4 software serial
|
||||||
|
|
||||||
// 3 Zähler definiert
|
// 3 Zähler definiert
|
||||||
const uint8_t meter[]=
|
const uint8_t meter[]=
|
||||||
|
@ -320,8 +325,8 @@ const uint8_t meter[]=
|
||||||
#define METERS_USED 2
|
#define METERS_USED 2
|
||||||
|
|
||||||
struct METER_DESC const meter_desc[METERS_USED]={
|
struct METER_DESC const meter_desc[METERS_USED]={
|
||||||
[0]={3,'o',0,SML_BAUDRATE,"OBIS1"}, // harware serial RX pin
|
[0]={3,'o',0,SML_BAUDRATE,"OBIS1",-1,1,0}, // harware serial RX pin
|
||||||
[1]={14,'o',0,SML_BAUDRATE,"OBIS2"}}; // GPIO14 software serial
|
[1]={14,'o',0,SML_BAUDRATE,"OBIS2",-1,1,0}}; // GPIO14 software serial
|
||||||
|
|
||||||
// 2 Zähler definiert
|
// 2 Zähler definiert
|
||||||
const uint8_t meter[]=
|
const uint8_t meter[]=
|
||||||
|
@ -342,9 +347,9 @@ const uint8_t meter[]=
|
||||||
#define METERS_USED 3
|
#define METERS_USED 3
|
||||||
|
|
||||||
struct METER_DESC const meter_desc[METERS_USED]={
|
struct METER_DESC const meter_desc[METERS_USED]={
|
||||||
[0]={3,'o',0,SML_BAUDRATE,"OBIS1"}, // harware serial RX pin
|
[0]={3,'o',0,SML_BAUDRATE,"OBIS1",-1,1,0}, // harware serial RX pin
|
||||||
[1]={14,'o',0,SML_BAUDRATE,"OBIS2"},
|
[1]={14,'o',0,SML_BAUDRATE,"OBIS2",-1,1,0},
|
||||||
[2]={1,'o',0,SML_BAUDRATE,"OBIS3"}};
|
[2]={1,'o',0,SML_BAUDRATE,"OBIS3",-1,1,0}};
|
||||||
|
|
||||||
// 3 Zähler definiert
|
// 3 Zähler definiert
|
||||||
const uint8_t meter[]=
|
const uint8_t meter[]=
|
||||||
|
@ -372,7 +377,7 @@ const uint8_t meter[]=
|
||||||
#undef METERS_USED
|
#undef METERS_USED
|
||||||
#define METERS_USED 1
|
#define METERS_USED 1
|
||||||
struct METER_DESC const meter_desc[METERS_USED]={
|
struct METER_DESC const meter_desc[METERS_USED]={
|
||||||
[0]={3,'o',0,SML_BAUDRATE,"OBIS"}};
|
[0]={3,'o',0,SML_BAUDRATE,"OBIS",-1,1,0}};
|
||||||
const uint8_t meter[]=
|
const uint8_t meter[]=
|
||||||
"1,1-0:1.8.1*255(@1," D_TPWRIN ",KWh," DJ_TPWRIN ",4|"
|
"1,1-0:1.8.1*255(@1," D_TPWRIN ",KWh," DJ_TPWRIN ",4|"
|
||||||
"1,=d 1 10 @1," D_TPWRCURR ",W," DJ_TPWRCURR ",0|"
|
"1,=d 1 10 @1," D_TPWRCURR ",W," DJ_TPWRCURR ",0|"
|
||||||
|
@ -385,7 +390,7 @@ const uint8_t meter[]=
|
||||||
#undef METERS_USED
|
#undef METERS_USED
|
||||||
#define METERS_USED 1
|
#define METERS_USED 1
|
||||||
struct METER_DESC const meter_desc[METERS_USED]={
|
struct METER_DESC const meter_desc[METERS_USED]={
|
||||||
[0]={3,'s',0,SML_BAUDRATE,"SML"}};
|
[0]={3,'s',0,SML_BAUDRATE,"SML",-1,1,0}};
|
||||||
// 2 Richtungszähler EHZ SML 8 bit 9600 baud, binär
|
// 2 Richtungszähler EHZ SML 8 bit 9600 baud, binär
|
||||||
const uint8_t meter[]=
|
const uint8_t meter[]=
|
||||||
//0x77,0x07,0x01,0x00,0x01,0x08,0x00,0xff
|
//0x77,0x07,0x01,0x00,0x01,0x08,0x00,0xff
|
||||||
|
@ -407,7 +412,7 @@ const uint8_t meter[]=
|
||||||
#undef METERS_USED
|
#undef METERS_USED
|
||||||
#define METERS_USED 3
|
#define METERS_USED 3
|
||||||
struct METER_DESC const meter_desc[METERS_USED]={
|
struct METER_DESC const meter_desc[METERS_USED]={
|
||||||
[0]={3,'o',0,SML_BAUDRATE,"OBIS"}, // harware serial RX pin
|
[0]={3,'o',0,SML_BAUDRATE,"OBIS",-1,1,0}, // harware serial RX pin
|
||||||
[1]={14,'c',0,50,"Gas"}, // GPIO14 gas counter
|
[1]={14,'c',0,50,"Gas"}, // GPIO14 gas counter
|
||||||
[2]={1,'c',0,10,"Wasser"}}; // water counter
|
[2]={1,'c',0,10,"Wasser"}}; // water counter
|
||||||
|
|
||||||
|
@ -430,9 +435,9 @@ const uint8_t meter[]=
|
||||||
#define METERS_USED 3
|
#define METERS_USED 3
|
||||||
|
|
||||||
struct METER_DESC const meter_desc[METERS_USED]={
|
struct METER_DESC const meter_desc[METERS_USED]={
|
||||||
[0]={1,'c',0,10,"H20"}, // GPIO1 Wasser Zähler
|
[0]={1,'c',0,10,"H20",-1,1,0}, // GPIO1 Wasser Zähler
|
||||||
[1]={4,'c',0,50,"GAS"}, // GPIO4 gas Zähler
|
[1]={4,'c',0,50,"GAS",-1,1,0}, // GPIO4 gas Zähler
|
||||||
[2]={3,'s',0,SML_BAUDRATE,"SML"}}; // SML harware serial RX pin
|
[2]={3,'s',0,SML_BAUDRATE,"SML",-1,1,0}}; // SML harware serial RX pin
|
||||||
|
|
||||||
const uint8_t meter[]=
|
const uint8_t meter[]=
|
||||||
//----------------------------Wasserzähler--sensor53 c1------------------------------------
|
//----------------------------Wasserzähler--sensor53 c1------------------------------------
|
||||||
|
@ -516,7 +521,7 @@ char meter_id[MAX_METERS][METER_ID_SIZE];
|
||||||
#define EBUS_SYNC 0xaa
|
#define EBUS_SYNC 0xaa
|
||||||
#define EBUS_ESC 0xa9
|
#define EBUS_ESC 0xa9
|
||||||
uint8_t ebus_pos;
|
uint8_t ebus_pos;
|
||||||
|
uint8_t mbus_pos;
|
||||||
|
|
||||||
#ifdef USE_MEDIAN_FILTER
|
#ifdef USE_MEDIAN_FILTER
|
||||||
// median filter, should be odd size
|
// median filter, should be odd size
|
||||||
|
@ -786,33 +791,21 @@ uint8_t dump2log=0;
|
||||||
|
|
||||||
bool Serial_available() {
|
bool Serial_available() {
|
||||||
uint8_t num=dump2log&7;
|
uint8_t num=dump2log&7;
|
||||||
if (num<1 || num>meters_used) return Serial.available();
|
if (num<1 || num>meters_used) num=1;
|
||||||
if (num==1) {
|
|
||||||
return Serial.available();
|
|
||||||
} else {
|
|
||||||
return meter_ss[num-1]->available();
|
return meter_ss[num-1]->available();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t Serial_read() {
|
uint8_t Serial_read() {
|
||||||
uint8_t num=dump2log&7;
|
uint8_t num=dump2log&7;
|
||||||
if (num<1 || num>meters_used) return Serial.read();
|
if (num<1 || num>meters_used) num=1;
|
||||||
if (num==1) {
|
|
||||||
return Serial.read();
|
|
||||||
} else {
|
|
||||||
return meter_ss[num-1]->read();
|
return meter_ss[num-1]->read();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t Serial_peek() {
|
uint8_t Serial_peek() {
|
||||||
uint8_t num=dump2log&7;
|
uint8_t num=dump2log&7;
|
||||||
if (num<1 || num>meters_used) return Serial.peek();
|
if (num<1 || num>meters_used) num=1;
|
||||||
if (num==1) {
|
|
||||||
return Serial.peek();
|
|
||||||
} else {
|
|
||||||
return meter_ss[num-1]->peek();
|
return meter_ss[num-1]->peek();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void Dump2log(void) {
|
void Dump2log(void) {
|
||||||
|
|
||||||
|
@ -1154,15 +1147,13 @@ uint8_t ebus_CalculateCRC( uint8_t *Data, uint16_t DataLen ) {
|
||||||
|
|
||||||
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') {
|
if (meter_desc_p[meters].type!='e' && meter_desc_p[meters].type!='m') {
|
||||||
// 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];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
uint8_t iob;
|
uint8_t iob=(uint8_t)meter_ss[meters]->read();
|
||||||
if (shard) iob=(uint8_t)Serial.read();
|
|
||||||
else iob=(uint8_t)meter_ss[meters]->read();
|
|
||||||
|
|
||||||
if (meter_desc_p[meters].type=='o') {
|
if (meter_desc_p[meters].type=='o') {
|
||||||
smltbuf[meters][SML_BSIZ-1]=iob&0x7f;
|
smltbuf[meters][SML_BSIZ-1]=iob&0x7f;
|
||||||
|
@ -1170,6 +1161,13 @@ void sml_shift_in(uint32_t meters,uint32_t shard) {
|
||||||
smltbuf[meters][SML_BSIZ-1]=iob;
|
smltbuf[meters][SML_BSIZ-1]=iob;
|
||||||
} else if (meter_desc_p[meters].type=='r') {
|
} else if (meter_desc_p[meters].type=='r') {
|
||||||
smltbuf[meters][SML_BSIZ-1]=iob;
|
smltbuf[meters][SML_BSIZ-1]=iob;
|
||||||
|
} else if (meter_desc_p[meters].type=='m') {
|
||||||
|
smltbuf[meters][mbus_pos] = iob;
|
||||||
|
mbus_pos++;
|
||||||
|
if (mbus_pos>=9) {
|
||||||
|
SML_Decode(meters);
|
||||||
|
mbus_pos=0;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (iob==EBUS_SYNC) {
|
if (iob==EBUS_SYNC) {
|
||||||
// should be end of telegramm
|
// should be end of telegramm
|
||||||
|
@ -1200,7 +1198,7 @@ void sml_shift_in(uint32_t meters,uint32_t shard) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sb_counter++;
|
sb_counter++;
|
||||||
if (meter_desc_p[meters].type!='e') SML_Decode(meters);
|
if (meter_desc_p[meters].type!='e' && meter_desc_p[meters].type!='m') SML_Decode(meters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1211,18 +1209,12 @@ uint32_t meters;
|
||||||
for (meters=0; meters<meters_used; meters++) {
|
for (meters=0; meters<meters_used; meters++) {
|
||||||
if (meter_desc_p[meters].type!='c') {
|
if (meter_desc_p[meters].type!='c') {
|
||||||
// poll for serial input
|
// poll for serial input
|
||||||
if (meter_desc_p[meters].srcpin==3) {
|
|
||||||
while (Serial.available()) {
|
|
||||||
sml_shift_in(meters,1);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
while (meter_ss[meters]->available()) {
|
while (meter_ss[meters]->available()) {
|
||||||
sml_shift_in(meters,0);
|
sml_shift_in(meters,0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void SML_Decode(uint8_t index) {
|
void SML_Decode(uint8_t index) {
|
||||||
|
@ -1348,7 +1340,8 @@ void SML_Decode(uint8_t index) {
|
||||||
} else {
|
} else {
|
||||||
// compare value
|
// compare value
|
||||||
uint8_t found=1;
|
uint8_t found=1;
|
||||||
int32_t ebus_dval=99;
|
uint32_t ebus_dval=99;
|
||||||
|
float mbus_dval=99;
|
||||||
while (*mp!='@') {
|
while (*mp!='@') {
|
||||||
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++!=*cp++) {
|
if (*mp++!=*cp++) {
|
||||||
|
@ -1363,7 +1356,7 @@ void SML_Decode(uint8_t index) {
|
||||||
found=0;
|
found=0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// ebus or raw
|
// ebus mbus or raw
|
||||||
// XXHHHHSSUU
|
// XXHHHHSSUU
|
||||||
if (*mp=='x' && *(mp+1)=='x') {
|
if (*mp=='x' && *(mp+1)=='x') {
|
||||||
//ignore
|
//ignore
|
||||||
|
@ -1389,7 +1382,15 @@ void SML_Decode(uint8_t index) {
|
||||||
int8_t val = *cp++;
|
int8_t val = *cp++;
|
||||||
ebus_dval=val;
|
ebus_dval=val;
|
||||||
mp+=2;
|
mp+=2;
|
||||||
} else {
|
}
|
||||||
|
else if (*mp=='f' && *(mp+1)=='f' && *(mp+2)=='f' && *(mp+3)=='f' && *(mp+4)=='f' && *(mp+5)=='f' && *(mp+6)=='f' && *(mp+7)=='f') {
|
||||||
|
uint32_t val= (*(cp+0)<<24)|(*(cp+1)<<16)|(*(cp+2)<<8)|(*(cp+3)<<0);
|
||||||
|
float *fp=(float*)&val;
|
||||||
|
mbus_dval=*fp;
|
||||||
|
mp+=8;
|
||||||
|
cp+=4;
|
||||||
|
}
|
||||||
|
else {
|
||||||
uint8_t val = hexnibble(*mp++) << 4;
|
uint8_t val = hexnibble(*mp++) << 4;
|
||||||
val |= hexnibble(*mp++);
|
val |= hexnibble(*mp++);
|
||||||
if (val!=*cp++) {
|
if (val!=*cp++) {
|
||||||
|
@ -1418,7 +1419,7 @@ void SML_Decode(uint8_t index) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
double dval;
|
double dval;
|
||||||
if (meter_desc_p[mindex].type!='e' && meter_desc_p[mindex].type!='r') {
|
if (meter_desc_p[mindex].type!='e' && meter_desc_p[mindex].type!='r' && meter_desc_p[mindex].type!='m') {
|
||||||
// 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') {
|
||||||
dval=xCharToDouble((char*)cp);
|
dval=xCharToDouble((char*)cp);
|
||||||
|
@ -1426,7 +1427,7 @@ void SML_Decode(uint8_t index) {
|
||||||
dval=sml_getvalue(cp,mindex);
|
dval=sml_getvalue(cp,mindex);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// ebus
|
// ebus or mbus
|
||||||
if (*mp=='b') {
|
if (*mp=='b') {
|
||||||
mp++;
|
mp++;
|
||||||
uint8_t shift=*mp&7;
|
uint8_t shift=*mp&7;
|
||||||
|
@ -1434,8 +1435,24 @@ void SML_Decode(uint8_t index) {
|
||||||
ebus_dval&=1;
|
ebus_dval&=1;
|
||||||
mp+=2;
|
mp+=2;
|
||||||
}
|
}
|
||||||
|
if (*mp=='i') {
|
||||||
|
// mbus index
|
||||||
|
mp++;
|
||||||
|
uint8_t mb_index=strtol((char*)mp,(char**)&mp,10);
|
||||||
|
if (mb_index!=meter_desc_p[mindex].index) {
|
||||||
|
goto nextsect;
|
||||||
|
}
|
||||||
|
uint16_t crc = MBUS_calculateCRC(&smltbuf[mindex][0],7);
|
||||||
|
if (lowByte(crc)!=smltbuf[mindex][7]) goto nextsect;
|
||||||
|
if (highByte(crc)!=smltbuf[mindex][8]) goto nextsect;
|
||||||
|
dval=mbus_dval;
|
||||||
|
//AddLog_P2(LOG_LEVEL_INFO, PSTR(">> %s"),mp);
|
||||||
|
mp++;
|
||||||
|
} else {
|
||||||
dval=ebus_dval;
|
dval=ebus_dval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
#ifdef USE_MEDIAN_FILTER
|
#ifdef USE_MEDIAN_FILTER
|
||||||
meter_vars[vindex]=median(&sml_mf[vindex],dval);
|
meter_vars[vindex]=median(&sml_mf[vindex],dval);
|
||||||
#else
|
#else
|
||||||
|
@ -1723,6 +1740,14 @@ void SML_Init(void) {
|
||||||
|
|
||||||
|
|
||||||
#ifdef USE_SCRIPT
|
#ifdef USE_SCRIPT
|
||||||
|
|
||||||
|
for (uint32_t cnt=0;cnt<MAX_METERS;cnt++) {
|
||||||
|
if (script_meter_desc[cnt].txmem) {
|
||||||
|
free(script_meter_desc[cnt].txmem);
|
||||||
|
script_meter_desc[cnt].txmem=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t meter_script=Run_Scripter(">M",-2,0);
|
uint8_t meter_script=Run_Scripter(">M",-2,0);
|
||||||
if (meter_script==99) {
|
if (meter_script==99) {
|
||||||
// use script definition
|
// use script definition
|
||||||
|
@ -1782,13 +1807,42 @@ void SML_Init(void) {
|
||||||
lp++;
|
lp++;
|
||||||
script_meter_desc[index].prefix[7]=0;
|
script_meter_desc[index].prefix[7]=0;
|
||||||
for (uint32_t cnt=0; cnt<8; cnt++) {
|
for (uint32_t cnt=0; cnt<8; cnt++) {
|
||||||
if (*lp==SCRIPT_EOL) {
|
if (*lp==SCRIPT_EOL || *lp==',') {
|
||||||
script_meter_desc[index].prefix[cnt]=0;
|
script_meter_desc[index].prefix[cnt]=0;
|
||||||
lp--;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
script_meter_desc[index].prefix[cnt]=*lp++;
|
script_meter_desc[index].prefix[cnt]=*lp++;
|
||||||
}
|
}
|
||||||
|
if (*lp==',') {
|
||||||
|
lp++;
|
||||||
|
script_meter_desc[index].trxpin=strtol(lp,&lp,10);
|
||||||
|
if (*lp!=',') goto next_line;
|
||||||
|
lp++;
|
||||||
|
script_meter_desc[index].tsecs=strtol(lp,&lp,10);
|
||||||
|
if (*lp==',') {
|
||||||
|
lp++;
|
||||||
|
char txbuff[256];
|
||||||
|
uint32_t txlen=0,tx_entries=1;
|
||||||
|
for (uint32_t cnt=0; cnt<sizeof(txbuff); cnt++) {
|
||||||
|
if (*lp==SCRIPT_EOL) {
|
||||||
|
txbuff[cnt]=0;
|
||||||
|
txlen=cnt;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (*lp==',') tx_entries++;
|
||||||
|
txbuff[cnt]=*lp++;
|
||||||
|
}
|
||||||
|
if (txlen) {
|
||||||
|
script_meter_desc[index].txmem=(char*)calloc(txlen+2,1);
|
||||||
|
if (script_meter_desc[index].txmem) {
|
||||||
|
strcpy(script_meter_desc[index].txmem,txbuff);
|
||||||
|
}
|
||||||
|
script_meter_desc[index].index=0;
|
||||||
|
script_meter_desc[index].max_index=tx_entries;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (*lp==SCRIPT_EOL) lp--;
|
||||||
goto next_line;
|
goto next_line;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1862,19 +1916,20 @@ next_line:
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// serial input, init
|
// serial input, init
|
||||||
if (meter_desc_p[meters].srcpin==3) {
|
|
||||||
ClaimSerial();
|
|
||||||
SetSerialBaudrate(meter_desc_p[meters].params);
|
|
||||||
} else {
|
|
||||||
#ifdef SPECIAL_SS
|
#ifdef SPECIAL_SS
|
||||||
meter_ss[meters] = new TasmotaSerial(meter_desc_p[meters].srcpin,-1,0,1);
|
if (meter_desc_p[meters].type=='m') {
|
||||||
|
meter_ss[meters] = new TasmotaSerial(meter_desc_p[meters].srcpin,meter_desc_p[meters].trxpin,1);
|
||||||
|
} else {
|
||||||
|
meter_ss[meters] = new TasmotaSerial(meter_desc_p[meters].srcpin,meter_desc_p[meters].trxpin,1,1);
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
meter_ss[meters] = new TasmotaSerial(meter_desc_p[meters].srcpin,-1);
|
meter_ss[meters] = new TasmotaSerial(meter_desc_p[meters].srcpin,meter_desc_p[meters].trxpin,1);
|
||||||
#endif
|
#endif
|
||||||
if (meter_ss[meters]->begin(meter_desc_p[meters].params)) {
|
if (meter_ss[meters]->begin(meter_desc_p[meters].params)) {
|
||||||
meter_ss[meters]->flush();
|
meter_ss[meters]->flush();
|
||||||
}
|
}
|
||||||
}
|
if (meter_ss[meters]->hardwareSerial()) { ClaimSerial(); }
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1958,25 +2013,102 @@ uint32_t ctime=millis();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SML_SEND_SEQ
|
#ifdef USE_SCRIPT
|
||||||
#define SML_SEQ_PERIOD 5
|
char *SML_Get_Sequence(char *cp,uint32_t index) {
|
||||||
uint8_t sml_seq_cnt;
|
if (!index) return cp;
|
||||||
void SendSeq(void) {
|
uint32_t cindex=0;
|
||||||
sml_seq_cnt++;
|
while (cp) {
|
||||||
if (sml_seq_cnt>SML_SEQ_PERIOD) {
|
cp=strchr(cp,',');
|
||||||
sml_seq_cnt=0;
|
if (cp) {
|
||||||
// send sequence every N Seconds
|
cp++;
|
||||||
uint8_t sequence[]={0x2F,0x3F,0x21,0x0D,0x0A,0};
|
cindex++;
|
||||||
uint8_t *ucp=sequence;
|
if (cindex==index) {
|
||||||
while (*ucp) {
|
return cp;
|
||||||
uint8_t iob=*ucp++;
|
}
|
||||||
// for no parity disable next line
|
|
||||||
iob|=(CalcEvenParity(iob)<<7);
|
|
||||||
Serial.write(iob);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t sml_250ms_cnt;
|
||||||
|
|
||||||
|
|
||||||
|
void SML_Check_Send(void) {
|
||||||
|
sml_250ms_cnt++;
|
||||||
|
for (uint32_t cnt=0; cnt<meters_used; cnt++) {
|
||||||
|
if (script_meter_desc[cnt].trxpin>=0 && script_meter_desc[cnt].txmem) {
|
||||||
|
if ((sml_250ms_cnt%script_meter_desc[cnt].tsecs)==0) {
|
||||||
|
if (script_meter_desc[cnt].max_index>1) {
|
||||||
|
script_meter_desc[cnt].index++;
|
||||||
|
if (script_meter_desc[cnt].index>=script_meter_desc[cnt].max_index) {
|
||||||
|
script_meter_desc[cnt].index=0;
|
||||||
|
}
|
||||||
|
char *cp=SML_Get_Sequence(script_meter_desc[cnt].txmem,script_meter_desc[cnt].index);
|
||||||
|
SML_Send_Seq(cnt,cp);
|
||||||
|
//AddLog_P2(LOG_LEVEL_INFO, PSTR(">> %s"),cp);
|
||||||
|
} else {
|
||||||
|
SML_Send_Seq(cnt,script_meter_desc[cnt].txmem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t sml_hexnibble(char chr) {
|
||||||
|
uint8_t rVal = 0;
|
||||||
|
if (isdigit(chr)) {
|
||||||
|
rVal = chr - '0';
|
||||||
|
} else {
|
||||||
|
if (chr >= 'A' && chr <= 'F') rVal = chr + 10 - 'A';
|
||||||
|
if (chr >= 'a' && chr <= 'f') rVal = chr + 10 - 'a';
|
||||||
|
}
|
||||||
|
return rVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
// send sequence every N Seconds
|
||||||
|
void SML_Send_Seq(uint32_t meter,char *seq) {
|
||||||
|
uint8_t sbuff[32];
|
||||||
|
uint8_t *ucp=sbuff,slen;
|
||||||
|
char *cp=seq;
|
||||||
|
while (*cp) {
|
||||||
|
if (!*cp || !*(cp+1)) break;
|
||||||
|
if (*cp==',') break;
|
||||||
|
uint8_t iob=(sml_hexnibble(*cp) << 4) | sml_hexnibble(*(cp+1));
|
||||||
|
cp+=2;
|
||||||
|
*ucp++=iob;
|
||||||
|
slen++;
|
||||||
|
if (slen>=sizeof(sbuff)) break;
|
||||||
|
}
|
||||||
|
if (script_meter_desc[meter].type=='m') {
|
||||||
|
*ucp++=0;
|
||||||
|
*ucp++=2;
|
||||||
|
// append crc
|
||||||
|
uint16_t crc = MBUS_calculateCRC(sbuff,6);
|
||||||
|
*ucp++=lowByte(crc);
|
||||||
|
*ucp++=highByte(crc);
|
||||||
|
slen+=4;
|
||||||
|
}
|
||||||
|
meter_ss[meter]->write(sbuff,slen);
|
||||||
|
}
|
||||||
|
#endif // USE_SCRIPT
|
||||||
|
|
||||||
|
uint16_t MBUS_calculateCRC(uint8_t *frame, uint8_t num) {
|
||||||
|
uint16_t crc, flag;
|
||||||
|
crc = 0xFFFF;
|
||||||
|
for (uint32_t i = 0; i < num; i++) {
|
||||||
|
crc ^= frame[i];
|
||||||
|
for (uint32_t j = 8; j; j--) {
|
||||||
|
if ((crc & 0x0001) != 0) { // If the LSB is set
|
||||||
|
crc >>= 1; // Shift right and XOR 0xA001
|
||||||
|
crc ^= 0xA001;
|
||||||
|
} else { // Else LSB is not set
|
||||||
|
crc >>= 1; // Just shift right
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return crc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
// for odd parity init with 1
|
// for odd parity init with 1
|
||||||
uint8_t CalcEvenParity(uint8_t data) {
|
uint8_t CalcEvenParity(uint8_t data) {
|
||||||
uint8_t parity=0;
|
uint8_t parity=0;
|
||||||
|
@ -1987,7 +2119,7 @@ uint8_t parity=0;
|
||||||
}
|
}
|
||||||
return parity;
|
return parity;
|
||||||
}
|
}
|
||||||
#endif
|
*/
|
||||||
|
|
||||||
|
|
||||||
// dump to log shows serial data on console
|
// dump to log shows serial data on console
|
||||||
|
@ -2053,6 +2185,7 @@ void SML_CounterSaveState(void) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
* Interface
|
* Interface
|
||||||
\*********************************************************************************************/
|
\*********************************************************************************************/
|
||||||
|
@ -2070,11 +2203,11 @@ bool Xsns53(byte function) {
|
||||||
if (dump2log) Dump2log();
|
if (dump2log) Dump2log();
|
||||||
else SML_Poll();
|
else SML_Poll();
|
||||||
break;
|
break;
|
||||||
#ifdef SML_SEND_SEQ
|
#ifdef USE_SCRIPT
|
||||||
case FUNC_EVERY_SECOND:
|
case FUNC_EVERY_250_MSECOND:
|
||||||
SendSeq();
|
SML_Check_Send();
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif // USE_SCRIPT
|
||||||
case FUNC_JSON_APPEND:
|
case FUNC_JSON_APPEND:
|
||||||
SML_Show(1);
|
SML_Show(1);
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue