mirror of
https://github.com/letscontrolit/ESPEasy.git
synced 2026-07-28 12:17:05 +00:00
Compare commits
43
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 | ||
|
|
ad06cbc835 |
Vendored
+74
@@ -1,3 +1,77 @@
|
||||
-------------------------------------------------
|
||||
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)
|
||||
-------------------------------------------------
|
||||
|
||||
+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
|
||||
|
||||
+68
-65
@@ -25,96 +25,96 @@
|
||||
\*********************************************************************************************/
|
||||
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("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 +123,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 +135,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 +157,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 +178,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();
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ 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)
|
||||
@@ -49,7 +49,7 @@ bool Command_MenInfo(struct EventStruct *event, const char* Line)
|
||||
Serial.println(sizeof(ExtraTaskSettings));
|
||||
Serial.print(F("DeviceStruct: "));
|
||||
Serial.println(sizeof(Device));
|
||||
return success;
|
||||
return success;
|
||||
}
|
||||
|
||||
bool Command_Background(struct EventStruct *event, const char* Line)
|
||||
@@ -60,7 +60,7 @@ bool Command_Background(struct EventStruct *event, const char* Line)
|
||||
while (!timeOutReached(timer))
|
||||
backgroundtasks();
|
||||
Serial.println(F("end"));
|
||||
return success;
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
@@ -68,7 +68,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 +83,4 @@ bool Command_logentry(struct EventStruct *event, const char* Line)
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif // COMMAND_DIAGNOSTIC_H
|
||||
#endif // COMMAND_DIAGNOSTIC_H
|
||||
|
||||
+5
-1
@@ -8,8 +8,11 @@ bool Command_HTTP_SendToHTTP(struct EventStruct *event, const char* Line)
|
||||
String strLine = Line;
|
||||
String host = parseString(strLine, 2);
|
||||
String port = parseString(strLine, 3);
|
||||
if (!isInt(port)) return false;
|
||||
int pathpos = getParamStartPos(strLine, 4);
|
||||
String path = strLine.substring(pathpos);
|
||||
String path;
|
||||
if (pathpos >= 0)
|
||||
path = strLine.substring(pathpos);
|
||||
WiFiClient client;
|
||||
if (client.connect(host.c_str(), port.toInt()))
|
||||
{
|
||||
@@ -20,6 +23,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;
|
||||
|
||||
+5
-2
@@ -39,12 +39,14 @@ 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);
|
||||
if (!isInt(port)) return success;
|
||||
int msgpos = getParamStartPos(strLine, 4);
|
||||
String message = strLine.substring(msgpos);
|
||||
String message;
|
||||
if (msgpos >= 0)
|
||||
message = strLine.substring(msgpos);
|
||||
IPAddress UDP_IP;
|
||||
if(UDP_IP.fromString(ip)) {
|
||||
portUDP.beginPacket(UDP_IP, port.toInt());
|
||||
@@ -56,6 +58,7 @@ bool Command_UDP_SendToUPD(struct EventStruct *event, const char* Line)
|
||||
#endif
|
||||
portUDP.endPacket();
|
||||
}
|
||||
success = true;
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
+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"));
|
||||
|
||||
+44
-41
@@ -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,8 +297,6 @@
|
||||
#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
|
||||
@@ -373,6 +378,7 @@
|
||||
#include "ESPEasyTimeTypes.h"
|
||||
#include "I2CTypes.h"
|
||||
#include <I2Cdev.h>
|
||||
#include <map>
|
||||
|
||||
#define FS_NO_GLOBALS
|
||||
#if defined(ESP8266)
|
||||
@@ -1035,6 +1041,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() :
|
||||
@@ -1109,16 +1120,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 +1160,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 +1292,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 +1306,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 +1322,6 @@ boolean UseRTOSMultitasking;
|
||||
|
||||
void (*MainLoopCall_ptr)(void);
|
||||
|
||||
#include <map>
|
||||
|
||||
class TimingStats {
|
||||
public:
|
||||
TimingStats() : _timeTotal(0.0), _count(0), _maxVal(0), _minVal(4294967295) {}
|
||||
@@ -1443,7 +1438,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 +1452,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 +1482,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
-222
@@ -233,17 +233,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 +313,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 +391,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 +429,7 @@ int getLoopCountPerSec() {
|
||||
|
||||
|
||||
|
||||
|
||||
/*********************************************************************************************\
|
||||
* MAIN LOOP
|
||||
\*********************************************************************************************/
|
||||
@@ -484,23 +479,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 +540,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 +556,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 +584,7 @@ void run10TimesPerSecond()
|
||||
void runOncePerSecond()
|
||||
{
|
||||
START_TIMER;
|
||||
setNextTimeInterval(timer1s, 1000);
|
||||
updateLogLevelCache();
|
||||
dailyResetCounter++;
|
||||
if (dailyResetCounter > 86400) // 1 day elapsed... //86400
|
||||
{
|
||||
@@ -620,8 +595,6 @@ void runOncePerSecond()
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
}
|
||||
|
||||
checkSensors();
|
||||
|
||||
if (Settings.ConnectionFailuresThreshold)
|
||||
if (connectionFailures > Settings.ConnectionFailuresThreshold)
|
||||
delayedReboot(60);
|
||||
@@ -658,8 +631,6 @@ void runOncePerSecond()
|
||||
PluginCall(PLUGIN_ONCE_A_SECOND, 0, dummyString);
|
||||
// unsigned long elapsed = micros() - start;
|
||||
|
||||
checkSystemTimers();
|
||||
|
||||
if (Settings.UseRules)
|
||||
rulesTimers();
|
||||
|
||||
@@ -701,6 +672,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 +690,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 +720,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 +787,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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
+186
-97
@@ -73,7 +73,7 @@ void deepSleep(int delay)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
saveUserVarToRTC();
|
||||
deepSleepStart(delay); // Call deepSleepStart function after these checks
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@ void deepSleepStart(int delay)
|
||||
#endif
|
||||
}
|
||||
|
||||
boolean remoteConfig(struct EventStruct *event, String& string)
|
||||
boolean remoteConfig(struct EventStruct *event, const String& string)
|
||||
{
|
||||
checkRAM(F("remoteConfig"));
|
||||
boolean success = false;
|
||||
@@ -112,7 +112,9 @@ boolean remoteConfig(struct EventStruct *event, String& string)
|
||||
if (parseString(string, 2) == F("task"))
|
||||
{
|
||||
int configCommandPos1 = getParamStartPos(string, 3);
|
||||
if (configCommandPos1 < 0) return success; // TD-er: Should this be return false?
|
||||
int configCommandPos2 = getParamStartPos(string, 4);
|
||||
if (configCommandPos2 < 0 || (configCommandPos2 - configCommandPos1) < 1) return success; // TD-er: Should this be return false?
|
||||
|
||||
String configTaskName = string.substring(configCommandPos1, configCommandPos2 - 1);
|
||||
String configCommand = string.substring(configCommandPos2);
|
||||
@@ -517,11 +519,13 @@ void fileSystemCheck()
|
||||
fs::FSInfo fs_info;
|
||||
SPIFFS.info(fs_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);
|
||||
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");
|
||||
@@ -1054,13 +1058,15 @@ String LoadFromFile(char* fname, int index, byte* memAddress, int datasize)
|
||||
START_TIMER;
|
||||
|
||||
checkRAM(F("LoadFromFile"));
|
||||
String log = F("LoadFromFile: ");
|
||||
log += fname;
|
||||
log += F(" index: ");
|
||||
log += index;
|
||||
log += F(" datasize: ");
|
||||
log += datasize;
|
||||
addLog(LOG_LEVEL_DEBUG, log);
|
||||
if (loglevelActiveFor(LOG_LEVEL_DEBUG_DEV)) {
|
||||
String log = F("LoadFromFile: ");
|
||||
log += fname;
|
||||
log += F(" index: ");
|
||||
log += index;
|
||||
log += F(" datasize: ");
|
||||
log += datasize;
|
||||
addLog(LOG_LEVEL_DEBUG_DEV, log);
|
||||
}
|
||||
|
||||
fs::File f = SPIFFS.open(fname, "r+");
|
||||
SPIFFS_CHECK(f, fname);
|
||||
@@ -1209,11 +1215,11 @@ void ResetFactory(void)
|
||||
|
||||
str2ip((char*)DEFAULT_SYSLOG_IP, Settings.Syslog_IP);
|
||||
|
||||
Settings.SyslogLevel = DEFAULT_SYSLOG_LEVEL;
|
||||
Settings.SerialLogLevel = DEFAULT_SERIAL_LOG_LEVEL;
|
||||
Settings.SyslogFacility = DEFAULT_SYSLOG_FACILITY;
|
||||
Settings.WebLogLevel = DEFAULT_WEB_LOG_LEVEL;
|
||||
Settings.SDLogLevel = DEFAULT_SD_LOG_LEVEL;
|
||||
setLogLevelFor(LOG_TO_SYSLOG, DEFAULT_SYSLOG_LEVEL);
|
||||
setLogLevelFor(LOG_TO_SERIAL, DEFAULT_SERIAL_LOG_LEVEL);
|
||||
setLogLevelFor(LOG_TO_WEBLOG, DEFAULT_WEB_LOG_LEVEL);
|
||||
setLogLevelFor(LOG_TO_SDCARD, DEFAULT_SD_LOG_LEVEL);
|
||||
Settings.SyslogFacility = DEFAULT_SYSLOG_FACILITY;
|
||||
Settings.UseValueLogger = DEFAULT_USE_SD_LOG;
|
||||
|
||||
Settings.UseSerial = DEFAULT_USE_SERIAL;
|
||||
@@ -1438,8 +1444,8 @@ String getPartitionType(byte pType, byte pSubType) {
|
||||
}
|
||||
|
||||
switch (partitionSubType) {
|
||||
case ESP_PARTITION_SUBTYPE_APP_FACTORY: return F("Factory application");
|
||||
case ESP_PARTITION_SUBTYPE_APP_TEST: return F("Test application");
|
||||
case ESP_PARTITION_SUBTYPE_APP_FACTORY: return F("Factory app");
|
||||
case ESP_PARTITION_SUBTYPE_APP_TEST: return F("Test app");
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
@@ -1522,21 +1528,48 @@ boolean isInt(const String& tBuf) {
|
||||
return isNumerical(tBuf, true);
|
||||
}
|
||||
|
||||
String getNumerical(const String& tBuf, bool mustBeInteger) {
|
||||
String result = "";
|
||||
const unsigned int bufLength = tBuf.length();
|
||||
if (bufLength == 0) return result;
|
||||
boolean decPt = false;
|
||||
int firstDec = 0;
|
||||
char c = tBuf.charAt(0);
|
||||
if(c == '+' || c == '-') {
|
||||
result += c;
|
||||
firstDec = 1;
|
||||
}
|
||||
for(unsigned int x=firstDec; x < bufLength; ++x) {
|
||||
c = tBuf.charAt(x);
|
||||
if(c == '.') {
|
||||
if (mustBeInteger) return result;
|
||||
// Only one decimal point allowed
|
||||
if(decPt) return result;
|
||||
else decPt = true;
|
||||
}
|
||||
else if(c < '0' || c > '9') return result;
|
||||
result += c;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
boolean isNumerical(const String& tBuf, bool mustBeInteger) {
|
||||
const unsigned int bufLength = tBuf.length();
|
||||
if (bufLength == 0) return false;
|
||||
boolean decPt = false;
|
||||
int firstDec = 0;
|
||||
if(tBuf.charAt(0) == '+' || tBuf.charAt(0) == '-')
|
||||
char c = tBuf.charAt(0);
|
||||
if(c == '+' || c == '-')
|
||||
firstDec = 1;
|
||||
for(unsigned int x=firstDec; x < bufLength; ++x) {
|
||||
if(tBuf.charAt(x) == '.') {
|
||||
c = tBuf.charAt(x);
|
||||
if(c == '.') {
|
||||
if (mustBeInteger) return false;
|
||||
// Only one decimal point allowed
|
||||
if(decPt) return false;
|
||||
else decPt = true;
|
||||
}
|
||||
else if(tBuf.charAt(x) < '0' || tBuf.charAt(x) > '9') return false;
|
||||
else if(c < '0' || c > '9') return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -1568,11 +1601,11 @@ void initLog()
|
||||
{
|
||||
//make sure addLog doesnt do any stuff before initalisation of Settings is complete.
|
||||
Settings.UseSerial=true;
|
||||
Settings.SyslogLevel=0;
|
||||
Settings.SyslogFacility=0;
|
||||
Settings.SerialLogLevel=2; //logging during initialisation
|
||||
Settings.WebLogLevel=2;
|
||||
Settings.SDLogLevel=0;
|
||||
setLogLevelFor(LOG_TO_SYSLOG, 0);
|
||||
setLogLevelFor(LOG_TO_SERIAL, 2); //logging during initialisation
|
||||
setLogLevelFor(LOG_TO_WEBLOG, 2);
|
||||
setLogLevelFor(LOG_TO_SDCARD, 0);
|
||||
}
|
||||
|
||||
/********************************************************************************************\
|
||||
@@ -1590,17 +1623,16 @@ String getLogLevelDisplayString(byte index, int& logLevel) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void addLog(byte loglevel, String& string)
|
||||
void addToLog(byte loglevel, String& string)
|
||||
{
|
||||
addLog(loglevel, string.c_str());
|
||||
addToLog(loglevel, string.c_str());
|
||||
}
|
||||
|
||||
void addLog(byte logLevel, const __FlashStringHelper* flashString)
|
||||
void addToLog(byte logLevel, const __FlashStringHelper* flashString)
|
||||
{
|
||||
checkRAM(F("addLog"));
|
||||
checkRAM(F("addToLog"));
|
||||
String s(flashString);
|
||||
addLog(logLevel, s.c_str());
|
||||
addToLog(logLevel, s.c_str());
|
||||
}
|
||||
|
||||
bool SerialAvailableForWrite() {
|
||||
@@ -1611,6 +1643,38 @@ bool SerialAvailableForWrite() {
|
||||
return true;
|
||||
}
|
||||
|
||||
void disableSerialLog() {
|
||||
log_to_serial_disabled = true;
|
||||
setLogLevelFor(LOG_TO_SERIAL, 0);
|
||||
}
|
||||
|
||||
void setLogLevelFor(byte destination, byte logLevel) {
|
||||
switch (destination) {
|
||||
case LOG_TO_SERIAL:
|
||||
if (!log_to_serial_disabled || logLevel == 0)
|
||||
Settings.SerialLogLevel = logLevel; break;
|
||||
case LOG_TO_SYSLOG: Settings.SyslogLevel = logLevel; break;
|
||||
case LOG_TO_WEBLOG: Settings.WebLogLevel = logLevel; break;
|
||||
case LOG_TO_SDCARD: Settings.SDLogLevel = logLevel; break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
updateLogLevelCache();
|
||||
}
|
||||
|
||||
void updateLogLevelCache() {
|
||||
byte max_lvl = 0;
|
||||
max_lvl = _max(max_lvl, Settings.SerialLogLevel);
|
||||
max_lvl = _max(max_lvl, Settings.SyslogLevel);
|
||||
max_lvl = _max(max_lvl, Settings.WebLogLevel);
|
||||
max_lvl = _max(max_lvl, Settings.SDLogLevel);
|
||||
highest_active_log_level = max_lvl;
|
||||
}
|
||||
|
||||
bool loglevelActiveFor(byte logLevel) {
|
||||
return loglevelActive(logLevel, highest_active_log_level);
|
||||
}
|
||||
|
||||
boolean loglevelActiveFor(byte destination, byte logLevel) {
|
||||
byte logLevelSettings = 0;
|
||||
switch (destination) {
|
||||
@@ -1644,7 +1708,7 @@ boolean loglevelActive(byte logLevel, byte logLevelSettings) {
|
||||
return (logLevel <= logLevelSettings);
|
||||
}
|
||||
|
||||
void addLog(byte logLevel, const char *line)
|
||||
void addToLog(byte logLevel, const char *line)
|
||||
{
|
||||
if (loglevelActiveFor(LOG_TO_SERIAL, logLevel)) {
|
||||
Serial.print(millis());
|
||||
@@ -2064,11 +2128,13 @@ String parseTemplate(String &tmpString, byte lineSize)
|
||||
newString += " ";
|
||||
}
|
||||
{
|
||||
String logFormatted = F("DEBUG: Formatted String='");
|
||||
logFormatted += newString;
|
||||
logFormatted += value;
|
||||
logFormatted += "'";
|
||||
addLog(LOG_LEVEL_DEBUG, logFormatted);
|
||||
if (loglevelActiveFor(LOG_LEVEL_DEBUG)) {
|
||||
String logFormatted = F("DEBUG: Formatted String='");
|
||||
logFormatted += newString;
|
||||
logFormatted += value;
|
||||
logFormatted += "'";
|
||||
addLog(LOG_LEVEL_DEBUG, logFormatted);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2076,10 +2142,12 @@ String parseTemplate(String &tmpString, byte lineSize)
|
||||
|
||||
newString += String(value);
|
||||
{
|
||||
String logParsed = F("DEBUG DEV: Parsed String='");
|
||||
logParsed += newString;
|
||||
logParsed += "'";
|
||||
addLog(LOG_LEVEL_DEBUG_DEV, logParsed);
|
||||
if (loglevelActiveFor(LOG_LEVEL_DEBUG_DEV)) {
|
||||
String logParsed = F("DEBUG DEV: Parsed String='");
|
||||
logParsed += newString;
|
||||
logParsed += "'";
|
||||
addLog(LOG_LEVEL_DEBUG_DEV, logParsed);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -2424,11 +2492,11 @@ void rulesProcessing(String& event)
|
||||
{
|
||||
checkRAM(F("rulesProcessing"));
|
||||
unsigned long timer = millis();
|
||||
String log = "";
|
||||
|
||||
log = F("EVENT: ");
|
||||
log += event;
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
|
||||
String log = F("EVENT: ");
|
||||
log += event;
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
}
|
||||
|
||||
for (byte x = 0; x < RULESETS_MAX; x++)
|
||||
{
|
||||
@@ -2444,10 +2512,14 @@ void rulesProcessing(String& event)
|
||||
rulesProcessingFile(fileName, event);
|
||||
}
|
||||
|
||||
log += F(" Processing time:");
|
||||
log += timePassedSince(timer);
|
||||
log += F(" milliSeconds");
|
||||
addLog(LOG_LEVEL_DEBUG, log);
|
||||
if (loglevelActiveFor(LOG_LEVEL_DEBUG)) {
|
||||
String log = F("EVENT: ");
|
||||
log += event;
|
||||
log += F(" Processing time:");
|
||||
log += timePassedSince(timer);
|
||||
log += F(" milliSeconds");
|
||||
addLog(LOG_LEVEL_DEBUG, log);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2470,8 +2542,7 @@ String rulesProcessingFile(String fileName, String& event)
|
||||
nestingLevel++;
|
||||
if (nestingLevel > RULES_MAX_NESTING_LEVEL)
|
||||
{
|
||||
log = F("EVENT: Error: Nesting level exceeded!");
|
||||
addLog(LOG_LEVEL_ERROR, log);
|
||||
addLog(LOG_LEVEL_ERROR, F("EVENT: Error: Nesting level exceeded!"));
|
||||
nestingLevel--;
|
||||
return (log);
|
||||
}
|
||||
@@ -2585,6 +2656,8 @@ String rulesProcessingFile(String fileName, String& event)
|
||||
{
|
||||
conditional = true;
|
||||
String check = lcAction.substring(split + 3);
|
||||
|
||||
|
||||
log = F("[if ");
|
||||
log += check;
|
||||
log += F("]=");
|
||||
@@ -2620,9 +2693,11 @@ String rulesProcessingFile(String fileName, String& event)
|
||||
{
|
||||
ifBranche = false;
|
||||
isCommand = false;
|
||||
log = F("else = ");
|
||||
log += (conditional && (condition == ifBranche)) ? F("true") : F("false");
|
||||
addLog(LOG_LEVEL_DEBUG, log);
|
||||
if (loglevelActiveFor(LOG_LEVEL_DEBUG)) {
|
||||
String log = F("else = ");
|
||||
log += (conditional && (condition == ifBranche)) ? F("true") : F("false");
|
||||
addLog(LOG_LEVEL_DEBUG, log);
|
||||
}
|
||||
}
|
||||
|
||||
if (lcAction == "endif") // conditional block ends here
|
||||
@@ -2649,9 +2724,12 @@ String rulesProcessingFile(String fileName, String& event)
|
||||
action.replace(F("%eventvalue%"), tmpString); // substitute %eventvalue% in actions with the actual value from the event
|
||||
}
|
||||
}
|
||||
log = F("ACT : ");
|
||||
log += action;
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
|
||||
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
|
||||
String log = F("ACT : ");
|
||||
log += action;
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
}
|
||||
|
||||
struct EventStruct TempEvent;
|
||||
parseCommandString(&TempEvent, action);
|
||||
@@ -2660,11 +2738,13 @@ String rulesProcessingFile(String fileName, String& event)
|
||||
String tmpAction(action);
|
||||
if (!PluginCall(PLUGIN_WRITE, &TempEvent, tmpAction)) {
|
||||
if (!tmpAction.equals(action)) {
|
||||
String log = F("PLUGIN_WRITE altered the string: ");
|
||||
log += action;
|
||||
log += F(" to: ");
|
||||
log += tmpAction;
|
||||
addLog(LOG_LEVEL_ERROR, log);
|
||||
if (loglevelActiveFor(LOG_LEVEL_ERROR)) {
|
||||
String log = F("PLUGIN_WRITE altered the string: ");
|
||||
log += action;
|
||||
log += F(" to: ");
|
||||
log += tmpAction;
|
||||
addLog(LOG_LEVEL_ERROR, log);
|
||||
}
|
||||
}
|
||||
ExecuteCommand(VALUE_SOURCE_SYSTEM, action.c_str());
|
||||
}
|
||||
@@ -2994,28 +3074,34 @@ void createRuleEvents(byte TaskIndex)
|
||||
|
||||
void SendValueLogger(byte TaskIndex)
|
||||
{
|
||||
bool featureSD = false;
|
||||
#ifdef FEATURE_SD
|
||||
featureSD = true;
|
||||
#endif
|
||||
|
||||
String logger;
|
||||
if (featureSD || loglevelActiveFor(LOG_LEVEL_DEBUG)) {
|
||||
LoadTaskSettings(TaskIndex);
|
||||
byte DeviceIndex = getDeviceIndex(Settings.TaskDeviceNumber[TaskIndex]);
|
||||
for (byte varNr = 0; varNr < Device[DeviceIndex].ValueCount; varNr++)
|
||||
{
|
||||
logger += getDateString('-');
|
||||
logger += F(" ");
|
||||
logger += getTimeString(':');
|
||||
logger += F(",");
|
||||
logger += Settings.Unit;
|
||||
logger += F(",");
|
||||
logger += ExtraTaskSettings.TaskDeviceName;
|
||||
logger += F(",");
|
||||
logger += ExtraTaskSettings.TaskDeviceValueNames[varNr];
|
||||
logger += F(",");
|
||||
logger += formatUserVarNoCheck(TaskIndex, varNr);
|
||||
logger += F("\r\n");
|
||||
}
|
||||
|
||||
LoadTaskSettings(TaskIndex);
|
||||
byte DeviceIndex = getDeviceIndex(Settings.TaskDeviceNumber[TaskIndex]);
|
||||
for (byte varNr = 0; varNr < Device[DeviceIndex].ValueCount; varNr++)
|
||||
{
|
||||
logger += getDateString('-');
|
||||
logger += F(" ");
|
||||
logger += getTimeString(':');
|
||||
logger += F(",");
|
||||
logger += Settings.Unit;
|
||||
logger += F(",");
|
||||
logger += ExtraTaskSettings.TaskDeviceName;
|
||||
logger += F(",");
|
||||
logger += ExtraTaskSettings.TaskDeviceValueNames[varNr];
|
||||
logger += F(",");
|
||||
logger += formatUserVarNoCheck(TaskIndex, varNr);
|
||||
logger += F("\r\n");
|
||||
addLog(LOG_LEVEL_DEBUG, logger);
|
||||
}
|
||||
|
||||
addLog(LOG_LEVEL_DEBUG, logger);
|
||||
|
||||
#ifdef FEATURE_SD
|
||||
String filename = F("VALUES.CSV");
|
||||
File logFile = SD.open(filename, FILE_WRITE);
|
||||
@@ -3087,15 +3173,17 @@ class RamTracker{
|
||||
if (writePtr >= TRACEENTRIES) writePtr=0; // inc write pointer and wrap around too.
|
||||
};
|
||||
void getTraceBuffer(){ // return giant strings, one line per trace. Add stremToWeb method to avoid large strings.
|
||||
String retval="Memtrace\n";
|
||||
for (int i = 0; i< TRACES; i++){
|
||||
retval += String(i);
|
||||
retval += ": lowest: ";
|
||||
retval += String(tracesMemory[i]);
|
||||
retval += " ";
|
||||
retval += traces[i];
|
||||
addLog(LOG_LEVEL_DEBUG_DEV, retval);
|
||||
retval="";
|
||||
if (loglevelActiveFor(LOG_LEVEL_DEBUG_DEV)) {
|
||||
String retval="Memtrace\n";
|
||||
for (int i = 0; i< TRACES; i++){
|
||||
retval += String(i);
|
||||
retval += ": lowest: ";
|
||||
retval += String(tracesMemory[i]);
|
||||
retval += " ";
|
||||
retval += traces[i];
|
||||
addLog(LOG_LEVEL_DEBUG_DEV, retval);
|
||||
retval="";
|
||||
}
|
||||
}
|
||||
}
|
||||
}myRamTracker; // instantiate class. (is global now)
|
||||
@@ -3367,10 +3455,11 @@ void ArduinoOTAInit()
|
||||
});
|
||||
ArduinoOTA.begin();
|
||||
|
||||
String log = F("OTA : Arduino OTA enabled on port ");
|
||||
log += ARDUINO_OTA_PORT;
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
|
||||
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
|
||||
String log = F("OTA : Arduino OTA enabled on port ");
|
||||
log += ARDUINO_OTA_PORT;
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
+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);
|
||||
}
|
||||
+56
-37
@@ -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;
|
||||
}
|
||||
|
||||
@@ -231,47 +235,38 @@ String to_json_object_value(const String& object, const String& value) {
|
||||
|
||||
|
||||
/*********************************************************************************************\
|
||||
Parse a string and get the xth command or parameter
|
||||
Parse a string and get the xth command or parameter in lower case
|
||||
\*********************************************************************************************/
|
||||
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 parseString(const String& string, byte indexFind) {
|
||||
int startpos = 0;
|
||||
if (indexFind > 0) {
|
||||
startpos = getParamStartPos(string, indexFind - 1);
|
||||
if (startpos < 0) return string;
|
||||
}
|
||||
return "";
|
||||
const int endpos = getParamStartPos(string, indexFind);
|
||||
String result = (endpos <= 0) ? string.substring(startpos) : string.substring(startpos, endpos - 1);
|
||||
result.toLowerCase();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************************************\
|
||||
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++)
|
||||
if (indexFind == 0) return 0;
|
||||
byte count = 1;
|
||||
const unsigned int strlength = string.length();
|
||||
if (strlength <= indexFind) return -1;
|
||||
for (unsigned int x = 0; x < (strlength - 1); ++x)
|
||||
{
|
||||
if (tmpString.charAt(x) == ',')
|
||||
const char c = string.charAt(x);
|
||||
if (c == ',' || c == ' ')
|
||||
{
|
||||
count++;
|
||||
if (count == (indexFind - 1))
|
||||
if (count == indexFind) {
|
||||
return x + 1;
|
||||
}
|
||||
++count;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
@@ -386,6 +381,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);
|
||||
@@ -438,8 +434,8 @@ 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)
|
||||
|
||||
repl(F("%tskname%"), ExtraTaskSettings.TaskDeviceName, s, useURLencode);
|
||||
if (s.indexOf(F("%vname")) != -1) {
|
||||
@@ -450,6 +446,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 +482,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) {
|
||||
|
||||
+70
-7
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
+164
-64
@@ -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;
|
||||
}
|
||||
|
||||
@@ -727,9 +729,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 +751,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 +945,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();
|
||||
@@ -2280,9 +2283,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 +3612,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 +3629,7 @@ void handle_json()
|
||||
}
|
||||
}
|
||||
TXBuffer.startJsonStream();
|
||||
if (taskNr == -1)
|
||||
if (!showSpecificTask)
|
||||
{
|
||||
TXBuffer += '{';
|
||||
if (showSystem) {
|
||||
@@ -3675,7 +3681,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 +3692,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 +3720,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 +3748,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 +3796,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 +4095,6 @@ void handleFileUpload() {
|
||||
if (!isLoggedIn()) return;
|
||||
|
||||
static boolean valid = false;
|
||||
String log = "";
|
||||
|
||||
HTTPUpload& upload = WebServer.upload();
|
||||
|
||||
@@ -4100,9 +4106,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 +4147,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 +4194,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 +4230,6 @@ bool loadFromFS(boolean spiffs, String path) {
|
||||
#endif
|
||||
}
|
||||
statusLED(true);
|
||||
|
||||
addLog(LOG_LEVEL_DEBUG, log);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -4689,9 +4702,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 +5237,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 +5301,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
|
||||
|
||||
+1
-1
@@ -504,7 +504,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) {"
|
||||
|
||||
+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!"));
|
||||
|
||||
+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
|
||||
|
||||
+14
-11
@@ -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]) {
|
||||
|
||||
@@ -324,11 +324,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);
|
||||
|
||||
@@ -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));
|
||||
|
||||
+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;
|
||||
}
|
||||
|
||||
@@ -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"));
|
||||
|
||||
@@ -167,11 +167,13 @@ boolean Plugin_048(byte function, struct EventStruct *event, String& string) {
|
||||
Adafruit_StepperMotor *myStepper;
|
||||
myStepper = AFMS.getStepper(Plugin_048_MotorStepsPerRevolution, param2.toInt());
|
||||
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")))
|
||||
{
|
||||
|
||||
+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;
|
||||
|
||||
+35
-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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
+11
-7
@@ -215,9 +215,11 @@ 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);
|
||||
success = true;
|
||||
if (paramPos >= 0) {
|
||||
String param = string.substring(paramPos);
|
||||
Plugin_055_AddStringFIFO(param);
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
if (command == F("chimeplay"))
|
||||
{
|
||||
@@ -231,10 +233,12 @@ boolean Plugin_055(byte function, struct EventStruct *event, String& string)
|
||||
{
|
||||
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"));
|
||||
success = true;
|
||||
if (paramPos >= 0) {
|
||||
String param = string.substring(paramPos);
|
||||
Plugin_055_WriteChime(name, param);
|
||||
Plugin_055_AddStringFIFO(F("1"));
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
+28
-22
@@ -1,4 +1,4 @@
|
||||
#ifdef USES_P057
|
||||
#ifdef USES_P057
|
||||
//#######################################################################################################
|
||||
//#################################### Plugin 057: HT16K33 LED ##########################################
|
||||
//#######################################################################################################
|
||||
@@ -157,25 +157,29 @@ boolean Plugin_057(byte function, struct EventStruct *event, String& string)
|
||||
if (command == F("mprint"))
|
||||
{
|
||||
int paramPos = getParamStartPos(lowerString, 2);
|
||||
String text = lowerString.substring(paramPos);
|
||||
byte seg = 0;
|
||||
if (paramPos >= 0) {
|
||||
String text = lowerString.substring(paramPos);
|
||||
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);
|
||||
success = true;
|
||||
if (paramPos >= 0) {
|
||||
uint8_t brightness = lowerString.substring(paramPos).toInt();
|
||||
Plugin_057_M->SetBrightness(brightness);
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
else if (command == F("m") || command == F("mx") || command == F("mnum"))
|
||||
{
|
||||
@@ -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
|
||||
|
||||
+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
|
||||
|
||||
+13
-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,21 @@ 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);
|
||||
}
|
||||
event->BaseVarIndex = event->TaskIndex * VARS_PER_TASK;
|
||||
checkRAM(F("PluginCall_init"),x);
|
||||
START_TIMER;
|
||||
bool retval = Plugin_ptr[x](Function, event, str);
|
||||
STOP_TIMER_TASK(x,Function);
|
||||
return retval;
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user