diff --git a/tasmota/xdrv_10_scripter.ino b/tasmota/xdrv_10_scripter.ino index 0461a632a..44bf82dd1 100755 --- a/tasmota/xdrv_10_scripter.ino +++ b/tasmota/xdrv_10_scripter.ino @@ -3801,15 +3801,15 @@ extern char *SML_GetSVal(uint32_t index); float fvar2; lp = GetNumericArgument(lp, OPER_EQU, &fvar2, gv); SCRIPT_SKIP_SPACES - if (fvar2==0) { + if (fvar2 == 0) { float fvar3; lp = GetNumericArgument(lp, OPER_EQU, &fvar3, gv); fvar = SML_SetBaud(fvar1, fvar3); - } else if (fvar2==1) { + } else if (fvar2 == 1) { char str[SCRIPT_MAXSSIZE]; lp = GetStringArgument(lp, OPER_EQU, str, 0); fvar = SML_Write(fvar1, str); - } else if (fvar2==2) { + } else if (fvar2 == 2) { char str[SCRIPT_MAXSSIZE]; str[0] = 0; fvar = SML_Read(fvar1, str, SCRIPT_MAXSSIZE); @@ -3817,8 +3817,27 @@ extern char *SML_GetSVal(uint32_t index); lp++; len = 0; goto strexit; - + } else if (fvar2 == 3) { + uint8_t vtype; + struct T_INDEX ind; + lp = isvar(lp, &vtype, &ind, 0, 0, 0); + if (vtype != VAR_NV) { + // found variable as result + if (vtype == NUM_RES || (vtype & STYPE) == 0) { + // numeric result + fvar = -1; + } else { + // string result + uint8_t sindex = glob_script_mem.type[ind.index].index; + char *cp = glob_script_mem.glob_snp + (sindex * glob_script_mem.max_ssize); + fvar = SML_Set_WStr(fvar1, cp); + } + } else { + fvar = -99; + } } else { + + #ifdef ED300L fvar = SML_Status(fvar1); #else diff --git a/tasmota/xsns_53_sml.ino b/tasmota/xsns_53_sml.ino index 974125946..9385802fc 100755 --- a/tasmota/xsns_53_sml.ino +++ b/tasmota/xsns_53_sml.ino @@ -89,6 +89,7 @@ struct METER_DESC { char *txmem; uint8_t index; uint8_t max_index; + char *script_str; uint8_t sopt; }; @@ -1848,93 +1849,117 @@ void SML_Decode(uint8_t index) { cp += skip; } } - } else if (!strncmp(mp,"UUuuUUuu",8)) { - uint32_t val= (cp[0]<<24)|(cp[1]<<16)|(cp[2]<<8)|(cp[3]<<0); - ebus_dval=val; - mbus_dval=val; - mp+=8; - cp+=4; - } else if (*mp=='U' && *(mp+1)=='U' && *(mp+2)=='u' && *(mp+3)=='u'){ - uint16_t val = cp[1]|(cp[0]<<8); - mbus_dval=val; - ebus_dval=val; - mp+=4; - cp+=2; - } else if (!strncmp(mp,"SSssSSss",8)) { - int32_t val= (cp[0]<<24)|(cp[1]<<16)|(cp[2]<<8)|(cp[3]<<0); - ebus_dval=val; - mbus_dval=val; - mp+=8; - cp+=4; - } else if (*mp=='u' && *(mp+1)=='u' && *(mp+2)=='U' && *(mp+3)=='U'){ - uint16_t val = cp[0]|(cp[1]<<8); - mbus_dval=val; - ebus_dval=val; - mp+=4; - cp+=2; - } else if (*mp=='u' && *(mp+1)=='u') { + } else if (!strncmp(mp, "UUuuUUuu", 8)) { + uint32_t val = (cp[0]<<24) | (cp[1]<<16) | (cp[2]<<8) | (cp[3]<<0); + mp += 8; + cp += 4; + if (*mp == 's') { + mp++; + // swap words + val = (val>>16) | (val<<16); + } + ebus_dval = val; + mbus_dval = val; + } else if (!strncmp(mp, "uuUUuuUU", 8)) { + uint32_t val = (cp[1]<<24) | (cp[0]<<16) | (cp[3]<<8) | (cp[2]<<0); + mp += 8; + cp += 4; + if (*mp == 's') { + mp++; + // swap words + val = (val>>16) | (val<<16); + } + ebus_dval = val; + mbus_dval = val; + } else if (!strncmp(mp, "UUuu", 4)) { + uint16_t val = cp[1] | (cp[0]<<8); + mbus_dval = val; + ebus_dval = val; + mp += 4; + cp += 2; + } else if (!strncmp(mp, "SSssSSss", 8)) { + int32_t val = (cp[0]<<24) | (cp[1]<<16) | (cp[2]<<8) | (cp[3]<<0); + mp += 8; + cp += 4; + if (*mp == 's') { + mp++; + // swap words + val = ((uint32_t)val>>16) | ((uint32_t)val<<16); + } + ebus_dval = val; + mbus_dval = val; + } else if (!strncmp(mp, "ssSSssSS", 8)) { + int32_t val = (cp[1]<<24) | (cp[0]<<16) | (cp[3]<<8) | (cp[2]<<0); + mp += 8; + cp += 4; + if (*mp == 's') { + mp++; + // swap words + val = ((uint32_t)val>>16) | ((uint32_t)val<<16); + } + ebus_dval = val; + mbus_dval = val; + } else if (!strncmp(mp, "uuUU", 4)) { + uint16_t val = cp[0] | (cp[1]<<8); + mbus_dval = val; + ebus_dval = val; + mp += 4; + cp += 2; + } else if (!strncmp(mp, "uu", 2)) { uint8_t val = *cp++; - mbus_dval=val; - ebus_dval=val; - mp+=2; - } else if (*mp=='s' && *(mp+1)=='s' && *(mp+2)=='S' && *(mp+3)=='S') { - int16_t val = *cp|(*(cp+1)<<8); - mbus_dval=val; - ebus_dval=val; - mp+=4; - cp+=2; - } else if (*mp=='S' && *(mp+1)=='S' && *(mp+2)=='s' && *(mp+3)=='s') { - int16_t val = cp[1]|(cp[0]<<8); - mbus_dval=val; - ebus_dval=val; - mp+=4; - cp+=2; - } - else if (*mp=='s' && *(mp+1)=='s') { + mbus_dval = val; + ebus_dval = val; + mp += 2; + } else if (!strncmp(mp, "ssSS", 4)) { + int16_t val = *cp | (*(cp+1)<<8); + mbus_dval = val; + ebus_dval = val; + mp += 4; + cp += 2; + } else if (!strncmp(mp, "SSss", 4)) { + int16_t val = cp[1] | (cp[0]<<8); + mbus_dval = val; + ebus_dval = val; + mp += 4; + cp += 2; + } else if (!strncmp(mp,"ss", 2)) { int8_t val = *cp++; - mbus_dval=val; - ebus_dval=val; - mp+=2; - } - else if (!strncmp(mp,"ffffffff",8)) { - uint32_t val= (cp[0]<<24)|(cp[1]<<16)|(cp[2]<<8)|(cp[3]<<0); - float *fp=(float*)&val; - ebus_dval=*fp; - mbus_dval=*fp; - mp+=8; - cp+=4; - } - else if (!strncmp(mp,"FFffFFff",8)) { + mbus_dval = val; + ebus_dval = val; + mp += 2; + } else if (!strncmp(mp, "ffffffff", 8)) { + uint32_t val = (cp[0]<<24) | (cp[1]<<16) | (cp[2]<<8) | (cp[3]<<0); + float *fp = (float*)&val; + ebus_dval = *fp; + mbus_dval = *fp; + mp += 8; + cp += 4; + } else if (!strncmp(mp, "FFffFFff", 8)) { // reverse word float - uint32_t val= (cp[1]<<0)|(cp[0]<<8)|(cp[3]<<16)|(cp[2]<<24); - float *fp=(float*)&val; - ebus_dval=*fp; - mbus_dval=*fp; - mp+=8; - cp+=4; - } - else if (!strncmp(mp,"eeeeee",6)) { - uint32_t val=(cp[0]<<16)|(cp[1]<<8)|(cp[2]<<0); - mbus_dval=val; - mp+=6; - cp+=3; - } - else if (!strncmp(mp,"vvvvvv",6)) { - mbus_dval=(float)((cp[0]<<8)|(cp[1])) + ((float)cp[2]/10.0); - mp+=6; - cp+=3; - } - else if (!strncmp(mp,"cccccc",6)) { - mbus_dval=(float)((cp[0]<<8)|(cp[1])) + ((float)cp[2]/100.0); - mp+=6; - cp+=3; - } - else if (!strncmp(mp,"pppp",4)) { - mbus_dval=(float)((cp[0]<<8)|cp[1]); - mp+=4; - cp+=2; - } - else if (*mp == 'v') { + uint32_t val = (cp[1]<<0) | (cp[0]<<8) | (cp[3]<<16) | (cp[2]<<24); + float *fp = (float*)&val; + ebus_dval = *fp; + mbus_dval = *fp; + mp += 8; + cp += 4; + } else if (!strncmp(mp, "eeeeee", 6)) { + uint32_t val = (cp[0]<<16) | (cp[1]<<8) | (cp[2]<<0); + mbus_dval = val; + mp += 6; + cp += 3; + } else if (!strncmp(mp, "vvvvvv", 6)) { + mbus_dval = (float)((cp[0]<<8) | (cp[1])) + ((float)cp[2]/10.0); + mp += 6; + cp += 3; + } else if (!strncmp(mp, "cccccc", 6)) { + mbus_dval = (float)((cp[0]<<8) | (cp[1])) + ((float)cp[2]/100.0); + mp += 6; + cp += 3; + } else if (!strncmp(mp, "pppp", 4)) { + mbus_dval = (float)((cp[0]<<8) | cp[1]); + mp += 4; + cp += 2; + } else if (*mp == 'v') { // vbus values vul, vsl, vuwh, vuwl, wswh, vswl, vswh // vub3, vsb3 etc mp++; @@ -2411,7 +2436,7 @@ uint8_t sml_cnt_index[MAX_COUNTERS] = { 0, 1, 2, 3 }; void IRAM_ATTR SML_CounterIsr(void *arg) { uint32_t index = *static_cast(arg); -uint32_t time = micros(); +uint32_t time = millis(); uint32_t debounce_time; if (digitalRead(meter_desc_p[sml_counters[index].sml_cnt_old_state].srcpin) == bitRead(sml_counter_pinstate, index)) { @@ -2420,15 +2445,15 @@ uint32_t debounce_time; debounce_time = time - sml_counters[index].sml_counter_ltime; - if (debounce_time <= sml_counters[index].sml_debounce * 1000) return; + if (debounce_time <= sml_counters[index].sml_debounce) return; if bitRead(sml_counter_pinstate, index) { // falling edge RtcSettings.pulse_counter[index]++; - sml_counters[index].sml_cnt_updated=1; + sml_counters[index].sml_cnt_updated = 1; } sml_counters[index].sml_counter_ltime = time; - sml_counter_pinstate ^= (1<pulse_counter[i]; - sml_counters[i].sml_cnt_last_ts=millis(); + sml_counters[i].sml_cnt_last_ts = millis(); } uint32_t uart_index = 2; + sml_counter_pinstate = 0; for (uint8_t meters = 0; meters < meters_used; meters++) { if (meter_desc_p[meters].type == 'c') { if (meter_desc_p[meters].flag & 2) { @@ -2819,11 +2845,17 @@ init10: // check for irq mode if (meter_desc_p[meters].params<=0) { // init irq mode - attachInterruptArg(meter_desc_p[meters].srcpin, SML_CounterIsr,&sml_cnt_index[cindex], CHANGE); - sml_counters[cindex].sml_cnt_old_state=meters; - sml_counters[cindex].sml_debounce=-meter_desc_p[meters].params; + sml_counters[cindex].sml_cnt_old_state = meters; + sml_counters[cindex].sml_debounce = -meter_desc_p[meters].params; + attachInterruptArg(meter_desc_p[meters].srcpin, SML_CounterIsr, &sml_cnt_index[cindex], CHANGE); + if (digitalRead(meter_desc_p[meters].srcpin) > 0) { + sml_counter_pinstate |= (1 << cindex); + } + sml_counters[cindex].sml_counter_ltime = millis(); } - InjektCounterValue(meters,RtcSettings.pulse_counter[cindex]); + + RtcSettings.pulse_counter[cindex] = Settings->pulse_counter[cindex]; + InjektCounterValue(meters, RtcSettings.pulse_counter[cindex]); cindex++; } } else { @@ -3007,6 +3039,15 @@ char *SML_GetSVal(uint32_t index) { if (index < 1 || index > MAX_METERS) { index = 1;} return &meter_id[index - 1][0]; } + +int32_t SML_Set_WStr(uint32_t meter, char *hstr) { + if (meter < 1 || meter > meters_used) return -1; + meter--; + if (!meter_ss[meter]) return -2; + script_meter_desc[meter].script_str = hstr; + return 0; +} + #endif // USE_SML_SCRIPT_CMD @@ -3114,29 +3155,35 @@ char *SML_Get_Sequence(char *cp,uint32_t index) { void SML_Check_Send(void) { sml_100ms_cnt++; char *cp; - for (uint32_t cnt=sml_desc_cnt; cnt=0 && script_meter_desc[cnt].txmem) { + for (uint32_t cnt = sml_desc_cnt; cnt < meters_used; cnt++) { + if (script_meter_desc[cnt].trxpin >= 0 && script_meter_desc[cnt].txmem) { //AddLog(LOG_LEVEL_INFO, PSTR("100 ms>> %d - %s - %d"),sml_desc_cnt,script_meter_desc[cnt].txmem,script_meter_desc[cnt].tsecs); - if ((sml_100ms_cnt>=script_meter_desc[cnt].tsecs)) { - sml_100ms_cnt=0; - //AddLog(LOG_LEVEL_INFO, PSTR("100 ms>> 2"),cp); - 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; + if ((sml_100ms_cnt >= script_meter_desc[cnt].tsecs)) { + sml_100ms_cnt = 0; + // check for scriptsync extra output + if (script_meter_desc[cnt].script_str) { + cp = script_meter_desc[cnt].script_str; + script_meter_desc[cnt].script_str = 0; + } else { + //AddLog(LOG_LEVEL_INFO, PSTR("100 ms>> 2"),cp); + 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; + sml_desc_cnt++; + } + cp=SML_Get_Sequence(script_meter_desc[cnt].txmem,script_meter_desc[cnt].index); + //SML_Send_Seq(cnt,cp); + } else { + cp = script_meter_desc[cnt].txmem; + //SML_Send_Seq(cnt,cp); sml_desc_cnt++; } - cp=SML_Get_Sequence(script_meter_desc[cnt].txmem,script_meter_desc[cnt].index); - //SML_Send_Seq(cnt,cp); - } else { - cp=script_meter_desc[cnt].txmem; - //SML_Send_Seq(cnt,cp); - sml_desc_cnt++; } //AddLog(LOG_LEVEL_INFO, PSTR(">> %s"),cp); SML_Send_Seq(cnt,cp); - if (sml_desc_cnt>=meters_used) { - sml_desc_cnt=0; + if (sml_desc_cnt >= meters_used) { + sml_desc_cnt = 0; } break; } @@ -3144,8 +3191,8 @@ void SML_Check_Send(void) { sml_desc_cnt++; } - if (sml_desc_cnt>=meters_used) { - sml_desc_cnt=0; + if (sml_desc_cnt >= meters_used) { + sml_desc_cnt = 0; } } }