diff --git a/lib/Itho/CC1101Packet.h b/lib/Itho/CC1101Packet.h index f96390d7e1..1df185876b 100644 --- a/lib/Itho/CC1101Packet.h +++ b/lib/Itho/CC1101Packet.h @@ -9,7 +9,7 @@ #include #define CC1101_BUFFER_LEN 64 -#define CC1101_DATA_LEN CC1101_BUFFER_LEN - 3 +#define CC1101_DATA_LEN (CC1101_BUFFER_LEN - 3) class CC1101Packet { diff --git a/platformio_core_defs.ini b/platformio_core_defs.ini index bc88094501..f32d85020f 100644 --- a/platformio_core_defs.ini +++ b/platformio_core_defs.ini @@ -124,7 +124,7 @@ build_flags = ${esp82xx_2_7_x.build_flags} -DLIBRARIES_NO_LOG=1 lib_ignore = ${esp82xx_2_7_x.lib_ignore} build_unflags = ${esp82xx_2_7_x.build_unflags} -extra_scripts = +extra_scripts = ${esp82xx_common.extra_scripts} [core_stage] @@ -138,8 +138,7 @@ build_flags = ${esp82xx_3_0_x.build_flags} -DPHASE_LOCKED_WAVEFORM build_unflags = ${esp82xx_3_0_x.build_unflags} lib_ignore = ${esp82xx_defaults.lib_ignore} -;extra_scripts = ${esp82xx_3_0_x.extra_scripts} -extra_scripts = +extra_scripts = ${esp82xx_common.extra_scripts} @@ -157,7 +156,7 @@ build_flags = ${esp82xx_3_0_x.build_flags} -DUSE_SECOND_HEAP build_unflags = ${esp82xx_3_0_x.build_unflags} lib_ignore = ${core_stage.lib_ignore} -extra_scripts = ${esp82xx_3_0_x.extra_scripts} +extra_scripts = ${esp82xx_common.extra_scripts} diff --git a/platformio_esp32_envs.ini b/platformio_esp32_envs.ini index da34eb19eb..7dc7ea0146 100644 --- a/platformio_esp32_envs.ini +++ b/platformio_esp32_envs.ini @@ -322,6 +322,13 @@ extends = env:custom_ESP32_4M316k build_flags = ${env:custom_ESP32_4M316k.build_flags} -DFEATURE_ETHERNET=1 +[env:custom_ESP32_4M316k_LittleFS_ETH] +extends = esp32_custom_base_LittleFS +board = esp32_4M +build_flags = ${esp32_custom_base_LittleFS.build_flags} + -DFEATURE_ETHERNET=1 + + [env:custom_IR_ESP32_4M316k_ETH] extends = env:custom_IR_ESP32_4M316k build_flags = ${env:custom_ESP32_4M316k.build_flags} diff --git a/platformio_esp82xx_base.ini b/platformio_esp82xx_base.ini index eaf09d7a7b..90a1b999e4 100644 --- a/platformio_esp82xx_base.ini +++ b/platformio_esp82xx_base.ini @@ -9,7 +9,7 @@ platform = ${core_2_7_4.platform} platform_packages = ${core_2_7_4.platform_packages} lib_ignore = ${core_2_7_4.lib_ignore} build_unflags = ${core_2_7_4.build_unflags} -extra_scripts = +extra_scripts = ${core_2_7_4.extra_scripts} [core312_platform] @@ -26,6 +26,7 @@ platform = ${core_2_7_4.platform} platform_packages = ${core_2_7_4.platform_packages} lib_ignore = ${core_2_7_4.lib_ignore} build_unflags = ${core_2_7_4.build_unflags} +extra_scripts = ${core_2_7_4.extra_scripts} [beta_platform_2ndheap] @@ -76,8 +77,8 @@ build_flags = ${minimal_size.build_flags} build_unflags = -DDEBUG_ESP_PORT -fexceptions monitor_filters = esp8266_exception_decoder -extra_scripts = pre:tools/pio/pre_default_check.py - ${extra_scripts_esp8266.extra_scripts} +extra_scripts = ${extra_scripts_esp8266.extra_scripts} + pre:tools/pio/pre_default_check.py src_filter = +<*> -<.git/> -<.svn/> - - - - -<*/Commands/> -<*/ControllerQueue/> -<*/DataStructs/> -<*/DataTypes/> -<*/ESPEasyCore/> -<*/Globals/> -<*/Helpers/> -<*/PluginStructs/> -<*/WebServer/> diff --git a/platformio_esp82xx_envs.ini b/platformio_esp82xx_envs.ini index b4d178387a..0f91944591 100644 --- a/platformio_esp82xx_envs.ini +++ b/platformio_esp82xx_envs.ini @@ -16,7 +16,7 @@ build_flags = ${core_stage.build_flags} -DPLUGIN_BUILD_CUSTOM -DFEATURE_DEFINE_SERIAL_CONSOLE_PORT=0 extra_scripts = ${extra_scripts_esp8266.extra_scripts} - ${core_stage.extra_scripts} + [esp8266_custom_common_274] @@ -47,7 +47,7 @@ lib_ignore = ESP32_ping I2C AXP192 Power management extra_scripts = pre:tools/pio/pre_custom_esp82xx.py ${extra_scripts_esp8266.extra_scripts} - ${core_stage.extra_scripts} + ; Custom: 4M1M version -------------------------- @@ -307,8 +307,6 @@ extends = esp8266_1M_OTA, core274_platform build_flags = ${core274_platform.build_flags} ${minimal_OTA_domoticz.build_flags} lib_ignore = ${core274_platform.lib_ignore} -extra_scripts = ${core274_platform.extra_scripts} - ${esp8266_1M_OTA.extra_scripts} [env:minimal_core_274_ESP8266_1M_OTA_Domoticz_MQTT] @@ -316,8 +314,6 @@ extends = esp8266_1M_OTA, core274_platform build_flags = ${core274_platform.build_flags} ${minimal_OTA_domoticz_MQTT.build_flags} lib_ignore = ${core274_platform.lib_ignore} -extra_scripts = ${core274_platform.extra_scripts} - ${esp8266_1M_OTA.extra_scripts} [env:minimal_core_274_ESP8266_1M_OTA_FHEM_HA] @@ -325,9 +321,6 @@ extends = esp8266_1M_OTA, core274_platform build_flags = ${core274_platform.build_flags} ${minimal_OTA_FHEM_HA.build_flags} lib_ignore = ${core274_platform.lib_ignore} -extra_scripts = ${core274_platform.extra_scripts} - ${esp8266_1M_OTA.extra_scripts} - [env:minimal_core_312_ESP8266_1M_OTA_Domoticz] @@ -335,8 +328,6 @@ extends = esp8266_1M_OTA, core312_platform build_flags = ${core312_platform.build_flags} ${minimal_OTA_domoticz.build_flags} build_unflags = ${core312_platform.build_unflags} -extra_scripts = ${core312_platform.extra_scripts} - ${esp8266_1M_OTA.extra_scripts} [env:minimal_core_312_ESP8266_1M_OTA_Domoticz_MQTT] @@ -344,8 +335,6 @@ extends = esp8266_1M_OTA, core312_platform build_flags = ${core312_platform.build_flags} ${minimal_OTA_domoticz_MQTT.build_flags} build_unflags = ${core312_platform.build_unflags} -extra_scripts = ${core312_platform.extra_scripts} - ${esp8266_1M_OTA.extra_scripts} [env:minimal_core_312_ESP8266_1M_OTA_FHEM_HA] @@ -353,8 +342,6 @@ extends = esp8266_1M_OTA, core312_platform build_flags = ${core312_platform.build_flags} ${minimal_OTA_FHEM_HA.build_flags} build_unflags = ${core312_platform.build_unflags} -extra_scripts = ${core312_platform.extra_scripts} - ${esp8266_1M_OTA.extra_scripts} @@ -537,6 +524,7 @@ extends = esp8266_4M1M, regular_platform build_flags = ${regular_platform.build_flags} ${esp8266_4M1M.build_flags} -D PLUGIN_ENERGY_COLLECTION + -D LIMIT_BUILD_SIZE -D WEBSERVER_USE_CDN_JS_CSS lib_ignore = ${regular_platform.lib_ignore} ESP8266SdFat @@ -544,6 +532,7 @@ lib_ignore = ${regular_platform.lib_ignore} SD SDFS LittleFS(esp8266) +extra_scripts = ${regular_platform.extra_scripts} ; display : 4096k version ---------------------------- diff --git a/src/_P122_SHT2x.ino b/src/_P122_SHT2x.ino index 1ccf17e7fd..2b1af222ad 100644 --- a/src/_P122_SHT2x.ino +++ b/src/_P122_SHT2x.ino @@ -234,12 +234,6 @@ boolean Plugin_122(uint8_t function, struct EventStruct *event, String& string) break; } - case PLUGIN_ONCE_A_SECOND: - { - // code to be executed once a second. Tasks which do not require fast response can be added here - success = true; - } - case PLUGIN_TEN_PER_SECOND: { // code to be executed 10 times per second. Tasks which require fast response can be added here @@ -251,6 +245,7 @@ boolean Plugin_122(uint8_t function, struct EventStruct *event, String& string) P122_data->update(); // SHT2x FSM evaluation } success = true; + break; } } // switch return success; diff --git a/src/src/CustomBuild/define_plugin_sets.h b/src/src/CustomBuild/define_plugin_sets.h index c39f61a93c..a82565da34 100644 --- a/src/src/CustomBuild/define_plugin_sets.h +++ b/src/src/CustomBuild/define_plugin_sets.h @@ -1676,7 +1676,7 @@ To create/register a plugin, you have to : #if !defined(USES_P138) && defined(ESP32) #define USES_P138 // IP5306 #endif - #ifndef USES_P148 + #if !defined(USES_P148) && defined(ESP32) #define USES_P148 // Sonoff POWR3xxD and THR3xxD display #endif diff --git a/src/src/DataStructs/DeviceStruct.cpp b/src/src/DataStructs/DeviceStruct.cpp index f23b9a3fdd..03e5247052 100644 --- a/src/src/DataStructs/DeviceStruct.cpp +++ b/src/src/DataStructs/DeviceStruct.cpp @@ -10,7 +10,8 @@ DeviceStruct::DeviceStruct() : TimerOption(false), TimerOptional(false), DecimalsOnly(false), DuplicateDetection(false), ExitTaskBeforeSave(true), ErrorStateValues(false), PluginStats(false), PluginLogsPeaks(false), PowerManager(false), - TaskLogsOwnPeaks(false), I2CNoDeviceCheck(false) {} + TaskLogsOwnPeaks(false), I2CNoDeviceCheck(false), + I2CMax100kHz(false) {} bool DeviceStruct::connectedToGPIOpins() const { switch(Type) { diff --git a/src/src/DataStructs/NodeStruct.cpp b/src/src/DataStructs/NodeStruct.cpp index e267fb996c..0bc543662c 100644 --- a/src/src/DataStructs/NodeStruct.cpp +++ b/src/src/DataStructs/NodeStruct.cpp @@ -149,12 +149,15 @@ IPAddress NodeStruct::IP() const { } #if FEATURE_USE_IPV6 -IPAddress NodeStruct::IPv6_link_local() const +IPAddress NodeStruct::IPv6_link_local(bool stripZone) const { if (hasIPv6_mac_based_link_local) { // Base IPv6 on MAC address IPAddress ipv6; if (IPv6_link_local_from_MAC(sta_mac, ipv6)) { + if (stripZone) { + return IPAddress(IPv6, &ipv6[0], 0); + } return ipv6; } } @@ -172,6 +175,11 @@ IPAddress NodeStruct::IPv6_global() const } return IN6ADDR_ANY; } + +bool NodeStruct::hasIPv6() const { + return hasIPv6_mac_based_link_local || + hasIPv6_mac_based_link_global; +} #endif diff --git a/src/src/DataStructs/NodeStruct.h b/src/src/DataStructs/NodeStruct.h index 8c839898de..f88af4515d 100644 --- a/src/src/DataStructs/NodeStruct.h +++ b/src/src/DataStructs/NodeStruct.h @@ -36,8 +36,10 @@ struct __attribute__((__packed__)) NodeStruct IPAddress IP() const; #if FEATURE_USE_IPV6 - IPAddress IPv6_link_local() const; + IPAddress IPv6_link_local(bool stripZone = false) const; IPAddress IPv6_global() const; + + bool hasIPv6() const; #endif MAC_address STA_MAC() const; diff --git a/src/src/DataStructs/NodesHandler.cpp b/src/src/DataStructs/NodesHandler.cpp index 50a01c44ae..7766d205f1 100644 --- a/src/src/DataStructs/NodesHandler.cpp +++ b/src/src/DataStructs/NodesHandler.cpp @@ -230,9 +230,7 @@ const NodeStruct* NodesHandler::getPreferredNode_notMatching(uint8_t unit_nr) co } const NodeStruct * NodesHandler::getPreferredNode_notMatching(const MAC_address& not_matching) const { - MAC_address this_mac; - - WiFi.macAddress(this_mac.mac); + MAC_address this_mac = NetworkMacAddress(); const NodeStruct *thisNode = getNodeByMac(this_mac); const NodeStruct *reject = getNodeByMac(not_matching); @@ -353,14 +351,10 @@ void NodesHandler::updateThisNode() { NodeStruct thisNode; // Set local data - #if FEATURE_ETHERNET { MAC_address mac = NetworkMacAddress(); mac.get(thisNode.sta_mac); } - #else - WiFi.macAddress(thisNode.sta_mac); - #endif WiFi.softAPmacAddress(thisNode.ap_mac); { const bool addIP = NetworkConnected(); @@ -494,8 +488,7 @@ void NodesHandler::updateThisNode() { const NodeStruct * NodesHandler::getThisNode() { node_time.now(); updateThisNode(); - MAC_address this_mac; - WiFi.macAddress(this_mac.mac); + MAC_address this_mac = NetworkMacAddress(); return getNodeByMac(this_mac.mac); } diff --git a/src/src/DataStructs/PluginStats.cpp b/src/src/DataStructs/PluginStats.cpp index f44a028170..cd0bee3d94 100644 --- a/src/src/DataStructs/PluginStats.cpp +++ b/src/src/DataStructs/PluginStats.cpp @@ -545,7 +545,7 @@ bool PluginStats_array::webformLoad_show_stats(struct EventStruct *event) const } # if FEATURE_CHART_JS -void PluginStats_array::plot_ChartJS() const +void PluginStats_array::plot_ChartJS(bool onlyJSON) const { const size_t nrSamples = nrSamplesPresent(); @@ -577,12 +577,13 @@ void PluginStats_array::plot_ChartJS() const 500 + (70 * (scales.nr_Y_scales() - 1)), 500, scales.toString(), - nrSamples); + nrSamples, + onlyJSON); } // Add labels - addHtml(F("labels:[")); + addHtml(F("\"labels\":[")); for (size_t i = 0; i < nrSamples; ++i) { if (i != 0) { @@ -590,16 +591,21 @@ void PluginStats_array::plot_ChartJS() const } addHtmlInt(i); } - addHtml(F("],datasets:[")); + addHtml(F("],\n\"datasets\":[")); // Data sets + bool first = true; for (size_t i = 0; i < VARS_PER_TASK; ++i) { if (_plugin_stats[i] != nullptr) { + if (!first) { + addHtml(','); + } + first = false; _plugin_stats[i]->plot_ChartJS_dataset(); } } - add_ChartJS_chart_footer(); + add_ChartJS_chart_footer(onlyJSON); } void PluginStats_array::plot_ChartJS_scatter( @@ -611,7 +617,8 @@ void PluginStats_array::plot_ChartJS_scatter( int width, int height, bool showAverage, - const String & options) const + const String & options, + bool onlyJSON) const { const PluginStats *stats_X = getPluginStats(values_X_axis_index); const PluginStats *stats_Y = getPluginStats(values_Y_axis_index); @@ -643,10 +650,11 @@ void PluginStats_array::plot_ChartJS_scatter( width, height, axisOptions, - nrSamples); + nrSamples, + onlyJSON); // Add labels, which will be shown in a tooltip when hovering with the mouse over a point. - addHtml(F("labels:[")); + addHtml(F("\"labels\":[")); for (size_t i = 0; i < nrSamples; ++i) { if (i != 0) { @@ -654,7 +662,7 @@ void PluginStats_array::plot_ChartJS_scatter( } addHtmlInt(i); } - addHtml(F("],datasets:[")); + addHtml(F("],\n\"datasets\":[")); // Long/Lat Coordinates add_ChartJS_dataset_header(datasetConfig); @@ -666,10 +674,11 @@ void PluginStats_array::plot_ChartJS_scatter( add_ChartJS_scatter_data_point(valX, valY, 6); } - add_ChartJS_dataset_footer(F("showLine:true")); + add_ChartJS_dataset_footer(F("\"showLine\":true")); if (showAverage) { // Add single point showing the average + addHtml(','); add_ChartJS_dataset_header( { F("Average"), @@ -680,9 +689,9 @@ void PluginStats_array::plot_ChartJS_scatter( const float valY = stats_Y->getSampleAvg(); add_ChartJS_scatter_data_point(valX, valY, 6); } - add_ChartJS_dataset_footer(F("pointRadius:6,pointHoverRadius:10")); + add_ChartJS_dataset_footer(F("\"pointRadius\":6,\"pointHoverRadius\":10")); } - add_ChartJS_chart_footer(); + add_ChartJS_chart_footer(onlyJSON); } # endif // if FEATURE_CHART_JS diff --git a/src/src/DataStructs/PluginStats.h b/src/src/DataStructs/PluginStats.h index 10ab26c50a..2d9dc8183f 100644 --- a/src/src/DataStructs/PluginStats.h +++ b/src/src/DataStructs/PluginStats.h @@ -17,11 +17,11 @@ # ifndef PLUGIN_STATS_NR_ELEMENTS # ifdef ESP8266 -# ifdef USE_SECOND_HEAP -# define PLUGIN_STATS_NR_ELEMENTS 50 -#else -# define PLUGIN_STATS_NR_ELEMENTS 16 -#endif +# ifdef USE_SECOND_HEAP +# define PLUGIN_STATS_NR_ELEMENTS 50 +# else // ifdef USE_SECOND_HEAP +# define PLUGIN_STATS_NR_ELEMENTS 16 +# endif // ifdef USE_SECOND_HEAP # endif // ifdef ESP8266 # ifdef ESP32 # define PLUGIN_STATS_NR_ELEMENTS 250 @@ -199,7 +199,7 @@ class PluginStats_array { bool webformLoad_show_stats(struct EventStruct *event) const; # if FEATURE_CHART_JS - void plot_ChartJS() const; + void plot_ChartJS(bool onlyJSON = false) const; void plot_ChartJS_scatter( taskVarIndex_t values_X_axis_index, @@ -210,7 +210,8 @@ class PluginStats_array { int width, int height, bool showAverage = true, - const String & options = EMPTY_STRING) const; + const String & options = EMPTY_STRING, + bool onlyJSON = false) const; # endif // if FEATURE_CHART_JS diff --git a/src/src/DataStructs/PluginTaskData_base.cpp b/src/src/DataStructs/PluginTaskData_base.cpp index 215dabf7b1..ed62347a5d 100644 --- a/src/src/DataStructs/PluginTaskData_base.cpp +++ b/src/src/DataStructs/PluginTaskData_base.cpp @@ -128,10 +128,10 @@ bool PluginTaskData_base::webformLoad_show_stats(struct EventStruct *event) cons } # if FEATURE_CHART_JS -void PluginTaskData_base::plot_ChartJS() const +void PluginTaskData_base::plot_ChartJS(bool onlyJSON) const { if (_plugin_stats_array != nullptr) { - _plugin_stats_array->plot_ChartJS(); + _plugin_stats_array->plot_ChartJS(onlyJSON); } } @@ -144,7 +144,8 @@ void PluginTaskData_base::plot_ChartJS_scatter( int width, int height, bool showAverage, - const String & options) const + const String & options, + bool onlyJSON) const { if (_plugin_stats_array != nullptr) { _plugin_stats_array->plot_ChartJS_scatter( @@ -156,7 +157,8 @@ void PluginTaskData_base::plot_ChartJS_scatter( width, height, showAverage, - options); + options, + onlyJSON); } } diff --git a/src/src/DataStructs/PluginTaskData_base.h b/src/src/DataStructs/PluginTaskData_base.h index 0714331dc7..755a1348c5 100644 --- a/src/src/DataStructs/PluginTaskData_base.h +++ b/src/src/DataStructs/PluginTaskData_base.h @@ -52,7 +52,7 @@ struct PluginTaskData_base { bool webformLoad_show_stats(struct EventStruct *event) const; # if FEATURE_CHART_JS - void plot_ChartJS() const; + void plot_ChartJS(bool onlyJSON = false) const; void plot_ChartJS_scatter( taskVarIndex_t values_X_axis_index, @@ -63,7 +63,8 @@ struct PluginTaskData_base { int width, int height, bool showAverage = true, - const String & options = EMPTY_STRING) const; + const String & options = EMPTY_STRING, + bool onlyJSON = false) const; # endif // if FEATURE_CHART_JS #endif // if FEATURE_PLUGIN_STATS diff --git a/src/src/ESPEasyCore/ESPEasyEth_ProcessEvent.cpp b/src/src/ESPEasyCore/ESPEasyEth_ProcessEvent.cpp index 6e48a796dc..fe6fa5bd46 100644 --- a/src/src/ESPEasyCore/ESPEasyEth_ProcessEvent.cpp +++ b/src/src/ESPEasyCore/ESPEasyEth_ProcessEvent.cpp @@ -29,10 +29,10 @@ void handle_unprocessedEthEvents() { // Process disconnect events before connect events. #if FEATURE_USE_IPV6 if (!EthEventData.processedGotIP6) { + EthEventData.processedGotIP6 = true; #if FEATURE_ESPEASY_P2P - updateUDPport(); + updateUDPport(true); #endif - EthEventData.processedGotIP6 = true; } #endif diff --git a/src/src/ESPEasyCore/ESPEasyWifi.cpp b/src/src/ESPEasyCore/ESPEasyWifi.cpp index 9370a46714..a4e49d7a06 100644 --- a/src/src/ESPEasyCore/ESPEasyWifi.cpp +++ b/src/src/ESPEasyCore/ESPEasyWifi.cpp @@ -231,10 +231,10 @@ bool WiFiConnected() { #if FEATURE_USE_IPV6 if (!WiFiEventData.processedGotIP6) { + WiFiEventData.processedGotIP6 = true; #if FEATURE_ESPEASY_P2P - updateUDPport(); + updateUDPport(true); #endif - WiFiEventData.processedGotIP6 = true; } #endif diff --git a/src/src/ESPEasyCore/ESPEasyWifi_ProcessEvent.cpp b/src/src/ESPEasyCore/ESPEasyWifi_ProcessEvent.cpp index 4e08ff0927..2a54bf8f75 100644 --- a/src/src/ESPEasyCore/ESPEasyWifi_ProcessEvent.cpp +++ b/src/src/ESPEasyCore/ESPEasyWifi_ProcessEvent.cpp @@ -211,7 +211,7 @@ void handle_unprocessedNetworkEvents() #endif // if FEATURE_ETHERNET #if FEATURE_ESPEASY_P2P - updateUDPport(); + updateUDPport(false); #endif } diff --git a/src/src/Helpers/Hardware_ADC.h b/src/src/Helpers/Hardware_ADC.h index e01ae17023..c9eb8e2a4c 100644 --- a/src/src/Helpers/Hardware_ADC.h +++ b/src/src/Helpers/Hardware_ADC.h @@ -65,8 +65,8 @@ class Hardware_ADC_t { Hardware_ADC_cali_t _adc_cali_handle; # if ESP_IDF_VERSION_MAJOR >= 5 - adc_channel_t _channel; - adc_oneshot_unit_handle_t _adc_handle; + adc_channel_t _channel = ADC_CHANNEL_0; + adc_oneshot_unit_handle_t _adc_handle = nullptr; # endif // if ESP_IDF_VERSION_MAJOR >= 5 #endif // ifdef ESP32 diff --git a/src/src/Helpers/Misc.h b/src/src/Helpers/Misc.h index 691cc1fcac..0f94ffad4c 100644 --- a/src/src/Helpers/Misc.h +++ b/src/src/Helpers/Misc.h @@ -16,8 +16,8 @@ // Simple bitwise get/set functions -#define setNBitToUL(N, B, V, M) N=(((N) & ~(M << (B))) | (static_cast((V) & M) << (B))) -#define getNBitFromUL(number, bitnr, mask) ((number >> bitnr) & mask) +#define setNBitToUL(N, B, V, M) N=(((N) & ~((M) << (B))) | (static_cast((V) & (M)) << (B))) +#define getNBitFromUL(number, bitnr, mask) (((number) >> (bitnr)) & (mask)) #define set8BitToUL(N, B, V) setNBitToUL(N, B, V, 0xFFUL) #define set4BitToUL(N, B, V) setNBitToUL(N, B, V, 0x0FUL) diff --git a/src/src/Helpers/Networking.cpp b/src/src/Helpers/Networking.cpp index 756ddc32ba..e6d8eaa997 100644 --- a/src/src/Helpers/Networking.cpp +++ b/src/src/Helpers/Networking.cpp @@ -219,11 +219,11 @@ void sendUDP(uint8_t unit, const uint8_t *data, uint8_t size) /*********************************************************************************************\ Update UDP port (ESPEasy propiertary protocol) \*********************************************************************************************/ -void updateUDPport() +void updateUDPport(bool force) { static uint16_t lastUsedUDPPort = 0; - if (Settings.UDPPort == lastUsedUDPPort) { + if (!force && Settings.UDPPort == lastUsedUDPPort) { return; } @@ -419,12 +419,15 @@ IPAddress getIPAddressForUnit(uint8_t unit) { return ip; } #if FEATURE_USE_IPV6 +/* + // FIXME TD-er: for now do not try to send to IPv6 if (it->second.hasIPv6_mac_based_link_local) { return it->second.IPv6_link_local(); } if (it->second.hasIPv6_mac_based_link_global) { return it->second.IPv6_global(); } +*/ #endif return it->second.IP(); } diff --git a/src/src/Helpers/Networking.h b/src/src/Helpers/Networking.h index e4f8204441..29d3cbde30 100644 --- a/src/src/Helpers/Networking.h +++ b/src/src/Helpers/Networking.h @@ -28,7 +28,7 @@ void sendSyslog(uint8_t logLevel, const String& message); /*********************************************************************************************\ Update UDP port (ESPEasy propiertary protocol) \*********************************************************************************************/ -void updateUDPport(); +void updateUDPport(bool force); /*********************************************************************************************\ diff --git a/src/src/Helpers/Numerical.cpp b/src/src/Helpers/Numerical.cpp index dae80fdcf2..633c000634 100644 --- a/src/src/Helpers/Numerical.cpp +++ b/src/src/Helpers/Numerical.cpp @@ -150,6 +150,9 @@ bool validDoubleFromString(const String& tBuf, ESPEASY_RULES_FLOAT_TYPE& result) } bool mustConsiderAsString(NumericalType detectedType) { + return detectedType != NumericalType::FloatingPoint && + detectedType != NumericalType::Integer; +/* switch (detectedType) { case NumericalType::FloatingPoint: case NumericalType::Integer: @@ -160,6 +163,7 @@ bool mustConsiderAsString(NumericalType detectedType) { return true; } return false; +*/ } bool mustConsiderAsJSONString(const String& value) { @@ -167,13 +171,22 @@ bool mustConsiderAsJSONString(const String& value) { // Empty string return true; } + const char c = value[0]; - NumericalType detectedType; - if (isNumerical(value, detectedType)) { - return mustConsiderAsString(detectedType); + if (isDigit(c) || c == '-' || c == '.' || c == '+' || c == ' ') { + NumericalType detectedType; + if (isNumerical(value, detectedType)) { + return mustConsiderAsString(detectedType); + } } - const bool isBool = (Settings.JSONBoolWithoutQuotes() && ((value.equalsIgnoreCase(F("true")) || value.equalsIgnoreCase(F("false"))))); - return !isBool; + if (equals(value, F("true")) || + equals(value, F("false")) || + equals(value, F("null"))) + { + return !Settings.JSONBoolWithoutQuotes(); + } + + return true; } String getNumerical(const String& tBuf, NumericalType requestedType, NumericalType& detectedType) { diff --git a/src/src/Helpers/StringConverter_Numerical.cpp b/src/src/Helpers/StringConverter_Numerical.cpp index ef795b1830..d10c100dc2 100644 --- a/src/src/Helpers/StringConverter_Numerical.cpp +++ b/src/src/Helpers/StringConverter_Numerical.cpp @@ -23,7 +23,6 @@ unsigned long str2int(const char *string) \*********************************************************************************************/ String toString(const float& value, unsigned int decimalPlaces) { - /* #ifndef LIMIT_BUILD_SIZE if (decimalPlaces == 0) { @@ -38,15 +37,18 @@ String toString(const float& value, unsigned int decimalPlaces) } } #endif // ifndef LIMIT_BUILD_SIZE - */ // #if FEATURE_USE_DOUBLE_AS_ESPEASY_RULES_FLOAT_TYPE // This has been fixed in ESP32 code, not (yet) in ESP8266 code // https://github.com/espressif/arduino-esp32/pull/6138/files // #ifdef ESP8266 char buf[decimalPlaces + 42]; + #ifdef USE_SECOND_HEAP String sValue; move_special(sValue, String(dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf))); + #else + String sValue(dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf)); + #endif /* #else diff --git a/src/src/Helpers/StringProvider.cpp b/src/src/Helpers/StringProvider.cpp index 08e910d626..2aeb6e1e24 100644 --- a/src/src/Helpers/StringProvider.cpp +++ b/src/src/Helpers/StringProvider.cpp @@ -260,6 +260,9 @@ const __FlashStringHelper * getLabel(LabelType::Enum label) { case LabelType::ETH_IP_ADDRESS_SUBNET: return F("Eth IP / Subnet"); case LabelType::ETH_IP_GATEWAY: return F("Eth Gateway"); case LabelType::ETH_IP_DNS: return F("Eth DNS"); +#if FEATURE_USE_IPV6 + case LabelType::ETH_IP6_LOCAL: return F("Eth IPv6 link local"); +#endif case LabelType::ETH_MAC: return F("Eth MAC"); case LabelType::ETH_DUPLEX: return F("Eth Mode"); case LabelType::ETH_SPEED: return F("Eth Speed"); @@ -435,7 +438,11 @@ String getValue(LabelType::Enum label) { #if FEATURE_USE_IPV6 case LabelType::IP6_LOCAL: return formatIP(NetworkLocalIP6()); case LabelType::IP6_GLOBAL: return formatIP(NetworkGlobalIP6()); -// case LabelType::IP6_ALL_ADDRESSES: +#if FEATURE_ETHERNET + case LabelType::ETH_IP6_LOCAL: return formatIP(NetworkLocalIP6()); +#endif +/* + case LabelType::IP6_ALL_ADDRESSES: { IP6Addresses_t addresses = NetworkAllIPv6(); String res; @@ -448,6 +455,7 @@ String getValue(LabelType::Enum label) { } return res; } +*/ #endif case LabelType::CLIENT_IP: return formatIP(web_server.client().remoteIP()); #if FEATURE_INTERNAL_TEMPERATURE diff --git a/src/src/Helpers/StringProvider.h b/src/src/Helpers/StringProvider.h index 9571edd8f4..ce11604180 100644 --- a/src/src/Helpers/StringProvider.h +++ b/src/src/Helpers/StringProvider.h @@ -203,6 +203,9 @@ struct LabelType { ETH_IP_ADDRESS_SUBNET, ETH_IP_GATEWAY, ETH_IP_DNS, +#if FEATURE_USE_IPV6 + ETH_IP6_LOCAL, +#endif ETH_MAC, ETH_DUPLEX, ETH_SPEED, diff --git a/src/src/Helpers/SystemVariables.cpp b/src/src/Helpers/SystemVariables.cpp index a8eaec3e79..14d5aa291f 100644 --- a/src/src/Helpers/SystemVariables.cpp +++ b/src/src/Helpers/SystemVariables.cpp @@ -90,6 +90,9 @@ LabelType::Enum SystemVariables2LabelType(SystemVariables::Enum enumval) { switch (enumval) { case SystemVariables::IP: label = LabelType::IP_ADDRESS; break; +#if FEATURE_USE_IPV6 + case SystemVariables::IP6_LOCAL: label = LabelType::IP6_LOCAL; break; +#endif case SystemVariables::SUBNET: label = LabelType::IP_SUBNET; break; case SystemVariables::DNS: label = LabelType::DNS; break; case SystemVariables::DNS_1: label = LabelType::DNS_1; break; @@ -523,6 +526,9 @@ const __FlashStringHelper * SystemVariables::toFlashString(SystemVariables::Enum case Enum::IP4: return F("ip4"); case Enum::IP: return F("ip"); +#if FEATURE_USE_IPV6 + case Enum::IP6_LOCAL: return F("ipv6local"); +#endif case Enum::ISMQTT: return F("ismqtt"); case Enum::ISMQTTIMP: return F("ismqttimp"); case Enum::ISNTP: return F("isntp"); diff --git a/src/src/Helpers/SystemVariables.h b/src/src/Helpers/SystemVariables.h index 220928ff59..30b8ac6a84 100644 --- a/src/src/Helpers/SystemVariables.h +++ b/src/src/Helpers/SystemVariables.h @@ -43,6 +43,9 @@ class SystemVariables { IP4, IP, +#if FEATURE_USE_IPV6 + IP6_LOCAL, +#endif ISMQTT, ISMQTTIMP, ISNTP, diff --git a/src/src/PluginStructs/P002_data_struct.cpp b/src/src/PluginStructs/P002_data_struct.cpp index 2e0d5c0b9e..a444531102 100644 --- a/src/src/PluginStructs/P002_data_struct.cpp +++ b/src/src/PluginStructs/P002_data_struct.cpp @@ -4,19 +4,19 @@ # include "../Globals/RulesCalculate.h" -#include "../Helpers/Hardware_ADC_cali.h" +# include "../Helpers/Hardware_ADC_cali.h" # ifndef DEFAULT_VREF # define DEFAULT_VREF 1100 # endif // ifndef DEFAULT_VREF -#ifndef P002_ADC_ATTEN_MAX -#if ESP_IDF_VERSION_MAJOR < 5 -#define P002_ADC_ATTEN_MAX ADC_ATTEN_MAX -#else -#define P002_ADC_ATTEN_MAX ADC_ATTENDB_MAX -#endif -#endif +# ifndef P002_ADC_ATTEN_MAX +# if ESP_IDF_VERSION_MAJOR < 5 +# define P002_ADC_ATTEN_MAX ADC_ATTEN_MAX +# else // if ESP_IDF_VERSION_MAJOR < 5 +# define P002_ADC_ATTEN_MAX ADC_ATTENDB_MAX +# endif // if ESP_IDF_VERSION_MAJOR < 5 +# endif // ifndef P002_ADC_ATTEN_MAX void P002_data_struct::init(struct EventStruct *event) @@ -64,7 +64,7 @@ void P002_data_struct::load(struct EventStruct *event) String lines[nr_lines]; LoadCustomTaskSettings(event->TaskIndex, lines, nr_lines, 0); const int stored_nr_lines = lines[P002_SAVED_NR_LINES].toInt(); - move_special(_formula, std::move(lines[P002_LINE_INDEX_FORMULA])); + move_special(_formula, std::move(lines[P002_LINE_INDEX_FORMULA])); move_special(_formula_preprocessed, RulesCalculate_t::preProces(_formula)); for (size_t i = P002_LINE_IDX_FIRST_MP; i < nr_lines && static_cast(i) < stored_nr_lines; i += P002_STRINGS_PER_MP) { @@ -72,9 +72,9 @@ void P002_data_struct::load(struct EventStruct *event) if (validFloatFromString(lines[i], adc) && validFloatFromString(lines[i + 1], value)) { // sizeof() multipoint item is multiple of 4 bytes, so should work just fine on 2nd heap - # ifdef USE_SECOND_HEAP + # ifdef USE_SECOND_HEAP HeapSelectIram ephemeral; - # endif // ifdef USE_SECOND_HEAP + # endif // ifdef USE_SECOND_HEAP _multipoint.emplace_back(adc, value); } @@ -82,9 +82,9 @@ void P002_data_struct::load(struct EventStruct *event) } std::sort(_multipoint.begin(), _multipoint.end()); { - # ifdef USE_SECOND_HEAP + # ifdef USE_SECOND_HEAP HeapSelectIram ephemeral; - # endif // ifdef USE_SECOND_HEAP + # endif // ifdef USE_SECOND_HEAP _binning.resize(_multipoint.size(), 0); _binningRange.resize(_multipoint.size()); @@ -132,11 +132,11 @@ void P002_data_struct::webformLoad(struct EventStruct *event) # ifdef ESP32 addRowLabel(F("Analog Pin")); - #if HAS_HALL_EFFECT_SENSOR + # if HAS_HALL_EFFECT_SENSOR addADC_PinSelect(AdcPinSelectPurpose::ADC_Touch_HallEffect, F("taskdevicepin1"), CONFIG_PIN1); - #else - addADC_PinSelect(AdcPinSelectPurpose::ADC_Touch, F("taskdevicepin1"), CONFIG_PIN1); - #endif + # else // if HAS_HALL_EFFECT_SENSOR + addADC_PinSelect(AdcPinSelectPurpose::ADC_Touch, F("taskdevicepin1"), CONFIG_PIN1); + # endif // if HAS_HALL_EFFECT_SENSOR addFormNote(F("Do not use ADC2 pins with WiFi active")); @@ -193,9 +193,9 @@ void P002_data_struct::webformLoad(struct EventStruct *event) for (size_t att = 0; att < P002_ADC_ATTEN_MAX; ++att) { const adc_atten_t attenuation = static_cast(att); - const int low = getADC_factory_calibrated_min(attenuation); - const int high = getADC_factory_calibrated_max(attenuation); - const float step = static_cast(high - low) / MAX_ADC_VALUE; + const int low = getADC_factory_calibrated_min(attenuation); + const int high = getADC_factory_calibrated_max(attenuation); + const float step = static_cast(high - low) / MAX_ADC_VALUE; String rowlabel = F("Attenuation @"); rowlabel += AttenuationToString(attenuation); @@ -220,7 +220,7 @@ void P002_data_struct::webformLoad(struct EventStruct *event) # if FEATURE_ADC_VCC addFormNote(F("Measuring ESP VCC, not A0. Unit is 1/1024 V. See documentation.")); # endif // if FEATURE_ADC_VCC -# endif // ifdef ESP8266 +# endif // ifdef ESP8266 webformLoad_2p_calibPoint( @@ -370,14 +370,14 @@ void P002_data_struct::webformLoad_calibrationCurve(struct EventStruct *event) { ChartJS_options_scales scales; - scales.add({F("x"), F("ADC Value")}); - scales.add({F("y"), F("Input Voltage (mV)")}); + scales.add({ F("x"), F("ADC Value") }); + scales.add({ F("y"), F("Input Voltage (mV)") }); axisOptions = scales.toString(); } add_ChartJS_chart_header( F("line"), F("fact_cal"), - {F("Factory Calibration per Attenuation")}, + { F("Factory Calibration per Attenuation") }, 500, 500, axisOptions); @@ -390,12 +390,12 @@ void P002_data_struct::webformLoad_calibrationCurve(struct EventStruct *event) size_t current_attenuation = getAttenuation(event); - if (current_attenuation >= P002_ADC_ATTEN_MAX) { -#if ESP_IDF_VERSION_MAJOR >= 5 - current_attenuation = ADC_ATTEN_DB_12; -#else - current_attenuation = ADC_ATTEN_DB_11; -#endif + if (current_attenuation >= P002_ADC_ATTEN_MAX) { +# if ESP_IDF_VERSION_MAJOR >= 5 + current_attenuation = ADC_ATTEN_DB_12; +# else // if ESP_IDF_VERSION_MAJOR >= 5 + current_attenuation = ADC_ATTEN_DB_11; +# endif // if ESP_IDF_VERSION_MAJOR >= 5 } for (size_t att = 0; att < P002_ADC_ATTEN_MAX; ++att) @@ -409,7 +409,11 @@ void P002_data_struct::webformLoad_calibrationCurve(struct EventStruct *event) ChartJS_dataset_config config( AttenuationToString(static_cast(att)), colors[att]); - config.hidden = att != current_attenuation; + config.hidden = att != current_attenuation; + + if (att != 0) { + addHtml(','); + } add_ChartJS_dataset( config, @@ -482,8 +486,8 @@ void P002_data_struct::webformLoad_2pt_calibrationCurve(struct EventStruct *even { ChartJS_options_scales scales; - scales.add({F("x"), getChartXaxisLabel(event)}); - scales.add({F("y"), F("Calibrated Output")}); + scales.add({ F("x"), getChartXaxisLabel(event) }); + scales.add({ F("y"), F("Calibrated Output") }); axisOptions = scales.toString(); } @@ -491,7 +495,7 @@ void P002_data_struct::webformLoad_2pt_calibrationCurve(struct EventStruct *even add_ChartJS_chart_header( F("line"), F("twoPointCurve"), - {F("Two Point Calibration Curve")}, + { F("Two Point Calibration Curve") }, 500, 500, axisOptions); @@ -596,11 +600,11 @@ adc_atten_t P002_data_struct::getAttenuation(struct EventStruct *event) { } P002_ATTENUATION = P002_ADC_11db; -#if ESP_IDF_VERSION_MAJOR >= 5 +# if ESP_IDF_VERSION_MAJOR >= 5 return ADC_ATTEN_DB_12; -#else +# else // if ESP_IDF_VERSION_MAJOR >= 5 return ADC_ATTEN_DB_11; -#endif +# endif // if ESP_IDF_VERSION_MAJOR >= 5 } # endif // ifdef ESP32 @@ -617,33 +621,34 @@ void P002_data_struct::webformLoad_multipointCurve(struct EventStruct *event) co { ChartJS_options_scales scales; - scales.add({F("x"), useBinning ? F("Bin Center Value") : F("Input")}); - scales.add({F("y"), useBinning ? F("Bin Output Value") : F("Output")}); + scales.add({ F("x"), useBinning ? F("Bin Center Value") : F("Input") }); + scales.add({ F("y"), useBinning ? F("Bin Output Value") : F("Output") }); axisOptions = scales.toString(); } add_ChartJS_chart_header( useBinning ? F("bar") : F("line"), F("mpcurve"), - {useBinning ? F("Bin Values") : F("Multipoint Curve")}, + { useBinning ? F("Bin Values") : F("Multipoint Curve") }, 500, 500, axisOptions); // Add labels - addHtml(F("labels:[")); + addHtml(F("\"labels\":[")); + for (size_t i = 0; i < _multipoint.size(); ++i) { if (i != 0) { addHtml(','); } addHtmlFloat(_multipoint[i]._adc, _nrDecimals); } - addHtml(F("],datasets:[")); + addHtml(F("],\n\"datasets\":[")); add_ChartJS_dataset_header( - { + { useBinning ? F("Bins") : F("Multipoint Values"), - F("rgb(255, 99, 132)")}); + F("rgb(255, 99, 132)") }); for (size_t i = 0; i < _multipoint.size(); ++i) { if (i != 0) { @@ -665,14 +670,14 @@ void P002_data_struct::webformLoad_multipointCurve(struct EventStruct *event) co { ChartJS_options_scales scales; - scales.add({F("x"), getChartXaxisLabel(event)}); - scales.add({F("y"), F("Output")}); + scales.add({ F("x"), getChartXaxisLabel(event) }); + scales.add({ F("y"), F("Output") }); axisOptions = scales.toString(); } add_ChartJS_chart_header( F("line"), F("mpCurveSimulated"), - {F("Simulated Input to Output Curve")}, + { F("Simulated Input to Output Curve") }, 500, 500, axisOptions); @@ -727,6 +732,10 @@ void P002_data_struct::webformLoad_multipointCurve(struct EventStruct *event) co color); config.hidden = hidden; + if (step != 0) { + addHtml(','); + } + add_ChartJS_dataset( config, values, diff --git a/src/src/PluginStructs/P025_data_struct.h b/src/src/PluginStructs/P025_data_struct.h index a96d9614e0..85c2780cdc 100644 --- a/src/src/PluginStructs/P025_data_struct.h +++ b/src/src/PluginStructs/P025_data_struct.h @@ -35,7 +35,7 @@ union P025_VARIOUS_BITS_t { // - PCONFIG(6) // - PCONFIG(7) # define P025_SENSOR_TYPE_INDEX 4 // Storing the output selector -# define P025_PCONFIG_INDEX(x) ((x == 0) ? 2 : x + P025_SENSOR_TYPE_INDEX) +# define P025_PCONFIG_INDEX(x) (((x) == 0) ? 2 : (x) + P025_SENSOR_TYPE_INDEX) # define P025_NR_OUTPUT_VALUES getValueCountFromSensorType(static_cast(PCONFIG(P025_SENSOR_TYPE_INDEX))) diff --git a/src/src/PluginStructs/P036_data_struct.h b/src/src/PluginStructs/P036_data_struct.h index 0880feaf76..af774636c9 100644 --- a/src/src/PluginStructs/P036_data_struct.h +++ b/src/src/PluginStructs/P036_data_struct.h @@ -203,9 +203,9 @@ typedef struct { uint16_t LastWidth = 0; // width of last line in pix uint16_t Width = 0; // width in pix uint8_t SLidx = 0; // index to DisplayLinesV1 - uint8_t reserved22; // Fillers added to achieve better instance/memory alignment (multiple of 8) - uint8_t reserved23; - uint8_t reserved24; + uint8_t reserved22{}; // Fillers added to achieve better instance/memory alignment (multiple of 8) + uint8_t reserved23{}; + uint8_t reserved24{}; } tScrollLine; typedef struct { @@ -216,8 +216,8 @@ typedef struct { uint16_t TickerAvgPixPerChar = 0; // max of average pixel per character or pix change per scroll time (100ms) int16_t MaxPixLen = 0; // Max pix length to display (display width + 2*TickerAvgPixPerChar) # ifdef ESP8266 // Helpful on ESP8266 only, it seems - uint8_t reserved15; // Fillers added to achieve better instance/memory alignment (multiple of 8) - uint8_t reserved16; + uint8_t reserved15{}; // Fillers added to achieve better instance/memory alignment (multiple of 8) + uint8_t reserved16{}; # endif // ifdef ESP8266 } tTicker; diff --git a/src/src/PluginStructs/P145_data_struct.cpp b/src/src/PluginStructs/P145_data_struct.cpp index 0146072485..649f6673bf 100644 --- a/src/src/PluginStructs/P145_data_struct.cpp +++ b/src/src/PluginStructs/P145_data_struct.cpp @@ -282,6 +282,7 @@ float P145_data_struct::getRZero(float rSensor) const break; case p145AlgNone: newValue = rzero; + break; default: if (sensordef.cleanRatio > 0.0f) { diff --git a/src/src/WebServer/Chart_JS.cpp b/src/src/WebServer/Chart_JS.cpp index b0aae8c11b..d01917fa65 100644 --- a/src/src/WebServer/Chart_JS.cpp +++ b/src/src/WebServer/Chart_JS.cpp @@ -11,9 +11,9 @@ void add_ChartJS_array(int valueCount, { for (int i = 0; i < valueCount; ++i) { if (i != 0) { - addHtml(','); + addHtml(',', '\n'); } - addHtml(wrapIfContains(array[i], ' ', '"')); + addHtml(to_json_value(array[i])); } } @@ -23,7 +23,7 @@ void add_ChartJS_array(int valueCount, { for (int i = 0; i < valueCount; ++i) { if (i != 0) { - addHtml(','); + addHtml(',', '\n'); } addHtmlFloat(array[i], nrDecimals); } @@ -34,7 +34,7 @@ void add_ChartJS_array(int valueCount, { for (int i = 0; i < valueCount; ++i) { if (i != 0) { - addHtml(','); + addHtml(',', '\n'); } addHtmlInt(array[i]); } @@ -47,9 +47,10 @@ void add_ChartJS_chart_header( int width, int height, const String & options, - size_t nrSamples) + size_t nrSamples, + bool onlyJSON) { - add_ChartJS_chart_header(chartType, String(id), chartTitle, width, height, options, nrSamples); + add_ChartJS_chart_header(chartType, String(id), chartTitle, width, height, options, nrSamples, onlyJSON); } void add_ChartJS_chart_header( @@ -59,67 +60,84 @@ void add_ChartJS_chart_header( int width, int height, const String & options, + size_t nrSamples, + bool onlyJSON) +{ + if (!onlyJSON) { + addHtml(F("")); + const char *id_c_str = id.c_str(); + addHtml(strformat( + F("")); +void add_ChartJS_chart_footer(bool onlyJSON) { + addHtml(F("]}}")); + + if (!onlyJSON) { + addHtml(F(");")); + } } #endif // if FEATURE_CHART_JS diff --git a/src/src/WebServer/Chart_JS.h b/src/src/WebServer/Chart_JS.h index 99ce8c668d..adcf2818f6 100644 --- a/src/src/WebServer/Chart_JS.h +++ b/src/src/WebServer/Chart_JS.h @@ -28,8 +28,9 @@ void add_ChartJS_chart_header( const ChartJS_title & chartTitle, int width, int height, - const String & options = EMPTY_STRING, - size_t nrSamples = 0); + const String & options = EMPTY_STRING, + size_t nrSamples = 0, + bool onlyJSON = false); void add_ChartJS_chart_header( const __FlashStringHelper *chartType, @@ -37,9 +38,15 @@ void add_ChartJS_chart_header( const ChartJS_title & chartTitle, int width, int height, - const String & options = EMPTY_STRING, - size_t nrSamples = 0); + const String & options = EMPTY_STRING, + size_t nrSamples = 0, + bool onlyJSON = false); +void add_ChartJS_chart_JSON_header( + const __FlashStringHelper *chartType, + const ChartJS_title & chartTitle, + const String & options, + size_t nrSamples); void add_ChartJS_chart_labels( int valueCount, @@ -50,7 +57,9 @@ void add_ChartJS_chart_labels( const String labels[]); -void add_ChartJS_scatter_data_point(float x, float y, int nrDecimals); +void add_ChartJS_scatter_data_point(float x, + float y, + int nrDecimals); void add_ChartJS_dataset( const ChartJS_dataset_config& config, @@ -64,7 +73,7 @@ void add_ChartJS_dataset_header(const ChartJS_dataset_config& config); void add_ChartJS_dataset_footer(const String& options = EMPTY_STRING); -void add_ChartJS_chart_footer(); +void add_ChartJS_chart_footer(bool onlyJSON = false); #endif // if FEATURE_CHART_JS #endif // ifndef WEBSERVER_CHART_JS_H diff --git a/src/src/WebServer/Chart_JS_scale.cpp b/src/src/WebServer/Chart_JS_scale.cpp index 364a929499..ccb5254ab9 100644 --- a/src/src/WebServer/Chart_JS_scale.cpp +++ b/src/src/WebServer/Chart_JS_scale.cpp @@ -57,10 +57,10 @@ String ChartJS_options_scale::toString() const String ticksStr; if (tickCount > 0) { - ticksStr = strformat(F(",ticks:{count:%d}"), tickCount); + ticksStr = strformat(F(",\"ticks\":{\"count\":%d}"), tickCount); } return strformat( - F("\"%s\":{display:%s,type:\"%s\",position:\"%s\",title:%s,weight:%d%s}"), + F("\"%s\":{\"display\":%s,\"type\":\"%s\",\"position\":\"%s\",\"title\":%s,\"weight\":%d%s}"), axisID.c_str(), displayStr.c_str(), typeStr.c_str(), @@ -114,7 +114,7 @@ String ChartJS_options_scales::toString() const { if (_scales.empty()) { return EMPTY_STRING; } - String res = F("scales:{"); + String res = F("\"scales\":{"); bool first = true; for (auto it = _scales.begin(); it != _scales.end(); ++it) { @@ -125,11 +125,11 @@ String ChartJS_options_scales::toString() const res += ','; } first = false; + res += '\n'; res += scale_str; } } res += '}'; - res += ','; return res; } diff --git a/src/src/WebServer/Chart_JS_title.cpp b/src/src/WebServer/Chart_JS_title.cpp index b2ed0a3bc1..14313d1355 100644 --- a/src/src/WebServer/Chart_JS_title.cpp +++ b/src/src/WebServer/Chart_JS_title.cpp @@ -18,7 +18,7 @@ ChartJS_title::ChartJS_title(const String& titleText, Align alignment) String ChartJS_title::toString() const { if (text.isEmpty()) { - return F("{display: false}"); + return F("{\"display\": false}"); } const String alignStr = @@ -28,11 +28,11 @@ String ChartJS_title::toString() const { String colorStr; if (!color.isEmpty()) { - colorStr = strformat(F(",color:\"%s\""), color.c_str()); + colorStr = strformat(F(",\"color\":\"%s\""), color.c_str()); } return strformat( - F("{display: true,align:\"%s\",text:\"%s\"%s}"), + F("{\"display\": true,\"align\":\"%s\",\"text\":\"%s\"%s}"), alignStr.c_str(), text.c_str(), colorStr.c_str()); diff --git a/src/src/WebServer/JSON.cpp b/src/src/WebServer/JSON.cpp index 8c1070667a..c233e7be54 100644 --- a/src/src/WebServer/JSON.cpp +++ b/src/src/WebServer/JSON.cpp @@ -121,6 +121,9 @@ void handle_json() #if FEATURE_ESPEASY_P2P bool showNodes = true; #endif + #if FEATURE_PLUGIN_STATS + bool showPluginStats = isFormItemChecked(F("showpluginstats")); + #endif if (equals(webArg(F("view")), F("sensorupdate"))) { showSystem = false; @@ -133,6 +136,9 @@ void handle_json() #if FEATURE_ESPEASY_P2P showNodes = false; #endif + #if FEATURE_PLUGIN_STATS + showPluginStats = false; + #endif } TXBuffer.startJsonStream(); @@ -338,7 +344,21 @@ void handle_json() if (rssi < 0) { stream_next_json_object_value(F("rssi"), rssi); } + if (it->second.build >= 20107) { + stream_next_json_object_value(F("load"), toString(it->second.getLoad(), 2)); + if (it->second.webgui_portnumber != 80) { + stream_next_json_object_value(F("webport"), it->second.webgui_portnumber); + } + } stream_next_json_object_value(F("ip"), formatIP(it->second.IP())); +#if FEATURE_USE_IPV6 + if (it->second.hasIPv6_mac_based_link_local) { + stream_next_json_object_value(F("ipv6local"), formatIP(it->second.IPv6_link_local(true))); + } + if (it->second.hasIPv6_mac_based_link_global) { + stream_next_json_object_value(F("ipv6global"), formatIP(it->second.IPv6_global())); + } +#endif stream_last_json_object_value(F("age"), it->second.getAge()); } // if node info exists } // for loop @@ -424,6 +444,18 @@ void handle_json() addHtml(F("],\n")); } +#if FEATURE_PLUGIN_STATS && FEATURE_CHART_JS + if (showPluginStats && Device[DeviceIndex].PluginStats) { + PluginTaskData_base *taskData = getPluginTaskDataBaseClassOnly(TaskIndex); + if (taskData != nullptr && taskData->nrSamplesPresent() > 0) { + addHtml(F("\"PluginStats\":\n")); + taskData->plot_ChartJS(true); + stream_comma_newline(); + } + } +#endif + + if (showSpecificTask) { stream_next_json_object_value(F("TTL"), ttl_json * 1000); } diff --git a/src/src/WebServer/RootPage.cpp b/src/src/WebServer/RootPage.cpp index 4c0dcba44f..053c0a3c46 100644 --- a/src/src/WebServer/RootPage.cpp +++ b/src/src/WebServer/RootPage.cpp @@ -198,7 +198,7 @@ void handle_root() { addRowLabelValue(LabelType::IP_ADDRESS); #if FEATURE_USE_IPV6 addRowLabelValue(LabelType::IP6_LOCAL); - addRowLabelValue(LabelType::IP6_GLOBAL); + // Do not show global IPv6 on the root page #endif addRowLabel(LabelType::WIFI_RSSI); addHtml(strformat( @@ -213,8 +213,8 @@ void handle_root() { addRowLabelValue(LabelType::ETH_SPEED_STATE); addRowLabelValue(LabelType::ETH_IP_ADDRESS); #if FEATURE_USE_IPV6 - addRowLabelValue(LabelType::IP6_LOCAL); - addRowLabelValue(LabelType::IP6_GLOBAL); + addRowLabelValue(LabelType::ETH_IP6_LOCAL); + // Do not show global IPv6 on the root page #endif } # endif // if FEATURE_ETHERNET @@ -342,26 +342,46 @@ void handle_root() { #endif ) { - html_add_wide_button_prefix(); - - addHtml(F("http://")); IPAddress ip = it->second.IP(); - #if FEATURE_USE_IPV6 + const uint16_t port = it->second.webgui_portnumber; + +#if FEATURE_USE_IPV6 bool isIPv6 = false; -// if (!it->second.hasIPv4) { - if (it->second.hasIPv6_mac_based_link_local) { - ip = it->second.IPv6_link_local(); - if (ip.zone() != 0) { - // Clear the zone as it is of no use here. - ip = IPAddress(IPv6, &ip[0], 0); - } - - isIPv6 = true; - } else if (it->second.hasIPv6_mac_based_link_global) { - ip = it->second.IPv6_global(); - isIPv6 = true; + if (it->second.hasIPv6_mac_based_link_local) { + ip = it->second.IPv6_link_local(true); + isIPv6 = true; + } else if (it->second.hasIPv6_mac_based_link_global) { + ip = it->second.IPv6_global(); + isIPv6 = true; + } + if (it->second.hasIPv4 && it->second.hasIPv6()) { + // Add 2 buttons for IPv4 and IPv6 address + html_add_wide_button_prefix(); + addHtml(F("http://")); + addHtml(wrap_String(formatIP(ip), '[', ']')); + if ((port != 0) && (port != 80)) { + addHtml(':'); + addHtmlInt(port); } - // } + addHtml('\'', '>'); + addHtml(formatIP(ip)); + addHtml(F("")); + + // Now prepare 2nd button prefix + addHtml(F("
")); + html_add_wide_button_prefix(); + ip = it->second.IP(); + isIPv6 = false; + } else { + // Add single wide button + html_add_wide_button_prefix(); + } +#else + html_add_wide_button_prefix(); +#endif + addHtml(F("http://")); +#if FEATURE_USE_IPV6 + if (isIPv6) { addHtml(wrap_String(formatIP(ip), '[', ']')); } else { @@ -371,8 +391,6 @@ void handle_root() { addHtml(formatIP(ip)); #endif - uint16_t port = it->second.webgui_portnumber; - if ((port != 0) && (port != 80)) { addHtml(':'); addHtmlInt(port); diff --git a/src/src/WebServer/SysInfoPage.cpp b/src/src/WebServer/SysInfoPage.cpp index cee763622c..fc8cba04c6 100644 --- a/src/src/WebServer/SysInfoPage.cpp +++ b/src/src/WebServer/SysInfoPage.cpp @@ -151,6 +151,9 @@ void handle_sysinfo_json() { json_prop(F("ethspeed"), getValue(LabelType::ETH_SPEED)); json_prop(F("ethstate"), getValue(LabelType::ETH_STATE)); json_prop(F("ethspeedstate"), getValue(LabelType::ETH_SPEED_STATE)); +#if FEATURE_USE_IPV6 + json_prop(F("ethipv6local"), getValue(LabelType::ETH_IP6_LOCAL)); +#endif json_close(); # endif // if FEATURE_ETHERNET diff --git a/src/src/WebServer/SysVarPage.cpp b/src/src/WebServer/SysVarPage.cpp index 0dece9c88c..6bc69bfd4c 100644 --- a/src/src/WebServer/SysVarPage.cpp +++ b/src/src/WebServer/SysVarPage.cpp @@ -48,6 +48,19 @@ void handle_sysvars() { html_table_header(F("Normal")); html_table_header(F("URL encoded"), F("ESPEasy_System_Variables"), 0); + addTableSeparator(F("Custom Variables"), 3, 3); + + if (customFloatVar.empty()) { + html_TR_TD(); + addHtml(F("No variables set")); + html_TD(); + html_TD(); + } else { + for (auto it = customFloatVar.begin(); it != customFloatVar.end(); ++it) { + addSysVar_html(strformat(F("%%v%u%%"), it->first), false); + } + } + addTableSeparator(F("Constants"), 3, 3); { const SystemVariables::Enum vars[] = { @@ -64,9 +77,7 @@ void handle_sysvars() { { const SystemVariables::Enum vars[] = { SystemVariables::MAC, -# if defined(ESP8266) SystemVariables::MAC_INT, -# endif // if defined(ESP8266) SystemVariables::IP, SystemVariables::IP4, SystemVariables::SUBNET, @@ -74,6 +85,9 @@ void handle_sysvars() { SystemVariables::DNS, SystemVariables::DNS_1, SystemVariables::DNS_2, +#if FEATURE_USE_IPV6 + SystemVariables::IP6_LOCAL, +#endif SystemVariables::RSSI, SystemVariables::SSID, SystemVariables::BSSID, @@ -248,21 +262,6 @@ void handle_sysvars() { addSysVar_enum_html(vars, NR_ELEMENTS(vars)); } - addTableSeparator(F("Custom Variables"), 3, 3); - - bool customVariablesAdded = false; - - for (auto it = customFloatVar.begin(); it != customFloatVar.end(); ++it) { - addSysVar_html(strformat(F("%%v%u%%"), it->first), false); - customVariablesAdded = true; - } - - if (!customVariablesAdded) { - html_TR_TD(); - addHtml(F("No variables set")); - html_TD(); - html_TD(); - } # ifndef BUILD_NO_SPECIAL_CHARACTERS_STRINGCONVERTER { addTableSeparator(F("Special Characters"), 3, 2);