mirror of
https://github.com/letscontrolit/ESPEasy.git
synced 2026-07-27 19:57:38 +00:00
Merge branch 'mega' into feature/P111_rc522_rfid
This commit is contained in:
@@ -61,6 +61,8 @@ before WiFi connection is made or during lost connection.
|
||||
- **Max Queue Depth** - Maximum length of the buffer queue to keep unsent messages.
|
||||
- **Max Retries** - Maximum number of retries to send a message.
|
||||
- **Full Queue Action** - How to handle when queue is full, ignore new or delete oldest message.
|
||||
- **Allow Expire** - Remove a queued message from the queue after <timeout> x <queue depth> x <retries>.
|
||||
- **De-duplicate** - Do not add a message to the queue if the same message from the same task is already present.
|
||||
- **Check Reply** - When set to false, a sent message is considered always successful.
|
||||
- **Client Timeout** - Timeout in msec for an network connection used by the controller.
|
||||
- **Sample Set Initiator** - Some controllers (e.g. C018 LoRa/TTN) can mark samples to belong to a set of samples. A new sample from set task index will increment this counter.
|
||||
|
||||
@@ -51,7 +51,7 @@ The NodeMCU boards have almost all usable pins made available and some which nee
|
||||
- :yellow:`Boot fail if pulled high`
|
||||
* - 16 (D0)
|
||||
- :red:`High at boot, pull down to GND`:yellow:`no interrupt`
|
||||
- :yellow:`no PWM / I2C support`
|
||||
- :yellow:`no I2C support`
|
||||
- Used to wake up from deep sleep
|
||||
* - 9 (SD2)
|
||||
- :red:`High at boot`
|
||||
@@ -248,4 +248,4 @@ GPIO 9, 10 & 11 output high at boot and may fail to boot of pulled either high o
|
||||
Pins used for RMII Ethernet PHY
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. include:: ../Reference/Ethernet_PHY_ESP32.rst
|
||||
.. include:: ../Reference/Ethernet_PHY_ESP32.rst
|
||||
|
||||
@@ -139,8 +139,8 @@ platform_packages =
|
||||
[core_esp32_1_12_2]
|
||||
platform = espressif32@1.12.4
|
||||
|
||||
[core_esp32_2_1_0]
|
||||
platform = espressif32@2.1.0
|
||||
[core_esp32_3_1_0]
|
||||
platform = espressif32@3.1.0
|
||||
|
||||
|
||||
[core_esp32_stage]
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
|
||||
[esp32_common]
|
||||
extends = common, core_esp32_2_1_0
|
||||
extends = common, core_esp32_3_1_0
|
||||
lib_ignore = ESP8266WiFi, ESP8266Ping, ESP8266WebServer, ESP8266HTTPUpdateServer, ESP8266mDNS, IRremoteESP8266, ESPEasy_ESP8266Ping, ESP32_ping, HeatpumpIR
|
||||
lib_deps = https://github.com/TD-er/ESPEasySerial.git#v2.0.5, adafruit/Adafruit ILI9341 @ ^1.5.6, Adafruit GFX Library, LOLIN_EPD, Adafruit BusIO
|
||||
board_build.f_flash = 80000000L
|
||||
|
||||
@@ -388,6 +388,13 @@ build_flags = ${normal_ir_extended_no_rx.build_flags}
|
||||
; Includes "normal" + "testing" plugins ;
|
||||
; *********************************************************************
|
||||
|
||||
[env:test_ESP8266_4M1M]
|
||||
extends = esp8266_4M1M
|
||||
platform = ${testing.platform}
|
||||
platform_packages = ${testing.platform_packages}
|
||||
build_flags = ${testing.build_flags}
|
||||
${esp8266_4M1M.build_flags}
|
||||
|
||||
|
||||
; TEST: 4096k version + FEATURE_ADC_VCC ----------
|
||||
[env:test_ESP8266_4M1M_VCC]
|
||||
|
||||
@@ -62,6 +62,8 @@
|
||||
// See: https://github.com/letscontrolit/ESPEasy/issues/2724
|
||||
#define DEFAULT_SEND_TO_HTTP_ACK false // Wait for ack with SendToHttp command.
|
||||
|
||||
#define DEFAULT_AP_DONT_FORCE_SETUP false // Allow optional usage of Sensor without WIFI avaiable // When set you can use the Sensor in AP-Mode without beeing forced to /setup
|
||||
|
||||
// --- Default Controller ------------------------------------------------------------------------------
|
||||
#define DEFAULT_CONTROLLER false // true or false enabled or disabled, set 1st controller
|
||||
// defaults
|
||||
|
||||
+23
-17
@@ -328,15 +328,6 @@ void setup()
|
||||
// progMemMD5check();
|
||||
LoadSettings();
|
||||
|
||||
#ifdef HAS_ETHERNET
|
||||
// This ensures, that changing WIFI OR ETHERNET MODE happens properly only after reboot. Changing without reboot would not be a good idea.
|
||||
// This only works after LoadSettings();
|
||||
active_network_medium = Settings.NetworkMedium;
|
||||
log = F("INIT : ETH_WIFI_MODE:");
|
||||
log += toString(active_network_medium);
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
#endif
|
||||
|
||||
Settings.UseRTOSMultitasking = false; // For now, disable it, we experience heap corruption.
|
||||
if (RTC.bootFailedCount > 10 && RTC.bootCounter > 10) {
|
||||
byte toDisable = RTC.bootFailedCount - 10;
|
||||
@@ -348,12 +339,19 @@ void setup()
|
||||
toDisable = disableNotification(toDisable);
|
||||
}
|
||||
}
|
||||
if (!WiFi_AP_Candidates.hasKnownCredentials()) {
|
||||
WiFiEventData.wifiSetup = true;
|
||||
RTC.clearLastWiFi(); // Must scan all channels
|
||||
// Wait until scan has finished to make sure as many as possible are found
|
||||
// We're still in the setup phase, so nothing else is taking resources of the ESP.
|
||||
WifiScan(false);
|
||||
#ifdef HAS_ETHERNET
|
||||
// This ensures, that changing WIFI OR ETHERNET MODE happens properly only after reboot. Changing without reboot would not be a good idea.
|
||||
// This only works after LoadSettings();
|
||||
setNetworkMedium(Settings.NetworkMedium);
|
||||
#endif
|
||||
if (active_network_medium == NetworkMedium_t::WIFI) {
|
||||
if (!WiFi_AP_Candidates.hasKnownCredentials()) {
|
||||
WiFiEventData.wifiSetup = true;
|
||||
RTC.clearLastWiFi(); // Must scan all channels
|
||||
// Wait until scan has finished to make sure as many as possible are found
|
||||
// We're still in the setup phase, so nothing else is taking resources of the ESP.
|
||||
WifiScan(false);
|
||||
}
|
||||
}
|
||||
|
||||
// setWifiMode(WIFI_STA);
|
||||
@@ -375,8 +373,9 @@ void setup()
|
||||
|
||||
initSerial();
|
||||
|
||||
if (Settings.Build != BUILD)
|
||||
if (Settings.Build != BUILD) {
|
||||
BuildFixes();
|
||||
}
|
||||
|
||||
|
||||
log = F("INIT : Free RAM:");
|
||||
@@ -692,14 +691,21 @@ void backgroundtasks()
|
||||
return;
|
||||
}
|
||||
START_TIMER
|
||||
const bool networkConnected = NetworkConnected();
|
||||
#if defined(FEATURE_ARDUINO_OTA) || defined(FEATURE_MDNS)
|
||||
const bool networkConnected =
|
||||
#endif
|
||||
NetworkConnected();
|
||||
runningBackgroundTasks=true;
|
||||
|
||||
/*
|
||||
// Not needed anymore, see: https://arduino-esp8266.readthedocs.io/en/latest/faq/readme.html#how-to-clear-tcp-pcbs-in-time-wait-state
|
||||
if (networkConnected) {
|
||||
#if defined(ESP8266)
|
||||
tcpCleanup();
|
||||
#endif
|
||||
}
|
||||
*/
|
||||
|
||||
process_serialWriteBuffer();
|
||||
if(!UseRTOSMultitasking){
|
||||
serial();
|
||||
|
||||
+1
-1
@@ -112,7 +112,7 @@ bool CPlugin_001(CPlugin::Function function, struct EventStruct *event, String&
|
||||
url += mapVccToDomoticz();
|
||||
# endif // if FEATURE_ADC_VCC
|
||||
|
||||
success = C001_DelayHandler->addToQueue(C001_queue_element(event->ControllerIndex, url));
|
||||
success = C001_DelayHandler->addToQueue(C001_queue_element(event->ControllerIndex, event->TaskIndex, url));
|
||||
Scheduler.scheduleNextDelayQueue(ESPEasy_Scheduler::IntervalTimer_e::TIMER_C001_DELAY_QUEUE,
|
||||
C001_DelayHandler->getNextScheduleTime());
|
||||
} // if ixd !=0
|
||||
|
||||
+1
-1
@@ -267,7 +267,7 @@ bool CPlugin_002(CPlugin::Function function, struct EventStruct *event, String&
|
||||
String pubname = CPlugin_002_pubname;
|
||||
parseControllerVariables(pubname, event, false);
|
||||
|
||||
success = MQTTpublish(event->ControllerIndex, pubname.c_str(), json.c_str(), CPlugin_002_mqtt_retainFlag);
|
||||
success = MQTTpublish(event->ControllerIndex, event->TaskIndex, pubname.c_str(), json.c_str(), CPlugin_002_mqtt_retainFlag);
|
||||
} // if ixd !=0
|
||||
else
|
||||
{
|
||||
|
||||
+1
-1
@@ -56,7 +56,7 @@ bool CPlugin_003(CPlugin::Function function, struct EventStruct *event, String&
|
||||
url += ",";
|
||||
url += formatUserVarNoCheck(event, 0);
|
||||
url += "\n";
|
||||
success = C003_DelayHandler->addToQueue(C003_queue_element(event->ControllerIndex, url));
|
||||
success = C003_DelayHandler->addToQueue(C003_queue_element(event->ControllerIndex, event->TaskIndex, url));
|
||||
Scheduler.scheduleNextDelayQueue(ESPEasy_Scheduler::IntervalTimer_e::TIMER_C003_DELAY_QUEUE, C003_DelayHandler->getNextScheduleTime());
|
||||
|
||||
break;
|
||||
|
||||
+2
-2
@@ -152,11 +152,11 @@ bool CPlugin_005(CPlugin::Function function, struct EventStruct *event, String&
|
||||
|
||||
// Small optimization so we don't try to copy potentially large strings
|
||||
if (event->sensorType == Sensor_VType::SENSOR_TYPE_STRING) {
|
||||
MQTTpublish(event->ControllerIndex, tmppubname.c_str(), event->String2.c_str(), mqtt_retainFlag);
|
||||
MQTTpublish(event->ControllerIndex, event->TaskIndex, tmppubname.c_str(), event->String2.c_str(), mqtt_retainFlag);
|
||||
value = event->String2.substring(0, 20); // For the log
|
||||
} else {
|
||||
value = formatUserVarNoCheck(event, x);
|
||||
MQTTpublish(event->ControllerIndex, tmppubname.c_str(), value.c_str(), mqtt_retainFlag);
|
||||
MQTTpublish(event->ControllerIndex, event->TaskIndex, tmppubname.c_str(), value.c_str(), mqtt_retainFlag);
|
||||
}
|
||||
# ifndef BUILD_NO_DEBUG
|
||||
|
||||
|
||||
+2
-2
@@ -128,10 +128,10 @@ bool CPlugin_006(CPlugin::Function function, struct EventStruct *event, String&
|
||||
|
||||
// Small optimization so we don't try to copy potentially large strings
|
||||
if (event->sensorType == Sensor_VType::SENSOR_TYPE_STRING) {
|
||||
MQTTpublish(event->ControllerIndex, tmppubname.c_str(), event->String2.c_str(), mqtt_retainFlag);
|
||||
MQTTpublish(event->ControllerIndex, event->TaskIndex, tmppubname.c_str(), event->String2.c_str(), mqtt_retainFlag);
|
||||
} else {
|
||||
String value = formatUserVarNoCheck(event, x);
|
||||
MQTTpublish(event->ControllerIndex, tmppubname.c_str(), value.c_str(), mqtt_retainFlag);
|
||||
MQTTpublish(event->ControllerIndex, event->TaskIndex, tmppubname.c_str(), value.c_str(), mqtt_retainFlag);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
+30
-29
@@ -42,10 +42,10 @@ byte msgCounter=0; // counter for send Messages (currently for information / log
|
||||
String CPlugin_014_pubname;
|
||||
bool CPlugin_014_mqtt_retainFlag = false;
|
||||
|
||||
|
||||
/*
|
||||
// send MQTT Message with complete Topic / Payload
|
||||
bool CPlugin_014_sendMQTTmsg(String& topic, const char* payload, int& errorCounter) {
|
||||
bool mqttReturn = MQTTpublish(CPLUGIN_ID_014, topic.c_str(), payload, true);
|
||||
bool mqttReturn = MQTTpublish(CPLUGIN_ID_014, INVALID_TASK_INDEX, topic.c_str(), payload, true);
|
||||
if (mqttReturn) msgCounter++;
|
||||
else errorCounter++;
|
||||
if (loglevelActiveFor(LOG_LEVEL_INFO) && mqttReturn) {
|
||||
@@ -64,11 +64,12 @@ bool CPlugin_014_sendMQTTmsg(String& topic, const char* payload, int& errorCount
|
||||
}
|
||||
return mqttReturn;
|
||||
}
|
||||
*/
|
||||
|
||||
// send MQTT Message with CPLUGIN_014_BASE_TOPIC Topic scheme / Payload
|
||||
bool CPlugin_014_sendMQTTdevice(String tmppubname, const char* topic, const char* payload, int& errorCounter) {
|
||||
bool CPlugin_014_sendMQTTdevice(String tmppubname, taskIndex_t taskIndex, const char* topic, const char* payload, int& errorCounter) {
|
||||
tmppubname.replace(F("#"), topic);
|
||||
bool mqttReturn = MQTTpublish(CPLUGIN_ID_014, tmppubname.c_str(), payload, true);
|
||||
bool mqttReturn = MQTTpublish(CPLUGIN_ID_014, taskIndex, tmppubname.c_str(), payload, true);
|
||||
if (mqttReturn) msgCounter++;
|
||||
else errorCounter++;
|
||||
if (loglevelActiveFor(LOG_LEVEL_INFO) && mqttReturn) {
|
||||
@@ -95,7 +96,7 @@ bool CPlugin_014_sendMQTTnode(String tmppubname, const char* node, const char* v
|
||||
tmppubname.replace(F("%device%"), node);
|
||||
tmppubname.replace(F("%node%"), value);
|
||||
tmppubname.replace(F("/%property%"), topic); // leading forward slash required to send "homie/device/value" topics
|
||||
bool mqttReturn = MQTTpublish(CPLUGIN_ID_014, tmppubname.c_str(), payload, true);
|
||||
bool mqttReturn = MQTTpublish(CPLUGIN_ID_014, INVALID_TASK_INDEX, tmppubname.c_str(), payload, true);
|
||||
if (mqttReturn) msgCounter++;
|
||||
else errorCounter++;
|
||||
if (loglevelActiveFor(LOG_LEVEL_INFO) && mqttReturn) {
|
||||
@@ -180,24 +181,24 @@ bool CPlugin_014(CPlugin::Function function, struct EventStruct *event, String&
|
||||
|
||||
#ifdef CPLUGIN_014_V3
|
||||
// $stats/uptime Device → Controller Time elapsed in seconds since the boot of the device Yes Yes
|
||||
CPlugin_014_sendMQTTdevice(pubname,"$stats/uptime",toString((wdcounter / 2)*60,0).c_str(),errorCounter);
|
||||
CPlugin_014_sendMQTTdevice(pubname, event->TaskIndex,"$stats/uptime",toString((wdcounter / 2)*60,0).c_str(),errorCounter);
|
||||
|
||||
// $stats/signal Device → Controller Signal strength in % Yes No
|
||||
float RssI = WiFi.RSSI();
|
||||
RssI = isnan(RssI) ? -100.0f : RssI;
|
||||
RssI = min(max(2 * (RssI + 100.0f), 0.0f), 100.0f);
|
||||
|
||||
CPlugin_014_sendMQTTdevice(pubname,"$stats/signal",toString(RssI,1).c_str(),errorCounter);
|
||||
CPlugin_014_sendMQTTdevice(pubname, event->TaskIndex,"$stats/signal",toString(RssI,1).c_str(),errorCounter);
|
||||
#endif
|
||||
|
||||
if (errorCounter>0)
|
||||
{
|
||||
// alert: this is the state the device is when connected to the MQTT broker, but something wrong is happening. E.g. a sensor is not providing data and needs human intervention. You have to send this message when something is wrong.
|
||||
CPlugin_014_sendMQTTdevice(pubname,"$state","alert",errorCounter);
|
||||
CPlugin_014_sendMQTTdevice(pubname, event->TaskIndex,"$state","alert",errorCounter);
|
||||
success = false;
|
||||
} else {
|
||||
// ready: this is the state the device is in when it is connected to the MQTT broker, has sent all Homie messages and is ready to operate. You have to send this message after all other announcements message have been sent.
|
||||
CPlugin_014_sendMQTTdevice(pubname,"$state","ready",errorCounter);
|
||||
CPlugin_014_sendMQTTdevice(pubname, event->TaskIndex,"$state","ready",errorCounter);
|
||||
success = true;
|
||||
}
|
||||
if (loglevelActiveFor(LOG_LEVEL_DEBUG)) {
|
||||
@@ -236,37 +237,37 @@ bool CPlugin_014(CPlugin::Function function, struct EventStruct *event, String&
|
||||
String unitName; // estaimate Units
|
||||
|
||||
// init: this is the state the device is in when it is connected to the MQTT broker, but has not yet sent all Homie messages and is not yet ready to operate. This is the first message that must that must be sent.
|
||||
CPlugin_014_sendMQTTdevice(pubname,"$state","init",errorCounter);
|
||||
CPlugin_014_sendMQTTdevice(pubname, event->TaskIndex,"$state","init",errorCounter);
|
||||
|
||||
// $homie Device → Controller Version of the Homie convention the device conforms to Yes Yes
|
||||
CPlugin_014_sendMQTTdevice(pubname,"$homie",CPLUGIN_014_HOMIE_VERSION,errorCounter);
|
||||
CPlugin_014_sendMQTTdevice(pubname, event->TaskIndex,"$homie",CPLUGIN_014_HOMIE_VERSION,errorCounter);
|
||||
|
||||
// $name Device → Controller Friendly name of the device Yes Yes
|
||||
CPlugin_014_sendMQTTdevice(pubname,"$name",Settings.Name,errorCounter);
|
||||
CPlugin_014_sendMQTTdevice(pubname, event->TaskIndex,"$name",Settings.Name,errorCounter);
|
||||
|
||||
// $localip Device → Controller IP of the device on the local network Yes Yes
|
||||
#ifdef CPLUGIN_014_V3
|
||||
CPlugin_014_sendMQTTdevice(pubname,"$localip",formatIP(NetworkLocalIP()).c_str(),errorCounter);
|
||||
CPlugin_014_sendMQTTdevice(pubname, event->TaskIndex,"$localip",formatIP(NetworkLocalIP()).c_str(),errorCounter);
|
||||
|
||||
// $mac Device → Controller Mac address of the device network interface. The format MUST be of the type A1:B2:C3:D4:E5:F6 Yes Yes
|
||||
CPlugin_014_sendMQTTdevice(pubname,"$mac",NetworkMacAddress().c_str(),errorCounter);
|
||||
CPlugin_014_sendMQTTdevice(pubname, event->TaskIndex,"$mac",NetworkMacAddress().c_str(),errorCounter);
|
||||
|
||||
// $implementation Device → Controller An identifier for the Homie implementation (example esp8266) Yes Yes
|
||||
#if defined(ESP8266)
|
||||
CPlugin_014_sendMQTTdevice(pubname,"$implementation","ESP8266",errorCounter);
|
||||
CPlugin_014_sendMQTTdevice(pubname, event->TaskIndex,"$implementation","ESP8266",errorCounter);
|
||||
#endif
|
||||
#if defined(ESP32)
|
||||
CPlugin_014_sendMQTTdevice(pubname,"$implementation","ESP32",errorCounter);
|
||||
CPlugin_014_sendMQTTdevice(pubname, event->TaskIndex,"$implementation","ESP32",errorCounter);
|
||||
#endif
|
||||
|
||||
// $fw/version Device → Controller Version of the firmware running on the device Yes Yes
|
||||
CPlugin_014_sendMQTTdevice(pubname,"$fw/version",toString(Settings.Build,0).c_str(),errorCounter);
|
||||
CPlugin_014_sendMQTTdevice(pubname, event->TaskIndex,"$fw/version",toString(Settings.Build,0).c_str(),errorCounter);
|
||||
|
||||
// $fw/name Device → Controller Name of the firmware running on the device. Allowed characters are the same as the device ID Yes Yes
|
||||
CPlugin_014_sendMQTTdevice(pubname,"$fw/name",getNodeTypeDisplayString(NODE_TYPE_ID).c_str(),errorCounter);
|
||||
CPlugin_014_sendMQTTdevice(pubname, event->TaskIndex,"$fw/name",getNodeTypeDisplayString(NODE_TYPE_ID).c_str(),errorCounter);
|
||||
|
||||
// $stats/interval Device → Controller Interval in seconds at which the device refreshes its $stats/+: See next section for details about statistical attributes Yes Yes
|
||||
CPlugin_014_sendMQTTdevice(pubname,"$stats/interval",CPLUGIN_014_INTERVAL,errorCounter);
|
||||
CPlugin_014_sendMQTTdevice(pubname, event->TaskIndex,"$stats/interval",CPLUGIN_014_INTERVAL,errorCounter);
|
||||
#endif
|
||||
|
||||
//always send the SYSTEM device with the cmd node
|
||||
@@ -460,17 +461,17 @@ bool CPlugin_014(CPlugin::Function function, struct EventStruct *event, String&
|
||||
|
||||
// and finally ...
|
||||
// $nodes Device → Controller Nodes the device exposes, with format id separated by a , if there are multiple nodes. To make a node an array, append [] to the ID. Yes Yes
|
||||
CPlugin_014_sendMQTTdevice(pubname, "$nodes", nodesList.c_str(), errorCounter);
|
||||
CPlugin_014_sendMQTTdevice(pubname, event->TaskIndex, "$nodes", nodesList.c_str(), errorCounter);
|
||||
}
|
||||
|
||||
if (errorCounter>0)
|
||||
{
|
||||
// alert: this is the state the device is when connected to the MQTT broker, but something wrong is happening. E.g. a sensor is not providing data and needs human intervention. You have to send this message when something is wrong.
|
||||
CPlugin_014_sendMQTTdevice(pubname,"$state","alert",errorCounter);
|
||||
CPlugin_014_sendMQTTdevice(pubname, event->TaskIndex,"$state","alert",errorCounter);
|
||||
success = false;
|
||||
} else {
|
||||
// ready: this is the state the device is in when it is connected to the MQTT broker, has sent all Homie messages and is ready to operate. You have to send this message after all other announcements message have been sent.
|
||||
CPlugin_014_sendMQTTdevice(pubname,"$state","ready",errorCounter);
|
||||
CPlugin_014_sendMQTTdevice(pubname, event->TaskIndex,"$state","ready",errorCounter);
|
||||
success = true;
|
||||
}
|
||||
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
|
||||
@@ -503,7 +504,7 @@ bool CPlugin_014(CPlugin::Function function, struct EventStruct *event, String&
|
||||
pubname = CPLUGIN_014_BASE_TOPIC; // Scheme to form device messages
|
||||
pubname.replace(F("%sysname%"), Settings.Name);
|
||||
// disconnected: this is the state the device is in when it is cleanly disconnected from the MQTT broker. You must send this message before cleanly disconnecting
|
||||
success = CPlugin_014_sendMQTTdevice(pubname,"$state","disconnected",errorCounter);
|
||||
success = CPlugin_014_sendMQTTdevice(pubname, event->TaskIndex,"$state","disconnected",errorCounter);
|
||||
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
|
||||
String log = F("C014 : Device: ");
|
||||
log += Settings.Name;
|
||||
@@ -519,7 +520,7 @@ bool CPlugin_014(CPlugin::Function function, struct EventStruct *event, String&
|
||||
pubname = CPLUGIN_014_BASE_TOPIC; // Scheme to form device messages
|
||||
pubname.replace(F("%sysname%"), Settings.Name);
|
||||
// sleeping: this is the state the device is in when the device is sleeping. You have to send this message before sleeping.
|
||||
success = CPlugin_014_sendMQTTdevice(pubname,"$state","sleeping",errorCounter);
|
||||
success = CPlugin_014_sendMQTTdevice(pubname, event->TaskIndex,"$state","sleeping",errorCounter);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -709,11 +710,11 @@ bool CPlugin_014(CPlugin::Function function, struct EventStruct *event, String&
|
||||
|
||||
// Small optimization so we don't try to copy potentially large strings
|
||||
if (event->getSensorType() == Sensor_VType::SENSOR_TYPE_STRING) {
|
||||
MQTTpublish(event->ControllerIndex, tmppubname.c_str(), event->String2.c_str(), mqtt_retainFlag);
|
||||
MQTTpublish(event->ControllerIndex, event->TaskIndex, tmppubname.c_str(), event->String2.c_str(), mqtt_retainFlag);
|
||||
value = event->String2.substring(0, 20); // For the log
|
||||
} else {
|
||||
value = formatUserVarNoCheck(event, x);
|
||||
MQTTpublish(event->ControllerIndex, tmppubname.c_str(), value.c_str(), mqtt_retainFlag);
|
||||
MQTTpublish(event->ControllerIndex, event->TaskIndex, tmppubname.c_str(), value.c_str(), mqtt_retainFlag);
|
||||
}
|
||||
if (loglevelActiveFor(LOG_LEVEL_DEBUG)) {
|
||||
String log = F("C014 : Sent to ");
|
||||
@@ -779,7 +780,7 @@ bool CPlugin_014(CPlugin::Function function, struct EventStruct *event, String&
|
||||
topic.replace(F("%tskname%"), CPLUGIN_014_SYSTEM_DEVICE);
|
||||
topic.replace(F("%valname%"), CPLUGIN_014_GPIO_VALUE + toString(port,0));
|
||||
|
||||
success = MQTTpublish(CPLUGIN_ID_014, topic.c_str(), valueBool.c_str(), false);
|
||||
success = MQTTpublish(CPLUGIN_ID_014, INVALID_TASK_INDEX, topic.c_str(), valueBool.c_str(), false);
|
||||
if (loglevelActiveFor(LOG_LEVEL_INFO) && success) {
|
||||
String log = F("C014 : Acknowledged GPIO");
|
||||
log += port;
|
||||
@@ -819,7 +820,7 @@ bool CPlugin_014(CPlugin::Function function, struct EventStruct *event, String&
|
||||
if ((commandName == F("taskvalueset")) || (commandName == F("dummyvalueset"))) // should work for both
|
||||
{
|
||||
valueStr = formatUserVarNoCheck(event, taskVarIndex); //parseString(string, 4);
|
||||
success = MQTTpublish(CPLUGIN_ID_014, topic.c_str(), valueStr.c_str(), false);
|
||||
success = MQTTpublish(CPLUGIN_ID_014, INVALID_TASK_INDEX, topic.c_str(), valueStr.c_str(), false);
|
||||
if (loglevelActiveFor(LOG_LEVEL_INFO) && success) {
|
||||
String log = F("C014 : Acknowledged: ");
|
||||
log += deviceName;
|
||||
@@ -872,7 +873,7 @@ bool CPlugin_014(CPlugin::Function function, struct EventStruct *event, String&
|
||||
valueStr = parseStringToEnd(string,4);
|
||||
break;
|
||||
}
|
||||
success = MQTTpublish(CPLUGIN_ID_014, topic.c_str(), valueStr.c_str(), false);
|
||||
success = MQTTpublish(CPLUGIN_ID_014, INVALID_TASK_INDEX, topic.c_str(), valueStr.c_str(), false);
|
||||
if (loglevelActiveFor(LOG_LEVEL_INFO) && success) {
|
||||
String log = F("C014 : homie acknowledge: ");
|
||||
log += deviceName;
|
||||
|
||||
@@ -54,6 +54,7 @@ bool CPlugin_016(CPlugin::Function function, struct EventStruct *event, String&
|
||||
Protocol[protocolCount].usesPort = false;
|
||||
Protocol[protocolCount].usesSampleSets = false;
|
||||
Protocol[protocolCount].needsNetwork = false;
|
||||
Protocol[protocolCount].allowsExpire = false;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -86,7 +86,6 @@ boolean NPlugin_001_send(const NotificationSettingsStruct& notificationsettings,
|
||||
// Use WiFiClient class to create TCP connections
|
||||
WiFiClient client;
|
||||
client.setTimeout(CONTROLLER_CLIENTTIMEOUT_DFLT);
|
||||
PrepareSend();
|
||||
String aHost = notificationsettings.Server;
|
||||
addLog(LOG_LEVEL_DEBUG, String(F("EMAIL: Connecting to ")) + aHost + notificationsettings.Port);
|
||||
if (!connectClient(client, aHost.c_str(), notificationsettings.Port)) {
|
||||
|
||||
@@ -238,7 +238,6 @@ boolean Plugin_020(byte function, struct EventStruct *event, String& string)
|
||||
int timeOut = RXWait;
|
||||
size_t bytes_read = 0;
|
||||
|
||||
PrepareSend();
|
||||
while (timeOut > 0)
|
||||
{
|
||||
while (Serial.available()) {
|
||||
|
||||
@@ -873,7 +873,7 @@ bool gpio_mode_range_helper(byte pin, byte pinMode, struct EventStruct *event, c
|
||||
{
|
||||
//int8_t state=0;
|
||||
byte mode=255;
|
||||
bool setSuccess=false;
|
||||
//bool setSuccess=false;
|
||||
|
||||
switch (pinMode) {
|
||||
case 0:
|
||||
@@ -893,14 +893,14 @@ bool gpio_mode_range_helper(byte pin, byte pinMode, struct EventStruct *event, c
|
||||
if (mode < 255) {
|
||||
switch(pluginID) {
|
||||
case PLUGIN_GPIO:
|
||||
setSuccess = setGPIOMode(pin, mode);
|
||||
/* setSuccess = */ setGPIOMode(pin, mode);
|
||||
break;
|
||||
case PLUGIN_PCF:
|
||||
//set pin = 1 when INPUT
|
||||
setSuccess = setPCFMode(pin, mode);
|
||||
/* setSuccess = */ setPCFMode(pin, mode);
|
||||
break;
|
||||
case PLUGIN_MCP:
|
||||
setSuccess = setMCPMode(pin, mode);
|
||||
/* setSuccess = */ setMCPMode(pin, mode);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -59,10 +59,10 @@ String Command_MQTT_Publish(struct EventStruct *event, const char *Line)
|
||||
|
||||
bool success = false;
|
||||
if (value[0] != '=') {
|
||||
success = MQTTpublish(enabledMqttController, topic.c_str(), value.c_str(), mqtt_retainFlag);
|
||||
success = MQTTpublish(enabledMqttController, INVALID_TASK_INDEX, topic.c_str(), value.c_str(), mqtt_retainFlag);
|
||||
}
|
||||
else {
|
||||
success = MQTTpublish(enabledMqttController, topic.c_str(), String(event->Par2).c_str(), mqtt_retainFlag);
|
||||
success = MQTTpublish(enabledMqttController, INVALID_TASK_INDEX, topic.c_str(), String(event->Par2).c_str(), mqtt_retainFlag);
|
||||
}
|
||||
if (success) {
|
||||
return return_command_success();
|
||||
|
||||
@@ -21,4 +21,18 @@ size_t C011_queue_element::getSize() const {
|
||||
return total;
|
||||
}
|
||||
|
||||
bool C011_queue_element::isDuplicate(const C011_queue_element& other) const {
|
||||
if (other.controller_idx != controller_idx ||
|
||||
other.TaskIndex != TaskIndex ||
|
||||
other.sensorType != sensorType ||
|
||||
other.idx != idx) {
|
||||
return false;
|
||||
}
|
||||
return (other.uri.equals(uri) &&
|
||||
other.HttpMethod.equals(HttpMethod) &&
|
||||
other.header.equals(header) &&
|
||||
other.postStr.equals(postStr));
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -22,6 +22,8 @@ public:
|
||||
|
||||
C011_queue_element(const struct EventStruct *event);
|
||||
|
||||
bool isDuplicate(const C011_queue_element& other) const;
|
||||
|
||||
size_t getSize() const;
|
||||
|
||||
String uri;
|
||||
@@ -29,6 +31,7 @@ public:
|
||||
String header;
|
||||
String postStr;
|
||||
int idx = 0;
|
||||
unsigned long _timestamp = millis();
|
||||
taskIndex_t TaskIndex = INVALID_TASK_INDEX;
|
||||
controllerIndex_t controller_idx = INVALID_CONTROLLER_INDEX;
|
||||
Sensor_VType sensorType = Sensor_VType::SENSOR_TYPE_NONE;
|
||||
|
||||
@@ -27,4 +27,24 @@ size_t C015_queue_element::getSize() const {
|
||||
return total;
|
||||
}
|
||||
|
||||
bool C015_queue_element::isDuplicate(const C015_queue_element& other) const {
|
||||
if (other.controller_idx != controller_idx ||
|
||||
other.TaskIndex != TaskIndex ||
|
||||
other.sensorType != sensorType ||
|
||||
other.valueCount != valueCount ||
|
||||
other.idx != idx) {
|
||||
return false;
|
||||
}
|
||||
for (byte i = 0; i < VARS_PER_TASK; ++i) {
|
||||
if (other.txt[i] != txt[i]) {
|
||||
return false;
|
||||
}
|
||||
if (other.vPin[i] != vPin[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -26,9 +26,12 @@ public:
|
||||
|
||||
size_t getSize() const;
|
||||
|
||||
bool isDuplicate(const C015_queue_element& other) const;
|
||||
|
||||
String txt[VARS_PER_TASK];
|
||||
int vPin[VARS_PER_TASK] = { 0 };
|
||||
int idx = 0;
|
||||
unsigned long _timestamp = millis();
|
||||
taskIndex_t TaskIndex = INVALID_TASK_INDEX;
|
||||
controllerIndex_t controller_idx = INVALID_CONTROLLER_INDEX;
|
||||
mutable byte valuesSent = 0; // Value must be set by const function checkDone()
|
||||
|
||||
@@ -6,11 +6,11 @@
|
||||
|
||||
#ifdef USES_C016
|
||||
|
||||
C016_queue_element::C016_queue_element() : timestamp(0), TaskIndex(INVALID_TASK_INDEX), controller_idx(0), sensorType(
|
||||
C016_queue_element::C016_queue_element() : _timestamp(0), TaskIndex(INVALID_TASK_INDEX), controller_idx(0), sensorType(
|
||||
Sensor_VType::SENSOR_TYPE_NONE) {}
|
||||
|
||||
C016_queue_element::C016_queue_element(const struct EventStruct *event, byte value_count, unsigned long unixTime) :
|
||||
timestamp(unixTime),
|
||||
_timestamp(unixTime),
|
||||
TaskIndex(event->TaskIndex),
|
||||
controller_idx(event->ControllerIndex),
|
||||
sensorType(event->sensorType),
|
||||
@@ -29,4 +29,19 @@ size_t C016_queue_element::getSize() const {
|
||||
return sizeof(*this);
|
||||
}
|
||||
|
||||
bool C016_queue_element::isDuplicate(const C016_queue_element& other) const {
|
||||
if (other.controller_idx != controller_idx ||
|
||||
other.TaskIndex != TaskIndex ||
|
||||
other.sensorType != sensorType ||
|
||||
other.valueCount != valueCount) {
|
||||
return false;
|
||||
}
|
||||
for (byte i = 0; i < VARS_PER_TASK; ++i) {
|
||||
if (other.values[i] != values[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -14,6 +14,9 @@ struct EventStruct;
|
||||
/*********************************************************************************************\
|
||||
* C016_queue_element for queueing requests for C016: Cached HTTP.
|
||||
\*********************************************************************************************/
|
||||
|
||||
// TD-er: This one has a fixed byte order and is stored.
|
||||
// This also means the order of members should not be changed!
|
||||
class C016_queue_element {
|
||||
public:
|
||||
|
||||
@@ -25,10 +28,12 @@ public:
|
||||
|
||||
size_t getSize() const;
|
||||
|
||||
bool isDuplicate(const C016_queue_element& other) const;
|
||||
|
||||
float values[VARS_PER_TASK] = { 0 };
|
||||
unsigned long timestamp = 0; // Unix timestamp
|
||||
unsigned long _timestamp = 0; // Unix timestamp
|
||||
taskIndex_t TaskIndex = INVALID_TASK_INDEX;
|
||||
byte controller_idx = 0;
|
||||
controllerIndex_t controller_idx = INVALID_CONTROLLER_INDEX;
|
||||
Sensor_VType sensorType = Sensor_VType::SENSOR_TYPE_NONE;
|
||||
byte valueCount = 0;
|
||||
};
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
C018_queue_element::C018_queue_element() {}
|
||||
|
||||
C018_queue_element::C018_queue_element(struct EventStruct *event, uint8_t sampleSetCount) :
|
||||
TaskIndex(event->TaskIndex),
|
||||
controller_idx(event->ControllerIndex)
|
||||
{
|
||||
#ifdef USES_PACKED_RAW_DATA
|
||||
@@ -27,4 +28,18 @@ size_t C018_queue_element::getSize() const {
|
||||
return sizeof(*this) + packed.length();
|
||||
}
|
||||
|
||||
bool C018_queue_element::isDuplicate(const C018_queue_element& other) const {
|
||||
if (other.controller_idx != controller_idx ||
|
||||
other.TaskIndex != TaskIndex) {
|
||||
return false;
|
||||
}
|
||||
for (byte i = 0; i < VARS_PER_TASK; ++i) {
|
||||
if (other.packed[i] != packed[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -25,7 +25,11 @@ public:
|
||||
|
||||
size_t getSize() const;
|
||||
|
||||
bool isDuplicate(const C018_queue_element& other) const;
|
||||
|
||||
String packed;
|
||||
unsigned long _timestamp = millis();
|
||||
taskIndex_t TaskIndex = INVALID_TASK_INDEX;
|
||||
controllerIndex_t controller_idx = INVALID_CONTROLLER_INDEX;
|
||||
};
|
||||
|
||||
|
||||
@@ -19,6 +19,9 @@
|
||||
#include <memory> // For std::shared_ptr
|
||||
#include <new> // std::nothrow
|
||||
|
||||
#ifndef CONTROLLER_QUEUE_MINIMAL_EXPIRE_TIME
|
||||
#define CONTROLLER_QUEUE_MINIMAL_EXPIRE_TIME 10000
|
||||
#endif
|
||||
|
||||
/*********************************************************************************************\
|
||||
* ControllerDelayHandlerStruct
|
||||
@@ -28,11 +31,13 @@ struct ControllerDelayHandlerStruct {
|
||||
ControllerDelayHandlerStruct() :
|
||||
lastSend(0),
|
||||
minTimeBetweenMessages(CONTROLLER_DELAY_QUEUE_DELAY_DFLT),
|
||||
expire_timeout(0),
|
||||
max_queue_depth(CONTROLLER_DELAY_QUEUE_DEPTH_DFLT),
|
||||
attempt(0),
|
||||
max_retries(CONTROLLER_DELAY_QUEUE_RETRY_DFLT),
|
||||
delete_oldest(false),
|
||||
must_check_reply(false) {}
|
||||
must_check_reply(false),
|
||||
deduplicate(false) {}
|
||||
|
||||
void configureControllerSettings(const ControllerSettingsStruct& settings) {
|
||||
minTimeBetweenMessages = settings.MinimalTimeBetweenMessages;
|
||||
@@ -40,6 +45,15 @@ struct ControllerDelayHandlerStruct {
|
||||
max_retries = settings.MaxRetry;
|
||||
delete_oldest = settings.DeleteOldest;
|
||||
must_check_reply = settings.MustCheckReply;
|
||||
deduplicate = settings.deduplicate();
|
||||
if (settings.allowExpire()) {
|
||||
expire_timeout = max_queue_depth * max_retries * (minTimeBetweenMessages + settings.ClientTimeout);
|
||||
if (expire_timeout < CONTROLLER_QUEUE_MINIMAL_EXPIRE_TIME) {
|
||||
expire_timeout = CONTROLLER_QUEUE_MINIMAL_EXPIRE_TIME;
|
||||
}
|
||||
} else {
|
||||
expire_timeout = 0;
|
||||
}
|
||||
|
||||
// Set some sound limits when not configured
|
||||
if (max_queue_depth == 0) { max_queue_depth = CONTROLLER_DELAY_QUEUE_DEPTH_DFLT; }
|
||||
@@ -89,21 +103,56 @@ struct ControllerDelayHandlerStruct {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Return true if last element was removed
|
||||
bool removeLastIfDuplicate() {
|
||||
if (deduplicate && !sendQueue.empty()) {
|
||||
auto back = sendQueue.back();
|
||||
// Use reverse iterator here, as it is more likely a duplicate is added shortly after another.
|
||||
auto it = sendQueue.rbegin(); // Same as back()
|
||||
++it; // The last element before back()
|
||||
for (; it != sendQueue.rend(); ++it) {
|
||||
if (back.isDuplicate(*it)) {
|
||||
#ifndef BUILD_NO_DEBUG
|
||||
if (loglevelActiveFor(LOG_LEVEL_DEBUG)) {
|
||||
const cpluginID_t cpluginID = getCPluginID_from_ControllerIndex(it->controller_idx);
|
||||
String log = get_formatted_Controller_number(cpluginID);
|
||||
log += F(" : Remove duplicate");
|
||||
addLog(LOG_LEVEL_DEBUG, log);
|
||||
}
|
||||
#endif // ifndef BUILD_NO_DEBUG
|
||||
|
||||
sendQueue.pop_back();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Try to add to the queue, if permitted by "delete_oldest"
|
||||
// Return false when no item was added.
|
||||
bool addToQueue(T&& element) {
|
||||
bool addToQueue(T&& element, bool checkDuplicate = true) {
|
||||
if (delete_oldest) {
|
||||
// Force add to the queue.
|
||||
// If max buffer is reached, the oldest in the queue (first to be served) will be removed.
|
||||
while (queueFull(element)) {
|
||||
sendQueue.pop_front();
|
||||
attempt = 0;
|
||||
}
|
||||
sendQueue.emplace_back(element);
|
||||
if (checkDuplicate) {
|
||||
// If message is already present consider adding to be a success.
|
||||
removeLastIfDuplicate();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!queueFull(element)) {
|
||||
sendQueue.emplace_back(element);
|
||||
if (checkDuplicate) {
|
||||
// If message is already present consider adding to be a success.
|
||||
removeLastIfDuplicate();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#ifndef BUILD_NO_DEBUG
|
||||
@@ -126,9 +175,21 @@ struct ControllerDelayHandlerStruct {
|
||||
if (attempt > max_retries) {
|
||||
sendQueue.pop_front();
|
||||
attempt = 0;
|
||||
|
||||
if (sendQueue.empty()) { return NULL; }
|
||||
}
|
||||
|
||||
if (expire_timeout != 0) {
|
||||
bool done = false;
|
||||
while (!done && !sendQueue.empty()) {
|
||||
if (timePassedSince(sendQueue.front()._timestamp) < static_cast<long>(expire_timeout)) {
|
||||
done = true;
|
||||
} else {
|
||||
sendQueue.pop_front();
|
||||
attempt = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sendQueue.empty()) { return NULL; }
|
||||
return &sendQueue.front();
|
||||
}
|
||||
|
||||
@@ -180,11 +241,13 @@ struct ControllerDelayHandlerStruct {
|
||||
std::list<T> sendQueue;
|
||||
unsigned long lastSend;
|
||||
unsigned int minTimeBetweenMessages;
|
||||
unsigned long expire_timeout = 0;
|
||||
byte max_queue_depth;
|
||||
byte attempt;
|
||||
byte max_retries;
|
||||
bool delete_oldest;
|
||||
bool must_check_reply;
|
||||
bool deduplicate;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -4,8 +4,9 @@
|
||||
MQTT_queue_element::MQTT_queue_element() {}
|
||||
|
||||
MQTT_queue_element::MQTT_queue_element(int ctrl_idx,
|
||||
taskIndex_t TaskIndex,
|
||||
const String& topic, const String& payload, bool retained) :
|
||||
_topic(topic), _payload(payload), controller_idx(ctrl_idx), _retained(retained)
|
||||
_topic(topic), _payload(payload), TaskIndex(TaskIndex), controller_idx(ctrl_idx), _retained(retained)
|
||||
{
|
||||
// some parts of the topic may have been replaced by empty strings,
|
||||
// or "/status" may have been appended to a topic ending with a "/"
|
||||
@@ -18,3 +19,19 @@ MQTT_queue_element::MQTT_queue_element(int ctrl_idx,
|
||||
size_t MQTT_queue_element::getSize() const {
|
||||
return sizeof(*this) + _topic.length() + _payload.length();
|
||||
}
|
||||
|
||||
bool MQTT_queue_element::isDuplicate(const MQTT_queue_element& other) const {
|
||||
if (other.controller_idx != controller_idx ||
|
||||
other._retained != _retained) {
|
||||
return false;
|
||||
}
|
||||
for (byte i = 0; i < VARS_PER_TASK; ++i) {
|
||||
if (other._topic[i] != _topic[i]) {
|
||||
return false;
|
||||
}
|
||||
if (other._payload[i] != _payload[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -14,14 +14,19 @@ public:
|
||||
MQTT_queue_element();
|
||||
|
||||
explicit MQTT_queue_element(int ctrl_idx,
|
||||
taskIndex_t TaskIndex,
|
||||
const String& topic,
|
||||
const String& payload,
|
||||
bool retained);
|
||||
|
||||
size_t getSize() const;
|
||||
|
||||
bool isDuplicate(const MQTT_queue_element& other) const;
|
||||
|
||||
String _topic;
|
||||
String _payload;
|
||||
unsigned long _timestamp = millis();
|
||||
taskIndex_t TaskIndex = INVALID_TASK_INDEX;
|
||||
controllerIndex_t controller_idx = INVALID_CONTROLLER_INDEX;
|
||||
bool _retained = false;
|
||||
};
|
||||
|
||||
@@ -2,9 +2,22 @@
|
||||
|
||||
simple_queue_element_string_only::simple_queue_element_string_only() {}
|
||||
|
||||
simple_queue_element_string_only::simple_queue_element_string_only(int ctrl_idx, const String& req) :
|
||||
txt(req), controller_idx(ctrl_idx) {}
|
||||
simple_queue_element_string_only::simple_queue_element_string_only(int ctrl_idx, taskIndex_t TaskIndex, const String& req) :
|
||||
txt(req), TaskIndex(TaskIndex), controller_idx(ctrl_idx) {}
|
||||
|
||||
size_t simple_queue_element_string_only::getSize() const {
|
||||
return sizeof(*this) + txt.length();
|
||||
}
|
||||
|
||||
bool simple_queue_element_string_only::isDuplicate(const simple_queue_element_string_only& other) const {
|
||||
if (other.controller_idx != controller_idx ||
|
||||
other.TaskIndex != TaskIndex) {
|
||||
return false;
|
||||
}
|
||||
for (byte i = 0; i < VARS_PER_TASK; ++i) {
|
||||
if (other.txt[i] != txt[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -13,12 +13,18 @@ public:
|
||||
|
||||
simple_queue_element_string_only();
|
||||
|
||||
simple_queue_element_string_only(int ctrl_idx,
|
||||
const String& req);
|
||||
explicit simple_queue_element_string_only(int ctrl_idx,
|
||||
taskIndex_t TaskIndex,
|
||||
const String& req);
|
||||
|
||||
size_t getSize() const;
|
||||
|
||||
bool isDuplicate(const simple_queue_element_string_only& other) const;
|
||||
|
||||
|
||||
String txt;
|
||||
unsigned long _timestamp = millis();
|
||||
taskIndex_t TaskIndex = INVALID_TASK_INDEX;
|
||||
controllerIndex_t controller_idx = INVALID_CONTROLLER_INDEX;
|
||||
};
|
||||
|
||||
|
||||
@@ -27,3 +27,18 @@ size_t queue_element_formatted_uservar::getSize() const {
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
bool queue_element_formatted_uservar::isDuplicate(const queue_element_formatted_uservar& other) const {
|
||||
if (other.controller_idx != controller_idx ||
|
||||
other.TaskIndex != TaskIndex ||
|
||||
other.sensorType != sensorType ||
|
||||
other.valueCount != valueCount) {
|
||||
return false;
|
||||
}
|
||||
for (byte i = 0; i < VARS_PER_TASK; ++i) {
|
||||
if (other.txt[i] != txt[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -21,8 +21,11 @@ public:
|
||||
|
||||
size_t getSize() const;
|
||||
|
||||
bool isDuplicate(const queue_element_formatted_uservar& other) const;
|
||||
|
||||
String txt[VARS_PER_TASK];
|
||||
int idx = 0;
|
||||
unsigned long _timestamp = millis();
|
||||
taskIndex_t TaskIndex = INVALID_TASK_INDEX;
|
||||
controllerIndex_t controller_idx = INVALID_CONTROLLER_INDEX;
|
||||
Sensor_VType sensorType = Sensor_VType::SENSOR_TYPE_NONE;
|
||||
|
||||
@@ -37,3 +37,18 @@ size_t queue_element_single_value_base::getSize() const {
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
bool queue_element_single_value_base::isDuplicate(const queue_element_single_value_base& other) const {
|
||||
if (other.controller_idx != controller_idx ||
|
||||
other.TaskIndex != TaskIndex ||
|
||||
other.valueCount != valueCount ||
|
||||
other.idx != idx) {
|
||||
return false;
|
||||
}
|
||||
for (byte i = 0; i < VARS_PER_TASK; ++i) {
|
||||
if (other.txt[i] != txt[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -27,8 +27,11 @@ public:
|
||||
|
||||
size_t getSize() const;
|
||||
|
||||
bool isDuplicate(const queue_element_single_value_base& other) const;
|
||||
|
||||
String txt[VARS_PER_TASK];
|
||||
int idx = 0;
|
||||
unsigned long _timestamp = millis();
|
||||
taskIndex_t TaskIndex = INVALID_TASK_INDEX;
|
||||
controllerIndex_t controller_idx = INVALID_CONTROLLER_INDEX;
|
||||
mutable byte valuesSent = 0; // Value must be set by const function checkDone()
|
||||
|
||||
@@ -99,6 +99,10 @@
|
||||
#define DEFAULT_SEND_TO_HTTP_ACK false // Wait for ack with SendToHttp command.
|
||||
#endif
|
||||
|
||||
#ifndef DEFAULT_AP_DONT_FORCE_SETUP
|
||||
#define DEFAULT_AP_DONT_FORCE_SETUP false // Allow optional usage of Sensor without WIFI avaiable // When set you can use the Sensor in AP-Mode without beeing forced to /setup
|
||||
#endif
|
||||
|
||||
// --- Default Controller ------------------------------------------------------------------------------
|
||||
#ifndef DEFAULT_CONTROLLER
|
||||
#define DEFAULT_CONTROLLER true // true or false enabled or disabled, set 1st controller defaults
|
||||
|
||||
@@ -143,9 +143,16 @@
|
||||
# ifndef DAT_OFFSET_CUSTOM_CONTROLLER
|
||||
# define DAT_OFFSET_CUSTOM_CONTROLLER 32768 // each custom controller config = 1k, 4 max.
|
||||
# endif // ifndef DAT_OFFSET_CUSTOM_CONTROLLER
|
||||
# ifndef CONFIG_FILE_SIZE
|
||||
# define CONFIG_FILE_SIZE 65536
|
||||
# endif // ifndef CONFIG_FILE_SIZE
|
||||
# ifdef LIMIT_BUILD_SIZE
|
||||
// Limit the config size for 1M builds, since their file system is also quite small
|
||||
# ifndef CONFIG_FILE_SIZE
|
||||
# define CONFIG_FILE_SIZE 36864 // DAT_OFFSET_CUSTOM_CONTROLLER + 4x DAT_CUSTOM_CONTROLLER_SIZE
|
||||
# endif // ifndef CONFIG_FILE_SIZE
|
||||
# else
|
||||
# ifndef CONFIG_FILE_SIZE
|
||||
# define CONFIG_FILE_SIZE 65536
|
||||
# endif // ifndef CONFIG_FILE_SIZE
|
||||
# endif
|
||||
# endif // ifdef USE_NON_STANDARD_24_TASKS
|
||||
#endif // if defined(ESP8266)
|
||||
|
||||
|
||||
@@ -899,16 +899,16 @@ To create/register a plugin, you have to :
|
||||
#define USES_P072 // HDC1080
|
||||
#define USES_P074 // TSL2561
|
||||
#define USES_P075 // Nextion
|
||||
#define USES_P076 // HWL8012 in POW r1
|
||||
//#define USES_P076 // HWL8012 in POW r1
|
||||
// Needs CSE7766 Energy sensor, via Serial RXD 4800 baud 8E1 (GPIO1), TXD (GPIO3)
|
||||
#define USES_P077 // CSE7766 in POW R2
|
||||
//#define USES_P077 // CSE7766 in POW R2
|
||||
#define USES_P078 // Eastron Modbus Energy meters
|
||||
#define USES_P080 // iButton Sensor DS1990A
|
||||
#define USES_P081 // Cron
|
||||
#define USES_P082 // GPS
|
||||
#define USES_P083 // SGP30
|
||||
#define USES_P084 // VEML6070
|
||||
#define USES_P085 // AcuDC24x
|
||||
//#define USES_P085 // AcuDC24x
|
||||
#define USES_P086 // Receiving values according Homie convention. Works together with C014 Homie controller
|
||||
//#define USES_P087 // Serial Proxy
|
||||
#define USES_P089 // Ping
|
||||
@@ -925,7 +925,7 @@ To create/register a plugin, you have to :
|
||||
#define USES_P101 // Wake On Lan
|
||||
#define USES_P106 // BME680
|
||||
#define USES_P107 // SI1145 UV index
|
||||
#define USES_P108 // DDS238-x ZN MODBUS energy meter (was P224 in the Playground)
|
||||
//#define USES_P108 // DDS238-x ZN MODBUS energy meter (was P224 in the Playground)
|
||||
// #define USES_P111 // RC522 RFID reader
|
||||
#endif
|
||||
|
||||
@@ -939,9 +939,7 @@ To create/register a plugin, you have to :
|
||||
#define USES_P027 // INA219
|
||||
#endif
|
||||
#ifndef USES_P076
|
||||
// TD-er: Disabled as it causes this 'energy' build to fail due to low iRAM.
|
||||
// It is still present in the POW builds.
|
||||
// #define USES_P076 // HWL8012 in POW r1
|
||||
#define USES_P076 // HWL8012 in POW r1
|
||||
#endif
|
||||
#ifndef USES_P077
|
||||
// Needs CSE7766 Energy sensor, via Serial RXD 4800 baud 8E1 (GPIO1), TXD (GPIO3)
|
||||
|
||||
@@ -104,7 +104,6 @@ bool ControllerSettingsStruct::checkHostReachable(bool quick) {
|
||||
}
|
||||
delay(1); // Make sure the Watchdog will not trigger a reset.
|
||||
|
||||
PrepareSend();
|
||||
if (quick && ipSet()) { return true; }
|
||||
|
||||
if (UseDNS) {
|
||||
@@ -255,3 +254,23 @@ void ControllerSettingsStruct::sendBinary(bool value)
|
||||
{
|
||||
bitWrite(VariousFlags, 7, value);
|
||||
}
|
||||
|
||||
bool ControllerSettingsStruct::allowExpire() const
|
||||
{
|
||||
return bitRead(VariousFlags, 9);
|
||||
}
|
||||
|
||||
void ControllerSettingsStruct::allowExpire(bool value)
|
||||
{
|
||||
bitWrite(VariousFlags, 9, value);
|
||||
}
|
||||
|
||||
bool ControllerSettingsStruct::deduplicate() const
|
||||
{
|
||||
return bitRead(VariousFlags, 10);
|
||||
}
|
||||
|
||||
void ControllerSettingsStruct::deduplicate(bool value)
|
||||
{
|
||||
bitWrite(VariousFlags, 10, value);
|
||||
}
|
||||
|
||||
@@ -69,6 +69,8 @@ struct ControllerSettingsStruct
|
||||
CONTROLLER_MAX_QUEUE_DEPTH,
|
||||
CONTROLLER_MAX_RETRIES,
|
||||
CONTROLLER_FULL_QUEUE_ACTION,
|
||||
CONTROLLER_ALLOW_EXPIRE,
|
||||
CONTROLLER_DEDUPLICATE,
|
||||
CONTROLLER_CHECK_REPLY,
|
||||
CONTROLLER_CLIENT_ID,
|
||||
CONTROLLER_UNIQUE_CLIENT_ID_RECONNECT,
|
||||
@@ -134,6 +136,12 @@ struct ControllerSettingsStruct
|
||||
bool sendBinary() const;
|
||||
void sendBinary(bool value);
|
||||
|
||||
bool allowExpire() const;
|
||||
void allowExpire(bool value);
|
||||
|
||||
bool deduplicate() const;
|
||||
void deduplicate(bool value);
|
||||
|
||||
boolean UseDNS;
|
||||
byte IP[4];
|
||||
unsigned int Port;
|
||||
|
||||
@@ -13,7 +13,7 @@ GpioFactorySettingsStruct::GpioFactorySettingsStruct(DeviceModel model)
|
||||
eth_mdio(DEFAULT_ETH_PIN_MDIO),
|
||||
eth_power(DEFAULT_ETH_PIN_POWER),
|
||||
eth_clock_mode(DEFAULT_ETH_CLOCK_MODE),
|
||||
active_network_medium(DEFAULT_NETWORK_MEDIUM)
|
||||
network_medium(DEFAULT_NETWORK_MEDIUM)
|
||||
|
||||
{
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
@@ -118,7 +118,7 @@ GpioFactorySettingsStruct::GpioFactorySettingsStruct(DeviceModel model)
|
||||
eth_mdio = 18;
|
||||
eth_power = 12;
|
||||
eth_clock_mode = EthClockMode_t::Int_50MHz_GPIO_17_inv;
|
||||
active_network_medium = NetworkMedium_t::Ethernet;
|
||||
network_medium = NetworkMedium_t::Ethernet;
|
||||
break;
|
||||
case DeviceMode_Olimex_ESP32_EVB:
|
||||
button[0] = 34; // BUT1 Button
|
||||
@@ -134,7 +134,7 @@ GpioFactorySettingsStruct::GpioFactorySettingsStruct(DeviceModel model)
|
||||
eth_mdio = 18;
|
||||
eth_power = -1; // No Ethernet power pin
|
||||
eth_clock_mode = EthClockMode_t::Ext_crystal_osc;
|
||||
active_network_medium = NetworkMedium_t::Ethernet;
|
||||
network_medium = NetworkMedium_t::Ethernet;
|
||||
break;
|
||||
|
||||
case DeviceMode_Olimex_ESP32_GATEWAY:
|
||||
@@ -149,7 +149,7 @@ GpioFactorySettingsStruct::GpioFactorySettingsStruct(DeviceModel model)
|
||||
eth_mdio = 18;
|
||||
eth_power = 5;
|
||||
eth_clock_mode = EthClockMode_t::Int_50MHz_GPIO_17_inv;
|
||||
active_network_medium = NetworkMedium_t::Ethernet;
|
||||
network_medium = NetworkMedium_t::Ethernet;
|
||||
// Rev A to E:
|
||||
// GPIO 5, 17 can be used only if Ethernet functionality is not used
|
||||
// GPIO 6, 7, 8, 9, 10, 11 used for internal flash and SD card
|
||||
|
||||
@@ -21,7 +21,7 @@ struct GpioFactorySettingsStruct {
|
||||
int8_t eth_mdio;
|
||||
int8_t eth_power;
|
||||
EthClockMode_t eth_clock_mode;
|
||||
NetworkMedium_t active_network_medium;
|
||||
NetworkMedium_t network_medium;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ ProtocolStruct::ProtocolStruct() :
|
||||
defaultPort(0), Number(0), usesMQTT(false), usesAccount(false), usesPassword(false),
|
||||
usesTemplate(false), usesID(false), Custom(false), usesHost(true), usesPort(true),
|
||||
usesQueue(true), usesCheckReply(true), usesTimeout(true), usesSampleSets(false),
|
||||
usesExtCreds(false), needsNetwork(true) {}
|
||||
usesExtCreds(false), needsNetwork(true), allowsExpire(true) {}
|
||||
|
||||
bool ProtocolStruct::useCredentials() const {
|
||||
return usesAccount || usesPassword;
|
||||
|
||||
@@ -31,6 +31,7 @@ struct ProtocolStruct
|
||||
bool usesSampleSets : 1;
|
||||
bool usesExtCreds : 1;
|
||||
bool needsNetwork : 1;
|
||||
bool allowsExpire : 1;
|
||||
};
|
||||
|
||||
typedef std::vector<ProtocolStruct> ProtocolVector;
|
||||
|
||||
@@ -148,6 +148,16 @@ void SettingsStruct_tmpl<N_TASKS>::UseMaxTXpowerForSending(bool value) {
|
||||
bitWrite(VariousBits1, 13, value);
|
||||
}
|
||||
|
||||
template<unsigned int N_TASKS>
|
||||
bool SettingsStruct_tmpl<N_TASKS>::ApDontForceSetup() const {
|
||||
return bitRead(VariousBits1, 14);
|
||||
}
|
||||
|
||||
template<unsigned int N_TASKS>
|
||||
void SettingsStruct_tmpl<N_TASKS>::ApDontForceSetup(bool value) {
|
||||
bitWrite(VariousBits1, 14, value);
|
||||
}
|
||||
|
||||
template<unsigned int N_TASKS>
|
||||
bool SettingsStruct_tmpl<N_TASKS>::CombineTaskValues_SingleEvent(taskIndex_t taskIndex) const {
|
||||
if (validTaskIndex(taskIndex))
|
||||
@@ -325,6 +335,7 @@ void SettingsStruct_tmpl<N_TASKS>::clearMisc() {
|
||||
gratuitousARP(DEFAULT_GRATUITOUS_ARP);
|
||||
TolerantLastArgParse(DEFAULT_TOLERANT_LAST_ARG_PARSE);
|
||||
SendToHttp_ack(DEFAULT_SEND_TO_HTTP_ACK);
|
||||
ApDontForceSetup(DEFAULT_AP_DONT_FORCE_SETUP);
|
||||
}
|
||||
|
||||
template<unsigned int N_TASKS>
|
||||
|
||||
@@ -98,6 +98,9 @@ class SettingsStruct_tmpl
|
||||
bool UseMaxTXpowerForSending() const;
|
||||
void UseMaxTXpowerForSending(bool value);
|
||||
|
||||
// When set you can use the Sensor in AP-Mode without beeing forced to /setup
|
||||
bool ApDontForceSetup() const;
|
||||
void ApDontForceSetup(bool value);
|
||||
|
||||
|
||||
// Flag indicating whether all task values should be sent in a single event or one event per task value (default behavior)
|
||||
|
||||
@@ -223,6 +223,7 @@ String getMiscStatsName(int stat) {
|
||||
case FS_GC_FAIL: return F("ESPEASY_FS GC fail");
|
||||
case RULES_PROCESSING: return F("rulesProcessing()");
|
||||
case GRAT_ARP_STATS: return F("sendGratuitousARP()");
|
||||
case SAVE_TO_RTC: return F("saveToRTC()");
|
||||
case BACKGROUND_TASKS: return F("backgroundtasks()");
|
||||
case HANDLE_SCHEDULER_IDLE: return F("handle_schedule() idle");
|
||||
case HANDLE_SCHEDULER_TASK: return F("handle_schedule() task");
|
||||
|
||||
@@ -76,10 +76,11 @@
|
||||
# define PARSE_TEMPLATE_PADDED 55
|
||||
# define RULES_PROCESSING 56
|
||||
# define GRAT_ARP_STATS 57
|
||||
# define BACKGROUND_TASKS 58
|
||||
# define HANDLE_SCHEDULER_IDLE 59
|
||||
# define HANDLE_SCHEDULER_TASK 60
|
||||
# define HANDLE_SERVING_WEBPAGE 61
|
||||
# define SAVE_TO_RTC 58
|
||||
# define BACKGROUND_TASKS 59
|
||||
# define HANDLE_SCHEDULER_IDLE 60
|
||||
# define HANDLE_SCHEDULER_TASK 61
|
||||
# define HANDLE_SERVING_WEBPAGE 62
|
||||
|
||||
|
||||
class TimingStats {
|
||||
|
||||
@@ -140,7 +140,6 @@ void Web_StreamingBuffer::startStream(bool json, const String& origin) {
|
||||
sentBytes = 0;
|
||||
buf = "";
|
||||
|
||||
PrepareSend();
|
||||
if (beforeTXRam < 3000) {
|
||||
lowMemorySkip = true;
|
||||
web_server.send(200, "text/plain", "Low memory. Cannot display webpage :-(");
|
||||
@@ -209,7 +208,7 @@ void Web_StreamingBuffer::sendContentBlocking(String& data) {
|
||||
beforeTXRam = freeBeforeSend;
|
||||
}
|
||||
duringTXRam = freeBeforeSend;
|
||||
PrepareSend();
|
||||
|
||||
#if defined(ESP8266) && defined(ARDUINO_ESP8266_RELEASE_2_3_0)
|
||||
String size = formatToHex(length) + "\r\n";
|
||||
|
||||
@@ -249,7 +248,7 @@ void Web_StreamingBuffer::sendHeaderBlocking(bool json, const String& origin) {
|
||||
#ifndef BUILD_NO_RAM_TRACKER
|
||||
checkRAM(F("sendHeaderBlocking"));
|
||||
#endif
|
||||
PrepareSend();
|
||||
|
||||
web_server.client().flush();
|
||||
String contenttype;
|
||||
|
||||
|
||||
@@ -186,7 +186,7 @@ bool MQTTConnect(controllerIndex_t controller_idx)
|
||||
if (MQTTclient.connected()) {
|
||||
MQTTclient.disconnect();
|
||||
}
|
||||
PrepareSend();
|
||||
|
||||
updateMQTTclient_connected();
|
||||
|
||||
// mqtt = WiFiClient(); // workaround see: https://github.com/esp8266/Arduino/issues/4497#issuecomment-373023864
|
||||
@@ -361,7 +361,6 @@ bool MQTTCheck(controllerIndex_t controller_idx)
|
||||
|
||||
if (MQTTclient_must_send_LWT_connected) {
|
||||
if (mqtt_sendLWT) {
|
||||
PrepareSend();
|
||||
if (MQTTclient.publish(LWTTopic.c_str(), LWTMessageConnect.c_str(), willRetain)) {
|
||||
MQTTclient_must_send_LWT_connected = false;
|
||||
}
|
||||
@@ -491,7 +490,7 @@ bool MQTT_queueFull(controllerIndex_t controller_idx) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MQTTpublish(controllerIndex_t controller_idx, const char *topic, const char *payload, bool retained)
|
||||
bool MQTTpublish(controllerIndex_t controller_idx, taskIndex_t taskIndex, const char *topic, const char *payload, bool retained)
|
||||
{
|
||||
if (MQTTDelayHandler == nullptr) {
|
||||
return false;
|
||||
@@ -500,7 +499,7 @@ bool MQTTpublish(controllerIndex_t controller_idx, const char *topic, const char
|
||||
if (MQTT_queueFull(controller_idx)) {
|
||||
return false;
|
||||
}
|
||||
const bool success = MQTTDelayHandler->addToQueue(MQTT_queue_element(controller_idx, topic, payload, retained));
|
||||
const bool success = MQTTDelayHandler->addToQueue(MQTT_queue_element(controller_idx, taskIndex, topic, payload, retained));
|
||||
|
||||
scheduleNextMQTTdelayQueue();
|
||||
return success;
|
||||
@@ -548,7 +547,7 @@ void MQTTStatus(struct EventStruct *event, const String& status)
|
||||
pubname += F("/status");
|
||||
}
|
||||
|
||||
MQTTpublish(enabledMqttController, pubname.c_str(), status.c_str(), mqtt_retainFlag);
|
||||
MQTTpublish(enabledMqttController, event->TaskIndex, pubname.c_str(), status.c_str(), mqtt_retainFlag);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ void SendStatus(struct EventStruct *event, const String& status);
|
||||
#ifdef USES_MQTT
|
||||
bool MQTT_queueFull(controllerIndex_t controller_idx);
|
||||
|
||||
bool MQTTpublish(controllerIndex_t controller_idx, const char *topic, const char *payload, bool retained);
|
||||
bool MQTTpublish(controllerIndex_t controller_idx, taskIndex_t taskIndex, const char *topic, const char *payload, bool retained);
|
||||
|
||||
|
||||
/*********************************************************************************************\
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "ESPEasyEth.h"
|
||||
#include "../ESPEasyCore/ESPEasyEth.h"
|
||||
|
||||
#ifdef HAS_ETHERNET
|
||||
|
||||
@@ -15,7 +15,11 @@ bool ethUseStaticIP() {
|
||||
}
|
||||
|
||||
void ethSetupStaticIPconfig() {
|
||||
if (!ethUseStaticIP()) { return; }
|
||||
if (!ethUseStaticIP()) {
|
||||
const IPAddress IP_zero(0, 0, 0, 0);
|
||||
ETH.config(IP_zero, IP_zero, IP_zero);
|
||||
return;
|
||||
}
|
||||
const IPAddress ip = Settings.ETH_IP;
|
||||
const IPAddress gw = Settings.ETH_Gateway;
|
||||
const IPAddress subnet = Settings.ETH_Subnet;
|
||||
@@ -36,54 +40,44 @@ void ethSetupStaticIPconfig() {
|
||||
}
|
||||
|
||||
bool ethCheckSettings() {
|
||||
bool result = true;
|
||||
if (!isValid(Settings.ETH_Phy_Type))
|
||||
result = false;
|
||||
if (!isValid(Settings.ETH_Clock_Mode))
|
||||
result = false;
|
||||
if (!isValid(Settings.NetworkMedium))
|
||||
result = false;
|
||||
if (Settings.ETH_Pin_mdc > MAX_GPIO)
|
||||
result = false;
|
||||
if (Settings.ETH_Pin_mdio > MAX_GPIO)
|
||||
result = false;
|
||||
if (Settings.ETH_Pin_power > MAX_GPIO)
|
||||
result = false;
|
||||
return result;
|
||||
return isValid(Settings.ETH_Phy_Type)
|
||||
&& isValid(Settings.ETH_Clock_Mode)
|
||||
&& isValid(Settings.NetworkMedium)
|
||||
&& (Settings.ETH_Pin_mdc <= MAX_GPIO)
|
||||
&& (Settings.ETH_Pin_mdio <= MAX_GPIO)
|
||||
&& (Settings.ETH_Pin_power <= MAX_GPIO);
|
||||
}
|
||||
|
||||
bool ethPrepare() {
|
||||
if (!ethCheckSettings())
|
||||
{
|
||||
addLog(LOG_LEVEL_ERROR, F("ETH: Settings not correct!!!"));
|
||||
return false;
|
||||
char hostname[40];
|
||||
safe_strncpy(hostname, NetworkCreateRFCCompliantHostname().c_str(), sizeof(hostname));
|
||||
ETH.setHostname(hostname);
|
||||
}
|
||||
char hostname[40];
|
||||
safe_strncpy(hostname, NetworkCreateRFCCompliantHostname().c_str(), sizeof(hostname));
|
||||
ETH.setHostname(hostname);
|
||||
ETH.config(INADDR_NONE, INADDR_NONE, INADDR_NONE);
|
||||
ethSetupStaticIPconfig();
|
||||
return true;
|
||||
}
|
||||
|
||||
void ethPrintSettings() {
|
||||
String settingsDebugLog;
|
||||
settingsDebugLog.reserve(115);
|
||||
settingsDebugLog += F("Eth Wifi mode: ");
|
||||
settingsDebugLog += toString(active_network_medium);
|
||||
settingsDebugLog += F(" ETH: PHY Type: ");
|
||||
settingsDebugLog += toString(Settings.ETH_Phy_Type);
|
||||
settingsDebugLog += F(" PHY Addr: ");
|
||||
settingsDebugLog += Settings.ETH_Phy_Addr;
|
||||
settingsDebugLog += F(" Eth Clock mode: ");
|
||||
settingsDebugLog += toString(Settings.ETH_Clock_Mode);
|
||||
settingsDebugLog += F(" MDC Pin: ");
|
||||
settingsDebugLog += String(Settings.ETH_Pin_mdc);
|
||||
settingsDebugLog += F(" MIO Pin: ");
|
||||
settingsDebugLog += String(Settings.ETH_Pin_mdio);
|
||||
settingsDebugLog += F(" Power Pin: ");
|
||||
settingsDebugLog += String(Settings.ETH_Pin_power);
|
||||
addLog(LOG_LEVEL_INFO, settingsDebugLog);
|
||||
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
|
||||
String log;
|
||||
log.reserve(115);
|
||||
// log += F("ETH/Wifi mode: ");
|
||||
// log += toString(active_network_medium);
|
||||
log += F("ETH PHY Type: ");
|
||||
log += toString(Settings.ETH_Phy_Type);
|
||||
log += F(" PHY Addr: ");
|
||||
log += Settings.ETH_Phy_Addr;
|
||||
log += F(" Eth Clock mode: ");
|
||||
log += toString(Settings.ETH_Clock_Mode);
|
||||
log += F(" MDC Pin: ");
|
||||
log += String(Settings.ETH_Pin_mdc);
|
||||
log += F(" MIO Pin: ");
|
||||
log += String(Settings.ETH_Pin_mdio);
|
||||
log += F(" Power Pin: ");
|
||||
log += String(Settings.ETH_Pin_power);
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t * ETHMacAddress(uint8_t* mac) {
|
||||
@@ -93,6 +87,12 @@ uint8_t * ETHMacAddress(uint8_t* mac) {
|
||||
|
||||
bool ETHConnectRelaxed() {
|
||||
ethPrintSettings();
|
||||
if (!ethCheckSettings())
|
||||
{
|
||||
addLog(LOG_LEVEL_ERROR, F("ETH: Settings not correct!!!"));
|
||||
|
||||
return false;
|
||||
}
|
||||
if (!ETH.begin( Settings.ETH_Phy_Addr,
|
||||
Settings.ETH_Pin_power,
|
||||
Settings.ETH_Pin_mdc,
|
||||
@@ -102,12 +102,6 @@ bool ETHConnectRelaxed() {
|
||||
{
|
||||
return false;
|
||||
}
|
||||
addLog(LOG_LEVEL_INFO, F("After ETH.begin"));
|
||||
if (!ethPrepare()) {
|
||||
// Dead code for now...
|
||||
addLog(LOG_LEVEL_ERROR, F("ETH : Could not prepare ETH!"));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -12,21 +12,36 @@
|
||||
#include "ETH.h"
|
||||
#endif
|
||||
|
||||
void setNetworkMedium(NetworkMedium_t medium) {
|
||||
switch (active_network_medium) {
|
||||
case NetworkMedium_t::Ethernet:
|
||||
#ifdef HAS_ETHERNET
|
||||
// FIXME TD-er: How to 'end' ETH?
|
||||
// ETH.end();
|
||||
#endif
|
||||
break;
|
||||
case NetworkMedium_t::WIFI:
|
||||
WiFi.mode(WIFI_OFF);
|
||||
break;
|
||||
}
|
||||
active_network_medium = medium;
|
||||
addLog(LOG_LEVEL_INFO, String(F("Set Network mode: ")) + toString(active_network_medium));
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************************************\
|
||||
Ethernet or Wifi Support for ESP32 Build flag HAS_ETHERNET
|
||||
\*********************************************************************************************/
|
||||
void NetworkConnectRelaxed() {
|
||||
if (NetworkConnected()) return;
|
||||
#ifdef HAS_ETHERNET
|
||||
addLog(LOG_LEVEL_INFO, F("Connect to: "));
|
||||
addLog(LOG_LEVEL_INFO, toString(active_network_medium));
|
||||
if(active_network_medium == NetworkMedium_t::Ethernet) {
|
||||
if (ETHConnectRelaxed()) {
|
||||
return;
|
||||
}
|
||||
// Failed to start the Ethernet network, probably not present of wrong parameters.
|
||||
// So set the runtime active medium to WiFi to try connecting to WiFi or at least start the AP.
|
||||
active_network_medium = NetworkMedium_t::WIFI;
|
||||
setNetworkMedium(NetworkMedium_t::WIFI);
|
||||
}
|
||||
#endif
|
||||
WiFiConnectRelaxed();
|
||||
@@ -41,17 +56,6 @@ bool NetworkConnected() {
|
||||
return WiFiConnected();
|
||||
}
|
||||
|
||||
void PrepareSend() {
|
||||
#ifdef HAS_ETHERNET
|
||||
if (active_network_medium == NetworkMedium_t::Ethernet) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if (Settings.UseMaxTXpowerForSending()) {
|
||||
SetWiFiTXpower(30); // Just some max, will be limited in SetWiFiTXpower
|
||||
}
|
||||
}
|
||||
|
||||
IPAddress NetworkLocalIP() {
|
||||
#ifdef HAS_ETHERNET
|
||||
if(active_network_medium == NetworkMedium_t::Ethernet) {
|
||||
|
||||
@@ -6,9 +6,10 @@
|
||||
#ifndef NETWORK_H
|
||||
#define NETWORK_H
|
||||
|
||||
void setNetworkMedium(NetworkMedium_t medium);
|
||||
|
||||
void NetworkConnectRelaxed();
|
||||
bool NetworkConnected();
|
||||
void PrepareSend();
|
||||
IPAddress NetworkLocalIP();
|
||||
IPAddress NetworkSubnetMask();
|
||||
IPAddress NetworkGatewayIP();
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include "../DataTypes/ESPEasyTimeSource.h"
|
||||
|
||||
#include "../ESPEasyCore/ESPEasyEth.h"
|
||||
#include "../ESPEasyCore/ESPEasy_Log.h"
|
||||
#include "../ESPEasyCore/ESPEasyNetwork.h"
|
||||
#include "../ESPEasyCore/ESPEasyWifi.h"
|
||||
@@ -59,27 +60,27 @@ void WiFiEvent(system_event_id_t event, system_event_info_t info) {
|
||||
// ESP32 WiFi ready
|
||||
break;
|
||||
case SYSTEM_EVENT_STA_START:
|
||||
addLog(LOG_LEVEL_INFO, F("WiFi : STA Started"));
|
||||
addLog(LOG_LEVEL_INFO, F("WiFi : STA Started"));
|
||||
break;
|
||||
case SYSTEM_EVENT_STA_STOP:
|
||||
addLog(LOG_LEVEL_INFO, F("WiFi : STA Stopped"));
|
||||
addLog(LOG_LEVEL_INFO, F("WiFi : STA Stopped"));
|
||||
break;
|
||||
case SYSTEM_EVENT_AP_START:
|
||||
addLog(LOG_LEVEL_INFO, F("WiFi : AP Started"));
|
||||
addLog(LOG_LEVEL_INFO, F("WiFi : AP Started"));
|
||||
break;
|
||||
case SYSTEM_EVENT_AP_STOP:
|
||||
addLog(LOG_LEVEL_INFO, F("WiFi : AP Stopped"));
|
||||
addLog(LOG_LEVEL_INFO, F("WiFi : AP Stopped"));
|
||||
break;
|
||||
case SYSTEM_EVENT_STA_LOST_IP:
|
||||
// ESP32 station lost IP and the IP is reset to 0
|
||||
WiFiEventData.markLostIP();
|
||||
addLog(LOG_LEVEL_INFO, F("WiFi : Lost IP"));
|
||||
addLog(LOG_LEVEL_INFO, F("WiFi : Lost IP"));
|
||||
break;
|
||||
|
||||
case SYSTEM_EVENT_AP_PROBEREQRECVED:
|
||||
// Receive probe request packet in soft-AP interface
|
||||
// TODO TD-er: Must implement like onProbeRequestAPmode for ESP8266
|
||||
addLog(LOG_LEVEL_INFO, F("WiFi : AP got probed"));
|
||||
addLog(LOG_LEVEL_INFO, F("WiFi : AP got probed"));
|
||||
break;
|
||||
|
||||
case SYSTEM_EVENT_STA_AUTHMODE_CHANGE:
|
||||
@@ -117,11 +118,15 @@ void WiFiEvent(system_event_id_t event, system_event_info_t info) {
|
||||
break;
|
||||
#ifdef HAS_ETHERNET
|
||||
case SYSTEM_EVENT_ETH_START:
|
||||
addLog(LOG_LEVEL_INFO, F("ETH Started"));
|
||||
if (ethPrepare()) {
|
||||
addLog(LOG_LEVEL_INFO, F("ETH Started"));
|
||||
} else {
|
||||
addLog(LOG_LEVEL_ERROR, F("ETH : Could not prepare ETH!"));
|
||||
}
|
||||
break;
|
||||
case SYSTEM_EVENT_ETH_CONNECTED:
|
||||
addLog(LOG_LEVEL_INFO, F("ETH Connected"));
|
||||
eth_connected = true;
|
||||
//eth_connected = true;
|
||||
processEthernetConnected();
|
||||
break;
|
||||
case SYSTEM_EVENT_ETH_GOT_IP:
|
||||
|
||||
@@ -212,8 +212,9 @@ void WiFiConnectRelaxed() {
|
||||
}
|
||||
|
||||
void AttemptWiFiConnect() {
|
||||
// Start connect attempt now, so no longer needed to attempt new connection.
|
||||
WiFiEventData.wifiConnectAttemptNeeded = false;
|
||||
if (!WiFiEventData.wifiConnectAttemptNeeded) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (WiFiEventData.wifiSetupConnect) {
|
||||
// wifiSetupConnect is when run from the setup page.
|
||||
@@ -245,9 +246,11 @@ void AttemptWiFiConnect() {
|
||||
} else {
|
||||
WiFi.begin(candidate.ssid.c_str(), candidate.key.c_str());
|
||||
}
|
||||
// Start connect attempt now, so no longer needed to attempt new connection.
|
||||
WiFiEventData.wifiConnectAttemptNeeded = false;
|
||||
}
|
||||
} else {
|
||||
if (!wifiAPmodeActivelyUsed()) {
|
||||
if (!wifiAPmodeActivelyUsed() || WiFiEventData.wifiSetupConnect) {
|
||||
if (!prepareWiFi()) {
|
||||
return;
|
||||
}
|
||||
@@ -267,7 +270,8 @@ bool prepareWiFi() {
|
||||
if (!WiFi_AP_Candidates.hasKnownCredentials()) {
|
||||
addLog(LOG_LEVEL_ERROR, F("WIFI : No valid wifi settings"));
|
||||
WiFiEventData.last_wifi_connect_attempt_moment.clear();
|
||||
WiFiEventData.wifi_connect_attempt = 1;
|
||||
WiFiEventData.wifi_connect_attempt = 1;
|
||||
WiFiEventData.wifiConnectAttemptNeeded = false;
|
||||
|
||||
// No need to wait longer to start AP mode.
|
||||
setAP(true);
|
||||
@@ -296,8 +300,11 @@ bool checkAndResetWiFi() {
|
||||
|
||||
switch(status) {
|
||||
case STATION_GOT_IP:
|
||||
// This is a valid status, no need to reset
|
||||
return false;
|
||||
if (WiFi.RSSI() < 0) {
|
||||
// This is a valid status, no need to reset
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case STATION_NO_AP_FOUND:
|
||||
case STATION_CONNECT_FAIL:
|
||||
case STATION_WRONG_PASSWORD:
|
||||
@@ -310,7 +317,7 @@ bool checkAndResetWiFi() {
|
||||
}
|
||||
break;
|
||||
}
|
||||
String log = F("WIFI : WiFiConnected() out of sync: ");
|
||||
String log = F("WiFi : WiFiConnected() out of sync: ");
|
||||
log += ESPeasyWifiStatusToString();
|
||||
log += F(" RSSI: ");
|
||||
log += String(WiFi.RSSI());
|
||||
@@ -328,7 +335,7 @@ bool checkAndResetWiFi() {
|
||||
if (!WiFiEventData.last_wifi_connect_attempt_moment.timeoutReached(15000)) {
|
||||
return false;
|
||||
}
|
||||
String log = F("WIFI : WiFiConnected() out of sync: ");
|
||||
String log = F("WiFi : WiFiConnected() out of sync: ");
|
||||
log += ESPeasyWifiStatusToString();
|
||||
log += F(" RSSI: ");
|
||||
log += String(WiFi.RSSI());
|
||||
@@ -406,6 +413,10 @@ void SetWiFiTXpower(float dBm, float rssi) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (Settings.UseMaxTXpowerForSending()) {
|
||||
dBm = 30; // Just some max, will be limited later
|
||||
}
|
||||
|
||||
// Range ESP32 : 2dBm - 20dBm
|
||||
// Range ESP8266: 0dBm - 20.5dBm
|
||||
float maxTXpwr;
|
||||
@@ -487,7 +498,7 @@ void SetWiFiTXpower(float dBm, float rssi) {
|
||||
|
||||
WiFiEventData.wifi_TX_pwr = dBm;
|
||||
|
||||
delay(1);
|
||||
delay(0);
|
||||
#ifndef BUILD_NO_DEBUG
|
||||
if (loglevelActiveFor(LOG_LEVEL_DEBUG)) {
|
||||
if (WiFiEventData.wifi_TX_pwr != maxTXpwr) {
|
||||
@@ -588,7 +599,7 @@ void WifiScan(bool async, uint8_t channel) {
|
||||
// Scan still busy
|
||||
return;
|
||||
}
|
||||
addLog(LOG_LEVEL_INFO, F("WIFI : Start network scan"));
|
||||
addLog(LOG_LEVEL_INFO, F("WiFi : Start network scan"));
|
||||
bool show_hidden = true;
|
||||
WiFiEventData.processedScanDone = false;
|
||||
WiFiEventData.lastGetScanMoment.setNow();
|
||||
@@ -1015,7 +1026,7 @@ void logConnectionStatus() {
|
||||
|
||||
if ((arduino_corelib_wifistatus == WL_CONNECTED) != (sdk_wifistatus == STATION_GOT_IP)) {
|
||||
if (loglevelActiveFor(LOG_LEVEL_ERROR)) {
|
||||
String log = F("WIFI : SDK station status differs from Arduino status. SDK-status: ");
|
||||
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);
|
||||
|
||||
@@ -400,7 +400,7 @@ void processScanDone() {
|
||||
WiFiEventData.processedScanDone = true;
|
||||
|
||||
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
|
||||
String log = F("WIFI : Scan finished, found: ");
|
||||
String log = F("WiFi : Scan finished, found: ");
|
||||
log += scanCompleteStatus;
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
}
|
||||
@@ -409,7 +409,7 @@ void processScanDone() {
|
||||
|
||||
const WiFi_AP_Candidate bestCandidate = WiFi_AP_Candidates.getBestScanResult();
|
||||
if (bestCandidate.usable() && loglevelActiveFor(LOG_LEVEL_INFO)) {
|
||||
String log = F("WIFI : Selected: ");
|
||||
String log = F("WiFi : Selected: ");
|
||||
log += bestCandidate.toString();
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
}
|
||||
@@ -470,6 +470,7 @@ void markWiFi_services_initialized() {
|
||||
#ifdef HAS_ETHERNET
|
||||
|
||||
void processEthernetConnected() {
|
||||
++WiFiEventData.wifi_reconnects;
|
||||
if (Settings.UseRules)
|
||||
{
|
||||
eventQueue.add(F("ETHERNET#Connected"));
|
||||
|
||||
@@ -121,7 +121,9 @@ void process_serialWriteBuffer() {
|
||||
|
||||
while (bytes_to_write > 0 && !serialWriteBuffer.empty()) {
|
||||
const char c = serialWriteBuffer.front();
|
||||
Serial.write(c);
|
||||
if (Settings.UseSerial) {
|
||||
Serial.write(c);
|
||||
}
|
||||
serialWriteBuffer.pop_front();
|
||||
--bytes_to_write;
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ bool C016_getCSVline(
|
||||
{
|
||||
C016_queue_element element;
|
||||
bool result = ControllerCache.peek((uint8_t*)&element, sizeof(element));
|
||||
timestamp = element.timestamp;
|
||||
timestamp = element._timestamp;
|
||||
controller_idx = element.controller_idx;
|
||||
TaskIndex = element.TaskIndex;
|
||||
sensorType = element.sensorType;
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
|
||||
#include "../../ESPEasy_common.h"
|
||||
|
||||
// Ethernet Connectiopn status
|
||||
|
||||
// Ethernet Connection status
|
||||
NetworkMedium_t active_network_medium = DEFAULT_NETWORK_MEDIUM;
|
||||
bool eth_connected = false;
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "../DataStructs/RTCStruct.h"
|
||||
#include "../DataStructs/RTCCacheStruct.h"
|
||||
#include "../DataStructs/RTC_cache_handler_struct.h"
|
||||
#include "../DataStructs/TimingStats.h"
|
||||
#include "../Globals/Plugins.h"
|
||||
#include "../Globals/RuntimeData.h"
|
||||
#include "../Helpers/CRC_functions.h"
|
||||
@@ -65,6 +66,7 @@ bool saveToRTC()
|
||||
return false;
|
||||
#else // if defined(ESP32)
|
||||
|
||||
START_TIMER
|
||||
if (!system_rtc_mem_write(RTC_BASE_STRUCT, (byte *)&RTC, sizeof(RTC)) || !readFromRTC())
|
||||
{
|
||||
# ifdef RTC_STRUCT_DEBUG
|
||||
@@ -74,6 +76,7 @@ bool saveToRTC()
|
||||
}
|
||||
else
|
||||
{
|
||||
STOP_TIMER(SAVE_TO_RTC);
|
||||
return true;
|
||||
}
|
||||
#endif // if defined(ESP32)
|
||||
|
||||
@@ -203,7 +203,7 @@ void ResetFactory()
|
||||
Settings.ETH_Pin_power = gpio_settings.eth_power;
|
||||
Settings.ETH_Phy_Type = gpio_settings.eth_phytype;
|
||||
Settings.ETH_Clock_Mode = gpio_settings.eth_clock_mode;
|
||||
Settings.NetworkMedium = gpio_settings.active_network_medium;
|
||||
Settings.NetworkMedium = gpio_settings.network_medium;
|
||||
|
||||
/*
|
||||
Settings.GlobalSync = DEFAULT_USE_GLOBAL_SYNC;
|
||||
|
||||
@@ -32,6 +32,10 @@
|
||||
#include "../DataStructs/C013_p2p_dataStructs.h"
|
||||
#endif
|
||||
|
||||
#ifdef USES_C016
|
||||
#include "../ControllerQueue/C016_queue_element.h"
|
||||
#endif
|
||||
|
||||
#ifdef USES_NOTIFIER
|
||||
#include "../DataStructs/NotificationStruct.h"
|
||||
#include "../DataStructs/NotificationSettingsStruct.h"
|
||||
@@ -99,6 +103,11 @@ void run_compiletime_checks() {
|
||||
check_size<C013_SensorInfoStruct, 137u>();
|
||||
check_size<C013_SensorDataStruct, 24u>();
|
||||
#endif
|
||||
#ifdef USES_C016
|
||||
check_size<C016_queue_element, 24u>();
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(USE_NON_STANDARD_24_TASKS) && defined(ESP8266)
|
||||
static_assert(TASKS_MAX == 24, "TASKS_MAX invalid size");
|
||||
#endif
|
||||
|
||||
@@ -977,7 +977,7 @@ bool hostReachable(const IPAddress& ip) {
|
||||
}
|
||||
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."));
|
||||
addLog(LOG_LEVEL_ERROR, F("WiFi : Detected strange behavior, reconnect wifi."));
|
||||
WifiDisconnect();
|
||||
}
|
||||
logConnectionStatus();
|
||||
@@ -1001,7 +1001,6 @@ bool connectClient(WiFiClient& client, IPAddress ip, uint16_t port)
|
||||
if (!NetworkConnected()) {
|
||||
return false;
|
||||
}
|
||||
PrepareSend();
|
||||
|
||||
// In case of domain name resolution error result can be negative.
|
||||
// https://github.com/esp8266/Arduino/blob/18f643c7e2d6a0da9d26ff2b14c94e6536ab78c1/libraries/Ethernet/src/Dns.cpp#L44
|
||||
@@ -1030,7 +1029,7 @@ bool resolveHostByName(const char *aHostname, IPAddress& aResult) {
|
||||
if (!NetworkConnected()) {
|
||||
return false;
|
||||
}
|
||||
PrepareSend();
|
||||
|
||||
#if defined(ARDUINO_ESP8266_RELEASE_2_3_0) || defined(ESP32)
|
||||
bool resolvedIP = WiFi.hostByName(aHostname, aResult) == 1;
|
||||
#else // if defined(ARDUINO_ESP8266_RELEASE_2_3_0) || defined(ESP32)
|
||||
@@ -1083,8 +1082,6 @@ void sendGratuitousARP() {
|
||||
}
|
||||
#ifdef SUPPORT_ARP
|
||||
|
||||
PrepareSend();
|
||||
|
||||
// See https://github.com/letscontrolit/ESPEasy/issues/2374
|
||||
START_TIMER;
|
||||
netif *n = netif_list;
|
||||
|
||||
@@ -293,7 +293,6 @@ void processMQTTdelayQueue() {
|
||||
|
||||
if (element == NULL) { return; }
|
||||
|
||||
PrepareSend();
|
||||
if (MQTTclient.publish(element->_topic.c_str(), element->_payload.c_str(), element->_retained)) {
|
||||
if (WiFiEventData.connectionFailures > 0) {
|
||||
--WiFiEventData.connectionFailures;
|
||||
@@ -358,7 +357,6 @@ void runPeriodicalMQTT() {
|
||||
//dont do this in backgroundtasks(), otherwise causes crashes. (https://github.com/letscontrolit/ESPEasy/issues/683)
|
||||
controllerIndex_t enabledMqttController = firstEnabledMQTT_ControllerIndex();
|
||||
if (validControllerIndex(enabledMqttController)) {
|
||||
PrepareSend();
|
||||
if (!MQTTclient.loop()) {
|
||||
updateMQTTclient_connected();
|
||||
if (MQTTCheck(enabledMqttController)) {
|
||||
|
||||
@@ -237,7 +237,7 @@ void ESPEasy_Scheduler::handle_schedule() {
|
||||
// No id ready to run right now.
|
||||
// Events are not that important to run immediately.
|
||||
// Make sure normal scheduled jobs run at higher priority.
|
||||
backgroundtasks();
|
||||
//backgroundtasks();
|
||||
process_system_event_queue();
|
||||
last_system_event_run = millis();
|
||||
STOP_TIMER(HANDLE_SCHEDULER_IDLE);
|
||||
|
||||
@@ -161,9 +161,9 @@ String getLabel(LabelType::Enum label) {
|
||||
case LabelType::ETH_SPEED: return F("Eth Speed");
|
||||
case LabelType::ETH_STATE: return F("Eth State");
|
||||
case LabelType::ETH_SPEED_STATE: return F("Eth Speed State");
|
||||
case LabelType::ETH_WIFI_MODE: return F("Network Type");
|
||||
case LabelType::ETH_CONNECTED: return F("Eth connected");
|
||||
#endif // ifdef HAS_ETHERNET
|
||||
case LabelType::ETH_WIFI_MODE: return F("Network Type");
|
||||
}
|
||||
return F("MissingString");
|
||||
}
|
||||
@@ -301,9 +301,9 @@ String getValue(LabelType::Enum label) {
|
||||
case LabelType::ETH_SPEED: return eth_connected ? getEthSpeed() : F("No Ethernet");
|
||||
case LabelType::ETH_STATE: return eth_connected ? (ETH.linkUp() ? F("Link Up") : F("Link Down")) : F("No Ethernet");
|
||||
case LabelType::ETH_SPEED_STATE: return eth_connected ? getEthLinkSpeedState() : F("No Ethernet");
|
||||
case LabelType::ETH_WIFI_MODE: return active_network_medium == NetworkMedium_t::WIFI ? F("WIFI") : F("ETHERNET");
|
||||
case LabelType::ETH_CONNECTED: return eth_connected ? F("CONNECTED") : F("DISCONNECTED"); // 0=disconnected, 1=connected
|
||||
#endif // ifdef HAS_ETHERNET
|
||||
case LabelType::ETH_WIFI_MODE: return active_network_medium == NetworkMedium_t::WIFI ? F("WIFI") : F("ETHERNET");
|
||||
}
|
||||
return F("MissingString");
|
||||
}
|
||||
|
||||
@@ -131,9 +131,9 @@ struct LabelType {
|
||||
ETH_SPEED,
|
||||
ETH_STATE,
|
||||
ETH_SPEED_STATE,
|
||||
ETH_WIFI_MODE,
|
||||
ETH_CONNECTED,
|
||||
#endif // ifdef HAS_ETHERNET
|
||||
ETH_WIFI_MODE,
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -193,9 +193,9 @@ void SystemVariables::parseSystemVariables(String& s, boolean useURLencode)
|
||||
}
|
||||
while (enumval != SystemVariables::Enum::UNKNOWN);
|
||||
|
||||
const int v_index = s.indexOf(F("%v"));
|
||||
int v_index = s.indexOf(F("%v"));
|
||||
|
||||
if ((v_index != -1)) {
|
||||
while ((v_index != -1)) {
|
||||
unsigned int i;
|
||||
if (validUIntFromString(s.substring(v_index + 2), i)) {
|
||||
const String key = String(F("%v")) + String(i) + '%';
|
||||
@@ -205,6 +205,7 @@ void SystemVariables::parseSystemVariables(String& s, boolean useURLencode)
|
||||
repl(key, value, s, useURLencode);
|
||||
}
|
||||
}
|
||||
v_index = s.indexOf(F("%v"), v_index + 1); // Find next occurance
|
||||
}
|
||||
|
||||
STOP_TIMER(PARSE_SYSVAR);
|
||||
|
||||
@@ -62,7 +62,7 @@ void WiFi_AP_CandidatesList::process_WiFiscan(uint8_t scancount) {
|
||||
#ifndef BUILD_NO_DEBUG
|
||||
|
||||
for (auto it = candidates.begin(); it != candidates.end(); ++it) {
|
||||
String log = F("WIFI : Scan result: ");
|
||||
String log = F("WiFi : Scan result: ");
|
||||
log += it->toString();
|
||||
addLog(LOG_LEVEL_INFO, log);
|
||||
}
|
||||
|
||||
@@ -523,8 +523,6 @@ String send_via_http(const String& logIdentifier,
|
||||
// "if you have XXX, send it; or failing that, just give me what you've got."
|
||||
http.addHeader(F("Accept"), F("*/*;q=0.1"));
|
||||
|
||||
PrepareSend();
|
||||
|
||||
delay(0);
|
||||
#if defined(CORE_POST_2_6_0) || defined(ESP32)
|
||||
http.begin(client, host, port, uri, false); // HTTP
|
||||
|
||||
@@ -44,6 +44,9 @@ String getControllerParameterName(protocolIndex_t ProtocolInde
|
||||
case ControllerSettingsStruct::CONTROLLER_MAX_QUEUE_DEPTH: name = F("Max Queue Depth"); break;
|
||||
case ControllerSettingsStruct::CONTROLLER_MAX_RETRIES: name = F("Max Retries"); break;
|
||||
case ControllerSettingsStruct::CONTROLLER_FULL_QUEUE_ACTION: name = F("Full Queue Action"); break;
|
||||
case ControllerSettingsStruct::CONTROLLER_ALLOW_EXPIRE: name = F("Allow Expire"); break;
|
||||
case ControllerSettingsStruct::CONTROLLER_DEDUPLICATE: name = F("De-duplicate"); break;
|
||||
|
||||
case ControllerSettingsStruct::CONTROLLER_CHECK_REPLY: name = F("Check Reply"); break;
|
||||
|
||||
case ControllerSettingsStruct::CONTROLLER_CLIENT_ID: name = F("Controller Client ID"); break;
|
||||
@@ -192,6 +195,12 @@ void addControllerParameterForm(const ControllerSettingsStruct& ControllerSettin
|
||||
addFormSelector(displayName, internalName, 2, options, NULL, NULL, ControllerSettings.DeleteOldest, false);
|
||||
break;
|
||||
}
|
||||
case ControllerSettingsStruct::CONTROLLER_ALLOW_EXPIRE:
|
||||
addFormCheckBox(displayName, internalName, ControllerSettings.allowExpire());
|
||||
break;
|
||||
case ControllerSettingsStruct::CONTROLLER_DEDUPLICATE:
|
||||
addFormCheckBox(displayName, internalName, ControllerSettings.deduplicate());
|
||||
break;
|
||||
case ControllerSettingsStruct::CONTROLLER_CHECK_REPLY:
|
||||
{
|
||||
String options[2];
|
||||
@@ -313,6 +322,12 @@ void saveControllerParameterForm(ControllerSettingsStruct & ControllerSet
|
||||
case ControllerSettingsStruct::CONTROLLER_FULL_QUEUE_ACTION:
|
||||
ControllerSettings.DeleteOldest = getFormItemInt(internalName, ControllerSettings.DeleteOldest);
|
||||
break;
|
||||
case ControllerSettingsStruct::CONTROLLER_ALLOW_EXPIRE:
|
||||
ControllerSettings.allowExpire(isFormItemChecked(internalName));
|
||||
break;
|
||||
case ControllerSettingsStruct::CONTROLLER_DEDUPLICATE:
|
||||
ControllerSettings.deduplicate(isFormItemChecked(internalName));
|
||||
break;
|
||||
case ControllerSettingsStruct::CONTROLLER_CHECK_REPLY:
|
||||
ControllerSettings.MustCheckReply = getFormItemInt(internalName, ControllerSettings.MustCheckReply);
|
||||
break;
|
||||
|
||||
@@ -118,7 +118,7 @@ void P044_Task::checkBlinkLED() {
|
||||
|
||||
void P044_Task::clearBuffer() {
|
||||
if (serial_buffer.length() > maxMessageSize) {
|
||||
maxMessageSize = serial_buffer.length();
|
||||
maxMessageSize = _min(serial_buffer.length(), P044_DATAGRAM_MAX_SIZE);
|
||||
}
|
||||
|
||||
serial_buffer = "";
|
||||
@@ -262,7 +262,6 @@ void P044_Task::handleSerialIn(struct EventStruct *event) {
|
||||
} while (true);
|
||||
|
||||
if (done) {
|
||||
PrepareSend();
|
||||
P1GatewayClient.print(serial_buffer);
|
||||
P1GatewayClient.flush();
|
||||
|
||||
|
||||
@@ -78,7 +78,10 @@ bool P082_data_struct::loop() {
|
||||
--available;
|
||||
char c = easySerial->read();
|
||||
# ifdef P082_SEND_GPS_TO_LOG
|
||||
_currentSentence += c;
|
||||
if (_currentSentence.length() <= 80) {
|
||||
// No need to capture more than 80 bytes as a NMEA message is never that long.
|
||||
_currentSentence += c;
|
||||
}
|
||||
# endif // ifdef P082_SEND_GPS_TO_LOG
|
||||
|
||||
if (gps->encode(c)) {
|
||||
|
||||
@@ -7,8 +7,9 @@
|
||||
# include <TinyGPS++.h>
|
||||
# include <ESPeasySerial.h>
|
||||
|
||||
|
||||
#ifndef LIMIT_BUILD_SIZE
|
||||
# define P082_SEND_GPS_TO_LOG
|
||||
#endif
|
||||
|
||||
# define P082_TIMESTAMP_AGE 1500
|
||||
# define P082_DEFAULT_FIX_TIMEOUT 2500 // TTL of fix status in ms since last update
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "../WebServer/Rules.h"
|
||||
|
||||
#include "../Globals/Services.h"
|
||||
#include "../Globals/Settings.h"
|
||||
|
||||
#include "../Globals/ESPEasyWiFiEvent.h"
|
||||
|
||||
@@ -16,10 +17,11 @@ void handleNotFound() {
|
||||
checkRAM(F("handleNotFound"));
|
||||
#endif
|
||||
|
||||
if (WiFiEventData.wifiSetup)
|
||||
// if Wifi setup, launch setup wizard if AP_DONT_FORCE_SETUP is not set.
|
||||
if (WiFiEventData.wifiSetup && !Settings.ApDontForceSetup())
|
||||
{
|
||||
web_server.send(200, F("text/html"), F("<meta HTTP-EQUIV='REFRESH' content='0; url=/setup'>"));
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isLoggedIn()) { return; }
|
||||
|
||||
@@ -79,6 +79,9 @@ void handle_config() {
|
||||
// Access point password.
|
||||
copyFormPassword(F("apkey"), SecuritySettings.WifiAPKey, sizeof(SecuritySettings.WifiAPKey));
|
||||
|
||||
// When set you can use the Sensor in AP-Mode without being forced to /setup
|
||||
Settings.ApDontForceSetup(isFormItemChecked(F("ApDontForceSetup")));
|
||||
|
||||
|
||||
// TD-er Read access control from form.
|
||||
SecuritySettings.IPblockLevel = getFormItemInt(F("ipblocklevel"));
|
||||
@@ -142,6 +145,9 @@ void handle_config() {
|
||||
addFormSeparator(2);
|
||||
addFormPasswordBox(F("WPA AP Mode Key"), F("apkey"), SecuritySettings.WifiAPKey, 63);
|
||||
|
||||
addFormCheckBox(F("Don't force /setup in AP-Mode"), F("ApDontForceSetup"), Settings.ApDontForceSetup());
|
||||
addFormNote(F("When set you can use the Sensor in AP-Mode without being forced to /setup. /setup can still be called."));
|
||||
|
||||
// TD-er add IP access box F("ipblocklevel")
|
||||
addFormSubHeader(F("Client IP filtering"));
|
||||
{
|
||||
|
||||
@@ -325,6 +325,10 @@ void handle_controllers_ControllerSettingsPage(controllerIndex_t controllerindex
|
||||
addControllerParameterForm(ControllerSettings, controllerindex, ControllerSettingsStruct::CONTROLLER_MAX_QUEUE_DEPTH);
|
||||
addControllerParameterForm(ControllerSettings, controllerindex, ControllerSettingsStruct::CONTROLLER_MAX_RETRIES);
|
||||
addControllerParameterForm(ControllerSettings, controllerindex, ControllerSettingsStruct::CONTROLLER_FULL_QUEUE_ACTION);
|
||||
if (Protocol[ProtocolIndex].allowsExpire) {
|
||||
addControllerParameterForm(ControllerSettings, controllerindex, ControllerSettingsStruct::CONTROLLER_ALLOW_EXPIRE);
|
||||
}
|
||||
addControllerParameterForm(ControllerSettings, controllerindex, ControllerSettingsStruct::CONTROLLER_DEDUPLICATE);
|
||||
}
|
||||
|
||||
if (Protocol[ProtocolIndex].usesCheckReply) {
|
||||
|
||||
@@ -33,11 +33,11 @@ void handle_root() {
|
||||
checkRAM(F("handle_root"));
|
||||
#endif
|
||||
|
||||
// if Wifi setup, launch setup wizard
|
||||
if (WiFiEventData.wifiSetup)
|
||||
// if Wifi setup, launch setup wizard if AP_DONT_FORCE_SETUP is not set.
|
||||
if (WiFiEventData.wifiSetup && !Settings.ApDontForceSetup())
|
||||
{
|
||||
web_server.send(200, F("text/html"), F("<meta HTTP-EQUIV='REFRESH' content='0; url=/setup'>"));
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isLoggedIn()) { return; }
|
||||
@@ -151,11 +151,16 @@ void handle_root() {
|
||||
addHtml(html);
|
||||
}
|
||||
|
||||
addRowLabelValue(LabelType::IP_ADDRESS);
|
||||
addRowLabel(LabelType::WIFI_RSSI);
|
||||
#ifdef HAS_ETHERNET
|
||||
addRowLabelValue(LabelType::ETH_WIFI_MODE);
|
||||
#endif
|
||||
|
||||
if (NetworkConnected())
|
||||
if (
|
||||
active_network_medium == NetworkMedium_t::WIFI &&
|
||||
NetworkConnected())
|
||||
{
|
||||
addRowLabelValue(LabelType::IP_ADDRESS);
|
||||
addRowLabel(LabelType::WIFI_RSSI);
|
||||
String html;
|
||||
html.reserve(32);
|
||||
html += String(WiFi.RSSI());
|
||||
@@ -166,7 +171,6 @@ void handle_root() {
|
||||
}
|
||||
|
||||
#ifdef HAS_ETHERNET
|
||||
addRowLabelValue(LabelType::ETH_WIFI_MODE);
|
||||
if(active_network_medium == NetworkMedium_t::Ethernet) {
|
||||
addRowLabelValue(LabelType::ETH_SPEED_STATE);
|
||||
addRowLabelValue(LabelType::ETH_IP_ADDRESS);
|
||||
|
||||
@@ -381,50 +381,51 @@ void handle_sysinfo_Ethernet() {
|
||||
addRowLabelValue(LabelType::ETH_SPEED);
|
||||
addRowLabelValue(LabelType::ETH_DUPLEX);
|
||||
addRowLabelValue(LabelType::ETH_MAC);
|
||||
addRowLabelValue(LabelType::ETH_IP_ADDRESS_SUBNET);
|
||||
addRowLabelValue(LabelType::ETH_IP_GATEWAY);
|
||||
addRowLabelValue(LabelType::ETH_IP_DNS);
|
||||
// addRowLabelValue(LabelType::ETH_IP_ADDRESS_SUBNET);
|
||||
// addRowLabelValue(LabelType::ETH_IP_GATEWAY);
|
||||
// addRowLabelValue(LabelType::ETH_IP_DNS);
|
||||
}
|
||||
}
|
||||
|
||||
# endif // ifdef HAS_ETHERNET
|
||||
|
||||
void handle_sysinfo_Network() {
|
||||
addTableSeparator(F("Network"), 2, 3, F("Wifi"));
|
||||
addTableSeparator(F("Network"), 2, 3);
|
||||
|
||||
# ifdef HAS_ETHERNET
|
||||
addRowLabelValue(LabelType::ETH_WIFI_MODE);
|
||||
# endif // ifdef HAS_ETHERNET
|
||||
|
||||
|
||||
if (
|
||||
# ifdef HAS_ETHERNET
|
||||
active_network_medium == NetworkMedium_t::WIFI &&
|
||||
# endif // ifdef HAS_ETHERNET
|
||||
NetworkConnected())
|
||||
{
|
||||
addRowLabel(F("Wifi"));
|
||||
{
|
||||
String html;
|
||||
html.reserve(64);
|
||||
|
||||
html += toString(getConnectionProtocol());
|
||||
html += F(" (RSSI ");
|
||||
html += WiFi.RSSI();
|
||||
html += F(" dBm)");
|
||||
addHtml(html);
|
||||
}
|
||||
}
|
||||
addRowLabelValue(LabelType::IP_CONFIG);
|
||||
addRowLabelValue(LabelType::IP_ADDRESS_SUBNET);
|
||||
addRowLabelValue(LabelType::GATEWAY);
|
||||
addRowLabelValue(LabelType::CLIENT_IP);
|
||||
addRowLabelValue(LabelType::DNS);
|
||||
addRowLabelValue(LabelType::ALLOWED_IP_RANGE);
|
||||
addRowLabelValue(LabelType::STA_MAC);
|
||||
addRowLabelValue(LabelType::AP_MAC);
|
||||
addRowLabelValue(LabelType::CONNECTED);
|
||||
addRowLabelValue(LabelType::NUMBER_RECONNECTS);
|
||||
|
||||
addTableSeparator(F("WiFi"), 2, 3, F("Wifi"));
|
||||
|
||||
const bool showWiFiConnectionInfo =
|
||||
active_network_medium == NetworkMedium_t::WIFI &&
|
||||
NetworkConnected();
|
||||
|
||||
addRowLabel(F("Wifi Connection"));
|
||||
if (showWiFiConnectionInfo)
|
||||
{
|
||||
String html;
|
||||
html.reserve(64);
|
||||
|
||||
html += toString(getConnectionProtocol());
|
||||
html += F(" (RSSI ");
|
||||
html += WiFi.RSSI();
|
||||
html += F(" dBm)");
|
||||
addHtml(html);
|
||||
} else addHtml('-');
|
||||
|
||||
addRowLabel(LabelType::SSID);
|
||||
if (showWiFiConnectionInfo)
|
||||
{
|
||||
String html;
|
||||
html.reserve(64);
|
||||
@@ -434,14 +435,26 @@ void handle_sysinfo_Network() {
|
||||
html += WiFi.BSSIDstr();
|
||||
html += ')';
|
||||
addHtml(html);
|
||||
} else addHtml('-');
|
||||
|
||||
addRowLabel(getLabel(LabelType::CHANNEL));
|
||||
if (showWiFiConnectionInfo) {
|
||||
addHtml(getValue(LabelType::CHANNEL));
|
||||
} else addHtml('-');
|
||||
|
||||
addRowLabel(getLabel(LabelType::ENCRYPTION_TYPE_STA));
|
||||
if (showWiFiConnectionInfo) {
|
||||
addHtml(getValue(LabelType::ENCRYPTION_TYPE_STA));
|
||||
} else addHtml('-');
|
||||
|
||||
if (active_network_medium == NetworkMedium_t::WIFI)
|
||||
{
|
||||
addRowLabel(LabelType::LAST_DISCONNECT_REASON);
|
||||
addHtml(getValue(LabelType::LAST_DISC_REASON_STR));
|
||||
}
|
||||
|
||||
addRowLabelValue(LabelType::CHANNEL);
|
||||
addRowLabelValue(LabelType::ENCRYPTION_TYPE_STA);
|
||||
addRowLabelValue(LabelType::CONNECTED);
|
||||
addRowLabel(LabelType::LAST_DISCONNECT_REASON);
|
||||
addHtml(getValue(LabelType::LAST_DISC_REASON_STR));
|
||||
addRowLabelValue(LabelType::NUMBER_RECONNECTS);
|
||||
addRowLabelValue(LabelType::STA_MAC);
|
||||
addRowLabelValue(LabelType::AP_MAC);
|
||||
}
|
||||
|
||||
void handle_sysinfo_WiFiSettings() {
|
||||
|
||||
Reference in New Issue
Block a user