Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[pull] mega from letscontrolit:mega #132

Merged
merged 16 commits into from
Sep 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ on:
tags-ignore: '**'
paths-ignore:
- 'dist/Release_notes.txt'
- 'docs/**'
pull_request:
branches: [mega]

Expand Down
62 changes: 58 additions & 4 deletions docs/source/Plugin/P026.rst
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.. include:: ../Plugin/_plugin_substitutions_p02x.repl
.. include:: ../Plugin/_plugin_substitutions_p02x.repl
.. _P026_page:

|P026_typename|
Expand All @@ -21,10 +21,48 @@ Maintainer: |P026_maintainer|

Used libraries: |P026_usedlibraries|

Supported hardware
------------------
.. Supported hardware
.. ------------------

|P026_usedby|
.. .. |P026_usedby|

Introduction
------------

To monitor some internal values of an ESPEasy equiped device, the SysInfo plugin is available. This device can show up to 4 values showing user-selected system data.

Configuration
-------------

.. image:: P026_DeviceConfiguration.png

* **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.

Output configuration
^^^^^^^^^^^^^^^^^^^^

* **Number Output Values**: Select from 1 to 4 output values, default is 4 (Quad). If more values are to be used, multiple tasks can be configured using this plugin.

.. image:: P026_NumberOutputOptions.png

* **Value 1..4**: Depending on the **Number Output Values** selection, 1 to 4 selections for output values are available. These can be chosen as desired.

.. image:: P026_ValuesOptions.png

* *Uptime*: The uptime of the unit in minutes.
* *Free RAM*: The amount of free memory in bytes.
* *Wifi RSSI*: The RSSI (Received signal strength indicator) value. This is a negative value.
* *Input VCC*: The voltage applied to the 3.3V VCC input of the ESP. This value is **only** available on ESP8266 builds with VCC enabled (included in the build name), else 0 will be shown.
* *System load*: The load as displayed on the Main and Info pages, a percentage in range 0 .. 100.
* *IP 1.Octet* .. *IP 4.Octet*: The separate parts of the active IP address of the unit, the octets are counted from left to right.
* *Web activity*: The time passed since the last web activity at the unit. Measured in seconds.
* *Free Stack*: The available stack space in bytes.
* *WiFi TX pwr*: The current setting for transmit power via WiFi. This is determined dynamically, depending on the corresponding settings in the Tools/Advanced page, RSSI and other factors.
* *Free 2nd Heap*: The available memory on the 2nd heap, **only** available in some specific ESP8266 builds, else it shows 0.
* *Internal temperature (ESP32)*: The internal temperature of the ESP. **Only** available on ESP32 units. For ESP32-S2/S3/C2/C3/C6 MCUs there is official support for the internal temperature sensor via the Espressif libraries, that has compensation applied so it shows a realistic value. For ESP32 Classic this is determined empirically, based on the deviation of the 150 kHz internal clock generator, that is rather temperature dependent, compared to the (stable) crystal frequency. This should not be seen as an absolute temperature, but *can* be used as a relative measurement f.e. when comparing heavy load vs. light load situations.
* *None*: No value.

.. Commands available
.. ^^^^^^^^^^^^^^^^^^
Expand All @@ -36,12 +74,28 @@ Supported hardware

.. .. include:: P026_events.repl

Data Acquisition
^^^^^^^^^^^^^^^^

This group of settings, **Single event with all values** and **Send to Controller** settings are standard available configuration items. Send to Controller is only visible when one or more Controllers are configured.

* **Interval** By default, Interval will be set to 60 sec. The data will be collected, and event(s) generated, using this interval.

Get Config values
~~~~~~~~~~~~~~~~~

These values are not available in *Minimal OTA* builds.

.. include:: P026_config_values.repl

Change log
----------

.. versionchanged:: 2.0
...

|added| 2023-09-25 ESP32 Internal temperature sensor option, Get Config values

|added|
Major overhaul for 2.0 release.

