mirror of
https://github.com/letscontrolit/ESPEasy.git
synced 2026-10-26 22:10:45 +00:00
Merge branch 'mega' into bugfix/Command-udpport-argument-parsing
This commit is contained in:
17 files changed
+359
-207
No files matched your search
@@ -82,7 +82,7 @@ jobs:
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
uv pip install --system pioarduino
|
||||
uv pip install --system pygit2>=1.10.1
|
||||
uv pip install --system -r requirements.txt
|
||||
- name: Get current date
|
||||
id: date
|
||||
run: |
|
||||
|
||||
@@ -41,28 +41,34 @@ jobs:
|
||||
- uses: actions/setup-python@v7
|
||||
with:
|
||||
python-version: '3.13'
|
||||
- name: Dependencies
|
||||
- name: Install uv
|
||||
uses: astral-sh/setup-uv@v7
|
||||
with:
|
||||
version: "latest"
|
||||
enable-cache: false
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt install binutils build-essential libffi-dev libgit2-dev
|
||||
pip install uv
|
||||
uv pip install --system pioarduino
|
||||
uv pip install --system -r requirements.txt
|
||||
pio pkg update -e ${{ matrix.env }}
|
||||
- name: Build and archive
|
||||
id: build-and-archive
|
||||
env:
|
||||
CHIP: ${{ matrix.chip }}
|
||||
ENV: ${{ matrix.env }}
|
||||
- name: Get current date
|
||||
id: date
|
||||
run: |
|
||||
python tools/ci/build-and-archive.py
|
||||
echo "builddate=$(date +'%Y%m%d')" >> $GITHUB_OUTPUT
|
||||
- name: Run PlatformIO
|
||||
env:
|
||||
PYTHONIOENCODING: utf-8
|
||||
PYTHONUTF8: '1'
|
||||
run: platformio run -e ${{ matrix.env }}
|
||||
- id: string
|
||||
uses: Entepotenz/change-string-case-action-min-dependencies@v1
|
||||
with:
|
||||
string: ${{ matrix.chip }}
|
||||
- uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: Bin-${{ steps.string.outputs.uppercase }}-${{ matrix.env }}
|
||||
# FIXME Workaround to (temporarily) not use # in the artifact name, see https://github.com/actions/upload-artifact/issues/473
|
||||
name: Bin-${{ steps.string.outputs.uppercase }}-${{ matrix.env }}-${{ steps.date.outputs.builddate }}_PR_${{ github.event.number }}_${{ github.run_id }} # Sort by ESP type
|
||||
path: |
|
||||
bin
|
||||
./build_output/bin
|
||||
if-no-files-found: ignore
|
||||
|
||||
prepare-dist:
|
||||
|
||||
@@ -72,7 +72,7 @@ bool PingClass::ping(IPAddress dest, int16_t count) {
|
||||
bool PingClass::ping(const char* host, int16_t count) {
|
||||
IPAddress remote_addr;
|
||||
|
||||
if (WiFi.hostByName(host, remote_addr))
|
||||
if (WiFi.hostByName(host, remote_addr) == 1)
|
||||
return ping(remote_addr, count);
|
||||
|
||||
return false;
|
||||
|
||||
@@ -1173,7 +1173,7 @@ bool HTTPClientLight::connect(void)
|
||||
} else {
|
||||
IPAddress remote_addr;
|
||||
// Add include "ESP8266WiFi.h" for this to work
|
||||
if (!WiFi.hostByName(_host.c_str(), remote_addr)) {
|
||||
if (Network.hostByName(_host.c_str(), remote_addr) != 1) {
|
||||
return false;
|
||||
}
|
||||
if(!_client->connect(remote_addr, _port, _connectTimeout)) {
|
||||
|
||||
@@ -335,7 +335,7 @@ int WiFiClientSecure_light::connect(const char* name, uint16_t port, int32_t tim
|
||||
DEBUG_BSSL("connect(%s,%d)\n", name, port);
|
||||
IPAddress remote_addr;
|
||||
clearLastError();
|
||||
if (!WiFi.hostByName(name, remote_addr)) {
|
||||
if (Network.hostByName(name, remote_addr) != 1) {
|
||||
DEBUG_BSSL("connect: Name loopup failure\n");
|
||||
setLastError(ERR_CANT_RESOLVE_IP);
|
||||
return 0;
|
||||
|
||||
@@ -191,9 +191,8 @@ extra_scripts = ${esp82xx_common.extra_scripts}
|
||||
;platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/esp32-arduino-lib-builder/releases/download/2904-2115-5.5/framework-arduinoespressif32-release_v5.5-f2a3fa2b.tar.xz
|
||||
|
||||
platform = https://github.com/Jason2866/platform-espressif32.git#Arduino/IDF55_gcc152
|
||||
;platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/esp32-arduino-lib-builder/releases/download/1807-0842-5.5/framework-arduinoespressif32-release_v5.5-67336dba.tar.xz
|
||||
;platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/esp32-arduino-lib-builder/releases/download/2805-1324-5.5/framework-arduinoespressif32-release_v5.5-f3cdb9d0.tar.xz
|
||||
platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/esp32-arduino-lib-builder/releases/download/2708-1939-5.5.5/framework-arduinoespressif32-v5.5.5-a63b839f.tar.xz
|
||||
;platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/esp32-arduino-lib-builder/releases/download/2708-1939-5.5.5/framework-arduinoespressif32-v5.5.5-a63b839f.tar.xz
|
||||
platform_packages =
|
||||
|
||||
custom_remove_include = true
|
||||
|
||||
|
||||
@@ -47,11 +47,11 @@ bool WiFi_pre_STA_setup()
|
||||
void doWiFiDisconnect() {
|
||||
uint8_t retry = 3;
|
||||
|
||||
#ifdef BOARD_HAS_SDIO_ESP_HOSTED
|
||||
# ifdef BOARD_HAS_SDIO_ESP_HOSTED
|
||||
bool wifioff = true;
|
||||
#else
|
||||
# else
|
||||
bool wifioff = Settings.WiFiRestart_connection_lost();
|
||||
#endif
|
||||
# endif // ifdef BOARD_HAS_SDIO_ESP_HOSTED
|
||||
|
||||
while (!WiFi.disconnect(wifioff) && retry) {
|
||||
--retry;
|
||||
@@ -402,13 +402,40 @@ WiFiConnectionProtocol doGetConnectionProtocol()
|
||||
|
||||
void doSetWiFiTXpower(float& dBm)
|
||||
{
|
||||
int8_t power = dBm * 4;
|
||||
if (WiFi.STA.started() || WiFi.AP.started()) {
|
||||
constexpr wifi_power_t options[] = {
|
||||
WIFI_POWER_21dBm,
|
||||
WIFI_POWER_20_5dBm,
|
||||
WIFI_POWER_20dBm,
|
||||
WIFI_POWER_19_5dBm,
|
||||
WIFI_POWER_19dBm,
|
||||
WIFI_POWER_18_5dBm,
|
||||
WIFI_POWER_17dBm,
|
||||
WIFI_POWER_15dBm,
|
||||
WIFI_POWER_13dBm,
|
||||
WIFI_POWER_11dBm,
|
||||
WIFI_POWER_8_5dBm,
|
||||
WIFI_POWER_7dBm,
|
||||
WIFI_POWER_5dBm,
|
||||
WIFI_POWER_2dBm,
|
||||
WIFI_POWER_MINUS_1dBm
|
||||
};
|
||||
|
||||
esp_wifi_set_max_tx_power(power);
|
||||
int8_t power = std::min(static_cast<int>(dBm * 4), static_cast<int>(options[0]));
|
||||
|
||||
if (esp_wifi_get_max_tx_power(&power) == ESP_OK) {
|
||||
dBm = static_cast<float>(power) / 4.0f;
|
||||
for (size_t i = 0; i < NR_ELEMENTS(options); ++i) {
|
||||
if (power >= options[i]) {
|
||||
power = options[i];
|
||||
esp_wifi_set_max_tx_power(power);
|
||||
|
||||
if (esp_wifi_get_max_tx_power(&power) == ESP_OK) {
|
||||
dBm = static_cast<float>(power) / 4.0f;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
dBm = 0;
|
||||
}
|
||||
|
||||
float doGetWiFiTXpower()
|
||||
|
||||
@@ -39,6 +39,16 @@ To create/register a plugin, you have to :
|
||||
\******************************************************************************/
|
||||
// FIXME TD-er: Make useful selections for these pages to be included. (e.g. view only)
|
||||
|
||||
|
||||
// FIXME TD-er: Disable Arduino OTA for now, seems to cause crashes/bootloop on some ESP32-variants (C3/C6, maybe more)
|
||||
// No idea why, disabled on 2026/09/22
|
||||
#ifdef FEATURE_ARDUINO_OTA
|
||||
#undef FEATURE_ARDUINO_OTA
|
||||
#endif
|
||||
#define FEATURE_ARDUINO_OTA 0
|
||||
|
||||
|
||||
|
||||
#ifndef WEBSERVER_CUSTOM_BUILD_DEFINED
|
||||
#ifndef WEBSERVER_TIMINGSTATS
|
||||
#define WEBSERVER_TIMINGSTATS
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "../ESPEasyCore/ESPEasy_Log.h"
|
||||
#include "../ESPEasyCore/ESPEasy_backgroundtasks.h"
|
||||
#include "../Globals/ESPEasy_Scheduler.h"
|
||||
#include "../Globals/ESPEasy_time.h"
|
||||
#include "../Globals/EventQueue.h"
|
||||
#include "../Globals/RTC.h"
|
||||
#include "../Globals/Settings.h"
|
||||
@@ -84,6 +85,7 @@ void ESPEasy_loop()
|
||||
#endif
|
||||
firstLoop = false;
|
||||
timerAwakeFromDeepSleep = millis(); // Allow to run for "awake" number of seconds, now we have wifi.
|
||||
Scheduler.sendGratuitousARP_now();
|
||||
|
||||
// schedule_all_task_device_timers(); // Disabled for now, since we are now using queues for controllers.
|
||||
if (Settings.UseRules && isDeepSleepEnabled())
|
||||
@@ -103,6 +105,7 @@ void ESPEasy_loop()
|
||||
#if FEATURE_ESPEASY_P2P
|
||||
sendSysInfoUDP(1);
|
||||
#endif
|
||||
node_time.initTime();
|
||||
}
|
||||
|
||||
setWebserverRunning(ESPEasy::net::NWPluginCall(NWPlugin::Function::NWPLUGIN_WEBSERVER_SHOULD_RUN));
|
||||
@@ -187,4 +190,9 @@ void ESPEasy_loop()
|
||||
|
||||
// deepsleep will never return, its a special kind of reboot
|
||||
}
|
||||
|
||||
if (firstLoopConnectionsEstablished) {
|
||||
// FIXME TD-er: First NTP call may fail, so we make several here.
|
||||
node_time.initTime();
|
||||
}
|
||||
}
|
||||
@@ -317,6 +317,8 @@ void ESPEasy_setup()
|
||||
RTC.bootFailedCount++;
|
||||
RTC.bootCounter++;
|
||||
lastMixedSchedulerId_beforereboot.mixed_id = RTC.lastMixedSchedulerId;
|
||||
|
||||
node_time.restoreFromRTC();
|
||||
readUserVarFromRTC();
|
||||
log = concat(F("INIT : "), getLastBootCauseString()) +
|
||||
concat(F(" #"), RTC.bootCounter);
|
||||
@@ -359,6 +361,9 @@ void ESPEasy_setup()
|
||||
|
||||
// progMemMD5check();
|
||||
LoadSettings();
|
||||
#if FEATURE_EXT_RTC
|
||||
node_time.restoreFromRTC();
|
||||
#endif
|
||||
#if FEATURE_DEFINE_SERIAL_CONSOLE_PORT
|
||||
ESPEasy_Console.reInit();
|
||||
#endif // if FEATURE_DEFINE_SERIAL_CONSOLE_PORT
|
||||
@@ -398,8 +403,6 @@ void ESPEasy_setup()
|
||||
logMemUsageAfter(F("hardwareInit()"));
|
||||
#endif // ifndef BUILD_NO_RAM_TRACKER
|
||||
|
||||
node_time.restoreFromRTC();
|
||||
|
||||
Settings.UseRTOSMultitasking = false; // For now, disable it, we experience heap corruption.
|
||||
|
||||
if ((RTC.bootFailedCount > 10) && (RTC.bootCounter > 10)) {
|
||||
|
||||
@@ -34,18 +34,18 @@
|
||||
# endif // ifdef ESP32
|
||||
|
||||
|
||||
# ifndef DALLAS_RESET_RETRIES
|
||||
# ifndef DALLAS_RETRIES
|
||||
|
||||
// Reset may fail if a
|
||||
# define DALLAS_RESET_RETRIES 3
|
||||
# endif // ifndef DALLAS_RESET_RETRIES
|
||||
# define DALLAS_RETRIES 3
|
||||
# endif // ifndef DALLAS_RETRIES
|
||||
|
||||
# include <vector>
|
||||
|
||||
unsigned char ROM_NO[8]{ 0 };
|
||||
uint8_t LastDiscrepancy{};
|
||||
uint8_t LastFamilyDiscrepancy{};
|
||||
uint8_t LastDeviceFlag{};
|
||||
bool LastDeviceFlag{};
|
||||
|
||||
int32_t usec_release{};
|
||||
int32_t presence_start{};
|
||||
@@ -199,6 +199,28 @@ void Dallas_addr_selector_webform_load(taskIndex_t TaskIndex, int8_t gpio_pin_rx
|
||||
nrVariables = VARS_PER_TASK;
|
||||
}
|
||||
|
||||
// find all suitable devices
|
||||
std::vector<uint64_t> scan_res;
|
||||
std::vector<bool> fixed_res;
|
||||
|
||||
for (uint8_t attempt = 0; attempt < DALLAS_RETRIES && scan_res.size() == 0; ++attempt)
|
||||
{
|
||||
Dallas_reset_search();
|
||||
uint8_t tmpAddress[8]{};
|
||||
|
||||
while (Dallas_search(tmpAddress, gpio_pin_rx, gpio_pin_tx))
|
||||
{
|
||||
scan_res.push_back(Dallas_addr_to_uint64(tmpAddress));
|
||||
bool hasFixedResolution = false;
|
||||
Dallas_getResolution(tmpAddress, gpio_pin_rx, gpio_pin_tx, hasFixedResolution);
|
||||
fixed_res.push_back(hasFixedResolution);
|
||||
}
|
||||
|
||||
if (scan_res.size() == 0) {
|
||||
delay(5);
|
||||
}
|
||||
}
|
||||
|
||||
std::map<uint64_t, String> addr_task_map;
|
||||
|
||||
for (taskIndex_t task = 0; validTaskIndex(task); ++task) {
|
||||
@@ -226,20 +248,6 @@ void Dallas_addr_selector_webform_load(taskIndex_t TaskIndex, int8_t gpio_pin_rx
|
||||
}
|
||||
}
|
||||
|
||||
// find all suitable devices
|
||||
std::vector<uint64_t> scan_res;
|
||||
std::vector<bool> fixed_res;
|
||||
|
||||
Dallas_reset_search();
|
||||
uint8_t tmpAddress[8]{};
|
||||
|
||||
while (Dallas_search(tmpAddress, gpio_pin_rx, gpio_pin_tx))
|
||||
{
|
||||
scan_res.push_back(Dallas_addr_to_uint64(tmpAddress));
|
||||
bool hasFixedResolution = false;
|
||||
Dallas_getResolution(tmpAddress, gpio_pin_rx, gpio_pin_tx, hasFixedResolution);
|
||||
fixed_res.push_back(hasFixedResolution);
|
||||
}
|
||||
|
||||
for (uint8_t var_index = 0; var_index < nrVariables; ++var_index) {
|
||||
String rowLabel = F("Device Address");
|
||||
@@ -250,15 +258,21 @@ void Dallas_addr_selector_webform_load(taskIndex_t TaskIndex, int8_t gpio_pin_rx
|
||||
}
|
||||
addRowLabel(rowLabel);
|
||||
addSelector_Head(concat(F("dallas_addr"), static_cast<int>(var_index)));
|
||||
addSelector_Item(F("- None -"), -1, false); // Empty choice
|
||||
addSelector_Item(F("- None -"), 0, false); // Empty choice
|
||||
|
||||
|
||||
// get currently saved address
|
||||
uint8_t savedAddress[8];
|
||||
Dallas_plugin_get_addr(savedAddress, TaskIndex, var_index); // Need to fetch only once?
|
||||
uint64_t saved_addr64{};
|
||||
{
|
||||
uint8_t savedAddress[8];
|
||||
Dallas_plugin_get_addr(savedAddress, TaskIndex, var_index); // Need to fetch only once?
|
||||
saved_addr64 = Dallas_addr_to_uint64(savedAddress);
|
||||
}
|
||||
|
||||
for (uint8_t index = 0; index < scan_res.size(); ++index) {
|
||||
const uint64_t scan_addr = scan_res[index];
|
||||
uint8_t tmpAddress[8]{};
|
||||
Dallas_uint64_to_addr(scan_res[index], tmpAddress);
|
||||
Dallas_uint64_to_addr(scan_addr, tmpAddress);
|
||||
|
||||
String option;
|
||||
# ifndef LIMIT_BUILD_SIZE
|
||||
@@ -270,14 +284,14 @@ void Dallas_addr_selector_webform_load(taskIndex_t TaskIndex, int8_t gpio_pin_rx
|
||||
}
|
||||
# endif // ifndef LIMIT_BUILD_SIZE
|
||||
option += Dallas_format_address(tmpAddress, fixed_res[index]);
|
||||
auto it = addr_task_map.find(scan_res[index]);
|
||||
auto it = addr_task_map.find(scan_addr);
|
||||
|
||||
if (it != addr_task_map.end()) {
|
||||
option += it->second;
|
||||
}
|
||||
|
||||
const bool selected = (memcmp(tmpAddress, savedAddress, 8) == 0);
|
||||
addSelector_Item_index64(option, scan_res[index], selected);
|
||||
const bool selected = scan_addr == saved_addr64;
|
||||
addSelector_Item_index64(option, scan_addr, selected);
|
||||
}
|
||||
addSelector_Foot();
|
||||
}
|
||||
@@ -793,7 +807,7 @@ bool Dallas_setResolution(const uint8_t ROM[8], uint8_t res, int8_t gpio_pin_rx,
|
||||
\*********************************************************************************************/
|
||||
uint8_t Dallas_reset(int8_t gpio_pin_rx, int8_t gpio_pin_tx)
|
||||
{
|
||||
for (uint8_t attempt = 0; attempt < DALLAS_RESET_RETRIES; ++attempt) {
|
||||
for (uint8_t attempt = 0; attempt < DALLAS_RETRIES; ++attempt) {
|
||||
presence_start = 0;
|
||||
presence_end = 0;
|
||||
|
||||
@@ -902,14 +916,12 @@ uint8_t Dallas_reset(int8_t gpio_pin_rx, int8_t gpio_pin_tx)
|
||||
|
||||
ISR_interrupts();
|
||||
}
|
||||
delay(1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
# define FALSE 0
|
||||
# define TRUE 1
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Dallas Reset Search
|
||||
\*********************************************************************************************/
|
||||
@@ -917,7 +929,7 @@ void Dallas_reset_search()
|
||||
{
|
||||
// reset the search state
|
||||
LastDiscrepancy = 0;
|
||||
LastDeviceFlag = FALSE;
|
||||
LastDeviceFlag = false;
|
||||
LastFamilyDiscrepancy = 0;
|
||||
|
||||
for (uint8_t i = 0; i < 8; i++) {
|
||||
@@ -930,16 +942,14 @@ void Dallas_reset_search()
|
||||
\*********************************************************************************************/
|
||||
uint8_t Dallas_search(uint8_t *newAddr, int8_t gpio_pin_rx, int8_t gpio_pin_tx)
|
||||
{
|
||||
uint8_t id_bit_number;
|
||||
uint8_t last_zero, rom_byte_number, search_result;
|
||||
unsigned char rom_byte_mask, search_direction;
|
||||
unsigned char search_direction;
|
||||
|
||||
// initialize for search
|
||||
id_bit_number = 1;
|
||||
last_zero = 0;
|
||||
rom_byte_number = 0;
|
||||
rom_byte_mask = 1;
|
||||
search_result = 0;
|
||||
uint8_t id_bit_number = 1;
|
||||
uint8_t last_zero = 0;
|
||||
uint8_t rom_byte_number = 0;
|
||||
unsigned char rom_byte_mask = 1;
|
||||
bool search_result = false;
|
||||
|
||||
// if the last call was not the last one
|
||||
if (!LastDeviceFlag)
|
||||
@@ -949,9 +959,9 @@ uint8_t Dallas_search(uint8_t *newAddr, int8_t gpio_pin_rx, int8_t gpio_pin_tx)
|
||||
{
|
||||
// reset the search
|
||||
LastDiscrepancy = 0;
|
||||
LastDeviceFlag = FALSE;
|
||||
LastDeviceFlag = false;
|
||||
LastFamilyDiscrepancy = 0;
|
||||
return FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
// issue the search command
|
||||
@@ -1035,10 +1045,10 @@ uint8_t Dallas_search(uint8_t *newAddr, int8_t gpio_pin_rx, int8_t gpio_pin_tx)
|
||||
|
||||
// check for last device
|
||||
if (LastDiscrepancy == 0) {
|
||||
LastDeviceFlag = TRUE;
|
||||
LastDeviceFlag = true;
|
||||
}
|
||||
|
||||
search_result = TRUE;
|
||||
search_result = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1046,9 +1056,9 @@ uint8_t Dallas_search(uint8_t *newAddr, int8_t gpio_pin_rx, int8_t gpio_pin_tx)
|
||||
if (!search_result || !ROM_NO[0])
|
||||
{
|
||||
LastDiscrepancy = 0;
|
||||
LastDeviceFlag = FALSE;
|
||||
LastDeviceFlag = false;
|
||||
LastFamilyDiscrepancy = 0;
|
||||
search_result = FALSE;
|
||||
search_result = false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 8; i++) {
|
||||
@@ -1058,9 +1068,6 @@ uint8_t Dallas_search(uint8_t *newAddr, int8_t gpio_pin_rx, int8_t gpio_pin_tx)
|
||||
return search_result;
|
||||
}
|
||||
|
||||
# undef FALSE
|
||||
# undef TRUE
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Dallas Read byte
|
||||
\*********************************************************************************************/
|
||||
|
||||
@@ -63,7 +63,7 @@ struct Dallas_SensorData {
|
||||
extern unsigned char ROM_NO[8];
|
||||
extern uint8_t LastDiscrepancy;
|
||||
extern uint8_t LastFamilyDiscrepancy;
|
||||
extern uint8_t LastDeviceFlag;
|
||||
extern bool LastDeviceFlag;
|
||||
|
||||
|
||||
/*********************************************************************************************\
|
||||
|
||||
@@ -1480,17 +1480,14 @@ String LoadTaskSettings(taskIndex_t TaskIndex)
|
||||
START_TIMER
|
||||
|
||||
ExtraTaskSettings.clear();
|
||||
Cache.clearTaskCache(TaskIndex);
|
||||
|
||||
const deviceIndex_t DeviceIndex = getDeviceIndex_from_TaskIndex(TaskIndex);
|
||||
|
||||
if (!validDeviceIndex(DeviceIndex)) {
|
||||
// No need to load from storage, as there is no plugin assigned to this task.
|
||||
ExtraTaskSettings.TaskIndex = TaskIndex; // Needed when an empty task was requested
|
||||
|
||||
// FIXME TD-er: Do we need to keep a cache of an empty task?
|
||||
// Maybe better to do this?
|
||||
Cache.clearTaskCache(TaskIndex);
|
||||
|
||||
// Cache.updateExtraTaskSettingsCache_afterLoad_Save();
|
||||
return EMPTY_STRING;
|
||||
}
|
||||
#ifndef BUILD_NO_RAM_TRACKER
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
|
||||
|
||||
#include "../Helpers/Convert.h"
|
||||
#include "../Helpers/ESPEasyRTC.h"
|
||||
#include "../Helpers/Hardware.h"
|
||||
#include "../Helpers/Hardware_I2C.h"
|
||||
#include "../Helpers/Misc.h"
|
||||
@@ -45,6 +46,14 @@
|
||||
# include <RTClib.h>
|
||||
#endif // if FEATURE_EXT_RTC
|
||||
|
||||
#ifndef BUILD_NO_DEBUG
|
||||
#define ESPEASY_NTP_DEBUG 1
|
||||
#else
|
||||
#define ESPEASY_NTP_DEBUG 0
|
||||
#endif
|
||||
|
||||
|
||||
#define ESPEASY_NTP_TIMEOUT 1000
|
||||
|
||||
ESPEasy_time::ESPEasy_time() {
|
||||
memset(&local_tm, 0, sizeof(tm));
|
||||
@@ -258,6 +267,7 @@ uint32_t ESPEasy_time::now_() {
|
||||
_timeSource = extTimeSource;
|
||||
} else {
|
||||
if (!isExternalTimeSource(_timeSource)
|
||||
|| lastSyncTime_ms == 0
|
||||
|| (timePassedSince(lastSyncTime_ms) > static_cast<long>(1000 * syncInterval)))
|
||||
{
|
||||
externalUnixTime_offset_usec = 0;
|
||||
@@ -439,6 +449,7 @@ uint32_t ESPEasy_time::now_() {
|
||||
}
|
||||
RTC.lastSysTime = getUnixTime();
|
||||
uint32_t localSystime = time_zone.toLocal(RTC.lastSysTime);
|
||||
saveToRTC();
|
||||
breakTime(localSystime, local_tm);
|
||||
|
||||
calcSunRiseAndSet(timeSynced);
|
||||
@@ -509,7 +520,7 @@ bool ESPEasy_time::systemTimePresent() const {
|
||||
|
||||
bool ESPEasy_time::getNtpTime(double& unixTime_d)
|
||||
{
|
||||
if (!Settings.UseNTP() || !ESPEasy::net::NetworkConnected(true)) {
|
||||
if (!Settings.UseNTP() || !ESPEasy::net::NetworkConnected()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -549,7 +560,7 @@ bool ESPEasy_time::getNtpTime(double& unixTime_d)
|
||||
|
||||
if (!hostReachable(timeServerIP)) {
|
||||
log += F(" unreachable");
|
||||
addLogMove(LOG_LEVEL_INFO, log);
|
||||
addLogMove(LOG_LEVEL_ERROR, log);
|
||||
STOP_TIMER(NTP_FAIL);
|
||||
return false;
|
||||
}
|
||||
@@ -557,6 +568,10 @@ bool ESPEasy_time::getNtpTime(double& unixTime_d)
|
||||
WiFiUDP udp;
|
||||
|
||||
if (!beginWiFiUDP_randomPort(udp)) {
|
||||
#if ESPEASY_NTP_DEBUG
|
||||
log += F(" failed beginWiFiUDP_randomPort");
|
||||
addLogMove(LOG_LEVEL_ERROR, log);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -567,8 +582,8 @@ bool ESPEasy_time::getNtpTime(double& unixTime_d)
|
||||
addLog(LOG_LEVEL_DEBUG_MORE, log);
|
||||
#endif // ifndef BUILD_NO_DEBUG
|
||||
|
||||
while (udp.parsePacket() > 0) { // discard any previously received packets
|
||||
}
|
||||
// while (udp.parsePacket() > 0) { // discard any previously received packets
|
||||
// }
|
||||
|
||||
FeedSW_watchdog();
|
||||
|
||||
@@ -576,6 +591,10 @@ bool ESPEasy_time::getNtpTime(double& unixTime_d)
|
||||
FeedSW_watchdog();
|
||||
udp.stop();
|
||||
STOP_TIMER(NTP_FAIL);
|
||||
#if ESPEASY_NTP_DEBUG
|
||||
log += F(" failed beginPacket");
|
||||
addLogMove(LOG_LEVEL_ERROR, log);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
constexpr int NTP_packet_size = sizeof(NTP_packet);
|
||||
@@ -590,7 +609,7 @@ bool ESPEasy_time::getNtpTime(double& unixTime_d)
|
||||
addLog(LOG_LEVEL_DEBUG, concat(F("NTP : before\n"), ntp_packet.toDebugString()));
|
||||
#endif // ifndef BUILD_NO_DEBUG
|
||||
|
||||
while (!timeOutReached(beginWait + 1000)) {
|
||||
while (!timeOutReached(beginWait + ESPEASY_NTP_TIMEOUT)) {
|
||||
const int size = udp.parsePacket();
|
||||
const int remotePort = udp.remotePort();
|
||||
|
||||
@@ -601,6 +620,10 @@ bool ESPEasy_time::getNtpTime(double& unixTime_d)
|
||||
#endif // ifndef BUILD_NO_DEBUG
|
||||
udp.stop();
|
||||
STOP_TIMER(NTP_FAIL);
|
||||
#if ESPEASY_NTP_DEBUG
|
||||
log += concat(F(" Reply from wrong port: "), remotePort);
|
||||
addLogMove(LOG_LEVEL_ERROR, log);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
udp.read(ntp_packet.data, NTP_packet_size); // read packet into the buffer
|
||||
@@ -626,6 +649,10 @@ bool ESPEasy_time::getNtpTime(double& unixTime_d)
|
||||
nextSyncTime = getUptime_in_sec() + 120;
|
||||
}
|
||||
STOP_TIMER(NTP_FAIL);
|
||||
#if ESPEASY_NTP_DEBUG
|
||||
log += F(" isUnsynchronized");
|
||||
addLogMove(LOG_LEVEL_ERROR, log);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -664,6 +691,10 @@ bool ESPEasy_time::getNtpTime(double& unixTime_d)
|
||||
// or no valid timestamps from the NTP server.
|
||||
nextSyncTime = getUptime_in_sec() + 60;
|
||||
STOP_TIMER(NTP_FAIL);
|
||||
#if ESPEASY_NTP_DEBUG
|
||||
log += F(" failed compute_usec");
|
||||
addLogMove(LOG_LEVEL_ERROR, log);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -707,10 +738,15 @@ bool ESPEasy_time::getNtpTime(double& unixTime_d)
|
||||
// Timeout.
|
||||
if (!useNTPpool) {
|
||||
// Retry again in a minute.
|
||||
nextSyncTime = getUptime_in_sec() + 60;
|
||||
nextSyncTime = getUptime_in_sec() + 10;
|
||||
}
|
||||
|
||||
#ifndef BUILD_NO_DEBUG
|
||||
#if ESPEASY_NTP_DEBUG
|
||||
log += strformat(F(" No reply, duration: %d ms"), timePassedSince(beginWait));
|
||||
addLogMove(LOG_LEVEL_ERROR, log);
|
||||
#endif
|
||||
|
||||
addLog(LOG_LEVEL_DEBUG_MORE, F("NTP : No reply"));
|
||||
#endif // ifndef BUILD_NO_DEBUG
|
||||
udp.stop();
|
||||
|
||||
@@ -1211,7 +1211,7 @@ bool setDNS(int index, const IPAddress& dns) {
|
||||
bool resolveHostByName(const char *aHostname, IPAddress& aResult, uint32_t timeout_ms) {
|
||||
START_TIMER;
|
||||
|
||||
if (!ESPEasy::net::NetworkConnected(true)) {
|
||||
if (!ESPEasy::net::NetworkConnected()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1220,16 +1220,32 @@ bool resolveHostByName(const char *aHostname, IPAddress& aResult, uint32_t timeo
|
||||
// FIXME TD-er: Must try to restore DNS server entries.
|
||||
scrubDNS();
|
||||
|
||||
#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)
|
||||
bool resolvedIP = WiFi.hostByName(aHostname, aResult, timeout_ms) == 1;
|
||||
#endif // if defined(ARDUINO_ESP8266_RELEASE_2_3_0) || defined(ESP32)
|
||||
delay(0);
|
||||
FeedSW_watchdog();
|
||||
bool resolvedIP{};
|
||||
String host(aHostname);
|
||||
host.trim();
|
||||
|
||||
if (!resolvedIP) {
|
||||
Scheduler.sendGratuitousARP_now();
|
||||
uint32_t start = millis();
|
||||
|
||||
for (int attempt = 0;
|
||||
attempt < 2 && !resolvedIP && timePassedSince(start) < timeout_ms;
|
||||
++attempt) {
|
||||
|
||||
#if defined(ARDUINO_ESP8266_RELEASE_2_3_0)
|
||||
resolvedIP = WiFi.hostByName(host.c_str(), aResult) == 1;
|
||||
#elif defined(ESP32)
|
||||
resolvedIP = Network.hostByName(host.c_str(), aResult) == 1;
|
||||
#else // if defined(ARDUINO_ESP8266_RELEASE_2_3_0) || defined(ESP32)
|
||||
resolvedIP = WiFi.hostByName(host.c_str(), aResult, timeout_ms) == 1;
|
||||
#endif // if defined(ARDUINO_ESP8266_RELEASE_2_3_0) || defined(ESP32)
|
||||
delay(0);
|
||||
FeedSW_watchdog();
|
||||
|
||||
if (!resolvedIP && attempt == 0) {
|
||||
#ifdef ESP32
|
||||
dns_clear_cache();
|
||||
#endif
|
||||
Scheduler.sendGratuitousARP_now();
|
||||
}
|
||||
}
|
||||
STOP_TIMER(HOST_BY_NAME_STATS);
|
||||
return resolvedIP;
|
||||
|
||||
@@ -42,39 +42,41 @@
|
||||
|
||||
|
||||
#ifdef USES_C015
|
||||
#include "../../ESPEasy_fdwdecl.h"
|
||||
# include "../../ESPEasy_fdwdecl.h"
|
||||
#endif
|
||||
|
||||
#if FEATURE_MDNS
|
||||
#include "../Helpers/MDNS_Helper.h"
|
||||
# include "../Helpers/MDNS_Helper.h"
|
||||
#endif
|
||||
|
||||
#define PLUGIN_ID_MQTT_IMPORT 37
|
||||
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Tasks that run 50 times per second
|
||||
* Tasks that run 50 times per second
|
||||
\*********************************************************************************************/
|
||||
|
||||
void run50TimesPerSecond() {
|
||||
String dummy;
|
||||
{
|
||||
// Do network calls first, so any needed checks or updates are done
|
||||
// Do network calls first, so any needed checks or updates are done
|
||||
// before any controller may need to use the network
|
||||
#ifdef ESP32
|
||||
static const NetworkInterface *lastDefaultInterface = nullptr;
|
||||
NetworkInterface * currentDefaultInterface = Network.getDefaultInterface();
|
||||
if (nonDefaultNetworkInterface_gotIP ||
|
||||
networkConnectionFailed ||
|
||||
lastDefaultInterface != currentDefaultInterface) {
|
||||
NetworkInterface *currentDefaultInterface = Network.getDefaultInterface();
|
||||
|
||||
if (nonDefaultNetworkInterface_gotIP ||
|
||||
networkConnectionFailed ||
|
||||
(lastDefaultInterface != currentDefaultInterface)) {
|
||||
nonDefaultNetworkInterface_gotIP = false;
|
||||
|
||||
// TODO TD-er: Must do something else here on failed connect?
|
||||
networkConnectionFailed = false;
|
||||
ESPEasy::net::NWPluginCall(NWPlugin::Function::NWPLUGIN_PRIORITY_ROUTE_CHANGED, 0, dummy);
|
||||
|
||||
if (lastDefaultInterface != currentDefaultInterface) {
|
||||
ESPEasy::net::NWPluginCall(NWPlugin::Function::NWPLUGIN_PRIORITY_ROUTE_CHANGED, 0, dummy);
|
||||
}
|
||||
lastDefaultInterface = currentDefaultInterface;
|
||||
}
|
||||
#endif
|
||||
#endif // ifdef ESP32
|
||||
|
||||
START_TIMER;
|
||||
ESPEasy::net::NWPluginCall(NWPlugin::Function::NWPLUGIN_FIFTY_PER_SECOND, 0, dummy);
|
||||
@@ -98,11 +100,12 @@ void run50TimesPerSecond() {
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Tasks that run 10 times per second
|
||||
* Tasks that run 10 times per second
|
||||
\*********************************************************************************************/
|
||||
void run10TimesPerSecond() {
|
||||
String dummy;
|
||||
//@giig19767g: WARNING: Monitor10xSec must run before PLUGIN_TEN_PER_SECOND
|
||||
|
||||
// @giig19767g: WARNING: Monitor10xSec must run before PLUGIN_TEN_PER_SECOND
|
||||
{
|
||||
START_TIMER;
|
||||
GPIO_Monitor10xSec();
|
||||
@@ -120,7 +123,8 @@ void run10TimesPerSecond() {
|
||||
}
|
||||
{
|
||||
START_TIMER;
|
||||
// PluginCall(PLUGIN_UNCONDITIONAL_POLL, 0, dummyString);
|
||||
|
||||
// PluginCall(PLUGIN_UNCONDITIONAL_POLL, 0, dummyString);
|
||||
PluginCall(PLUGIN_MONITOR, 0, dummy);
|
||||
STOP_TIMER(PLUGIN_CALL_10PSU);
|
||||
}
|
||||
@@ -129,14 +133,16 @@ void run10TimesPerSecond() {
|
||||
CPluginCall(CPlugin::Function::CPLUGIN_TEN_PER_SECOND, 0, dummy);
|
||||
STOP_TIMER(CPLUGIN_CALL_10PS);
|
||||
}
|
||||
|
||||
|
||||
#ifdef USES_C015
|
||||
|
||||
if (ESPEasy::net::NetworkConnected()) {
|
||||
Blynk_Run_c015();
|
||||
}
|
||||
#endif
|
||||
if (!UseRTOSMultitasking &&
|
||||
(ESPEasy::net::NetworkConnected() || ESPEasy::net::wifi::wifiAPmodeActivelyUsed())) {
|
||||
#endif // ifdef USES_C015
|
||||
|
||||
if (!UseRTOSMultitasking &&
|
||||
(ESPEasy::net::NetworkConnected() || ESPEasy::net::wifi::wifiAPmodeActivelyUsed())) {
|
||||
// FIXME TD-er: What about client connected via AP?
|
||||
START_TIMER
|
||||
web_server.handleClient();
|
||||
@@ -144,20 +150,20 @@ void run10TimesPerSecond() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Tasks each second
|
||||
* Tasks each second
|
||||
\*********************************************************************************************/
|
||||
void runOncePerSecond()
|
||||
{
|
||||
START_TIMER;
|
||||
updateLogLevelCache();
|
||||
dailyResetCounter++;
|
||||
|
||||
if (dailyResetCounter > 86400) // 1 day elapsed... //86400
|
||||
{
|
||||
RTC.flashDayCounter=0;
|
||||
RTC.flashDayCounter = 0;
|
||||
saveToRTC();
|
||||
dailyResetCounter=0;
|
||||
dailyResetCounter = 0;
|
||||
#ifndef LIMIT_BUILD_SIZE
|
||||
addLog(LOG_LEVEL_INFO, F("SYS : Reset 24h counters"));
|
||||
#endif
|
||||
@@ -165,37 +171,42 @@ void runOncePerSecond()
|
||||
|
||||
if (Settings.ConnectionFailuresThreshold) {
|
||||
auto data = ESPEasy::net::getDefaultRoute_NWPluginData_static_runtime();
|
||||
if (data && data->getConnectionFailures() > Settings.ConnectionFailuresThreshold)
|
||||
|
||||
if (data && (data->getConnectionFailures() > Settings.ConnectionFailuresThreshold)) {
|
||||
delayedReboot(60, IntendedRebootReason_e::DelayedReboot);
|
||||
}
|
||||
}
|
||||
|
||||
if (cmd_within_mainloop != 0)
|
||||
{
|
||||
switch (cmd_within_mainloop)
|
||||
{
|
||||
case CMD_WIFI_DISCONNECT:
|
||||
{
|
||||
ESPEasy::net::wifi::WifiDisconnect();
|
||||
break;
|
||||
}
|
||||
{
|
||||
ESPEasy::net::wifi::WifiDisconnect();
|
||||
break;
|
||||
}
|
||||
case CMD_REBOOT:
|
||||
{
|
||||
reboot(IntendedRebootReason_e::CommandReboot);
|
||||
break;
|
||||
}
|
||||
{
|
||||
reboot(IntendedRebootReason_e::CommandReboot);
|
||||
break;
|
||||
}
|
||||
}
|
||||
cmd_within_mainloop = 0;
|
||||
}
|
||||
|
||||
// clock events
|
||||
if (node_time.reportNewMinute()) {
|
||||
String dummy;
|
||||
PluginCall(PLUGIN_CLOCK_IN, 0, dummy);
|
||||
|
||||
if (Settings.UseRules)
|
||||
{
|
||||
// FIXME TD-er: What to do when the system time is not (yet) present?
|
||||
if (node_time.systemTimePresent()) {
|
||||
// TD-er: Do not add to the eventQueue, but execute right now.
|
||||
const String event = strformat(
|
||||
F("Clock#Time=%s,%s"),
|
||||
F("Clock#Time=%s,%s"),
|
||||
node_time.weekday_str().c_str(),
|
||||
node_time.getTimeString(':', false).c_str());
|
||||
rulesProcessing(event);
|
||||
@@ -203,12 +214,14 @@ void runOncePerSecond()
|
||||
}
|
||||
}
|
||||
|
||||
// uint32_t start = micros();
|
||||
// uint32_t start = micros();
|
||||
String dummy;
|
||||
PluginCall(PLUGIN_ONCE_A_SECOND, 0, dummy);
|
||||
// uint32_t elapsed = micros() - start;
|
||||
|
||||
// uint32_t elapsed = micros() - start;
|
||||
|
||||
#if FEATURE_NETWORK_STATS
|
||||
|
||||
for (ESPEasy::net::networkIndex_t x = 0; x < NETWORK_MAX; x++) {
|
||||
if (Settings.getNetworkEnabled(x)) {
|
||||
EventStruct tempEvent;
|
||||
@@ -216,26 +229,28 @@ void runOncePerSecond()
|
||||
ESPEasy::net::NWPluginCall(NWPlugin::Function::NWPLUGIN_RECORD_STATS, &tempEvent);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif // if FEATURE_NETWORK_STATS
|
||||
|
||||
// I2C Watchdog feed
|
||||
#if FEATURE_I2C
|
||||
|
||||
if (Settings.WDI2CAddress != 0)
|
||||
{
|
||||
#if FEATURE_I2C_MULTIPLE
|
||||
# if FEATURE_I2C_MULTIPLE
|
||||
I2CSelectHighClockSpeed(Settings.getI2CInterfaceWDT()); // Select bus
|
||||
#endif // if FEATURE_I2C_MULTIPLE
|
||||
# endif // if FEATURE_I2C_MULTIPLE
|
||||
I2C_write8(Settings.WDI2CAddress, 0xA5);
|
||||
}
|
||||
#endif
|
||||
#endif // if FEATURE_I2C
|
||||
|
||||
#if FEATURE_MDNS
|
||||
#ifdef ESP8266
|
||||
# ifdef ESP8266
|
||||
|
||||
// Allow MDNS processing
|
||||
if (ESPEasy::net::NetworkConnected()) {
|
||||
MDNS.announce();
|
||||
}
|
||||
#endif
|
||||
# endif // ifdef ESP8266
|
||||
#endif // if FEATURE_MDNS
|
||||
|
||||
#if FEATURE_INTERNAL_TEMPERATURE && defined(ESP32_CLASSIC)
|
||||
@@ -247,21 +262,22 @@ void runOncePerSecond()
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Tasks each 30 seconds
|
||||
* Tasks each 30 seconds
|
||||
\*********************************************************************************************/
|
||||
void runEach30Seconds()
|
||||
{
|
||||
#ifndef BUILD_NO_RAM_TRACKER
|
||||
checkRAMtoLog();
|
||||
#endif
|
||||
wdcounter++;
|
||||
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
|
||||
|
||||
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
|
||||
auto data = ESPEasy::net::getDefaultRoute_NWPluginData_static_runtime();
|
||||
|
||||
if (!data) {
|
||||
addLogMove(LOG_LEVEL_INFO, strformat(
|
||||
F("WD : Uptime %d FreeMem %u"),
|
||||
getUptimeMinutes(),
|
||||
FreeMem()));
|
||||
F("WD : Uptime %d FreeMem %u"),
|
||||
getUptimeMinutes(),
|
||||
FreeMem()));
|
||||
} else {
|
||||
String log = strformat(
|
||||
F("WD : Uptime %d ConnectFailures %u FreeMem %u"),
|
||||
@@ -270,14 +286,17 @@ void runEach30Seconds()
|
||||
FreeMem());
|
||||
bool logWiFiStatus = true;
|
||||
#if FEATURE_ETHERNET
|
||||
if(active_network_medium == ESPEasy::net::NetworkMedium_t::Ethernet) {
|
||||
|
||||
if (active_network_medium == ESPEasy::net::NetworkMedium_t::Ethernet) {
|
||||
logWiFiStatus = false;
|
||||
log += F( " EthSpeedState ");
|
||||
log += getValue(LabelType::ETH_SPEED_STATE);
|
||||
// log += F(" ETH status: ");
|
||||
// log += EthEventData.ESPEasyEthStatusToString();
|
||||
log += F(" EthSpeedState ");
|
||||
log += getValue(LabelType::ETH_SPEED_STATE);
|
||||
|
||||
// log += F(" ETH status: ");
|
||||
// log += EthEventData.ESPEasyEthStatusToString();
|
||||
}
|
||||
#endif // if FEATURE_ETHERNET
|
||||
|
||||
if (logWiFiStatus) {
|
||||
log += strformat(
|
||||
F(" WiFiStatus: %s ESPeasy internal wifi status: %s (%s)"),
|
||||
@@ -285,35 +304,41 @@ void runEach30Seconds()
|
||||
FsP(ESPEasy::net::wifi::toString(ESPEasyWiFi.getState())),
|
||||
data->statusToString().c_str());
|
||||
}
|
||||
// log += F(" ListenInterval ");
|
||||
// log += WiFi.getListenInterval();
|
||||
|
||||
// log += F(" ListenInterval ");
|
||||
// log += WiFi.getListenInterval();
|
||||
addLogMove(LOG_LEVEL_INFO, log);
|
||||
#if FEATURE_DEFINE_SERIAL_CONSOLE_PORT
|
||||
// addLogMove(LOG_LEVEL_INFO, ESPEASY_SERIAL_CONSOLE_PORT.getLogString());
|
||||
#endif
|
||||
|
||||
// addLogMove(LOG_LEVEL_INFO, ESPEASY_SERIAL_CONSOLE_PORT.getLogString());
|
||||
#endif // if FEATURE_DEFINE_SERIAL_CONSOLE_PORT
|
||||
}
|
||||
}
|
||||
ESPEasy::net::wifi::WiFi_AP_Candidates.purge_expired();
|
||||
#if FEATURE_ESPEASY_P2P
|
||||
sendSysInfoUDP(1);
|
||||
refreshNodeList();
|
||||
#endif
|
||||
#endif // if FEATURE_ESPEASY_P2P
|
||||
|
||||
// sending $stats to homie controller
|
||||
CPluginCall(CPlugin::Function::CPLUGIN_INTERVAL, 0);
|
||||
|
||||
#if defined(ESP8266)
|
||||
#if FEATURE_SSDP
|
||||
if (Settings.UseSSDP)
|
||||
SSDP_update();
|
||||
# if FEATURE_SSDP
|
||||
|
||||
#endif // if FEATURE_SSDP
|
||||
#endif
|
||||
if (Settings.UseSSDP) {
|
||||
SSDP_update();
|
||||
}
|
||||
|
||||
# endif // if FEATURE_SSDP
|
||||
#endif // if defined(ESP8266)
|
||||
#if FEATURE_ADC_VCC
|
||||
// if (!WiFiEventData.wifiConnectInProgress) {
|
||||
vcc = ESP.getVcc() / 1000.0f;
|
||||
// }
|
||||
#endif
|
||||
|
||||
// if (!WiFiEventData.wifiConnectInProgress) {
|
||||
vcc = ESP.getVcc() / 1000.0f;
|
||||
|
||||
// }
|
||||
#endif // if FEATURE_ADC_VCC
|
||||
|
||||
#if FEATURE_REPORTING
|
||||
ReportStatus();
|
||||
@@ -323,7 +348,6 @@ void runEach30Seconds()
|
||||
|
||||
#if FEATURE_MQTT
|
||||
|
||||
|
||||
void scheduleNextMQTTdelayQueue() {
|
||||
if (MQTTDelayHandler != nullptr) {
|
||||
Scheduler.scheduleNextDelayQueue(SchedulerIntervalTimer_e::TIMER_MQTT_DELAY_QUEUE, MQTTDelayHandler->getNextScheduleTime());
|
||||
@@ -334,6 +358,7 @@ void schedule_all_MQTTimport_tasks() {
|
||||
constexpr pluginID_t PLUGIN_MQTT_IMPORT(PLUGIN_ID_MQTT_IMPORT);
|
||||
|
||||
deviceIndex_t DeviceIndex = getDeviceIndex(PLUGIN_MQTT_IMPORT); // Check if P037_MQTTimport is present in the build
|
||||
|
||||
if (validDeviceIndex(DeviceIndex)) {
|
||||
for (taskIndex_t task = 0; task < TASKS_MAX; task++) {
|
||||
if ((Settings.getPluginID_for_task(task) == PLUGIN_MQTT_IMPORT) &&
|
||||
@@ -343,7 +368,7 @@ void schedule_all_MQTTimport_tasks() {
|
||||
event.Par1 = MQTTclient_connected ? 1 : 0;
|
||||
Scheduler.schedule_plugin_task_event_timer(
|
||||
task,
|
||||
PLUGIN_MQTT_CONNECTION_STATE,
|
||||
PLUGIN_MQTT_CONNECTION_STATE,
|
||||
std::move(event));
|
||||
}
|
||||
}
|
||||
@@ -355,6 +380,7 @@ void processMQTTdelayQueue() {
|
||||
return;
|
||||
}
|
||||
runPeriodicalMQTT(); // Update MQTT connected state.
|
||||
|
||||
if (!MQTTclient_connected) {
|
||||
scheduleNextMQTTdelayQueue();
|
||||
return;
|
||||
@@ -372,8 +398,8 @@ void processMQTTdelayQueue() {
|
||||
String dummy;
|
||||
|
||||
// FIXME TD-er: Do we need anything from the element in the event?
|
||||
// TempEvent.String1 = element->_topic;
|
||||
// TempEvent.String2 = element->_payload;
|
||||
// TempEvent.String1 = element->_topic;
|
||||
// TempEvent.String2 = element->_payload;
|
||||
if (PluginCall(PLUGIN_PROCESS_CONTROLLER_DATA, &TempEvent, dummy)) {
|
||||
handled = true;
|
||||
MQTTDelayHandler->markProcessed(true);
|
||||
@@ -384,13 +410,14 @@ void processMQTTdelayQueue() {
|
||||
if (!handled) {
|
||||
if (MQTTclient.publish(element->_topic.c_str(), element->_payload.c_str(), element->_retained)) {
|
||||
auto data = ESPEasy::net::getDefaultRoute_NWPluginData_static_runtime();
|
||||
|
||||
if (data) {
|
||||
data->markPublishSuccess();
|
||||
}
|
||||
MQTTDelayHandler->markProcessed(true);
|
||||
} else {
|
||||
MQTTDelayHandler->markProcessed(false);
|
||||
#ifndef BUILD_NO_DEBUG
|
||||
# ifndef BUILD_NO_DEBUG
|
||||
|
||||
if (loglevelActiveFor(LOG_LEVEL_DEBUG)) {
|
||||
String log = F("MQTT : process MQTT queue not published, ");
|
||||
@@ -398,40 +425,46 @@ void processMQTTdelayQueue() {
|
||||
log += F(" items left in queue");
|
||||
addLogMove(LOG_LEVEL_DEBUG, log);
|
||||
}
|
||||
#endif // ifndef BUILD_NO_DEBUG
|
||||
# endif // ifndef BUILD_NO_DEBUG
|
||||
}
|
||||
}
|
||||
Scheduler.setIntervalTimerOverride(SchedulerIntervalTimer_e::TIMER_MQTT, 10); // Make sure the MQTT is being processed as soon as possible.
|
||||
Scheduler.setIntervalTimerOverride(SchedulerIntervalTimer_e::TIMER_MQTT, 10); // Make sure the MQTT is being processed as soon as
|
||||
// possible.
|
||||
scheduleNextMQTTdelayQueue();
|
||||
STOP_TIMER(MQTT_DELAY_QUEUE);
|
||||
}
|
||||
|
||||
void updateMQTTclient_connected() {
|
||||
const bool actual_MQTTclient_connected = ESPEasy::net::NetworkConnected(true) && MQTTclient.connected();
|
||||
|
||||
if (MQTTclient_connected != actual_MQTTclient_connected) {
|
||||
MQTTclient_connected = actual_MQTTclient_connected;
|
||||
|
||||
if (!actual_MQTTclient_connected) {
|
||||
// Make sure PubSubClient isn't trying to do a graceful disconnect
|
||||
// FIXME TD-er: This seems to cause a crash on ESP32-xx, though no idea how to fix.
|
||||
// See also: https://github.com/espressif/arduino-esp32/issues/12517
|
||||
mqtt.stop();
|
||||
mqtt.stop();
|
||||
}
|
||||
MQTTclient_connected_stats.set(actual_MQTTclient_connected);
|
||||
|
||||
if (!MQTTclient_connected) {
|
||||
if (loglevelActiveFor(LOG_LEVEL_ERROR)) {
|
||||
String connectionError = F("MQTT : Connection lost, state: ");
|
||||
connectionError += getMQTT_state();
|
||||
#ifndef BUILD_NO_DEBUG
|
||||
# ifndef BUILD_NO_DEBUG
|
||||
auto duration_ms = MQTTclient_connected_stats.getLastOnDuration_ms();
|
||||
|
||||
if (duration_ms > 0) {
|
||||
connectionError += concat(F(" Connected duration: "), format_msec_duration_HMS(duration_ms));
|
||||
connectionError += concat(F(" (successful) Reconnect Count: "), MQTTclient_connected_stats.getCycleCount());
|
||||
}
|
||||
#endif
|
||||
# endif // ifndef BUILD_NO_DEBUG
|
||||
addLogMove(LOG_LEVEL_ERROR, connectionError);
|
||||
}
|
||||
MQTTclient_must_send_LWT_connected = false;
|
||||
}
|
||||
|
||||
if (Settings.UseRules) {
|
||||
if (MQTTclient_connected) {
|
||||
eventQueue.add(F("MQTT#Connected"));
|
||||
@@ -439,9 +472,11 @@ void updateMQTTclient_connected() {
|
||||
eventQueue.add(F("MQTT#Disconnected"));
|
||||
}
|
||||
}
|
||||
|
||||
// Now schedule all tasks using the MQTT Import plugin.
|
||||
schedule_all_MQTTimport_tasks();
|
||||
}
|
||||
|
||||
if (!MQTTclient_connected) {
|
||||
// As suggested here: https://github.com/letscontrolit/ESPEasy/issues/1356
|
||||
if (timermqtt_interval < 30000) {
|
||||
@@ -452,36 +487,41 @@ void updateMQTTclient_connected() {
|
||||
}
|
||||
Scheduler.setIntervalTimer(SchedulerIntervalTimer_e::TIMER_MQTT);
|
||||
scheduleNextMQTTdelayQueue();
|
||||
#if FEATURE_MQTT_CONNECT_BACKGROUND
|
||||
# if FEATURE_MQTT_CONNECT_BACKGROUND
|
||||
MQTTConnectInBackground(CONTROLLER_MAX, true); // Report state
|
||||
#endif // if FEATURE_MQTT_CONNECT_BACKGROUND
|
||||
# endif // if FEATURE_MQTT_CONNECT_BACKGROUND
|
||||
}
|
||||
|
||||
void runPeriodicalMQTT() {
|
||||
START_TIMER
|
||||
|
||||
// MQTT_KEEPALIVE = 15 seconds.
|
||||
if (!ESPEasy::net::NetworkConnected()) {
|
||||
updateMQTTclient_connected();
|
||||
return;
|
||||
}
|
||||
//dont do this in backgroundtasks(), otherwise causes crashes. (https://github.com/letscontrolit/ESPEasy/issues/683)
|
||||
|
||||
// dont do this in backgroundtasks(), otherwise causes crashes. (https://github.com/letscontrolit/ESPEasy/issues/683)
|
||||
controllerIndex_t enabledMqttController = firstEnabledMQTT_ControllerIndex();
|
||||
|
||||
if (validControllerIndex(enabledMqttController)) {
|
||||
if (!MQTTclient.loop()) {
|
||||
updateMQTTclient_connected();
|
||||
|
||||
if (MQTTCheck(enabledMqttController)) {
|
||||
updateMQTTclient_connected();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (MQTTclient.connected()) {
|
||||
#if FEATURE_MQTT_CONNECT_BACKGROUND
|
||||
# if FEATURE_MQTT_CONNECT_BACKGROUND
|
||||
|
||||
if (MQTT_task_data.taskHandle) {
|
||||
vTaskDelete(MQTT_task_data.taskHandle);
|
||||
MQTT_task_data.taskHandle = NULL;
|
||||
}
|
||||
MQTT_task_data.status = MQTT_connect_status_e::Disconnected;
|
||||
#endif // if FEATURE_MQTT_CONNECT_BACKGROUND
|
||||
# endif // if FEATURE_MQTT_CONNECT_BACKGROUND
|
||||
MQTTclient.disconnect();
|
||||
updateMQTTclient_connected();
|
||||
}
|
||||
@@ -489,40 +529,40 @@ void runPeriodicalMQTT() {
|
||||
STOP_TIMER(PERIODICAL_MQTT);
|
||||
}
|
||||
|
||||
|
||||
#endif //if FEATURE_MQTT
|
||||
|
||||
|
||||
#endif // if FEATURE_MQTT
|
||||
|
||||
void logTimerStatistics() {
|
||||
// This function is called every 30 seconds.
|
||||
wdcounter++;
|
||||
loopCounterLast = loopCounter;
|
||||
loopCounter = 0;
|
||||
if (loopCounterLast > loopCounterMax)
|
||||
loopCounter = 0;
|
||||
|
||||
if (loopCounterLast > loopCounterMax) {
|
||||
loopCounterMax = loopCounterLast;
|
||||
}
|
||||
|
||||
Scheduler.updateIdleTimeStats();
|
||||
|
||||
#ifndef BUILD_NO_DEBUG
|
||||
const uint8_t loglevel = LOG_LEVEL_DEBUG;
|
||||
|
||||
if (loglevelActiveFor(loglevel)) {
|
||||
addLogMove(loglevel, strformat(
|
||||
F("LoopStats: shortest: %u longest: %u avg: %.2f LC_Max: %u LC_Last: %u"),
|
||||
shortestLoop,
|
||||
longestLoop,
|
||||
loop_usec_duration_total / loopCounter_full,
|
||||
loopCounterMax,
|
||||
loopCounterLast));
|
||||
F("LoopStats: shortest: %u longest: %u avg: %.2f LC_Max: %u LC_Last: %u"),
|
||||
shortestLoop,
|
||||
longestLoop,
|
||||
loop_usec_duration_total / loopCounter_full,
|
||||
loopCounterMax,
|
||||
loopCounterLast));
|
||||
addLogMove(loglevel, concat(
|
||||
F("Scheduler stats: (called/tasks/max_length/idle%) "),
|
||||
Scheduler.getQueueStats()));
|
||||
F("Scheduler stats: (called/tasks/max_length/idle%) "),
|
||||
Scheduler.getQueueStats()));
|
||||
}
|
||||
#endif
|
||||
#endif // ifndef BUILD_NO_DEBUG
|
||||
loop_usec_duration_total = 0;
|
||||
loopCounter_full = 1;
|
||||
loopCounter_full = 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/********************************************************************************************\
|
||||
Clean up all before going to sleep or reboot.
|
||||
\*********************************************************************************************/
|
||||
@@ -530,30 +570,34 @@ void flushAndDisconnectAllClients() {
|
||||
if (anyControllerEnabled()) {
|
||||
#if FEATURE_MQTT
|
||||
bool mqttControllerEnabled = validControllerIndex(firstEnabledMQTT_ControllerIndex());
|
||||
#endif //if FEATURE_MQTT
|
||||
#endif // if FEATURE_MQTT
|
||||
uint32_t timer = millis() + 1000;
|
||||
|
||||
while (!timeOutReached(timer)) {
|
||||
// call to all controllers (delay queue) to flush all data.
|
||||
CPluginCall(CPlugin::Function::CPLUGIN_FLUSH, 0);
|
||||
#if FEATURE_MQTT
|
||||
#if FEATURE_MQTT
|
||||
|
||||
if (mqttControllerEnabled && MQTTclient.connected()) {
|
||||
MQTTclient.loop();
|
||||
}
|
||||
#endif //if FEATURE_MQTT
|
||||
#endif // if FEATURE_MQTT
|
||||
}
|
||||
#if FEATURE_MQTT
|
||||
|
||||
if (mqttControllerEnabled && MQTTclient.connected()) {
|
||||
#if FEATURE_MQTT_CONNECT_BACKGROUND
|
||||
# if FEATURE_MQTT_CONNECT_BACKGROUND
|
||||
|
||||
if (MQTT_task_data.taskHandle) {
|
||||
vTaskDelete(MQTT_task_data.taskHandle);
|
||||
MQTT_task_data.taskHandle = NULL;
|
||||
}
|
||||
MQTT_task_data.status = MQTT_connect_status_e::Disconnected;
|
||||
#endif // if FEATURE_MQTT_CONNECT_BACKGROUND
|
||||
# endif // if FEATURE_MQTT_CONNECT_BACKGROUND
|
||||
MQTTclient.disconnect();
|
||||
updateMQTTclient_connected();
|
||||
}
|
||||
#endif //if FEATURE_MQTT
|
||||
#endif // if FEATURE_MQTT
|
||||
saveToRTC();
|
||||
delay(100); // Flush anything in the network buffers.
|
||||
}
|
||||
@@ -561,14 +605,13 @@ void flushAndDisconnectAllClients() {
|
||||
process_serialWriteBuffer();
|
||||
}
|
||||
|
||||
|
||||
void prepareShutdown(IntendedRebootReason_e reason)
|
||||
{
|
||||
#if FEATURE_MDNS
|
||||
end_mDNS();
|
||||
#endif
|
||||
|
||||
// WiFiEventData.intent_to_reboot = true;
|
||||
// WiFiEventData.intent_to_reboot = true;
|
||||
#if FEATURE_MQTT
|
||||
runPeriodicalMQTT(); // Flush outstanding MQTT messages
|
||||
#endif // if FEATURE_MQTT
|
||||
@@ -577,7 +620,8 @@ void prepareShutdown(IntendedRebootReason_e reason)
|
||||
saveUserVarToRTC();
|
||||
CPluginCall(CPlugin::Function::CPLUGIN_EXIT_ALL, 0);
|
||||
ESPEasy::net::NWPluginCall(NWPlugin::Function::NWPLUGIN_EXIT_ALL, 0);
|
||||
// ESPEasy::net::wifi::setWifiMode(WIFI_OFF);
|
||||
|
||||
// ESPEasy::net::wifi::setWifiMode(WIFI_OFF);
|
||||
ESPEASY_FS.end();
|
||||
process_serialWriteBuffer();
|
||||
delay(100); // give the node time to flush all before reboot or sleep
|
||||
@@ -585,5 +629,3 @@ void prepareShutdown(IntendedRebootReason_e reason)
|
||||
Scheduler.markIntendedReboot(reason);
|
||||
saveToRTC();
|
||||
}
|
||||
|
||||
|
||||
@@ -141,6 +141,7 @@ void ESPEasy_Scheduler::setIntervalTimer(SchedulerIntervalTimer_e intervalTimer,
|
||||
}
|
||||
|
||||
void ESPEasy_Scheduler::sendGratuitousARP_now() {
|
||||
if (!ESPEasy::net::NetworkConnected(true)) return;
|
||||
sendGratuitousARP();
|
||||
|
||||
if (Settings.gratuitousARP()) {
|
||||
|
||||
Reference in new issue
Block a user