From fd3f77fb171c5d0acce493870634e416e98ee860 Mon Sep 17 00:00:00 2001
From: Jason2866 <24528715+Jason2866@users.noreply.github.com>
Date: Thu, 10 Sep 2020 15:06:06 +0200
Subject: [PATCH 01/23] Fix compile error on MAC
See https://github.com/platformio/platformio-core/issues/3659
Thx @ivankravets
---
platformio.ini | 1 -
1 file changed, 1 deletion(-)
diff --git a/platformio.ini b/platformio.ini
index ecf7d41ab..f70cfa812 100644
--- a/platformio.ini
+++ b/platformio.ini
@@ -11,7 +11,6 @@
description = Provide ESP8266 based devices with Web, MQTT and OTA firmware
src_dir = tasmota
build_dir = .pioenvs
-workspace_dir = .pioenvs
build_cache_dir = .cache
extra_configs = platformio_tasmota32.ini
platformio_tasmota_env.ini
From ed83e770a4a2dd9452dc739c5fb02959fea3263a Mon Sep 17 00:00:00 2001
From: Jason2866 <24528715+Jason2866@users.noreply.github.com>
Date: Thu, 10 Sep 2020 15:10:34 +0200
Subject: [PATCH 02/23] is not needed anymore too
since we do not support core 2.3.0 anymore
---
platformio.ini | 1 -
1 file changed, 1 deletion(-)
diff --git a/platformio.ini b/platformio.ini
index f70cfa812..b07184478 100644
--- a/platformio.ini
+++ b/platformio.ini
@@ -10,7 +10,6 @@
[platformio]
description = Provide ESP8266 based devices with Web, MQTT and OTA firmware
src_dir = tasmota
-build_dir = .pioenvs
build_cache_dir = .cache
extra_configs = platformio_tasmota32.ini
platformio_tasmota_env.ini
From da4caa6ec166b51586ad6d7362cb696c8d83f5c3 Mon Sep 17 00:00:00 2001
From: Jason2866 <24528715+Jason2866@users.noreply.github.com>
Date: Thu, 10 Sep 2020 16:41:31 +0200
Subject: [PATCH 03/23] path changed
---
pio/name-firmware.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pio/name-firmware.py b/pio/name-firmware.py
index 1490ecc5c..1c79056de 100644
--- a/pio/name-firmware.py
+++ b/pio/name-firmware.py
@@ -5,7 +5,7 @@ import shutil
OUTPUT_DIR = "build_output{}".format(os.path.sep)
def bin_map_copy(source, target, env):
- variant = str(target[0]).split(os.path.sep)[1]
+ variant = str(target[0]).split(os.path.sep)[2]
# check if output directories exist and create if necessary
if not os.path.isdir(OUTPUT_DIR):
From 3d256b83c2214b52252e4c8dc01effde96dd92ac Mon Sep 17 00:00:00 2001
From: Jason2866 <24528715+Jason2866@users.noreply.github.com>
Date: Thu, 10 Sep 2020 16:42:37 +0200
Subject: [PATCH 04/23] path changed
---
pio/gzip-firmware.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pio/gzip-firmware.py b/pio/gzip-firmware.py
index 43af1f933..248bb5a02 100644
--- a/pio/gzip-firmware.py
+++ b/pio/gzip-firmware.py
@@ -6,7 +6,7 @@ import gzip
OUTPUT_DIR = "build_output{}".format(os.path.sep)
def bin_gzip(source, target, env):
- variant = str(target[0]).split(os.path.sep)[1]
+ variant = str(target[0]).split(os.path.sep)[2]
# create string with location and file names based on variant
bin_file = "{}firmware{}{}.bin".format(OUTPUT_DIR, os.path.sep, variant)
From b239a1d77e10f64f9ffa5f0267bd12c19794ef04 Mon Sep 17 00:00:00 2001
From: Jason2866 <24528715+Jason2866@users.noreply.github.com>
Date: Fri, 11 Sep 2020 10:11:18 +0200
Subject: [PATCH 05/23] Update platformio.ini
---
platformio.ini | 22 +++++++++++++---------
1 file changed, 13 insertions(+), 9 deletions(-)
diff --git a/platformio.ini b/platformio.ini
index b07184478..a0c4d82b5 100644
--- a/platformio.ini
+++ b/platformio.ini
@@ -7,16 +7,9 @@
; Please visit documentation for the other options and examples
; http://docs.platformio.org/en/stable/projectconf.html
-[platformio]
-description = Provide ESP8266 based devices with Web, MQTT and OTA firmware
-src_dir = tasmota
-build_cache_dir = .cache
-extra_configs = platformio_tasmota32.ini
- platformio_tasmota_env.ini
- platformio_tasmota_env32.ini
- platformio_override.ini
-; *** Build/upload environment
+; *** Tasmota build variant selection
+[build_envs]
default_envs =
; *** Uncomment by deleting ";" in the line(s) below to select version(s)
; tasmota
@@ -51,10 +44,21 @@ default_envs =
; tasmota-TW
; tasmota-UK
;
+; *** Selection for Tasmota ESP32 is done in platformio_tasmota32.ini
+;
; *** alternatively can be done in: platformio_override.ini
; *** See example: platformio_override_sample.ini
; *********************************************************************
+[platformio]
+description = Provide ESP8266 / ESP32 based devices with Web, MQTT and OTA firmware
+src_dir = tasmota
+build_cache_dir = .cache
+extra_configs = platformio_tasmota32.ini
+ platformio_tasmota_env.ini
+ platformio_tasmota_env32.ini
+ platformio_override.ini
+default_envs = ${build_envs.default_envs}
[common]
framework = arduino
From ef3855e92f24cc3099bca4127f104f784a3b993d Mon Sep 17 00:00:00 2001
From: Jason2866 <24528715+Jason2866@users.noreply.github.com>
Date: Fri, 11 Sep 2020 10:13:12 +0200
Subject: [PATCH 06/23] Make selecting ESP32 versions possible
without using override file
---
platformio_tasmota32.ini | 38 ++++++++++++++++++++++++++++++++++++++
1 file changed, 38 insertions(+)
diff --git a/platformio_tasmota32.ini b/platformio_tasmota32.ini
index 549f2e333..739ec2338 100644
--- a/platformio_tasmota32.ini
+++ b/platformio_tasmota32.ini
@@ -1,6 +1,44 @@
; *** BETA ESP32 Tasmota version ***
; *** expect the unexpected. Some features not working!!! ***
+[platformio]
+
+; *** Tasmota build variant selection
+default_envs = ${build_envs.default_envs}
+; *** Uncomment by deleting ";" in the line(s) below to select version(s)
+; tasmota32
+; tasmota32-webcam
+; tasmota32-minimal
+; tasmota32-lite
+; tasmota32-knx
+; tasmota32-sensors
+; tasmota32-display
+; tasmota32-ir
+; tasmota32-ircustom
+; tasmota32-BG
+; tasmota32-BR
+; tasmota32-CN
+; tasmota32-CZ
+; tasmota32-DE
+; tasmota32-ES
+; tasmota32-FR
+; tasmota32-GR
+; tasmota32-HE
+; tasmota32-HU
+; tasmota32-IT
+; tasmota32-KO
+; tasmota32-NL
+; tasmota32-PL
+; tasmota32-PT
+; tasmota32-RO
+; tasmota32-RU
+; tasmota32-SE
+; tasmota32-SK
+; tasmota32-TR
+; tasmota32-TW
+; tasmota32-UK
+
+
[common32]
platform = espressif32@2.0.0
platform_packages = tool-esptoolpy@1.20800.0
From 9afa8a5d4f564d9b5295809114d12c35f9b5d6e5 Mon Sep 17 00:00:00 2001
From: gemu2015
Date: Fri, 11 Sep 2020 15:44:16 +0200
Subject: [PATCH 07/23] scripter update
reformatting,
bug fixes,
new options for google charts
formulas in text substitutions %(formula)%
---
tasmota/xdrv_10_scripter.ino | 4120 +++++++++++++++++-----------------
1 file changed, 2068 insertions(+), 2052 deletions(-)
diff --git a/tasmota/xdrv_10_scripter.ino b/tasmota/xdrv_10_scripter.ino
index cd5f986d2..ea8223233 100755
--- a/tasmota/xdrv_10_scripter.ino
+++ b/tasmota/xdrv_10_scripter.ino
@@ -136,19 +136,19 @@ Ticker Script_ticker4;
void Script_ticker1_end(void) {
Script_ticker1.detach();
- Run_Scripter(">ti1", 4,0);
+ Run_Scripter(">ti1", 4, 0);
}
void Script_ticker2_end(void) {
Script_ticker2.detach();
- Run_Scripter(">ti2", 4,0);
+ Run_Scripter(">ti2", 4, 0);
}
void Script_ticker3_end(void) {
Script_ticker3.detach();
- Run_Scripter(">ti3", 4,0);
+ Run_Scripter(">ti3", 4, 0);
}
void Script_ticker4_end(void) {
Script_ticker4.detach();
- Run_Scripter(">ti4", 4,0);
+ Run_Scripter(">ti4", 4, 0);
}
#endif
@@ -169,7 +169,7 @@ FS *fsp;
#ifdef LITTLEFS_SCRIPT_SIZE
-void SaveFile(const char *name,const uint8_t *buf,uint32_t len) {
+void SaveFile(const char *name, const uint8_t *buf, uint32_t len) {
File file = fsp->open(name, "w");
if (!file) return;
file.write(buf, len);
@@ -179,7 +179,7 @@ void SaveFile(const char *name,const uint8_t *buf,uint32_t len) {
uint8_t fs_mounted=0;
-void LoadFile(const char *name,uint8_t *buf,uint32_t len) {
+void LoadFile(const char *name, uint8_t *buf, uint32_t len) {
if (!fs_mounted) {
#ifdef ESP32
if (!SPIFFS.begin(FORMAT_SPIFFS_IF_FAILED)) {
@@ -214,7 +214,7 @@ FS *fsp;
#else
SDClass *fsp;
#endif
-#endif
+#endif //USE_SCRIPT_FATFS
#ifndef ESP32
// esp8266
@@ -404,7 +404,7 @@ struct SCRIPT_MEM {
FILE_FLAGS file_flags[SFS_MAX];
uint8_t script_sd_found;
char flink[2][14];
-#endif
+#endif //USE_SCRIPT_FATFS
#ifdef USE_SCRIPT_GLOBVARS
UDP_FLAGS udp_flags;
#endif
@@ -423,8 +423,8 @@ char * IPAddressToString(const IPAddress& ip_address) {
sprintf_P(ipbuffer, PSTR("%u.%u.%u.%u"), ip_address[0], ip_address[1], ip_address[2], ip_address[3]);
return ipbuffer;
}
-#endif
-#endif
+#endif //USE_DEVICE_GROUPS
+#endif //USE_SCRIPT_GLOBVARS
int16_t last_findex;
int16_t last_sindex;
@@ -436,10 +436,10 @@ uint32_t script_lastmillis;
#ifdef USE_BUTTON_EVENT
int8_t script_button[MAX_KEYS];
-#endif
+#endif //USE_BUTTON_EVENT
-char *GetNumericResult(char *lp,uint8_t lastop,float *fp,JsonObject *jo);
-char *GetStringResult(char *lp,uint8_t lastop,char *cp,JsonObject *jo);
+char *GetNumericArgument(char *lp,uint8_t lastop,float *fp,JsonObject *jo);
+char *GetStringArgument(char *lp,uint8_t lastop,char *cp,JsonObject *jo);
char *ForceStringVar(char *lp,char *dstr);
void send_download(void);
uint8_t reject(char *name);
@@ -447,75 +447,80 @@ uint8_t reject(char *name);
void ScriptEverySecond(void) {
if (bitRead(Settings.rule_enabled, 0)) {
- struct T_INDEX *vtp=glob_script_mem.type;
- float delta=(millis()-script_lastmillis)/1000.0;
- script_lastmillis=millis();
+ struct T_INDEX *vtp = glob_script_mem.type;
+ float delta = (millis() - script_lastmillis) / 1000.0;
+ script_lastmillis = millis();
for (uint8_t count=0; count0) {
// decrement
- *fp-=delta;
- if (*fp<0) *fp=0;
+ *fp -= delta;
+ if (*fp<0) *fp = 0;
}
}
if (vtp[count].bits.is_autoinc) {
// increments timers
- float *fp=&glob_script_mem.fvars[vtp[count].index];
+ float *fp = &glob_script_mem.fvars[vtp[count].index];
if (*fp>=0) {
- *fp+=delta;
+ *fp += delta;
}
}
}
- Run_Scripter(">S",2,0);
+ Run_Scripter(">S", 2, 0);
}
}
void RulesTeleperiod(void) {
- if (bitRead(Settings.rule_enabled, 0) && mqtt_data[0]) Run_Scripter(">T",2, mqtt_data);
+ if (bitRead(Settings.rule_enabled, 0) && mqtt_data[0]) Run_Scripter(">T", 2, mqtt_data);
}
// EEPROM MACROS
// i2c eeprom
-#define EEP_WRITE(A,B,C) eeprom_writeBytes(A,B,(uint8_t*)C);
-#define EEP_READ(A,B,C) eeprom_readBytes(A,B,(uint8_t*)C);
+#define EEP_WRITE(A,B,C) eeprom_writeBytes(A, B, (uint8_t*)C);
+#define EEP_READ(A,B,C) eeprom_readBytes(A, B, (uint8_t*)C);
#define SCRIPT_SKIP_SPACES while (*lp==' ' || *lp=='\t') lp++;
#define SCRIPT_SKIP_EOL while (*lp==SCRIPT_EOL) lp++;
-float *Get_MFAddr(uint8_t index,uint16_t *len,uint16_t *ipos);
+float *Get_MFAddr(uint8_t index, uint16_t *len, uint16_t *ipos);
// allocates all variables and presets them
int16_t Init_Scripter(void) {
char *script;
- script=glob_script_mem.script_ram;
+ script = glob_script_mem.script_ram;
// scan lines for >DEF
- uint16_t lines=0,nvars=0,svars=0,vars=0;
- char *lp=script;
+ uint16_t lines = 0;
+ uint16_t nvars = 0;
+ uint16_t svars = 0;
+ uint16_t vars = 0;
+ char *lp = script;
char vnames[MAXVARS*10];
- char *vnames_p=vnames;
+ char *vnames_p = vnames;
char *vnp[MAXVARS];
- char **vnp_p=vnp;
+ char **vnp_p = vnp;
char strings[MAXSVARS*SCRIPT_MAXSSIZE];
struct M_FILT mfilt[MAXFILT];
- char *strings_p=strings;
+ char *strings_p = strings;
char *snp[MAXSVARS];
- char **snp_p=snp;
- uint8_t numperm=0,numflt=0,count;
+ char **snp_p = snp;
+ uint8_t numperm = 0;
+ uint8_t numflt = 0;
+ uint8_t count;
- glob_script_mem.max_ssize=SCRIPT_SVARSIZE;
- glob_script_mem.scriptptr=0;
+ glob_script_mem.max_ssize = SCRIPT_SVARSIZE;
+ glob_script_mem.scriptptr = 0;
if (!*script) return -999;
float fvalues[MAXVARS];
struct T_INDEX vtypes[MAXVARS];
- char init=0;
+ char init = 0;
while (1) {
// check line
// skip leading spaces
@@ -527,84 +532,84 @@ char *script;
if (init) {
// init section
if (*lp=='>' || !*lp) {
- init=0;
+ init = 0;
break;
}
- char *op=strchr(lp,'=');
+ char *op = strchr(lp, '=');
if (op) {
- vtypes[vars].bits.data=0;
+ vtypes[vars].bits.data = 0;
// found variable definition
if (*lp=='p' && *(lp+1)==':') {
- lp+=2;
+ lp += 2;
if (numpermMAXFILT) {
return -6;
}
} else {
- vtypes[vars].bits.is_filter=0;
+ vtypes[vars].bits.is_filter = 0;
}
- *vnp_p++=vnames_p;
+ *vnp_p ++= vnames_p;
while (lpMAXNVARS) {
return -1;
@@ -616,27 +621,27 @@ char *script;
while (*op==' ') op++;
if (isdigit(*op)) {
// lenght define follows
- uint16_t flen=atoi(op);
+ uint16_t flen = atoi(op);
if (flen>MAX_ARRAY_SIZE) {
// limit array size
- flen=MAX_ARRAY_SIZE;
+ flen = MAX_ARRAY_SIZE;
}
- mfilt[numflt-1].numvals&=OR_FILT_MASK;
- mfilt[numflt-1].numvals|=flen&AND_FILT_MASK;
+ mfilt[numflt-1].numvals &= OR_FILT_MASK;
+ mfilt[numflt-1].numvals |= flen&AND_FILT_MASK;
}
}
} else {
// string vars
op++;
- *snp_p++=strings_p;
+ *snp_p ++= strings_p;
while (*op!='\"') {
if (*op==SCRIPT_EOL) break;
- *strings_p++=*op++;
+ *strings_p++ = *op++;
}
- *strings_p++=0;
- vtypes[vars].bits.is_string=1;
- vtypes[vars].index=svars;
+ *strings_p++ = 0;
+ vtypes[vars].bits.is_string = 1;
+ vtypes[vars].index = svars;
svars++;
if (svars>MAXSVARS) {
return -2;
@@ -648,15 +653,15 @@ char *script;
}
}
} else {
- if (!strncmp(lp,">D",2)) {
- lp+=2;
+ if (!strncmp(lp, ">D", 2)) {
+ lp += 2;
SCRIPT_SKIP_SPACES
if (isdigit(*lp)) {
- uint8_t ssize=atoi(lp)+1;
+ uint8_t ssize = atoi(lp)+1;
if (ssize<10 || ssize>SCRIPT_MAXSSIZE) ssize=SCRIPT_MAXSSIZE;
- glob_script_mem.max_ssize=ssize;
+ glob_script_mem.max_ssize = ssize;
}
- init=1;
+ init = 1;
}
}
// next line
@@ -666,78 +671,78 @@ char *script;
lp++;
}
- uint16_t fsize=0;
+ uint16_t fsize = 0;
for (count=0; countnumvals=mfilt[count].numvals;
- mp+=sizeof(struct M_FILT)+((mfilt[count].numvals&AND_FILT_MASK)-1)*sizeof(float);
+ uint8_t *mp = (uint8_t*)glob_script_mem.mfilt;
+ for (count = 0; countnumvals = mfilt[count].numvals;
+ mp += sizeof(struct M_FILT) + ((mfilt[count].numvals & AND_FILT_MASK) - 1) * sizeof(float);
}
- glob_script_mem.numvars=vars;
- glob_script_mem.script_dprec=SCRIPT_FLOAT_PRECISION;
- glob_script_mem.script_loglevel=LOG_LEVEL_INFO;
+ glob_script_mem.numvars = vars;
+ glob_script_mem.script_dprec = SCRIPT_FLOAT_PRECISION;
+ glob_script_mem.script_loglevel = LOG_LEVEL_INFO;
#if SCRIPT_DEBUG>2
- struct T_INDEX *dvtp=glob_script_mem.type;
- for (uint8_t count=0; count=0
// user sd card
- fsp=&SD;
+ fsp = &SD;
if (SD.begin(USE_SCRIPT_FATFS)) {
#else
// use flash file
@@ -836,35 +841,35 @@ char *script;
if (FFat.begin(true)) {
#else
if (fsp->begin()) {
-#endif
+#endif // ESP32
#endif // USE_SCRIPT_FATFS>=0
- glob_script_mem.script_sd_found=1;
+ glob_script_mem.script_sd_found = 1;
} else {
- glob_script_mem.script_sd_found=0;
+ glob_script_mem.script_sd_found = 0;
}
}
- for (uint8_t cnt=0;cnt0
ClaimSerial();
SetSerialBaudrate(9600);
-#endif
+#endif //SCRIPT_DEBUG
// store start of actual program here
- glob_script_mem.scriptptr=lp-1;
- glob_script_mem.scriptptr_bu=glob_script_mem.scriptptr;
+ glob_script_mem.scriptptr = lp - 1;
+ glob_script_mem.scriptptr_bu = glob_script_mem.scriptptr;
#ifdef USE_SCRIPT_GLOBVARS
if (glob_script_mem.udp_flags.udp_used) {
Script_Init_UDP();
- glob_script=Run_Scripter(">G",-2,0);
+ glob_script = Run_Scripter(">G", -2, 0);
}
-#endif
+#endif //USE_SCRIPT_GLOBVARS
return 0;
@@ -899,42 +904,42 @@ void Script_PollUdp(void) {
if (glob_script_mem.udp_flags.udp_connected ) {
while (Script_PortUdp.parsePacket()) {
char packet_buffer[SCRIPT_UDP_BUFFER_SIZE];
- int32_t len = Script_PortUdp.read(packet_buffer, SCRIPT_UDP_BUFFER_SIZE -1);
+ int32_t len = Script_PortUdp.read(packet_buffer, SCRIPT_UDP_BUFFER_SIZE - 1);
packet_buffer[len] = 0;
script_udp_remote_ip = Script_PortUdp.remoteIP();
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("UDP: Packet %s - %d - %s"), packet_buffer, len, script_udp_remote_ip.toString().c_str());
char *lp=packet_buffer;
- if (!strncmp(lp,"=>",2)) {
- lp+=2;
- char *cp=strchr(lp,'=');
+ if (!strncmp(lp,"=>", 2)) {
+ lp += 2;
+ char *cp=strchr(lp, '=');
if (cp) {
char vnam[32];
- for (uint32_t count=0; countG",2,0);
+ Run_Scripter(">G", 2, 0);
}
}
}
@@ -950,167 +955,169 @@ void script_udp_sendvar(char *vname,float *fp,char *sp) {
if (!glob_script_mem.udp_flags.udp_used) return;
if (!glob_script_mem.udp_flags.udp_connected) return;
- char sbuf[SCRIPT_MAXSSIZE+4];
- strcpy(sbuf,"=>");
- strcat(sbuf,vname);
- strcat(sbuf,"=");
+ char sbuf[SCRIPT_MAXSSIZE + 4];
+ strcpy(sbuf, "=>");
+ strcat(sbuf, vname);
+ strcat(sbuf, "=");
if (fp) {
char flstr[16];
- dtostrfd(*fp,8,flstr);
- strcat(sbuf,flstr);
- AddLog_P2(LOG_LEVEL_DEBUG, PSTR("num var updated - %s"),sbuf);
+ dtostrfd(*fp, 8, flstr);
+ strcat(sbuf, flstr);
+ AddLog_P2(LOG_LEVEL_DEBUG, PSTR("num var updated - %s"), sbuf);
} else {
- strcat(sbuf,sp);
- AddLog_P2(LOG_LEVEL_DEBUG, PSTR("string var updated - %s"),sbuf);
+ strcat(sbuf, sp);
+ AddLog_P2(LOG_LEVEL_DEBUG, PSTR("string var updated - %s"), sbuf);
}
- Script_PortUdp.beginPacket(IPAddress(239,255,255,250), SCRIPT_UDP_PORT);
+ Script_PortUdp.beginPacket(IPAddress(239, 255, 255, 250), SCRIPT_UDP_PORT);
// Udp.print(String("RET UC: ") + String(recv_Packet));
- Script_PortUdp.write((const uint8_t*)sbuf,strlen(sbuf));
+ Script_PortUdp.write((const uint8_t*)sbuf, strlen(sbuf));
Script_PortUdp.endPacket();
}
-#endif
+#endif //USE_SCRIPT_GLOBVARS
#ifdef USE_LIGHT
#ifdef USE_WS2812
void ws2812_set_array(float *array ,uint32_t len, uint32_t offset) {
Ws2812ForceSuspend();
- for (uint32_t cnt=0;cntSettings.light_pixels) break;
- uint32_t col=array[cnt];
- Ws2812SetColor(index+1,col>>16,col>>8,col,0);
+ uint32_t col = array[cnt];
+ Ws2812SetColor(index + 1, col>>16, col>>8, col, 0);
}
Ws2812ForceUpdate();
}
-#endif
-#endif
+#endif //USE_WS2812
+#endif //USE_LIGHT
-float median_array(float *array,uint16_t len) {
+float median_array(float *array, uint16_t len) {
uint8_t ind[len];
- uint8_t mind=0,index=0,flg;
- float min=FLT_MAX;
+ uint8_t mind = 0;
+ uint8_t index = 0;
+ uint8_t flg;
+ float min = FLT_MAX;
- for (uint8_t hcnt=0; hcntnumvals&AND_FILT_MASK;
- if (ipos) *ipos=mflp->index;
+ *len = mflp->numvals & AND_FILT_MASK;
+ if (ipos) *ipos = mflp->index;
return mflp->rbuff;
}
- mp+=sizeof(struct M_FILT)+((mflp->numvals&AND_FILT_MASK)-1)*sizeof(float);
+ mp += sizeof(struct M_FILT) + ((mflp->numvals & AND_FILT_MASK) - 1) * sizeof(float);
}
return 0;
}
-float Get_MFVal(uint8_t index,int16_t bind) {
- uint8_t *mp=(uint8_t*)glob_script_mem.mfilt;
- for (uint8_t count=0; countnumvals&AND_FILT_MASK;
+ uint16_t maxind = mflp->numvals & AND_FILT_MASK;
if (!bind) {
return mflp->index;
}
if (bind<0) {
return maxind;
}
- if (bind<1 || bind>maxind) bind=maxind;
- return mflp->rbuff[bind-1];
+ if (bind<1 || bind>maxind) bind = maxind;
+ return mflp->rbuff[bind - 1];
}
- mp+=sizeof(struct M_FILT)+((mflp->numvals&AND_FILT_MASK)-1)*sizeof(float);
+ mp += sizeof(struct M_FILT) + ((mflp->numvals & AND_FILT_MASK) - 1) * sizeof(float);
}
return 0;
}
-void Set_MFVal(uint8_t index,uint16_t bind,float val) {
- uint8_t *mp=(uint8_t*)glob_script_mem.mfilt;
- for (uint8_t count=0; countnumvals&AND_FILT_MASK;
+ uint16_t maxind = mflp->numvals & AND_FILT_MASK;
if (!bind) {
- mflp->index=val;
+ mflp->index = val;
} else {
- if (bind<1 || bind>maxind) bind=maxind;
- mflp->rbuff[bind-1]=val;
+ if (bind<1 || bind>maxind) bind = maxind;
+ mflp->rbuff[bind-1] = val;
}
return;
}
- mp+=sizeof(struct M_FILT)+((mflp->numvals&AND_FILT_MASK)-1)*sizeof(float);
+ mp += sizeof(struct M_FILT) + ((mflp->numvals & AND_FILT_MASK) - 1) * sizeof(float);
}
}
float Get_MFilter(uint8_t index) {
- uint8_t *mp=(uint8_t*)glob_script_mem.mfilt;
- for (uint8_t count=0; countnumvals&OR_FILT_MASK) {
+ if (mflp->numvals & OR_FILT_MASK) {
// moving average
- return mflp->maccu/(mflp->numvals&AND_FILT_MASK);
+ return mflp->maccu / (mflp->numvals & AND_FILT_MASK);
} else {
// median, sort array indices
- return median_array(mflp->rbuff,mflp->numvals);
+ return median_array(mflp->rbuff, mflp->numvals);
}
}
- mp+=sizeof(struct M_FILT)+((mflp->numvals&AND_FILT_MASK)-1)*sizeof(float);
+ mp += sizeof(struct M_FILT) + ((mflp->numvals & AND_FILT_MASK) - 1) * sizeof(float);
}
return 0;
}
void Set_MFilter(uint8_t index, float invar) {
- uint8_t *mp=(uint8_t*)glob_script_mem.mfilt;
- for (uint8_t count=0; countnumvals&OR_FILT_MASK) {
+ if (mflp->numvals & OR_FILT_MASK) {
// moving average
- mflp->maccu-=mflp->rbuff[mflp->index];
- mflp->maccu+=invar;
- mflp->rbuff[mflp->index]=invar;
+ mflp->maccu -= mflp->rbuff[mflp->index];
+ mflp->maccu += invar;
+ mflp->rbuff[mflp->index] = invar;
mflp->index++;
- if (mflp->index>=(mflp->numvals&AND_FILT_MASK)) mflp->index=0;
+ if (mflp->index>=(mflp->numvals&AND_FILT_MASK)) mflp->index = 0;
} else {
// median
- mflp->rbuff[mflp->index]=invar;
+ mflp->rbuff[mflp->index] = invar;
mflp->index++;
- if (mflp->index>=mflp->numvals) mflp->index=0;
+ if (mflp->index>=mflp->numvals) mflp->index = 0;
}
break;
}
- mp+=sizeof(struct M_FILT)+((mflp->numvals&AND_FILT_MASK)-1)*sizeof(float);
+ mp += sizeof(struct M_FILT) + ((mflp->numvals & AND_FILT_MASK) - 1) * sizeof(float);
}
}
@@ -1124,17 +1131,16 @@ int8_t index;
float DoMedian5(uint8_t index, float in) {
- if (index>=MEDIAN_FILTER_NUM) index=0;
+ if (index>=MEDIAN_FILTER_NUM) index = 0;
- struct MEDIAN_FILTER* mf=&script_mf[index];
- mf->buffer[mf->index]=in;
+ struct MEDIAN_FILTER* mf = &script_mf[index];
+ mf->buffer[mf->index] = in;
mf->index++;
- if (mf->index>=MEDIAN_SIZE) mf->index=0;
- return median_array(mf->buffer,MEDIAN_SIZE);
+ if (mf->index>=MEDIAN_SIZE) mf->index = 0;
+ return median_array(mf->buffer, MEDIAN_SIZE);
}
#ifdef USE_LIGHT
-//#ifdef USE_WS2812
uint32_t HSVToRGB(uint16_t hue, uint8_t saturation, uint8_t value) {
float r = 0, g = 0, b = 0;
struct HSV {
@@ -1143,9 +1149,9 @@ struct HSV {
float V;
} hsv;
-hsv.H=hue;
-hsv.S=(float)saturation/100.0;
-hsv.V=(float)value/100.0;
+hsv.H = hue;
+hsv.S = (float)saturation / 100.0;
+hsv.V = (float)value / 100.0;
if (hsv.S == 0) {
r = hsv.V;
@@ -1208,16 +1214,16 @@ if (hsv.S == 0) {
}
- uint8_t ir,ig,ib;
- ir=r*255;
- ig=g*255;
- ib=b*255;
+ uint8_t ir, ig, ib;
+ ir = r * 255;
+ ig = g * 255;
+ ib = b * 255;
- uint32_t rgb=(ir<<16)|(ig<<8)|ib;
+ uint32_t rgb = (ir<<16) | (ig<<8) | ib;
return rgb;
}
-#endif
-//#endif
+#endif //USE_LIGHT
+
#ifdef USE_ANGLE_FUNC
uint32_t pulse_time_hl;
@@ -1249,8 +1255,8 @@ uint32_t MeasurePulseTime(int32_t in) {
if (in >= 0) {
// define pin;
pt_pin = in;
- pinMode(pt_pin&0x3f,INPUT_PULLUP);
- attachInterrupt(pt_pin&0x3f, MP_Timer, CHANGE);
+ pinMode(pt_pin & 0x3f, INPUT_PULLUP);
+ attachInterrupt(pt_pin & 0x3f, MP_Timer, CHANGE);
pulse_ltime_lh = millis();
pulse_ltime_hl = millis();
return 0;
@@ -1269,26 +1275,26 @@ uint32_t MeasurePulseTime(int32_t in) {
#ifdef USE_SCRIPT_GLOBVARS
uint32_t match_vars(char *dvnam, float **fp, char **sp, uint32_t *ind) {
- uint16_t olen=strlen(dvnam);
- struct T_INDEX *vtp=glob_script_mem.type;
- for (uint32_t count=0; count ff=nothing found, fe=constant number,fd = constant string else bit 7 => 80 = string, 0 = number
// no flash strings here for performance reasons!!!
-char *isvar(char *lp, uint8_t *vtype,struct T_INDEX *tind,float *fp,char *sp,JsonObject *jo) {
- uint16_t count,len=0;
- uint8_t nres=0;
+char *isvar(char *lp, uint8_t *vtype, struct T_INDEX *tind, float *fp, char *sp, JsonObject *jo) {
+ uint16_t count,len = 0;
+ uint8_t nres = 0;
char vname[32];
- float fvar=0;
- tind->index=0;
- tind->bits.data=0;
+ float fvar = 0;
+ tind->index = 0;
+ tind->bits.data = 0;
if (isdigit(*lp) || (*lp=='-' && isdigit(*(lp+1))) || *lp=='.') {
// isnumber
if (fp) {
if (*lp=='0' && *(lp+1)=='x') {
- lp+=2;
- *fp=strtol(lp,0,16);
+ lp += 2;
+ *fp = strtol(lp, 0, 16);
} else {
- *fp=CharToFloat(lp);
+ *fp = CharToFloat(lp);
}
}
if (*lp=='-') lp++;
@@ -1324,109 +1330,109 @@ char *isvar(char *lp, uint8_t *vtype,struct T_INDEX *tind,float *fp,char *sp,Jso
if (*lp==0 || *lp==SCRIPT_EOL) break;
lp++;
}
- tind->bits.constant=1;
- tind->bits.is_string=0;
- *vtype=NUM_RES;
+ tind->bits.constant = 1;
+ tind->bits.is_string = 0;
+ *vtype = NUM_RES;
return lp;
}
if (*lp=='"') {
lp++;
while (*lp!='"') {
if (*lp==0 || *lp==SCRIPT_EOL) break;
- uint8_t iob=*lp;
+ uint8_t iob = *lp;
if (iob=='\\') {
lp++;
if (*lp=='t') {
- iob='\t';
+ iob = '\t';
} else if (*lp=='n') {
- iob='\n';
+ iob = '\n';
} else if (*lp=='r') {
- iob='\r';
+ iob = '\r';
} else if (*lp=='\\') {
- iob='\\';
+ iob = '\\';
} else {
lp--;
}
- if (sp) *sp++=iob;
+ if (sp) *sp++ = iob;
} else {
- if (sp) *sp++=iob;
+ if (sp) *sp++ = iob;
}
lp++;
}
- if (sp) *sp=0;
- *vtype=STR_RES;
- tind->bits.constant=1;
- tind->bits.is_string=1;
- return lp+1;
+ if (sp) *sp = 0;
+ *vtype = STR_RES;
+ tind->bits.constant = 1;
+ tind->bits.is_string = 1;
+ return lp + 1;
}
if (*lp=='-') {
// inverted var
- nres=1;
+ nres = 1;
lp++;
}
- const char *term="\n\r ])=+-/*%>index=VAR_NV;
- glob_script_mem.var_not_found=1;
+ *vtype = VAR_NV;
+ tind->index = VAR_NV;
+ glob_script_mem.var_not_found = 1;
return lp;
}
- struct T_INDEX *vtp=glob_script_mem.type;
+ struct T_INDEX *vtp = glob_script_mem.type;
char dvnam[32];
- strcpy (dvnam,vname);
- uint8_t olen=len;
- last_findex=-1;
- last_sindex=-1;
- char *ja=strchr(dvnam,'[');
+ strcpy (dvnam, vname);
+ uint8_t olen = len;
+ last_findex = -1;
+ last_sindex = -1;
+ char *ja = strchr(dvnam, '[');
if (ja) {
- *ja=0;
+ *ja = 0;
ja++;
- olen=strlen(dvnam);
+ olen = strlen(dvnam);
}
- for (count=0; countindex=count; // overwrite with global var index
+ if (!strncmp(cp, dvnam, olen)) {
+ uint8_t index = vtp[count].index;
+ *tind = vtp[count];
+ tind->index = count; // overwrite with global var index
if (vtp[count].bits.is_string==0) {
- *vtype=NTYPE|index;
+ *vtype = NTYPE | index;
if (vtp[count].bits.is_filter) {
if (ja) {
- lp+=olen+1;
- lp=GetNumericResult(lp,OPER_EQU,&fvar,0);
- last_findex=fvar;
- fvar=Get_MFVal(index,fvar);
- len=1;
+ lp += olen + 1;
+ lp = GetNumericArgument(lp, OPER_EQU, &fvar, 0);
+ last_findex = fvar;
+ fvar = Get_MFVal(index, fvar);
+ len = 1;
} else {
- fvar=Get_MFilter(index);
+ fvar = Get_MFilter(index);
}
} else {
- fvar=glob_script_mem.fvars[index];
+ fvar = glob_script_mem.fvars[index];
}
- if (nres) fvar=-fvar;
- if (fp) *fp=fvar;
+ if (nres) fvar = -fvar;
+ if (fp) *fp = fvar;
} else {
- *vtype=STYPE|index;
- if (sp) strlcpy(sp,glob_script_mem.glob_snp+(index*glob_script_mem.max_ssize),SCRIPT_MAXSSIZE);
+ *vtype = STYPE|index;
+ if (sp) strlcpy(sp, glob_script_mem.glob_snp + (index * glob_script_mem.max_ssize), SCRIPT_MAXSSIZE);
}
- return lp+len;
+ return lp + len;
}
}
}
@@ -1434,50 +1440,50 @@ char *isvar(char *lp, uint8_t *vtype,struct T_INDEX *tind,float *fp,char *sp,Jso
if (jo) {
// look for json input
char jvname[32];
- strcpy(jvname,vname);
+ strcpy(jvname, vname);
const char* str_value;
uint8_t aindex;
String vn;
- char *ja=strchr(jvname,'[');
+ char *ja=strchr(jvname, '[');
if (ja) {
// json array
- *ja=0;
+ *ja = 0;
ja++;
// fetch array index
float fvar;
- GetNumericResult(ja,OPER_EQU,&fvar,0);
- aindex=fvar;
- if (aindex<1 || aindex>6) aindex=1;
+ GetNumericArgument(ja, OPER_EQU, &fvar, 0);
+ aindex = fvar;
+ if (aindex<1 || aindex>6) aindex = 1;
aindex--;
}
if (jo->success()) {
- char *subtype=strchr(jvname,'#');
+ char *subtype = strchr(jvname, '#');
char *subtype2;
if (subtype) {
- *subtype=0;
+ *subtype = 0;
subtype++;
- subtype2=strchr(subtype,'#');
+ subtype2 = strchr(subtype, '#');
if (subtype2) {
- *subtype2=0;
+ *subtype2 = 0;
*subtype2++;
}
}
- vn=jvname;
+ vn = jvname;
str_value = (*jo)[vn];
if ((*jo)[vn].success()) {
if (subtype) {
- JsonObject &jobj1=(*jo)[vn];
+ JsonObject &jobj1 = (*jo)[vn];
if (jobj1.success()) {
- vn=subtype;
- jo=&jobj1;
+ vn = subtype;
+ jo = &jobj1;
str_value = (*jo)[vn];
if ((*jo)[vn].success()) {
// 2. stage
if (subtype2) {
- JsonObject &jobj2=(*jo)[vn];
+ JsonObject &jobj2 = (*jo)[vn];
if ((*jo)[vn].success()) {
- vn=subtype2;
- jo=&jobj2;
+ vn = subtype2;
+ jo = &jobj2;
str_value = (*jo)[vn];
if ((*jo)[vn].success()) {
goto skip;
@@ -1502,33 +1508,33 @@ char *isvar(char *lp, uint8_t *vtype,struct T_INDEX *tind,float *fp,char *sp,Jso
}
if (str_value && *str_value) {
if ((*jo).is(vn)) {
- if (!strncmp(str_value,"ON",2)) {
- if (fp) *fp=1;
+ if (!strncmp(str_value, "ON", 2)) {
+ if (fp) *fp = 1;
goto nexit;
- } else if (!strncmp(str_value,"OFF",3)) {
- if (fp) *fp=0;
+ } else if (!strncmp(str_value, "OFF", 3)) {
+ if (fp) *fp = 0;
goto nexit;
} else {
- *vtype=STR_RES;
- tind->bits.constant=1;
- tind->bits.is_string=1;
- if (sp) strlcpy(sp,str_value,SCRIPT_MAXSSIZE);
- return lp+len;
+ *vtype = STR_RES;
+ tind->bits.constant = 1;
+ tind->bits.is_string = 1;
+ if (sp) strlcpy(sp, str_value, SCRIPT_MAXSSIZE);
+ return lp + len;
}
} else {
if (fp) {
- if (!strncmp(vn.c_str(),"Epoch",5)) {
- *fp=atoi(str_value)-(uint32_t)EPOCH_OFFSET;
+ if (!strncmp(vn.c_str(), "Epoch", 5)) {
+ *fp = atoi(str_value) - (uint32_t)EPOCH_OFFSET;
} else {
- *fp=CharToFloat((char*)str_value);
+ *fp = CharToFloat((char*)str_value);
}
}
nexit:
- *vtype=NUM_RES;
- tind->bits.constant=1;
- tind->bits.is_string=0;
- return lp+len;
+ *vtype = NUM_RES;
+ tind->bits.constant = 1;
+ tind->bits.is_string = 0;
+ return lp + len;
}
}
}
@@ -1539,29 +1545,28 @@ chknext:
switch (vname[0]) {
case 'a':
#ifdef USE_ANGLE_FUNC
- if (!strncmp(vname,"acos(",5)) {
- lp+=5;
- lp=GetNumericResult(lp,OPER_EQU,&fvar,0);
- fvar=acosf(fvar);
+ if (!strncmp(vname, "acos(", 5)) {
+ lp=GetNumericArgument(lp + 5, OPER_EQU, &fvar, 0);
+ fvar = acosf(fvar);
lp++;
- len=0;
+ len = 0;
goto exit;
}
#endif
- if (!strncmp(vname,"asc(",4)) {
+ if (!strncmp(vname, "asc(", 4)) {
char str[SCRIPT_MAXSSIZE];
- lp=GetStringResult(lp+4,OPER_EQU,str,0);
- fvar=str[0];
+ lp = GetStringArgument(lp + 4, OPER_EQU, str, 0);
+ fvar = str[0];
lp++;
- len=0;
+ len = 0;
goto exit;
}
- if (!strncmp(vname,"adc(",4)) {
- lp=GetNumericResult(lp+4,OPER_EQU,&fvar,0);
+ if (!strncmp(vname, "adc(", 4)) {
+ lp = GetNumericArgument(lp + 4, OPER_EQU, &fvar, 0);
while (*lp==' ') lp++;
- float fvar1=1;
+ float fvar1 = 1;
if (*lp!=')') {
- lp=GetNumericResult(lp,OPER_EQU,&fvar1,0);
+ lp = GetNumericArgument(lp, OPER_EQU, &fvar1, 0);
if (fvar1<32 || fvar1>39) fvar1 = 32;
}
lp++;
@@ -1569,146 +1574,144 @@ chknext:
#ifdef ESP32
// ESP32
#ifdef USE_ADC
- fvar=AdcRead(fvar1, fvar);
+ fvar = AdcRead(fvar1, fvar);
#else
- fvar=999.999;
+ fvar = 999.999;
#endif // USE_ADC
#else
// ESP8266
#ifndef USE_ADC_VCC
- fvar=AdcRead(fvar);
+ fvar = AdcRead(fvar);
#else
- fvar=(float)ESP.getVcc()/1000.0;
+ fvar = (float)ESP.getVcc() / 1000.0;
#endif // USE_ADC_VCC
#endif // ESP32
- len=0;
+ len = 0;
goto exit;
}
break;
case 'b':
- if (!strncmp(vname,"boot",4)) {
+ if (!strncmp(vname, "boot", 4)) {
if (rules_flag.system_boot) {
- rules_flag.system_boot=0;
- fvar=1;
+ rules_flag.system_boot = 0;
+ fvar = 1;
}
goto exit;
}
#ifdef USE_BUTTON_EVENT
- if (!strncmp(vname,"bt[",3)) {
+ if (!strncmp(vname, "bt[", 3)) {
// tasmota button state
- GetNumericResult(vname+3,OPER_EQU,&fvar,0);
- uint32_t index=fvar;
- if (index<1 || index>MAX_KEYS) index=1;
- fvar=script_button[index-1];
- script_button[index-1]|=0x80;
+ GetNumericArgument(vname+3, OPER_EQU, &fvar, 0);
+ uint32_t index = fvar;
+ if (index<1 || index>MAX_KEYS) index = 1;
+ fvar=script_button[index - 1];
+ script_button[index - 1] |= 0x80;
len++;
goto exit;
}
-#endif
+#endif //USE_BUTTON_EVENT
break;
case 'c':
- if (!strncmp(vname,"chg[",4)) {
+ if (!strncmp(vname, "chg[", 4)) {
// var changed
struct T_INDEX ind;
uint8_t vtype;
- isvar(vname+4,&vtype,&ind,0,0,0);
+ isvar(vname + 4, &vtype, &ind, 0, 0, 0);
if (!ind.bits.constant) {
- uint8_t index=glob_script_mem.type[ind.index].index;
- if (glob_script_mem.fvars[index]!=glob_script_mem.s_fvars[index]) {
+ uint8_t index = glob_script_mem.type[ind.index].index;
+ if (glob_script_mem.fvars[index] != glob_script_mem.s_fvars[index]) {
// var has changed
- glob_script_mem.s_fvars[index]=glob_script_mem.fvars[index];
- fvar=1;
+ glob_script_mem.s_fvars[index] = glob_script_mem.fvars[index];
+ fvar = 1;
len++;
goto exit;
} else {
- fvar=0;
+ fvar = 0;
len++;
goto exit;
}
}
}
#ifdef ESP32
- if (!strncmp(vname,"core",4)) {
- fvar=xPortGetCoreID();
+ if (!strncmp(vname, "core", 4)) {
+ fvar = xPortGetCoreID();
goto exit;
}
#ifdef USE_SCRIPT_TASK
- if (!strncmp(vname,"ct(",3)) {
- lp+=3;
- lp=GetNumericResult(lp,OPER_EQU,&fvar,0);
+ if (!strncmp(vname, "ct(", 3)) {
+ lp = GetNumericArgument(lp + 3, OPER_EQU, &fvar, 0);
while (*lp==' ') lp++;
float fvar1;
- lp=GetNumericResult(lp,OPER_EQU,&fvar1,0);
+ lp = GetNumericArgument(lp, OPER_EQU, &fvar1, 0);
while (*lp==' ') lp++;
float fvar2;
- lp=GetNumericResult(lp,OPER_EQU,&fvar2,0);
+ lp = GetNumericArgument(lp, OPER_EQU, &fvar2, 0);
lp++;
- fvar=scripter_create_task(fvar,fvar1,fvar2);
- len=0;
+ fvar = scripter_create_task(fvar, fvar1, fvar2);
+ len = 0;
goto exit;
}
-#endif
-#endif
+#endif //USE_SCRIPT_TASK
+#endif //ESP32
break;
case 'd':
- if (!strncmp(vname,"day",3)) {
- fvar=RtcTime.day_of_month;
+ if (!strncmp(vname, "day", 3)) {
+ fvar = RtcTime.day_of_month;
goto exit;
}
break;
case 'e':
- if (!strncmp(vname,"epoch",5)) {
- fvar=UtcTime()-(uint32_t)EPOCH_OFFSET;
+ if (!strncmp(vname, "epoch", 5)) {
+ fvar = UtcTime() - (uint32_t)EPOCH_OFFSET;
goto exit;
}
- if (!strncmp(vname,"eres",4)) {
- fvar=event_handeled;
- tind->index=SCRIPT_EVENT_HANDLED;
+ if (!strncmp(vname, "eres", 4)) {
+ fvar = event_handeled;
+ tind->index = SCRIPT_EVENT_HANDLED;
goto exit_settable;
}
#ifdef USE_ENERGY_SENSOR
- if (!strncmp(vname,"enrg[",5)) {
- lp+=5;
- lp=GetNumericResult(lp,OPER_EQU,&fvar,0);
+ if (!strncmp(vname, "enrg[", 5)) {
+ lp=GetNumericArgument(lp + 5, OPER_EQU, &fvar, 0);
while (*lp==' ') lp++;
switch ((uint32_t)fvar) {
case 0:
- fvar=Energy.total;
+ fvar = Energy.total;
break;
case 1:
- fvar=Energy.voltage[0];
+ fvar = Energy.voltage[0];
break;
case 2:
- fvar=Energy.voltage[1];
+ fvar = Energy.voltage[1];
break;
case 3:
- fvar=Energy.voltage[2];
+ fvar = Energy.voltage[2];
break;
case 4:
- fvar=Energy.current[0];
+ fvar = Energy.current[0];
break;
case 5:
- fvar=Energy.current[1];
+ fvar = Energy.current[1];
break;
case 6:
- fvar=Energy.current[2];
+ fvar = Energy.current[2];
break;
case 7:
- fvar=Energy.active_power[0];
+ fvar = Energy.active_power[0];
break;
case 8:
- fvar=Energy.active_power[1];
+ fvar = Energy.active_power[1];
break;
case 9:
- fvar=Energy.active_power[2];
+ fvar = Energy.active_power[2];
break;
default:
- fvar=99999;
+ fvar = 99999;
break;
}
- len=0;
+ len = 0;
lp++;
goto exit;
}
@@ -1717,166 +1720,161 @@ chknext:
case 'f':
//#define DEBUG_FS
#ifdef USE_SCRIPT_FATFS
- if (!strncmp(vname,"fo(",3)) {
- lp+=3;
+ if (!strncmp(vname, "fo(", 3)) {
char str[SCRIPT_MAXSSIZE];
- lp=GetStringResult(lp,OPER_EQU,str,0);
+ lp = GetStringArgument(lp + 3, OPER_EQU, str, 0);
while (*lp==' ') lp++;
- uint8_t mode=0;
+ uint8_t mode = 0;
if ((*lp=='r') || (*lp=='w') || (*lp=='a')) {
switch (*lp) {
case 'r':
- mode=0;
+ mode = 0;
break;
case 'w':
- mode=1;
+ mode = 1;
break;
case 'a':
- mode=2;
+ mode = 2;
break;
}
lp++;
} else {
- lp=GetNumericResult(lp,OPER_EQU,&fvar,0);
- mode=fvar;
+ lp = GetNumericArgument(lp, OPER_EQU, &fvar, 0);
+ mode = fvar;
}
- fvar=-1;
- for (uint8_t cnt=0;cntopen(str,FILE_READ);
+ glob_script_mem.files[cnt] = fsp->open(str, FILE_READ);
if (glob_script_mem.files[cnt].isDirectory()) {
glob_script_mem.files[cnt].rewindDirectory();
- glob_script_mem.file_flags[cnt].is_dir=1;
+ glob_script_mem.file_flags[cnt].is_dir = 1;
} else {
- glob_script_mem.file_flags[cnt].is_dir=0;
+ glob_script_mem.file_flags[cnt].is_dir = 0;
}
}
else {
if (mode==1) {
- glob_script_mem.files[cnt]=fsp->open(str,FILE_WRITE);
+ glob_script_mem.files[cnt] = fsp->open(str,FILE_WRITE);
#ifdef DEBUG_FS
- AddLog_P2(LOG_LEVEL_INFO,PSTR("open file for write %d"),cnt);
+ AddLog_P2(LOG_LEVEL_INFO, PSTR("open file for write %d"), cnt);
#endif
} else {
- glob_script_mem.files[cnt]=fsp->open(str,FILE_APPEND);
+ glob_script_mem.files[cnt] = fsp->open(str,FILE_APPEND);
#ifdef DEBUG_FS
- AddLog_P2(LOG_LEVEL_INFO,PSTR("open file for append %d"),cnt);
+ AddLog_P2(LOG_LEVEL_INFO, PSTR("open file for append %d"), cnt);
#endif
}
}
if (glob_script_mem.files[cnt]) {
- fvar=cnt;
- glob_script_mem.file_flags[cnt].is_open=1;
+ fvar = cnt;
+ glob_script_mem.file_flags[cnt].is_open = 1;
} else {
- AddLog_P(LOG_LEVEL_INFO,PSTR("file open failed"));
+ AddLog_P(LOG_LEVEL_INFO, PSTR("file open failed"));
}
break;
}
}
lp++;
- len=0;
+ len = 0;
goto exit;
}
- if (!strncmp(vname,"fc(",3)) {
- lp+=3;
- lp=GetNumericResult(lp,OPER_EQU,&fvar,0);
+ if (!strncmp(vname, "fc(", 3)) {
+ lp = GetNumericArgument(lp + 3, OPER_EQU, &fvar, 0);
if (fvar>=0) {
- uint8_t ind=fvar;
- if (ind>=SFS_MAX) ind=SFS_MAX-1;
+ uint8_t ind = fvar;
+ if (ind>=SFS_MAX) ind = SFS_MAX - 1;
#ifdef DEBUG_FS
- AddLog_P2(LOG_LEVEL_INFO,PSTR("closing file %d"),ind);
+ AddLog_P2(LOG_LEVEL_INFO, PSTR("closing file %d"), ind);
#endif
glob_script_mem.files[ind].close();
- glob_script_mem.file_flags[ind].is_open=0;
+ glob_script_mem.file_flags[ind].is_open = 0;
}
- fvar=0;
+ fvar = 0;
lp++;
- len=0;
+ len = 0;
goto exit;
}
- if (!strncmp(vname,"ff(",3)) {
- lp+=3;
- lp=GetNumericResult(lp,OPER_EQU,&fvar,0);
- uint8_t ind=fvar;
- if (ind>=SFS_MAX) ind=SFS_MAX-1;
+ if (!strncmp(vname, "ff(", 3)) {
+ lp = GetNumericArgument(lp + 3, OPER_EQU, &fvar, 0);
+ uint8_t ind = fvar;
+ if (ind>=SFS_MAX) ind = SFS_MAX - 1;
glob_script_mem.files[ind].flush();
- fvar=0;
+ fvar = 0;
lp++;
- len=0;
+ len = 0;
goto exit;
}
- if (!strncmp(vname,"fw(",3)) {
- lp+=3;
+ if (!strncmp(vname, "fw(", 3)) {
char str[SCRIPT_MAXSSIZE];
- lp=ForceStringVar(lp,str);
+ lp = ForceStringVar(lp + 3, str);
while (*lp==' ') lp++;
- lp=GetNumericResult(lp,OPER_EQU,&fvar,0);
- uint8_t ind=fvar;
- if (ind>=SFS_MAX) ind=SFS_MAX-1;
+ lp = GetNumericArgument(lp, OPER_EQU, &fvar, 0);
+ uint8_t ind = fvar;
+ if (ind>=SFS_MAX) ind = SFS_MAX - 1;
if (glob_script_mem.file_flags[ind].is_open) {
- fvar=glob_script_mem.files[ind].print(str);
+ fvar = glob_script_mem.files[ind].print(str);
} else {
- fvar=0;
+ fvar = 0;
}
lp++;
- len=0;
+ len = 0;
goto exit;
}
- if (!strncmp(vname,"fr(",3)) {
- lp+=3;
+ if (!strncmp(vname, "fr(", 3)) {
struct T_INDEX ind;
uint8_t vtype;
- uint8_t sindex=0;
- lp=isvar(lp,&vtype,&ind,0,0,0);
+ uint8_t sindex = 0;
+ lp = isvar(lp + 3, &vtype, &ind, 0, 0, 0);
if (vtype!=VAR_NV) {
// found variable as result
if ((vtype&STYPE)==0) {
// error
- fvar=0;
+ fvar = 0;
goto exit;
} else {
// string result
- sindex=glob_script_mem.type[ind.index].index;
+ sindex = glob_script_mem.type[ind.index].index;
}
} else {
// error
- fvar=0;
+ fvar = 0;
goto exit;
}
while (*lp==' ') lp++;
- lp=GetNumericResult(lp,OPER_EQU,&fvar,0);
- uint8_t find=fvar;
- if (find>=SFS_MAX) find=SFS_MAX-1;
- uint8_t index=0;
- char str[glob_script_mem.max_ssize+1];
- char *cp=str;
+ lp = GetNumericArgument(lp, OPER_EQU, &fvar, 0);
+ uint8_t find = fvar;
+ if (find>=SFS_MAX) find = SFS_MAX - 1;
+ uint8_t index = 0;
+ char str[glob_script_mem.max_ssize + 1];
+ char *cp = str;
if (glob_script_mem.file_flags[find].is_open) {
if (glob_script_mem.file_flags[find].is_dir) {
while (true) {
- File entry=glob_script_mem.files[find].openNextFile();
+ File entry = glob_script_mem.files[find].openNextFile();
if (entry) {
if (!reject((char*)entry.name())) {
- char *ep=(char*)entry.name();
+ char *ep = (char*)entry.name();
if (*ep=='/') ep++;
char *lcp = strrchr(ep,'/');
if (lcp) {
- ep=lcp+1;
+ ep = lcp + 1;
}
- strcpy(str,ep);
+ strcpy(str, ep);
entry.close();
break;
}
} else {
- *cp=0;
+ *cp = 0;
break;
}
entry.close();
}
- index=strlen(str);
+ index = strlen(str);
} else {
while (glob_script_mem.files[find].available()) {
uint8_t buf[1];
@@ -1884,244 +1882,234 @@ chknext:
if (buf[0]=='\t' || buf[0]==',' || buf[0]=='\n' || buf[0]=='\r') {
break;
} else {
- *cp++=buf[0];
+ *cp++ = buf[0];
index++;
- if (index>=glob_script_mem.max_ssize-1) break;
+ if (index>=glob_script_mem.max_ssize - 1) break;
}
}
- *cp=0;
+ *cp = 0;
}
} else {
- strcpy(str,"file error");
+ strcpy(str, "file error");
}
lp++;
- strlcpy(glob_script_mem.glob_snp+(sindex*glob_script_mem.max_ssize),str,glob_script_mem.max_ssize);
- fvar=index;
- len=0;
+ strlcpy(glob_script_mem.glob_snp + (sindex * glob_script_mem.max_ssize), str, glob_script_mem.max_ssize);
+ fvar = index;
+ len = 0;
goto exit;
}
- if (!strncmp(vname,"fd(",3)) {
- lp+=3;
- char str[glob_script_mem.max_ssize+1];
- lp=GetStringResult(lp,OPER_EQU,str,0);
+ if (!strncmp(vname, "fd(", 3)) {
+ char str[glob_script_mem.max_ssize + 1];
+ lp = GetStringArgument(lp + 3, OPER_EQU, str, 0);
fsp->remove(str);
lp++;
- len=0;
+ len = 0;
goto exit;
}
#if defined(ESP32) && defined(USE_WEBCAM)
- if (!strncmp(vname,"fwp(",4)) {
- lp+=4;
- lp=GetNumericResult(lp,OPER_EQU,&fvar,0);
+ if (!strncmp(vname, "fwp(", 4)) {
+ lp = GetNumericArgument(lp + 4, OPER_EQU, &fvar, 0);
while (*lp==' ') lp++;
float fvar1;
- lp=GetNumericResult(lp,OPER_EQU,&fvar1,0);
- uint8_t ind=fvar1;
- if (ind>=SFS_MAX) ind=SFS_MAX-1;
+ lp = GetNumericArgument(lp, OPER_EQU, &fvar1, 0);
+ uint8_t ind = fvar1;
+ if (ind>=SFS_MAX) ind = SFS_MAX - 1;
if (glob_script_mem.file_flags[ind].is_open) {
uint8_t *buff;
- float maxps=WcGetPicstore(-1,0);
- if (fvar<1 || fvar>maxps) fvar=1;
- uint32_t len=WcGetPicstore(fvar-1, &buff);
+ float maxps = WcGetPicstore(-1, 0);
+ if (fvar<1 || fvar>maxps) fvar = 1;
+ uint32_t len = WcGetPicstore(fvar - 1, &buff);
if (len) {
//glob_script_mem.files[ind].seek(0,SeekEnd);
- fvar=glob_script_mem.files[ind].write(buff,len);
+ fvar = glob_script_mem.files[ind].write(buff, len);
} else {
- fvar=0;
+ fvar = 0;
}
//AddLog_P2(LOG_LEVEL_INFO, PSTR("picture save: %d"), len);
} else {
- fvar=0;
+ fvar = 0;
}
lp++;
- len=0;
+ len = 0;
goto exit;
}
-#endif
+#endif //ESP32 && USE_WEBCAM
#ifdef USE_SCRIPT_FATFS_EXT
- if (!strncmp(vname,"fe(",3)) {
- lp+=3;
- char str[glob_script_mem.max_ssize+1];
- lp=GetStringResult(lp,OPER_EQU,str,0);
+ if (!strncmp(vname, "fe(", 3)) {
+ char str[glob_script_mem.max_ssize + 1];
+ lp = GetStringArgument(lp + 3, OPER_EQU, str, 0);
// execute script
- File ef=fsp->open(str,FILE_READ);
+ File ef = fsp->open(str, FILE_READ);
if (ef) {
- uint16_t fsiz=ef.size();
+ uint16_t fsiz = ef.size();
if (fsiz<2048) {
- char *script=(char*)calloc(fsiz+16,1);
+ char *script = (char*)calloc(fsiz + 16, 1);
if (script) {
ef.read((uint8_t*)script,fsiz);
execute_script(script);
free(script);
- fvar=1;
+ fvar = 1;
}
}
ef.close();
}
lp++;
- len=0;
+ len = 0;
goto exit;
}
- if (!strncmp(vname,"fmd(",4)) {
- lp+=4;
- char str[glob_script_mem.max_ssize+1];
- lp=GetStringResult(lp,OPER_EQU,str,0);
- fvar=fsp->mkdir(str);
+ if (!strncmp(vname, "fmd(", 4)) {
+ char str[glob_script_mem.max_ssize + 1];
+ lp = GetStringArgument(lp + 4, OPER_EQU, str, 0);
+ fvar = fsp->mkdir(str);
lp++;
- len=0;
+ len = 0;
goto exit;
}
- if (!strncmp(vname,"frd(",4)) {
- lp+=4;
- char str[glob_script_mem.max_ssize+1];
- lp=GetStringResult(lp,OPER_EQU,str,0);
- fvar=fsp->rmdir(str);
+ if (!strncmp(vname, "frd(", 4)) {
+ char str[glob_script_mem.max_ssize + 1];
+ lp = GetStringArgument(lp + 4, OPER_EQU, str, 0);
+ fvar = fsp->rmdir(str);
lp++;
- len=0;
+ len = 0;
goto exit;
}
- if (!strncmp(vname,"fx(",3)) {
- lp+=3;
- char str[glob_script_mem.max_ssize+1];
- lp=GetStringResult(lp,OPER_EQU,str,0);
- if (fsp->exists(str)) fvar=1;
- else fvar=0;
+ if (!strncmp(vname, "fx(", 3)) {
+ char str[glob_script_mem.max_ssize + 1];
+ lp = GetStringArgument(lp + 3, OPER_EQU, str, 0);
+ if (fsp->exists(str)) fvar = 1;
+ else fvar = 0;
lp++;
- len=0;
+ len = 0;
goto exit;
}
#endif // USE_SCRIPT_FATFS_EXT
- if (!strncmp(vname,"fl1(",4) || !strncmp(vname,"fl2(",4) ) {
- uint8_t lknum=*(lp+2)&3;
- lp+=4;
- char str[glob_script_mem.max_ssize+1];
- lp=GetStringResult(lp,OPER_EQU,str,0);
- if (lknum<1 || lknum>2) lknum=1;
- strlcpy(glob_script_mem.flink[lknum-1],str,14);
+ if (!strncmp(vname, "fl1(", 4) || !strncmp(vname, "fl2(", 4) ) {
+ uint8_t lknum = *(lp+2)&3;
+ char str[glob_script_mem.max_ssize + 1];
+ lp = GetStringArgument(lp + 4, OPER_EQU, str, 0);
+ if (lknum<1 || lknum>2) lknum = 1;
+ strlcpy(glob_script_mem.flink[lknum - 1], str, 14);
lp++;
- fvar=0;
- len=0;
+ fvar = 0;
+ len = 0;
goto exit;
}
- if (!strncmp(vname,"fsm",3)) {
+ if (!strncmp(vname, "fsm", 3)) {
fvar=glob_script_mem.script_sd_found;
//card_init();
goto exit;
}
#endif //USE_SCRIPT_FATFS
- if (!strncmp(vname,"freq",4)) {
+ if (!strncmp(vname, "freq", 4)) {
#ifdef ESP32
- fvar=getCpuFrequencyMhz();
+ fvar = getCpuFrequencyMhz();
#else
- fvar=ESP.getCpuFreqMHz();
+ fvar = ESP.getCpuFreqMHz();
#endif
goto exit;
}
break;
case 'g':
- if (!strncmp(vname,"gtmp",4)) {
- fvar=global_temperature_celsius;
+ if (!strncmp(vname, "gtmp", 4)) {
+ fvar = global_temperature_celsius;
goto exit;
}
- if (!strncmp(vname,"ghum",4)) {
- fvar=global_humidity;
+ if (!strncmp(vname, "ghum", 4)) {
+ fvar = global_humidity;
goto exit;
}
- if (!strncmp(vname,"gprs",4)) {
- fvar=global_pressure_hpa;
+ if (!strncmp(vname, "gprs", 4)) {
+ fvar = global_pressure_hpa;
goto exit;
}
- if (!strncmp(vname,"gtopic",6)) {
- if (sp) strlcpy(sp,SettingsText(SET_MQTT_GRP_TOPIC),glob_script_mem.max_ssize);
+ if (!strncmp(vname, "gtopic", 6)) {
+ if (sp) strlcpy(sp, SettingsText(SET_MQTT_GRP_TOPIC), glob_script_mem.max_ssize);
goto strexit;
}
#ifdef SCRIPT_GET_HTTPS_JP
- if (!strncmp(vname,"gjp(",4)) {
+ if (!strncmp(vname, "gjp(", 4)) {
char host[SCRIPT_MAXSSIZE];
- lp=GetStringResult(lp+4,OPER_EQU,host,0);
+ lp = GetStringArgument(lp + 4, OPER_EQU, host, 0);
SCRIPT_SKIP_SPACES
char path[SCRIPT_MAXSSIZE];
- lp=GetStringResult(lp,OPER_EQU,path,0);
- fvar=call2https(host,path);
+ lp = GetStringArgument(lp, OPER_EQU, path, 0);
+ fvar = call2https(host, path);
lp++;
- len=0;
+ len = 0;
goto exit;
}
-#endif
+#endif //SCRIPT_GET_HTTPS_JP
break;
case 'h':
- if (!strncmp(vname,"hours",5)) {
- fvar=RtcTime.hour;
+ if (!strncmp(vname, "hours", 5)) {
+ fvar = RtcTime.hour;
goto exit;
}
- if (!strncmp(vname,"heap",4)) {
- fvar=ESP_getFreeHeap();
+ if (!strncmp(vname, "heap", 4)) {
+ fvar = ESP_getFreeHeap();
goto exit;
}
- if (!strncmp(vname,"hn(",3)) {
- lp=GetNumericResult(lp+3,OPER_EQU,&fvar,0);
- if (fvar<0 || fvar>255) fvar=0;
+ if (!strncmp(vname, "hn(", 3)) {
+ lp = GetNumericArgument(lp + 3, OPER_EQU, &fvar, 0);
+ if (fvar<0 || fvar>255) fvar = 0;
lp++;
- len=0;
+ len = 0;
if (sp) {
- sprintf(sp,"%02x",(uint8_t)fvar);
+ sprintf(sp, "%02x", (uint8_t)fvar);
}
goto strexit;
}
- if (!strncmp(vname,"hx(",3)) {
- lp=GetNumericResult(lp+3,OPER_EQU,&fvar,0);
+ if (!strncmp(vname, "hx(", 3)) {
+ lp = GetNumericArgument(lp + 3, OPER_EQU, &fvar, 0);
lp++;
- len=0;
+ len = 0;
if (sp) {
- sprintf(sp,"%08x",(uint32_t)fvar);
+ sprintf(sp, "%08x", (uint32_t)fvar);
}
goto strexit;
}
- if (!strncmp(vname,"hd(",3)) {
+ if (!strncmp(vname, "hd(", 3)) {
char str[SCRIPT_MAXSSIZE];
- lp=GetStringResult(lp+3,OPER_EQU,str,0);
- fvar=strtol(str,NULL,16);
+ lp = GetStringArgument(lp + 3, OPER_EQU, str, 0);
+ fvar = strtol(str, NULL, 16);
lp++;
- len=0;
+ len = 0;
goto exit;
}
#ifdef USE_LIGHT
-//#ifdef USE_WS2812
- if (!strncmp(vname,"hsvrgb(",7)) {
- lp=GetNumericResult(lp+7,OPER_EQU,&fvar,0);
- if (fvar<0 || fvar>360) fvar=0;
+ if (!strncmp(vname, "hsvrgb(", 7)) {
+ lp = GetNumericArgument(lp + 7, OPER_EQU, &fvar, 0);
+ if (fvar<0 || fvar>360) fvar = 0;
SCRIPT_SKIP_SPACES
// arg2
float fvar2;
- lp=GetNumericResult(lp,OPER_EQU,&fvar2,0);
- if (fvar2<0 || fvar2>100) fvar2=0;
+ lp = GetNumericArgument(lp, OPER_EQU, &fvar2, 0);
+ if (fvar2<0 || fvar2>100) fvar2 = 0;
SCRIPT_SKIP_SPACES
// arg3
float fvar3;
- lp=GetNumericResult(lp,OPER_EQU,&fvar3,0);
- if (fvar3<0 || fvar3>100) fvar3=0;
-
- fvar=HSVToRGB(fvar,fvar2,fvar3);
+ lp = GetNumericArgument(lp, OPER_EQU, &fvar3, 0);
+ if (fvar3<0 || fvar3>100) fvar3 = 0;
+ fvar = HSVToRGB(fvar, fvar2, fvar3);
lp++;
- len=0;
+ len = 0;
goto exit;
}
-//#endif
-#endif
+#endif //USE_LIGHT
break;
#define MAX_SARRAY_NUM 32
case 'i':
- if (!strncmp(vname,"int(",4)) {
- lp=GetNumericResult(lp+4,OPER_EQU,&fvar,0);
- fvar=floor(fvar);
+ if (!strncmp(vname, "int(", 4)) {
+ lp = GetNumericArgument(lp + 4, OPER_EQU, &fvar, 0);
+ fvar = floor(fvar);
lp++;
- len=0;
+ len = 0;
goto exit;
}
- if (!strncmp(vname,"is(",3)) {
- lp=GetNumericResult(lp+3,OPER_EQU,&fvar,0);
+ if (!strncmp(vname, "is(", 3)) {
+ lp = GetNumericArgument(lp + 3, OPER_EQU, &fvar, 0);
SCRIPT_SKIP_SPACES
if (*lp!='"') {
break;
@@ -2131,15 +2119,15 @@ chknext:
if (glob_script_mem.si_num>0 && glob_script_mem.last_index_string) {
free(glob_script_mem.last_index_string);
}
- char *sstart=lp;
- uint8_t slen=0;
- for (uint32_t cnt=0; cnt<256; cnt++) {
+ char *sstart = lp;
+ uint8_t slen = 0;
+ for (uint32_t cnt = 0; cnt<256; cnt++) {
if (*lp=='\n' || *lp=='"' || *lp==0) {
lp++;
if (cnt>0 && !slen) {
slen++;
}
- glob_script_mem.siro_num=slen;
+ glob_script_mem.siro_num = slen;
break;
}
if (*lp=='|') {
@@ -2151,31 +2139,31 @@ chknext:
glob_script_mem.si_num = fvar;
if (glob_script_mem.si_num>0) {
if (glob_script_mem.si_num>MAX_SARRAY_NUM) {
- glob_script_mem.si_num=MAX_SARRAY_NUM;
+ glob_script_mem.si_num = MAX_SARRAY_NUM;
}
- glob_script_mem.last_index_string=(char*)calloc(glob_script_mem.max_ssize*glob_script_mem.si_num,1);
- for (uint32_t cnt=0; cntglob_script_mem.si_num) {
- index=glob_script_mem.si_num;
+ index = glob_script_mem.si_num;
}
- strlcpy(str,glob_script_mem.last_index_string+(index*glob_script_mem.max_ssize),glob_script_mem.max_ssize);
+ strlcpy(str,glob_script_mem.last_index_string + (index * glob_script_mem.max_ssize), glob_script_mem.max_ssize);
}
}
lp++;
- if (sp) strlcpy(sp,str,glob_script_mem.max_ssize);
- len=0;
+ if (sp) strlcpy(sp, str, glob_script_mem.max_ssize);
+ len = 0;
goto strexit;
}
break;
case 'l':
- if (!strncmp(vname,"lip",3)) {
- if (sp) strlcpy(sp,(const char*)WiFi.localIP().toString().c_str(),glob_script_mem.max_ssize);
+ if (!strncmp(vname, "lip", 3)) {
+ if (sp) strlcpy(sp, (const char*)WiFi.localIP().toString().c_str(), glob_script_mem.max_ssize);
goto strexit;
}
#ifdef USE_SCRIPT_GLOBVARS
- if (!strncmp(vname,"luip",4)) {
- if (sp) strlcpy(sp,IPAddressToString(last_udp_ip),glob_script_mem.max_ssize);
+ if (!strncmp(vname, "luip", 4)) {
+ if (sp) strlcpy(sp, IPAddressToString(last_udp_ip), glob_script_mem.max_ssize);
goto strexit;
}
-#endif
- if (!strncmp(vname,"loglvl",6)) {
- fvar=glob_script_mem.script_loglevel;
- tind->index=SCRIPT_LOGLEVEL;
+#endif //USE_SCRIPT_GLOBVARS
+ if (!strncmp(vname, "loglvl", 6)) {
+ fvar = glob_script_mem.script_loglevel;
+ tind->index = SCRIPT_LOGLEVEL;
exit_settable:
- if (fp) *fp=fvar;
- *vtype=NTYPE;
- tind->bits.settable=1;
- tind->bits.is_string=0;
- return lp+len;
+ if (fp) *fp = fvar;
+ *vtype = NTYPE;
+ tind->bits.settable = 1;
+ tind->bits.is_string = 0;
+ return lp + len;
}
break;
case 'm':
- if (!strncmp(vname,"med(",4)) {
+ if (!strncmp(vname, "med(", 4)) {
float fvar1;
- lp=GetNumericResult(lp+4,OPER_EQU,&fvar1,0);
+ lp = GetNumericArgument(lp + 4, OPER_EQU, &fvar1, 0);
SCRIPT_SKIP_SPACES
// arg2
float fvar2;
- lp=GetNumericResult(lp,OPER_EQU,&fvar2,0);
- fvar=DoMedian5(fvar1,fvar2);
+ lp = GetNumericArgument(lp, OPER_EQU, &fvar2, 0);
+ fvar = DoMedian5(fvar1, fvar2);
lp++;
- len=0;
+ len = 0;
goto exit;
}
#ifdef USE_ANGLE_FUNC
- if (!strncmp(vname,"mpt(",4)) {
- lp=GetNumericResult(lp+4,OPER_EQU,&fvar,0);
- fvar=MeasurePulseTime(fvar);
+ if (!strncmp(vname, "mpt(", 4)) {
+ lp = GetNumericArgument(lp + 4, OPER_EQU, &fvar, 0);
+ fvar = MeasurePulseTime(fvar);
lp++;
- len=0;
+ len = 0;
goto exit;
}
-#endif
- if (!strncmp(vname,"micros",6)) {
- fvar=micros();
+#endif //USE_ANGLE_FUNC
+ if (!strncmp(vname, "micros", 6)) {
+ fvar = micros();
goto exit;
}
- if (!strncmp(vname,"millis",6)) {
- fvar=millis();
+ if (!strncmp(vname, "millis", 6)) {
+ fvar = millis();
goto exit;
}
- if (!strncmp(vname,"mins",4)) {
- fvar=RtcTime.minute;
+ if (!strncmp(vname, "mins", 4)) {
+ fvar = RtcTime.minute;
goto exit;
}
- if (!strncmp(vname,"month",5)) {
- fvar=RtcTime.month;
+ if (!strncmp(vname, "month", 5)) {
+ fvar = RtcTime.month;
goto exit;
}
- if (!strncmp(vname,"mqttc",5)) {
+ if (!strncmp(vname, "mqttc", 5)) {
if (rules_flag.mqtt_connected) {
- rules_flag.mqtt_connected=0;
- fvar=1;
+ rules_flag.mqtt_connected = 0;
+ fvar = 1;
}
goto exit;
}
- if (!strncmp(vname,"mqttd",5)) {
+ if (!strncmp(vname, "mqttd", 5)) {
if (rules_flag.mqtt_disconnected) {
- rules_flag.mqtt_disconnected=0;
- fvar=1;
+ rules_flag.mqtt_disconnected = 0;
+ fvar = 1;
}
goto exit;
}
- if (!strncmp(vname,"mqtts",5)) {
- fvar=!global_state.mqtt_down;
+ if (!strncmp(vname, "mqtts", 5)) {
+ fvar = !global_state.mqtt_down;
goto exit;
}
- if (!strncmp(vname,"mp(",3)) {
- lp+=3;
+ if (!strncmp(vname, "mp(", 3)) {
float fvar1;
- lp=GetNumericResult(lp,OPER_EQU,&fvar1,0);
+ lp = GetNumericArgument(lp + 3, OPER_EQU, &fvar1, 0);
SCRIPT_SKIP_SPACES
while (*lp!=')') {
- char *opp=lp;
+ char *opp = lp;
lp++;
float fvar2;
- lp=GetNumericResult(lp,OPER_EQU,&fvar2,0);
+ lp = GetNumericArgument(lp, OPER_EQU, &fvar2, 0);
SCRIPT_SKIP_SPACES
- fvar=fvar1;
+ fvar = fvar1;
if ((*opp=='<' && fvar1' && fvar1>fvar2) ||
- (*opp=='=' && fvar1==fvar2))
- {
- if (*lp!='<' && *lp!='>' && *lp!='=' && *lp!=')' && *lp!=SCRIPT_EOL) {
- float fvar3;
- lp=GetNumericResult(lp,OPER_EQU,&fvar3,0);
- SCRIPT_SKIP_SPACES
- fvar=fvar3;
- } else {
- fvar=fvar2;
- }
- break;
+ (*opp=='=' && fvar1==fvar2)) {
+ if (*lp!='<' && *lp!='>' && *lp!='=' && *lp!=')' && *lp!=SCRIPT_EOL) {
+ float fvar3;
+ lp = GetNumericArgument(lp, OPER_EQU, &fvar3, 0);
+ SCRIPT_SKIP_SPACES
+ fvar=fvar3;
+ } else {
+ fvar = fvar2;
+ }
+ break;
}
while (*lp!='<' && *lp!='>' && *lp!='=' && *lp!=')' && *lp!=SCRIPT_EOL) lp++;
}
- len=0;
+ len = 0;
goto exit;
}
#ifdef USE_MORITZ
- if (!strncmp(vname,"mo(",3)) {
+ if (!strncmp(vname, "mo(", 3)) {
float fvar1;
- lp=GetNumericResult(lp+3,OPER_EQU,&fvar1,0);
+ lp = GetNumericArgument(lp + 3, OPER_EQU, &fvar1, 0);
SCRIPT_SKIP_SPACES
float fvar2;
- lp=GetNumericResult(lp,OPER_EQU,&fvar2,0);
+ lp = GetNumericArgument(lp, OPER_EQU, &fvar2, 0);
SCRIPT_SKIP_SPACES
char rbuff[64];
- fvar=mo_getvars(fvar1,fvar2,rbuff);
+ fvar = mo_getvars(fvar1, fvar2, rbuff);
lp++;
- if (sp) strlcpy(sp,rbuff,glob_script_mem.max_ssize);
- len=0;
+ if (sp) strlcpy(sp, rbuff, glob_script_mem.max_ssize);
+ len = 0;
goto strexit;
}
-#endif
+#endif //USE_MORITZ
break;
case 'p':
- if (!strncmp(vname,"pin[",4)) {
+ if (!strncmp(vname, "pin[", 4)) {
// raw pin level
- GetNumericResult(vname+4,OPER_EQU,&fvar,0);
- fvar=digitalRead((uint8_t)fvar);
+ GetNumericArgument(vname + 4, OPER_EQU, &fvar, 0);
+ fvar = digitalRead((uint8_t)fvar);
// skip ] bracket
len++;
goto exit;
}
- if (!strncmp(vname,"pn[",3)) {
- GetNumericResult(vname+3,OPER_EQU,&fvar,0);
- fvar=Pin(fvar);
+ if (!strncmp(vname, "pn[", 3)) {
+ GetNumericArgument(vname + 3, OPER_EQU, &fvar, 0);
+ fvar = Pin(fvar);
// skip ] bracket
len++;
goto exit;
}
#if defined(ESP32) && (defined(USE_I2S_AUDIO) || defined(USE_TTGO_WATCH))
- if (!strncmp(vname,"pl(",3)) {
+ if (!strncmp(vname, "pl(", 3)) {
char path[SCRIPT_MAXSSIZE];
- lp=GetStringResult(lp+3,OPER_EQU,path,0);
+ lp = GetStringArgument(lp + 3, OPER_EQU, path, 0);
Play_mp3(path);
len++;
- len=0;
+ len = 0;
goto exit;
}
#endif // USE_I2S_AUDIO
- if (!strncmp(vname,"pd[",3)) {
- GetNumericResult(vname+3,OPER_EQU,&fvar,0);
- uint8_t gpiopin=fvar;
+ if (!strncmp(vname, "pd[", 3)) {
+ GetNumericArgument(vname + 3, OPER_EQU, &fvar, 0);
+ uint8_t gpiopin = fvar;
/*
for (uint8_t i=0;iMAX_COUNTERS) index=1;
- fvar=RtcSettings.pulse_counter[index-1];
- len+=1;
+ if (!strncmp(vname, "pc[", 3)) {
+ GetNumericArgument(vname + 3, OPER_EQU, &fvar, 0);
+ uint8_t index = fvar;
+ if (index<1 || index>MAX_COUNTERS) index = 1;
+ fvar = RtcSettings.pulse_counter[index - 1];
+ len += 1;
goto exit;
}
break;
case 'r':
- if (!strncmp(vname,"ram",3)) {
- fvar=glob_script_mem.script_mem_size+(glob_script_mem.script_size)+(PMEM_SIZE);
+ if (!strncmp(vname, "ram", 3)) {
+ fvar = glob_script_mem.script_mem_size + (glob_script_mem.script_size) + (PMEM_SIZE);
goto exit;
}
- if (!strncmp(vname,"rnd(",4)) {
+ if (!strncmp(vname, "rnd(", 4)) {
// tasmota switch state
- GetNumericResult(vname+4,OPER_EQU,&fvar,0);
+ GetNumericArgument(vname + 4, OPER_EQU, &fvar, 0);
if (fvar<0) {
randomSeed(-fvar);
- fvar=0;
+ fvar = 0;
} else {
- fvar=random(fvar);
+ fvar = random(fvar);
}
// skip ] bracket
len++;
@@ -2444,81 +2429,78 @@ chknext:
}
break;
case 's':
- if (!strncmp(vname,"secs",4)) {
- fvar=RtcTime.second;
+ if (!strncmp(vname, "secs", 4)) {
+ fvar = RtcTime.second;
goto exit;
}
- if (!strncmp(vname,"sw[",3)) {
+ if (!strncmp(vname, "sw[", 3)) {
// tasmota switch state
- GetNumericResult(vname+3,OPER_EQU,&fvar,0);
- fvar=SwitchLastState((uint32_t)fvar);
+ GetNumericArgument(vname + 3, OPER_EQU, &fvar, 0);
+ fvar = SwitchLastState((uint32_t)fvar);
// skip ] bracket
len++;
goto exit;
}
- if (!strncmp(vname,"stack",5)) {
- fvar=GetStack();
+ if (!strncmp(vname, "stack", 5)) {
+ fvar = GetStack();
goto exit;
}
- if (!strncmp(vname,"slen",4)) {
- fvar=strlen(glob_script_mem.script_ram);
+ if (!strncmp(vname, "slen", 4)) {
+ fvar = strlen(glob_script_mem.script_ram);
goto exit;
}
- if (!strncmp(vname,"sl(",3)) {
- lp+=3;
+ if (!strncmp(vname, "sl(", 3)) {
char str[SCRIPT_MAXSSIZE];
- lp=GetStringResult(lp,OPER_EQU,str,0);
+ lp = GetStringArgument(lp + 3, OPER_EQU, str, 0);
lp++;
- len=0;
- fvar=strlen(str);
+ len = 0;
+ fvar = strlen(str);
goto exit;
}
- if (!strncmp(vname,"sb(",3)) {
- lp+=3;
+ if (!strncmp(vname, "sb(", 3)) {
char str[SCRIPT_MAXSSIZE];
- lp=GetStringResult(lp,OPER_EQU,str,0);
+ lp = GetStringArgument(lp + 3, OPER_EQU, str, 0);
SCRIPT_SKIP_SPACES
float fvar1;
- lp=GetNumericResult(lp,OPER_EQU,&fvar1,0);
+ lp = GetNumericArgument(lp, OPER_EQU, &fvar1, 0);
SCRIPT_SKIP_SPACES
float fvar2;
- lp=GetNumericResult(lp,OPER_EQU,&fvar2,0);
+ lp = GetNumericArgument(lp, OPER_EQU, &fvar2, 0);
lp++;
- len=0;
+ len = 0;
if (fvar1<0) {
- fvar1=strlen(str)+fvar1;
+ fvar1 = strlen(str) + fvar1;
}
- memcpy(sp,&str[(uint8_t)fvar1],(uint8_t)fvar2);
+ memcpy(sp, &str[(uint8_t)fvar1], (uint8_t)fvar2);
sp[(uint8_t)fvar2] = '\0';
goto strexit;
}
- if (!strncmp(vname,"st(",3)) {
- lp+=3;
+ if (!strncmp(vname, "st(", 3)) {
char str[SCRIPT_MAXSSIZE];
- lp=GetStringResult(lp,OPER_EQU,str,0);
+ lp = GetStringArgument(lp + 3, OPER_EQU, str, 0);
while (*lp==' ') lp++;
char token[2];
- token[0]=*lp++;
- token[1]=0;
+ token[0] = *lp++;
+ token[1] = 0;
while (*lp==' ') lp++;
- lp=GetNumericResult(lp,OPER_EQU,&fvar,0);
+ lp = GetNumericArgument(lp, OPER_EQU, &fvar, 0);
// skip ) bracket
lp++;
- len=0;
+ len = 0;
if (sp) {
// get stringtoken
- char *st=strtok(str,token);
+ char *st = strtok(str, token);
if (!st) {
- *sp=0;
+ *sp = 0;
} else {
- for (uint8_t cnt=1; cnt<=fvar; cnt++) {
+ for (uint8_t cnt = 1; cnt<=fvar; cnt++) {
if (cnt==fvar) {
- strcpy(sp,st);
+ strcpy(sp, st);
break;
}
- st=strtok(NULL,token);
+ st = strtok(NULL, token);
if (!st) {
- *sp=0;
+ *sp = 0;
break;
}
}
@@ -2526,249 +2508,237 @@ chknext:
}
goto strexit;
}
- if (!strncmp(vname,"s(",2)) {
- lp+=2;
- lp=GetNumericResult(lp,OPER_EQU,&fvar,0);
- char str[glob_script_mem.max_ssize+1];
- dtostrfd(fvar,glob_script_mem.script_dprec,str);
- if (sp) strlcpy(sp,str,glob_script_mem.max_ssize);
+ if (!strncmp(vname, "s(", 2)) {
+ lp = GetNumericArgument(lp + 2, OPER_EQU, &fvar, 0);
+ char str[glob_script_mem.max_ssize + 1];
+ dtostrfd(fvar, glob_script_mem.script_dprec, str);
+ if (sp) strlcpy(sp, str, glob_script_mem.max_ssize);
lp++;
- len=0;
+ len = 0;
goto strexit;
}
#if defined(ESP32) && (defined(USE_I2S_AUDIO) || defined(USE_TTGO_WATCH))
- if (!strncmp(vname,"say(",4)) {
+ if (!strncmp(vname, "say(", 4)) {
char text[SCRIPT_MAXSSIZE];
- lp=GetStringResult(lp+4,OPER_EQU,text,0);
+ lp = GetStringArgument(lp + 4, OPER_EQU, text, 0);
Say(text);
len++;
- len=0;
+ len = 0;
goto exit;
}
#endif // USE_I2S_AUDIO
#ifdef ESP32
- if (!strncmp(vname,"sf(",3)) {
- lp+=2;
- lp=GetNumericResult(lp,OPER_EQU,&fvar,0);
- if (fvar<80) fvar=80;
- if (fvar>240) fvar=240;
+ if (!strncmp(vname, "sf(", 3)) {
+ lp = GetNumericArgument(lp + 3, OPER_EQU, &fvar, 0);
+ if (fvar<80) fvar = 80;
+ if (fvar>240) fvar = 240;
setCpuFrequencyMhz(fvar);
- fvar=getCpuFrequencyMhz();
+ fvar = getCpuFrequencyMhz();
lp++;
- len=0;
+ len = 0;
goto exit;
}
-#endif
+#endif //ESP32
#ifdef USE_TTGO_WATCH
- if (!strncmp(vname,"slp(",4)) {
- lp=GetNumericResult(lp+4,OPER_EQU,&fvar,0);
+ if (!strncmp(vname, "slp(", 4)) {
+ lp = GetNumericArgument(lp + 4, OPER_EQU, &fvar, 0);
SCRIPT_SKIP_SPACES
TTGO_Sleep(fvar);
lp++;
- len=0;
+ len = 0;
goto exit;
}
-#endif
+#endif //USE_TTGO_WATCH
#if defined(USE_TIMERS) && defined(USE_SUNRISE)
- if (!strncmp(vname,"sunrise",7)) {
- fvar=SunMinutes(0);
+ if (!strncmp(vname, "sunrise", 7)) {
+ fvar = SunMinutes(0);
goto exit;
}
- if (!strncmp(vname,"sunset",6)) {
- fvar=SunMinutes(1);
+ if (!strncmp(vname, "sunset", 6)) {
+ fvar = SunMinutes(1);
goto exit;
}
-#endif
+#endif //USE_TIMERS
#ifdef USE_SHUTTER
- if (!strncmp(vname,"sht[",4)) {
- GetNumericResult(vname+4,OPER_EQU,&fvar,0);
- uint8_t index=fvar;
+ if (!strncmp(vname, "sht[", 4)) {
+ GetNumericArgument(vname + 4, OPER_EQU, &fvar, 0);
+ uint8_t index = fvar;
if (index<=shutters_present) {
- fvar=Settings.shutter_position[index-1];
+ fvar = Settings.shutter_position[index - 1];
} else {
- fvar=-1;
+ fvar = -1;
}
- len+=1;
+ len += 1;
goto exit;
}
-#endif
+#endif //USE_SHUTTER
#ifdef USE_ANGLE_FUNC
- if (!strncmp(vname,"sin(",4)) {
- lp+=4;
- lp=GetNumericResult(lp,OPER_EQU,&fvar,0);
- fvar=sinf(fvar);
+ if (!strncmp(vname, "sin(", 4)) {
+ lp = GetNumericArgument(lp + 4, OPER_EQU, &fvar, 0);
+ fvar = sinf(fvar);
lp++;
- len=0;
+ len = 0;
goto exit;
}
- if (!strncmp(vname,"sqrt(",5)) {
- lp+=5;
- lp=GetNumericResult(lp,OPER_EQU,&fvar,0);
- fvar=sqrtf(fvar);
+ if (!strncmp(vname, "sqrt(", 5)) {
+ lp = GetNumericArgument(lp + 5, OPER_EQU, &fvar, 0);
+ fvar = sqrtf(fvar);
lp++;
- len=0;
+ len = 0;
goto exit;
}
-#endif
+#endif //USE_ANGLE_FUNC
#if defined(USE_SML_M) && defined (USE_SML_SCRIPT_CMD)
- if (!strncmp(vname,"sml[",4)) {
- lp+=4;
- lp=GetNumericResult(lp,OPER_EQU,&fvar,0);
+ if (!strncmp(vname, "sml[", 4)) {
+ lp = GetNumericArgument(lp + 4, OPER_EQU, &fvar, 0);
SCRIPT_SKIP_SPACES
- fvar=SML_GetVal(fvar);
+ fvar = SML_GetVal(fvar);
lp++;
- len=0;
+ len = 0;
goto exit;
}
- if (!strncmp(vname,"sml(",4)) {
- lp+=4;
+ if (!strncmp(vname, "sml(", 4)) {
float fvar1;
- lp=GetNumericResult(lp,OPER_EQU,&fvar1,0);
+ lp = GetNumericArgument(lp + 4, OPER_EQU, &fvar1, 0);
SCRIPT_SKIP_SPACES
float fvar2;
- lp=GetNumericResult(lp,OPER_EQU,&fvar2,0);
+ lp = GetNumericArgument(lp, OPER_EQU, &fvar2, 0);
SCRIPT_SKIP_SPACES
if (fvar2==0) {
float fvar3;
- lp=GetNumericResult(lp,OPER_EQU,&fvar3,0);
- fvar=SML_SetBaud(fvar1,fvar3);
+ lp = GetNumericArgument(lp, OPER_EQU, &fvar3, 0);
+ fvar = SML_SetBaud(fvar1, fvar3);
} else if (fvar2==1) {
char str[SCRIPT_MAXSSIZE];
- lp=GetStringResult(lp,OPER_EQU,str,0);
- fvar=SML_Write(fvar1,str);
+ lp = GetStringArgument(lp, OPER_EQU, str, 0);
+ fvar = SML_Write(fvar1, str);
} else if (fvar2==2) {
char str[SCRIPT_MAXSSIZE];
- str[0]=0;
- fvar=SML_Read(fvar1,str,SCRIPT_MAXSSIZE);
- if (sp) strlcpy(sp,str,glob_script_mem.max_ssize);
+ str[0] = 0;
+ fvar = SML_Read(fvar1, str, SCRIPT_MAXSSIZE);
+ if (sp) strlcpy(sp, str, glob_script_mem.max_ssize);
lp++;
- len=0;
+ len = 0;
goto strexit;
} else {
#ifdef ED300L
- fvar=SML_Status(fvar1);
+ fvar = SML_Status(fvar1);
#else
- fvar=0;
-#endif
+ fvar = 0;
+#endif //ED300L
}
lp++;
- len=0;
+ len = 0;
goto exit;
}
-#endif
+#endif //USE_SML_M
break;
case 't':
- if (!strncmp(vname,"time",4)) {
- fvar=MinutesPastMidnight();
+ if (!strncmp(vname, "time", 4)) {
+ fvar = MinutesPastMidnight();
goto exit;
}
- if (!strncmp(vname,"tper",4)) {
- fvar=Settings.tele_period;
- tind->index=SCRIPT_TELEPERIOD;
+ if (!strncmp(vname, "tper", 4)) {
+ fvar = Settings.tele_period;
+ tind->index = SCRIPT_TELEPERIOD;
goto exit_settable;
}
- if (!strncmp(vname,"tinit",5)) {
- if (rules_flag.time_init) {
- rules_flag.time_init=0;
- fvar=1;
- }
+ if (!strncmp(vname, "tinit", 5)) {
+ fvar = rules_flag.time_init;
goto exit;
}
- if (!strncmp(vname,"tset",4)) {
- if (rules_flag.time_set) {
- rules_flag.time_set=0;
- fvar=1;
- }
+ if (!strncmp(vname, "tset", 4)) {
+ fvar = rules_flag.time_set;
goto exit;
}
- if (!strncmp(vname,"tstamp",6)) {
- if (sp) strlcpy(sp,GetDateAndTime(DT_LOCAL).c_str(),glob_script_mem.max_ssize);
+ if (!strncmp(vname, "tstamp", 6)) {
+ if (sp) strlcpy(sp, GetDateAndTime(DT_LOCAL).c_str(), glob_script_mem.max_ssize);
goto strexit;
}
- if (!strncmp(vname,"topic",5)) {
- if (sp) strlcpy(sp,SettingsText(SET_MQTT_TOPIC),glob_script_mem.max_ssize);
+ if (!strncmp(vname, "topic", 5)) {
+ if (sp) strlcpy(sp, SettingsText(SET_MQTT_TOPIC), glob_script_mem.max_ssize);
goto strexit;
}
#ifdef USE_SCRIPT_TIMER
- if (!strncmp(vname,"ts1(",4)) {
- lp=GetNumericResult(lp+4,OPER_EQU,&fvar,0);
- if (fvar<10) fvar=10;
+ if (!strncmp(vname, "ts1(", 4)) {
+ lp = GetNumericArgument(lp + 4, OPER_EQU, &fvar, 0);
+ if (fvar<10) fvar = 10;
Script_ticker1.attach_ms(fvar, Script_ticker1_end);
lp++;
- len=0;
+ len = 0;
goto exit;
}
- if (!strncmp(vname,"ts2(",4)) {
- lp=GetNumericResult(lp+4,OPER_EQU,&fvar,0);
- if (fvar<10) fvar=10;
+ if (!strncmp(vname, "ts2(", 4)) {
+ lp = GetNumericArgument(lp + 4, OPER_EQU, &fvar, 0);
+ if (fvar<10) fvar = 10;
Script_ticker2.attach_ms(fvar, Script_ticker2_end);
lp++;
- len=0;
+ len = 0;
goto exit;
}
- if (!strncmp(vname,"ts3(",4)) {
- lp=GetNumericResult(lp+4,OPER_EQU,&fvar,0);
- if (fvar<10) fvar=10;
+ if (!strncmp(vname, "ts3(", 4)) {
+ lp = GetNumericArgument(lp + 4, OPER_EQU, &fvar, 0);
+ if (fvar<10) fvar = 10;
Script_ticker3.attach_ms(fvar, Script_ticker3_end);
lp++;
- len=0;
+ len = 0;
goto exit;
}
- if (!strncmp(vname,"ts4(",4)) {
- lp=GetNumericResult(lp+4,OPER_EQU,&fvar,0);
- if (fvar<10) fvar=10;
+ if (!strncmp(vname, "ts4(", 4)) {
+ lp = GetNumericArgument(lp + 4, OPER_EQU, &fvar, 0);
+ if (fvar<10) fvar = 10;
Script_ticker4.attach_ms(fvar, Script_ticker4_end);
lp++;
- len=0;
+ len = 0;
goto exit;
}
#endif // USE_SCRIPT_TIMER
#ifdef USE_DISPLAY
#ifdef USE_TOUCH_BUTTONS
- if (!strncmp(vname,"tbut[",5)) {
- GetNumericResult(vname+5,OPER_EQU,&fvar,0);
- uint8_t index=fvar;
- if (index<1 || index>MAXBUTTONS) index=1;
+ if (!strncmp(vname, "tbut[", 5)) {
+ GetNumericArgument(vname + 5, OPER_EQU, &fvar, 0);
+ uint8_t index = fvar;
+ if (index<1 || index>MAXBUTTONS) index = 1;
index--;
if (buttons[index]) {
- fvar=buttons[index]->vpower.on_off;
+ fvar = buttons[index]->vpower.on_off;
} else {
- fvar=-1;
+ fvar = -1;
}
- len+=1;
+ len += 1;
goto exit;
}
-#endif
-#endif
+#endif //USE_TOUCH_BUTTONS
+#endif //USE_DISPLAY
break;
case 'u':
- if (!strncmp(vname,"uptime",6)) {
- fvar=MinutesUptime();
+ if (!strncmp(vname, "uptime", 6)) {
+ fvar = MinutesUptime();
goto exit;
}
- if (!strncmp(vname,"upsecs",6)) {
- fvar=uptime;
+ if (!strncmp(vname, "upsecs", 6)) {
+ fvar = uptime;
goto exit;
}
- if (!strncmp(vname,"upd[",4)) {
+ if (!strncmp(vname, "upd[", 4)) {
// var was updated
struct T_INDEX ind;
uint8_t vtype;
- isvar(vname+4,&vtype,&ind,0,0,0);
+ isvar(vname + 4, &vtype, &ind, 0, 0, 0);
if (!ind.bits.constant) {
if (!ind.bits.changed) {
- fvar=0;
+ fvar = 0;
len++;
goto exit;
} else {
- glob_script_mem.type[ind.index].bits.changed=0;
- fvar=1;
+ glob_script_mem.type[ind.index].bits.changed = 0;
+ fvar = 1;
len++;
goto exit;
}
@@ -2779,112 +2749,111 @@ chknext:
case 'w':
#if defined(ESP32) && defined(USE_WEBCAM)
- if (!strncmp(vname,"wc(",3)) {
- lp+=3;
+ if (!strncmp(vname, "wc(", 3)) {
float fvar1;
- lp=GetNumericResult(lp,OPER_EQU,&fvar1,0);
+ lp = GetNumericArgument(lp + 3, OPER_EQU, &fvar1, 0);
SCRIPT_SKIP_SPACES
switch ((uint32)fvar1) {
case 0:
{ float fvar2;
- lp=GetNumericResult(lp,OPER_EQU,&fvar2,0);
- fvar=WcSetup(fvar2);
+ lp = GetNumericArgument(lp, OPER_EQU, &fvar2, 0);
+ fvar = WcSetup(fvar2);
}
break;
case 1:
{ float fvar2;
- lp=GetNumericResult(lp,OPER_EQU,&fvar2,0);
- fvar=WcGetFrame(fvar2);
+ lp = GetNumericArgument(lp, OPER_EQU, &fvar2, 0);
+ fvar = WcGetFrame(fvar2);
}
break;
case 2:
{ float fvar2,fvar3;
- lp=GetNumericResult(lp,OPER_EQU,&fvar2,0);
+ lp = GetNumericArgument(lp, OPER_EQU, &fvar2, 0);
SCRIPT_SKIP_SPACES
- lp=GetNumericResult(lp,OPER_EQU,&fvar3,0);
- fvar=WcSetOptions(fvar2,fvar3);
+ lp = GetNumericArgument(lp, OPER_EQU, &fvar3, 0);
+ fvar = WcSetOptions(fvar2, fvar3);
}
break;
case 3:
- fvar=WcGetWidth();
+ fvar = WcGetWidth();
break;
case 4:
- fvar=WcGetHeight();
+ fvar = WcGetHeight();
break;
case 5:
{ float fvar2;
- lp=GetNumericResult(lp,OPER_EQU,&fvar2,0);
- fvar=WcSetStreamserver(fvar2);
+ lp = GetNumericArgument(lp, OPER_EQU, &fvar2, 0);
+ fvar = WcSetStreamserver(fvar2);
}
break;
case 6:
{ float fvar2;
- lp=GetNumericResult(lp,OPER_EQU,&fvar2,0);
- fvar=WcSetMotionDetect(fvar2);
+ lp = GetNumericArgument(lp, OPER_EQU, &fvar2, 0);
+ fvar = WcSetMotionDetect(fvar2);
}
break;
#ifdef USE_FACE_DETECT
case 7:
{ float fvar2;
- lp=GetNumericResult(lp,OPER_EQU,&fvar2,0);
- fvar=WcSetFaceDetect(fvar2);
+ lp = GetNumericArgument(lp, OPER_EQU, &fvar2, 0);
+ fvar = WcSetFaceDetect(fvar2);
}
break;
-#endif
+#endif //USE_FACE_DETECT
default:
- fvar=0;
+ fvar = 0;
}
lp++;
- len=0;
+ len = 0;
goto exit;
}
#endif //ESP32, USE_WEBCAM
#if defined(USE_TTGO_WATCH) && defined(USE_BMA423)
- if (!strncmp(vname,"wdclk",5)) {
- fvar=TTGO_doubleclick();
+ if (!strncmp(vname, "wdclk", 5)) {
+ fvar = TTGO_doubleclick();
goto exit;
}
- if (!strncmp(vname,"wbut",4)) {
- fvar=TTGO_button();
+ if (!strncmp(vname, "wbut", 4)) {
+ fvar = TTGO_button();
goto exit;
}
#endif // USE_TTGO_WATCH
#if defined(USE_TTGO_WATCH) && defined(USE_FT5206)
- if (!strncmp(vname,"wtch(",5)) {
- lp=GetNumericResult(lp+5,OPER_EQU,&fvar,0);
- fvar=Touch_Status(fvar);
+ if (!strncmp(vname, "wtch(", 5)) {
+ lp = GetNumericArgument(lp + 5, OPER_EQU, &fvar, 0);
+ fvar = Touch_Status(fvar);
lp++;
- len=0;
+ len = 0;
goto exit;
}
#endif // USE_FT5206
- if (!strncmp(vname,"wday",4)) {
- fvar=RtcTime.day_of_week;
+ if (!strncmp(vname, "wday", 4)) {
+ fvar = RtcTime.day_of_week;
goto exit;
}
- if (!strncmp(vname,"wific",5)) {
+ if (!strncmp(vname, "wific", 5)) {
if (rules_flag.wifi_connected) {
- rules_flag.wifi_connected=0;
- fvar=1;
+ rules_flag.wifi_connected = 0;
+ fvar = 1;
}
goto exit;
}
- if (!strncmp(vname,"wifid",5)) {
+ if (!strncmp(vname, "wifid", 5)) {
if (rules_flag.wifi_disconnected) {
- rules_flag.wifi_disconnected=0;
- fvar=1;
+ rules_flag.wifi_disconnected = 0;
+ fvar = 1;
}
goto exit;
}
- if (!strncmp(vname,"wifis",5)) {
- fvar=!global_state.wifi_down;
+ if (!strncmp(vname, "wifis", 5)) {
+ fvar = !global_state.wifi_down;
goto exit;
}
break;
case 'y':
- if (!strncmp(vname,"year",4)) {
- fvar=RtcTime.year;
+ if (!strncmp(vname, "year", 4)) {
+ fvar = RtcTime.year;
goto exit;
}
break;
@@ -2894,23 +2863,23 @@ chknext:
// nothing valid found
notfound:
if (fp) *fp=0;
- *vtype=VAR_NV;
- tind->index=VAR_NV;
- glob_script_mem.var_not_found=1;
+ *vtype = VAR_NV;
+ tind->index = VAR_NV;
+ glob_script_mem.var_not_found = 1;
return lp;
// return constant numbers
exit:
- if (fp) *fp=fvar;
- *vtype=NUM_RES;
- tind->bits.constant=1;
- tind->bits.is_string=0;
- return lp+len;
+ if (fp) *fp = fvar;
+ *vtype = NUM_RES;
+ tind->bits.constant = 1;
+ tind->bits.is_string = 0;
+ return lp + len;
// return constant strings
strexit:
- *vtype=STYPE;
- tind->bits.constant=1;
- tind->bits.is_string=1;
- return lp+len;
+ *vtype = STYPE;
+ tind->bits.constant = 1;
+ tind->bits.is_string = 1;
+ return lp + len;
}
@@ -2918,113 +2887,113 @@ strexit:
char *getop(char *lp, uint8_t *operand) {
switch (*lp) {
case '=':
- if (*(lp+1)=='=') {
- *operand=OPER_EQUEQU;
- return lp+2;
+ if (*(lp + 1)=='=') {
+ *operand = OPER_EQUEQU;
+ return lp + 2;
} else {
- *operand=OPER_EQU;
- return lp+1;
+ *operand = OPER_EQU;
+ return lp + 1;
}
break;
case '+':
- if (*(lp+1)=='=') {
- *operand=OPER_PLSEQU;
- return lp+2;
+ if (*(lp + 1)=='=') {
+ *operand = OPER_PLSEQU;
+ return lp + 2;
} else {
- *operand=OPER_PLS;
- return lp+1;
+ *operand = OPER_PLS;
+ return lp + 1;
}
break;
case '-':
- if (*(lp+1)=='=') {
- *operand=OPER_MINEQU;
- return lp+2;
+ if (*(lp + 1)=='=') {
+ *operand = OPER_MINEQU;
+ return lp + 2;
} else {
- *operand=OPER_MIN;
- return lp+1;
+ *operand = OPER_MIN;
+ return lp + 1;
}
break;
case '*':
- if (*(lp+1)=='=') {
- *operand=OPER_MULEQU;
- return lp+2;
+ if (*(lp + 1)=='=') {
+ *operand = OPER_MULEQU;
+ return lp + 2;
} else {
- *operand=OPER_MUL;
- return lp+1;
+ *operand = OPER_MUL;
+ return lp + 1;
}
break;
case '/':
- if (*(lp+1)=='=') {
- *operand=OPER_DIVEQU;
- return lp+2;
+ if (*(lp + 1)=='=') {
+ *operand = OPER_DIVEQU;
+ return lp + 2;
} else {
- *operand=OPER_DIV;
- return lp+1;
+ *operand = OPER_DIV;
+ return lp + 1;
}
break;
case '!':
- if (*(lp+1)=='=') {
- *operand=OPER_NOTEQU;
- return lp+2;
+ if (*(lp + 1)=='=') {
+ *operand = OPER_NOTEQU;
+ return lp + 2;
}
break;
case '>':
- if (*(lp+1)=='=') {
- *operand=OPER_GRTEQU;
- return lp+2;
+ if (*(lp + 1)=='=') {
+ *operand = OPER_GRTEQU;
+ return lp + 2;
} else {
- *operand=OPER_GRT;
- return lp+1;
+ *operand = OPER_GRT;
+ return lp + 1;
}
break;
case '<':
- if (*(lp+1)=='=') {
- *operand=OPER_LOWEQU;
- return lp+2;
+ if (*(lp + 1)=='=') {
+ *operand = OPER_LOWEQU;
+ return lp + 2;
} else {
- *operand=OPER_LOW;
- return lp+1;
+ *operand = OPER_LOW;
+ return lp + 1;
}
break;
case '%':
- if (*(lp+1)=='=') {
- *operand=OPER_PERCEQU;
- return lp+2;
+ if (*(lp + 1)=='=') {
+ *operand = OPER_PERCEQU;
+ return lp + 2;
} else {
- *operand=OPER_PERC;
- return lp+1;
+ *operand = OPER_PERC;
+ return lp + 1;
}
break;
case '^':
- if (*(lp+1)=='=') {
- *operand=OPER_XOREQU;
- return lp+2;
+ if (*(lp + 1)=='=') {
+ *operand = OPER_XOREQU;
+ return lp + 2;
} else {
- *operand=OPER_XOR;
- return lp+1;
+ *operand = OPER_XOR;
+ return lp + 1;
}
break;
case '&':
- if (*(lp+1)=='=') {
- *operand=OPER_ANDEQU;
- return lp+2;
+ if (*(lp + 1)=='=') {
+ *operand = OPER_ANDEQU;
+ return lp + 2;
} else {
- *operand=OPER_AND;
- return lp+1;
+ *operand = OPER_AND;
+ return lp + 1;
}
break;
case '|':
- if (*(lp+1)=='=') {
- *operand=OPER_OREQU;
- return lp+2;
+ if (*(lp + 1)=='=') {
+ *operand = OPER_OREQU;
+ return lp + 2;
} else {
- *operand=OPER_OR;
- return lp+1;
+ *operand = OPER_OR;
+ return lp + 1;
}
break;
}
- *operand=0;
+ *operand = 0;
return lp;
}
@@ -3043,31 +3012,31 @@ uint16_t GetStack(void) {
register uint8_t *sp asm("a1");
return (sp - pxTaskGetStackStart(NULL));
}
-#endif
+#endif //ESP8266
-char *GetStringResult(char *lp,uint8_t lastop,char *cp,JsonObject *jo) {
- uint8_t operand=0;
+char *GetStringArgument(char *lp, uint8_t lastop, char *cp, JsonObject *jo) {
+ uint8_t operand = 0;
uint8_t vtype;
char *slp;
struct T_INDEX ind;
char str[SCRIPT_MAXSSIZE],str1[SCRIPT_MAXSSIZE];
while (1) {
- lp=isvar(lp,&vtype,&ind,0,str1,jo);
- if (vtype!=STR_RES && !(vtype&STYPE)) {
+ lp=isvar(lp, &vtype, &ind, 0, str1, jo);
+ if (vtype!=STR_RES && !(vtype & STYPE)) {
// numeric type
- glob_script_mem.glob_error=1;
+ glob_script_mem.glob_error = 1;
return lp;
}
switch (lastop) {
case OPER_EQU:
- strlcpy(str,str1,sizeof(str));
+ strlcpy(str, str1, sizeof(str));
break;
case OPER_PLS:
- strncat(str,str1,sizeof(str)-strlen(str1));
+ strncat(str, str1, sizeof(str) - strlen(str1));
break;
}
- slp=lp;
- lp=getop(lp,&operand);
+ slp = lp;
+ lp = getop(lp, &operand);
switch (operand) {
case OPER_EQUEQU:
case OPER_NOTEQU:
@@ -3075,24 +3044,24 @@ char *GetStringResult(char *lp,uint8_t lastop,char *cp,JsonObject *jo) {
case OPER_LOWEQU:
case OPER_GRT:
case OPER_GRTEQU:
- lp=slp;
- strcpy(cp,str);
+ lp = slp;
+ strcpy(cp, str);
return lp;
break;
default:
break;
}
- lastop=operand;
+ lastop = operand;
if (!operand) {
- strcpy(cp,str);
+ strcpy(cp, str);
return lp;
}
}
return lp;
}
-char *GetNumericResult(char *lp,uint8_t lastop,float *fp,JsonObject *jo) {
-uint8_t operand=0;
+char *GetNumericArgument(char *lp, uint8_t lastop, float *fp, JsonObject *jo) {
+uint8_t operand = 0;
float fvar1,fvar;
char *slp;
uint8_t vtype;
@@ -3101,50 +3070,50 @@ struct T_INDEX ind;
// get 1. value
if (*lp=='(') {
lp++;
- lp=GetNumericResult(lp,OPER_EQU,&fvar1,jo);
+ lp = GetNumericArgument(lp, OPER_EQU, &fvar1, jo);
lp++;
//if (*lp==')') lp++;
} else {
- lp=isvar(lp,&vtype,&ind,&fvar1,0,jo);
- if (vtype!=NUM_RES && vtype&STYPE) {
+ lp = isvar(lp, &vtype, &ind, &fvar1, 0, jo);
+ if ((vtype!=NUM_RES) && (vtype&STYPE)) {
// string type
- glob_script_mem.glob_error=1;
+ glob_script_mem.glob_error = 1;
}
}
switch (lastop) {
case OPER_EQU:
- fvar=fvar1;
+ fvar = fvar1;
break;
case OPER_PLS:
- fvar+=fvar1;
+ fvar += fvar1;
break;
case OPER_MIN:
- fvar-=fvar1;
+ fvar -= fvar1;
break;
case OPER_MUL:
- fvar*=fvar1;
+ fvar *= fvar1;
break;
case OPER_DIV:
- fvar/=fvar1;
+ fvar /= fvar1;
break;
case OPER_PERC:
- fvar=fmodf(fvar,fvar1);
+ fvar = fmodf(fvar, fvar1);
break;
case OPER_XOR:
- fvar=(uint32_t)fvar^(uint32_t)fvar1;
+ fvar = (uint32_t)fvar ^ (uint32_t)fvar1;
break;
case OPER_AND:
- fvar=(uint32_t)fvar&(uint32_t)fvar1;
+ fvar = (uint32_t)fvar & (uint32_t)fvar1;
break;
case OPER_OR:
- fvar=(uint32_t)fvar|(uint32_t)fvar1;
+ fvar = (uint32_t)fvar | (uint32_t)fvar1;
break;
default:
break;
}
- slp=lp;
- lp=getop(lp,&operand);
+ slp = lp;
+ lp = getop(lp, &operand);
switch (operand) {
case OPER_EQUEQU:
case OPER_NOTEQU:
@@ -3152,102 +3121,115 @@ struct T_INDEX ind;
case OPER_LOWEQU:
case OPER_GRT:
case OPER_GRTEQU:
- lp=slp;
- *fp=fvar;
+ lp = slp;
+ *fp = fvar;
return lp;
break;
default:
break;
}
- lastop=operand;
+ lastop = operand;
if (!operand) {
- *fp=fvar;
+ *fp = fvar;
return lp;
}
}
}
-char *ForceStringVar(char *lp,char *dstr) {
+char *ForceStringVar(char *lp, char *dstr) {
float fvar;
- char *slp=lp;
- glob_script_mem.glob_error=0;
- lp=GetStringResult(lp,OPER_EQU,dstr,0);
+ char *slp = lp;
+ glob_script_mem.glob_error = 0;
+ lp = GetStringArgument(lp, OPER_EQU, dstr, 0);
if (glob_script_mem.glob_error) {
// mismatch
- lp=GetNumericResult(slp,OPER_EQU,&fvar,0);
- dtostrfd(fvar,6,dstr);
- glob_script_mem.glob_error=0;
+ lp = GetNumericArgument(slp, OPER_EQU, &fvar, 0);
+ dtostrfd(fvar, 6, dstr);
+ glob_script_mem.glob_error = 0;
}
return lp;
}
// replace vars in cmd %var%
-void Replace_Cmd_Vars(char *srcbuf,uint32_t srcsize, char *dstbuf,uint32_t dstsize) {
+void Replace_Cmd_Vars(char *srcbuf, uint32_t srcsize, char *dstbuf, uint32_t dstsize) {
char *cp;
uint16_t count;
uint8_t vtype;
- uint8_t dprec=glob_script_mem.script_dprec;
+ uint8_t dprec = glob_script_mem.script_dprec;
float fvar;
- cp=srcbuf;
+ cp = srcbuf;
struct T_INDEX ind;
char string[SCRIPT_MAXSSIZE];
- dstsize-=2;
- for (count=0;count=sizeof(str)) len=len>=sizeof(str);
- strlcpy(str,cp,len);
+ if (len>=sizeof(str)) len = sizeof(str);
+ strlcpy(str, cp, len);
toSLog(str);
}
void toLogEOL(const char *s1,const char *str) {
if (!str) return;
- uint8_t index=0;
- char *cp=log_data;
- strcpy(cp,s1);
- cp+=strlen(s1);
+ uint8_t index = 0;
+ char *cp = log_data;
+ strcpy(cp, s1);
+ cp += strlen(s1);
while (*str) {
if (*str==SCRIPT_EOL) break;
- *cp++=*str++;
+ *cp++ = *str++;
}
- *cp=0;
+ *cp = 0;
AddLog(LOG_LEVEL_INFO);
}
@@ -3297,70 +3279,70 @@ void toSLog(const char *str) {
#endif
}
-char *Evaluate_expression(char *lp,uint8_t and_or, uint8_t *result,JsonObject *jo) {
+char *Evaluate_expression(char *lp, uint8_t and_or, uint8_t *result,JsonObject *jo) {
float fvar,*dfvar,fvar1;
uint8_t numeric;
struct T_INDEX ind;
- uint8_t vtype=0,lastop;
- uint8_t res=0;
- char *llp=lp;
+ uint8_t vtype = 0,lastop;
+ uint8_t res = 0;
+ char *llp = lp;
char *slp;
SCRIPT_SKIP_SPACES
if (*lp=='(') {
- uint8_t res=0;
- uint8_t xand_or=0;
+ uint8_t res = 0;
+ uint8_t xand_or = 0;
lp++;
loop:
SCRIPT_SKIP_SPACES
- lp=Evaluate_expression(lp,xand_or,&res,jo);
+ lp = Evaluate_expression(lp, xand_or, &res, jo);
if (*lp==')') {
lp++;
goto exit0;
}
// check for next and or
SCRIPT_SKIP_SPACES
- if (!strncmp(lp,"or",2)) {
- lp+=2;
- xand_or=1;
+ if (!strncmp(lp, "or", 2)) {
+ lp += 2;
+ xand_or = 1;
goto loop;
- } else if (!strncmp(lp,"and",3)) {
- lp+=3;
- xand_or=2;
+ } else if (!strncmp(lp, "and", 3)) {
+ lp += 3;
+ xand_or = 2;
goto loop;
}
exit0:
if (!and_or) {
- *result=res;
+ *result = res;
} else if (and_or==1) {
*result|=res;
} else {
- *result&=res;
+ *result &= res;
}
goto exit10;
}
- llp=lp;
+ llp = lp;
// compare
- dfvar=&fvar;
- glob_script_mem.glob_error=0;
- slp=lp;
- numeric=1;
- lp=GetNumericResult(lp,OPER_EQU,dfvar,0);
+ dfvar = &fvar;
+ glob_script_mem.glob_error = 0;
+ slp = lp;
+ numeric = 1;
+ lp = GetNumericArgument(lp, OPER_EQU, dfvar, 0);
if (glob_script_mem.glob_error==1) {
// was string, not number
char cmpstr[SCRIPT_MAXSSIZE];
- lp=slp;
- numeric=0;
+ lp = slp;
+ numeric = 0;
// get the string
- lp=isvar(lp,&vtype,&ind,0,cmpstr,0);
- lp=getop(lp,&lastop);
+ lp = isvar(lp, &vtype, &ind, 0, cmpstr, 0);
+ lp = getop(lp, &lastop);
// compare string
char str[SCRIPT_MAXSSIZE];
- lp=GetStringResult(lp,OPER_EQU,str,jo);
+ lp = GetStringArgument(lp, OPER_EQU, str, jo);
if (lastop==OPER_EQUEQU || lastop==OPER_NOTEQU) {
- res=strcmp(cmpstr,str);
+ res = strcmp(cmpstr, str);
if (lastop==OPER_EQUEQU) res=!res;
goto exit;
}
@@ -3368,26 +3350,26 @@ exit0:
} else {
// numeric
// evaluate operand
- lp=getop(lp,&lastop);
- lp=GetNumericResult(lp,OPER_EQU,&fvar1,jo);
+ lp = getop(lp, &lastop);
+ lp = GetNumericArgument(lp, OPER_EQU, &fvar1, jo);
switch (lastop) {
case OPER_EQUEQU:
- res=(*dfvar==fvar1);
+ res = (*dfvar==fvar1);
break;
case OPER_NOTEQU:
- res=(*dfvar!=fvar1);
+ res = (*dfvar!=fvar1);
break;
case OPER_LOW:
- res=(*dfvarfvar1);
+ res = (*dfvar>fvar1);
break;
case OPER_GRTEQU:
- res=(*dfvar>=fvar1);
+ res = (*dfvar>=fvar1);
break;
default:
// error
@@ -3396,11 +3378,11 @@ exit0:
exit:
if (!and_or) {
- *result=res;
+ *result = res;
} else if (and_or==1) {
- *result|=res;
+ *result |= res;
} else {
- *result&=res;
+ *result &= res;
}
}
@@ -3408,8 +3390,8 @@ exit:
exit10:
#if IFTHEN_DEBUG>0
char tbuff[128];
- sprintf(tbuff,"p1=%d,p2=%d,cmpres=%d,and_or=%d line: ",(int32_t)*dfvar,(int32_t)fvar1,*result,and_or);
- toLogEOL(tbuff,llp);
+ sprintf(tbuff,"p1=%d,p2=%d,cmpres=%d,and_or=%d line: ", (int32_t)*dfvar, (int32_t)fvar1, *result, and_or);
+ toLogEOL(tbuff, llp);
#endif
return lp;
}
@@ -3420,28 +3402,28 @@ TimerHandle_t beep_th;
void StopBeep( TimerHandle_t xTimer );
void StopBeep( TimerHandle_t xTimer ) {
- ledcWriteTone(7,0);
+ ledcWriteTone(7, 0);
xTimerStop(xTimer, 0);
}
void esp32_beep(int32_t freq ,uint32_t len) {
if (freq<0) {
- ledcSetup(7,500,10);
- ledcAttachPin(-freq,7);
- ledcWriteTone(7,0);
+ ledcSetup(7, 500, 10);
+ ledcAttachPin(-freq, 7);
+ ledcWriteTone(7, 0);
if (!beep_th) {
- beep_th = xTimerCreate("beep",100,pdFALSE,( void * ) 0,StopBeep);
+ beep_th = xTimerCreate("beep", 100, pdFALSE, ( void * ) 0, StopBeep);
}
} else {
if (!beep_th) return;
if (!freq) {
- ledcWriteTone(7,0);
+ ledcWriteTone(7, 0);
xTimerStop(beep_th, 10);
return;
}
if (len < 10) return;
if (xTimerIsTimerActive(beep_th)) return;
- ledcWriteTone(7,freq);
+ ledcWriteTone(7, freq);
uint32_t ticks = pdMS_TO_TICKS(len);
xTimerChangePeriod( beep_th, ticks, 10);
}
@@ -3460,13 +3442,13 @@ int16_t Run_Scripter(const char *type, int8_t tlen, char *js) {
if (tasm_cmd_activ && tlen>0) return 0;
- JsonObject *jo=0;
+ JsonObject *jo = 0;
DynamicJsonBuffer jsonBuffer; // on heap
- JsonObject &jobj=jsonBuffer.parseObject(js);
+ JsonObject &jobj = jsonBuffer.parseObject(js);
if (js) {
- jo=&jobj;
+ jo = &jobj;
} else {
- jo=0;
+ jo = 0;
}
return Run_script_sub(type, tlen, jo);
@@ -3477,23 +3459,23 @@ int16_t Run_script_sub(const char *type, int8_t tlen, JsonObject *jo) {
char *lp_next;
int16_t globaindex,saindex;
struct T_INDEX ind;
- uint8_t operand,lastop,numeric=1,if_state[IF_NEST],if_exe[IF_NEST],if_result[IF_NEST],and_or,ifstck=0;
- if_state[ifstck]=0;
- if_result[ifstck]=0;
- if_exe[ifstck]=1;
+ uint8_t operand,lastop,numeric = 1,if_state[IF_NEST],if_exe[IF_NEST],if_result[IF_NEST],and_or,ifstck = 0;
+ if_state[ifstck] = 0;
+ if_result[ifstck] = 0;
+ if_exe[ifstck] = 1;
char cmpstr[SCRIPT_MAXSSIZE];
- uint8_t check=0;
+ uint8_t check = 0;
if (tlen<0) {
- tlen=abs(tlen);
- check=1;
+ tlen = abs(tlen);
+ check = 1;
}
float *dfvar,*cv_count,cv_max,cv_inc;
char *cv_ptr;
- float fvar=0,fvar1,sysvar,swvar;
- uint8_t section=0,sysv_type=0,swflg=0;
+ float fvar = 0,fvar1,sysvar,swvar;
+ uint8_t section = 0,sysv_type = 0,swflg = 0;
- char *lp=glob_script_mem.scriptptr;
+ char *lp = glob_script_mem.scriptptr;
while (1) {
// check line
@@ -3514,71 +3496,71 @@ int16_t Run_script_sub(const char *type, int8_t tlen, JsonObject *jo) {
if (*lp=='#') {
return 0;
}
- glob_script_mem.var_not_found=0;
+ glob_script_mem.var_not_found = 0;
//#if SCRIPT_DEBUG>0
#ifdef IFTHEN_DEBUG
char tbuff[128];
- sprintf(tbuff,"stack=%d,exe=%d,state=%d,cmpres=%d line: ",ifstck,if_exe[ifstck],if_state[ifstck],if_result[ifstck]);
- toLogEOL(tbuff,lp);
-#endif
+ sprintf(tbuff, "stack=%d,exe=%d,state=%d,cmpres=%d line: ", ifstck, if_exe[ifstck], if_state[ifstck], if_result[ifstck]);
+ toLogEOL(tbuff, lp);
+#endif //IFTHEN_DEBUG
//if (if_state[s_ifstck]==3 && if_result[s_ifstck]) goto next_line;
//if (if_state[s_ifstck]==2 && !if_result[s_ifstck]) goto next_line;
- if (!strncmp(lp,"if",2)) {
- lp+=2;
+ if (!strncmp(lp, "if", 2)) {
+ lp += 2;
if (ifstck=2) {
- lp+=5;
+ if_state[ifstck] = 1;
+ if_result[ifstck] = 0;
+ if (ifstck==1) if_exe[ifstck] = 1;
+ else if_exe[ifstck] = if_exe[ifstck - 1];
+ and_or = 0;
+ } else if (!strncmp(lp, "then", 4) && if_state[ifstck]==1) {
+ lp += 4;
+ if_state[ifstck] = 2;
+ if (if_exe[ifstck - 1]) if_exe[ifstck] = if_result[ifstck];
+ } else if (!strncmp(lp, "else", 4) && if_state[ifstck]==2) {
+ lp += 4;
+ if_state[ifstck] = 3;
+ if (if_exe[ifstck - 1]) if_exe[ifstck] = !if_result[ifstck];
+ } else if (!strncmp(lp, "endif", 5) && if_state[ifstck]>=2) {
+ lp += 5;
if (ifstck>0) {
- if_state[ifstck]=0;
+ if_state[ifstck] = 0;
ifstck--;
}
goto next_line;
- } else if (!strncmp(lp,"or",2) && if_state[ifstck]==1) {
- lp+=2;
- and_or=1;
- } else if (!strncmp(lp,"and",3) && if_state[ifstck]==1) {
- lp+=3;
- and_or=2;
+ } else if (!strncmp(lp, "or", 2) && if_state[ifstck]==1) {
+ lp += 2;
+ and_or = 1;
+ } else if (!strncmp(lp, "and", 3) && if_state[ifstck]==1) {
+ lp += 3;
+ and_or = 2;
}
if (*lp=='{' && if_state[ifstck]==1) {
- lp+=1; // then
- if_state[ifstck]=2;
- if (if_exe[ifstck-1]) if_exe[ifstck]=if_result[ifstck];
+ lp += 1; // then
+ if_state[ifstck] = 2;
+ if (if_exe[ifstck - 1]) if_exe[ifstck]=if_result[ifstck];
} else if (*lp=='{' && if_state[ifstck]==3) {
- lp+=1; // after else
+ lp += 1; // after else
//if_state[ifstck]=3;
} else if (*lp=='}' && if_state[ifstck]>=2) {
lp++; // must check for else
- char *slp=lp;
- uint8_t iselse=0;
- for (uint8_t count=0; count<8;count++) {
+ char *slp = lp;
+ uint8_t iselse = 0;
+ for (uint8_t count = 0; count<8;count++) {
if (*lp=='}') {
// must be endif
break;
}
- if (!strncmp(lp,"else",4)) {
+ if (!strncmp(lp, "else", 4)) {
// is before else, no endif
- if_state[ifstck]=3;
+ if_state[ifstck] = 3;
if (if_exe[ifstck-1]) if_exe[ifstck]=!if_result[ifstck];
- lp+=4;
- iselse=1;
+ lp += 4;
+ iselse = 1;
SCRIPT_SKIP_SPACES
if (*lp=='{') lp++;
break;
@@ -3586,111 +3568,111 @@ int16_t Run_script_sub(const char *type, int8_t tlen, JsonObject *jo) {
lp++;
}
if (!iselse) {
- lp=slp;
+ lp = slp;
// endif
if (ifstck>0) {
- if_state[ifstck]=0;
+ if_state[ifstck] = 0;
ifstck--;
}
goto next_line;
}
}
- if (!strncmp(lp,"for",3)) {
+ if (!strncmp(lp, "for", 3)) {
// start for next loop, fetch 3 params
// simple implementation, zero loop count not supported
- lp+=3;
+ lp += 3;
SCRIPT_SKIP_SPACES
- lp_next=0;
- lp=isvar(lp,&vtype,&ind,0,0,0);
+ lp_next = 0;
+ lp = isvar(lp, &vtype, &ind, 0, 0, 0);
if ((vtype!=VAR_NV) && (vtype&STYPE)==0) {
// numeric var
- uint8_t index=glob_script_mem.type[ind.index].index;
- cv_count=&glob_script_mem.fvars[index];
+ uint8_t index = glob_script_mem.type[ind.index].index;
+ cv_count = &glob_script_mem.fvars[index];
SCRIPT_SKIP_SPACES
- lp=GetNumericResult(lp,OPER_EQU,cv_count,0);
+ lp = GetNumericArgument(lp, OPER_EQU, cv_count, 0);
SCRIPT_SKIP_SPACES
- lp=GetNumericResult(lp,OPER_EQU,&cv_max,0);
+ lp = GetNumericArgument(lp, OPER_EQU, &cv_max, 0);
SCRIPT_SKIP_SPACES
- lp=GetNumericResult(lp,OPER_EQU,&cv_inc,0);
+ lp = GetNumericArgument(lp, OPER_EQU, &cv_inc, 0);
//SCRIPT_SKIP_EOL
- cv_ptr=lp;
+ cv_ptr = lp;
if (*cv_count<=cv_max && cv_inc>0) {
// inc loop
- floop=1;
+ floop = 1;
} else {
// dec loop
- floop=2;
+ floop = 2;
if (cv_inc>0) {
- floop=1;
+ floop = 1;
}
}
} else {
// error
- toLogEOL("for error",lp);
+ toLogEOL("for error", lp);
}
- } else if (!strncmp(lp,"next",4)) {
- lp_next=lp;
+ } else if (!strncmp(lp, "next", 4)) {
+ lp_next = lp;
if (floop>0) {
// for next loop
- *cv_count+=cv_inc;
+ *cv_count += cv_inc;
if (floop==1) {
if (*cv_count<=cv_max) {
- lp=cv_ptr;
+ lp = cv_ptr;
} else {
- lp+=4;
- floop=0;
+ lp += 4;
+ floop = 0;
}
} else {
if (*cv_count>=cv_max) {
- lp=cv_ptr;
+ lp = cv_ptr;
} else {
- lp+=4;
- floop=0;
+ lp += 4;
+ floop = 0;
}
}
}
}
- if (!strncmp(lp,"switch",6)) {
- lp+=6;
+ if (!strncmp(lp, "switch", 6)) {
+ lp += 6;
SCRIPT_SKIP_SPACES
- char *slp=lp;
- lp=GetNumericResult(lp,OPER_EQU,&swvar,0);
+ char *slp = lp;
+ lp = GetNumericArgument(lp, OPER_EQU, &swvar, 0);
if (glob_script_mem.glob_error==1) {
// was string, not number
- lp=slp;
+ lp = slp;
// get the string
- lp=isvar(lp,&vtype,&ind,0,cmpstr,0);
- swflg=0x81;
+ lp = isvar(lp, &vtype, &ind, 0, cmpstr, 0);
+ swflg = 0x81;
} else {
- swflg=1;
+ swflg = 1;
}
- } else if (!strncmp(lp,"case",4) && swflg>0) {
- lp+=4;
+ } else if (!strncmp(lp, "case", 4) && swflg>0) {
+ lp += 4;
SCRIPT_SKIP_SPACES
float cvar;
- if (!(swflg&0x80)) {
- lp=GetNumericResult(lp,OPER_EQU,&cvar,0);
+ if (!(swflg & 0x80)) {
+ lp = GetNumericArgument(lp, OPER_EQU, &cvar, 0);
if (swvar!=cvar) {
- swflg=2;
+ swflg = 2;
} else {
- swflg=1;
+ swflg = 1;
}
} else {
char str[SCRIPT_MAXSSIZE];
- lp=GetStringResult(lp,OPER_EQU,str,0);
- if (!strcmp(cmpstr,str)) {
- swflg=0x81;
+ lp = GetStringArgument(lp, OPER_EQU, str, 0);
+ if (!strcmp(cmpstr, str)) {
+ swflg = 0x81;
} else {
- swflg=0x82;
+ swflg = 0x82;
}
}
- } else if (!strncmp(lp,"ends",4) && swflg>0) {
- lp+=4;
- swflg=0;
+ } else if (!strncmp(lp, "ends", 4) && swflg>0) {
+ lp += 4;
+ swflg = 0;
}
- if ((swflg&3)==2) goto next_line;
+ if ((swflg & 3)==2) goto next_line;
SCRIPT_SKIP_SPACES
//SCRIPT_SKIP_EOL
@@ -3702,34 +3684,34 @@ int16_t Run_script_sub(const char *type, int8_t tlen, JsonObject *jo) {
if (!if_exe[ifstck] && if_state[ifstck]!=1) goto next_line;
#ifdef IFTHEN_DEBUG
- sprintf(tbuff,"stack=%d,exe=%d,state=%d,cmpres=%d execute line: ",ifstck,if_exe[ifstck],if_state[ifstck],if_result[ifstck]);
- toLogEOL(tbuff,lp);
-#endif
+ sprintf(tbuff, "stack=%d,exe=%d,state=%d,cmpres=%d execute line: ", ifstck, if_exe[ifstck], if_state[ifstck], if_result[ifstck]);
+ toLogEOL(tbuff, lp);
+#endif //IFTHEN_DEBUG
- if (!strncmp(lp,"break",5)) {
- lp+=5;
+ if (!strncmp(lp, "break", 5)) {
+ lp += 5;
if (floop) {
// should break loop
if (lp_next) {
- lp=lp_next;
+ lp = lp_next;
}
- floop=0;
+ floop = 0;
} else {
- section=0;
+ section = 0;
}
goto next_line;
- } else if (!strncmp(lp,"dp",2) && isdigit(*(lp+2))) {
- lp+=2;
+ } else if (!strncmp(lp, "dp", 2) && isdigit(*(lp + 2))) {
+ lp += 2;
// number precision
- glob_script_mem.script_dprec=atoi(lp);
+ glob_script_mem.script_dprec = atoi(lp);
goto next_line;
}
#ifdef USE_DISPLAY
- else if (!strncmp(lp,"dt",2)) {
+ else if (!strncmp(lp, "dt", 2)) {
char dstbuf[256];
- lp+=2;
+ lp += 2;
SCRIPT_SKIP_SPACES
- Replace_Cmd_Vars(lp,1,dstbuf,sizeof(dstbuf));
+ Replace_Cmd_Vars(lp, 1, dstbuf, sizeof(dstbuf));
char *savptr = XdrvMailbox.data;
XdrvMailbox.data = dstbuf;
XdrvMailbox.data_len = 0;
@@ -3737,165 +3719,160 @@ int16_t Run_script_sub(const char *type, int8_t tlen, JsonObject *jo) {
XdrvMailbox.data = savptr;
goto next_line;
}
-#endif
- else if (!strncmp(lp,"delay(",6)) {
- lp+=5;
+#endif //USE_DISPLAY
+ else if (!strncmp(lp, "delay(", 6)) {
// delay
- lp=GetNumericResult(lp,OPER_EQU,&fvar,0);
+ lp = GetNumericArgument(lp + 5, OPER_EQU, &fvar, 0);
delay(fvar);
goto next_line;
- } else if (!strncmp(lp,"spinm(",6)) {
- lp+=6;
+ } else if (!strncmp(lp, "spinm(", 6)) {
// set pin mode
- lp=GetNumericResult(lp,OPER_EQU,&fvar,0);
- int8_t pinnr=fvar;
+ lp = GetNumericArgument(lp + 6, OPER_EQU, &fvar, 0);
+ int8_t pinnr = fvar;
SCRIPT_SKIP_SPACES
- uint8_t mode=0;
+ uint8_t mode = 0;
if ((*lp=='I') || (*lp=='O') || (*lp=='P')) {
switch (*lp) {
case 'I':
- mode=0;
+ mode = 0;
break;
case 'O':
- mode=1;
+ mode = 1;
break;
case 'P':
- mode=2;
+ mode = 2;
break;
}
lp++;
} else {
- lp=GetNumericResult(lp,OPER_EQU,&fvar,0);
- mode=fvar;
+ lp = GetNumericArgument(lp, OPER_EQU, &fvar, 0);
+ mode = fvar;
}
uint8_t pm=0;
- if (mode==0) pm=INPUT;
- if (mode==1) pm=OUTPUT;
- if (mode==2) pm=INPUT_PULLUP;
- pinMode(pinnr,pm);
+ if (mode==0) pm = INPUT;
+ if (mode==1) pm = OUTPUT;
+ if (mode==2) pm = INPUT_PULLUP;
+ pinMode(pinnr, pm);
goto next_line;
- } else if (!strncmp(lp,"spin(",5)) {
- lp+=5;
+ } else if (!strncmp(lp, "spin(", 5)) {
// set pin
- lp=GetNumericResult(lp,OPER_EQU,&fvar,0);
- int8_t pinnr=fvar;
+ lp = GetNumericArgument(lp + 5, OPER_EQU, &fvar, 0);
+ int8_t pinnr = fvar;
SCRIPT_SKIP_SPACES
- lp=GetNumericResult(lp,OPER_EQU,&fvar,0);
- int8_t mode=fvar;
- digitalWrite(pinnr,mode&1);
+ lp = GetNumericArgument(lp, OPER_EQU, &fvar, 0);
+ int8_t mode = fvar;
+ digitalWrite(pinnr, mode & 1);
goto next_line;
- } else if (!strncmp(lp,"svars(",5)) {
- lp+=5;
+ } else if (!strncmp(lp, "svars(", 5)) {
+ lp += 5;
// save vars
Scripter_save_pvars();
goto next_line;
}
#ifdef USE_LIGHT
#ifdef USE_WS2812
- else if (!strncmp(lp,"ws2812(",7)) {
- lp+=7;
- lp=isvar(lp,&vtype,&ind,0,0,0);
+ else if (!strncmp(lp, "ws2812(", 7)) {
+ lp = isvar(lp + 7, &vtype, &ind, 0, 0, 0);
if (vtype!=VAR_NV) {
SCRIPT_SKIP_SPACES
if (*lp!=')') {
- lp=GetNumericResult(lp,OPER_EQU,&fvar,0);
+ lp = GetNumericArgument(lp, OPER_EQU, &fvar, 0);
} else {
- fvar=0;
+ fvar = 0;
}
// found variable as result
- uint8_t index=glob_script_mem.type[ind.index].index;
+ uint8_t index = glob_script_mem.type[ind.index].index;
if ((vtype&STYPE)==0) {
// numeric result
if (glob_script_mem.type[ind.index].bits.is_filter) {
- uint16_t len=0;
- float *fa=Get_MFAddr(index,&len,0);
+ uint16_t len = 0;
+ float *fa = Get_MFAddr(index, &len, 0);
//Serial.printf(">> 2 %d\n",(uint32_t)*fa);
- if (fa && len) ws2812_set_array(fa,len,fvar);
+ if (fa && len) ws2812_set_array(fa, len, fvar);
}
}
}
goto next_line;
}
-#endif
-#endif
+#endif //USE_WS2812
+#endif //USE_LIGHT
#ifdef ESP32
- else if (!strncmp(lp,"beep(",5)) {
- lp+=5;
- lp=GetNumericResult(lp,OPER_EQU,&fvar,0);
+ else if (!strncmp(lp, "beep(", 5)) {
+ lp = GetNumericArgument(lp + 5, OPER_EQU, &fvar, 0);
SCRIPT_SKIP_SPACES
float fvar1;
- lp=GetNumericResult(lp,OPER_EQU,&fvar1,0);
- esp32_beep(fvar,fvar1);
+ lp = GetNumericArgument(lp, OPER_EQU, &fvar1, 0);
+ esp32_beep(fvar, fvar1);
lp++;
goto next_line;
}
-#endif
+#endif //ESP32
else if (!strncmp(lp,"=>",2) || !strncmp(lp,"->",2) || !strncmp(lp,"+>",2) || !strncmp(lp,"print",5)) {
// execute cmd
- uint8_t sflag=0,pflg=0,svmqtt,swll;
+ uint8_t sflag = 0,pflg = 0,svmqtt,swll;
if (*lp=='p') {
- pflg=1;
- lp+=5;
+ pflg = 1;
+ lp += 5;
}
else {
- if (*lp=='-') sflag=1;
- if (*lp=='+') sflag=2;
- lp+=2;
+ if (*lp=='-') sflag = 1;
+ if (*lp=='+') sflag = 2;
+ lp += 2;
}
- char *slp=lp;
+ char *slp = lp;
SCRIPT_SKIP_SPACES
#define SCRIPT_CMDMEM 512
- char *cmdmem=(char*)malloc(SCRIPT_CMDMEM);
+ char *cmdmem = (char*)malloc(SCRIPT_CMDMEM);
if (cmdmem) {
- char *cmd=cmdmem;
+ char *cmd = cmdmem;
uint16_t count;
- for (count=0; count';
- lp=GetStringResult(lp,OPER_EQU,&str[1],0);
+ str[0] = '>';
+ lp = GetStringArgument(lp, OPER_EQU, &str[1], 0);
lp++;
//execute_script(str);
- char *svd_sp=glob_script_mem.scriptptr;
- strcat(str,"\n#");
- glob_script_mem.scriptptr=str;
- Run_script_sub(">",1,jo);
- glob_script_mem.scriptptr=svd_sp;
+ char *svd_sp = glob_script_mem.scriptptr;
+ strcat(str, "\n#");
+ glob_script_mem.scriptptr = str;
+ Run_script_sub(">", 1, jo);
+ glob_script_mem.scriptptr = svd_sp;
}
// check for variable result
if (if_state[ifstck]==1) {
// evaluate exxpression
- lp=Evaluate_expression(lp,and_or,&if_result[ifstck],jo);
+ lp = Evaluate_expression(lp, and_or, &if_result[ifstck], jo);
SCRIPT_SKIP_SPACES
if (*lp=='{' && if_state[ifstck]==1) {
- lp+=1; // then
- if_state[ifstck]=2;
- if (if_exe[ifstck-1]) if_exe[ifstck]=if_result[ifstck];
+ lp += 1; // then
+ if_state[ifstck] = 2;
+ if (if_exe[ifstck - 1]) if_exe[ifstck] = if_result[ifstck];
}
goto next_line;
} else {
- char *vnp=lp;
- lp=isvar(lp,&vtype,&ind,&sysvar,0,0);
+ char *vnp = lp;
+ lp = isvar(lp, &vtype, &ind, &sysvar, 0, 0);
if (vtype!=VAR_NV) {
#ifdef USE_SCRIPT_GLOBVARS
char varname[16];
- uint32_t vnl=(uint32_t)lp-(uint32)vnp;
- strncpy(varname,vnp,vnl);
- varname[vnl]=0;
-#endif
+ uint32_t vnl = (uint32_t)lp - (uint32)vnp;
+ strncpy(varname, vnp, vnl);
+ varname[vnl] = 0;
+#endif //USE_SCRIPT_GLOBVARS
// found variable as result
- globvindex=ind.index; // save destination var index here
- globaindex=last_findex;
- uint8_t index=glob_script_mem.type[ind.index].index;
+ globvindex = ind.index; // save destination var index here
+ globaindex = last_findex;
+ uint8_t index = glob_script_mem.type[ind.index].index;
if ((vtype&STYPE)==0) {
// numeric result
if (ind.bits.settable || ind.bits.is_filter) {
- dfvar=&sysvar;
+ dfvar = &sysvar;
if (ind.bits.settable) {
- sysv_type=ind.index;
+ sysv_type = ind.index;
} else {
- sysv_type=0;
+ sysv_type = 0;
}
} else {
- dfvar=&glob_script_mem.fvars[index];
- sysv_type=0;
+ dfvar = &glob_script_mem.fvars[index];
+ sysv_type = 0;
}
- numeric=1;
- lp=getop(lp,&lastop);
- char *slp=lp;
- glob_script_mem.glob_error=0;
- lp=GetNumericResult(lp,OPER_EQU,&fvar,jo);
+ numeric = 1;
+ lp = getop(lp, &lastop);
+ char *slp = lp;
+ glob_script_mem.glob_error = 0;
+ lp = GetNumericArgument(lp, OPER_EQU, &fvar, jo);
if (glob_script_mem.glob_error==1) {
// mismatch was string, not number
// get the string and convert to number
- lp=isvar(slp,&vtype,&ind,0,cmpstr,jo);
- fvar=CharToFloat(cmpstr);
+ lp = isvar(slp, &vtype, &ind, 0, cmpstr, jo);
+ fvar = CharToFloat(cmpstr);
}
switch (lastop) {
case OPER_EQU:
@@ -3984,105 +3961,105 @@ int16_t Run_script_sub(const char *type, int8_t tlen, JsonObject *jo) {
if (!jo) toLogEOL("var not found: ",lp);
goto next_line;
}
- *dfvar=fvar;
+ *dfvar = fvar;
break;
case OPER_PLSEQU:
- *dfvar+=fvar;
+ *dfvar += fvar;
break;
case OPER_MINEQU:
- *dfvar-=fvar;
+ *dfvar -= fvar;
break;
case OPER_MULEQU:
- *dfvar*=fvar;
+ *dfvar *= fvar;
break;
case OPER_DIVEQU:
- *dfvar/=fvar;
+ *dfvar /= fvar;
break;
case OPER_PERCEQU:
- *dfvar=fmodf(*dfvar,fvar);
+ *dfvar = fmodf(*dfvar, fvar);
break;
case OPER_ANDEQU:
- *dfvar=(uint32_t)*dfvar&(uint32_t)fvar;
+ *dfvar = (uint32_t)*dfvar & (uint32_t)fvar;
break;
case OPER_OREQU:
- *dfvar=(uint32_t)*dfvar|(uint32_t)fvar;
+ *dfvar = (uint32_t)*dfvar | (uint32_t)fvar;
break;
case OPER_XOREQU:
- *dfvar=(uint32_t)*dfvar^(uint32_t)fvar;
+ *dfvar = (uint32_t)*dfvar ^ (uint32_t)fvar;
break;
default:
// error
break;
}
// var was changed
- glob_script_mem.type[globvindex].bits.changed=1;
+ glob_script_mem.type[globvindex].bits.changed = 1;
#ifdef USE_SCRIPT_GLOBVARS
if (glob_script_mem.type[globvindex].bits.global) {
- script_udp_sendvar(varname,dfvar,0);
+ script_udp_sendvar(varname, dfvar, 0);
}
-#endif
+#endif //USE_SCRIPT_GLOBVARS
if (glob_script_mem.type[globvindex].bits.is_filter) {
if (globaindex>=0) {
- Set_MFVal(glob_script_mem.type[globvindex].index,globaindex,*dfvar);
+ Set_MFVal(glob_script_mem.type[globvindex].index, globaindex, *dfvar);
} else {
- Set_MFilter(glob_script_mem.type[globvindex].index,*dfvar);
+ Set_MFilter(glob_script_mem.type[globvindex].index, *dfvar);
}
}
if (sysv_type) {
switch (sysv_type) {
case SCRIPT_LOGLEVEL:
- glob_script_mem.script_loglevel=*dfvar;
+ glob_script_mem.script_loglevel = *dfvar;
break;
case SCRIPT_TELEPERIOD:
- if (*dfvar<10) *dfvar=10;
- if (*dfvar>300) *dfvar=300;
- Settings.tele_period=*dfvar;
+ if (*dfvar<10) *dfvar = 10;
+ if (*dfvar>300) *dfvar = 300;
+ Settings.tele_period = *dfvar;
break;
case SCRIPT_EVENT_HANDLED:
- event_handeled=*dfvar;
+ event_handeled = *dfvar;
break;
}
- sysv_type=0;
+ sysv_type = 0;
}
} else {
// string result
- numeric=0;
- sindex=index;
- saindex=last_sindex;
+ numeric = 0;
+ sindex = index;
+ saindex = last_sindex;
// string result
char str[SCRIPT_MAXSSIZE];
- lp=getop(lp,&lastop);
- char *slp=lp;
- glob_script_mem.glob_error=0;
- lp=GetStringResult(lp,OPER_EQU,str,jo);
+ lp = getop(lp, &lastop);
+ char *slp = lp;
+ glob_script_mem.glob_error = 0;
+ lp = GetStringArgument(lp, OPER_EQU, str, jo);
if (!jo && glob_script_mem.glob_error) {
// mismatch
- lp=GetNumericResult(slp,OPER_EQU,&fvar,0);
- dtostrfd(fvar,6,str);
- glob_script_mem.glob_error=0;
+ lp = GetNumericArgument(slp, OPER_EQU, &fvar, 0);
+ dtostrfd(fvar, 6, str);
+ glob_script_mem.glob_error = 0;
}
if (!glob_script_mem.var_not_found) {
// var was changed
- glob_script_mem.type[globvindex].bits.changed=1;
+ glob_script_mem.type[globvindex].bits.changed = 1;
#ifdef USE_SCRIPT_GLOBVARS
if (glob_script_mem.type[globvindex].bits.global) {
- script_udp_sendvar(varname,0,str);
+ script_udp_sendvar(varname, 0, str);
}
-#endif
+#endif //USE_SCRIPT_GLOBVARS
if (saindex>=0) {
if (lastop==OPER_EQU) {
- strlcpy(glob_script_mem.last_index_string+(saindex*glob_script_mem.max_ssize),str,glob_script_mem.max_ssize);
+ strlcpy(glob_script_mem.last_index_string + (saindex * glob_script_mem.max_ssize), str, glob_script_mem.max_ssize);
} else if (lastop==OPER_PLSEQU) {
- strncat(glob_script_mem.last_index_string+(saindex*glob_script_mem.max_ssize),str,glob_script_mem.max_ssize);
+ strncat(glob_script_mem.last_index_string + (saindex * glob_script_mem.max_ssize), str, glob_script_mem.max_ssize);
}
- last_sindex=-1;
+ last_sindex = -1;
} else {
if (lastop==OPER_EQU) {
- strlcpy(glob_script_mem.glob_snp+(sindex*glob_script_mem.max_ssize),str,glob_script_mem.max_ssize);
+ strlcpy(glob_script_mem.glob_snp + (sindex * glob_script_mem.max_ssize), str, glob_script_mem.max_ssize);
} else if (lastop==OPER_PLSEQU) {
- strncat(glob_script_mem.glob_snp+(sindex*glob_script_mem.max_ssize),str,glob_script_mem.max_ssize);
+ strncat(glob_script_mem.glob_snp + (sindex * glob_script_mem.max_ssize), str, glob_script_mem.max_ssize);
}
}
}
@@ -4091,7 +4068,7 @@ int16_t Run_script_sub(const char *type, int8_t tlen, JsonObject *jo) {
}
SCRIPT_SKIP_SPACES
if (*lp=='{' && if_state[ifstck]==3) {
- lp+=1; // else
+ lp += 1; // else
//if_state[ifstck]=3;
}
goto next_line;
@@ -4102,67 +4079,67 @@ int16_t Run_script_sub(const char *type, int8_t tlen, JsonObject *jo) {
if (*lp=='>' && tlen==1) {
// called from cmdline
lp++;
- section=1;
- fromscriptcmd=1;
+ section = 1;
+ fromscriptcmd = 1;
goto startline;
}
- if (!strncmp(lp,type,tlen)) {
+ if (!strncmp(lp, type, tlen)) {
// found section
- section=1;
- glob_script_mem.section_ptr=lp;
+ section = 1;
+ glob_script_mem.section_ptr = lp;
if (check) {
return 99;
}
// check for subroutine
- char *ctype=(char*)type;
+ char *ctype = (char*)type;
if (*ctype=='#') {
// check for parameter
- ctype+=tlen;
+ ctype += tlen;
if (*ctype=='(' && *(lp+tlen)=='(') {
float fparam;
- numeric=1;
- glob_script_mem.glob_error=0;
- GetNumericResult((char*)ctype,OPER_EQU,&fparam,0);
+ numeric = 1;
+ glob_script_mem.glob_error = 0;
+ GetNumericArgument((char*)ctype, OPER_EQU, &fparam, 0);
if (glob_script_mem.glob_error==1) {
// was string, not number
- numeric=0;
+ numeric = 0;
// get the string
- GetStringResult((char*)ctype+1,OPER_EQU,cmpstr,0);
+ GetStringArgument((char*)ctype + 1, OPER_EQU, cmpstr, 0);
}
- lp+=tlen;
+ lp += tlen;
if (*lp=='(') {
// fetch destination
lp++;
- lp=isvar(lp,&vtype,&ind,0,0,0);
+ lp = isvar(lp, &vtype, &ind, 0, 0, 0);
if (vtype!=VAR_NV) {
// found variable as result
- uint8_t index=glob_script_mem.type[ind.index].index;
+ uint8_t index = glob_script_mem.type[ind.index].index;
if ((vtype&STYPE)==0) {
// numeric result
- dfvar=&glob_script_mem.fvars[index];
+ dfvar = &glob_script_mem.fvars[index];
if (numeric) {
- *dfvar=fparam;
+ *dfvar = fparam;
} else {
// mismatch
- *dfvar=CharToFloat(cmpstr);
+ *dfvar = CharToFloat(cmpstr);
}
} else {
// string result
- sindex=index;
+ sindex = index;
if (!numeric) {
- strlcpy(glob_script_mem.glob_snp+(sindex*glob_script_mem.max_ssize),cmpstr,glob_script_mem.max_ssize);
+ strlcpy(glob_script_mem.glob_snp + (sindex * glob_script_mem.max_ssize), cmpstr, glob_script_mem.max_ssize);
} else {
// mismatch
- dtostrfd(fparam,6,glob_script_mem.glob_snp+(sindex*glob_script_mem.max_ssize));
+ dtostrfd(fparam, 6, glob_script_mem.glob_snp + (sindex * glob_script_mem.max_ssize));
}
}
}
}
} else {
- lp+=tlen;
+ lp += tlen;
if (*ctype=='(' || (*lp!=SCRIPT_EOL && *lp!='?')) {
// revert
- section=0;
+ section = 0;
}
}
}
@@ -4201,11 +4178,11 @@ void ScripterEvery100ms(void) {
if (strlen(mqtt_data)) {
mqtt_data[0] = '{';
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data);
- Run_Scripter(">T",2, mqtt_data);
+ Run_Scripter(">T", 2, mqtt_data);
}
}
if (Settings.rule_enabled) {
- if (fast_script==99) Run_Scripter(">F",2,0);
+ if (fast_script==99) Run_Scripter(">F", 2, 0);
}
}
@@ -4213,48 +4190,48 @@ void ScripterEvery100ms(void) {
// can hold 11 floats or floats + strings
// should report overflow later
void Scripter_save_pvars(void) {
- int16_t mlen=0;
- float *fp=(float*)glob_script_mem.script_pram;
+ int16_t mlen = 0;
+ float *fp = (float*)glob_script_mem.script_pram;
mlen+=sizeof(float);
- struct T_INDEX *vtp=glob_script_mem.type;
- for (uint8_t count=0; countglob_script_mem.script_pram_size) {
- vtp[count].bits.is_permanent=0;
+ vtp[count].bits.is_permanent = 0;
return;
}
while (len--) {
- *fp++=*fa++;
+ *fp++ = *fa++;
}
} else {
- mlen+=sizeof(float);
+ mlen += sizeof(float);
if (mlen>glob_script_mem.script_pram_size) {
- vtp[count].bits.is_permanent=0;
+ vtp[count].bits.is_permanent = 0;
return;
}
- *fp++=glob_script_mem.fvars[index];
+ *fp++ = glob_script_mem.fvars[index];
}
}
}
- char *cp=(char*)fp;
- for (uint8_t count=0; countglob_script_mem.script_pram_size) {
- vtp[count].bits.is_permanent=0;
+ vtp[count].bits.is_permanent = 0;
return;
}
- strcpy(cp,sp);
- cp+=slen+1;
+ strcpy(cp, sp);
+ cp += slen + 1;
}
}
}
@@ -4351,7 +4328,7 @@ const char HTTP_FORM_SCRIPT1b[] PROGMEM =
"});"
-#endif
+#endif //SCRIPT_STRIP_COMMENTS
"";
@@ -4415,38 +4392,38 @@ void script_upload_start(void) {
HTTPUpload& upload = Webserver->upload();
if (upload.status == UPLOAD_FILE_START) {
//AddLog_P(LOG_LEVEL_INFO, PSTR("HTP: upload start"));
- script_ex_ptr=(uint8_t*)glob_script_mem.script_ram;
+ script_ex_ptr = (uint8_t*)glob_script_mem.script_ram;
//AddLog_P2(LOG_LEVEL_INFO, PSTR("HTP: upload file %s, %d"),upload.filename.c_str(),upload.totalSize);
- if (strcmp(upload.filename.c_str(),"execute_script")) {
- Web.upload_error=1;
+ if (strcmp(upload.filename.c_str(), "execute_script")) {
+ Web.upload_error = 1;
WSSend(500, CT_PLAIN, F("500: wrong filename"));
return;
}
if (upload.totalSize>=glob_script_mem.script_size) {
- Web.upload_error=1;
+ Web.upload_error = 1;
WSSend(500, CT_PLAIN, F("500: file to large"));
return;
}
- uplsize=0;
+ uplsize = 0;
sc_state = bitRead(Settings.rule_enabled, 0);
- bitWrite(Settings.rule_enabled,0,0);
+ bitWrite(Settings.rule_enabled, 0, 0);
} else if(upload.status == UPLOAD_FILE_WRITE) {
//AddLog_P(LOG_LEVEL_INFO, PSTR("HTP: upload write"));
- uint32_t csiz=upload.currentSize;
- uint32_t tsiz=glob_script_mem.script_size-1;
+ uint32_t csiz = upload.currentSize;
+ uint32_t tsiz = glob_script_mem.script_size - 1;
if (uplsizeopen(path, FILE_READ);
+ File dir = fsp->open(path, FILE_READ);
if (dir) {
dir.rewindDirectory();
if (strlen(path)>1) {
- snprintf_P(npath,sizeof(npath),PSTR("http://%s/upl?download=%s"),WiFi.localIP().toString().c_str(),path);
- for (uint8_t cnt=strlen(npath)-1;cnt>0;cnt--) {
+ snprintf_P(npath, sizeof(npath), PSTR("http://%s/upl?download=%s"), WiFi.localIP().toString().c_str(),path);
+ for (uint8_t cnt = strlen(npath) - 1; cnt>0; cnt--) {
if (npath[cnt]=='/') {
- if (npath[cnt-1]=='=') npath[cnt+1]=0;
- else npath[cnt]=0;
+ if (npath[cnt - 1]=='=') npath[cnt + 1] = 0;
+ else npath[cnt] = 0;
break;
}
}
- WSContentSend_P(HTTP_FORM_SDC_DIRd,npath,path,"..");
+ WSContentSend_P(HTTP_FORM_SDC_DIRd, npath,path, "..");
}
char *ep;
while (true) {
- File entry=dir.openNextFile();
+ File entry = dir.openNextFile();
if (!entry) {
break;
}
// esp32 returns path here, shorten to filename
- ep=(char*)entry.name();
+ ep = (char*)entry.name();
if (*ep=='/') ep++;
char *lcp = strrchr(ep,'/');
if (lcp) {
- ep=lcp+1;
+ ep = lcp + 1;
}
//AddLog_P2(LOG_LEVEL_INFO, PSTR("entry: %s"),ep);
- time_t tm=entry.getLastWrite();
+ time_t tm = entry.getLastWrite();
char tstr[24];
strftime(tstr, 22, "%d-%m-%Y - %H:%M:%S ", localtime(&tm));
- char *pp=path;
- if (!*(pp+1)) pp++;
- char *cp=name;
+ char *pp = path;
+ if (!*(pp + 1)) pp++;
+ char *cp = name;
// osx formatted disks contain a lot of stuff we dont want
if (reject((char*)ep)) goto fclose;
- for (uint8_t cnt=0;cnt1) {
- strcat(path,"/");
+ strcat(path, "/");
}
- strcat(path,ep);
- ListDir(path,depth+4);
- path[plen]=0;
+ strcat(path, ep);
+ ListDir(path, depth + 4);
+ path[plen] = 0;
} else {
- snprintf_P(npath,sizeof(npath),HTTP_FORM_SDC_HREF,WiFi.localIP().toString().c_str(),pp,ep);
- WSContentSend_P(HTTP_FORM_SDC_DIRb,npath,ep,name,tstr,entry.size());
+ snprintf_P(npath, sizeof(npath), HTTP_FORM_SDC_HREF, WiFi.localIP().toString().c_str(), pp,ep);
+ WSContentSend_P(HTTP_FORM_SDC_DIRb, npath, ep, name, tstr, entry.size());
}
fclose:
entry.close();
@@ -4576,18 +4553,18 @@ void ListDir(char *path, uint8_t depth) {
char path[48];
void Script_FileUploadConfiguration(void) {
- uint8_t depth=0;
+ uint8_t depth = 0;
- strcpy(path,"/");
+ strcpy(path, "/");
if (!HttpCheckPriviledgedAccess()) { return; }
if (Webserver->hasArg("download")) {
String stmp = Webserver->arg("download");
- char *cp=(char*)stmp.c_str();
+ char *cp = (char*)stmp.c_str();
if (DownloadFile(cp)) {
// is directory
- strcpy(path,cp);
+ strcpy(path, cp);
}
}
@@ -4598,7 +4575,7 @@ void Script_FileUploadConfiguration(void) {
#ifdef SDCARD_DIR
WSContentSend_P(HTTP_FORM_SDC_DIRa);
if (glob_script_mem.script_sd_found) {
- ListDir(path,depth);
+ ListDir(path, depth);
}
WSContentSend_P(HTTP_FORM_SDC_DIRc);
#endif
@@ -4629,15 +4606,15 @@ void script_upload(void) {
char npath[48];
#if defined(ESP32) && defined(USE_SCRIPT_FATFS) && USE_SCRIPT_FATFS==-1
//sprintf(npath,"/%s",upload.filename.c_str());
- sprintf(npath,"%s/%s",path,upload.filename.c_str());
+ sprintf(npath, "%s/%s", path, upload.filename.c_str());
#else
- sprintf(npath,"%s/%s",path,upload.filename.c_str());
+ sprintf(npath, "%s/%s", path, upload.filename.c_str());
#endif
fsp->remove(npath);
- upload_file=fsp->open(npath,FILE_WRITE);
- if (!upload_file) Web.upload_error=1;
+ upload_file = fsp->open(npath, FILE_WRITE);
+ if (!upload_file) Web.upload_error = 1;
} else if(upload.status == UPLOAD_FILE_WRITE) {
- if (upload_file) upload_file.write(upload.buf,upload.currentSize);
+ if (upload_file) upload_file.write(upload.buf, upload.currentSize);
} else if(upload.status == UPLOAD_FILE_END) {
if (upload_file) upload_file.close();
if (Web.upload_error) {
@@ -4658,7 +4635,7 @@ uint8_t DownloadFile(char *file) {
return 0;
}
- download_file=fsp->open(file,FILE_READ);
+ download_file = fsp->open(file, FILE_READ);
if (!download_file) {
AddLog_P(LOG_LEVEL_INFO,PSTR("could not open file"));
return 0;
@@ -4669,20 +4646,20 @@ uint8_t DownloadFile(char *file) {
return 1;
}
- uint32_t flen=download_file.size();
+ uint32_t flen = download_file.size();
download_Client = Webserver->client();
Webserver->setContentLength(flen);
char attachment[100];
char *cp;
- for (uint8_t cnt=strlen(file); cnt>=0; cnt--) {
+ for (uint8_t cnt = strlen(file); cnt>=0; cnt--) {
if (file[cnt]=='/') {
- cp=&file[cnt+1];
+ cp = &file[cnt + 1];
break;
}
}
- snprintf_P(attachment, sizeof(attachment), PSTR("attachment; filename=%s"),cp);
+ snprintf_P(attachment, sizeof(attachment), PSTR("attachment; filename=%s"), cp);
Webserver->sendHeader(F("Content-Disposition"), attachment);
WSSend(200, CT_STREAM, "");
@@ -4690,15 +4667,15 @@ uint8_t DownloadFile(char *file) {
uint16_t bread;
// transfer is about 150kb/s
- uint8_t cnt=0;
+ uint8_t cnt = 0;
while (download_file.available()) {
- bread=download_file.read(buff,sizeof(buff));
- uint16_t bw=download_Client.write((const char*)buff,bread);
+ bread = download_file.read(buff, sizeof(buff));
+ uint16_t bw = download_Client.write((const char*)buff, bread);
if (!bw) break;
cnt++;
if (cnt>7) {
- cnt=0;
- if (glob_script_mem.script_loglevel&0x80) {
+ cnt = 0;
+ if (glob_script_mem.script_loglevel & 0x80) {
// this indeed multitasks, but is slower 50 kB/s
loop();
}
@@ -4747,8 +4724,8 @@ void HandleScriptConfiguration(void) {
#ifdef xSCRIPT_STRIP_COMMENTS
- uint16_t ssize=glob_script_mem.script_size;
- if (bitRead(Settings.rule_enabled, 1)) ssize*=2;
+ uint16_t ssize = glob_script_mem.script_size;
+ if (bitRead(Settings.rule_enabled, 1)) ssize *= 2;
WSContentSend_P(HTTP_FORM_SCRIPT1,1,1,bitRead(Settings.rule_enabled,0) ? " checked" : "",ssize);
#else
WSContentSend_P(HTTP_FORM_SCRIPT1,1,1,bitRead(Settings.rule_enabled,0) ? " checked" : "",glob_script_mem.script_size);
@@ -4763,10 +4740,10 @@ void HandleScriptConfiguration(void) {
#ifdef USE_SCRIPT_FATFS
if (glob_script_mem.script_sd_found) {
WSContentSend_P(HTTP_FORM_SCRIPT1d);
- if (glob_script_mem.flink[0][0]) WSContentSend_P(HTTP_FORM_SCRIPT1c,1,glob_script_mem.flink[0]);
- if (glob_script_mem.flink[1][0]) WSContentSend_P(HTTP_FORM_SCRIPT1c,2,glob_script_mem.flink[1]);
+ if (glob_script_mem.flink[0][0]) WSContentSend_P(HTTP_FORM_SCRIPT1c, 1, glob_script_mem.flink[0]);
+ if (glob_script_mem.flink[1][0]) WSContentSend_P(HTTP_FORM_SCRIPT1c, 2, glob_script_mem.flink[1]);
}
-#endif
+#endif //USE_SCRIPT_FATFS
WSContentSend_P(HTTP_SCRIPT_FORM_END);
WSContentSpaceButton(BUTTON_CONFIGURATION);
@@ -4777,22 +4754,22 @@ void SaveScript(void) {
#ifdef EEP_SCRIPT_SIZE
if (glob_script_mem.flags&1) {
- EEP_WRITE(0,EEP_SCRIPT_SIZE,glob_script_mem.script_ram);
+ EEP_WRITE(0, EEP_SCRIPT_SIZE, glob_script_mem.script_ram);
}
#endif // EEP_SCRIPT_SIZE
#ifdef USE_SCRIPT_FATFS
- if (glob_script_mem.flags&1) {
+ if (glob_script_mem.flags & 1) {
fsp->remove(FAT_SCRIPT_NAME);
- File file=fsp->open(FAT_SCRIPT_NAME,FILE_WRITE);
- file.write((const uint8_t*)glob_script_mem.script_ram,FAT_SCRIPT_SIZE);
+ File file = fsp->open(FAT_SCRIPT_NAME, FILE_WRITE);
+ file.write((const uint8_t*)glob_script_mem.script_ram, FAT_SCRIPT_SIZE);
file.close();
}
#endif // USE_SCRIPT_FATFS
#ifdef LITTLEFS_SCRIPT_SIZE
if (glob_script_mem.flags&1) {
- SaveFile("/script.txt",(uint8_t*)glob_script_mem.script_ram,LITTLEFS_SCRIPT_SIZE);
+ SaveFile("/script.txt", (uint8_t*)glob_script_mem.script_ram, LITTLEFS_SCRIPT_SIZE);
}
#endif // LITTLEFS_SCRIPT_SIZE
}
@@ -4800,9 +4777,9 @@ void SaveScript(void) {
void ScriptSaveSettings(void) {
if (Webserver->hasArg("c1")) {
- bitWrite(Settings.rule_enabled,0,1);
+ bitWrite(Settings.rule_enabled, 0, 1);
} else {
- bitWrite(Settings.rule_enabled,0,0);
+ bitWrite(Settings.rule_enabled, 0, 0);
}
@@ -4810,42 +4787,42 @@ void ScriptSaveSettings(void) {
if (*str.c_str()) {
- str.replace("\r\n","\n");
- str.replace("\r","\n");
+ str.replace("\r\n", "\n");
+ str.replace("\r", "\n");
#ifdef xSCRIPT_STRIP_COMMENTS
if (bitRead(Settings.rule_enabled, 1)) {
- char *sp=(char*)str.c_str();
- char *sp1=sp;
- char *dp=sp;
- uint8_t flg=0;
+ char *sp = (char*)str.c_str();
+ char *sp1 = sp;
+ char *dp = sp;
+ uint8_t flg = 0;
while (*sp) {
while (*sp==' ') sp++;
- sp1=sp;
- sp=strchr(sp,'\n');
+ sp1 = sp;
+ sp = strchr(sp,'\n');
if (!sp) {
- flg=1;
+ flg = 1;
} else {
- *sp=0;
+ *sp = 0;
}
if (*sp1!=';') {
- uint8_t slen=strlen(sp1);
+ uint8_t slen = strlen(sp1);
if (slen) {
- strcpy(dp,sp1);
- dp+=slen;
- *dp++='\n';
+ strcpy(dp, sp1);
+ dp += slen;
+ *dp++ = '\n';
}
}
if (flg) {
- *dp=0;
+ *dp = 0;
break;
}
sp++;
}
}
-#endif
+#endif //xSCRIPT_STRIP_COMMENTS
- strlcpy(glob_script_mem.script_ram,str.c_str(), glob_script_mem.script_size);
+ strlcpy(glob_script_mem.script_ram, str.c_str(), glob_script_mem.script_size);
if (glob_script_mem.script_ram[0]!='>' && glob_script_mem.script_ram[1]!='D') {
AddLog_P2(LOG_LEVEL_INFO, PSTR("script error: must start with >D"));
@@ -4863,8 +4840,8 @@ void SaveScriptEnd(void) {
if (glob_script_mem.script_mem) {
Scripter_save_pvars();
free(glob_script_mem.script_mem);
- glob_script_mem.script_mem=0;
- glob_script_mem.script_mem_size=0;
+ glob_script_mem.script_mem = 0;
+ glob_script_mem.script_mem_size = 0;
}
#ifdef USE_SCRIPT_COMPRESSION
@@ -4879,20 +4856,20 @@ void SaveScriptEnd(void) {
#endif // USE_SCRIPT_COMPRESSION
if (bitRead(Settings.rule_enabled, 0)) {
- int16_t res=Init_Scripter();
+ int16_t res = Init_Scripter();
if (res) {
AddLog_P2(LOG_LEVEL_INFO, PSTR("script init error: %d"), res);
return;
}
- Run_Scripter(">B\n",3,0);
- Run_Scripter(">BS",3,0);
+ Run_Scripter(">B\n", 3, 0);
+ Run_Scripter(">BS", 3, 0);
- fast_script=Run_Scripter(">F",-2,0);
+ fast_script = Run_Scripter(">F", -2, 0);
}
}
-#endif
+#endif // USE_WEBSERVER
#if defined(USE_SCRIPT_HUE) && defined(USE_WEBSERVER) && defined(USE_EMULATION) && defined(USE_EMULATION_HUE) && defined(USE_LIGHT)
@@ -5026,22 +5003,22 @@ break;
void Script_HueStatus(String *response, uint16_t hue_devs) {
if (hue_script[hue_devs].type=='p') {
- *response+=FPSTR(SCRIPT_HUE_LIGHTS_STATUS_JSON2);
- response->replace("{j1",hue_script[hue_devs].name);
+ *response += FPSTR(SCRIPT_HUE_LIGHTS_STATUS_JSON2);
+ response->replace("{j1", hue_script[hue_devs].name);
response->replace("{j2", GetHueDeviceId(hue_devs));
- uint8_t pwr=glob_script_mem.fvars[hue_script[hue_devs].index[0]-1];
+ uint8_t pwr = glob_script_mem.fvars[hue_script[hue_devs].index[0] - 1];
response->replace("{state}", (pwr ? "true" : "false"));
return;
}
- *response+=FPSTR(SCRIPT_HUE_LIGHTS_STATUS_JSON1);
- uint8_t pwr=glob_script_mem.fvars[hue_script[hue_devs].index[0]-1];
+ *response += FPSTR(SCRIPT_HUE_LIGHTS_STATUS_JSON1);
+ uint8_t pwr = glob_script_mem.fvars[hue_script[hue_devs].index[0] - 1];
response->replace("{state}", (pwr ? "true" : "false"));
String light_status = "";
if (hue_script[hue_devs].index[1]>0) {
// bri
light_status += "\"bri\":";
- uint32_t bri=glob_script_mem.fvars[hue_script[hue_devs].index[1]-1];
+ uint32_t bri = glob_script_mem.fvars[hue_script[hue_devs].index[1] - 1];
if (bri > 254) bri = 254;
if (bri < 1) bri = 1;
light_status += String(bri);
@@ -5049,7 +5026,7 @@ void Script_HueStatus(String *response, uint16_t hue_devs) {
}
if (hue_script[hue_devs].index[2]>0) {
// hue
- uint32_t hue=glob_script_mem.fvars[hue_script[hue_devs].index[2]-1];
+ uint32_t hue = glob_script_mem.fvars[hue_script[hue_devs].index[2] - 1];
//hue = changeUIntScale(hue, 0, 359, 0, 65535);
light_status += "\"hue\":";
light_status += String(hue);
@@ -5057,7 +5034,7 @@ void Script_HueStatus(String *response, uint16_t hue_devs) {
}
if (hue_script[hue_devs].index[3]>0) {
// sat
- uint32_t sat=glob_script_mem.fvars[hue_script[hue_devs].index[3]-1] ;
+ uint32_t sat = glob_script_mem.fvars[hue_script[hue_devs].index[3] - 1] ;
if (sat > 254) sat = 254;
if (sat < 1) sat = 1;
light_status += "\"sat\":";
@@ -5066,7 +5043,7 @@ void Script_HueStatus(String *response, uint16_t hue_devs) {
}
if (hue_script[hue_devs].index[4]>0) {
// ct
- uint32_t ct=glob_script_mem.fvars[hue_script[hue_devs].index[4]-1];
+ uint32_t ct = glob_script_mem.fvars[hue_script[hue_devs].index[4] - 1];
light_status += "\"ct\":";
light_status += String(ct);
light_status += ",";
@@ -5101,7 +5078,7 @@ void Script_HueStatus(String *response, uint16_t hue_devs) {
}
response->replace("{light_status}", light_status);
- response->replace("{j1",hue_script[hue_devs].name);
+ response->replace("{j1", hue_script[hue_devs].name);
response->replace("{j2", GetHueDeviceId(hue_devs));
}
@@ -5109,14 +5086,14 @@ void Script_HueStatus(String *response, uint16_t hue_devs) {
void Script_Check_Hue(String *response) {
if (!bitRead(Settings.rule_enabled, 0)) return;
- uint8_t hue_script_found=Run_Scripter(">H",-2,0);
+ uint8_t hue_script_found = Run_Scripter(">H", -2, 0);
if (hue_script_found!=99) return;
char tmp[256];
- uint8_t hue_devs=0;
- uint8_t vindex=0;
+ uint8_t hue_devs = 0;
+ uint8_t vindex = 0;
char *cp;
- char *lp=glob_script_mem.section_ptr+2;
+ char *lp = glob_script_mem.section_ptr + 2;
while (lp) {
SCRIPT_SKIP_SPACES
while (*lp==SCRIPT_EOL) {
@@ -5127,69 +5104,69 @@ void Script_Check_Hue(String *response) {
}
if (*lp!=';') {
// check this line
- Replace_Cmd_Vars(lp,1,tmp,sizeof(tmp));
+ Replace_Cmd_Vars(lp, 1, tmp, sizeof(tmp));
// check for hue defintions
// NAME, TYPE , vars
- cp=tmp;
- cp=strchr(cp,',');
+ cp = tmp;
+ cp = strchr(cp,',');
if (!cp) break;
- *cp=0;
+ *cp = 0;
// copy name
- strlcpy(hue_script[hue_devs].name,tmp,HUE_DEV_NSIZE);
+ strlcpy(hue_script[hue_devs].name, tmp, HUE_DEV_NSIZE);
cp++;
while (*cp==' ') cp++;
// get type
- hue_script[hue_devs].type=*cp;
+ hue_script[hue_devs].type = *cp;
- for (vindex=0;vindex0) *response+=",\"";
- else *response+="\"";
+ if (hue_devs>0) *response += ",\"";
+ else *response += "\"";
}
- *response+=String(EncodeLightId(hue_devs+devices_present+1))+"\":";
- Script_HueStatus(response,hue_devs);
+ *response += String(EncodeLightId(hue_devs + devices_present + 1))+"\":";
+ Script_HueStatus(response, hue_devs);
//AddLog_P2(LOG_LEVEL_INFO, PSTR("Hue: %s - %d "),response->c_str(), hue_devs);
}
@@ -5252,13 +5229,13 @@ void Script_Handle_Hue(String *path) {
bool resp = false;
uint8_t device = DecodeLightId(atoi(path->c_str()));
- uint8_t index = device-devices_present-1;
+ uint8_t index = device - devices_present - 1;
if (Webserver->args()) {
response = "[";
StaticJsonBuffer<400> jsonBuffer;
- JsonObject &hue_json = jsonBuffer.parseObject(Webserver->arg((Webserver->args())-1));
+ JsonObject &hue_json = jsonBuffer.parseObject(Webserver->arg((Webserver->args()) - 1));
if (hue_json.containsKey("on")) {
response += FPSTR(sHUE_LIGHT_RESPONSE_JSON);
@@ -5267,26 +5244,26 @@ void Script_Handle_Hue(String *path) {
bool on = hue_json["on"];
if (on==false) {
- glob_script_mem.fvars[hue_script[index].index[0]-1]=0;
+ glob_script_mem.fvars[hue_script[index].index[0] - 1] = 0;
response.replace("{re", "false");
} else {
- glob_script_mem.fvars[hue_script[index].index[0]-1]=1;
+ glob_script_mem.fvars[hue_script[index].index[0] - 1] = 1;
response.replace("{re", "true");
}
- glob_script_mem.type[hue_script[index].vindex[0]].bits.changed=1;
+ glob_script_mem.type[hue_script[index].vindex[0]].bits.changed = 1;
resp = true;
}
if (hue_json.containsKey("bri")) { // Brightness is a scale from 1 (the minimum the light is capable of) to 254 (the maximum). Note: a brightness of 1 is not off.
tmp = hue_json["bri"];
- bri=tmp;
+ bri = tmp;
if (254 <= bri) { bri = 255; }
if (resp) { response += ","; }
response += FPSTR(sHUE_LIGHT_RESPONSE_JSON);
response.replace("{id", String(EncodeLightId(device)));
response.replace("{cm", "bri");
response.replace("{re", String(tmp));
- glob_script_mem.fvars[hue_script[index].index[1]-1]=bri;
- glob_script_mem.type[hue_script[index].vindex[1]].bits.changed=1;
+ glob_script_mem.fvars[hue_script[index].index[1] - 1] = bri;
+ glob_script_mem.type[hue_script[index].vindex[1]].bits.changed = 1;
resp = true;
}
if (hue_json.containsKey("xy")) { // Saturation of the light. 254 is the most saturated (colored) and 0 is the least saturated (white).
@@ -5303,10 +5280,10 @@ void Script_Handle_Hue(String *path) {
response.replace("{id", String(device));
response.replace("{cm", "xy");
response.replace("{re", "[" + x_str + "," + y_str + "]");
- glob_script_mem.fvars[hue_script[index].index[2]-1]=hue;
- glob_script_mem.type[hue_script[index].vindex[2]].bits.changed=1;
- glob_script_mem.fvars[hue_script[index].index[3]-1]=sat;
- glob_script_mem.type[hue_script[index].vindex[3]].bits.changed=1;
+ glob_script_mem.fvars[hue_script[index].index[2]-1] = hue;
+ glob_script_mem.type[hue_script[index].vindex[2]].bits.changed = 1;
+ glob_script_mem.fvars[hue_script[index].index[3]-1] = sat;
+ glob_script_mem.type[hue_script[index].vindex[3]].bits.changed = 1;
resp = true;
}
@@ -5314,27 +5291,27 @@ void Script_Handle_Hue(String *path) {
tmp = hue_json["hue"];
//hue = changeUIntScale(tmp, 0, 65535, 0, 359);
//tmp = changeUIntScale(hue, 0, 359, 0, 65535);
- hue=tmp;
+ hue = tmp;
if (resp) { response += ","; }
response += FPSTR(sHUE_LIGHT_RESPONSE_JSON);
response.replace("{id", String(EncodeLightId(device)));
response.replace("{cm", "hue");
response.replace("{re", String(tmp));
- glob_script_mem.fvars[hue_script[index].index[2]-1]=hue;
- glob_script_mem.type[hue_script[index].vindex[2]].bits.changed=1;
+ glob_script_mem.fvars[hue_script[index].index[2] - 1] = hue;
+ glob_script_mem.type[hue_script[index].vindex[2]].bits.changed = 1;
resp = true;
}
if (hue_json.containsKey("sat")) { // Saturation of the light. 254 is the most saturated (colored) and 0 is the least saturated (white).
tmp = hue_json["sat"];
- sat=tmp;
+ sat = tmp;
if (254 <= sat) { sat = 255; }
if (resp) { response += ","; }
response += FPSTR(sHUE_LIGHT_RESPONSE_JSON);
response.replace("{id", String(EncodeLightId(device)));
response.replace("{cm", "sat");
response.replace("{re", String(tmp));
- glob_script_mem.fvars[hue_script[index].index[3]-1]=sat;
- glob_script_mem.type[hue_script[index].vindex[3]].bits.changed=1;
+ glob_script_mem.fvars[hue_script[index].index[3] - 1] = sat;
+ glob_script_mem.type[hue_script[index].vindex[3]].bits.changed = 1;
resp = true;
}
if (hue_json.containsKey("ct")) { // Color temperature 153 (Cold) to 500 (Warm)
@@ -5344,8 +5321,8 @@ void Script_Handle_Hue(String *path) {
response.replace("{id", String(EncodeLightId(device)));
response.replace("{cm", "ct");
response.replace("{re", String(ct));
- glob_script_mem.fvars[hue_script[index].index[4]-1]=ct;
- glob_script_mem.type[hue_script[index].vindex[4]].bits.changed=1;
+ glob_script_mem.fvars[hue_script[index].index[4] - 1] = ct;
+ glob_script_mem.type[hue_script[index].vindex[4]].bits.changed = 1;
resp = true;
}
response += "]";
@@ -5356,7 +5333,7 @@ void Script_Handle_Hue(String *path) {
AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_HTTP D_HUE " Result (%s)"), response.c_str());
WSSend(code, CT_JSON, response);
if (resp) {
- Run_Scripter(">E",2,0);
+ Run_Scripter(">E", 2, 0);
}
}
#endif // hue interface
@@ -5369,30 +5346,30 @@ bool Script_SubCmd(void) {
if (tasm_cmd_activ) return false;
char command[CMDSZ];
- strlcpy(command,XdrvMailbox.topic,CMDSZ);
- uint32_t pl=XdrvMailbox.payload;
+ strlcpy(command, XdrvMailbox.topic, CMDSZ);
+ uint32_t pl = XdrvMailbox.payload;
char pld[64];
- strlcpy(pld,XdrvMailbox.data,sizeof(pld));
+ strlcpy(pld, XdrvMailbox.data, sizeof(pld));
char cmdbuff[128];
- char *cp=cmdbuff;
- *cp++='#';
- strcpy(cp,XdrvMailbox.topic);
- uint8_t tlen=strlen(XdrvMailbox.topic);
- cp+=tlen;
+ char *cp = cmdbuff;
+ *cp++ = '#';
+ strcpy(cp, XdrvMailbox.topic);
+ uint8_t tlen = strlen(XdrvMailbox.topic);
+ cp += tlen;
if (XdrvMailbox.index > 0) {
- *cp++=XdrvMailbox.index|0x30;
+ *cp++ = XdrvMailbox.index | 0x30;
tlen++;
}
if ((XdrvMailbox.payload>0) || (XdrvMailbox.data_len>0)) {
- *cp++='(';
- strncpy(cp,XdrvMailbox.data,XdrvMailbox.data_len);
- cp+=XdrvMailbox.data_len;
- *cp++=')';
- *cp=0;
+ *cp++ = '(';
+ strncpy(cp, XdrvMailbox.data,XdrvMailbox.data_len);
+ cp += XdrvMailbox.data_len;
+ *cp++ = ')';
+ *cp = 0;
}
//toLog(cmdbuff);
- uint32_t res=Run_Scripter(cmdbuff,tlen+1,0);
+ uint32_t res = Run_Scripter(cmdbuff, tlen + 1, 0);
//AddLog_P2(LOG_LEVEL_INFO,">>%d",res);
if (res) return false;
else {
@@ -5404,14 +5381,14 @@ bool Script_SubCmd(void) {
}
return true;
}
-#endif
+#endif //USE_SCRIPT_SUB_COMMAND
void execute_script(char *script) {
- char *svd_sp=glob_script_mem.scriptptr;
- strcat(script,"\n#");
- glob_script_mem.scriptptr=script;
- Run_Scripter(">",1,0);
- glob_script_mem.scriptptr=svd_sp;
+ char *svd_sp = glob_script_mem.scriptptr;
+ strcat(script, "\n#");
+ glob_script_mem.scriptptr = script;
+ Run_Scripter(">", 1, 0);
+ glob_script_mem.scriptptr = svd_sp;
}
#define D_CMND_SCRIPT "Script"
#define D_CMND_SUBSCRIBE "Subscribe"
@@ -5441,44 +5418,44 @@ bool ScriptCommand(void) {
break;
#ifdef xSCRIPT_STRIP_COMMENTS
case 2:
- bitWrite(Settings.rule_enabled, 1,0);
+ bitWrite(Settings.rule_enabled, 1, 0);
break;
case 3:
- bitWrite(Settings.rule_enabled, 1,1);
+ bitWrite(Settings.rule_enabled, 1, 1);
break;
-#endif
+#endif //xSCRIPT_STRIP_COMMENTS
}
} else {
if ('>' == XdrvMailbox.data[0]) {
// execute script
- snprintf_P (mqtt_data, sizeof(mqtt_data), PSTR("{\"%s\":\"%s\"}"),command,XdrvMailbox.data);
+ snprintf_P (mqtt_data, sizeof(mqtt_data), PSTR("{\"%s\":\"%s\"}"), command,XdrvMailbox.data);
if (bitRead(Settings.rule_enabled, 0)) {
- for (uint8_t count=0; count, [, ]
String result = ScriptSubscribe(XdrvMailbox.data, XdrvMailbox.data_len);
@@ -5486,7 +5463,7 @@ bool ScriptCommand(void) {
} else if (CMND_UNSUBSCRIBE == command_code) { //MQTT Un-subscribe command. UnSubscribe
String result = ScriptUnsubscribe(XdrvMailbox.data, XdrvMailbox.data_len);
Response_P(S_JSON_COMMAND_SVALUE, command, result.c_str());
-#endif //SUPPORT_MQTT_EVENT
+#endif //SUPPORT_MQTT_EVENT
}
return serviced;
}
@@ -5508,7 +5485,7 @@ void dateTime(uint16_t* date, uint16_t* time) {
*time = xFAT_TIME(RtcTime.hour,RtcTime.minute,RtcTime.second);
}
-#endif
+#endif //USE_SCRIPT_FATFS
@@ -5519,7 +5496,7 @@ void dateTime(uint16_t* date, uint16_t* time) {
#endif
#ifndef MQTT_EVENT_JSIZE
#define MQTT_EVENT_JSIZE 400
-#endif
+#endif //SUPPORT_MQTT_EVENT
/********************************************************************************************/
/*
@@ -5565,21 +5542,21 @@ bool ScriptMqttData(void)
if ((dot = key1.indexOf('.')) > 0) {
key2 = key1.substring(dot+1);
key1 = key1.substring(0, dot);
- lkey=key2;
+ lkey = key2;
if (!jsonData[key1][key2].success()) break; //Failed to get the key/value, ignore this message.
value = (const char *)jsonData[key1][key2];
} else {
if (!jsonData[key1].success()) break;
value = (const char *)jsonData[key1];
- lkey=key1;
+ lkey = key1;
}
}
value.trim();
char sbuffer[128];
- if (!strncmp(lkey.c_str(),"Epoch",5)) {
- uint32_t ep=atoi(value.c_str())-(uint32_t)EPOCH_OFFSET;
- snprintf_P(sbuffer, sizeof(sbuffer), PSTR(">%s=%d\n"), event_item.Event.c_str(),ep);
+ if (!strncmp(lkey.c_str(), "Epoch", 5)) {
+ uint32_t ep = atoi(value.c_str()) - (uint32_t)EPOCH_OFFSET;
+ snprintf_P(sbuffer, sizeof(sbuffer), PSTR(">%s=%d\n"), event_item.Event.c_str(), ep);
} else {
snprintf_P(sbuffer, sizeof(sbuffer), PSTR(">%s=\"%s\"\n"), event_item.Event.c_str(), value.c_str());
}
@@ -5611,7 +5588,7 @@ String ScriptSubscribe(const char *data, int data_len)
MQTT_Subscription subscription_item;
String events;
if (data_len > 0) {
- char parameters[data_len+1];
+ char parameters[data_len + 1];
memcpy(parameters, data, data_len);
parameters[data_len] = '\0';
String event_name, topic, key;
@@ -5632,7 +5609,7 @@ String ScriptSubscribe(const char *data, int data_len)
//event_name.toUpperCase();
if (event_name.length() > 0 && topic.length() > 0) {
//Search all subscriptions
- for (uint32_t index=0; index < subscriptions.size(); index++) {
+ for (uint32_t index = 0; index < subscriptions.size(); index++) {
if (subscriptions.get(index).Event.equals(event_name)) {
//If find exists one, remove it.
String stopic = subscriptions.get(index).Topic + "/#";
@@ -5665,7 +5642,7 @@ String ScriptSubscribe(const char *data, int data_len)
}
} else {
//If did not specify the event name, list all subscribed event
- for (uint32_t index=0; index < subscriptions.size(); index++) {
+ for (uint32_t index = 0; index < subscriptions.size(); index++) {
subscription_item = subscriptions.get(index);
events.concat(subscription_item.Event + "," + subscription_item.Topic
+ (subscription_item.Key.length()>0 ? "," : "")
@@ -5795,15 +5772,15 @@ void ScriptGetSDCard(void) {
if (!HttpCheckPriviledgedAccess()) { return; }
String stmp = Webserver->uri();
- char *cp=strstr_P(stmp.c_str(),PSTR("/sdc/"));
+ char *cp = strstr_P(stmp.c_str(), PSTR("/sdc/"));
// if (cp) Serial.printf(">>>%s\n",cp);
if (cp) {
#ifdef ESP32
- cp+=4;
+ cp += 4;
#else
- cp+=5;
+ cp += 5;
#endif
- if (strstr_P(cp,PSTR("scrdmp.bmp"))) {
+ if (strstr_P(cp, PSTR("scrdmp.bmp"))) {
SendFile(cp);
return;
} else {
@@ -5821,34 +5798,34 @@ extern uint8_t *buffer;
void SendFile(char *fname) {
char buff[512];
const char *mime;
- uint8_t sflg=0;
- char *jpg=strstr(fname,".jpg");
+ uint8_t sflg = 0;
+ char *jpg = strstr(fname,".jpg");
if (jpg) {
- mime="image/jpeg";
+ mime = "image/jpeg";
}
#ifdef USE_DISPLAY_DUMP
- char *sbmp=strstr_P(fname,PSTR("scrdmp.bmp"));
+ char *sbmp = strstr_P(fname, PSTR("scrdmp.bmp"));
if (sbmp) {
- mime="image/bmp";
- sflg=1;
+ mime = "image/bmp";
+ sflg = 1;
}
#endif // USE_DISPLAY_DUMP
- char *bmp=strstr(fname,".bmp");
+ char *bmp = strstr(fname, ".bmp");
if (bmp) {
- mime="image/bmp";
+ mime = "image/bmp";
}
- char *html=strstr(fname,".html");
+ char *html = strstr(fname, ".html");
if (html) {
- mime="text/html";
+ mime = "text/html";
}
- char *txt=strstr(fname,".txt");
+ char *txt = strstr(fname, ".txt");
if (txt) {
- mime="text/plain";
+ mime = "text/plain";
}
- WSContentSend_P(HTTP_SCRIPT_MIMES,fname,mime);
+ WSContentSend_P(HTTP_SCRIPT_MIMES, fname, mime);
if (sflg) {
#ifdef USE_DISPLAY_DUMP
@@ -5856,8 +5833,8 @@ char buff[512];
#define fileHeaderSize 14
#define infoHeaderSize 40
if (buffer) {
- uint8_t *bp=buffer;
- uint8_t *lbuf=(uint8_t*)calloc(Settings.display_width+2,3);
+ uint8_t *bp = buffer;
+ uint8_t *lbuf = (uint8_t*)calloc(Settings.display_width + 2, 3);
uint8_t *lbp;
uint8_t fileHeader[fileHeaderSize];
createBitmapFileHeader(Settings.display_height , Settings.display_width , fileHeader);
@@ -5865,37 +5842,37 @@ char buff[512];
uint8_t infoHeader[infoHeaderSize];
createBitmapInfoHeader(Settings.display_height, Settings.display_width, infoHeader );
Webserver->client().write((uint8_t *)infoHeader, infoHeaderSize);
- for (uint32_t lins=0; lins>1;
+ bits = bits>>1;
}
bp++;
}
- Webserver->client().write((const char*)lbuf, Settings.display_width*3);
+ Webserver->client().write((const char*)lbuf, Settings.display_width * 3);
}
if (lbuf) free(lbuf);
Webserver->client().stop();
}
#endif // USE_DISPLAY_DUMP
} else {
- File file=fsp->open(fname,FILE_READ);
+ File file = fsp->open(fname,FILE_READ);
uint32_t siz = file.size();
- uint32_t len=sizeof(buff);
+ uint32_t len = sizeof(buff);
while (siz > 0) {
- if (len>siz) len=siz;
- file.read((uint8_t *)buff,len );
+ if (len>siz) len = siz;
+ file.read((uint8_t *)buff, len);
Webserver->client().write((const char*)buff, len);
siz -= len;
}
@@ -5930,7 +5907,7 @@ void ScriptFullWebpage(void) {
}
WSContentBegin(200, CT_HTML);
- const char *title="Full Screen";
+ const char *title = "Full Screen";
WSContentSend_P(HTTP_SCRIPT_FULLPAGE1, SettingsText(SET_DEVICENAME), title, fullpage_refresh);
WSContentSend_P(HTTP_SCRIPT_FULLPAGE2, fullpage_refresh);
//WSContentSend_P(PSTR(""));
@@ -5954,34 +5931,34 @@ void Script_Check_HTML_Setvars(void) {
if (Webserver->hasArg("sv")) {
String stmp = Webserver->arg("sv");
- Serial.printf("fwp has arg dv %s\n",stmp.c_str());
+ Serial.printf("fwp has arg dv %s\n", stmp.c_str());
char cmdbuf[64];
- memset(cmdbuf,0,sizeof(cmdbuf));
- char *cp=cmdbuf;
- *cp++='>';
- strncpy(cp,stmp.c_str(),sizeof(cmdbuf)-1);
- char *cp1=strchr(cp,'_');
+ memset(cmdbuf, 0, sizeof(cmdbuf));
+ char *cp = cmdbuf;
+ *cp++ = '>';
+ strncpy(cp, stmp.c_str(), sizeof(cmdbuf) - 1);
+ char *cp1 = strchr(cp, '_');
if (!cp1) return;
- *cp1=0;
+ *cp1 = 0;
char vname[32];
- strncpy(vname,cp,sizeof(vname));
- *cp1='=';
+ strncpy(vname, cp, sizeof(vname));
+ *cp1 = '=';
cp1++;
struct T_INDEX ind;
uint8_t vtype;
- isvar(vname,&vtype,&ind,0,0,0);
+ isvar(vname, &vtype, &ind, 0, 0, 0);
if (vtype!=NUM_RES && vtype&STYPE) {
// string type must insert quotes
- uint8_t tlen=strlen(cp1);
- memmove(cp1+1,cp1,tlen);
- *cp1='\"';
- *(cp1+tlen+1)='\"';
+ uint8_t tlen = strlen(cp1);
+ memmove(cp1 + 1, cp1, tlen);
+ *cp1 = '\"';
+ *(cp1 + tlen +1 ) = '\"';
}
//toLog(cmdbuf);
execute_script(cmdbuf);
- Run_Scripter(">E",2,0);
+ Run_Scripter(">E", 2, 0);
}
}
@@ -6048,7 +6025,9 @@ const char SCRIPT_MSG_GTABLEd[] PROGMEM =
const char SCRIPT_MSG_GTABLEb[] PROGMEM =
"]);"
- "var options={%s" CHART_EXTRA_OPTIONS "};"
+ "var options={%s" CHART_EXTRA_OPTIONS "};";
+
+const char SCRIPT_MSG_GTABLEbx[] PROGMEM =
"var chart=new google.visualization.%s(document.getElementById('chart%1d'));"
"chart.draw(data,options);}"
"google.charts.setOnLoadCallback(drawChart);";
@@ -6087,60 +6066,60 @@ const char SCRIPT_MSG_GTE1[] PROGMEM = "'%s'";
char *gc_get_arrays(char *lp, float **arrays, uint8_t *ranum, uint16_t *rentries, uint16_t *ipos) {
struct T_INDEX ind;
uint8_t vtype;
-uint16 entries=0;
-uint16_t cipos=0;
+uint16 entries = 0;
+uint16_t cipos = 0;
- uint8_t anum=0;
+ uint8_t anum = 0;
while (anum> 2 %d\n",len);
if (fa && len>=entries) {
if (!entries) {
entries = len;
}
// add array to list
- arrays[anum]=fa;
+ arrays[anum] = fa;
anum++;
}
} else {
// single numeric
- arrays[anum]=&glob_script_mem.fvars[index];
+ arrays[anum] = &glob_script_mem.fvars[index];
anum++;
- entries=1;
+ entries = 1;
}
} else {
- lp=lp1;
+ lp = lp1;
break;
}
}
}
//Serial.printf(">> %d - %d - %d\n",anum,entries,(uint32_t)*arrays[0]);
- *ranum=anum;
- *rentries=entries;
- *ipos=cipos;
+ *ranum = anum;
+ *rentries = entries;
+ *ipos = cipos;
return lp;
}
char *gc_send_labels(char *lp,uint32_t anum) {
WSContentSend_PD("[");
- for (uint32_t cnt=0; cntw",-2,0);
+ web_script = Run_Scripter(">w", -2, 0);
} else {
- web_script=Run_Scripter(">W",-2,0);
+ web_script = Run_Scripter(">W", -2, 0);
}
if (web_script==99) {
char tmp[256];
- uint8_t optflg=0;
- uint8_t chartindex=1;
- uint8_t google_libs=0;
- char *lp=glob_script_mem.section_ptr+2;
+ uint8_t optflg = 0;
+ uint8_t chartindex = 1;
+ uint8_t google_libs = 0;
+ char *lp = glob_script_mem.section_ptr + 2;
if (mc=='w') {
while (*lp) {
if (*lp=='\n') break;
@@ -6194,175 +6173,175 @@ void ScriptWebShow(char mc) {
}
if (*lp!=';') {
// send this line to web
- Replace_Cmd_Vars(lp,1,tmp,sizeof(tmp));
- char *lin=tmp;
+ Replace_Cmd_Vars(lp, 1, tmp, sizeof(tmp));
+ char *lin = tmp;
if ((!mc && (*lin!='$')) || (mc=='w' && (*lin!='$'))) {
// normal web section
if (*lin=='@') {
lin++;
- optflg=1;
+ optflg = 1;
} else {
- optflg=0;
+ optflg = 0;
}
// check for input elements
- if (!strncmp(lin,"sl(",3)) {
+ if (!strncmp(lin, "sl(", 3)) {
// insert slider sl(min max var left mid right)
- char *lp=lin;
+ char *lp = lin;
float min;
- lp=GetNumericResult(lp+3,OPER_EQU,&min,0);
+ lp = GetNumericArgument(lp + 3, OPER_EQU, &min, 0);
SCRIPT_SKIP_SPACES
// arg2
float max;
- lp=GetNumericResult(lp,OPER_EQU,&max,0);
+ lp = GetNumericArgument(lp, OPER_EQU, &max, 0);
SCRIPT_SKIP_SPACES
float val;
- char *slp=lp;
- lp=GetNumericResult(lp,OPER_EQU,&val,0);
+ char *slp = lp;
+ lp = GetNumericArgument(lp, OPER_EQU, &val, 0);
SCRIPT_SKIP_SPACES
char vname[16];
- ScriptGetVarname(vname,slp,sizeof(vname));
+ ScriptGetVarname(vname, slp, sizeof(vname));
char left[SCRIPT_MAXSSIZE];
- lp=GetStringResult(lp,OPER_EQU,left,0);
+ lp = GetStringArgument(lp, OPER_EQU, left, 0);
SCRIPT_SKIP_SPACES
char mid[SCRIPT_MAXSSIZE];
- lp=GetStringResult(lp,OPER_EQU,mid,0);
+ lp = GetStringArgument(lp, OPER_EQU, mid, 0);
SCRIPT_SKIP_SPACES
char right[SCRIPT_MAXSSIZE];
- lp=GetStringResult(lp,OPER_EQU,right,0);
+ lp = GetStringArgument(lp, OPER_EQU, right, 0);
SCRIPT_SKIP_SPACES
- WSContentSend_PD(SCRIPT_MSG_SLIDER,left,mid,right,(uint32_t)min,(uint32_t)max,(uint32_t)val,vname);
+ WSContentSend_PD(SCRIPT_MSG_SLIDER, left,mid, right, (uint32_t)min, (uint32_t)max, (uint32_t)val, vname);
- } else if (!strncmp(lin,"ck(",3)) {
- char *lp=lin+3;
- char *slp=lp;
+ } else if (!strncmp(lin, "ck(", 3)) {
+ char *lp = lin + 3;
+ char *slp = lp;
float val;
- lp=GetNumericResult(lp,OPER_EQU,&val,0);
+ lp = GetNumericArgument(lp, OPER_EQU, &val, 0);
SCRIPT_SKIP_SPACES
char vname[16];
- ScriptGetVarname(vname,slp,sizeof(vname));
+ ScriptGetVarname(vname, slp, sizeof(vname));
char label[SCRIPT_MAXSSIZE];
- lp=GetStringResult(lp,OPER_EQU,label,0);
+ lp = GetStringArgument(lp, OPER_EQU, label, 0);
const char *cp;
uint8_t uval;
if (val>0) {
- cp="checked='checked'";
- uval=0;
+ cp = "checked='checked'";
+ uval = 0;
} else {
- cp="";
- uval=1;
+ cp = "";
+ uval = 1;
}
- WSContentSend_PD(SCRIPT_MSG_CHKBOX,label,(char*)cp,uval,vname);
+ WSContentSend_PD(SCRIPT_MSG_CHKBOX, label, (char*)cp, uval, vname);
- } else if (!strncmp(lin,"bu(",3)) {
- char *lp=lin+3;
- uint8_t bcnt=0;
- char *found=lin;
+ } else if (!strncmp(lin, "bu(", 3)) {
+ char *lp = lin + 3;
+ uint8_t bcnt = 0;
+ char *found = lin;
while (bcnt<4) {
- found=strstr(found,"bu(");
+ found = strstr(found, "bu(");
if (!found) break;
- found+=3;
+ found += 3;
bcnt++;
}
- uint8_t proz=100/bcnt;
- if (!optflg && bcnt>1) proz-=2;
+ uint8_t proz = 100 / bcnt;
+ if (!optflg && bcnt>1) proz -= 2;
if (optflg) WSContentSend_PD(SCRIPT_MSG_BUT_START_TBL);
else WSContentSend_PD(SCRIPT_MSG_BUT_START);
- for (uint32_t cnt=0;cnt0) {
- cp=ontxt;
- uval=0;
+ cp = ontxt;
+ uval = 0;
} else {
- cp=offtxt;
- uval=1;
+ cp = offtxt;
+ uval = 1;
}
if (bcnt>1 && cnt==bcnt-1) {
- if (!optflg) proz+=2;
+ if (!optflg) proz += 2;
}
if (!optflg) {
- WSContentSend_PD(SCRIPT_MSG_BUTTONa,proz,uval,vname,cp);
+ WSContentSend_PD(SCRIPT_MSG_BUTTONa, proz, uval, vname, cp);
} else {
- WSContentSend_PD(SCRIPT_MSG_BUTTONa_TBL,proz,uval,vname,cp);
+ WSContentSend_PD(SCRIPT_MSG_BUTTONa_TBL, proz, uval, vname, cp);
}
if (bcnt>1 && cnt%s"),lin);
+ WSContentSend_PD(PSTR("%s
"), lin);
} else {
- WSContentSend_PD(PSTR("{s}%s{e}"),lin);
+ WSContentSend_PD(PSTR("{s}%s{e}"), lin);
}
}
}
@@ -6375,58 +6354,67 @@ void ScriptWebShow(char mc) {
lin++;
exgc:
char *lp;
- if (!strncmp(lin,"gc(",3)) {
+ if (!strncmp(lin, "gc(", 3)) {
// get google table
- lp=lin+3;
+ lp = lin + 3;
SCRIPT_SKIP_SPACES
const char *type;
const char *func;
char options[312];
- uint8_t nanum=MAX_GARRAY;
- uint8_t y2f=0;
+ uint8_t nanum = MAX_GARRAY;
+ uint8_t y2f = 0;
+ uint8_t tonly = 0;
char ctype;
- ctype=*lp;
+ ctype = *lp;
lp++;
- if (!(google_libs&GLIBS_MAIN)) {
- google_libs|=GLIBS_MAIN;
+ if (!(google_libs & GLIBS_MAIN)) {
+ google_libs |= GLIBS_MAIN;
WSContentSend_PD(SCRIPT_MSG_GTABLE);
}
switch (ctype) {
case 'l':
- type=PSTR("LineChart");
+ type = PSTR("LineChart");
break;
case 'b':
- type=PSTR("BarChart");
+ type = PSTR("BarChart");
break;
case 'p':
- type=PSTR("PieChart");
+ type = PSTR("PieChart");
break;
case 'g':
- type=PSTR("Gauge");
- if (!(google_libs&GLIBS_GAUGE)) {
- google_libs|=GLIBS_GAUGE;
+ type = PSTR("Gauge");
+ if (!(google_libs & GLIBS_GAUGE)) {
+ google_libs |= GLIBS_GAUGE;
WSContentSend_PD(SCRIPT_MSG_GAUGE);
}
break;
case 't':
- type=PSTR("Table");
- if (!(google_libs&GLIBS_TABLE)) {
- google_libs|=GLIBS_TABLE;
+ type = PSTR("Table");
+ if (!(google_libs & GLIBS_TABLE)) {
+ google_libs |= GLIBS_TABLE;
WSContentSend_PD(SCRIPT_MSG_TABLE);
}
break;
case 'T':
- type=PSTR("Timeline");
- if (!(google_libs&GLIBS_TIMELINE)) {
- google_libs|=GLIBS_TIMELINE;
+ type = PSTR("Timeline");
+ if (!(google_libs & GLIBS_TIMELINE)) {
+ google_libs |= GLIBS_TIMELINE;
WSContentSend_PD(SCRIPT_MSG_TIMELINE);
}
break;
case 'h':
- type=PSTR("Histogram");
+ type = PSTR("Histogram");
break;
case 'c':
- type=PSTR("ColumnChart");
+ type = PSTR("ColumnChart");
+ break;
+ case 'C':
+ type = PSTR("ComboChart");
+ break;
+ case 'e':
+ WSContentSend_PD(SCRIPT_MSG_GTABLEbx, type, chartindex);
+ chartindex++;
+ goto nextwebline;
break;
default:
// error
@@ -6435,24 +6423,28 @@ exgc:
}
if (ctype=='l' && *lp=='f') {
lp++;
- func=PSTR(",curveType:'function'");
+ func = PSTR(",curveType:'function'");
} else {
- func="";
+ func = "";
}
if (*lp=='2') {
lp++;
- nanum=2;
- y2f=1;
+ nanum = 2;
+ y2f = 1;
+ }
+ if (*lp=='t') {
+ lp++;
+ tonly = 1;
}
SCRIPT_SKIP_SPACES
//Serial.printf("type %d\n",ctype);
float *arrays[MAX_GARRAY];
- uint8_t anum=0;
- uint16_t entries=0;
- uint16_t ipos=0;
- lp=gc_get_arrays(lp, &arrays[0], &anum, &entries, &ipos);
+ uint8_t anum = 0;
+ uint16_t entries = 0;
+ uint16_t ipos = 0;
+ lp = gc_get_arrays(lp, &arrays[0], &anum, &entries, &ipos);
if (anum>nanum) {
goto nextwebline;
@@ -6461,98 +6453,120 @@ exgc:
//Serial.printf("arrays %d\n",anum);
//Serial.printf("entries %d\n",entries);
if (ctype=='T') {
- if (anum && !(entries&1)) {
+ if (anum && !(entries & 1)) {
WSContentSend_PD(SCRIPT_MSG_GTABLEa);
WSContentSend_PD(SCRIPT_MSG_GTABLEd);
char label[SCRIPT_MAXSSIZE];
- lp=GetStringResult(lp,OPER_EQU,label,0);
+ lp = GetStringArgument(lp, OPER_EQU, label, 0);
SCRIPT_SKIP_SPACES
- for (uint32_t ind=0; ind=entries) todflg=entries-1;
+ int16_t divflg = 1;
+ int16_t todflg = -1;
+ if (!strncmp(label, "cnt", 3)) {
+ char *cp = &label[3];
+ //todflg=atoi(&label[3]);
+ todflg = strtol(cp, &cp, 10);
+ if (todflg>=entries) todflg = entries - 1;
+ if (*cp=='/') {
+ cp++;
+ divflg = strtol(cp, &cp, 10);
+ }
} else {
- uint16 segments=1;
- for (uint32_t cnt=0; cnt=entries) aind=entries-1;
- for (uint32_t cnt=0; cnt=entries) aind = entries - 1;
+ for (uint32_t cnt = 0; cnt < entries; cnt++) {
WSContentSend_PD("['");
char lbl[16];
if (todflg>=0) {
- sprintf(lbl,"%d",todflg);
+ sprintf(lbl, "%d", todflg / divflg);
todflg++;
- if (todflg>=entries) {
- todflg=0;
+ if (todflg >= entries) {
+ todflg = 0;
}
} else {
- GetTextIndexed(lbl, sizeof(lbl), aind/divflg, label);
+ if (todflg==-1) {
+ GetTextIndexed(lbl, sizeof(lbl), aind / divflg, label);
+ } else {
+ // day,hours,mins
+ GetTextIndexed(lbl, sizeof(lbl), aind / divflg, label + 4);
+ sprintf(lbl, "%s-%02d", lbl, aind % divflg);
+ }
}
WSContentSend_PD(lbl);
WSContentSend_PD("',");
- for (uint32_t ind=0; ind=entries) {
- aind=0;
+ aind = 0;
}
}
-
+ // table complete
+ if (tonly) {
+ WSContentSend_PD("]);");
+ goto nextwebline;
+ }
// get header
char header[SCRIPT_MAXSSIZE];
- lp=GetStringResult(lp,OPER_EQU,header,0);
+ lp = GetStringArgument(lp, OPER_EQU, header, 0);
SCRIPT_SKIP_SPACES
switch (ctype) {
case 't':
- snprintf_P(options,sizeof(options),SCRIPT_MSG_GOPT2);
+ snprintf_P(options, sizeof(options), SCRIPT_MSG_GOPT2);
break;
default:
- snprintf_P(options,sizeof(options),SCRIPT_MSG_GOPT1,header);
+ snprintf_P(options, sizeof(options), SCRIPT_MSG_GOPT1, header);
break;
}
// check for 2 axis option
@@ -6560,49 +6574,52 @@ exgc:
// 2 y axes variant
SCRIPT_SKIP_SPACES
float max1;
- lp=GetNumericResult(lp,OPER_EQU,&max1,0);
+ lp = GetNumericArgument(lp, OPER_EQU, &max1, 0);
SCRIPT_SKIP_SPACES
float max2;
- lp=GetNumericResult(lp,OPER_EQU,&max2,0);
+ lp = GetNumericArgument(lp, OPER_EQU, &max2, 0);
SCRIPT_SKIP_SPACES
- snprintf_P(options,sizeof(options),SCRIPT_MSG_GOPT3,header,(uint32_t)max1,(uint32_t)max2,func);
+ snprintf_P(options, sizeof(options), SCRIPT_MSG_GOPT3, header, (uint32_t)max1, (uint32_t)max2, func);
} else {
SCRIPT_SKIP_SPACES
- if (*lp!=')') {
- float max1;
- lp=GetNumericResult(lp,OPER_EQU,&max1,0);
- SCRIPT_SKIP_SPACES
- float max2;
- lp=GetNumericResult(lp,OPER_EQU,&max2,0);
- SCRIPT_SKIP_SPACES
- snprintf_P(options,sizeof(options),SCRIPT_MSG_GOPT6,header,(uint32_t)max1,(uint32_t)max2,func);
+ if (ctype!='g') {
+ if (*lp!=')') {
+ float max1;
+ lp = GetNumericArgument(lp, OPER_EQU, &max1, 0);
+ SCRIPT_SKIP_SPACES
+ float max2;
+ lp = GetNumericArgument(lp, OPER_EQU, &max2, 0);
+ SCRIPT_SKIP_SPACES
+ snprintf_P(options, sizeof(options), SCRIPT_MSG_GOPT6, header, (uint32_t)max1, (uint32_t)max2, func);
+ }
}
}
if (ctype=='g') {
float yellowFrom;
- lp=GetNumericResult(lp,OPER_EQU,&yellowFrom,0);
+ lp = GetNumericArgument(lp, OPER_EQU, &yellowFrom, 0);
SCRIPT_SKIP_SPACES
float redFrom;
- lp=GetNumericResult(lp,OPER_EQU,&redFrom,0);
+ lp = GetNumericArgument(lp, OPER_EQU, &redFrom, 0);
SCRIPT_SKIP_SPACES
float maxValue;
- lp=GetNumericResult(lp,OPER_EQU,&maxValue,0);
+ lp = GetNumericArgument(lp, OPER_EQU, &maxValue, 0);
SCRIPT_SKIP_SPACES
- float redTo=maxValue;
- float yellowTo=redFrom;
- snprintf_P(options,sizeof(options),SCRIPT_MSG_GAUGEOPT,(uint32_t)maxValue,(uint32_t)redFrom,(uint32_t)redTo,
- (uint32_t)yellowFrom,(uint32_t)yellowTo);
+ float redTo = maxValue;
+ float yellowTo = redFrom;
+ snprintf_P(options, sizeof(options), SCRIPT_MSG_GAUGEOPT, (uint32_t)maxValue, (uint32_t)redFrom, (uint32_t)redTo,
+ (uint32_t)yellowFrom, (uint32_t)yellowTo);
}
}
- WSContentSend_PD(SCRIPT_MSG_GTABLEb,options,type,chartindex);
+ WSContentSend_PD(SCRIPT_MSG_GTABLEb, options);
+ WSContentSend_PD(SCRIPT_MSG_GTABLEbx, type, chartindex);
chartindex++;
} else {
- WSContentSend_PD(PSTR("%s"),lin);
+ WSContentSend_PD(PSTR("%s"), lin);
}
#else
lin++;
- WSContentSend_PD(PSTR("%s"),lin);
+ WSContentSend_PD(PSTR("%s"), lin);
} else {
// WSContentSend_PD(PSTR("%s"),lin);
#endif //USE_GOOGLE_CHARTS
@@ -6626,10 +6643,10 @@ nextwebline:
#ifdef USE_SENDMAIL
void script_send_email_body(void(*func)(char *)) {
-uint8_t msect=Run_Scripter(">m",-2,0);
+uint8_t msect = Run_Scripter(">m", -2, 0);
if (msect==99) {
char tmp[256];
- char *lp=glob_script_mem.section_ptr+2;
+ char *lp = glob_script_mem.section_ptr + 2;
while (lp) {
while (*lp==SCRIPT_EOL) {
lp++;
@@ -6639,7 +6656,7 @@ uint8_t msect=Run_Scripter(">m",-2,0);
}
if (*lp!=';') {
// send this line to smtp
- Replace_Cmd_Vars(lp,1,tmp,sizeof(tmp));
+ Replace_Cmd_Vars(lp, 1, tmp, sizeof(tmp));
//client->println(tmp);
func(tmp);
}
@@ -6656,14 +6673,14 @@ uint8_t msect=Run_Scripter(">m",-2,0);
func((char*)"*");
}
}
-#endif
+#endif //USE_SENDMAIL
#ifdef USE_SCRIPT_JSON_EXPORT
void ScriptJsonAppend(void) {
- uint8_t web_script=Run_Scripter(">J",-2,0);
+ uint8_t web_script = Run_Scripter(">J", -2, 0);
if (web_script==99) {
char tmp[256];
- char *lp=glob_script_mem.section_ptr+2;
+ char *lp = glob_script_mem.section_ptr + 2;
while (lp) {
while (*lp==SCRIPT_EOL) {
lp++;
@@ -6673,8 +6690,8 @@ void ScriptJsonAppend(void) {
}
if (*lp!=';') {
// send this line to mqtt
- Replace_Cmd_Vars(lp,1,tmp,sizeof(tmp));
- ResponseAppend_P(PSTR("%s"),tmp);
+ Replace_Cmd_Vars(lp, 1, tmp, sizeof(tmp));
+ ResponseAppend_P(PSTR("%s"), tmp);
}
if (*lp==SCRIPT_EOL) {
lp++;
@@ -6690,7 +6707,7 @@ void ScriptJsonAppend(void) {
bool RulesProcessEvent(char *json_event) {
- if (bitRead(Settings.rule_enabled, 0)) Run_Scripter(">E",2,json_event);
+ if (bitRead(Settings.rule_enabled, 0)) Run_Scripter(">E", 2, json_event);
return true;
}
@@ -6703,7 +6720,7 @@ bool RulesProcessEvent(char *json_event) {
#ifndef STASK_PRIO
#define STASK_PRIO 1
-#endif
+#endif //ESP32
#if 1
@@ -6724,7 +6741,7 @@ void script_task1(void *arg) {
//if (time<=esp32_tasks[0].task_timer) {vTaskDelay( pdMS_TO_TICKS( time ) ); }
delay(esp32_tasks[0].task_timer);
if (bitRead(Settings.rule_enabled, 0)) {
- Run_Scripter(">t1",3,0);
+ Run_Scripter(">t1", 3, 0);
}
}
}
@@ -6740,7 +6757,7 @@ void script_task2(void *arg) {
//if (time<=esp32_tasks[1].task_timer) {vTaskDelay( pdMS_TO_TICKS( time ) ); }
delay(esp32_tasks[1].task_timer);
if (bitRead(Settings.rule_enabled, 0)) {
- Run_Scripter(">t2",3,0);
+ Run_Scripter(">t2", 3, 0);
}
}
}
@@ -6769,14 +6786,14 @@ TaskHandle_t task_t2;
void script_task1(void *arg) {
while (1) {
delay(task_timer1);
- Run_Scripter(">t1",3,0);
+ Run_Scripter(">t1", 3, 0);
}
}
void script_task2(void *arg) {
while (1) {
delay(task_timer2);
- Run_Scripter(">t2",3,0);
+ Run_Scripter(">t2", 3, 0);
}
}
@@ -6805,12 +6822,12 @@ uint32_t scripter_create_task(uint32_t num, uint32_t time, uint32_t core) {
#include "WiFiClientSecureLightBearSSL.h"
#else
#include
-#endif
+#endif //ESP8266
// get tesla powerwall info page json string
uint32_t call2https(const char *host, const char *path) {
if (global_state.wifi_down) return 1;
- uint32_t status=0;
+ uint32_t status = 0;
#ifdef ESP32
WiFiClientSecure *httpsClient;
httpsClient = new WiFiClientSecure;
@@ -6821,8 +6838,7 @@ uint32_t call2https(const char *host, const char *path) {
httpsClient->setTimeout(1500);
- int retry = 0;
- String result;
+ uint32_t retry = 0;
while ((!httpsClient->connect(host, 443)) && (retry < 5)) {
delay(100);
retry++;
@@ -6842,6 +6858,7 @@ uint32_t call2https(const char *host, const char *path) {
break;
}
}
+ String result;
while (httpsClient->available()) {
String line = httpsClient->readStringUntil('\n');
if (line!="") {
@@ -6850,20 +6867,19 @@ uint32_t call2https(const char *host, const char *path) {
}
httpsClient->stop();
delete httpsClient;
- Run_Scripter(">jp",3,(char*)result.c_str());
+ Run_Scripter(">jp", 3, (char*)result.c_str());
return 0;
}
-
#endif // SCRIPT_GET_HTTPS_JP
-void cpy2lf(char *dst,uint32_t dstlen, char *src) {
+void cpy2lf(char *dst, uint32_t dstlen, char *src) {
for (uint32_t cnt=0; cnt0) glob_script_mem.script_ram[len_decompressed]=0;
+ if (len_decompressed>0) glob_script_mem.script_ram[len_decompressed] = 0;
// indicates scripter use compression
bitWrite(Settings.rule_once, 6, 1);
//AddLog_P2(LOG_LEVEL_INFO, PSTR("decompressed script len %d"),len_decompressed);
@@ -6908,29 +6924,29 @@ bool Xdrv10(uint8_t function)
#endif // USE_SCRIPT_COMPRESSION
#ifdef USE_BUTTON_EVENT
- for (uint32_t cnt=0;cnt=0
AddLog_P(LOG_LEVEL_INFO,PSTR("FATFS mount OK!"));
//fsp->dateTimeCallback(dateTime);
- glob_script_mem.script_sd_found=1;
+ glob_script_mem.script_sd_found = 1;
char *script;
- script=(char*)calloc(FAT_SCRIPT_SIZE+4,1);
+ script = (char*)calloc(FAT_SCRIPT_SIZE + 4, 1);
if (!script) break;
- glob_script_mem.script_ram=script;
- glob_script_mem.script_size=FAT_SCRIPT_SIZE;
+ glob_script_mem.script_ram = script;
+ glob_script_mem.script_size = FAT_SCRIPT_SIZE;
if (fsp->exists(FAT_SCRIPT_NAME)) {
- File file=fsp->open(FAT_SCRIPT_NAME,FILE_READ);
- file.read((uint8_t*)script,FAT_SCRIPT_SIZE);
+ File file = fsp->open(FAT_SCRIPT_NAME, FILE_READ);
+ file.read((uint8_t*)script, FAT_SCRIPT_SIZE);
file.close();
}
- script[FAT_SCRIPT_SIZE-1]=0;
+ script[FAT_SCRIPT_SIZE - 1] = 0;
// use rules storage for permanent vars
- glob_script_mem.script_pram=(uint8_t*)Settings.rules[0];
- glob_script_mem.script_pram_size=MAX_SCRIPT_SIZE;
+ glob_script_mem.script_pram = (uint8_t*)Settings.rules[0];
+ glob_script_mem.script_pram_size = MAX_SCRIPT_SIZE;
- glob_script_mem.flags=1;
+ glob_script_mem.flags = 1;
} else {
AddLog_P(LOG_LEVEL_INFO,PSTR("FATFS mount failed!"));
- glob_script_mem.script_sd_found=0;
+ glob_script_mem.script_sd_found = 0;
}
#endif // USE_SCRIPT_FATFS
@@ -6997,46 +7013,46 @@ bool Xdrv10(uint8_t function)
#else
// lfs on esp8266
fsp = &LittleFS;
-#endif
+#endif //ESP32
char *script;
- script=(char*)calloc(LITTLEFS_SCRIPT_SIZE+4,1);
+ script = (char*)calloc(LITTLEFS_SCRIPT_SIZE + 4, 1);
if (!script) break;
- LoadFile("/script.txt",(uint8_t*)script,LITTLEFS_SCRIPT_SIZE);
+ LoadFile("/script.txt", (uint8_t*)script, LITTLEFS_SCRIPT_SIZE);
- glob_script_mem.script_ram=script;
- glob_script_mem.script_size=LITTLEFS_SCRIPT_SIZE;
- script[LITTLEFS_SCRIPT_SIZE-1]=0;
+ glob_script_mem.script_ram = script;
+ glob_script_mem.script_size = LITTLEFS_SCRIPT_SIZE;
+ script[LITTLEFS_SCRIPT_SIZE-1] = 0;
// use rules storage for permanent vars
- glob_script_mem.script_pram=(uint8_t*)Settings.rules[0];
- glob_script_mem.script_pram_size=MAX_SCRIPT_SIZE;
- glob_script_mem.flags=1;
+ glob_script_mem.script_pram = (uint8_t*)Settings.rules[0];
+ glob_script_mem.script_pram_size = MAX_SCRIPT_SIZE;
+ glob_script_mem.flags = 1;
#endif // LITTLEFS_SCRIPT_SIZE
// a valid script MUST start with >D
if (glob_script_mem.script_ram[0]!='>' && glob_script_mem.script_ram[1]!='D') {
// clr all
- memset(glob_script_mem.script_ram,0,glob_script_mem.script_size);
+ memset(glob_script_mem.script_ram, 0 ,glob_script_mem.script_size);
strcpy_P(glob_script_mem.script_ram, PSTR(">D\nscript error must start with >D"));
bitWrite(Settings.rule_enabled, 0, 0);
}
// assure permanent memory is 4 byte aligned
- { uint32_t ptr=(uint32_t)glob_script_mem.script_pram;
- ptr&=0xfffffffc;
- ptr+=4;
- glob_script_mem.script_pram=(uint8_t*)ptr;
- glob_script_mem.script_pram_size-=4;
+ { uint32_t ptr = (uint32_t)glob_script_mem.script_pram;
+ ptr &= 0xfffffffc;
+ ptr += 4;
+ glob_script_mem.script_pram = (uint8_t*)ptr;
+ glob_script_mem.script_pram_size -= 4;
}
if (bitRead(Settings.rule_enabled, 0)) Init_Scripter();
break;
case FUNC_INIT:
if (bitRead(Settings.rule_enabled, 0)) {
- Run_Scripter(">B\n",3,0);
- fast_script=Run_Scripter(">F",-2,0);
+ Run_Scripter(">B\n", 3, 0);
+ fast_script = Run_Scripter(">F", -2, 0);
#if defined(USE_SCRIPT_HUE) && defined(USE_WEBSERVER) && defined(USE_EMULATION) && defined(USE_EMULATION_HUE) && defined(USE_LIGHT)
Script_Check_Hue(0);
-#endif
+#endif //USE_SCRIPT_HUE
}
break;
case FUNC_EVERY_100_MSECOND:
@@ -7050,18 +7066,18 @@ bool Xdrv10(uint8_t function)
break;
case FUNC_SET_POWER:
#ifdef SCRIPT_POWER_SECTION
- if (bitRead(Settings.rule_enabled, 0)) Run_Scripter(">P",2,0);
+ if (bitRead(Settings.rule_enabled, 0)) Run_Scripter(">P", 2, 0);
#else
if (bitRead(Settings.rule_enabled, 0)) {
- Run_Scripter(">E",2,0);
- result=event_handeled;
+ Run_Scripter(">E", 2, 0);
+ result = event_handeled;
}
-#endif
+#endif //SCRIPT_POWER_SECTION
break;
case FUNC_RULES_PROCESS:
if (bitRead(Settings.rule_enabled, 0)) {
- Run_Scripter(">E",2,mqtt_data);
- result=event_handeled;
+ Run_Scripter(">E", 2, mqtt_data);
+ result = event_handeled;
}
break;
#ifdef USE_WEBSERVER
@@ -7073,11 +7089,11 @@ bool Xdrv10(uint8_t function)
if (bitRead(Settings.rule_enabled, 0)) {
ScriptWebShow('$');
#ifdef SCRIPT_FULL_WEBPAGE
- uint8_t web_script=Run_Scripter(">w",-2,0);
+ uint8_t web_script = Run_Scripter(">w", -2, 0);
if (web_script==99) {
char bname[48];
- cpy2lf(bname,sizeof(bname),glob_script_mem.section_ptr+3);
- WSContentSend_PD(HTTP_WEB_FULL_DISPLAY,bname);
+ cpy2lf(bname, sizeof(bname), glob_script_mem.section_ptr + 3);
+ WSContentSend_PD(HTTP_WEB_FULL_DISPLAY, bname);
Webserver->on("/sfd", ScriptFullWebpage);
#ifdef USE_SCRIPT_FATFS
Webserver->onNotFound(ScriptGetSDCard);
@@ -7090,24 +7106,24 @@ bool Xdrv10(uint8_t function)
case FUNC_WEB_ADD_HANDLER:
Webserver->on("/" WEB_HANDLE_SCRIPT, HandleScriptConfiguration);
Webserver->on("/ta",HTTP_POST, HandleScriptTextareaConfiguration);
- Webserver->on("/exs", HTTP_POST,[]() { Webserver->sendHeader("Location","/exs");Webserver->send(303);},script_upload_start);
- Webserver->on("/exs", HTTP_GET,ScriptExecuteUploadSuccess);
+ Webserver->on("/exs", HTTP_POST,[]() { Webserver->sendHeader("Location","/exs");Webserver->send(303);}, script_upload_start);
+ Webserver->on("/exs", HTTP_GET, ScriptExecuteUploadSuccess);
#ifdef USE_SCRIPT_FATFS
- Webserver->on("/u3", HTTP_POST,[]() { Webserver->sendHeader("Location","/u3");Webserver->send(303);},script_upload);
- Webserver->on("/u3", HTTP_GET,ScriptFileUploadSuccess);
- Webserver->on("/upl", HTTP_GET,Script_FileUploadConfiguration);
-#endif
+ Webserver->on("/u3", HTTP_POST,[]() { Webserver->sendHeader("Location","/u3");Webserver->send(303);}, script_upload);
+ Webserver->on("/u3", HTTP_GET, ScriptFileUploadSuccess);
+ Webserver->on("/upl", HTTP_GET, Script_FileUploadConfiguration);
+#endif //USE_SCRIPT_FATFS
break;
#endif // USE_WEBSERVER
case FUNC_SAVE_BEFORE_RESTART:
if (bitRead(Settings.rule_enabled, 0)) {
- Run_Scripter(">R",2,0);
+ Run_Scripter(">R", 2, 0);
Scripter_save_pvars();
}
#ifdef USE_SCRIPT_GLOBVARS
Script_Stop_UDP();
-#endif
+#endif //USE_SCRIPT_GLOBVARS
break;
#ifdef SUPPORT_MQTT_EVENT
case FUNC_MQTT_DATA:
@@ -7136,18 +7152,18 @@ bool Xdrv10(uint8_t function)
case FUNC_BUTTON_PRESSED:
if (bitRead(Settings.rule_enabled, 0)) {
if ((script_button[XdrvMailbox.index]&1)!=(XdrvMailbox.payload&1)) {
- script_button[XdrvMailbox.index]=XdrvMailbox.payload;
- Run_Scripter(">b",2,0);
+ script_button[XdrvMailbox.index] = XdrvMailbox.payload;
+ Run_Scripter(">b", 2, 0);
}
}
break;
-#endif
+#endif //USE_BUTTON_EVENT
#ifdef USE_SCRIPT_GLOBVARS
case FUNC_LOOP:
Script_PollUdp();
break;
-#endif
+#endif //USE_SCRIPT_GLOBVARS
}
return result;
From 01ab99f8a1108f06144349f25a98f8babc013ab3 Mon Sep 17 00:00:00 2001
From: gemu2015
Date: Fri, 11 Sep 2020 15:45:21 +0200
Subject: [PATCH 08/23] display fix touch init, some formatting
---
tasmota/xdrv_13_display.ino | 28 ++++++++++++++--------------
1 file changed, 14 insertions(+), 14 deletions(-)
diff --git a/tasmota/xdrv_13_display.ino b/tasmota/xdrv_13_display.ino
index 3a87826f3..8a0c5d395 100644
--- a/tasmota/xdrv_13_display.ino
+++ b/tasmota/xdrv_13_display.ino
@@ -506,7 +506,7 @@ void DisplayText(void)
}
}
break;
-#endif
+#endif // USE_SCRIPT_FATFS
case 'h':
// hor line to
var = atoiv(cp, &temp);
@@ -696,7 +696,7 @@ void DisplayText(void)
Restore_graph(temp,bbuff);
break;
}
-#endif
+#endif // USE_SCRIPT_FATFS
{ int16_t num,gxp,gyp,gxs,gys,dec,icol;
float ymin,ymax;
var=atoiv(cp,&num);
@@ -744,7 +744,7 @@ void DisplayText(void)
AddValue(num,temp);
}
break;
-#endif
+#endif // USE_GRAPH
#ifdef USE_AWATCH
case 'w':
@@ -752,7 +752,7 @@ void DisplayText(void)
cp += var;
DrawAClock(temp);
break;
-#endif
+#endif // USE_AWATCH
#ifdef USE_TOUCH_BUTTONS
case 'b':
@@ -834,12 +834,13 @@ void DisplayText(void)
buttons[num]->vpower.is_pushbutton=0;
}
if (dflg) buttons[num]->xdrawButton(buttons[num]->vpower.on_off);
+ buttons[num]->vpower.disable=!dflg;
}
}
}
}
break;
-#endif
+#endif // USE_TOUCH_BUTTONS
default:
// unknown escape
Response_P(PSTR("Unknown Escape"));
@@ -1530,8 +1531,8 @@ void CmndDisplayRows(void)
bool jpg2rgb888(const uint8_t *src, size_t src_len, uint8_t * out, jpg_scale_t scale);
char get_jpeg_size(unsigned char* data, unsigned int data_size, unsigned short *width, unsigned short *height);
void rgb888_to_565(uint8_t *in, uint16_t *out, uint32_t len);
-#endif
-#endif
+#endif // JPEG_PICTS
+#endif // ESP32
#if defined(USE_SCRIPT_FATFS) && defined(USE_SCRIPT)
extern FS *fsp;
@@ -1626,7 +1627,7 @@ void Draw_RGB_Bitmap(char *file,uint16_t xp, uint16_t yp) {
#endif // ESP32
}
}
-#endif
+#endif // USE_SCRIPT_FATFS
#ifdef USE_AWATCH
#define MINUTE_REDUCT 4
@@ -1663,7 +1664,7 @@ void DrawAClock(uint16_t rad) {
temp=((float)RtcTime.minute*(pi/30.0)-(pi/2.0));
renderer->writeLine(disp_xpos, disp_ypos,disp_xpos+(frad-MINUTE_REDUCT)*cosf(temp),disp_ypos+(frad-MINUTE_REDUCT)*sinf(temp), fg_color);
}
-#endif
+#endif // USE_AWATCH
#ifdef USE_GRAPH
@@ -1938,7 +1939,7 @@ void Restore_graph(uint8_t num, char *path) {
fp.close();
RedrawGraph(num,1);
}
-#endif
+#endif // USE_SCRIPT_FATFS
void RedrawGraph(uint8_t num, uint8_t flags) {
uint16_t index=num%NUM_GRAPHS;
@@ -2050,16 +2051,13 @@ void AddValue(uint8_t num,float fval) {
#ifdef USE_FT5206
+#include
// touch panel controller
#undef FT5206_address
#define FT5206_address 0x38
-#include
FT5206_Class *touchp;
TP_Point pLoc;
-
-
-extern VButton *buttons[];
bool FT5206_found;
bool Touch_Init(TwoWire &i2c) {
@@ -2088,6 +2086,7 @@ uint32_t Touch_Status(uint32_t sel) {
}
}
+
#ifdef USE_TOUCH_BUTTONS
void Touch_MQTT(uint8_t index, const char *cp) {
ResponseTime_P(PSTR(",\"FT5206\":{\"%s%d\":\"%d\"}}"), cp, index+1, buttons[index]->vpower.on_off);
@@ -2184,6 +2183,7 @@ uint8_t vbutt=0;
pLoc.y = 0;
}
}
+
#endif // USE_TOUCH_BUTTONS
#endif // USE_FT5206
From 8468e093fc74b4c6f304a3af43f95d3547f749bb Mon Sep 17 00:00:00 2001
From: gemu2015
Date: Fri, 11 Sep 2020 15:45:59 +0200
Subject: [PATCH 09/23] i2s audio update
save heap memory on esp32 with psram
---
tasmota/xdrv_42_i2s_audio.ino | 18 +++++++++++++++---
1 file changed, 15 insertions(+), 3 deletions(-)
diff --git a/tasmota/xdrv_42_i2s_audio.ino b/tasmota/xdrv_42_i2s_audio.ino
index 77492992b..5a31d832b 100644
--- a/tasmota/xdrv_42_i2s_audio.ino
+++ b/tasmota/xdrv_42_i2s_audio.ino
@@ -52,7 +52,7 @@ AudioFileSourceFS *file;
AudioOutputI2S *out;
AudioFileSourceID3 *id3;
AudioGeneratorMP3 *decoder = NULL;
-
+void *mp3ram = NULL;
#ifdef USE_WEBRADIO
AudioFileSourceICYStream *ifile = NULL;
@@ -210,6 +210,12 @@ void I2S_Init(void) {
is2_volume=10;
out->SetGain(((float)is2_volume/100.0)*4.0);
out->stop();
+ mp3ram = nullptr;
+
+#ifdef ESP32
+ if (psramFound()) {
+ mp3ram = heap_caps_malloc(preallocateCodecSize, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
+ }
#ifdef USE_WEBRADIO
if (psramFound()) {
@@ -223,6 +229,7 @@ void I2S_Init(void) {
//Serial.printf_P(PSTR("FATAL ERROR: Unable to preallocate %d bytes for app\n"), preallocateBufferSize+preallocateCodecSize);
}
#endif // USE_WEBRADIO
+#endif // ESP32
}
#ifdef ESP32
@@ -285,7 +292,7 @@ void Webradio(const char *url) {
retryms = millis() + 2000;
}
- xTaskCreatePinnedToCore(mp3_task2, "MP3", 8192, NULL, 3, &mp3_task_h, 1);
+ xTaskCreatePinnedToCore(mp3_task2, "MP3-2", 8192, NULL, 3, &mp3_task_h, 1);
}
void mp3_task2(void *arg){
@@ -366,7 +373,12 @@ void Play_mp3(const char *path) {
file = new AudioFileSourceFS(*fsp,path);
id3 = new AudioFileSourceID3(file);
- mp3 = new AudioGeneratorMP3();
+
+ if (mp3ram) {
+ mp3 = new AudioGeneratorMP3(mp3ram, preallocateCodecSize);
+ } else {
+ mp3 = new AudioGeneratorMP3();
+ }
mp3->begin(id3, out);
if (I2S_Task) {
From ecc27aa3835cfe8b0fb78027762a743771b92212 Mon Sep 17 00:00:00 2001
From: Stephan Hadinger
Date: Sat, 12 Sep 2020 10:57:54 +0200
Subject: [PATCH 10/23] Add Zigbee auto-config when pairing
---
tasmota/CHANGELOG.md | 1 +
tasmota/settings.h | 2 +-
tasmota/xdrv_23_zigbee_2_devices.ino | 57 +++-
tasmota/xdrv_23_zigbee_5_converters.ino | 66 +++--
tasmota/xdrv_23_zigbee_6_commands.ino | 10 +-
tasmota/xdrv_23_zigbee_8_parsers.ino | 337 +++++++++++++++++++++++-
6 files changed, 430 insertions(+), 43 deletions(-)
diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md
index faaa2ae17..d07791a2e 100644
--- a/tasmota/CHANGELOG.md
+++ b/tasmota/CHANGELOG.md
@@ -8,6 +8,7 @@
- Fix crash in ``ZbRestore``
- Add new shutter modes (#9244)
- Add ``#define USE_MQTT_AWS_IOT_LIGHT`` for password based AWS IoT authentication
+- Add Zigbee auto-config when pairing
### 8.5.0 20200907
diff --git a/tasmota/settings.h b/tasmota/settings.h
index 2ceadd523..a9c8680c1 100644
--- a/tasmota/settings.h
+++ b/tasmota/settings.h
@@ -129,7 +129,7 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu
uint32_t virtual_ct_cw : 1; // bit 25 (v8.4.0.1) - SetOption107 - Virtual CT Channel - signals whether the hardware white is cold CW (true) or warm WW (false)
uint32_t teleinfo_rawdata : 1; // bit 26 (v8.4.0.2) - SetOption108 - enable Teleinfo + Tasmota Energy device (0) or Teleinfo raw data only (1)
uint32_t alexa_gen_1 : 1; // bit 27 (v8.4.0.3) - SetOption109 - Alexa gen1 mode - if you only have Echo Dot 2nd gen devices
- uint32_t spare28 : 1; // bit 28
+ uint32_t zb_disable_autobind : 1; // bit 28 (v8.5.0.1) - SetOption110 - disable Zigbee auto-config when pairing new devices
uint32_t spare29 : 1; // bit 29
uint32_t spare30 : 1; // bit 30
uint32_t spare31 : 1; // bit 31
diff --git a/tasmota/xdrv_23_zigbee_2_devices.ino b/tasmota/xdrv_23_zigbee_2_devices.ino
index 8ad36f861..1e2c29704 100644
--- a/tasmota/xdrv_23_zigbee_2_devices.ino
+++ b/tasmota/xdrv_23_zigbee_2_devices.ino
@@ -36,6 +36,10 @@ public:
char * manufacturerId;
char * modelId;
char * friendlyName;
+ // _defer_last_time : what was the last time an outgoing message is scheduled
+ // this is designed for flow control and avoid messages to be lost or unanswered
+ uint32_t defer_last_message_sent;
+
uint8_t endpoints[endpoints_max]; // static array to limit memory consumption, list of endpoints until 0x00 or end of array
// Used for attribute reporting
Z_attribute_list attr_list;
@@ -78,6 +82,7 @@ public:
manufacturerId(nullptr),
modelId(nullptr),
friendlyName(nullptr),
+ defer_last_message_sent(0),
endpoints{ 0, 0, 0, 0, 0, 0, 0, 0 },
attr_list(),
shortaddr(_shortaddr),
@@ -145,21 +150,28 @@ public:
* Structures for deferred callbacks
\*********************************************************************************************/
-typedef int32_t (*Z_DeviceTimer)(uint16_t shortaddr, uint16_t groupaddr, uint16_t cluster, uint8_t endpoint, uint32_t value);
+typedef void (*Z_DeviceTimer)(uint16_t shortaddr, uint16_t groupaddr, uint16_t cluster, uint8_t endpoint, uint32_t value);
// Category for Deferred actions, this allows to selectively remove active deferred or update them
typedef enum Z_Def_Category {
- Z_CAT_NONE = 0, // no category, it will happen anyways
+ Z_CAT_ALWAYS = 0, // no category, it will happen whatever new timers
+ // Below will clear any event in the same category for the same address (shortaddr / groupaddr)
+ Z_CLEAR_DEVICE = 0x01,
Z_CAT_READ_ATTR, // Attribute reporting, either READ_ATTRIBUTE or REPORT_ATTRIBUTE, we coalesce all attributes reported if we can
Z_CAT_VIRTUAL_OCCUPANCY, // Creation of a virtual attribute, typically after a time-out. Ex: Aqara presence sensor
Z_CAT_REACHABILITY, // timer set to measure reachability of device, i.e. if we don't get an answer after 1s, it is marked as unreachable (for Alexa)
- Z_CAT_READ_0006, // Read 0x0006 cluster
- Z_CAT_READ_0008, // Read 0x0008 cluster
- Z_CAT_READ_0102, // Read 0x0300 cluster
- Z_CAT_READ_0300, // Read 0x0300 cluster
+ // Below will clear based on device + cluster pair.
+ Z_CLEAR_DEVICE_CLUSTER,
+ Z_CAT_READ_CLUSTER,
+ // Below will clear based on device + cluster + endpoint
+ Z_CLEAR_DEVICE_CLUSTER_ENDPOINT,
+ Z_CAT_EP_DESC, // read endpoint descriptor to gather clusters
+ Z_CAT_BIND, // send auto-binding to coordinator
+ Z_CAT_CONFIG_ATTR, // send a config attribute reporting request
+ Z_CAT_READ_ATTRIBUTE, // read a single attribute
} Z_Def_Category;
-const uint32_t Z_CAT_REACHABILITY_TIMEOUT = 1000; // 1000 ms or 1s
+const uint32_t Z_CAT_REACHABILITY_TIMEOUT = 2000; // 1000 ms or 1s
typedef struct Z_Deferred {
// below are per device timers, used for example to query the new state of the device
@@ -258,8 +270,9 @@ public:
bool isHueBulbHidden(uint16_t shortaddr) const ;
// Timers
- void resetTimersForDevice(uint16_t shortaddr, uint16_t groupaddr, uint8_t category);
+ void resetTimersForDevice(uint16_t shortaddr, uint16_t groupaddr, uint8_t category, uint16_t cluster = 0xFFFF, uint8_t endpoint = 0xFF);
void setTimer(uint16_t shortaddr, uint16_t groupaddr, uint32_t wait_ms, uint16_t cluster, uint8_t endpoint, uint8_t category, uint32_t value, Z_DeviceTimer func);
+ void queueTimer(uint16_t shortaddr, uint16_t groupaddr, uint32_t wait_ms, uint16_t cluster, uint8_t endpoint, uint8_t category, uint32_t value, Z_DeviceTimer func);
void runTimer(void);
// Append or clear attributes Json structure
@@ -723,12 +736,17 @@ bool Z_Devices::isHueBulbHidden(uint16_t shortaddr) const {
// Deferred actions
// Parse for a specific category, of all deferred for a device if category == 0xFF
-void Z_Devices::resetTimersForDevice(uint16_t shortaddr, uint16_t groupaddr, uint8_t category) {
+// Only with specific cluster number or for all clusters if cluster == 0xFFFF
+void Z_Devices::resetTimersForDevice(uint16_t shortaddr, uint16_t groupaddr, uint8_t category, uint16_t cluster, uint8_t endpoint) {
// iterate the list of deferred, and remove any linked to the shortaddr
for (auto & defer : _deferred) {
if ((defer.shortaddr == shortaddr) && (defer.groupaddr == groupaddr)) {
if ((0xFF == category) || (defer.category == category)) {
- _deferred.remove(&defer);
+ if ((0xFFFF == cluster) || (defer.cluster == cluster)) {
+ if ((0xFF == endpoint) || (defer.endpoint == endpoint)) {
+ _deferred.remove(&defer);
+ }
+ }
}
}
}
@@ -737,8 +755,8 @@ void Z_Devices::resetTimersForDevice(uint16_t shortaddr, uint16_t groupaddr, uin
// Set timer for a specific device
void Z_Devices::setTimer(uint16_t shortaddr, uint16_t groupaddr, uint32_t wait_ms, uint16_t cluster, uint8_t endpoint, uint8_t category, uint32_t value, Z_DeviceTimer func) {
// First we remove any existing timer for same device in same category, except for category=0x00 (they need to happen anyway)
- if (category) { // if category == 0, we leave all previous
- resetTimersForDevice(shortaddr, groupaddr, category); // remove any cluster
+ if (category >= Z_CLEAR_DEVICE) { // if category == 0, we leave all previous timers
+ resetTimersForDevice(shortaddr, groupaddr, category, category >= Z_CLEAR_DEVICE_CLUSTER ? cluster : 0xFFFF, category >= Z_CLEAR_DEVICE_CLUSTER_ENDPOINT ? endpoint : 0xFF); // remove any cluster
}
// Now create the new timer
@@ -753,6 +771,21 @@ void Z_Devices::setTimer(uint16_t shortaddr, uint16_t groupaddr, uint32_t wait_m
func };
}
+// Set timer after the already queued events
+// I.e. the wait_ms is not counted from now, but from the last event queued, which is 'now' or in the future
+void Z_Devices::queueTimer(uint16_t shortaddr, uint16_t groupaddr, uint32_t wait_ms, uint16_t cluster, uint8_t endpoint, uint8_t category, uint32_t value, Z_DeviceTimer func) {
+ Z_Device & device = getShortAddr(shortaddr);
+ uint32_t now_millis = millis();
+ if (TimeReached(device.defer_last_message_sent)) {
+ device.defer_last_message_sent = now_millis;
+ }
+ // defer_last_message_sent equals now or a value in the future
+ device.defer_last_message_sent += wait_ms;
+
+ // for queueing we don't clear the backlog, so we force category to Z_CAT_ALWAYS
+ setTimer(shortaddr, groupaddr, (device.defer_last_message_sent - now_millis), cluster, endpoint, Z_CAT_ALWAYS, value, func);
+}
+
// Run timer at each tick
// WARNING: don't set a new timer within a running timer, this causes memory corruption
void Z_Devices::runTimer(void) {
diff --git a/tasmota/xdrv_23_zigbee_5_converters.ino b/tasmota/xdrv_23_zigbee_5_converters.ino
index 1155a6f2e..e70e6702d 100644
--- a/tasmota/xdrv_23_zigbee_5_converters.ino
+++ b/tasmota/xdrv_23_zigbee_5_converters.ino
@@ -124,6 +124,16 @@ uint16_t CxToCluster(uint8_t cx) {
}
return 0xFFFF;
}
+
+uint8_t ClusterToCx(uint16_t cluster) {
+ for (uint8_t i=0; icluster_short));
+ uint16_t conv_attr_id = pgm_read_word(&converter->attribute);
+
+ if ((conv_cluster == cluster) && (conv_attr_id == attr_id)) {
+ if (multiplier) { *multiplier = pgm_read_byte(&converter->multiplier); }
+ if (attr_type) { *attr_type = pgm_read_byte(&converter->type); }
+ return (const __FlashStringHelper*) (Z_strings + pgm_read_word(&converter->name_offset));
+ }
+ }
+ return nullptr;
+}
+
class ZCLFrame {
public:
@@ -1095,35 +1124,30 @@ void ZCLFrame::generateCallBacks(Z_attribute_list& attr_list) {
// Set timers to read back values.
// If it's a device address, also set a timer for reachability test
void sendHueUpdate(uint16_t shortaddr, uint16_t groupaddr, uint16_t cluster, uint8_t endpoint = 0) {
- int32_t z_cat = -1;
- uint32_t wait_ms = 0;
+ uint32_t wait_ms = 0xFFFF;
switch (cluster) {
case 0x0006:
- z_cat = Z_CAT_READ_0006;
wait_ms = 200; // wait 0.2 s
break;
case 0x0008:
- z_cat = Z_CAT_READ_0008;
wait_ms = 1050; // wait 1.0 s
break;
case 0x0102:
- z_cat = Z_CAT_READ_0102;
wait_ms = 10000; // wait 10.0 s
break;
case 0x0300:
- z_cat = Z_CAT_READ_0300;
wait_ms = 1050; // wait 1.0 s
break;
default:
break;
}
- if (z_cat >= 0) {
+ if (0xFFFF != wait_ms) {
if ((BAD_SHORTADDR != shortaddr) && (0 == endpoint)) {
endpoint = zigbee_devices.findFirstEndpoint(shortaddr);
}
if ((BAD_SHORTADDR == shortaddr) || (endpoint)) { // send if group address or endpoint is known
- zigbee_devices.setTimer(shortaddr, groupaddr, wait_ms, cluster, endpoint, z_cat, 0 /* value */, &Z_ReadAttrCallback);
+ zigbee_devices.queueTimer(shortaddr, groupaddr, wait_ms, cluster, endpoint, Z_CAT_READ_CLUSTER, 0 /* value */, &Z_ReadAttrCallback);
if (BAD_SHORTADDR != shortaddr) { // reachability test is not possible for group addresses, since we don't know the list of devices in the group
zigbee_devices.setTimer(shortaddr, groupaddr, wait_ms + Z_CAT_REACHABILITY_TIMEOUT, cluster, endpoint, Z_CAT_REACHABILITY, 0 /* value */, &Z_Unreachable);
}
@@ -1170,16 +1194,27 @@ void ZCLFrame::parseReadAttributes(Z_attribute_list& attr_list) {
// ZCL_CONFIGURE_REPORTING_RESPONSE
void ZCLFrame::parseConfigAttributes(Z_attribute_list& attr_list) {
- uint32_t i = 0;
uint32_t len = _payload.len();
- uint8_t status = _payload.get8(i);
- Z_attribute_list attr_config_response;
- attr_config_response.addAttribute(F("Status")).setUInt(status);
- attr_config_response.addAttribute(F("StatusMsg")).setStr(getZigbeeStatusMessage(status).c_str());
+ Z_attribute_list attr_config_list;
+ for (uint32_t i=0; len >= i+4; i+=4) {
+ uint8_t status = _payload.get8(i);
+ uint16_t attr_id = _payload.get8(i+2);
+
+ Z_attribute_list attr_config_response;
+ attr_config_response.addAttribute(F("Status")).setUInt(status);
+ attr_config_response.addAttribute(F("StatusMsg")).setStr(getZigbeeStatusMessage(status).c_str());
+
+ const __FlashStringHelper* attr_name = zigbeeFindAttributeById(_cluster_id, attr_id, nullptr, nullptr);
+ if (attr_name) {
+ attr_config_list.addAttribute(attr_name).setStrRaw(attr_config_response.toString(true).c_str());
+ } else {
+ attr_config_list.addAttribute(_cluster_id, attr_id).setStrRaw(attr_config_response.toString(true).c_str());
+ }
+ }
Z_attribute &attr_1 = attr_list.addAttribute(F("ConfigResponse"));
- attr_1.setStrRaw(attr_config_response.toString(true).c_str());
+ attr_1.setStrRaw(attr_config_list.toString(true).c_str());
}
// ZCL_READ_REPORTING_CONFIGURATION_RESPONSE
@@ -1534,11 +1569,10 @@ void ZCLFrame::syntheticAqaraVibration(class Z_attribute_list &attr_list, class
}
/// Publish a message for `"Occupancy":0` when the timer expired
-int32_t Z_OccupancyCallback(uint16_t shortaddr, uint16_t groupaddr, uint16_t cluster, uint8_t endpoint, uint32_t value) {
+void Z_OccupancyCallback(uint16_t shortaddr, uint16_t groupaddr, uint16_t cluster, uint8_t endpoint, uint32_t value) {
Z_attribute_list attr_list;
attr_list.addAttribute(F(OCCUPANCY)).setUInt(0);
zigbee_devices.jsonPublishNow(shortaddr, attr_list);
- return 0; // Fix GCC 10.1 warning
}
// ======================================================================
diff --git a/tasmota/xdrv_23_zigbee_6_commands.ino b/tasmota/xdrv_23_zigbee_6_commands.ino
index a32f637c4..947e2ffe0 100644
--- a/tasmota/xdrv_23_zigbee_6_commands.ino
+++ b/tasmota/xdrv_23_zigbee_6_commands.ino
@@ -148,7 +148,7 @@ const uint8_t CLUSTER_0009[] = { ZLE(0x0000) }; // AlarmCount
const uint8_t CLUSTER_0300[] = { ZLE(0x0000), ZLE(0x0001), ZLE(0x0003), ZLE(0x0004), ZLE(0x0007), ZLE(0x0008) }; // Hue, Sat, X, Y, CT, ColorMode
// This callback is registered after a cluster specific command and sends a read command for the same cluster
-int32_t Z_ReadAttrCallback(uint16_t shortaddr, uint16_t groupaddr, uint16_t cluster, uint8_t endpoint, uint32_t value) {
+void Z_ReadAttrCallback(uint16_t shortaddr, uint16_t groupaddr, uint16_t cluster, uint8_t endpoint, uint32_t value) {
size_t attrs_len = 0;
const uint8_t* attrs = nullptr;
@@ -188,16 +188,14 @@ int32_t Z_ReadAttrCallback(uint16_t shortaddr, uint16_t groupaddr, uint16_t clus
attrs, attrs_len
}));
}
- return 0; // Fix GCC 10.1 warning
}
// This callback is registered after a an attribute read command was made to a light, and fires if we don't get any response after 1000 ms
-int32_t Z_Unreachable(uint16_t shortaddr, uint16_t groupaddr, uint16_t cluster, uint8_t endpoint, uint32_t value) {
+void Z_Unreachable(uint16_t shortaddr, uint16_t groupaddr, uint16_t cluster, uint8_t endpoint, uint32_t value) {
if (BAD_SHORTADDR != shortaddr) {
zigbee_devices.setReachable(shortaddr, false); // mark device as reachable
}
- return 0; // Fix GCC 10.1 warning
}
// returns true if char is 'x', 'y' or 'z'
@@ -349,6 +347,10 @@ void convertClusterSpecific(class Z_attribute_list &attr_list, uint16_t cluster,
if ((0 != xyz.z) && (0xFF != xyz.z)) {
attr_list.addAttribute(command_name, PSTR("Zone")).setUInt(xyz.z);
}
+ // for now convert alamrs 1 and 2 to Occupancy
+ // TODO we may only do this conversion to ZoneType == 0x000D 'Motion Sensor'
+ // Occupancy is 0406/0000 of type Zmap8
+ attr_list.addAttribute(0x0406, 0x0000).setUInt((xyz.x) & 0x01 ? 1 : 0);
break;
case 0x00040000:
case 0x00040001:
diff --git a/tasmota/xdrv_23_zigbee_8_parsers.ino b/tasmota/xdrv_23_zigbee_8_parsers.ino
index d800eaf71..788c72e88 100644
--- a/tasmota/xdrv_23_zigbee_8_parsers.ino
+++ b/tasmota/xdrv_23_zigbee_8_parsers.ino
@@ -533,7 +533,11 @@ int32_t Z_ReceiveActiveEp(int32_t res, const class SBuffer &buf) {
#endif
for (uint32_t i = 0; i < activeEpCount; i++) {
- zigbee_devices.addEndpoint(nwkAddr, activeEpList[i]);
+ uint8_t ep = activeEpList[i];
+ zigbee_devices.addEndpoint(nwkAddr, ep);
+ if ((i < 4) && (ep < 0x10)) {
+ zigbee_devices.queueTimer(nwkAddr, 0 /* groupaddr */, 1500, ep /* fake cluster as ep */, ep, Z_CAT_EP_DESC, 0 /* value */, &Z_SendSimpleDescReq);
+ }
}
Response_P(PSTR("{\"" D_JSON_ZIGBEE_STATE "\":{"
@@ -546,7 +550,132 @@ int32_t Z_ReceiveActiveEp(int32_t res, const class SBuffer &buf) {
ResponseAppend_P(PSTR("]}}"));
MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEEZCL_RECEIVED));
- Z_SendAFInfoRequest(nwkAddr); // probe for ModelId and ManufId
+ Z_SendDeviceInfoRequest(nwkAddr); // probe for ModelId and ManufId
+
+ return -1;
+}
+
+// list of clusters that need bindings
+const uint8_t Z_bindings[] PROGMEM = {
+ Cx0001, Cx0006, Cx0008, Cx0300,
+ Cx0400, Cx0402, Cx0403, Cx0405, Cx0406,
+ Cx0500,
+};
+
+int32_t Z_ClusterToCxBinding(uint16_t cluster) {
+ uint8_t cx = ClusterToCx(cluster);
+ for (uint32_t i=0; i= 0) {
+ bitSet(cluster_map, found_cx);
+ bitSet(cluster_in_map, found_cx);
+ }
+ }
+ // scan out clusters
+ for (uint32_t i=0; i= 0) {
+ bitSet(cluster_map, found_cx);
+ }
+ }
+
+ // if IAS device, request the device type
+ if (bitRead(cluster_map, Z_ClusterToCxBinding(0x0500))) {
+ // send a read command to cluster 0x0500, attribute 0x0001 (ZoneType) - to read the type of sensor
+ zigbee_devices.queueTimer(shortaddr, 0 /* groupaddr */, 2000, 0x0500, endpoint, Z_CAT_READ_ATTRIBUTE, 0x0001, &Z_SendSingleAttributeRead);
+ }
+
+ // enqueue bind requests
+ for (uint32_t i=0; i 0) { ResponseAppend_P(PSTR(",")); }
+ ResponseAppend_P(PSTR("\"0x%04X\""), buf.get16(numInIndex + i*2));
+ }
+ ResponseAppend_P(PSTR("],\"OutClusters\":["));
+ for (uint32_t i = 0; i < numOutCluster; i++) {
+ if (i > 0) { ResponseAppend_P(PSTR(",")); }
+ ResponseAppend_P(PSTR("\"0x%04X\""), buf.get16(numOutIndex + i*2));
+ }
+ ResponseAppend_P(PSTR("]}}"));
+ MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_ZIGBEEZCL_RECEIVED));
+ XdrvRulesProcess();
+ }
return -1;
}
@@ -831,7 +960,7 @@ int32_t Z_MgmtBindRsp(int32_t res, const class SBuffer &buf) {
//uint64_t srcaddr = buf.get16(idx); // unused
uint8_t srcep = buf.get8(idx + 8);
- uint8_t cluster = buf.get16(idx + 9);
+ uint16_t cluster = buf.get16(idx + 9);
uint8_t addrmode = buf.get8(idx + 11);
uint16_t group = 0x0000;
uint64_t dstaddr = 0;
@@ -960,9 +1089,31 @@ void Z_SendActiveEpReq(uint16_t shortaddr) {
}
//
-// Send AF Info Request
+// Probe the clusters_out on the first endpoint
//
-void Z_SendAFInfoRequest(uint16_t shortaddr) {
+// Send ZDO_SIMPLE_DESC_REQ to get full list of supported Clusters for a specific endpoint
+void Z_SendSimpleDescReq(uint16_t shortaddr, uint16_t groupaddr, uint16_t cluster, uint8_t endpoint, uint32_t value) {
+#ifdef USE_ZIGBEE_ZNP
+ uint8_t SimpleDescReq[] = { Z_SREQ | Z_ZDO, ZDO_SIMPLE_DESC_REQ, // 2504
+ Z_B0(shortaddr), Z_B1(shortaddr), Z_B0(shortaddr), Z_B1(shortaddr),
+ endpoint };
+ ZigbeeZNPSend(SimpleDescReq, sizeof(SimpleDescReq));
+#endif
+#ifdef USE_ZIGBEE_EZSP
+ uint8_t SimpleDescReq[] = { Z_B0(shortaddr), Z_B1(shortaddr), endpoint };
+ EZ_SendZDO(shortaddr, ZDO_SIMPLE_DESC_REQ, SimpleDescReq, sizeof(SimpleDescReq));
+#endif
+}
+
+
+//
+// Send AF Info Request
+// Queue requests for the device
+// 1. Request for 'ModelId' and 'Manufacturer': 0000/0005, 0000/0006
+// 2. Auto-bind to coordinator:
+// Iterate among
+//
+void Z_SendDeviceInfoRequest(uint16_t shortaddr) {
uint8_t endpoint = zigbee_devices.findFirstEndpoint(shortaddr);
if (0x00 == endpoint) { endpoint = 0x01; } // if we don't know the endpoint, try 0x01
uint8_t transacid = zigbee_devices.getNextSeqNumber(shortaddr);
@@ -983,6 +1134,170 @@ void Z_SendAFInfoRequest(uint16_t shortaddr) {
}));
}
+//
+// Send sing attribute read request in Timer
+//
+void Z_SendSingleAttributeRead(uint16_t shortaddr, uint16_t groupaddr, uint16_t cluster, uint8_t endpoint, uint32_t value) {
+ uint8_t transacid = zigbee_devices.getNextSeqNumber(shortaddr);
+ uint8_t InfoReq[2] = { Z_B0(value), Z_B1(value) }; // list of single attribute
+
+ ZigbeeZCLSend_Raw(ZigbeeZCLSendMessage({
+ shortaddr,
+ 0x0000, /* group */
+ cluster /*cluster*/,
+ endpoint,
+ ZCL_READ_ATTRIBUTES,
+ 0x0000, /* manuf */
+ false /* not cluster specific */,
+ true /* response */,
+ transacid, /* zcl transaction id */
+ InfoReq, sizeof(InfoReq)
+ }));
+}
+
+//
+// Auto-bind some clusters to the coordinator's endpoint 0x01
+//
+void Z_AutoBind(uint16_t shortaddr, uint16_t groupaddr, uint16_t cluster, uint8_t endpoint, uint32_t value) {
+ uint64_t srcLongAddr = zigbee_devices.getDeviceLongAddr(shortaddr);
+
+ AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_ZIGBEE "auto-bind `ZbBind {\"Device\":\"0x%04X\",\"Endpoint\":%d,\"Cluster\":\"0x%04X\"}`"),
+ shortaddr, endpoint, cluster);
+#ifdef USE_ZIGBEE_ZNP
+ SBuffer buf(34);
+ buf.add8(Z_SREQ | Z_ZDO);
+ buf.add8(ZDO_BIND_REQ);
+ buf.add16(shortaddr);
+ buf.add64(srcLongAddr);
+ buf.add8(endpoint);
+ buf.add16(cluster);
+ buf.add8(Z_Addr_IEEEAddress); // DstAddrMode - 0x03 = ADDRESS_64_BIT
+ buf.add64(localIEEEAddr);
+ buf.add8(0x01); // toEndpoint
+
+ ZigbeeZNPSend(buf.getBuffer(), buf.len());
+#endif // USE_ZIGBEE_ZNP
+
+#ifdef USE_ZIGBEE_EZSP
+ SBuffer buf(24);
+
+ // ZDO message payload (see Zigbee spec 2.4.3.2.2)
+ buf.add64(srcLongAddr);
+ buf.add8(endpoint);
+ buf.add16(cluster);
+ buf.add8(Z_Addr_IEEEAddress); // DstAddrMode - 0x03 = ADDRESS_64_BIT
+ buf.add64(localIEEEAddr);
+ buf.add8(0x01); // toEndpoint
+
+ EZ_SendZDO(shortaddr, ZDO_BIND_REQ, buf.buf(), buf.len());
+#endif // USE_ZIGBEE_EZSP
+}
+
+//
+// Auto-bind some clusters to the coordinator's endpoint 0x01
+//
+
+// the structure below indicates which attributes need to be configured for attribute reporting
+typedef struct Z_autoAttributeReporting_t {
+ uint16_t cluster;
+ uint16_t attr_id;
+ uint16_t min_interval; // minimum interval in seconds (consecutive reports won't happen before this value)
+ uint16_t max_interval; // maximum interval in seconds (attribut will always be reported after this interval)
+ float report_change; // for non discrete attributes, the value change that triggers a report
+} Z_autoAttributeReporting_t;
+
+// Note the attribute must be registered in the converter list, used to retrieve the type of the attribute
+const Z_autoAttributeReporting_t Z_autoAttributeReporting[] PROGMEM = {
+ { 0x0001, 0x0020, 15*60, 15*60, 0.1 }, // BatteryVoltage
+ { 0x0001, 0x0021, 15*60, 15*60, 1 }, // BatteryPercentage
+ { 0x0006, 0x0000, 1, 60*60, 0 }, // Power
+ { 0x0008, 0x0000, 1, 60*60, 5 }, // Dimmer
+ { 0x0300, 0x0000, 1, 60*60, 5 }, // Hue
+ { 0x0300, 0x0001, 1, 60*60, 5 }, // Sat
+ { 0x0300, 0x0003, 1, 60*60, 100 }, // X
+ { 0x0300, 0x0004, 1, 60*60, 100 }, // Y
+ { 0x0300, 0x0007, 1, 60*60, 5 }, // CT
+ { 0x0300, 0x0008, 1, 60*60, 0 }, // ColorMode
+ { 0x0400, 0x0000, 10, 60*60, 5 }, // Illuminance (5 lux)
+ { 0x0402, 0x0000, 30, 60*60, 0.2 }, // Temperature (0.2 °C)
+ { 0x0403, 0x0000, 30, 60*60, 1 }, // Pressure (1 hPa)
+ { 0x0405, 0x0000, 30, 60*60, 1.0 }, // Humidity (1 %)
+ { 0x0406, 0x0000, 10, 60*60, 0 }, // Occupancy
+ { 0x0500, 0x0002, 1, 60*60, 0 }, // ZoneStatus
+};
+
+//
+// Called by Device Auto-config
+// Configures default values for the most common Attribute Rerporting configurations
+//
+// Note: must be of type `Z_DeviceTimer`
+void Z_AutoConfigReportingForCluster(uint16_t shortaddr, uint16_t groupaddr, uint16_t cluster, uint8_t endpoint, uint32_t value) {
+ // Buffer, max 12 bytes per attribute
+ SBuffer buf(12*6);
+
+
+ Response_P(PSTR("ZbSend {\"Device\":\"0x%04X\",\"Config\":{"), shortaddr);
+
+ boolean comma = false;
+ for (uint32_t i=0; i 0) {
+ AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_ZIGBEE "auto-bind `%s`"), mqtt_data);
+ ZigbeeZCLSend_Raw(ZigbeeZCLSendMessage({
+ shortaddr,
+ 0x0000, /* group */
+ cluster /*cluster*/,
+ endpoint,
+ ZCL_CONFIGURE_REPORTING,
+ 0x0000, /* manuf */
+ false /* not cluster specific */,
+ false /* no response */,
+ zigbee_devices.getNextSeqNumber(shortaddr), /* zcl transaction id */
+ buf.buf(), buf.len()
+ }));
+ }
+}
//
// Handle trustCenterJoinHandler
@@ -1189,6 +1504,8 @@ int32_t EZ_IncomingMessage(int32_t res, const class SBuffer &buf) {
return Z_ReceiveActiveEp(res, zdo_buf);
case ZDO_IEEE_addr_rsp:
return Z_ReceiveIEEEAddr(res, zdo_buf);
+ case ZDO_Simple_Desc_rsp:
+ return Z_ReceiveSimpleDesc(res, zdo_buf);
case ZDO_Bind_rsp:
return Z_BindRsp(res, zdo_buf);
case ZDO_Unbind_rsp:
@@ -1279,9 +1596,8 @@ int32_t EZ_Recv_Default(int32_t res, const class SBuffer &buf) {
\*********************************************************************************************/
// Publish the received values once they have been coalesced
-int32_t Z_PublishAttributes(uint16_t shortaddr, uint16_t groupaddr, uint16_t cluster, uint8_t endpoint, uint32_t value) {
+void Z_PublishAttributes(uint16_t shortaddr, uint16_t groupaddr, uint16_t cluster, uint8_t endpoint, uint32_t value) {
zigbee_devices.jsonPublishFlush(shortaddr);
- return 1;
}
/*********************************************************************************************\
@@ -1363,6 +1679,7 @@ const Z_Dispatcher Z_DispatchTable[] PROGMEM = {
{ { Z_AREQ | Z_ZDO, ZDO_PERMIT_JOIN_IND }, &ZNP_ReceivePermitJoinStatus }, // 45CB
{ { Z_AREQ | Z_ZDO, ZDO_NODE_DESC_RSP }, &ZNP_ReceiveNodeDesc }, // 4582
{ { Z_AREQ | Z_ZDO, ZDO_ACTIVE_EP_RSP }, &Z_ReceiveActiveEp }, // 4585
+ { { Z_AREQ | Z_ZDO, ZDO_SIMPLE_DESC_RSP}, &Z_ReceiveSimpleDesc}, // 4584
{ { Z_AREQ | Z_ZDO, ZDO_IEEE_ADDR_RSP }, &Z_ReceiveIEEEAddr }, // 4581
{ { Z_AREQ | Z_ZDO, ZDO_BIND_RSP }, &Z_BindRsp }, // 45A1
{ { Z_AREQ | Z_ZDO, ZDO_UNBIND_RSP }, &Z_UnbindRsp }, // 45A2
@@ -1413,11 +1730,11 @@ void Z_Query_Bulb(uint16_t shortaddr, uint32_t &wait_ms) {
uint8_t endpoint = zigbee_devices.findFirstEndpoint(shortaddr);
if (endpoint) { // send only if we know the endpoint
- zigbee_devices.setTimer(shortaddr, 0 /* groupaddr */, wait_ms, 0x0006, endpoint, Z_CAT_NONE, 0 /* value */, &Z_ReadAttrCallback);
+ zigbee_devices.setTimer(shortaddr, 0 /* groupaddr */, wait_ms, 0x0006, endpoint, Z_CAT_READ_CLUSTER, 0 /* value */, &Z_ReadAttrCallback);
wait_ms += inter_message_ms;
- zigbee_devices.setTimer(shortaddr, 0 /* groupaddr */, wait_ms, 0x0008, endpoint, Z_CAT_NONE, 0 /* value */, &Z_ReadAttrCallback);
+ zigbee_devices.setTimer(shortaddr, 0 /* groupaddr */, wait_ms, 0x0008, endpoint, Z_CAT_READ_CLUSTER, 0 /* value */, &Z_ReadAttrCallback);
wait_ms += inter_message_ms;
- zigbee_devices.setTimer(shortaddr, 0 /* groupaddr */, wait_ms, 0x0300, endpoint, Z_CAT_NONE, 0 /* value */, &Z_ReadAttrCallback);
+ zigbee_devices.setTimer(shortaddr, 0 /* groupaddr */, wait_ms, 0x0300, endpoint, Z_CAT_READ_CLUSTER, 0 /* value */, &Z_ReadAttrCallback);
wait_ms += inter_message_ms;
zigbee_devices.setTimer(shortaddr, 0, wait_ms + Z_CAT_REACHABILITY_TIMEOUT, 0, endpoint, Z_CAT_REACHABILITY, 0 /* value */, &Z_Unreachable);
wait_ms += 1000; // wait 1 second between devices
From 828490a1b20495dda963dde01c78a6a8a9225638 Mon Sep 17 00:00:00 2001
From: Jason2866 <24528715+Jason2866@users.noreply.github.com>
Date: Sat, 12 Sep 2020 11:15:46 +0200
Subject: [PATCH 11/23] override not needed
---
.github/workflows/CI_github_ESP32.yml | 90 +++++++++-----------------
.github/workflows/Tasmota_build.yml | 93 +++++++++------------------
2 files changed, 61 insertions(+), 122 deletions(-)
diff --git a/.github/workflows/CI_github_ESP32.yml b/.github/workflows/CI_github_ESP32.yml
index cc9af6f19..64fbd39b2 100644
--- a/.github/workflows/CI_github_ESP32.yml
+++ b/.github/workflows/CI_github_ESP32.yml
@@ -17,8 +17,7 @@ jobs:
platformio upgrade --dev
platformio update
- name: Run PlatformIO
- run: |
- mv -f platformio_override_sample.ini platformio_override.ini
+ run: |
platformio run -e tasmota32
tasmota32-webcam:
@@ -34,8 +33,7 @@ jobs:
platformio upgrade --dev
platformio update
- name: Run PlatformIO
- run: |
- mv -f platformio_override_sample.ini platformio_override.ini
+ run: |
platformio run -e tasmota32-webcam
tasmota32-minimal:
@@ -51,8 +49,7 @@ jobs:
platformio upgrade --dev
platformio update
- name: Run PlatformIO
- run: |
- mv -f platformio_override_sample.ini platformio_override.ini
+ run: |
platformio run -e tasmota32-minimal
tasmota32-lite:
runs-on: ubuntu-latest
@@ -67,8 +64,7 @@ jobs:
platformio upgrade --dev
platformio update
- name: Run PlatformIO
- run: |
- mv -f platformio_override_sample.ini platformio_override.ini
+ run: |
platformio run -e tasmota32-lite
tasmota32-knx:
runs-on: ubuntu-latest
@@ -83,8 +79,7 @@ jobs:
platformio upgrade --dev
platformio update
- name: Run PlatformIO
- run: |
- mv -f platformio_override_sample.ini platformio_override.ini
+ run: |
platformio run -e tasmota32-knx
tasmota32-sensors:
@@ -100,8 +95,7 @@ jobs:
platformio upgrade --dev
platformio update
- name: Run PlatformIO
- run: |
- mv -f platformio_override_sample.ini platformio_override.ini
+ run: |
platformio run -e tasmota32-sensors
tasmota32-display:
runs-on: ubuntu-latest
@@ -116,8 +110,7 @@ jobs:
platformio upgrade --dev
platformio update
- name: Run PlatformIO
- run: |
- mv -f platformio_override_sample.ini platformio_override.ini
+ run: |
platformio run -e tasmota32-display
tasmota32-ir:
runs-on: ubuntu-latest
@@ -132,8 +125,7 @@ jobs:
platformio upgrade --dev
platformio update
- name: Run PlatformIO
- run: |
- mv -f platformio_override_sample.ini platformio_override.ini
+ run: |
platformio run -e tasmota32-ir
tasmota32-BG:
runs-on: ubuntu-latest
@@ -148,8 +140,7 @@ jobs:
platformio upgrade --dev
platformio update
- name: Run PlatformIO
- run: |
- mv -f platformio_override_sample.ini platformio_override.ini
+ run: |
platformio run -e tasmota32-BG
tasmota32-BR:
@@ -165,8 +156,7 @@ jobs:
platformio upgrade --dev
platformio update
- name: Run PlatformIO
- run: |
- mv -f platformio_override_sample.ini platformio_override.ini
+ run: |
platformio run -e tasmota32-BR
tasmota32-CN:
runs-on: ubuntu-latest
@@ -181,8 +171,7 @@ jobs:
platformio upgrade --dev
platformio update
- name: Run PlatformIO
- run: |
- mv -f platformio_override_sample.ini platformio_override.ini
+ run: |
platformio run -e tasmota32-CN
tasmota32-CZ:
runs-on: ubuntu-latest
@@ -197,8 +186,7 @@ jobs:
platformio upgrade --dev
platformio update
- name: Run PlatformIO
- run: |
- mv -f platformio_override_sample.ini platformio_override.ini
+ run: |
platformio run -e tasmota32-CZ
tasmota32-DE:
runs-on: ubuntu-latest
@@ -213,8 +201,7 @@ jobs:
platformio upgrade --dev
platformio update
- name: Run PlatformIO
- run: |
- mv -f platformio_override_sample.ini platformio_override.ini
+ run: |
platformio run -e tasmota32-DE
tasmota32-ES:
@@ -230,8 +217,7 @@ jobs:
platformio upgrade --dev
platformio update
- name: Run PlatformIO
- run: |
- mv -f platformio_override_sample.ini platformio_override.ini
+ run: |
platformio run -e tasmota32-ES
tasmota32-FR:
runs-on: ubuntu-latest
@@ -246,8 +232,7 @@ jobs:
platformio upgrade --dev
platformio update
- name: Run PlatformIO
- run: |
- mv -f platformio_override_sample.ini platformio_override.ini
+ run: |
platformio run -e tasmota32-FR
tasmota32-GR:
runs-on: ubuntu-latest
@@ -262,8 +247,7 @@ jobs:
platformio upgrade --dev
platformio update
- name: Run PlatformIO
- run: |
- mv -f platformio_override_sample.ini platformio_override.ini
+ run: |
platformio run -e tasmota32-GR
tasmota32-HE:
runs-on: ubuntu-latest
@@ -278,8 +262,7 @@ jobs:
platformio upgrade --dev
platformio update
- name: Run PlatformIO
- run: |
- mv -f platformio_override_sample.ini platformio_override.ini
+ run: |
platformio run -e tasmota32-HE
tasmota32-HU:
@@ -295,8 +278,7 @@ jobs:
platformio upgrade --dev
platformio update
- name: Run PlatformIO
- run: |
- mv -f platformio_override_sample.ini platformio_override.ini
+ run: |
platformio run -e tasmota32-HU
tasmota32-IT:
runs-on: ubuntu-latest
@@ -311,8 +293,7 @@ jobs:
platformio upgrade --dev
platformio update
- name: Run PlatformIO
- run: |
- mv -f platformio_override_sample.ini platformio_override.ini
+ run: |
platformio run -e tasmota32-IT
tasmota32-KO:
runs-on: ubuntu-latest
@@ -327,8 +308,7 @@ jobs:
platformio upgrade --dev
platformio update
- name: Run PlatformIO
- run: |
- mv -f platformio_override_sample.ini platformio_override.ini
+ run: |
platformio run -e tasmota32-KO
tasmota32-NL:
runs-on: ubuntu-latest
@@ -343,8 +323,7 @@ jobs:
platformio upgrade --dev
platformio update
- name: Run PlatformIO
- run: |
- mv -f platformio_override_sample.ini platformio_override.ini
+ run: |
platformio run -e tasmota32-NL
tasmota32-PL:
@@ -360,8 +339,7 @@ jobs:
platformio upgrade --dev
platformio update
- name: Run PlatformIO
- run: |
- mv -f platformio_override_sample.ini platformio_override.ini
+ run: |
platformio run -e tasmota32-PL
tasmota32-PT:
runs-on: ubuntu-latest
@@ -376,8 +354,7 @@ jobs:
platformio upgrade --dev
platformio update
- name: Run PlatformIO
- run: |
- mv -f platformio_override_sample.ini platformio_override.ini
+ run: |
platformio run -e tasmota32-PT
tasmota32-RO:
runs-on: ubuntu-latest
@@ -392,8 +369,7 @@ jobs:
platformio upgrade --dev
platformio update
- name: Run PlatformIO
- run: |
- mv -f platformio_override_sample.ini platformio_override.ini
+ run: |
platformio run -e tasmota32-RO
tasmota32-RU:
runs-on: ubuntu-latest
@@ -408,8 +384,7 @@ jobs:
platformio upgrade --dev
platformio update
- name: Run PlatformIO
- run: |
- mv -f platformio_override_sample.ini platformio_override.ini
+ run: |
platformio run -e tasmota32-RU
tasmota32-SE:
@@ -425,8 +400,7 @@ jobs:
platformio upgrade --dev
platformio update
- name: Run PlatformIO
- run: |
- mv -f platformio_override_sample.ini platformio_override.ini
+ run: |
platformio run -e tasmota32-SE
tasmota32-SK:
runs-on: ubuntu-latest
@@ -441,8 +415,7 @@ jobs:
platformio upgrade --dev
platformio update
- name: Run PlatformIO
- run: |
- mv -f platformio_override_sample.ini platformio_override.ini
+ run: |
platformio run -e tasmota32-SK
tasmota32-TR:
runs-on: ubuntu-latest
@@ -457,8 +430,7 @@ jobs:
platformio upgrade --dev
platformio update
- name: Run PlatformIO
- run: |
- mv -f platformio_override_sample.ini platformio_override.ini
+ run: |
platformio run -e tasmota32-TR
tasmota32-TW:
runs-on: ubuntu-latest
@@ -473,8 +445,7 @@ jobs:
platformio upgrade --dev
platformio update
- name: Run PlatformIO
- run: |
- mv -f platformio_override_sample.ini platformio_override.ini
+ run: |
platformio run -e tasmota32-TW
tasmota32-UK:
@@ -490,6 +461,5 @@ jobs:
platformio upgrade --dev
platformio update
- name: Run PlatformIO
- run: |
- mv -f platformio_override_sample.ini platformio_override.ini
+ run: |
platformio run -e tasmota32-UK
diff --git a/.github/workflows/Tasmota_build.yml b/.github/workflows/Tasmota_build.yml
index 5d5665715..4a890b89d 100644
--- a/.github/workflows/Tasmota_build.yml
+++ b/.github/workflows/Tasmota_build.yml
@@ -750,8 +750,7 @@ jobs:
platformio upgrade --dev
platformio update
- name: Run PlatformIO
- run: |
- mv -f platformio_override_sample.ini platformio_override.ini
+ run: |
platformio run -e tasmota32
- uses: actions/upload-artifact@v2
with:
@@ -774,8 +773,7 @@ jobs:
platformio upgrade --dev
platformio update
- name: Run PlatformIO
- run: |
- mv -f platformio_override_sample.ini platformio_override.ini
+ run: |
platformio run -e tasmota32-minimal
- uses: actions/upload-artifact@v2
with:
@@ -798,8 +796,7 @@ jobs:
platformio upgrade --dev
platformio update
- name: Run PlatformIO
- run: |
- mv -f platformio_override_sample.ini platformio_override.ini
+ run: |
platformio run -e tasmota32-lite
- uses: actions/upload-artifact@v2
with:
@@ -822,8 +819,7 @@ jobs:
platformio upgrade --dev
platformio update
- name: Run PlatformIO
- run: |
- mv -f platformio_override_sample.ini platformio_override.ini
+ run: |
platformio run -e tasmota32-webcam
- uses: actions/upload-artifact@v2
with:
@@ -846,8 +842,7 @@ jobs:
platformio upgrade --dev
platformio update
- name: Run PlatformIO
- run: |
- mv -f platformio_override_sample.ini platformio_override.ini
+ run: |
platformio run -e tasmota32-knx
- uses: actions/upload-artifact@v2
with:
@@ -870,8 +865,7 @@ jobs:
platformio upgrade --dev
platformio update
- name: Run PlatformIO
- run: |
- mv -f platformio_override_sample.ini platformio_override.ini
+ run: |
platformio run -e tasmota32-sensors
- uses: actions/upload-artifact@v2
with:
@@ -894,8 +888,7 @@ jobs:
platformio upgrade --dev
platformio update
- name: Run PlatformIO
- run: |
- mv -f platformio_override_sample.ini platformio_override.ini
+ run: |
platformio run -e tasmota32-display
- uses: actions/upload-artifact@v2
with:
@@ -918,8 +911,7 @@ jobs:
platformio upgrade --dev
platformio update
- name: Run PlatformIO
- run: |
- mv -f platformio_override_sample.ini platformio_override.ini
+ run: |
platformio run -e tasmota32-ir
- uses: actions/upload-artifact@v2
with:
@@ -942,8 +934,7 @@ jobs:
platformio upgrade --dev
platformio update
- name: Run PlatformIO
- run: |
- mv -f platformio_override_sample.ini platformio_override.ini
+ run: |
platformio run -e tasmota32-ircustom
- uses: actions/upload-artifact@v2
with:
@@ -966,8 +957,7 @@ jobs:
platformio upgrade --dev
platformio update
- name: Run PlatformIO
- run: |
- mv -f platformio_override_sample.ini platformio_override.ini
+ run: |
platformio run -e tasmota32-BG
- uses: actions/upload-artifact@v2
with:
@@ -990,8 +980,7 @@ jobs:
platformio upgrade --dev
platformio update
- name: Run PlatformIO
- run: |
- mv -f platformio_override_sample.ini platformio_override.ini
+ run: |
platformio run -e tasmota32-BR
- uses: actions/upload-artifact@v2
with:
@@ -1014,8 +1003,7 @@ jobs:
platformio upgrade --dev
platformio update
- name: Run PlatformIO
- run: |
- mv -f platformio_override_sample.ini platformio_override.ini
+ run: |
platformio run -e tasmota32-CN
- uses: actions/upload-artifact@v2
with:
@@ -1038,8 +1026,7 @@ jobs:
platformio upgrade --dev
platformio update
- name: Run PlatformIO
- run: |
- mv -f platformio_override_sample.ini platformio_override.ini
+ run: |
platformio run -e tasmota32-CZ
- uses: actions/upload-artifact@v2
with:
@@ -1062,8 +1049,7 @@ jobs:
platformio upgrade --dev
platformio update
- name: Run PlatformIO
- run: |
- mv -f platformio_override_sample.ini platformio_override.ini
+ run: |
platformio run -e tasmota32-DE
- uses: actions/upload-artifact@v2
with:
@@ -1086,8 +1072,7 @@ jobs:
platformio upgrade --dev
platformio update
- name: Run PlatformIO
- run: |
- mv -f platformio_override_sample.ini platformio_override.ini
+ run: |
platformio run -e tasmota32-ES
- uses: actions/upload-artifact@v2
with:
@@ -1110,8 +1095,7 @@ jobs:
platformio upgrade --dev
platformio update
- name: Run PlatformIO
- run: |
- mv -f platformio_override_sample.ini platformio_override.ini
+ run: |
platformio run -e tasmota32-FR
- uses: actions/upload-artifact@v2
with:
@@ -1134,8 +1118,7 @@ jobs:
platformio upgrade --dev
platformio update
- name: Run PlatformIO
- run: |
- mv -f platformio_override_sample.ini platformio_override.ini
+ run: |
platformio run -e tasmota32-GR
- uses: actions/upload-artifact@v2
with:
@@ -1158,8 +1141,7 @@ jobs:
platformio upgrade --dev
platformio update
- name: Run PlatformIO
- run: |
- mv -f platformio_override_sample.ini platformio_override.ini
+ run: |
platformio run -e tasmota32-HE
- uses: actions/upload-artifact@v2
with:
@@ -1182,8 +1164,7 @@ jobs:
platformio upgrade --dev
platformio update
- name: Run PlatformIO
- run: |
- mv -f platformio_override_sample.ini platformio_override.ini
+ run: |
platformio run -e tasmota32-HU
- uses: actions/upload-artifact@v2
with:
@@ -1206,8 +1187,7 @@ jobs:
platformio upgrade --dev
platformio update
- name: Run PlatformIO
- run: |
- mv -f platformio_override_sample.ini platformio_override.ini
+ run: |
platformio run -e tasmota32-IT
- uses: actions/upload-artifact@v2
with:
@@ -1230,8 +1210,7 @@ jobs:
platformio upgrade --dev
platformio update
- name: Run PlatformIO
- run: |
- mv -f platformio_override_sample.ini platformio_override.ini
+ run: |
platformio run -e tasmota32-KO
- uses: actions/upload-artifact@v2
with:
@@ -1254,8 +1233,7 @@ jobs:
platformio upgrade --dev
platformio update
- name: Run PlatformIO
- run: |
- mv -f platformio_override_sample.ini platformio_override.ini
+ run: |
platformio run -e tasmota32-NL
- uses: actions/upload-artifact@v2
with:
@@ -1278,8 +1256,7 @@ jobs:
platformio upgrade --dev
platformio update
- name: Run PlatformIO
- run: |
- mv -f platformio_override_sample.ini platformio_override.ini
+ run: |
platformio run -e tasmota32-PL
- uses: actions/upload-artifact@v2
with:
@@ -1302,8 +1279,7 @@ jobs:
platformio upgrade --dev
platformio update
- name: Run PlatformIO
- run: |
- mv -f platformio_override_sample.ini platformio_override.ini
+ run: |
platformio run -e tasmota32-PT
- uses: actions/upload-artifact@v2
with:
@@ -1326,8 +1302,7 @@ jobs:
platformio upgrade --dev
platformio update
- name: Run PlatformIO
- run: |
- mv -f platformio_override_sample.ini platformio_override.ini
+ run: |
platformio run -e tasmota32-RO
- uses: actions/upload-artifact@v2
with:
@@ -1350,8 +1325,7 @@ jobs:
platformio upgrade --dev
platformio update
- name: Run PlatformIO
- run: |
- mv -f platformio_override_sample.ini platformio_override.ini
+ run: |
platformio run -e tasmota32-RU
- uses: actions/upload-artifact@v2
with:
@@ -1374,8 +1348,7 @@ jobs:
platformio upgrade --dev
platformio update
- name: Run PlatformIO
- run: |
- mv -f platformio_override_sample.ini platformio_override.ini
+ run: |
platformio run -e tasmota32-SE
- uses: actions/upload-artifact@v2
with:
@@ -1398,8 +1371,7 @@ jobs:
platformio upgrade --dev
platformio update
- name: Run PlatformIO
- run: |
- mv -f platformio_override_sample.ini platformio_override.ini
+ run: |
platformio run -e tasmota32-SK
- uses: actions/upload-artifact@v2
with:
@@ -1422,8 +1394,7 @@ jobs:
platformio upgrade --dev
platformio update
- name: Run PlatformIO
- run: |
- mv -f platformio_override_sample.ini platformio_override.ini
+ run: |
platformio run -e tasmota32-TR
- uses: actions/upload-artifact@v2
with:
@@ -1446,8 +1417,7 @@ jobs:
platformio upgrade --dev
platformio update
- name: Run PlatformIO
- run: |
- mv -f platformio_override_sample.ini platformio_override.ini
+ run: |
platformio run -e tasmota32-TW
- uses: actions/upload-artifact@v2
with:
@@ -1470,8 +1440,7 @@ jobs:
platformio upgrade --dev
platformio update
- name: Run PlatformIO
- run: |
- mv -f platformio_override_sample.ini platformio_override.ini
+ run: |
platformio run -e tasmota32-UK
- uses: actions/upload-artifact@v2
with:
From 414cf1f9ac38976f15944108a6fc6ba7a73ab234 Mon Sep 17 00:00:00 2001
From: nicandris
Date: Sat, 12 Sep 2020 12:59:51 +0200
Subject: [PATCH 12/23] added support for Aqara button WXKG12LM
---
tasmota/xdrv_23_zigbee_5_converters.ino | 27 ++++++++++++++++++++++++-
1 file changed, 26 insertions(+), 1 deletion(-)
diff --git a/tasmota/xdrv_23_zigbee_5_converters.ino b/tasmota/xdrv_23_zigbee_5_converters.ino
index e70e6702d..5e3140afd 100644
--- a/tasmota/xdrv_23_zigbee_5_converters.ino
+++ b/tasmota/xdrv_23_zigbee_5_converters.ino
@@ -1494,7 +1494,7 @@ void ZCLFrame::syntheticAqaraCubeOrButton(class Z_attribute_list &attr_list, cla
// presentValue = x + 128 = 180º flip to side x on top
// presentValue = x + 256 = push/slide cube while side x is on top
// presentValue = x + 512 = double tap while side x is on top
- } else if (modelId.startsWith(F("lumi.remote"))) { // only for Aqara button
+ } else if (modelId.startsWith(F("lumi.remote"))) { // only for Aqara button WXKG11LM
int32_t val = attr.getInt();
const __FlashStringHelper *aqara_click = F("click");
const __FlashStringHelper *aqara_action = F("action");
@@ -1516,6 +1516,31 @@ void ZCLFrame::syntheticAqaraCubeOrButton(class Z_attribute_list &attr_list, cla
attr_list.addAttribute(aqara_click).setUInt(val);
break;
}
+ } else if (modelId.startsWith(F("lumi.sensor_switch"))) { // only for Aqara button WXKG12LM
+ int32_t val = attr.getInt();
+ const __FlashStringHelper *aqara_click = F("click");
+ const __FlashStringHelper *aqara_action = F("action");
+
+ switch (val) {
+ case 1:
+ attr_list.addAttribute(aqara_click).setStr(PSTR("single"));
+ break;
+ case 2:
+ attr_list.addAttribute(aqara_click).setStr(PSTR("double"));
+ break;
+ case 16:
+ attr_list.addAttribute(aqara_action).setStr(PSTR("hold"));
+ break;
+ case 17:
+ attr_list.addAttribute(aqara_action).setStr(PSTR("release"));
+ break;
+ case 18:
+ attr_list.addAttribute(aqara_action).setStr(PSTR("shake"));
+ break;
+ default:
+ attr_list.addAttribute(aqara_click).setUInt(val);
+ break;
+ }
}
}
From a951a38d393ba2fb70602a4f6f269dfdb2384c4f Mon Sep 17 00:00:00 2001
From: nicandris
Date: Sat, 12 Sep 2020 13:10:35 +0200
Subject: [PATCH 13/23] merged together the 2 aqara buttons
---
tasmota/xdrv_23_zigbee_5_converters.ino | 24 ++++--------------------
1 file changed, 4 insertions(+), 20 deletions(-)
diff --git a/tasmota/xdrv_23_zigbee_5_converters.ino b/tasmota/xdrv_23_zigbee_5_converters.ino
index 5e3140afd..542aa3a41 100644
--- a/tasmota/xdrv_23_zigbee_5_converters.ino
+++ b/tasmota/xdrv_23_zigbee_5_converters.ino
@@ -1494,7 +1494,7 @@ void ZCLFrame::syntheticAqaraCubeOrButton(class Z_attribute_list &attr_list, cla
// presentValue = x + 128 = 180º flip to side x on top
// presentValue = x + 256 = push/slide cube while side x is on top
// presentValue = x + 512 = double tap while side x is on top
- } else if (modelId.startsWith(F("lumi.remote"))) { // only for Aqara button WXKG11LM
+ } else if (modelId.startsWith(F("lumi.remote")) || modelId.startsWith(F("lumi.sensor_switch"))) { // only for Aqara buttons WXKG11LM & WXKG12LM
int32_t val = attr.getInt();
const __FlashStringHelper *aqara_click = F("click");
const __FlashStringHelper *aqara_action = F("action");
@@ -1503,25 +1503,6 @@ void ZCLFrame::syntheticAqaraCubeOrButton(class Z_attribute_list &attr_list, cla
case 0:
attr_list.addAttribute(aqara_action).setStr(PSTR("hold"));
break;
- case 1:
- attr_list.addAttribute(aqara_click).setStr(PSTR("single"));
- break;
- case 2:
- attr_list.addAttribute(aqara_click).setStr(PSTR("double"));
- break;
- case 255:
- attr_list.addAttribute(aqara_click).setStr(PSTR("release"));
- break;
- default:
- attr_list.addAttribute(aqara_click).setUInt(val);
- break;
- }
- } else if (modelId.startsWith(F("lumi.sensor_switch"))) { // only for Aqara button WXKG12LM
- int32_t val = attr.getInt();
- const __FlashStringHelper *aqara_click = F("click");
- const __FlashStringHelper *aqara_action = F("action");
-
- switch (val) {
case 1:
attr_list.addAttribute(aqara_click).setStr(PSTR("single"));
break;
@@ -1537,6 +1518,9 @@ void ZCLFrame::syntheticAqaraCubeOrButton(class Z_attribute_list &attr_list, cla
case 18:
attr_list.addAttribute(aqara_action).setStr(PSTR("shake"));
break;
+ case 255:
+ attr_list.addAttribute(aqara_action).setStr(PSTR("release"));
+ break;
default:
attr_list.addAttribute(aqara_click).setUInt(val);
break;
From c46fa48a30f7c38bd0143f7b500cb203571d1685 Mon Sep 17 00:00:00 2001
From: Staars
Date: Sat, 12 Sep 2020 19:04:11 +0200
Subject: [PATCH 14/23] support MLX90640
---
tasmota/xdrv_84_MLX90640.ino | 625 +++++++++++++++++++++++++++++++++++
1 file changed, 625 insertions(+)
create mode 100644 tasmota/xdrv_84_MLX90640.ino
diff --git a/tasmota/xdrv_84_MLX90640.ino b/tasmota/xdrv_84_MLX90640.ino
new file mode 100644
index 000000000..808b8f9d2
--- /dev/null
+++ b/tasmota/xdrv_84_MLX90640.ino
@@ -0,0 +1,625 @@
+/*
+ xdrv_84_MLX90640.ino - MLX90640 support for Tasmota
+
+ Copyright (C) 2020 Christian Baars and Theo Arends
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+
+ --------------------------------------------------------------------------------------------
+ Version yyyymmdd Action Description
+ --------------------------------------------------------------------------------------------
+ 0.9.0.0 20200827 started - based on https://github.com/melexis/mlx90640-library
+*/
+
+#ifdef USE_I2C
+#ifdef USE_MLX90640
+
+#define MLX90640_ADDRESS 0x33
+#define MLX90640_POI_NUM 6 //some parts of the JS are hardcoded for 6!!
+
+/*********************************************************************************************\
+* MLX90640
+\*********************************************************************************************/
+
+#define XDRV_84 84
+#include
+
+const char MLX90640type[] PROGMEM = "MLX90640";
+
+#ifdef USE_WEBSERVER
+#define WEB_HANDLE_MLX90640 "mlx"
+const char HTTP_BTN_MENU_MLX90640[] PROGMEM = "
";
+#endif // USE_WEBSERVER
+
+struct {
+ uint32_t type:1;
+ uint32_t ready:1;
+ uint32_t dumpedEE:1;
+ uint32_t extractedParams:1;
+ paramsMLX90640 *params;
+ float Ta;
+ uint16_t Frame[834];
+ float To[768];
+ uint8_t pois[2*MLX90640_POI_NUM] = {2,1, 30,1, 10,12, 22,12, 2,23, 30,23}; // {x1,y1,x2,y2,...,x6,y6}
+} MLX90640;
+
+/*********************************************************************************************\
+ * commands
+\*********************************************************************************************/
+
+#define D_CMND_MLX90640 "MLX"
+
+const char S_JSON_MLX90640_COMMAND_NVALUE[] PROGMEM = "{\"" D_CMND_MLX90640 "%s\":%d}";
+const char S_JSON_MLX90640_COMMAND[] PROGMEM = "{\"" D_CMND_MLX90640 "%s\"}";
+const char kMLX90640_Commands[] PROGMEM = "POI";
+
+enum MLX90640_Commands { // commands useable in console or rules
+ CMND_MLX90640_POI // MLXPOIn xxyy - set POI number n to x,y
+ };
+
+/************************************************************************\
+ * Web GUI
+\************************************************************************/
+#ifdef USE_WEBSERVER
+
+#ifdef USE_UNISHOX_COMPRESSION
+const size_t HTTP_MLX90640_1_SNS_SIZE = 389;
+const char HTTP_MLX90640_1_SNS_COMPRESSED[] PROGMEM = "\x3D\x3C\x1F\xF4\x65\x2A\x2B\x32\x18\xCF\x87\xDD\x33\x65\x1D\x86\xBB\x33\xB0\x41"
+ "\xA4\x7D\x9F\x81\xE7\x7A\x90\xDB\x18\x7C\x3B\xA6\x76\x10\xB6\x75\x1B\x0E\x43\xA8"
+ "\x8C\x8E\x43\xA8\x8D\x87\x28\xEA\x23\x23\x94\x77\x8F\x87\xE1\x02\x0D\x13\xAC\xD8"
+ "\x72\x1D\xE3\xD6\x77\x48\xC8\xE5\x1D\x64\x6C\x39\x47\x78\xEC\x3B\xA4\x64\x72\x1D"
+ "\x64\x6C\x39\x0E\xF1\xDB\x23\x61\xCA\x3C\x10\x20\xE3\x3A\x36\xC7\x9A\x3E\x2E\x63"
+ "\xE8\xB4\x6D\x8F\x33\xC1\x9D\xFD\x07\x7C\x67\x7E\x3A\x83\xA3\x61\xD4\x3D\xF1\x0F"
+ "\x06\x77\xF4\x3C\x43\x0D\x87\x50\xCC\xD3\xE1\xEF\x1E\xF9\xE0\xCE\xFE\xBE\x56\x7C"
+ "\x3D\xE3\xDF\x3C\x18\x17\xC1\xD6\xE7\x21\xE7\x44\x37\x05\xF9\x90\xCC\xF1\xDD\x04"
+ "\x2C\x65\x33\x3A\x3B\xC8\xF6\x82\x0E\x87\xF6\x1D\x23\xE0\x21\x66\x87\x41\xE7\x44"
+ "\x3B\x05\xF0\x9B\xC3\xC4\x18\x5A\xFA\x8B\xEC\x3A\x3B\xA7\x78\xF0\x67\x7F\x46\xC4"
+ "\x7C\x4C\xCE\x8E\x81\x85\xAF\xA8\x8D\x87\x5F\xD8\x74\x74\x09\x98\xA3\xC6\x98\x3B"
+ "\xA6\xC3\xF0\xE5\xD3\x3B\xC7\xB4\x8D\x87\xC3\x97\x11\xE0\xF7\x17\xDD\x0B\xFF\x23"
+ "\xDA\x6C\x3C\xD1\x0D\xBA\x14\x74\x30\x16\x67\xCE\xE8\xDB\x18\x77\x4D\x87\x51\xC6"
+ "\x75\x5D\x33\xA9\x9D\x57\x0E\x88\xEF\x1D\xE3\xA8\x8C\x81\x32\xF9\xDD\x04\x5D\x04"
+ "\x8C\x91\xD6\xBE\xC3\xA3\xA5\x60\xC3\xBC\x75\x1C\x67\x55\x63\x3A\x99\xD5\x56\x74"
+ "\x47\x78\xEF\x1E\xE3\xC1\xEE";
+#define HTTP_MLX90640_1_SNS Decompress(HTTP_MLX90640_1_SNS_COMPRESSED,HTTP_MLX90640_1_SNS_SIZE).c_str()
+#else
+const char HTTP_MLX90640_1_SNS[] PROGMEM =
+ ""
+;
+#endif //USE_UNISHOX_COMPRESSION
+#ifdef USE_UNISHOX_COMPRESSION
+const size_t HTTP_MLX90640_4b_SNS_SIZE = 418;
+const char HTTP_MLX90640_4b_SNS_COMPRESSED[] PROGMEM = "\x3D\x07\x60\x86\x4B\x38\x2C\xB1\x0F\x87\xDF\x9D\x0B\x18\x77\x4E\xF1\xE0\xFB\x3F"
+ "\x0F\x40\xEF\x8C\xEF\xCB\x44\x3E\x1F\x63\x42\x36\x1F\x68\x7F\x44\xA1\x47\xC3\xEC"
+ "\xE5\xE3\x3E\xCE\xE1\x0A\x7A\x3C\x2A\x2B\x8F\x87\xD9\xCA\xC6\x7D\x9F\x87\xA1\xD8"
+ "\x40\x83\x83\x9F\x87\xA0\x9A\x66\x7E\x1E\x87\x60\x9A\x66\x7E\x1E\x9E\x61\x30\xE9"
+ "\x68\x87\xC3\xEC\x66\x69\x04\x7D\xAC\xE0\xC5\x5F\x0F\x33\xE1\xF6\x37\x3C\x77\x4E"
+ "\xF1\xF6\x7E\x1E\x98\x32\xB7\x39\x19\xD8\x42\xD9\xF0\xFB\x38\xCF\xB3\xF0\x88\x61"
+ "\x61\x69\xD6\x72\x1E\x87\x61\x02\x0D\x40\x4B\xB8\x72\x10\x20\xDC\x39\x44\x0A\x77"
+ "\x0E\x51\x02\x0D\xC3\x96\x40\xA7\x70\xE5\x90\x20\xDC\x39\x84\x0A\x77\x0E\x61\x02"
+ "\x0D\xC3\x9A\x40\xA7\x70\xE6\x90\x20\xDC\x39\xC4\x08\xB7\x0E\xC0\x41\xE1\x2A\x01"
+ "\xFC\x3D\x04\xD3\x30\x41\xE2\x0C\xE4\x3E\xC8\x10\xF8\x5B\x13\x4C\xCF\xC2\x18\x58"
+ "\x5A\x75\x9C\x67\x99\xDC\x3D\x0B\xC3\x2F\x96\x88\x7C\x3E\xEC\xE4\x3E\xCF\xC3\xD0"
+ "\xEC\x2F\x0C\xBE\x3F\x26\x3B\x32\xF2\x0D\x1D\xDF\x3E\xF6\x7C\xEF\x02\x2E\x1E\x08"
+ "\x39\x11\xCA\x20\x44\xC8\x8E\xC1\xD8\x21\x91\xF8";
+#define HTTP_MLX90640_4b_SNS Decompress(HTTP_MLX90640_4b_SNS_COMPRESSED,HTTP_MLX90640_4b_SNS_SIZE).c_str()
+#else
+const char HTTP_MLX90640_4b_SNS[] PROGMEM =
+ ""
+ ""
+ ""
+ ""
+ ""
+ "POI-0: °C (sensor)
"
+ ""
+ ""
+ ;
+#endif //USE_UNISHOX_COMPRESSION
+void MLX90640UpdateGUI(void){
+ WSContentStart_P("mlx");
+ WSContentSendStyle();
+ WSContentSend_P(HTTP_MLX90640_1_SNS);
+ WSContentSend_P(HTTP_MLX90640_2a_SNS);
+ WSContentSend_P(HTTP_MLX90640_2b_SNS);
+ WSContentSend_P(HTTP_MLX90640_3a_SNS);
+ WSContentSend_P(HTTP_MLX90640_3b_SNS);
+ WSContentSend_P(HTTP_MLX90640_4a_SNS);
+ WSContentSend_P(HTTP_MLX90640_4b_SNS);
+ WSContentSpaceButton(BUTTON_MAIN);
+ WSContentStop();
+}
+
+void MLX90640HandleWebGuiResponse(void){
+ char tmp[(MLX90640_POI_NUM*2)+4];
+ WebGetArg("ul", tmp, sizeof(tmp)); // update line
+ if (strlen(tmp)) {
+ uint8_t _line = atoi(tmp);
+ // AddLog_P2(LOG_LEVEL_DEBUG, "MLX90640: send line %u", _line);
+ float _buf[65];
+ if(_line==0){_buf[0]=1000+MLX90640.Ta;} //ambient temperature modulation hack
+ else{_buf[0]=(float)_line;}
+ memcpy((char*)&_buf[1],(char*)&MLX90640.To[_line*64],64*4);
+ Webserver->send(200,PSTR("application/octet-stream"),(const char*)&_buf,65*4);
+ return;
+ }
+ WebGetArg("up", tmp, sizeof(tmp)); // update POI to browser
+ if (strlen(tmp)==1) {
+ Webserver->send(200,PSTR("application/octet-stream"),(const char*)&MLX90640.pois,MLX90640_POI_NUM*2);
+ return;
+ }
+ else if (strlen(tmp)>2) { // receive updated POI from browser
+ uint32_t _poi = atoi(tmp);
+ uint32_t _poiNum = (_poi-(_poi%10000))/10000;
+ MLX90640.pois[_poiNum*2] = (_poi%10000)/100;
+ MLX90640.pois[(_poiNum*2)+1] = _poi%100;
+ // AddLog_P2(LOG_LEVEL_DEBUG, PSTR("RAW: %u, POI-%u: x: %u, y: %u"),_poi,_poiNum,MLX90640.pois[_poiNum],MLX90640.pois[_poiNum+1]);
+ for(int i = 0;i(MLX90640_POI_NUM-1)&&XdrvMailbox.index<1) return false;
+ _idx = (XdrvMailbox.index-1)*2;
+ if (XdrvMailbox.data_len > 0) {
+ uint32_t _coord = TextToInt(XdrvMailbox.data);
+ MLX90640.pois[_idx] = (_coord%10000)/100;
+ if(MLX90640.pois[_idx]>31) MLX90640.pois[_idx]=31;
+ MLX90640.pois[_idx+1] = _coord%100;
+ if(MLX90640.pois[_idx+1]>23) MLX90640.pois[_idx+1]=23;
+ }
+ AddLog_P2(LOG_LEVEL_INFO, PSTR("POI-%u = x:%u,y:%u"),XdrvMailbox.index,MLX90640.pois[_idx],MLX90640.pois[_idx+1]);
+ Response_P(S_JSON_MLX90640_COMMAND_NVALUE, command, XdrvMailbox.payload);
+ break;
+ default:
+ // else for Unknown command
+ serviced = false;
+ break;
+ }
+ } else {
+ return false;
+ }
+ return serviced;
+}
+
+/************************************************************************\
+ * Init
+\************************************************************************/
+void MLX90640init()
+{
+ if (MLX90640.type || !I2cSetDevice(MLX90640_ADDRESS)) { return; }
+
+ Wire.setClock(400000);
+ int status = -1;
+ if(!MLX90640.dumpedEE){
+ status = MLX90640_DumpEE(MLX90640_ADDRESS, MLX90640.Frame);
+ if (status != 0){
+ AddLog_P2(LOG_LEVEL_INFO, PSTR("Failed to load system parameters"));
+ }
+ else {
+ AddLog_P2(LOG_LEVEL_INFO, PSTR("MLX90640: started"));
+ MLX90640.type = true;
+ }
+ MLX90640.params = new paramsMLX90640;
+ }
+}
+
+/************************************************************************\
+ * Run loop
+\************************************************************************/
+void MLX90640every100msec(){
+ static uint32_t _job = 0;
+ int status;
+ uint32_t _time;
+
+ if(!MLX90640.extractedParams){
+ static uint32_t _chunk = 0;
+ AddLog_P2(LOG_LEVEL_DEBUG, PSTR("MLX90640: will read chunk: %u"), _chunk);
+ _time = millis();
+ status = MLX90640_ExtractParameters(MLX90640.Frame, MLX90640.params, _chunk);
+ if (status == 0){
+ AddLog_P2(LOG_LEVEL_DEBUG, PSTR("MLX90640: parameter received after: %u msec, status: %u"), TimePassedSince(_time), status);
+ }
+ if (_chunk == 5) MLX90640.extractedParams = true;
+ _chunk++;
+ return;
+ }
+
+ switch(_job){
+ case 0:
+ if(MLX90640_SynchFrame(MLX90640_ADDRESS)!=0){
+ _job=-1;
+ AddLog_P2(LOG_LEVEL_DEBUG, PSTR("MLX90640: frame not ready"));
+ break;
+ }
+ // _time = millis();
+ status = MLX90640_GetFrameData(MLX90640_ADDRESS, MLX90640.Frame);
+ // AddLog_P2(LOG_LEVEL_DEBUG, PSTR("MLX90640: got frame 0 in %u msecs, status: %i"), TimePassedSince(_time), status);
+ break;
+ case 1:
+ MLX90640.Ta = MLX90640_GetTa(MLX90640.Frame, MLX90640.params);
+ break;
+ case 2:
+ // _time = millis();
+ MLX90640_CalculateTo(MLX90640.Frame, MLX90640.params, 0.95f, MLX90640.Ta - 8, MLX90640.To, 0);
+ // AddLog_P2(LOG_LEVEL_DEBUG, PSTR("MLX90640: calculated temperatures in %u msecs"), TimePassedSince(_time));
+ break;
+ case 5:
+ if(MLX90640_SynchFrame(MLX90640_ADDRESS)!=0){
+ _job=4;
+ break;
+ }
+ // _time = millis();
+ status = MLX90640_GetFrameData(MLX90640_ADDRESS, MLX90640.Frame);
+ // // AddLog_P2(LOG_LEVEL_DEBUG, PSTR("MLX90640: got frame 1 in %u msecs, status: %i"), TimePassedSince(_time), status);
+ break;
+ case 7:
+ // _time = millis();
+ MLX90640_CalculateTo(MLX90640.Frame, MLX90640.params, 0.95f, MLX90640.Ta - 8, MLX90640.To, 1);
+ // AddLog_P2(LOG_LEVEL_DEBUG, PSTR("MLX90640: calculated temperatures in %u msecs"), TimePassedSince(_time));
+ break;
+ default:
+ break;
+ }
+ _job++;
+ if(_job>10) _job=0;
+}
+
+
+/*********************************************************************************************\
+ * Interface
+\*********************************************************************************************/
+
+void MLX90640Show(uint8_t json)
+{
+ char amb_tstr[FLOATSZ];
+ dtostrfd(MLX90640.Ta, Settings.flag2.temperature_resolution, amb_tstr);
+ if (json) {
+ ResponseAppend_P(PSTR(",\"MLX90640\":{\"" D_JSON_TEMPERATURE "\":[%s"), amb_tstr);
+ for(int i = 0;ion("/mlx", MLX90640HandleWebGui);
+ break;
+#endif // USE_WEBSERVER
+ case FUNC_COMMAND:
+ result = MLX90640Cmd();
+ break;
+ }
+ }
+ return result;
+}
+
+#endif // USE_MLX90640_SENSOR
+#endif // USE_I2C
From 3300196436cc97be1c18c7d27088735165e63cf7 Mon Sep 17 00:00:00 2001
From: Staars
Date: Sat, 12 Sep 2020 19:05:19 +0200
Subject: [PATCH 15/23] add modified mlx90640-lib
---
lib/mlx90640-library/MLX90640_API.cpp | 1640 +++++++++++++++++++++++++
lib/mlx90640-library/MLX90640_API.h | 74 ++
2 files changed, 1714 insertions(+)
create mode 100644 lib/mlx90640-library/MLX90640_API.cpp
create mode 100644 lib/mlx90640-library/MLX90640_API.h
diff --git a/lib/mlx90640-library/MLX90640_API.cpp b/lib/mlx90640-library/MLX90640_API.cpp
new file mode 100644
index 000000000..87d871530
--- /dev/null
+++ b/lib/mlx90640-library/MLX90640_API.cpp
@@ -0,0 +1,1640 @@
+/**
+ * @copyright (C) 2017 Melexis N.V.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include
+#include
+#include
+
+void ExtractVDDParameters(uint16_t *eeData, paramsMLX90640 *mlx90640);
+void ExtractPTATParameters(uint16_t *eeData, paramsMLX90640 *mlx90640);
+void ExtractGainParameters(uint16_t *eeData, paramsMLX90640 *mlx90640);
+void ExtractTgcParameters(uint16_t *eeData, paramsMLX90640 *mlx90640);
+void ExtractResolutionParameters(uint16_t *eeData, paramsMLX90640 *mlx90640);
+void ExtractKsTaParameters(uint16_t *eeData, paramsMLX90640 *mlx90640);
+void ExtractKsToParameters(uint16_t *eeData, paramsMLX90640 *mlx90640);
+void ExtractAlphaParameters(uint16_t *eeData, paramsMLX90640 *mlx90640);
+void ExtractOffsetParameters(uint16_t *eeData, paramsMLX90640 *mlx90640);
+void ExtractKtaPixelParameters(uint16_t *eeData, paramsMLX90640 *mlx90640);
+void ExtractKvPixelParameters(uint16_t *eeData, paramsMLX90640 *mlx90640);
+void ExtractCPParameters(uint16_t *eeData, paramsMLX90640 *mlx90640);
+void ExtractCILCParameters(uint16_t *eeData, paramsMLX90640 *mlx90640);
+int ExtractDeviatingPixels(uint16_t *eeData, paramsMLX90640 *mlx90640);
+int CheckAdjacentPixels(uint16_t pix1, uint16_t pix2);
+float GetMedian(float *values, int n);
+int IsPixelBad(uint16_t pixel,paramsMLX90640 *params);
+int ValidateFrameData(uint16_t *frameData);
+int ValidateAuxData(uint16_t *auxData);
+int MLX90640_I2CRead(uint8_t addr, uint32_t reg, uint16_t len, uint16_t *reg_data);
+int MLX90640_I2CWrite(uint8_t _deviceAddress, unsigned int writeAddress, uint16_t data);
+
+// I2C
+#define I2C_BUFFER_LENGTH 128
+
+int MLX90640_I2CRead(uint8_t addr, uint32_t reg, uint16_t len, uint16_t *reg_data){
+ int bytesRemaining = len * 2;
+ int dataSpot = 0; //Start at beginning of array
+ while (bytesRemaining > 0)
+ {
+ Wire.beginTransmission(addr);
+ Wire.write(reg >> 8); //MSB
+ Wire.write(reg & 0xFF); //LSB
+ if (Wire.endTransmission(false) != 0) //Do not release bus
+ {
+ return (0); //Sensor did not ACK
+ }
+ int numberOfBytesToRead = bytesRemaining;
+ if (numberOfBytesToRead > I2C_BUFFER_LENGTH) numberOfBytesToRead = I2C_BUFFER_LENGTH;
+ Wire.requestFrom((int)addr, numberOfBytesToRead);
+ if (Wire.available())
+ {
+ for (uint32_t x = 0 ; x < numberOfBytesToRead / 2; x++)
+ {
+ reg_data[dataSpot] = Wire.read() << 8; //MSB
+ reg_data[dataSpot] |= Wire.read(); //LSB
+ dataSpot++;
+ }
+ }
+ bytesRemaining -= numberOfBytesToRead;
+ reg += numberOfBytesToRead / 2;
+ }
+ return (0); //Success
+}
+
+int MLX90640_I2CWrite(uint8_t _deviceAddress, unsigned int writeAddress, uint16_t data)
+{
+ Wire.beginTransmission((uint8_t)_deviceAddress);
+ Wire.write(writeAddress >> 8); //MSB
+ Wire.write(writeAddress & 0xFF); //LSB
+ Wire.write(data >> 8); //MSB
+ Wire.write(data & 0xFF); //LSB
+ if (Wire.endTransmission() != 0)
+ {
+ //Sensor did not ACK
+ return (-1);
+ }
+ uint16_t dataCheck;
+ MLX90640_I2CRead(_deviceAddress, writeAddress, 1, &dataCheck);
+ if (dataCheck != data)
+ {
+ return -2;
+ }
+ return (0); //Success
+}
+
+int MLX90640_DumpEE(uint8_t slaveAddr, uint16_t *eeData)
+{
+ return MLX90640_I2CRead(slaveAddr, 0x2400, 832, eeData);
+}
+
+int MLX90640_SynchFrame(uint8_t slaveAddr)
+{
+ uint16_t dataReady = 0;
+ uint16_t statusRegister;
+ int error = 1;
+
+ error = MLX90640_I2CWrite(slaveAddr, 0x8000, 0x0030);
+ if(error == -1)
+ {
+ return error;
+ }
+
+ while(dataReady == 0)
+ {
+ error = MLX90640_I2CRead(slaveAddr, 0x8000, 1, &statusRegister);
+ if(error != 0)
+ {
+ return error;
+ }
+ dataReady = statusRegister & 0x0008;
+ }
+
+ return 0;
+}
+
+// int MLX90640_TriggerMeasurement(uint8_t slaveAddr) // ATM not used in Tasmota
+// {
+// int error = 1;
+// uint16_t ctrlReg;
+
+// error = MLX90640_I2CRead(slaveAddr, 0x800D, 1, &ctrlReg);
+
+// if ( error != 0)
+// {
+// return error;
+// }
+
+// ctrlReg |= 0x8000;
+// error = MLX90640_I2CWrite(slaveAddr, 0x800D, ctrlReg);
+
+// if ( error != 0)
+// {
+// return error;
+// }
+
+// // error = MLX90640_I2CGeneralReset();
+
+// // if ( error != 0)
+// // {
+// // return error;
+// // }
+
+// error = MLX90640_I2CRead(slaveAddr, 0x800D, 1, &ctrlReg);
+
+// if ( error != 0)
+// {
+// return error;
+// }
+
+// if ((ctrlReg & 0x8000) != 0)
+// {
+// return -9;
+// }
+
+// return 0;
+// }
+
+int MLX90640_GetFrameData(uint8_t slaveAddr, uint16_t *frameData)
+{
+ uint16_t dataReady = 0;
+ uint16_t controlRegister1;
+ uint16_t statusRegister;
+ int error = 1;
+ uint16_t data[64];
+ uint8_t cnt = 0;
+
+ while(dataReady == 0)
+ {
+ error = MLX90640_I2CRead(slaveAddr, 0x8000, 1, &statusRegister);
+ if(error != 0)
+ {
+ return error;
+ }
+ dataReady = statusRegister & 0x0008;
+ }
+
+ error = MLX90640_I2CWrite(slaveAddr, 0x8000, 0x0030);
+ if(error == -1)
+ {
+ return error;
+ }
+
+ error = MLX90640_I2CRead(slaveAddr, 0x0400, 768, frameData);
+ if(error != 0)
+ {
+ return error;
+ }
+
+ error = MLX90640_I2CRead(slaveAddr, 0x0700, 64, data);
+ if(error != 0)
+ {
+ return error;
+ }
+
+ error = MLX90640_I2CRead(slaveAddr, 0x800D, 1, &controlRegister1);
+ frameData[832] = controlRegister1;
+ frameData[833] = statusRegister & 0x0001;
+
+ if(error != 0)
+ {
+ return error;
+ }
+
+ error = ValidateAuxData(data);
+ if(error == 0)
+ {
+ for(cnt=0; cnt<64; cnt++)
+ {
+ frameData[cnt+768] = data[cnt];
+ }
+ }
+
+ error = ValidateFrameData(frameData);
+ if (error != 0)
+ {
+ return error;
+ }
+
+ return frameData[833];
+}
+
+int ValidateFrameData(uint16_t *frameData)
+{
+ uint8_t line = 0;
+
+ for(int i=0; i<768; i+=32)
+ {
+ if((frameData[i] == 0x7FFF) && (line%2 == frameData[833])) return -8;
+ line = line + 1;
+ }
+
+ return 0;
+}
+
+int ValidateAuxData(uint16_t *auxData)
+{
+
+ if(auxData[0] == 0x7FFF) return -8;
+
+ for(int i=8; i<19; i++)
+ {
+ if(auxData[i] == 0x7FFF) return -8;
+ }
+
+ for(int i=20; i<23; i++)
+ {
+ if(auxData[i] == 0x7FFF) return -8;
+ }
+
+ for(int i=24; i<33; i++)
+ {
+ if(auxData[i] == 0x7FFF) return -8;
+ }
+
+ for(int i=40; i<51; i++)
+ {
+ if(auxData[i] == 0x7FFF) return -8;
+ }
+
+ for(int i=52; i<55; i++)
+ {
+ if(auxData[i] == 0x7FFF) return -8;
+ }
+
+ for(int i=56; i<64; i++)
+ {
+ if(auxData[i] == 0x7FFF) return -8;
+ }
+
+ return 0;
+
+}
+
+int MLX90640_ExtractParameters(uint16_t *eeData, paramsMLX90640 *mlx90640, int _chunk) // Tasmota
+{
+ int error = 0;
+ switch(_chunk){
+ case 0:
+ ExtractVDDParameters(eeData, mlx90640);
+ ExtractPTATParameters(eeData, mlx90640);
+ ExtractGainParameters(eeData, mlx90640);
+ ExtractTgcParameters(eeData, mlx90640);
+ ExtractResolutionParameters(eeData, mlx90640);
+ ExtractKsTaParameters(eeData, mlx90640);
+ ExtractKsToParameters(eeData, mlx90640);
+ break;
+ case 1:
+ ExtractCPParameters(eeData, mlx90640);
+ ExtractAlphaParameters(eeData, mlx90640);
+ break;
+ case 2:
+ ExtractOffsetParameters(eeData, mlx90640);
+ break;
+ case 3:
+ ExtractKtaPixelParameters(eeData, mlx90640);
+ break;
+ case 4:
+ ExtractKvPixelParameters(eeData, mlx90640);
+ break;
+ case 5:
+ ExtractCILCParameters(eeData, mlx90640);
+ error = ExtractDeviatingPixels(eeData, mlx90640);
+ break;
+ }
+ return error;
+}
+
+//------------------------------------------------------------------------------
+
+int MLX90640_SetResolution(uint8_t slaveAddr, uint8_t resolution)
+{
+ uint16_t controlRegister1;
+ int value;
+ int error;
+
+ value = (resolution & 0x03) << 10;
+
+ error = MLX90640_I2CRead(slaveAddr, 0x800D, 1, &controlRegister1);
+
+ if(error == 0)
+ {
+ value = (controlRegister1 & 0xF3FF) | value;
+ error = MLX90640_I2CWrite(slaveAddr, 0x800D, value);
+ }
+
+ return error;
+}
+
+//------------------------------------------------------------------------------
+
+int MLX90640_GetCurResolution(uint8_t slaveAddr)
+{
+ uint16_t controlRegister1;
+ int resolutionRAM;
+ int error;
+
+ error = MLX90640_I2CRead(slaveAddr, 0x800D, 1, &controlRegister1);
+ if(error != 0)
+ {
+ return error;
+ }
+ resolutionRAM = (controlRegister1 & 0x0C00) >> 10;
+
+ return resolutionRAM;
+}
+
+//------------------------------------------------------------------------------
+
+int MLX90640_SetRefreshRate(uint8_t slaveAddr, uint8_t refreshRate)
+{
+ uint16_t controlRegister1;
+ int value;
+ int error;
+
+ value = (refreshRate & 0x07)<<7;
+
+ error = MLX90640_I2CRead(slaveAddr, 0x800D, 1, &controlRegister1);
+ if(error == 0)
+ {
+ value = (controlRegister1 & 0xFC7F) | value;
+ error = MLX90640_I2CWrite(slaveAddr, 0x800D, value);
+ }
+
+ return error;
+}
+
+//------------------------------------------------------------------------------
+
+int MLX90640_GetRefreshRate(uint8_t slaveAddr)
+{
+ uint16_t controlRegister1;
+ int refreshRate;
+ int error;
+
+ error = MLX90640_I2CRead(slaveAddr, 0x800D, 1, &controlRegister1);
+ if(error != 0)
+ {
+ return error;
+ }
+ refreshRate = (controlRegister1 & 0x0380) >> 7;
+
+ return refreshRate;
+}
+
+//------------------------------------------------------------------------------
+
+int MLX90640_SetInterleavedMode(uint8_t slaveAddr)
+{
+ uint16_t controlRegister1;
+ int value;
+ int error;
+
+ error = MLX90640_I2CRead(slaveAddr, 0x800D, 1, &controlRegister1);
+
+ if(error == 0)
+ {
+ value = (controlRegister1 & 0xEFFF);
+ error = MLX90640_I2CWrite(slaveAddr, 0x800D, value);
+ }
+
+ return error;
+}
+
+//------------------------------------------------------------------------------
+
+int MLX90640_SetChessMode(uint8_t slaveAddr)
+{
+ uint16_t controlRegister1;
+ int value;
+ int error;
+
+ error = MLX90640_I2CRead(slaveAddr, 0x800D, 1, &controlRegister1);
+
+ if(error == 0)
+ {
+ value = (controlRegister1 | 0x1000);
+ error = MLX90640_I2CWrite(slaveAddr, 0x800D, value);
+ }
+
+ return error;
+}
+
+//------------------------------------------------------------------------------
+
+int MLX90640_GetCurMode(uint8_t slaveAddr)
+{
+ uint16_t controlRegister1;
+ int modeRAM;
+ int error;
+
+ error = MLX90640_I2CRead(slaveAddr, 0x800D, 1, &controlRegister1);
+ if(error != 0)
+ {
+ return error;
+ }
+ modeRAM = (controlRegister1 & 0x1000) >> 12;
+
+ return modeRAM;
+}
+
+//------------------------------------------------------------------------------
+void MLX90640_CalculateTo(uint16_t *frameData, const paramsMLX90640 *params, float emissivity, float tr, float *result, uint8_t _part)
+{
+ float vdd;
+ float ta;
+ float ta4;
+ float tr4;
+ float taTr;
+ float gain;
+ float irDataCP[2];
+ float irData;
+ float alphaCompensated;
+ uint8_t mode;
+ int8_t ilPattern;
+ int8_t chessPattern;
+ int8_t pattern;
+ int8_t conversionPattern;
+ float Sx;
+ float To;
+ float alphaCorrR[4];
+ int8_t range;
+ uint16_t subPage;
+ float ktaScale;
+ float kvScale;
+ float alphaScale;
+ float kta;
+ float kv;
+
+ subPage = frameData[833];
+ vdd = MLX90640_GetVdd(frameData, params);
+ ta = MLX90640_GetTa(frameData, params);
+
+ ta4 = (ta + 273.15);
+ ta4 = ta4 * ta4;
+ ta4 = ta4 * ta4;
+ tr4 = (tr + 273.15);
+ tr4 = tr4 * tr4;
+ tr4 = tr4 * tr4;
+ taTr = tr4 - (tr4-ta4)/emissivity;
+
+ ktaScale = pow(2,(double)params->ktaScale);
+ kvScale = pow(2,(double)params->kvScale);
+ alphaScale = pow(2,(double)params->alphaScale);
+
+ alphaCorrR[0] = 1 / (1 + params->ksTo[0] * 40);
+ alphaCorrR[1] = 1 ;
+ alphaCorrR[2] = (1 + params->ksTo[1] * params->ct[2]);
+ alphaCorrR[3] = alphaCorrR[2] * (1 + params->ksTo[2] * (params->ct[3] - params->ct[2]));
+
+//------------------------- Gain calculation -----------------------------------
+ gain = frameData[778];
+ if(gain > 32767)
+ {
+ gain = gain - 65536;
+ }
+
+ gain = params->gainEE / gain;
+
+//------------------------- To calculation -------------------------------------
+ mode = (frameData[832] & 0x1000) >> 5;
+
+ irDataCP[0] = frameData[776];
+ irDataCP[1] = frameData[808];
+ for( int i = 0; i < 2; i++)
+ {
+ if(irDataCP[i] > 32767)
+ {
+ irDataCP[i] = irDataCP[i] - 65536;
+ }
+ irDataCP[i] = irDataCP[i] * gain;
+ }
+ irDataCP[0] = irDataCP[0] - params->cpOffset[0] * (1 + params->cpKta * (ta - 25)) * (1 + params->cpKv * (vdd - 3.3));
+ if( mode == params->calibrationModeEE)
+ {
+ irDataCP[1] = irDataCP[1] - params->cpOffset[1] * (1 + params->cpKta * (ta - 25)) * (1 + params->cpKv * (vdd - 3.3));
+ }
+ else
+ {
+ irDataCP[1] = irDataCP[1] - (params->cpOffset[1] + params->ilChessC[0]) * (1 + params->cpKta * (ta - 25)) * (1 + params->cpKv * (vdd - 3.3));
+ }
+
+ uint32_t _offset = _part*(768/2);
+ for( int pixelNumber = _offset; pixelNumber < (_offset+(768/2)); pixelNumber++)
+ {
+ ilPattern = pixelNumber / 32 - (pixelNumber / 64) * 2;
+ chessPattern = ilPattern ^ (pixelNumber - (pixelNumber/2)*2);
+ conversionPattern = ((pixelNumber + 2) / 4 - (pixelNumber + 3) / 4 + (pixelNumber + 1) / 4 - pixelNumber / 4) * (1 - 2 * ilPattern);
+
+ if(mode == 0)
+ {
+ pattern = ilPattern;
+ }
+ else
+ {
+ pattern = chessPattern;
+ }
+
+ if(pattern == frameData[833])
+ {
+ irData = frameData[pixelNumber];
+ if(irData > 32767)
+ {
+ irData = irData - 65536;
+ }
+ irData = irData * gain;
+
+ kta = params->kta[pixelNumber]/ktaScale;
+ kv = params->kv[pixelNumber]/kvScale;
+ irData = irData - params->offset[pixelNumber]*(1 + kta*(ta - 25))*(1 + kv*(vdd - 3.3));
+
+ if(mode != params->calibrationModeEE)
+ {
+ irData = irData + params->ilChessC[2] * (2 * ilPattern - 1) - params->ilChessC[1] * conversionPattern;
+ }
+
+ irData = irData - params->tgc * irDataCP[subPage];
+ irData = irData / emissivity;
+
+ alphaCompensated = SCALEALPHA*alphaScale/params->alpha[pixelNumber];
+ alphaCompensated = alphaCompensated*(1 + params->KsTa * (ta - 25));
+
+ Sx = alphaCompensated * alphaCompensated * alphaCompensated * (irData + alphaCompensated * taTr);
+ Sx = sqrt(sqrt(Sx)) * params->ksTo[1];
+
+ To = sqrt(sqrt(irData/(alphaCompensated * (1 - params->ksTo[1] * 273.15) + Sx) + taTr)) - 273.15;
+
+ if(To < params->ct[1])
+ {
+ range = 0;
+ }
+ else if(To < params->ct[2])
+ {
+ range = 1;
+ }
+ else if(To < params->ct[3])
+ {
+ range = 2;
+ }
+ else
+ {
+ range = 3;
+ }
+
+ To = sqrt(sqrt(irData / (alphaCompensated * alphaCorrR[range] * (1 + params->ksTo[range] * (To - params->ct[range]))) + taTr)) - 273.15;
+
+ result[pixelNumber] = To;
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+
+// void MLX90640_GetImage(uint16_t *frameData, const paramsMLX90640 *params, float *result)
+// {
+// float vdd;
+// float ta;
+// float gain;
+// float irDataCP[2];
+// float irData;
+// float alphaCompensated;
+// uint8_t mode;
+// int8_t ilPattern;
+// int8_t chessPattern;
+// int8_t pattern;
+// int8_t conversionPattern;
+// float image;
+// uint16_t subPage;
+// float ktaScale;
+// float kvScale;
+// float kta;
+// float kv;
+
+// subPage = frameData[833];
+// vdd = MLX90640_GetVdd(frameData, params);
+// ta = MLX90640_GetTa(frameData, params);
+
+// ktaScale = pow(2,(double)params->ktaScale);
+// kvScale = pow(2,(double)params->kvScale);
+
+// //------------------------- Gain calculation -----------------------------------
+// gain = frameData[778];
+// if(gain > 32767)
+// {
+// gain = gain - 65536;
+// }
+
+// gain = params->gainEE / gain;
+
+// //------------------------- Image calculation -------------------------------------
+// mode = (frameData[832] & 0x1000) >> 5;
+
+// irDataCP[0] = frameData[776];
+// irDataCP[1] = frameData[808];
+// for( int i = 0; i < 2; i++)
+// {
+// if(irDataCP[i] > 32767)
+// {
+// irDataCP[i] = irDataCP[i] - 65536;
+// }
+// irDataCP[i] = irDataCP[i] * gain;
+// }
+// irDataCP[0] = irDataCP[0] - params->cpOffset[0] * (1 + params->cpKta * (ta - 25)) * (1 + params->cpKv * (vdd - 3.3));
+// if( mode == params->calibrationModeEE)
+// {
+// irDataCP[1] = irDataCP[1] - params->cpOffset[1] * (1 + params->cpKta * (ta - 25)) * (1 + params->cpKv * (vdd - 3.3));
+// }
+// else
+// {
+// irDataCP[1] = irDataCP[1] - (params->cpOffset[1] + params->ilChessC[0]) * (1 + params->cpKta * (ta - 25)) * (1 + params->cpKv * (vdd - 3.3));
+// }
+
+// for( int pixelNumber = 0; pixelNumber < 768; pixelNumber++)
+// {
+// ilPattern = pixelNumber / 32 - (pixelNumber / 64) * 2;
+// chessPattern = ilPattern ^ (pixelNumber - (pixelNumber/2)*2);
+// conversionPattern = ((pixelNumber + 2) / 4 - (pixelNumber + 3) / 4 + (pixelNumber + 1) / 4 - pixelNumber / 4) * (1 - 2 * ilPattern);
+
+// if(mode == 0)
+// {
+// pattern = ilPattern;
+// }
+// else
+// {
+// pattern = chessPattern;
+// }
+
+// if(pattern == frameData[833])
+// {
+// irData = frameData[pixelNumber];
+// if(irData > 32767)
+// {
+// irData = irData - 65536;
+// }
+// irData = irData * gain;
+
+// kta = params->kta[pixelNumber]/ktaScale;
+// kv = params->kv[pixelNumber]/kvScale;
+// irData = irData - params->offset[pixelNumber]*(1 + kta*(ta - 25))*(1 + kv*(vdd - 3.3));
+
+// if(mode != params->calibrationModeEE)
+// {
+// irData = irData + params->ilChessC[2] * (2 * ilPattern - 1) - params->ilChessC[1] * conversionPattern;
+// }
+
+// irData = irData - params->tgc * irDataCP[subPage];
+
+// alphaCompensated = params->alpha[pixelNumber];
+
+// image = irData*alphaCompensated;
+
+// result[pixelNumber] = image;
+// }
+// }
+// }
+
+//------------------------------------------------------------------------------
+
+float MLX90640_GetVdd(uint16_t *frameData, const paramsMLX90640 *params)
+{
+ float vdd;
+ float resolutionCorrection;
+
+ int resolutionRAM;
+
+ vdd = frameData[810];
+ if(vdd > 32767)
+ {
+ vdd = vdd - 65536;
+ }
+ resolutionRAM = (frameData[832] & 0x0C00) >> 10;
+ resolutionCorrection = pow(2, (double)params->resolutionEE) / pow(2, (double)resolutionRAM);
+ vdd = (resolutionCorrection * vdd - params->vdd25) / params->kVdd + 3.3;
+
+ return vdd;
+}
+
+//------------------------------------------------------------------------------
+
+float MLX90640_GetTa(uint16_t *frameData, const paramsMLX90640 *params)
+{
+ float ptat;
+ float ptatArt;
+ float vdd;
+ float ta;
+
+ vdd = MLX90640_GetVdd(frameData, params);
+
+ ptat = frameData[800];
+ if(ptat > 32767)
+ {
+ ptat = ptat - 65536;
+ }
+
+ ptatArt = frameData[768];
+ if(ptatArt > 32767)
+ {
+ ptatArt = ptatArt - 65536;
+ }
+ ptatArt = (ptat / (ptat * params->alphaPTAT + ptatArt)) * pow(2, (double)18);
+
+ ta = (ptatArt / (1 + params->KvPTAT * (vdd - 3.3)) - params->vPTAT25);
+ ta = ta / params->KtPTAT + 25;
+
+ return ta;
+}
+
+//------------------------------------------------------------------------------
+
+int MLX90640_GetSubPageNumber(uint16_t *frameData)
+{
+ return frameData[833];
+
+}
+
+//------------------------------------------------------------------------------
+void MLX90640_BadPixelsCorrection(uint16_t *pixels, float *to, int mode, paramsMLX90640 *params)
+{
+ float ap[4];
+ uint8_t pix;
+ uint8_t line;
+ uint8_t column;
+
+ pix = 0;
+ while(pixels[pix] != 0xFFFF)
+ {
+ line = pixels[pix]>>5;
+ column = pixels[pix] - (line<<5);
+
+ if(mode == 1)
+ {
+ if(line == 0)
+ {
+ if(column == 0)
+ {
+ to[pixels[pix]] = to[33];
+ }
+ else if(column == 31)
+ {
+ to[pixels[pix]] = to[62];
+ }
+ else
+ {
+ to[pixels[pix]] = (to[pixels[pix]+31] + to[pixels[pix]+33])/2.0;
+ }
+ }
+ else if(line == 23)
+ {
+ if(column == 0)
+ {
+ to[pixels[pix]] = to[705];
+ }
+ else if(column == 31)
+ {
+ to[pixels[pix]] = to[734];
+ }
+ else
+ {
+ to[pixels[pix]] = (to[pixels[pix]-33] + to[pixels[pix]-31])/2.0;
+ }
+ }
+ else if(column == 0)
+ {
+ to[pixels[pix]] = (to[pixels[pix]-31] + to[pixels[pix]+33])/2.0;
+ }
+ else if(column == 31)
+ {
+ to[pixels[pix]] = (to[pixels[pix]-33] + to[pixels[pix]+31])/2.0;
+ }
+ else
+ {
+ ap[0] = to[pixels[pix]-33];
+ ap[1] = to[pixels[pix]-31];
+ ap[2] = to[pixels[pix]+31];
+ ap[3] = to[pixels[pix]+33];
+ to[pixels[pix]] = GetMedian(ap,4);
+ }
+ }
+ else
+ {
+ if(column == 0)
+ {
+ to[pixels[pix]] = to[pixels[pix]+1];
+ }
+ else if(column == 1 || column == 30)
+ {
+ to[pixels[pix]] = (to[pixels[pix]-1]+to[pixels[pix]+1])/2.0;
+ }
+ else if(column == 31)
+ {
+ to[pixels[pix]] = to[pixels[pix]-1];
+ }
+ else
+ {
+ if(IsPixelBad(pixels[pix]-2,params) == 0 && IsPixelBad(pixels[pix]+2,params) == 0)
+ {
+ ap[0] = to[pixels[pix]+1] - to[pixels[pix]+2];
+ ap[1] = to[pixels[pix]-1] - to[pixels[pix]-2];
+ if(fabs(ap[0]) > fabs(ap[1]))
+ {
+ to[pixels[pix]] = to[pixels[pix]-1] + ap[1];
+ }
+ else
+ {
+ to[pixels[pix]] = to[pixels[pix]+1] + ap[0];
+ }
+ }
+ else
+ {
+ to[pixels[pix]] = (to[pixels[pix]-1]+to[pixels[pix]+1])/2.0;
+ }
+ }
+ }
+ pix = pix + 1;
+ }
+}
+
+//------------------------------------------------------------------------------
+
+void ExtractVDDParameters(uint16_t *eeData, paramsMLX90640 *mlx90640)
+{
+ int16_t kVdd;
+ int16_t vdd25;
+
+ kVdd = eeData[51];
+
+ kVdd = (eeData[51] & 0xFF00) >> 8;
+ if(kVdd > 127)
+ {
+ kVdd = kVdd - 256;
+ }
+ kVdd = 32 * kVdd;
+ vdd25 = eeData[51] & 0x00FF;
+ vdd25 = ((vdd25 - 256) << 5) - 8192;
+
+ mlx90640->kVdd = kVdd;
+ mlx90640->vdd25 = vdd25;
+}
+
+//------------------------------------------------------------------------------
+
+void ExtractPTATParameters(uint16_t *eeData, paramsMLX90640 *mlx90640)
+{
+ float KvPTAT;
+ float KtPTAT;
+ int16_t vPTAT25;
+ float alphaPTAT;
+
+ KvPTAT = (eeData[50] & 0xFC00) >> 10;
+ if(KvPTAT > 31)
+ {
+ KvPTAT = KvPTAT - 64;
+ }
+ KvPTAT = KvPTAT/4096;
+
+ KtPTAT = eeData[50] & 0x03FF;
+ if(KtPTAT > 511)
+ {
+ KtPTAT = KtPTAT - 1024;
+ }
+ KtPTAT = KtPTAT/8;
+
+ vPTAT25 = eeData[49];
+
+ alphaPTAT = (eeData[16] & 0xF000) / pow(2, (double)14) + 8.0f;
+
+ mlx90640->KvPTAT = KvPTAT;
+ mlx90640->KtPTAT = KtPTAT;
+ mlx90640->vPTAT25 = vPTAT25;
+ mlx90640->alphaPTAT = alphaPTAT;
+}
+
+//------------------------------------------------------------------------------
+
+void ExtractGainParameters(uint16_t *eeData, paramsMLX90640 *mlx90640)
+{
+ int16_t gainEE;
+
+ gainEE = eeData[48];
+ if(gainEE > 32767)
+ {
+ gainEE = gainEE -65536;
+ }
+
+ mlx90640->gainEE = gainEE;
+}
+
+//------------------------------------------------------------------------------
+
+void ExtractTgcParameters(uint16_t *eeData, paramsMLX90640 *mlx90640)
+{
+ float tgc;
+ tgc = eeData[60] & 0x00FF;
+ if(tgc > 127)
+ {
+ tgc = tgc - 256;
+ }
+ tgc = tgc / 32.0f;
+
+ mlx90640->tgc = tgc;
+}
+
+//------------------------------------------------------------------------------
+
+void ExtractResolutionParameters(uint16_t *eeData, paramsMLX90640 *mlx90640)
+{
+ uint8_t resolutionEE;
+ resolutionEE = (eeData[56] & 0x3000) >> 12;
+
+ mlx90640->resolutionEE = resolutionEE;
+}
+
+//------------------------------------------------------------------------------
+
+void ExtractKsTaParameters(uint16_t *eeData, paramsMLX90640 *mlx90640)
+{
+ float KsTa;
+ KsTa = (eeData[60] & 0xFF00) >> 8;
+ if(KsTa > 127)
+ {
+ KsTa = KsTa -256;
+ }
+ KsTa = KsTa / 8192.0f;
+
+ mlx90640->KsTa = KsTa;
+}
+
+//------------------------------------------------------------------------------
+
+void ExtractKsToParameters(uint16_t *eeData, paramsMLX90640 *mlx90640)
+{
+ int KsToScale;
+ int8_t step;
+
+ step = ((eeData[63] & 0x3000) >> 12) * 10;
+
+ mlx90640->ct[0] = -40;
+ mlx90640->ct[1] = 0;
+ mlx90640->ct[2] = (eeData[63] & 0x00F0) >> 4;
+ mlx90640->ct[3] = (eeData[63] & 0x0F00) >> 8;
+
+ mlx90640->ct[2] = mlx90640->ct[2]*step;
+ mlx90640->ct[3] = mlx90640->ct[2] + mlx90640->ct[3]*step;
+ mlx90640->ct[4] = 400;
+
+ KsToScale = (eeData[63] & 0x000F) + 8;
+ KsToScale = 1 << KsToScale;
+
+ mlx90640->ksTo[0] = eeData[61] & 0x00FF;
+ mlx90640->ksTo[1] = (eeData[61] & 0xFF00) >> 8;
+ mlx90640->ksTo[2] = eeData[62] & 0x00FF;
+ mlx90640->ksTo[3] = (eeData[62] & 0xFF00) >> 8;
+
+ for(int i = 0; i < 4; i++)
+ {
+ if(mlx90640->ksTo[i] > 127)
+ {
+ mlx90640->ksTo[i] = mlx90640->ksTo[i] - 256;
+ }
+ mlx90640->ksTo[i] = mlx90640->ksTo[i] / KsToScale;
+ }
+
+ mlx90640->ksTo[4] = -0.0002;
+}
+
+//------------------------------------------------------------------------------
+
+void ExtractAlphaParameters(uint16_t *eeData, paramsMLX90640 *mlx90640)
+{
+ int accRow[24];
+ int accColumn[32];
+ int p = 0;
+ int alphaRef;
+ uint8_t alphaScale;
+ uint8_t accRowScale;
+ uint8_t accColumnScale;
+ uint8_t accRemScale;
+ float alphaTemp[768];
+ float temp;
+
+
+ accRemScale = eeData[32] & 0x000F;
+ accColumnScale = (eeData[32] & 0x00F0) >> 4;
+ accRowScale = (eeData[32] & 0x0F00) >> 8;
+ alphaScale = ((eeData[32] & 0xF000) >> 12) + 30;
+ alphaRef = eeData[33];
+
+ for(int i = 0; i < 6; i++)
+ {
+ p = i * 4;
+ accRow[p + 0] = (eeData[34 + i] & 0x000F);
+ accRow[p + 1] = (eeData[34 + i] & 0x00F0) >> 4;
+ accRow[p + 2] = (eeData[34 + i] & 0x0F00) >> 8;
+ accRow[p + 3] = (eeData[34 + i] & 0xF000) >> 12;
+ }
+
+ for(int i = 0; i < 24; i++)
+ {
+ if (accRow[i] > 7)
+ {
+ accRow[i] = accRow[i] - 16;
+ }
+ }
+
+ for(int i = 0; i < 8; i++)
+ {
+ p = i * 4;
+ accColumn[p + 0] = (eeData[40 + i] & 0x000F);
+ accColumn[p + 1] = (eeData[40 + i] & 0x00F0) >> 4;
+ accColumn[p + 2] = (eeData[40 + i] & 0x0F00) >> 8;
+ accColumn[p + 3] = (eeData[40 + i] & 0xF000) >> 12;
+ }
+
+ for(int i = 0; i < 32; i ++)
+ {
+ if (accColumn[i] > 7)
+ {
+ accColumn[i] = accColumn[i] - 16;
+ }
+ }
+
+ for(int i = 0; i < 24; i++)
+ {
+ for(int j = 0; j < 32; j ++)
+ {
+ p = 32 * i +j;
+ alphaTemp[p] = (eeData[64 + p] & 0x03F0) >> 4;
+ if (alphaTemp[p] > 31)
+ {
+ alphaTemp[p] = alphaTemp[p] - 64;
+ }
+ alphaTemp[p] = alphaTemp[p]*(1 << accRemScale);
+ alphaTemp[p] = (alphaRef + (accRow[i] << accRowScale) + (accColumn[j] << accColumnScale) + alphaTemp[p]);
+ alphaTemp[p] = alphaTemp[p] / pow(2,(double)alphaScale);
+ alphaTemp[p] = alphaTemp[p] - mlx90640->tgc * (mlx90640->cpAlpha[0] + mlx90640->cpAlpha[1])/2;
+ alphaTemp[p] = SCALEALPHA/alphaTemp[p];
+ }
+ }
+
+ temp = alphaTemp[0];
+ for(int i = 1; i < 768; i++)
+ {
+ if (alphaTemp[i] > temp)
+ {
+ temp = alphaTemp[i];
+ }
+ }
+
+ alphaScale = 0;
+ while(temp < 32767.4)
+ {
+ temp = temp*2;
+ alphaScale = alphaScale + 1;
+ }
+
+ for(int i = 0; i < 768; i++)
+ {
+ temp = alphaTemp[i] * pow(2,(double)alphaScale);
+ mlx90640->alpha[i] = (temp + 0.5);
+
+ }
+
+ mlx90640->alphaScale = alphaScale;
+
+}
+
+//------------------------------------------------------------------------------
+
+void ExtractOffsetParameters(uint16_t *eeData, paramsMLX90640 *mlx90640)
+{
+ int occRow[24];
+ int occColumn[32];
+ int p = 0;
+ int16_t offsetRef;
+ uint8_t occRowScale;
+ uint8_t occColumnScale;
+ uint8_t occRemScale;
+
+
+ occRemScale = (eeData[16] & 0x000F);
+ occColumnScale = (eeData[16] & 0x00F0) >> 4;
+ occRowScale = (eeData[16] & 0x0F00) >> 8;
+ offsetRef = eeData[17];
+ if (offsetRef > 32767)
+ {
+ offsetRef = offsetRef - 65536;
+ }
+
+ for(int i = 0; i < 6; i++)
+ {
+ p = i * 4;
+ occRow[p + 0] = (eeData[18 + i] & 0x000F);
+ occRow[p + 1] = (eeData[18 + i] & 0x00F0) >> 4;
+ occRow[p + 2] = (eeData[18 + i] & 0x0F00) >> 8;
+ occRow[p + 3] = (eeData[18 + i] & 0xF000) >> 12;
+ }
+
+ for(int i = 0; i < 24; i++)
+ {
+ if (occRow[i] > 7)
+ {
+ occRow[i] = occRow[i] - 16;
+ }
+ }
+
+ for(int i = 0; i < 8; i++)
+ {
+ p = i * 4;
+ occColumn[p + 0] = (eeData[24 + i] & 0x000F);
+ occColumn[p + 1] = (eeData[24 + i] & 0x00F0) >> 4;
+ occColumn[p + 2] = (eeData[24 + i] & 0x0F00) >> 8;
+ occColumn[p + 3] = (eeData[24 + i] & 0xF000) >> 12;
+ }
+
+ for(int i = 0; i < 32; i ++)
+ {
+ if (occColumn[i] > 7)
+ {
+ occColumn[i] = occColumn[i] - 16;
+ }
+ }
+
+ for(int i = 0; i < 24; i++)
+ {
+ for(int j = 0; j < 32; j ++)
+ {
+ p = 32 * i +j;
+ mlx90640->offset[p] = (eeData[64 + p] & 0xFC00) >> 10;
+ if (mlx90640->offset[p] > 31)
+ {
+ mlx90640->offset[p] = mlx90640->offset[p] - 64;
+ }
+ mlx90640->offset[p] = mlx90640->offset[p]*(1 << occRemScale);
+ mlx90640->offset[p] = (offsetRef + (occRow[i] << occRowScale) + (occColumn[j] << occColumnScale) + mlx90640->offset[p]);
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+
+void ExtractKtaPixelParameters(uint16_t *eeData, paramsMLX90640 *mlx90640)
+{
+ int p = 0;
+ int8_t KtaRC[4];
+ int8_t KtaRoCo;
+ int8_t KtaRoCe;
+ int8_t KtaReCo;
+ int8_t KtaReCe;
+ uint8_t ktaScale1;
+ uint8_t ktaScale2;
+ uint8_t split;
+ float ktaTemp[768];
+ float temp;
+
+ KtaRoCo = (eeData[54] & 0xFF00) >> 8;
+ if (KtaRoCo > 127)
+ {
+ KtaRoCo = KtaRoCo - 256;
+ }
+ KtaRC[0] = KtaRoCo;
+
+ KtaReCo = (eeData[54] & 0x00FF);
+ if (KtaReCo > 127)
+ {
+ KtaReCo = KtaReCo - 256;
+ }
+ KtaRC[2] = KtaReCo;
+
+ KtaRoCe = (eeData[55] & 0xFF00) >> 8;
+ if (KtaRoCe > 127)
+ {
+ KtaRoCe = KtaRoCe - 256;
+ }
+ KtaRC[1] = KtaRoCe;
+
+ KtaReCe = (eeData[55] & 0x00FF);
+ if (KtaReCe > 127)
+ {
+ KtaReCe = KtaReCe - 256;
+ }
+ KtaRC[3] = KtaReCe;
+
+ ktaScale1 = ((eeData[56] & 0x00F0) >> 4) + 8;
+ ktaScale2 = (eeData[56] & 0x000F);
+
+ for(int i = 0; i < 24; i++)
+ {
+ for(int j = 0; j < 32; j ++)
+ {
+ p = 32 * i +j;
+ split = 2*(p/32 - (p/64)*2) + p%2;
+ ktaTemp[p] = (eeData[64 + p] & 0x000E) >> 1;
+ if (ktaTemp[p] > 3)
+ {
+ ktaTemp[p] = ktaTemp[p] - 8;
+ }
+ ktaTemp[p] = ktaTemp[p] * (1 << ktaScale2);
+ ktaTemp[p] = KtaRC[split] + ktaTemp[p];
+ ktaTemp[p] = ktaTemp[p] / pow(2,(double)ktaScale1);
+ //ktaTemp[p] = ktaTemp[p] * mlx90640->offset[p];
+ }
+ }
+
+ temp = fabs(ktaTemp[0]);
+ for(int i = 1; i < 768; i++)
+ {
+ if (fabs(ktaTemp[i]) > temp)
+ {
+ temp = fabs(ktaTemp[i]);
+ }
+ }
+
+ ktaScale1 = 0;
+ while(temp < 63.4)
+ {
+ temp = temp*2;
+ ktaScale1 = ktaScale1 + 1;
+ }
+
+ for(int i = 0; i < 768; i++)
+ {
+ temp = ktaTemp[i] * pow(2,(double)ktaScale1);
+ if (temp < 0)
+ {
+ mlx90640->kta[i] = (temp - 0.5);
+ }
+ else
+ {
+ mlx90640->kta[i] = (temp + 0.5);
+ }
+
+ }
+
+ mlx90640->ktaScale = ktaScale1;
+}
+
+
+//------------------------------------------------------------------------------
+
+void ExtractKvPixelParameters(uint16_t *eeData, paramsMLX90640 *mlx90640)
+{
+ int p = 0;
+ int8_t KvT[4];
+ int8_t KvRoCo;
+ int8_t KvRoCe;
+ int8_t KvReCo;
+ int8_t KvReCe;
+ uint8_t kvScale;
+ uint8_t split;
+ float kvTemp[768];
+ float temp;
+
+ KvRoCo = (eeData[52] & 0xF000) >> 12;
+ if (KvRoCo > 7)
+ {
+ KvRoCo = KvRoCo - 16;
+ }
+ KvT[0] = KvRoCo;
+
+ KvReCo = (eeData[52] & 0x0F00) >> 8;
+ if (KvReCo > 7)
+ {
+ KvReCo = KvReCo - 16;
+ }
+ KvT[2] = KvReCo;
+
+ KvRoCe = (eeData[52] & 0x00F0) >> 4;
+ if (KvRoCe > 7)
+ {
+ KvRoCe = KvRoCe - 16;
+ }
+ KvT[1] = KvRoCe;
+
+ KvReCe = (eeData[52] & 0x000F);
+ if (KvReCe > 7)
+ {
+ KvReCe = KvReCe - 16;
+ }
+ KvT[3] = KvReCe;
+
+ kvScale = (eeData[56] & 0x0F00) >> 8;
+
+
+ for(int i = 0; i < 24; i++)
+ {
+ for(int j = 0; j < 32; j ++)
+ {
+ p = 32 * i +j;
+ split = 2*(p/32 - (p/64)*2) + p%2;
+ kvTemp[p] = KvT[split];
+ kvTemp[p] = kvTemp[p] / pow(2,(double)kvScale);
+ //kvTemp[p] = kvTemp[p] * mlx90640->offset[p];
+ }
+ }
+
+ temp = fabs(kvTemp[0]);
+ for(int i = 1; i < 768; i++)
+ {
+ if (fabs(kvTemp[i]) > temp)
+ {
+ temp = fabs(kvTemp[i]);
+ }
+ }
+
+ kvScale = 0;
+ while(temp < 63.4)
+ {
+ temp = temp*2;
+ kvScale = kvScale + 1;
+ }
+
+ for(int i = 0; i < 768; i++)
+ {
+ temp = kvTemp[i] * pow(2,(double)kvScale);
+ if (temp < 0)
+ {
+ mlx90640->kv[i] = (temp - 0.5);
+ }
+ else
+ {
+ mlx90640->kv[i] = (temp + 0.5);
+ }
+
+ }
+
+ mlx90640->kvScale = kvScale;
+}
+
+//------------------------------------------------------------------------------
+
+void ExtractCPParameters(uint16_t *eeData, paramsMLX90640 *mlx90640)
+{
+ float alphaSP[2];
+ int16_t offsetSP[2];
+ float cpKv;
+ float cpKta;
+ uint8_t alphaScale;
+ uint8_t ktaScale1;
+ uint8_t kvScale;
+
+ alphaScale = ((eeData[32] & 0xF000) >> 12) + 27;
+
+ offsetSP[0] = (eeData[58] & 0x03FF);
+ if (offsetSP[0] > 511)
+ {
+ offsetSP[0] = offsetSP[0] - 1024;
+ }
+
+ offsetSP[1] = (eeData[58] & 0xFC00) >> 10;
+ if (offsetSP[1] > 31)
+ {
+ offsetSP[1] = offsetSP[1] - 64;
+ }
+ offsetSP[1] = offsetSP[1] + offsetSP[0];
+
+ alphaSP[0] = (eeData[57] & 0x03FF);
+ if (alphaSP[0] > 511)
+ {
+ alphaSP[0] = alphaSP[0] - 1024;
+ }
+ alphaSP[0] = alphaSP[0] / pow(2,(double)alphaScale);
+
+ alphaSP[1] = (eeData[57] & 0xFC00) >> 10;
+ if (alphaSP[1] > 31)
+ {
+ alphaSP[1] = alphaSP[1] - 64;
+ }
+ alphaSP[1] = (1 + alphaSP[1]/128) * alphaSP[0];
+
+ cpKta = (eeData[59] & 0x00FF);
+ if (cpKta > 127)
+ {
+ cpKta = cpKta - 256;
+ }
+ ktaScale1 = ((eeData[56] & 0x00F0) >> 4) + 8;
+ mlx90640->cpKta = cpKta / pow(2,(double)ktaScale1);
+
+ cpKv = (eeData[59] & 0xFF00) >> 8;
+ if (cpKv > 127)
+ {
+ cpKv = cpKv - 256;
+ }
+ kvScale = (eeData[56] & 0x0F00) >> 8;
+ mlx90640->cpKv = cpKv / pow(2,(double)kvScale);
+
+ mlx90640->cpAlpha[0] = alphaSP[0];
+ mlx90640->cpAlpha[1] = alphaSP[1];
+ mlx90640->cpOffset[0] = offsetSP[0];
+ mlx90640->cpOffset[1] = offsetSP[1];
+}
+
+//------------------------------------------------------------------------------
+
+void ExtractCILCParameters(uint16_t *eeData, paramsMLX90640 *mlx90640)
+{
+ float ilChessC[3];
+ uint8_t calibrationModeEE;
+
+ calibrationModeEE = (eeData[10] & 0x0800) >> 4;
+ calibrationModeEE = calibrationModeEE ^ 0x80;
+
+ ilChessC[0] = (eeData[53] & 0x003F);
+ if (ilChessC[0] > 31)
+ {
+ ilChessC[0] = ilChessC[0] - 64;
+ }
+ ilChessC[0] = ilChessC[0] / 16.0f;
+
+ ilChessC[1] = (eeData[53] & 0x07C0) >> 6;
+ if (ilChessC[1] > 15)
+ {
+ ilChessC[1] = ilChessC[1] - 32;
+ }
+ ilChessC[1] = ilChessC[1] / 2.0f;
+
+ ilChessC[2] = (eeData[53] & 0xF800) >> 11;
+ if (ilChessC[2] > 15)
+ {
+ ilChessC[2] = ilChessC[2] - 32;
+ }
+ ilChessC[2] = ilChessC[2] / 8.0f;
+
+ mlx90640->calibrationModeEE = calibrationModeEE;
+ mlx90640->ilChessC[0] = ilChessC[0];
+ mlx90640->ilChessC[1] = ilChessC[1];
+ mlx90640->ilChessC[2] = ilChessC[2];
+}
+
+//------------------------------------------------------------------------------
+
+int ExtractDeviatingPixels(uint16_t *eeData, paramsMLX90640 *mlx90640)
+{
+ uint16_t pixCnt = 0;
+ uint16_t brokenPixCnt = 0;
+ uint16_t outlierPixCnt = 0;
+ int warn = 0;
+ int i;
+
+ for(pixCnt = 0; pixCnt<5; pixCnt++)
+ {
+ mlx90640->brokenPixels[pixCnt] = 0xFFFF;
+ mlx90640->outlierPixels[pixCnt] = 0xFFFF;
+ }
+
+ pixCnt = 0;
+ while (pixCnt < 768 && brokenPixCnt < 5 && outlierPixCnt < 5)
+ {
+ if(eeData[pixCnt+64] == 0)
+ {
+ mlx90640->brokenPixels[brokenPixCnt] = pixCnt;
+ brokenPixCnt = brokenPixCnt + 1;
+ }
+ else if((eeData[pixCnt+64] & 0x0001) != 0)
+ {
+ mlx90640->outlierPixels[outlierPixCnt] = pixCnt;
+ outlierPixCnt = outlierPixCnt + 1;
+ }
+
+ pixCnt = pixCnt + 1;
+
+ }
+
+ if(brokenPixCnt > 4)
+ {
+ warn = -3;
+ }
+ else if(outlierPixCnt > 4)
+ {
+ warn = -4;
+ }
+ else if((brokenPixCnt + outlierPixCnt) > 4)
+ {
+ warn = -5;
+ }
+ else
+ {
+ for(pixCnt=0; pixCntbrokenPixels[pixCnt],mlx90640->brokenPixels[i]);
+ if(warn != 0)
+ {
+ return warn;
+ }
+ }
+ }
+
+ for(pixCnt=0; pixCntoutlierPixels[pixCnt],mlx90640->outlierPixels[i]);
+ if(warn != 0)
+ {
+ return warn;
+ }
+ }
+ }
+
+ for(pixCnt=0; pixCntbrokenPixels[pixCnt],mlx90640->outlierPixels[i]);
+ if(warn != 0)
+ {
+ return warn;
+ }
+ }
+ }
+
+ }
+
+
+ return warn;
+
+}
+
+//------------------------------------------------------------------------------
+
+ int CheckAdjacentPixels(uint16_t pix1, uint16_t pix2)
+ {
+ int pixPosDif;
+
+ pixPosDif = pix1 - pix2;
+ if(pixPosDif > -34 && pixPosDif < -30)
+ {
+ return -6;
+ }
+ if(pixPosDif > -2 && pixPosDif < 2)
+ {
+ return -6;
+ }
+ if(pixPosDif > 30 && pixPosDif < 34)
+ {
+ return -6;
+ }
+
+ return 0;
+ }
+
+//------------------------------------------------------------------------------
+
+float GetMedian(float *values, int n)
+ {
+ float temp;
+
+ for(int i=0; ioutlierPixels[i] || pixel == params->brokenPixels[i])
+ {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+//------------------------------------------------------------------------------
diff --git a/lib/mlx90640-library/MLX90640_API.h b/lib/mlx90640-library/MLX90640_API.h
new file mode 100644
index 000000000..efbcdff5b
--- /dev/null
+++ b/lib/mlx90640-library/MLX90640_API.h
@@ -0,0 +1,74 @@
+/**
+ * @copyright (C) 2017 Melexis N.V.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+#ifndef _MLX90640_API_H_
+#define _MLX90640_API_H_
+
+#include
+
+#define SCALEALPHA 0.000001
+
+typedef struct
+ {
+ int16_t kVdd;
+ int16_t vdd25;
+ float KvPTAT;
+ float KtPTAT;
+ uint16_t vPTAT25;
+ float alphaPTAT;
+ int16_t gainEE;
+ float tgc;
+ float cpKv;
+ float cpKta;
+ uint8_t resolutionEE;
+ uint8_t calibrationModeEE;
+ float KsTa;
+ float ksTo[5];
+ int16_t ct[5];
+ uint16_t alpha[768];
+ uint8_t alphaScale;
+ int16_t offset[768];
+ int8_t kta[768];
+ uint8_t ktaScale;
+ int8_t kv[768];
+ uint8_t kvScale;
+ float cpAlpha[2];
+ int16_t cpOffset[2];
+ float ilChessC[3];
+ uint16_t brokenPixels[5];
+ uint16_t outlierPixels[5];
+ } paramsMLX90640;
+
+ int MLX90640_DumpEE(uint8_t slaveAddr, uint16_t *eeData);
+ int MLX90640_SynchFrame(uint8_t slaveAddr);
+ // int MLX90640_TriggerMeasurement(uint8_t slaveAddr);
+ int MLX90640_GetFrameData(uint8_t slaveAddr, uint16_t *frameData);
+ int MLX90640_ExtractParameters(uint16_t *eeData, paramsMLX90640 *mlx90640,int _chunk);
+ float MLX90640_GetVdd(uint16_t *frameData, const paramsMLX90640 *params);
+ float MLX90640_GetTa(uint16_t *frameData, const paramsMLX90640 *params);
+ // void MLX90640_GetImage(uint16_t *frameData, const paramsMLX90640 *params, float *result);
+ void MLX90640_CalculateTo(uint16_t *frameData, const paramsMLX90640 *params, float emissivity, float tr, float *result, uint8_t _part);
+ int MLX90640_SetResolution(uint8_t slaveAddr, uint8_t resolution);
+ int MLX90640_GetCurResolution(uint8_t slaveAddr);
+ int MLX90640_SetRefreshRate(uint8_t slaveAddr, uint8_t refreshRate);
+ int MLX90640_GetRefreshRate(uint8_t slaveAddr);
+ int MLX90640_GetSubPageNumber(uint16_t *frameData);
+ int MLX90640_GetCurMode(uint8_t slaveAddr);
+ int MLX90640_SetInterleavedMode(uint8_t slaveAddr);
+ int MLX90640_SetChessMode(uint8_t slaveAddr);
+ void MLX90640_BadPixelsCorrection(uint16_t *pixels, float *to, int mode, paramsMLX90640 *params);
+
+#endif
From a62ff5176e0abd3582e3f1633fc2397ab5f8c1cc Mon Sep 17 00:00:00 2001
From: Staars
Date: Sat, 12 Sep 2020 19:16:36 +0200
Subject: [PATCH 16/23] add mlx90640 to configs
---
I2CDEVICES.md | 3 ++-
tasmota/my_user_config.h | 1 +
tasmota/xdrv_84_MLX90640.ino | 1 +
tools/decode-status.py | 2 +-
4 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/I2CDEVICES.md b/I2CDEVICES.md
index 457116347..5d60c5fb4 100644
--- a/I2CDEVICES.md
+++ b/I2CDEVICES.md
@@ -74,4 +74,5 @@ Index | Define | Driver | Device | Address(es) | Description
49 | USE_VEML6075 | xsns_70 | VEML6075 | 0x10 | UVA/UVB/UVINDEX Sensor
50 | USE_VEML7700 | xsns_71 | VEML7700 | 0x10 | Ambient light intensity sensor
51 | USE_MCP9808 | xsns_72 | MCP9808 | 0x18 - 0x1F | Temperature sensor
- 52 | USE_HP303B | xsns_73 | HP303B | 0x76 - 0x77 | Pressure and temperature sensor
\ No newline at end of file
+ 52 | USE_HP303B | xsns_73 | HP303B | 0x76 - 0x77 | Pressure and temperature sensor
+ 53 | USE_MLX90640 | xdrv_84 | MLX90640 | 0x33 | IR array temperature sensor
\ No newline at end of file
diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h
index 5f94c5fc0..e7fd061f5 100644
--- a/tasmota/my_user_config.h
+++ b/tasmota/my_user_config.h
@@ -557,6 +557,7 @@
// #define USE_VEML7700 // [I2cDriver50] Enable VEML7700 Ambient Light sensor (I2C addresses 0x10) (+4k5 code)
// #define USE_MCP9808 // [I2cDriver51] Enable MCP9808 temperature sensor (I2C addresses 0x18 - 0x1F) (+0k9 code)
// #define USE_HP303B // [I2cDriver52] Enable HP303B temperature and pressure sensor (I2C address 0x76 or 0x77) (+6k2 code)
+// #define USE_MLX90640 // Enable MLX90640 IR array temperature sensor (I2C address 0x33) (+4k9 code)
// #define USE_DISPLAY // Add I2C Display Support (+2k code)
#define USE_DISPLAY_MODES1TO5 // Enable display mode 1 to 5 in addition to mode 0
diff --git a/tasmota/xdrv_84_MLX90640.ino b/tasmota/xdrv_84_MLX90640.ino
index 808b8f9d2..a1016c917 100644
--- a/tasmota/xdrv_84_MLX90640.ino
+++ b/tasmota/xdrv_84_MLX90640.ino
@@ -34,6 +34,7 @@
\*********************************************************************************************/
#define XDRV_84 84
+#define XI2C_53 53 // See I2CDEVICES.md
#include
const char MLX90640type[] PROGMEM = "MLX90640";
diff --git a/tools/decode-status.py b/tools/decode-status.py
index 876c9eb91..3758b528c 100755
--- a/tools/decode-status.py
+++ b/tools/decode-status.py
@@ -220,7 +220,7 @@ a_features = [[
"USE_WINDMETER","USE_OPENTHERM","USE_THERMOSTAT","USE_VEML6075",
"USE_VEML7700","USE_MCP9808","USE_BL0940","USE_TELEGRAM",
"USE_HP303B","USE_TCP_BRIDGE","USE_TELEINFO","USE_LMT01",
- "USE_PROMETHEUS","USE_IEM3000","USE_DYP","",
+ "USE_PROMETHEUS","USE_IEM3000","USE_DYP","USE_MLX90640",
"","","","",
"","","USE_ETHERNET","USE_WEBCAM"
],[
From 9b67090ee8291c273b01890963ff279429a86f8b Mon Sep 17 00:00:00 2001
From: Staars
Date: Sat, 12 Sep 2020 19:23:10 +0200
Subject: [PATCH 17/23] add I2cDriver53
---
tasmota/my_user_config.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h
index e7fd061f5..e77efe401 100644
--- a/tasmota/my_user_config.h
+++ b/tasmota/my_user_config.h
@@ -557,7 +557,7 @@
// #define USE_VEML7700 // [I2cDriver50] Enable VEML7700 Ambient Light sensor (I2C addresses 0x10) (+4k5 code)
// #define USE_MCP9808 // [I2cDriver51] Enable MCP9808 temperature sensor (I2C addresses 0x18 - 0x1F) (+0k9 code)
// #define USE_HP303B // [I2cDriver52] Enable HP303B temperature and pressure sensor (I2C address 0x76 or 0x77) (+6k2 code)
-// #define USE_MLX90640 // Enable MLX90640 IR array temperature sensor (I2C address 0x33) (+4k9 code)
+// #define USE_MLX90640 // [I2cDriver53] Enable MLX90640 IR array temperature sensor (I2C address 0x33) (+4k9 code)
// #define USE_DISPLAY // Add I2C Display Support (+2k code)
#define USE_DISPLAY_MODES1TO5 // Enable display mode 1 to 5 in addition to mode 0
From b0b35a953d8ae0f081e0ab7caa7b5ab251cc6bc0 Mon Sep 17 00:00:00 2001
From: Stephan Hadinger
Date: Sun, 13 Sep 2020 16:11:20 +0200
Subject: [PATCH 18/23] Zigbee minor fixes
---
tasmota/xdrv_23_zigbee_5_converters.ino | 5 +++++
tasmota/xdrv_23_zigbee_8_parsers.ino | 2 +-
tasmota/xdrv_23_zigbee_A_impl.ino | 13 +++++++++----
3 files changed, 15 insertions(+), 5 deletions(-)
diff --git a/tasmota/xdrv_23_zigbee_5_converters.ino b/tasmota/xdrv_23_zigbee_5_converters.ino
index 542aa3a41..edcdb3135 100644
--- a/tasmota/xdrv_23_zigbee_5_converters.ino
+++ b/tasmota/xdrv_23_zigbee_5_converters.ino
@@ -1080,6 +1080,11 @@ void ZCLFrame::generateSyntheticAttributes(Z_attribute_list& attr_list) {
uint32_t ccccaaaa = (attr.key.id.cluster << 16) | attr.key.id.attr_id;
switch (ccccaaaa) { // 0xccccaaaa . c=cluster, a=attribute
+ case 0x00010020: // BatteryVoltage
+ if (attr_list.countAttribute(0x0001,0x0021) == 0) { // if it does not already contain BatteryPercentage
+ uint32_t mv = attr.getUInt()*100;
+ attr_list.addAttribute(0x0001, 0x0021).setUInt(toPercentageCR2032(mv) * 2);
+ }
case 0x0000FF01:
syntheticAqaraSensor(attr_list, attr);
break;
diff --git a/tasmota/xdrv_23_zigbee_8_parsers.ino b/tasmota/xdrv_23_zigbee_8_parsers.ino
index 788c72e88..c7585134b 100644
--- a/tasmota/xdrv_23_zigbee_8_parsers.ino
+++ b/tasmota/xdrv_23_zigbee_8_parsers.ino
@@ -1774,7 +1774,7 @@ void Z_AutoResponder(uint16_t srcaddr, uint16_t cluster, uint8_t endpoint, const
for (uint32_t i=0; i()) {
+ // value is an array []
const JsonArray& attr_arr = val_attr.as();
attrs_len = attr_arr.size() * attr_item_len;
attrs = (uint8_t*) calloc(attrs_len, 1);
@@ -569,6 +570,7 @@ void ZbSendRead(const JsonVariant &val_attr, uint16_t device, uint16_t groupaddr
i += attr_item_len - 2 - attr_item_offset; // normally 0
}
} else if (val_attr.is()) {
+ // value is an object {}
const JsonObject& attr_obj = val_attr.as();
attrs_len = attr_obj.size() * attr_item_len;
attrs = (uint8_t*) calloc(attrs_len, 1);
@@ -619,10 +621,13 @@ void ZbSendRead(const JsonVariant &val_attr, uint16_t device, uint16_t groupaddr
attrs_len = actual_attr_len;
} else {
- attrs_len = attr_item_len;
- attrs = (uint8_t*) calloc(attrs_len, 1);
- attrs[0 + attr_item_offset] = val & 0xFF; // little endian
- attrs[1 + attr_item_offset] = val >> 8;
+ // value is a literal
+ if (0xFFFF != cluster) {
+ attrs_len = attr_item_len;
+ attrs = (uint8_t*) calloc(attrs_len, 1);
+ attrs[0 + attr_item_offset] = val & 0xFF; // little endian
+ attrs[1 + attr_item_offset] = val >> 8;
+ }
}
if (attrs_len > 0) {
From 9aa18c23f0d123b16704631a74a0da3160a2daee Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Mon, 14 Sep 2020 11:49:33 +0200
Subject: [PATCH 19/23] Add support for MLX90640
Add support for MLX90640 IR array temperature sensor by Christian Baars
---
RELEASENOTES.md | 4 +++-
tasmota/CHANGELOG.md | 1 +
tasmota/my_user_config.h | 2 +-
tasmota/support_features.ino | 5 +++--
...rv_84_MLX90640.ino => xdrv_43_mlx90640.ino} | 18 +++++++++---------
5 files changed, 17 insertions(+), 13 deletions(-)
rename tasmota/{xdrv_84_MLX90640.ino => xdrv_43_mlx90640.ino} (98%)
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index 796435d03..3e4973403 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -47,7 +47,7 @@ The following binary downloads have been compiled with ESP8266/Arduino library c
- **tasmota-zbbridge.bin** = The dedicated Sonoff Zigbee Bridge version.
- **tasmota-minimal.bin** = The Minimal version allows intermediate OTA uploads to support larger versions and does NOT change any persistent parameter. This version **should NOT be used for initial installation**.
-Binaries for ESP8266 based devices can be downloaded from http://ota.tasmota.com/tasmota/release. Binaries for ESP32 based devices can be downloaded from http://ota.tasmota.com/tasmota32/release. The base links can be used for OTA upgrades like ``OtaUrl http://ota.tasmota.com/tasmota/release/tasmota.bin``
+The attached binaries can also be downloaded from http://ota.tasmota.com/tasmota/release for ESP8266 or http://ota.tasmota.com/tasmota32/release for ESP32. The links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmota.com/tasmota/release/tasmota.bin``
[List](MODULES.md) of embedded modules.
@@ -61,3 +61,5 @@ Binaries for ESP8266 based devices can be downloaded from http://ota.tasmota.com
- Fix crash in ``ZbRestore``
- Add new shutter modes (#9244)
- Add ``#define USE_MQTT_AWS_IOT_LIGHT`` for password based AWS IoT authentication
+- Add Zigbee auto-config when pairing
+- Add support for MLX90640 IR array temperature sensor by Christian Baars
diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md
index d07791a2e..66a086bd6 100644
--- a/tasmota/CHANGELOG.md
+++ b/tasmota/CHANGELOG.md
@@ -9,6 +9,7 @@
- Add new shutter modes (#9244)
- Add ``#define USE_MQTT_AWS_IOT_LIGHT`` for password based AWS IoT authentication
- Add Zigbee auto-config when pairing
+- Add support for MLX90640 IR array temperature sensor by Christian Baars
### 8.5.0 20200907
diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h
index d74cecfe5..f2673bda6 100644
--- a/tasmota/my_user_config.h
+++ b/tasmota/my_user_config.h
@@ -558,7 +558,7 @@
// #define USE_VEML7700 // [I2cDriver50] Enable VEML7700 Ambient Light sensor (I2C addresses 0x10) (+4k5 code)
// #define USE_MCP9808 // [I2cDriver51] Enable MCP9808 temperature sensor (I2C addresses 0x18 - 0x1F) (+0k9 code)
// #define USE_HP303B // [I2cDriver52] Enable HP303B temperature and pressure sensor (I2C address 0x76 or 0x77) (+6k2 code)
-// #define USE_MLX90640 // [I2cDriver53] Enable MLX90640 IR array temperature sensor (I2C address 0x33) (+4k9 code)
+// #define USE_MLX90640 // [I2cDriver53] Enable MLX90640 IR array temperature sensor (I2C address 0x33) (+20k code)
// #define USE_DISPLAY // Add I2C Display Support (+2k code)
#define USE_DISPLAY_MODES1TO5 // Enable display mode 1 to 5 in addition to mode 0
diff --git a/tasmota/support_features.ino b/tasmota/support_features.ino
index d7f8328d3..50da89faa 100644
--- a/tasmota/support_features.ino
+++ b/tasmota/support_features.ino
@@ -601,8 +601,9 @@ void GetFeatures(void)
#ifdef USE_I2S_AUDIO
feature6 |= 0x00800000; // xdrv_42_i2s_audio.ino
#endif
-
-// feature6 |= 0x01000000;
+#ifdef USE_MLX90640
+ feature6 |= 0x01000000; // xdrv_43_mlx90640.ino
+#endif
// feature6 |= 0x02000000;
// feature6 |= 0x04000000;
// feature6 |= 0x08000000;
diff --git a/tasmota/xdrv_84_MLX90640.ino b/tasmota/xdrv_43_mlx90640.ino
similarity index 98%
rename from tasmota/xdrv_84_MLX90640.ino
rename to tasmota/xdrv_43_mlx90640.ino
index a1016c917..88832acc6 100644
--- a/tasmota/xdrv_84_MLX90640.ino
+++ b/tasmota/xdrv_43_mlx90640.ino
@@ -1,5 +1,5 @@
/*
- xdrv_84_MLX90640.ino - MLX90640 support for Tasmota
+ xdrv_43_mlx90640.ino - MLX90640 support for Tasmota
Copyright (C) 2020 Christian Baars and Theo Arends
@@ -33,7 +33,7 @@
* MLX90640
\*********************************************************************************************/
-#define XDRV_84 84
+#define XDRV_43 43
#define XI2C_53 53 // See I2CDEVICES.md
#include
@@ -144,7 +144,7 @@ const char HTTP_MLX90640_2a_SNS_COMPRESSED[] PROGMEM = "\x33\xBF\xA0\xB7\x9A\x3E
#else
const char HTTP_MLX90640_2a_SNS[] PROGMEM =
"var line = 0;"
- "setInterval(function() {"
+ "setInterval(function() {"
"rl('ul',line);" // 0 = do NOT force refresh
"},200);"
"function rl(s,v){" //source, value
@@ -209,7 +209,7 @@ const char HTTP_MLX90640_2b_SNS[] PROGMEM =
"for (var j=0;j<32;j++){"
"var y = 239 - Math.floor(map(rA[(i*32)+j],0,40,0,239));" // 40 is max. temp for heat map
// console.log(gPx.data[y],gPx.data[y+1],gPx.data[y+2]);
- "octx.fillStyle = 'rgb(' + gPx.data[(y*4)] + ',' + gPx.data[(y*4)+1] +',' + gPx.data[(y*4)+2] + ')';"
+ "octx.fillStyle = 'rgb(' + gPx.data[(y*4)] + ',' + gPx.data[(y*4)+1] +',' + gPx.data[(y*4)+2] + ')';"
"octx.fillRect(j*1,i*1,1,1);"
"}"
"}"
@@ -254,7 +254,7 @@ const char HTTP_MLX90640_3a_SNS[] PROGMEM =
"rO.deleteContents();"
"for(var p in poi){"
//"console.log('poi:'+ poi[p][0]);"
- "var c=150;"
+ "var c=150;"
"if(eb('poiL').value==p){c=255;}"
// "console.log(c);"
"ctx.fillStyle = 'rgba('+c+','+c+','+c+',0.6)';"
@@ -411,18 +411,18 @@ void MLX90640UpdateGUI(void){
void MLX90640HandleWebGuiResponse(void){
char tmp[(MLX90640_POI_NUM*2)+4];
WebGetArg("ul", tmp, sizeof(tmp)); // update line
- if (strlen(tmp)) {
+ if (strlen(tmp)) {
uint8_t _line = atoi(tmp);
// AddLog_P2(LOG_LEVEL_DEBUG, "MLX90640: send line %u", _line);
float _buf[65];
- if(_line==0){_buf[0]=1000+MLX90640.Ta;} //ambient temperature modulation hack
+ if(_line==0){_buf[0]=1000+MLX90640.Ta;} //ambient temperature modulation hack
else{_buf[0]=(float)_line;}
memcpy((char*)&_buf[1],(char*)&MLX90640.To[_line*64],64*4);
Webserver->send(200,PSTR("application/octet-stream"),(const char*)&_buf,65*4);
return;
}
WebGetArg("up", tmp, sizeof(tmp)); // update POI to browser
- if (strlen(tmp)==1) {
+ if (strlen(tmp)==1) {
Webserver->send(200,PSTR("application/octet-stream"),(const char*)&MLX90640.pois,MLX90640_POI_NUM*2);
return;
}
@@ -591,7 +591,7 @@ void MLX90640Show(uint8_t json)
* Interface
\*********************************************************************************************/
-bool Xdrv84(uint8_t function)
+bool Xdrv43(uint8_t function)
{
bool result = false;
From 26e041ab6efe14da3d918154e9d4d0d87f352198 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Mon, 14 Sep 2020 12:26:32 +0200
Subject: [PATCH 20/23] Fix reset BMP sensors
Fix reset BMP sensors when executing command ``SaveData`` and define USE_DEEPSLEEP enabled (#9300)
---
RELEASENOTES.md | 1 +
tasmota/CHANGELOG.md | 1 +
tasmota/xsns_09_bmp.ino | 20 +++++++++++---------
3 files changed, 13 insertions(+), 9 deletions(-)
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index 3e4973403..9b3740986 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -59,6 +59,7 @@ The attached binaries can also be downloaded from http://ota.tasmota.com/tasmota
- Fix energy total counters (#9263, #9266)
- Fix crash in ``ZbRestore``
+- Fix reset BMP sensors when executing command ``SaveData`` and define USE_DEEPSLEEP enabled (#9300)
- Add new shutter modes (#9244)
- Add ``#define USE_MQTT_AWS_IOT_LIGHT`` for password based AWS IoT authentication
- Add Zigbee auto-config when pairing
diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md
index 66a086bd6..5c0d36fd2 100644
--- a/tasmota/CHANGELOG.md
+++ b/tasmota/CHANGELOG.md
@@ -6,6 +6,7 @@
- Fix energy total counters (#9263, #9266)
- Fix crash in ``ZbRestore``
+- Fix reset BMP sensors when executing command ``SaveData`` and define USE_DEEPSLEEP enabled (#9300)
- Add new shutter modes (#9244)
- Add ``#define USE_MQTT_AWS_IOT_LIGHT`` for password based AWS IoT authentication
- Add Zigbee auto-config when pairing
diff --git a/tasmota/xsns_09_bmp.ino b/tasmota/xsns_09_bmp.ino
index 9e3ee59b4..8e1bd074a 100644
--- a/tasmota/xsns_09_bmp.ino
+++ b/tasmota/xsns_09_bmp.ino
@@ -613,15 +613,17 @@ void BmpShow(bool json)
void BMP_EnterSleep(void)
{
- for (uint32_t bmp_idx = 0; bmp_idx < bmp_count; bmp_idx++) {
- switch (bmp_sensors[bmp_idx].bmp_type) {
- case BMP180_CHIPID:
- case BMP280_CHIPID:
- case BME280_CHIPID:
- I2cWrite8(bmp_sensors[bmp_idx].bmp_address, BMP_REGISTER_RESET, BMP_CMND_RESET);
- break;
- default:
- break;
+ if (DeepSleepEnabled()) {
+ for (uint32_t bmp_idx = 0; bmp_idx < bmp_count; bmp_idx++) {
+ switch (bmp_sensors[bmp_idx].bmp_type) {
+ case BMP180_CHIPID:
+ case BMP280_CHIPID:
+ case BME280_CHIPID:
+ I2cWrite8(bmp_sensors[bmp_idx].bmp_address, BMP_REGISTER_RESET, BMP_CMND_RESET);
+ break;
+ default:
+ break;
+ }
}
}
}
From bf115647c314e94242a6eaafd080e08911b4c3bb Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Mon, 14 Sep 2020 16:14:58 +0200
Subject: [PATCH 21/23] Prep 8-bit GPIO to 16-bit GPIO change
Prep 8-bit GPIO to 16-bit GPIO change - phase 1
---
tasmota/tasmota_template.h | 2207 ++++++++++++++++++++----------------
1 file changed, 1215 insertions(+), 992 deletions(-)
diff --git a/tasmota/tasmota_template.h b/tasmota/tasmota_template.h
index 32a914f8f..944165eef 100644
--- a/tasmota/tasmota_template.h
+++ b/tasmota/tasmota_template.h
@@ -254,6 +254,229 @@ enum ProgramSelectablePins {
GPIO_USER, // User configurable needs to be 255
GPIO_MAX };
+/*
+// Indexed by UserSelectablePins to convert legacy (8-bit) GPIOs
+const uint16_t kGpioConvert[] PROGMEM = {
+ GPIO_NONE,
+ AGPIO(GPIO_DHT11), // DHT11
+ AGPIO(GPIO_DHT22), // DHT21, DHT22, AM2301, AM2302, AM2321
+ AGPIO(GPIO_SI7021), // iTead SI7021
+ AGPIO(GPIO_DSB), // Single wire DS18B20 or DS18S20
+ AGPIO(GPIO_I2C_SCL), // I2C SCL
+ AGPIO(GPIO_I2C_SDA), // I2C SDA
+ AGPIO(GPIO_WS2812), // WS2812 Led string
+ AGPIO(GPIO_IRSEND), // IR remote
+ AGPIO(GPIO_SWT1), // Switch
+ AGPIO(GPIO_SWT1) +1,
+ AGPIO(GPIO_SWT1) +2,
+ AGPIO(GPIO_SWT1) +3,
+ AGPIO(GPIO_SWT1) +4,
+ AGPIO(GPIO_SWT1) +5,
+ AGPIO(GPIO_SWT1) +6,
+ AGPIO(GPIO_SWT1) +7,
+ AGPIO(GPIO_KEY1), // Button
+ AGPIO(GPIO_KEY1) +1,
+ AGPIO(GPIO_KEY1) +2,
+ AGPIO(GPIO_KEY1) +3,
+ AGPIO(GPIO_REL1), // Relay
+ AGPIO(GPIO_REL1) +1,
+ AGPIO(GPIO_REL1) +2,
+ AGPIO(GPIO_REL1) +3,
+ AGPIO(GPIO_REL1) +4,
+ AGPIO(GPIO_REL1) +5,
+ AGPIO(GPIO_REL1) +6,
+ AGPIO(GPIO_REL1) +7,
+ AGPIO(GPIO_REL1_INV), // Relay inverted
+ AGPIO(GPIO_REL1_INV) +1,
+ AGPIO(GPIO_REL1_INV) +2,
+ AGPIO(GPIO_REL1_INV) +3,
+ AGPIO(GPIO_REL1_INV) +4,
+ AGPIO(GPIO_REL1_INV) +5,
+ AGPIO(GPIO_REL1_INV) +6,
+ AGPIO(GPIO_REL1_INV) +7,
+ AGPIO(GPIO_PWM1), // PWM
+ AGPIO(GPIO_PWM1) +1,
+ AGPIO(GPIO_PWM1) +2,
+ AGPIO(GPIO_PWM1) +3,
+ AGPIO(GPIO_PWM1) +4,
+ AGPIO(GPIO_CNTR1), // Counter
+ AGPIO(GPIO_CNTR1) +1,
+ AGPIO(GPIO_CNTR1) +2,
+ AGPIO(GPIO_CNTR1) +3,
+ AGPIO(GPIO_PWM1_INV), // PWM inverted
+ AGPIO(GPIO_PWM1_INV) +1,
+ AGPIO(GPIO_PWM1_INV) +2,
+ AGPIO(GPIO_PWM1_INV) +3,
+ AGPIO(GPIO_PWM1_INV) +4,
+ AGPIO(GPIO_IRRECV), // IR receive
+ AGPIO(GPIO_LED1), // Led
+ AGPIO(GPIO_LED1) +1,
+ AGPIO(GPIO_LED1) +2,
+ AGPIO(GPIO_LED1) +3,
+ AGPIO(GPIO_LED1_INV), // Led inverted
+ AGPIO(GPIO_LED1_INV) +1,
+ AGPIO(GPIO_LED1_INV) +2,
+ AGPIO(GPIO_LED1_INV) +3,
+ AGPIO(GPIO_MHZ_TXD), // MH-Z19 Serial interface
+ AGPIO(GPIO_MHZ_RXD),
+ AGPIO(GPIO_PZEM0XX_TX), // PZEM0XX Serial interface
+ AGPIO(GPIO_PZEM004_RX), // PZEM004T Serial interface
+ AGPIO(GPIO_SAIR_TX), // SenseAir Serial interface
+ AGPIO(GPIO_SAIR_RX), // SenseAir Serial interface
+ AGPIO(GPIO_SPI_CS), // SPI Chip Select
+ AGPIO(GPIO_SPI_DC), // SPI Data Direction
+ AGPIO(GPIO_BACKLIGHT), // Display backlight control
+ AGPIO(GPIO_PMS5003_RX), // Plantower PMS5003 Serial interface
+ AGPIO(GPIO_SDS0X1_RX), // Nova Fitness SDS011 Serial interface
+ AGPIO(GPIO_SBR_TX), // Serial Bridge Serial interface
+ AGPIO(GPIO_SBR_RX), // Serial Bridge Serial interface
+ AGPIO(GPIO_SR04_TRIG), // SR04 Tri/TXgger pin
+ AGPIO(GPIO_SR04_ECHO), // SR04 Ech/RXo pin
+ AGPIO(GPIO_SDM120_TX), // SDM120 Serial interface
+ AGPIO(GPIO_SDM120_RX), // SDM120 Serial interface
+ AGPIO(GPIO_SDM630_TX), // SDM630 Serial interface
+ AGPIO(GPIO_SDM630_RX), // SDM630 Serial interface
+ AGPIO(GPIO_TM16CLK), // TM1638 Clock
+ AGPIO(GPIO_TM16DIO), // TM1638 Data I/O
+ AGPIO(GPIO_TM16STB), // TM1638 Strobe
+ AGPIO(GPIO_SWT1_NP), // Switch no pullup
+ AGPIO(GPIO_SWT1_NP) +1,
+ AGPIO(GPIO_SWT1_NP) +2,
+ AGPIO(GPIO_SWT1_NP) +3,
+ AGPIO(GPIO_SWT1_NP) +4,
+ AGPIO(GPIO_SWT1_NP) +5,
+ AGPIO(GPIO_SWT1_NP) +6,
+ AGPIO(GPIO_SWT1_NP) +7,
+ AGPIO(GPIO_KEY1_NP), // Button no pullup
+ AGPIO(GPIO_KEY1_NP) +1,
+ AGPIO(GPIO_KEY1_NP) +2,
+ AGPIO(GPIO_KEY1_NP) +3,
+ AGPIO(GPIO_CNTR1_NP), // Counter no pullup
+ AGPIO(GPIO_CNTR1_NP) +1,
+ AGPIO(GPIO_CNTR1_NP) +2,
+ AGPIO(GPIO_CNTR1_NP) +3,
+ AGPIO(GPIO_PZEM016_RX), // PZEM-014,016 Serial Modbus interface
+ AGPIO(GPIO_PZEM017_RX), // PZEM-003,017 Serial Modbus interface
+ AGPIO(GPIO_MP3_DFR562), // RB-DFR-562, DFPlayer Mini MP3 Player Serial interface
+ AGPIO(GPIO_SDS0X1_TX), // Nova Fitness SDS011 Serial interface
+ AGPIO(GPIO_HX711_SCK), // HX711 Load Cell clock
+ AGPIO(GPIO_HX711_DAT), // HX711 Load Cell data
+ AGPIO(GPIO_TX2X_TXD_BLACK), // TX20/TX23 Transmission Pin
+ AGPIO(GPIO_RFSEND), // RF transmitter
+ AGPIO(GPIO_RFRECV), // RF receiver
+ AGPIO(GPIO_TUYA_TX), // Tuya Serial interface
+ AGPIO(GPIO_TUYA_RX), // Tuya Serial interface
+ AGPIO(GPIO_MGC3130_XFER),
+ AGPIO(GPIO_MGC3130_RESET),
+ AGPIO(GPIO_SSPI_MISO), // Software SPI Master Input Client Output
+ AGPIO(GPIO_SSPI_MOSI), // Software SPI Master Output Client Input
+ AGPIO(GPIO_SSPI_SCLK), // Software SPI Serial Clock
+ AGPIO(GPIO_SSPI_CS), // Software SPI Chip Select
+ AGPIO(GPIO_SSPI_DC), // Software SPI Data or Command
+ AGPIO(GPIO_RF_SENSOR), // Rf receiver with sensor decoding
+ AGPIO(GPIO_AZ_TXD), // AZ-Instrument 7798 CO2 datalogger Serial interface
+ AGPIO(GPIO_AZ_RXD), // AZ-Instrument 7798 CO2 datalogger Serial interface
+ AGPIO(GPIO_MAX31855CS), // MAX31855 Serial interface
+ AGPIO(GPIO_MAX31855CLK), // MAX31855 Serial interface
+ AGPIO(GPIO_MAX31855DO), // MAX31855 Serial interface
+ AGPIO(GPIO_KEY1_INV), // Button inverted
+ AGPIO(GPIO_KEY1_INV) +1,
+ AGPIO(GPIO_KEY1_INV) +2,
+ AGPIO(GPIO_KEY1_INV) +3,
+ AGPIO(GPIO_KEY1_INV_NP), // Button inverted no pullup
+ AGPIO(GPIO_KEY1_INV_NP) +1,
+ AGPIO(GPIO_KEY1_INV_NP) +2,
+ AGPIO(GPIO_KEY1_INV_NP) +3,
+ AGPIO(GPIO_NRG_SEL), // HLW8012/HLJ-01 Sel output (1 = Voltage)
+ AGPIO(GPIO_NRG_SEL_INV), // HLW8012/HLJ-01 Sel output (0 = Voltage)
+ AGPIO(GPIO_NRG_CF1), // HLW8012/HLJ-01 CF1 voltage / current
+ AGPIO(GPIO_HLW_CF), // HLW8012 CF power
+ AGPIO(GPIO_HJL_CF), // HJL-01/BL0937 CF power
+ AGPIO(GPIO_MCP39F5_TX), // MCP39F501 Serial interface (Shelly2)
+ AGPIO(GPIO_MCP39F5_RX), // MCP39F501 Serial interface (Shelly2)
+ AGPIO(GPIO_MCP39F5_RST), // MCP39F501 Reset (Shelly2)
+ AGPIO(GPIO_PN532_TXD), // PN532 HSU Tx
+ AGPIO(GPIO_PN532_RXD), // PN532 HSU Rx
+ AGPIO(GPIO_SM16716_CLK), // SM16716 CLOCK
+ AGPIO(GPIO_SM16716_DAT), // SM16716 DATA
+ AGPIO(GPIO_SM16716_SEL), // SM16716 SELECT
+ AGPIO(GPIO_DI), // my92x1 PWM input
+ AGPIO(GPIO_DCKI), // my92x1 CLK input
+ AGPIO(GPIO_CSE7766_TX), // CSE7766 Serial interface (S31 and Pow R2)
+ AGPIO(GPIO_CSE7766_RX), // CSE7766 Serial interface (S31 and Pow R2)
+ AGPIO(GPIO_ARIRFRCV), // AriLux RF Receive input
+ AGPIO(GPIO_TXD), // Serial interface
+ AGPIO(GPIO_RXD), // Serial interface
+ AGPIO(GPIO_ROT1A), // Rotary A Pin
+ AGPIO(GPIO_ROT1B), // Rotary B Pin
+ AGPIO(GPIO_ROT1A) +1, // Rotary A Pin
+ AGPIO(GPIO_ROT1B) +1, // Rotary B Pin
+ AGPIO(GPIO_HRE_CLOCK),
+ AGPIO(GPIO_HRE_DATA),
+ AGPIO(GPIO_ADE7953_IRQ), // ADE7953 IRQ
+ AGPIO(GPIO_LEDLNK), // Link led
+ AGPIO(GPIO_LEDLNK_INV), // Inverted link led
+ AGPIO(GPIO_ARIRFSEL), // Arilux RF Receive input selected
+ AGPIO(GPIO_BUZZER), // Buzzer
+ AGPIO(GPIO_BUZZER_INV), // Inverted buzzer
+ AGPIO(GPIO_OLED_RESET), // OLED Display Reset
+ AGPIO(GPIO_SOLAXX1_TX), // Solax Inverter tx pin
+ AGPIO(GPIO_SOLAXX1_RX), // Solax Inverter rx pin
+ AGPIO(GPIO_ZIGBEE_TX), // Zigbee Serial interface
+ AGPIO(GPIO_ZIGBEE_RX), // Zigbee Serial interface
+ AGPIO(GPIO_RDM6300_RX),
+ AGPIO(GPIO_IBEACON_TX),
+ AGPIO(GPIO_IBEACON_RX),
+ AGPIO(GPIO_A4988_DIR), // A4988 direction pin
+ AGPIO(GPIO_A4988_STP), // A4988 step pin
+ AGPIO(GPIO_A4988_ENA), // A4988 enabled pin
+ AGPIO(GPIO_A4988_MS1), // A4988 microstep pin1
+ AGPIO(GPIO_A4988_MS2), // A4988 microstep pin2
+ AGPIO(GPIO_A4988_MS3), // A4988 microstep pin3
+ AGPIO(GPIO_DDS2382_TX), // DDS2382 Serial interface
+ AGPIO(GPIO_DDS2382_RX), // DDS2382 Serial interface
+ AGPIO(GPIO_DDSU666_TX), // DDSU666 Serial interface
+ AGPIO(GPIO_DDSU666_RX), // DDSU666 Serial interface
+ AGPIO(GPIO_SM2135_CLK), // SM2135 CLOCK
+ AGPIO(GPIO_SM2135_DAT), // SM2135 DATA
+ AGPIO(GPIO_DEEPSLEEP),
+ AGPIO(GPIO_EXS_ENABLE), // EXS MCU Enable
+ AGPIO(GPIO_TASMOTACLIENT_TXD), // Tasmota Client TX
+ AGPIO(GPIO_TASMOTACLIENT_RXD), // Tasmota Client RX
+ AGPIO(GPIO_TASMOTACLIENT_RST), // Tasmota Client Reset
+ AGPIO(GPIO_TASMOTACLIENT_RST_INV), // Tasmota Client Reset Inverted
+ AGPIO(GPIO_HPMA_RX), // Honeywell HPMA115S0 Serial interface
+ AGPIO(GPIO_HPMA_TX), // Honeywell HPMA115S0 Serial interface
+ AGPIO(GPIO_GPS_RX), // GPS serial interface
+ AGPIO(GPIO_GPS_TX), // GPS serial interface
+ AGPIO(GPIO_DSB_OUT), // Pseudo Single wire DS18B20 or DS18S20
+ AGPIO(GPIO_DHT11_OUT), // Pseudo Single wire DHT11, DHT21, DHT22, AM2301, AM2302, AM2321
+ AGPIO(GPIO_HM10_RX), // GPS serial interface
+ AGPIO(GPIO_HM10_TX), // GPS serial interface
+ AGPIO(GPIO_LE01MR_RX), // F7F LE-01MR energy meter rx pin
+ AGPIO(GPIO_LE01MR_TX), // F7F LE-01MR energy meter tx pin
+ AGPIO(GPIO_CC1101_GDO0), // CC1101 pin for RX
+ AGPIO(GPIO_CC1101_GDO2), // CC1101 pin for RX
+ AGPIO(GPIO_HRXL_RX),
+ AGPIO(GPIO_ELECTRIQ_MOODL_TX),
+ AGPIO(GPIO_AS3935), // AS3935 IRQ Pin
+ AGPIO(GPIO_PMS5003_TX), // Plantower PMS5003 Serial interface
+ AGPIO(GPIO_BOILER_OT_RX),
+ AGPIO(GPIO_BOILER_OT_TX),
+ AGPIO(GPIO_WINDMETER_SPEED),
+ AGPIO(GPIO_BL0940_RX), // BL0940 Serial interface
+ AGPIO(GPIO_TCP_TX), // TCP Serial bridge
+ AGPIO(GPIO_TCP_RX), // TCP Serial bridge
+ AGPIO(GPIO_TELEINFO_RX),
+ AGPIO(GPIO_TELEINFO_ENABLE),
+ AGPIO(GPIO_LMT01), // LMT01, count pulses on GPIO
+ AGPIO(GPIO_IEM3000_TX), // IEM3000 Serial interface
+ AGPIO(GPIO_IEM3000_RX), // IEM3000 Serial interface
+ AGPIO(GPIO_ZIGBEE_RST), // Zigbee reset
+ AGPIO(GPIO_DYP_RX)
+};
+*/
+
// Text in webpage Module Parameters and commands GPIOS and GPIO
const char kSensorNames[] PROGMEM =
D_SENSOR_NONE "|"
@@ -1032,1065 +1255,1065 @@ const uint8_t kModuleTemplateList[MAXMODULE] PROGMEM = {
\*********************************************************************************************/
const mytmplt8266 kModules8266[TMP_MAXMODULE_8285] PROGMEM = {
- { // SONOFF_BASIC - Sonoff Basic (ESP8266)
- AGPIO(GPIO_KEY1), // GPIO00 Button
- AGPIO(GPIO_USER), // GPIO01 Serial RXD and Optional sensor
- AGPIO(GPIO_USER), // GPIO02 Only available on newer Sonoff Basic R2 V1
- AGPIO(GPIO_USER), // GPIO03 Serial TXD and Optional sensor
- AGPIO(GPIO_USER), // GPIO04 Optional sensor
- 0, // GPIO05
- // GPIO06 (SD_CLK Flash)
- // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
- // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
- // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
- // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
- // GPIO11 (SD_CMD Flash)
- AGPIO(GPIO_REL1), // GPIO12 Red Led and Relay (0 = Off, 1 = On)
- AGPIO(GPIO_LED1_INV), // GPIO13 Green Led (0 = On, 1 = Off) - Link and Power status
- AGPIO(GPIO_USER), // GPIO14 Optional sensor
- 0, // GPIO15
- 0, // GPIO16
- 0 // ADC0 Analog input
+ { // SONOFF_BASIC - Sonoff Basic (ESP8266)
+ GPIO_KEY1, // GPIO00 Button
+ GPIO_USER, // GPIO01 Serial RXD and Optional sensor
+ GPIO_USER, // GPIO02 Only available on newer Sonoff Basic R2 V1
+ GPIO_USER, // GPIO03 Serial TXD and Optional sensor
+ GPIO_USER, // GPIO04 Optional sensor
+ 0, // GPIO05
+ // GPIO06 (SD_CLK Flash)
+ // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
+ // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
+ // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
+ // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
+ // GPIO11 (SD_CMD Flash)
+ GPIO_REL1, // GPIO12 Red Led and Relay (0 = Off, 1 = On)
+ GPIO_LED1_INV, // GPIO13 Green Led (0 = On, 1 = Off) - Link and Power status
+ GPIO_USER, // GPIO14 Optional sensor
+ 0, // GPIO15
+ 0, // GPIO16
+ 0 // ADC0 Analog input
},
- { // SONOFF_SV - Sonoff SV (ESP8266)
- AGPIO(GPIO_KEY1), // GPIO00 Button
- AGPIO(GPIO_USER), // GPIO01 Serial RXD and Optional sensor
+ { // SONOFF_SV - Sonoff SV (ESP8266)
+ GPIO_KEY1, // GPIO00 Button
+ GPIO_USER, // GPIO01 Serial RXD and Optional sensor
0,
- AGPIO(GPIO_USER), // GPIO03 Serial TXD and Optional sensor
- AGPIO(GPIO_USER), // GPIO04 Optional sensor
- AGPIO(GPIO_USER), // GPIO05 Optional sensor
- // GPIO06 (SD_CLK Flash)
- // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
- // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
- // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
- // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
- // GPIO11 (SD_CMD Flash)
- AGPIO(GPIO_REL1), // GPIO12 Red Led and Relay (0 = Off, 1 = On)
- AGPIO(GPIO_LED1_INV), // GPIO13 Green Led (0 = On, 1 = Off) - Link and Power status
- AGPIO(GPIO_USER), // GPIO14 Optional sensor
+ GPIO_USER, // GPIO03 Serial TXD and Optional sensor
+ GPIO_USER, // GPIO04 Optional sensor
+ GPIO_USER, // GPIO05 Optional sensor
+ // GPIO06 (SD_CLK Flash)
+ // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
+ // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
+ // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
+ // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
+ // GPIO11 (SD_CMD Flash)
+ GPIO_REL1, // GPIO12 Red Led and Relay (0 = Off, 1 = On)
+ GPIO_LED1_INV, // GPIO13 Green Led (0 = On, 1 = Off) - Link and Power status
+ GPIO_USER, // GPIO14 Optional sensor
0, 0,
- AGPIO(ADC0_USER) // ADC0 Analog input
+ ADC0_USER // ADC0 Analog input
},
- { // SONOFF_DUAL - Sonoff Dual (ESP8266)
- AGPIO(GPIO_USER), // GPIO00 Pad
- AGPIO(GPIO_TXD), // GPIO01 Relay control
+ { // SONOFF_DUAL - Sonoff Dual (ESP8266)
+ GPIO_USER, // GPIO00 Pad
+ GPIO_TXD, // GPIO01 Relay control
0,
- AGPIO(GPIO_RXD), // GPIO03 Relay control
- AGPIO(GPIO_USER), // GPIO04 Optional sensor
+ GPIO_RXD, // GPIO03 Relay control
+ GPIO_USER, // GPIO04 Optional sensor
0,
- // GPIO06 (SD_CLK Flash)
- // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
- // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
- // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
- // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
- // GPIO11 (SD_CMD Flash)
+ // GPIO06 (SD_CLK Flash)
+ // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
+ // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
+ // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
+ // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
+ // GPIO11 (SD_CMD Flash)
0,
- AGPIO(GPIO_LED1_INV), // GPIO13 Blue Led (0 = On, 1 = Off) - Link and Power status
- AGPIO(GPIO_USER), // GPIO14 Optional sensor
+ GPIO_LED1_INV, // GPIO13 Blue Led (0 = On, 1 = Off) - Link and Power status
+ GPIO_USER, // GPIO14 Optional sensor
0, 0, 0
},
- { // SONOFF_POW - Sonoff Pow (ESP8266 - HLW8012)
- AGPIO(GPIO_KEY1), // GPIO00 Button
+ { // SONOFF_POW - Sonoff Pow (ESP8266 - HLW8012)
+ GPIO_KEY1, // GPIO00 Button
0, 0, 0, 0,
- AGPIO(GPIO_NRG_SEL), // GPIO05 HLW8012 Sel output (1 = Voltage)
- // GPIO06 (SD_CLK Flash)
- // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
- // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
- // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
- // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
- // GPIO11 (SD_CMD Flash)
- AGPIO(GPIO_REL1), // GPIO12 Red Led and Relay (0 = Off, 1 = On)
- AGPIO(GPIO_NRG_CF1), // GPIO13 HLW8012 CF1 voltage / current
- AGPIO(GPIO_HLW_CF), // GPIO14 HLW8012 CF power
- AGPIO(GPIO_LED1), // GPIO15 Blue Led (0 = On, 1 = Off) - Link and Power status
+ GPIO_NRG_SEL, // GPIO05 HLW8012 Sel output (1 = Voltage)
+ // GPIO06 (SD_CLK Flash)
+ // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
+ // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
+ // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
+ // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
+ // GPIO11 (SD_CMD Flash)
+ GPIO_REL1, // GPIO12 Red Led and Relay (0 = Off, 1 = On)
+ GPIO_NRG_CF1, // GPIO13 HLW8012 CF1 voltage / current
+ GPIO_HLW_CF, // GPIO14 HLW8012 CF power
+ GPIO_LED1, // GPIO15 Blue Led (0 = On, 1 = Off) - Link and Power status
0, 0
},
- { // SONOFF_LED - Sonoff LED (ESP8266)
- AGPIO(GPIO_KEY1), // GPIO00 Button
+ { // SONOFF_LED - Sonoff LED (ESP8266)
+ GPIO_KEY1, // GPIO00 Button
0, 0, 0,
- AGPIO(GPIO_USER), // GPIO04 Optional sensor (PWM3 Green)
- AGPIO(GPIO_USER), // GPIO05 Optional sensor (PWM2 Red)
- // GPIO06 (SD_CLK Flash)
- // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
- // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
- // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
- // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
- // GPIO11 (SD_CMD Flash)
- AGPIO(GPIO_PWM1), // GPIO12 Cold light (PWM0 Cold)
- AGPIO(GPIO_LED1_INV), // GPIO13 Blue Led (0 = On, 1 = Off) - Link and Power status
- AGPIO(GPIO_PWM1) +1, // GPIO14 Warm light (PWM1 Warm)
- AGPIO(GPIO_USER), // GPIO15 Optional sensor (PWM4 Blue)
+ GPIO_USER, // GPIO04 Optional sensor (PWM3 Green)
+ GPIO_USER, // GPIO05 Optional sensor (PWM2 Red)
+ // GPIO06 (SD_CLK Flash)
+ // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
+ // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
+ // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
+ // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
+ // GPIO11 (SD_CMD Flash)
+ GPIO_PWM1, // GPIO12 Cold light (PWM0 Cold)
+ GPIO_LED1_INV, // GPIO13 Blue Led (0 = On, 1 = Off) - Link and Power status
+ GPIO_PWM2, // GPIO14 Warm light (PWM1 Warm)
+ GPIO_USER, // GPIO15 Optional sensor (PWM4 Blue)
0, 0
},
- { // ELECTRODRAGON - ElectroDragon IoT Relay Board (ESP8266)
- AGPIO(GPIO_KEY1) +1, // GPIO00 Button 2
- AGPIO(GPIO_USER), // GPIO01 Serial RXD and Optional sensor
- AGPIO(GPIO_KEY1), // GPIO02 Button 1
- AGPIO(GPIO_USER), // GPIO03 Serial TXD and Optional sensor
- AGPIO(GPIO_USER), // GPIO04 Optional sensor
- AGPIO(GPIO_USER), // GPIO05 Optional sensor
- // GPIO06 (SD_CLK Flash)
- // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
- // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
- // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
- // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
- // GPIO11 (SD_CMD Flash)
- AGPIO(GPIO_REL1) +1, // GPIO12 Red Led and Relay 2 (0 = Off, 1 = On)
- AGPIO(GPIO_REL1), // GPIO13 Red Led and Relay 1 (0 = Off, 1 = On)
- AGPIO(GPIO_USER), // GPIO14 Optional sensor
- AGPIO(GPIO_USER), // GPIO15 Optional sensor
- AGPIO(GPIO_LED1), // GPIO16 Green/Blue Led (1 = On, 0 = Off) - Link and Power status
- AGPIO(ADC0_USER) // ADC0 A0 Analog input
+ { // ELECTRODRAGON - ElectroDragon IoT Relay Board (ESP8266)
+ GPIO_KEY2, // GPIO00 Button 2
+ GPIO_USER, // GPIO01 Serial RXD and Optional sensor
+ GPIO_KEY1, // GPIO02 Button 1
+ GPIO_USER, // GPIO03 Serial TXD and Optional sensor
+ GPIO_USER, // GPIO04 Optional sensor
+ GPIO_USER, // GPIO05 Optional sensor
+ // GPIO06 (SD_CLK Flash)
+ // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
+ // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
+ // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
+ // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
+ // GPIO11 (SD_CMD Flash)
+ GPIO_REL2, // GPIO12 Red Led and Relay 2 (0 = Off, 1 = On)
+ GPIO_REL1, // GPIO13 Red Led and Relay 1 (0 = Off, 1 = On)
+ GPIO_USER, // GPIO14 Optional sensor
+ GPIO_USER, // GPIO15 Optional sensor
+ GPIO_LED1, // GPIO16 Green/Blue Led (1 = On, 0 = Off) - Link and Power status
+ ADC0_USER // ADC0 A0 Analog input
},
- { // EXS_RELAY - ES-Store Latching relay(s) (ESP8266)
- // https://ex-store.de/ESP8266-WiFi-Relay-V31
- // V3.1 Module Pin 1 VCC 3V3, Module Pin 6 GND
- // https://ex-store.de/2-Kanal-WiFi-WLan-Relay-V5-Blackline-fuer-Unterputzmontage
- AGPIO(GPIO_USER), // GPIO00 V3.1 Module Pin 8 - V5.0 Module Pin 4
- AGPIO(GPIO_USER), // GPIO01 UART0_TXD V3.1 Module Pin 2 - V5.0 Module Pin 3
- AGPIO(GPIO_USER), // GPIO02 V3.1 Module Pin 7
- AGPIO(GPIO_USER), // GPIO03 UART0_RXD V3.1 Module Pin 3
- AGPIO(GPIO_USER), // GPIO04 V3.1 Module Pin 10 - V5.0 Module Pin 2
- AGPIO(GPIO_USER), // GPIO05 V3.1 Module Pin 9 - V5.0 Module Pin 1
- // GPIO06 (SD_CLK Flash)
- // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
- // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
- // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
- // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
- // GPIO11 (SD_CMD Flash)
- AGPIO(GPIO_REL1), // GPIO12 Relay1 ( 1 = Off)
- AGPIO(GPIO_REL1) +1, // GPIO13 Relay1 ( 1 = On)
- AGPIO(GPIO_USER), // GPIO14 V3.1 Module Pin 5 - V5.0 GPIO_REL3_INV Relay2 ( 1 = Off)
- AGPIO(GPIO_LED1), // GPIO15 V5.0 LED1 - Link and Power status
- AGPIO(GPIO_USER), // GPIO16 V3.1 Module Pin 4 - V5.0 GPIO_REL4_INV Relay2 ( 1 = On)
+ { // EXS_RELAY - ES-Store Latching relay(s) (ESP8266)
+ // https://ex-store.de/ESP8266-WiFi-Relay-V31
+ // V3.1 Module Pin 1 VCC 3V3, Module Pin 6 GND
+ // https://ex-store.de/2-Kanal-WiFi-WLan-Relay-V5-Blackline-fuer-Unterputzmontage
+ GPIO_USER, // GPIO00 V3.1 Module Pin 8 - V5.0 Module Pin 4
+ GPIO_USER, // GPIO01 UART0_TXD V3.1 Module Pin 2 - V5.0 Module Pin 3
+ GPIO_USER, // GPIO02 V3.1 Module Pin 7
+ GPIO_USER, // GPIO03 UART0_RXD V3.1 Module Pin 3
+ GPIO_USER, // GPIO04 V3.1 Module Pin 10 - V5.0 Module Pin 2
+ GPIO_USER, // GPIO05 V3.1 Module Pin 9 - V5.0 Module Pin 1
+ // GPIO06 (SD_CLK Flash)
+ // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
+ // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
+ // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
+ // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
+ // GPIO11 (SD_CMD Flash)
+ GPIO_REL1, // GPIO12 Relay1 ( 1 = Off)
+ GPIO_REL2, // GPIO13 Relay1 ( 1 = On)
+ GPIO_USER, // GPIO14 V3.1 Module Pin 5 - V5.0 GPIO_REL3_INV Relay2 ( 1 = Off)
+ GPIO_LED1, // GPIO15 V5.0 LED1 - Link and Power status
+ GPIO_USER, // GPIO16 V3.1 Module Pin 4 - V5.0 GPIO_REL4_INV Relay2 ( 1 = On)
0
},
- { // WION - Indoor Tap (ESP8266)
- // https://www.amazon.com/gp/product/B00ZYLUBJU/ref=s9_acsd_al_bw_c_x_3_w
- AGPIO(GPIO_USER), // GPIO00 Optional sensor (pm clock)
+ { // WION - Indoor Tap (ESP8266)
+ // https://www.amazon.com/gp/product/B00ZYLUBJU/ref=s9_acsd_al_bw_c_x_3_w
+ GPIO_USER, // GPIO00 Optional sensor (pm clock)
0,
- AGPIO(GPIO_LED1), // GPIO02 Green Led (1 = On, 0 = Off) - Link and Power status
+ GPIO_LED1, // GPIO02 Green Led (1 = On, 0 = Off) - Link and Power status
0, 0, 0,
- // GPIO06 (SD_CLK Flash)
- // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
- // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
- // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
- // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
- // GPIO11 (SD_CMD Flash)
- AGPIO(GPIO_USER), // GPIO12 Optional sensor (pm data)
- AGPIO(GPIO_KEY1), // GPIO13 Button
+ // GPIO06 (SD_CLK Flash)
+ // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
+ // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
+ // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
+ // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
+ // GPIO11 (SD_CMD Flash)
+ GPIO_USER, // GPIO12 Optional sensor (pm data)
+ GPIO_KEY1, // GPIO13 Button
0,
- AGPIO(GPIO_REL1), // GPIO15 Relay (0 = Off, 1 = On)
+ GPIO_REL1, // GPIO15 Relay (0 = Off, 1 = On)
0, 0
},
- { // SONOFF_DEV - Sonoff Dev (ESP8266)
- AGPIO(GPIO_KEY1), // GPIO00 E-FW Button
- AGPIO(GPIO_USER), // GPIO01 TX Serial RXD and Optional sensor
+ { // SONOFF_DEV - Sonoff Dev (ESP8266)
+ GPIO_KEY1, // GPIO00 E-FW Button
+ GPIO_USER, // GPIO01 TX Serial RXD and Optional sensor
0, // GPIO02
- AGPIO(GPIO_USER), // GPIO03 RX Serial TXD and Optional sensor
- AGPIO(GPIO_USER), // GPIO04 Optional sensor
- AGPIO(GPIO_USER), // GPIO05 Optional sensor
- // GPIO06 (SD_CLK Flash)
- // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
- // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
- // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
- // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
- // GPIO11 (SD_CMD Flash)
- AGPIO(GPIO_USER), // GPIO12
- AGPIO(GPIO_USER), // GPIO13 BLUE LED
- AGPIO(GPIO_USER), // GPIO14 Optional sensor
- 0, // GPIO15
- 0, // GPIO16
- AGPIO(ADC0_USER) // ADC0 A0 Analog input
+ GPIO_USER, // GPIO03 RX Serial TXD and Optional sensor
+ GPIO_USER, // GPIO04 Optional sensor
+ GPIO_USER, // GPIO05 Optional sensor
+ // GPIO06 (SD_CLK Flash)
+ // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
+ // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
+ // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
+ // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
+ // GPIO11 (SD_CMD Flash)
+ GPIO_USER, // GPIO12
+ GPIO_USER, // GPIO13 BLUE LED
+ GPIO_USER, // GPIO14 Optional sensor
+ 0, // GPIO15
+ 0, // GPIO16
+ ADC0_USER // ADC0 A0 Analog input
},
- { // H801 - Lixada H801 Wifi (ESP8266)
- AGPIO(GPIO_USER), // GPIO00 E-FW Button
- AGPIO(GPIO_LED1), // GPIO01 Green LED - Link and Power status
- AGPIO(GPIO_USER), // GPIO02 TX and Optional sensor - Pin next to TX on the PCB
- AGPIO(GPIO_USER), // GPIO03 RX and Optional sensor - Pin next to GND on the PCB
- AGPIO(GPIO_PWM1) +4, // GPIO04 W2 - PWM5
- AGPIO(GPIO_LED1_INV) +1, // GPIO05 Red LED
- // GPIO06 (SD_CLK Flash)
- // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
- // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
- // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
- // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
- // GPIO11 (SD_CMD Flash)
- AGPIO(GPIO_PWM1) +2, // GPIO12 Blue
- AGPIO(GPIO_PWM1) +1, // GPIO13 Green
- AGPIO(GPIO_PWM1) +3, // GPIO14 W1 - PWM4
- AGPIO(GPIO_PWM1), // GPIO15 Red
+ { // H801 - Lixada H801 Wifi (ESP8266)
+ GPIO_USER, // GPIO00 E-FW Button
+ GPIO_LED1, // GPIO01 Green LED - Link and Power status
+ GPIO_USER, // GPIO02 TX and Optional sensor - Pin next to TX on the PCB
+ GPIO_USER, // GPIO03 RX and Optional sensor - Pin next to GND on the PCB
+ GPIO_PWM5, // GPIO04 W2 - PWM5
+ GPIO_LED2_INV, // GPIO05 Red LED
+ // GPIO06 (SD_CLK Flash)
+ // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
+ // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
+ // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
+ // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
+ // GPIO11 (SD_CMD Flash)
+ GPIO_PWM3, // GPIO12 Blue
+ GPIO_PWM2, // GPIO13 Green
+ GPIO_PWM4, // GPIO14 W1 - PWM4
+ GPIO_PWM1, // GPIO15 Red
0, 0
},
- { // SONOFF_SC - onoff SC (ESP8266)
- AGPIO(GPIO_KEY1), // GPIO00 Button
- AGPIO(GPIO_TXD), // GPIO01 RXD to ATMEGA328P
- AGPIO(GPIO_USER), // GPIO02 Optional sensor
- AGPIO(GPIO_RXD), // GPIO03 TXD to ATMEGA328P
+ { // SONOFF_SC - onoff SC (ESP8266)
+ GPIO_KEY1, // GPIO00 Button
+ GPIO_TXD, // GPIO01 RXD to ATMEGA328P
+ GPIO_USER, // GPIO02 Optional sensor
+ GPIO_RXD, // GPIO03 TXD to ATMEGA328P
0, 0,
- // GPIO06 (SD_CLK Flash)
- // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
- // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
- // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
- // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
- // GPIO11 (SD_CMD Flash)
+ // GPIO06 (SD_CLK Flash)
+ // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
+ // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
+ // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
+ // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
+ // GPIO11 (SD_CMD Flash)
0,
- AGPIO(GPIO_LED1_INV), // GPIO13 Green Led (0 = On, 1 = Off) - Link and Power status
+ GPIO_LED1_INV, // GPIO13 Green Led (0 = On, 1 = Off) - Link and Power status
0, 0, 0, 0
},
- { // SONOFF_BN - Sonoff BN-SZ01 Ceiling led (ESP8285)
+ { // SONOFF_BN - Sonoff BN-SZ01 Ceiling led (ESP8285)
0, 0, 0, 0, 0, 0,
- // GPIO06 (SD_CLK Flash)
- // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
- // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
- // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
- // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
- // GPIO11 (SD_CMD Flash)
- AGPIO(GPIO_PWM1), // GPIO12 Light
- AGPIO(GPIO_LED1_INV), // GPIO13 Red Led (0 = On, 1 = Off) - Link and Power status
+ // GPIO06 (SD_CLK Flash)
+ // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
+ // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
+ // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
+ // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
+ // GPIO11 (SD_CMD Flash)
+ GPIO_PWM1, // GPIO12 Light
+ GPIO_LED1_INV, // GPIO13 Red Led (0 = On, 1 = Off) - Link and Power status
0, 0, 0, 0
},
- { // HUAFAN_SS - Hua Fan Smart Socket (ESP8266) - like Sonoff Pow
- AGPIO(GPIO_LEDLNK_INV), // GPIO00 Blue Led (0 = On, 1 = Off) - Link status
+ { // HUAFAN_SS - Hua Fan Smart Socket (ESP8266) - like Sonoff Pow
+ GPIO_LEDLNK_INV, // GPIO00 Blue Led (0 = On, 1 = Off) - Link status
0, 0,
- AGPIO(GPIO_LED1_INV), // GPIO03 Red Led (0 = On, 1 = Off) - Power status
- AGPIO(GPIO_KEY1), // GPIO04 Button
- AGPIO(GPIO_REL1_INV), // GPIO05 Relay (0 = On, 1 = Off)
- // GPIO06 (SD_CLK Flash)
- // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
- // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
- // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
- // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
- // GPIO11 (SD_CMD Flash)
- AGPIO(GPIO_NRG_CF1), // GPIO12 HLW8012 CF1 voltage / current
- AGPIO(GPIO_NRG_SEL), // GPIO13 HLW8012 Sel output (1 = Voltage)
- AGPIO(GPIO_HLW_CF), // GPIO14 HLW8012 CF power
+ GPIO_LED1_INV, // GPIO03 Red Led (0 = On, 1 = Off) - Power status
+ GPIO_KEY1, // GPIO04 Button
+ GPIO_REL1_INV, // GPIO05 Relay (0 = On, 1 = Off)
+ // GPIO06 (SD_CLK Flash)
+ // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
+ // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
+ // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
+ // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
+ // GPIO11 (SD_CMD Flash)
+ GPIO_NRG_CF1, // GPIO12 HLW8012 CF1 voltage / current
+ GPIO_NRG_SEL, // GPIO13 HLW8012 Sel output (1 = Voltage)
+ GPIO_HLW_CF, // GPIO14 HLW8012 CF power
0, 0, 0
},
- { // SONOFF_BRIDGE - Sonoff RF Bridge 433 (ESP8285)
- AGPIO(GPIO_KEY1), // GPIO00 Button
- AGPIO(GPIO_TXD), // GPIO01 RF bridge control
- AGPIO(GPIO_USER), // GPIO02 Optional sensor
- AGPIO(GPIO_RXD), // GPIO03 RF bridge control
- AGPIO(GPIO_USER), // GPIO04 Optional sensor
- AGPIO(GPIO_USER), // GPIO05 Optional sensor
- // GPIO06 (SD_CLK Flash)
- // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
- // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
- // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
- // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
- // GPIO11 (SD_CMD Flash)
- AGPIO(GPIO_USER), // GPIO12 Optional sensor
- AGPIO(GPIO_LED1_INV), // GPIO13 Blue Led (0 = On, 1 = Off) - Link and Power status
- AGPIO(GPIO_USER), // GPIO14 Optional sensor
+ { // SONOFF_BRIDGE - Sonoff RF Bridge 433 (ESP8285)
+ GPIO_KEY1, // GPIO00 Button
+ GPIO_TXD, // GPIO01 RF bridge control
+ GPIO_USER, // GPIO02 Optional sensor
+ GPIO_RXD, // GPIO03 RF bridge control
+ GPIO_USER, // GPIO04 Optional sensor
+ GPIO_USER, // GPIO05 Optional sensor
+ // GPIO06 (SD_CLK Flash)
+ // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
+ // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
+ // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
+ // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
+ // GPIO11 (SD_CMD Flash)
+ GPIO_USER, // GPIO12 Optional sensor
+ GPIO_LED1_INV, // GPIO13 Blue Led (0 = On, 1 = Off) - Link and Power status
+ GPIO_USER, // GPIO14 Optional sensor
0, 0, 0
},
- { // SONOFF_B1 - Sonoff B1 (ESP8285 - my9231)
- AGPIO(GPIO_KEY1), // GPIO00 Pad
- AGPIO(GPIO_USER), // GPIO01 Serial RXD and Optional sensor pad
- AGPIO(GPIO_USER), // GPIO02 Optional sensor SDA pad
- AGPIO(GPIO_USER), // GPIO03 Serial TXD and Optional sensor pad
+ { // SONOFF_B1 - Sonoff B1 (ESP8285 - my9231)
+ GPIO_KEY1, // GPIO00 Pad
+ GPIO_USER, // GPIO01 Serial RXD and Optional sensor pad
+ GPIO_USER, // GPIO02 Optional sensor SDA pad
+ GPIO_USER, // GPIO03 Serial TXD and Optional sensor pad
0, 0,
- // GPIO06 (SD_CLK Flash)
- // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
- // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
- // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
- // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
- // GPIO11 (SD_CMD Flash)
- AGPIO(GPIO_DI), // GPIO12 my9231 DI
+ // GPIO06 (SD_CLK Flash)
+ // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
+ // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
+ // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
+ // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
+ // GPIO11 (SD_CMD Flash)
+ GPIO_DI, // GPIO12 my9231 DI
0,
- AGPIO(GPIO_DCKI), // GPIO14 my9231 DCKI
+ GPIO_DCKI, // GPIO14 my9231 DCKI
0, 0, 0
},
- { // AILIGHT - Ai-Thinker RGBW led (ESP8266 - my9291)
- AGPIO(GPIO_KEY1), // GPIO00 Pad
- AGPIO(GPIO_USER), // GPIO01 Serial RXD and Optional sensor pad
- AGPIO(GPIO_USER), // GPIO02 Optional sensor SDA pad
- AGPIO(GPIO_USER), // GPIO03 Serial TXD and Optional sensor pad
+ { // AILIGHT - Ai-Thinker RGBW led (ESP8266 - my9291)
+ GPIO_KEY1, // GPIO00 Pad
+ GPIO_USER, // GPIO01 Serial RXD and Optional sensor pad
+ GPIO_USER, // GPIO02 Optional sensor SDA pad
+ GPIO_USER, // GPIO03 Serial TXD and Optional sensor pad
0, 0,
- // GPIO06 (SD_CLK Flash)
- // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
- // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
- // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
- // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
- // GPIO11 (SD_CMD Flash)
+ // GPIO06 (SD_CLK Flash)
+ // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
+ // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
+ // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
+ // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
+ // GPIO11 (SD_CMD Flash)
0,
- AGPIO(GPIO_DI), // GPIO13 my9291 DI
+ GPIO_DI, // GPIO13 my9291 DI
0,
- AGPIO(GPIO_DCKI), // GPIO15 my9291 DCKI
+ GPIO_DCKI, // GPIO15 my9291 DCKI
0, 0
},
- { // SONOFF_T11 - Sonoff T1 1CH (ESP8285)
- AGPIO(GPIO_KEY1), // GPIO00 Button 1
- AGPIO(GPIO_USER), // GPIO01 Serial RXD and Optional sensor
- AGPIO(GPIO_USER), // GPIO02 Optional Sensor (J3 Pin 5)
- AGPIO(GPIO_USER), // GPIO03 Serial TXD and Optional sensor
+ { // SONOFF_T11 - Sonoff T1 1CH (ESP8285)
+ GPIO_KEY1, // GPIO00 Button 1
+ GPIO_USER, // GPIO01 Serial RXD and Optional sensor
+ GPIO_USER, // GPIO02 Optional Sensor (J3 Pin 5)
+ GPIO_USER, // GPIO03 Serial TXD and Optional sensor
0, 0,
- // GPIO06 (SD_CLK Flash)
- // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
- // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
- // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
- // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
- // GPIO11 (SD_CMD Flash)
- AGPIO(GPIO_REL1), // GPIO12 Blue Led and Relay 1 (0 = Off, 1 = On)
- AGPIO(GPIO_LED1_INV), // GPIO13 Blue Led (0 = On, 1 = Off) - Link and Power status
+ // GPIO06 (SD_CLK Flash)
+ // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
+ // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
+ // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
+ // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
+ // GPIO11 (SD_CMD Flash)
+ GPIO_REL1, // GPIO12 Blue Led and Relay 1 (0 = Off, 1 = On)
+ GPIO_LED1_INV, // GPIO13 Blue Led (0 = On, 1 = Off) - Link and Power status
0, 0, 0, 0
},
- { // SUPLA1 - Supla Espablo (ESP8266)
- // http://www.wykop.pl/ramka/3325399/diy-supla-do-puszki-instalacyjnej-podtynkowej-supla-org/
- 0, // GPIO00 Flash jumper
- AGPIO(GPIO_USER), // GPIO01 Serial RXD and Optional sensor
+ { // SUPLA1 - Supla Espablo (ESP8266)
+ // http://www.wykop.pl/ramka/3325399/diy-supla-do-puszki-instalacyjnej-podtynkowej-supla-org/
+ 0, // GPIO00 Flash jumper
+ GPIO_USER, // GPIO01 Serial RXD and Optional sensor
#ifdef USE_DS18x20
- AGPIO(GPIO_DSB), // GPIO02 DS18B20 sensor
+ GPIO_DSB, // GPIO02 DS18B20 sensor
#else
- AGPIO(GPIO_USER), // GPIO02 Optional sensor
+ GPIO_USER, // GPIO02 Optional sensor
#endif
- AGPIO(GPIO_USER), // GPIO03 Serial TXD and Optional sensor
- AGPIO(GPIO_KEY1), // GPIO04 Button 1
- AGPIO(GPIO_REL1), // GPIO05 Relay 1 (0 = Off, 1 = On)
- // GPIO06 (SD_CLK Flash)
- // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
- // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
- // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
- // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
- // GPIO11 (SD_CMD Flash)
- AGPIO(GPIO_USER), // GPIO12 Optional sensor
- AGPIO(GPIO_REL1) +1, // GPIO13 Relay 2 (0 = Off, 1 = On)
- AGPIO(GPIO_USER), // GPIO14 Optional sensor
+ GPIO_USER, // GPIO03 Serial TXD and Optional sensor
+ GPIO_KEY1, // GPIO04 Button 1
+ GPIO_REL1, // GPIO05 Relay 1 (0 = Off, 1 = On)
+ // GPIO06 (SD_CLK Flash)
+ // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
+ // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
+ // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
+ // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
+ // GPIO11 (SD_CMD Flash)
+ GPIO_USER, // GPIO12 Optional sensor
+ GPIO_REL2, // GPIO13 Relay 2 (0 = Off, 1 = On)
+ GPIO_USER, // GPIO14 Optional sensor
0,
- AGPIO(GPIO_LED1), // GPIO16 Led (1 = On, 0 = Off) - Link and Power status
- AGPIO(ADC0_USER) // ADC0 A0 Analog input
+ GPIO_LED1, // GPIO16 Led (1 = On, 0 = Off) - Link and Power status
+ ADC0_USER // ADC0 A0 Analog input
},
- { // WITTY - Witty Cloud Dev Board (ESP8266)
- // https://www.aliexpress.com/item/ESP8266-serial-WIFI-Witty-cloud-Development-Board-ESP-12F-module-MINI-nodemcu/32643464555.html
- AGPIO(GPIO_USER), // GPIO00 D3 flash push button on interface board
- AGPIO(GPIO_USER), // GPIO01 Serial RXD and Optional sensor
- AGPIO(GPIO_LED1_INV), // GPIO02 D4 Blue Led (0 = On, 1 = Off) on ESP-12F - Link and Power status
- AGPIO(GPIO_USER), // GPIO03 Serial TXD and Optional sensor
- AGPIO(GPIO_KEY1), // GPIO04 D2 push button on ESP-12F board
- AGPIO(GPIO_USER), // GPIO05 D1 optional sensor
- // GPIO06 (SD_CLK Flash)
- // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
- // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
- // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
- // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
- // GPIO11 (SD_CMD Flash)
- AGPIO(GPIO_PWM1) +1, // GPIO12 D6 RGB LED Green
- AGPIO(GPIO_PWM1) +2, // GPIO13 D7 RGB LED Blue
- AGPIO(GPIO_USER), // GPIO14 D5 optional sensor
- AGPIO(GPIO_PWM1), // GPIO15 D8 RGB LED Red
- AGPIO(GPIO_USER), // GPIO16 D0 optional sensor
- AGPIO(ADC0_USER) // ADC0 A0 Light sensor / Requires USE_ADC_VCC in user_config.h to be disabled
+ { // WITTY - Witty Cloud Dev Board (ESP8266)
+ // https://www.aliexpress.com/item/ESP8266-serial-WIFI-Witty-cloud-Development-Board-ESP-12F-module-MINI-nodemcu/32643464555.html
+ GPIO_USER, // GPIO00 D3 flash push button on interface board
+ GPIO_USER, // GPIO01 Serial RXD and Optional sensor
+ GPIO_LED1_INV, // GPIO02 D4 Blue Led (0 = On, 1 = Off) on ESP-12F - Link and Power status
+ GPIO_USER, // GPIO03 Serial TXD and Optional sensor
+ GPIO_KEY1, // GPIO04 D2 push button on ESP-12F board
+ GPIO_USER, // GPIO05 D1 optional sensor
+ // GPIO06 (SD_CLK Flash)
+ // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
+ // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
+ // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
+ // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
+ // GPIO11 (SD_CMD Flash)
+ GPIO_PWM2, // GPIO12 D6 RGB LED Green
+ GPIO_PWM3, // GPIO13 D7 RGB LED Blue
+ GPIO_USER, // GPIO14 D5 optional sensor
+ GPIO_PWM1, // GPIO15 D8 RGB LED Red
+ GPIO_USER, // GPIO16 D0 optional sensor
+ ADC0_USER // ADC0 A0 Light sensor / Requires USE_ADC_VCC in user_config.h to be disabled
},
- { // YUNSHAN - Yunshan Wifi Relay (ESP8266)
- // https://www.ebay.com/p/Esp8266-220v-10a-Network-Relay-WiFi-Module/1369583381
- // Schematics and Info https://ucexperiment.wordpress.com/2016/12/18/yunshan-esp8266-250v-15a-acdc-network-wifi-relay-module/
- 0, // GPIO00 Flash jumper - Module Pin 8
- AGPIO(GPIO_USER), // GPIO01 Serial RXD and Optional sensor - Module Pin 2
- AGPIO(GPIO_LED1_INV), // GPIO02 Blue Led (0 = On, 1 = Off) on ESP-12F - Module Pin 7 - Link and Power status
- AGPIO(GPIO_USER), // GPIO03 Serial TXD and Optional sensor - Module Pin 3
- AGPIO(GPIO_REL1), // GPIO04 Red Led and Relay (0 = Off, 1 = On) - Module Pin 10
- AGPIO(GPIO_KEY1), // GPIO05 Blue Led and OptoCoupler input - Module Pin 9
- // GPIO06 (SD_CLK Flash)
- // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
- // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
- // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
- // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
- // GPIO11 (SD_CMD Flash)
+ { // YUNSHAN - Yunshan Wifi Relay (ESP8266)
+ // https://www.ebay.com/p/Esp8266-220v-10a-Network-Relay-WiFi-Module/1369583381
+ // Schematics and Info https://ucexperiment.wordpress.com/2016/12/18/yunshan-esp8266-250v-15a-acdc-network-wifi-relay-module/
+ 0, // GPIO00 Flash jumper - Module Pin 8
+ GPIO_USER, // GPIO01 Serial RXD and Optional sensor - Module Pin 2
+ GPIO_LED1_INV, // GPIO02 Blue Led (0 = On, 1 = Off) on ESP-12F - Module Pin 7 - Link and Power status
+ GPIO_USER, // GPIO03 Serial TXD and Optional sensor - Module Pin 3
+ GPIO_REL1, // GPIO04 Red Led and Relay (0 = Off, 1 = On) - Module Pin 10
+ GPIO_KEY1, // GPIO05 Blue Led and OptoCoupler input - Module Pin 9
+ // GPIO06 (SD_CLK Flash)
+ // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
+ // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
+ // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
+ // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
+ // GPIO11 (SD_CMD Flash)
0, 0, 0, 0, 0, 0
},
- { // MAGICHOME - Magic Home (aka Flux-light) (ESP8266) and Arilux LC10 (ESP8285)
- // https://www.aliexpress.com/item/Magic-Home-Mini-RGB-RGBW-Wifi-Controller-For-Led-Strip-Panel-light-Timing-Function-16million-colors/32686853650.html
+ { // MAGICHOME - Magic Home (aka Flux-light) (ESP8266) and Arilux LC10 (ESP8285)
+ // https://www.aliexpress.com/item/Magic-Home-Mini-RGB-RGBW-Wifi-Controller-For-Led-Strip-Panel-light-Timing-Function-16million-colors/32686853650.html
0,
- AGPIO(GPIO_USER), // GPIO01 Serial RXD and Optional sensor
- AGPIO(GPIO_LED1_INV), // GPIO02 Blue onboard LED - Link and Power status
- AGPIO(GPIO_USER), // GPIO03 Serial TXD and Optional sensor
- AGPIO(GPIO_ARIRFRCV), // GPIO04 IR or RF receiver (optional) (Arilux LC10)
- AGPIO(GPIO_PWM1) +1, // GPIO05 RGB LED Green
- // GPIO06 (SD_CLK Flash)
- // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
- // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
- // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
- // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
- // GPIO11 (SD_CMD Flash)
- AGPIO(GPIO_PWM1) +2, // GPIO12 RGB LED Blue
- AGPIO(GPIO_USER), // GPIO13 RGBW LED White (optional - set to PWM4 for Cold White or Warm White as used on Arilux LC10)
- AGPIO(GPIO_PWM1), // GPIO14 RGB LED Red
- AGPIO(GPIO_ARIRFSEL), // GPIO15 RF receiver control (Arilux LC10)
+ GPIO_USER, // GPIO01 Serial RXD and Optional sensor
+ GPIO_LED1_INV, // GPIO02 Blue onboard LED - Link and Power status
+ GPIO_USER, // GPIO03 Serial TXD and Optional sensor
+ GPIO_ARIRFRCV, // GPIO04 IR or RF receiver (optional) (Arilux LC10)
+ GPIO_PWM2, // GPIO05 RGB LED Green
+ // GPIO06 (SD_CLK Flash)
+ // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
+ // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
+ // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
+ // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
+ // GPIO11 (SD_CMD Flash)
+ GPIO_PWM3, // GPIO12 RGB LED Blue
+ GPIO_USER, // GPIO13 RGBW LED White (optional - set to PWM4 for Cold White or Warm White as used on Arilux LC10)
+ GPIO_PWM1, // GPIO14 RGB LED Red
+ GPIO_ARIRFSEL, // GPIO15 RF receiver control (Arilux LC10)
0, 0
},
- { // LUANIHVIO - ESP8266_HVIO
- // https://luani.de/projekte/esp8266-hvio/
- 0, // GPIO00 Flash jumper
- AGPIO(GPIO_USER), // GPIO01 Serial RXD and Optional sensor
- AGPIO(GPIO_USER), // GPIO02 Optional sensor / I2C SDA pad
- AGPIO(GPIO_USER), // GPIO03 Serial TXD and Optional sensor
- AGPIO(GPIO_REL1), // GPIO04 Relay 1 (0 = Off, 1 = On)
- AGPIO(GPIO_REL1) +1, // GPIO05 Relay 2 (0 = Off, 1 = On)
- // GPIO06 (SD_CLK Flash)
- // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
- // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
- // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
- // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
- // GPIO11 (SD_CMD Flash)
- AGPIO(GPIO_SWT1), // GPIO12 External input 1 (0 = On, 1 = Off)
- AGPIO(GPIO_SWT1) +1, // GPIO13 External input 2 (0 = On, 1 = Off)
- AGPIO(GPIO_USER), // GPIO14 Optional sensor / I2C SCL pad
- AGPIO(GPIO_LED1), // GPIO15 Led (1 = On, 0 = Off) - Link and Power status
+ { // LUANIHVIO - ESP8266_HVIO
+ // https://luani.de/projekte/esp8266-hvio/
+ 0, // GPIO00 Flash jumper
+ GPIO_USER, // GPIO01 Serial RXD and Optional sensor
+ GPIO_USER, // GPIO02 Optional sensor / I2C SDA pad
+ GPIO_USER, // GPIO03 Serial TXD and Optional sensor
+ GPIO_REL1, // GPIO04 Relay 1 (0 = Off, 1 = On)
+ GPIO_REL2, // GPIO05 Relay 2 (0 = Off, 1 = On)
+ // GPIO06 (SD_CLK Flash)
+ // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
+ // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
+ // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
+ // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
+ // GPIO11 (SD_CMD Flash)
+ GPIO_SWT1, // GPIO12 External input 1 (0 = On, 1 = Off)
+ GPIO_SWT2, // GPIO13 External input 2 (0 = On, 1 = Off)
+ GPIO_USER, // GPIO14 Optional sensor / I2C SCL pad
+ GPIO_LED1, // GPIO15 Led (1 = On, 0 = Off) - Link and Power status
0,
- AGPIO(ADC0_USER) // ADC0 A0 Analog input
+ ADC0_USER // ADC0 A0 Analog input
},
- { // KMC_70011 - KMC 70011
- // https://www.amazon.com/KMC-Timing-Monitoring-Network-125V-240V/dp/B06XRX2GTQ
- AGPIO(GPIO_KEY1), // GPIO00 Button
+ { // KMC_70011 - KMC 70011
+ // https://www.amazon.com/KMC-Timing-Monitoring-Network-125V-240V/dp/B06XRX2GTQ
+ GPIO_KEY1, // GPIO00 Button
0, 0, 0,
- AGPIO(GPIO_HLW_CF), // GPIO04 HLW8012 CF power
- AGPIO(GPIO_NRG_CF1), // GPIO05 HLW8012 CF1 voltage / current
- // GPIO06 (SD_CLK Flash)
- // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
- // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
- // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
- // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
- // GPIO11 (SD_CMD Flash)
- AGPIO(GPIO_NRG_SEL), // GPIO12 HLW8012 SEL (1 = Voltage)
- AGPIO(GPIO_LED1_INV), // GPIO13 Green Led - Link and Power status
- AGPIO(GPIO_REL1), // GPIO14 Relay
+ GPIO_HLW_CF, // GPIO04 HLW8012 CF power
+ GPIO_NRG_CF1, // GPIO05 HLW8012 CF1 voltage / current
+ // GPIO06 (SD_CLK Flash)
+ // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
+ // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
+ // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
+ // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
+ // GPIO11 (SD_CMD Flash)
+ GPIO_NRG_SEL, // GPIO12 HLW8012 SEL (1 = Voltage)
+ GPIO_LED1_INV, // GPIO13 Green Led - Link and Power status
+ GPIO_REL1, // GPIO14 Relay
0, 0, 0
},
- { // ARILUX_LC01 - Arilux AL-LC01 (ESP8285)
- // https://www.banggood.com/nl/ARILUX-AL-LC01-Super-Mini-LED-WIFI-Smart-RGB-Controller-For-RGB-LED-Strip-Light-DC-9-12V-p-1058603.html
- // (PwmFrequency 1111Hz)
- AGPIO(GPIO_KEY1), // GPIO00 Optional Button
- AGPIO(GPIO_USER), // GPIO01 Serial RXD and Optional sensor
- AGPIO(GPIO_ARIRFSEL), // GPIO02 RF receiver control
- AGPIO(GPIO_USER), // GPIO03 Serial TXD and Optional sensor
- AGPIO(GPIO_ARIRFRCV), // GPIO04 IR or RF receiver (optional)
- AGPIO(GPIO_PWM1), // GPIO05 RGB LED Red
- // GPIO06 (SD_CLK Flash)
- // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
- // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
- // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
- // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
- // GPIO11 (SD_CMD Flash)
- AGPIO(GPIO_PWM1) +1, // GPIO12 RGB LED Green
- AGPIO(GPIO_PWM1) +2, // GPIO13 RGB LED Blue
- AGPIO(GPIO_USER), // GPIO14 RGBW LED White (optional - set to PWM4 for Cold White or Warm White)
+ { // ARILUX_LC01 - Arilux AL-LC01 (ESP8285)
+ // https://www.banggood.com/nl/ARILUX-AL-LC01-Super-Mini-LED-WIFI-Smart-RGB-Controller-For-RGB-LED-Strip-Light-DC-9-12V-p-1058603.html
+ // (PwmFrequency 1111Hz)
+ GPIO_KEY1, // GPIO00 Optional Button
+ GPIO_USER, // GPIO01 Serial RXD and Optional sensor
+ GPIO_ARIRFSEL, // GPIO02 RF receiver control
+ GPIO_USER, // GPIO03 Serial TXD and Optional sensor
+ GPIO_ARIRFRCV, // GPIO04 IR or RF receiver (optional)
+ GPIO_PWM1, // GPIO05 RGB LED Red
+ // GPIO06 (SD_CLK Flash)
+ // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
+ // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
+ // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
+ // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
+ // GPIO11 (SD_CMD Flash)
+ GPIO_PWM2, // GPIO12 RGB LED Green
+ GPIO_PWM3, // GPIO13 RGB LED Blue
+ GPIO_USER, // GPIO14 RGBW LED White (optional - set to PWM4 for Cold White or Warm White)
0, 0, 0
},
- { // ARILUX_LC11 - Arilux AL-LC11 (ESP8266)
- // https://www.banggood.com/nl/ARILUX-AL-LC11-Super-Mini-LED-WIFI-APP-Controller-RF-Remote-Control-For-RGBWW-LED-Strip-DC9-28V-p-1085112.html
- // (PwmFrequency 540Hz)
- AGPIO(GPIO_KEY1), // GPIO00 Optional Button
- AGPIO(GPIO_USER), // GPIO01 Serial RXD and Optional sensor
- AGPIO(GPIO_ARIRFSEL), // GPIO02 RF receiver control
- AGPIO(GPIO_USER), // GPIO03 Serial TXD and Optional sensor
- AGPIO(GPIO_PWM1) +1, // GPIO04 RGB LED Green
- AGPIO(GPIO_PWM1), // GPIO05 RGB LED Red
- // GPIO06 (SD_CLK Flash)
- // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
- // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
- // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
- // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
- // GPIO11 (SD_CMD Flash)
- AGPIO(GPIO_PWM1) +4, // GPIO12 RGBCW LED Warm
- AGPIO(GPIO_PWM1) +3, // GPIO13 RGBW LED Cold
- AGPIO(GPIO_PWM1) +2, // GPIO14 RGB LED Blue
- AGPIO(GPIO_ARIRFRCV), // GPIO15 RF receiver input
+ { // ARILUX_LC11 - Arilux AL-LC11 (ESP8266)
+ // https://www.banggood.com/nl/ARILUX-AL-LC11-Super-Mini-LED-WIFI-APP-Controller-RF-Remote-Control-For-RGBWW-LED-Strip-DC9-28V-p-1085112.html
+ // (PwmFrequency 540Hz)
+ GPIO_KEY1, // GPIO00 Optional Button
+ GPIO_USER, // GPIO01 Serial RXD and Optional sensor
+ GPIO_ARIRFSEL, // GPIO02 RF receiver control
+ GPIO_USER, // GPIO03 Serial TXD and Optional sensor
+ GPIO_PWM2, // GPIO04 RGB LED Green
+ GPIO_PWM1, // GPIO05 RGB LED Red
+ // GPIO06 (SD_CLK Flash)
+ // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
+ // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
+ // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
+ // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
+ // GPIO11 (SD_CMD Flash)
+ GPIO_PWM5, // GPIO12 RGBCW LED Warm
+ GPIO_PWM4, // GPIO13 RGBW LED Cold
+ GPIO_PWM3, // GPIO14 RGB LED Blue
+ GPIO_ARIRFRCV, // GPIO15 RF receiver input
0, 0
},
- { // ARILUX_LC06 - Arilux AL-LC06 (ESP8285)
- // https://www.banggood.com/ARILUX-AL-LC06-LED-WIFI-Smartphone-Controller-Romote-5-Channels-DC12-24V-For-RGBWW-Strip-light-p-1061476.html
- AGPIO(GPIO_KEY1), // GPIO00 Optional Button
- AGPIO(GPIO_USER), // GPIO01 Serial RXD and Optional sensor
- AGPIO(GPIO_USER), // GPIO02 Empty pad
- AGPIO(GPIO_USER), // GPIO03 Serial TXD and Optional sensor
- AGPIO(GPIO_USER), // GPIO04 W2 - PWM5
+ { // ARILUX_LC06 - Arilux AL-LC06 (ESP8285)
+ // https://www.banggood.com/ARILUX-AL-LC06-LED-WIFI-Smartphone-Controller-Romote-5-Channels-DC12-24V-For-RGBWW-Strip-light-p-1061476.html
+ GPIO_KEY1, // GPIO00 Optional Button
+ GPIO_USER, // GPIO01 Serial RXD and Optional sensor
+ GPIO_USER, // GPIO02 Empty pad
+ GPIO_USER, // GPIO03 Serial TXD and Optional sensor
+ GPIO_USER, // GPIO04 W2 - PWM5
0,
- // GPIO06 (SD_CLK Flash)
- // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
- // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
- // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
- // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
- // GPIO11 (SD_CMD Flash)
- AGPIO(GPIO_PWM1) +1, // GPIO12 RGB LED Green
- AGPIO(GPIO_PWM1) +2, // GPIO13 RGB LED Blue
- AGPIO(GPIO_PWM1), // GPIO14 RGB LED Red
- AGPIO(GPIO_USER), // GPIO15 RGBW LED White
+ // GPIO06 (SD_CLK Flash)
+ // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
+ // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
+ // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
+ // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
+ // GPIO11 (SD_CMD Flash)
+ GPIO_PWM2, // GPIO12 RGB LED Green
+ GPIO_PWM3, // GPIO13 RGB LED Blue
+ GPIO_PWM1, // GPIO14 RGB LED Red
+ GPIO_USER, // GPIO15 RGBW LED White
0, 0
},
- { // ZENGGE_ZF_WF017 - Zenggee ZJ-WF017-A (ESP12S))
- // https://www.ebay.com/p/Smartphone-Android-IOS-WiFi-Music-Controller-for-RGB-5050-3528-LED-Strip-Light/534446632?_trksid=p2047675.l2644
- AGPIO(GPIO_KEY1), // GPIO00 Optional Button
+ { // ZENGGE_ZF_WF017 - Zenggee ZJ-WF017-A (ESP12S))
+ // https://www.ebay.com/p/Smartphone-Android-IOS-WiFi-Music-Controller-for-RGB-5050-3528-LED-Strip-Light/534446632?_trksid=p2047675.l2644
+ GPIO_KEY1, // GPIO00 Optional Button
0,
- AGPIO(GPIO_USER), // GPIO02 Empty pad
+ GPIO_USER, // GPIO02 Empty pad
0,
- AGPIO(GPIO_USER), // GPIO04 W2 - PWM5
+ GPIO_USER, // GPIO04 W2 - PWM5
0,
- // GPIO06 (SD_CLK Flash)
- // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
- // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
- // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
- // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
- // GPIO11 (SD_CMD Flash)
- AGPIO(GPIO_PWM1) +1, // GPIO12 RGB LED Green
- AGPIO(GPIO_PWM1), // GPIO13 RGB LED Red
- AGPIO(GPIO_PWM1) +2, // GPIO14 RGB LED Blue
+ // GPIO06 (SD_CLK Flash)
+ // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
+ // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
+ // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
+ // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
+ // GPIO11 (SD_CMD Flash)
+ GPIO_PWM2, // GPIO12 RGB LED Green
+ GPIO_PWM1, // GPIO13 RGB LED Red
+ GPIO_PWM3, // GPIO14 RGB LED Blue
0, 0, 0
},
- { // SONOFF_POW_R2 - Sonoff Pow R2 (ESP8285 - CSE7766)
- AGPIO(GPIO_KEY1), // GPIO00 Button
- AGPIO(GPIO_CSE7766_TX), // GPIO01 Serial RXD 4800 baud 8E1 CSE7766 energy sensor
+ { // SONOFF_POW_R2 - Sonoff Pow R2 (ESP8285 - CSE7766)
+ GPIO_KEY1, // GPIO00 Button
+ GPIO_CSE7766_TX, // GPIO01 Serial RXD 4800 baud 8E1 CSE7766 energy sensor
0,
- AGPIO(GPIO_CSE7766_RX), // GPIO03 Serial TXD
+ GPIO_CSE7766_RX, // GPIO03 Serial TXD
0, 0,
- // GPIO06 (SD_CLK Flash)
- // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
- // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
- // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
- // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
- // GPIO11 (SD_CMD Flash)
- AGPIO(GPIO_REL1), // GPIO12 Red Led and Relay (0 = Off, 1 = On)
- AGPIO(GPIO_LED1_INV), // GPIO13 Blue Led (0 = On, 1 = Off) - Link and Power status
+ // GPIO06 (SD_CLK Flash)
+ // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
+ // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
+ // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
+ // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
+ // GPIO11 (SD_CMD Flash)
+ GPIO_REL1, // GPIO12 Red Led and Relay (0 = Off, 1 = On)
+ GPIO_LED1_INV, // GPIO13 Blue Led (0 = On, 1 = Off) - Link and Power status
0, 0, 0, 0
},
- { // BLITZWOLF_BWSHP - BlitzWolf BW-SHP2 and BW-SHP6 (ESP8285 - BL0937 or HJL-01 Energy Monitoring)
- // https://www.banggood.com/BlitzWolf-BW-SHP2-Smart-WIFI-Socket-EU-Plug-220V-16A-Work-with-Amazon-Alexa-Google-Assistant-p-1292899.html
- // https://www.amazon.de/Steckdose-Homecube-intelligente-Verbrauchsanzeige-funktioniert/dp/B076Q2LKHG/ref=sr_1_fkmr0_1
- // https://www.amazon.de/Intelligente-Stromverbrauch-Fernsteurung-Schaltbare-Energieklasse/dp/B076WZQS4S/ref=sr_1_1
- // https://www.aliexpress.com/store/product/BlitzWolf-BW-SHP6-EU-Plug-Metering-Version-WIFI-Smart-Socket-220V-240V-10A-Work-with-Amazon/1965360_32945504669.html
- AGPIO(GPIO_LED1_INV), // GPIO00 Red Led (1 = On, 0 = Off) - Power status
- AGPIO(GPIO_USER), // GPIO01 Serial RXD and Optional sensor
- AGPIO(GPIO_LEDLNK_INV), // GPIO02 Blue Led (1 = On, 0 = Off) - Link status
- AGPIO(GPIO_USER), // GPIO03 Serial TXD and Optional sensor
+ { // BLITZWOLF_BWSHP - BlitzWolf BW-SHP2 and BW-SHP6 (ESP8285 - BL0937 or HJL-01 Energy Monitoring)
+ // https://www.banggood.com/BlitzWolf-BW-SHP2-Smart-WIFI-Socket-EU-Plug-220V-16A-Work-with-Amazon-Alexa-Google-Assistant-p-1292899.html
+ // https://www.amazon.de/Steckdose-Homecube-intelligente-Verbrauchsanzeige-funktioniert/dp/B076Q2LKHG/ref=sr_1_fkmr0_1
+ // https://www.amazon.de/Intelligente-Stromverbrauch-Fernsteurung-Schaltbare-Energieklasse/dp/B076WZQS4S/ref=sr_1_1
+ // https://www.aliexpress.com/store/product/BlitzWolf-BW-SHP6-EU-Plug-Metering-Version-WIFI-Smart-Socket-220V-240V-10A-Work-with-Amazon/1965360_32945504669.html
+ GPIO_LED1_INV, // GPIO00 Red Led (1 = On, 0 = Off) - Power status
+ GPIO_USER, // GPIO01 Serial RXD and Optional sensor
+ GPIO_LEDLNK_INV, // GPIO02 Blue Led (1 = On, 0 = Off) - Link status
+ GPIO_USER, // GPIO03 Serial TXD and Optional sensor
0,
- AGPIO(GPIO_HJL_CF), // GPIO05 BL0937 or HJL-01 CF power
- // GPIO06 (SD_CLK Flash)
- // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
- // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
- // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
- // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
- // GPIO11 (SD_CMD Flash)
- AGPIO(GPIO_NRG_SEL_INV), // GPIO12 BL0937 or HJL-01 Sel output (0 = Voltage)
- AGPIO(GPIO_KEY1), // GPIO13 Button
- AGPIO(GPIO_NRG_CF1), // GPIO14 BL0937 or HJL-01 CF1 current / voltage
- AGPIO(GPIO_REL1), // GPIO15 Relay (0 = Off, 1 = On)
+ GPIO_HJL_CF, // GPIO05 BL0937 or HJL-01 CF power
+ // GPIO06 (SD_CLK Flash)
+ // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
+ // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
+ // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
+ // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
+ // GPIO11 (SD_CMD Flash)
+ GPIO_NRG_SEL_INV, // GPIO12 BL0937 or HJL-01 Sel output (0 = Voltage)
+ GPIO_KEY1, // GPIO13 Button
+ GPIO_NRG_CF1, // GPIO14 BL0937 or HJL-01 CF1 current / voltage
+ GPIO_REL1, // GPIO15 Relay (0 = Off, 1 = On)
0, 0
},
- { // SHELLY1 - Shelly1 Open Source (ESP8266 - 2MB) - https://shelly.cloud/shelly1-open-source/
- AGPIO(GPIO_USER), // GPIO00 - Can be changed to GPIO_USER, only if Shelly is powered with 12V DC
- AGPIO(GPIO_USER), // GPIO01 Serial RXD - Can be changed to GPIO_USER, only if Shelly is powered with 12V DC
+ { // SHELLY1 - Shelly1 Open Source (ESP8266 - 2MB) - https://shelly.cloud/shelly1-open-source/
+ GPIO_USER, // GPIO00 - Can be changed to GPIO_USER, only if Shelly is powered with 12V DC
+ GPIO_USER, // GPIO01 Serial RXD - Can be changed to GPIO_USER, only if Shelly is powered with 12V DC
0,
- AGPIO(GPIO_USER), // GPIO03 Serial TXD - Can be changed to GPIO_USER, only if Shelly is powered with 12V DC
- AGPIO(GPIO_REL1), // GPIO04 Relay (0 = Off, 1 = On)
- AGPIO(GPIO_SWT1_NP), // GPIO05 SW pin
- // GPIO06 (SD_CLK Flash)
- // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
- // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
- // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
- // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
- // GPIO11 (SD_CMD Flash)
+ GPIO_USER, // GPIO03 Serial TXD - Can be changed to GPIO_USER, only if Shelly is powered with 12V DC
+ GPIO_REL1, // GPIO04 Relay (0 = Off, 1 = On)
+ GPIO_SWT1_NP, // GPIO05 SW pin
+ // GPIO06 (SD_CLK Flash)
+ // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
+ // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
+ // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
+ // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
+ // GPIO11 (SD_CMD Flash)
0, 0, 0, 0, 0, 0
},
- { // SHELLY2 - Shelly2 (ESP8266 - 2MB) - https://shelly.cloud/shelly2/
+ { // SHELLY2 - Shelly2 (ESP8266 - 2MB) - https://shelly.cloud/shelly2/
0,
- AGPIO(GPIO_MCP39F5_TX), // GPIO01 MCP39F501 Serial input
+ GPIO_MCP39F5_TX, // GPIO01 MCP39F501 Serial input
0,
- AGPIO(GPIO_MCP39F5_RX), // GPIO03 MCP39F501 Serial output
- AGPIO(GPIO_REL1), // GPIO04
- AGPIO(GPIO_REL1) +1, // GPIO05
- // GPIO06 (SD_CLK Flash)
- // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
- // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
- // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
- // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
- // GPIO11 (SD_CMD Flash)
- AGPIO(GPIO_SWT1), // GPIO12
+ GPIO_MCP39F5_RX, // GPIO03 MCP39F501 Serial output
+ GPIO_REL1, // GPIO04
+ GPIO_REL2, // GPIO05
+ // GPIO06 (SD_CLK Flash)
+ // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
+ // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
+ // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
+ // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
+ // GPIO11 (SD_CMD Flash)
+ GPIO_SWT1, // GPIO12
0,
- AGPIO(GPIO_SWT1) +1, // GPIO14
- AGPIO(GPIO_MCP39F5_RST), // GPIO15 MCP39F501 Reset
+ GPIO_SWT2, // GPIO14
+ GPIO_MCP39F5_RST, // GPIO15 MCP39F501 Reset
0,
0
},
- { // PHILIPS - Xiaomi Philips bulb (ESP8266)
+ { // PHILIPS - Xiaomi Philips bulb (ESP8266)
0, 0, 0, 0, 0, 0,
- // GPIO06 (SD_CLK Flash)
- // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
- // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
- // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
- // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
- // GPIO11 (SD_CMD Flash)
- AGPIO(GPIO_PWM1) +1, // GPIO12 cold/warm light
+ // GPIO06 (SD_CLK Flash)
+ // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
+ // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
+ // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
+ // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
+ // GPIO11 (SD_CMD Flash)
+ GPIO_PWM2, // GPIO12 cold/warm light
0, 0,
- AGPIO(GPIO_PWM1), // GPIO15 light intensity
+ GPIO_PWM1, // GPIO15 light intensity
0, 0
},
- { // NEO_COOLCAM - Neo Coolcam (ESP8266)
- // https://www.banggood.com/NEO-COOLCAM-WiFi-Mini-Smart-Plug-APP-Remote-Control-Timing-Smart-Socket-EU-Plug-p-1288562.html?cur_warehouse=CN
+ { // NEO_COOLCAM - Neo Coolcam (ESP8266)
+ // https://www.banggood.com/NEO-COOLCAM-WiFi-Mini-Smart-Plug-APP-Remote-Control-Timing-Smart-Socket-EU-Plug-p-1288562.html?cur_warehouse=CN
0, 0, 0, 0,
- AGPIO(GPIO_LED1_INV), // GPIO04 Red Led (0 = On, 1 = Off) - Link and Power status
+ GPIO_LED1_INV, // GPIO04 Red Led (0 = On, 1 = Off) - Link and Power status
0,
- // GPIO06 (SD_CLK Flash)
- // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
- // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
- // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
- // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
- // GPIO11 (SD_CMD Flash)
- AGPIO(GPIO_REL1), // GPIO12 Red Led and Relay (0 = Off, 1 = On)
- AGPIO(GPIO_KEY1), // GPIO13 Button
+ // GPIO06 (SD_CLK Flash)
+ // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
+ // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
+ // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
+ // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
+ // GPIO11 (SD_CMD Flash)
+ GPIO_REL1, // GPIO12 Red Led and Relay (0 = Off, 1 = On)
+ GPIO_KEY1, // GPIO13 Button
0, 0, 0, 0
},
- { // ESP_SWITCH - Michael Haustein 4 channel wall switch (ESP07 = ESP8266)
- // Use rules for further actions like - rule on power1#state do publish cmnd/other_device/power %value% endon
- AGPIO(GPIO_KEY1) +1, // GPIO00 Button 2
- AGPIO(GPIO_USER), // GPIO01 Serial RXD and Optional sensor
- AGPIO(GPIO_REL1_INV) +2, // GPIO02 Yellow Led 3 (0 = On, 1 = Off)
- AGPIO(GPIO_USER), // GPIO03 Serial TXD and Optional sensor
- AGPIO(GPIO_KEY1), // GPIO04 Button 1
- AGPIO(GPIO_REL1_INV) +1, // GPIO05 Red Led 2 (0 = On, 1 = Off)
- // GPIO06 (SD_CLK Flash)
- // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
- // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
- // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
- // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
- // GPIO11 (SD_CMD Flash)
- AGPIO(GPIO_REL1_INV) +3, // GPIO12 Blue Led 4 (0 = On, 1 = Off)
- AGPIO(GPIO_KEY1) +3, // GPIO13 Button 4
- AGPIO(GPIO_KEY1) +2, // GPIO14 Button 3
- AGPIO(GPIO_LED1), // GPIO15 Optional sensor
- AGPIO(GPIO_REL1_INV), // GPIO16 Green Led 1 (0 = On, 1 = Off)
+ { // ESP_SWITCH - Michael Haustein 4 channel wall switch (ESP07 = ESP8266)
+ // Use rules for further actions like - rule on power1#state do publish cmnd/other_device/power %value% endon
+ GPIO_KEY2, // GPIO00 Button 2
+ GPIO_USER, // GPIO01 Serial RXD and Optional sensor
+ GPIO_REL3_INV, // GPIO02 Yellow Led 3 (0 = On, 1 = Off)
+ GPIO_USER, // GPIO03 Serial TXD and Optional sensor
+ GPIO_KEY1, // GPIO04 Button 1
+ GPIO_REL2_INV, // GPIO05 Red Led 2 (0 = On, 1 = Off)
+ // GPIO06 (SD_CLK Flash)
+ // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
+ // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
+ // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
+ // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
+ // GPIO11 (SD_CMD Flash)
+ GPIO_REL4_INV, // GPIO12 Blue Led 4 (0 = On, 1 = Off)
+ GPIO_KEY4, // GPIO13 Button 4
+ GPIO_KEY3, // GPIO14 Button 3
+ GPIO_LED1, // GPIO15 Optional sensor
+ GPIO_REL1_INV, // GPIO16 Green Led 1 (0 = On, 1 = Off)
0
},
- { // OBI - OBI socket (ESP8266) - https://www.obi.de/hausfunksteuerung/wifi-stecker-schuko/p/2291706
- AGPIO(GPIO_USER), // GPIO00
- AGPIO(GPIO_USER), // GPIO01 Serial RXD
+ { // OBI - OBI socket (ESP8266) - https://www.obi.de/hausfunksteuerung/wifi-stecker-schuko/p/2291706
+ GPIO_USER, // GPIO00
+ GPIO_USER, // GPIO01 Serial RXD
0,
- AGPIO(GPIO_USER), // GPIO03 Serial TXD
- AGPIO(GPIO_LED1), // GPIO04 Blue LED - Link and Power status
- AGPIO(GPIO_REL1), // GPIO05 (Relay OFF, but used as Relay Switch)
- // GPIO06 (SD_CLK Flash)
- // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
- // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
- // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
- // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
- // GPIO11 (SD_CMD Flash)
- AGPIO(GPIO_LED1) +2, // GPIO12 (Relay ON, but set to LOW, so we can switch with GPIO05)
- AGPIO(GPIO_USER), // GPIO13
- AGPIO(GPIO_KEY1), // GPIO14 Button
+ GPIO_USER, // GPIO03 Serial TXD
+ GPIO_LED1, // GPIO04 Blue LED - Link and Power status
+ GPIO_REL1, // GPIO05 (Relay OFF, but used as Relay Switch)
+ // GPIO06 (SD_CLK Flash)
+ // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
+ // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
+ // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
+ // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
+ // GPIO11 (SD_CMD Flash)
+ GPIO_LED3, // GPIO12 (Relay ON, but set to LOW, so we can switch with GPIO05)
+ GPIO_USER, // GPIO13
+ GPIO_KEY1, // GPIO14 Button
0,
- AGPIO(GPIO_USER), // GPIO16
- AGPIO(ADC0_USER) // ADC0 A0 Analog input
+ GPIO_USER, // GPIO16
+ ADC0_USER // ADC0 A0 Analog input
},
- { // TECKIN - https://www.amazon.de/gp/product/B07D5V139R
+ { // TECKIN - https://www.amazon.de/gp/product/B07D5V139R
0,
- AGPIO(GPIO_KEY1), // GPIO01 Serial TXD and Button
+ GPIO_KEY1, // GPIO01 Serial TXD and Button
0,
- AGPIO(GPIO_LED1_INV), // GPIO03 Serial RXD and Red Led (0 = On, 1 = Off) - Power status
- AGPIO(GPIO_HJL_CF), // GPIO04 BL0937 or HJL-01 CF power
- AGPIO(GPIO_NRG_CF1), // GPIO05 BL0937 or HJL-01 CF1 current / voltage
- // GPIO06 (SD_CLK Flash)
- // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
- // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
- // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
- // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
- // GPIO11 (SD_CMD Flash)
- AGPIO(GPIO_NRG_SEL_INV), // GPIO12 BL0937 or HJL-01 Sel output (0 = Voltage)
- AGPIO(GPIO_LEDLNK_INV), // GPIO13 Blue Led (0 = On, 1 = Off) - Link status
- AGPIO(GPIO_REL1), // GPIO14 Relay (0 = Off, 1 = On)
+ GPIO_LED1_INV, // GPIO03 Serial RXD and Red Led (0 = On, 1 = Off) - Power status
+ GPIO_HJL_CF, // GPIO04 BL0937 or HJL-01 CF power
+ GPIO_NRG_CF1, // GPIO05 BL0937 or HJL-01 CF1 current / voltage
+ // GPIO06 (SD_CLK Flash)
+ // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
+ // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
+ // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
+ // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
+ // GPIO11 (SD_CMD Flash)
+ GPIO_NRG_SEL_INV, // GPIO12 BL0937 or HJL-01 Sel output (0 = Voltage)
+ GPIO_LEDLNK_INV, // GPIO13 Blue Led (0 = On, 1 = Off) - Link status
+ GPIO_REL1, // GPIO14 Relay (0 = Off, 1 = On)
0, 0, 0
},
- { // APLIC_WDP303075 - Aplic WDP 303075 (ESP8285 - HLW8012 Energy Monitoring)
- // https://www.amazon.de/dp/B07CNWVNJ2
+ { // APLIC_WDP303075 - Aplic WDP 303075 (ESP8285 - HLW8012 Energy Monitoring)
+ // https://www.amazon.de/dp/B07CNWVNJ2
0, 0, 0,
- AGPIO(GPIO_KEY1), // GPIO03 Button
- AGPIO(GPIO_HLW_CF), // GPIO04 HLW8012 CF power
- AGPIO(GPIO_NRG_CF1), // GPIO05 HLW8012 CF1 current / voltage
- // GPIO06 (SD_CLK Flash)
- // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
- // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
- // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
- // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
- // GPIO11 (SD_CMD Flash)
- AGPIO(GPIO_NRG_SEL_INV), // GPIO12 HLW8012 CF Sel output (0 = Voltage)
- AGPIO(GPIO_LED1_INV), // GPIO13 LED (0 = On, 1 = Off) - Link and Power status
- AGPIO(GPIO_REL1), // GPIO14 Relay SRU 5VDC SDA (0 = Off, 1 = On )
+ GPIO_KEY1, // GPIO03 Button
+ GPIO_HLW_CF, // GPIO04 HLW8012 CF power
+ GPIO_NRG_CF1, // GPIO05 HLW8012 CF1 current / voltage
+ // GPIO06 (SD_CLK Flash)
+ // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
+ // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
+ // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
+ // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
+ // GPIO11 (SD_CMD Flash)
+ GPIO_NRG_SEL_INV, // GPIO12 HLW8012 CF Sel output (0 = Voltage)
+ GPIO_LED1_INV, // GPIO13 LED (0 = On, 1 = Off) - Link and Power status
+ GPIO_REL1, // GPIO14 Relay SRU 5VDC SDA (0 = Off, 1 = On )
0, 0, 0
},
- { // TUYA_DIMMER - Tuya MCU device (ESP8266 w/ separate MCU)
- // https://www.amazon.com/gp/product/B07CTNSZZ8/ref=oh_aui_detailpage_o00_s00?ie=UTF8&psc=1
- AGPIO(GPIO_USER), // Virtual Button (controlled by MCU)
- AGPIO(GPIO_USER), // GPIO01 MCU serial control
- AGPIO(GPIO_USER),
- AGPIO(GPIO_USER), // GPIO03 MCU serial control
- AGPIO(GPIO_USER),
- AGPIO(GPIO_USER),
- // GPIO06 (SD_CLK Flash)
- // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
- // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
- // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
- // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
- // GPIO11 (SD_CMD Flash)
- AGPIO(GPIO_USER),
- AGPIO(GPIO_USER),
- AGPIO(GPIO_USER), // GPIO14 Green Led
- AGPIO(GPIO_USER),
- AGPIO(GPIO_USER),
+ { // TUYA_DIMMER - Tuya MCU device (ESP8266 w/ separate MCU)
+ // https://www.amazon.com/gp/product/B07CTNSZZ8/ref=oh_aui_detailpage_o00_s00?ie=UTF8&psc=1
+ GPIO_USER, // Virtual Button (controlled by MCU)
+ GPIO_USER, // GPIO01 MCU serial control
+ GPIO_USER,
+ GPIO_USER, // GPIO03 MCU serial control
+ GPIO_USER,
+ GPIO_USER,
+ // GPIO06 (SD_CLK Flash)
+ // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
+ // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
+ // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
+ // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
+ // GPIO11 (SD_CMD Flash)
+ GPIO_USER,
+ GPIO_USER,
+ GPIO_USER, // GPIO14 Green Led
+ GPIO_USER,
+ GPIO_USER,
0
},
- { // GOSUND - https://www.amazon.de/gp/product/B0777BWS1P
+ { // GOSUND - https://www.amazon.de/gp/product/B0777BWS1P
0,
- AGPIO(GPIO_LEDLNK_INV), // GPIO01 Serial RXD and LED1 (blue) inv - Link status
+ GPIO_LEDLNK_INV, // GPIO01 Serial RXD and LED1 (blue) inv - Link status
0,
- AGPIO(GPIO_KEY1), // GPIO03 Serial TXD and Button
- AGPIO(GPIO_HJL_CF), // GPIO04 BL0937 or HJL-01 CF power
- AGPIO(GPIO_NRG_CF1), // GPIO05 BL0937 or HJL-01 CF1 current / voltage
- // GPIO06 (SD_CLK Flash)
- // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
- // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
- // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
- // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
- // GPIO11 (SD_CMD Flash)
- AGPIO(GPIO_NRG_SEL_INV), // GPIO12 BL0937 or HJL-01 Sel output (0 = Voltage)
- AGPIO(GPIO_LED1_INV), // GPIO13 LED2 (red) inv - Power status
- AGPIO(GPIO_REL1), // GPIO14 Relay (0 = Off, 1 = On)
+ GPIO_KEY1, // GPIO03 Serial TXD and Button
+ GPIO_HJL_CF, // GPIO04 BL0937 or HJL-01 CF power
+ GPIO_NRG_CF1, // GPIO05 BL0937 or HJL-01 CF1 current / voltage
+ // GPIO06 (SD_CLK Flash)
+ // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
+ // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
+ // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
+ // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
+ // GPIO11 (SD_CMD Flash)
+ GPIO_NRG_SEL_INV, // GPIO12 BL0937 or HJL-01 Sel output (0 = Voltage)
+ GPIO_LED1_INV, // GPIO13 LED2 (red) inv - Power status
+ GPIO_REL1, // GPIO14 Relay (0 = Off, 1 = On)
0, 0, 0
},
- { // ARMTRONIX_DIMMERS - ARMTRONIX Dimmer, one or two channel (ESP8266 w/ separate MCU dimmer)
- // https://www.tindie.com/products/Armtronix/wifi-ac-dimmer-two-triac-board/
- // https://www.tindie.com/products/Armtronix/wifi-ac-dimmer-esp8266-one-triac-board-alexaecho/
- AGPIO(GPIO_USER),
- AGPIO(GPIO_TXD), // GPIO01 MCU serial control
- AGPIO(GPIO_USER),
- AGPIO(GPIO_RXD), // GPIO03 MCU serial control
- AGPIO(GPIO_USER),
- AGPIO(GPIO_USER),
- // GPIO06 (SD_CLK Flash)
- // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
- // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
- // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
- // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
- // GPIO11 (SD_CMD Flash)
- AGPIO(GPIO_USER),
- AGPIO(GPIO_USER),
- AGPIO(GPIO_USER),
- AGPIO(GPIO_USER),
- AGPIO(GPIO_USER),
+ { // ARMTRONIX_DIMMERS - ARMTRONIX Dimmer, one or two channel (ESP8266 w/ separate MCU dimmer)
+ // https://www.tindie.com/products/Armtronix/wifi-ac-dimmer-two-triac-board/
+ // https://www.tindie.com/products/Armtronix/wifi-ac-dimmer-esp8266-one-triac-board-alexaecho/
+ GPIO_USER,
+ GPIO_TXD, // GPIO01 MCU serial control
+ GPIO_USER,
+ GPIO_RXD, // GPIO03 MCU serial control
+ GPIO_USER,
+ GPIO_USER,
+ // GPIO06 (SD_CLK Flash)
+ // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
+ // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
+ // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
+ // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
+ // GPIO11 (SD_CMD Flash)
+ GPIO_USER,
+ GPIO_USER,
+ GPIO_USER,
+ GPIO_USER,
+ GPIO_USER,
0
},
- { // SK03_TUYA - Outdoor smart plug with power monitoring HLW8012 chip - https://www.amazon.com/gp/product/B07CG7MBPV
- AGPIO(GPIO_KEY1), // GPIO00 Button
+ { // SK03_TUYA - Outdoor smart plug with power monitoring HLW8012 chip - https://www.amazon.com/gp/product/B07CG7MBPV
+ GPIO_KEY1, // GPIO00 Button
0, 0, 0,
- AGPIO(GPIO_HLW_CF), // GPIO04 HLW8012 CF power
- AGPIO(GPIO_NRG_CF1), // GPIO05 HLW8012 CF1 current / voltage
- // GPIO06 (SD_CLK Flash)
- // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
- // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
- // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
- // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
- // GPIO11 (SD_CMD Flash)
- AGPIO(GPIO_NRG_SEL_INV), // GPIO12 HLW8012 CF Sel output (0 = Voltage)
- AGPIO(GPIO_LED1_INV), // GPIO13 Red Led (0 = On, 1 = Off) - Power status
- AGPIO(GPIO_LEDLNK_INV), // GPIO14 Blue Led (0 = On, 1 = Off) - Link status
- AGPIO(GPIO_REL1), // GPIO15 Relay (0 = Off, 1 = On)
+ GPIO_HLW_CF, // GPIO04 HLW8012 CF power
+ GPIO_NRG_CF1, // GPIO05 HLW8012 CF1 current / voltage
+ // GPIO06 (SD_CLK Flash)
+ // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
+ // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
+ // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
+ // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
+ // GPIO11 (SD_CMD Flash)
+ GPIO_NRG_SEL_INV, // GPIO12 HLW8012 CF Sel output (0 = Voltage)
+ GPIO_LED1_INV, // GPIO13 Red Led (0 = On, 1 = Off) - Power status
+ GPIO_LEDLNK_INV, // GPIO14 Blue Led (0 = On, 1 = Off) - Link status
+ GPIO_REL1, // GPIO15 Relay (0 = Off, 1 = On)
0, 0
},
- { // PS_16_DZ - PS-16-DZ Dimmer (ESP8266 w/ separate Nuvoton MCU dimmer)
- // https://www.aliexpress.com/item/SM-Smart-WIFI-Wall-Dimmer-Light-Switch-US-Ewelink-APP-Remote-Control-Wi-Fi-Wirele-Work/32871151902.html
- AGPIO(GPIO_USER),
- AGPIO(GPIO_TXD), // GPIO01 MCU serial control
- AGPIO(GPIO_USER),
- AGPIO(GPIO_RXD), // GPIO03 MCU serial control
- AGPIO(GPIO_USER),
- AGPIO(GPIO_USER),
- // GPIO06 (SD_CLK Flash)
- // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
- // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
- // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
- // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
- // GPIO11 (SD_CMD Flash)
- AGPIO(GPIO_USER),
- AGPIO(GPIO_LED1), // GPIO13 WiFi LED - Link and Power status
- AGPIO(GPIO_USER),
- AGPIO(GPIO_USER),
- AGPIO(GPIO_USER),
+ { // PS_16_DZ - PS-16-DZ Dimmer (ESP8266 w/ separate Nuvoton MCU dimmer)
+ // https://www.aliexpress.com/item/SM-Smart-WIFI-Wall-Dimmer-Light-Switch-US-Ewelink-APP-Remote-Control-Wi-Fi-Wirele-Work/32871151902.html
+ GPIO_USER,
+ GPIO_TXD, // GPIO01 MCU serial control
+ GPIO_USER,
+ GPIO_RXD, // GPIO03 MCU serial control
+ GPIO_USER,
+ GPIO_USER,
+ // GPIO06 (SD_CLK Flash)
+ // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
+ // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
+ // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
+ // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
+ // GPIO11 (SD_CMD Flash)
+ GPIO_USER,
+ GPIO_LED1, // GPIO13 WiFi LED - Link and Power status
+ GPIO_USER,
+ GPIO_USER,
+ GPIO_USER,
0
},
- { // TECKIN_US - Teckin SP20 US with Energy Monitoring
- // https://www.amazon.com/Outlet-Compatible-Monitoring-Function-Required/dp/B079Q5W22B
- // https://www.amazon.com/Outlet-ZOOZEE-Monitoring-Function-Compatible/dp/B07J2LR5KN
- AGPIO(GPIO_LED1_INV), // GPIO00 Red Led (1 = On, 0 = Off) - Power status
+ { // TECKIN_US - Teckin SP20 US with Energy Monitoring
+ // https://www.amazon.com/Outlet-Compatible-Monitoring-Function-Required/dp/B079Q5W22B
+ // https://www.amazon.com/Outlet-ZOOZEE-Monitoring-Function-Compatible/dp/B07J2LR5KN
+ GPIO_LED1_INV, // GPIO00 Red Led (1 = On, 0 = Off) - Power status
0,
- AGPIO(GPIO_LEDLNK_INV), // GPIO02 Blue Led (1 = On, 0 = Off) - Link status
+ GPIO_LEDLNK_INV, // GPIO02 Blue Led (1 = On, 0 = Off) - Link status
0,
- AGPIO(GPIO_REL1), // GPIO04 Relay (0 = Off, 1 = On)
- AGPIO(GPIO_HJL_CF), // GPIO05 BL0937 or HJL-01 CF power
- // GPIO06 (SD_CLK Flash)
- // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
- // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
- // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
- // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
- // GPIO11 (SD_CMD Flash)
- AGPIO(GPIO_NRG_SEL_INV), // GPIO12 BL0937 or HJL-01 Sel output (0 = Voltage)
- AGPIO(GPIO_KEY1), // GPIO13 Button
- AGPIO(GPIO_NRG_CF1), // GPIO14 BL0937 or HJL-01 CF1 current / voltage
+ GPIO_REL1, // GPIO04 Relay (0 = Off, 1 = On)
+ GPIO_HJL_CF, // GPIO05 BL0937 or HJL-01 CF power
+ // GPIO06 (SD_CLK Flash)
+ // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
+ // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
+ // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
+ // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
+ // GPIO11 (SD_CMD Flash)
+ GPIO_NRG_SEL_INV, // GPIO12 BL0937 or HJL-01 Sel output (0 = Voltage)
+ GPIO_KEY1, // GPIO13 Button
+ GPIO_NRG_CF1, // GPIO14 BL0937 or HJL-01 CF1 current / voltage
0, 0, 0
},
- { // MANZOKU_EU_4 - "MANZOKU" labeled power strip, EU version
- // https://www.amazon.de/Steckdosenleiste-AOFO-Mehrfachsteckdose-Überspannungsschutz-Sprachsteuerung/dp/B07GBSD11P/
- // https://www.amazon.de/Steckdosenleiste-Geekbes-USB-Anschluss-Kompatibel-gesteuert/dp/B078W23BW9/
- 0, // GPIO00
- 0, // GPIO01 Serial RXD
+ { // MANZOKU_EU_4 - "MANZOKU" labeled power strip, EU version
+ // https://www.amazon.de/Steckdosenleiste-AOFO-Mehrfachsteckdose-Überspannungsschutz-Sprachsteuerung/dp/B07GBSD11P/
+ // https://www.amazon.de/Steckdosenleiste-Geekbes-USB-Anschluss-Kompatibel-gesteuert/dp/B078W23BW9/
+ 0, // GPIO00
+ 0, // GPIO01 Serial RXD
0,
- AGPIO(GPIO_KEY1), // GPIO03 Serial TXD + Button
- AGPIO(GPIO_REL1) +1, // GPIO04 Relay 2
- AGPIO(GPIO_REL1), // GPIO05 Relay 1
- // GPIO06 (SD_CLK Flash)
- // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
- // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
- // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
- // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
- // GPIO11 (SD_CMD Flash)
- AGPIO(GPIO_REL1) +2, // GPIO12 Relay 3
- AGPIO(GPIO_REL1) +3, // GPIO13 Relay 4
- AGPIO(GPIO_USER), // GPIO14
+ GPIO_KEY1, // GPIO03 Serial TXD + Button
+ GPIO_REL2, // GPIO04 Relay 2
+ GPIO_REL1, // GPIO05 Relay 1
+ // GPIO06 (SD_CLK Flash)
+ // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
+ // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
+ // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
+ // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
+ // GPIO11 (SD_CMD Flash)
+ GPIO_REL3, // GPIO12 Relay 3
+ GPIO_REL4, // GPIO13 Relay 4
+ GPIO_USER, // GPIO14
0,
- AGPIO(GPIO_USER), // GPIO16
+ GPIO_USER, // GPIO16
0
},
- { // OBI2 - OBI socket (ESP8266) - https://www.obi.de/hausfunksteuerung/wifi-stecker-schuko-2-stueck-weiss/p/4077673
- 0, // GPIO00
- 0, // GPIO01 Serial RXD
+ { // OBI2 - OBI socket (ESP8266) - https://www.obi.de/hausfunksteuerung/wifi-stecker-schuko-2-stueck-weiss/p/4077673
+ 0, // GPIO00
+ 0, // GPIO01 Serial RXD
0,
- 0, // GPIO03 Serial TXD
- AGPIO(GPIO_REL1), // GPIO04 Relay 1
- AGPIO(GPIO_KEY1), // GPIO05 Button
- // GPIO06 (SD_CLK Flash)
- // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
- // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
- // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
- // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
- // GPIO11 (SD_CMD Flash)
- AGPIO(GPIO_LEDLNK_INV), // GPIO12 Green LED - Link status
- AGPIO(GPIO_LED1), // GPIO13 Red LED - Power status
+ 0, // GPIO03 Serial TXD
+ GPIO_REL1, // GPIO04 Relay 1
+ GPIO_KEY1, // GPIO05 Button
+ // GPIO06 (SD_CLK Flash)
+ // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
+ // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
+ // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
+ // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
+ // GPIO11 (SD_CMD Flash)
+ GPIO_LEDLNK_INV, // GPIO12 Green LED - Link status
+ GPIO_LED1, // GPIO13 Red LED - Power status
0, 0, 0, 0
},
- { // YTF_IR_BRIDGE - https://www.aliexpress.com/item/Tuya-universal-Smart-IR-Hub-remote-control-Voice-Control-AC-TV-Work-With-Alexa-Google-Home/32951202513.html
- AGPIO(GPIO_USER), // GPIO00
- AGPIO(GPIO_USER), // GPIO01 Serial RXD
- AGPIO(GPIO_USER), // GPIO02
- AGPIO(GPIO_USER), // GPIO03 Serial TXD
- AGPIO(GPIO_LED1_INV), // GPIO04 Blue Led - Link status
- AGPIO(GPIO_IRRECV), // GPIO05 IR Receiver
- // GPIO06 (SD_CLK Flash)
- // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
- // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
- // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
- // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
- // GPIO11 (SD_CMD Flash)
- 0, // GPIO12
- AGPIO(GPIO_KEY1), // GPIO13 Button
- AGPIO(GPIO_IRSEND), // GPIO14 IR Transmitter
+ { // YTF_IR_BRIDGE - https://www.aliexpress.com/item/Tuya-universal-Smart-IR-Hub-remote-control-Voice-Control-AC-TV-Work-With-Alexa-Google-Home/32951202513.html
+ GPIO_USER, // GPIO00
+ GPIO_USER, // GPIO01 Serial RXD
+ GPIO_USER, // GPIO02
+ GPIO_USER, // GPIO03 Serial TXD
+ GPIO_LED1_INV, // GPIO04 Blue Led - Link status
+ GPIO_IRRECV, // GPIO05 IR Receiver
+ // GPIO06 (SD_CLK Flash)
+ // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
+ // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
+ // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
+ // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
+ // GPIO11 (SD_CMD Flash)
+ 0, // GPIO12
+ GPIO_KEY1, // GPIO13 Button
+ GPIO_IRSEND, // GPIO14 IR Transmitter
0, 0, 0
},
- { // DIGOO - Digoo DG-SP202
- // https://www.banggood.com/DIGOO-DG-SP202-Dual-EU-Plug-Smart-WIFI-Socket-Individual-Controllable-Energy-Monitor-Remote-Control-Timing-Smart-Home-Outlet-let-p-1375323.html
- AGPIO(GPIO_KEY1), // GPIO00 Button1
- 0, // GPIO01 Serial RXD
- 0, // GPIO02
- 0, // GPIO03 Serial TXD
- AGPIO(GPIO_HJL_CF), // GPIO04 BL0937 or HJL-01 CF power
- AGPIO(GPIO_NRG_CF1), // GPIO05 BL0937 or HJL-01 CF1 current / voltage
- // GPIO06 (SD_CLK Flash)
- // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
- // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
- // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
- // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
- // GPIO11 (SD_CMD Flash)
- AGPIO(GPIO_NRG_SEL_INV), // GPIO12 BL0937 or HJL-01 Sel output (0 = Voltage)
- AGPIO(GPIO_LED1), // GPIO13 Blue Leds - Link Status
- AGPIO(GPIO_REL1) +1, // GPIO14 Relay2 (0 = Off, 1 = On) and Red Led
- AGPIO(GPIO_REL1), // GPIO15 Relay1 (0 = Off, 1 = On) and Red Led
- AGPIO(GPIO_KEY1_NP) +1, // GPIO16 Button2, externally pulled up
+ { // DIGOO - Digoo DG-SP202
+ // https://www.banggood.com/DIGOO-DG-SP202-Dual-EU-Plug-Smart-WIFI-Socket-Individual-Controllable-Energy-Monitor-Remote-Control-Timing-Smart-Home-Outlet-let-p-1375323.html
+ GPIO_KEY1, // GPIO00 Button1
+ 0, // GPIO01 Serial RXD
+ 0, // GPIO02
+ 0, // GPIO03 Serial TXD
+ GPIO_HJL_CF, // GPIO04 BL0937 or HJL-01 CF power
+ GPIO_NRG_CF1, // GPIO05 BL0937 or HJL-01 CF1 current / voltage
+ // GPIO06 (SD_CLK Flash)
+ // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
+ // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
+ // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
+ // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
+ // GPIO11 (SD_CMD Flash)
+ GPIO_NRG_SEL_INV, // GPIO12 BL0937 or HJL-01 Sel output (0 = Voltage)
+ GPIO_LED1, // GPIO13 Blue Leds - Link Status
+ GPIO_REL2, // GPIO14 Relay2 (0 = Off, 1 = On) and Red Led
+ GPIO_REL1, // GPIO15 Relay1 (0 = Off, 1 = On) and Red Led
+ GPIO_KEY2_NP, // GPIO16 Button2, externally pulled up
0
},
- { // KA10 - SMANERGY KA10 (ESP8285 - BL0937 Energy Monitoring) - https://www.amazon.es/dp/B07MBTCH2Y
- 0, // GPIO00
- AGPIO(GPIO_LEDLNK_INV), // GPIO01 Blue LED - Link status
- 0, // GPIO02
- AGPIO(GPIO_KEY1), // GPIO03 Button
- AGPIO(GPIO_HJL_CF), // GPIO04 BL0937 CF power
- AGPIO(GPIO_NRG_CF1), // GPIO05 BL0937 CF1 voltage / current
- // GPIO06 (SD_CLK Flash)
- // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
- // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
- // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
- // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
- // GPIO11 (SD_CMD Flash)
- AGPIO(GPIO_NRG_SEL_INV), // GPIO12 BL0937 Sel output (1 = Voltage)
- AGPIO(GPIO_LED1), // GPIO13 Red LED - Power status
- AGPIO(GPIO_REL1), // GPIO14 Relay 1
+ { // KA10 - SMANERGY KA10 (ESP8285 - BL0937 Energy Monitoring) - https://www.amazon.es/dp/B07MBTCH2Y
+ 0, // GPIO00
+ GPIO_LEDLNK_INV, // GPIO01 Blue LED - Link status
+ 0, // GPIO02
+ GPIO_KEY1, // GPIO03 Button
+ GPIO_HJL_CF, // GPIO04 BL0937 CF power
+ GPIO_NRG_CF1, // GPIO05 BL0937 CF1 voltage / current
+ // GPIO06 (SD_CLK Flash)
+ // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
+ // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
+ // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
+ // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
+ // GPIO11 (SD_CMD Flash)
+ GPIO_NRG_SEL_INV, // GPIO12 BL0937 Sel output (1 = Voltage)
+ GPIO_LED1, // GPIO13 Red LED - Power status
+ GPIO_REL1, // GPIO14 Relay 1
0, 0, 0
},
- { // ZX2820
- AGPIO(GPIO_KEY1), // GPIO00 Button
+ { // ZX2820
+ GPIO_KEY1, // GPIO00 Button
0, 0, 0,
- AGPIO(GPIO_HLW_CF), // GPIO04 HLW8012 CF power
- AGPIO(GPIO_NRG_CF1), // GPIO05 HLW8012 CF1 voltage / current
- // GPIO06 (SD_CLK Flash)
- // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
- // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
- // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
- // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
- // GPIO11 (SD_CMD Flash)
- AGPIO(GPIO_NRG_SEL_INV), // GPIO12 HLW8012 SEL (0 = Voltage)
- AGPIO(GPIO_LED1_INV), // GPIO13 Green Led - Link and Power status
- AGPIO(GPIO_REL1), // GPIO14 Relay
+ GPIO_HLW_CF, // GPIO04 HLW8012 CF power
+ GPIO_NRG_CF1, // GPIO05 HLW8012 CF1 voltage / current
+ // GPIO06 (SD_CLK Flash)
+ // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
+ // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
+ // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
+ // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
+ // GPIO11 (SD_CMD Flash)
+ GPIO_NRG_SEL_INV, // GPIO12 HLW8012 SEL (0 = Voltage)
+ GPIO_LED1_INV, // GPIO13 Green Led - Link and Power status
+ GPIO_REL1, // GPIO14 Relay
0, 0, 0
},
- { // MI_DESK_LAMP - Mi LED Desk Lamp - https://www.mi.com/global/smartlamp/
+ { // MI_DESK_LAMP - Mi LED Desk Lamp - https://www.mi.com/global/smartlamp/
0, 0,
- AGPIO(GPIO_KEY1), // GPIO02 Button
+ GPIO_KEY1, // GPIO02 Button
0,
- AGPIO(GPIO_PWM1), // GPIO04 Cold White
- AGPIO(GPIO_PWM1) +1, // GPIO05 Warm White
- // GPIO06 (SD_CLK Flash)
- // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
- // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
- // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
- // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
- // GPIO11 (SD_CMD Flash)
- AGPIO(GPIO_ROT1A), // GPIO12 Rotary switch A pin
- AGPIO(GPIO_ROT1B), // GPIO13 Rotary switch B pin
+ GPIO_PWM1, // GPIO04 Cold White
+ GPIO_PWM2, // GPIO05 Warm White
+ // GPIO06 (SD_CLK Flash)
+ // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
+ // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
+ // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
+ // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
+ // GPIO11 (SD_CMD Flash)
+ GPIO_ROT1A, // GPIO12 Rotary switch A pin
+ GPIO_ROT1B, // GPIO13 Rotary switch B pin
0, 0, 0, 0
},
- { // SP10 - Tuya SP10 (BL0937 Energy Monitoring)
- // https://www.aliexpress.com/item/Smart-Mini-WiFi-Plug-Outlet-Switch-Work-With-ForEcho-Alexa-Google-Home-Remote-EU-Smart-Socket/32963670423.html
- 0, // GPIO00
- AGPIO(GPIO_PWM1), // GPIO01 Nightlight
- 0, // GPIO02
- AGPIO(GPIO_KEY1), // GPIO03 Button
- AGPIO(GPIO_HJL_CF), // GPIO04 BL0937 CF power
- AGPIO(GPIO_NRG_CF1), // GPIO05 BL0937 CF1 voltage / current
- // GPIO06 (SD_CLK Flash)
- // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
- // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
- // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
- // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
- // GPIO11 (SD_CMD Flash)
- AGPIO(GPIO_NRG_SEL_INV), // GPIO12 BL0937 Sel output (1 = Voltage)
- AGPIO(GPIO_LED1), // GPIO13 Blue LED - Link status
- AGPIO(GPIO_REL1), // GPIO14 Relay and red LED
+ { // SP10 - Tuya SP10 (BL0937 Energy Monitoring)
+ // https://www.aliexpress.com/item/Smart-Mini-WiFi-Plug-Outlet-Switch-Work-With-ForEcho-Alexa-Google-Home-Remote-EU-Smart-Socket/32963670423.html
+ 0, // GPIO00
+ GPIO_PWM1, // GPIO01 Nightlight
+ 0, // GPIO02
+ GPIO_KEY1, // GPIO03 Button
+ GPIO_HJL_CF, // GPIO04 BL0937 CF power
+ GPIO_NRG_CF1, // GPIO05 BL0937 CF1 voltage / current
+ // GPIO06 (SD_CLK Flash)
+ // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
+ // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
+ // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
+ // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
+ // GPIO11 (SD_CMD Flash)
+ GPIO_NRG_SEL_INV, // GPIO12 BL0937 Sel output (1 = Voltage)
+ GPIO_LED1, // GPIO13 Blue LED - Link status
+ GPIO_REL1, // GPIO14 Relay and red LED
0, 0, 0
},
- { // WAGA - WAGA life CHCZ02MB (HJL-01 Energy Monitoring)
- // https://www.ebay.com/itm/332595697006
- AGPIO(GPIO_LED1_INV), // GPIO00 Red LED
- 0, // GPIO01 Serial RXD
- 0, // GPIO02
- AGPIO(GPIO_NRG_SEL_INV), // GPIO03 HJL-01 Sel output (1 = Voltage)
- 0, // GPIO04
- AGPIO(GPIO_HJL_CF), // GPIO05 HJL-01 CF power
- // GPIO06 (SD_CLK Flash)
- // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
- // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
- // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
- // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
- // GPIO11 (SD_CMD Flash)
- AGPIO(GPIO_REL1), // GPIO12 Relay
- AGPIO(GPIO_KEY1), // GPIO13 Button
- AGPIO(GPIO_NRG_CF1), // GPIO14 HJL-01 CF1 voltage / current
- AGPIO(GPIO_LEDLNK_INV), // GPIO15 Blue LED - Link status
+ { // WAGA - WAGA life CHCZ02MB (HJL-01 Energy Monitoring)
+ // https://www.ebay.com/itm/332595697006
+ GPIO_LED1_INV, // GPIO00 Red LED
+ 0, // GPIO01 Serial RXD
+ 0, // GPIO02
+ GPIO_NRG_SEL_INV, // GPIO03 HJL-01 Sel output (1 = Voltage)
+ 0, // GPIO04
+ GPIO_HJL_CF, // GPIO05 HJL-01 CF power
+ // GPIO06 (SD_CLK Flash)
+ // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
+ // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
+ // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
+ // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
+ // GPIO11 (SD_CMD Flash)
+ GPIO_REL1, // GPIO12 Relay
+ GPIO_KEY1, // GPIO13 Button
+ GPIO_NRG_CF1, // GPIO14 HJL-01 CF1 voltage / current
+ GPIO_LEDLNK_INV, // GPIO15 Blue LED - Link status
0, 0
},
- { // SYF05 - Sunyesmart SYF05 (a.k.a. Fcmila) = TYWE3S + SM16726
- // Also works with Merkury 904 RGBW Bulbs with 13 set to GPIO_SM16716_SEL
- // https://www.flipkart.com/fc-mila-bxav-xs-ad-smart-bulb/p/itmf85zgs45fzr7n
- // https://docs.tuya.com/en/hardware/WiFi-module/wifi-e3s-module.html
- // http://www.datasheet-pdf.com/PDF/SM16716-Datasheet-Sunmoon-932771
- AGPIO(GPIO_USER), // GPIO00 N.C.
- 0, // GPIO01 Serial RXD
- AGPIO(GPIO_USER), // GPIO02 N.C.
- 0, // GPIO03 Serial TXD
- AGPIO(GPIO_SM16716_CLK), // GPIO04 SM16716 Clock
- AGPIO(GPIO_PWM1), // GPIO05 White
- // GPIO06 (SD_CLK Flash)
- // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
- // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
- // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
- // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
- // GPIO11 (SD_CMD Flash)
- AGPIO(GPIO_USER), // GPIO12 Alt. White on some devices
- AGPIO(GPIO_USER), // GPIO13 SM16716 Enable on some devices
- AGPIO(GPIO_SM16716_DAT), // GPIO14 SM16716 Data
- 0, // GPIO15 wired to GND
- AGPIO(GPIO_USER), // GPIO16 N.C.
- AGPIO(ADC0_USER) // ADC0 A0 Analog input
+ { // SYF05 - Sunyesmart SYF05 (a.k.a. Fcmila) = TYWE3S + SM16726
+ // Also works with Merkury 904 RGBW Bulbs with 13 set to GPIO_SM16716_SEL
+ // https://www.flipkart.com/fc-mila-bxav-xs-ad-smart-bulb/p/itmf85zgs45fzr7n
+ // https://docs.tuya.com/en/hardware/WiFi-module/wifi-e3s-module.html
+ // http://www.datasheet-pdf.com/PDF/SM16716-Datasheet-Sunmoon-932771
+ GPIO_USER, // GPIO00 N.C.
+ 0, // GPIO01 Serial RXD
+ GPIO_USER, // GPIO02 N.C.
+ 0, // GPIO03 Serial TXD
+ GPIO_SM16716_CLK, // GPIO04 SM16716 Clock
+ GPIO_PWM1, // GPIO05 White
+ // GPIO06 (SD_CLK Flash)
+ // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
+ // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
+ // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
+ // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
+ // GPIO11 (SD_CMD Flash)
+ GPIO_USER, // GPIO12 Alt. White on some devices
+ GPIO_USER, // GPIO13 SM16716 Enable on some devices
+ GPIO_SM16716_DAT, // GPIO14 SM16716 Data
+ 0, // GPIO15 wired to GND
+ GPIO_USER, // GPIO16 N.C.
+ ADC0_USER // ADC0 A0 Analog input
},
- { // EXS_DIMMER - EX-Store WiFi Dimmer v4, two channel (ESP8266 w/ separate MCU dimmer)
- // https://ex-store.de/2-Kanal-RS232-WiFi-WLan-Dimmer-Modul-V4-fuer-Unterputzmontage-230V-3A
- // https://ex-store.de/2-Kanal-RS232-WiFi-WLan-Dimmer-Modul-V4-fuer-Unterputzmontage-230V-3A-ESP8266-V12-Stift-und-Buchsenleisten
+ { // EXS_DIMMER - EX-Store WiFi Dimmer v4, two channel (ESP8266 w/ separate MCU dimmer)
+ // https://ex-store.de/2-Kanal-RS232-WiFi-WLan-Dimmer-Modul-V4-fuer-Unterputzmontage-230V-3A
+ // https://ex-store.de/2-Kanal-RS232-WiFi-WLan-Dimmer-Modul-V4-fuer-Unterputzmontage-230V-3A-ESP8266-V12-Stift-und-Buchsenleisten
0,
- AGPIO(GPIO_TXD), // GPIO01 MCU serial control
- AGPIO(GPIO_LEDLNK), // GPIO02 LED Link
- AGPIO(GPIO_RXD), // GPIO03 MCU serial control
- AGPIO(GPIO_USER), // GPIO04
- AGPIO(GPIO_USER), // GPIO05
- // GPIO06 (SD_CLK Flash)
- // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
- // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
- // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
- // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
- // GPIO11 (SD_CMD Flash)
- AGPIO(GPIO_USER), // GPIO12
- AGPIO(GPIO_EXS_ENABLE), // GPIO13 EXS MCU Enable
- AGPIO(GPIO_USER), // GPIO14
- 0, // GPIO15
+ GPIO_TXD, // GPIO01 MCU serial control
+ GPIO_LEDLNK, // GPIO02 LED Link
+ GPIO_RXD, // GPIO03 MCU serial control
+ GPIO_USER, // GPIO04
+ GPIO_USER, // GPIO05
+ // GPIO06 (SD_CLK Flash)
+ // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
+ // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
+ // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
+ // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
+ // GPIO11 (SD_CMD Flash)
+ GPIO_USER, // GPIO12
+ GPIO_EXS_ENABLE, // GPIO13 EXS MCU Enable
+ GPIO_USER, // GPIO14
+ 0, // GPIO15
0, 0
},
- { // PWM_DIMMER - Support for Martin Jerry/acenx/Tessan/NTONPOWER SD0x PWM
- // dimmer switches. The brightness of the load for these dimmers is
- // controlled by a PWM GPIO pin. There are typically power, up & down
- // buttons and 4 LED's. Examples are:
- // https://www.amazon.com/dp/B07FXYSVR1
- // https://www.amazon.com/dp/B07V26Q3VD
- // https://www.amazon.com/dp/B07K67D43J
- // https://www.amazon.com/dp/B07TTGFWFM
- AGPIO(GPIO_KEY1) +2, // GPIO00 Up button
- AGPIO(GPIO_KEY1) +1, // GPIO01 Down button
- 0, // GPIO02
- AGPIO(GPIO_LED1_INV) +3, // GPIO03 Level 5 LED
- AGPIO(GPIO_LEDLNK_INV), // GPIO04 LED Link
- AGPIO(GPIO_LED1_INV) +2, // GPIO05 Level 4 LED
- // GPIO06 (SD_CLK Flash)
- // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
- // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
- // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
- // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
- // GPIO11 (SD_CMD Flash)
- AGPIO(GPIO_LED1_INV) +1, // GPIO12 Level 3 LED
- AGPIO(GPIO_PWM1), // GPIO13 Dimmer PWM
- AGPIO(GPIO_LED1_INV), // GPIO12 Level 2 LED
- AGPIO(GPIO_KEY1_INV), // GPIO15 Power button
- AGPIO(GPIO_REL1_INV), // GPIO16 Power relay/Level 1 LED
+ { // PWM_DIMMER - Support for Martin Jerry/acenx/Tessan/NTONPOWER SD0x PWM
+ // dimmer switches. The brightness of the load for these dimmers is
+ // controlled by a PWM GPIO pin. There are typically power, up & down
+ // buttons and 4 LED's. Examples are:
+ // https://www.amazon.com/dp/B07FXYSVR1
+ // https://www.amazon.com/dp/B07V26Q3VD
+ // https://www.amazon.com/dp/B07K67D43J
+ // https://www.amazon.com/dp/B07TTGFWFM
+ GPIO_KEY3, // GPIO00 Up button
+ GPIO_KEY2, // GPIO01 Down button
+ 0, // GPIO02
+ GPIO_LED4_INV, // GPIO03 Level 5 LED
+ GPIO_LEDLNK_INV, // GPIO04 LED Link
+ GPIO_LED3_INV, // GPIO05 Level 4 LED
+ // GPIO06 (SD_CLK Flash)
+ // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
+ // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
+ // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
+ // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
+ // GPIO11 (SD_CMD Flash)
+ GPIO_LED2_INV, // GPIO12 Level 3 LED
+ GPIO_PWM1, // GPIO13 Dimmer PWM
+ GPIO_LED1_INV, // GPIO12 Level 2 LED
+ GPIO_KEY1_INV, // GPIO15 Power button
+ GPIO_REL1_INV, // GPIO16 Power relay/Level 1 LED
0
},
- { // SONOFF_ZB_BRIDGE - Sonoff Zigbee Bridge (ESP8266)
- AGPIO(GPIO_LED1_INV), // GPIO00 Green Led (0 = On, 1 = Off) - Traffic between ESP and EFR
- AGPIO(GPIO_ZIGBEE_TX), // GPIO01 Zigbee Serial control
- 0, // GPIO02
- AGPIO(GPIO_ZIGBEE_RX), // GPIO03 Zigbee Serial control
- AGPIO(GPIO_ZIGBEE_RST), // GPIO04 Zigbee Reset
- 0, // GPIO05 EFR32 Bootloader mode (drive Low for Gecko Bootloader, inactive or high for Zigbee EmberZNet)
- // GPIO06 (SD_CLK Flash)
- // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
- // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
- // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
- // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
- // GPIO11 (SD_CMD Flash)
- AGPIO(GPIO_I2C_SDA), // GPIO12 I2C SDA - connected to 512KB EEPROM
- AGPIO(GPIO_LEDLNK_INV), // GPIO13 Blue Led (0 = On, 1 = Off) - Link status
- AGPIO(GPIO_I2C_SCL), // GPIO14 I2C SCL - connected to 512KB EEPROM
- 0, // GPIO15 connected to IO15 pad, also used for logging
- AGPIO(GPIO_KEY1), // GPIO16 Button
+ { // SONOFF_ZB_BRIDGE - Sonoff Zigbee Bridge (ESP8266)
+ GPIO_LED1_INV, // GPIO00 Green Led (0 = On, 1 = Off) - Traffic between ESP and EFR
+ GPIO_ZIGBEE_TX, // GPIO01 Zigbee Serial control
+ 0, // GPIO02
+ GPIO_ZIGBEE_RX, // GPIO03 Zigbee Serial control
+ GPIO_ZIGBEE_RST, // GPIO04 Zigbee Reset
+ 0, // GPIO05 EFR32 Bootloader mode (drive Low for Gecko Bootloader, inactive or high for Zigbee EmberZNet)
+ // GPIO06 (SD_CLK Flash)
+ // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
+ // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
+ // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
+ // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
+ // GPIO11 (SD_CMD Flash)
+ GPIO_I2C_SDA, // GPIO12 I2C SDA - connected to 512KB EEPROM
+ GPIO_LEDLNK_INV, // GPIO13 Blue Led (0 = On, 1 = Off) - Link status
+ GPIO_I2C_SCL, // GPIO14 I2C SCL - connected to 512KB EEPROM
+ 0, // GPIO15 connected to IO15 pad, also used for logging
+ GPIO_KEY1, // GPIO16 Button
0
}
};
@@ -2100,113 +2323,113 @@ const mytmplt8266 kModules8266[TMP_MAXMODULE_8285] PROGMEM = {
\*********************************************************************************************/
const mytmplt kModules8285[TMP_MAXMODULE_8266 - TMP_WEMOS] PROGMEM = {
- { // WEMOS - Any ESP8266/ESP8285 device like WeMos and NodeMCU hardware (ESP8266)
- AGPIO(GPIO_USER), // GPIO00 D3 Wemos Button Shield
- AGPIO(GPIO_USER), // GPIO01 TX Serial RXD
- AGPIO(GPIO_USER), // GPIO02 D4 Wemos DHT Shield
- AGPIO(GPIO_USER), // GPIO03 RX Serial TXD and Optional sensor
- AGPIO(GPIO_USER), // GPIO04 D2 Wemos I2C SDA
- AGPIO(GPIO_USER), // GPIO05 D1 Wemos I2C SCL / Wemos Relay Shield (0 = Off, 1 = On) / Wemos WS2812B RGB led Shield
- // GPIO06 (SD_CLK Flash)
- // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
- // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
- AGPIO(GPIO_USER), // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
- AGPIO(GPIO_USER), // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
- // GPIO11 (SD_CMD Flash)
- AGPIO(GPIO_USER), // GPIO12 D6
- AGPIO(GPIO_USER), // GPIO13 D7
- AGPIO(GPIO_USER), // GPIO14 D5
- AGPIO(GPIO_USER), // GPIO15 D8
- AGPIO(GPIO_USER), // GPIO16 D0 Wemos Wake
- AGPIO(ADC0_USER) // ADC0 A0 Analog input
+ { // WEMOS - Any ESP8266/ESP8285 device like WeMos and NodeMCU hardware (ESP8266)
+ GPIO_USER, // GPIO00 D3 Wemos Button Shield
+ GPIO_USER, // GPIO01 TX Serial RXD
+ GPIO_USER, // GPIO02 D4 Wemos DHT Shield
+ GPIO_USER, // GPIO03 RX Serial TXD and Optional sensor
+ GPIO_USER, // GPIO04 D2 Wemos I2C SDA
+ GPIO_USER, // GPIO05 D1 Wemos I2C SCL / Wemos Relay Shield (0 = Off, 1 = On) / Wemos WS2812B RGB led Shield
+ // GPIO06 (SD_CLK Flash)
+ // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
+ // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
+ GPIO_USER, // GPIO09 (SD_DATA2 Flash QIO or ESP8285)
+ GPIO_USER, // GPIO10 (SD_DATA3 Flash QIO or ESP8285)
+ // GPIO11 (SD_CMD Flash)
+ GPIO_USER, // GPIO12 D6
+ GPIO_USER, // GPIO13 D7
+ GPIO_USER, // GPIO14 D5
+ GPIO_USER, // GPIO15 D8
+ GPIO_USER, // GPIO16 D0 Wemos Wake
+ ADC0_USER // ADC0 A0 Analog input
},
- { // SONOFF_4CH - Sonoff 4CH (ESP8285)
- AGPIO(GPIO_KEY1), // GPIO00 Button 1
- AGPIO(GPIO_USER), // GPIO01 Serial RXD and Optional sensor
- AGPIO(GPIO_USER), // GPIO02 Optional sensor
- AGPIO(GPIO_USER), // GPIO03 Serial TXD and Optional sensor
- AGPIO(GPIO_REL1) +2, // GPIO04 Sonoff 4CH Red Led and Relay 3 (0 = Off, 1 = On)
- AGPIO(GPIO_REL1) +1, // GPIO05 Sonoff 4CH Red Led and Relay 2 (0 = Off, 1 = On)
- // GPIO06 (SD_CLK Flash)
- // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
- // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
- AGPIO(GPIO_KEY1) +1, // GPIO09 Button 2
- AGPIO(GPIO_KEY1) +2, // GPIO10 Button 3
- // GPIO11 (SD_CMD Flash)
- AGPIO(GPIO_REL1), // GPIO12 Red Led and Relay 1 (0 = Off, 1 = On) - Link and Power status
- AGPIO(GPIO_LED1_INV), // GPIO13 Blue Led (0 = On, 1 = Off)
- AGPIO(GPIO_KEY1) +3, // GPIO14 Button 4
- AGPIO(GPIO_REL1) +3, // GPIO15 Red Led and Relay 4 (0 = Off, 1 = On)
+ { // SONOFF_4CH - Sonoff 4CH (ESP8285)
+ GPIO_KEY1, // GPIO00 Button 1
+ GPIO_USER, // GPIO01 Serial RXD and Optional sensor
+ GPIO_USER, // GPIO02 Optional sensor
+ GPIO_USER, // GPIO03 Serial TXD and Optional sensor
+ GPIO_REL3, // GPIO04 Sonoff 4CH Red Led and Relay 3 (0 = Off, 1 = On)
+ GPIO_REL2, // GPIO05 Sonoff 4CH Red Led and Relay 2 (0 = Off, 1 = On)
+ // GPIO06 (SD_CLK Flash)
+ // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
+ // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
+ GPIO_KEY2, // GPIO09 Button 2
+ GPIO_KEY3, // GPIO10 Button 3
+ // GPIO11 (SD_CMD Flash)
+ GPIO_REL1, // GPIO12 Red Led and Relay 1 (0 = Off, 1 = On) - Link and Power status
+ GPIO_LED1_INV, // GPIO13 Blue Led (0 = On, 1 = Off)
+ GPIO_KEY4, // GPIO14 Button 4
+ GPIO_REL4, // GPIO15 Red Led and Relay 4 (0 = Off, 1 = On)
0, 0
},
- { // SONOFF_T12 - Sonoff T1 2CH (ESP8285)
- AGPIO(GPIO_KEY1), // GPIO00 Button 1
- AGPIO(GPIO_USER), // GPIO01 Serial RXD and Optional sensor
- AGPIO(GPIO_USER), // GPIO02 Optional Sensor (J3 Pin 5)
- AGPIO(GPIO_USER), // GPIO03 Serial TXD and Optional sensor
+ { // SONOFF_T12 - Sonoff T1 2CH (ESP8285)
+ GPIO_KEY1, // GPIO00 Button 1
+ GPIO_USER, // GPIO01 Serial RXD and Optional sensor
+ GPIO_USER, // GPIO02 Optional Sensor (J3 Pin 5)
+ GPIO_USER, // GPIO03 Serial TXD and Optional sensor
0,
- AGPIO(GPIO_REL1) +1, // GPIO05 Blue Led and Relay 2 (0 = Off, 1 = On)
- // GPIO06 (SD_CLK Flash)
- // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
- // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
- AGPIO(GPIO_KEY1) +1, // GPIO09 Button 2
- 0, // GPIO10
- // GPIO11 (SD_CMD Flash)
- AGPIO(GPIO_REL1), // GPIO12 Blue Led and Relay 1 (0 = Off, 1 = On)
- AGPIO(GPIO_LED1_INV), // GPIO13 Blue Led (0 = On, 1 = Off) - Link and Power status
+ GPIO_REL2, // GPIO05 Blue Led and Relay 2 (0 = Off, 1 = On)
+ // GPIO06 (SD_CLK Flash)
+ // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
+ // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
+ GPIO_KEY2, // GPIO09 Button 2
+ 0, // GPIO10
+ // GPIO11 (SD_CMD Flash)
+ GPIO_REL1, // GPIO12 Blue Led and Relay 1 (0 = Off, 1 = On)
+ GPIO_LED1_INV, // GPIO13 Blue Led (0 = On, 1 = Off) - Link and Power status
0, 0, 0, 0
},
- { // SONOFF_T13 - Sonoff T1 3CH (ESP8285)
- AGPIO(GPIO_KEY1), // GPIO00 Button 1
- AGPIO(GPIO_USER), // GPIO01 Serial RXD and Optional sensor
- AGPIO(GPIO_USER), // GPIO02 Optional Sensor (J3 Pin 5)
- AGPIO(GPIO_USER), // GPIO03 Serial TXD and Optional sensor
- AGPIO(GPIO_REL1) +2, // GPIO04 Blue Led and Relay 3 (0 = Off, 1 = On)
- AGPIO(GPIO_REL1) +1, // GPIO05 Blue Led and Relay 2 (0 = Off, 1 = On)
- // GPIO06 (SD_CLK Flash)
- // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
- // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
- AGPIO(GPIO_KEY1) +1, // GPIO09 Button 2
- AGPIO(GPIO_KEY1) +2, // GPIO10 Button 3
- // GPIO11 (SD_CMD Flash)
- AGPIO(GPIO_REL1), // GPIO12 Blue Led and Relay 1 (0 = Off, 1 = On)
- AGPIO(GPIO_LED1_INV), // GPIO13 Blue Led (0 = On, 1 = Off) - Link and Power status
+ { // SONOFF_T13 - Sonoff T1 3CH (ESP8285)
+ GPIO_KEY1, // GPIO00 Button 1
+ GPIO_USER, // GPIO01 Serial RXD and Optional sensor
+ GPIO_USER, // GPIO02 Optional Sensor (J3 Pin 5)
+ GPIO_USER, // GPIO03 Serial TXD and Optional sensor
+ GPIO_REL3, // GPIO04 Blue Led and Relay 3 (0 = Off, 1 = On)
+ GPIO_REL2, // GPIO05 Blue Led and Relay 2 (0 = Off, 1 = On)
+ // GPIO06 (SD_CLK Flash)
+ // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
+ // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
+ GPIO_KEY2, // GPIO09 Button 2
+ GPIO_KEY3, // GPIO10 Button 3
+ // GPIO11 (SD_CMD Flash)
+ GPIO_REL1, // GPIO12 Blue Led and Relay 1 (0 = Off, 1 = On)
+ GPIO_LED1_INV, // GPIO13 Blue Led (0 = On, 1 = Off) - Link and Power status
0, 0, 0, 0
},
- { // SONOFF_DUAL_R2 - Sonoff Dual R2 (ESP8285)
- AGPIO(GPIO_USER), // GPIO00 Button 0 on header (0 = On, 1 = Off)
- AGPIO(GPIO_USER), // GPIO01 Serial RXD and Optional sensor
+ { // SONOFF_DUAL_R2 - Sonoff Dual R2 (ESP8285)
+ GPIO_USER, // GPIO00 Button 0 on header (0 = On, 1 = Off)
+ GPIO_USER, // GPIO01 Serial RXD and Optional sensor
0,
- AGPIO(GPIO_USER), // GPIO03 Serial TXD and Optional sensor
+ GPIO_USER, // GPIO03 Serial TXD and Optional sensor
0,
- AGPIO(GPIO_REL1) +1, // GPIO05 Relay 2 (0 = Off, 1 = On)
- // GPIO06 (SD_CLK Flash)
- // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
- // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
- AGPIO(GPIO_USER), // GPIO09 Button 1 on header (0 = On, 1 = Off)
- AGPIO(GPIO_KEY1), // GPIO10 Button on casing
- // GPIO11 (SD_CMD Flash)
- AGPIO(GPIO_REL1), // GPIO12 Relay 1 (0 = Off, 1 = On)
- AGPIO(GPIO_LED1_INV), // GPIO13 Blue Led (0 = On, 1 = Off) - Link and Power status
+ GPIO_REL2, // GPIO05 Relay 2 (0 = Off, 1 = On)
+ // GPIO06 (SD_CLK Flash)
+ // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
+ // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
+ GPIO_USER, // GPIO09 Button 1 on header (0 = On, 1 = Off)
+ GPIO_KEY1, // GPIO10 Button on casing
+ // GPIO11 (SD_CMD Flash)
+ GPIO_REL1, // GPIO12 Relay 1 (0 = Off, 1 = On)
+ GPIO_LED1_INV, // GPIO13 Blue Led (0 = On, 1 = Off) - Link and Power status
0, 0, 0, 0
},
- { // SONOFF_IFAN03 - Sonoff iFan03 (ESP8285)
- AGPIO(GPIO_KEY1), // GPIO00 WIFI_KEY0 Button 1
- AGPIO(GPIO_TXD), // GPIO01 ESP_TXD Serial RXD connection to P0.5 of RF microcontroller
- 0, // GPIO02 ESP_LOG
- AGPIO(GPIO_RXD), // GPIO03 ESP_RXD Serial TXD connection to P0.4 of RF microcontroller
- 0, // GPIO04 DEBUG_RX
- 0, // GPIO05 DEBUG_TX
- // GPIO06 (SD_CLK Flash)
- // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
- // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
- AGPIO(GPIO_REL1_INV), // GPIO09 WIFI_O0 Relay 1 (0 = Off, 1 = On) controlling the light
- AGPIO(GPIO_BUZZER_INV), // GPIO10 WIFI_O4 Buzzer (0 = Off, 1 = On)
- // GPIO11 (SD_CMD Flash)
- AGPIO(GPIO_REL1) +2, // GPIO12 WIFI_O2 Relay 3 (0 = Off, 1 = On) controlling the fan
- AGPIO(GPIO_LED1_INV), // GPIO13 WIFI_CHK Blue Led on PCA (0 = On, 1 = Off) - Link and Power status
- AGPIO(GPIO_REL1) +1, // GPIO14 WIFI_O1 Relay 2 (0 = Off, 1 = On) controlling the fan
- AGPIO(GPIO_REL1) +3, // GPIO15 WIFI_O3 Relay 4 (0 = Off, 1 = On) controlling the fan
+ { // SONOFF_IFAN03 - Sonoff iFan03 (ESP8285)
+ GPIO_KEY1, // GPIO00 WIFI_KEY0 Button 1
+ GPIO_TXD, // GPIO01 ESP_TXD Serial RXD connection to P0.5 of RF microcontroller
+ 0, // GPIO02 ESP_LOG
+ GPIO_RXD, // GPIO03 ESP_RXD Serial TXD connection to P0.4 of RF microcontroller
+ 0, // GPIO04 DEBUG_RX
+ 0, // GPIO05 DEBUG_TX
+ // GPIO06 (SD_CLK Flash)
+ // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT)
+ // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT)
+ GPIO_REL1_INV, // GPIO09 WIFI_O0 Relay 1 (0 = Off, 1 = On) controlling the light
+ GPIO_BUZZER_INV, // GPIO10 WIFI_O4 Buzzer (0 = Off, 1 = On)
+ // GPIO11 (SD_CMD Flash)
+ GPIO_REL3, // GPIO12 WIFI_O2 Relay 3 (0 = Off, 1 = On) controlling the fan
+ GPIO_LED1_INV, // GPIO13 WIFI_CHK Blue Led on PCA (0 = On, 1 = Off) - Link and Power status
+ GPIO_REL2, // GPIO14 WIFI_O1 Relay 2 (0 = Off, 1 = On) controlling the fan
+ GPIO_REL4, // GPIO15 WIFI_O3 Relay 4 (0 = Off, 1 = On) controlling the fan
0, 0
}
};
From 6eadeb81eae306f46b25ee5099eee725b25fdf2e Mon Sep 17 00:00:00 2001
From: Stephan Hadinger
Date: Mon, 14 Sep 2020 21:48:32 +0200
Subject: [PATCH 22/23] Fix TLS crash
---
tasmota/WiFiClientSecureLightBearSSL.cpp | 2 -
tasmota/xdrv_02_mqtt.ino | 50 +++++++++++++-----------
2 files changed, 28 insertions(+), 24 deletions(-)
diff --git a/tasmota/WiFiClientSecureLightBearSSL.cpp b/tasmota/WiFiClientSecureLightBearSSL.cpp
index d85373688..f0a6bcfbb 100755
--- a/tasmota/WiFiClientSecureLightBearSSL.cpp
+++ b/tasmota/WiFiClientSecureLightBearSSL.cpp
@@ -874,10 +874,8 @@ extern "C" {
// we support only P256 EC curve for AWS IoT, no EC curve for Letsencrypt unless forced
br_ssl_engine_set_ec(&cc->eng, &br_ec_p256_m15); // TODO
#endif
-#ifdef USE_MQTT_AWS_IOT_LIGHT
static const char * alpn_mqtt = "mqtt";
br_ssl_engine_set_protocol_names(&cc->eng, &alpn_mqtt, 1);
-#endif
}
}
diff --git a/tasmota/xdrv_02_mqtt.ino b/tasmota/xdrv_02_mqtt.ino
index bcd71005f..58fd04c2c 100644
--- a/tasmota/xdrv_02_mqtt.ino
+++ b/tasmota/xdrv_02_mqtt.ino
@@ -57,7 +57,7 @@ struct MQTT {
uint8_t initial_connection_state = 2; // MQTT connection messages state
bool connected = false; // MQTT virtual connection status
bool allowed = false; // MQTT enabled and parameters valid
- bool tls_private_key = false; // MQTT require a private key before connecting
+ bool mqtt_tls = false; // MQTT TLS is enabled
} Mqtt;
#ifdef USE_MQTT_TLS
@@ -149,22 +149,24 @@ void MqttInit(void)
// Turn on TLS for port 8883 (TLS) and 8884 (TLS, client certificate)
Settings.flag4.mqtt_tls = true;
}
+ Mqtt.mqtt_tls = Settings.flag4.mqtt_tls; // this flag should not change even if we change the SetOption (until reboot)
// Detect AWS IoT and set default parameters
String host = String(SettingsText(SET_MQTT_HOST));
if (host.indexOf(".iot.") && host.endsWith(".amazonaws.com")) { // look for ".iot." and ".amazonaws.com" in the domain name
Settings.flag4.mqtt_no_retain = true;
- // Mqtt.tls_private_key = true;
}
- if (Settings.flag4.mqtt_tls) {
+ if (Mqtt.mqtt_tls) {
tlsClient = new BearSSL::WiFiClientSecure_light(1024,1024);
#ifdef USE_MQTT_AWS_IOT
loadTlsDir(); // load key and certificate data from Flash
- tlsClient->setClientECCert(AWS_IoT_Client_Certificate,
- AWS_IoT_Private_Key,
- 0xFFFF /* all usages, don't care */, 0);
+ if ((nullptr != AWS_IoT_Private_Key) && (nullptr != AWS_IoT_Client_Certificate)) {
+ tlsClient->setClientECCert(AWS_IoT_Client_Certificate,
+ AWS_IoT_Private_Key,
+ 0xFFFF /* all usages, don't care */, 0);
+ }
#endif
#ifdef USE_MQTT_TLS_CA_CERT
@@ -578,8 +580,8 @@ void MqttReconnect(void)
}
#if defined(USE_MQTT_TLS) && defined(USE_MQTT_AWS_IOT)
// don't enable MQTT for AWS IoT if Private Key or Certificate are not set
- if (Settings.flag4.mqtt_tls && Mqtt.tls_private_key) {
- if (!AWS_IoT_Private_Key || !AWS_IoT_Client_Certificate) {
+ if (Mqtt.mqtt_tls) {
+ if (0 == strlen(SettingsText(SET_MQTT_PWD))) { // we anticipate that an empty password does not make sense with TLS. This avoids failed connections
Mqtt.allowed = false;
}
}
@@ -614,7 +616,7 @@ void MqttReconnect(void)
if (MqttClient.connected()) { MqttClient.disconnect(); }
#ifdef USE_MQTT_TLS
- if (Settings.flag4.mqtt_tls) {
+ if (Mqtt.mqtt_tls) {
tlsClient->stop();
} else {
EspClient = WiFiClient(); // Wifi Client reconnect issue 4497 (https://github.com/esp8266/Arduino/issues/4497)
@@ -632,10 +634,12 @@ void MqttReconnect(void)
MqttClient.setCallback(MqttDataHandler);
#if defined(USE_MQTT_TLS) && defined(USE_MQTT_AWS_IOT)
// re-assign private keys in case it was updated in between
- if (Settings.flag4.mqtt_tls) {
- tlsClient->setClientECCert(AWS_IoT_Client_Certificate,
- AWS_IoT_Private_Key,
- 0xFFFF /* all usages, don't care */, 0);
+ if (Mqtt.mqtt_tls) {
+ if ((nullptr != AWS_IoT_Private_Key) && (nullptr != AWS_IoT_Client_Certificate)) {
+ tlsClient->setClientECCert(AWS_IoT_Client_Certificate,
+ AWS_IoT_Private_Key,
+ 0xFFFF /* all usages, don't care */, 0);
+ }
}
#endif
MqttClient.setServer(SettingsText(SET_MQTT_HOST), Settings.mqtt_port);
@@ -645,7 +649,7 @@ void MqttReconnect(void)
bool allow_all_fingerprints;
bool learn_fingerprint1;
bool learn_fingerprint2;
- if (Settings.flag4.mqtt_tls) {
+ if (Mqtt.mqtt_tls) {
allow_all_fingerprints = false;
learn_fingerprint1 = is_fingerprint_mono_value(Settings.mqtt_fingerprint[0], 0x00);
learn_fingerprint2 = is_fingerprint_mono_value(Settings.mqtt_fingerprint[1], 0x00);
@@ -658,16 +662,18 @@ void MqttReconnect(void)
#endif
bool lwt_retain = Settings.flag4.mqtt_no_retain ? false : true; // no retained last will if "no_retain"
#if defined(USE_MQTT_TLS) && defined(USE_MQTT_AWS_IOT)
- if (Settings.flag4.mqtt_tls && Mqtt.tls_private_key) {
- // If we require private key then we should null user/pwd
- mqtt_user = nullptr;
- mqtt_pwd = nullptr;
+ if (Mqtt.mqtt_tls) {
+ if ((nullptr != AWS_IoT_Private_Key) && (nullptr != AWS_IoT_Client_Certificate)) {
+ // if private key is there, we remove user/pwd
+ mqtt_user = nullptr;
+ mqtt_pwd = nullptr;
+ }
}
#endif
if (MqttClient.connect(mqtt_client, mqtt_user, mqtt_pwd, stopic, 1, lwt_retain, mqtt_data, MQTT_CLEAN_SESSION)) {
#ifdef USE_MQTT_TLS
- if (Settings.flag4.mqtt_tls) {
+ if (Mqtt.mqtt_tls) {
AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_MQTT "TLS connected in %d ms, max ThunkStack used %d"),
millis() - mqtt_connect_time, tlsClient->getMaxThunkStackUse());
if (!tlsClient->getMFLNStatus()) {
@@ -739,7 +745,7 @@ void MqttReconnect(void)
MqttConnected();
} else {
#ifdef USE_MQTT_TLS
- if (Settings.flag4.mqtt_tls) {
+ if (Mqtt.mqtt_tls) {
AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_MQTT "TLS connection error: %d"), tlsClient->getLastError());
}
#endif
@@ -1311,7 +1317,7 @@ void HandleMqttConfiguration(void)
SettingsText(SET_MQTT_HOST),
Settings.mqtt_port,
#ifdef USE_MQTT_TLS
- Settings.flag4.mqtt_tls ? " checked" : "", // SetOption102 - Enable MQTT TLS
+ Mqtt.mqtt_tls ? " checked" : "", // SetOption102 - Enable MQTT TLS
#endif // USE_MQTT_TLS
Format(str, MQTT_CLIENT_ID, sizeof(str)), MQTT_CLIENT_ID, SettingsText(SET_MQTT_CLIENT));
WSContentSend_P(HTTP_FORM_MQTT2,
@@ -1346,7 +1352,7 @@ void MqttSaveSettings(void)
WebGetArg("ml", tmp, sizeof(tmp));
Settings.mqtt_port = (!strlen(tmp)) ? MQTT_PORT : atoi(tmp);
#ifdef USE_MQTT_TLS
- Settings.flag4.mqtt_tls = Webserver->hasArg("b3"); // SetOption102 - Enable MQTT TLS
+ Mqtt.mqtt_tls = Webserver->hasArg("b3"); // SetOption102 - Enable MQTT TLS
#endif
WebGetArg("mc", tmp, sizeof(tmp));
SettingsUpdateText(SET_MQTT_CLIENT, (!strlen(tmp)) ? MQTT_CLIENT_ID : tmp);
From ea85b706853957b94dc73d29da161c3b6f23309f Mon Sep 17 00:00:00 2001
From: Stephan Hadinger
Date: Mon, 14 Sep 2020 22:06:19 +0200
Subject: [PATCH 23/23] Zigbee minor improvements
---
tasmota/support.ino | 24 ++++
tasmota/xdrv_23_zigbee_1_headers.ino | 1 +
tasmota/xdrv_23_zigbee_1z_libs.ino | 19 ++-
tasmota/xdrv_23_zigbee_2_devices.ino | 63 +++++----
tasmota/xdrv_23_zigbee_5_converters.ino | 74 +++++++++++
tasmota/xdrv_23_zigbee_8_parsers.ino | 73 ++++++----
tasmota/xdrv_23_zigbee_9_serial.ino | 2 +
tasmota/xdrv_23_zigbee_A_impl.ino | 170 +++++++++++-------------
8 files changed, 266 insertions(+), 160 deletions(-)
diff --git a/tasmota/support.ino b/tasmota/support.ino
index 8d4044906..eddffeab6 100644
--- a/tasmota/support.ino
+++ b/tasmota/support.ino
@@ -2006,3 +2006,27 @@ String Decompress(const char * compressed, size_t uncompressed_size) {
}
#endif // USE_UNISHOX_COMPRESSION
+
+/*********************************************************************************************\
+ * High entropy hardware random generator
+ * Thanks to DigitalAlchemist
+\*********************************************************************************************/
+// Based on code from https://raw.githubusercontent.com/espressif/esp-idf/master/components/esp32/hw_random.c
+uint32_t HwRandom(void) {
+#if ESP8266
+ // https://web.archive.org/web/20160922031242/http://esp8266-re.foogod.com/wiki/Random_Number_Generator
+ #define _RAND_ADDR 0x3FF20E44UL
+#else // ESP32
+ #define _RAND_ADDR 0x3FF75144UL
+#endif
+ static uint32_t last_ccount = 0;
+ uint32_t ccount;
+ uint32_t result = 0;
+ do {
+ ccount = ESP.getCycleCount();
+ result ^= *(volatile uint32_t *)_RAND_ADDR;
+ } while (ccount - last_ccount < 64);
+ last_ccount = ccount;
+ return result ^ *(volatile uint32_t *)_RAND_ADDR;
+#undef _RAND_ADDR
+}
diff --git a/tasmota/xdrv_23_zigbee_1_headers.ino b/tasmota/xdrv_23_zigbee_1_headers.ino
index 604c53835..c7e3093e2 100644
--- a/tasmota/xdrv_23_zigbee_1_headers.ino
+++ b/tasmota/xdrv_23_zigbee_1_headers.ino
@@ -37,6 +37,7 @@ public:
};
void ZigbeeZCLSend_Raw(const ZigbeeZCLSendMessage &zcl);
+bool ZbAppendWriteBuf(SBuffer & buf, const Z_attribute & attr, bool prepend_status_ok = false);
// get the result as a string (const char*) and nullptr if there is no field or the string is empty
const char * getCaseInsensitiveConstCharNull(const JsonObject &json, const char *needle) {
diff --git a/tasmota/xdrv_23_zigbee_1z_libs.ino b/tasmota/xdrv_23_zigbee_1z_libs.ino
index 0590cff81..1f9012152 100644
--- a/tasmota/xdrv_23_zigbee_1z_libs.ino
+++ b/tasmota/xdrv_23_zigbee_1z_libs.ino
@@ -101,11 +101,13 @@ public:
SBuffer* bval;
char* sval;
} val;
- Za_type type; // uint8_t in size, type of attribute, see above
- bool key_is_str; // is the key a string?
- bool key_is_pmem; // is the string in progmem, so we don't need to make a copy
- bool val_str_raw; // if val is String, it is raw JSON and should not be escaped
- uint8_t key_suffix; // append a suffix to key (default is 1, explicitly output if >1)
+ Za_type type; // uint8_t in size, type of attribute, see above
+ bool key_is_str; // is the key a string?
+ bool key_is_pmem; // is the string in progmem, so we don't need to make a copy
+ bool val_str_raw; // if val is String, it is raw JSON and should not be escaped
+ uint8_t key_suffix; // append a suffix to key (default is 1, explicitly output if >1)
+ uint8_t attr_type; // [opt] type of the attribute, default to Zunk (0xFF)
+ uint8_t attr_multiplier; // [opt] multiplier for attribute, defaults to 0x01 (no change)
// Constructor with all defaults
Z_attribute():
@@ -115,7 +117,9 @@ public:
key_is_str(false),
key_is_pmem(false),
val_str_raw(false),
- key_suffix(1)
+ key_suffix(1),
+ attr_type(0xFF),
+ attr_multiplier(1)
{};
Z_attribute(const Z_attribute & rhs) {
@@ -247,6 +251,7 @@ public:
}
inline bool isNum(void) const { return (type >= Za_type::Za_bool) && (type <= Za_type::Za_float); }
+ inline bool isNone(void) const { return (type == Za_type::Za_none);}
// get num values
float getFloat(void) const {
switch (type) {
@@ -483,6 +488,8 @@ protected:
key_is_str = rhs.key_is_str;
key_is_pmem = rhs.key_is_pmem;
key_suffix = rhs.key_suffix;
+ attr_type = rhs.attr_type;
+ attr_multiplier = rhs.attr_multiplier;
// copy value
copyVal(rhs);
// don't touch next pointer
diff --git a/tasmota/xdrv_23_zigbee_2_devices.ino b/tasmota/xdrv_23_zigbee_2_devices.ino
index 1e2c29704..b84db3e2e 100644
--- a/tasmota/xdrv_23_zigbee_2_devices.ino
+++ b/tasmota/xdrv_23_zigbee_2_devices.ino
@@ -951,44 +951,43 @@ uint16_t Z_Devices::parseDeviceParam(const char * param, bool short_must_be_know
// Display the tracked status for a light
String Z_Devices::dumpLightState(uint16_t shortaddr) const {
- DynamicJsonBuffer jsonBuffer;
- JsonObject& json = jsonBuffer.createObject();
+ Z_attribute_list attr_list;
char hex[8];
const Z_Device & device = findShortAddr(shortaddr);
- if (foundDevice(device)) {
- const char * fname = getFriendlyName(shortaddr);
+ const char * fname = getFriendlyName(shortaddr);
+ bool use_fname = (Settings.flag4.zigbee_use_names) && (fname); // should we replace shortaddr with friendlyname?
+ snprintf_P(hex, sizeof(hex), PSTR("0x%04X"), shortaddr);
- bool use_fname = (Settings.flag4.zigbee_use_names) && (fname); // should we replace shortaddr with friendlyname?
-
- snprintf_P(hex, sizeof(hex), PSTR("0x%04X"), shortaddr);
-
- JsonObject& dev = use_fname ? json.createNestedObject((char*) fname) // casting (char*) forces a copy
- : json.createNestedObject(hex);
- if (use_fname) {
- dev[F(D_JSON_ZIGBEE_DEVICE)] = hex;
- } else if (fname) {
- dev[F(D_JSON_ZIGBEE_NAME)] = (char*) fname;
- }
-
- // expose the last known status of the bulb, for Hue integration
- dev[F(D_JSON_ZIGBEE_LIGHT)] = getHueBulbtype(shortaddr); // sign extend, 0xFF changed as -1
- // dump all known values
- dev[F("Reachable")] = device.getReachable(); // TODO TODO
- if (device.validPower()) { dev[F("Power")] = device.getPower(); }
- if (device.validDimmer()) { dev[F("Dimmer")] = device.dimmer; }
- if (device.validColormode()) { dev[F("Colormode")] = device.colormode; }
- if (device.validCT()) { dev[F("CT")] = device.ct; }
- if (device.validSat()) { dev[F("Sat")] = device.sat; }
- if (device.validHue()) { dev[F("Hue")] = device.hue; }
- if (device.validX()) { dev[F("X")] = device.x; }
- if (device.validY()) { dev[F("Y")] = device.y; }
+ attr_list.addAttribute(F(D_JSON_ZIGBEE_DEVICE)).setStr(hex);
+ if (fname) {
+ attr_list.addAttribute(F(D_JSON_ZIGBEE_NAME)).setStr(fname);
}
- String payload = "";
- payload.reserve(200);
- json.printTo(payload);
- return payload;
+ if (foundDevice(device)) {
+ // expose the last known status of the bulb, for Hue integration
+ attr_list.addAttribute(F(D_JSON_ZIGBEE_LIGHT)).setInt(getHueBulbtype(shortaddr)); // sign extend, 0xFF changed as -1
+ // dump all known values
+ attr_list.addAttribute(F("Reachable")).setBool(device.getReachable());
+ if (device.validPower()) { attr_list.addAttribute(F("Power")).setUInt(device.getPower()); }
+ if (device.validDimmer()) { attr_list.addAttribute(F("Dimmer")).setUInt(device.dimmer); }
+ if (device.validColormode()) { attr_list.addAttribute(F("Colormode")).setUInt(device.colormode); }
+ if (device.validCT()) { attr_list.addAttribute(F("CT")).setUInt(device.ct); }
+ if (device.validSat()) { attr_list.addAttribute(F("Sat")).setUInt(device.sat); }
+ if (device.validHue()) { attr_list.addAttribute(F("Hue")).setUInt(device.hue); }
+ if (device.validX()) { attr_list.addAttribute(F("X")).setUInt(device.x); }
+ if (device.validY()) { attr_list.addAttribute(F("Y")).setUInt(device.y); }
+ }
+
+ Z_attribute_list attr_list_root;
+ Z_attribute * attr_root;
+ if (use_fname) {
+ attr_root = &attr_list_root.addAttribute(fname);
+ } else {
+ attr_root = &attr_list_root.addAttribute(hex);
+ }
+ attr_root->setStrRaw(attr_list.toString(true).c_str());
+ return attr_list_root.toString(true);
}
// Dump the internal memory of Zigbee devices
diff --git a/tasmota/xdrv_23_zigbee_5_converters.ino b/tasmota/xdrv_23_zigbee_5_converters.ino
index edcdb3135..f29c514d5 100644
--- a/tasmota/xdrv_23_zigbee_5_converters.ino
+++ b/tasmota/xdrv_23_zigbee_5_converters.ino
@@ -1664,4 +1664,78 @@ void ZCLFrame::postProcessAttributes(uint16_t shortaddr, Z_attribute_list& attr_
}
}
+//
+// Given an attribute string, retrieve all attribute details.
+// Input: the attribute has a key name, either: / or /% or ""
+// Ex: "0008/0000", "0008/0000%20", "Dimmer"
+// Use:
+// Z_attribute attr;
+// attr.setKeyName("0008/0000%20")
+// if (Z_parseAttributeKey(attr)) {
+// // ok
+// }
+//
+// Output:
+// The `attr` attribute has the correct cluster, attr_id, attr_type, attr_multiplier
+// Note: the attribute value is unchanged and unparsed
+//
+// Note: if the type is specified in the key, the multiplier is not applied, no conversion happens
+bool Z_parseAttributeKey(class Z_attribute & attr) {
+ // check if the name has the format "XXXX/YYYY" where XXXX is the cluster, YYYY the attribute id
+ // alternative "XXXX/YYYY%ZZ" where ZZ is the type (for unregistered attributes)
+ if (attr.key_is_str) {
+ const char * key = attr.key.key;
+ char * delimiter = strchr(key, '/');
+ char * delimiter2 = strchr(key, '%');
+ if (delimiter) {
+ uint16_t attr_id = 0xFFFF;
+ uint16_t cluster_id = 0xFFFF;
+ uint8_t type_id = Zunk;
+
+ cluster_id = strtoul(key, &delimiter, 16);
+ if (!delimiter2) {
+ attr_id = strtoul(delimiter+1, nullptr, 16);
+ } else {
+ attr_id = strtoul(delimiter+1, &delimiter2, 16);
+ type_id = strtoul(delimiter2+1, nullptr, 16);
+ }
+ attr.setKeyId(cluster_id, attr_id);
+ attr.attr_type = type_id;
+ }
+ }
+ // AddLog_P2(LOG_LEVEL_DEBUG, PSTR("cluster_id = 0x%04X, attr_id = 0x%04X"), cluster_id, attr_id);
+
+ // do we already know the type, i.e. attribute and cluster are also known
+ if (Zunk == attr.attr_type) {
+ // scan attributes to find by name, and retrieve type
+ for (uint32_t i = 0; i < ARRAY_SIZE(Z_PostProcess); i++) {
+ const Z_AttributeConverter *converter = &Z_PostProcess[i];
+ bool match = false;
+ uint16_t local_attr_id = pgm_read_word(&converter->attribute);
+ uint16_t local_cluster_id = CxToCluster(pgm_read_byte(&converter->cluster_short));
+ uint8_t local_type_id = pgm_read_byte(&converter->type);
+ int8_t local_multiplier = pgm_read_byte(&converter->multiplier);
+ // AddLog_P2(LOG_LEVEL_DEBUG, PSTR("Try cluster = 0x%04X, attr = 0x%04X, type_id = 0x%02X"), local_cluster_id, local_attr_id, local_type_id);
+
+ if (!attr.key_is_str) {
+ if ((attr.key.id.cluster == local_cluster_id) && (attr.key.id.attr_id == local_attr_id)) {
+ attr.attr_type = local_type_id;
+ break;
+ }
+ } else if (pgm_read_word(&converter->name_offset)) {
+ const char * key = attr.key.key;
+ // AddLog_P2(LOG_LEVEL_DEBUG, PSTR("Comparing '%s' with '%s'"), attr_name, converter->name);
+ if (0 == strcasecmp_P(key, Z_strings + pgm_read_word(&converter->name_offset))) {
+ // match
+ attr.setKeyId(local_cluster_id, local_attr_id);
+ attr.attr_type = local_type_id;
+ attr.attr_multiplier = local_multiplier;
+ break;
+ }
+ }
+ }
+ }
+ return (Zunk != attr.attr_type) ? true : false;
+}
+
#endif // USE_ZIGBEE
diff --git a/tasmota/xdrv_23_zigbee_8_parsers.ino b/tasmota/xdrv_23_zigbee_8_parsers.ino
index c7585134b..c761cabb6 100644
--- a/tasmota/xdrv_23_zigbee_8_parsers.ino
+++ b/tasmota/xdrv_23_zigbee_8_parsers.ino
@@ -1768,20 +1768,21 @@ int32_t Z_State_Ready(uint8_t value) {
//
// Mostly used for routers/end-devices
// json: holds the attributes in JSON format
-void Z_AutoResponder(uint16_t srcaddr, uint16_t cluster, uint8_t endpoint, const uint16_t *attr_list, size_t attr_len) {
- DynamicJsonBuffer jsonBuffer;
- JsonObject& json_out = jsonBuffer.createObject();
+void Z_AutoResponder(uint16_t srcaddr, uint16_t cluster, uint8_t endpoint, const uint16_t *attr_list_ids, size_t attr_len) {
+ Z_attribute_list attr_list;
for (uint32_t i=0; i 0xFEFF) ? uxy[i] : 0xFEFF;
}
- if (0x0000 == attr) { json_out[F("Hue")] = changeUIntScale(hue, 0, 360, 0, 254); }
- if (0x0001 == attr) { json_out[F("Sat")] = changeUIntScale(sat, 0, 255, 0, 254); }
- if (0x0003 == attr) { json_out[F("X")] = uxy[0]; }
- if (0x0004 == attr) { json_out[F("Y")] = uxy[1]; }
- if (0x0007 == attr) { json_out[F("CT")] = LightGetColorTemp(); }
+ if (0x0000 == attr_id) { attr.setUInt(changeUIntScale(hue, 0, 360, 0, 254)); }
+ if (0x0001 == attr_id) { attr.setUInt(changeUIntScale(sat, 0, 255, 0, 254)); }
+ if (0x0003 == attr_id) { attr.setUInt(uxy[0]); }
+ if (0x0004 == attr_id) { attr.setUInt(uxy[1]); }
+ if (0x0007 == attr_id) { attr.setUInt(LightGetColorTemp()); }
}
break;
#endif
case 0x000A0000: // Time
- json_out[F("Time")] = (Rtc.utc_time > (60 * 60 * 24 * 365 * 10)) ? Rtc.utc_time - 946684800 : Rtc.utc_time;
+ attr.setUInt((Rtc.utc_time > (60 * 60 * 24 * 365 * 10)) ? Rtc.utc_time - 946684800 : Rtc.utc_time);
break;
case 0x000AFF00: // TimeEpoch - Tasmota specific
- json_out[F("TimeEpoch")] = Rtc.utc_time;
+ attr.setUInt(Rtc.utc_time);
break;
case 0x000A0001: // TimeStatus
- json_out[F("TimeStatus")] = (Rtc.utc_time > (60 * 60 * 24 * 365 * 10)) ? 0x02 : 0x00; // if time is beyond 2010 then we are synchronized
+ attr.setUInt((Rtc.utc_time > (60 * 60 * 24 * 365 * 10)) ? 0x02 : 0x00); // if time is beyond 2010 then we are synchronized
break;
case 0x000A0002: // TimeZone
- json_out[F("TimeZone")] = Settings.toffset[0] * 60;
+ attr.setUInt(Settings.toffset[0] * 60);
break;
case 0x000A0007: // LocalTime // TODO take DST
- json_out[F("LocalTime")] = Settings.toffset[0] * 60 + ((Rtc.utc_time > (60 * 60 * 24 * 365 * 10)) ? Rtc.utc_time - 946684800 : Rtc.utc_time);
+ attr.setUInt(Settings.toffset[0] * 60 + ((Rtc.utc_time > (60 * 60 * 24 * 365 * 10)) ? Rtc.utc_time - 946684800 : Rtc.utc_time));
break;
}
+ if (!attr.isNone()) {
+ Z_parseAttributeKey(attr);
+ attr_list.addAttribute(cluster, attr_id) = attr;
+ }
}
- if (json_out.size() > 0) {
+ SBuffer buf(200);
+ for (const auto & attr : attr_list) {
+ if (!ZbAppendWriteBuf(buf, attr, true)) { // true = need status indicator in Read Attribute Responses
+ return; // error
+ }
+ }
+
+ if (buf.len() > 0) {
// we have a non-empty output
// log first
- String msg("");
- msg.reserve(100);
- json_out.printTo(msg);
AddLog_P2(LOG_LEVEL_INFO, PSTR("ZIG: Auto-responder: ZbSend {\"Device\":\"0x%04X\""
",\"Cluster\":\"0x%04X\""
",\"Endpoint\":%d"
",\"Response\":%s}"
),
srcaddr, cluster, endpoint,
- msg.c_str());
+ attr_list.toString().c_str());
// send
- const JsonVariant &json_out_v = json_out;
- ZbSendReportWrite(json_out_v, srcaddr, 0 /* group */,cluster, endpoint, 0 /* manuf */, ZCL_READ_ATTRIBUTES_RESPONSE);
+ // all good, send the packet
+ uint8_t seq = zigbee_devices.getNextSeqNumber(srcaddr);
+ ZigbeeZCLSend_Raw(ZigbeeZCLSendMessage({
+ srcaddr,
+ 0x0000,
+ cluster /*cluster*/,
+ endpoint,
+ ZCL_READ_ATTRIBUTES_RESPONSE,
+ 0x0000, /* manuf */
+ false /* not cluster specific */,
+ false /* no response */,
+ seq, /* zcl transaction id */
+ buf.getBuffer(), buf.len()
+ }));
}
}
diff --git a/tasmota/xdrv_23_zigbee_9_serial.ino b/tasmota/xdrv_23_zigbee_9_serial.ino
index fd69ee16a..c14c7f248 100644
--- a/tasmota/xdrv_23_zigbee_9_serial.ino
+++ b/tasmota/xdrv_23_zigbee_9_serial.ino
@@ -595,7 +595,9 @@ int32_t ZigbeeProcessInputEZSP(class SBuffer &buf) {
case EZSP_getNetworkParameters: // 2800
case EZSP_sendUnicast: // 3400
case EZSP_sendBroadcast: // 3600
+ case EZSP_sendMulticast: // 3800
case EZSP_messageSentHandler: // 3F00
+ case EZSP_incomingMessageHandler: // 4500
case EZSP_setConfigurationValue: // 5300
case EZSP_setPolicy: // 5500
case 0x0059: // 5900 - supposedly removed by still happening
diff --git a/tasmota/xdrv_23_zigbee_A_impl.ino b/tasmota/xdrv_23_zigbee_A_impl.ino
index 495db0e1b..5ca3b555e 100644
--- a/tasmota/xdrv_23_zigbee_A_impl.ino
+++ b/tasmota/xdrv_23_zigbee_A_impl.ino
@@ -212,6 +212,34 @@ void ZbApplyMultiplier(double &val_d, int8_t multiplier) {
}
}
+//
+// Send Attribute Write, apply mutlipliers before
+//
+bool ZbAppendWriteBuf(SBuffer & buf, const Z_attribute & attr, bool prepend_status_ok) {
+ double val_d = attr.getFloat();
+ const char * val_str = attr.getStr();
+
+ if (attr.key_is_str) { return false; }
+ if (attr.isNum() && (1 != attr.attr_multiplier)) {
+ ZbApplyMultiplier(val_d, attr.attr_multiplier);
+ }
+
+ // push the value in the buffer
+ buf.add16(attr.key.id.attr_id); // prepend with attribute identifier
+ if (prepend_status_ok) {
+ buf.add8(Z_SUCCESS); // status OK = 0x00
+ }
+ buf.add8(attr.attr_type); // prepend with attribute type
+ int32_t res = encodeSingleAttribute(buf, val_d, val_str, attr.attr_type);
+ if (res < 0) {
+ // remove the attribute type we just added
+ // buf.setLen(buf.len() - (operation == ZCL_READ_ATTRIBUTES_RESPONSE ? 4 : 3));
+ AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_ZIGBEE "Unsupported attribute type %04X/%04X '0x%02X'"), attr.key.id.cluster, attr.key.id.attr_id, attr.attr_type);
+ return false;
+ }
+ return true;
+}
+
// Parse "Report", "Write", "Response" or "Condig" attribute
// Operation is one of: ZCL_REPORT_ATTRIBUTES (0x0A), ZCL_WRITE_ATTRIBUTES (0x02) or ZCL_READ_ATTRIBUTES_RESPONSE (0x01)
void ZbSendReportWrite(const JsonObject &val_pubwrite, uint16_t device, uint16_t groupaddr, uint16_t cluster, uint8_t endpoint, uint16_t manuf, uint8_t operation) {
@@ -226,99 +254,42 @@ void ZbSendReportWrite(const JsonObject &val_pubwrite, uint16_t device, uint16_t
const char *key = it->key;
const JsonVariant &value = it->value;
- uint16_t attr_id = 0xFFFF;
- uint16_t cluster_id = 0xFFFF;
- uint8_t type_id = Znodata;
- int8_t multiplier = 1; // multiplier to adjust the key value
- double val_d = 0; // I try to avoid `double` but this type capture both float and (u)int32_t without prevision loss
- const char* val_str = ""; // variant as string
-
- // check if the name has the format "XXXX/YYYY" where XXXX is the cluster, YYYY the attribute id
- // alternative "XXXX/YYYY%ZZ" where ZZ is the type (for unregistered attributes)
- char * delimiter = strchr(key, '/');
- char * delimiter2 = strchr(key, '%');
- if (delimiter) {
- cluster_id = strtoul(key, &delimiter, 16);
- if (!delimiter2) {
- attr_id = strtoul(delimiter+1, nullptr, 16);
- } else {
- attr_id = strtoul(delimiter+1, &delimiter2, 16);
- type_id = strtoul(delimiter2+1, nullptr, 16);
- }
- }
- // AddLog_P2(LOG_LEVEL_DEBUG, PSTR("cluster_id = 0x%04X, attr_id = 0x%04X"), cluster_id, attr_id);
-
- // do we already know the type, i.e. attribute and cluster are also known
- if (Znodata == type_id) {
- // scan attributes to find by name, and retrieve type
- for (uint32_t i = 0; i < ARRAY_SIZE(Z_PostProcess); i++) {
- const Z_AttributeConverter *converter = &Z_PostProcess[i];
- bool match = false;
- uint16_t local_attr_id = pgm_read_word(&converter->attribute);
- uint16_t local_cluster_id = CxToCluster(pgm_read_byte(&converter->cluster_short));
- uint8_t local_type_id = pgm_read_byte(&converter->type);
- int8_t local_multiplier = pgm_read_byte(&converter->multiplier);
- // AddLog_P2(LOG_LEVEL_DEBUG, PSTR("Try cluster = 0x%04X, attr = 0x%04X, type_id = 0x%02X"), local_cluster_id, local_attr_id, local_type_id);
-
- if (delimiter) {
- if ((cluster_id == local_cluster_id) && (attr_id == local_attr_id)) {
- type_id = local_type_id;
- break;
- }
- } else if (pgm_read_word(&converter->name_offset)) {
- // AddLog_P2(LOG_LEVEL_DEBUG, PSTR("Comparing '%s' with '%s'"), attr_name, converter->name);
- if (0 == strcasecmp_P(key, Z_strings + pgm_read_word(&converter->name_offset))) {
- // match
- cluster_id = local_cluster_id;
- attr_id = local_attr_id;
- type_id = local_type_id;
- multiplier = local_multiplier;
- break;
- }
- }
- }
- }
-
- // Buffer ready, do some sanity checks
- // AddLog_P2(LOG_LEVEL_DEBUG, PSTR("cluster_id = 0x%04X, attr_id = 0x%04X, type_id = 0x%02X"), cluster_id, attr_id, type_id);
- if ((0xFFFF == attr_id) || (0xFFFF == cluster_id)) {
- Response_P(PSTR("{\"%s\":\"%s'%s'\"}"), XdrvMailbox.command, PSTR("Unknown attribute "), key);
- return;
- }
- if (Znodata == type_id) {
- Response_P(PSTR("{\"%s\":\"%s'%s'\"}"), XdrvMailbox.command, PSTR("Unknown attribute type for attribute "), key);
- return;
- }
-
- if (0xFFFF == cluster) {
- cluster = cluster_id; // set the cluster for this packet
- } else if (cluster != cluster_id) {
- ResponseCmndChar_P(PSTR("No more than one cluster id per command"));
- return;
- }
-
- // ////////////////////////////////////////////////////////////////////////////////
- // Split encoding depending on message
- if (operation != ZCL_CONFIGURE_REPORTING) {
- // apply multiplier if needed
- val_d = value.as();
- val_str = value.as();
- ZbApplyMultiplier(val_d, multiplier);
-
- // push the value in the buffer
- buf.add16(attr_id); // prepend with attribute identifier
- if (operation == ZCL_READ_ATTRIBUTES_RESPONSE) {
- buf.add8(Z_SUCCESS); // status OK = 0x00
- }
- buf.add8(type_id); // prepend with attribute type
- int32_t res = encodeSingleAttribute(buf, val_d, val_str, type_id);
- if (res < 0) {
- // remove the attribute type we just added
- // buf.setLen(buf.len() - (operation == ZCL_READ_ATTRIBUTES_RESPONSE ? 4 : 3));
- Response_P(PSTR("{\"%s\":\"%s'%s' 0x%02X\"}"), XdrvMailbox.command, PSTR("Unsupported attribute type "), key, type_id);
+ Z_attribute attr;
+ attr.setKeyName(key);
+ if (Z_parseAttributeKey(attr)) {
+ // Buffer ready, do some sanity checks
+ if (0xFFFF == cluster) {
+ cluster = attr.key.id.cluster; // set the cluster for this packet
+ } else if (cluster != attr.key.id.cluster) {
+ ResponseCmndChar_P(PSTR("No more than one cluster id per command"));
return;
}
+ } else {
+ if (attr.key_is_str) {
+ Response_P(PSTR("{\"%s\":\"%s'%s'\"}"), XdrvMailbox.command, PSTR("Unknown attribute "), key);
+ return;
+ }
+ if (Zunk == attr.attr_type) {
+ Response_P(PSTR("{\"%s\":\"%s'%s'\"}"), XdrvMailbox.command, PSTR("Unknown attribute type for attribute "), key);
+ return;
+ }
+ }
+
+ if (value.is()) {
+ attr.setStr(value.as());
+ } else if (value.is()) {
+ attr.setFloat(value.as());
+ }
+
+ double val_d = 0; // I try to avoid `double` but this type capture both float and (u)int32_t without prevision loss
+ const char* val_str = ""; // variant as string
+ ////////////////////////////////////////////////////////////////////////////////
+ // Split encoding depending on message
+ if (operation != ZCL_CONFIGURE_REPORTING) {
+ if (!ZbAppendWriteBuf(buf, attr, operation == ZCL_READ_ATTRIBUTES_RESPONSE)) {
+ return; // error
+ }
} else {
// ////////////////////////////////////////////////////////////////////////////////
// ZCL_CONFIGURE_REPORTING
@@ -350,7 +321,7 @@ void ZbSendReportWrite(const JsonObject &val_pubwrite, uint16_t device, uint16_t
if (nullptr != &val_attr_rc) {
val_d = val_attr_rc.as();
val_str = val_attr_rc.as();
- ZbApplyMultiplier(val_d, multiplier);
+ ZbApplyMultiplier(val_d, attr.attr_multiplier);
}
// read TimeoutPeriod
@@ -358,22 +329,22 @@ void ZbSendReportWrite(const JsonObject &val_pubwrite, uint16_t device, uint16_t
const JsonVariant &val_attr_timeout = GetCaseInsensitive(attr_config, PSTR("TimeoutPeriod"));
if (nullptr != &val_attr_timeout) { attr_timeout = strToUInt(val_attr_timeout); }
- bool attr_discrete = Z_isDiscreteDataType(type_id);
+ bool attr_discrete = Z_isDiscreteDataType(attr.attr_type);
// all fields are gathered, output the butes into the buffer, ZCL 2.5.7.1
// common bytes
buf.add8(attr_direction ? 0x01 : 0x00);
- buf.add16(attr_id);
+ buf.add16(attr.key.id.attr_id);
if (attr_direction) {
buf.add16(attr_timeout);
} else {
- buf.add8(type_id);
+ buf.add8(attr.attr_type);
buf.add16(attr_min_interval);
buf.add16(attr_max_interval);
if (!attr_discrete) {
- int32_t res = encodeSingleAttribute(buf, val_d, val_str, type_id);
+ int32_t res = encodeSingleAttribute(buf, val_d, val_str, attr.attr_type);
if (res < 0) {
- Response_P(PSTR("{\"%s\":\"%s'%s' 0x%02X\"}"), XdrvMailbox.command, PSTR("Unsupported attribute type "), key, type_id);
+ Response_P(PSTR("{\"%s\":\"%s'%s' 0x%02X\"}"), XdrvMailbox.command, PSTR("Unsupported attribute type "), key, attr.attr_type);
return;
}
}
@@ -1312,6 +1283,13 @@ void CmndZbConfig(void) {
const JsonVariant &val_txradio = GetCaseInsensitive(json, PSTR("TxRadio"));
if (nullptr != &val_txradio) { zb_txradio_dbm = strToUInt(val_txradio); }
+ // if network key is zero, we generate a truly random key with a hardware generator from ESP
+ if ((0 == zb_precfgkey_l) && (0 == zb_precfgkey_h)) {
+ AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_ZIGBEE "generating random Zigbee network key"));
+ zb_precfgkey_l = (uint64_t)HwRandom() << 32 | HwRandom();
+ zb_precfgkey_h = (uint64_t)HwRandom() << 32 | HwRandom();
+ }
+
// Check if a parameter was changed after all
if ( (zb_channel != Settings.zb_channel) ||
(zb_pan_id != Settings.zb_pan_id) ||