Expand Down
Binary file added docs/source/Plugin/P026_DeviceConfiguration.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/source/Plugin/P026_NumberOutputOptions.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/source/Plugin/P026_ValuesOptions.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
59 changes: 59 additions & 0 deletions docs/source/Plugin/P026_config_values.repl
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
.. csv-table::
:header: "Config value", "Information"
:widths: 20, 30

"
| ``[<taskname>#uptime]``
","
| Returns the uptime of the unit in minutes.
"
"
| ``[<taskname>#freeheap]``
","
| Returns the amount of free memory in bytes.
"
"
| ``[<taskname>#rssi]``
","
| Returns the RSSI (Received signal strength indicator) value. This is a negative value.
"
"
| ``[<taskname>#vcc]``
","
| Returns the voltage applied to the 3.3V VCC input of the ESP. This value is **only** available on ESP8266 builds with VCC enabled (included in the build name), else 0 will be shown.
"
"
| ``[<taskname>#load]``
","
| Returns the load as displayed on the Main and Info pages, a percentage in range 0 .. 100.
"
"
| ``[<taskname>#ip1]`` .. ``[<taskname>#ip4]``
","
| Returns the separate parts of the active IPv4 address of the unit, the parts 1..4 are counted from left to right.
"
"
| ``[<taskname>#web]``
","
| Returns the time passed since the last web activity at the unit. Measured in seconds.
"
"
| ``[<taskname>#freestack]``
","
| Returns the available stack space in bytes.
"
"
| ``[<taskname>#txpwr]``
","
| Returns the current setting for transmit power via WiFi. This is determined dynamically, depending on the corresponding settings in the Tools/Advanced page, RSSI and other factors.
"
"
| ``[<taskname>#free2ndheap]``
","
| Returns the available memory on the 2nd heap, **only** available in some specific ESP8266 builds, else it shows 0.
"
"
| ``[<taskname>#internaltemp]``
","
| Returns the internal temperature of the ESP. **Only** available on ESP32 units. For ESP32-S2/S3/C2/C3/C6 MCUs there is official support for the internal temperature sensor via the Espressif libraries, that has compensation applied so it shows a realistic value. For ESP32 Classic this is determined empirically, based on the deviation of the 150 kHz internal clock generator, that is rather temperature dependent, compared to the (stable) crystal frequency. This should not be seen as an absolute temperature, but *can* be used as a relative measurement f.e. when comparing heavy load vs. light load situations.
"
10 changes: 7 additions & 3 deletions docs/source/Plugin/P036.rst
Original file line number Diff line number Diff line change
Expand Up @@ -66,17 +66,21 @@ Device Settings
.. image:: P036_ScrollOptions.png

* **Scroll**: Switching between pages can be "instant", "scrolling" or a "ticker" band. Please note that scrolling will need more resources of the ESP, which can have an effect on other active tasks of the node.

For the ``Ticker`` there are some restrictions:

* Depending on the build used (NORMAL and CUSTOM) this option is available
* only one line is displaying the ticker string
* all line contents are parsed and combined to this ticker string, the parsing happens only at each ticker start (using the setting ``Interval``)
* the optional split token ``<|>`` is replaced by three spaces
* the gaps between the ticker items must be set by the ``line content`` (tailing spaces)
* the gaps between the ticker items must be set by the ``line content`` (trailing spaces)
* the starting alignment (left, center, right) depends on the setting ``Align content (global)``
* the font is taken from the setting ``Modify font`` of the first line, the ``Alignment`` settings of the lines are ignored (always right aligned)
* the ticker speed depends on the length of the ticker string and the setting ``Interval`` setting
* the ticker speed depends on the length of the ticker string and the task ``Interval`` setting
* the footer is automatically hidden

.. spacer

* **GPIO <- Display button**: Setting up a ``Display Button``, allows to configure a Display Timeout and wake the display on demand, either by a button, or by using some presence detection.

.. image:: P036_PinModeOptions.png
Expand Down Expand Up @@ -108,7 +112,7 @@ Content

.. image:: P036_HeaderOptions.png

* **Header** / **Header (alternate)**: The plugin allows for a header line, which may show some user selectable information. When using a different setting for **Header (alternate)**, the header will be updated halfway of the Interval time.
* **Header** / **Header (alternate)**: The plugin allows for a header line, which may show some user selectable information. When using a different setting for **Header (alternate)**, the header will be updated halfway of the Interval time. The **User defined 1/2** options are not available in all builds. If they are available, their content can be set using the ``oledframedcmd,userDef1,'<user Defined Header1>'`` and ``oledframedcmd,userDef2,'<user Defined Header2>'`` commands (by default they are empty), see the command reference below for details.

* **Scroll long lines**: When checked, lines that won't fit on the display will be scrolled to be completely shown.

Expand Down
Binary file modified docs/source/Plugin/P036_HeaderOptions.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
122 changes: 77 additions & 45 deletions src/_P026_Sysinfo.ino
Original file line number Diff line number Diff line change
Expand Up @@ -5,44 +5,46 @@
// #################################### Plugin 026: System Info ##########################################
// #######################################################################################################


# include "src/DataStructs/ESPEasy_packed_raw_data.h"
# include "src/ESPEasyCore/ESPEasyNetwork.h"
# include "src/Globals/ESPEasyWiFiEvent.h"
# include "src/Helpers/Memory.h"

# include "ESPEasy-Globals.h"
/** Changelog:
* 2023-09-24 tonhuisman: Add support for getting all values via Get Config option [<taskname>#<valuename>] where <valuename> is the default
* name as set for an output value. None is ignored. Not available in MINIMAL_OTA builds.
* Move all includes to P026_data_struct.h
* 2023-09-23 tonhuisman: Add Internal temperature option for ESP32
* Format source using Uncrustify
* Move #if check to P026_data_struct.h as Arduino compiler doesn't support that :(
* Move other defines to P026_data_struct.h
* 2023-09-23 tonhuisman: Start changelog
*/

# define PLUGIN_026
# define PLUGIN_ID_026 26
# define PLUGIN_NAME_026 "Generic - System Info"

// place sensor type selector right after the output value settings
# define P026_QUERY1_CONFIG_POS 0
# define P026_SENSOR_TYPE_INDEX (P026_QUERY1_CONFIG_POS + VARS_PER_TASK)
# define P026_NR_OUTPUT_VALUES getValueCountFromSensorType(static_cast<Sensor_VType>(PCONFIG(P026_SENSOR_TYPE_INDEX)))

# define P026_NR_OUTPUT_OPTIONS 14
# include "src/PluginStructs/P026_data_struct.h" // Arduino doesn't do #if in .ino sources :(

const __FlashStringHelper* Plugin_026_valuename(uint8_t value_nr, bool displayString) {
const __FlashStringHelper* strings[] {
F("Uptime") , F("uptime"),
F("Free RAM") , F("freeheap"),
F("Wifi RSSI") , F("rssi"),
F("Input VCC") , F("vcc"),
F("System load") , F("load"),
F("IP 1.Octet") , F("ip1"),
F("IP 2.Octet") , F("ip2"),
F("IP 3.Octet") , F("ip3"),
F("IP 4.Octet") , F("ip4"),
F("Web activity") , F("web"),
F("Free Stack") , F("freestack"),
F("None") , F(""),
F("WiFi TX pwr") , F("txpwr"),
F("Free 2nd Heap"), F("free2ndheap")
const __FlashStringHelper *strings[] {
F("Uptime"), F("uptime"),
F("Free RAM"), F("freeheap"),
F("Wifi RSSI"), F("rssi"),
F("Input VCC"), F("vcc"),
F("System load"), F("load"),
F("IP 1.Octet"), F("ip1"),
F("IP 2.Octet"), F("ip2"),
F("IP 3.Octet"), F("ip3"),
F("IP 4.Octet"), F("ip4"),
F("Web activity"), F("web"),
F("Free Stack"), F("freestack"),
F("None"), F(""),
F("WiFi TX pwr"), F("txpwr"),
F("Free 2nd Heap"), F("free2ndheap"),
# if FEATURE_INTERNAL_TEMPERATURE
F("Internal temperature (ESP32)"), F("internaltemp"),
# endif // if FEATURE_INTERNAL_TEMPERATURE
};
const size_t index = (2* value_nr) + (displayString ? 0 : 1);
const size_t index = (2 * value_nr) + (displayString ? 0 : 1);
constexpr size_t nrStrings = NR_ELEMENTS(strings);

if (index < nrStrings) {
return strings[index];
}
Expand Down Expand Up @@ -77,6 +79,7 @@ boolean Plugin_026(uint8_t function, struct EventStruct *event, String& string)
case PLUGIN_GET_DEVICEVALUENAMES:
{
const int valueCount = P026_NR_OUTPUT_VALUES;

for (uint8_t i = 0; i < VARS_PER_TASK; ++i) {
if (i < valueCount) {
const uint8_t pconfigIndex = i + P026_QUERY1_CONFIG_POS;
Expand Down Expand Up @@ -134,8 +137,9 @@ boolean Plugin_026(uint8_t function, struct EventStruct *event, String& string)
// Work around to get the "none" at the end.
options[index] = Plugin_026_valuename(11, true);
indices[index] = 11;

const int valueCount = P026_NR_OUTPUT_VALUES;

for (uint8_t i = 0; i < valueCount; ++i) {
const uint8_t pconfigIndex = i + P026_QUERY1_CONFIG_POS;
sensorTypeHelper_loadOutputSelector(event, pconfigIndex, i, P026_NR_OUTPUT_OPTIONS, options, indices);
Expand All @@ -153,6 +157,7 @@ boolean Plugin_026(uint8_t function, struct EventStruct *event, String& string)
{
// Save output selector parameters.
const int valueCount = P026_NR_OUTPUT_VALUES;

for (uint8_t i = 0; i < valueCount; ++i) {
const uint8_t pconfigIndex = i + P026_QUERY1_CONFIG_POS;
const uint8_t choice = PCONFIG(pconfigIndex);
Expand All @@ -171,10 +176,12 @@ boolean Plugin_026(uint8_t function, struct EventStruct *event, String& string)
case PLUGIN_READ:
{
const int valueCount = P026_NR_OUTPUT_VALUES;

for (int i = 0; i < valueCount; ++i) {
UserVar[event->BaseVarIndex + i] = P026_get_value(PCONFIG(i));
}
#ifndef LIMIT_BUILD_SIZE
# ifndef LIMIT_BUILD_SIZE

if (loglevelActiveFor(LOG_LEVEL_INFO)) {
String log;

Expand All @@ -191,30 +198,49 @@ boolean Plugin_026(uint8_t function, struct EventStruct *event, String& string)
addLogMove(LOG_LEVEL_INFO, log);
}
}
#endif
# endif // ifndef LIMIT_BUILD_SIZE
success = true;
break;
}
# ifndef PLUGIN_BUILD_MINIMAL_OTA
case PLUGIN_GET_CONFIG_VALUE:
{
const String cmd = parseString(string, 1);

for (uint8_t option = 0; option < P026_NR_OUTPUT_OPTIONS; ++option) {
if ((option != 11) && equals(cmd, Plugin_026_valuename(option, false))) { // Use default valuename
string = floatToString(P026_get_value(option), 2, true); // Trim trailing zeroes
success = true;
break;
}
}
break;
}
# endif // ifndef PLUGIN_BUILD_MINIMAL_OTA
# if FEATURE_PACKED_RAW_DATA
case PLUGIN_GET_PACKED_RAW_DATA:
{
// Matching JS code:
// return decode(bytes,
// [header, uint24, uint24, int8, vcc, pct_8, uint8, uint8, uint8, uint8, uint24, uint16],
// ['header', 'uptime', 'freeheap', 'rssi', 'vcc', 'load', 'ip1', 'ip2', 'ip3', 'ip4', 'web', 'freestack']);
// on ESP32 you can add 'internaltemperature' of type int16 (1e2) to the list (disabled for now, so not available)
uint8_t index = 0;
string += LoRa_addInt(P026_get_value(index++), PackedData_uint24); // uptime
string += LoRa_addInt(P026_get_value(index++), PackedData_uint24); // freeheap
string += LoRa_addFloat(P026_get_value(index++), PackedData_int8); // rssi
string += LoRa_addFloat(P026_get_value(index++), PackedData_vcc); // vcc
string += LoRa_addFloat(P026_get_value(index++), PackedData_pct_8); // load
string += LoRa_addInt(P026_get_value(index++), PackedData_uint8); // ip1
string += LoRa_addInt(P026_get_value(index++), PackedData_uint8); // ip2
string += LoRa_addInt(P026_get_value(index++), PackedData_uint8); // ip3
string += LoRa_addInt(P026_get_value(index++), PackedData_uint8); // ip4
string += LoRa_addInt(P026_get_value(index++), PackedData_uint24); // web
string += LoRa_addInt(P026_get_value(index++), PackedData_uint16); // freestack
event->Par1 = index; // valuecount
string += LoRa_addInt(P026_get_value(index++), PackedData_uint24); // uptime
string += LoRa_addInt(P026_get_value(index++), PackedData_uint24); // freeheap
string += LoRa_addFloat(P026_get_value(index++), PackedData_int8); // rssi
string += LoRa_addFloat(P026_get_value(index++), PackedData_vcc); // vcc
string += LoRa_addFloat(P026_get_value(index++), PackedData_pct_8); // load
string += LoRa_addInt(P026_get_value(index++), PackedData_uint8); // ip1
string += LoRa_addInt(P026_get_value(index++), PackedData_uint8); // ip2
string += LoRa_addInt(P026_get_value(index++), PackedData_uint8); // ip3
string += LoRa_addInt(P026_get_value(index++), PackedData_uint8); // ip4
string += LoRa_addInt(P026_get_value(index++), PackedData_uint24); // web
string += LoRa_addInt(P026_get_value(index++), PackedData_uint16); // freestack
// # if FEATURE_INTERNAL_TEMPERATURE
// string += LoRa_addInt(P026_get_value(index++) * 100.0f, PackedData_int16_1e2); // internal temperature in 0.01 degrees
// # endif // if FEATURE_INTERNAL_TEMPERATURE
event->Par1 = index; // valuecount
success = true;
break;
}
Expand All @@ -226,6 +252,7 @@ boolean Plugin_026(uint8_t function, struct EventStruct *event, String& string)
float P026_get_value(uint8_t type)
{
float res{};

switch (type)
{
case 0: res = getUptimeMinutes(); break;
Expand All @@ -243,7 +270,7 @@ float P026_get_value(uint8_t type)
case 6:
case 7:
case 8:
res = NetworkLocalIP()[type - 5]; break;
res = NetworkLocalIP()[type - 5]; break;
case 9: res = timePassedSince(lastWeb) / 1000.0f; break; // respond in seconds
case 10: res = getCurrentFreeStack(); break;
case 12: res = WiFiEventData.wifi_TX_pwr; break;
Expand All @@ -252,6 +279,11 @@ float P026_get_value(uint8_t type)
res = FreeMem2ndHeap();
# endif // ifdef USE_SECOND_HEAP
break;
case 14:
# if FEATURE_INTERNAL_TEMPERATURE
res = getInternalTemperature();
# endif // if FEATURE_INTERNAL_TEMPERATURE
break;
}
return res;
}
Expand Down
Loading