mirror of
https://github.com/letscontrolit/ESPEasy.git
synced 2026-07-28 04:07:47 +00:00
Compare commits
74
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fda973bb78 | ||
|
|
402de69fd5 | ||
|
|
41341b46de | ||
|
|
3574517014 | ||
|
|
cca785e1f0 | ||
|
|
4215e058d0 | ||
|
|
2f91fbe931 | ||
|
|
90febfd46f | ||
|
|
ccc5b68111 | ||
|
|
07f6b86138 | ||
|
|
7b2667feaa | ||
|
|
48bd7b334d | ||
|
|
9dd4242590 | ||
|
|
ac8c29e9c5 | ||
|
|
387b0f68a8 | ||
|
|
fa130bf649 | ||
|
|
e596403c0a | ||
|
|
1030bd0b0f | ||
|
|
985e463ddf | ||
|
|
3787fa637a | ||
|
|
ac62eb40a0 | ||
|
|
b9e883beba | ||
|
|
6281c002e0 | ||
|
|
4e8a3cab2f | ||
|
|
423b90a661 | ||
|
|
63fc99dd34 | ||
|
|
71caf09c70 | ||
|
|
ee3164a8f6 | ||
|
|
3d5f612ac9 | ||
|
|
79f2eaf808 | ||
|
|
1806a1438a | ||
|
|
5108967c35 | ||
|
|
d0f1014bef | ||
|
|
2afc143051 | ||
|
|
b2bf70e4ce | ||
|
|
6a5f090198 | ||
|
|
92c0543743 | ||
|
|
1859aaad7d | ||
|
|
7e67ce536d | ||
|
|
2bd573963a | ||
|
|
447e958e74 | ||
|
|
43908b37cd | ||
|
|
04b631e4c9 | ||
|
|
2e8fc777d2 | ||
|
|
e060c83cf8 | ||
|
|
5480af2d5d | ||
|
|
ff28605d39 | ||
|
|
fe0ca9b9a3 | ||
|
|
54ef70aee9 | ||
|
|
e24d077061 | ||
|
|
7ebf29d857 | ||
|
|
33c6925376 | ||
|
|
0b383a1f3b | ||
|
|
70d1b0807c | ||
|
|
8e1f4d628b | ||
|
|
ef29603f05 | ||
|
|
71b27d95fa | ||
|
|
787c1c6c39 | ||
|
|
74e4848edc | ||
|
|
9a7690473a | ||
|
|
c401edde6b | ||
|
|
3fc1ba27e5 | ||
|
|
b2212d2edb | ||
|
|
76f7dc82fc | ||
|
|
86233b65bc | ||
|
|
984cfe23a0 | ||
|
|
621087d48f | ||
|
|
00683a38c5 | ||
|
|
9336697f1a | ||
|
|
ad06cbc835 | ||
|
|
f5b026e678 | ||
|
|
e29eb2eb3c | ||
|
|
10329f4351 | ||
|
|
ab4750d5fa |
@@ -1,3 +1,4 @@
|
||||
### If you self compile, please state this and PLEASE try to ONLY REPORT ISSUES WITH OFFICIAL BUILDS! ###
|
||||
<!--- If you self compile, please state this and PLEASE try to ONLY REPORT ISSUES WITH OFFICIAL BUILDS! --->
|
||||
<!--- NOTE: This is not a support forum! For questions and support go here: --->
|
||||
<!--- https://www.letscontrolit.com/forum/viewforum.php?f=1 --->
|
||||
|
||||
Vendored
+135
@@ -1,3 +1,138 @@
|
||||
-------------------------------------------------
|
||||
Changes in release mega-20180802 (since mega-20180801)
|
||||
-------------------------------------------------
|
||||
|
||||
Release date: Thu Aug 2 04:00:14 CEST 2018
|
||||
|
||||
Grovkillen (1):
|
||||
Added extra info to self compilers
|
||||
|
||||
|
||||
-------------------------------------------------
|
||||
Changes in release mega-20180801 (since mega-20180723)
|
||||
-------------------------------------------------
|
||||
|
||||
Release date: Wed Aug 1 04:00:18 CEST 2018
|
||||
|
||||
Edwin Eefting (1):
|
||||
Power down PN532 after reading. Saves power and reduces interference with Wifi.
|
||||
|
||||
TD-er (11):
|
||||
[ExtraTaskSettings] Added some comments & clarifications
|
||||
[ExtraTaskSettings] Added extra clear functions and checks
|
||||
[ExtraTaskSettings] Keep ExtraTaskSettings actualized for plugin calls
|
||||
[meminfodetail] Add command `meminfodetail`
|
||||
[FileHandling] Write some log indicating file operation
|
||||
[compiler fix] Forgot to declare String
|
||||
[Storage] Split storage related functions to new file
|
||||
[Storage] Simplify settings I/O error handling
|
||||
[#882] Add checks on names in task setup
|
||||
[#1379] Check for "forbidden" characters in names.
|
||||
[#1306] Added %R% and %N% for literals \r and \n
|
||||
|
||||
|
||||
-------------------------------------------------
|
||||
Changes in release mega-20180723 (since mega-20180722)
|
||||
-------------------------------------------------
|
||||
|
||||
Release date: Mon Jul 23 04:00:09 CEST 2018
|
||||
|
||||
TD-er (8):
|
||||
[parseString] Fix 1-of error in getParamStartPos
|
||||
[parseString] Use quotes to use special characters in command parameters
|
||||
[parseString] Add checks when command parameters used as int
|
||||
[Travis CI] Signed/unsigned compare fix
|
||||
[GetArgv] Make sure only matching ", ' or [ is allowed
|
||||
[WebLogViewer] Removed reRunCount as quick fix for web log viewer
|
||||
[Compiler warning] Initialize the matching_parenthesis to something
|
||||
[GetArgv] Add some C-array size checks
|
||||
|
||||
|
||||
-------------------------------------------------
|
||||
Changes in release mega-20180722 (since mega-20180720)
|
||||
-------------------------------------------------
|
||||
|
||||
Release date: Sun Jul 22 04:00:08 CEST 2018
|
||||
|
||||
TD-er (12):
|
||||
[#1591] Move system timers to main scheduler
|
||||
[#1592] Remove systemCMDTimers
|
||||
[#1596] Remove timerSensor and make it set its own interval.
|
||||
[Log Viewer] Fix a 1-off error when parsing logs
|
||||
[LogLevel] LoadFromFile log to LOG_LEVEL_DEBUG_DEV
|
||||
[LogLevel] Use function to set loglevel and keep track of max log level
|
||||
[LogLevel] Check loglevel before sending to log
|
||||
[LogLevel] Add checks for LOG_LEVEL_DEBUG_MORE
|
||||
[LogLevel] Add checks for LOG_LEVEL_DEBUG_DEV
|
||||
[LogLevel] Added extra checks and make sure loglevel cache is up to date
|
||||
[Scheduler] Keep statistics on timeDiff computations
|
||||
[Scheduler] Call yield() when idle
|
||||
|
||||
|
||||
-------------------------------------------------
|
||||
Changes in release mega-20180720 (since mega-20180719)
|
||||
-------------------------------------------------
|
||||
|
||||
Release date: Fri Jul 20 04:00:16 CEST 2018
|
||||
|
||||
TD-er (2):
|
||||
[ParseString] Make ParseString more efficient and check results before use
|
||||
[ParseString] Fix getting the right part of the command line
|
||||
|
||||
|
||||
-------------------------------------------------
|
||||
Changes in release mega-20180719 (since mega-20180716)
|
||||
-------------------------------------------------
|
||||
|
||||
Release date: Thu Jul 19 04:00:14 CEST 2018
|
||||
|
||||
Benno Eigenmann (1):
|
||||
lib_archive already exists & Implicit dependency not found
|
||||
|
||||
TD-er (1):
|
||||
[sunrise/sunset] Allow offset from sunrise/sunset
|
||||
|
||||
denisfrench (1):
|
||||
When clientid = %sysname%, only add %unit% if non-zero
|
||||
|
||||
stefan (1):
|
||||
Fix for P077 crashes
|
||||
|
||||
|
||||
-------------------------------------------------
|
||||
Changes in release mega-20180716 (since mega-20180714)
|
||||
-------------------------------------------------
|
||||
|
||||
Release date: Mon Jul 16 04:00:09 CEST 2018
|
||||
|
||||
TD-er (4):
|
||||
[WiFi] Reset wifi when IP is set to 0.0.0.0
|
||||
[Scheduler] Complete rewrite of time based scheduling
|
||||
[JSON] Fixed broken JSON output on /json URL
|
||||
[ESP32] Show partition table on sysinfo page
|
||||
|
||||
|
||||
-------------------------------------------------
|
||||
Changes in release mega-20180714 (since mega-20180712)
|
||||
-------------------------------------------------
|
||||
|
||||
Release date: Sat Jul 14 04:00:13 CEST 2018
|
||||
|
||||
Gijs Noorlander (1):
|
||||
[#1567] Only check values set before sending
|
||||
|
||||
|
||||
-------------------------------------------------
|
||||
Changes in release mega-20180712 (since mega-20180710)
|
||||
-------------------------------------------------
|
||||
|
||||
Release date: Thu Jul 12 04:00:12 CEST 2018
|
||||
|
||||
TD-er (2):
|
||||
[#1555] Fix TSL2591 values are not transferred to controller
|
||||
[#1542] Fix Domoticz IDX more than 4 characters
|
||||
|
||||
|
||||
-------------------------------------------------
|
||||
Changes in release mega-20180710 (since mega-20180708)
|
||||
-------------------------------------------------
|
||||
|
||||
+17
-18
@@ -70,7 +70,7 @@ platform = espressif32@1.1.1
|
||||
platform = https://github.com/platformio/platform-espressif32.git#feature/stage
|
||||
|
||||
[core_esp32]
|
||||
platform = ${core_esp32_1_1_1.platform}
|
||||
platform = ${core_esp32_0_12_0.platform}
|
||||
build_flags = -D BUILD_GIT='"${sysenv.TRAVIS_TAG}"'
|
||||
-lstdc++ -lsupc++
|
||||
lib_ignore = AS_BH1750, ESP8266WiFi, ESP8266Ping, ESP8266WebServer, ESP8266HTTPUpdateServer, ESP8266mDNS, IRremoteESP8266, ESPEasy_ESP8266Ping, SerialSensors
|
||||
@@ -79,7 +79,7 @@ monitor_speed = 115200
|
||||
|
||||
|
||||
[common]
|
||||
build_flags = -D BUILD_GIT='"${sysenv.TRAVIS_TAG}"' ; ${compiler_warnings.build_flags}
|
||||
build_flags = -D BUILD_GIT='"${sysenv.TRAVIS_TAG}"'
|
||||
-D PIO_FRAMEWORK_ARDUINO_LWIP2_LOW_MEMORY
|
||||
-D NDEBUG
|
||||
-D VTABLES_IN_FLASH
|
||||
@@ -183,7 +183,6 @@ lib_deps = ${common.lib_deps}
|
||||
lib_ignore = ${common.lib_ignore}
|
||||
lib_ldf_mode = ${common.lib_ldf_mode}
|
||||
lib_archive = ${common.lib_archive}
|
||||
lib_archive = ${common.lib_archive}
|
||||
framework = ${common.framework}
|
||||
upload_speed = ${common.upload_speed}
|
||||
monitor_speed = ${common.monitor_speed}
|
||||
@@ -416,7 +415,7 @@ build_flags = ${esp8266_1M.build_flags} -D PLUGIN_BUILD_DEV -D FLA
|
||||
;lib_deps = ${common.lib_deps}
|
||||
;lib_ignore = ${common.lib_ignore}
|
||||
;lib_ldf_mode = ${common.lib_ldf_mode}
|
||||
lib_archive = ${common.lib_archive}
|
||||
;lib_archive = ${common.lib_archive}
|
||||
;board_build.flash_mode = ${Sonoff.board_build.flash_mode}
|
||||
;board = ${Sonoff.board}
|
||||
;build_flags = ${Sonoff.build_flags} -D PLUGIN_SET_SONOFF_BASIC
|
||||
@@ -430,7 +429,7 @@ lib_archive = ${common.lib_archive}
|
||||
;lib_deps = ${common.lib_deps}
|
||||
;lib_ignore = ${common.lib_ignore}
|
||||
;lib_ldf_mode = ${common.lib_ldf_mode}
|
||||
lib_archive = ${common.lib_archive}
|
||||
;lib_archive = ${common.lib_archive}
|
||||
;board_build.flash_mode = ${Sonoff.board_build.flash_mode}
|
||||
;board = ${Sonoff.board}
|
||||
;build_flags = ${Sonoff.build_flags} -D PLUGIN_SET_SONOFF_TH10
|
||||
@@ -444,7 +443,7 @@ lib_archive = ${common.lib_archive}
|
||||
;lib_deps = ${common.lib_deps}
|
||||
;lib_ignore = ${common.lib_ignore}
|
||||
;lib_ldf_mode = ${common.lib_ldf_mode}
|
||||
lib_archive = ${common.lib_archive}
|
||||
;lib_archive = ${common.lib_archive}
|
||||
;board_build.flash_mode = ${Sonoff.board_build.flash_mode}
|
||||
;board = ${Sonoff.board}
|
||||
;build_flags = ${Sonoff.build_flags} -D PLUGIN_SET_SONOFF_TH16
|
||||
@@ -498,7 +497,7 @@ build_flags = ${Sonoff.build_flags} -D PLUGIN_SET_SONOFF_POW_R2
|
||||
;lib_deps = ${common.lib_deps}
|
||||
;lib_ignore = ${common.lib_ignore}
|
||||
;lib_ldf_mode = ${common.lib_ldf_mode}
|
||||
lib_archive = ${common.lib_archive}
|
||||
;lib_archive = ${common.lib_archive}
|
||||
;board_build.flash_mode = ${Sonoff.board_build.flash_mode}
|
||||
;board = ${Sonoff.board}
|
||||
;build_flags = ${Sonoff.build_flags} -D PLUGIN_SET_SONOFF_S20
|
||||
@@ -512,7 +511,7 @@ lib_archive = ${common.lib_archive}
|
||||
;lib_deps = ${common.lib_deps}
|
||||
;lib_ignore = ${common.lib_ignore}
|
||||
;lib_ldf_mode = ${common.lib_ldf_mode}
|
||||
lib_archive = ${common.lib_archive}
|
||||
;lib_archive = ${common.lib_archive}
|
||||
;board_build.flash_mode = ${Sonoff.board_build.flash_mode}
|
||||
;board = ${Sonoff.board}
|
||||
;build_flags = ${Sonoff.build_flags} -D PLUGIN_SET_SONOFF_4CH
|
||||
@@ -526,7 +525,7 @@ lib_archive = ${common.lib_archive}
|
||||
;lib_deps = ${common.lib_deps}
|
||||
;lib_ignore = ${common.lib_ignore}
|
||||
;lib_ldf_mode = ${common.lib_ldf_mode}
|
||||
lib_archive = ${common.lib_archive}
|
||||
;lib_archive = ${common.lib_archive}
|
||||
;board_build.flash_mode = ${Sonoff.board_build.flash_mode}
|
||||
;board = ${Sonoff.board}
|
||||
;build_flags = ${Sonoff.build_flags} -D PLUGIN_SET_SONOFF_TOUCH
|
||||
@@ -544,7 +543,7 @@ lib_archive = ${common.lib_archive}
|
||||
;lib_deps = ${common.lib_deps}
|
||||
;lib_ignore = ${common.lib_ignore}
|
||||
;lib_ldf_mode = ${common.lib_ldf_mode}
|
||||
lib_archive = ${common.lib_archive}
|
||||
;lib_archive = ${common.lib_archive}
|
||||
;board_upload.maximum_size = ${esp8266_1M.board_upload.maximum_size}
|
||||
;board_build.flash_mode = ${esp8266_1M.board_build.flash_mode}
|
||||
;board = esp01_1m
|
||||
@@ -559,7 +558,7 @@ lib_archive = ${common.lib_archive}
|
||||
;lib_deps = ${common.lib_deps}
|
||||
;lib_ignore = ${common.lib_ignore}
|
||||
;lib_ldf_mode = ${common.lib_ldf_mode}
|
||||
lib_archive = ${common.lib_archive}
|
||||
;lib_archive = ${common.lib_archive}
|
||||
;board_upload.maximum_size = ${esp8266_1M.board_upload.maximum_size}
|
||||
;board_build.flash_mode = ${esp8266_1M.board_build.flash_mode}
|
||||
;board = esp01_1m
|
||||
@@ -574,7 +573,7 @@ lib_archive = ${common.lib_archive}
|
||||
;lib_deps = ${common.lib_deps}
|
||||
;lib_ignore = ${common.lib_ignore}
|
||||
;lib_ldf_mode = ${common.lib_ldf_mode}
|
||||
lib_archive = ${common.lib_archive}
|
||||
;lib_archive = ${common.lib_archive}
|
||||
;board_upload.maximum_size = ${esp8266_1M.board_upload.maximum_size}
|
||||
;board_build.flash_mode = ${esp8266_1M.board_build.flash_mode}
|
||||
;board = esp01_1m
|
||||
@@ -596,7 +595,7 @@ lib_archive = ${common.lib_archive}
|
||||
;lib_deps = ${common.lib_deps}
|
||||
;lib_ignore = ${common.lib_ignore}
|
||||
;lib_ldf_mode = ${common.lib_ldf_mode}
|
||||
lib_archive = ${common.lib_archive}
|
||||
;lib_archive = ${common.lib_archive}
|
||||
;board_upload.maximum_size = ${esp8266_1M.board_upload.maximum_size}
|
||||
;board_build.flash_mode = ${esp8266_1M.board_build.flash_mode}
|
||||
;board = esp01_1m
|
||||
@@ -612,7 +611,7 @@ lib_archive = ${common.lib_archive}
|
||||
;lib_deps = ${common.lib_deps}
|
||||
;lib_ignore = ${common.lib_ignore}
|
||||
;lib_ldf_mode = ${common.lib_ldf_mode}
|
||||
lib_archive = ${common.lib_archive}
|
||||
;lib_archive = ${common.lib_archive}
|
||||
;board_upload.maximum_size = ${esp8266_1M.board_upload.maximum_size}
|
||||
;board_build.flash_mode = ${esp8266_1M.board_build.flash_mode}
|
||||
;board = esp01_1m
|
||||
@@ -630,7 +629,7 @@ lib_archive = ${common.lib_archive}
|
||||
;lib_deps = ${common.lib_deps}
|
||||
;lib_ignore = ${common.lib_ignore}
|
||||
;lib_ldf_mode = ${common.lib_ldf_mode}
|
||||
lib_archive = ${common.lib_archive}
|
||||
;lib_archive = ${common.lib_archive}
|
||||
;board_upload.maximum_size = ${esp8266_1M.board_upload.maximum_size}
|
||||
;board_build.flash_mode = ${esp8266_1M.board_build.flash_mode}
|
||||
;board = esp01_1m
|
||||
@@ -645,7 +644,7 @@ lib_archive = ${common.lib_archive}
|
||||
;lib_deps = ${common.lib_deps}
|
||||
;lib_ignore = ${common.lib_ignore}
|
||||
;lib_ldf_mode = ${common.lib_ldf_mode}
|
||||
lib_archive = ${common.lib_archive}
|
||||
;lib_archive = ${common.lib_archive}
|
||||
;board_upload.maximum_size = ${esp8266_1M.board_upload.maximum_size}
|
||||
;board_build.flash_mode = ${esp8266_1M.board_build.flash_mode}
|
||||
;board = esp01_1m
|
||||
@@ -660,7 +659,7 @@ lib_archive = ${common.lib_archive}
|
||||
;lib_deps = ${common.lib_deps}
|
||||
;lib_ignore = ${common.lib_ignore}
|
||||
;lib_ldf_mode = ${common.lib_ldf_mode}
|
||||
lib_archive = ${common.lib_archive}
|
||||
;lib_archive = ${common.lib_archive}
|
||||
;board_upload.maximum_size = ${esp8266_1M.board_upload.maximum_size}
|
||||
;board_build.flash_mode = ${esp8266_1M.board_build.flash_mode}
|
||||
;board = esp01_1m
|
||||
@@ -675,7 +674,7 @@ lib_archive = ${common.lib_archive}
|
||||
;lib_deps = ${common.lib_deps}
|
||||
;lib_ignore = ${common.lib_ignore}
|
||||
;lib_ldf_mode = ${common.lib_ldf_mode}
|
||||
lib_archive = ${common.lib_archive}
|
||||
;lib_archive = ${common.lib_archive}
|
||||
;board_upload.maximum_size = ${esp8266_1M.board_upload.maximum_size}
|
||||
;board_build.flash_mode = ${esp8266_1M.board_build.flash_mode}
|
||||
;board = esp01_1m
|
||||
|
||||
+70
-66
@@ -25,96 +25,97 @@
|
||||
\*********************************************************************************************/
|
||||
bool doExecuteCommand(const char * cmd, struct EventStruct *event, const char* line) {
|
||||
// Simple macro to match command to function call.
|
||||
#define COMMAND_CASE(S,C) if (strcmp_P(cmd_lc, PSTR(S)) == 0) return (C(event,line));
|
||||
|
||||
String tmpcmd;
|
||||
tmpcmd = cmd;
|
||||
tmpcmd.toLowerCase();
|
||||
String log = F("Command: ");
|
||||
log += tmpcmd;
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
char cmd_lc[INPUT_COMMAND_SIZE];
|
||||
tmpcmd.toCharArray(cmd_lc, tmpcmd.length() + 1);
|
||||
#define COMMAND_CASE(S,C) if (strcmp_P(cmd_lc, PSTR(S)) == 0) return (C(event,line));
|
||||
|
||||
String tmpcmd;
|
||||
tmpcmd = cmd;
|
||||
tmpcmd.toLowerCase();
|
||||
String log = F("Command: ");
|
||||
log += tmpcmd;
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
char cmd_lc[INPUT_COMMAND_SIZE];
|
||||
tmpcmd.toCharArray(cmd_lc, tmpcmd.length() + 1);
|
||||
switch (cmd_lc[0]) {
|
||||
case 'a': {
|
||||
case 'a': {
|
||||
COMMAND_CASE("accessinfo" , Command_AccessInfo_Ls); // Network Command
|
||||
break;
|
||||
}
|
||||
case 'b': {
|
||||
break;
|
||||
}
|
||||
case 'b': {
|
||||
COMMAND_CASE("background" , Command_Background); // Diagnostic.h
|
||||
#ifdef CPLUGIN_012
|
||||
COMMAND_CASE("blynkget" , Command_Blynk_Get);
|
||||
#endif
|
||||
COMMAND_CASE("build" , Command_Settings_Build); // Settings.h
|
||||
break;
|
||||
}
|
||||
case 'c': {
|
||||
break;
|
||||
}
|
||||
case 'c': {
|
||||
COMMAND_CASE("clearaccessblock" , Command_AccessInfo_Clear); // Network Command
|
||||
COMMAND_CASE("clearrtcram" , Command_RTC_Clear); // RTC.h
|
||||
COMMAND_CASE("config" , Command_Task_RemoteConfig); // Tasks.h
|
||||
break;
|
||||
}
|
||||
case 'd': {
|
||||
break;
|
||||
}
|
||||
case 'd': {
|
||||
COMMAND_CASE("debug" , Command_Debug); // Diagnostic.h
|
||||
COMMAND_CASE("deepsleep" , Command_System_deepSleep); // System.h
|
||||
COMMAND_CASE("delay" , Command_Delay); // Timers.h
|
||||
COMMAND_CASE("dns" , Command_DNS); // Network Command
|
||||
COMMAND_CASE("dst" , Command_DST); // Time.h
|
||||
break;
|
||||
}
|
||||
case 'e': {
|
||||
break;
|
||||
}
|
||||
case 'e': {
|
||||
COMMAND_CASE("erase" , Command_WiFi_Erase); // WiFi.h
|
||||
COMMAND_CASE("event" , Command_Rules_Events); // Rule.h
|
||||
COMMAND_CASE("executerules" , Command_Rules_Execute); // Rule.h
|
||||
break;
|
||||
}
|
||||
case 'g': {
|
||||
break;
|
||||
}
|
||||
case 'g': {
|
||||
COMMAND_CASE("gateway" , Command_Gateway); // Network Command
|
||||
break;
|
||||
}
|
||||
case 'i': {
|
||||
break;
|
||||
}
|
||||
case 'i': {
|
||||
COMMAND_CASE("i2cscanner" , Command_i2c_Scanner); // i2c.h
|
||||
COMMAND_CASE("ip" , Command_IP); // Network Command
|
||||
break;
|
||||
}
|
||||
case 'l': {
|
||||
break;
|
||||
}
|
||||
case 'l': {
|
||||
COMMAND_CASE("load" , Command_Settings_Load); // Settings.h
|
||||
COMMAND_CASE("logentry" , Command_logentry); // Diagnostic.h
|
||||
COMMAND_CASE("lowmem" , Command_Lowmem); // Diagnostic.h
|
||||
break;
|
||||
}
|
||||
case 'm': {
|
||||
break;
|
||||
}
|
||||
case 'm': {
|
||||
COMMAND_CASE("malloc" , Command_Malloc); // Diagnostic.h
|
||||
COMMAND_CASE("meminfo" , Command_MenInfo); // Diagnostic.h
|
||||
COMMAND_CASE("meminfo" , Command_MemInfo); // Diagnostic.h
|
||||
COMMAND_CASE("meminfodetail" , Command_MemInfo_detail); // Diagnostic.h
|
||||
COMMAND_CASE("messagedelay" , Command_MQTT_messageDelay); // MQTT.h
|
||||
COMMAND_CASE("mqttretainflag" , Command_MQTT_Retain); // MQTT.h
|
||||
break;
|
||||
}
|
||||
case 'n': {
|
||||
break;
|
||||
}
|
||||
case 'n': {
|
||||
COMMAND_CASE("name" , Command_Settings_Name); // Settings.h
|
||||
COMMAND_CASE("nosleep" , Command_System_NoSleep); // System.h
|
||||
COMMAND_CASE("notify" , Command_Notifications_Notify); // Notifications.h
|
||||
COMMAND_CASE("ntphost" , Command_NTPHost); // Time.h
|
||||
break;
|
||||
}
|
||||
case 'p': {
|
||||
break;
|
||||
}
|
||||
case 'p': {
|
||||
COMMAND_CASE("password" , Command_Settings_Password); // Settings.h
|
||||
COMMAND_CASE("publish" , Command_MQTT_Publish); // MQTT.h
|
||||
break;
|
||||
}
|
||||
case 'r': {
|
||||
break;
|
||||
}
|
||||
case 'r': {
|
||||
COMMAND_CASE("reboot" , Command_System_Reboot); // System.h
|
||||
COMMAND_CASE("reset" , Command_Settings_Reset); // Settings.h
|
||||
COMMAND_CASE("resetflashwritecounter" , Command_RTC_resetFlashWriteCounter); // RTC.h
|
||||
COMMAND_CASE("restart" , Command_System_Restart); // System.h
|
||||
COMMAND_CASE("rules" , Command_Rules_UseRules); // Rule.h
|
||||
break;
|
||||
}
|
||||
case 's': {
|
||||
break;
|
||||
}
|
||||
case 's': {
|
||||
COMMAND_CASE("save" , Command_Settings_Save); // Settings.h
|
||||
#if FEATURE_SD
|
||||
COMMAND_CASE("sdcard" , Command_SD_LS); // SDCARDS.h
|
||||
COMMAND_CASE("sdremove" , Command_SD_Remove); // SDCARDS.h
|
||||
COMMAND_CASE("sdremove" , Command_SD_Remove); // SDCARDS.h
|
||||
#endif
|
||||
COMMAND_CASE("sendto" , Command_UPD_SendTo); // UDP.h
|
||||
COMMAND_CASE("sendtohttp" , Command_HTTP_SendToHTTP); // HTTP.h
|
||||
@@ -123,9 +124,9 @@ bool doExecuteCommand(const char * cmd, struct EventStruct *event, const char* l
|
||||
COMMAND_CASE("settings" , Command_Settings_Print); // Settings.h
|
||||
COMMAND_CASE("subnet" , Command_Subnet); // Network Command
|
||||
COMMAND_CASE("sysload" , Command_SysLoad); // Diagnostic.h
|
||||
break;
|
||||
}
|
||||
case 't': {
|
||||
break;
|
||||
}
|
||||
case 't': {
|
||||
COMMAND_CASE("taskclear" , Command_Task_Clear); // Tasks.h
|
||||
COMMAND_CASE("taskclearall" , Command_Task_ClearAll); // Tasks.h
|
||||
COMMAND_CASE("taskrun" , Command_Task_Run); // Tasks.h
|
||||
@@ -135,16 +136,16 @@ bool doExecuteCommand(const char * cmd, struct EventStruct *event, const char* l
|
||||
COMMAND_CASE("timerresume" , Command_Timer_Resume); // Timers.h
|
||||
COMMAND_CASE("timerset" , Command_Timer_Set); // Timers.h
|
||||
COMMAND_CASE("timezone" , Command_TimeZone); // Time.h
|
||||
break;
|
||||
}
|
||||
case 'u': {
|
||||
break;
|
||||
}
|
||||
case 'u': {
|
||||
COMMAND_CASE("udpport" , Command_UDP_Port); // UDP.h
|
||||
COMMAND_CASE("udptest" , Command_UDP_Test); // UDP.h
|
||||
COMMAND_CASE("unit" , Command_Settings_Unit); // Settings.h
|
||||
COMMAND_CASE("usentp" , Command_useNTP); // Time.h
|
||||
break;
|
||||
}
|
||||
case 'w': {
|
||||
break;
|
||||
}
|
||||
case 'w': {
|
||||
COMMAND_CASE("wdconfig" , Command_WD_Config); // WD.h
|
||||
COMMAND_CASE("wdread" , Command_WD_Read); // WD.h
|
||||
COMMAND_CASE("wifiapmode" , Command_Wifi_APMode); // WiFi.h
|
||||
@@ -157,12 +158,15 @@ bool doExecuteCommand(const char * cmd, struct EventStruct *event, const char* l
|
||||
COMMAND_CASE("wifissid" , Command_Wifi_SSID); // WiFi.h
|
||||
COMMAND_CASE("wifissid2" , Command_Wifi_SSID2); // WiFi.h
|
||||
COMMAND_CASE("wifistamode" , Command_Wifi_STAMode); // WiFi.h
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
addLog(LOG_LEVEL_INFO, F("Command unknown"));
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
String errorUnknown = F("Command unknown: \"");
|
||||
errorUnknown += cmd_lc;
|
||||
errorUnknown += '\"';
|
||||
addLog(LOG_LEVEL_INFO, errorUnknown);
|
||||
return false;
|
||||
|
||||
#undef COMMAND_CASE
|
||||
@@ -175,17 +179,17 @@ void ExecuteCommand(byte source, const char *Line)
|
||||
boolean success = false;
|
||||
char TmpStr1[INPUT_COMMAND_SIZE];
|
||||
TmpStr1[0] = 0;
|
||||
char cmd[INPUT_COMMAND_SIZE];
|
||||
char cmd[INPUT_COMMAND_SIZE];
|
||||
cmd[0] = 0;
|
||||
struct EventStruct TempEvent;
|
||||
TempEvent.Source = source;
|
||||
TempEvent.Source = source;
|
||||
GetArgv(Line, cmd, 1);
|
||||
if (GetArgv(Line, TmpStr1, 2)) TempEvent.Par1 = str2int(TmpStr1);
|
||||
if (GetArgv(Line, TmpStr1, 3)) TempEvent.Par2 = str2int(TmpStr1);
|
||||
if (GetArgv(Line, TmpStr1, 4)) TempEvent.Par3 = str2int(TmpStr1);
|
||||
if (GetArgv(Line, TmpStr1, 5)) TempEvent.Par4 = str2int(TmpStr1);
|
||||
if (GetArgv(Line, TmpStr1, 6)) TempEvent.Par5 = str2int(TmpStr1);
|
||||
|
||||
|
||||
success = doExecuteCommand((char*)&cmd[0], &TempEvent, Line);
|
||||
yield();
|
||||
|
||||
|
||||
+40
-10
@@ -35,21 +35,51 @@ bool Command_SerialFloat(struct EventStruct *event, const char* Line)
|
||||
pinMode(1, INPUT);
|
||||
pinMode(3, INPUT);
|
||||
delay(60000);
|
||||
return success;
|
||||
return success;
|
||||
}
|
||||
|
||||
bool Command_MenInfo(struct EventStruct *event, const char* Line)
|
||||
bool Command_MemInfo(struct EventStruct *event, const char* Line)
|
||||
{
|
||||
bool success = true;
|
||||
Serial.print(F("SecurityStruct : "));
|
||||
Serial.print(F("SecurityStruct | "));
|
||||
Serial.println(sizeof(SecuritySettings));
|
||||
Serial.print(F("SettingsStruct : "));
|
||||
Serial.print(F("SettingsStruct | "));
|
||||
Serial.println(sizeof(Settings));
|
||||
Serial.print(F("ExtraTaskSettingsStruct: "));
|
||||
Serial.print(F("ExtraTaskSettingsStruct| "));
|
||||
Serial.println(sizeof(ExtraTaskSettings));
|
||||
Serial.print(F("DeviceStruct: "));
|
||||
Serial.print(F("DeviceStruct | "));
|
||||
Serial.println(sizeof(Device));
|
||||
return success;
|
||||
return success;
|
||||
}
|
||||
|
||||
bool Command_MemInfo_detail(struct EventStruct *event, const char* Line)
|
||||
{
|
||||
bool success = true;
|
||||
Command_MemInfo(event, Line);
|
||||
for (int st = 0; st < SettingsType_MAX; ++st) {
|
||||
SettingsType settingsType = static_cast<SettingsType>(st);
|
||||
int max_index, offset, max_size;
|
||||
int struct_size = 0;
|
||||
Serial.println();
|
||||
Serial.print(getSettingsTypeString(settingsType));
|
||||
Serial.println(F(" | start | end | max_size | struct_size"));
|
||||
Serial.println(F("--- | --- | --- | --- | ---"));
|
||||
getSettingsParameters(settingsType, 0, max_index, offset, max_size, struct_size);
|
||||
for (int i = 0; i < max_index; ++i) {
|
||||
getSettingsParameters(settingsType, i, offset, max_size);
|
||||
Serial.print(i);
|
||||
Serial.print('|');
|
||||
Serial.print(offset);
|
||||
Serial.print('|');
|
||||
Serial.print(offset + max_size);
|
||||
Serial.print('|');
|
||||
Serial.print(max_size);
|
||||
Serial.print('|');
|
||||
Serial.println(struct_size);
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool Command_Background(struct EventStruct *event, const char* Line)
|
||||
@@ -60,7 +90,7 @@ bool Command_Background(struct EventStruct *event, const char* Line)
|
||||
while (!timeOutReached(timer))
|
||||
backgroundtasks();
|
||||
Serial.println(F("end"));
|
||||
return success;
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
@@ -68,7 +98,7 @@ bool Command_Debug(struct EventStruct *event, const char* Line)
|
||||
{
|
||||
char TmpStr1[INPUT_COMMAND_SIZE];
|
||||
if (GetArgv(Line, TmpStr1, 2)) {
|
||||
Settings.SerialLogLevel = event->Par1;
|
||||
setLogLevelFor(LOG_TO_SERIAL, event->Par1);
|
||||
}
|
||||
else{
|
||||
Serial.println();
|
||||
@@ -83,4 +113,4 @@ bool Command_logentry(struct EventStruct *event, const char* Line)
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif // COMMAND_DIAGNOSTIC_H
|
||||
#endif // COMMAND_DIAGNOSTIC_H
|
||||
|
||||
+16
-3
@@ -8,8 +8,20 @@ bool Command_HTTP_SendToHTTP(struct EventStruct *event, const char* Line)
|
||||
String strLine = Line;
|
||||
String host = parseString(strLine, 2);
|
||||
String port = parseString(strLine, 3);
|
||||
int pathpos = getParamStartPos(strLine, 4);
|
||||
String path = strLine.substring(pathpos);
|
||||
if (loglevelActiveFor(LOG_LEVEL_DEBUG)) {
|
||||
String log = F("SendToHTTP: Host: ");
|
||||
log += host;
|
||||
log += F(" port: ");
|
||||
log += port;
|
||||
addLog(LOG_LEVEL_DEBUG, log);
|
||||
}
|
||||
if (!isInt(port)) return false;
|
||||
String path = parseStringToEndKeepCase(strLine, 4);
|
||||
if (loglevelActiveFor(LOG_LEVEL_DEBUG)) {
|
||||
String log = F("SendToHTTP: Path: ");
|
||||
log += path;
|
||||
addLog(LOG_LEVEL_DEBUG, log);
|
||||
}
|
||||
WiFiClient client;
|
||||
if (client.connect(host.c_str(), port.toInt()))
|
||||
{
|
||||
@@ -20,6 +32,7 @@ bool Command_HTTP_SendToHTTP(struct EventStruct *event, const char* Line)
|
||||
reply += host;
|
||||
reply += F("\r\n");
|
||||
reply += F("Connection: close\r\n\r\n");
|
||||
addLog(LOG_LEVEL_DEBUG, reply);
|
||||
client.print(reply);
|
||||
|
||||
unsigned long timer = millis() + 200;
|
||||
@@ -43,4 +56,4 @@ bool Command_HTTP_SendToHTTP(struct EventStruct *event, const char* Line)
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif // COMMAND_HTTP_H
|
||||
#endif // COMMAND_HTTP_H
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
bool Command_Task_Clear(struct EventStruct *event, const char* Line)
|
||||
{
|
||||
bool success = true;
|
||||
// Par1 is here for 1 ... TASKS_MAX
|
||||
taskClear(event->Par1 - 1, true);
|
||||
return success;
|
||||
}
|
||||
@@ -12,13 +13,13 @@ bool Command_Task_Clear(struct EventStruct *event, const char* Line)
|
||||
bool Command_Task_ClearAll(struct EventStruct *event, const char* Line)
|
||||
{
|
||||
bool success = true;
|
||||
for (byte t=0; t<TASKS_MAX; t++)
|
||||
for (byte t = 0; t < TASKS_MAX; t++)
|
||||
taskClear(t, false);
|
||||
return success;
|
||||
}
|
||||
|
||||
bool Command_Task_ValueSet(struct EventStruct *event, const char* Line)
|
||||
{
|
||||
{
|
||||
bool success = true;
|
||||
char TmpStr1[INPUT_COMMAND_SIZE];
|
||||
if (GetArgv(Line, TmpStr1, 4))
|
||||
@@ -29,14 +30,14 @@ bool Command_Task_ValueSet(struct EventStruct *event, const char* Line)
|
||||
}
|
||||
else
|
||||
{
|
||||
//TODO: Get Task description and var name
|
||||
//TODO: Get Task description and var name
|
||||
Serial.println(UserVar[(VARS_PER_TASK * (event->Par1 - 1)) + event->Par2 - 1]);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
bool Command_Task_ValueSetAndRun(struct EventStruct *event, const char* Line)
|
||||
{
|
||||
{
|
||||
bool success = true;
|
||||
char TmpStr1[INPUT_COMMAND_SIZE];
|
||||
if (GetArgv(Line, TmpStr1, 4))
|
||||
@@ -50,7 +51,7 @@ bool Command_Task_ValueSetAndRun(struct EventStruct *event, const char* Line)
|
||||
}
|
||||
|
||||
bool Command_Task_Run(struct EventStruct *event, const char* Line)
|
||||
{
|
||||
{
|
||||
bool success = true;
|
||||
SensorSendTask(event->Par1 - 1);
|
||||
return success;
|
||||
@@ -64,4 +65,4 @@ bool Command_Task_RemoteConfig(struct EventStruct *event, const char* Line)
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif // COMMAND_TASKS_H
|
||||
#endif // COMMAND_TASKS_H
|
||||
|
||||
+5
-5
@@ -39,12 +39,11 @@ bool Command_UDP_SendToUPD(struct EventStruct *event, const char* Line)
|
||||
{
|
||||
bool success = false;
|
||||
if (wifiStatus == ESPEASY_WIFI_SERVICES_INITIALIZED) {
|
||||
success = true;
|
||||
String strLine = Line;
|
||||
String ip = parseString(strLine, 2);
|
||||
String port = parseString(strLine, 3);
|
||||
int msgpos = getParamStartPos(strLine, 4);
|
||||
String message = strLine.substring(msgpos);
|
||||
if (!isInt(port)) return success;
|
||||
String message = parseStringToEndKeepCase(strLine, 4);
|
||||
IPAddress UDP_IP;
|
||||
if(UDP_IP.fromString(ip)) {
|
||||
portUDP.beginPacket(UDP_IP, port.toInt());
|
||||
@@ -56,8 +55,9 @@ bool Command_UDP_SendToUPD(struct EventStruct *event, const char* Line)
|
||||
#endif
|
||||
portUDP.endPacket();
|
||||
}
|
||||
success = true;
|
||||
}
|
||||
return success;
|
||||
return success;
|
||||
}
|
||||
|
||||
#endif // COMMAND_UDP_H
|
||||
#endif // COMMAND_UDP_H
|
||||
|
||||
+16
-11
@@ -60,7 +60,8 @@ void sendData(struct EventStruct *event)
|
||||
}
|
||||
|
||||
boolean validUserVar(struct EventStruct *event) {
|
||||
for (int i = 0; i < VARS_PER_TASK; ++i) {
|
||||
byte valueCount = getValueCountFromSensorType(event->sensorType);
|
||||
for (int i = 0; i < valueCount; ++i) {
|
||||
const float f(UserVar[event->BaseVarIndex + i]);
|
||||
if (!isValidFloat(f)) return false;
|
||||
}
|
||||
@@ -92,14 +93,16 @@ void callback(char* c_topic, byte* b_payload, unsigned int length) {
|
||||
c_payload[length] = 0;
|
||||
|
||||
/*
|
||||
String log;
|
||||
log=F("MQTT : Topic: ");
|
||||
log+=c_topic;
|
||||
addLog(LOG_LEVEL_DEBUG_MORE, log);
|
||||
if (loglevelActiveFor(LOG_LEVEL_DEBUG_MORE)) {
|
||||
String log;
|
||||
log=F("MQTT : Topic: ");
|
||||
log+=c_topic;
|
||||
addLog(LOG_LEVEL_DEBUG_MORE, log);
|
||||
|
||||
log=F("MQTT : Payload: ");
|
||||
log+=c_payload;
|
||||
addLog(LOG_LEVEL_DEBUG_MORE, log);
|
||||
log=F("MQTT : Payload: ");
|
||||
log+=c_payload;
|
||||
addLog(LOG_LEVEL_DEBUG_MORE, log);
|
||||
}
|
||||
*/
|
||||
|
||||
// sprintf_P(log, PSTR("%s%s"), "MQTT : Topic: ", c_topic);
|
||||
@@ -141,8 +144,10 @@ bool MQTTConnect(int controller_idx)
|
||||
String clientid;
|
||||
if(Settings.MQTTUseUnitNameAsClientId){
|
||||
clientid = Settings.Name;
|
||||
clientid += F("_");
|
||||
clientid += Settings.Unit;
|
||||
if (Settings.Unit != 0) { // only append non-zero unit number
|
||||
clientid += F("_");
|
||||
clientid += Settings.Unit;
|
||||
}
|
||||
}
|
||||
else{
|
||||
clientid = F("ESPClient_");
|
||||
@@ -259,7 +264,7 @@ void SendStatus(byte source, String status)
|
||||
boolean MQTTpublish(int controller_idx, const char* topic, const char* payload, boolean retained)
|
||||
{
|
||||
if (MQTTclient.publish(topic, payload, retained)) {
|
||||
timermqtt = millis() + 10; // Make sure the MQTT is being processed as soon as possible.
|
||||
setIntervalTimerOverride(TIMER_MQTT, 10); // Make sure the MQTT is being processed as soon as possible.
|
||||
return true;
|
||||
}
|
||||
addLog(LOG_LEVEL_DEBUG, F("MQTT : publish failed"));
|
||||
|
||||
+235
-107
@@ -196,6 +196,13 @@
|
||||
#define NODE_TYPE_ID_ARDUINO_EASY_STD 65
|
||||
#define NODE_TYPE_ID_NANO_EASY_STD 81
|
||||
|
||||
#define TIMER_20MSEC 1
|
||||
#define TIMER_100MSEC 2
|
||||
#define TIMER_1SEC 3
|
||||
#define TIMER_30SEC 4
|
||||
#define TIMER_MQTT 5
|
||||
#define TIMER_STATISTICS 6
|
||||
|
||||
#define PLUGIN_INIT_ALL 1
|
||||
#define PLUGIN_INIT 2
|
||||
#define PLUGIN_READ 3
|
||||
@@ -290,13 +297,12 @@
|
||||
#define NPLUGIN_MAX 4
|
||||
#define UNIT_MAX 32 // Only relevant for UDP unicast message 'sweeps' and the nodelist.
|
||||
#define RULES_TIMER_MAX 8
|
||||
#define SYSTEM_TIMER_MAX 8
|
||||
#define SYSTEM_CMD_TIMER_MAX 2
|
||||
#define PINSTATE_TABLE_MAX 32
|
||||
#define RULES_MAX_SIZE 2048
|
||||
#define RULES_MAX_NESTING_LEVEL 3
|
||||
#define RULESETS_MAX 4
|
||||
#define RULES_BUFFER_SIZE 64
|
||||
#define NAME_FORMULA_LENGTH_MAX 40
|
||||
|
||||
#define PIN_MODE_UNDEFINED 0
|
||||
#define PIN_MODE_INPUT 1
|
||||
@@ -339,8 +345,9 @@
|
||||
#define BOOT_CAUSE_DEEP_SLEEP 2
|
||||
#define BOOT_CAUSE_EXT_WD 10
|
||||
|
||||
#define DAT_TASKS_SIZE 2048
|
||||
#define DAT_TASKS_CUSTOM_OFFSET 1024
|
||||
#define DAT_TASKS_DISTANCE 2048 // DAT_TASKS_SIZE + DAT_TASKS_CUSTOM_SIZE
|
||||
#define DAT_TASKS_SIZE 1024
|
||||
#define DAT_TASKS_CUSTOM_OFFSET 1024 // Equal to DAT_TASKS_SIZE
|
||||
#define DAT_TASKS_CUSTOM_SIZE 1024
|
||||
#define DAT_CUSTOM_CONTROLLER_SIZE 1024
|
||||
#define DAT_CONTROLLER_SIZE 1024
|
||||
@@ -359,6 +366,30 @@
|
||||
#define CONFIG_FILE_SIZE 131072
|
||||
#endif
|
||||
|
||||
enum SettingsType {
|
||||
TaskSettings_Type = 0,
|
||||
CustomTaskSettings_Type,
|
||||
ControllerSettings_Type,
|
||||
CustomControllerSettings_Type,
|
||||
NotificationSettings_Type,
|
||||
|
||||
SettingsType_MAX
|
||||
|
||||
};
|
||||
bool getSettingsParameters(SettingsType settingsType, int index, int& offset, int& max_size);
|
||||
String getSettingsTypeString(SettingsType settingsType) {
|
||||
switch (settingsType) {
|
||||
case TaskSettings_Type: return F("TaskSettings");
|
||||
case CustomTaskSettings_Type: return F("CustomTaskSettings");
|
||||
case ControllerSettings_Type: return F("ControllerSettings");
|
||||
case CustomControllerSettings_Type: return F("CustomControllerSettings");
|
||||
case NotificationSettings_Type: return F("NotificationSettings");
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return String();
|
||||
}
|
||||
|
||||
/*
|
||||
To modify the stock configuration without changing this repo file :
|
||||
- define USE_CUSTOM_H as a build flags. ie : export PLATFORMIO_BUILD_FLAGS="'-DUSE_CUSTOM_H'"
|
||||
@@ -373,6 +404,7 @@
|
||||
#include "ESPEasyTimeTypes.h"
|
||||
#include "I2CTypes.h"
|
||||
#include <I2Cdev.h>
|
||||
#include <map>
|
||||
|
||||
#define FS_NO_GLOBALS
|
||||
#if defined(ESP8266)
|
||||
@@ -575,48 +607,94 @@ struct SecurityStruct
|
||||
|
||||
struct SettingsStruct
|
||||
{
|
||||
SettingsStruct() :
|
||||
PID(0), Version(0), Build(0), IP_Octet(0), Unit(0), Delay(0),
|
||||
Pin_i2c_sda(-1), Pin_i2c_scl(-1), Pin_status_led(-1), Pin_sd_cs(-1),
|
||||
UDPPort(0), SyslogLevel(0), SerialLogLevel(0), WebLogLevel(0), SDLogLevel(0),
|
||||
BaudRate(0), MessageDelay(0), deepSleep(0),
|
||||
CustomCSS(false), DST(false), WDI2CAddress(0),
|
||||
UseRules(false), UseSerial(false), UseSSDP(false), UseNTP(false),
|
||||
WireClockStretchLimit(0), GlobalSync(false), ConnectionFailuresThreshold(0),
|
||||
TimeZone(0), MQTTRetainFlag(false), InitSPI(false),
|
||||
Pin_status_led_Inversed(false), deepSleepOnFail(false), UseValueLogger(false),
|
||||
DST_Start(0), DST_End(0), UseRTOSMultitasking(false), Pin_Reset(-1),
|
||||
SyslogFacility(DEFAULT_SYSLOG_FACILITY), StructSize(0), MQTTUseUnitNameAsClientId(0)
|
||||
{
|
||||
for (byte i = 0; i < CONTROLLER_MAX; ++i) {
|
||||
Protocol[i] = 0;
|
||||
ControllerEnabled[i] = false;
|
||||
for (byte task = 0; task < TASKS_MAX; ++task) {
|
||||
TaskDeviceID[i][task] = 0;
|
||||
TaskDeviceSendData[i][task] = false;
|
||||
}
|
||||
}
|
||||
for (byte task = 0; task < TASKS_MAX; ++task) {
|
||||
TaskDeviceNumber[task] = 0;
|
||||
OLD_TaskDeviceID[task] = 0;
|
||||
TaskDevicePin1PullUp[task] = false;
|
||||
for (byte cv = 0; cv < PLUGIN_CONFIGVAR_MAX; ++cv) {
|
||||
TaskDevicePluginConfig[task][cv] = 0;
|
||||
}
|
||||
TaskDevicePin1Inversed[task] = false;
|
||||
for (byte cv = 0; cv < PLUGIN_CONFIGFLOATVAR_MAX; ++cv) {
|
||||
TaskDevicePluginConfigFloat[task][cv] = 0.0;
|
||||
}
|
||||
for (byte cv = 0; cv < PLUGIN_CONFIGLONGVAR_MAX; ++cv) {
|
||||
TaskDevicePluginConfigLong[task][cv] = 0;
|
||||
}
|
||||
OLD_TaskDeviceSendData[task] = false;
|
||||
TaskDeviceGlobalSync[task] = false;
|
||||
TaskDeviceDataFeed[task] = 0;
|
||||
TaskDeviceTimer[task] = 0;
|
||||
TaskDeviceEnabled[task] = false;
|
||||
}
|
||||
SettingsStruct() {
|
||||
clearAll();
|
||||
}
|
||||
|
||||
void clearAll() {
|
||||
PID = 0;
|
||||
Version = 0;
|
||||
Build = 0;
|
||||
IP_Octet = 0;
|
||||
Unit = 0;
|
||||
Delay = 0;
|
||||
Pin_i2c_sda = -1;
|
||||
Pin_i2c_scl = -1;
|
||||
Pin_status_led = -1;
|
||||
Pin_sd_cs = -1;
|
||||
UDPPort = 0;
|
||||
SyslogLevel = 0;
|
||||
SerialLogLevel = 0;
|
||||
WebLogLevel = 0;
|
||||
SDLogLevel = 0;
|
||||
BaudRate = 0;
|
||||
MessageDelay = 0;
|
||||
deepSleep = 0;
|
||||
CustomCSS = false;
|
||||
DST = false;
|
||||
WDI2CAddress = 0;
|
||||
UseRules = false;
|
||||
UseSerial = false;
|
||||
UseSSDP = false;
|
||||
UseNTP = false;
|
||||
WireClockStretchLimit = 0;
|
||||
GlobalSync = false;
|
||||
ConnectionFailuresThreshold = 0;
|
||||
TimeZone = 0;
|
||||
MQTTRetainFlag = false;
|
||||
InitSPI = false;
|
||||
Pin_status_led_Inversed = false;
|
||||
deepSleepOnFail = false;
|
||||
UseValueLogger = false;
|
||||
DST_Start = 0;
|
||||
DST_End = 0;
|
||||
UseRTOSMultitasking = false;
|
||||
Pin_Reset = -1;
|
||||
SyslogFacility = DEFAULT_SYSLOG_FACILITY;
|
||||
StructSize = 0;
|
||||
MQTTUseUnitNameAsClientId = 0;
|
||||
|
||||
for (byte i = 0; i < CONTROLLER_MAX; ++i) {
|
||||
Protocol[i] = 0;
|
||||
ControllerEnabled[i] = false;
|
||||
}
|
||||
for (byte i = 0; i < NOTIFICATION_MAX; ++i) {
|
||||
Notification[i] = 0;
|
||||
NotificationEnabled[i] = false;
|
||||
}
|
||||
for (byte task = 0; task < TASKS_MAX; ++task) {
|
||||
clearTask(task);
|
||||
}
|
||||
}
|
||||
|
||||
void clearTask(byte task) {
|
||||
for (byte i = 0; i < CONTROLLER_MAX; ++i) {
|
||||
TaskDeviceID[i][task] = 0;
|
||||
TaskDeviceSendData[i][task] = false;
|
||||
}
|
||||
TaskDeviceNumber[task] = 0;
|
||||
OLD_TaskDeviceID[task] = 0;
|
||||
TaskDevicePin1[task] = -1;
|
||||
TaskDevicePin2[task] = -1;
|
||||
TaskDevicePin3[task] = -1;
|
||||
TaskDevicePort[task] = 0;
|
||||
TaskDevicePin1PullUp[task] = false;
|
||||
for (byte cv = 0; cv < PLUGIN_CONFIGVAR_MAX; ++cv) {
|
||||
TaskDevicePluginConfig[task][cv] = 0;
|
||||
}
|
||||
TaskDevicePin1Inversed[task] = false;
|
||||
for (byte cv = 0; cv < PLUGIN_CONFIGFLOATVAR_MAX; ++cv) {
|
||||
TaskDevicePluginConfigFloat[task][cv] = 0.0;
|
||||
}
|
||||
for (byte cv = 0; cv < PLUGIN_CONFIGLONGVAR_MAX; ++cv) {
|
||||
TaskDevicePluginConfigLong[task][cv] = 0;
|
||||
}
|
||||
OLD_TaskDeviceSendData[task] = false;
|
||||
TaskDeviceGlobalSync[task] = false;
|
||||
TaskDeviceDataFeed[task] = 0;
|
||||
TaskDeviceTimer[task] = 0;
|
||||
TaskDeviceEnabled[task] = false;
|
||||
}
|
||||
|
||||
unsigned long PID;
|
||||
int Version;
|
||||
@@ -677,12 +755,12 @@ struct SettingsStruct
|
||||
long TaskDevicePluginConfigLong[TASKS_MAX][PLUGIN_CONFIGLONGVAR_MAX];
|
||||
boolean OLD_TaskDeviceSendData[TASKS_MAX];
|
||||
boolean TaskDeviceGlobalSync[TASKS_MAX];
|
||||
byte TaskDeviceDataFeed[TASKS_MAX];
|
||||
byte TaskDeviceDataFeed[TASKS_MAX]; // When set to 0, only read local connected sensorsfeeds
|
||||
unsigned long TaskDeviceTimer[TASKS_MAX];
|
||||
boolean TaskDeviceEnabled[TASKS_MAX];
|
||||
boolean ControllerEnabled[CONTROLLER_MAX];
|
||||
boolean NotificationEnabled[NOTIFICATION_MAX];
|
||||
unsigned int TaskDeviceID[CONTROLLER_MAX][TASKS_MAX];
|
||||
unsigned int TaskDeviceID[CONTROLLER_MAX][TASKS_MAX]; // IDX number (mainly used by Domoticz)
|
||||
boolean TaskDeviceSendData[CONTROLLER_MAX][TASKS_MAX];
|
||||
boolean Pin_status_led_Inversed;
|
||||
boolean deepSleepOnFail;
|
||||
@@ -854,15 +932,26 @@ struct NotificationSettingsStruct
|
||||
//its safe to extend this struct, up to 4096 bytes, default values in config are 0
|
||||
};
|
||||
|
||||
// This is only used by some plugins to store extra settings like formula descriptions.
|
||||
// These settings can only be active for one plugin, meaning they have to be loaded
|
||||
// over and over again from flash when another active plugin uses these values.
|
||||
//FIXME @TD-er: Should think of another mechanism to make this more efficient.
|
||||
struct ExtraTaskSettingsStruct
|
||||
{
|
||||
ExtraTaskSettingsStruct() : TaskIndex(0) {
|
||||
TaskDeviceName[0] = 0;
|
||||
ExtraTaskSettingsStruct() : TaskIndex(TASKS_MAX) {
|
||||
clear();
|
||||
}
|
||||
|
||||
void clear() {
|
||||
TaskIndex = TASKS_MAX;
|
||||
for (byte j = 0; j < (NAME_FORMULA_LENGTH_MAX + 1); ++j) {
|
||||
TaskDeviceName[j] = 0;
|
||||
}
|
||||
for (byte i = 0; i < VARS_PER_TASK; ++i) {
|
||||
for (byte j = 0; j < 41; ++j) {
|
||||
for (byte j = 0; j < (NAME_FORMULA_LENGTH_MAX + 1); ++j) {
|
||||
TaskDeviceFormula[i][j] = 0;
|
||||
TaskDeviceValueNames[i][j] = 0;
|
||||
TaskDeviceValueDecimals[i] = 0;
|
||||
TaskDeviceValueDecimals[i] = 2;
|
||||
}
|
||||
}
|
||||
for (byte i = 0; i < PLUGIN_EXTRACONFIGVAR_MAX; ++i) {
|
||||
@@ -871,10 +960,46 @@ struct ExtraTaskSettingsStruct
|
||||
}
|
||||
}
|
||||
|
||||
byte TaskIndex;
|
||||
char TaskDeviceName[41];
|
||||
char TaskDeviceFormula[VARS_PER_TASK][41];
|
||||
char TaskDeviceValueNames[VARS_PER_TASK][41];
|
||||
bool checkUniqueValueNames() {
|
||||
for (int i = 0; i < (VARS_PER_TASK - 1); ++i) {
|
||||
for (int j = i; j < VARS_PER_TASK; ++j) {
|
||||
if (i != j && TaskDeviceValueNames[i][0] != 0) {
|
||||
if (strcasecmp(TaskDeviceValueNames[i], TaskDeviceValueNames[j]) == 0)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool checkInvalidCharInNames(const char* name) {
|
||||
int pos = 0;
|
||||
while (*(name+pos) != 0) {
|
||||
switch (*(name+pos)) {
|
||||
case ',':
|
||||
case ' ':
|
||||
case '#':
|
||||
case '[':
|
||||
case ']':
|
||||
return false;
|
||||
}
|
||||
++pos;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool checkInvalidCharInNames() {
|
||||
if (!checkInvalidCharInNames(&TaskDeviceName[0])) return false;
|
||||
for (int i = 0; i < (VARS_PER_TASK - 1); ++i) {
|
||||
if (!checkInvalidCharInNames(&TaskDeviceValueNames[i][0])) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
byte TaskIndex; // Always < TASKS_MAX
|
||||
char TaskDeviceName[NAME_FORMULA_LENGTH_MAX + 1];
|
||||
char TaskDeviceFormula[VARS_PER_TASK][NAME_FORMULA_LENGTH_MAX + 1];
|
||||
char TaskDeviceValueNames[VARS_PER_TASK][NAME_FORMULA_LENGTH_MAX + 1];
|
||||
long TaskDevicePluginConfigLong[PLUGIN_EXTRACONFIGVAR_MAX];
|
||||
byte TaskDeviceValueDecimals[VARS_PER_TASK];
|
||||
int16_t TaskDevicePluginConfig[PLUGIN_EXTRACONFIGVAR_MAX];
|
||||
@@ -1035,6 +1160,11 @@ struct LogStruct {
|
||||
|
||||
} Logging;
|
||||
|
||||
byte highest_active_log_level = 0;
|
||||
bool log_to_serial_disabled = false;
|
||||
// Do this in a template to prevent casting to String when not needed.
|
||||
#define addLog(L,S) if (loglevelActiveFor(L)) { addToLog(L,S); }
|
||||
|
||||
struct DeviceStruct
|
||||
{
|
||||
DeviceStruct() :
|
||||
@@ -1042,20 +1172,26 @@ struct DeviceStruct
|
||||
PullUpOption(false), InverseLogicOption(false), FormulaOption(false),
|
||||
ValueCount(0), Custom(false), SendDataOption(false), GlobalSyncOption(false),
|
||||
TimerOption(false), TimerOptional(false), DecimalsOnly(false) {}
|
||||
byte Number;
|
||||
byte Type;
|
||||
byte VType;
|
||||
byte Ports;
|
||||
boolean PullUpOption;
|
||||
boolean InverseLogicOption;
|
||||
boolean FormulaOption;
|
||||
byte ValueCount;
|
||||
|
||||
bool connectedToGPIOpins() {
|
||||
return (Type >= DEVICE_TYPE_SINGLE && Type <= DEVICE_TYPE_TRIPLE);
|
||||
}
|
||||
|
||||
|
||||
byte Number; // Plugin ID number. (PLUGIN_ID_xxx)
|
||||
byte Type; // How the device is connected. e.g. DEVICE_TYPE_SINGLE => connected through 1 datapin
|
||||
byte VType; // Type of value the plugin will return, used only for Domoticz
|
||||
byte Ports; // Port to use when device has multiple I/O pins (N.B. not used much)
|
||||
boolean PullUpOption; // Allow to set internal pull-up resistors.
|
||||
boolean InverseLogicOption; // Allow to invert the boolean state (e.g. a switch)
|
||||
boolean FormulaOption; // Allow to enter a formula to convert values during read. (not possible with Custom enabled)
|
||||
byte ValueCount; // The number of output values of a plugin. The value should match the number of keys PLUGIN_VALUENAME1_xxx
|
||||
boolean Custom;
|
||||
boolean SendDataOption;
|
||||
boolean GlobalSyncOption;
|
||||
boolean TimerOption;
|
||||
boolean TimerOptional;
|
||||
boolean DecimalsOnly;
|
||||
boolean SendDataOption; // Allow to send data to a controller.
|
||||
boolean GlobalSyncOption; // No longer used. Was used for ESPeasy values sync between nodes
|
||||
boolean TimerOption; // Allow to set the "Interval" timer for the plugin.
|
||||
boolean TimerOptional; // When taskdevice timer is not set and not optional, use default "Interval" delay (Settings.Delay)
|
||||
boolean DecimalsOnly; // Allow to set the number of decimals (otherwise treated a 0 decimals)
|
||||
} Device[DEVICES_MAX + 1]; // 1 more because first device is empty device
|
||||
|
||||
struct ProtocolStruct
|
||||
@@ -1109,16 +1245,8 @@ struct systemTimerStruct
|
||||
int Par3;
|
||||
int Par4;
|
||||
int Par5;
|
||||
} systemTimers[SYSTEM_TIMER_MAX];
|
||||
|
||||
#define NOTAVAILABLE_SYSTEM_TIMER_ERROR "There are no system timer available, max parallel timers are " STR(SYSTEM_TIMER_MAX)
|
||||
|
||||
struct systemCMDTimerStruct
|
||||
{
|
||||
systemCMDTimerStruct() : timer(0) {}
|
||||
unsigned long timer;
|
||||
String action;
|
||||
} systemCMDTimers[SYSTEM_CMD_TIMER_MAX];
|
||||
};
|
||||
std::map<unsigned long, systemTimerStruct> systemTimers;
|
||||
|
||||
struct pinStatesStruct
|
||||
{
|
||||
@@ -1157,19 +1285,15 @@ String printWebString = "";
|
||||
boolean printToWebJSON = false;
|
||||
|
||||
float UserVar[VARS_PER_TASK * TASKS_MAX];
|
||||
struct rulesTiemerStatus
|
||||
struct rulesTimerStatus
|
||||
{
|
||||
unsigned long timestamp;
|
||||
unsigned int interval; //interval in millisencond
|
||||
unsigned int interval; //interval in milliseconds
|
||||
boolean paused;
|
||||
} RulesTimer[RULES_TIMER_MAX];
|
||||
|
||||
unsigned long timerSensor[TASKS_MAX];
|
||||
unsigned long timer100ms;
|
||||
unsigned long timer20ms;
|
||||
unsigned long timer1s;
|
||||
unsigned long timerwd;
|
||||
unsigned long timermqtt;
|
||||
msecTimerHandlerStruct msecTimerHandler;
|
||||
|
||||
unsigned long timermqtt_interval;
|
||||
unsigned long lastSend;
|
||||
unsigned long lastWeb;
|
||||
@@ -1293,6 +1417,7 @@ bool processedScanDone = true;
|
||||
bool webserver_state = false;
|
||||
bool webserver_init = false;
|
||||
|
||||
unsigned long idle_msec_per_sec = 0;
|
||||
unsigned long elapsed10ps = 0;
|
||||
unsigned long elapsed10psU = 0;
|
||||
unsigned long elapsed50ps = 0;
|
||||
@@ -1306,9 +1431,6 @@ unsigned long loopCounter_full = 1;
|
||||
float loop_usec_duration_total = 0.0;
|
||||
unsigned long countFindPluginId = 0;
|
||||
|
||||
unsigned long systemTimerCalls = 1;
|
||||
float systemTimerDurationTotal = 0.0;
|
||||
|
||||
unsigned long dailyResetCounter = 0;
|
||||
|
||||
String eventBuffer = "";
|
||||
@@ -1325,8 +1447,6 @@ boolean UseRTOSMultitasking;
|
||||
|
||||
void (*MainLoopCall_ptr)(void);
|
||||
|
||||
#include <map>
|
||||
|
||||
class TimingStats {
|
||||
public:
|
||||
TimingStats() : _timeTotal(0.0), _count(0), _maxVal(0), _minVal(4294967295) {}
|
||||
@@ -1443,7 +1563,7 @@ bool mustLogFunction(int function) {
|
||||
case PLUGIN_SERIAL_IN: return true;
|
||||
case PLUGIN_UDP_IN: return true;
|
||||
case PLUGIN_CLOCK_IN: return false;
|
||||
case PLUGIN_TIMER_IN: return false;
|
||||
case PLUGIN_TIMER_IN: return true;
|
||||
case PLUGIN_FIFTY_PER_SECOND: return true;
|
||||
case PLUGIN_SET_CONFIG: return false;
|
||||
case PLUGIN_GET_DEVICEGPIONAMES: return false;
|
||||
@@ -1457,16 +1577,21 @@ bool mustLogFunction(int function) {
|
||||
|
||||
std::map<int,TimingStats> pluginStats;
|
||||
std::map<int,TimingStats> miscStats;
|
||||
unsigned long timediff_calls = 0;
|
||||
unsigned long timediff_cpu_cycles_total = 0;
|
||||
|
||||
#define LOADFILE_STATS 0
|
||||
#define LOOP_STATS 1
|
||||
#define PLUGIN_CALL_50PS 2
|
||||
#define PLUGIN_CALL_10PS 3
|
||||
#define PLUGIN_CALL_10PSU 4
|
||||
#define PLUGIN_CALL_1PS 5
|
||||
#define CHECK_SENSORS 6
|
||||
#define SEND_DATA_STATS 7
|
||||
#define LOADFILE_STATS 0
|
||||
#define LOOP_STATS 1
|
||||
#define PLUGIN_CALL_50PS 2
|
||||
#define PLUGIN_CALL_10PS 3
|
||||
#define PLUGIN_CALL_10PSU 4
|
||||
#define PLUGIN_CALL_1PS 5
|
||||
#define SENSOR_SEND_TASK 6
|
||||
#define SEND_DATA_STATS 7
|
||||
#define COMPUTE_FORMULA_STATS 8
|
||||
#define PROC_SYS_TIMER 9
|
||||
#define SET_NEW_TIMER 10
|
||||
#define TIME_DIFF_COMPUTE 11
|
||||
|
||||
|
||||
|
||||
@@ -1482,13 +1607,16 @@ String getMiscStatsName(int stat) {
|
||||
switch (stat) {
|
||||
case LOADFILE_STATS: return F("Load File");
|
||||
case LOOP_STATS: return F("Loop");
|
||||
case PLUGIN_CALL_50PS : return F("Plugin call 50 p/s ");
|
||||
case PLUGIN_CALL_10PS : return F("Plugin call 10 p/s ");
|
||||
case PLUGIN_CALL_10PSU : return F("Plugin call 10 p/s U");
|
||||
case PLUGIN_CALL_1PS : return F("Plugin call 1 p/s ");
|
||||
case CHECK_SENSORS: return F("checkSensors() ");
|
||||
case SEND_DATA_STATS: return F("sendData() ");
|
||||
case COMPUTE_FORMULA_STATS: return F("Compute formula ");
|
||||
case PLUGIN_CALL_50PS: return F("Plugin call 50 p/s ");
|
||||
case PLUGIN_CALL_10PS: return F("Plugin call 10 p/s ");
|
||||
case PLUGIN_CALL_10PSU: return F("Plugin call 10 p/s U");
|
||||
case PLUGIN_CALL_1PS: return F("Plugin call 1 p/s ");
|
||||
case SENSOR_SEND_TASK: return F("SensorSendTask() ");
|
||||
case SEND_DATA_STATS: return F("sendData() ");
|
||||
case COMPUTE_FORMULA_STATS: return F("Compute formula ");
|
||||
case PROC_SYS_TIMER: return F("proc_system_timer() ");
|
||||
case SET_NEW_TIMER: return F("setNewTimerAt() ");
|
||||
case TIME_DIFF_COMPUTE: return F("timeDiff() ");
|
||||
}
|
||||
return F("Unknown");
|
||||
}
|
||||
|
||||
+58
-224
@@ -195,8 +195,6 @@ void setup()
|
||||
// setWifiMode(WIFI_STA);
|
||||
checkRuleSets();
|
||||
|
||||
ExtraTaskSettings.TaskIndex = 255; // make sure this is an unused nr to prevent cache load on boot
|
||||
|
||||
// if different version, eeprom settings structure has changed. Full Reset needed
|
||||
// on a fresh ESP module eeprom values are set to 255. Version results into -1 (signed int)
|
||||
if (Settings.Version != VERSION || Settings.PID != ESP_PROJECT_PID)
|
||||
@@ -233,17 +231,6 @@ void setup()
|
||||
checkRAM(F("hardwareInit"));
|
||||
hardwareInit();
|
||||
|
||||
//After booting, we want all the tasks to run without delaying more than neccesary.
|
||||
//Plugins that need an initial startup delay need to overwrite their initial timerSensor value in PLUGIN_INIT
|
||||
//They should also check if we returned from deep sleep so that they can skip the delay in that case.
|
||||
for (byte x = 0; x < TASKS_MAX; x++)
|
||||
if (Settings.TaskDeviceTimer[x] !=0)
|
||||
timerSensor[x] = millis() + (x * Settings.MessageDelay);
|
||||
|
||||
timer100ms = 0; // timer for periodic actions 10 x per/sec
|
||||
timer1s = 0; // timer for periodic actions once per/sec
|
||||
timerwd = 0; // timer for watchdog once per 30 sec
|
||||
timermqtt = 10000; // Timer for the MQTT keep alive loop, initial value can be high, since it will be set as soon as IP is set.
|
||||
timermqtt_interval = 250; // Interval for checking MQTT
|
||||
timerAwakeFromDeepSleep = millis();
|
||||
|
||||
@@ -324,9 +311,16 @@ void setup()
|
||||
// #ifndef ESP32
|
||||
// connectionCheck.attach(30, connectionCheckHandler);
|
||||
// #endif
|
||||
timer20ms = millis();
|
||||
timer100ms = millis();
|
||||
timer1s = millis();
|
||||
|
||||
// Start the interval timers at N msec from now.
|
||||
// Make sure to start them at some time after eachother,
|
||||
// since they will keep running at the same interval.
|
||||
setIntervalTimerOverride(TIMER_20MSEC, 5); // timer for periodic actions 50 x per/sec
|
||||
setIntervalTimerOverride(TIMER_100MSEC, 66); // timer for periodic actions 10 x per/sec
|
||||
setIntervalTimerOverride(TIMER_1SEC, 777); // timer for periodic actions once per/sec
|
||||
setIntervalTimerOverride(TIMER_30SEC, 1333); // timer for watchdog once per 30 sec
|
||||
setIntervalTimerOverride(TIMER_MQTT, 88); // timer for interaction with MQTT
|
||||
setIntervalTimerOverride(TIMER_STATISTICS, 2222);
|
||||
}
|
||||
|
||||
#ifdef USE_RTOS_MULTITASKING
|
||||
@@ -395,38 +389,36 @@ void updateLoopStats() {
|
||||
longestLoop = usecSince;
|
||||
}
|
||||
|
||||
void updateLoopStats_30sec() {
|
||||
void updateLoopStats_30sec(byte loglevel) {
|
||||
loopCounterLast = loopCounter;
|
||||
loopCounter = 0;
|
||||
if (loopCounterLast > loopCounterMax)
|
||||
loopCounterMax = loopCounterLast;
|
||||
|
||||
String log = F("LoopStats: shortestLoop: ");
|
||||
log += shortestLoop;
|
||||
log += F(" longestLoop: ");
|
||||
log += longestLoop;
|
||||
log += F(" avgLoopDuration: ");
|
||||
log += loop_usec_duration_total / loopCounter_full;
|
||||
log += F(" systemTimerDuration: ");
|
||||
log += systemTimerDurationTotal / systemTimerCalls;
|
||||
log += F(" systemTimerCalls: ");
|
||||
log += systemTimerCalls;
|
||||
log += F(" loopCounterMax: ");
|
||||
log += loopCounterMax;
|
||||
log += F(" loopCounterLast: ");
|
||||
log += loopCounterLast;
|
||||
log += F(" countFindPluginId: ");
|
||||
log += countFindPluginId;
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
msecTimerHandler.updateIdleTimeStats();
|
||||
|
||||
if (loglevelActiveFor(loglevel)) {
|
||||
String log = F("LoopStats: shortestLoop: ");
|
||||
log += shortestLoop;
|
||||
log += F(" longestLoop: ");
|
||||
log += longestLoop;
|
||||
log += F(" avgLoopDuration: ");
|
||||
log += loop_usec_duration_total / loopCounter_full;
|
||||
log += F(" loopCounterMax: ");
|
||||
log += loopCounterMax;
|
||||
log += F(" loopCounterLast: ");
|
||||
log += loopCounterLast;
|
||||
log += F(" countFindPluginId: ");
|
||||
log += countFindPluginId;
|
||||
addLog(loglevel, log);
|
||||
}
|
||||
countFindPluginId = 0;
|
||||
loop_usec_duration_total = 0;
|
||||
loopCounter_full = 1;
|
||||
systemTimerDurationTotal = 0;
|
||||
systemTimerCalls = 1;
|
||||
}
|
||||
|
||||
int getCPUload() {
|
||||
return 100 - (100 * loopCounterLast / loopCounterMax);
|
||||
float getCPUload() {
|
||||
return 100.0 - msecTimerHandler.getIdleTimePct();
|
||||
}
|
||||
|
||||
int getLoopCountPerSec() {
|
||||
@@ -435,6 +427,7 @@ int getLoopCountPerSec() {
|
||||
|
||||
|
||||
|
||||
|
||||
/*********************************************************************************************\
|
||||
* MAIN LOOP
|
||||
\*********************************************************************************************/
|
||||
@@ -484,23 +477,7 @@ void loop()
|
||||
//normal mode, run each task when its time
|
||||
else
|
||||
{
|
||||
|
||||
if (timeOutReached(timer20ms))
|
||||
run50TimesPerSecond();
|
||||
|
||||
if (timeOutReached(timer100ms))
|
||||
if(!UseRTOSMultitasking)
|
||||
run10TimesPerSecond();
|
||||
|
||||
if (timeOutReached(timerwd))
|
||||
runEach30Seconds();
|
||||
|
||||
if (timeOutReached(timer1s))
|
||||
runOncePerSecond();
|
||||
|
||||
if (timeOutReached(timermqtt)) {
|
||||
runPeriodicalMQTT();
|
||||
}
|
||||
handle_schedule();
|
||||
}
|
||||
|
||||
backgroundtasks();
|
||||
@@ -561,16 +538,14 @@ void updateMQTTclient_connected() {
|
||||
} else {
|
||||
timermqtt_interval = 250;
|
||||
}
|
||||
timermqtt = millis() + timermqtt_interval;
|
||||
setIntervalTimer(TIMER_MQTT);
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Tasks that run 50 times per second
|
||||
\*********************************************************************************************/
|
||||
|
||||
void run50TimesPerSecond()
|
||||
{
|
||||
setNextTimeInterval(timer20ms, 20);
|
||||
void run50TimesPerSecond() {
|
||||
START_TIMER;
|
||||
PluginCall(PLUGIN_FIFTY_PER_SECOND, 0, dummyString);
|
||||
STOP_TIMER(PLUGIN_CALL_50PS);
|
||||
@@ -579,9 +554,7 @@ void run50TimesPerSecond()
|
||||
/*********************************************************************************************\
|
||||
* Tasks that run 10 times per second
|
||||
\*********************************************************************************************/
|
||||
void run10TimesPerSecond()
|
||||
{
|
||||
setNextTimeInterval(timer100ms, 100);
|
||||
void run10TimesPerSecond() {
|
||||
{
|
||||
START_TIMER;
|
||||
PluginCall(PLUGIN_TEN_PER_SECOND, 0, dummyString);
|
||||
@@ -609,7 +582,7 @@ void run10TimesPerSecond()
|
||||
void runOncePerSecond()
|
||||
{
|
||||
START_TIMER;
|
||||
setNextTimeInterval(timer1s, 1000);
|
||||
updateLogLevelCache();
|
||||
dailyResetCounter++;
|
||||
if (dailyResetCounter > 86400) // 1 day elapsed... //86400
|
||||
{
|
||||
@@ -620,8 +593,6 @@ void runOncePerSecond()
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
}
|
||||
|
||||
checkSensors();
|
||||
|
||||
if (Settings.ConnectionFailuresThreshold)
|
||||
if (connectionFailures > Settings.ConnectionFailuresThreshold)
|
||||
delayedReboot(60);
|
||||
@@ -658,8 +629,6 @@ void runOncePerSecond()
|
||||
PluginCall(PLUGIN_ONCE_A_SECOND, 0, dummyString);
|
||||
// unsigned long elapsed = micros() - start;
|
||||
|
||||
checkSystemTimers();
|
||||
|
||||
if (Settings.UseRules)
|
||||
rulesTimers();
|
||||
|
||||
@@ -701,6 +670,17 @@ void runOncePerSecond()
|
||||
STOP_TIMER(PLUGIN_CALL_1PS);
|
||||
}
|
||||
|
||||
void logTimerStatistics() {
|
||||
byte loglevel = LOG_LEVEL_DEBUG;
|
||||
updateLoopStats_30sec(loglevel);
|
||||
logStatistics(loglevel, true);
|
||||
if (loglevelActiveFor(loglevel)) {
|
||||
String queueLog = F("Scheduler stats: (called/tasks/max_length/idle%) ");
|
||||
queueLog += msecTimerHandler.getQueueStats();
|
||||
addLog(loglevel, queueLog);
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Tasks each 30 seconds
|
||||
\*********************************************************************************************/
|
||||
@@ -708,19 +688,18 @@ void runEach30Seconds()
|
||||
{
|
||||
extern void checkRAMtoLog();
|
||||
checkRAMtoLog();
|
||||
updateLoopStats_30sec();
|
||||
logStatistics(true);
|
||||
wdcounter++;
|
||||
timerwd = millis() + 30000;
|
||||
String log;
|
||||
log.reserve(60);
|
||||
log = F("WD : Uptime ");
|
||||
log += wdcounter / 2;
|
||||
log += F(" ConnectFailures ");
|
||||
log += connectionFailures;
|
||||
log += F(" FreeMem ");
|
||||
log += FreeMem();
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
|
||||
String log;
|
||||
log.reserve(60);
|
||||
log = F("WD : Uptime ");
|
||||
log += wdcounter / 2;
|
||||
log += F(" ConnectFailures ");
|
||||
log += connectionFailures;
|
||||
log += F(" FreeMem ");
|
||||
log += FreeMem();
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
}
|
||||
sendSysInfoUDP(1);
|
||||
refreshNodeList();
|
||||
|
||||
@@ -739,33 +718,6 @@ void runEach30Seconds()
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Check sensor timers
|
||||
\*********************************************************************************************/
|
||||
void checkSensors()
|
||||
{
|
||||
START_TIMER;
|
||||
checkRAM(F("checkSensors"));
|
||||
bool isDeepSleep = isDeepSleepEnabled();
|
||||
//check all the devices and only run the sendtask if its time, or we if we used deep sleep mode
|
||||
for (byte x = 0; x < TASKS_MAX; x++)
|
||||
{
|
||||
if (
|
||||
(Settings.TaskDeviceTimer[x] != 0) &&
|
||||
(isDeepSleep || timeOutReached(timerSensor[x]))
|
||||
)
|
||||
{
|
||||
setNextTimeInterval(timerSensor[x], Settings.TaskDeviceTimer[x] * 1000);
|
||||
if (timerSensor[x] == 0) // small fix if result is 0, else timer will be stopped...
|
||||
timerSensor[x] = 1;
|
||||
SensorSendTask(x);
|
||||
}
|
||||
}
|
||||
saveUserVarToRTC();
|
||||
STOP_TIMER(CHECK_SENSORS);
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************************************\
|
||||
* send all sensordata
|
||||
\*********************************************************************************************/
|
||||
@@ -833,124 +785,6 @@ void SensorSendTask(byte TaskIndex)
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************************************\
|
||||
* set global system timer
|
||||
\*********************************************************************************************/
|
||||
void setSystemTimer(unsigned long timer, byte plugin, int Par1, int Par2, int Par3)
|
||||
{
|
||||
setSystemTimer(timer, plugin, -1, Par1, Par2, Par3, 0, 0);
|
||||
}
|
||||
|
||||
void setSystemTimer(unsigned long timer, byte plugin, short taskIndex, int Par1, int Par2, int Par3)
|
||||
{
|
||||
setSystemTimer(timer, plugin, taskIndex , Par1, Par2, Par3, 0, 0);
|
||||
}
|
||||
|
||||
void setSystemTimer(unsigned long timer, byte plugin, short taskIndex, int Par1, int Par2, int Par3, int Par4)
|
||||
{
|
||||
setSystemTimer(timer, plugin, taskIndex , Par1, Par2, Par3, Par4, 0);
|
||||
}
|
||||
|
||||
void setSystemTimer(unsigned long timer, byte plugin, short taskIndex, int Par1, int Par2, int Par3, int Par4, int Par5)
|
||||
{
|
||||
// plugin number and par1 form a unique key that can be used to restart a timer
|
||||
// first check if a timer is not already running for this request
|
||||
byte firstAvailable = SYSTEM_TIMER_MAX;
|
||||
for (byte x = 0; x < SYSTEM_TIMER_MAX; x++)
|
||||
{
|
||||
if (systemTimers[x].timer != 0)
|
||||
{
|
||||
if ((systemTimers[x].plugin == plugin) && systemTimers[x].TaskIndex == taskIndex && (systemTimers[x].Par1 == Par1))
|
||||
{
|
||||
firstAvailable = x;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if(firstAvailable == SYSTEM_TIMER_MAX)
|
||||
{
|
||||
firstAvailable = x;
|
||||
}
|
||||
}
|
||||
if (firstAvailable == SYSTEM_TIMER_MAX )
|
||||
{
|
||||
addLog(LOG_LEVEL_ERROR, F(NOTAVAILABLE_SYSTEM_TIMER_ERROR));
|
||||
}
|
||||
else
|
||||
{
|
||||
systemTimers[firstAvailable].plugin = plugin;
|
||||
systemTimers[firstAvailable].TaskIndex = taskIndex;
|
||||
systemTimers[firstAvailable].Par1 = Par1;
|
||||
systemTimers[firstAvailable].Par2 = Par2;
|
||||
systemTimers[firstAvailable].Par3 = Par3;
|
||||
systemTimers[firstAvailable].Par4 = Par4;
|
||||
systemTimers[firstAvailable].Par5 = Par5;
|
||||
systemTimers[firstAvailable].timer = timer > 0
|
||||
? millis() + timer
|
||||
: 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//EDWIN: this function seems to be unused?
|
||||
/*********************************************************************************************\
|
||||
* set global system command timer
|
||||
\*********************************************************************************************/
|
||||
void setSystemCMDTimer(unsigned long timer, String& action)
|
||||
{
|
||||
for (byte x = 0; x < SYSTEM_CMD_TIMER_MAX; x++)
|
||||
if (systemCMDTimers[x].timer == 0)
|
||||
{
|
||||
systemCMDTimers[x].timer = millis() + timer;
|
||||
systemCMDTimers[x].action = action;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************************************\
|
||||
* check global system timers
|
||||
\*********************************************************************************************/
|
||||
void checkSystemTimers()
|
||||
{
|
||||
unsigned long start = micros();
|
||||
for (byte x = 0; x < SYSTEM_TIMER_MAX; x++)
|
||||
if (systemTimers[x].timer != 0)
|
||||
{
|
||||
if (timeOutReached(systemTimers[x].timer))
|
||||
{
|
||||
struct EventStruct TempEvent;
|
||||
TempEvent.TaskIndex = systemTimers[x].TaskIndex;
|
||||
TempEvent.Par1 = systemTimers[x].Par1;
|
||||
TempEvent.Par2 = systemTimers[x].Par2;
|
||||
TempEvent.Par3 = systemTimers[x].Par3;
|
||||
TempEvent.Par4 = systemTimers[x].Par4;
|
||||
TempEvent.Par5 = systemTimers[x].Par5;
|
||||
systemTimers[x].timer = 0;
|
||||
const int y = getPluginId(systemTimers[x].TaskIndex);
|
||||
if (y >= 0) {
|
||||
Plugin_ptr[y](PLUGIN_TIMER_IN, &TempEvent, dummyString);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (byte x = 0; x < SYSTEM_CMD_TIMER_MAX; x++)
|
||||
if (systemCMDTimers[x].timer != 0)
|
||||
if (timeOutReached(systemCMDTimers[x].timer))
|
||||
{
|
||||
struct EventStruct TempEvent;
|
||||
parseCommandString(&TempEvent, systemCMDTimers[x].action);
|
||||
if (!PluginCall(PLUGIN_WRITE, &TempEvent, systemCMDTimers[x].action))
|
||||
ExecuteCommand(VALUE_SOURCE_SYSTEM, systemCMDTimers[x].action.c_str());
|
||||
systemCMDTimers[x].timer = 0;
|
||||
systemCMDTimers[x].action = "";
|
||||
}
|
||||
|
||||
++systemTimerCalls;
|
||||
systemTimerDurationTotal += usecPassedSince(start);;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************************************\
|
||||
* run background tasks
|
||||
\*********************************************************************************************/
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
void logStatistics(bool clearLog) {
|
||||
void logStatistics(byte loglevel, bool clearLog) {
|
||||
if (loglevelActiveFor(loglevel)) {
|
||||
String log;
|
||||
log.reserve(80);
|
||||
for (auto& x: pluginStats) {
|
||||
if (!x.second.isEmpty()) {
|
||||
const int pluginId = x.first/32;
|
||||
String P_name = "";
|
||||
String P_name = "";
|
||||
Plugin_ptr[pluginId](PLUGIN_GET_DEVICENAME, NULL, P_name);
|
||||
log = F("PluginStats P_");
|
||||
log += pluginId + 1;
|
||||
@@ -14,7 +15,7 @@ void logStatistics(bool clearLog) {
|
||||
log += getPluginFunctionName(x.first%32);
|
||||
log += ' ';
|
||||
log += getLogLine(x.second);
|
||||
addLog(LOG_LEVEL_DEBUG, log);
|
||||
addLog(loglevel, log);
|
||||
if (clearLog) x.second.reset();
|
||||
}
|
||||
}
|
||||
@@ -23,8 +24,19 @@ void logStatistics(bool clearLog) {
|
||||
log = getMiscStatsName(x.first);
|
||||
log += F(" stats: ");
|
||||
log += getLogLine(x.second);
|
||||
addLog(LOG_LEVEL_DEBUG, log);
|
||||
addLog(loglevel, log);
|
||||
if (clearLog) x.second.reset();
|
||||
}
|
||||
}
|
||||
log = getMiscStatsName(TIME_DIFF_COMPUTE);
|
||||
log += F(" stats: Count: ");
|
||||
log += timediff_calls;
|
||||
log += F(" - CPU cycles per call: ");
|
||||
log += static_cast<float>(timediff_cpu_cycles_total) / static_cast<float>(timediff_calls);
|
||||
addLog(loglevel, log);
|
||||
if (clearLog) {
|
||||
timediff_calls = 0;
|
||||
timediff_cpu_cycles_total = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,697 @@
|
||||
/********************************************************************************************\
|
||||
SPIFFS error handling
|
||||
Look here for error # reference: https://github.com/pellepl/spiffs/blob/master/src/spiffs.h
|
||||
\*********************************************************************************************/
|
||||
#define SPIFFS_CHECK(result, fname) if (!(result)) { return(FileError(__LINE__, fname)); }
|
||||
String FileError(int line, const char * fname)
|
||||
{
|
||||
String err = F("FS : Error while reading/writing ");
|
||||
err += fname;
|
||||
err += F(" in ");
|
||||
err += line;
|
||||
addLog(LOG_LEVEL_ERROR, err);
|
||||
return(err);
|
||||
}
|
||||
|
||||
/********************************************************************************************\
|
||||
Keep track of number of flash writes.
|
||||
\*********************************************************************************************/
|
||||
|
||||
void flashCount()
|
||||
{
|
||||
if (RTC.flashDayCounter <= MAX_FLASHWRITES_PER_DAY)
|
||||
RTC.flashDayCounter++;
|
||||
RTC.flashCounter++;
|
||||
saveToRTC();
|
||||
}
|
||||
|
||||
String flashGuard()
|
||||
{
|
||||
checkRAM(F("flashGuard"));
|
||||
if (RTC.flashDayCounter > MAX_FLASHWRITES_PER_DAY)
|
||||
{
|
||||
String log = F("FS : Daily flash write rate exceeded! (powercycle to reset this)");
|
||||
addLog(LOG_LEVEL_ERROR, log);
|
||||
return log;
|
||||
}
|
||||
flashCount();
|
||||
return(String());
|
||||
}
|
||||
|
||||
//use this in function that can return an error string. it automaticly returns with an error string if there where too many flash writes.
|
||||
#define FLASH_GUARD() { String flashErr=flashGuard(); if (flashErr.length()) return(flashErr); }
|
||||
|
||||
/********************************************************************************************\
|
||||
Fix stuff to clear out differences between releases
|
||||
\*********************************************************************************************/
|
||||
String BuildFixes()
|
||||
{
|
||||
checkRAM(F("BuildFixes"));
|
||||
Serial.println(F("\nBuild changed!"));
|
||||
|
||||
if (Settings.Build < 145)
|
||||
{
|
||||
String fname=F(FILE_NOTIFICATION);
|
||||
fs::File f = SPIFFS.open(fname, "w");
|
||||
SPIFFS_CHECK(f, fname.c_str());
|
||||
|
||||
if (f)
|
||||
{
|
||||
for (int x = 0; x < 4096; x++)
|
||||
{
|
||||
SPIFFS_CHECK(f.write(0), fname.c_str());
|
||||
}
|
||||
f.close();
|
||||
}
|
||||
}
|
||||
|
||||
if (Settings.Build < 20101)
|
||||
{
|
||||
Serial.println(F("Fix reset Pin"));
|
||||
Settings.Pin_Reset = -1;
|
||||
}
|
||||
if (Settings.Build < 20102) {
|
||||
// Settings were 'mangled' by using older version
|
||||
// Have to patch settings to make sure no bogus data is being used.
|
||||
Serial.println(F("Fix settings with uninitalized data or corrupted by switching between versions"));
|
||||
Settings.UseRTOSMultitasking = false;
|
||||
Settings.Pin_Reset = -1;
|
||||
Settings.SyslogFacility = DEFAULT_SYSLOG_FACILITY;
|
||||
Settings.MQTTUseUnitNameAsClientId = DEFAULT_MQTT_USE_UNITNANE_AS_CLIENTID;
|
||||
Settings.StructSize = sizeof(Settings);
|
||||
}
|
||||
|
||||
Settings.Build = BUILD;
|
||||
return(SaveSettings());
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************************************\
|
||||
Mount FS and check config.dat
|
||||
\*********************************************************************************************/
|
||||
void fileSystemCheck()
|
||||
{
|
||||
checkRAM(F("fileSystemCheck"));
|
||||
addLog(LOG_LEVEL_INFO, F("FS : Mounting..."));
|
||||
if (SPIFFS.begin())
|
||||
{
|
||||
#if defined(ESP8266)
|
||||
fs::FSInfo fs_info;
|
||||
SPIFFS.info(fs_info);
|
||||
|
||||
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
|
||||
String log = F("FS : Mount successful, used ");
|
||||
log=log+fs_info.usedBytes;
|
||||
log=log+F(" bytes of ");
|
||||
log=log+fs_info.totalBytes;
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
}
|
||||
#endif
|
||||
|
||||
fs::File f = SPIFFS.open(FILE_CONFIG, "r");
|
||||
if (!f)
|
||||
{
|
||||
ResetFactory();
|
||||
}
|
||||
f.close();
|
||||
}
|
||||
else
|
||||
{
|
||||
String log = F("FS : Mount failed");
|
||||
Serial.println(log);
|
||||
addLog(LOG_LEVEL_ERROR, log);
|
||||
ResetFactory();
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************************************\
|
||||
Save settings to SPIFFS
|
||||
\*********************************************************************************************/
|
||||
String SaveSettings(void)
|
||||
{
|
||||
checkRAM(F("SaveSettings"));
|
||||
MD5Builder md5;
|
||||
uint8_t tmp_md5[16] = {0};
|
||||
String err;
|
||||
|
||||
Settings.StructSize = sizeof(struct SettingsStruct);
|
||||
|
||||
// FIXME @TD-er: As discussed in #1292, the CRC for the settings is now disabled.
|
||||
/*
|
||||
memcpy( Settings.ProgmemMd5, CRCValues.runTimeMD5, 16);
|
||||
md5.begin();
|
||||
md5.add((uint8_t *)&Settings, sizeof(Settings)-16);
|
||||
md5.calculate();
|
||||
md5.getBytes(tmp_md5);
|
||||
if (memcmp(tmp_md5, Settings.md5, 16) != 0) {
|
||||
// Settings have changed, save to file.
|
||||
memcpy(Settings.md5, tmp_md5, 16);
|
||||
*/
|
||||
err=SaveToFile((char*)FILE_CONFIG, 0, (byte*)&Settings, sizeof(Settings));
|
||||
if (err.length())
|
||||
return(err);
|
||||
// }
|
||||
|
||||
memcpy( SecuritySettings.ProgmemMd5, CRCValues.runTimeMD5, 16);
|
||||
md5.begin();
|
||||
md5.add((uint8_t *)&SecuritySettings, sizeof(SecuritySettings)-16);
|
||||
md5.calculate();
|
||||
md5.getBytes(tmp_md5);
|
||||
if (memcmp(tmp_md5, SecuritySettings.md5, 16) != 0) {
|
||||
// Settings have changed, save to file.
|
||||
memcpy(SecuritySettings.md5, tmp_md5, 16);
|
||||
err=SaveToFile((char*)FILE_SECURITY, 0, (byte*)&SecuritySettings, sizeof(SecuritySettings));
|
||||
if (WifiIsAP(WiFi.getMode())) {
|
||||
// Security settings are saved, may be update of WiFi settings or hostname.
|
||||
wifiSetupConnect = true;
|
||||
}
|
||||
}
|
||||
return (err);
|
||||
}
|
||||
|
||||
/********************************************************************************************\
|
||||
Load settings from SPIFFS
|
||||
\*********************************************************************************************/
|
||||
String LoadSettings()
|
||||
{
|
||||
checkRAM(F("LoadSettings"));
|
||||
String err;
|
||||
uint8_t calculatedMd5[16];
|
||||
MD5Builder md5;
|
||||
|
||||
err=LoadFromFile((char*)FILE_CONFIG, 0, (byte*)&Settings, sizeof( SettingsStruct));
|
||||
if (err.length())
|
||||
return(err);
|
||||
|
||||
// FIXME @TD-er: As discussed in #1292, the CRC for the settings is now disabled.
|
||||
/*
|
||||
if (Settings.StructSize > 16) {
|
||||
md5.begin();
|
||||
md5.add((uint8_t *)&Settings, Settings.StructSize -16);
|
||||
md5.calculate();
|
||||
md5.getBytes(calculatedMd5);
|
||||
}
|
||||
if (memcmp (calculatedMd5, Settings.md5,16)==0){
|
||||
addLog(LOG_LEVEL_INFO, F("CRC : Settings CRC ...OK"));
|
||||
if (memcmp(Settings.ProgmemMd5, CRCValues.runTimeMD5, 16)!=0)
|
||||
addLog(LOG_LEVEL_INFO, F("CRC : binary has changed since last save of Settings"));
|
||||
}
|
||||
else{
|
||||
addLog(LOG_LEVEL_ERROR, F("CRC : Settings CRC ...FAIL"));
|
||||
}
|
||||
*/
|
||||
|
||||
err=LoadFromFile((char*)FILE_SECURITY, 0, (byte*)&SecuritySettings, sizeof( SecurityStruct));
|
||||
md5.begin();
|
||||
md5.add((uint8_t *)&SecuritySettings, sizeof(SecuritySettings)-16);
|
||||
md5.calculate();
|
||||
md5.getBytes(calculatedMd5);
|
||||
if (memcmp (calculatedMd5, SecuritySettings.md5, 16)==0){
|
||||
addLog(LOG_LEVEL_INFO, F("CRC : SecuritySettings CRC ...OK "));
|
||||
if (memcmp(SecuritySettings.ProgmemMd5,CRCValues.runTimeMD5, 16)!=0)
|
||||
addLog(LOG_LEVEL_INFO, F("CRC : binary has changed since last save of Settings"));
|
||||
}
|
||||
else{
|
||||
addLog(LOG_LEVEL_ERROR, F("CRC : SecuritySettings CRC ...FAIL"));
|
||||
}
|
||||
setUseStaticIP(useStaticIP());
|
||||
ExtraTaskSettings.clear(); // make sure these will not contain old settings.
|
||||
return(err);
|
||||
}
|
||||
|
||||
/********************************************************************************************\
|
||||
Offsets in settings files
|
||||
\*********************************************************************************************/
|
||||
bool getSettingsParameters(SettingsType settingsType, int index, int& max_index, int& offset, int& max_size, int& struct_size) {
|
||||
struct_size = 0;
|
||||
switch (settingsType) {
|
||||
case TaskSettings_Type:
|
||||
max_index = TASKS_MAX;
|
||||
offset = DAT_OFFSET_TASKS + (index * DAT_TASKS_DISTANCE);
|
||||
max_size = DAT_TASKS_SIZE;
|
||||
struct_size = sizeof(ExtraTaskSettingsStruct);
|
||||
break;
|
||||
case CustomTaskSettings_Type:
|
||||
max_index = TASKS_MAX;
|
||||
offset = DAT_OFFSET_TASKS + (index * DAT_TASKS_DISTANCE) + DAT_TASKS_CUSTOM_OFFSET;
|
||||
max_size = DAT_TASKS_CUSTOM_SIZE;
|
||||
// struct_size may differ.
|
||||
break;
|
||||
case ControllerSettings_Type:
|
||||
max_index = CONTROLLER_MAX;
|
||||
offset = DAT_OFFSET_CONTROLLER + (index * DAT_CONTROLLER_SIZE);
|
||||
max_size = DAT_CONTROLLER_SIZE;
|
||||
struct_size = sizeof(ControllerSettingsStruct);
|
||||
break;
|
||||
case CustomControllerSettings_Type:
|
||||
max_index = CONTROLLER_MAX;
|
||||
offset = DAT_OFFSET_CUSTOM_CONTROLLER + (index * DAT_CUSTOM_CONTROLLER_SIZE);
|
||||
max_size = DAT_CUSTOM_CONTROLLER_SIZE;
|
||||
// struct_size may differ.
|
||||
break;
|
||||
case NotificationSettings_Type:
|
||||
max_index = NOTIFICATION_MAX;
|
||||
offset = index * DAT_NOTIFICATION_SIZE;
|
||||
max_size = DAT_NOTIFICATION_SIZE;
|
||||
struct_size = sizeof(NotificationSettingsStruct);
|
||||
break;
|
||||
default:
|
||||
max_index = -1;
|
||||
offset = -1;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool getAndLogSettingsParameters(bool read, SettingsType settingsType, int index, int& offset, int& max_size) {
|
||||
if (loglevelActiveFor(LOG_LEVEL_DEBUG_DEV)) {
|
||||
String log = read ? F("Read") : F("Write");
|
||||
log += F(" settings: ");
|
||||
log += getSettingsTypeString(settingsType);
|
||||
log += F(" index: ");
|
||||
log += index;
|
||||
addLog(LOG_LEVEL_DEBUG_DEV, log);
|
||||
}
|
||||
return getSettingsParameters(settingsType, index, offset, max_size);
|
||||
}
|
||||
|
||||
bool getSettingsParameters(SettingsType settingsType, int index, int& offset, int& max_size) {
|
||||
int max_index = -1;
|
||||
int struct_size;
|
||||
if (!getSettingsParameters(settingsType, index, max_index, offset, max_size, struct_size))
|
||||
return false;
|
||||
if (index >= 0 && index < max_index) return true;
|
||||
offset = -1;
|
||||
return false;
|
||||
}
|
||||
|
||||
/********************************************************************************************\
|
||||
Save Task settings to SPIFFS
|
||||
\*********************************************************************************************/
|
||||
String SaveTaskSettings(byte TaskIndex)
|
||||
{
|
||||
checkRAM(F("SaveTaskSettings"));
|
||||
if (ExtraTaskSettings.TaskIndex != TaskIndex)
|
||||
return F("SaveTaskSettings taskIndex does not match");
|
||||
String err = SaveToFile(TaskSettings_Type, TaskIndex, (char*)FILE_CONFIG, (byte*)&ExtraTaskSettings, sizeof(struct ExtraTaskSettingsStruct));
|
||||
if (err.length() == 0)
|
||||
err = checkTaskSettings(TaskIndex);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************************************\
|
||||
Load Task settings from SPIFFS
|
||||
\*********************************************************************************************/
|
||||
String LoadTaskSettings(byte TaskIndex)
|
||||
{
|
||||
checkRAM(F("LoadTaskSettings"));
|
||||
if (ExtraTaskSettings.TaskIndex == TaskIndex)
|
||||
return(String()); //already loaded
|
||||
ExtraTaskSettings.clear();
|
||||
String result = "";
|
||||
result = LoadFromFile(TaskSettings_Type, TaskIndex, (char*)FILE_CONFIG, (byte*)&ExtraTaskSettings, sizeof(struct ExtraTaskSettingsStruct));
|
||||
|
||||
// After loading, some settings may need patching.
|
||||
ExtraTaskSettings.TaskIndex = TaskIndex; // Needed when an empty task was requested
|
||||
if (ExtraTaskSettings.TaskDeviceValueNames[0][0] == 0) {
|
||||
// if field set empty, reload defaults
|
||||
struct EventStruct TempEvent;
|
||||
TempEvent.TaskIndex = TaskIndex;
|
||||
String dummyString;
|
||||
//the plugin call should populate ExtraTaskSettings with its default values.
|
||||
PluginCall(PLUGIN_GET_DEVICEVALUENAMES, &TempEvent, dummyString);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************************************\
|
||||
Save Custom Task settings to SPIFFS
|
||||
\*********************************************************************************************/
|
||||
String SaveCustomTaskSettings(int TaskIndex, byte* memAddress, int datasize)
|
||||
{
|
||||
checkRAM(F("SaveCustomTaskSettings"));
|
||||
return(SaveToFile(CustomTaskSettings_Type, TaskIndex, (char*)FILE_CONFIG, memAddress, datasize));
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************************************\
|
||||
Clear custom task settings
|
||||
\*********************************************************************************************/
|
||||
String ClearCustomTaskSettings(int TaskIndex)
|
||||
{
|
||||
// addLog(LOG_LEVEL_DEBUG, F("Clearing custom task settings"));
|
||||
return(ClearInFile(CustomTaskSettings_Type, TaskIndex, (char*)FILE_CONFIG));
|
||||
}
|
||||
|
||||
/********************************************************************************************\
|
||||
Load Custom Task settings to SPIFFS
|
||||
\*********************************************************************************************/
|
||||
String LoadCustomTaskSettings(int TaskIndex, byte* memAddress, int datasize)
|
||||
{
|
||||
checkRAM(F("LoadCustomTaskSettings"));
|
||||
return(LoadFromFile(CustomTaskSettings_Type, TaskIndex, (char*)FILE_CONFIG, memAddress, datasize));
|
||||
}
|
||||
|
||||
/********************************************************************************************\
|
||||
Save Controller settings to SPIFFS
|
||||
\*********************************************************************************************/
|
||||
String SaveControllerSettings(int ControllerIndex, byte* memAddress, int datasize)
|
||||
{
|
||||
checkRAM(F("SaveControllerSettings"));
|
||||
return SaveToFile(ControllerSettings_Type, ControllerIndex, (char*)FILE_CONFIG, memAddress, datasize);
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************************************\
|
||||
Load Controller settings to SPIFFS
|
||||
\*********************************************************************************************/
|
||||
String LoadControllerSettings(int ControllerIndex, byte* memAddress, int datasize)
|
||||
{
|
||||
checkRAM(F("LoadControllerSettings"));
|
||||
return(LoadFromFile(ControllerSettings_Type, ControllerIndex, (char*)FILE_CONFIG, memAddress, datasize));
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************************************\
|
||||
Clear Custom Controller settings
|
||||
\*********************************************************************************************/
|
||||
String ClearCustomControllerSettings(int ControllerIndex)
|
||||
{
|
||||
checkRAM(F("ClearCustomControllerSettings"));
|
||||
// addLog(LOG_LEVEL_DEBUG, F("Clearing custom controller settings"));
|
||||
return(ClearInFile(CustomControllerSettings_Type, ControllerIndex, (char*)FILE_CONFIG));
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************************************\
|
||||
Save Custom Controller settings to SPIFFS
|
||||
\*********************************************************************************************/
|
||||
String SaveCustomControllerSettings(int ControllerIndex,byte* memAddress, int datasize)
|
||||
{
|
||||
checkRAM(F("SaveCustomControllerSettings"));
|
||||
return SaveToFile(CustomControllerSettings_Type, ControllerIndex, (char*)FILE_CONFIG, memAddress, datasize);
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************************************\
|
||||
Load Custom Controller settings to SPIFFS
|
||||
\*********************************************************************************************/
|
||||
String LoadCustomControllerSettings(int ControllerIndex,byte* memAddress, int datasize)
|
||||
{
|
||||
checkRAM(F("LoadCustomControllerSettings"));
|
||||
return(LoadFromFile(CustomControllerSettings_Type, ControllerIndex, (char*)FILE_CONFIG, memAddress, datasize));
|
||||
}
|
||||
|
||||
/********************************************************************************************\
|
||||
Save Controller settings to SPIFFS
|
||||
\*********************************************************************************************/
|
||||
String SaveNotificationSettings(int NotificationIndex, byte* memAddress, int datasize)
|
||||
{
|
||||
checkRAM(F("SaveNotificationSettings"));
|
||||
return SaveToFile(NotificationSettings_Type, NotificationIndex, (char*)FILE_NOTIFICATION, memAddress, datasize);
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************************************\
|
||||
Load Controller settings to SPIFFS
|
||||
\*********************************************************************************************/
|
||||
String LoadNotificationSettings(int NotificationIndex, byte* memAddress, int datasize)
|
||||
{
|
||||
checkRAM(F("LoadNotificationSettings"));
|
||||
return(LoadFromFile(NotificationSettings_Type, NotificationIndex, (char*)FILE_NOTIFICATION, memAddress, datasize));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/********************************************************************************************\
|
||||
Init a file with zeros on SPIFFS
|
||||
\*********************************************************************************************/
|
||||
String InitFile(const char* fname, int datasize)
|
||||
{
|
||||
checkRAM(F("InitFile"));
|
||||
FLASH_GUARD();
|
||||
|
||||
fs::File f = SPIFFS.open(fname, "w");
|
||||
SPIFFS_CHECK(f, fname);
|
||||
|
||||
for (int x = 0; x < datasize ; x++)
|
||||
{
|
||||
SPIFFS_CHECK(f.write(0), fname);
|
||||
}
|
||||
f.close();
|
||||
|
||||
//OK
|
||||
return String();
|
||||
}
|
||||
|
||||
/********************************************************************************************\
|
||||
Save data into config file on SPIFFS
|
||||
\*********************************************************************************************/
|
||||
String SaveToFile(char* fname, int index, byte* memAddress, int datasize)
|
||||
{
|
||||
if (index < 0) {
|
||||
String log = F("SaveToFile: ");
|
||||
log += fname;
|
||||
log += F(" ERROR, invalid position in file");
|
||||
addLog(LOG_LEVEL_ERROR, log);
|
||||
return log;
|
||||
}
|
||||
|
||||
checkRAM(F("SaveToFile"));
|
||||
FLASH_GUARD();
|
||||
|
||||
fs::File f = SPIFFS.open(fname, "r+");
|
||||
SPIFFS_CHECK(f, fname);
|
||||
|
||||
SPIFFS_CHECK(f.seek(index, fs::SeekSet), fname);
|
||||
byte *pointerToByteToSave = memAddress;
|
||||
for (int x = 0; x < datasize ; x++)
|
||||
{
|
||||
SPIFFS_CHECK(f.write(*pointerToByteToSave), fname);
|
||||
pointerToByteToSave++;
|
||||
}
|
||||
f.close();
|
||||
String log = F("FILE : Saved ");
|
||||
log=log+fname;
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
|
||||
//OK
|
||||
return String();
|
||||
}
|
||||
|
||||
/********************************************************************************************\
|
||||
Clear a certain area in a file (set to 0)
|
||||
\*********************************************************************************************/
|
||||
String ClearInFile(char* fname, int index, int datasize)
|
||||
{
|
||||
if (index < 0) {
|
||||
String log = F("ClearInFile: ");
|
||||
log += fname;
|
||||
log += F(" ERROR, invalid position in file");
|
||||
addLog(LOG_LEVEL_ERROR, log);
|
||||
return log;
|
||||
}
|
||||
|
||||
checkRAM(F("ClearInFile"));
|
||||
FLASH_GUARD();
|
||||
|
||||
fs::File f = SPIFFS.open(fname, "r+");
|
||||
SPIFFS_CHECK(f, fname);
|
||||
|
||||
SPIFFS_CHECK(f.seek(index, fs::SeekSet), fname);
|
||||
for (int x = 0; x < datasize ; x++)
|
||||
{
|
||||
SPIFFS_CHECK(f.write(0), fname);
|
||||
}
|
||||
f.close();
|
||||
|
||||
//OK
|
||||
return String();
|
||||
|
||||
}
|
||||
|
||||
/********************************************************************************************\
|
||||
Load data from config file on SPIFFS
|
||||
\*********************************************************************************************/
|
||||
String LoadFromFile(char* fname, int offset, byte* memAddress, int datasize)
|
||||
{
|
||||
if (offset < 0) {
|
||||
String log = F("LoadFromFile: ");
|
||||
log += fname;
|
||||
log += F(" ERROR, invalid position in file");
|
||||
addLog(LOG_LEVEL_ERROR, log);
|
||||
return log;
|
||||
}
|
||||
START_TIMER;
|
||||
|
||||
checkRAM(F("LoadFromFile"));
|
||||
|
||||
fs::File f = SPIFFS.open(fname, "r+");
|
||||
SPIFFS_CHECK(f, fname);
|
||||
SPIFFS_CHECK(f.seek(offset, fs::SeekSet), fname);
|
||||
SPIFFS_CHECK(f.read(memAddress,datasize), fname);
|
||||
f.close();
|
||||
|
||||
STOP_TIMER(LOADFILE_STATS);
|
||||
|
||||
return(String());
|
||||
}
|
||||
|
||||
/********************************************************************************************\
|
||||
Wrapper functions to handle errors in accessing settings
|
||||
\*********************************************************************************************/
|
||||
String getSettingsFileIndexRangeError(bool read, SettingsType settingsType, int index) {
|
||||
if (settingsType >= SettingsType_MAX) {
|
||||
String error = F("Unknown settingsType: ");
|
||||
error += static_cast<int>(settingsType);
|
||||
return error;
|
||||
}
|
||||
String error = read ? F("Load") : F("Save");
|
||||
error += getSettingsTypeString(settingsType);
|
||||
error += F(" index out of range: ");
|
||||
error += index;
|
||||
return error;
|
||||
}
|
||||
|
||||
String getSettingsFileDatasizeError(bool read, SettingsType settingsType, int index, int datasize, int max_size) {
|
||||
String error = read ? F("Load") : F("Save");
|
||||
error += getSettingsTypeString(settingsType);
|
||||
error += '(';
|
||||
error += index;
|
||||
error += F(") datasize(");
|
||||
error += datasize;
|
||||
error += F(") > max_size(");
|
||||
error += max_size;
|
||||
error += ')';
|
||||
return error;
|
||||
}
|
||||
|
||||
String LoadFromFile(SettingsType settingsType, int index, char* fname, byte* memAddress, int datasize) {
|
||||
bool read = true;
|
||||
int offset, max_size;
|
||||
if (!getAndLogSettingsParameters(read, settingsType, index, offset, max_size)) {
|
||||
return getSettingsFileIndexRangeError(read, settingsType, index);
|
||||
}
|
||||
if (datasize > max_size)
|
||||
return getSettingsFileDatasizeError(read, settingsType, index, datasize, max_size);
|
||||
return(LoadFromFile(fname, offset, memAddress, datasize));
|
||||
}
|
||||
|
||||
String SaveToFile(SettingsType settingsType, int index, char* fname, byte* memAddress, int datasize) {
|
||||
bool read = false;
|
||||
int offset, max_size;
|
||||
if (!getAndLogSettingsParameters(read, settingsType, index, offset, max_size)) {
|
||||
return getSettingsFileIndexRangeError(read, settingsType, index);
|
||||
}
|
||||
if (datasize > max_size)
|
||||
return getSettingsFileDatasizeError(read, settingsType, index, datasize, max_size);
|
||||
return(SaveToFile(fname, offset, memAddress, datasize));
|
||||
}
|
||||
|
||||
String ClearInFile(SettingsType settingsType, int index, char* fname) {
|
||||
bool read = false;
|
||||
int offset, max_size;
|
||||
if (!getAndLogSettingsParameters(read, settingsType, index, offset, max_size)) {
|
||||
return getSettingsFileIndexRangeError(read, settingsType, index);
|
||||
}
|
||||
return(ClearInFile(fname, offset, max_size));
|
||||
}
|
||||
|
||||
/********************************************************************************************\
|
||||
Check SPIFFS area settings
|
||||
\*********************************************************************************************/
|
||||
int SpiffsSectors()
|
||||
{
|
||||
checkRAM(F("SpiffsSectors"));
|
||||
#if defined(ESP8266)
|
||||
uint32_t _sectorStart = ((uint32_t)&_SPIFFS_start - 0x40200000) / SPI_FLASH_SEC_SIZE;
|
||||
uint32_t _sectorEnd = ((uint32_t)&_SPIFFS_end - 0x40200000) / SPI_FLASH_SEC_SIZE;
|
||||
return _sectorEnd - _sectorStart;
|
||||
#endif
|
||||
#if defined(ESP32)
|
||||
return 32;
|
||||
#endif
|
||||
}
|
||||
|
||||
/********************************************************************************************\
|
||||
Get partition table information
|
||||
\*********************************************************************************************/
|
||||
#ifdef ESP32
|
||||
String getPartitionType(byte pType, byte pSubType) {
|
||||
esp_partition_type_t partitionType = static_cast<esp_partition_type_t>(pType);
|
||||
esp_partition_subtype_t partitionSubType = static_cast<esp_partition_subtype_t>(pSubType);
|
||||
if (partitionType == ESP_PARTITION_TYPE_APP) {
|
||||
if (partitionSubType >= ESP_PARTITION_SUBTYPE_APP_OTA_MIN &&
|
||||
partitionSubType < ESP_PARTITION_SUBTYPE_APP_OTA_MAX) {
|
||||
String result = F("OTA partition ");
|
||||
result += (partitionSubType - ESP_PARTITION_SUBTYPE_APP_OTA_MIN);
|
||||
return result;
|
||||
}
|
||||
|
||||
switch (partitionSubType) {
|
||||
case ESP_PARTITION_SUBTYPE_APP_FACTORY: return F("Factory app");
|
||||
case ESP_PARTITION_SUBTYPE_APP_TEST: return F("Test app");
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
if (partitionType == ESP_PARTITION_TYPE_DATA) {
|
||||
switch (partitionSubType) {
|
||||
case ESP_PARTITION_SUBTYPE_DATA_OTA: return F("OTA selection");
|
||||
case ESP_PARTITION_SUBTYPE_DATA_PHY: return F("PHY init data");
|
||||
case ESP_PARTITION_SUBTYPE_DATA_NVS: return F("NVS");
|
||||
case ESP_PARTITION_SUBTYPE_DATA_COREDUMP: return F("COREDUMP");
|
||||
case ESP_PARTITION_SUBTYPE_DATA_ESPHTTPD: return F("ESPHTTPD");
|
||||
case ESP_PARTITION_SUBTYPE_DATA_FAT: return F("FAT");
|
||||
case ESP_PARTITION_SUBTYPE_DATA_SPIFFS: return F("SPIFFS");
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
String result = F("Unknown(");
|
||||
result += partitionSubType;
|
||||
result += ')';
|
||||
return result;
|
||||
}
|
||||
|
||||
String getPartitionTableHeader(const String& itemSep, const String& lineEnd) {
|
||||
String result;
|
||||
result += F("Address");
|
||||
result += itemSep;
|
||||
result += F("Size");
|
||||
result += itemSep;
|
||||
result += F("Label");
|
||||
result += itemSep;
|
||||
result += F("Partition Type");
|
||||
result += itemSep;
|
||||
result += F("Encrypted");
|
||||
result += lineEnd;
|
||||
return result;
|
||||
}
|
||||
|
||||
String getPartitionTable(byte pType, const String& itemSep, const String& lineEnd) {
|
||||
esp_partition_type_t partitionType = static_cast<esp_partition_type_t>(pType);
|
||||
String result;
|
||||
const esp_partition_t * _mypart;
|
||||
esp_partition_iterator_t _mypartiterator = esp_partition_find(partitionType, ESP_PARTITION_SUBTYPE_ANY, NULL);
|
||||
if (_mypartiterator) {
|
||||
do {
|
||||
_mypart = esp_partition_get(_mypartiterator);
|
||||
result += formatToHex(_mypart->address);
|
||||
result += itemSep;
|
||||
result += formatToHex_decimal(_mypart->size, 1024);
|
||||
result += itemSep;
|
||||
result += _mypart->label;
|
||||
result += itemSep;
|
||||
result += getPartitionType(_mypart->type, _mypart->subtype);
|
||||
result += itemSep;
|
||||
result += (_mypart->encrypted ? F("Yes") : F("-"));
|
||||
result += lineEnd;
|
||||
} while ((_mypartiterator = esp_partition_next(_mypartiterator)) != NULL);
|
||||
}
|
||||
esp_partition_iterator_release(_mypartiterator);
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
@@ -2,6 +2,7 @@
|
||||
#define ESPEASY_TIMETYPES_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <list>
|
||||
|
||||
struct timeStruct {
|
||||
timeStruct() : Second(0), Minute(0), Hour(0), Wday(0), Day(0), Month(0), Year(0) {}
|
||||
@@ -65,6 +66,149 @@ uint32_t calcTimeChangeForRule(const TimeChangeRule& r, int yr);
|
||||
String getTimeString(char delimiter, bool show_seconds=true);
|
||||
String getTimeString_ampm(char delimiter, bool show_seconds=true);
|
||||
long timeDiff(unsigned long prev, unsigned long next);
|
||||
long timePassedSince(unsigned long timestamp);
|
||||
boolean timeOutReached(unsigned long timer);
|
||||
long usecPassedSince(unsigned long timestamp);
|
||||
boolean usecTimeOutReached(unsigned long timer);
|
||||
void setSystemTimer(unsigned long timer, byte plugin, short taskIndex, int Par1,
|
||||
int Par2 = 0, int Par3 = 0, int Par4 = 0, int Par5 = 0);
|
||||
|
||||
|
||||
|
||||
|
||||
/*********************************************************************************************\
|
||||
* TimerHandler Used by the Scheduler
|
||||
\*********************************************************************************************/
|
||||
|
||||
struct timer_id_couple {
|
||||
timer_id_couple(unsigned long id, unsigned long newtimer) : _id(id), _timer(newtimer) {}
|
||||
|
||||
timer_id_couple(unsigned long id) : _id(id) {
|
||||
_timer = millis();
|
||||
}
|
||||
|
||||
bool operator<(const timer_id_couple& other) {
|
||||
const unsigned long now(millis());
|
||||
// timediff > 0, means timer has already passed
|
||||
return (timeDiff(_timer, now) > timeDiff(other._timer, now));
|
||||
}
|
||||
|
||||
unsigned long _id;
|
||||
unsigned long _timer;
|
||||
};
|
||||
|
||||
struct msecTimerHandlerStruct {
|
||||
|
||||
msecTimerHandlerStruct() : get_called(0), get_called_ret_id(0), max_queue_length(0),
|
||||
last_exec_time_usec(0), total_idle_time_usec(0), is_idle(false), idle_time_pct(0.0)
|
||||
{
|
||||
last_log_start_time = millis();
|
||||
}
|
||||
|
||||
void registerAt(unsigned long id, unsigned long timer) {
|
||||
timer_id_couple item(id, timer);
|
||||
insert(item);
|
||||
}
|
||||
|
||||
// Check if timeout has been reached and also return its set timer.
|
||||
// Return 0 if no item has reached timeout moment.
|
||||
unsigned long getNextId(unsigned long& timer) {
|
||||
++get_called;
|
||||
if (_timer_ids.empty()) {
|
||||
recordIdle();
|
||||
return 0;
|
||||
}
|
||||
timer_id_couple item = _timer_ids.front();
|
||||
if (!timeOutReached(item._timer)) {
|
||||
recordIdle();
|
||||
return 0;
|
||||
}
|
||||
recordRunning();
|
||||
unsigned long size = _timer_ids.size();
|
||||
if (size > max_queue_length) max_queue_length = size;
|
||||
_timer_ids.pop_front();
|
||||
timer = item._timer;
|
||||
++get_called_ret_id;
|
||||
return item._id;
|
||||
}
|
||||
|
||||
String getQueueStats() {
|
||||
|
||||
String result;
|
||||
result += get_called;
|
||||
result += '/';
|
||||
result += get_called_ret_id;
|
||||
result += '/';
|
||||
result += max_queue_length;
|
||||
result += '/';
|
||||
result += idle_time_pct;
|
||||
get_called = 0;
|
||||
get_called_ret_id = 0;
|
||||
//max_queue_length = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
void updateIdleTimeStats() {
|
||||
const long duration = timePassedSince(last_log_start_time);
|
||||
last_log_start_time = millis();
|
||||
idle_time_pct = total_idle_time_usec / duration / 10.0;
|
||||
total_idle_time_usec = 0;
|
||||
}
|
||||
|
||||
float getIdleTimePct() {
|
||||
return idle_time_pct;
|
||||
}
|
||||
|
||||
private:
|
||||
struct match_id {
|
||||
match_id(unsigned long id) : _id(id) {}
|
||||
bool operator() (const timer_id_couple& item) { return _id == item._id; }
|
||||
unsigned long _id;
|
||||
};
|
||||
|
||||
void insert(const timer_id_couple& item) {
|
||||
if (item._id == 0) return;
|
||||
|
||||
// Make sure only one is present with the same id.
|
||||
_timer_ids.remove_if(match_id(item._id));
|
||||
const bool mustSort = !_timer_ids.empty();
|
||||
_timer_ids.push_front(item);
|
||||
if (mustSort)
|
||||
_timer_ids.sort(); // TD-er: Must check if this is an expensive operation.
|
||||
// It should be a relative light operation, to insert into a sorted list.
|
||||
// Perhaps it is better to use std::set ????
|
||||
// Keep in mind: order is based on timer, uniqueness is based on id.
|
||||
}
|
||||
|
||||
void recordIdle() {
|
||||
if (is_idle) return;
|
||||
last_exec_time_usec = micros();
|
||||
is_idle = true;
|
||||
yield(); // Nothing to do, so call yield for backgroundtasks
|
||||
}
|
||||
|
||||
void recordRunning() {
|
||||
if (!is_idle) return;
|
||||
is_idle = false;
|
||||
total_idle_time_usec += usecPassedSince(last_exec_time_usec);
|
||||
}
|
||||
|
||||
// Statistics
|
||||
unsigned long get_called;
|
||||
unsigned long get_called_ret_id;
|
||||
unsigned long max_queue_length;
|
||||
|
||||
// Compute idle system time
|
||||
unsigned long last_exec_time_usec;
|
||||
unsigned long total_idle_time_usec;
|
||||
unsigned long last_log_start_time;
|
||||
bool is_idle;
|
||||
float idle_time_pct;
|
||||
|
||||
// The list of set timers
|
||||
std::list<timer_id_couple> _timer_ids;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* ESPEASY_TIMETYPES_H_ */
|
||||
|
||||
+151
-109
@@ -11,19 +11,21 @@ void processConnect() {
|
||||
++wifi_reconnects;
|
||||
if (wifiStatus < ESPEASY_WIFI_CONNECTED) return;
|
||||
const long connect_duration = timeDiff(last_wifi_connect_attempt_moment, lastConnectMoment);
|
||||
String log = F("WIFI : Connected! AP: ");
|
||||
log += WiFi.SSID();
|
||||
log += F(" (");
|
||||
log += WiFi.BSSIDstr();
|
||||
log += F(") Ch: ");
|
||||
log += last_channel;
|
||||
if (connect_duration > 0 && connect_duration < 30000) {
|
||||
// Just log times when they make sense.
|
||||
log += F(" Duration: ");
|
||||
log += connect_duration;
|
||||
log += F(" ms");
|
||||
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
|
||||
String log = F("WIFI : Connected! AP: ");
|
||||
log += WiFi.SSID();
|
||||
log += F(" (");
|
||||
log += WiFi.BSSIDstr();
|
||||
log += F(") Ch: ");
|
||||
log += last_channel;
|
||||
if (connect_duration > 0 && connect_duration < 30000) {
|
||||
// Just log times when they make sense.
|
||||
log += F(" Duration: ");
|
||||
log += connect_duration;
|
||||
log += F(" ms");
|
||||
}
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
}
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
if (Settings.UseRules && bssid_changed) {
|
||||
String event = F("WiFi#ChangedAccesspoint");
|
||||
rulesProcessing(event);
|
||||
@@ -42,14 +44,16 @@ void processDisconnect() {
|
||||
String event = F("WiFi#Disconnected");
|
||||
rulesProcessing(event);
|
||||
}
|
||||
String log = F("WIFI : Disconnected! Reason: '");
|
||||
log += getLastDisconnectReason();
|
||||
log += F("'");
|
||||
if (lastConnectedDuration > 0) {
|
||||
log += F(" Connected for ");
|
||||
log += format_msec_duration(lastConnectedDuration);
|
||||
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
|
||||
String log = F("WIFI : Disconnected! Reason: '");
|
||||
log += getLastDisconnectReason();
|
||||
log += F("'");
|
||||
if (lastConnectedDuration > 0) {
|
||||
log += F(" Connected for ");
|
||||
log += format_msec_duration(lastConnectedDuration);
|
||||
}
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
}
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
logConnectionStatus();
|
||||
}
|
||||
|
||||
@@ -64,52 +68,57 @@ void processGotIP() {
|
||||
processedGetIP = true;
|
||||
const IPAddress gw = WiFi.gatewayIP();
|
||||
const IPAddress subnet = WiFi.subnetMask();
|
||||
String log = F("WIFI : ");
|
||||
if (useStaticIP()) {
|
||||
log += F("Static IP: ");
|
||||
} else {
|
||||
log += F("DHCP IP: ");
|
||||
}
|
||||
log += formatIP(ip);
|
||||
log += F(" (");
|
||||
log += WifiGetHostname();
|
||||
log += F(") GW: ");
|
||||
log += formatIP(gw);
|
||||
log += F(" SN: ");
|
||||
log += formatIP(subnet);
|
||||
|
||||
const long dhcp_duration = timeDiff(lastConnectMoment, lastGetIPmoment);
|
||||
if (dhcp_duration > 0 && dhcp_duration < 30000) {
|
||||
// Just log times when they make sense.
|
||||
log += F(" duration: ");
|
||||
log += dhcp_duration;
|
||||
log += F(" ms");
|
||||
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
|
||||
String log = F("WIFI : ");
|
||||
if (useStaticIP()) {
|
||||
log += F("Static IP: ");
|
||||
} else {
|
||||
log += F("DHCP IP: ");
|
||||
}
|
||||
log += formatIP(ip);
|
||||
log += F(" (");
|
||||
log += WifiGetHostname();
|
||||
log += F(") GW: ");
|
||||
log += formatIP(gw);
|
||||
log += F(" SN: ");
|
||||
log += formatIP(subnet);
|
||||
if (dhcp_duration > 0 && dhcp_duration < 30000) {
|
||||
// Just log times when they make sense.
|
||||
log += F(" duration: ");
|
||||
log += dhcp_duration;
|
||||
log += F(" ms");
|
||||
}
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
}
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
|
||||
// fix octet?
|
||||
if (Settings.IP_Octet != 0 && Settings.IP_Octet != 255)
|
||||
{
|
||||
ip[3] = Settings.IP_Octet;
|
||||
log = F("IP : Fixed IP octet:");
|
||||
log += formatIP(ip);
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
|
||||
String log = F("IP : Fixed IP octet:");
|
||||
log += formatIP(ip);
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
}
|
||||
WiFi.config(ip, gw, subnet);
|
||||
}
|
||||
|
||||
#ifdef FEATURE_MDNS
|
||||
|
||||
log = F("WIFI : ");
|
||||
if (MDNS.begin(WifiGetHostname().c_str(), WiFi.localIP())) {
|
||||
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
|
||||
String log = F("WIFI : ");
|
||||
if (MDNS.begin(WifiGetHostname().c_str(), WiFi.localIP())) {
|
||||
|
||||
log += F("mDNS started, with name: ");
|
||||
log += WifiGetHostname();
|
||||
log += F(".local");
|
||||
log += F("mDNS started, with name: ");
|
||||
log += WifiGetHostname();
|
||||
log += F(".local");
|
||||
}
|
||||
else{
|
||||
log += F("mDNS failed");
|
||||
}
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
}
|
||||
else{
|
||||
log += F("mDNS failed");
|
||||
}
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
#endif
|
||||
|
||||
// First try to get the time, since that may be used in logs
|
||||
@@ -118,7 +127,7 @@ void processGotIP() {
|
||||
}
|
||||
mqtt_reconnect_count = 0;
|
||||
timermqtt_interval = 100;
|
||||
timermqtt = millis() + timermqtt_interval;
|
||||
setIntervalTimer(TIMER_MQTT);
|
||||
if (Settings.UseRules)
|
||||
{
|
||||
String event = F("WiFi#Connected");
|
||||
@@ -140,11 +149,13 @@ void processGotIP() {
|
||||
void processConnectAPmode() {
|
||||
if (processedConnectAPmode) return;
|
||||
processedConnectAPmode = true;
|
||||
String log = F("AP Mode: Client connected: ");
|
||||
log += formatMAC(lastMacConnectedAPmode);
|
||||
log += F(" Connected devices: ");
|
||||
log += WiFi.softAPgetStationNum();
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
|
||||
String log = F("AP Mode: Client connected: ");
|
||||
log += formatMAC(lastMacConnectedAPmode);
|
||||
log += F(" Connected devices: ");
|
||||
log += WiFi.softAPgetStationNum();
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
}
|
||||
timerAPoff = 0; // Disable timer to switch AP off
|
||||
setWebserverRunning(true);
|
||||
// Start DNS, only used if the ESP has no valid WiFi config
|
||||
@@ -160,11 +171,13 @@ void processDisconnectAPmode() {
|
||||
if (processedDisconnectAPmode) return;
|
||||
processedDisconnectAPmode = true;
|
||||
const int nrStationsConnected = WiFi.softAPgetStationNum();
|
||||
String log = F("AP Mode: Client disconnected: ");
|
||||
log += formatMAC(lastMacDisconnectedAPmode);
|
||||
log += F(" Connected devices: ");
|
||||
log += nrStationsConnected;
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
|
||||
String log = F("AP Mode: Client disconnected: ");
|
||||
log += formatMAC(lastMacDisconnectedAPmode);
|
||||
log += F(" Connected devices: ");
|
||||
log += nrStationsConnected;
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
}
|
||||
if (nrStationsConnected == 0) {
|
||||
timerAPoff = millis() + WIFI_AP_OFF_TIMER_DURATION;
|
||||
}
|
||||
@@ -183,9 +196,11 @@ void processDisableAPmode() {
|
||||
void processScanDone() {
|
||||
if (processedScanDone) return;
|
||||
processedScanDone = true;
|
||||
String log = F("WIFI : Scan finished, found: ");
|
||||
log += scan_done_number;
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
|
||||
String log = F("WIFI : Scan finished, found: ");
|
||||
log += scan_done_number;
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
}
|
||||
|
||||
int bestScanID = -1;
|
||||
int32_t bestRssi = -1000;
|
||||
@@ -207,9 +222,11 @@ void processScanDone() {
|
||||
if (!selectNextWiFiSettings()) done = true;
|
||||
}
|
||||
if (bestScanID >= 0) {
|
||||
log = F("WIFI : Selected: ");
|
||||
log += formatScanResult(bestScanID, " ");
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
|
||||
String log = F("WIFI : Selected: ");
|
||||
log += formatScanResult(bestScanID, " ");
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
}
|
||||
lastWiFiSettings = bestWiFiSettings;
|
||||
uint8_t * scanbssid = WiFi.BSSID(bestScanID);
|
||||
if (scanbssid) {
|
||||
@@ -333,17 +350,21 @@ void setAPinternal(bool enable)
|
||||
addLog(LOG_LEVEL_ERROR, F("WIFI : [AP] softAPConfig failed!"));
|
||||
}
|
||||
if (WiFi.softAP(softAPSSID.c_str(),pwd.c_str())) {
|
||||
String log(F("WIFI : AP Mode ssid will be "));
|
||||
log += softAPSSID;
|
||||
log += F(" with address ");
|
||||
log += WiFi.softAPIP().toString();
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
|
||||
String log(F("WIFI : AP Mode ssid will be "));
|
||||
log += softAPSSID;
|
||||
log += F(" with address ");
|
||||
log += WiFi.softAPIP().toString();
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
}
|
||||
} else {
|
||||
String log(F("WIFI : Error while starting AP Mode with SSID: "));
|
||||
log += softAPSSID;
|
||||
log += F(" IP: ");
|
||||
log += apIP.toString();
|
||||
addLog(LOG_LEVEL_ERROR, log);
|
||||
if (loglevelActiveFor(LOG_LEVEL_ERROR)) {
|
||||
String log(F("WIFI : Error while starting AP Mode with SSID: "));
|
||||
log += softAPSSID;
|
||||
log += F(" IP: ");
|
||||
log += apIP.toString();
|
||||
addLog(LOG_LEVEL_ERROR, log);
|
||||
}
|
||||
}
|
||||
#ifdef ESP32
|
||||
|
||||
@@ -445,7 +466,6 @@ bool prepareWiFi() {
|
||||
return false;
|
||||
}
|
||||
setSTA(true);
|
||||
String log = "";
|
||||
char hostname[40];
|
||||
strncpy(hostname, WifiGetHostname().c_str(), sizeof(hostname));
|
||||
#if defined(ESP8266)
|
||||
@@ -524,15 +544,17 @@ void setupStaticIPconfig() {
|
||||
const IPAddress gw = Settings.Gateway;
|
||||
const IPAddress subnet = Settings.Subnet;
|
||||
const IPAddress dns = Settings.DNS;
|
||||
String log = F("IP : Static IP : ");
|
||||
log += formatIP(ip);
|
||||
log += F(" GW: ");
|
||||
log += formatIP(gw);
|
||||
log += F(" SN: ");
|
||||
log += formatIP(subnet);
|
||||
log += F(" DNS: ");
|
||||
log += formatIP(dns);
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
|
||||
String log = F("IP : Static IP : ");
|
||||
log += formatIP(ip);
|
||||
log += F(" GW: ");
|
||||
log += formatIP(gw);
|
||||
log += F(" SN: ");
|
||||
log += formatIP(subnet);
|
||||
log += F(" DNS: ");
|
||||
log += formatIP(dns);
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
}
|
||||
WiFi.config(ip, gw, subnet, dns);
|
||||
}
|
||||
|
||||
@@ -564,11 +586,13 @@ bool tryConnectWiFi() {
|
||||
}
|
||||
const char* ssid = getLastWiFiSettingsSSID();
|
||||
const char* passphrase = getLastWiFiSettingsPassphrase();
|
||||
String log = F("WIFI : Connecting ");
|
||||
log += ssid;
|
||||
log += F(" attempt #");
|
||||
log += wifi_connect_attempt;
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
|
||||
String log = F("WIFI : Connecting ");
|
||||
log += ssid;
|
||||
log += F(" attempt #");
|
||||
log += wifi_connect_attempt;
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
}
|
||||
setupStaticIPconfig();
|
||||
last_wifi_connect_attempt_moment = millis();
|
||||
switch (wifi_connect_attempt) {
|
||||
@@ -585,15 +609,19 @@ bool tryConnectWiFi() {
|
||||
logConnectionStatus();
|
||||
switch (WiFi.status()) {
|
||||
case WL_NO_SSID_AVAIL: {
|
||||
log = F("WIFI : No SSID found matching: ");
|
||||
log += ssid;
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
|
||||
String log = F("WIFI : No SSID found matching: ");
|
||||
log += ssid;
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
case WL_CONNECT_FAILED: {
|
||||
log = F("WIFI : Connection failed to: ");
|
||||
log += ssid;
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
|
||||
String log = F("WIFI : Connection failed to: ");
|
||||
log += ssid;
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
default:
|
||||
@@ -728,18 +756,22 @@ void logConnectionStatus() {
|
||||
#ifndef ESP32
|
||||
const uint8_t sdk_wifistatus = wifi_station_get_connect_status();
|
||||
if ((arduino_corelib_wifistatus == WL_CONNECTED) != (sdk_wifistatus == STATION_GOT_IP)) {
|
||||
log = F("WIFI : SDK station status differs from Arduino status. SDK-status: ");
|
||||
log += SDKwifiStatusToString(sdk_wifistatus);
|
||||
log += F(" Arduino status: ");
|
||||
log += ArduinoWifiStatusToString(arduino_corelib_wifistatus);
|
||||
addLog(LOG_LEVEL_ERROR, log);
|
||||
if (loglevelActiveFor(LOG_LEVEL_ERROR)) {
|
||||
String log = F("WIFI : SDK station status differs from Arduino status. SDK-status: ");
|
||||
log += SDKwifiStatusToString(sdk_wifistatus);
|
||||
log += F(" Arduino status: ");
|
||||
log += ArduinoWifiStatusToString(arduino_corelib_wifistatus);
|
||||
addLog(LOG_LEVEL_ERROR, log);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
log = F("WIFI : Arduino wifi status: ");
|
||||
log += ArduinoWifiStatusToString(arduino_corelib_wifistatus);
|
||||
log += F(" ESPeasy internal wifi status: ");
|
||||
log += ESPeasyWifiStatusToString();
|
||||
addLog(LOG_LEVEL_DEBUG_MORE, log);
|
||||
if (loglevelActiveFor(LOG_LEVEL_DEBUG_MORE)) {
|
||||
String log = F("WIFI : Arduino wifi status: ");
|
||||
log += ArduinoWifiStatusToString(arduino_corelib_wifistatus);
|
||||
log += F(" ESPeasy internal wifi status: ");
|
||||
log += ESPeasyWifiStatusToString();
|
||||
addLog(LOG_LEVEL_DEBUG_MORE, log);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -752,6 +784,16 @@ void WifiCheck()
|
||||
return;
|
||||
|
||||
processDisableAPmode();
|
||||
IPAddress ip = WiFi.localIP();
|
||||
if (!useStaticIP()) {
|
||||
if (ip[0] == 0 && ip[1] == 0 && ip[2] == 0 && ip[3] == 0) {
|
||||
if (WiFiConnected()) {
|
||||
// Some strange situation where the DHCP renew probably has failed and erased the config.
|
||||
resetWiFi();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (wifiStatus != ESPEASY_WIFI_SERVICES_INITIALIZED) {
|
||||
if (timeOutReached(last_wifi_connect_attempt_moment + (1000 + wifi_connect_attempt * 200))) {
|
||||
WiFiConnectRelaxed();
|
||||
|
||||
+254
-712
File diff suppressed because it is too large
Load Diff
+17
-12
@@ -121,9 +121,11 @@ void checkUDP()
|
||||
formatMAC(mac, macaddress);
|
||||
char ipaddress[20];
|
||||
formatIP(ip, ipaddress);
|
||||
char log[80];
|
||||
sprintf_P(log, PSTR("UDP : %s,%s,%u"), macaddress, ipaddress, unit);
|
||||
addLog(LOG_LEVEL_DEBUG_MORE, log);
|
||||
if (loglevelActiveFor(LOG_LEVEL_DEBUG_MORE)) {
|
||||
char log[80];
|
||||
sprintf_P(log, PSTR("UDP : %s,%s,%u"), macaddress, ipaddress, unit);
|
||||
addLog(LOG_LEVEL_DEBUG_MORE, log);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -181,9 +183,12 @@ void sendUDP(byte unit, byte* data, byte size)
|
||||
if (unit != 255)
|
||||
if (Nodes[unit].ip[0] == 0)
|
||||
return;
|
||||
String log = F("UDP : Send UDP message to ");
|
||||
log += unit;
|
||||
addLog(LOG_LEVEL_DEBUG_MORE, log);
|
||||
|
||||
if (loglevelActiveFor(LOG_LEVEL_DEBUG_MORE)) {
|
||||
String log = F("UDP : Send UDP message to ");
|
||||
log += unit;
|
||||
addLog(LOG_LEVEL_DEBUG_MORE, log);
|
||||
}
|
||||
|
||||
statusLED(true);
|
||||
|
||||
@@ -220,7 +225,6 @@ void refreshNodeList()
|
||||
\*********************************************************************************************/
|
||||
void sendSysInfoUDP(byte repeats)
|
||||
{
|
||||
char log[80];
|
||||
if (Settings.UDPPort == 0 || !WiFiConnected(100))
|
||||
return;
|
||||
|
||||
@@ -235,8 +239,7 @@ void sendSysInfoUDP(byte repeats)
|
||||
// 1 byte node type id
|
||||
|
||||
// send my info to the world...
|
||||
strcpy_P(log, PSTR("UDP : Send Sysinfo message"));
|
||||
addLog(LOG_LEVEL_DEBUG_MORE, log);
|
||||
addLog(LOG_LEVEL_DEBUG_MORE, F("UDP : Send Sysinfo message"));
|
||||
for (byte counter = 0; counter < repeats; counter++)
|
||||
{
|
||||
uint8_t mac[] = {0, 0, 0, 0, 0, 0};
|
||||
@@ -635,9 +638,11 @@ bool hostReachable(const IPAddress& ip) {
|
||||
delay(50);
|
||||
--retry;
|
||||
}
|
||||
String log = F("Host unreachable: ");
|
||||
log += formatIP(ip);
|
||||
addLog(LOG_LEVEL_ERROR, log);
|
||||
if (loglevelActiveFor(LOG_LEVEL_ERROR)) {
|
||||
String log = F("Host unreachable: ");
|
||||
log += formatIP(ip);
|
||||
addLog(LOG_LEVEL_ERROR, log);
|
||||
}
|
||||
if (ip[1] == 0 && ip[2] == 0 && ip[3] == 0) {
|
||||
// Work-around to fix connected but not able to communicate.
|
||||
addLog(LOG_LEVEL_ERROR, F("Wifi : Detected strange behavior, reconnect wifi."));
|
||||
|
||||
@@ -0,0 +1,194 @@
|
||||
#define TIMER_ID_SHIFT 28
|
||||
|
||||
#define CONST_INTERVAL_TIMER 1
|
||||
#define GENERIC_TIMER 2
|
||||
#define SYSTEM_TIMER 3
|
||||
#define TASK_DEVICE_TIMER 4
|
||||
|
||||
void setTimer(unsigned long id) {
|
||||
setTimer(GENERIC_TIMER, id, 0);
|
||||
}
|
||||
|
||||
void setIntervalTimer(unsigned long id) {
|
||||
setIntervalTimer(id, millis());
|
||||
}
|
||||
|
||||
void setIntervalTimerOverride(unsigned long id, unsigned long msecFromNow) {
|
||||
unsigned long timer = millis();
|
||||
setNextTimeInterval(timer, msecFromNow);
|
||||
setNewTimerAt(getMixedId(CONST_INTERVAL_TIMER, id), timer);
|
||||
}
|
||||
|
||||
void setIntervalTimer(unsigned long id, unsigned long lasttimer) {
|
||||
// Set the initial timers for the regular runs
|
||||
unsigned long interval = 0;
|
||||
switch (id) {
|
||||
case TIMER_20MSEC: interval = 20; break;
|
||||
case TIMER_100MSEC: interval = 100; break;
|
||||
case TIMER_1SEC: interval = 1000; break;
|
||||
case TIMER_30SEC: interval = 30000; break;
|
||||
case TIMER_MQTT: interval = timermqtt_interval; break;
|
||||
case TIMER_STATISTICS: interval = 30000; break;
|
||||
}
|
||||
unsigned long timer = lasttimer;
|
||||
setNextTimeInterval(timer, interval);
|
||||
setNewTimerAt(getMixedId(CONST_INTERVAL_TIMER, id), timer);
|
||||
}
|
||||
|
||||
void setTimer(unsigned long timerType, unsigned long id, unsigned long msecFromNow) {
|
||||
setNewTimerAt(getMixedId(timerType, id), millis() + msecFromNow);
|
||||
}
|
||||
|
||||
void setSystemTimer(unsigned long timer, byte plugin, short taskIndex, int Par1, int Par2, int Par3, int Par4, int Par5)
|
||||
{
|
||||
// plugin number and par1 form a unique key that can be used to restart a timer
|
||||
const unsigned long systemTimerId = createSystemTimerId(plugin, Par1);
|
||||
systemTimerStruct timer_data;
|
||||
timer_data.TaskIndex = taskIndex;
|
||||
timer_data.Par1 = Par1;
|
||||
timer_data.Par2 = Par2;
|
||||
timer_data.Par3 = Par3;
|
||||
timer_data.Par4 = Par4;
|
||||
timer_data.Par5 = Par5;
|
||||
systemTimers[systemTimerId] = timer_data;
|
||||
setTimer(SYSTEM_TIMER, systemTimerId, timer);
|
||||
}
|
||||
|
||||
void setNewTimerAt(unsigned long id, unsigned long timer) {
|
||||
START_TIMER;
|
||||
msecTimerHandler.registerAt(id, timer);
|
||||
STOP_TIMER(SET_NEW_TIMER);
|
||||
}
|
||||
|
||||
unsigned long createSystemTimerId(byte plugin, int Par1) {
|
||||
const unsigned long mask = (1 << TIMER_ID_SHIFT) -1;
|
||||
const unsigned long mixed = (Par1 << 8) + plugin;
|
||||
return (mixed & mask);
|
||||
}
|
||||
|
||||
/* // Not (yet) used
|
||||
void splitSystemTimerId(const unsigned long mixed_id, byte& plugin, int& Par1) {
|
||||
const unsigned long mask = (1 << TIMER_ID_SHIFT) -1;
|
||||
plugin = mixed_id & 0xFF;
|
||||
Par1 = (mixed_id & mask) >> 8;
|
||||
}
|
||||
*/
|
||||
|
||||
unsigned long getMixedId(unsigned long timerType, unsigned long id) {
|
||||
return (timerType << TIMER_ID_SHIFT) + id;
|
||||
}
|
||||
|
||||
void handle_schedule() {
|
||||
unsigned long timer;
|
||||
const unsigned long mixed_id = msecTimerHandler.getNextId(timer);
|
||||
if (mixed_id == 0) return;
|
||||
const unsigned long timerType = (mixed_id >> TIMER_ID_SHIFT);
|
||||
const unsigned long mask = (1 << TIMER_ID_SHIFT) -1;
|
||||
const unsigned long id = mixed_id & mask;
|
||||
|
||||
switch (timerType) {
|
||||
case CONST_INTERVAL_TIMER:
|
||||
setIntervalTimer(id, timer);
|
||||
process_interval_timer(id);
|
||||
break;
|
||||
case SYSTEM_TIMER:
|
||||
process_system_timer(id);
|
||||
break;
|
||||
case TASK_DEVICE_TIMER:
|
||||
process_task_device_timer(id, timer);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void process_interval_timer(unsigned long id) {
|
||||
switch (id) {
|
||||
case TIMER_20MSEC:
|
||||
run50TimesPerSecond();
|
||||
break;
|
||||
case TIMER_100MSEC:
|
||||
if(!UseRTOSMultitasking)
|
||||
run10TimesPerSecond();
|
||||
break;
|
||||
case TIMER_1SEC:
|
||||
runOncePerSecond();
|
||||
break;
|
||||
case TIMER_30SEC:
|
||||
runEach30Seconds();
|
||||
break;
|
||||
case TIMER_MQTT:
|
||||
runPeriodicalMQTT();
|
||||
break;
|
||||
case TIMER_STATISTICS:
|
||||
logTimerStatistics();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void process_system_timer(unsigned long id) {
|
||||
START_TIMER;
|
||||
const systemTimerStruct timer_data = systemTimers[id];
|
||||
struct EventStruct TempEvent;
|
||||
TempEvent.TaskIndex = timer_data.TaskIndex;
|
||||
TempEvent.Par1 = timer_data.Par1;
|
||||
TempEvent.Par2 = timer_data.Par2;
|
||||
TempEvent.Par3 = timer_data.Par3;
|
||||
TempEvent.Par4 = timer_data.Par4;
|
||||
TempEvent.Par5 = timer_data.Par5;
|
||||
// TD-er: Not sure if we have to keep original source for notifications.
|
||||
TempEvent.Source = VALUE_SOURCE_SYSTEM;
|
||||
const int y = getPluginId(timer_data.TaskIndex);
|
||||
/*
|
||||
String log = F("proc_system_timer: Pluginid: ");
|
||||
log += y;
|
||||
log += F(" taskIndex: ");
|
||||
log += timer_data.TaskIndex;
|
||||
log += F(" sysTimerID: ");
|
||||
log += id;
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
*/
|
||||
if (y >= 0) {
|
||||
String dummy;
|
||||
Plugin_ptr[y](PLUGIN_TIMER_IN, &TempEvent, dummy);
|
||||
}
|
||||
systemTimers.erase(id);
|
||||
STOP_TIMER(PROC_SYS_TIMER);
|
||||
}
|
||||
|
||||
void schedule_task_device_timer_at_init(unsigned long task_index) {
|
||||
unsigned long runAt = millis();
|
||||
if (!isDeepSleepEnabled()) {
|
||||
// Deepsleep is not enabled, add some offset based on the task index
|
||||
// to make sure not all are run at the same time.
|
||||
// This scheduled time may be overriden by the plugin's own init.
|
||||
runAt += (task_index * 37) + Settings.MessageDelay;
|
||||
}
|
||||
schedule_task_device_timer(task_index, runAt);
|
||||
}
|
||||
|
||||
void schedule_task_device_timer(unsigned long task_index, unsigned long runAt) {
|
||||
/*
|
||||
String log = F("schedule_task_device_timer: task: ");
|
||||
log += task_index;
|
||||
log += F(" @ ");
|
||||
log += runAt;
|
||||
if (Settings.TaskDeviceEnabled[task_index]) {
|
||||
log += F(" (enabled)");
|
||||
}
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
*/
|
||||
if (task_index >= TASKS_MAX) return;
|
||||
if (Settings.TaskDeviceEnabled[task_index]) {
|
||||
setNewTimerAt(getMixedId(TASK_DEVICE_TIMER, task_index), runAt);
|
||||
}
|
||||
}
|
||||
|
||||
void process_task_device_timer(unsigned long task_index, unsigned long lasttimer) {
|
||||
unsigned long newtimer = Settings.TaskDeviceTimer[task_index];
|
||||
if (newtimer != 0) {
|
||||
newtimer = lasttimer + (newtimer * 1000);
|
||||
schedule_task_device_timer(task_index, newtimer);
|
||||
}
|
||||
START_TIMER;
|
||||
SensorSendTask(task_index);
|
||||
STOP_TIMER(SENSOR_SEND_TASK);
|
||||
}
|
||||
+144
-39
@@ -60,14 +60,18 @@ String formatMAC(const uint8_t* mac) {
|
||||
return String(str);
|
||||
}
|
||||
|
||||
String formatToHex(unsigned long value) {
|
||||
String result = F("0x");
|
||||
String formatToHex(unsigned long value, const String& prefix) {
|
||||
String result = prefix;
|
||||
String hex(value, HEX);
|
||||
hex.toUpperCase();
|
||||
result += hex;
|
||||
return result;
|
||||
}
|
||||
|
||||
String formatToHex(unsigned long value) {
|
||||
return formatToHex(value, F("0x"));
|
||||
}
|
||||
|
||||
String formatHumanReadable(unsigned long value, unsigned long factor) {
|
||||
float floatValue(value);
|
||||
byte steps = 0;
|
||||
@@ -83,7 +87,7 @@ String formatHumanReadable(unsigned long value, unsigned long factor) {
|
||||
case 2: result += 'M'; break;
|
||||
case 3: result += 'G'; break;
|
||||
case 4: result += 'T'; break;
|
||||
default:
|
||||
default:
|
||||
result += '*';
|
||||
result += factor;
|
||||
result += '^';
|
||||
@@ -135,10 +139,10 @@ String toString(WiFiMode_t mode)
|
||||
break;
|
||||
case WIFI_AP_STA:
|
||||
result = F("AP+STA");
|
||||
break;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -229,49 +233,123 @@ String to_json_object_value(const String& object, const String& value) {
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************************************\
|
||||
Parse a string and get the xth command or parameter
|
||||
Strip wrapping chars (e.g. quotes)
|
||||
\*********************************************************************************************/
|
||||
String parseString(String& string, byte indexFind)
|
||||
{
|
||||
String tmpString = string;
|
||||
tmpString += ',';
|
||||
tmpString.replace(' ', ',');
|
||||
String locateString = "";
|
||||
byte count = 0;
|
||||
int index = tmpString.indexOf(',');
|
||||
while (index > 0)
|
||||
{
|
||||
count++;
|
||||
locateString = tmpString.substring(0, index);
|
||||
tmpString = tmpString.substring(index + 1);
|
||||
index = tmpString.indexOf(',');
|
||||
if (count == indexFind)
|
||||
{
|
||||
locateString.toLowerCase();
|
||||
return locateString;
|
||||
}
|
||||
|
||||
String stripWrappingChar(const String& text, char wrappingChar) {
|
||||
unsigned int length = text.length();
|
||||
if (length >= 2 && stringWrappedWithChar(text, wrappingChar)) {
|
||||
return text.substring(1, length -1);
|
||||
}
|
||||
return "";
|
||||
return text;
|
||||
}
|
||||
|
||||
bool stringWrappedWithChar(const String& text, char wrappingChar) {
|
||||
unsigned int length = text.length();
|
||||
if (length < 2) return false;
|
||||
if (text.charAt(0) != wrappingChar) return false;
|
||||
return (text.charAt(length - 1) == wrappingChar);
|
||||
}
|
||||
|
||||
bool isQuoteChar(char c) {
|
||||
return (c == '\'' || c == '"');
|
||||
}
|
||||
|
||||
bool isParameterSeparatorChar(char c) {
|
||||
return (c == ',' || c == ' ');
|
||||
}
|
||||
|
||||
String stripQuotes(const String& text) {
|
||||
if (text.length() >= 2) {
|
||||
char c = text.charAt(0);
|
||||
if (isQuoteChar(c)) {
|
||||
return stripWrappingChar(text, c);
|
||||
}
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
Parse a string and get the xth command or parameter in lower case
|
||||
\*********************************************************************************************/
|
||||
String parseString(const String& string, byte indexFind, bool toEndOfString, bool toLowerCase) {
|
||||
int startpos = 0;
|
||||
if (indexFind > 0) {
|
||||
startpos = getParamStartPos(string, indexFind);
|
||||
if (startpos < 0) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
const int endpos = getParamStartPos(string, indexFind + 1);
|
||||
String result;
|
||||
if (toEndOfString || endpos <= 0) {
|
||||
result = string.substring(startpos);
|
||||
} else {
|
||||
result = string.substring(startpos, endpos - 1);
|
||||
}
|
||||
if (toLowerCase)
|
||||
result.toLowerCase();
|
||||
return stripQuotes(result);
|
||||
}
|
||||
|
||||
String parseString(const String& string, byte indexFind) {
|
||||
return parseString(string, indexFind, false, true);
|
||||
}
|
||||
|
||||
String parseStringKeepCase(const String& string, byte indexFind) {
|
||||
return parseString(string, indexFind, false, false);
|
||||
}
|
||||
|
||||
String parseStringToEnd(const String& string, byte indexFind) {
|
||||
return parseString(string, indexFind, true, true);
|
||||
}
|
||||
|
||||
String parseStringToEndKeepCase(const String& string, byte indexFind) {
|
||||
return parseString(string, indexFind, true, false);
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
Parse a string and get the xth command or parameter
|
||||
\*********************************************************************************************/
|
||||
int getParamStartPos(String& string, byte indexFind)
|
||||
int getParamStartPos(const String& string, byte indexFind)
|
||||
{
|
||||
String tmpString = string;
|
||||
byte count = 0;
|
||||
tmpString.replace(' ', ',');
|
||||
for (unsigned int x = 0; x < tmpString.length(); x++)
|
||||
// We need to find the xth command, so we need to find the position of the (X-1)th separator.
|
||||
if (indexFind <= 1) return 0;
|
||||
byte count = 1;
|
||||
bool quotedStringActive = false;
|
||||
char quoteStartChar = '"';
|
||||
unsigned int lastParamStartPos = 0;
|
||||
const unsigned int strlength = string.length();
|
||||
if (strlength < indexFind) return -1;
|
||||
for (unsigned int x = 0; x < (strlength - 1); ++x)
|
||||
{
|
||||
if (tmpString.charAt(x) == ',')
|
||||
{
|
||||
count++;
|
||||
if (count == (indexFind - 1))
|
||||
return x + 1;
|
||||
const char c = string.charAt(x);
|
||||
// Check if we are parsing a quoted string parameter
|
||||
if (!quotedStringActive) {
|
||||
if (isQuoteChar(c)) {
|
||||
// Only allow ' or " right after parameter separator.
|
||||
if (lastParamStartPos == x ) {
|
||||
quotedStringActive = true;
|
||||
quoteStartChar = c;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (c == quoteStartChar) {
|
||||
// Found end of quoted string
|
||||
quotedStringActive = false;
|
||||
}
|
||||
}
|
||||
// Do further parsing.
|
||||
if (!quotedStringActive) {
|
||||
if (isParameterSeparatorChar(c))
|
||||
{
|
||||
lastParamStartPos = x + 1;
|
||||
++count;
|
||||
if (count == indexFind) {
|
||||
return lastParamStartPos;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
@@ -386,6 +464,7 @@ void parseSpecialCharacters(String& s, boolean useURLencode)
|
||||
|
||||
// Simple macro to create the replacement string only when needed.
|
||||
#define SMART_REPL(T,S) if (s.indexOf(T) != -1) { repl((T), (S), s, useURLencode);}
|
||||
#define SMART_REPL_T(T,S) if (s.indexOf(T) != -1) { (S((T), s, useURLencode));}
|
||||
void parseSystemVariables(String& s, boolean useURLencode)
|
||||
{
|
||||
parseSpecialCharacters(s, useURLencode);
|
||||
@@ -398,6 +477,8 @@ void parseSystemVariables(String& s, boolean useURLencode)
|
||||
repl(F("%CR%"), F("\r"), s, useURLencode);
|
||||
repl(F("%LF%"), F("\n"), s, useURLencode);
|
||||
repl(F("%SP%"), F(" "), s, useURLencode); //space
|
||||
repl(F("%R%"), F("\\r"), s, useURLencode);
|
||||
repl(F("%N%"), F("\\n"), s, useURLencode);
|
||||
SMART_REPL(F("%ip4%"),WiFi.localIP().toString().substring(WiFi.localIP().toString().lastIndexOf('.')+1)) //4th IP octet
|
||||
SMART_REPL(F("%ip%"),WiFi.localIP().toString())
|
||||
SMART_REPL(F("%rssi%"), String((wifiStatus == ESPEASY_WIFI_DISCONNECTED) ? 0 : WiFi.RSSI()))
|
||||
@@ -438,9 +519,10 @@ void parseSystemVariables(String& s, boolean useURLencode)
|
||||
SMART_REPL(F("%lcltime_am%"), getDateTimeString_ampm('-',':',' '))
|
||||
SMART_REPL(F("%uptime%"), String(wdcounter / 2))
|
||||
SMART_REPL(F("%unixtime%"), String(getUnixTime()))
|
||||
SMART_REPL(F("%sunrise%"), getSunriseTimeString(':'))
|
||||
SMART_REPL(F("%sunset%"), getSunsetTimeString(':'))
|
||||
SMART_REPL_T(F("%sunset"), replSunSetTimeString)
|
||||
SMART_REPL_T(F("%sunrise"), replSunRiseTimeString)
|
||||
|
||||
// FIXME TD-er: Must make sure LoadTaskSettings has been performed before this is called.
|
||||
repl(F("%tskname%"), ExtraTaskSettings.TaskDeviceName, s, useURLencode);
|
||||
if (s.indexOf(F("%vname")) != -1) {
|
||||
repl(F("%vname1%"), ExtraTaskSettings.TaskDeviceValueNames[0], s, useURLencode);
|
||||
@@ -450,6 +532,28 @@ void parseSystemVariables(String& s, boolean useURLencode)
|
||||
}
|
||||
}
|
||||
|
||||
String getReplacementString(const String& format, String& s) {
|
||||
int startpos = s.indexOf(format);
|
||||
int endpos = s.indexOf('%', startpos + 1);
|
||||
String R = s.substring(startpos, endpos + 1);
|
||||
String log = F("ReplacementString SunTime: ");
|
||||
log += R;
|
||||
log += F(" offset: ");
|
||||
log += getSecOffset(R);
|
||||
addLog(LOG_LEVEL_DEBUG, log);
|
||||
return R;
|
||||
}
|
||||
|
||||
void replSunRiseTimeString(const String& format, String& s, boolean useURLencode) {
|
||||
String R = getReplacementString(format, s);
|
||||
repl(R, getSunriseTimeString(':', getSecOffset(R)), s, useURLencode);
|
||||
}
|
||||
|
||||
void replSunSetTimeString(const String& format, String& s, boolean useURLencode) {
|
||||
String R = getReplacementString(format, s);
|
||||
repl(R, getSunsetTimeString(':', getSecOffset(R)), s, useURLencode);
|
||||
}
|
||||
|
||||
void parseEventVariables(String& s, struct EventStruct *event, boolean useURLencode)
|
||||
{
|
||||
SMART_REPL(F("%id%"), String(event->idx))
|
||||
@@ -464,6 +568,7 @@ void parseEventVariables(String& s, struct EventStruct *event, boolean useURLenc
|
||||
}
|
||||
}
|
||||
}
|
||||
#undef SMART_REPL_T
|
||||
#undef SMART_REPL
|
||||
|
||||
bool getConvertArgument(const String& marker, const String& s, float& argument, int& startIndex, int& endIndex) {
|
||||
|
||||
+75
-10
@@ -17,6 +17,7 @@ uint32_t syncInterval = 3600; // time sync will be attempted after this many se
|
||||
uint32_t sysTime = 0;
|
||||
uint32_t prevMillis = 0;
|
||||
uint32_t nextSyncTime = 0;
|
||||
timeStruct tsRise, tsSet;
|
||||
timeStruct sunRise;
|
||||
timeStruct sunSet;
|
||||
|
||||
@@ -62,7 +63,6 @@ void calcSunRiseAndSet() {
|
||||
float da = diurnalArc(dec, Settings.Latitude);
|
||||
float rise = 12 - da - eqt - Settings.Longitude / 15.0;
|
||||
float set = 12 + da - eqt - Settings.Longitude / 15.0;
|
||||
timeStruct tsRise, tsSet;
|
||||
tsRise.Hour = (int)rise;
|
||||
tsRise.Minute = (rise - (int)rise) * 60.0;
|
||||
tsSet.Hour = (int)set;
|
||||
@@ -74,6 +74,25 @@ void calcSunRiseAndSet() {
|
||||
breakTime(toLocal(makeTime(tsSet)), sunSet);
|
||||
}
|
||||
|
||||
timeStruct getSunRise(int secOffset) {
|
||||
return addSeconds(tsRise, secOffset, true);
|
||||
}
|
||||
|
||||
timeStruct getSunSet(int secOffset) {
|
||||
return addSeconds(tsSet, secOffset, true);
|
||||
}
|
||||
|
||||
timeStruct addSeconds(const timeStruct& ts, int seconds, bool toLocalTime) {
|
||||
unsigned long time = makeTime(ts);
|
||||
time += seconds;
|
||||
if (toLocalTime) {
|
||||
time = toLocal(time);
|
||||
}
|
||||
timeStruct result;
|
||||
breakTime(time, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
void breakTime(unsigned long timeInput, struct timeStruct &tm) {
|
||||
uint8_t year;
|
||||
uint8_t month, monthLength;
|
||||
@@ -142,6 +161,30 @@ uint32_t getUnixTime() {
|
||||
return sysTime;
|
||||
}
|
||||
|
||||
int getSecOffset(const String& format) {
|
||||
int position_minus = format.indexOf('-');
|
||||
int position_plus = format.indexOf('+');
|
||||
if (position_minus == -1 && position_plus == -1)
|
||||
return 0;
|
||||
int sign_position = _max(position_minus, position_plus);
|
||||
int position_percent = format.indexOf('%', sign_position);
|
||||
if (position_percent == -1) {
|
||||
return 0;
|
||||
}
|
||||
String valueStr = getNumerical(format.substring(sign_position, position_percent), true);
|
||||
if (!isInt(valueStr)) return 0;
|
||||
int value = valueStr.toInt();
|
||||
switch (format.charAt(position_percent - 1)) {
|
||||
case 'm':
|
||||
case 'M':
|
||||
return value * 60;
|
||||
case 'h':
|
||||
case 'H':
|
||||
return value * 3600;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
String getSunriseTimeString(char delimiter) {
|
||||
return getTimeString(sunRise, delimiter, false, false);
|
||||
}
|
||||
@@ -150,6 +193,19 @@ String getSunsetTimeString(char delimiter) {
|
||||
return getTimeString(sunSet, delimiter, false, false);
|
||||
}
|
||||
|
||||
String getSunriseTimeString(char delimiter, int secOffset) {
|
||||
if (secOffset == 0)
|
||||
return getSunriseTimeString(delimiter);
|
||||
return getTimeString(getSunRise(secOffset), delimiter, false, false);
|
||||
}
|
||||
|
||||
String getSunsetTimeString(char delimiter, int secOffset) {
|
||||
if (secOffset == 0)
|
||||
return getSunsetTimeString(delimiter);
|
||||
return getTimeString(getSunSet(secOffset), delimiter, false, false);
|
||||
}
|
||||
|
||||
|
||||
unsigned long now() {
|
||||
// calculate number of seconds passed since last call to now()
|
||||
bool timeSynced = false;
|
||||
@@ -331,16 +387,17 @@ unsigned long getNtpTime()
|
||||
secsSince1900 |= (unsigned long)packetBuffer[41] << 16;
|
||||
secsSince1900 |= (unsigned long)packetBuffer[42] << 8;
|
||||
secsSince1900 |= (unsigned long)packetBuffer[43];
|
||||
log = F("NTP : NTP replied: ");
|
||||
log += timePassedSince(beginWait);
|
||||
log += F(" mSec");
|
||||
addLog(LOG_LEVEL_DEBUG_MORE, log);
|
||||
if (loglevelActiveFor(LOG_LEVEL_DEBUG_MORE)) {
|
||||
String log = F("NTP : NTP replied: ");
|
||||
log += timePassedSince(beginWait);
|
||||
log += F(" mSec");
|
||||
addLog(LOG_LEVEL_DEBUG_MORE, log);
|
||||
}
|
||||
return secsSince1900 - 2208988800UL;
|
||||
}
|
||||
delay(10);
|
||||
}
|
||||
log = F("NTP : No reply");
|
||||
addLog(LOG_LEVEL_DEBUG_MORE, log);
|
||||
addLog(LOG_LEVEL_DEBUG_MORE, F("NTP : No reply"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -355,6 +412,7 @@ unsigned long getNtpTime()
|
||||
// Returned value is positive when "next" is after "prev"
|
||||
long timeDiff(const unsigned long prev, const unsigned long next)
|
||||
{
|
||||
unsigned long start = ESP.getCycleCount();
|
||||
long signed_diff = 0;
|
||||
// To cast a value to a signed long, the difference may not exceed half the ULONG_MAX
|
||||
const unsigned long half_max_unsigned_long = 2147483647u; // = 2^31 -1
|
||||
@@ -381,6 +439,11 @@ long timeDiff(const unsigned long prev, const unsigned long next)
|
||||
signed_diff = static_cast<long>((ULONG_MAX - prev) + next + 1u);
|
||||
}
|
||||
}
|
||||
unsigned long end = ESP.getCycleCount();
|
||||
if (end > start) {
|
||||
++timediff_calls;
|
||||
timediff_cpu_cycles_total += (end - start);
|
||||
}
|
||||
return signed_diff;
|
||||
}
|
||||
|
||||
@@ -573,8 +636,9 @@ unsigned long string2TimeLong(const String &str)
|
||||
// format 0000WWWWAAAABBBBCCCCDDDD
|
||||
// WWWW=weekday, AAAA=hours tens digit, BBBB=hours, CCCC=minutes tens digit DDDD=minutes
|
||||
|
||||
#define TmpStr1Length 10
|
||||
char command[20];
|
||||
char TmpStr1[10];
|
||||
char TmpStr1[TmpStr1Length];
|
||||
int w, x, y;
|
||||
unsigned long a;
|
||||
{
|
||||
@@ -585,7 +649,7 @@ unsigned long string2TimeLong(const String &str)
|
||||
}
|
||||
unsigned long lngTime = 0;
|
||||
|
||||
if (GetArgv(command, TmpStr1, 1))
|
||||
if (GetArgv(command, TmpStr1, TmpStr1Length, 1))
|
||||
{
|
||||
String day = TmpStr1;
|
||||
String weekDays = F("allsunmontuewedthufrisatwrkwkd");
|
||||
@@ -595,7 +659,7 @@ unsigned long string2TimeLong(const String &str)
|
||||
lngTime |= (unsigned long)y << 16;
|
||||
}
|
||||
|
||||
if (GetArgv(command, TmpStr1, 2))
|
||||
if (GetArgv(command, TmpStr1, TmpStr1Length, 2))
|
||||
{
|
||||
y = 0;
|
||||
for (x = strlen(TmpStr1) - 1; x >= 0; x--)
|
||||
@@ -619,6 +683,7 @@ unsigned long string2TimeLong(const String &str)
|
||||
}
|
||||
}
|
||||
}
|
||||
#undef TmpStr1Length
|
||||
return lngTime;
|
||||
}
|
||||
|
||||
|
||||
+192
-78
@@ -149,15 +149,16 @@ public:
|
||||
sendContentBlocking(buf);
|
||||
finalRam = ESP.getFreeHeap();
|
||||
/*
|
||||
String log = String("Ram usage: Webserver only: ") + maxServerUsage +
|
||||
" including Core: " + maxCoreUsage +
|
||||
" flashStringCalls: " + flashStringCalls +
|
||||
" flashStringData: " + flashStringData;
|
||||
addLog(LOG_LEVEL_DEBUG, log);
|
||||
if (loglevelActiveFor(LOG_LEVEL_DEBUG)) {
|
||||
String log = String("Ram usage: Webserver only: ") + maxServerUsage +
|
||||
" including Core: " + maxCoreUsage +
|
||||
" flashStringCalls: " + flashStringCalls +
|
||||
" flashStringData: " + flashStringData;
|
||||
addLog(LOG_LEVEL_DEBUG, log);
|
||||
}
|
||||
*/
|
||||
} else {
|
||||
String log = String("Webpage skipped: low memory: ") + finalRam;
|
||||
addLog(LOG_LEVEL_DEBUG, log);
|
||||
addLog(LOG_LEVEL_DEBUG, String("Webpage skipped: low memory: ") + finalRam);
|
||||
lowMemorySkip = false;
|
||||
}
|
||||
}
|
||||
@@ -167,8 +168,7 @@ void sendContentBlocking(String& data) {
|
||||
checkRAM(F("sendContentBlocking"));
|
||||
uint32_t freeBeforeSend = ESP.getFreeHeap();
|
||||
const uint32_t length = data.length();
|
||||
String log = String("sendcontent free: ") + freeBeforeSend + " chunk size:" + length;
|
||||
addLog(LOG_LEVEL_DEBUG_DEV, log);
|
||||
addLog(LOG_LEVEL_DEBUG_DEV, String("sendcontent free: ") + freeBeforeSend + " chunk size:" + length);
|
||||
freeBeforeSend = ESP.getFreeHeap();
|
||||
if (TXBuffer.beforeTXRam > freeBeforeSend)
|
||||
TXBuffer.beforeTXRam = freeBeforeSend;
|
||||
@@ -355,11 +355,13 @@ boolean clientIPallowed()
|
||||
String response = F("IP blocked: ");
|
||||
response += formatIP(client.remoteIP());
|
||||
WebServer.send(403, "text/html", response);
|
||||
response += F(" Allowed: ");
|
||||
response += formatIP(low);
|
||||
response += F(" - ");
|
||||
response += formatIP(high);
|
||||
addLog(LOG_LEVEL_ERROR, response);
|
||||
if (loglevelActiveFor(LOG_LEVEL_ERROR)) {
|
||||
response += F(" Allowed: ");
|
||||
response += formatIP(low);
|
||||
response += F(" - ");
|
||||
response += formatIP(high);
|
||||
addLog(LOG_LEVEL_ERROR, response);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -425,7 +427,13 @@ bool isFormItem(const String& id)
|
||||
void addHtmlError(String error){
|
||||
if (error.length()>0)
|
||||
{
|
||||
TXBuffer += F("<div class=\"alert\"><span class=\"closebtn\" onclick=\"this.parentElement.style.display='none';\">×</span>");
|
||||
TXBuffer += F("<div class=\"");
|
||||
if (error.startsWith(F("Warn"))) {
|
||||
TXBuffer += F("warning");
|
||||
} else {
|
||||
TXBuffer += F("alert");
|
||||
}
|
||||
TXBuffer += F("\"><span class=\"closebtn\" onclick=\"this.parentElement.style.display='none';\">×</span>");
|
||||
TXBuffer += error;
|
||||
TXBuffer += F("</div>");
|
||||
}
|
||||
@@ -727,9 +735,11 @@ void getWebPageTemplateVar(const String& varName )
|
||||
|
||||
else
|
||||
{
|
||||
String log = F("Templ: Unknown Var : ");
|
||||
log += varName;
|
||||
addLog(LOG_LEVEL_ERROR, log);
|
||||
if (loglevelActiveFor(LOG_LEVEL_ERROR)) {
|
||||
String log = F("Templ: Unknown Var : ");
|
||||
log += varName;
|
||||
addLog(LOG_LEVEL_ERROR, log);
|
||||
}
|
||||
//no return string - eat var name
|
||||
}
|
||||
|
||||
@@ -747,10 +757,12 @@ void writeDefaultCSS(void)
|
||||
fs::File f = SPIFFS.open(F("esp.css"), "w");
|
||||
if (f)
|
||||
{
|
||||
String log = F("CSS : Writing default CSS file to SPIFFS (");
|
||||
log += defaultCSS.length();
|
||||
log += F(" bytes)");
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
|
||||
String log = F("CSS : Writing default CSS file to SPIFFS (");
|
||||
log += defaultCSS.length();
|
||||
log += F(" bytes)");
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
}
|
||||
defaultCSS= PGMT(pgDefaultCSS);
|
||||
f.write((const unsigned char*)defaultCSS.c_str(), defaultCSS.length()); //note: content must be in RAM - a write of F("XXX") does not work
|
||||
f.close();
|
||||
@@ -939,21 +951,18 @@ void handle_root() {
|
||||
// disconnect here could result into a crash/reboot...
|
||||
if (strcasecmp_P(sCommand.c_str(), PSTR("wifidisconnect")) == 0)
|
||||
{
|
||||
String log = F("WIFI : Disconnecting...");
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
addLog(LOG_LEVEL_INFO, F("WIFI : Disconnecting..."));
|
||||
cmd_within_mainloop = CMD_WIFI_DISCONNECT;
|
||||
}
|
||||
|
||||
if (strcasecmp_P(sCommand.c_str(), PSTR("reboot")) == 0)
|
||||
{
|
||||
String log = F(" : Rebooting...");
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
addLog(LOG_LEVEL_INFO, F(" : Rebooting..."));
|
||||
cmd_within_mainloop = CMD_REBOOT;
|
||||
}
|
||||
if (strcasecmp_P(sCommand.c_str(), PSTR("reset")) == 0)
|
||||
{
|
||||
String log = F(" : factory reset...");
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
addLog(LOG_LEVEL_INFO, F(" : factory reset..."));
|
||||
cmd_within_mainloop = CMD_REBOOT;
|
||||
TXBuffer+= F("OK. Please wait > 1 min and connect to Acces point.<BR><BR>PW=configesp<BR>URL=<a href='http://192.168.4.1'>192.168.4.1</a>");
|
||||
TXBuffer.endStream();
|
||||
@@ -1818,12 +1827,15 @@ void handle_devices() {
|
||||
}
|
||||
const int edit = getFormItemInt(F("edit"), 0);
|
||||
|
||||
// taskIndex in the URL is 1 ... TASKS_MAX
|
||||
// For use in other functions, set it to 0 ... (TASKS_MAX - 1)
|
||||
byte taskIndex = getFormItemInt(F("index"), 0);
|
||||
boolean taskIndexNotSet = taskIndex == 0;
|
||||
--taskIndex;
|
||||
|
||||
byte DeviceIndex = 0;
|
||||
|
||||
LoadTaskSettings(taskIndex); // Make sure ExtraTaskSettings are up-to-date
|
||||
// FIXME TD-er: Might have to clear any caches here.
|
||||
if (edit != 0 && !taskIndexNotSet) // when form submitted
|
||||
{
|
||||
if (Settings.TaskDeviceNumber[taskIndex] != taskdevicenumber) // change of device: cleanup old device and reset default settings
|
||||
@@ -1841,7 +1853,7 @@ void handle_devices() {
|
||||
if (ExtraTaskSettings.TaskDeviceValueNames[0][0] == 0) // if field set empty, reload defaults
|
||||
PluginCall(PLUGIN_GET_DEVICEVALUENAMES, &TempEvent, dummyString); //the plugin should populate ExtraTaskSettings with its default values.
|
||||
|
||||
ClearCustomTaskSettings(taskIndex);
|
||||
ClearCustomTaskSettings(taskIndex);
|
||||
}
|
||||
}
|
||||
else if (taskdevicenumber != 0) //save settings
|
||||
@@ -2118,13 +2130,16 @@ void handle_devices() {
|
||||
addFormNote(F("This plugin is only supported on task 1-4 for now"));
|
||||
}
|
||||
|
||||
addFormTextBox( F("Name"), F("TDN"), ExtraTaskSettings.TaskDeviceName, 40); //="taskdevicename"
|
||||
addFormTextBox( F("Name"), F("TDN"), ExtraTaskSettings.TaskDeviceName, NAME_FORMULA_LENGTH_MAX); //="taskdevicename"
|
||||
|
||||
addFormCheckBox(F("Enabled"), F("TDE"), Settings.TaskDeviceEnabled[taskIndex]); //="taskdeviceenabled"
|
||||
|
||||
// section: Sensor / Actuator
|
||||
if (!Device[DeviceIndex].Custom && Settings.TaskDeviceDataFeed[taskIndex] == 0 &&
|
||||
((Device[DeviceIndex].Ports != 0) || (Device[DeviceIndex].PullUpOption) || (Device[DeviceIndex].InverseLogicOption) || (Device[DeviceIndex].Type >= DEVICE_TYPE_SINGLE && Device[DeviceIndex].Type <= DEVICE_TYPE_TRIPLE)) )
|
||||
((Device[DeviceIndex].Ports != 0) ||
|
||||
(Device[DeviceIndex].PullUpOption) ||
|
||||
(Device[DeviceIndex].InverseLogicOption) ||
|
||||
(Device[DeviceIndex].connectedToGPIOpins())) )
|
||||
{
|
||||
addFormSubHeader((Device[DeviceIndex].SendDataOption) ? F("Sensor") : F("Actuator"));
|
||||
|
||||
@@ -2150,12 +2165,14 @@ void handle_devices() {
|
||||
TempEvent.String3 = F("3rd GPIO");
|
||||
PluginCall(PLUGIN_GET_DEVICEGPIONAMES, &TempEvent, dummyString);
|
||||
|
||||
if (Device[DeviceIndex].Type >= DEVICE_TYPE_SINGLE && Device[DeviceIndex].Type <= DEVICE_TYPE_TRIPLE)
|
||||
addFormPinSelect(TempEvent.String1, F("taskdevicepin1"), Settings.TaskDevicePin1[taskIndex]);
|
||||
if (Device[DeviceIndex].Type >= DEVICE_TYPE_DUAL && Device[DeviceIndex].Type <= DEVICE_TYPE_TRIPLE)
|
||||
addFormPinSelect( TempEvent.String2, F("taskdevicepin2"), Settings.TaskDevicePin2[taskIndex]);
|
||||
if (Device[DeviceIndex].Type == DEVICE_TYPE_TRIPLE)
|
||||
addFormPinSelect(TempEvent.String3, F("taskdevicepin3"), Settings.TaskDevicePin3[taskIndex]);
|
||||
if (Device[DeviceIndex].connectedToGPIOpins()) {
|
||||
if (Device[DeviceIndex].Type >= DEVICE_TYPE_SINGLE)
|
||||
addFormPinSelect(TempEvent.String1, F("taskdevicepin1"), Settings.TaskDevicePin1[taskIndex]);
|
||||
if (Device[DeviceIndex].Type >= DEVICE_TYPE_DUAL)
|
||||
addFormPinSelect( TempEvent.String2, F("taskdevicepin2"), Settings.TaskDevicePin2[taskIndex]);
|
||||
if (Device[DeviceIndex].Type == DEVICE_TYPE_TRIPLE)
|
||||
addFormPinSelect(TempEvent.String3, F("taskdevicepin3"), Settings.TaskDevicePin3[taskIndex]);
|
||||
}
|
||||
}
|
||||
|
||||
//add plugins content
|
||||
@@ -2193,7 +2210,7 @@ void handle_devices() {
|
||||
TXBuffer += F("<TR><TD>IDX:<TD>");
|
||||
id = F("TDID"); //="taskdeviceid"
|
||||
id += controllerNr + 1;
|
||||
addNumericBox(id, Settings.TaskDeviceID[controllerNr][taskIndex], 0, 9999);
|
||||
addNumericBox(id, Settings.TaskDeviceID[controllerNr][taskIndex], 0, 999999999); // Looks like it is an unsigned int, so could be up to 4 bln.
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2239,14 +2256,14 @@ void handle_devices() {
|
||||
TXBuffer += F("<TD>");
|
||||
String id = F("TDVN"); //="taskdevicevaluename"
|
||||
id += (varNr + 1);
|
||||
addTextBox(id, ExtraTaskSettings.TaskDeviceValueNames[varNr], 40);
|
||||
addTextBox(id, ExtraTaskSettings.TaskDeviceValueNames[varNr], NAME_FORMULA_LENGTH_MAX);
|
||||
|
||||
if (Device[DeviceIndex].FormulaOption)
|
||||
{
|
||||
TXBuffer += F("<TD>");
|
||||
String id = F("TDF"); //="taskdeviceformula"
|
||||
id += (varNr + 1);
|
||||
addTextBox(id, ExtraTaskSettings.TaskDeviceFormula[varNr], 40);
|
||||
addTextBox(id, ExtraTaskSettings.TaskDeviceFormula[varNr], NAME_FORMULA_LENGTH_MAX);
|
||||
}
|
||||
|
||||
if (Device[DeviceIndex].FormulaOption || Device[DeviceIndex].DecimalsOnly)
|
||||
@@ -2280,9 +2297,11 @@ void handle_devices() {
|
||||
|
||||
|
||||
checkRAM(F("handle_devices"));
|
||||
String log = F("DEBUG: String size:");
|
||||
log += String(TXBuffer.sentBytes);
|
||||
addLog(LOG_LEVEL_DEBUG_DEV, log);
|
||||
if (loglevelActiveFor(LOG_LEVEL_DEBUG_DEV)) {
|
||||
String log = F("DEBUG: String size:");
|
||||
log += String(TXBuffer.sentBytes);
|
||||
addLog(LOG_LEVEL_DEBUG_DEV, log);
|
||||
}
|
||||
sendHeadandTail(F("TmplStd"),_TAIL);
|
||||
TXBuffer.endStream();
|
||||
}
|
||||
@@ -3607,6 +3626,7 @@ void stream_last_json_object_value(const String& object, const String& value) {
|
||||
void handle_json()
|
||||
{
|
||||
const int taskNr = getFormItemInt(F("tasknr"), -1);
|
||||
const bool showSpecificTask = taskNr > 0;
|
||||
bool showSystem = true;
|
||||
bool showWifi = true;
|
||||
bool showDataAcquisition = true;
|
||||
@@ -3623,7 +3643,7 @@ void handle_json()
|
||||
}
|
||||
}
|
||||
TXBuffer.startJsonStream();
|
||||
if (taskNr == -1)
|
||||
if (!showSpecificTask)
|
||||
{
|
||||
TXBuffer += '{';
|
||||
if (showSystem) {
|
||||
@@ -3675,7 +3695,7 @@ void handle_json()
|
||||
|
||||
byte firstTaskIndex = 0;
|
||||
byte lastTaskIndex = TASKS_MAX - 1;
|
||||
if (taskNr > 0 )
|
||||
if (showSpecificTask)
|
||||
{
|
||||
firstTaskIndex = taskNr - 1;
|
||||
lastTaskIndex = taskNr - 1;
|
||||
@@ -3686,7 +3706,7 @@ void handle_json()
|
||||
lastActiveTaskIndex = TaskIndex;
|
||||
}
|
||||
|
||||
if (taskNr == 0 ) TXBuffer += F("\"Sensors\":[\n");
|
||||
if (!showSpecificTask) TXBuffer += F("\"Sensors\":[\n");
|
||||
unsigned long ttl_json = 60; // The shortest interval per enabled task (with output values) in seconds
|
||||
for (byte TaskIndex = firstTaskIndex; TaskIndex <= lastActiveTaskIndex; TaskIndex++)
|
||||
{
|
||||
@@ -3714,7 +3734,7 @@ void handle_json()
|
||||
}
|
||||
TXBuffer += F("],\n");
|
||||
}
|
||||
if (taskNr != 0) {
|
||||
if (showSpecificTask) {
|
||||
stream_next_json_object_value(F("TTL"), String(ttl_json * 1000));
|
||||
}
|
||||
if (showDataAcquisition) {
|
||||
@@ -3742,7 +3762,7 @@ void handle_json()
|
||||
TXBuffer += F("\n");
|
||||
}
|
||||
}
|
||||
if (taskNr == 0) {
|
||||
if (!showSpecificTask) {
|
||||
TXBuffer += F("],\n");
|
||||
stream_last_json_object_value(F("TTL"), String(ttl_json * 1000));
|
||||
}
|
||||
@@ -3790,12 +3810,13 @@ void handle_advanced() {
|
||||
if (dst_end.isValid()) { Settings.DST_End = dst_end.toFlashStoredValue(); }
|
||||
str2ip(syslogip.c_str(), Settings.Syslog_IP);
|
||||
Settings.UDPPort = getFormItemInt(F("udpport"));
|
||||
Settings.SyslogLevel = getFormItemInt(F("sysloglevel"));
|
||||
|
||||
Settings.SyslogFacility = getFormItemInt(F("syslogfacility"));
|
||||
Settings.UseSerial = isFormItemChecked(F("useserial"));
|
||||
Settings.SerialLogLevel = getFormItemInt(F("serialloglevel"));
|
||||
Settings.WebLogLevel = getFormItemInt(F("webloglevel"));
|
||||
Settings.SDLogLevel = getFormItemInt(F("sdloglevel"));
|
||||
setLogLevelFor(LOG_TO_SYSLOG, getFormItemInt(F("sysloglevel")));
|
||||
setLogLevelFor(LOG_TO_SERIAL, getFormItemInt(F("serialloglevel")));
|
||||
setLogLevelFor(LOG_TO_WEBLOG, getFormItemInt(F("webloglevel")));
|
||||
setLogLevelFor(LOG_TO_SDCARD, getFormItemInt(F("sdloglevel")));
|
||||
Settings.UseValueLogger = isFormItemChecked(F("valuelogger"));
|
||||
Settings.BaudRate = getFormItemInt(F("baudrate"));
|
||||
Settings.UseNTP = isFormItemChecked(F("usentp"));
|
||||
@@ -4088,7 +4109,6 @@ void handleFileUpload() {
|
||||
if (!isLoggedIn()) return;
|
||||
|
||||
static boolean valid = false;
|
||||
String log = "";
|
||||
|
||||
HTTPUpload& upload = WebServer.upload();
|
||||
|
||||
@@ -4100,9 +4120,11 @@ void handleFileUpload() {
|
||||
|
||||
if (upload.status == UPLOAD_FILE_START)
|
||||
{
|
||||
log = F("Upload: START, filename: ");
|
||||
log += upload.filename;
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
|
||||
String log = F("Upload: START, filename: ");
|
||||
log += upload.filename;
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
}
|
||||
valid = false;
|
||||
uploadResult = 0;
|
||||
}
|
||||
@@ -4139,16 +4161,20 @@ void handleFileUpload() {
|
||||
}
|
||||
}
|
||||
if (uploadFile) uploadFile.write(upload.buf, upload.currentSize);
|
||||
log = F("Upload: WRITE, Bytes: ");
|
||||
log += upload.currentSize;
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
|
||||
String log = F("Upload: WRITE, Bytes: ");
|
||||
log += upload.currentSize;
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
}
|
||||
}
|
||||
else if (upload.status == UPLOAD_FILE_END)
|
||||
{
|
||||
if (uploadFile) uploadFile.close();
|
||||
log = F("Upload: END, Size: ");
|
||||
log += upload.totalSize;
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
|
||||
String log = F("Upload: END, Size: ");
|
||||
log += upload.totalSize;
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
}
|
||||
}
|
||||
|
||||
if (valid)
|
||||
@@ -4182,8 +4208,11 @@ bool loadFromFS(boolean spiffs, String path) {
|
||||
else if (path.endsWith(F(".txt"))) dataType = F("application/octet-stream");
|
||||
else if (path.endsWith(F(".dat"))) dataType = F("application/octet-stream");
|
||||
else if (path.endsWith(F(".esp"))) return handle_custom(path);
|
||||
String log = F("HTML : Request file ");
|
||||
log += path;
|
||||
if (loglevelActiveFor(LOG_LEVEL_DEBUG)) {
|
||||
String log = F("HTML : Request file ");
|
||||
log += path;
|
||||
addLog(LOG_LEVEL_DEBUG, log);
|
||||
}
|
||||
|
||||
path = path.substring(1);
|
||||
if (spiffs)
|
||||
@@ -4215,8 +4244,6 @@ bool loadFromFS(boolean spiffs, String path) {
|
||||
#endif
|
||||
}
|
||||
statusLED(true);
|
||||
|
||||
addLog(LOG_LEVEL_DEBUG, log);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -4689,9 +4716,11 @@ void handle_setup() {
|
||||
strncpy(SecuritySettings.WifiKey, password.c_str(), sizeof(SecuritySettings.WifiKey));
|
||||
strncpy(SecuritySettings.WifiSSID, ssid.c_str(), sizeof(SecuritySettings.WifiSSID));
|
||||
wifiSetupConnect = true;
|
||||
String reconnectlog = F("WIFI : Credentials Changed, retry connection. SSID: ");
|
||||
reconnectlog += ssid;
|
||||
addLog(LOG_LEVEL_INFO, reconnectlog);
|
||||
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
|
||||
String reconnectlog = F("WIFI : Credentials Changed, retry connection. SSID: ");
|
||||
reconnectlog += ssid;
|
||||
addLog(LOG_LEVEL_INFO, reconnectlog);
|
||||
}
|
||||
status = 1;
|
||||
refreshCount = 0;
|
||||
}
|
||||
@@ -5222,15 +5251,15 @@ void handle_sysinfo() {
|
||||
addHelpButton(F("https://dl.espressif.com/doc/esp-idf/latest/api-guides/partition-tables.html"));
|
||||
TXBuffer += F("</H3></TD></TR>");
|
||||
|
||||
TXBuffer += F("<TR><TD>Data Partition Table<TD><tt>");
|
||||
TXBuffer += getPartitionTableHeader(F(" - "), F("<BR>"));
|
||||
TXBuffer += getPartitionTable(ESP_PARTITION_TYPE_DATA, F(" - "), F("<BR>"));
|
||||
TXBuffer += F("</tt>");
|
||||
TXBuffer += F("<TR><TD>Data Partition Table<TD>");
|
||||
// TXBuffer += getPartitionTableHeader(F(" - "), F("<BR>"));
|
||||
// TXBuffer += getPartitionTable(ESP_PARTITION_TYPE_DATA, F(" - "), F("<BR>"));
|
||||
getPartitionTableSVG(ESP_PARTITION_TYPE_DATA, 0x5856e6);
|
||||
|
||||
TXBuffer += F("<TR><TD>App Partition Table<TD><tt>");
|
||||
TXBuffer += getPartitionTableHeader(F(" - "), F("<BR>"));
|
||||
TXBuffer += getPartitionTable(ESP_PARTITION_TYPE_APP , F(" - "), F("<BR>"));
|
||||
TXBuffer += F("</tt>");
|
||||
TXBuffer += F("<TR><TD>App Partition Table<TD>");
|
||||
// TXBuffer += getPartitionTableHeader(F(" - "), F("<BR>"));
|
||||
// TXBuffer += getPartitionTable(ESP_PARTITION_TYPE_APP , F(" - "), F("<BR>"));
|
||||
getPartitionTableSVG(ESP_PARTITION_TYPE_APP, 0xab56e6);
|
||||
#endif
|
||||
|
||||
TXBuffer += F("</table></form>");
|
||||
@@ -5286,3 +5315,88 @@ void handle_favicon() {
|
||||
checkRAM(F("handle_favicon"));
|
||||
WebServer.send_P(200, PSTR("image/x-icon"), favicon_8b_ico, favicon_8b_ico_len);
|
||||
}
|
||||
|
||||
#ifdef ESP32
|
||||
|
||||
void createSvgRectPath(unsigned int color, int xoffset, int yoffset, int size, int height, int range, float svgBarWidth) {
|
||||
float width = svgBarWidth * size / range;
|
||||
if (width < 2) width = 2;
|
||||
TXBuffer += formatToHex(color, F("<path fill=\"#"));
|
||||
TXBuffer += F("\" d=\"M");
|
||||
TXBuffer += toString(svgBarWidth * xoffset / range, 2);
|
||||
TXBuffer += ' ';
|
||||
TXBuffer += yoffset;
|
||||
TXBuffer += 'h';
|
||||
TXBuffer += toString(width, 2);
|
||||
TXBuffer += 'v';
|
||||
TXBuffer += height;
|
||||
TXBuffer += 'H';
|
||||
TXBuffer += toString(svgBarWidth * xoffset / range, 2);
|
||||
TXBuffer += F("z\"/>\n");
|
||||
}
|
||||
|
||||
int getPartionCount(byte pType) {
|
||||
esp_partition_type_t partitionType = static_cast<esp_partition_type_t>(pType);
|
||||
esp_partition_iterator_t _mypartiterator = esp_partition_find(partitionType, ESP_PARTITION_SUBTYPE_ANY, NULL);
|
||||
int nrPartitions = 0;
|
||||
if (_mypartiterator) {
|
||||
do {
|
||||
++nrPartitions;
|
||||
} while ((_mypartiterator = esp_partition_next(_mypartiterator)) != NULL);
|
||||
}
|
||||
esp_partition_iterator_release(_mypartiterator);
|
||||
return nrPartitions;
|
||||
}
|
||||
|
||||
void createSvgTextElement(const String& text, float textXoffset, float textYoffset) {
|
||||
TXBuffer += F("<text style=\"line-height:1.25\" x=\"");
|
||||
TXBuffer += toString(textXoffset, 2);
|
||||
TXBuffer += F("\" y=\"");
|
||||
TXBuffer += toString(textYoffset, 2);
|
||||
TXBuffer += F("\" stroke-width=\".3\" font-family=\"sans-serif\" font-size=\"8\" letter-spacing=\"0\" word-spacing=\"0\">\n");
|
||||
TXBuffer += F("<tspan x=\"");
|
||||
TXBuffer += toString(textXoffset, 2);
|
||||
TXBuffer += F("\" y=\"");
|
||||
TXBuffer += toString(textYoffset, 2);
|
||||
TXBuffer += F("\">");
|
||||
TXBuffer += text;
|
||||
TXBuffer += F("</tspan>\n</text>");
|
||||
}
|
||||
|
||||
void getPartitionTableSVG(byte pType, unsigned int partitionColor) {
|
||||
int nrPartitions = getPartionCount(pType);
|
||||
if (nrPartitions == 0) return;
|
||||
|
||||
const int barHeight = 16;
|
||||
const int svgBarWidth = 200;
|
||||
const int shiftY = 2;
|
||||
|
||||
uint32_t realSize = getFlashRealSizeInBytes();
|
||||
esp_partition_type_t partitionType = static_cast<esp_partition_type_t>(pType);
|
||||
const esp_partition_t * _mypart;
|
||||
esp_partition_iterator_t _mypartiterator = esp_partition_find(partitionType, ESP_PARTITION_SUBTYPE_ANY, NULL);
|
||||
TXBuffer += F("<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"500\" height=\"");
|
||||
TXBuffer += nrPartitions * barHeight + shiftY;
|
||||
TXBuffer += F("\">");
|
||||
int partNr = 0;
|
||||
if (_mypartiterator) {
|
||||
do {
|
||||
_mypart = esp_partition_get(_mypartiterator);
|
||||
float yOffset = partNr * barHeight + shiftY;
|
||||
createSvgRectPath(0xcdcdcd, 0, yOffset, realSize, barHeight - 2, realSize, svgBarWidth);
|
||||
createSvgRectPath(partitionColor, _mypart->address, yOffset, _mypart->size, barHeight - 2, realSize, svgBarWidth);
|
||||
float textXoffset = svgBarWidth + 2;
|
||||
float textYoffset = yOffset + 0.9 * barHeight;
|
||||
createSvgTextElement(formatHumanReadable(_mypart->size, 1024), textXoffset, textYoffset);
|
||||
textXoffset = svgBarWidth + 60;
|
||||
createSvgTextElement(_mypart->label, textXoffset, textYoffset);
|
||||
textXoffset = svgBarWidth + 130;
|
||||
createSvgTextElement(getPartitionType(_mypart->type, _mypart->subtype), textXoffset, textYoffset);
|
||||
++partNr;
|
||||
} while ((_mypartiterator = esp_partition_next(_mypartiterator)) != NULL);
|
||||
}
|
||||
TXBuffer += F("</svg>\n");
|
||||
esp_partition_iterator_release(_mypartiterator);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
+18
-26
@@ -255,6 +255,7 @@ static const char pgDefaultCSS[] PROGMEM = {
|
||||
".div_br {clear: both; }"
|
||||
// The alert message box
|
||||
".alert {padding: 20px; background-color: #f44336; color: white; margin-bottom: 15px; }"
|
||||
".warning {padding: 20px; background-color: #ffca17; color: white; margin-bottom: 15px; }"
|
||||
// The close button
|
||||
".closebtn {margin-left: 15px; color: white; font-weight: bold; float: right; font-size: 22px; line-height: 20px; cursor: pointer; transition: 0.3s; }"
|
||||
// When moving the mouse over the close button
|
||||
@@ -463,11 +464,11 @@ static const char jsFetchAndParseLog[] PROGMEM = {
|
||||
"textToDisplay = 'Fetching log entries...';"
|
||||
"}"
|
||||
"document.getElementById('copyText_1').innerHTML = textToDisplay;"
|
||||
"loopDeLoop(1000, 0, 0);"
|
||||
"loopDeLoop(1000, 0);"
|
||||
|
||||
"const logLevel = new Array('Unused','Error','Info','Debug','Debug More','Undefined','Undefined','Undefined','Undefined','Debug Dev');"
|
||||
|
||||
"function loopDeLoop(timeForNext, activeRequests, reRunCount) {"
|
||||
"function loopDeLoop(timeForNext, activeRequests) {"
|
||||
"const maximumRequests = 1;"
|
||||
"const url = '/logjson';"
|
||||
"if (isNaN(activeRequests)){activeRequests = maximumRequests;}"
|
||||
@@ -504,7 +505,7 @@ static const char jsFetchAndParseLog[] PROGMEM = {
|
||||
"if (logEntriesChunk == null) {"
|
||||
"logEntriesChunk = '';"
|
||||
"}"
|
||||
"for (c = 0; c < data.Log.nrEntries + 1; c++) {"
|
||||
"for (c = 0; c < data.Log.nrEntries; ++c) {"
|
||||
"try {"
|
||||
"logEntry = data.Log.Entries[c].timestamp;"
|
||||
"} catch (err) {"
|
||||
@@ -517,32 +518,23 @@ static const char jsFetchAndParseLog[] PROGMEM = {
|
||||
"}"
|
||||
"}"
|
||||
"timeForNext = data.Log.TTL;"
|
||||
"if (timeForNext < 1000) {"
|
||||
"reRunCount++;"
|
||||
"} else {"
|
||||
"reRunCount = 3;"
|
||||
"}"
|
||||
//"console.log(reRunCount + ' : ' + logEntriesChunk.length);"
|
||||
"if (reRunCount > 2) {"
|
||||
"if (logEntriesChunk !== '') {"
|
||||
"if (document.getElementById('copyText_1').innerHTML == 'Fetching log entries...') {"
|
||||
"document.getElementById('copyText_1').innerHTML = '';"
|
||||
"}"
|
||||
"document.getElementById('copyText_1').innerHTML += logEntriesChunk;"
|
||||
"}"
|
||||
"logEntriesChunk = '';"
|
||||
"reRunCount = 0;"
|
||||
"autoscroll_on = document.getElementById('autoscroll').checked;"
|
||||
"if (autoscroll_on == true && currentIDtoScrollTo !== '') {"
|
||||
"document.getElementById(currentIDtoScrollTo).scrollIntoView({"
|
||||
"behavior: scrolling_type"
|
||||
"});"
|
||||
"}"
|
||||
"if (logEntriesChunk !== '') {"
|
||||
"if (document.getElementById('copyText_1').innerHTML == 'Fetching log entries...') {"
|
||||
"document.getElementById('copyText_1').innerHTML = '';"
|
||||
"}"
|
||||
"document.getElementById('copyText_1').innerHTML += logEntriesChunk;"
|
||||
"}"
|
||||
"logEntriesChunk = '';"
|
||||
"autoscroll_on = document.getElementById('autoscroll').checked;"
|
||||
"if (autoscroll_on == true && currentIDtoScrollTo !== '') {"
|
||||
"document.getElementById(currentIDtoScrollTo).scrollIntoView({"
|
||||
"behavior: scrolling_type"
|
||||
"});"
|
||||
"}"
|
||||
"document.getElementById('current_loglevel').innerHTML = 'Logging: ' + logLevel[data.Log.SettingsWebLogLevel] + ' (' + data.Log.SettingsWebLogLevel + ')';"
|
||||
//"console.log('Next fetch in: ' + timeForNext + 'mSec, active requests: ' + activeRequests);"
|
||||
"clearInterval(i);"
|
||||
"loopDeLoop(timeForNext, 0, reRunCount);"
|
||||
"loopDeLoop(timeForNext, 0);"
|
||||
"return;"
|
||||
"})"
|
||||
"})"
|
||||
@@ -552,7 +544,7 @@ static const char jsFetchAndParseLog[] PROGMEM = {
|
||||
"document.getElementById('copyText_1').scrollTop = document.getElementById('copyText_1').scrollHeight;"
|
||||
"timeForNext = 5000;"
|
||||
"clearInterval(i);"
|
||||
"loopDeLoop(timeForNext, 0, 0);"
|
||||
"loopDeLoop(timeForNext, 0);"
|
||||
"return;"
|
||||
"})};"
|
||||
"check = 1;"
|
||||
|
||||
+16
-8
@@ -59,8 +59,10 @@ boolean CPlugin_004(byte function, struct EventStruct *event, String& string)
|
||||
if (!ControllerSettings.connectToHost(client))
|
||||
{
|
||||
connectionFailures++;
|
||||
strcpy_P(log, PSTR("HTTP : connection failed"));
|
||||
addLog(LOG_LEVEL_ERROR, log);
|
||||
if (loglevelActiveFor(LOG_LEVEL_ERROR)) {
|
||||
strcpy_P(log, PSTR("HTTP : connection failed"));
|
||||
addLog(LOG_LEVEL_ERROR, log);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
statusLED(true);
|
||||
@@ -107,18 +109,24 @@ boolean CPlugin_004(byte function, struct EventStruct *event, String& string)
|
||||
String line;
|
||||
safeReadStringUntil(client, line, '\n');
|
||||
|
||||
line.toCharArray(log, 80);
|
||||
addLog(LOG_LEVEL_DEBUG_MORE, log);
|
||||
if (loglevelActiveFor(LOG_LEVEL_DEBUG_MORE)) {
|
||||
line.toCharArray(log, 80);
|
||||
addLog(LOG_LEVEL_DEBUG_MORE, log);
|
||||
}
|
||||
if (line.substring(0, 15) == F("HTTP/1.1 200 OK"))
|
||||
{
|
||||
strcpy_P(log, PSTR("HTTP : Success!"));
|
||||
addLog(LOG_LEVEL_DEBUG, log);
|
||||
if (loglevelActiveFor(LOG_LEVEL_DEBUG)) {
|
||||
strcpy_P(log, PSTR("HTTP : Success!"));
|
||||
addLog(LOG_LEVEL_DEBUG, log);
|
||||
}
|
||||
success = true;
|
||||
}
|
||||
delay(1);
|
||||
}
|
||||
strcpy_P(log, PSTR("HTTP : closing connection"));
|
||||
addLog(LOG_LEVEL_DEBUG, log);
|
||||
if (loglevelActiveFor(LOG_LEVEL_DEBUG)) {
|
||||
strcpy_P(log, PSTR("HTTP : closing connection"));
|
||||
addLog(LOG_LEVEL_DEBUG, log);
|
||||
}
|
||||
|
||||
client.flush();
|
||||
client.stop();
|
||||
|
||||
+4
-2
@@ -102,8 +102,10 @@ boolean CPlugin_007(byte function, struct EventStruct *event, String& string)
|
||||
String line;
|
||||
safeReadStringUntil(client, line, '\n');
|
||||
|
||||
line.toCharArray(log, 80);
|
||||
addLog(LOG_LEVEL_DEBUG_MORE, log);
|
||||
if (loglevelActiveFor(LOG_LEVEL_DEBUG_MORE)) {
|
||||
line.toCharArray(log, 80);
|
||||
addLog(LOG_LEVEL_DEBUG_MORE, log);
|
||||
}
|
||||
if (line.substring(0, 15) == F("HTTP/1.1 200 OK"))
|
||||
{
|
||||
strcpy_P(log, PSTR("HTTP : Success!"));
|
||||
|
||||
+1
-1
@@ -100,7 +100,7 @@ boolean CPlugin_009(byte function, struct EventStruct *event, String& string)
|
||||
// Each sensor value get an own object (0..n)
|
||||
// sprintf(itemNames[x],"%d",x);
|
||||
JsonObject& val = SENSOR.createNestedObject(String(x));
|
||||
val[F("deviceName")] = ExtraTaskSettings.TaskDeviceName;
|
||||
val[F("deviceName")] = getTaskDeviceName(event->TaskIndex);
|
||||
val[F("valueName")] = ExtraTaskSettings.TaskDeviceValueNames[x];
|
||||
val[F("type")] = event->sensorType;
|
||||
val[F("value")] = formatUserVarNoCheck(event, x);
|
||||
|
||||
+5
-4
@@ -71,7 +71,6 @@ void C010_Send(struct EventStruct *event, byte varIndex, const String& formatted
|
||||
ControllerSettingsStruct ControllerSettings;
|
||||
LoadControllerSettings(event->ControllerIndex, (byte*)&ControllerSettings, sizeof(ControllerSettings));
|
||||
|
||||
char log[80];
|
||||
// boolean success = false;
|
||||
addLog(LOG_LEVEL_DEBUG, String(F("UDP : sending to ")) + ControllerSettings.getHostPortString());
|
||||
statusLED(true);
|
||||
@@ -91,8 +90,10 @@ void C010_Send(struct EventStruct *event, byte varIndex, const String& formatted
|
||||
portUDP.endPacket();
|
||||
}
|
||||
|
||||
msg.toCharArray(log, 80);
|
||||
addLog(LOG_LEVEL_DEBUG_MORE, log);
|
||||
|
||||
if (loglevelActiveFor(LOG_LEVEL_DEBUG_MORE)) {
|
||||
char log[80];
|
||||
msg.toCharArray(log, 80);
|
||||
addLog(LOG_LEVEL_DEBUG_MORE, log);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
+17
-12
@@ -117,7 +117,7 @@ void C013_SendUDPTaskInfo(byte destUnit, byte sourceTaskIndex, byte destTaskInde
|
||||
infoReply.destTaskIndex = destTaskIndex;
|
||||
LoadTaskSettings(infoReply.sourceTaskIndex);
|
||||
infoReply.deviceNumber = Settings.TaskDeviceNumber[infoReply.sourceTaskIndex];
|
||||
strcpy(infoReply.taskName, ExtraTaskSettings.TaskDeviceName);
|
||||
strcpy(infoReply.taskName, getTaskDeviceName(infoReply.sourceTaskIndex).c_str());
|
||||
for (byte x = 0; x < VARS_PER_TASK; x++)
|
||||
strcpy(infoReply.ValueNames[x], ExtraTaskSettings.TaskDeviceValueNames[x]);
|
||||
|
||||
@@ -180,9 +180,11 @@ void C013_sendUDP(byte unit, byte* data, byte size)
|
||||
if (unit != 255)
|
||||
if (Nodes[unit].ip[0] == 0)
|
||||
return;
|
||||
String log = F("C013 : Send UDP message to ");
|
||||
log += unit;
|
||||
addLog(LOG_LEVEL_DEBUG_MORE, log);
|
||||
if (loglevelActiveFor(LOG_LEVEL_DEBUG_MORE)) {
|
||||
String log = F("C013 : Send UDP message to ");
|
||||
log += unit;
|
||||
addLog(LOG_LEVEL_DEBUG_MORE, log);
|
||||
}
|
||||
|
||||
statusLED(true);
|
||||
|
||||
@@ -197,16 +199,17 @@ void C013_sendUDP(byte unit, byte* data, byte size)
|
||||
}
|
||||
|
||||
void C013_Receive(struct EventStruct *event) {
|
||||
|
||||
if (event->Data[1] > 1 && event->Data[1] < 6)
|
||||
{
|
||||
String log = (F("C013 : msg "));
|
||||
for (byte x = 1; x < 6; x++)
|
||||
if (loglevelActiveFor(LOG_LEVEL_DEBUG_MORE)) {
|
||||
if (event->Data[1] > 1 && event->Data[1] < 6)
|
||||
{
|
||||
log += " ";
|
||||
log += (int)event->Data[x];
|
||||
String log = (F("C013 : msg "));
|
||||
for (byte x = 1; x < 6; x++)
|
||||
{
|
||||
log += " ";
|
||||
log += (int)event->Data[x];
|
||||
}
|
||||
addLog(LOG_LEVEL_DEBUG_MORE, log);
|
||||
}
|
||||
addLog(LOG_LEVEL_DEBUG_MORE, log);
|
||||
}
|
||||
|
||||
switch (event->Data[1]) {
|
||||
@@ -225,6 +228,7 @@ void C013_Receive(struct EventStruct *event) {
|
||||
// so it will write only once and has to be cleared manually through webgui
|
||||
if (Settings.TaskDeviceNumber[infoReply.destTaskIndex] == 0)
|
||||
{
|
||||
taskClear(infoReply.destTaskIndex, false);
|
||||
Settings.TaskDeviceNumber[infoReply.destTaskIndex] = infoReply.deviceNumber;
|
||||
Settings.TaskDeviceDataFeed[infoReply.destTaskIndex] = 1; // remote feed
|
||||
for (byte x = 0; x < CONTROLLER_MAX; x++)
|
||||
@@ -232,6 +236,7 @@ void C013_Receive(struct EventStruct *event) {
|
||||
strcpy(ExtraTaskSettings.TaskDeviceName, infoReply.taskName);
|
||||
for (byte x = 0; x < VARS_PER_TASK; x++)
|
||||
strcpy( ExtraTaskSettings.TaskDeviceValueNames[x], infoReply.ValueNames[x]);
|
||||
ExtraTaskSettings.TaskIndex = infoReply.destTaskIndex;
|
||||
SaveTaskSettings(infoReply.destTaskIndex);
|
||||
SaveSettings();
|
||||
}
|
||||
|
||||
+12
-6
@@ -141,10 +141,12 @@ boolean Plugin_001(byte function, struct EventStruct *event, String& string)
|
||||
String device = parseString(string, 1);
|
||||
String command = parseString(string, 2);
|
||||
String strPar1 = parseString(string, 3);
|
||||
int par1 = strPar1.toInt();
|
||||
if (device == F("gpio") && command == F("pinstate"))
|
||||
{
|
||||
string = digitalRead(par1);
|
||||
int par1;
|
||||
if (validIntFromString(strPar1, par1)) {
|
||||
string = digitalRead(par1);
|
||||
}
|
||||
success = true;
|
||||
}
|
||||
break;
|
||||
@@ -324,11 +326,15 @@ boolean Plugin_001(byte function, struct EventStruct *event, String& string)
|
||||
success = true;
|
||||
if (event->Par1 >= 0 && event->Par1 <= PIN_D_MAX)
|
||||
{
|
||||
const bool pinStateHigh = event->Par2 != 0;
|
||||
const uint16_t pinStateValue = pinStateHigh ? 1 : 0;
|
||||
const uint16_t inversePinStateValue = pinStateHigh ? 0 : 1;
|
||||
pinMode(event->Par1, OUTPUT);
|
||||
digitalWrite(event->Par1, event->Par2);
|
||||
setPinState(PLUGIN_ID_001, event->Par1, PIN_MODE_OUTPUT, event->Par2);
|
||||
setSystemTimer(time_in_msec ? event->Par3 : event->Par3 * 1000,
|
||||
PLUGIN_ID_001, event->Par1, !event->Par2, 0);
|
||||
digitalWrite(event->Par1, pinStateValue);
|
||||
setPinState(PLUGIN_ID_001, event->Par1, PIN_MODE_OUTPUT, pinStateValue);
|
||||
unsigned long timer = time_in_msec ? event->Par3 : event->Par3 * 1000;
|
||||
// Create a future system timer call to set the GPIO pin back to its normal value.
|
||||
setSystemTimer(timer, PLUGIN_ID_001, event->TaskIndex, event->Par1, inversePinStateValue);
|
||||
log = String(F("SW : GPIO ")) + String(event->Par1) +
|
||||
String(F(" Pulse set for ")) + String(event->Par3) + String(time_in_msec ? F(" msec") : F(" sec"));
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
|
||||
+1
-1
@@ -146,7 +146,7 @@ boolean Plugin_009(byte function, struct EventStruct *event, String& string)
|
||||
{
|
||||
Plugin_009_Write(event->Par1, event->Par2);
|
||||
setPinState(PLUGIN_ID_009, event->Par1, PIN_MODE_OUTPUT, event->Par2);
|
||||
setSystemTimer(event->Par3 * 1000, PLUGIN_ID_009, event->Par1, !event->Par2, 0);
|
||||
setSystemTimer(event->Par3 * 1000, PLUGIN_ID_009, event->TaskIndex, event->Par1, !event->Par2);
|
||||
log = String(F("MCP : GPIO ")) + String(event->Par1) + String(F(" Pulse set for ")) + String(event->Par3) + String(F(" S"));
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
SendStatus(event->Source, getPinStateJSON(SEARCH_PIN_STATE, PLUGIN_ID_009, event->Par1, log, 0));
|
||||
|
||||
+1
-1
@@ -123,7 +123,7 @@ boolean Plugin_011(byte function, struct EventStruct *event, String& string)
|
||||
if (event->Par1 >= 0 && event->Par1 <= 13)
|
||||
{
|
||||
Plugin_011_Write(event->Par1, event->Par2);
|
||||
setSystemTimer(event->Par3 * 1000, PLUGIN_ID_011, event->Par1, !event->Par2, 0);
|
||||
setSystemTimer(event->Par3 * 1000, PLUGIN_ID_011, event->TaskIndex, event->Par1, !event->Par2);
|
||||
setPinState(PLUGIN_ID_011, event->Par1, PIN_MODE_OUTPUT, event->Par2);
|
||||
log = String(F("PME : GPIO ")) + String(event->Par1) + String(F(" Pulse set for ")) + String(event->Par3) + String(F(" S"));
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
|
||||
+25
-1
@@ -27,6 +27,7 @@
|
||||
#define PN532_COMMAND_INLISTPASSIVETARGET (0x4A)
|
||||
#define PN532_RESPONSE_INLISTPASSIVETARGET (0x4B)
|
||||
#define PN532_MIFARE_ISO14443A (0x00)
|
||||
#define PN532_COMMAND_POWERDOWN (0x16)
|
||||
|
||||
uint8_t Plugin_017_pn532_packetbuffer[64];
|
||||
uint8_t Plugin_017_command;
|
||||
@@ -95,7 +96,7 @@ boolean Plugin_017(byte function, struct EventStruct *event, String& string)
|
||||
static byte errorCount=0;
|
||||
|
||||
counter++;
|
||||
if (counter == 3)
|
||||
if (counter == 3 )
|
||||
{
|
||||
if (digitalRead(4) == 0 || digitalRead(5) == 0)
|
||||
{
|
||||
@@ -123,6 +124,7 @@ boolean Plugin_017(byte function, struct EventStruct *event, String& string)
|
||||
Plugin_017_Init(Settings.TaskDevicePin3[event->TaskIndex]);
|
||||
}
|
||||
|
||||
|
||||
if (error == 0) {
|
||||
unsigned long key = uid[0];
|
||||
for (uint8_t i = 1; i < 4; i++) {
|
||||
@@ -232,6 +234,23 @@ uint32_t getFirmwareVersion(void)
|
||||
}
|
||||
|
||||
|
||||
void Plugin_017_powerDown(void)
|
||||
{
|
||||
|
||||
Plugin_017_pn532_packetbuffer[0] = PN532_COMMAND_POWERDOWN;
|
||||
Plugin_017_pn532_packetbuffer[1] = 1 << 7; //allowed wakeup source is i2c
|
||||
|
||||
if (Plugin_017_writeCommand(Plugin_017_pn532_packetbuffer, 2)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// delay(50); // we can try to read faster, but it will only put extra load on the I2C bus...
|
||||
|
||||
// read and ignore response
|
||||
Plugin_017_readResponse(Plugin_017_pn532_packetbuffer, sizeof(Plugin_017_pn532_packetbuffer));
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************************************\
|
||||
* PN532 read tag
|
||||
\*********************************************************************************************/
|
||||
@@ -273,6 +292,10 @@ byte Plugin_017_readPassiveTargetID(uint8_t cardbaudrate, uint8_t *uid, uint8_t
|
||||
uid[i] = Plugin_017_pn532_packetbuffer[6 + i];
|
||||
}
|
||||
|
||||
// Plugin_017_Init(-1);
|
||||
Plugin_017_powerDown();
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -325,6 +348,7 @@ int16_t Plugin_017_readResponse(uint8_t buf[], uint8_t len)
|
||||
if (!Wire.requestFrom(PN532_I2C_ADDRESS, len + 2))
|
||||
return -1;
|
||||
|
||||
|
||||
if (!(Wire.read() & 1))
|
||||
return -1;
|
||||
|
||||
|
||||
@@ -145,7 +145,7 @@ boolean Plugin_019(byte function, struct EventStruct *event, String& string)
|
||||
success = true;
|
||||
Plugin_019_Write(event->Par1, event->Par2);
|
||||
setPinState(PLUGIN_ID_019, event->Par1, PIN_MODE_OUTPUT, event->Par2);
|
||||
setSystemTimer(event->Par3 * 1000, PLUGIN_ID_019, event->Par1, !event->Par2, 0);
|
||||
setSystemTimer(event->Par3 * 1000, PLUGIN_ID_019, event->TaskIndex, event->Par1, !event->Par2);
|
||||
log = String(F("PCF : GPIO ")) + String(event->Par1) + String(F(" Pulse set for ")) + String(event->Par3) + String(F(" S"));
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
SendStatus(event->Source, getPinStateJSON(SEARCH_PIN_STATE, PLUGIN_ID_019, event->Par1, log, 0));
|
||||
|
||||
+12
-12
@@ -23,12 +23,12 @@
|
||||
#define PCA9685_ALLLED_REG (byte)0xFA
|
||||
|
||||
/*
|
||||
is bit flag any bit rapresent the initialization state of PCA9685
|
||||
is bit flag any bit rapresent the initialization state of PCA9685
|
||||
es: bit 3 is set 1 PCA9685 with address 0X40 + 0x03 is intin
|
||||
*/
|
||||
#define IS_INIT(state, bit) ((state & 1 << bit) == 1 << bit)
|
||||
#define SET_INIT(state, bit) (state|= 1 << bit)
|
||||
long long initializeState; //
|
||||
long long initializeState; //
|
||||
|
||||
boolean Plugin_022(byte function, struct EventStruct *event, String& string)
|
||||
{
|
||||
@@ -85,7 +85,7 @@ boolean Plugin_022(byte function, struct EventStruct *event, String& string)
|
||||
Settings.TaskDevicePort[event->TaskIndex] = getFormItemInt(F("i2c_addr"));
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
case PLUGIN_WRITE:
|
||||
{
|
||||
@@ -100,7 +100,7 @@ boolean Plugin_022(byte function, struct EventStruct *event, String& string)
|
||||
String name = line.substring(0,dotPos);
|
||||
name.replace(F("["),F(""));
|
||||
name.replace(F("]"),F(""));
|
||||
if(name.equalsIgnoreCase(ExtraTaskSettings.TaskDeviceName) == true)
|
||||
if(name.equalsIgnoreCase(getTaskDeviceName(event->TaskIndex)) == true)
|
||||
{
|
||||
line = line.substring(dotPos + 1);
|
||||
istanceCommand = true;
|
||||
@@ -121,7 +121,7 @@ boolean Plugin_022(byte function, struct EventStruct *event, String& string)
|
||||
if(event->Par2 >=0 && event->Par2 <= PCA9685_MAX_PWM)
|
||||
{
|
||||
if (!IS_INIT(initializeState, (address - PCA9685_ADDRESS))) Plugin_022_initialize(address);
|
||||
|
||||
|
||||
Plugin_022_Write(address, event->Par1, event->Par2);
|
||||
setPinState(PLUGIN_ID_022, event->Par1, PIN_MODE_PWM, event->Par2);
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
@@ -139,7 +139,7 @@ boolean Plugin_022(byte function, struct EventStruct *event, String& string)
|
||||
{
|
||||
success = true;
|
||||
if(event->Par1 >= PCA9685_MIN_FREQUENCY && event->Par1 <= PCA9685_MAX_FREQUENCY)
|
||||
{
|
||||
{
|
||||
if (!IS_INIT(initializeState, (address - PCA9685_ADDRESS))) Plugin_022_initialize(address);
|
||||
|
||||
Plugin_022_Frequency(address, event->Par1);
|
||||
@@ -150,7 +150,7 @@ boolean Plugin_022(byte function, struct EventStruct *event, String& string)
|
||||
}
|
||||
else{
|
||||
addLog(LOG_LEVEL_ERROR,String(F("PCA ")) + String(address, HEX) + String(F(" The frequesncy ")) + String(event->Par1) + String(F(" is out of range.")));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -175,7 +175,7 @@ boolean Plugin_022(byte function, struct EventStruct *event, String& string)
|
||||
if(parseString(line,2) == "all")
|
||||
{
|
||||
pin = -1;
|
||||
log += String(F("all"));
|
||||
log += String(F("all"));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -189,10 +189,10 @@ boolean Plugin_022(byte function, struct EventStruct *event, String& string)
|
||||
else
|
||||
{
|
||||
log += F(" on");
|
||||
Plugin_022_On(address, pin);
|
||||
Plugin_022_On(address, pin);
|
||||
}
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
setPinState(PLUGIN_ID_022, pin, PIN_MODE_OUTPUT, event->Par2);
|
||||
setPinState(PLUGIN_ID_022, pin, PIN_MODE_OUTPUT, event->Par2);
|
||||
SendStatus(event->Source, getPinStateJSON(SEARCH_PIN_STATE, PLUGIN_ID_022, pin, log, 0));
|
||||
}
|
||||
else{
|
||||
@@ -237,7 +237,7 @@ boolean Plugin_022(byte function, struct EventStruct *event, String& string)
|
||||
log += String(autoreset);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
setSystemTimer(event->Par3 , PLUGIN_ID_022
|
||||
, event->TaskIndex
|
||||
@@ -286,7 +286,7 @@ boolean Plugin_022(byte function, struct EventStruct *event, String& string)
|
||||
, autoreset);
|
||||
}
|
||||
setPinState(PLUGIN_ID_022, event->Par1, PIN_MODE_OUTPUT, event->Par2);
|
||||
SendStatus(event->Source, getPinStateJSON(SEARCH_PIN_STATE, PLUGIN_ID_022, event->Par1, log, 0));
|
||||
SendStatus(event->Source, getPinStateJSON(SEARCH_PIN_STATE, PLUGIN_ID_022, event->Par1, log, 0));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
+4
-4
@@ -235,7 +235,7 @@ boolean Plugin_023(byte function, struct EventStruct *event, String& string)
|
||||
String name = arguments.substring(0,dotPos);
|
||||
name.replace(F("["),F(""));
|
||||
name.replace(F("]"),F(""));
|
||||
if(name.equalsIgnoreCase(ExtraTaskSettings.TaskDeviceName) == true)
|
||||
if(name.equalsIgnoreCase(getTaskDeviceName(event->TaskIndex)) == true)
|
||||
{
|
||||
arguments = arguments.substring(dotPos+1);
|
||||
}
|
||||
@@ -244,7 +244,7 @@ boolean Plugin_023(byte function, struct EventStruct *event, String& string)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int argIndex = arguments.indexOf(',');
|
||||
if (argIndex)
|
||||
arguments = arguments.substring(0, argIndex);
|
||||
@@ -492,7 +492,7 @@ void Plugin_023_reset_display(struct Plugin_023_OLED_SettingStruct &oled)
|
||||
|
||||
|
||||
void Plugin_023_StartUp_OLED(struct Plugin_023_OLED_SettingStruct &oled)
|
||||
{
|
||||
{
|
||||
Plugin_023_init_OLED(oled);
|
||||
Plugin_023_reset_display(oled);
|
||||
Plugin_023_displayOff(oled);
|
||||
@@ -644,7 +644,7 @@ void Plugin_023_init_OLED(struct Plugin_023_OLED_SettingStruct &oled)
|
||||
multiplex = 0x3F;
|
||||
compins = 0x12;
|
||||
}
|
||||
|
||||
|
||||
Plugin_023_sendcommand(address, 0xAE); //display off
|
||||
Plugin_023_sendcommand(address, 0xD5); //SETDISPLAYCLOCKDIV
|
||||
Plugin_023_sendcommand(address, 0x80); // the suggested ratio 0x80
|
||||
|
||||
+55
-39
@@ -312,26 +312,28 @@ boolean Plugin_028(byte function, struct EventStruct *event, String& string)
|
||||
} else {
|
||||
UserVar[event->BaseVarIndex + 2] = sensor.last_press_val;
|
||||
}
|
||||
String log;
|
||||
log.reserve(40); // Prevent re-allocation
|
||||
log = sensor.getDeviceName();
|
||||
log += F(" : Address: 0x");
|
||||
log += String(i2cAddress,HEX);
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
log = sensor.getDeviceName();
|
||||
log += F(" : Temperature: ");
|
||||
log += UserVar[event->BaseVarIndex];
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
if (sensor.hasHumidity()) {
|
||||
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
|
||||
String log;
|
||||
log.reserve(40); // Prevent re-allocation
|
||||
log = sensor.getDeviceName();
|
||||
log += F(" : Humidity: ");
|
||||
log += UserVar[event->BaseVarIndex + 1];
|
||||
log += F(" : Address: 0x");
|
||||
log += String(i2cAddress,HEX);
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
log = sensor.getDeviceName();
|
||||
log += F(" : Temperature: ");
|
||||
log += UserVar[event->BaseVarIndex];
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
if (sensor.hasHumidity()) {
|
||||
log = sensor.getDeviceName();
|
||||
log += F(" : Humidity: ");
|
||||
log += UserVar[event->BaseVarIndex + 1];
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
}
|
||||
log = sensor.getDeviceName();
|
||||
log += F(" : Barometric Pressure: ");
|
||||
log += UserVar[event->BaseVarIndex + 2];
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
}
|
||||
log = sensor.getDeviceName();
|
||||
log += F(" : Barometric Pressure: ");
|
||||
log += UserVar[event->BaseVarIndex + 2];
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
@@ -395,9 +397,11 @@ bool Plugin_028_update_measurements(const uint8_t i2cAddress, float tempOffset)
|
||||
|
||||
|
||||
String log;
|
||||
log.reserve(120); // Prevent re-allocation
|
||||
log = sensor.getDeviceName();
|
||||
log += F(":");
|
||||
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
|
||||
log.reserve(120); // Prevent re-allocation
|
||||
log = sensor.getDeviceName();
|
||||
log += F(":");
|
||||
}
|
||||
boolean logAdded = false;
|
||||
if (sensor.hasHumidity()) {
|
||||
// Apply half of the temp offset, to correct the dew point offset.
|
||||
@@ -409,34 +413,46 @@ bool Plugin_028_update_measurements(const uint8_t i2cAddress, float tempOffset)
|
||||
}
|
||||
if (tempOffset > 0.1 || tempOffset < -0.1) {
|
||||
// There is some offset to apply.
|
||||
log += F(" Apply temp offset ");
|
||||
log += tempOffset;
|
||||
log += F("C");
|
||||
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
|
||||
log += F(" Apply temp offset ");
|
||||
log += tempOffset;
|
||||
log += F("C");
|
||||
}
|
||||
if (sensor.hasHumidity()) {
|
||||
log += F(" humidity ");
|
||||
log += sensor.last_hum_val;
|
||||
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
|
||||
log += F(" humidity ");
|
||||
log += sensor.last_hum_val;
|
||||
}
|
||||
sensor.last_hum_val = compute_humidity_from_dewpoint(sensor.last_temp_val + tempOffset, sensor.last_dew_temp_val);
|
||||
log += F("% => ");
|
||||
log += sensor.last_hum_val;
|
||||
log += F("%");
|
||||
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
|
||||
log += F("% => ");
|
||||
log += sensor.last_hum_val;
|
||||
log += F("%");
|
||||
}
|
||||
} else {
|
||||
sensor.last_hum_val = 0.0;
|
||||
}
|
||||
log += F(" temperature ");
|
||||
log += sensor.last_temp_val;
|
||||
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
|
||||
log += F(" temperature ");
|
||||
log += sensor.last_temp_val;
|
||||
}
|
||||
sensor.last_temp_val = sensor.last_temp_val + tempOffset;
|
||||
log += F("C => ");
|
||||
log += sensor.last_temp_val;
|
||||
log += F("C");
|
||||
logAdded = true;
|
||||
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
|
||||
log += F("C => ");
|
||||
log += sensor.last_temp_val;
|
||||
log += F("C");
|
||||
logAdded = true;
|
||||
}
|
||||
}
|
||||
if (sensor.hasHumidity()) {
|
||||
log += F(" dew point ");
|
||||
log += sensor.last_dew_temp_val;
|
||||
log += F("C");
|
||||
logAdded = true;
|
||||
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
|
||||
log += F(" dew point ");
|
||||
log += sensor.last_dew_temp_val;
|
||||
log += F("C");
|
||||
logAdded = true;
|
||||
}
|
||||
}
|
||||
if (logAdded)
|
||||
if (logAdded && loglevelActiveFor(LOG_LEVEL_INFO))
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
return true;
|
||||
}
|
||||
|
||||
+10
-10
@@ -80,7 +80,7 @@ boolean Plugin_035(byte function, struct EventStruct *event, String& string)
|
||||
if (irReceiver != 0) irReceiver->disableIRIn(); // Stop the receiver
|
||||
#endif
|
||||
|
||||
if (GetArgv(command, TmpStr1, 2)) IrType = TmpStr1;
|
||||
if (GetArgv(command, TmpStr1, 100, 2)) IrType = TmpStr1;
|
||||
|
||||
if (IrType.equalsIgnoreCase(F("RAW"))) {
|
||||
String IrRaw;
|
||||
@@ -88,10 +88,10 @@ boolean Plugin_035(byte function, struct EventStruct *event, String& string)
|
||||
unsigned int IrPLen=0;
|
||||
unsigned int IrBLen=0;
|
||||
|
||||
if (GetArgv(command, TmpStr1, 3)) IrRaw = TmpStr1;
|
||||
if (GetArgv(command, TmpStr1, 4)) IrHz = str2int(TmpStr1);
|
||||
if (GetArgv(command, TmpStr1, 5)) IrPLen = str2int(TmpStr1);
|
||||
if (GetArgv(command, TmpStr1, 6)) IrBLen = str2int(TmpStr1);
|
||||
if (GetArgv(command, TmpStr1, 100, 3)) IrRaw = TmpStr1;
|
||||
if (GetArgv(command, TmpStr1, 100, 4)) IrHz = str2int(TmpStr1);
|
||||
if (GetArgv(command, TmpStr1, 100, 5)) IrPLen = str2int(TmpStr1);
|
||||
if (GetArgv(command, TmpStr1, 100, 6)) IrBLen = str2int(TmpStr1);
|
||||
|
||||
printWebString += F("<a href='https://en.wikipedia.org/wiki/Base32#base32hex'>Base32Hex</a> RAW Code: ");
|
||||
printWebString += IrRaw;
|
||||
@@ -200,11 +200,11 @@ boolean Plugin_035(byte function, struct EventStruct *event, String& string)
|
||||
unsigned int IrRepeat=0;
|
||||
unsigned long IrSecondCode=0UL;
|
||||
|
||||
if (GetArgv(command, TmpStr1, 2)) IrType = TmpStr1;
|
||||
if (GetArgv(command, TmpStr1, 3)) IrCode = strtoul(TmpStr1, NULL, 16); //(long) TmpStr1
|
||||
if (GetArgv(command, TmpStr1, 4)) IrBits = str2int(TmpStr1);
|
||||
if (GetArgv(command, TmpStr1, 5)) IrRepeat = str2int(TmpStr1);
|
||||
if (GetArgv(command, TmpStr1, 6)) IrSecondCode = strtoul(TmpStr1, NULL, 16);
|
||||
if (GetArgv(command, TmpStr1, 100, 2)) IrType = TmpStr1;
|
||||
if (GetArgv(command, TmpStr1, 100, 3)) IrCode = strtoul(TmpStr1, NULL, 16); //(long) TmpStr1
|
||||
if (GetArgv(command, TmpStr1, 100, 4)) IrBits = str2int(TmpStr1);
|
||||
if (GetArgv(command, TmpStr1, 100, 5)) IrRepeat = str2int(TmpStr1);
|
||||
if (GetArgv(command, TmpStr1, 100, 6)) IrSecondCode = strtoul(TmpStr1, NULL, 16);
|
||||
|
||||
if (IrType.equalsIgnoreCase(F("NEC"))) Plugin_035_irSender->sendNEC(IrCode, IrBits);
|
||||
if (IrType.equalsIgnoreCase(F("JVC"))) Plugin_035_irSender->sendJVC(IrCode, IrBits, 2);
|
||||
|
||||
@@ -168,7 +168,8 @@ boolean Plugin_036(byte function, struct EventStruct *event, String& string)
|
||||
case PLUGIN_WEBFORM_SAVE:
|
||||
{
|
||||
//update now
|
||||
timerSensor[event->TaskIndex] = millis() + (Settings.TaskDeviceTimer[event->TaskIndex] * 1000);
|
||||
schedule_task_device_timer(event->TaskIndex,
|
||||
millis() + (Settings.TaskDeviceTimer[event->TaskIndex] * 1000));
|
||||
frameCounter=0;
|
||||
|
||||
Settings.TaskDevicePluginConfig[event->TaskIndex][0] = getFormItemInt(F("plugin_036_adr"));
|
||||
|
||||
@@ -200,7 +200,7 @@ boolean Plugin_037(byte function, struct EventStruct *event, String& string)
|
||||
log = F("ERR : Illegal Payload ");
|
||||
log += Payload;
|
||||
log += " ";
|
||||
log += ExtraTaskSettings.TaskDeviceName;
|
||||
log += getTaskDeviceName(event->TaskIndex);
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
success = false;
|
||||
break;
|
||||
@@ -227,7 +227,7 @@ boolean Plugin_037(byte function, struct EventStruct *event, String& string)
|
||||
// Log the event
|
||||
|
||||
String log = F("IMPT : [");
|
||||
log += ExtraTaskSettings.TaskDeviceName;
|
||||
log += getTaskDeviceName(event->TaskIndex);
|
||||
log += F("#");
|
||||
log += ExtraTaskSettings.TaskDeviceValueNames[x];
|
||||
log += F("] : ");
|
||||
@@ -239,7 +239,7 @@ boolean Plugin_037(byte function, struct EventStruct *event, String& string)
|
||||
if (Settings.UseRules)
|
||||
{
|
||||
String RuleEvent = F("");
|
||||
RuleEvent += ExtraTaskSettings.TaskDeviceName;
|
||||
RuleEvent += getTaskDeviceName(event->TaskIndex);
|
||||
RuleEvent += F("#");
|
||||
RuleEvent += ExtraTaskSettings.TaskDeviceValueNames[x];
|
||||
RuleEvent += F("=");
|
||||
@@ -287,7 +287,7 @@ boolean MQTTSubscribe_037()
|
||||
{
|
||||
String log = F("IMPT : [");
|
||||
LoadTaskSettings(y);
|
||||
log += ExtraTaskSettings.TaskDeviceName;
|
||||
log += getTaskDeviceName(y);
|
||||
log += F("#");
|
||||
log += ExtraTaskSettings.TaskDeviceValueNames[x];
|
||||
log += F("] subscribed to ");
|
||||
|
||||
@@ -359,6 +359,7 @@ boolean Plugin_042(byte function, struct EventStruct *event, String& string)
|
||||
UserVar[event->BaseVarIndex + 2] = Candle_type;
|
||||
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case PLUGIN_WRITE:
|
||||
|
||||
@@ -317,7 +317,7 @@ boolean Plugin_044(byte function, struct EventStruct *event, String& string)
|
||||
if (Settings.UseRules)
|
||||
{
|
||||
LoadTaskSettings(event->TaskIndex);
|
||||
String eventString = ExtraTaskSettings.TaskDeviceName;
|
||||
String eventString = getTaskDeviceName(event->TaskIndex);
|
||||
eventString += F("#Data");
|
||||
rulesProcessing(eventString);
|
||||
}
|
||||
|
||||
@@ -98,21 +98,23 @@ boolean Plugin_048(byte function, struct EventStruct *event, String& string) {
|
||||
}
|
||||
|
||||
case PLUGIN_WRITE: {
|
||||
|
||||
String tmpString = string;
|
||||
|
||||
String cmd = parseString(tmpString, 1);
|
||||
String cmd = parseString(string, 1);
|
||||
|
||||
// Commands:
|
||||
// MotorShieldCMD,<DCMotor>,<Motornumber>,<Forward/Backward/Release>,<Speed>
|
||||
|
||||
if (cmd.equalsIgnoreCase(F("MotorShieldCMD")))
|
||||
{
|
||||
String param1 = parseString(tmpString, 2);
|
||||
String param2 = parseString(tmpString, 3);
|
||||
String param3 = parseString(tmpString, 4);
|
||||
String param4 = parseString(tmpString, 5);
|
||||
String param5 = parseString(tmpString, 6);
|
||||
String param1 = parseString(string, 2);
|
||||
String param2 = parseString(string, 3);
|
||||
String param3 = parseString(string, 4);
|
||||
String param4 = parseString(string, 5);
|
||||
String param5 = parseString(string, 6);
|
||||
|
||||
int p2_int;
|
||||
int p4_int;
|
||||
const bool param2_is_int = validIntFromString(param2, p2_int);
|
||||
const bool param4_is_int = validIntFromString(param4, p4_int);
|
||||
|
||||
// Create the motor shield object with the default I2C address
|
||||
AFMS = Adafruit_MotorShield(Plugin_048_MotorShield_address);
|
||||
@@ -121,15 +123,15 @@ boolean Plugin_048(byte function, struct EventStruct *event, String& string) {
|
||||
addLog(LOG_LEVEL_DEBUG, log);
|
||||
|
||||
if (param1.equalsIgnoreCase(F("DCMotor"))) {
|
||||
if (param2.toInt() > 0 && param2.toInt() < 5)
|
||||
if (param2_is_int && p2_int > 0 && p2_int < 5)
|
||||
{
|
||||
Adafruit_DCMotor *myMotor;
|
||||
myMotor = AFMS.getMotor(param2.toInt());
|
||||
myMotor = AFMS.getMotor(p2_int);
|
||||
if (param3.equalsIgnoreCase(F("Forward")))
|
||||
{
|
||||
byte speed = 255;
|
||||
if (param4.toInt() >= 0 && param4.toInt() <= 255)
|
||||
speed = param4.toInt();
|
||||
if (param4_is_int && p4_int >= 0 && p4_int <= 255)
|
||||
speed = p4_int;
|
||||
AFMS.begin();
|
||||
addLog(LOG_LEVEL_INFO, String(F("DCMotor")) + param2 + String(F("->Forward Speed: ")) + String(speed));
|
||||
myMotor->setSpeed(speed);
|
||||
@@ -139,8 +141,8 @@ boolean Plugin_048(byte function, struct EventStruct *event, String& string) {
|
||||
if (param3.equalsIgnoreCase(F("Backward")))
|
||||
{
|
||||
byte speed = 255;
|
||||
if (param4.toInt() >= 0 && param4.toInt() <= 255)
|
||||
speed = param4.toInt();
|
||||
if (param4_is_int && p4_int >= 0 && p4_int <= 255)
|
||||
speed = p4_int;
|
||||
AFMS.begin();
|
||||
addLog(LOG_LEVEL_INFO, String(F("DCMotor")) + param2 + String(F("->Backward Speed: ")) + String(speed));
|
||||
myMotor->setSpeed(speed);
|
||||
@@ -162,22 +164,24 @@ boolean Plugin_048(byte function, struct EventStruct *event, String& string) {
|
||||
{
|
||||
// Stepper# is which port it is connected to. If you're using M1 and M2, its port 1.
|
||||
// If you're using M3 and M4 indicate port 2
|
||||
if (param2.toInt() > 0 && param2.toInt() < 3)
|
||||
if (param2_is_int && p2_int > 0 && p2_int < 3)
|
||||
{
|
||||
Adafruit_StepperMotor *myStepper;
|
||||
myStepper = AFMS.getStepper(Plugin_048_MotorStepsPerRevolution, param2.toInt());
|
||||
myStepper = AFMS.getStepper(Plugin_048_MotorStepsPerRevolution, p2_int);
|
||||
myStepper->setSpeed(Plugin_048_StepperSpeed);
|
||||
String log = F("MotorShield: StepsPerRevolution: ");
|
||||
log += String(Plugin_048_MotorStepsPerRevolution);
|
||||
log += F(" Stepperspeed: ");
|
||||
log += String(Plugin_048_StepperSpeed);
|
||||
addLog(LOG_LEVEL_DEBUG_MORE, log);
|
||||
if (loglevelActiveFor(LOG_LEVEL_DEBUG_MORE)) {
|
||||
String log = F("MotorShield: StepsPerRevolution: ");
|
||||
log += String(Plugin_048_MotorStepsPerRevolution);
|
||||
log += F(" Stepperspeed: ");
|
||||
log += String(Plugin_048_StepperSpeed);
|
||||
addLog(LOG_LEVEL_DEBUG_MORE, log);
|
||||
}
|
||||
|
||||
if (param3.equalsIgnoreCase(F("Forward")))
|
||||
{
|
||||
if (param4.toInt())
|
||||
if (param4_is_int && p4_int != 0)
|
||||
{
|
||||
int steps = param4.toInt();
|
||||
int steps = p4_int;
|
||||
if (param5.equalsIgnoreCase(F("SINGLE")))
|
||||
{
|
||||
AFMS.begin();
|
||||
@@ -215,9 +219,9 @@ boolean Plugin_048(byte function, struct EventStruct *event, String& string) {
|
||||
|
||||
if (param3.equalsIgnoreCase(F("Backward")))
|
||||
{
|
||||
if (param4.toInt())
|
||||
if (param4_is_int && p4_int != 0)
|
||||
{
|
||||
int steps = param4.toInt();
|
||||
int steps = p4_int;
|
||||
if (param5.equalsIgnoreCase(F("SINGLE")))
|
||||
{
|
||||
AFMS.begin();
|
||||
|
||||
+1
-1
@@ -247,7 +247,7 @@ boolean Plugin_049(byte function, struct EventStruct *event, String& string)
|
||||
|
||||
//delay first read, because hardware needs to initialize on cold boot
|
||||
//otherwise we get a weird value or read error
|
||||
timerSensor[event->TaskIndex] = millis() + 15000;
|
||||
schedule_task_device_timer(event->TaskIndex, millis() + 15000);
|
||||
|
||||
Plugin_049_init = true;
|
||||
success = true;
|
||||
|
||||
@@ -81,6 +81,7 @@ boolean Plugin_051(byte function, struct EventStruct *event, String& string)
|
||||
addLog(LOG_LEVEL_ERROR, F("AM2320: Sensor offline"));
|
||||
break;
|
||||
case 0:
|
||||
{
|
||||
UserVar[event->BaseVarIndex] = th.t;
|
||||
UserVar[event->BaseVarIndex + 1] = th.h;
|
||||
|
||||
@@ -92,6 +93,7 @@ boolean Plugin_051(byte function, struct EventStruct *event, String& string)
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -65,17 +65,17 @@ boolean Plugin_052(byte function, struct EventStruct *event, String& string)
|
||||
|
||||
case PLUGIN_WRITE:
|
||||
{
|
||||
String tmpString = string;
|
||||
|
||||
String cmd = parseString(tmpString, 1);
|
||||
String param1 = parseString(tmpString, 2);
|
||||
|
||||
String cmd = parseString(string, 1);
|
||||
String param1 = parseString(string, 2);
|
||||
|
||||
if (cmd.equalsIgnoreCase(F("senseair_setrelay")))
|
||||
{
|
||||
if (param1.toInt() == 0 || param1.toInt() == 1 || param1.toInt() == -1) {
|
||||
Plugin_052_setRelayStatus(param1.toInt());
|
||||
addLog(LOG_LEVEL_INFO, String(F("Senseair command: relay=")) + param1);
|
||||
int par1;
|
||||
if (validIntFromString(param1, par1)) {
|
||||
if (par1 == 0 || par1 == 1 || par1 == -1) {
|
||||
Plugin_052_setRelayStatus(par1);
|
||||
addLog(LOG_LEVEL_INFO, String(F("Senseair command: relay=")) + param1);
|
||||
}
|
||||
}
|
||||
success = true;
|
||||
}
|
||||
|
||||
+36
-30
@@ -100,7 +100,6 @@ boolean PacketAvailable(void)
|
||||
}
|
||||
|
||||
boolean Plugin_053_process_data(struct EventStruct *event) {
|
||||
String log;
|
||||
uint16_t checksum = 0, checksum2 = 0;
|
||||
uint16_t framelength = 0;
|
||||
uint16 packet_header = 0;
|
||||
@@ -113,9 +112,11 @@ boolean Plugin_053_process_data(struct EventStruct *event) {
|
||||
SerialRead16(&framelength, &checksum);
|
||||
if (framelength != (PMSx003_SIZE - 4))
|
||||
{
|
||||
log = F("PMSx003 : invalid framelength - ");
|
||||
log += framelength;
|
||||
addLog(LOG_LEVEL_ERROR, log);
|
||||
if (loglevelActiveFor(LOG_LEVEL_ERROR)) {
|
||||
String log = F("PMSx003 : invalid framelength - ");
|
||||
log += framelength;
|
||||
addLog(LOG_LEVEL_ERROR, log);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -123,33 +124,37 @@ boolean Plugin_053_process_data(struct EventStruct *event) {
|
||||
for (int i = 0; i < 13; i++)
|
||||
SerialRead16(&data[i], &checksum);
|
||||
|
||||
log = F("PMSx003 : pm1.0=");
|
||||
log += data[0];
|
||||
log += F(", pm2.5=");
|
||||
log += data[1];
|
||||
log += F(", pm10=");
|
||||
log += data[2];
|
||||
log += F(", pm1.0a=");
|
||||
log += data[3];
|
||||
log += F(", pm2.5a=");
|
||||
log += data[4];
|
||||
log += F(", pm10a=");
|
||||
log += data[5];
|
||||
addLog(LOG_LEVEL_DEBUG, log);
|
||||
if (loglevelActiveFor(LOG_LEVEL_DEBUG)) {
|
||||
String log = F("PMSx003 : pm1.0=");
|
||||
log += data[0];
|
||||
log += F(", pm2.5=");
|
||||
log += data[1];
|
||||
log += F(", pm10=");
|
||||
log += data[2];
|
||||
log += F(", pm1.0a=");
|
||||
log += data[3];
|
||||
log += F(", pm2.5a=");
|
||||
log += data[4];
|
||||
log += F(", pm10a=");
|
||||
log += data[5];
|
||||
addLog(LOG_LEVEL_DEBUG, log);
|
||||
}
|
||||
|
||||
log = F("PMSx003 : count/0.1L : 0.3um=");
|
||||
log += data[6];
|
||||
log += F(", 0.5um=");
|
||||
log += data[7];
|
||||
log += F(", 1.0um=");
|
||||
log += data[8];
|
||||
log += F(", 2.5um=");
|
||||
log += data[9];
|
||||
log += F(", 5.0um=");
|
||||
log += data[10];
|
||||
log += F(", 10um=");
|
||||
log += data[11];
|
||||
addLog(LOG_LEVEL_DEBUG_MORE, log);
|
||||
if (loglevelActiveFor(LOG_LEVEL_DEBUG_MORE)) {
|
||||
String log = F("PMSx003 : count/0.1L : 0.3um=");
|
||||
log += data[6];
|
||||
log += F(", 0.5um=");
|
||||
log += data[7];
|
||||
log += F(", 1.0um=");
|
||||
log += data[8];
|
||||
log += F(", 2.5um=");
|
||||
log += data[9];
|
||||
log += F(", 5.0um=");
|
||||
log += data[10];
|
||||
log += F(", 10um=");
|
||||
log += data[11];
|
||||
addLog(LOG_LEVEL_DEBUG_MORE, log);
|
||||
}
|
||||
|
||||
// Compare checksums
|
||||
SerialRead16(&checksum2, NULL);
|
||||
@@ -296,6 +301,7 @@ boolean Plugin_053(byte function, struct EventStruct *event, String& string)
|
||||
// When new data is available, return true
|
||||
success = values_received;
|
||||
values_received = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return success;
|
||||
|
||||
@@ -160,13 +160,15 @@ boolean Plugin_054(byte function, struct EventStruct *event, String& string)
|
||||
|
||||
if (param == F("log"))
|
||||
{
|
||||
String log = F("DMX : ");
|
||||
for (int16_t i = 0; i < Plugin_054_DMXSize; i++)
|
||||
{
|
||||
log += Plugin_054_DMXBuffer[i];
|
||||
log += F(", ");
|
||||
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
|
||||
String log = F("DMX : ");
|
||||
for (int16_t i = 0; i < Plugin_054_DMXSize; i++)
|
||||
{
|
||||
log += Plugin_054_DMXBuffer[i];
|
||||
log += F(", ");
|
||||
}
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
}
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
success = true;
|
||||
}
|
||||
|
||||
|
||||
+14
-10
@@ -214,26 +214,30 @@ boolean Plugin_055(byte function, struct EventStruct *event, String& string)
|
||||
|
||||
if (command == F("chime"))
|
||||
{
|
||||
int paramPos = getParamStartPos(string, 2);
|
||||
String param = string.substring(paramPos);
|
||||
Plugin_055_AddStringFIFO(param);
|
||||
String param = parseStringToEndKeepCase(string, 2);
|
||||
if (param.length() > 0) {
|
||||
Plugin_055_AddStringFIFO(param);
|
||||
}
|
||||
success = true;
|
||||
}
|
||||
if (command == F("chimeplay"))
|
||||
{
|
||||
String name = parseString(string, 2);
|
||||
String param;
|
||||
Plugin_055_ReadChime(name, param);
|
||||
Plugin_055_AddStringFIFO(param);
|
||||
if (name.length() > 0) {
|
||||
String param;
|
||||
Plugin_055_ReadChime(name, param);
|
||||
Plugin_055_AddStringFIFO(param);
|
||||
}
|
||||
success = true;
|
||||
}
|
||||
if (command == F("chimesave"))
|
||||
{
|
||||
String name = parseString(string, 2);
|
||||
int paramPos = getParamStartPos(string, 3);
|
||||
String param = string.substring(paramPos);
|
||||
Plugin_055_WriteChime(name, param);
|
||||
Plugin_055_AddStringFIFO(F("1"));
|
||||
String param = parseStringToEndKeepCase(string, 3);
|
||||
if (name.length() > 0 && param.length() > 0) {
|
||||
Plugin_055_WriteChime(name, param);
|
||||
Plugin_055_AddStringFIFO(F("1"));
|
||||
}
|
||||
success = true;
|
||||
}
|
||||
|
||||
|
||||
+32
-26
@@ -1,4 +1,4 @@
|
||||
#ifdef USES_P057
|
||||
#ifdef USES_P057
|
||||
//#######################################################################################################
|
||||
//#################################### Plugin 057: HT16K33 LED ##########################################
|
||||
//#######################################################################################################
|
||||
@@ -150,31 +150,33 @@ boolean Plugin_057(byte function, struct EventStruct *event, String& string)
|
||||
if (!Plugin_057_M)
|
||||
return false;
|
||||
|
||||
String lowerString=string;
|
||||
lowerString.toLowerCase();
|
||||
String command = parseString(lowerString, 1);
|
||||
String command = parseString(string, 1);
|
||||
|
||||
if (command == F("mprint"))
|
||||
{
|
||||
int paramPos = getParamStartPos(lowerString, 2);
|
||||
String text = lowerString.substring(paramPos);
|
||||
byte seg = 0;
|
||||
String text = parseStringToEnd(string, 2);
|
||||
if (text.length() > 0) {
|
||||
byte seg = 0;
|
||||
|
||||
Plugin_057_M->ClearRowBuffer();
|
||||
while (text[seg] && seg < 8)
|
||||
{
|
||||
// uint16_t value = 0;
|
||||
char c = text[seg];
|
||||
Plugin_057_M->SetDigit(seg, c);
|
||||
seg++;
|
||||
Plugin_057_M->ClearRowBuffer();
|
||||
while (text[seg] && seg < 8)
|
||||
{
|
||||
// uint16_t value = 0;
|
||||
char c = text[seg];
|
||||
Plugin_057_M->SetDigit(seg, c);
|
||||
seg++;
|
||||
}
|
||||
Plugin_057_M->TransmitRowBuffer();
|
||||
success = true;
|
||||
}
|
||||
Plugin_057_M->TransmitRowBuffer();
|
||||
success = true;
|
||||
}
|
||||
else if (command == F("mbr")) {
|
||||
int paramPos = getParamStartPos(lowerString, 2);
|
||||
uint8_t brightness = lowerString.substring(paramPos).toInt();
|
||||
Plugin_057_M->SetBrightness(brightness);
|
||||
String param = parseString(string, 2);
|
||||
int brightness;
|
||||
if (validIntFromString(param, brightness)) {
|
||||
if (brightness >= 0 && brightness <= 255)
|
||||
Plugin_057_M->SetBrightness(brightness);
|
||||
}
|
||||
success = true;
|
||||
}
|
||||
else if (command == F("m") || command == F("mx") || command == F("mnum"))
|
||||
@@ -186,6 +188,8 @@ boolean Plugin_057(byte function, struct EventStruct *event, String& string)
|
||||
uint8_t seg = 0;
|
||||
uint16_t value = 0;
|
||||
|
||||
String lowerString=string;
|
||||
lowerString.toLowerCase();
|
||||
lowerString.replace(F(" "), " ");
|
||||
lowerString.replace(F(" ="), "=");
|
||||
lowerString.replace(F("= "), "=");
|
||||
@@ -199,13 +203,15 @@ boolean Plugin_057(byte function, struct EventStruct *event, String& string)
|
||||
|
||||
if (param == F("log"))
|
||||
{
|
||||
String log = F("MX : ");
|
||||
for (byte i = 0; i < 8; i++)
|
||||
{
|
||||
log += String(Plugin_057_M->GetRow(i), 16);
|
||||
log += F("h, ");
|
||||
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
|
||||
String log = F("MX : ");
|
||||
for (byte i = 0; i < 8; i++)
|
||||
{
|
||||
log += String(Plugin_057_M->GetRow(i), 16);
|
||||
log += F("h, ");
|
||||
}
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
}
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
success = true;
|
||||
}
|
||||
|
||||
@@ -323,4 +329,4 @@ boolean Plugin_057(byte function, struct EventStruct *event, String& string)
|
||||
return success;
|
||||
}
|
||||
|
||||
#endif // USES_P057
|
||||
#endif // USES_P057
|
||||
|
||||
+11
-11
@@ -121,20 +121,20 @@ boolean Plugin_065(byte function, struct EventStruct *event, String& string)
|
||||
if (!Plugin_065_SoftSerial)
|
||||
break;
|
||||
|
||||
String lowerString=string;
|
||||
lowerString.toLowerCase();
|
||||
String command = parseString(lowerString, 1);
|
||||
String param = parseString(lowerString, 2);
|
||||
String command = parseString(string, 1);
|
||||
String param = parseString(string, 2);
|
||||
|
||||
if (command == F("play"))
|
||||
{
|
||||
String log = F("MP3 : play=");
|
||||
|
||||
uint16_t track = param.toInt();
|
||||
Plugin_065_Play(track);
|
||||
log += track;
|
||||
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
int track;
|
||||
if (validIntFromString(param, track)) {
|
||||
Plugin_065_Play(track);
|
||||
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
|
||||
String log = F("MP3 : play=");
|
||||
log += track;
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
}
|
||||
}
|
||||
success = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -266,10 +266,7 @@ boolean Plugin_067(byte function, struct EventStruct *event, String& string)
|
||||
|
||||
case PLUGIN_WRITE:
|
||||
{
|
||||
String lowerString=string;
|
||||
lowerString.toLowerCase();
|
||||
String command = parseString(lowerString, 1);
|
||||
|
||||
String command = parseString(string, 1);
|
||||
if (command == F("tare"))
|
||||
{
|
||||
String log = F("HX711: tare");
|
||||
|
||||
@@ -153,22 +153,22 @@ boolean Plugin_070(byte function, struct EventStruct *event, String& string)
|
||||
String param3 = parseString(lowerString, 4);
|
||||
|
||||
if (command == F("clock")) {
|
||||
if (param1 != "") {
|
||||
int val_Mode = param1.toInt();
|
||||
int val_Mode;
|
||||
if (validIntFromString(param1, val_Mode)) {
|
||||
if (val_Mode > -1 && val_Mode < 2) {
|
||||
Plugin_070_enabled = val_Mode;
|
||||
CONFIG(0) = Plugin_070_enabled;
|
||||
}
|
||||
}
|
||||
if (param2 != "") {
|
||||
int val_Bright = param2.toInt();
|
||||
int val_Bright;
|
||||
if (validIntFromString(param2, val_Bright)) {
|
||||
if (val_Bright > -1 && val_Bright < 256) {
|
||||
Plugin_070_brightness = val_Bright;
|
||||
CONFIG(1) = Plugin_070_brightness;
|
||||
}
|
||||
}
|
||||
if (param3 != "") {
|
||||
int val_Marks = param3.toInt();
|
||||
int val_Marks;
|
||||
if (validIntFromString(param3, val_Marks)) {
|
||||
if (val_Marks > -1 && val_Marks < 256) {
|
||||
Plugin_070_marks = val_Marks;
|
||||
CONFIG(2) = Plugin_070_marks;
|
||||
@@ -281,5 +281,5 @@ void timeToStrip(int hours, int minutes, int seconds) {
|
||||
}
|
||||
}
|
||||
|
||||
#endif // PLUGIN_BUILD_DISABLED
|
||||
#endif // PLUGIN_BUILD_DISABLED
|
||||
#endif // USES_P070
|
||||
|
||||
@@ -252,11 +252,12 @@ boolean Plugin_074(byte function, struct EventStruct *event, String& string)
|
||||
log += F(" IR: ");
|
||||
log += String(ir);
|
||||
addLog(LOG_LEVEL_INFO,log);
|
||||
success = true;
|
||||
}
|
||||
else {
|
||||
addLog(LOG_LEVEL_ERROR,F("TSL2591: Sensor not initialized!?"));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -138,8 +138,8 @@ boolean Plugin_076(byte function, struct EventStruct *event, String& string)
|
||||
UserVar[event->BaseVarIndex + 2] = hpower;
|
||||
UserVar[event->BaseVarIndex + 3] = hpowfact;
|
||||
//Plugin_076_hlw->toggleMode();
|
||||
success = true;
|
||||
}
|
||||
success = true;
|
||||
break;
|
||||
|
||||
case PLUGIN_INIT:
|
||||
|
||||
+247
-239
@@ -27,7 +27,7 @@ boolean Plugin_077_init = false;
|
||||
unsigned long energy_power_calibration = HLW_PREF_PULSE;
|
||||
unsigned long energy_voltage_calibration = HLW_UREF_PULSE;
|
||||
unsigned long energy_current_calibration = HLW_IREF_PULSE;
|
||||
*/
|
||||
*/
|
||||
|
||||
uint8_t cse_receive_flag = 0;
|
||||
|
||||
@@ -48,272 +48,280 @@ float energy_power = 0; // 123.1 W
|
||||
|
||||
boolean Plugin_077(byte function, struct EventStruct *event, String& string)
|
||||
{
|
||||
boolean success = false;
|
||||
boolean success = false;
|
||||
|
||||
switch (function) {
|
||||
case PLUGIN_DEVICE_ADD:
|
||||
{
|
||||
Device[++deviceCount].Number = PLUGIN_ID_077;
|
||||
Device[deviceCount].VType = SENSOR_TYPE_QUAD;
|
||||
Device[deviceCount].Ports = 0;
|
||||
Device[deviceCount].PullUpOption = false;
|
||||
Device[deviceCount].InverseLogicOption = false;
|
||||
Device[deviceCount].FormulaOption = true;
|
||||
Device[deviceCount].ValueCount = 4;
|
||||
Device[deviceCount].SendDataOption = true;
|
||||
Device[deviceCount].TimerOption = true;
|
||||
Device[deviceCount].TimerOptional = true;
|
||||
Device[deviceCount].GlobalSyncOption = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case PLUGIN_GET_DEVICENAME:
|
||||
{
|
||||
string = F(PLUGIN_NAME_077);
|
||||
break;
|
||||
}
|
||||
|
||||
case PLUGIN_GET_DEVICEVALUENAMES:
|
||||
{
|
||||
strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_VALUENAME1_077));
|
||||
strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[1], PSTR(PLUGIN_VALUENAME2_077));
|
||||
strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[2], PSTR(PLUGIN_VALUENAME3_077));
|
||||
strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[3], PSTR(PLUGIN_VALUENAME4_077));
|
||||
break;
|
||||
}
|
||||
|
||||
case PLUGIN_WEBFORM_LOAD:
|
||||
{
|
||||
addFormNumericBox(F("U Ref"), F("plugin_077_URef"), Settings.TaskDevicePluginConfig[event->TaskIndex][0]);
|
||||
addUnit(F("uSec"));
|
||||
|
||||
addFormNumericBox(F("I Ref"), F("plugin_077_IRef"), Settings.TaskDevicePluginConfig[event->TaskIndex][1]);
|
||||
addUnit(F("uSec"));
|
||||
|
||||
addFormNumericBox(F("P Ref"), F("plugin_077_PRef"), Settings.TaskDevicePluginConfig[event->TaskIndex][2]);
|
||||
addUnit(F("uSec"));
|
||||
addFormNote(F("Use 0 to read values stored on chip / default values"));
|
||||
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case PLUGIN_WEBFORM_SAVE:
|
||||
{
|
||||
Settings.TaskDevicePluginConfig[event->TaskIndex][0] = getFormItemInt(F("plugin_077_URef"));;
|
||||
Settings.TaskDevicePluginConfig[event->TaskIndex][1] = getFormItemInt(F("plugin_077_IRef"));
|
||||
Settings.TaskDevicePluginConfig[event->TaskIndex][2] = getFormItemInt(F("plugin_077_PRef"));
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case PLUGIN_INIT:
|
||||
{
|
||||
Plugin_077_init = true;
|
||||
if (Settings.TaskDevicePluginConfig[event->TaskIndex][0] == 0) Settings.TaskDevicePluginConfig[event->TaskIndex][0] = HLW_UREF_PULSE;
|
||||
if (Settings.TaskDevicePluginConfig[event->TaskIndex][1] == 0) Settings.TaskDevicePluginConfig[event->TaskIndex][1] = HLW_IREF_PULSE;
|
||||
if (Settings.TaskDevicePluginConfig[event->TaskIndex][2] == 0) Settings.TaskDevicePluginConfig[event->TaskIndex][2] = HLW_PREF_PULSE;
|
||||
|
||||
Settings.UseSerial = true; // Enable Serial port
|
||||
Settings.SerialLogLevel = 0; // disable logging on serial port (used for CSE7766 communication)
|
||||
Settings.BaudRate = 4800; // set BaudRate for CSE7766
|
||||
Serial.flush();
|
||||
Serial.begin(Settings.BaudRate);
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
|
||||
/* currently not needed!
|
||||
case PLUGIN_TEN_PER_SECOND:
|
||||
switch (function) {
|
||||
case PLUGIN_DEVICE_ADD:
|
||||
{
|
||||
Device[++deviceCount].Number = PLUGIN_ID_077;
|
||||
Device[deviceCount].VType = SENSOR_TYPE_QUAD;
|
||||
Device[deviceCount].Ports = 0;
|
||||
Device[deviceCount].PullUpOption = false;
|
||||
Device[deviceCount].InverseLogicOption = false;
|
||||
Device[deviceCount].FormulaOption = true;
|
||||
Device[deviceCount].ValueCount = 4;
|
||||
Device[deviceCount].SendDataOption = true;
|
||||
Device[deviceCount].TimerOption = true;
|
||||
Device[deviceCount].TimerOptional = true;
|
||||
Device[deviceCount].GlobalSyncOption = true;
|
||||
break;
|
||||
}
|
||||
|
||||
long cf_frequency = 0;
|
||||
case PLUGIN_GET_DEVICENAME:
|
||||
{
|
||||
string = F(PLUGIN_NAME_077);
|
||||
break;
|
||||
}
|
||||
|
||||
case PLUGIN_GET_DEVICEVALUENAMES:
|
||||
{
|
||||
strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_VALUENAME1_077));
|
||||
strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[1], PSTR(PLUGIN_VALUENAME2_077));
|
||||
strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[2], PSTR(PLUGIN_VALUENAME3_077));
|
||||
strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[3], PSTR(PLUGIN_VALUENAME4_077));
|
||||
break;
|
||||
}
|
||||
|
||||
case PLUGIN_WEBFORM_LOAD:
|
||||
{
|
||||
addFormNumericBox(F("U Ref"), F("plugin_077_URef"), Settings.TaskDevicePluginConfig[event->TaskIndex][0]);
|
||||
addUnit(F("uSec"));
|
||||
|
||||
addFormNumericBox(F("I Ref"), F("plugin_077_IRef"), Settings.TaskDevicePluginConfig[event->TaskIndex][1]);
|
||||
addUnit(F("uSec"));
|
||||
|
||||
addFormNumericBox(F("P Ref"), F("plugin_077_PRef"), Settings.TaskDevicePluginConfig[event->TaskIndex][2]);
|
||||
addUnit(F("uSec"));
|
||||
addFormNote(F("Use 0 to read values stored on chip / default values"));
|
||||
|
||||
if (CSE_PULSES_NOT_INITIALIZED == cf_pulses_last_time) {
|
||||
cf_pulses_last_time = cf_pulses; // Init after restart
|
||||
} else {
|
||||
if (cf_pulses < cf_pulses_last_time) { // Rolled over after 65535 pulses
|
||||
cf_frequency = (65536 - cf_pulses_last_time) + cf_pulses;
|
||||
} else {
|
||||
cf_frequency = cf_pulses - cf_pulses_last_time;
|
||||
}
|
||||
if (cf_frequency) {
|
||||
cf_pulses_last_time = cf_pulses;
|
||||
// energy_kWhtoday_delta += (cf_frequency * energy_power_calibration) / 36;
|
||||
// EnergyUpdateToday();
|
||||
}
|
||||
}
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
*/
|
||||
|
||||
case PLUGIN_READ:
|
||||
{
|
||||
// We do not actually read as this is already done by reading the serial output
|
||||
// Instead we just send the last known state stored in Uservar
|
||||
addLog(LOG_LEVEL_DEBUG_DEV, F("CSE: plugin read"));
|
||||
case PLUGIN_WEBFORM_SAVE:
|
||||
{
|
||||
Settings.TaskDevicePluginConfig[event->TaskIndex][0] = getFormItemInt(F("plugin_077_URef"));;
|
||||
Settings.TaskDevicePluginConfig[event->TaskIndex][1] = getFormItemInt(F("plugin_077_IRef"));
|
||||
Settings.TaskDevicePluginConfig[event->TaskIndex][2] = getFormItemInt(F("plugin_077_PRef"));
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case PLUGIN_INIT:
|
||||
{
|
||||
Plugin_077_init = true;
|
||||
if (Settings.TaskDevicePluginConfig[event->TaskIndex][0] == 0) Settings.TaskDevicePluginConfig[event->TaskIndex][0] = HLW_UREF_PULSE;
|
||||
if (Settings.TaskDevicePluginConfig[event->TaskIndex][1] == 0) Settings.TaskDevicePluginConfig[event->TaskIndex][1] = HLW_IREF_PULSE;
|
||||
if (Settings.TaskDevicePluginConfig[event->TaskIndex][2] == 0) Settings.TaskDevicePluginConfig[event->TaskIndex][2] = HLW_PREF_PULSE;
|
||||
|
||||
Settings.UseSerial = true; // Enable Serial port
|
||||
disableSerialLog(); // disable logging on serial port (used for CSE7766 communication)
|
||||
Settings.BaudRate = 4800; // set BaudRate for CSE7766
|
||||
Serial.flush();
|
||||
Serial.begin(Settings.BaudRate);
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
|
||||
/* currently not needed!
|
||||
case PLUGIN_TEN_PER_SECOND:
|
||||
{
|
||||
|
||||
long cf_frequency = 0;
|
||||
|
||||
if (CSE_PULSES_NOT_INITIALIZED == cf_pulses_last_time) {
|
||||
cf_pulses_last_time = cf_pulses; // Init after restart
|
||||
} else {
|
||||
if (cf_pulses < cf_pulses_last_time) { // Rolled over after 65535 pulses
|
||||
cf_frequency = (65536 - cf_pulses_last_time) + cf_pulses;
|
||||
} else {
|
||||
cf_frequency = cf_pulses - cf_pulses_last_time;
|
||||
}
|
||||
if (cf_frequency) {
|
||||
cf_pulses_last_time = cf_pulses;
|
||||
// energy_kWhtoday_delta += (cf_frequency * energy_power_calibration) / 36;
|
||||
// EnergyUpdateToday();
|
||||
}
|
||||
}
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
*/
|
||||
|
||||
case PLUGIN_READ:
|
||||
{
|
||||
addLog(LOG_LEVEL_DEBUG_DEV, F("CSE: plugin read"));
|
||||
// sendData(event);
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
// Variables set in PLUGIN_SERIAL_IN as soon as there are new values!
|
||||
// UserVar[event->BaseVarIndex] = energy_voltage;
|
||||
// UserVar[event->BaseVarIndex + 1] = energy_power;
|
||||
// UserVar[event->BaseVarIndex + 2] = energy_current;
|
||||
// UserVar[event->BaseVarIndex + 3] = cf_pulses;
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case PLUGIN_SERIAL_IN:
|
||||
{
|
||||
if (Plugin_077_init) {
|
||||
if (Serial.available() > 0) {
|
||||
serial_in_byte = Serial.read();
|
||||
success = true;
|
||||
}
|
||||
case PLUGIN_SERIAL_IN:
|
||||
{
|
||||
if (Plugin_077_init) {
|
||||
if (Serial.available() > 0) {
|
||||
serial_in_byte = Serial.read();
|
||||
success = true;
|
||||
|
||||
if (cse_receive_flag) {
|
||||
serial_in_buffer[serial_in_byte_counter++] = serial_in_byte;
|
||||
if (24 == serial_in_byte_counter) {
|
||||
addLog(LOG_LEVEL_DEBUG_DEV, F("CSE: packet received"));
|
||||
CseReceived(event);
|
||||
cse_receive_flag = 0;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (0x5A == serial_in_byte) { // 0x5A - Packet header 2
|
||||
cse_receive_flag = 1;
|
||||
addLog(LOG_LEVEL_DEBUG_DEV, F("CSE: Header received"));
|
||||
} else {
|
||||
serial_in_byte_counter = 0;
|
||||
}
|
||||
serial_in_buffer[serial_in_byte_counter++] = serial_in_byte;
|
||||
}
|
||||
serial_in_byte = 0; // Discard
|
||||
if (cse_receive_flag) {
|
||||
serial_in_buffer[serial_in_byte_counter++] = serial_in_byte;
|
||||
if (24 == serial_in_byte_counter) {
|
||||
addLog(LOG_LEVEL_DEBUG_DEV, F("CSE: packet received"));
|
||||
CseReceived(event);
|
||||
cse_receive_flag = 0;
|
||||
serial_in_byte_counter = 0;
|
||||
// new packet received, update values
|
||||
UserVar[event->BaseVarIndex] = energy_voltage;
|
||||
UserVar[event->BaseVarIndex + 1] = energy_power;
|
||||
UserVar[event->BaseVarIndex + 2] = energy_current;
|
||||
UserVar[event->BaseVarIndex + 3] = cf_pulses;
|
||||
// break;
|
||||
}
|
||||
} else {
|
||||
if (0x5A == serial_in_byte) { // 0x5A - Packet header 2
|
||||
cse_receive_flag = 1;
|
||||
addLog(LOG_LEVEL_DEBUG_DEV, F("CSE: Header received"));
|
||||
} else {
|
||||
serial_in_byte_counter = 0;
|
||||
}
|
||||
serial_in_buffer[serial_in_byte_counter++] = serial_in_byte;
|
||||
}
|
||||
serial_in_byte = 0; // Discard
|
||||
|
||||
UserVar[event->BaseVarIndex] = energy_voltage;
|
||||
UserVar[event->BaseVarIndex + 1] = energy_power;
|
||||
UserVar[event->BaseVarIndex + 2] = energy_current;
|
||||
UserVar[event->BaseVarIndex + 3] = cf_pulses;
|
||||
|
||||
// String log = F("Variable: Tag: ");
|
||||
// log += key;
|
||||
// addLog(LOG_LEVEL_INFO, log);
|
||||
// success = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return success;
|
||||
// String log = F("Variable: Tag: ");
|
||||
// log += key;
|
||||
// addLog(LOG_LEVEL_INFO, log);
|
||||
// success = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
void CseReceived(struct EventStruct *event)
|
||||
{
|
||||
String log;
|
||||
uint8_t header = serial_in_buffer[0];
|
||||
if ((header & 0xFC) == 0xFC) {
|
||||
addLog(LOG_LEVEL_DEBUG, F("CSE: Abnormal hardware"));
|
||||
return;
|
||||
}
|
||||
uint8_t header = serial_in_buffer[0];
|
||||
if ((header & 0xFC) == 0xFC) {
|
||||
addLog(LOG_LEVEL_DEBUG, F("CSE: Abnormal hardware"));
|
||||
return;
|
||||
}
|
||||
|
||||
// Calculate checksum
|
||||
uint8_t checksum = 0;
|
||||
for (byte i = 2; i < 23; i++) checksum += serial_in_buffer[i];
|
||||
if (checksum != serial_in_buffer[23]) {
|
||||
addLog(LOG_LEVEL_DEBUG, F("CSE: Checksum Failure"));
|
||||
return;
|
||||
}
|
||||
// Calculate checksum
|
||||
uint8_t checksum = 0;
|
||||
for (byte i = 2; i < 23; i++) checksum += serial_in_buffer[i];
|
||||
if (checksum != serial_in_buffer[23]) {
|
||||
addLog(LOG_LEVEL_DEBUG, F("CSE: Checksum Failure"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Get chip calibration data (coefficients) and use as initial defaults
|
||||
if (HLW_UREF_PULSE == Settings.TaskDevicePluginConfig[event->TaskIndex][0]) {
|
||||
long voltage_coefficient = 191200; // uSec
|
||||
if (CSE_NOT_CALIBRATED != header) {
|
||||
voltage_coefficient = serial_in_buffer[2] << 16 | serial_in_buffer[3] << 8 | serial_in_buffer[4];
|
||||
}
|
||||
Settings.TaskDevicePluginConfig[event->TaskIndex][0] = voltage_coefficient / CSE_UREF;
|
||||
}
|
||||
if (HLW_IREF_PULSE == Settings.TaskDevicePluginConfig[event->TaskIndex][1]) {
|
||||
long current_coefficient = 16140; // uSec
|
||||
if (CSE_NOT_CALIBRATED != header) {
|
||||
current_coefficient = serial_in_buffer[8] << 16 | serial_in_buffer[9] << 8 | serial_in_buffer[10];
|
||||
}
|
||||
Settings.TaskDevicePluginConfig[event->TaskIndex][1] = current_coefficient;
|
||||
}
|
||||
if (HLW_PREF_PULSE == Settings.TaskDevicePluginConfig[event->TaskIndex][2]) {
|
||||
long power_coefficient = 5364000; // uSec
|
||||
if (CSE_NOT_CALIBRATED != header) {
|
||||
power_coefficient = serial_in_buffer[14] << 16 | serial_in_buffer[15] << 8 | serial_in_buffer[16];
|
||||
}
|
||||
Settings.TaskDevicePluginConfig[event->TaskIndex][2] = power_coefficient / CSE_PREF;
|
||||
}
|
||||
// Get chip calibration data (coefficients) and use as initial defaults
|
||||
if (HLW_UREF_PULSE == Settings.TaskDevicePluginConfig[event->TaskIndex][0]) {
|
||||
long voltage_coefficient = 191200; // uSec
|
||||
if (CSE_NOT_CALIBRATED != header) {
|
||||
voltage_coefficient = serial_in_buffer[2] << 16 | serial_in_buffer[3] << 8 | serial_in_buffer[4];
|
||||
}
|
||||
Settings.TaskDevicePluginConfig[event->TaskIndex][0] = voltage_coefficient / CSE_UREF;
|
||||
}
|
||||
if (HLW_IREF_PULSE == Settings.TaskDevicePluginConfig[event->TaskIndex][1]) {
|
||||
long current_coefficient = 16140; // uSec
|
||||
if (CSE_NOT_CALIBRATED != header) {
|
||||
current_coefficient = serial_in_buffer[8] << 16 | serial_in_buffer[9] << 8 | serial_in_buffer[10];
|
||||
}
|
||||
Settings.TaskDevicePluginConfig[event->TaskIndex][1] = current_coefficient;
|
||||
}
|
||||
if (HLW_PREF_PULSE == Settings.TaskDevicePluginConfig[event->TaskIndex][2]) {
|
||||
long power_coefficient = 5364000; // uSec
|
||||
if (CSE_NOT_CALIBRATED != header) {
|
||||
power_coefficient = serial_in_buffer[14] << 16 | serial_in_buffer[15] << 8 | serial_in_buffer[16];
|
||||
}
|
||||
Settings.TaskDevicePluginConfig[event->TaskIndex][2] = power_coefficient / CSE_PREF;
|
||||
}
|
||||
|
||||
|
||||
uint8_t adjustement = serial_in_buffer[20];
|
||||
voltage_cycle = serial_in_buffer[5] << 16 | serial_in_buffer[6] << 8 | serial_in_buffer[7];
|
||||
current_cycle = serial_in_buffer[11] << 16 | serial_in_buffer[12] << 8 | serial_in_buffer[13];
|
||||
power_cycle = serial_in_buffer[17] << 16 | serial_in_buffer[18] << 8 | serial_in_buffer[19];
|
||||
cf_pulses = serial_in_buffer[21] << 8 | serial_in_buffer[22];
|
||||
uint8_t adjustement = serial_in_buffer[20];
|
||||
voltage_cycle = serial_in_buffer[5] << 16 | serial_in_buffer[6] << 8 | serial_in_buffer[7];
|
||||
current_cycle = serial_in_buffer[11] << 16 | serial_in_buffer[12] << 8 | serial_in_buffer[13];
|
||||
power_cycle = serial_in_buffer[17] << 16 | serial_in_buffer[18] << 8 | serial_in_buffer[19];
|
||||
cf_pulses = serial_in_buffer[21] << 8 | serial_in_buffer[22];
|
||||
|
||||
log = F("CSE: adjustement ");
|
||||
log += adjustement;
|
||||
addLog(LOG_LEVEL_DEBUG_DEV, log);
|
||||
log = F("CSE: voltage_cycle ");
|
||||
log += voltage_cycle;
|
||||
addLog(LOG_LEVEL_DEBUG_DEV, log);
|
||||
log = F("CSE: current_cycle ");
|
||||
log += current_cycle;
|
||||
addLog(LOG_LEVEL_DEBUG_DEV, log);
|
||||
log = F("CSE: power_cycle ");
|
||||
log += power_cycle;
|
||||
addLog(LOG_LEVEL_DEBUG_DEV, log);
|
||||
log = F("CSE: cf_pulses ");
|
||||
log += cf_pulses;
|
||||
addLog(LOG_LEVEL_DEBUG_DEV, log);
|
||||
if (loglevelActiveFor(LOG_LEVEL_DEBUG_DEV)) {
|
||||
String log = F("CSE: adjustement ");
|
||||
log += adjustement;
|
||||
addLog(LOG_LEVEL_DEBUG_DEV, log);
|
||||
log = F("CSE: voltage_cycle ");
|
||||
log += voltage_cycle;
|
||||
addLog(LOG_LEVEL_DEBUG_DEV, log);
|
||||
log = F("CSE: current_cycle ");
|
||||
log += current_cycle;
|
||||
addLog(LOG_LEVEL_DEBUG_DEV, log);
|
||||
log = F("CSE: power_cycle ");
|
||||
log += power_cycle;
|
||||
addLog(LOG_LEVEL_DEBUG_DEV, log);
|
||||
log = F("CSE: cf_pulses ");
|
||||
log += cf_pulses;
|
||||
addLog(LOG_LEVEL_DEBUG_DEV, log);
|
||||
}
|
||||
|
||||
// if (energy_power_on) { // Powered on
|
||||
// if (energy_power_on) { // Powered on
|
||||
|
||||
if (adjustement & 0x40) { // Voltage valid
|
||||
energy_voltage = (float)(Settings.TaskDevicePluginConfig[event->TaskIndex][0] * CSE_UREF) / (float)voltage_cycle;
|
||||
}
|
||||
if (adjustement & 0x10) { // Power valid
|
||||
if ((header & 0xF2) == 0xF2) { // Power cycle exceeds range
|
||||
energy_power = 0;
|
||||
} else {
|
||||
if (0 == power_cycle_first) power_cycle_first = power_cycle; // Skip first incomplete power_cycle
|
||||
if (power_cycle_first != power_cycle) {
|
||||
power_cycle_first = -1;
|
||||
energy_power = (float)(Settings.TaskDevicePluginConfig[event->TaskIndex][2] * CSE_PREF) / (float)power_cycle;
|
||||
} else {
|
||||
energy_power = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
power_cycle_first = 0;
|
||||
energy_power = 0; // Powered on but no load
|
||||
}
|
||||
if (adjustement & 0x20) { // Current valid
|
||||
if (0 == energy_power) {
|
||||
energy_current = 0;
|
||||
} else {
|
||||
energy_current = (float)Settings.TaskDevicePluginConfig[event->TaskIndex][1] / (float)current_cycle;
|
||||
}
|
||||
}
|
||||
if (adjustement & 0x40) { // Voltage valid
|
||||
energy_voltage = (float)(Settings.TaskDevicePluginConfig[event->TaskIndex][0] * CSE_UREF) / (float)voltage_cycle;
|
||||
}
|
||||
if (adjustement & 0x10) { // Power valid
|
||||
if ((header & 0xF2) == 0xF2) { // Power cycle exceeds range
|
||||
energy_power = 0;
|
||||
} else {
|
||||
if (0 == power_cycle_first) power_cycle_first = power_cycle; // Skip first incomplete power_cycle
|
||||
if (power_cycle_first != power_cycle) {
|
||||
power_cycle_first = -1;
|
||||
energy_power = (float)(Settings.TaskDevicePluginConfig[event->TaskIndex][2] * CSE_PREF) / (float)power_cycle;
|
||||
} else {
|
||||
energy_power = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
power_cycle_first = 0;
|
||||
energy_power = 0; // Powered on but no load
|
||||
}
|
||||
if (adjustement & 0x20) { // Current valid
|
||||
if (0 == energy_power) {
|
||||
energy_current = 0;
|
||||
} else {
|
||||
energy_current = (float)Settings.TaskDevicePluginConfig[event->TaskIndex][1] / (float)current_cycle;
|
||||
}
|
||||
}
|
||||
|
||||
// } else { // Powered off
|
||||
// power_cycle_first = 0;
|
||||
// energy_voltage = 0;
|
||||
// energy_power = 0;
|
||||
// energy_current = 0;
|
||||
// }
|
||||
// } else { // Powered off
|
||||
// power_cycle_first = 0;
|
||||
// energy_voltage = 0;
|
||||
// energy_power = 0;
|
||||
// energy_current = 0;
|
||||
// }
|
||||
|
||||
log = F("CSE voltage: ");
|
||||
log += energy_voltage;
|
||||
addLog(LOG_LEVEL_DEBUG, log);
|
||||
log = F("CSE power: ");
|
||||
log += energy_power;
|
||||
addLog(LOG_LEVEL_DEBUG, log);
|
||||
log = F("CSE current: ");
|
||||
log += energy_current;
|
||||
addLog(LOG_LEVEL_DEBUG, log);
|
||||
log = F("CSE piulses: ");
|
||||
log += cf_pulses;
|
||||
addLog(LOG_LEVEL_DEBUG, log);
|
||||
if (loglevelActiveFor(LOG_LEVEL_DEBUG)) {
|
||||
String log = F("CSE voltage: ");
|
||||
log += energy_voltage;
|
||||
addLog(LOG_LEVEL_DEBUG, log);
|
||||
log = F("CSE power: ");
|
||||
log += energy_power;
|
||||
addLog(LOG_LEVEL_DEBUG, log);
|
||||
log = F("CSE current: ");
|
||||
log += energy_current;
|
||||
addLog(LOG_LEVEL_DEBUG, log);
|
||||
log = F("CSE piulses: ");
|
||||
log += cf_pulses;
|
||||
addLog(LOG_LEVEL_DEBUG, log);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // USES_P077
|
||||
|
||||
+21
-5
@@ -1137,9 +1137,9 @@ byte PluginCall(byte Function, struct EventStruct *event, String& str)
|
||||
TempEvent.sensorType = Device[DeviceIndex].VType;
|
||||
checkRAM(F("PluginCall_s"),x);
|
||||
START_TIMER;
|
||||
bool retval = (Plugin_ptr[x](Function, event, str));
|
||||
bool retval = (Plugin_ptr[x](Function, &TempEvent, str));
|
||||
STOP_TIMER_TASK(x,Function);
|
||||
if (retval) return true;
|
||||
if (retval) return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1168,7 +1168,7 @@ byte PluginCall(byte Function, struct EventStruct *event, String& str)
|
||||
//TempEvent.idx = Settings.TaskDeviceID[y]; todo check
|
||||
TempEvent.sensorType = Device[DeviceIndex].VType;
|
||||
START_TIMER;
|
||||
bool retval = (Plugin_ptr[x](Function, event, str));
|
||||
bool retval = (Plugin_ptr[x](Function, &TempEvent, str));
|
||||
STOP_TIMER_TASK(x,Function);
|
||||
if (retval){
|
||||
checkRAM(F("PluginCallUDP"),x);
|
||||
@@ -1206,6 +1206,10 @@ byte PluginCall(byte Function, struct EventStruct *event, String& str)
|
||||
TempEvent.sensorType = Device[DeviceIndex].VType;
|
||||
TempEvent.OriginTaskIndex = event->TaskIndex;
|
||||
checkRAM(F("PluginCall_s"),x);
|
||||
if (Function == PLUGIN_INIT) {
|
||||
// Schedule the plugin to be read.
|
||||
schedule_task_device_timer_at_init(TempEvent.TaskIndex);
|
||||
}
|
||||
START_TIMER;
|
||||
Plugin_ptr[x](Function, &TempEvent, str);
|
||||
STOP_TIMER_TASK(x,Function);
|
||||
@@ -1228,17 +1232,29 @@ byte PluginCall(byte Function, struct EventStruct *event, String& str)
|
||||
case PLUGIN_GET_DEVICEGPIONAMES:
|
||||
case PLUGIN_READ:
|
||||
case PLUGIN_SET_CONFIG:
|
||||
case PLUGIN_GET_CONFIG:
|
||||
case PLUGIN_GET_CONFIG:
|
||||
{
|
||||
const int x = getPluginId(event->TaskIndex);
|
||||
if (x >= 0) {
|
||||
if (Plugin_id[x] != 0 ) {
|
||||
if (Function == PLUGIN_INIT) {
|
||||
// Schedule the plugin to be read.
|
||||
schedule_task_device_timer_at_init(event->TaskIndex);
|
||||
}
|
||||
if (Function != PLUGIN_GET_DEVICEVALUENAMES) {
|
||||
// LoadTaskSettings may call PLUGIN_GET_DEVICEVALUENAMES.
|
||||
LoadTaskSettings(event->TaskIndex);
|
||||
}
|
||||
|
||||
event->BaseVarIndex = event->TaskIndex * VARS_PER_TASK;
|
||||
checkRAM(F("PluginCall_init"),x);
|
||||
START_TIMER;
|
||||
bool retval = Plugin_ptr[x](Function, event, str);
|
||||
if (Function == PLUGIN_GET_DEVICEVALUENAMES) {
|
||||
ExtraTaskSettings.TaskIndex = event->TaskIndex;
|
||||
}
|
||||
STOP_TIMER_TASK(x,Function);
|
||||
return retval;
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user