mirror of
https://github.com/letscontrolit/ESPEasy.git
synced 2026-07-28 12:17:05 +00:00
Compare commits
33
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e0785eb796 | ||
|
|
75a83787a4 | ||
|
|
65bea6343c | ||
|
|
6fe61411a0 | ||
|
|
4552e91022 | ||
|
|
cc94d70e6c | ||
|
|
2435078f76 | ||
|
|
dd2cd50d4b | ||
|
|
fe38eb629d | ||
|
|
e961507456 | ||
|
|
e5ee5644bf | ||
|
|
39c2d54aee | ||
|
|
68efd5ff9e | ||
|
|
627f516f85 | ||
|
|
a45fadf42e | ||
|
|
2ae52b849c | ||
|
|
1d8b6d346b | ||
|
|
2a5ac327d3 | ||
|
|
886101d4d4 | ||
|
|
8fc6486855 | ||
|
|
eeb1cc71b3 | ||
|
|
13837830e8 | ||
|
|
f86ff46a82 | ||
|
|
e901bc957a | ||
|
|
e7e10c5305 | ||
|
|
466ddfbe88 | ||
|
|
c8f02d2a4c | ||
|
|
af1d9b38c9 | ||
|
|
7294217489 | ||
|
|
208fa8a3aa | ||
|
|
b3b8eff127 | ||
|
|
c6a90ab2d0 | ||
|
|
e7d28e8576 |
@@ -1,8 +1,8 @@
|
||||
|Latest Nightly | Build Status | Patreon | Ko-Fi |
|
||||
|-------|-------|-------|-------|
|
||||
| [](https://github.com/letscontrolit/ESPEasy/releases/latest) | [](https://travis-ci.org/letscontrolit/ESPEasy) | [](https://www.patreon.com/GrovkillenTDer) | [](https://ko-fi.com/grovkillentder) |
|
||||
|Latest Nightly | Build Status | Patreon | Ko-Fi | PayPal |
|
||||
|-------|-------|-------|-------|-------|
|
||||
| [](https://github.com/letscontrolit/ESPEasy/releases/latest) | [](https://travis-ci.org/letscontrolit/ESPEasy) | [](https://www.patreon.com/GrovkillenTDer) | [](https://ko-fi.com/grovkillentder) | [](https://www.paypal.me/espeasy) |
|
||||
|
||||
For ways to *support* us, see [this announcement on the forum](https://www.letscontrolit.com/forum/viewtopic.php?f=14&t=5787), or have a look at the [Patreon](https://www.patreon.com/GrovkillenTDer) or [Ko-Fi](https://ko-fi.com/grovkillentder) links above.
|
||||
For ways to *support* us, see [this announcement on the forum](https://www.letscontrolit.com/forum/viewtopic.php?f=14&t=5787), or have a look at the [Patreon](https://www.patreon.com/GrovkillenTDer), [Ko-Fi](https://ko-fi.com/grovkillentder) or [PayPal](https://www.paypal.me/espeasy) links above.
|
||||
|
||||
# ESPEasy (development branch)
|
||||
|
||||
|
||||
Vendored
+54
@@ -0,0 +1,54 @@
|
||||
_____ ____ ____
|
||||
| ____/ ___|| _ \ ___ __ _ ___ _ _
|
||||
| _| \___ \| |_) / _ \/ _` / __| | | |
|
||||
| |___ ___) | __/ __/ (_| \__ \ |_| |
|
||||
|_____|____/|_| \___|\__,_|___/\__, |
|
||||
|___/
|
||||
|
||||
|
||||
This is the distribution folder for ESPeasy.
|
||||
In here you will find a flash tool to program the ESP module.
|
||||
|
||||
Also a number of binary images is included.
|
||||
|
||||
The filename is quite descriptive:
|
||||
ESP_Easy_mega-<date>_<buildType>_<chip>_<memorySize>.bin
|
||||
|
||||
Build type can be: (differ in included plugins)
|
||||
- normal => Only Stable plugins and controllers
|
||||
- test => Stable + Testing
|
||||
- dev => Stable + Testing + Development
|
||||
|
||||
There is also a number of special builds:
|
||||
- normal_IR => "Normal" + IR receiver/transmitter plugins and library
|
||||
- hard_xxxxx => Special builds for some off-the-shelff hardware.
|
||||
|
||||
Chip can be:
|
||||
- ESP8266 => Most likely option
|
||||
- ESP8285 => Used in some Sonoff modules
|
||||
- ESP32 => Experimental support at this moment
|
||||
- ESP8266PUYA => For ESP modules with a flash chip labeled "PUYA" (often 1 MB)
|
||||
|
||||
The "PUYA" version deserves a bit more attention.
|
||||
If you cannot save settings, better try to see if the flash chip has "PUYA" written on it.
|
||||
If so, try the "PUYA" build.
|
||||
|
||||
MemorySize can be:
|
||||
- 1024 => 1 MB flash modules (e.g. almost all Sonoff modules)
|
||||
- 2048 => 2 MB flash modules (e.g. Shelly1)
|
||||
- 4096 => 4 MB flash modules (e.g. NodeMCU)
|
||||
|
||||
|
||||
To help recover from a bad flash, there are also blank images included.
|
||||
- blank_1MB.bin
|
||||
- blank_2MB.bin
|
||||
- blank_4MB.bin
|
||||
|
||||
When the wrong image is flashed, or the module behaves unstable, or is in a reboot loop,
|
||||
flash these images first and then the right image for the module.
|
||||
|
||||
Another great flash tool can be found here: (Windows only)
|
||||
https://github.com/Grovkillen/ESP_Easy_Flasher
|
||||
|
||||
For more information, see: https://github.com/letscontrolit/ESPEasy
|
||||
Or our forum: https://www.letscontrolit.com/forum/
|
||||
Vendored
+60
@@ -1,3 +1,63 @@
|
||||
-------------------------------------------------
|
||||
Changes in release mega-20180914 (since mega-20180910)
|
||||
-------------------------------------------------
|
||||
|
||||
Release date: Fri Sep 14 04:00:17 CEST 2018
|
||||
|
||||
Gijs Noorlander (1):
|
||||
Added PayPal link
|
||||
|
||||
Markus Gloede (1):
|
||||
Fix IR plugin passing received code
|
||||
|
||||
Plebs (7):
|
||||
Use parameters inside rules when calling commands
|
||||
few changes
|
||||
fixed ESP32 compatibility issue
|
||||
fixed calls to F-macro
|
||||
adding more parameters to EVENT
|
||||
final version with '=' sign as a prefix to identify the formula in rules
|
||||
added %eventvalue4%
|
||||
|
||||
TD-er (2):
|
||||
[Flash tools] Add blank files and README.txt
|
||||
[CrashRecover] Disable failing step based on failed boot count
|
||||
|
||||
sakinit (1):
|
||||
Feature: Split webserver spiffs filelist into pages
|
||||
|
||||
|
||||
-------------------------------------------------
|
||||
Changes in release mega-20180910 (since mega-20180909)
|
||||
-------------------------------------------------
|
||||
|
||||
Release date: Mon Sep 10 04:00:22 CEST 2018
|
||||
|
||||
TD-er (2):
|
||||
[HTTP] Command SendToHttp cannot connect
|
||||
[Domoticz IDX] Allow for IDX of > 9999
|
||||
|
||||
sakinit (1):
|
||||
Reduced buffer size to prevent stack overflow
|
||||
|
||||
|
||||
-------------------------------------------------
|
||||
Changes in release mega-20180909 (since mega-20180908)
|
||||
-------------------------------------------------
|
||||
|
||||
Release date: Sun Sep 9 04:00:14 CEST 2018
|
||||
|
||||
Gijs Noorlander (1):
|
||||
Revert [WDT] Add watchdog feed to backgroundtasks()
|
||||
|
||||
TD-er (5):
|
||||
[#1720] WiFi read all lines from slow servers
|
||||
Add forward declaration for void backgroundtasks()
|
||||
[Serial Log] Limit serial log to prevent buffer overflow
|
||||
[ESP32] Fix Build, ESP32 doesn't have the availableForWrite
|
||||
[Serial log] Use buffer to prevent Serial buffer to overflow
|
||||
|
||||
|
||||
-------------------------------------------------
|
||||
Changes in release mega-20180908 (since mega-20180904)
|
||||
-------------------------------------------------
|
||||
|
||||
Vendored
+1
File diff suppressed because one or more lines are too long
Vendored
+1
File diff suppressed because one or more lines are too long
Vendored
+1
File diff suppressed because one or more lines are too long
+5
-5
@@ -216,11 +216,11 @@ void ExecuteCommand(byte source, const char *Line)
|
||||
// since commands can originate from anywhere.
|
||||
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);
|
||||
if (GetArgv(Line, TmpStr1, 2)) TempEvent.Par1 = CalculateParam(TmpStr1);
|
||||
if (GetArgv(Line, TmpStr1, 3)) TempEvent.Par2 = CalculateParam(TmpStr1);
|
||||
if (GetArgv(Line, TmpStr1, 4)) TempEvent.Par3 = CalculateParam(TmpStr1);
|
||||
if (GetArgv(Line, TmpStr1, 5)) TempEvent.Par4 = CalculateParam(TmpStr1);
|
||||
if (GetArgv(Line, TmpStr1, 6)) TempEvent.Par5 = CalculateParam(TmpStr1);
|
||||
|
||||
if (source == VALUE_SOURCE_WEB_FRONTEND) {
|
||||
// Must run immediately, to see result in web frontend
|
||||
|
||||
+2
-1
@@ -24,7 +24,8 @@ String Command_HTTP_SendToHTTP(struct EventStruct *event, const char* Line)
|
||||
}
|
||||
WiFiClient client;
|
||||
const int port_int = port.toInt();
|
||||
if (client.connect(host.c_str(), port_int) != 1) {
|
||||
const bool connected = client.connect(host.c_str(), port_int) == 1;
|
||||
if (connected) {
|
||||
String hostportString = host;
|
||||
if (port_int != 0 && port_int != 80) {
|
||||
hostportString += ':';
|
||||
|
||||
+12
-2
@@ -357,6 +357,9 @@
|
||||
#define SENSOR_TYPE_LONG 20
|
||||
#define SENSOR_TYPE_WIND 21
|
||||
|
||||
#define UNIT_NUMBER_MAX 9999 // Stored in Settings.Unit
|
||||
#define DOMOTICZ_MAX_IDX 999999999 // Looks like it is an unsigned int, so could be up to 4 bln.
|
||||
|
||||
#define VALUE_SOURCE_SYSTEM 1
|
||||
#define VALUE_SOURCE_SERIAL 2
|
||||
#define VALUE_SOURCE_HTTP 3
|
||||
@@ -400,6 +403,7 @@ bool loglevelActiveFor(byte logLevel);
|
||||
void addToLog(byte loglevel, const String& string);
|
||||
void addToLog(byte logLevel, const __FlashStringHelper* flashString);
|
||||
void statusLED(boolean traffic);
|
||||
void backgroundtasks();
|
||||
|
||||
enum SettingsType {
|
||||
BasicSettings_Type = 0,
|
||||
@@ -443,6 +447,7 @@ bool showSettingsFileLayout = false;
|
||||
#include "I2CTypes.h"
|
||||
#include <I2Cdev.h>
|
||||
#include <map>
|
||||
#include <deque>
|
||||
|
||||
#define FS_NO_GLOBALS
|
||||
#if defined(ESP8266)
|
||||
@@ -1240,6 +1245,9 @@ struct LogStruct {
|
||||
|
||||
} Logging;
|
||||
|
||||
std::deque<char> serialLogBuffer;
|
||||
unsigned long last_serial_log_emptied = 0;
|
||||
|
||||
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.
|
||||
@@ -1374,18 +1382,20 @@ struct pinStatesStruct
|
||||
//max 40 bytes: ( 74 - 64 ) * 4
|
||||
struct RTCStruct
|
||||
{
|
||||
RTCStruct() : ID1(0), ID2(0), unused1(false), factoryResetCounter(0),
|
||||
deepSleepState(0), bootFailedCount(0), flashDayCounter(0),
|
||||
flashCounter(0), bootCounter(0) {}
|
||||
byte ID1;
|
||||
byte ID2;
|
||||
boolean unused1;
|
||||
byte factoryResetCounter;
|
||||
byte deepSleepState;
|
||||
byte unused2;
|
||||
byte bootFailedCount;
|
||||
byte flashDayCounter;
|
||||
unsigned long flashCounter;
|
||||
unsigned long bootCounter;
|
||||
} RTC;
|
||||
|
||||
|
||||
int deviceCount = -1;
|
||||
int protocolCount = -1;
|
||||
int notificationCount = -1;
|
||||
|
||||
+21
-2
@@ -158,6 +158,7 @@ void setup()
|
||||
//warm boot
|
||||
if (readFromRTC())
|
||||
{
|
||||
RTC.bootFailedCount++;
|
||||
RTC.bootCounter++;
|
||||
readUserVarFromRTC();
|
||||
|
||||
@@ -193,6 +194,16 @@ void setup()
|
||||
fileSystemCheck();
|
||||
progMemMD5check();
|
||||
LoadSettings();
|
||||
if (RTC.bootFailedCount > 10 && RTC.bootCounter > 10) {
|
||||
byte toDisable = RTC.bootFailedCount - 10;
|
||||
toDisable = disablePlugin(toDisable);
|
||||
if (toDisable != 0) {
|
||||
toDisable = disableController(toDisable);
|
||||
}
|
||||
if (toDisable != 0) {
|
||||
toDisable = disableNotification(toDisable);
|
||||
}
|
||||
}
|
||||
|
||||
// setWifiMode(WIFI_STA);
|
||||
checkRuleSets();
|
||||
@@ -465,7 +476,10 @@ void loop()
|
||||
firstLoop = false;
|
||||
timerAwakeFromDeepSleep = millis(); // Allow to run for "awake" number of seconds, now we have wifi.
|
||||
// schedule_all_task_device_timers(); Disabled for now, since we are now using queues for controllers.
|
||||
}
|
||||
|
||||
RTC.bootFailedCount = 0;
|
||||
saveToRTC();
|
||||
}
|
||||
|
||||
// Deep sleep mode, just run all tasks one (more) time and go back to sleep as fast as possible
|
||||
if ((firstLoopConnectionsEstablished || readyForSleep()) && isDeepSleepEnabled())
|
||||
@@ -828,11 +842,16 @@ void backgroundtasks()
|
||||
//checkRAM(F("backgroundtasks"));
|
||||
//always start with a yield
|
||||
yield();
|
||||
/*
|
||||
// Remove this watchdog feed for now.
|
||||
// See https://github.com/letscontrolit/ESPEasy/issues/1722#issuecomment-419659193
|
||||
|
||||
#ifdef ESP32
|
||||
// Have to find a similar function to call ESP32's esp_task_wdt_feed();
|
||||
#else
|
||||
ESP.wdtFeed();
|
||||
#endif
|
||||
*/
|
||||
|
||||
//prevent recursion!
|
||||
if (runningBackgroundTasks)
|
||||
@@ -844,7 +863,7 @@ void backgroundtasks()
|
||||
#if defined(ESP8266)
|
||||
tcpCleanup();
|
||||
#endif
|
||||
|
||||
process_serialLogBuffer();
|
||||
if(!UseRTOSMultitasking){
|
||||
if (Settings.UseSerial)
|
||||
if (Serial.available())
|
||||
|
||||
@@ -219,6 +219,51 @@ String LoadSettings()
|
||||
return(err);
|
||||
}
|
||||
|
||||
/********************************************************************************************\
|
||||
Disable Plugin, based on bootFailedCount
|
||||
\*********************************************************************************************/
|
||||
byte disablePlugin(byte bootFailedCount) {
|
||||
for (byte i = 0; i < TASKS_MAX && bootFailedCount > 0; ++i) {
|
||||
if (Settings.TaskDeviceEnabled[i]) {
|
||||
--bootFailedCount;
|
||||
if (bootFailedCount == 0) {
|
||||
Settings.TaskDeviceEnabled[i] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return bootFailedCount;
|
||||
}
|
||||
|
||||
/********************************************************************************************\
|
||||
Disable Controller, based on bootFailedCount
|
||||
\*********************************************************************************************/
|
||||
byte disableController(byte bootFailedCount) {
|
||||
for (byte i = 0; i < CONTROLLER_MAX && bootFailedCount > 0; ++i) {
|
||||
if (Settings.ControllerEnabled[i]) {
|
||||
--bootFailedCount;
|
||||
if (bootFailedCount == 0) {
|
||||
Settings.ControllerEnabled[i] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return bootFailedCount;
|
||||
}
|
||||
|
||||
/********************************************************************************************\
|
||||
Disable Notification, based on bootFailedCount
|
||||
\*********************************************************************************************/
|
||||
byte disableNotification(byte bootFailedCount) {
|
||||
for (byte i = 0; i < NOTIFICATION_MAX && bootFailedCount > 0; ++i) {
|
||||
if (Settings.NotificationEnabled[i]) {
|
||||
--bootFailedCount;
|
||||
if (bootFailedCount == 0) {
|
||||
Settings.NotificationEnabled[i] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return bootFailedCount;
|
||||
}
|
||||
|
||||
/********************************************************************************************\
|
||||
Offsets in settings files
|
||||
\*********************************************************************************************/
|
||||
|
||||
+110
-9
@@ -365,11 +365,11 @@ void parseCommandString(struct EventStruct *event, const String& string)
|
||||
event->Par4 = 0;
|
||||
event->Par5 = 0;
|
||||
|
||||
if (GetArgv(command, TmpStr1, 2)) event->Par1 = str2int(TmpStr1);
|
||||
if (GetArgv(command, TmpStr1, 3)) event->Par2 = str2int(TmpStr1);
|
||||
if (GetArgv(command, TmpStr1, 4)) event->Par3 = str2int(TmpStr1);
|
||||
if (GetArgv(command, TmpStr1, 5)) event->Par4 = str2int(TmpStr1);
|
||||
if (GetArgv(command, TmpStr1, 6)) event->Par5 = str2int(TmpStr1);
|
||||
if (GetArgv(command, TmpStr1, 2)) event->Par1 = CalculateParam(TmpStr1);
|
||||
if (GetArgv(command, TmpStr1, 3)) event->Par2 = CalculateParam(TmpStr1);
|
||||
if (GetArgv(command, TmpStr1, 4)) event->Par3 = CalculateParam(TmpStr1);
|
||||
if (GetArgv(command, TmpStr1, 5)) event->Par4 = CalculateParam(TmpStr1);
|
||||
if (GetArgv(command, TmpStr1, 6)) event->Par5 = CalculateParam(TmpStr1);
|
||||
}
|
||||
|
||||
/********************************************************************************************\
|
||||
@@ -1162,10 +1162,23 @@ boolean loglevelActive(byte logLevel, byte logLevelSettings) {
|
||||
|
||||
void addToLog(byte logLevel, const char *line)
|
||||
{
|
||||
const size_t line_length = strlen(line);
|
||||
if (loglevelActiveFor(LOG_TO_SERIAL, logLevel)) {
|
||||
Serial.print(millis());
|
||||
Serial.print(F(" : "));
|
||||
Serial.println(line);
|
||||
int roomLeft = ESP.getFreeHeap() - 5000;
|
||||
if (roomLeft > 0) {
|
||||
String timestamp_log(millis());
|
||||
timestamp_log += F(" : ");
|
||||
for (size_t i = 0; i < timestamp_log.length(); ++i) {
|
||||
serialLogBuffer.push_back(timestamp_log[i]);
|
||||
}
|
||||
size_t pos = 0;
|
||||
while (pos < line_length && pos < static_cast<size_t>(roomLeft)) {
|
||||
serialLogBuffer.push_back(line[pos]);
|
||||
++pos;
|
||||
}
|
||||
serialLogBuffer.push_back('\r');
|
||||
serialLogBuffer.push_back('\n');
|
||||
}
|
||||
}
|
||||
if (loglevelActiveFor(LOG_TO_SYSLOG, logLevel)) {
|
||||
syslog(logLevel, line);
|
||||
@@ -1184,6 +1197,25 @@ void addToLog(byte logLevel, const char *line)
|
||||
#endif
|
||||
}
|
||||
|
||||
void process_serialLogBuffer() {
|
||||
if (serialLogBuffer.size() == 0) return;
|
||||
if (timePassedSince(last_serial_log_emptied) > 10000) {
|
||||
last_serial_log_emptied = millis();
|
||||
serialLogBuffer.clear();
|
||||
return;
|
||||
}
|
||||
size_t snip = 128; // Some default, ESP32 doesn't have the availableForWrite function yet.
|
||||
#if defined(ESP8266)
|
||||
snip = Serial.availableForWrite();
|
||||
#endif
|
||||
if (snip > 0) last_serial_log_emptied = millis();
|
||||
size_t bytes_to_write = serialLogBuffer.size();
|
||||
if (snip < bytes_to_write) bytes_to_write = snip;
|
||||
for (size_t i = 0; i < bytes_to_write; ++i) {
|
||||
Serial.write(serialLogBuffer.front());
|
||||
serialLogBuffer.pop_front();
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************************************\
|
||||
Delayed reboot, in case of issues, do not reboot with high frequency as it might not help...
|
||||
@@ -1788,6 +1820,12 @@ int Calculate(const char *input, float* result)
|
||||
//*sp=0; // bug, it stops calculating after 50 times
|
||||
sp = globalstack - 1;
|
||||
oc=c=0;
|
||||
|
||||
if (input[0] == '=') {
|
||||
++strpos;
|
||||
c = *strpos;
|
||||
}
|
||||
|
||||
while (strpos < strend)
|
||||
{
|
||||
// read one token from the input stream
|
||||
@@ -1913,6 +1951,56 @@ int Calculate(const char *input, float* result)
|
||||
return CALCULATE_OK;
|
||||
}
|
||||
|
||||
int CalculateParam(char *TmpStr) {
|
||||
int returnValue;
|
||||
|
||||
// Minimize calls to the Calulate function.
|
||||
// Only if TmpStr starts with '=' then call Calculate(). Otherwise do not call it
|
||||
if (TmpStr[0] != '=') {
|
||||
returnValue=str2int(TmpStr);
|
||||
} else {
|
||||
float param=0;
|
||||
TmpStr[0] = ' '; //replace '=' with space
|
||||
int returnCode=Calculate(TmpStr, ¶m);
|
||||
if (returnCode!=CALCULATE_OK) {
|
||||
String errorDesc;
|
||||
switch (returnCode) {
|
||||
case CALCULATE_ERROR_STACK_OVERFLOW:
|
||||
errorDesc = F("Stack Overflow");
|
||||
break;
|
||||
case CALCULATE_ERROR_BAD_OPERATOR:
|
||||
errorDesc = F("Bad Operator");
|
||||
break;
|
||||
case CALCULATE_ERROR_PARENTHESES_MISMATCHED:
|
||||
errorDesc = F("Parenthesis mismatch");
|
||||
break;
|
||||
case CALCULATE_ERROR_UNKNOWN_TOKEN:
|
||||
errorDesc = F("Unknown token");
|
||||
break;
|
||||
default:
|
||||
errorDesc = F("Unknown error");
|
||||
break;
|
||||
}
|
||||
String log = String(F("CALCULATE PARAM ERROR: ")) + errorDesc;
|
||||
addLog(LOG_LEVEL_ERROR, log);
|
||||
log = F("CALCULATE PARAM ERROR details: ");
|
||||
log += TmpStr;
|
||||
log += F(" = ");
|
||||
log += round(param);
|
||||
addLog(LOG_LEVEL_ERROR, log);
|
||||
} else {
|
||||
if (loglevelActiveFor(LOG_LEVEL_DEBUG)) {
|
||||
String log = F("CALCULATE PARAM: ");
|
||||
log += TmpStr;
|
||||
log += F(" = ");
|
||||
log += round(param);
|
||||
addLog(LOG_LEVEL_DEBUG, log);
|
||||
}
|
||||
}
|
||||
returnValue=round(param); //return integer only as it's valid only for device and task id
|
||||
}
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
void checkRuleSets(){
|
||||
for (byte x=0; x < RULESETS_MAX; x++){
|
||||
@@ -2222,7 +2310,20 @@ void processMatchedRule(
|
||||
if (equalsPos > 0)
|
||||
{
|
||||
String tmpString = event.substring(equalsPos + 1);
|
||||
action.replace(F("%eventvalue%"), tmpString); // substitute %eventvalue% in actions with the actual value from the event
|
||||
|
||||
char command[INPUT_COMMAND_SIZE];
|
||||
command[0] = 0;
|
||||
char tmpParam[INPUT_COMMAND_SIZE];
|
||||
tmpParam[0] = 0;
|
||||
tmpString.toCharArray(command, INPUT_COMMAND_SIZE);
|
||||
|
||||
if (GetArgv(command,tmpParam,1)) {
|
||||
action.replace(F("%eventvalue%"), tmpParam); // for compatibility issues
|
||||
action.replace(F("%eventvalue1%"), tmpParam); // substitute %eventvalue1% in actions with the actual value from the event
|
||||
}
|
||||
if (GetArgv(command,tmpParam,2)) action.replace(F("%eventvalue2%"), tmpParam); // substitute %eventvalue2% in actions with the actual value from the event
|
||||
if (GetArgv(command,tmpParam,3)) action.replace(F("%eventvalue3%"), tmpParam); // substitute %eventvalue3% in actions with the actual value from the event
|
||||
if (GetArgv(command,tmpParam,4)) action.replace(F("%eventvalue4%"), tmpParam); // substitute %eventvalue4% in actions with the actual value from the event
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+42
-3
@@ -1082,7 +1082,7 @@ void handle_config() {
|
||||
Settings.Name[25] = 0;
|
||||
SecuritySettings.Password[25] = 0;
|
||||
addFormTextBox( F("Unit Name"), F("name"), Settings.Name, 25);
|
||||
addFormNumericBox( F("Unit Number"), F("unit"), Settings.Unit, 0, 9999);
|
||||
addFormNumericBox( F("Unit Number"), F("unit"), Settings.Unit, 0, UNIT_NUMBER_MAX);
|
||||
addFormPasswordBox(F("Admin Password"), F("password"), SecuritySettings.Password, 25);
|
||||
|
||||
addFormSubHeader(F("Wifi Settings"));
|
||||
@@ -2283,7 +2283,7 @@ void handle_devices() {
|
||||
html_TR_TD(); TXBuffer += F("IDX:<TD>");
|
||||
id = F("TDID"); //="taskdeviceid"
|
||||
id += controllerNr + 1;
|
||||
addNumericBox(id, Settings.TaskDeviceID[controllerNr][taskIndex], 0, 999999999); // Looks like it is an unsigned int, so could be up to 4 bln.
|
||||
addNumericBox(id, Settings.TaskDeviceID[controllerNr][taskIndex], 0, DOMOTICZ_MAX_IDX);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4569,18 +4569,40 @@ void handle_filelist() {
|
||||
checkRuleSets();
|
||||
}
|
||||
|
||||
const int pageSize = 25;
|
||||
int startIdx = 0;
|
||||
|
||||
String fstart = WebServer.arg(F("start"));
|
||||
if (fstart.length() > 0)
|
||||
{
|
||||
startIdx = atoi(fstart.c_str());
|
||||
}
|
||||
int endIdx = startIdx + pageSize - 1;
|
||||
|
||||
TXBuffer += F("<table class='multirow' border=1px frame='box' rules='all'><TH style='width:50px;'><TH>Filename<TH style='width:80px;'>Size");
|
||||
|
||||
fs::Dir dir = SPIFFS.openDir("");
|
||||
|
||||
int count = -1;
|
||||
while (dir.next())
|
||||
{
|
||||
++count;
|
||||
|
||||
if (count < startIdx)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
html_TR_TD();
|
||||
if (dir.fileName() != F(FILE_CONFIG) && dir.fileName() != F(FILE_SECURITY) && dir.fileName() != F(FILE_NOTIFICATION))
|
||||
{
|
||||
TXBuffer += F("<a class='button link' href=\"filelist?delete=");
|
||||
TXBuffer += dir.fileName();
|
||||
if (startIdx > 0)
|
||||
{
|
||||
TXBuffer += F("&start=");
|
||||
TXBuffer += startIdx;
|
||||
}
|
||||
TXBuffer += F("\">Del</a>");
|
||||
}
|
||||
|
||||
@@ -4592,9 +4614,26 @@ void handle_filelist() {
|
||||
fs::File f = dir.openFile("r");
|
||||
html_TD();
|
||||
TXBuffer += f.size();
|
||||
if (count >= endIdx)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
TXBuffer += F("</table></form>");
|
||||
TXBuffer += F("<BR><a class='button link' href=\"/upload\">Upload</a><BR><BR>");
|
||||
TXBuffer += F("<BR><a class='button link' href=\"/upload\">Upload</a>");
|
||||
if (startIdx > 0)
|
||||
{
|
||||
TXBuffer += F("<a class='button link' href=\"/filelist?start=");
|
||||
TXBuffer += max(0, startIdx - pageSize);
|
||||
TXBuffer += F("\">Previous</a>");
|
||||
}
|
||||
if (count >= endIdx and dir.next())
|
||||
{
|
||||
TXBuffer += F("<a class='button link' href=\"/filelist?start=");
|
||||
TXBuffer += endIdx + 1;
|
||||
TXBuffer += F("\">Next</a>");
|
||||
}
|
||||
TXBuffer += F("<BR><BR>");
|
||||
sendHeadandTail(F("TmplStd"),true);
|
||||
TXBuffer.endStream();
|
||||
#endif
|
||||
|
||||
+2
-2
@@ -82,7 +82,7 @@ bool do_process_c003_delay_queue(int controller_number, const C003_queue_element
|
||||
delay(1);
|
||||
|
||||
timer = millis() + 1000;
|
||||
while (client.available() && !timeOutReached(timer) && !success)
|
||||
while (client_available(client) && !timeOutReached(timer) && !success)
|
||||
{
|
||||
|
||||
// String line = client.readStringUntil('\n');
|
||||
@@ -109,7 +109,7 @@ bool do_process_c003_delay_queue(int controller_number, const C003_queue_element
|
||||
addLog(LOG_LEVEL_DEBUG, log);
|
||||
client.print(element.txt);
|
||||
delay(10);
|
||||
while (client.available())
|
||||
while (client_available(client))
|
||||
client.read();
|
||||
|
||||
strcpy_P(log, PSTR("TELNT: closing connection"));
|
||||
|
||||
+2
-2
@@ -113,7 +113,7 @@ boolean Blynk_get(const String& command, byte controllerIndex, float *data )
|
||||
char log[80] = {0};
|
||||
|
||||
// Read all the lines of the reply from server and log them
|
||||
while (client.available()) {
|
||||
while (client_available(client)) {
|
||||
String line;
|
||||
safeReadStringUntil(client, line, '\n');
|
||||
addLog(LOG_LEVEL_DEBUG_MORE, line);
|
||||
@@ -154,7 +154,7 @@ boolean Blynk_get(const String& command, byte controllerIndex, float *data )
|
||||
client.flush();
|
||||
client.stop();
|
||||
|
||||
// important - backgroudtasks - free mem
|
||||
// important - backgroundtasks - free mem
|
||||
timer = millis() + Settings.MessageDelay;
|
||||
while (!timeOutReached(timer))
|
||||
backgroundtasks();
|
||||
|
||||
+18
-3
@@ -380,7 +380,9 @@ ControllerDelayHandlerStruct<MQTT_queue_element> MQTTDelayHandler;
|
||||
bool safeReadStringUntil(Stream &input, String &str, char terminator, unsigned int maxSize = 1024, unsigned int timeout = 1000)
|
||||
{
|
||||
int c;
|
||||
const unsigned long timer = millis() + timeout;
|
||||
const unsigned long start = millis();
|
||||
const unsigned long timer = start + timeout;
|
||||
unsigned long backgroundtasks_timer = start + 100;
|
||||
str = "";
|
||||
|
||||
do {
|
||||
@@ -401,7 +403,13 @@ bool safeReadStringUntil(Stream &input, String &str, char terminator, unsigned i
|
||||
}
|
||||
}
|
||||
}
|
||||
yield();
|
||||
// We must run the backgroundtasks every now and then.
|
||||
if (timeOutReached(backgroundtasks_timer)) {
|
||||
backgroundtasks_timer += 100;
|
||||
backgroundtasks();
|
||||
} else {
|
||||
yield();
|
||||
}
|
||||
} while (!timeOutReached(timer));
|
||||
|
||||
addLog(LOG_LEVEL_ERROR, F("Timeout while reading input data!"));
|
||||
@@ -592,6 +600,13 @@ bool try_connect_host(int controller_number, WiFiClient& client, ControllerSetti
|
||||
F("HTTP : "), controller_number, ControllerSettings);
|
||||
}
|
||||
|
||||
// Use "client.available() || client.connected()" to read all lines from slow servers.
|
||||
// See: https://github.com/esp8266/Arduino/pull/5113
|
||||
// https://github.com/esp8266/Arduino/pull/1829
|
||||
bool client_available(WiFiClient& client) {
|
||||
return client.available() || client.connected();
|
||||
}
|
||||
|
||||
bool send_via_http(const String& logIdentifier, WiFiClient& client, const String& postStr) {
|
||||
bool success = false;
|
||||
// This will send the request to the server
|
||||
@@ -602,7 +617,7 @@ bool send_via_http(const String& logIdentifier, WiFiClient& client, const String
|
||||
delay(1);
|
||||
|
||||
// Read all the lines of the reply from server and print them to Serial
|
||||
while (client.available() && !success) {
|
||||
while (client_available(client) && !success) {
|
||||
// String line = client.readStringUntil('\n');
|
||||
String line;
|
||||
safeReadStringUntil(client, line, '\n');
|
||||
|
||||
@@ -155,7 +155,10 @@ boolean Plugin_016(byte function, struct EventStruct *event, String& string)
|
||||
{
|
||||
if (irReceiver->decode(&results))
|
||||
{
|
||||
unsigned long IRcode = results.value;
|
||||
irReceiver->resume();
|
||||
UserVar[event->BaseVarIndex] = (IRcode & 0xFFFF);
|
||||
UserVar[event->BaseVarIndex + 1] = ((IRcode >> 16) & 0xFFFF);
|
||||
String log = "IR: ";
|
||||
if (results.overflow)
|
||||
log += F("WARNING: IR code is too big for buffer. This result shouldn't be trusted until this is resolved. Edit & increase CAPTURE_BUFFER_SIZE.\n");
|
||||
|
||||
@@ -53,7 +53,7 @@ boolean Plugin_029(byte function, struct EventStruct *event, String& string)
|
||||
addHtml(F("<TR><TD>IDX:<TD>"));
|
||||
String id = F("TDID"); //="taskdeviceid"
|
||||
id += controllerNr + 1;
|
||||
addNumericBox(id, Settings.TaskDeviceID[controllerNr][event->TaskIndex], 0, 9999);
|
||||
addNumericBox(id, Settings.TaskDeviceID[controllerNr][event->TaskIndex], 0, DOMOTICZ_MAX_IDX);
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
|
||||
+16
-12
@@ -16,7 +16,7 @@
|
||||
|
||||
#define P044_STATUS_LED 12
|
||||
#define P044_BUFFER_SIZE 1024
|
||||
#define P044_NETBUF_SIZE 600
|
||||
#define P044_NETBUF_SIZE 128
|
||||
#define P044_DISABLED 0
|
||||
#define P044_WAITING 1
|
||||
#define P044_READING 2
|
||||
@@ -31,7 +31,7 @@ boolean CRCcheck = false;
|
||||
unsigned int currCRC = 0;
|
||||
int checkI = 0;
|
||||
|
||||
WiFiServer *P1GatewayServer;
|
||||
WiFiServer *P1GatewayServer = nullptr;
|
||||
WiFiClient P1GatewayClient;
|
||||
|
||||
boolean Plugin_044(byte function, struct EventStruct *event, String& string)
|
||||
@@ -125,7 +125,11 @@ boolean Plugin_044(byte function, struct EventStruct *event, String& string)
|
||||
#if defined(ESP32)
|
||||
Serial.begin(ExtraTaskSettings.TaskDevicePluginConfigLong[1], serialconfig);
|
||||
#endif
|
||||
if (P1GatewayServer) P1GatewayServer->close();
|
||||
if (P1GatewayServer)
|
||||
{
|
||||
P1GatewayServer->close();
|
||||
delete P1GatewayServer;
|
||||
}
|
||||
P1GatewayServer = new WiFiServer(ExtraTaskSettings.TaskDevicePluginConfigLong[0]);
|
||||
P1GatewayServer->begin();
|
||||
|
||||
@@ -164,7 +168,7 @@ boolean Plugin_044(byte function, struct EventStruct *event, String& string)
|
||||
{
|
||||
if (P1GatewayServer) {
|
||||
P1GatewayServer->close();
|
||||
//FIXME: shouldnt P1P1GatewayServer be deleted?
|
||||
delete P1GatewayServer;
|
||||
P1GatewayServer = NULL;
|
||||
}
|
||||
success = true;
|
||||
@@ -175,7 +179,6 @@ boolean Plugin_044(byte function, struct EventStruct *event, String& string)
|
||||
{
|
||||
if (Plugin_044_init)
|
||||
{
|
||||
size_t bytes_read;
|
||||
if (P1GatewayServer->hasClient())
|
||||
{
|
||||
if (P1GatewayClient) P1GatewayClient.stop();
|
||||
@@ -186,24 +189,25 @@ boolean Plugin_044(byte function, struct EventStruct *event, String& string)
|
||||
if (P1GatewayClient.connected())
|
||||
{
|
||||
connectionState = 1;
|
||||
uint8_t net_buf[P044_BUFFER_SIZE];
|
||||
uint8_t net_buf[P044_NETBUF_SIZE];
|
||||
int count = P1GatewayClient.available();
|
||||
if (count > 0)
|
||||
{
|
||||
if (count > P044_BUFFER_SIZE)
|
||||
count = P044_BUFFER_SIZE;
|
||||
bytes_read = P1GatewayClient.read(net_buf, count);
|
||||
Serial.write(net_buf, bytes_read);
|
||||
size_t net_bytes_read;
|
||||
if (count > P044_NETBUF_SIZE)
|
||||
count = P044_NETBUF_SIZE;
|
||||
net_bytes_read = P1GatewayClient.read(net_buf, count);
|
||||
Serial.write(net_buf, net_bytes_read);
|
||||
Serial.flush(); // Waits for the transmission of outgoing serial data to complete
|
||||
|
||||
if (count == P044_BUFFER_SIZE) // if we have a full buffer, drop the last position to stuff with string end marker
|
||||
if (count == P044_NETBUF_SIZE) // if we have a full buffer, drop the last position to stuff with string end marker
|
||||
{
|
||||
count--;
|
||||
// and log buffer full situation
|
||||
addLog(LOG_LEVEL_ERROR, F("P1 : Error: network buffer full!"));
|
||||
}
|
||||
net_buf[count] = 0; // before logging as a char array, zero terminate the last position to be safe.
|
||||
char log[P044_BUFFER_SIZE + 40];
|
||||
char log[P044_NETBUF_SIZE + 40];
|
||||
sprintf_P(log, PSTR("P1 : Error: N>: %s"), (char*)net_buf);
|
||||
addLog(LOG_LEVEL_DEBUG, log);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user