diff --git a/docs/source/Plugin/P007.rst b/docs/source/Plugin/P007.rst index 1370c279d..5f14b0366 100644 --- a/docs/source/Plugin/P007.rst +++ b/docs/source/Plugin/P007.rst @@ -24,7 +24,7 @@ Used libraries: |P007_usedlibraries| Introduction ------------ -The PCF8591 is an Analog to Digital converter, connected via an I2C bus. The plugin supports to read from 1 up to 4 input values. If desired, multiple Tasks *can* be defined, addressing other, or duplicate, inputs. +The PCF8591 is an Analog to Digital and Digital to Analog converter, connected via an I2C bus. The plugin supports to read from 1 up to 4 input values, and has a single analog output that can be changed by a command. If desired, multiple Tasks *can* be defined, addressing other, or duplicate, inputs. Supported hardware ------------------ @@ -54,6 +54,8 @@ I2C Options The available settings here depend on the build used. At least the **Force Slow I2C speed** option is available, but selections for the I2C Multiplexer can also be shown. For details see the :ref:`Hardware_page` +As the chip is specified to only work correctly up to 100 kHz, the **Force Slow I2C speed** checkbox should normally be *enabled*. + * **I2C Address**: The address the device is using. There are a number of addresses the module can use, and they can usually be set at the board using jumper pins. The available options: @@ -88,6 +90,34 @@ When selecting f.e. the Quad option and saving the settings, the number of outpu For any 'excess' values, events *will* be generated! +Hardware configuration +^^^^^^^^^^^^^^^^^^^^^^ + +* **Input mode** The chip supports several input modes, the desired mode can be selected here. + +Available options are: + +.. image:: P007_InputModeOptions.png + :alt: Input mode options + +* *4 single-ended inputs* De standard configuration is to have 4 inputs that are measured with regards to GND. +* *3 differential inputs, A0/A1/A2 differential with AIN3* AIN0 .. AIN2 are measured differential to AIN3, resulting in 3 available values. +* *2 single-ended, A0, A1, AIN2/AIN3 differential -> A2* AIN0 and AIN1 are measured with regards to GND into the first 2 values, the third value is measured differentially from AIN2 and AIN3. +* *AIN0/AIN1 differential -> A0, AIN2/AIN3 differential -> A1* 2 values are measured, the first differentially from AIN0 and AIN1, and the second differentially from AIN2 and AIN3. + +When configuring a differential option from above list, the 4th and 3rd values are undefined when not used, but can still be read. The results are then undefined. + +The chip documentation describes it like this: + +.. image:: P007_InputModeSchematics.png + :alt: Chip documentation for Input mode + +* **Enable Analog output (AOUT)** Enabling the Analog output has 2 effects: + +1) The AOUT pin can be set to a linear value in the range 0..255 between 0V and Vref (Vref can sometimes be set using a potentiometer on the board) using the ``analogout`` command (see below). + +2) The internal oscillator will be enabled continuesly, causing higher power usage, but also improved measurements when reading an analog input as it avoids the startup time of the oscillator that can cause inaccurate readings. + Data Acquisition ^^^^^^^^^^^^^^^^ @@ -100,10 +130,10 @@ Values The name for the value(s) is initially set to a default name, but can be changed if desired. Also, a formula can be entered to re-calculate a value before display/sending to a controller, and the number of decimals can be changed, for a Temperature, usually 1 decimal is enough to be displayed (value will be rounded). -.. Commands available -.. ^^^^^^^^^^^^^^^^^^ +Commands available +^^^^^^^^^^^^^^^^^^ -.. .. include:: P007_commands.repl +.. include:: P007_commands.repl .. Events .. ~~~~~~ @@ -116,6 +146,9 @@ Change log .. versionchanged:: 2.0 ... + |added| + 2022-05-08 Selection of Input mode, Enable Analog output (AOUT) and ``analogout`` command. + |added| 2021-08-06 Selection of 1 to 4 input values to be read. diff --git a/docs/source/Plugin/P007_DeviceConfiguration.png b/docs/source/Plugin/P007_DeviceConfiguration.png index 7f221b7a0..a69af4fe1 100644 Binary files a/docs/source/Plugin/P007_DeviceConfiguration.png and b/docs/source/Plugin/P007_DeviceConfiguration.png differ diff --git a/docs/source/Plugin/P007_InputModeOptions.png b/docs/source/Plugin/P007_InputModeOptions.png new file mode 100644 index 000000000..117cf89be Binary files /dev/null and b/docs/source/Plugin/P007_InputModeOptions.png differ diff --git a/docs/source/Plugin/P007_InputModeSchematics.png b/docs/source/Plugin/P007_InputModeSchematics.png new file mode 100644 index 000000000..e046f5593 Binary files /dev/null and b/docs/source/Plugin/P007_InputModeSchematics.png differ diff --git a/docs/source/Plugin/P007_commands.repl b/docs/source/Plugin/P007_commands.repl new file mode 100644 index 000000000..b770d86de --- /dev/null +++ b/docs/source/Plugin/P007_commands.repl @@ -0,0 +1,14 @@ +.. csv-table:: + :header: "Command", "Extra information" + :widths: 20, 30 + + " + ``analogout,`` + + Value: 0..255 + + "," + The value is linearly scaled from 0V to Vref. Vref is often the same as VCC for the chip, but can sometimes be configured using a potentiometer on the board. + + Only available if **Enable Analog output (AOUT)** is enabled. + " diff --git a/docs/source/Plugin/P093.rst b/docs/source/Plugin/P093.rst index 30c49528d..c20ecad4f 100644 --- a/docs/source/Plugin/P093.rst +++ b/docs/source/Plugin/P093.rst @@ -53,8 +53,6 @@ Parts required to make a CN105 female connector * `PAP-05V-S `_, * `SPHD-002T-P0.5 `_, -One can also get `premade pigtails `_. - Example using D1 mini PRO ~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -89,7 +87,23 @@ Commands Example ------- -A full working example using openHAB can be found `here `_. +There are several ways how to control AC unit using ESP Easy. + +**Using HTTP:** + +Generally commands are send via http using syntax ``http:///control?cmd=`` where ```` is the IP of your ESP Easy device, for example ``192.168.0.100``: + +.. include:: P093_examples_http.repl + +**Using MQTT:** + +Commands are send via MQTT using syntax ``/cmd`` with payload: ````. For example, if your `unit name `_ is ``MyESPEasy``, one would send the below payload to topic ``MyESPEasy/cmd``: + +.. include:: P093_examples_mqtt.repl + +Please check `here `_ for more details on how to send commands using ESP Easy. + +Please `check `_ for an example integration with openHAB. Special thanks -------------- diff --git a/docs/source/Plugin/P093_commands.repl b/docs/source/Plugin/P093_commands.repl index 3901f0e4d..4f7a036f0 100644 --- a/docs/source/Plugin/P093_commands.repl +++ b/docs/source/Plugin/P093_commands.repl @@ -1,5 +1,5 @@ .. csv-table:: - :header: "Command", "Extra information" + :header: "Command", "Description" :widths: 20, 40 " diff --git a/docs/source/Plugin/P093_examples_http.repl b/docs/source/Plugin/P093_examples_http.repl new file mode 100644 index 000000000..791499f2d --- /dev/null +++ b/docs/source/Plugin/P093_examples_http.repl @@ -0,0 +1,19 @@ +.. csv-table:: + :header: "Command", "Description" + :widths: 20, 40 + + " + ``http://192.168.0.100/control?cmd=MitsubishiHP,power,ON`` + "," + Turn on AC + " + " + ``http://192.168.0.100/control?cmd=MitsubishiHP,temperature,23`` + "," + Set target temperature to 23 + " + " + ``http://192.168.0.100/control?cmd=MitsubishiHP,fan,AUTO`` + "," + Set fan mode to ``AUTO`` + " diff --git a/docs/source/Plugin/P093_examples_mqtt.repl b/docs/source/Plugin/P093_examples_mqtt.repl new file mode 100644 index 000000000..26c3c2a61 --- /dev/null +++ b/docs/source/Plugin/P093_examples_mqtt.repl @@ -0,0 +1,19 @@ +.. csv-table:: + :header: "Payload", "Description" + :widths: 20, 40 + + " + ``MitsubishiHP,power,ON`` + "," + Turn on AC + " + " + ``MitsubishiHP,temperature,23`` + "," + Set target temperature to 23 + " + " + ``MitsubishiHP,fan,AUTO`` + "," + Set fan mode to ``AUTO`` + " diff --git a/docs/source/Plugin/P132.rst b/docs/source/Plugin/P132.rst new file mode 100644 index 000000000..655990d52 --- /dev/null +++ b/docs/source/Plugin/P132.rst @@ -0,0 +1,127 @@ +.. include:: ../Plugin/_plugin_substitutions_p13x.repl +.. _P132_page: + +|P132_typename| +================================================== + +|P132_shortinfo| + +Plugin details +-------------- + +Type: |P132_type| + +Name: |P132_name| + +Status: |P132_status| + +GitHub: |P132_github|_ + +Maintainer: |P132_maintainer| + +Used libraries: |P132_usedlibraries| + +Description +----------- + +The INA3221 Voltage/Current sensor can be used to measure voltage and/or current for DC input, up to 26V. It has 3 separate channels available. + +It can be used to replace the :ref:`p027_page`, except that the I2C protocol isn't directly compatible, so it is not a drop-in replacement. + +Configuration +------------- + +.. image:: P132_DeviceConfiguration.png + :alt: Device Configuration + +**Name** A unique name should be entered here. + +**Enabled** The device can be disabled or enabled. When not enabled the device should not use any resources. + +I2C Options +^^^^^^^^^^^^ + +The available settings here depend on the build used. At least the **Force Slow I2C speed** option is available, but selections for the I2C Multiplexer can also be shown. For details see the :ref:`Hardware_page` + +**I2C Address**: The address the sensor is using. The different addresses can be selected by connecting the appropriate signal to ``A0``. Often also documented on the board. + +.. image:: P132_I2CAddressOptions.png + :alt: Available I2C address options + +Device Settings +^^^^^^^^^^^^^^^ + +* **Power value 1..4**: As a plugin only has 4 available output values and the sensor has 6 values available, here we have to select what output receives what measured value. + +Available options are: + +.. image:: P132_PowerValueOptions.png + :alt: Available Power Value options + +* *Current channel 1..3*: Measure the current from channel 1..3. +* *Voltage channel 1..3*: Measure the voltage from channel 1..3. + +NB: To get all measured values, an extra Task can be configured to provide the measurements not handled in the current task, or you could f.e. configure separate tasks for Voltage and Current measurements. These tasks shouldn't interfere, assuming both get the same configuration settings for **Shunt resistor**, **Averaging samples** and **Conversion rate Voltage** / **Conversion rate Current**. + +Hardware +^^^^^^^^ + +* **Shunt resistor**: As there are different hardware configurations available for the board, using different shunt resistor values, here you can select the value that is present on the board used. + +.. image:: P132_ShuntResistorOptions.png + :alt: Available options for shunt resistor values + +Measurement +^^^^^^^^^^^ + +* **Averaging samples**: To increase the accuracy of measurements, the chip allows to take the average value for a set of samples. The desired number of samples can be selected in this setting, default: 1. + +.. image:: P132_AveragingSamplesOptions.png + :alt: Averaging samples options + +When combining a higher number of samples with a longer **Conversion rate**, taking all possible measurements will require more time, affecting the **Interval** that would be feasible for a reliable measurement. The worst-case scenarios (maximum **Conversion rate** settings) have been calculated, and are shown as a note below this setting. + +* **Conversion rate Voltage/Current**: To change the accuracy of measurements, a different conversion rate can be selected. Lowering the conversion rate will decrease the accuracy, and allow a higher sampling frequency, but as the measurements are read at a smallest **Interval** of 1 second, there isn't much use in lowering the conversion rate. When increasing the conversion rate, accuracy will increase, but, also depending on the **Averaging samples** configured, increases the time it takes to complete all measurements. (Calculation formula below). + +There are separate **Conversion rate** settings for the **Voltage** and **Current** measurements, as that's available in the chip. + +.. image:: P132_ConversionRateOptions.png + :alt: Conversion rate options + +To calculate the minimally required **Interval** setting for the task, this formula can be used: + + | (3 * Averaging samples * Conversion rate Voltage) + (3 * Averaging samples * Conversion rate Current), and round that up to a seconds value. + + | Example: (Worst case) 3 * 1024 * 0.008244 + 3 * 1024 * 0.008244 = 50.65 seconds => ~51 minimum Interval. + + | Example: (Default case) 3 * 1 * 0.00144 + 3 * 1 * 0.00144 = 0.008 seconds => 1 minimum Interval. + +Data Acquisition +^^^^^^^^^^^^^^^^ + +The Data Acquisition, Send to Controller and Interval settings are standard available configuration items. Send to Controller only when one or more Controllers are configured. + +Values +^^^^^^ + +The Values available for this sensor, are named ``Value1`` through ``Value4``, and can be adjusted as desired. The Formula field can be used to recalculate the shown results. + +.. Commands available +.. ^^^^^^^^^^^^^^^^^^ + +.. .. include:: P132_commands.repl + +.. Events +.. ~~~~~~ + +.. .. include:: P132_events.repl + +Change log +---------- + +.. versionchanged:: 2.0 + ... + + |added| + 2022-04-23 Initial release version. + diff --git a/docs/source/Plugin/P132_AveragingSamplesOptions.png b/docs/source/Plugin/P132_AveragingSamplesOptions.png new file mode 100644 index 000000000..e52da84b0 Binary files /dev/null and b/docs/source/Plugin/P132_AveragingSamplesOptions.png differ diff --git a/docs/source/Plugin/P132_ConversionRateOptions.png b/docs/source/Plugin/P132_ConversionRateOptions.png new file mode 100644 index 000000000..19c4c45b7 Binary files /dev/null and b/docs/source/Plugin/P132_ConversionRateOptions.png differ diff --git a/docs/source/Plugin/P132_DeviceConfiguration.png b/docs/source/Plugin/P132_DeviceConfiguration.png new file mode 100644 index 000000000..cda14124f Binary files /dev/null and b/docs/source/Plugin/P132_DeviceConfiguration.png differ diff --git a/docs/source/Plugin/P132_I2CAddressOptions.png b/docs/source/Plugin/P132_I2CAddressOptions.png new file mode 100644 index 000000000..11ebc6d44 Binary files /dev/null and b/docs/source/Plugin/P132_I2CAddressOptions.png differ diff --git a/docs/source/Plugin/P132_PowerValueOptions.png b/docs/source/Plugin/P132_PowerValueOptions.png new file mode 100644 index 000000000..7b831bb66 Binary files /dev/null and b/docs/source/Plugin/P132_PowerValueOptions.png differ diff --git a/docs/source/Plugin/P132_ShuntResistorOptions.png b/docs/source/Plugin/P132_ShuntResistorOptions.png new file mode 100644 index 000000000..2e65be415 Binary files /dev/null and b/docs/source/Plugin/P132_ShuntResistorOptions.png differ diff --git a/docs/source/Plugin/_Plugin.rst b/docs/source/Plugin/_Plugin.rst index 4fec8d521..ac7c3f30f 100644 --- a/docs/source/Plugin/_Plugin.rst +++ b/docs/source/Plugin/_Plugin.rst @@ -149,7 +149,8 @@ There are different released versions of ESP Easy: ":ref:`P124_page`","|P124_status|","P124" ":ref:`P125_page`","|P125_status|","P125" ":ref:`P126_page`","|P126_status|","P126" - ":ref:`P127_page`","|P127_status|","P125" + ":ref:`P127_page`","|P127_status|","P127" + ":ref:`P132_page`","|P132_status|","P132" Internal GPIO handling diff --git a/docs/source/Plugin/_plugin_categories.repl b/docs/source/Plugin/_plugin_categories.repl index 43ddeeb55..f2995882d 100644 --- a/docs/source/Plugin/_plugin_categories.repl +++ b/docs/source/Plugin/_plugin_categories.repl @@ -5,7 +5,7 @@ .. |Plugin_Distance| replace:: :ref:`P110_page`, :ref:`P113_page` .. |Plugin_Dust| replace:: :ref:`P018_page`, :ref:`P053_page`, :ref:`P056_page` .. |Plugin_Energy_AC| replace:: :ref:`P076_page`, :ref:`P077_page`, :ref:`P078_page`, :ref:`P102_page`, :ref:`P108_page` -.. |Plugin_Energy_DC| replace:: :ref:`P027_page`, :ref:`P085_page`, :ref:`P115_page` +.. |Plugin_Energy_DC| replace:: :ref:`P027_page`, :ref:`P085_page`, :ref:`P115_page`, :ref:`P132_page` .. |Plugin_Energy_Heat| replace:: :ref:`P088_page`, :ref:`P093_page` .. |Plugin_Environment| replace:: :ref:`P004_page`, :ref:`P005_page`, :ref:`P006_page`, :ref:`P014_page`, :ref:`P024_page`, :ref:`P028_page`, :ref:`P030_page`, :ref:`P031_page`, :ref:`P032_page`, :ref:`P034_page`, :ref:`P039_page`, :ref:`P047_page`, :ref:`P051_page`, :ref:`P068_page`, :ref:`P069_page`, :ref:`P072_page`, :ref:`P103_page`, :ref:`P104_page`, :ref:`P105_page`, :ref:`P106_page` .. |Plugin_Extra_IO| replace:: :ref:`P011_page`, :ref:`P022_page` diff --git a/docs/source/Plugin/_plugin_substitutions.repl b/docs/source/Plugin/_plugin_substitutions.repl index 9f0022404..56e782b5b 100644 --- a/docs/source/Plugin/_plugin_substitutions.repl +++ b/docs/source/Plugin/_plugin_substitutions.repl @@ -11,3 +11,4 @@ .. include:: ../Plugin/_plugin_substitutions_p10x.repl .. include:: ../Plugin/_plugin_substitutions_p11x.repl .. include:: ../Plugin/_plugin_substitutions_p12x.repl +.. include:: ../Plugin/_plugin_substitutions_p13x.repl diff --git a/docs/source/Plugin/_plugin_substitutions_p13x.repl b/docs/source/Plugin/_plugin_substitutions_p13x.repl new file mode 100644 index 000000000..0576fa019 --- /dev/null +++ b/docs/source/Plugin/_plugin_substitutions_p13x.repl @@ -0,0 +1,12 @@ +.. |P132_name| replace:: :cyan:`INA3221` +.. |P132_type| replace:: :cyan:`Energy (DC)` +.. |P132_typename| replace:: :cyan:`Energy (DC) - INA3221` +.. |P132_porttype| replace:: `.` +.. |P132_status| replace:: :yellow:`ENERGY` +.. |P132_github| replace:: P132_INA3221.ino +.. _P132_github: https://github.com/letscontrolit/ESPEasy/blob/mega/src/_P132_INA3221.ino +.. |P132_usedby| replace:: `.` +.. |P132_shortinfo| replace:: `3-channel I2C DC Voltage/Current sensor` +.. |P132_maintainer| replace:: `tonhuisman` +.. |P132_compileinfo| replace:: `.` +.. |P132_usedlibraries| replace:: `.` diff --git a/docs/source/Reference/SystemVariable.rst b/docs/source/Reference/SystemVariable.rst index b61bdd59f..a3b134c95 100644 --- a/docs/source/Reference/SystemVariable.rst +++ b/docs/source/Reference/SystemVariable.rst @@ -46,17 +46,41 @@ More uses of these system variables can be seen in the rules section and formula - Current time if NTP is enabled (hh:mm:ss, hh:mm prior to v2.0). - * - ``%systm_hm%`` - - 01:23 + - 1:23 - Current time if NTP is enabled (hh:mm "old behavior"). - + * - ``%systm_hm_0%`` + - 01:23 + - Current time if NTP is enabled (0-prefixed if hour < 10). + - + * - ``%systm_hm_sp%`` + - ` 1:23` + - Current time if NTP is enabled (space-prefixed if hour < 10). + - * - ``%systime_am%`` - 1:23:54 AM - Current AM/PM time if NTP is enabled (hh:mm:ss xM). - + * - ``%systime_am_0%`` + - 01:23:54 AM + - Current AM/PM time if NTP is enabled (0-prefixed if hour < 10). + - + * - ``%systime_am_sp%`` + - ` 1:23:54 AM` + - Current AM/PM time if NTP is enabled (space-prefixed if hour < 10). + - * - ``%systm_hm_am%`` - 1:23 AM - Current AM/PM time if NTP is enabled (hh:mm:ss xM). - + * - ``%systm_hm_am_0%`` + - 01:23 AM + - Current AM/PM time if NTP is enabled (0-prefixed if hour < 10). + - + * - ``%systm_hm_am_sp%`` + - ` 1:23 AM` + - Current AM/PM time if NTP is enabled (space-prefixed if hour < 10). + - * - ``%lcltime%`` - 2020-03-16 01:23:54 - Current date/time if NTP is enabled (YYYY-MM-DD hh:mm:ss). diff --git a/platformio_special_envs.ini b/platformio_special_envs.ini index 0462399c7..9b109ff72 100644 --- a/platformio_special_envs.ini +++ b/platformio_special_envs.ini @@ -74,34 +74,42 @@ lib_ignore = ${regular_platform.lib_ignore} extra_scripts = ${extra_scripts_esp8266.extra_scripts} -[env:spec_debug_custom_ESP32_4M316k] +[env:spec_debug_custom_ESP32_16M8M] extends = esp32_common build_type = ${debug_pio.build_type} check_tool = ${debug_pio.check_tool} check_flags = ${debug_pio.check_flags} platform = ${esp32_common.platform} build_flags = ${esp32_common.build_flags} ${debug_pio.build_flags} -DPLUGIN_BUILD_CUSTOM -board = esp32dev +board = esp32_16M8M +board_upload.maximum_size = 4194304 extra_scripts = ${esp32_common.extra_scripts} pre:tools/pio/pre_custom_esp32.py [env:spec_debug_max_ESP32_16M8M] -extends = esp32_common +extends = esp32_base build_type = ${debug_pio.build_type} check_tool = ${debug_pio.check_tool} check_flags = ${debug_pio.check_flags} lib_ignore = ${esp32_always.lib_ignore} ESP32_ping board_upload.maximum_size = 4194304 -build_flags = ${esp32_common.build_flags} +build_flags = ${esp32_base.build_flags} ${debug_pio.build_flags} + -DUSE_LITTLEFS -DFEATURE_ARDUINO_OTA -DPLUGIN_BUILD_MAX_ESP32 -DPLUGIN_BUILD_IR_EXTENDED +lib_deps = ${esp32_base.lib_deps} + LittleFS +board_build.filesystem = littlefs + ; TODO: To enable PS-RAM Support needs more build flags than these 2, for now define BOARD_HAS_PSRAM is used to en/disable detecting PS-Ram size on Info page ; -DBOARD_HAS_PSRAM // both flags already enabled for Lolin D32 Pro board by PlatformIO ; -mfix-esp32-psram-cache-issue -board = lolin_d32_pro +;board = lolin_d32_pro +board = esp32_16M8M + diff --git a/requirements.txt b/requirements.txt index b76df45a9..efe4ff1d0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ esptool==4.0 -platformio>=6.0.1 +platformio>=6.0.2 pygit2==1.9.1 \ No newline at end of file diff --git a/src/Custom-sample.h b/src/Custom-sample.h index 623298750..898c53a85 100644 --- a/src/Custom-sample.h +++ b/src/Custom-sample.h @@ -141,7 +141,7 @@ #define DEFAULT_SERIAL_BAUD 115200 // Serial Port Baud Rate #define DEFAULT_SYSLOG_FACILITY 0 // kern -#define DEFAULT_SYNC_UDP_PORT 0 // Used for ESPEasy p2p. (IANA registered port: 8266) +#define DEFAULT_SYNC_UDP_PORT 8266 // Used for ESPEasy p2p. (IANA registered port: 8266) #define BUILD_NO_DEBUG @@ -427,6 +427,7 @@ static const char DATA_ESPEASY_DEFAULT_MIN_CSS[] PROGMEM = { // #define USES_P125 // ADXL345 SPI Acceleration / Gravity // #define USES_P126 // 74HC595 Shift register // #define USES_P127 // CDM7160 +// #define USES_P132 // INA3221 // Special plugins needing IR library diff --git a/src/_C010.cpp b/src/_C010.cpp index b316971f2..988c1f10c 100644 --- a/src/_C010.cpp +++ b/src/_C010.cpp @@ -89,8 +89,10 @@ bool CPlugin_010(CPlugin::Function function, struct EventStruct *event, String& element.txt[x] = pubname; parseSingleControllerVariable(element.txt[x], event, x, false); element.txt[x].replace(F("%value%"), formattedValue); +#ifndef BUILD_NO_DEBUG if (loglevelActiveFor(LOG_LEVEL_DEBUG_MORE)) addLog(LOG_LEVEL_DEBUG_MORE, element.txt[x]); +#endif } } } diff --git a/src/_C012.cpp b/src/_C012.cpp index bee7b9aa3..3ffeaac0a 100644 --- a/src/_C012.cpp +++ b/src/_C012.cpp @@ -70,8 +70,11 @@ bool CPlugin_012(CPlugin::Function function, struct EventStruct *event, String& element.txt[x] += event->idx + x; element.txt[x] += F("?value="); element.txt[x] += formattedValue; - if (loglevelActiveFor(LOG_LEVEL_DEBUG_MORE)) + #ifndef BUILD_NO_DEBUG + if (loglevelActiveFor(LOG_LEVEL_DEBUG_MORE)) { addLog(LOG_LEVEL_DEBUG_MORE, element.txt[x]); + } + #endif } } diff --git a/src/_C013.cpp b/src/_C013.cpp index 036c0caa5..a7a5a1796 100644 --- a/src/_C013.cpp +++ b/src/_C013.cpp @@ -37,7 +37,7 @@ bool CPlugin_013(CPlugin::Function function, struct EventStruct *event, String& Protocol[protocolCount].usesTemplate = false; Protocol[protocolCount].usesAccount = false; Protocol[protocolCount].usesPassword = false; - Protocol[protocolCount].defaultPort = 65501; + Protocol[protocolCount].defaultPort = 8266; Protocol[protocolCount].usesID = false; Protocol[protocolCount].Custom = true; break; diff --git a/src/_C018.cpp b/src/_C018.cpp index 99ffb2739..49b079265 100644 --- a/src/_C018.cpp +++ b/src/_C018.cpp @@ -627,8 +627,8 @@ bool CPlugin_018(CPlugin::Function function, struct EventStruct *event, String& } { - String options[2] = { F("OTAA"), F("ABP") }; - int values[2] = { C018_USE_OTAA, C018_USE_ABP }; + const __FlashStringHelper * options[2] = { F("OTAA"), F("ABP") }; + const int values[2] = { C018_USE_OTAA, C018_USE_ABP }; addFormSelector_script(F("Activation Method"), F("joinmethod"), 2, options, values, nullptr, joinmethod, F("joinChanged(this)")); // Script to toggle OTAA/ABP fields visibility when changing selection. diff --git a/src/_P001_Switch.ino b/src/_P001_Switch.ino index 8f4f91543..4daae8afa 100644 --- a/src/_P001_Switch.ino +++ b/src/_P001_Switch.ino @@ -408,7 +408,7 @@ boolean Plugin_001(uint8_t function, struct EventStruct *event, String& string) // long timerstats = millis(); // Bug fixed: avoid 10xSEC in case of a non-fully configured device (no GPIO defined yet) - const String monitorEventString = F("GPIO"); + const __FlashStringHelper * monitorEventString = F("GPIO"); if (validGpio(CONFIG_PIN1)) { @@ -531,7 +531,7 @@ boolean Plugin_001(uint8_t function, struct EventStruct *event, String& string) // send task event sendData(event); // send monitor event - if (currentStatus.monitor) sendMonitorEvent(monitorEventString.c_str(), CONFIG_PIN1, output_value); + if (currentStatus.monitor) sendMonitorEvent(monitorEventString, CONFIG_PIN1, output_value); // reset Userdata so it displays the correct state value in the web page UserVar[event->BaseVarIndex] = sendState ? 1 : 0; @@ -625,7 +625,7 @@ boolean Plugin_001(uint8_t function, struct EventStruct *event, String& string) // send task event sendData(event); // send monitor event - if (currentStatus.monitor) sendMonitorEvent(monitorEventString.c_str(), CONFIG_PIN1, output_value); + if (currentStatus.monitor) sendMonitorEvent(monitorEventString, CONFIG_PIN1, output_value); // reset Userdata so it displays the correct state value in the web page UserVar[event->BaseVarIndex] = sendState ? 1 : 0; @@ -654,7 +654,7 @@ boolean Plugin_001(uint8_t function, struct EventStruct *event, String& string) // send task event: DO NOT SEND TASK EVENT //sendData(event); // send monitor event - if (currentStatus.monitor) sendMonitorEvent(monitorEventString.c_str(), CONFIG_PIN1, SAFE_BUTTON_EVENT); + if (currentStatus.monitor) sendMonitorEvent(monitorEventString, CONFIG_PIN1, SAFE_BUTTON_EVENT); // reset Userdata so it displays the correct state value in the web page UserVar[event->BaseVarIndex] = tempUserVar; diff --git a/src/_P007_PCF8591.ino b/src/_P007_PCF8591.ino index 6600e6de1..7c8ce962e 100644 --- a/src/_P007_PCF8591.ino +++ b/src/_P007_PCF8591.ino @@ -5,6 +5,15 @@ // #################################### Plugin 007: ExtWiredAnalog ####################################### // ####################################################################################################### +/** Changelog: + * 2022-05-08 tonhuisman: Use ESPEasy core I2C functions where possible + * Add support for use of the Analog output pin and 'analogout,' command + * Add configuration of all possible analog input modes + * 2022-05-08 tonhuisman: Started changelog, older changes not recorded + ********************************************************************************************************/ + +// commands: +// analogout, : If the Analog output is enabled, the value range is 0..255, and linear to Vref # define PLUGIN_007 # define PLUGIN_ID_007 7 @@ -13,6 +22,9 @@ # define P007_SENSOR_TYPE_INDEX 2 # define P007_NR_OUTPUT_VALUES getValueCountFromSensorType(static_cast(PCONFIG(P007_SENSOR_TYPE_INDEX))) +# define P007_INPUT_MODE PCONFIG_LONG(0) +# define P007_OUTPUT_MODE PCONFIG_LONG(1) +# define P007_OUTPUT_ENABLED (0b01000000) String Plugin_007_valuename(uint8_t value_nr, bool displayString) { String name = F(PLUGIN_VALUENAME1_007); @@ -77,7 +89,7 @@ boolean Plugin_007(uint8_t function, struct EventStruct *event, String& string) if (PCONFIG(P007_SENSOR_TYPE_INDEX) == 0) { PCONFIG(P007_SENSOR_TYPE_INDEX) = static_cast(Sensor_VType::SENSOR_TYPE_SINGLE); } - event->Par1 = P004_NR_OUTPUT_VALUES; + event->Par1 = P007_NR_OUTPUT_VALUES; success = true; break; } @@ -129,6 +141,30 @@ boolean Plugin_007(uint8_t function, struct EventStruct *event, String& string) break; } + case PLUGIN_WEBFORM_LOAD: + { + addFormSubHeader(F("Hardware configuration")); + + const __FlashStringHelper *inputModeOptions[] = { + F("4 single-ended inputs"), + F("3 differential inputs, A0/A1/A2 differential with AIN3"), + F("2 single-ended, A0, A1, AIN2/AIN3 differential -> A2"), + F("AIN0/AIN1 differential -> A0, AIN2/AIN3 differential -> A1"), + }; + const int inputModeValues[] = { + 0b00000000, + 0b00010000, + 0b00100000, + 0b00110000, + }; + addFormSelector(F("Input mode"), F("plugin_007_input_mode"), 4, inputModeOptions, inputModeValues, P007_INPUT_MODE); + + addFormCheckBox(F("Enable Analog output (AOUT)"), F("plugin_007_output_mode"), P007_OUTPUT_MODE == P007_OUTPUT_ENABLED); + + success = true; + break; + } + case PLUGIN_WEBFORM_SAVE: { if (PCONFIG(P007_SENSOR_TYPE_INDEX) == 0) { @@ -138,6 +174,9 @@ boolean Plugin_007(uint8_t function, struct EventStruct *event, String& string) uint8_t port = getFormItemInt(F("plugin_007_port")); CONFIG_PORT = (((i2c - 0x48) << 2) + port); + P007_INPUT_MODE = getFormItemInt(F("plugin_007_input_mode")); + P007_OUTPUT_MODE = isFormItemChecked(F("plugin_007_output_mode")) ? P007_OUTPUT_ENABLED : 0; + success = true; break; } @@ -158,13 +197,15 @@ boolean Plugin_007(uint8_t function, struct EventStruct *event, String& string) for (; var < P007_NR_OUTPUT_VALUES; ++port, ++var) { if (port <= 4) { // Only read available ports, hardwired limited to 4 - Wire.beginTransmission(address); + // Setup all required bits to the config register + uint8_t configRegister = port - 1; + configRegister |= P007_INPUT_MODE; + configRegister |= P007_OUTPUT_MODE; // get the current pin value - Wire.write(port - 1); - Wire.endTransmission(); + I2C_write8(address, configRegister); - Wire.requestFrom(address, (uint8_t)0x2); + Wire.requestFrom(address, (uint8_t)0x2); // No fitting I2C standard function available if (Wire.available()) { @@ -173,6 +214,7 @@ boolean Plugin_007(uint8_t function, struct EventStruct *event, String& string) if (loglevelActiveFor(LOG_LEVEL_INFO)) { String log; + if (log.reserve(40)) { log += F("PCF : Analog port: A"); log += port - 1; @@ -196,6 +238,28 @@ boolean Plugin_007(uint8_t function, struct EventStruct *event, String& string) } break; } + + case PLUGIN_WRITE: + { + String command = parseString(string, 1); + + if ((P007_OUTPUT_MODE == P007_OUTPUT_ENABLED) && + command.equals(F("analogout")) && + (event->Par1 >= 0) && (event->Par1 <= 255)) { + uint8_t unit = (CONFIG_PORT - 1) / 4; + uint8_t address = 0x48 + unit; + + // Setup all required bits to the config register + uint8_t configRegister = 0; + configRegister |= P007_INPUT_MODE; + configRegister |= P007_OUTPUT_MODE; + + I2C_write8_reg(address, configRegister, static_cast(event->Par1)); + + success = true; + } + break; + } } return success; } diff --git a/src/_P009_MCP.ino b/src/_P009_MCP.ino index e931ef8c8..52c1878c0 100644 --- a/src/_P009_MCP.ino +++ b/src/_P009_MCP.ino @@ -289,7 +289,7 @@ boolean Plugin_009(uint8_t function, struct EventStruct *event, String& string) case PLUGIN_TEN_PER_SECOND: { const int8_t state = GPIO_MCP_Read(CONFIG_PORT); - const String monitorEventString = F("MCP"); + const __FlashStringHelper * monitorEventString = F("MCP"); /**************************************************************************\ 20181022 - @giig1967g: new doubleclick logic is: @@ -392,7 +392,7 @@ boolean Plugin_009(uint8_t function, struct EventStruct *event, String& string) sendData(event); // send monitor event - if (currentStatus.monitor) { sendMonitorEvent(monitorEventString.c_str(), CONFIG_PORT, output_value); } + if (currentStatus.monitor) { sendMonitorEvent(monitorEventString, CONFIG_PORT, output_value); } // Reset forceEvent currentStatus.forceEvent = 0; @@ -459,7 +459,7 @@ boolean Plugin_009(uint8_t function, struct EventStruct *event, String& string) sendData(event); // send monitor event - if (currentStatus.monitor) { sendMonitorEvent(monitorEventString.c_str(), CONFIG_PORT, output_value); } + if (currentStatus.monitor) { sendMonitorEvent(monitorEventString, CONFIG_PORT, output_value); } // reset Userdata so it displays the correct state value in the web page UserVar[event->BaseVarIndex] = sendState ? 1 : 0; @@ -483,7 +483,7 @@ boolean Plugin_009(uint8_t function, struct EventStruct *event, String& string) // send task event: DO NOT SEND TASK EVENT //sendData(event); // send monitor event - if (currentStatus.monitor) { sendMonitorEvent(monitorEventString.c_str(), CONFIG_PORT, 4); } + if (currentStatus.monitor) { sendMonitorEvent(monitorEventString, CONFIG_PORT, 4); } // reset Userdata so it displays the correct state value in the web page UserVar[event->BaseVarIndex] = tempUserVar; @@ -506,7 +506,7 @@ boolean Plugin_009(uint8_t function, struct EventStruct *event, String& string) sendData(event); // send monitor event - if (currentStatus.monitor) { sendMonitorEvent(monitorEventString.c_str(), CONFIG_PORT, -1); } + if (currentStatus.monitor) { sendMonitorEvent(monitorEventString, CONFIG_PORT, -1); } savePortStatus(key, currentStatus); } diff --git a/src/_P013_HCSR04.ino b/src/_P013_HCSR04.ino index dab198098..389560f4d 100644 --- a/src/_P013_HCSR04.ino +++ b/src/_P013_HCSR04.ino @@ -94,7 +94,7 @@ boolean Plugin_013(uint8_t function, struct EventStruct *even } - String strUnit = (measuringUnit == UNIT_CM) ? F("cm") : F("inch"); + const __FlashStringHelper * strUnit = (measuringUnit == UNIT_CM) ? F("cm") : F("inch"); { const __FlashStringHelper *optionsOpMode[2]; diff --git a/src/_P015_TSL2561.ino b/src/_P015_TSL2561.ino index 39d34449b..6766e1b95 100644 --- a/src/_P015_TSL2561.ino +++ b/src/_P015_TSL2561.ino @@ -152,7 +152,9 @@ boolean Plugin_015(uint8_t function, struct EventStruct *event, String& string) UserVar[event->BaseVarIndex + 3]); // ir_broadband_ratio if (P015_SLEEP) { +#ifndef BUILD_NO_DEBUG addLog(LOG_LEVEL_DEBUG_MORE, F("TSL2561: sleeping...")); +#endif P015_data->setPowerDown(); } } diff --git a/src/_P019_PCF8574.ino b/src/_P019_PCF8574.ino index 849eb0eb8..9023f7ece 100644 --- a/src/_P019_PCF8574.ino +++ b/src/_P019_PCF8574.ino @@ -340,7 +340,7 @@ boolean Plugin_019(uint8_t function, struct EventStruct *event, String& string) case PLUGIN_TEN_PER_SECOND: { const int8_t state = Plugin_019_Read(CONFIG_PORT); - const String monitorEventString = F("PCF"); + const __FlashStringHelper * monitorEventString = F("PCF"); /**************************************************************************\ 20181022 - @giig1967g: new doubleclick logic is: @@ -449,7 +449,7 @@ boolean Plugin_019(uint8_t function, struct EventStruct *event, String& string) // send task event sendData(event); // send monitor event - if (currentStatus.monitor) sendMonitorEvent(monitorEventString.c_str(), CONFIG_PORT, output_value); + if (currentStatus.monitor) sendMonitorEvent(monitorEventString, CONFIG_PORT, output_value); // Reset forceEvent currentStatus.forceEvent = 0; @@ -514,7 +514,7 @@ boolean Plugin_019(uint8_t function, struct EventStruct *event, String& string) // send task event sendData(event); // send monitor event - if (currentStatus.monitor) sendMonitorEvent(monitorEventString.c_str(), CONFIG_PORT, output_value); + if (currentStatus.monitor) sendMonitorEvent(monitorEventString, CONFIG_PORT, output_value); // reset Userdata so it displays the correct state value in the web page UserVar[event->BaseVarIndex] = sendState ? 1 : 0; @@ -540,7 +540,7 @@ boolean Plugin_019(uint8_t function, struct EventStruct *event, String& string) // send task event: DO NOT SEND TASK EVENT //sendData(event); // send monitor event - if (currentStatus.monitor) sendMonitorEvent(monitorEventString.c_str(), CONFIG_PORT, SAFE_BUTTON_EVENT); + if (currentStatus.monitor) sendMonitorEvent(monitorEventString, CONFIG_PORT, SAFE_BUTTON_EVENT); // reset Userdata so it displays the correct state value in the web page UserVar[event->BaseVarIndex] = tempUserVar; @@ -563,7 +563,7 @@ boolean Plugin_019(uint8_t function, struct EventStruct *event, String& string) // send task event sendData(event); // send monitor event - if (currentStatus.monitor) sendMonitorEvent(monitorEventString.c_str(), CONFIG_PORT, -1); + if (currentStatus.monitor) sendMonitorEvent(monitorEventString, CONFIG_PORT, -1); savePortStatus(key, currentStatus); } diff --git a/src/_P020_Ser2Net.ino b/src/_P020_Ser2Net.ino index 3838453bf..2344e1b4c 100644 --- a/src/_P020_Ser2Net.ino +++ b/src/_P020_Ser2Net.ino @@ -167,7 +167,7 @@ boolean Plugin_020(uint8_t function, struct EventStruct *event, String& string) const ESPEasySerialPort port = static_cast(CONFIG_PORT); // const ESPEasySerialPort port= ESPEasySerialPort::serial0; - if ((rxPin < 0) && (rxPin < 0)) { + if ((rxPin < 0) && (txPin < 0)) { ESPeasySerialType::getSerialTypePins(port, rxPin, txPin); CONFIG_PIN1 = rxPin; CONFIG_PIN2 = txPin; diff --git a/src/_P037_MQTTImport.ino b/src/_P037_MQTTImport.ino index 39f679fd6..1489f59c5 100644 --- a/src/_P037_MQTTImport.ino +++ b/src/_P037_MQTTImport.ino @@ -134,19 +134,15 @@ boolean Plugin_037(uint8_t function, struct EventStruct *event, String& string) case PLUGIN_WEBFORM_LOAD: { addFormSubHeader(F("Options")); - # if P037_MAPPING_SUPPORT || P037_JSON_SUPPORT || P037_FILTER_SUPPORT - const __FlashStringHelper *optionsNoYes[2] = { F("No"), F("Yes") }; - int optionValuesNoYes[2] = { 0, 1 }; - # endif // if P037_MAPPING_SUPPORT || P037_JSON_SUPPORT || P037_FILTER_SUPPORT # if P037_JSON_SUPPORT - addFormSelector(F("Parse JSON messages"), F("p037_parse_json"), 2, optionsNoYes, optionValuesNoYes, P037_PARSE_JSON, true); + addFormSelector_YesNo(F("Parse JSON messages"), F("p037_parse_json"), P037_PARSE_JSON, true); # endif // if P037_JSON_SUPPORT # if P037_FILTER_SUPPORT - addFormSelector(F("Apply filters"), F("p037_apply_filters"), 2, optionsNoYes, optionValuesNoYes, P037_APPLY_FILTERS, true); + addFormSelector_YesNo(F("Apply filters"), F("p037_apply_filters"), P037_APPLY_FILTERS, true); # endif // if P037_FILTER_SUPPORT # if P037_MAPPING_SUPPORT - addFormSelector(F("Apply mappings"), F("p037_apply_mappings"), 2, optionsNoYes, optionValuesNoYes, P037_APPLY_MAPPINGS, true); + addFormSelector_YesNo(F("Apply mappings"), F("p037_apply_mappings"), P037_APPLY_MAPPINGS, true); # endif // if P037_MAPPING_SUPPORT # if P037_MAPPING_SUPPORT || P037_JSON_SUPPORT || P037_FILTER_SUPPORT # if !defined(LIMIT_BUILD_SIZE) diff --git a/src/_P038_NeoPixel.ino b/src/_P038_NeoPixel.ino index ba21876ad..6048bc68f 100644 --- a/src/_P038_NeoPixel.ino +++ b/src/_P038_NeoPixel.ino @@ -102,10 +102,9 @@ boolean Plugin_038(uint8_t function, struct EventStruct *event, String& string) initPluginTaskData(event->TaskIndex, new (std::nothrow) P038_data_struct(CONFIG_PIN1, P038_CONFIG_LEDCOUNT, P038_CONFIG_STRIPTYPE)); P038_data_struct *P038_data = static_cast(getPluginTaskData(event->TaskIndex)); - if (nullptr == P038_data) { - return success; - } - success = P038_data->plugin_init(event); + if (nullptr != P038_data) { + success = P038_data->plugin_init(event); + } break; } @@ -114,10 +113,9 @@ boolean Plugin_038(uint8_t function, struct EventStruct *event, String& string) { P038_data_struct *P038_data = static_cast(getPluginTaskData(event->TaskIndex)); - if (nullptr == P038_data) { - return success; + if (nullptr != P038_data) { + success = P038_data->plugin_exit(event); } - success = P038_data->plugin_exit(event); break; } @@ -126,10 +124,9 @@ boolean Plugin_038(uint8_t function, struct EventStruct *event, String& string) { P038_data_struct *P038_data = static_cast(getPluginTaskData(event->TaskIndex)); - if (nullptr == P038_data) { - return success; + if (nullptr != P038_data) { + success = P038_data->plugin_write(event, string); } - success = P038_data->plugin_write(event, string); break; } diff --git a/src/_P039_Thermosensors.ino b/src/_P039_Thermosensors.ino index 61b6e2977..28433f893 100644 --- a/src/_P039_Thermosensors.ino +++ b/src/_P039_Thermosensors.ino @@ -1222,7 +1222,7 @@ float readMax31865(struct EventStruct *event) // read conversion result and faults from plugin data structure // if pointer exists and conversion has been finished - if ((nullptr != P039_data) && (true == P039_data->convReady)) { + if (P039_data->convReady) { rawValue = P039_data->conversionResult; registers[MAX31865_FAULT] = P039_data->deviceFaults; } @@ -1270,14 +1270,12 @@ float readMax31865(struct EventStruct *event) // start time to follow up on BIAS activation before starting the conversion // and start conversion sequence via TIMER API - if(nullptr != P039_data){ - // save current timer for next calculation - P039_data->timer = millis(); + // save current timer for next calculation + P039_data->timer = millis(); - // set next state to MAX31865_BIAS_ON_STATE + // set next state to MAX31865_BIAS_ON_STATE - Scheduler.setPluginTaskTimer(MAX31865_BIAS_WAIT_TIME, event->TaskIndex, MAX31865_BIAS_ON_STATE); - } + Scheduler.setPluginTaskTimer(MAX31865_BIAS_WAIT_TIME, event->TaskIndex, MAX31865_BIAS_ON_STATE); #ifndef BUILD_NO_DEBUG if (loglevelActiveFor(LOG_LEVEL_DEBUG_MORE)) diff --git a/src/_P062_MPR121_KeyPad.ino b/src/_P062_MPR121_KeyPad.ino index ad4a29e1f..15204a6a3 100644 --- a/src/_P062_MPR121_KeyPad.ino +++ b/src/_P062_MPR121_KeyPad.ino @@ -177,10 +177,8 @@ boolean Plugin_062(uint8_t function, struct EventStruct *event, String& string) html_end_table(); if (canCalibrate) { - const __FlashStringHelper *options1[2] = { F("No"), F("Yes") }; - int optionValues1[2] = { 0, 1 }; - int choice1 = tbUseCalibration ? 1 : 0; - addFormSelector(F("Enable Calibration"), F("p062_use_calibration"), 2, options1, optionValues1, choice1, true); + const int choice1 = tbUseCalibration ? 1 : 0; + addFormSelector_YesNo(F("Enable Calibration"), F("p062_use_calibration"), choice1, true); if (tbUseCalibration) { addFormCheckBox(F("Clear calibrationdata"), F("p062_clear_calibrate"), false); diff --git a/src/_P073_7DGT.ino b/src/_P073_7DGT.ino index dfdddf48b..5bcb74728 100644 --- a/src/_P073_7DGT.ino +++ b/src/_P073_7DGT.ino @@ -114,7 +114,7 @@ boolean Plugin_073(uint8_t function, struct EventStruct *event, String& string) F("TM1637 - 4 digit (dots)"), F("TM1637 - 6 digit"), F("MAX7219 - 8 digit") }; - addFormSelector(F("Display Type"), F("plugin_073_displtype"), 4, displtype, nullptr, PCONFIG(0)); + addFormSelector(F("Display Type"), F("displtype"), 4, displtype, nullptr, PCONFIG(0)); } { const __FlashStringHelper *displout[] = { F("Manual"), @@ -123,10 +123,10 @@ boolean Plugin_073(uint8_t function, struct EventStruct *event, String& string) F("Clock 12h - Blink"), F("Clock 12h - No Blink"), F("Date") }; - addFormSelector(F("Display Output"), F("plugin_073_displout"), 6, displout, nullptr, PCONFIG(1)); + addFormSelector(F("Display Output"), F("displout"), 6, displout, nullptr, PCONFIG(1)); } - addFormNumericBox(F("Brightness"), F("plugin_073_brightness"), PCONFIG(2), 0, 15); + addFormNumericBox(F("Brightness"), F("brightness"), PCONFIG(2), 0, 15); addUnit(F("0..15")); # ifdef P073_EXTRA_FONTS @@ -135,16 +135,16 @@ boolean Plugin_073(uint8_t function, struct EventStruct *event, String& string) F("Siekoo"), F("Siekoo with uppercase 'CHNORUX'"), F("dSEG7") }; - addFormSelector(F("Font set"), F("plugin_073_fontset"), 4, fontset, nullptr, PCONFIG(4)); + addFormSelector(F("Font set"), F("fontset"), 4, fontset, nullptr, PCONFIG(4)); addFormNote(F("Check documentation for examples of the font sets.")); } # endif // P073_EXTRA_FONTS addFormSubHeader(F("Options")); - addFormCheckBox(F("Text show periods as dot"), F("plugin_073_periods"), bitRead(PCONFIG_LONG(0), P073_OPTION_PERIOD)); + addFormCheckBox(F("Text show periods as dot"), F("periods"), bitRead(PCONFIG_LONG(0), P073_OPTION_PERIOD)); - addFormCheckBox(F("Hide ° for Temperatures"), F("plugin_073_hide_degree"), bitRead(PCONFIG_LONG(0), P073_OPTION_HIDEDEGREE)); + addFormCheckBox(F("Hide ° for Temperatures"), F("hide_degree"), bitRead(PCONFIG_LONG(0), P073_OPTION_HIDEDEGREE)); # ifdef P073_7DDT_COMMAND addFormNote(F("Commands 7dt,<temp> and 7ddt,<temp1>,<temp2>")); # else // ifdef P073_7DDT_COMMAND @@ -152,38 +152,38 @@ boolean Plugin_073(uint8_t function, struct EventStruct *event, String& string) # endif // P073_7DDT_COMMAND # ifdef P073_SCROLL_TEXT - addFormCheckBox(F("Scroll text > display width"), F("plugin_073_scroll_text"), bitRead(PCONFIG_LONG(0), P073_OPTION_SCROLLTEXT)); - addFormCheckBox(F("Scroll text in from right"), F("plugin_073_scroll_full"), bitRead(PCONFIG_LONG(0), P073_OPTION_SCROLLFULL)); + addFormCheckBox(F("Scroll text > display width"), F("scroll_text"), bitRead(PCONFIG_LONG(0), P073_OPTION_SCROLLTEXT)); + addFormCheckBox(F("Scroll text in from right"), F("scroll_full"), bitRead(PCONFIG_LONG(0), P073_OPTION_SCROLLFULL)); if (PCONFIG(3) == 0) { PCONFIG(3) = 10; } - addFormNumericBox(F("Scroll speed (0.1 sec/step)"), F("plugin_073_scrollspeed"), PCONFIG(3), 1, 600); + addFormNumericBox(F("Scroll speed (0.1 sec/step)"), F("scrollspeed"), PCONFIG(3), 1, 600); addUnit(F("1..600 = 0.1..60 sec/step")); # endif // P073_SCROLL_TEXT addFormSubHeader(F("Options for MAX7219 - 8 digit")); bool bRightAlign = bitRead(PCONFIG_LONG(0), P073_OPTION_RIGHTALIGN); - addFormCheckBox(F("Right-align Temperature (7dt)"), F("plugin_073_temp_rightalign"), bRightAlign); + addFormCheckBox(F("Right-align Temperature (7dt)"), F("temp_rightalign"), bRightAlign); success = true; break; } case PLUGIN_WEBFORM_SAVE: { - PCONFIG(0) = getFormItemInt(F("plugin_073_displtype")); - PCONFIG(1) = getFormItemInt(F("plugin_073_displout")); - PCONFIG(2) = getFormItemInt(F("plugin_073_brightness")); + PCONFIG(0) = getFormItemInt(F("displtype")); + PCONFIG(1) = getFormItemInt(F("displout")); + PCONFIG(2) = getFormItemInt(F("brightness")); uint32_t lSettings = 0; - bitWrite(lSettings, P073_OPTION_PERIOD, isFormItemChecked(F("plugin_073_periods"))); - bitWrite(lSettings, P073_OPTION_HIDEDEGREE, isFormItemChecked(F("plugin_073_hide_degree"))); - bitWrite(lSettings, P073_OPTION_RIGHTALIGN, isFormItemChecked(F("plugin_073_temp_rightalign"))); + bitWrite(lSettings, P073_OPTION_PERIOD, isFormItemChecked(F("periods"))); + bitWrite(lSettings, P073_OPTION_HIDEDEGREE, isFormItemChecked(F("hide_degree"))); + bitWrite(lSettings, P073_OPTION_RIGHTALIGN, isFormItemChecked(F("temp_rightalign"))); # ifdef P073_SCROLL_TEXT - bitWrite(lSettings, P073_OPTION_SCROLLTEXT, isFormItemChecked(F("plugin_073_scroll_text"))); - bitWrite(lSettings, P073_OPTION_SCROLLFULL, isFormItemChecked(F("plugin_073_scroll_full"))); - PCONFIG(3) = getFormItemInt(F("plugin_073_scrollspeed")); + bitWrite(lSettings, P073_OPTION_SCROLLTEXT, isFormItemChecked(F("scroll_text"))); + bitWrite(lSettings, P073_OPTION_SCROLLFULL, isFormItemChecked(F("scroll_full"))); + PCONFIG(3) = getFormItemInt(F("scrollspeed")); # endif // P073_SCROLL_TEXT # ifdef P073_EXTRA_FONTS - PCONFIG(4) = getFormItemInt(F("plugin_073_fontset")); + PCONFIG(4) = getFormItemInt(F("fontset")); # endif // P073_EXTRA_FONTS PCONFIG_LONG(0) = lSettings; @@ -356,8 +356,10 @@ bool p073_plugin_write(struct EventStruct *event, return false; } - String cmd = parseString(string, 1); - String text = parseStringToEndKeepCase(string, 2); + const String cmd = parseString(string, 1); + if (cmd.length() < 3 || cmd[0] != '7') return false; + + const String text = parseStringToEndKeepCase(string, 2); if (cmd.equals("7dn")) { return p073_plugin_write_7dn(event, text); @@ -508,11 +510,11 @@ bool p073_plugin_write_7dt(struct EventStruct *event, return false; } - double p073_temptemp = 0; + float p073_temptemp = 0; bool p073_tempflagdot = false; if (!text.isEmpty()) { - validDoubleFromString(text, p073_temptemp); + validFloatFromString(text, p073_temptemp); } if (loglevelActiveFor(LOG_LEVEL_INFO)) { @@ -581,15 +583,15 @@ bool p073_plugin_write_7ddt(struct EventStruct *event, return false; } - double p073_lefttemp = 0.0; - double p073_righttemp = 0.0; + float p073_lefttemp = 0.0f; + float p073_righttemp = 0.0f; bool p073_tempflagdot = false; if (!text.isEmpty()) { - validDoubleFromString(parseString(text, 1), p073_lefttemp); + validFloatFromString(parseString(text, 1), p073_lefttemp); if (text.indexOf(',') > -1) { - validDoubleFromString(parseString(text, 2), p073_righttemp); + validFloatFromString(parseString(text, 2), p073_righttemp); } } @@ -619,25 +621,25 @@ bool p073_plugin_write_7ddt(struct EventStruct *event, { uint8_t firstDot = -1; // No decimals is no dots uint8_t secondDot = -1; - double hideFactor = P073_data->hideDegree ? 10.0 : 1.0; + float hideFactor = P073_data->hideDegree ? 10.0f : 1.0f; bool firstDecimals = false; bool secondDecimals = false; - if ((p073_lefttemp > 999.99 * hideFactor) || (p073_lefttemp < -99.99 * hideFactor)) { - p073_lefttemp = -101.0 * hideFactor; // Triggers on -100 + if ((p073_lefttemp > 999.99f * hideFactor) || (p073_lefttemp < -99.99f * hideFactor)) { + p073_lefttemp = -101.0f * hideFactor; // Triggers on -100 } else { - if ((p073_lefttemp < 100.0 * hideFactor) && (p073_lefttemp > -10.0 * hideFactor)) { - p073_lefttemp = round(p073_lefttemp * 10.0); + if ((p073_lefttemp < 100.0f * hideFactor) && (p073_lefttemp > -10.0f * hideFactor)) { + p073_lefttemp = round(p073_lefttemp * 10.0f); firstDot = P073_data->hideDegree ? 2 : 1; firstDecimals = true; } } - if ((p073_righttemp > 999.99 * hideFactor) || (p073_righttemp < -99.99 * hideFactor)) { - p073_righttemp = -101.0 * hideFactor; + if ((p073_righttemp > 999.99f * hideFactor) || (p073_righttemp < -99.99f * hideFactor)) { + p073_righttemp = -101.0f * hideFactor; } else { - if ((p073_righttemp < 100.0 * hideFactor) && (p073_righttemp > -10.0 * hideFactor)) { - p073_righttemp = round(p073_righttemp * 10.0); + if ((p073_righttemp < 100.0f * hideFactor) && (p073_righttemp > -10.0f * hideFactor)) { + p073_righttemp = round(p073_righttemp * 10.0f); secondDot = P073_data->hideDegree ? 6 : 5; secondDecimals = true; } diff --git a/src/_P098_PWM_motor.ino b/src/_P098_PWM_motor.ino index 20eac42bf..33ff5eeb1 100644 --- a/src/_P098_PWM_motor.ino +++ b/src/_P098_PWM_motor.ino @@ -169,7 +169,7 @@ boolean Plugin_098(uint8_t function, struct EventStruct *event, String& string) { # define P098_PWM_MODE_TYPES static_cast(P098_config_struct::PWM_mode_type::MAX_TYPE) - String options[P098_PWM_MODE_TYPES]; + const __FlashStringHelper * options[P098_PWM_MODE_TYPES]; int optionValues[P098_PWM_MODE_TYPES]; for (int i = 0; i < P098_PWM_MODE_TYPES; ++i) { diff --git a/src/_P099_XPT2046Touch.ino b/src/_P099_XPT2046Touch.ino index 6ed48e9f0..7ea207f0e 100644 --- a/src/_P099_XPT2046Touch.ino +++ b/src/_P099_XPT2046Touch.ino @@ -204,10 +204,8 @@ boolean Plugin_099(uint8_t function, struct EventStruct *event, String& string) bool tbUseCalibration = bitRead(P099_CONFIG_FLAGS, P099_FLAGS_USE_CALIBRATION); { - const __FlashStringHelper * options4[2] = { F("No"), F("Yes") }; - int optionValues4[2] = { 0, 1 }; int choice4 = tbUseCalibration ? 1 : 0; - addFormSelector(F("Calibrate to screen resolution"), F("p099_use_calibration"), 2, options4, optionValues4, choice4, true); + addFormSelector_YesNo(F("Calibrate to screen resolution"), F("p099_use_calibration"), choice4, true); } if (tbUseCalibration) { diff --git a/src/_P119_ITG3205_Gyro.ino b/src/_P119_ITG3205_Gyro.ino index df6eab3a2..cb83c60eb 100644 --- a/src/_P119_ITG3205_Gyro.ino +++ b/src/_P119_ITG3205_Gyro.ino @@ -111,10 +111,11 @@ boolean Plugin_119(uint8_t function, struct EventStruct *event, String& string) addUnit(F("1..100")); const __FlashStringHelper *frequencyOptions[] = { - F("10x per second"), - F("50x per second") }; + F("10"), + F("50") }; int frequencyValues[] = { P119_FREQUENCY_10, P119_FREQUENCY_50 }; addFormSelector(F("Measuring frequency"), F("p119_frequency"), 2, frequencyOptions, frequencyValues, P119_FREQUENCY); + addUnit(F("Hz")); success = true; break; diff --git a/src/_P124_MultiRelay.ino b/src/_P124_MultiRelay.ino index 223d9ff72..b3539ba1b 100644 --- a/src/_P124_MultiRelay.ino +++ b/src/_P124_MultiRelay.ino @@ -105,13 +105,8 @@ boolean Plugin_124(uint8_t function, struct EventStruct *event, String& string) int optionValuesMode2[] { 2, 4, 8 }; addFormSelector(F("Number of relays"), F("plugin_124_relays"), 3, optionsMode2, optionValuesMode2, P124_CONFIG_RELAY_COUNT, true); - const __FlashStringHelper *noYesOptions[] = { - F("No"), - F("Yes") - }; - int noYesValues[] = { 0, 1 }; - addFormSelector(F("Initialize relays on startup"), - getPluginCustomArgName(P124_FLAGS_INIT_RELAYS), 2, noYesOptions, noYesValues, + addFormSelector_YesNo(F("Initialize relays on startup"), + getPluginCustomArgName(P124_FLAGS_INIT_RELAYS), bitRead(P124_CONFIG_FLAGS, P124_FLAGS_INIT_RELAYS) ? 1 : 0, true); String label; @@ -129,8 +124,8 @@ boolean Plugin_124(uint8_t function, struct EventStruct *event, String& string) } } - addFormSelector(F("Reset relays on exit"), - getPluginCustomArgName(P124_FLAGS_EXIT_RELAYS), 2, noYesOptions, noYesValues, + addFormSelector_YesNo(F("Reset relays on exit"), + getPluginCustomArgName(P124_FLAGS_EXIT_RELAYS), bitRead(P124_CONFIG_FLAGS, P124_FLAGS_EXIT_RELAYS) ? 1 : 0, true); if (bitRead(P124_CONFIG_FLAGS, P124_FLAGS_EXIT_RELAYS)) { diff --git a/src/_P132_INA3221.ino b/src/_P132_INA3221.ino new file mode 100644 index 000000000..47a8b7aa0 --- /dev/null +++ b/src/_P132_INA3221.ino @@ -0,0 +1,264 @@ +#ifdef USES_P132 + +// ####################################################################################################### +// ######################### Plugin 132: INA3221 DC Voltage/Current sensor ############################### +// ####################################################################################################### + +/** + * Changelog: + * 2022-04-23, tonhuisman: Add separate settings for Conversion rate Voltage and Current + * 2022-04-21, tonhuisman: Move source into PluginStructs + * 2022-04-20, tonhuisman: Add averaging of samples and conversion rate settings + * 2022-04-19, tonhuisman: Adapt to general ESPEasy coding standards + **/ + +// Initial development: ## 25 jan 2021 Fred van Duin #### + +#include "_Plugin_Helper.h" + +#define PLUGIN_132 +#define PLUGIN_ID_132 132 +#define PLUGIN_NAME_132 "Energy (DC) - INA3221 [TESTING]" +#define PLUGIN_VALUENAME1_132 "Value1" +#define PLUGIN_VALUENAME2_132 "Value2" +#define PLUGIN_VALUENAME3_132 "Value3" +#define PLUGIN_VALUENAME4_132 "Value4" + +#include "./src/PluginStructs/P132_data_struct.h" + +boolean Plugin_132(uint8_t function, struct EventStruct *event, String& string) +{ + boolean success = false; + + switch (function) + { + case PLUGIN_DEVICE_ADD: + { + Device[++deviceCount].Number = PLUGIN_ID_132; + Device[deviceCount].Type = DEVICE_TYPE_I2C; + Device[deviceCount].VType = Sensor_VType::SENSOR_TYPE_QUAD; + Device[deviceCount].Ports = 0; + Device[deviceCount].PullUpOption = false; + Device[deviceCount].InverseLogicOption = false; + Device[deviceCount].FormulaOption = true; + Device[deviceCount].ValueCount = 4; + Device[deviceCount].SendDataOption = true; + Device[deviceCount].TimerOption = true; + Device[deviceCount].GlobalSyncOption = true; + break; + } + + case PLUGIN_GET_DEVICENAME: + { + string = F(PLUGIN_NAME_132); + break; + } + + case PLUGIN_GET_DEVICEVALUENAMES: + { + strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_VALUENAME1_132)); + strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[1], PSTR(PLUGIN_VALUENAME2_132)); + strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[2], PSTR(PLUGIN_VALUENAME3_132)); + strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[3], PSTR(PLUGIN_VALUENAME4_132)); + break; + } + + case PLUGIN_I2C_HAS_ADDRESS: + case PLUGIN_WEBFORM_SHOW_I2C_PARAMS: + { + const uint8_t i2cAddressValues[] = { 0x40, 0x41, 0x42, 0x43 }; + + if (function == PLUGIN_WEBFORM_SHOW_I2C_PARAMS) { + addFormSelectorI2C(F("i2c_addr"), 4, i2cAddressValues, P132_I2C_ADDR); + addFormNote(F("A0 connected to: GND= 0x40, VCC= 0x41, SDA= 0x42, SCL= 0x43")); + } else { + success = intArrayContains(4, i2cAddressValues, event->Par1); + } + break; + } + + case PLUGIN_SET_DEFAULTS: + { + P132_VALUE_1 = 0; // Configure randomly + P132_VALUE_2 = 1; + P132_VALUE_3 = 2; + P132_VALUE_4 = 3; + uint32_t lSettings = 0; + set3BitToUL(lSettings, P132_FLAG_AVERAGE, 0x00); + set3BitToUL(lSettings, P132_FLAG_CONVERSION_B, 0x04); // Voltage + set3BitToUL(lSettings, P132_FLAG_CONVERSION_S, 0x04); // Current + P132_CONFIG_FLAGS = lSettings; + break; + } + + case PLUGIN_WEBFORM_LOAD: + { + #define INA3221_var_OPTION 6 + { + const __FlashStringHelper *varOptions[] = { + F("Current channel 1"), + F("Voltage channel 1"), + F("Current channel 2"), + F("Voltage channel 2"), + F("Current channel 3"), + F("Voltage channel 3") + }; + + for (uint8_t r = 0; r < VARS_PER_TASK; r++) { + String label = F("Power value "); + label += (r + 1); + addFormSelector(label, getPluginCustomArgName(r), INA3221_var_OPTION, varOptions, NULL, PCONFIG(P132_CONFIG_BASE + r)); + } + } + + + addFormSubHeader(F("Hardware")); + + #define INA3221_shunt_OPTION 3 + { + const __FlashStringHelper *varshuntptions[] = { + F("0.1 ohm"), + F("0.01 ohm"), + F("0.005 ohm"), + }; + int shuntvalue[] = { 1, 10, 20 }; + addFormSelector(F("Shunt resistor"), F("p132_shunt"), INA3221_shunt_OPTION, varshuntptions, shuntvalue, P132_SHUNT); + addFormNote(F("Select as is installed on the board.")); + } + + addFormSubHeader(F("Measurement")); + + #define INA3221_average_OPTION 8 + { + const __FlashStringHelper *averagingSamples[] = { + F("1 (default)"), + F("4"), + F("16"), + F("64"), + F("128"), + F("256"), + F("512"), + F("1024"), + }; + int averageValue[] = { 0b000, 0b001, 0b010, 0b011, 0b100, 0b101, 0b110, 0b111 }; + addFormSelector(F("Averaging samples"), + F("p132_average"), + INA3221_average_OPTION, + averagingSamples, + averageValue, + P132_GET_AVERAGE); + addFormNote(F("Samples > 16 then min. Interval: 64= 4, 128= 7, 256= 14, 512= 26, 1024= 52 seconds!")); + } + + #define INA3221_conversion_OPTION 8 + { + const __FlashStringHelper *conversionRates[] = { + F("140 µsec"), + F("204 µsec"), + F("332 µsec"), + F("588 µsec"), + F("1.1 msec (default)"), + F("2.116 msec"), + F("4.156 msec"), + F("8.244 msec"), + }; + + // 140us 204us 332us 588us 1.1ms 2.1ms 4.1ms 8.2ms + int conversionValues[] = { 0b000, 0b001, 0b010, 0b011, 0b100, 0b101, 0b110, 0b111 }; + addFormSelector(F("Conversion rate Voltage"), + F("p132_conversion_v"), + INA3221_conversion_OPTION, + conversionRates, + conversionValues, + P132_GET_CONVERSION_B); + + addFormSelector(F("Conversion rate Current"), + F("p132_conversion_c"), + INA3221_conversion_OPTION, + conversionRates, + conversionValues, + P132_GET_CONVERSION_S); + } + + success = true; + break; + } + + case PLUGIN_WEBFORM_SAVE: + { + P132_I2C_ADDR = getFormItemInt(F("i2c_addr")); + + for (uint8_t r = 0; r < VARS_PER_TASK; r++) { + PCONFIG(P132_CONFIG_BASE + r) = getFormItemInt(getPluginCustomArgName(r)); + } + P132_SHUNT = getFormItemInt(F("p132_shunt")); + + uint32_t lSettings = 0; + set3BitToUL(lSettings, P132_FLAG_AVERAGE, getFormItemInt(F("p132_average"))); + set3BitToUL(lSettings, P132_FLAG_CONVERSION_B, getFormItemInt(F("p132_conversion_v"))); + set3BitToUL(lSettings, P132_FLAG_CONVERSION_S, getFormItemInt(F("p132_conversion_c"))); + P132_CONFIG_FLAGS = lSettings; + + success = true; + break; + } + + case PLUGIN_INIT: + { + initPluginTaskData(event->TaskIndex, new (std::nothrow) P132_data_struct(event)); + P132_data_struct *P132_data = static_cast(getPluginTaskData(event->TaskIndex)); + + if (nullptr == P132_data) { + return success; + } + + success = true; + break; + } + + case PLUGIN_READ: + { + P132_data_struct *P132_data = static_cast(getPluginTaskData(event->TaskIndex)); + + if (nullptr == P132_data) { + return success; + } + + uint8_t reg; + + for (uint8_t r = 0; r < VARS_PER_TASK; r++) { + // VALUES 1..4 + reg = static_cast(PCONFIG(P132_CONFIG_BASE + r) + 1); + + if ((reg == 2) || (reg == 4) || (reg == 6)) { + UserVar[event->BaseVarIndex + r] = P132_data->getBusVoltage_V(reg) + + (P132_data->getShuntVoltage_mV(reg - 1) / 1000.0f); + } else { + UserVar[event->BaseVarIndex + r] = (P132_data->getShuntVoltage_mV(reg) / 100.0f) * P132_SHUNT; + } + } + + #ifndef BUILD_NO_DEBUG + + if (loglevelActiveFor(LOG_LEVEL_INFO)) { + String log = F("INA3221: Values: "); + log += UserVar[event->BaseVarIndex]; + log += F(", "); + log += UserVar[event->BaseVarIndex + 1]; + log += F(", "); + log += UserVar[event->BaseVarIndex + 2]; + log += F(", "); + log += UserVar[event->BaseVarIndex + 3]; + addLog(LOG_LEVEL_INFO, log); + } + #endif // ifndef BUILD_NO_DEBUG + + success = true; + break; + } + } + + return success; +} + +#endif // USES_P132 diff --git a/src/src/Commands/InternalCommands.cpp b/src/src/Commands/InternalCommands.cpp index 42df34a8d..dc5375d47 100644 --- a/src/src/Commands/InternalCommands.cpp +++ b/src/src/Commands/InternalCommands.cpp @@ -194,7 +194,7 @@ bool do_command_case_check(command_case_data & data, if (mustCheckNrArguments) { if (!checkNrArguments(data.cmd, data.line, nrArguments)) { data.status = return_incorrect_nr_arguments(); - data.retval = false; + //data.retval = false; return true; // Command is handled } } diff --git a/src/src/ControllerQueue/C015_queue_element.h b/src/src/ControllerQueue/C015_queue_element.h index 8b70fd305..825ad9eec 100644 --- a/src/src/ControllerQueue/C015_queue_element.h +++ b/src/src/ControllerQueue/C015_queue_element.h @@ -13,7 +13,7 @@ struct EventStruct; /*********************************************************************************************\ * C015_queue_element for queueing requests for 015: Blynk -* Using queue_element_single_value_base +* Using SimpleQueueElement_formatted_Strings \*********************************************************************************************/ class C015_queue_element { diff --git a/src/src/ControllerQueue/ControllerDelayHandlerStruct.h b/src/src/ControllerQueue/ControllerDelayHandlerStruct.h index cdb798108..ea36276bb 100644 --- a/src/src/ControllerQueue/ControllerDelayHandlerStruct.h +++ b/src/src/ControllerQueue/ControllerDelayHandlerStruct.h @@ -310,20 +310,16 @@ struct ControllerDelayHandlerStruct { void process_c##NNN####M##_delay_queue() { \ if (C##NNN####M##_DelayHandler == nullptr) return; \ C##NNN####M##_queue_element *element(C##NNN####M##_DelayHandler->getNext()); \ - if (element == nullptr) return; \ - MakeControllerSettings(ControllerSettings); \ - bool ready = true; \ - if (!AllocatedControllerSettings()) { \ - ready = false; \ - } else { \ - LoadControllerSettings(element->controller_idx, ControllerSettings); \ - C##NNN####M##_DelayHandler->configureControllerSettings(ControllerSettings); \ - if (!C##NNN####M##_DelayHandler->readyToProcess(*element)) { ready = false; } \ - } \ - if (ready) { \ - START_TIMER; \ - C##NNN####M##_DelayHandler->markProcessed(do_process_c##NNN####M##_delay_queue(M, *element, ControllerSettings)); \ - STOP_TIMER(C##NNN####M##_DELAY_QUEUE); \ + if (element == nullptr) return; \ + if (C##NNN####M##_DelayHandler->readyToProcess(*element)) { \ + MakeControllerSettings(ControllerSettings); \ + if (AllocatedControllerSettings()) { \ + LoadControllerSettings(element->controller_idx, ControllerSettings); \ + C##NNN####M##_DelayHandler->configureControllerSettings(ControllerSettings); \ + START_TIMER; \ + C##NNN####M##_DelayHandler->markProcessed(do_process_c##NNN####M##_delay_queue(M, *element, ControllerSettings)); \ + STOP_TIMER(C##NNN####M##_DELAY_QUEUE); \ + } \ } \ Scheduler.scheduleNextDelayQueue(ESPEasy_Scheduler::IntervalTimer_e::TIMER_C##NNN####M##_DELAY_QUEUE, C##NNN####M##_DelayHandler->getNextScheduleTime()); \ } \ diff --git a/src/src/ControllerQueue/DelayQueueElements.cpp b/src/src/ControllerQueue/DelayQueueElements.cpp index 17eec061d..62cc342a2 100644 --- a/src/src/ControllerQueue/DelayQueueElements.cpp +++ b/src/src/ControllerQueue/DelayQueueElements.cpp @@ -46,7 +46,6 @@ void exit_mqtt_delay_queue() { * C001_queue_element for queueing requests for C001. \*********************************************************************************************/ #ifdef USES_C001 -# define C001_queue_element simple_queue_element_string_only DEFINE_Cxxx_DELAY_QUEUE_MACRO_CPP(00, 1) // -V522 #endif // ifdef USES_C001 @@ -54,7 +53,6 @@ DEFINE_Cxxx_DELAY_QUEUE_MACRO_CPP(00, 1) // -V522 * C003_queue_element for queueing requests for C003 Nodo Telnet. \*********************************************************************************************/ #ifdef USES_C003 -# define C003_queue_element simple_queue_element_string_only DEFINE_Cxxx_DELAY_QUEUE_MACRO_CPP(00, 3) // -V522 #endif // ifdef USES_C003 @@ -63,7 +61,6 @@ DEFINE_Cxxx_DELAY_QUEUE_MACRO_CPP(00, 4) // -V522 #endif // ifdef USES_C004 #ifdef USES_C007 -# define C007_queue_element queue_element_formatted_uservar DEFINE_Cxxx_DELAY_QUEUE_MACRO_CPP(00, 7) // -V522 #endif // ifdef USES_C007 @@ -71,25 +68,22 @@ DEFINE_Cxxx_DELAY_QUEUE_MACRO_CPP(00, 7) // -V522 /*********************************************************************************************\ * C008_queue_element for queueing requests for 008: Generic HTTP -* Using queue_element_single_value_base +* Using SimpleQueueElement_formatted_Strings \*********************************************************************************************/ #ifdef USES_C008 -# define C008_queue_element queue_element_single_value_base DEFINE_Cxxx_DELAY_QUEUE_MACRO_CPP(00, 8) // -V522 #endif // ifdef USES_C008 #ifdef USES_C009 -# define C009_queue_element queue_element_formatted_uservar DEFINE_Cxxx_DELAY_QUEUE_MACRO_CPP(00, 9) // -V522 #endif // ifdef USES_C009 /*********************************************************************************************\ * C010_queue_element for queueing requests for 010: Generic UDP -* Using queue_element_single_value_base +* Using SimpleQueueElement_formatted_Strings \*********************************************************************************************/ #ifdef USES_C010 -# define C010_queue_element queue_element_single_value_base DEFINE_Cxxx_DELAY_QUEUE_MACRO_CPP( 0, 10) // -V522 #endif // ifdef USES_C010 @@ -105,10 +99,9 @@ DEFINE_Cxxx_DELAY_QUEUE_MACRO_CPP( 0, 11) // -V522 /*********************************************************************************************\ * C012_queue_element for queueing requests for 012: Blynk -* Using queue_element_single_value_base +* Using SimpleQueueElement_formatted_Strings \*********************************************************************************************/ #ifdef USES_C012 -# define C012_queue_element queue_element_single_value_base DEFINE_Cxxx_DELAY_QUEUE_MACRO_CPP( 0, 12) // -V522 #endif // ifdef USES_C012 diff --git a/src/src/ControllerQueue/DelayQueueElements.h b/src/src/ControllerQueue/DelayQueueElements.h index e0e9f74d9..a56cd96ac 100644 --- a/src/src/ControllerQueue/DelayQueueElements.h +++ b/src/src/ControllerQueue/DelayQueueElements.h @@ -54,14 +54,14 @@ DEFINE_Cxxx_DELAY_QUEUE_MACRO(00, 3) #endif // ifdef USES_C003 #ifdef USES_C004 -# include "../ControllerQueue/queue_element_formatted_uservar.h" -# define C004_queue_element queue_element_formatted_uservar +#include "../ControllerQueue/SimpleQueueElement_formatted_Strings.h" +# define C004_queue_element SimpleQueueElement_formatted_Strings DEFINE_Cxxx_DELAY_QUEUE_MACRO(00, 4) #endif // ifdef USES_C004 #ifdef USES_C007 -# include "../ControllerQueue/queue_element_formatted_uservar.h" -# define C007_queue_element queue_element_formatted_uservar +#include "../ControllerQueue/SimpleQueueElement_formatted_Strings.h" +# define C007_queue_element SimpleQueueElement_formatted_Strings DEFINE_Cxxx_DELAY_QUEUE_MACRO(00, 7) #endif // ifdef USES_C007 @@ -69,28 +69,28 @@ DEFINE_Cxxx_DELAY_QUEUE_MACRO(00, 7) /*********************************************************************************************\ * C008_queue_element for queueing requests for 008: Generic HTTP -* Using queue_element_single_value_base +* Using SimpleQueueElement_formatted_Strings \*********************************************************************************************/ #ifdef USES_C008 -#include "../ControllerQueue/queue_element_single_value_base.h" -# define C008_queue_element queue_element_single_value_base +#include "../ControllerQueue/SimpleQueueElement_formatted_Strings.h" +# define C008_queue_element SimpleQueueElement_formatted_Strings DEFINE_Cxxx_DELAY_QUEUE_MACRO(00, 8) #endif // ifdef USES_C008 #ifdef USES_C009 -# include "../ControllerQueue/queue_element_formatted_uservar.h" -# define C009_queue_element queue_element_formatted_uservar +#include "../ControllerQueue/SimpleQueueElement_formatted_Strings.h" +# define C009_queue_element SimpleQueueElement_formatted_Strings DEFINE_Cxxx_DELAY_QUEUE_MACRO(00, 9) #endif // ifdef USES_C009 /*********************************************************************************************\ * C010_queue_element for queueing requests for 010: Generic UDP -* Using queue_element_single_value_base +* Using SimpleQueueElement_formatted_Strings \*********************************************************************************************/ #ifdef USES_C010 -#include "../ControllerQueue/queue_element_single_value_base.h" -# define C010_queue_element queue_element_single_value_base +#include "../ControllerQueue/SimpleQueueElement_formatted_Strings.h" +# define C010_queue_element SimpleQueueElement_formatted_Strings DEFINE_Cxxx_DELAY_QUEUE_MACRO( 0, 10) #endif // ifdef USES_C010 @@ -107,11 +107,11 @@ DEFINE_Cxxx_DELAY_QUEUE_MACRO( 0, 11) /*********************************************************************************************\ * C012_queue_element for queueing requests for 012: Blynk -* Using queue_element_single_value_base +* Using SimpleQueueElement_formatted_Strings \*********************************************************************************************/ #ifdef USES_C012 -#include "../ControllerQueue/queue_element_single_value_base.h" -# define C012_queue_element queue_element_single_value_base +#include "../ControllerQueue/SimpleQueueElement_formatted_Strings.h" +# define C012_queue_element SimpleQueueElement_formatted_Strings DEFINE_Cxxx_DELAY_QUEUE_MACRO( 0, 12) #endif // ifdef USES_C012 @@ -142,8 +142,8 @@ DEFINE_Cxxx_DELAY_QUEUE_MACRO(0, 16) #ifdef USES_C017 -# include "../ControllerQueue/queue_element_formatted_uservar.h" -# define C017_queue_element queue_element_formatted_uservar +# include "../ControllerQueue/SimpleQueueElement_formatted_Strings.h" +# define C017_queue_element SimpleQueueElement_formatted_Strings DEFINE_Cxxx_DELAY_QUEUE_MACRO(0, 17) #endif // ifdef USES_C017 diff --git a/src/src/ControllerQueue/SimpleQueueElement_formatted_Strings.cpp b/src/src/ControllerQueue/SimpleQueueElement_formatted_Strings.cpp new file mode 100644 index 000000000..dada39c1f --- /dev/null +++ b/src/src/ControllerQueue/SimpleQueueElement_formatted_Strings.cpp @@ -0,0 +1,102 @@ +#include "../ControllerQueue/SimpleQueueElement_formatted_Strings.h" + +#include "../DataStructs/ESPEasy_EventStruct.h" +#include "../Helpers/StringConverter.h" + +#include "../../_Plugin_Helper.h" + + +SimpleQueueElement_formatted_Strings::SimpleQueueElement_formatted_Strings(struct EventStruct *event) : + idx(event->idx), + TaskIndex(event->TaskIndex), + controller_idx(event->ControllerIndex), + sensorType(event->sensorType), + valuesSent(0) +{ + #ifdef USE_SECOND_HEAP + HeapSelectIram ephemeral; + #endif + + valueCount = getValueCountForTask(TaskIndex); + + for (uint8_t i = 0; i < valueCount; ++i) { + txt[i] = formatUserVarNoCheck(event, i); + } +} + +SimpleQueueElement_formatted_Strings::SimpleQueueElement_formatted_Strings(const struct EventStruct *event, uint8_t value_count) : + idx(event->idx), + TaskIndex(event->TaskIndex), + controller_idx(event->ControllerIndex), + sensorType(event->sensorType), + valuesSent(0), + valueCount(value_count) {} + +SimpleQueueElement_formatted_Strings::SimpleQueueElement_formatted_Strings(SimpleQueueElement_formatted_Strings&& rval) + : idx(rval.idx), _timestamp(rval._timestamp), TaskIndex(rval.TaskIndex), + controller_idx(rval.controller_idx), sensorType(rval.sensorType), + valuesSent(rval.valuesSent), valueCount(rval.valueCount) +{ + #ifdef USE_SECOND_HEAP + HeapSelectIram ephemeral; + #endif + + for (uint8_t i = 0; i < VARS_PER_TASK; ++i) { + txt[i] = std::move(rval.txt[i]); + } +} + +SimpleQueueElement_formatted_Strings& SimpleQueueElement_formatted_Strings::operator=(SimpleQueueElement_formatted_Strings&& rval) { + idx = rval.idx; + _timestamp = rval._timestamp; + TaskIndex = rval.TaskIndex; + controller_idx = rval.controller_idx; + sensorType = rval.sensorType; + valuesSent = rval.valuesSent; + valueCount = rval.valueCount; + + for (size_t i = 0; i < VARS_PER_TASK; ++i) { + #ifdef USE_SECOND_HEAP + HeapSelectIram ephemeral; + if (rval.txt[i].length() && !mmu_is_iram(&(rval.txt[i][0]))) { + txt[i] = rval.txt[i]; + } else { + txt[i] = std::move(rval.txt[i]); + } + #else + txt[i] = std::move(rval.txt[i]); + #endif // ifdef USE_SECOND_HEAP + } + return *this; +} + +bool SimpleQueueElement_formatted_Strings::checkDone(bool succesfull) const { + if (succesfull) { ++valuesSent; } + return valuesSent >= valueCount || valuesSent >= VARS_PER_TASK; +} + +size_t SimpleQueueElement_formatted_Strings::getSize() const { + size_t total = sizeof(*this); + + for (int i = 0; i < VARS_PER_TASK; ++i) { + total += txt[i].length(); + } + return total; +} + +bool SimpleQueueElement_formatted_Strings::isDuplicate(const SimpleQueueElement_formatted_Strings& rval) const { + if ((rval.controller_idx != controller_idx) || + (rval.TaskIndex != TaskIndex) || + (rval.sensorType != sensorType) || + (rval.valueCount != valueCount) || + (rval.idx != idx)) { + return false; + } + + for (uint8_t i = 0; i < VARS_PER_TASK; ++i) { + if (rval.txt[i] != txt[i]) { + return false; + } + } + return true; +} diff --git a/src/src/ControllerQueue/SimpleQueueElement_formatted_Strings.h b/src/src/ControllerQueue/SimpleQueueElement_formatted_Strings.h new file mode 100644 index 000000000..833f5e649 --- /dev/null +++ b/src/src/ControllerQueue/SimpleQueueElement_formatted_Strings.h @@ -0,0 +1,64 @@ +#ifndef CONTROLQUEUE_QUEUE_ELEMENT_SINGLE_VALUE_BASE_H +#define CONTROLQUEUE_QUEUE_ELEMENT_SINGLE_VALUE_BASE_H + + +#include "../../ESPEasy_common.h" +#include "../CustomBuild/ESPEasyLimits.h" +#include "../DataStructs/DeviceStruct.h" +#include "../DataStructs/UnitMessageCount.h" +#include "../Globals/CPlugins.h" +#include "../Globals/Plugins.h" + +struct EventStruct; + +/*********************************************************************************************\ +* Base element class for keeping task value strings in a controller queue +* Can also be used for controllers only sending a single value at a time. +\*********************************************************************************************/ +class SimpleQueueElement_formatted_Strings { +public: + + SimpleQueueElement_formatted_Strings() = default; + + // Constructor formatting the task values using the default formatter + SimpleQueueElement_formatted_Strings(struct EventStruct *event); + + // Constructor not formatting the values + SimpleQueueElement_formatted_Strings(const struct EventStruct *event, + uint8_t value_count); + + +#ifdef USE_SECOND_HEAP + SimpleQueueElement_formatted_Strings(const SimpleQueueElement_formatted_Strings& rval) = default; +#else + SimpleQueueElement_formatted_Strings(const SimpleQueueElement_formatted_Strings& rval) = delete; +#endif + + SimpleQueueElement_formatted_Strings(SimpleQueueElement_formatted_Strings&& rval); + + SimpleQueueElement_formatted_Strings& operator=(SimpleQueueElement_formatted_Strings&& other); + + + // For controllers that only send a single value per request and thus need to keep track of the number of values already sent. + bool checkDone(bool succesfull) const; + + size_t getSize() const; + + bool isDuplicate(const SimpleQueueElement_formatted_Strings& other) const; + + const UnitMessageCount_t * getUnitMessageCount() const { + return nullptr; + } + + String txt[VARS_PER_TASK]; + int idx = 0; + unsigned long _timestamp = millis(); + taskIndex_t TaskIndex = INVALID_TASK_INDEX; + controllerIndex_t controller_idx = INVALID_CONTROLLER_INDEX; + Sensor_VType sensorType = Sensor_VType::SENSOR_TYPE_NONE; + mutable uint8_t valuesSent = 0; // Value must be set by const function checkDone() + uint8_t valueCount = 0; +}; + + +#endif // CONTROLQUEUE_QUEUE_ELEMENT_SINGLE_VALUE_BASE_H diff --git a/src/src/ControllerQueue/queue_element_formatted_uservar.cpp b/src/src/ControllerQueue/queue_element_formatted_uservar.cpp deleted file mode 100644 index afd52778a..000000000 --- a/src/src/ControllerQueue/queue_element_formatted_uservar.cpp +++ /dev/null @@ -1,89 +0,0 @@ -#include "../ControllerQueue/queue_element_formatted_uservar.h" - -#include "../DataStructs/ESPEasy_EventStruct.h" -#include "../Helpers/StringConverter.h" -#include "../../_Plugin_Helper.h" - - -queue_element_formatted_uservar::queue_element_formatted_uservar(queue_element_formatted_uservar&& other) - : - idx(other.idx), - _timestamp(other._timestamp), - TaskIndex(other.TaskIndex), - controller_idx(other.controller_idx), - sensorType(other.sensorType), - valueCount(other.valueCount) -{ - #ifdef USE_SECOND_HEAP - HeapSelectIram ephemeral; - #endif - - for (size_t i = 0; i < VARS_PER_TASK; ++i) { - txt[i] = std::move(other.txt[i]); - } -} - -queue_element_formatted_uservar::queue_element_formatted_uservar(EventStruct *event) : - idx(event->idx), - TaskIndex(event->TaskIndex), - controller_idx(event->ControllerIndex), - sensorType(event->sensorType) -{ - #ifdef USE_SECOND_HEAP - HeapSelectIram ephemeral; - #endif - - valueCount = getValueCountForTask(TaskIndex); - - for (uint8_t i = 0; i < valueCount; ++i) { - txt[i] = formatUserVarNoCheck(event, i); - } -} - -queue_element_formatted_uservar& queue_element_formatted_uservar::operator=(queue_element_formatted_uservar&& other) { - idx = other.idx; - _timestamp = other._timestamp; - TaskIndex = other.TaskIndex; - controller_idx = other.controller_idx; - sensorType = other.sensorType; - valueCount = other.valueCount; - - for (size_t i = 0; i < VARS_PER_TASK; ++i) { - #ifdef USE_SECOND_HEAP - HeapSelectIram ephemeral; - if (other.txt[i].length() && !mmu_is_iram(&(other.txt[i][0]))) { - txt[i] = other.txt[i]; - } else { - txt[i] = std::move(other.txt[i]); - } - #else - txt[i] = std::move(other.txt[i]); - #endif // ifdef USE_SECOND_HEAP - } - return *this; -} - -size_t queue_element_formatted_uservar::getSize() const { - size_t total = sizeof(*this); - - for (int i = 0; i < VARS_PER_TASK; ++i) { - total += txt[i].length(); - } - return total; -} - -bool queue_element_formatted_uservar::isDuplicate(const queue_element_formatted_uservar& other) const { - if ((other.controller_idx != controller_idx) || - (other.TaskIndex != TaskIndex) || - (other.sensorType != sensorType) || - (other.valueCount != valueCount)) { - return false; - } - - for (uint8_t i = 0; i < VARS_PER_TASK; ++i) { - if (other.txt[i] != txt[i]) { - return false; - } - } - return true; -} diff --git a/src/src/ControllerQueue/queue_element_formatted_uservar.h b/src/src/ControllerQueue/queue_element_formatted_uservar.h deleted file mode 100644 index cd3d6136c..000000000 --- a/src/src/ControllerQueue/queue_element_formatted_uservar.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef CONTROLLERQUEUE_QUEUE_ELEMENT_FORMATTED_USERVAR_H -#define CONTROLLERQUEUE_QUEUE_ELEMENT_FORMATTED_USERVAR_H - -#include "../../ESPEasy_common.h" -#include "../DataStructs/DeviceStruct.h" -#include "../DataStructs/UnitMessageCount.h" -#include "../Globals/CPlugins.h" -#include "../Globals/Plugins.h" - - -struct EventStruct; - -/*********************************************************************************************\ -* For queueing task values already formatted according to the task settings -\*********************************************************************************************/ -class queue_element_formatted_uservar { -public: - - queue_element_formatted_uservar() = default; - -#ifdef USE_SECOND_HEAP - queue_element_formatted_uservar(const queue_element_formatted_uservar& other) = default; -#else - queue_element_formatted_uservar(const queue_element_formatted_uservar& other) = delete; -#endif - - queue_element_formatted_uservar(queue_element_formatted_uservar&& other); - - queue_element_formatted_uservar(struct EventStruct *event); - - queue_element_formatted_uservar& operator=(queue_element_formatted_uservar&& other); - - size_t getSize() const; - - bool isDuplicate(const queue_element_formatted_uservar& other) const; - - const UnitMessageCount_t * getUnitMessageCount() const { - return nullptr; - } - - String txt[VARS_PER_TASK]; - int idx = 0; - unsigned long _timestamp = millis(); - taskIndex_t TaskIndex = INVALID_TASK_INDEX; - controllerIndex_t controller_idx = INVALID_CONTROLLER_INDEX; - Sensor_VType sensorType = Sensor_VType::SENSOR_TYPE_NONE; - uint8_t valueCount = 0; -}; - -#endif // CONTROLLERQUEUE_QUEUE_ELEMENT_FORMATTED_USERVAR_H diff --git a/src/src/ControllerQueue/queue_element_single_value_base.cpp b/src/src/ControllerQueue/queue_element_single_value_base.cpp deleted file mode 100644 index f000dd318..000000000 --- a/src/src/ControllerQueue/queue_element_single_value_base.cpp +++ /dev/null @@ -1,71 +0,0 @@ -#include "../ControllerQueue/queue_element_single_value_base.h" - -#include "../DataStructs/ESPEasy_EventStruct.h" - -queue_element_single_value_base::queue_element_single_value_base(const struct EventStruct *event, uint8_t value_count) : - idx(event->idx), - TaskIndex(event->TaskIndex), - controller_idx(event->ControllerIndex), - valuesSent(0), - valueCount(value_count) {} - -queue_element_single_value_base::queue_element_single_value_base(queue_element_single_value_base&& rval) - : idx(rval.idx), _timestamp(rval._timestamp), TaskIndex(rval.TaskIndex), - controller_idx(rval.controller_idx), - valuesSent(rval.valuesSent), valueCount(rval.valueCount) -{ - #ifdef USE_SECOND_HEAP - HeapSelectIram ephemeral; - #endif - - for (uint8_t i = 0; i < VARS_PER_TASK; ++i) { - txt[i] = std::move(rval.txt[i]); - } -} - -queue_element_single_value_base& queue_element_single_value_base::operator=(queue_element_single_value_base&& rval) { - idx = rval.idx; - _timestamp = rval._timestamp; - TaskIndex = rval.TaskIndex; - controller_idx = rval.controller_idx; - valuesSent = rval.valuesSent; - valueCount = rval.valueCount; - #ifdef USE_SECOND_HEAP - HeapSelectIram ephemeral; - #endif // ifdef USE_SECOND_HEAP - - for (uint8_t i = 0; i < VARS_PER_TASK; ++i) { - txt[i] = std::move(rval.txt[i]); - } - return *this; -} - -bool queue_element_single_value_base::checkDone(bool succesfull) const { - if (succesfull) { ++valuesSent; } - return valuesSent >= valueCount || valuesSent >= VARS_PER_TASK; -} - -size_t queue_element_single_value_base::getSize() const { - size_t total = sizeof(*this); - - for (int i = 0; i < VARS_PER_TASK; ++i) { - total += txt[i].length(); - } - return total; -} - -bool queue_element_single_value_base::isDuplicate(const queue_element_single_value_base& other) const { - if ((other.controller_idx != controller_idx) || - (other.TaskIndex != TaskIndex) || - (other.valueCount != valueCount) || - (other.idx != idx)) { - return false; - } - - for (uint8_t i = 0; i < VARS_PER_TASK; ++i) { - if (other.txt[i] != txt[i]) { - return false; - } - } - return true; -} diff --git a/src/src/ControllerQueue/queue_element_single_value_base.h b/src/src/ControllerQueue/queue_element_single_value_base.h deleted file mode 100644 index bbe18d164..000000000 --- a/src/src/ControllerQueue/queue_element_single_value_base.h +++ /dev/null @@ -1,56 +0,0 @@ -#ifndef CONTROLQUEUE_QUEUE_ELEMENT_SINGLE_VALUE_BASE_H -#define CONTROLQUEUE_QUEUE_ELEMENT_SINGLE_VALUE_BASE_H - - -#include "../../ESPEasy_common.h" -#include "../CustomBuild/ESPEasyLimits.h" -#include "../DataStructs/UnitMessageCount.h" -#include "../Globals/CPlugins.h" -#include "../Globals/Plugins.h" - -struct EventStruct; - -/*********************************************************************************************\ -* Base class for controllers that only send a single value per request and thus needs to -* keep track of the number of values already sent. -\*********************************************************************************************/ -class queue_element_single_value_base { -public: - - queue_element_single_value_base() = default; - - queue_element_single_value_base(const struct EventStruct *event, - uint8_t value_count); - -#ifdef USE_SECOND_HEAP - queue_element_single_value_base(const queue_element_single_value_base& rval) = default; -#else - queue_element_single_value_base(const queue_element_single_value_base& rval) = delete; -#endif - - queue_element_single_value_base(queue_element_single_value_base&& rval); - - queue_element_single_value_base& operator=(queue_element_single_value_base&& other); - - - bool checkDone(bool succesfull) const; - - size_t getSize() const; - - bool isDuplicate(const queue_element_single_value_base& other) const; - - const UnitMessageCount_t * getUnitMessageCount() const { - return nullptr; - } - - String txt[VARS_PER_TASK]; - int idx = 0; - unsigned long _timestamp = millis(); - taskIndex_t TaskIndex = INVALID_TASK_INDEX; - controllerIndex_t controller_idx = INVALID_CONTROLLER_INDEX; - mutable uint8_t valuesSent = 0; // Value must be set by const function checkDone() - uint8_t valueCount = 0; -}; - - -#endif // CONTROLQUEUE_QUEUE_ELEMENT_SINGLE_VALUE_BASE_H diff --git a/src/src/CustomBuild/ESPEasyDefaults.h b/src/src/CustomBuild/ESPEasyDefaults.h index 29d9a78b2..898a3b147 100644 --- a/src/src/CustomBuild/ESPEasyDefaults.h +++ b/src/src/CustomBuild/ESPEasyDefaults.h @@ -309,7 +309,7 @@ #endif #ifndef DEFAULT_SYNC_UDP_PORT -#define DEFAULT_SYNC_UDP_PORT 0 // Used for ESPEasy p2p. (IANA registered port: 8266) +#define DEFAULT_SYNC_UDP_PORT 8266 // Used for ESPEasy p2p. (IANA registered port: 8266) #endif // --- Defaults to be used for custom automatic provisioning builds ------------------------------------ diff --git a/src/src/CustomBuild/define_plugin_sets.h b/src/src/CustomBuild/define_plugin_sets.h index 11f3d611f..5f979033e 100644 --- a/src/src/CustomBuild/define_plugin_sets.h +++ b/src/src/CustomBuild/define_plugin_sets.h @@ -1243,6 +1243,9 @@ To create/register a plugin, you have to : #ifndef USES_P115 #define USES_P115 // Fuel Gauge MAX1704x #endif + #ifndef USES_P132 + #define USES_P132 // INA3221 + #endif #endif // Collection of all display plugins. (also NeoPixel) @@ -1541,7 +1544,7 @@ To create/register a plugin, you have to : // #define USES_P131 // #endif #ifndef USES_P132 -// #define USES_P132 // + #define USES_P132 // INA3221 #endif #ifndef USES_P133 // #define USES_P133 // diff --git a/src/src/DataStructs_templ/SettingsStruct.cpp b/src/src/DataStructs_templ/SettingsStruct.cpp index a8367929a..28425d28c 100644 --- a/src/src/DataStructs_templ/SettingsStruct.cpp +++ b/src/src/DataStructs_templ/SettingsStruct.cpp @@ -11,7 +11,7 @@ #define DATASTRUCTS_SETTINGSSTRUCT_CPP template -SettingsStruct_tmpl::SettingsStruct_tmpl() : ResetFactoryDefaultPreference(0) { +SettingsStruct_tmpl::SettingsStruct_tmpl() : ResetFactoryDefaultPreference(0) { //-V730 clearAll(); clearNetworkSettings(); } diff --git a/src/src/ESPEasyCore/ESPEasyGPIO.cpp b/src/src/ESPEasyCore/ESPEasyGPIO.cpp index 8ef57cff2..e3bc0aaf1 100644 --- a/src/src/ESPEasyCore/ESPEasyGPIO.cpp +++ b/src/src/ESPEasyCore/ESPEasyGPIO.cpp @@ -456,7 +456,7 @@ void GPIO_Monitor10xSec() it->second.state = currentState; //update state ONLY if task flag=false otherwise it will not be picked up by 10xSEC function // send event if not task, otherwise is sent in the task PLUGIN_TEN_PER_SECOND if (it->second.monitor) { - sendMonitorEvent(String(eventString).c_str(), gpioPort, currentState); + sendMonitorEvent(eventString, gpioPort, currentState); } } } @@ -467,7 +467,7 @@ void GPIO_Monitor10xSec() } // prefix should be either "GPIO", "PCF", "MCP" -void sendMonitorEvent(const char* prefix, int port, int8_t state) +void sendMonitorEvent(const __FlashStringHelper * prefix, int port, int8_t state) { String eventString = prefix; eventString += '#'; diff --git a/src/src/ESPEasyCore/ESPEasyGPIO.h b/src/src/ESPEasyCore/ESPEasyGPIO.h index 540f89264..47119777d 100644 --- a/src/src/ESPEasyCore/ESPEasyGPIO.h +++ b/src/src/ESPEasyCore/ESPEasyGPIO.h @@ -67,7 +67,7 @@ void GPIO_PCF_WriteAllPins(uint8_t Par1, uint8_t Par2); void GPIO_Monitor10xSec(); // prefix should be either "GPIO", "PCF", "MCP" -void sendMonitorEvent(const char* prefix, int port, int8_t state); +void sendMonitorEvent(const __FlashStringHelper * prefix, int port, int8_t state); bool checkValidPortRange(pluginID_t pluginID, int port); bool checkValidPortAddress(pluginID_t pluginID, uint8_t address); diff --git a/src/src/Helpers/ESPEasy_time.cpp b/src/src/Helpers/ESPEasy_time.cpp index 0c623e89f..d2b79138c 100644 --- a/src/src/Helpers/ESPEasy_time.cpp +++ b/src/src/Helpers/ESPEasy_time.cpp @@ -493,42 +493,45 @@ String ESPEasy_time::getDateString(const struct tm& ts, char delimiter) { return DateString; } -String ESPEasy_time::getTimeString(char delimiter, bool show_seconds /*=true*/) const +String ESPEasy_time::getTimeString(char delimiter, bool show_seconds /*=true*/, char hour_prefix /*='\0'*/) const { - return getTimeString(tm, delimiter, false, show_seconds); + return getTimeString(tm, delimiter, false, show_seconds, hour_prefix); } -String ESPEasy_time::getTimeString_ampm(char delimiter, bool show_seconds /*=true*/) const +String ESPEasy_time::getTimeString_ampm(char delimiter, bool show_seconds /*=true*/, char hour_prefix /*='\0'*/) const { - return getTimeString(tm, delimiter, true, show_seconds); + return getTimeString(tm, delimiter, true, show_seconds, hour_prefix); } // returns the current Time separated by the given delimiter // time format example with ':' delimiter: 23:59:59 (HH:MM:SS) -String ESPEasy_time::getTimeString(const struct tm& ts, char delimiter, bool am_pm, bool show_seconds) +String ESPEasy_time::getTimeString(const struct tm& ts, char delimiter, bool am_pm, bool show_seconds, char hour_prefix /*='\0'*/) { char TimeString[20]; // 19 digits plus the null char + char hour_prefix_s[2] = { 0 }; if (am_pm) { uint8_t hour(ts.tm_hour % 12); if (hour == 0) { hour = 12; } const char a_or_p = ts.tm_hour < 12 ? 'A' : 'P'; + if (hour < 10) { hour_prefix_s[0] = hour_prefix; } if (show_seconds) { - sprintf_P(TimeString, PSTR("%d%c%02d%c%02d %cM"), - hour, delimiter, ts.tm_min, delimiter, ts.tm_sec, a_or_p); + sprintf_P(TimeString, PSTR("%s%d%c%02d%c%02d %cM"), + hour_prefix_s, hour, delimiter, ts.tm_min, delimiter, ts.tm_sec, a_or_p); } else { - sprintf_P(TimeString, PSTR("%d%c%02d %cM"), - hour, delimiter, ts.tm_min, a_or_p); + sprintf_P(TimeString, PSTR("%s%d%c%02d %cM"), + hour_prefix_s, hour, delimiter, ts.tm_min, a_or_p); } } else { if (show_seconds) { sprintf_P(TimeString, PSTR("%02d%c%02d%c%02d"), ts.tm_hour, delimiter, ts.tm_min, delimiter, ts.tm_sec); } else { - sprintf_P(TimeString, PSTR("%d%c%02d"), - ts.tm_hour, delimiter, ts.tm_min); + if (ts.tm_hour < 10) { hour_prefix_s[0] = hour_prefix; } + sprintf_P(TimeString, PSTR("%s%d%c%02d"), + hour_prefix_s, ts.tm_hour, delimiter, ts.tm_min); } } return TimeString; diff --git a/src/src/Helpers/ESPEasy_time.h b/src/src/Helpers/ESPEasy_time.h index 306aec573..ef8da1c79 100644 --- a/src/src/Helpers/ESPEasy_time.h +++ b/src/src/Helpers/ESPEasy_time.h @@ -67,13 +67,13 @@ static String getDateString(const struct tm& ts, char delimiter); // Formats the current Time // Default time format example: 235959 (HHMMSS) -String getTimeString(char delimiter = '\0', bool show_seconds=true) const; +String getTimeString(char delimiter = '\0', bool show_seconds = true, char hour_prefix = '\0') const; -String getTimeString_ampm(char delimiter = '\0', bool show_seconds=true) const; +String getTimeString_ampm(char delimiter = '\0', bool show_seconds = true, char hour_prefix = '\0') const; // returns the current Time separated by the given delimiter // time format example with ':' delimiter: 23:59:59 (HH:MM:SS) -static String getTimeString(const struct tm& ts, char delimiter, bool am_pm, bool show_seconds); +static String getTimeString(const struct tm& ts, char delimiter, bool am_pm, bool show_seconds, char hour_prefix = '\0'); diff --git a/src/src/Helpers/SystemVariables.cpp b/src/src/Helpers/SystemVariables.cpp index 5b39977f6..8cc8eb50d 100644 --- a/src/src/Helpers/SystemVariables.cpp +++ b/src/src/Helpers/SystemVariables.cpp @@ -70,56 +70,63 @@ String timeReplacement_leadZero(int value) } // FIXME TD-er: Try to match these with StringProvider::getValue - - -String SystemVariables::getSystemVariable(SystemVariables::Enum enumval) { +LabelType::Enum SystemVariables2LabelType(SystemVariables::Enum enumval) { LabelType::Enum label = LabelType::MAX_LABEL; - switch (enumval) { - case IP: label = LabelType::IP_ADDRESS; break; - case SUBNET: label = LabelType::IP_SUBNET; break; - case DNS: label = LabelType::DNS; break; - case DNS_1: label = LabelType::DNS_1; break; - case DNS_2: label = LabelType::DNS_2; break; - case GATEWAY: label = LabelType::GATEWAY; break; - case CLIENTIP: label = LabelType::CLIENT_IP; break; + case SystemVariables::IP: label = LabelType::IP_ADDRESS; break; + case SystemVariables::SUBNET: label = LabelType::IP_SUBNET; break; + case SystemVariables::DNS: label = LabelType::DNS; break; + case SystemVariables::DNS_1: label = LabelType::DNS_1; break; + case SystemVariables::DNS_2: label = LabelType::DNS_2; break; + case SystemVariables::GATEWAY: label = LabelType::GATEWAY; break; + case SystemVariables::CLIENTIP: label = LabelType::CLIENT_IP; break; #ifdef HAS_ETHERNET - case ETHWIFIMODE: label = LabelType::ETH_WIFI_MODE; break; // 0=WIFI, 1=ETH - case ETHCONNECTED: label = LabelType::ETH_CONNECTED; break; // 0=disconnected, 1=connected - case ETHDUPLEX: label = LabelType::ETH_DUPLEX; break; - case ETHSPEED: label = LabelType::ETH_SPEED; break; - case ETHSTATE: label = LabelType::ETH_STATE; break; - case ETHSPEEDSTATE: label = LabelType::ETH_SPEED_STATE; break; + case SystemVariables::ETHWIFIMODE: label = LabelType::ETH_WIFI_MODE; break; // 0=WIFI, 1=ETH + case SystemVariables::ETHCONNECTED: label = LabelType::ETH_CONNECTED; break; // 0=disconnected, 1=connected + case SystemVariables::ETHDUPLEX: label = LabelType::ETH_DUPLEX; break; + case SystemVariables::ETHSPEED: label = LabelType::ETH_SPEED; break; + case SystemVariables::ETHSTATE: label = LabelType::ETH_STATE; break; + case SystemVariables::ETHSPEEDSTATE: label = LabelType::ETH_SPEED_STATE; break; #endif // ifdef HAS_ETHERNET - case LCLTIME: label = LabelType::LOCAL_TIME; break; - case MAC: label = LabelType::STA_MAC; break; - case RSSI: label = LabelType::WIFI_RSSI; break; - case SUNRISE_S: label = LabelType::SUNRISE_S; break; - case SUNSET_S: label = LabelType::SUNSET_S; break; - case SUNRISE_M: label = LabelType::SUNRISE_M; break; - case SUNSET_M: label = LabelType::SUNSET_M; break; - case SYSBUILD_DESCR: label = LabelType::BUILD_DESC; break; - case SYSBUILD_FILENAME: label = LabelType::BINARY_FILENAME; break; - case SYSBUILD_GIT: label = LabelType::GIT_BUILD; break; - case SYSSTACK: label = LabelType::FREE_STACK; break; - case UNIT_sysvar: label = LabelType::UNIT_NR; break; - case FLASH_FREQ: label = LabelType::FLASH_CHIP_SPEED; break; - case FLASH_SIZE: label = LabelType::FLASH_CHIP_REAL_SIZE; break; - case FLASH_CHIP_VENDOR: label = LabelType::FLASH_CHIP_VENDOR; break; - case FLASH_CHIP_MODEL: label = LabelType::FLASH_CHIP_MODEL; break; - case FS_SIZE: label = LabelType::FS_SIZE; break; - case FS_FREE: label = LabelType::FS_FREE; break; + case SystemVariables::LCLTIME: label = LabelType::LOCAL_TIME; break; + case SystemVariables::MAC: label = LabelType::STA_MAC; break; + case SystemVariables::RSSI: label = LabelType::WIFI_RSSI; break; + case SystemVariables::SUNRISE_S: label = LabelType::SUNRISE_S; break; + case SystemVariables::SUNSET_S: label = LabelType::SUNSET_S; break; + case SystemVariables::SUNRISE_M: label = LabelType::SUNRISE_M; break; + case SystemVariables::SUNSET_M: label = LabelType::SUNSET_M; break; + case SystemVariables::SYSBUILD_DESCR: label = LabelType::BUILD_DESC; break; + case SystemVariables::SYSBUILD_FILENAME: label = LabelType::BINARY_FILENAME; break; + case SystemVariables::SYSBUILD_GIT: label = LabelType::GIT_BUILD; break; + case SystemVariables::SYSSTACK: label = LabelType::FREE_STACK; break; + case SystemVariables::UNIT_sysvar: label = LabelType::UNIT_NR; break; + case SystemVariables::FLASH_FREQ: label = LabelType::FLASH_CHIP_SPEED; break; + case SystemVariables::FLASH_SIZE: label = LabelType::FLASH_CHIP_REAL_SIZE; break; + case SystemVariables::FLASH_CHIP_VENDOR: label = LabelType::FLASH_CHIP_VENDOR; break; + case SystemVariables::FLASH_CHIP_MODEL: label = LabelType::FLASH_CHIP_MODEL; break; + case SystemVariables::FS_SIZE: label = LabelType::FS_SIZE; break; + case SystemVariables::FS_FREE: label = LabelType::FS_FREE; break; - case ESP_CHIP_ID: label = LabelType::ESP_CHIP_ID; break; - case ESP_CHIP_FREQ: label = LabelType::ESP_CHIP_FREQ; break; - case ESP_CHIP_MODEL: label = LabelType::ESP_CHIP_MODEL; break; - case ESP_CHIP_REVISION: label = LabelType::ESP_CHIP_REVISION; break; - case ESP_CHIP_CORES: label = LabelType::ESP_CHIP_CORES; break; - case ESP_BOARD_NAME: label = LabelType::ESP_BOARD_NAME; break; + case SystemVariables::ESP_CHIP_ID: label = LabelType::ESP_CHIP_ID; break; + case SystemVariables::ESP_CHIP_FREQ: label = LabelType::ESP_CHIP_FREQ; break; + case SystemVariables::ESP_CHIP_MODEL: label = LabelType::ESP_CHIP_MODEL; break; + case SystemVariables::ESP_CHIP_REVISION: label = LabelType::ESP_CHIP_REVISION; break; + case SystemVariables::ESP_CHIP_CORES: label = LabelType::ESP_CHIP_CORES; break; + case SystemVariables::ESP_BOARD_NAME: label = LabelType::ESP_BOARD_NAME; break; + + default: + // No matching LabelType yet. + break; } + return label; +} + + +String SystemVariables::getSystemVariable(SystemVariables::Enum enumval) { + const LabelType::Enum label = SystemVariables2LabelType(enumval); if (LabelType::MAX_LABEL != label) { return getValue(label); @@ -169,8 +176,14 @@ String SystemVariables::getSystemVariable(SystemVariables::Enum enumval) { case SYSSEC_D: return String(((node_time.hour() * 60) + node_time.minute()) * 60 + node_time.second()); case SYSTIME: return node_time.getTimeString(':'); case SYSTIME_AM: return node_time.getTimeString_ampm(':'); + case SYSTIME_AM_0: return node_time.getTimeString_ampm(':', true, '0'); + case SYSTIME_AM_SP: return node_time.getTimeString_ampm(':', true, ' '); case SYSTM_HM: return node_time.getTimeString(':', false); + case SYSTM_HM_0: return node_time.getTimeString(':', false, '0'); + case SYSTM_HM_SP: return node_time.getTimeString(':', false, ' '); case SYSTM_HM_AM: return node_time.getTimeString_ampm(':', false); + case SYSTM_HM_AM_0: return node_time.getTimeString_ampm(':', false, '0'); + case SYSTM_HM_AM_SP: return node_time.getTimeString_ampm(':', false, ' '); case SYSWEEKDAY: return String(node_time.weekday()); case SYSWEEKDAY_S: return node_time.weekday_str(); case SYSYEAR_0: @@ -190,6 +203,10 @@ String SystemVariables::getSystemVariable(SystemVariables::Enum enumval) { case VCC: return String(-1); #endif // if FEATURE_ADC_VCC case WI_CH: return String((WiFiEventData.WiFiDisconnected()) ? 0 : WiFi.channel()); + + default: + // Already handled above. + return EMPTY_STRING; } return EMPTY_STRING; } @@ -355,8 +372,14 @@ const __FlashStringHelper * SystemVariables::toString(SystemVariables::Enum enum case Enum::SYSSTACK: return F("%sysstack%"); case Enum::SYSTIME: return F("%systime%"); case Enum::SYSTIME_AM: return F("%systime_am%"); + case Enum::SYSTIME_AM_0: return F("%systime_am_0%"); + case Enum::SYSTIME_AM_SP: return F("%systime_am_sp%"); case Enum::SYSTM_HM: return F("%systm_hm%"); + case Enum::SYSTM_HM_0: return F("%systm_hm_0%"); + case Enum::SYSTM_HM_SP: return F("%systm_hm_sp%"); case Enum::SYSTM_HM_AM: return F("%systm_hm_am%"); + case Enum::SYSTM_HM_AM_0: return F("%systm_hm_am_0%"); + case Enum::SYSTM_HM_AM_SP: return F("%systm_hm_am_sp%"); case Enum::SYSWEEKDAY: return F("%sysweekday%"); case Enum::SYSWEEKDAY_S: return F("%sysweekday_s%"); case Enum::SYSYEAR: return F("%sysyear%"); diff --git a/src/src/Helpers/SystemVariables.h b/src/src/Helpers/SystemVariables.h index 2f48576dd..05f39c970 100644 --- a/src/src/Helpers/SystemVariables.h +++ b/src/src/Helpers/SystemVariables.h @@ -69,8 +69,14 @@ public: SYSSTACK, SYSTIME, SYSTIME_AM, + SYSTIME_AM_0, + SYSTIME_AM_SP, SYSTM_HM, + SYSTM_HM_0, + SYSTM_HM_SP, SYSTM_HM_AM, + SYSTM_HM_AM_0, + SYSTM_HM_AM_SP, SYSWEEKDAY, SYSWEEKDAY_S, SYSYEAR, diff --git a/src/src/PluginStructs/P037_data_struct.cpp b/src/src/PluginStructs/P037_data_struct.cpp index a4a17f700..f80a408be 100644 --- a/src/src/PluginStructs/P037_data_struct.cpp +++ b/src/src/PluginStructs/P037_data_struct.cpp @@ -178,7 +178,7 @@ bool P037_data_struct::webform_load( addFormSubHeader(F("Topic subscriptions")); // Global topic prefix - addFormTextBox(F("Prefix for all topics"), F("p037_topicprefix"), globalTopicPrefix, 40); + addFormTextBox(F("Prefix for all topics"), F("topicprefix"), globalTopicPrefix, 40); # ifdef P037_JSON_SUPPORT @@ -201,14 +201,14 @@ bool P037_data_struct::webform_load( addHtml(F(" ")); addHtmlInt(varNr + 1); html_TD(); - id = F("p037_template"); + id = F("template"); id += (varNr + 1); addTextBox(id, mqttTopics[varNr], 40, false, false, EMPTY_STRING, F("wide")); html_TD(); - id = F("p037_attribute"); + id = F("attribute"); id += (varNr + 1); addTextBox(id, jsonAttributes[varNr], @@ -220,7 +220,7 @@ bool P037_data_struct::webform_load( { String label = F("MQTT Topic "); label += (varNr + 1); - id = F("p037_template"); + id = F("template"); id += (varNr + 1); addFormTextBox(label, id, mqttTopics[varNr], 40); } @@ -495,7 +495,7 @@ bool P037_data_struct::webform_save( for (uint8_t varNr = 0; varNr < VARS_PER_TASK; varNr++) { - String argName = F("p037_template"); + String argName = F("template"); argName += (varNr + 1); mqttTopics[varNr] = web_server.arg(argName); @@ -503,14 +503,14 @@ bool P037_data_struct::webform_save( # ifdef P037_JSON_SUPPORT if (jsonEnabled) { - argName = F("p037_attribute"); + argName = F("attribute"); argName += (varNr + 1); jsonAttributes[varNr] = web_server.arg(argName); } # endif // P037_JSON_SUPPORT } - globalTopicPrefix = web_server.arg(F("p037_topicprefix")); + globalTopicPrefix = web_server.arg(F("topicprefix")); # if P037_MAPPING_SUPPORT || P037_FILTER_SUPPORT String left, right; @@ -545,8 +545,7 @@ bool P037_data_struct::webform_save( valueArray[mappingOffset] = EMPTY_STRING; } - if ((left.isEmpty() && !right.isEmpty()) || - (!left.isEmpty() && right.isEmpty())) { + if (left.isEmpty() != right.isEmpty()) { if (firstError) { error += F("Name and value should both be filled for mapping "); firstError = false; @@ -592,8 +591,7 @@ bool P037_data_struct::webform_save( valueArray[filterOffset] = EMPTY_STRING; } - if ((left.isEmpty() && !right.isEmpty()) || - (!left.isEmpty() && right.isEmpty())) { + if (left.isEmpty() != right.isEmpty()) { if (firstError) { error += F("Name and value should both be filled for filter "); firstError = false; @@ -656,14 +654,14 @@ String P037_data_struct::mapValue(const String& input, const String& attribute) if (!input.isEmpty()) { parseMappings(); - String operands = P037_OPERAND_LIST; + const String operands = P037_OPERAND_LIST; int8_t idx = 0; for (uint8_t mappingOffset = P037_START_MAPPINGS; mappingOffset <= P037_END_MAPPINGS && idx <= _maxIdx; mappingOffset++) { - String name = parseStringKeepCase(valueArray[mappingOffset], 1, P037_VALUE_SEPARATOR); - String oper = parseString(valueArray[mappingOffset], 2, P037_VALUE_SEPARATOR); - String valu = parseStringKeepCase(valueArray[mappingOffset], 3, P037_VALUE_SEPARATOR); + const String name = parseStringKeepCase(valueArray[mappingOffset], 1, P037_VALUE_SEPARATOR); + const String oper = parseString(valueArray[mappingOffset], 2, P037_VALUE_SEPARATOR); + const String valu = parseStringKeepCase(valueArray[mappingOffset], 3, P037_VALUE_SEPARATOR); if ((name == input) || ((!attribute.isEmpty()) && (name == attribute))) { int8_t operandIndex = operands.indexOf(oper); diff --git a/src/src/PluginStructs/P038_data_struct.cpp b/src/src/PluginStructs/P038_data_struct.cpp index fc18bbe28..904e69341 100644 --- a/src/src/PluginStructs/P038_data_struct.cpp +++ b/src/src/PluginStructs/P038_data_struct.cpp @@ -47,16 +47,21 @@ bool P038_data_struct::plugin_write(struct EventStruct *event, const String& str bool success = false; if (isInitialized()) { - String log; - - if (loglevelActiveFor(LOG_LEVEL_INFO) && - log.reserve(64)) { - log += F("P038 : write - "); - log += string; - addLogMove(LOG_LEVEL_INFO, log); + const String cmd = parseString(string, 1); + if (!cmd.startsWith(F("neo"))) { + return success; } - String cmd = parseString(string, 1); + { + String log; + + if (loglevelActiveFor(LOG_LEVEL_INFO) && + log.reserve(64)) { + log += F("P038 : write - "); + log += string; + addLogMove(LOG_LEVEL_INFO, log); + } + } if (cmd.equals(F("neopixel"))) { // NeoPixel Plugin_038_pixels->setPixelColor(event->Par1 - 1, Plugin_038_pixels->Color(event->Par2, event->Par3, event->Par4, event->Par5)); diff --git a/src/src/PluginStructs/P073_data_struct.cpp b/src/src/PluginStructs/P073_data_struct.cpp index b222577f2..b7730bdcb 100644 --- a/src/src/PluginStructs/P073_data_struct.cpp +++ b/src/src/PluginStructs/P073_data_struct.cpp @@ -428,7 +428,7 @@ uint8_t P073_data_struct::mapCharToFontPosition(char character, } else if (isAlpha(character)) { position = character - (isLowerCase(character) ? 'a' : 'A') + 42; } else { - uint8_t idx = specialChars.indexOf(character); + int idx = specialChars.indexOf(character); if (idx > -1) { position = idx + 10; diff --git a/src/src/PluginStructs/P120_data_struct.cpp b/src/src/PluginStructs/P120_data_struct.cpp index 6556761de..49c7f2ef4 100644 --- a/src/src/PluginStructs/P120_data_struct.cpp +++ b/src/src/PluginStructs/P120_data_struct.cpp @@ -528,10 +528,11 @@ bool P120_data_struct::plugin_webform_load(struct EventStruct *event) { addUnit(F("1..100")); const __FlashStringHelper *frequencyOptions[] = { - F("10x per second"), - F("50x per second") }; + F("10"), + F("50") }; int frequencyValues[] = { P120_FREQUENCY_10, P120_FREQUENCY_50 }; addFormSelector(F("Measuring frequency"), F("p120_frequency"), 2, frequencyOptions, frequencyValues, P120_FREQUENCY); + addUnit(F("Hz")); addFormNote(F("Values X/Y/Z are updated 1x per second, Controller updates & Value-events are based on 'Interval' setting.")); } diff --git a/src/src/PluginStructs/P132_data_struct.cpp b/src/src/PluginStructs/P132_data_struct.cpp new file mode 100644 index 000000000..ef41a4256 --- /dev/null +++ b/src/src/PluginStructs/P132_data_struct.cpp @@ -0,0 +1,145 @@ +#include "../PluginStructs/P132_data_struct.h" + +#ifdef USES_P132 + +// **************************************************************************/ +// Constructor +// **************************************************************************/ +P132_data_struct::P132_data_struct(struct EventStruct *event) { + _i2c_address = P132_I2C_ADDR; + setCalibration_INA3221(event); +} + +// **************************************************************************/ +// Destructor +// **************************************************************************/ +P132_data_struct::~P132_data_struct() {} + +// **************************************************************************/ +// Gets the raw bus voltage (7FF8 / 32760) LSB 8mV +// **************************************************************************/ +int16_t P132_data_struct::getBusVoltage_raw(byte reg) { + uint16_t value = I2C_read16_reg(_i2c_address, reg); + + // Shift to the right 3 to drop CNVR and OVF and multiply by LSB 8 mV + # ifndef BUILD_NO_DEBUG + + if (loglevelActiveFor(LOG_LEVEL_DEBUG)) { + String log = F("INA3221: get raw bus "); + log += value; + log += F(" reg - "); + log += reg; + addLog(LOG_LEVEL_DEBUG, log); + } + # endif // ifndef BUILD_NO_DEBUG + return (int16_t)((value >> 3) * 8); +} + +// **************************************************************************/ +// Gets the raw shunt voltage (integer, so +-32760) LSB 40 uV +// **************************************************************************/ +int16_t P132_data_struct::getShuntVoltage_raw(byte reg) { + uint16_t value = I2C_read16_reg(_i2c_address, reg); + + # ifndef BUILD_NO_DEBUG + String log = F("INA3221: get raw shunt voltage "); + log += value; + log += F(" value2 - "); + # endif // ifndef BUILD_NO_DEBUG + + // Shift to the right 3 to drop CNVR and OVF and multiply by LSB + if (value > 32767) { // check value is negative + // value = 0; // no negative measure + value = ((value >> 3) | 57344); // correct int16_t value + # ifndef BUILD_NO_DEBUG + log += F(" value_neg - "); + log += value; + # endif // ifndef BUILD_NO_DEBUG + } else { + value = (value >> 3); + # ifndef BUILD_NO_DEBUG + log += F(" value_pos - "); + log += value; + # endif // ifndef BUILD_NO_DEBUG + } + # ifndef BUILD_NO_DEBUG + log += F(" reg - "); + log += reg; + addLog(LOG_LEVEL_DEBUG, log); + # endif // ifndef BUILD_NO_DEBUG + return value; +} + +// **************************************************************************/ +// Gets the shunt voltage in mV (32760 so +-163.8 mV) 7ff8 LSB 40uV +// **************************************************************************/ +float P132_data_struct::getShuntVoltage_mV(byte reg) { + int16_t value = getShuntVoltage_raw(reg); + + # ifndef BUILD_NO_DEBUG + + if (loglevelActiveFor(LOG_LEVEL_DEBUG)) { + String log = F("INA3221: shunt voltage in mV * 0.04 "); + log += value; + log += F(" reg - "); + log += reg; + addLog(LOG_LEVEL_DEBUG, log); + } + # endif // ifndef BUILD_NO_DEBUG + return value * 0.04f; +} + +// **************************************************************************/ +// Gets the Bus voltage in volts +// **************************************************************************/ +float P132_data_struct::getBusVoltage_V(byte reg) { + int16_t value = getBusVoltage_raw(reg); + + # ifndef BUILD_NO_DEBUG + + if (loglevelActiveFor(LOG_LEVEL_DEBUG)) { + String log = F("INA3221: get bus voltage "); + log += value; + log += F(" reg - "); + log += reg; + addLog(LOG_LEVEL_DEBUG, log); + } + # endif // ifndef BUILD_NO_DEBUG + return value * 0.001f; +} + +// **************************************************************************/ +// Configures to INA3221 +// **************************************************************************/ +void P132_data_struct::setCalibration_INA3221(struct EventStruct *event) { + // Set Config register + uint32_t config = I2C_read16_reg(_i2c_address, 0x00); // read, chip default: 0x7127 + uint16_t mfgid = I2C_read16_reg(_i2c_address, 0xFE); // read manufacturer ID, should be 0x5449 + + set3BitToUL(config, INA3221_AVERAGE_BIT, P132_GET_AVERAGE); + set3BitToUL(config, INA3221_CONVERSION_BUS_BIT, P132_GET_CONVERSION_B); + set3BitToUL(config, INA3221_CONVERSION_SHUNT_BIT, P132_GET_CONVERSION_S); + + # ifndef BUILD_NO_DEBUG + + if (loglevelActiveFor(LOG_LEVEL_INFO)) { + String log = F("INA3221: init I2C: 0x"); + log += String(_i2c_address, HEX); + log += F(" mfg: 0x"); + log += String(mfgid, HEX); + log += F(", config: 0x"); + log += String(config, HEX); + log += F(", 0b"); + log += String(config, BIN); + addLog(LOG_LEVEL_INFO, log); + } + # endif // ifndef BUILD_NO_DEBUG + + if (mfgid != 0x5449) { + addLogMove(LOG_LEVEL_ERROR, F("INA3221: Invalid Manufacturer ID! (0x5449)")); + } + + I2C_write16_reg(_i2c_address, 0x00, static_cast(config)); +} + +#endif // ifdef USES_P132 diff --git a/src/src/PluginStructs/P132_data_struct.h b/src/src/PluginStructs/P132_data_struct.h new file mode 100644 index 000000000..837ce44fe --- /dev/null +++ b/src/src/PluginStructs/P132_data_struct.h @@ -0,0 +1,50 @@ +#ifndef PLUGINSTRUCTS_P132_DATA_STRUCT_H +#define PLUGINSTRUCTS_P132_DATA_STRUCT_H + +#include "../../_Plugin_Helper.h" +#ifdef USES_P132 + +// # define P132_DEBUG_LOG // Enable for some (extra) logging + +# define P132_CONFIG_BASE 2 // Better not change this... +# define P132_I2C_ADDR PCONFIG(1) +# define P132_VALUE_1 PCONFIG(P132_CONFIG_BASE) +# define P132_VALUE_2 PCONFIG(P132_CONFIG_BASE + 1) +# define P132_VALUE_3 PCONFIG(P132_CONFIG_BASE + 2) +# define P132_VALUE_4 PCONFIG(P132_CONFIG_BASE + 3) +# define P132_SHUNT PCONFIG(6) + +# define P132_CONFIG_FLAGS PCONFIG_LONG(0) +# define P132_FLAG_AVERAGE 0 +# define P132_FLAG_CONVERSION_B 3 +# define P132_FLAG_CONVERSION_S 6 + +# define P132_GET_AVERAGE get3BitFromUL(P132_CONFIG_FLAGS, P132_FLAG_AVERAGE) +# define P132_GET_CONVERSION_B get3BitFromUL(P132_CONFIG_FLAGS, P132_FLAG_CONVERSION_B) +# define P132_GET_CONVERSION_S get3BitFromUL(P132_CONFIG_FLAGS, P132_FLAG_CONVERSION_S) + +# define INA3221_AVERAGE_BIT 9 +# define INA3221_CONVERSION_BUS_BIT 6 +# define INA3221_CONVERSION_SHUNT_BIT 3 + +struct P132_data_struct : public PluginTaskData_base { +public: + + P132_data_struct(struct EventStruct *event); + + P132_data_struct() = delete; + ~P132_data_struct(); + + float getShuntVoltage_mV(byte reg); + float getBusVoltage_V(byte reg); + +private: + + void setCalibration_INA3221(struct EventStruct *event); + int16_t getBusVoltage_raw(byte reg); + int16_t getShuntVoltage_raw(byte reg); + + int8_t _i2c_address; +}; +#endif // ifdef USES_P132 +#endif // ifndef PLUGINSTRUCTS_P132_DATA_STRUCT_H diff --git a/src/src/WebServer/AdvancedConfigPage.cpp b/src/src/WebServer/AdvancedConfigPage.cpp index 6440b08a9..3248d729a 100644 --- a/src/src/WebServer/AdvancedConfigPage.cpp +++ b/src/src/WebServer/AdvancedConfigPage.cpp @@ -201,7 +201,7 @@ void handle_advanced() { addFormSubHeader(F("Inter-ESPEasy Network")); - + if (Settings.UDPPort != 8266 ) addFormNote(F("Preferred P2P port is 8266")); addFormNumericBox(F("UDP port"), F("udpport"), Settings.UDPPort, 0, 65535); // TODO sort settings in groups or move to other pages/groups diff --git a/src/src/WebServer/HardwarePage.cpp b/src/src/WebServer/HardwarePage.cpp index 5a6f12c51..856e79849 100644 --- a/src/src/WebServer/HardwarePage.cpp +++ b/src/src/WebServer/HardwarePage.cpp @@ -81,7 +81,7 @@ void handle_hardware() { // do not add the pin state select for these pins. } else { if (validGpio(gpio)) { - String int_pinlabel = "p"; + String int_pinlabel('p'); int_pinlabel += gpio; Settings.setPinBootState(gpio, static_cast(getFormItemInt(int_pinlabel))); } @@ -167,7 +167,7 @@ void handle_hardware() { // Script to show GPIO pins for User-defined SPI GPIOs html_add_script(F("function spiOptionChanged(elem) {var spipinstyle = elem.value == 9 ? '' : 'none';document.getElementById('tr_spipinsclk').style.display = spipinstyle;document.getElementById('tr_spipinmiso').style.display = spipinstyle;document.getElementById('tr_spipinmosi').style.display = spipinstyle;}"), false); - const String spi_options[] = { + const __FlashStringHelper * spi_options[] = { getSPI_optionToString(SPI_Options_e::None), getSPI_optionToString(SPI_Options_e::Vspi), getSPI_optionToString(SPI_Options_e::Hspi), diff --git a/src/src/WebServer/Markup_Forms.cpp b/src/src/WebServer/Markup_Forms.cpp index acd09cb7e..cc05d678a 100644 --- a/src/src/WebServer/Markup_Forms.cpp +++ b/src/src/WebServer/Markup_Forms.cpp @@ -55,7 +55,7 @@ void addFormNote(const String& text, const String& id) // Add a checkbox Form // ******************************************************************************** -void addFormCheckBox_disabled(const String& label, const String& id, boolean checked +void addFormCheckBox_disabled(const String& label, const String& id, bool checked #ifdef ENABLE_TOOLTIPS , const String& tooltip #endif // ifdef ENABLE_TOOLTIPS @@ -67,19 +67,19 @@ void addFormCheckBox_disabled(const String& label, const String& id, boolean che ); } -void addFormCheckBox(const __FlashStringHelper * label, const __FlashStringHelper * id, boolean checked, bool disabled) +void addFormCheckBox(const __FlashStringHelper * label, const __FlashStringHelper * id, bool checked, bool disabled) { addRowLabel_tr_id(label, id); addCheckBox(id, checked, disabled); } -void addFormCheckBox(const __FlashStringHelper * label, const String& id, boolean checked, bool disabled) +void addFormCheckBox(const __FlashStringHelper * label, const String& id, bool checked, bool disabled) { addRowLabel_tr_id(label, id); addCheckBox(id, checked, disabled); } -void addFormCheckBox(const String& label, const String& id, boolean checked, bool disabled +void addFormCheckBox(const String& label, const String& id, bool checked, bool disabled #ifdef ENABLE_TOOLTIPS , const String& tooltip #endif // ifdef ENABLE_TOOLTIPS @@ -93,7 +93,7 @@ void addFormCheckBox(const String& label, const String& id, boolean checked, boo ); } -void addFormCheckBox(LabelType::Enum label, boolean checked, bool disabled +void addFormCheckBox(LabelType::Enum label, bool checked, bool disabled #ifdef ENABLE_TOOLTIPS , const String& tooltip #endif // ifdef ENABLE_TOOLTIPS @@ -105,7 +105,7 @@ void addFormCheckBox(LabelType::Enum label, boolean checked, bool disabled ); } -void addFormCheckBox_disabled(LabelType::Enum label, boolean checked) { +void addFormCheckBox_disabled(LabelType::Enum label, bool checked) { addFormCheckBox(label, checked, true); } @@ -424,7 +424,7 @@ void addFormSelector(const String& label, const int indices[], const String attr[], int selectedIndex, - boolean reloadonchange) + bool reloadonchange) { addRowLabel_tr_id(label, id); addSelector(id, optionCount, options, indices, attr, selectedIndex, reloadonchange, true); @@ -448,7 +448,7 @@ void addFormSelector(const String & label, const int indices[], const String attr[], int selectedIndex, - boolean reloadonchange + bool reloadonchange #ifdef ENABLE_TOOLTIPS , const String& tooltip #endif // ifdef ENABLE_TOOLTIPS @@ -462,14 +462,14 @@ void addFormSelector(const String & label, ); } -void addFormSelector_script(const String & label, - const String & id, - int optionCount, - const String options[], - const int indices[], - const String attr[], - int selectedIndex, - const String& onChangeCall +void addFormSelector_script(const __FlashStringHelper * label, + const __FlashStringHelper * id, + int optionCount, + const __FlashStringHelper * options[], + const int indices[], + const String attr[], + int selectedIndex, + const __FlashStringHelper * onChangeCall #ifdef ENABLE_TOOLTIPS , const String& tooltip #endif // ifdef ENABLE_TOOLTIPS @@ -485,6 +485,51 @@ void addFormSelector_script(const String & label, addSelector_Foot(); } +void addFormSelector_script(const String & label, + const String & id, + int optionCount, + const String options[], + const int indices[], + const String attr[], + int selectedIndex, + const __FlashStringHelper * onChangeCall + #ifdef ENABLE_TOOLTIPS + , const String& tooltip + #endif // ifdef ENABLE_TOOLTIPS + ) +{ + addRowLabel_tr_id(label, id); + do_addSelector_Head(id, F("wide"), onChangeCall, false + #ifdef ENABLE_TOOLTIPS + , tooltip + #endif // ifdef ENABLE_TOOLTIPS + ); + addSelector_options(optionCount, options, indices, attr, selectedIndex); + addSelector_Foot(); +} + +void addFormSelector_YesNo(const __FlashStringHelper * label, + const __FlashStringHelper * id, + int selectedIndex, + bool reloadonchange) +{ + const __FlashStringHelper *optionsNoYes[2] = { F("No"), F("Yes") }; + int optionValuesNoYes[2] = { 0, 1 }; + addFormSelector(label, id, 2, optionsNoYes, optionValuesNoYes, selectedIndex, reloadonchange); +} + +void addFormSelector_YesNo(const __FlashStringHelper * label, + const String& id, + int selectedIndex, + bool reloadonchange) +{ + const __FlashStringHelper *optionsNoYes[2] = { F("No"), F("Yes") }; + int optionValuesNoYes[2] = { 0, 1 }; + addFormSelector(label, id, 2, optionsNoYes, optionValuesNoYes, selectedIndex, reloadonchange); +} + + + // ******************************************************************************** // Add a GPIO pin select dropdown list // ******************************************************************************** @@ -582,6 +627,12 @@ bool getCheckWebserverArg_int(const String& key, int& value) { return validIntFromString(valueStr, value); } +bool update_whenset_FormItemInt(const __FlashStringHelper * key, + int & value) +{ + return update_whenset_FormItemInt(String(key), value); +} + bool update_whenset_FormItemInt(const String& key, int& value) { int tmpVal; @@ -592,6 +643,13 @@ bool update_whenset_FormItemInt(const String& key, int& value) { return false; } +bool update_whenset_FormItemInt(const __FlashStringHelper * key, + uint8_t& value) +{ + return update_whenset_FormItemInt(String(key), value); +} + + bool update_whenset_FormItemInt(const String& key, uint8_t& value) { int tmpVal; diff --git a/src/src/WebServer/Markup_Forms.h b/src/src/WebServer/Markup_Forms.h index a1b9456ae..58f9bfd62 100644 --- a/src/src/WebServer/Markup_Forms.h +++ b/src/src/WebServer/Markup_Forms.h @@ -17,7 +17,7 @@ void addFormSeparator(int clspan); // Add a note as row start // ******************************************************************************** void addFormNote(const __FlashStringHelper * text); -void addFormNote(const String& text, const String& id = ""); +void addFormNote(const String& text, const String& id = EMPTY_STRING); // ******************************************************************************** // Create Forms @@ -30,7 +30,7 @@ void addFormNote(const String& text, const String& id = ""); void addFormCheckBox_disabled(const String& label, const String& id, - boolean checked + bool checked #ifdef ENABLE_TOOLTIPS , const String& tooltip = EMPTY_STRING @@ -39,7 +39,7 @@ void addFormCheckBox_disabled(const String& label, void addFormCheckBox(const String& label, const String& id, - boolean checked, + bool checked, bool disabled = false #ifdef ENABLE_TOOLTIPS , @@ -48,7 +48,7 @@ void addFormCheckBox(const String& label, ); void addFormCheckBox(LabelType::Enum label, - boolean checked, + bool checked, bool disabled = false #ifdef ENABLE_TOOLTIPS , @@ -57,9 +57,9 @@ void addFormCheckBox(LabelType::Enum label, ); void addFormCheckBox_disabled(LabelType::Enum label, - boolean checked); -void addFormCheckBox(const __FlashStringHelper * label, const __FlashStringHelper * id, boolean checked, bool disabled = false); -void addFormCheckBox(const __FlashStringHelper * label, const String& id, boolean checked, bool disabled = false); + bool checked); +void addFormCheckBox(const __FlashStringHelper * label, const __FlashStringHelper * id, bool checked, bool disabled = false); +void addFormCheckBox(const __FlashStringHelper * label, const String& id, bool checked, bool disabled = false); // ******************************************************************************** // Add a Numeric Box form @@ -128,7 +128,7 @@ void addFormTextBox(const __FlashStringHelper * label, int maxlength, bool readonly = false, bool required = false, - const String& pattern = ""); + const String& pattern = EMPTY_STRING); void addFormTextBox(const String& label, const String& id, @@ -136,7 +136,7 @@ void addFormTextBox(const String& label, int maxlength, bool readonly = false, bool required = false, - const String& pattern = "" + const String& pattern = EMPTY_STRING #ifdef ENABLE_TOOLTIPS , const String& tooltip = EMPTY_STRING @@ -252,16 +252,7 @@ void addFormSelector(const String& label, const int indices[], const String attr[], int selectedIndex, - boolean reloadonchange); - -void addFormSelector_script(const String& label, - const String& id, - int optionCount, - const __FlashStringHelper * options[], - const int indices[], - const String attr[], - int selectedIndex, - const String& onChangeCall); + bool reloadonchange); void addFormSelector(const String& label, @@ -270,7 +261,12 @@ void addFormSelector(const String& label, const String options[], const int indices[], int selectedIndex, - bool reloadonchange); + bool reloadonchange + #ifdef ENABLE_TOOLTIPS + , + const String& tooltip = EMPTY_STRING + #endif + ); void addFormSelector(const String& label, const String& id, @@ -279,13 +275,28 @@ void addFormSelector(const String& label, const int indices[], const String attr[], int selectedIndex, - boolean reloadonchange + bool reloadonchange #ifdef ENABLE_TOOLTIPS , const String& tooltip = EMPTY_STRING #endif ); +void addFormSelector_script(const __FlashStringHelper * label, + const __FlashStringHelper * id, + int optionCount, + const __FlashStringHelper * options[], + const int indices[], + const String attr[], + int selectedIndex, + const __FlashStringHelper * onChangeCall + #ifdef ENABLE_TOOLTIPS + , + const String& tooltip = EMPTY_STRING + #endif + ); + + void addFormSelector_script(const String& label, const String& id, int optionCount, @@ -293,13 +304,23 @@ void addFormSelector_script(const String& label, const int indices[], const String attr[], int selectedIndex, - const String& onChangeCall + const __FlashStringHelper * onChangeCall #ifdef ENABLE_TOOLTIPS , const String& tooltip = EMPTY_STRING #endif ); +void addFormSelector_YesNo(const __FlashStringHelper * label, + const __FlashStringHelper * id, + int selectedIndex, + bool reloadonchange); + +void addFormSelector_YesNo(const __FlashStringHelper * label, + const String& id, + int selectedIndex, + bool reloadonchange); + // ******************************************************************************** // Add a GPIO pin select dropdown list // ******************************************************************************** @@ -317,9 +338,15 @@ int getFormItemInt(const String& key, int defaultValue); bool getCheckWebserverArg_int(const String& key, int & value); +bool update_whenset_FormItemInt(const __FlashStringHelper * key, + int & value); + bool update_whenset_FormItemInt(const String& key, int & value); +bool update_whenset_FormItemInt(const __FlashStringHelper * key, + uint8_t & value); + bool update_whenset_FormItemInt(const String& key, uint8_t & value); diff --git a/src/src/WebServer/NotificationPage.cpp b/src/src/WebServer/NotificationPage.cpp index 0426d1b76..12d922978 100644 --- a/src/src/WebServer/NotificationPage.cpp +++ b/src/src/WebServer/NotificationPage.cpp @@ -56,7 +56,7 @@ void handle_notifications() { } else { - if (Settings.Notification != 0) + if (Settings.Notification[notificationindex] != 0) { nprotocolIndex_t NotificationProtocolIndex = getNProtocolIndex_from_NotifierIndex(notificationindex); diff --git a/src/src/WebServer/RootPage.cpp b/src/src/WebServer/RootPage.cpp index 014e65289..263a27133 100644 --- a/src/src/WebServer/RootPage.cpp +++ b/src/src/WebServer/RootPage.cpp @@ -255,6 +255,7 @@ void handle_root() { html_end_table(); html_BR(); + if (Settings.Unit == 0 && Settings.UDPPort != 0) addFormNote(F("Warning: Unit number is 0, please change it if you want to send data to other units.")); html_BR(); html_table_class_multirow_noborder(); html_TR(); diff --git a/src/src/WebServer/SettingsArchive.cpp b/src/src/WebServer/SettingsArchive.cpp index a38bd771e..a0f325d71 100644 --- a/src/src/WebServer/SettingsArchive.cpp +++ b/src/src/WebServer/SettingsArchive.cpp @@ -69,7 +69,7 @@ void handle_settingsarchive() { ProvisioningSettings.setPass(web_server.arg(F("pass"))); } } - error += saveProvisioningSettings(ProvisioningSettings); + error = saveProvisioningSettings(ProvisioningSettings); } #endif @@ -82,9 +82,9 @@ void handle_settingsarchive() { if (web_server.hasArg(F("download"))) { // Try downloading files. // Don't use the ProvisioningSettings, as not all may be stored. - String url = webArg(F("url")); - String user = webArg(F("user")); - String pass = webArg(F("pass")); + const String url = webArg(F("url")); + const String user = webArg(F("user")); + const String pass = webArg(F("pass")); addTableSeparator(F("Download result"), 2, 3); bool somethingDownloaded = false; @@ -205,7 +205,7 @@ void handle_settingsarchive() { // download filetype selectors // ******************************************************************************** void addDownloadFiletypeCheckbox(FileType::Enum filetype, unsigned int filenr) { - String filetype_str = getFileName(filetype, filenr); + const String filetype_str = getFileName(filetype, filenr); String label = F("Fetch "); label += filetype_str; @@ -214,8 +214,7 @@ void addDownloadFiletypeCheckbox(FileType::Enum filetype, unsigned int filenr) { } void storeDownloadFiletypeCheckbox(FileType::Enum filetype, unsigned int filenr) { - String filetype_str = getFileName(filetype, filenr); - bool isChecked = isFormItemChecked(filetype_str); + const bool isChecked = isFormItemChecked(getFileName(filetype, filenr)); switch (filetype) { case FileType::CONFIG_DAT: ResetFactoryDefaultPreference.fetchConfigDat(isChecked); break; diff --git a/src/src/WebServer/SysVarPage.cpp b/src/src/WebServer/SysVarPage.cpp index 40cb71c88..be4b2b922 100644 --- a/src/src/WebServer/SysVarPage.cpp +++ b/src/src/WebServer/SysVarPage.cpp @@ -100,9 +100,15 @@ void handle_sysvars() { addSysVar_enum_html(SystemVariables::LCLTIME); addSysVar_enum_html(SystemVariables::LCLTIME_AM); addSysVar_enum_html(SystemVariables::SYSTM_HM); + addSysVar_enum_html(SystemVariables::SYSTM_HM_0); + addSysVar_enum_html(SystemVariables::SYSTM_HM_SP); addSysVar_enum_html(SystemVariables::SYSTM_HM_AM); + addSysVar_enum_html(SystemVariables::SYSTM_HM_AM_0); + addSysVar_enum_html(SystemVariables::SYSTM_HM_AM_SP); addSysVar_enum_html(SystemVariables::SYSTIME); addSysVar_enum_html(SystemVariables::SYSTIME_AM); + addSysVar_enum_html(SystemVariables::SYSTIME_AM_0); + addSysVar_enum_html(SystemVariables::SYSTIME_AM_SP); addSysVar_enum_html(SystemVariables::SYSBUILD_DATE); addSysVar_enum_html(SystemVariables::SYSBUILD_TIME); addSysVar_enum_html(SystemVariables::SYSBUILD_FILENAME); diff --git a/src/src/WebServer/WebServer.cpp b/src/src/WebServer/WebServer.cpp index 24ba549b5..5ebfe96a3 100644 --- a/src/src/WebServer/WebServer.cpp +++ b/src/src/WebServer/WebServer.cpp @@ -76,6 +76,10 @@ void safe_strncpy_webserver_arg(char *dest, const String& arg, size_t max_size) } } +void safe_strncpy_webserver_arg(char *dest, const __FlashStringHelper * arg, size_t max_size) { + safe_strncpy_webserver_arg(dest, String(arg), max_size); +} + void sendHeadandTail(const __FlashStringHelper * tmplName, boolean Tail, boolean rebooting) { // This function is called twice per serving a web page. // So it must keep track of the timer longer than the scope of this function. diff --git a/src/src/WebServer/WebServer.h b/src/src/WebServer/WebServer.h index f09d60681..3800753be 100644 --- a/src/src/WebServer/WebServer.h +++ b/src/src/WebServer/WebServer.h @@ -20,6 +20,8 @@ void safe_strncpy_webserver_arg(char *dest, const String& arg, size_t max_size); +void safe_strncpy_webserver_arg(char *dest, const __FlashStringHelper * arg, size_t max_size); + void sendHeadandTail(const __FlashStringHelper * tmplName, boolean Tail = false, boolean rebooting = false);