For some strange reason....
Build log:
```
$ PLATFORMIO_BUILD_FLAGS="-D CONTINUOUS_INTEGRATION" platformio run -e $ENV
Processing minimal_core_242_ESP8266_1M_OTA (platform: https://github.com/TD-er/platform-espressif8266.git#patch/v1.8.0_Puya; board: esp01_1m; framework: arduino)
--------------------------------------------------------------------------------
Platform Manager: Installing git+https://github.com/TD-er/platform-espressif8266.git#patch/v1.8.0_Puya
git version 2.27.0
Cloning into '/home/travis/.platformio/.cache/tmp/pkg-installing-aktun99x'...
Platform Manager: espressif8266 @ 1.8.0+sha.9ffc857 has been installed!
The platform 'https://github.com/TD-er/platform-espressif8266.git#patch/v1.8.0_Puya' has been successfully installed!
The rest of the packages will be installed later depending on your build environment.
Tool Manager: Installing toolchain-xtensa @ ~1.40802.0
Downloading...
Unpacking...
Tool Manager: toolchain-xtensa @ 1.40802.0 has been installed!
Tool Manager: Installing framework-arduinoespressif8266 @ 2.20402.4-puya
Tool Manager: Warning! More than one package has been found by framework-arduinoespressif8266 @ 2.20402.4-puya requirements:
- platformio/framework-arduinoespressif8266 @ 3.20704.0
- jason2866/framework-arduinoespressif8266 @ 2.7.4.1
Tool Manager: Please specify detailed REQUIREMENTS using package owner and version (showed above) to avoid name conflicts
Error: Could not find the package with 'framework-arduinoespressif8266 @ 2.20402.4-puya' requirements for your system 'linux_x86_64'
The command "PLATFORMIO_BUILD_FLAGS="-D CONTINUOUS_INTEGRATION" platformio run -e $ENV" exited with 1.
```
Maybe @jason2866 does have an idea?
When adding the new webform I2C params function, it struck me how inconsistent the formatting of our code is.
So how looks like a good moment to uncrustify all I2C plugins as their code is touched anyway.
Use PIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK22x_191122 for all builds, unless mentioned otherwise.
This does seem to work just fine and reduces the number of bin files.
Loading and saving of display lines must be done using a temporary object and not via the task data object in memory as that may have been changed via write commands.
For example the Framed OLED plugin has a default number of lines per page of 0, but the limits of the field only allows 1 .. 4.
This makes it impossible to save the default settings without changing something.
There may be other settings which may have similar issues.
During load, the (large) task data struct was allocated on the heap, regardless whether it was already present in memory when the task was initialized.
During save, the (large) task data struct was allocated on the stack.
Both load and save now check whether there is already an instance present and use that instance.
If not, it creates a temporary instance for loading and saving of the settings.
Also the scrolling variable was not initialized, so it could happen the display would not start to show the pages as it was marked as "still being scrolling"
Fixes: #3155
For the ESP8266, we keep things like the last boot cause in RTC memory.
Currently that's not supported on ESP32 (in our code) so the last boot cause is never read and stored.
The max. UDP packet size could allow for a large memory allocation when a large packet was received.
No matter if this was a valid packet to process anyway.
The WiFi.connected() call sometimes returns `WL_DISCONNECTED` even though it is connected and serving web pages etc.
Added a timeout of 15 seconds to get out of this or else the WiFi state is reset to try again fresh.
It appeared the log handling function was sometimes processing flash strings or progmem strings and thus crashing with an exception.
Crashes like these:
```
ets Jan 8 2013,rst cause:4, boot mode:(3,6)
0x40275929 in String::operator=(char const*) at ??:?
0x4022cab9 in process_serialWriteBuffer() at ??:?
0x4023532b in addToSerialBuffer(char const*) at ??:?
0x402756a0 in String::copy(char const*, unsigned int) at ??:?
0x40238bd3 in addToLog(unsigned char, char const*) at ??:?
0x40275cac in String::concat(String const&) at ??:?
0x402b3849 in wifi_station_get_rssi at ??:?
0x402754bd in String::invalidate() at ??:?
0x40238c88 in addToLog(unsigned char, String const&) at ??:?
0x4025be2a in WiFiConnected() at ??:?
0x4025a500 in NetworkConnected() at ??:?
0x402cd8b0 in chip_v6_unset_chanfreq at ??:?
0x40238a9e in syslog(unsigned char, char const*) at ??:?
0x4021ebd3 in getMaxFreeBlock() at ??:?
0x4022cab9 in process_serialWriteBuffer() at ??:?
0x402754bd in String::invalidate() at ??:?
0x40238c25 in addToLog(unsigned12484 : Info : EVENT: Clock#Time=Mon,11:27
```
Also converted:
- StringConverter.ino
- Scheduler.ino
- ESPEasyStorage.ino
- Hardware.ino
- ESPEasy_checks.ino
- Convert.ino
Plus some clean up of now made obsolete forward declarations in ESPEasy_fwddelcs.h
Fixes: #3123
ControllerSettings and (large) struct for the controller config were active at the same time while it is not needed.
Also the host to send data to was connected twice, which may also lead to strange results.
There is still room for improvement as we still try to create the entire string in a fixed size buffer.
Maybe we can also send out the data in chunks?
Or determine the needed array size at runtime.
BUG: MaxFramesToDisplay was not updated if all display lines were empty -> display_indicator() crashed due to memory overflow
CHG: MaxFramesToDisplay will be updated after receiving command with new line content
CHG: Added some checks if P036_data are valid and if P036_data->isInitialized()
Add checks to see if allocating the relative large ControllerSettingsStruct failed.
This can be caused by either running out of memory or when memory gets fragmented.
Quote often the ControllerSettings are only used to get one or two values.
No need to keep this ~800 bytes large object allocated for more than absolutely needed.
`NOTIFIER_SET_NONE` should only be used for not adding default selection of plugins.
The positive define (USES_NOTIFIER) should be used in the code to determine whether the notifier page should be displayed. (and included in the code)
When the plugin task data is initialized, the execution order is:
- construct new data (and previously: start webserver)
- destroy existing data
As the webserver is stopped at destruction of the existing data,
start the webserver after the existing data is destroyed ( and no
longer at construction).
The serial data reading algorithm is 'reverted' to commit 1de1350 to
handle the parsing results within reading loop again.
E.g. the 'start detected' error is logged again.
CHG: re-schedule Settings.TaskDeviceTimer after JumpToPage to avoid any scheduled page change while jumping to pages
CHG: correct calculation of the page indicator counts
Just add "_LittleFS" to the PIO env label and it will compile with LittleFS instead of SPIFFS.
First impression:
- Load speed of web page is just WOW! (average 170 msec)
- Saving settings is terribly slow (1...2 seconds)
CHG merged with Tonis PR #3026
CHG: Jump to any page (Display button or command) is always without page scrolling
CHG: Jump to next page (Display button) is not allowed while page scrolling is running
BUG: temporary pointer to P036_data_struct was not deleted in PLUGIN_WEBFORM_LOAD
CHG: PLUGIN_WEBFORM_SAVE does not use a temporary pointer to P036_data_struct
CHG: Comments
CHG: Memory optimization (issue #2799)
CHG: Added setting for 'Disable scrolling while WiFi is not connected', scrolling is not smooth as long as the ESP tries to connect Wifi (Load 100%!)
BUG: Wifi-Bars not fully right for 128 pixel wide displays
BUG: clearing window for scrolling lines was too high and to narrow
BUG: content of lines with pixel width > 255 had to be shortened
CHG: scrolling lines improved
CHG: variables renamed for better understanding
Updated all packages we use to their latest version.
At least the latest Sphinx does seem to squish the documentation a bit, so we may need to update the template of our documentation.
Generate filename, included in the build
Use post Python scripts to move files to the right directory
Use post Python scripts to generate .bin.gz files.
ETH.macAddress()
which returns a String.
I changed it to the byte version of the function and now
uint8_t * NetworkMacAddressAsBytes(uint8_t* mac)
returns either this in Ethernet mode or
WiFi.macAddress(mac)
in Wifi mode.
- Hostname Handling refactored for better overview:
- String NetworkGetHostNameFromSettings() returns Settings.getHostname()
- String NetworkCreateRFCCompliantHostname() creates a RFCcompliant Hostname from Settings.cpp
- String NetworkGetHostname() returns the Hostname prevoiusly set in ETH or Wifi dependong on Mode
- MacAddress Handling refactored
- String NetworkMacAddress() returns the Mac addres of ETH or Wifi depending on Mode
- String WifiSoftAPmacAddress() returns WiFi.softAPmacAddress(mac) as String
- remove useless comments
- ETH.config moved after ETH.begin
- Added note: Be aware with ESPEasyP2P Network, since IP Address will change. There could be conflicts.
- Ethernet JSON
- Ethernet Variables
[APDS-9960 library] Added extensions and applied fixes from original Github project (including not merged yet improvements)
[P064] Added/updated documentation for Gesture - APDS-9960 plugin
[Documentation] Updated footer copyright notice to show 2018..2020
- ESP P2P is working
- Only ETH.beginPacket() with Standard Parameter is working at the moment, configuration will follow.
- Network.in not cpp/h files but this will be changed in future
- Some TODO: PKR: comments will be removed in the future, too
Fixes: #3019
Only setting the internal counter values is not enough.
The output values must also be set and a call to any optional formula must also be made.
A call to `PLUGIN_READ` will also store the values in RTC.
Especially on some custom devices wich need custom builds, the variable
is missing. This provides a new environment variable to customize the
default pin for the reset button.
It has become next to impossible to keep track of active issues due to the sheer amount of open issues.
So let's enable the stale bot to let the users requesting issues decide whether an issue is still active or not.
This one does seem to be the more stable one.
Still a bit uncertain what the difference is between
- `PIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK22x_190703`
-`PIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK22x_191122`
If it is really fixed now, we should for sure move away from .ino files as this is really bad the Arduino processor trips over these formatting issues.
The function `executeInternalCommand` now takes roughly 3 kByte less in the binary.
Expansion of the macro resulted in quite some additional binary size.
Now the logic is moved to a separate function.
When checking the "Use Extended Credentials", the user name + pass field for the controller can be extended up-to 128 bytes.
This limit is only applicable to the text field, so it can later be extended to longer when needed.
All user + pass fields for all controllers must be within the 1 kByte (including 1 extra byte per field)
this commit adds support for Gitpod.io, a free automated
dev environment that makes contributing and generally working on GitHub
projects much easier. It allows anyone to start a ready-to-code dev
environment for any branch, issue and pull request with a single click.
For I2C UART an I2C clock of 400 kHz is needed to be able to handle continuous streams of data.
But the default was still 100 kHz, unless you selected a plugin that may have set the I2C frequency to 400 kHz like the Framed OLED plugin.
- Argument number was incorrect
- did not set time source. (so you had to set NTP which defeats the purpose of this command
- Added documentation
- Moved the command call to the correct first letter of the alphabet.
This does include almost all needed for a plugin.
So it will make intellisense highlighting useful as otherwise almost each line in a plugin file will be marked red.
ESP32's WebServer class has the same name as our global object had.
So you could only define it in ESPEasy.ino.
Now it is renamed to `web_server` and now ESP32 and ESP8266 will happily build with the global object defined in .h/.cpp.
Trying to make the parseSystemVariables function smaller
Moved time related functions to their respective .h/.cpp classes.
This will make the code a bit more clean and also reduces the build size.
The TXBuffer is a "header only" implementation.
This means it may be compiled "inline" and thus takes quite a bit of compiled code.
This makes the binary larger and slows the ESP down.
Now it is even possible to make core 2.6.3 builds using "minimal OTA".
The "Dev" build is roughly 55k smaller.
Sometimes a unit may crash and is not able to connect to WiFi.
But time based rules or the cron daemon may not work when there is no concept of time.
This stores the last known system time in RTC memory to keep track of time.
It can also be used for some diagnostics while it is also sent to log what the last known time was before the crash/reboot.
Each normal reboot does cause a "shift" in time of roughly -1 second. Abnormal (warm) reboots may add more as those may have been the result of watchdog reboots.
The plugin was assuming the values stored in UserVar were correct.
After a cold boot, or when the NTP time (or via GPS) was not yet set, these values for last time or next time could be just about any value.
This means it was possible the Cron task would never fire an event if the next time was computed far in the future.
Also restructured the code a bit, to make it more readable.
Also removed ProtocolIndex from the event struct as it is redundant information which can easily be forgotten to set.
Sorted the described commands in the documentation and added a few missing commands.
The sensor cannot output useful values after the IAQ init.
So we now keep track of the last known baseline values and restore them after the sensor is initialized.
For example after a reboot or a crash.
Also the values of TVOC = 0 and eCO2 = 400 will be ignored as new values right after sensor init.
The sensor was performing IAQ init for every read, while it should only be done at init of the sensor.
The IAQ measurement should be performed every second.
See also #2886
This does make sure the initial network connection can transfer data.
On some nodes it took a lot of attempts to get a connection established right after boot.
The functions used to call CPlugins are now part of an enum.
This also means the compiler can help to detect when some functions are not dealt with in a switch statement.
As suggested by @uzi18 should the plugin function defines be an enum instead of defines.
This will allow to do compile time checks and also check whether all cases are handled.
The calls to the existing library were blocking, so they could take a long time to send a message (over 2 seconds)
Now the library is using a state machine and the handling can be dealt with by calling the ...loop functions frequently.
The extra padding to a minimal line length does only make sense for use on displays and some special formatting.
So the majority of the uses of parseTemplate now uses 0 as minimum line length.
Fixes: #2866
Closes: #2867 (superseeds PR)
This was rather messy code and no checks.
It is now somewhat similar to the code for plugins defining the relation between:
- Plugin ID
- Task Index
- Device Index.
* substring
* strtol (useful for converting hex or binary numbers)
* 100ths division
in eventvalue parsing.
Using this modification I am able to handle the messages sent from Opentherm Gateway ( http://otgw.tclcode.com/ ) and to set variables of a dummy device in rules.
Example:
* Message coming from the serial interface: T101813C0
** The B denotes that the message is from the boiler.
** The next 4 bytes (actually 2bytes hex encoded) denote the status and type of the message.
** the last 4 bytes (actually 2bytes hex encoded) denote the payload.
* Message that ends up in rules when using ser2net (P020) and Generic handling: !Serial#BT101813C0
The room temperature in this sample is 19.75°C
Rule used to parse this and set a variable in a dummy device:
// Room temperature
on !Serial#T1018* do
TaskValueSet 2,1,[strtol:16:[substring:13:15:%eventvalue%]].[div100ths:[strtol:16:[substring:15:17:%eventvalue%]]:256]
endon
Now the variable can be used in the rules/controller/log/whatever.
CHG: Moved the array for the received bit changes to stativ uint_8t, the ISR call uses only a volatile pointer to it
CHG: some more defines and name changes for better explanation
Removed the while (P092_receiving) loop.
Starting of the receiving and processing of the received bit stream iare now done in the PLUGIN_ONCE_A_SECOND call
PLUGIN_READ call just uses the already processed data
See this issue where the changes in behavior for wificlient.connected() is discussed: https://github.com/esp8266/Arduino/issues/6701
A change dating back to April 2018 ( https://github.com/esp8266/Arduino/pull/4626 ) does have some implications on how to interpret the client.connected() result.
It is very well possible there is still data in the buffers waiting to be read.
So the loop() function of pubsubclient should first try to empty the received data and then decide what to do with the connected state.
So reading is fine, if there is data available, but writing needs an extra check.
The DL-Bus is used in heating control units e.g. sold by Technische Alternative (www.ta.co.at).
The idea for this plug-in is based on Martin Kropf's project UVR31_RF24 (https://github.com/martinkropf/UVR31_RF24)
The plug-in is tested and workis fine for the ESR21 device.
The plug-in should be also able to decode the information from the UVR31, UVR1611 and UVR 61-3 devices but not tested yet.
The selected input needs a voltage divider as follows because the DL-Bus runs on 12 volts.
Some JSON was invalid, for example when the closing entry of a list was optional (WiFi scanner)
The generated JSON for the I2C scanner was a bit useless, so made it more useful by only outputting addresses which have some device and included the list of supported devices.
I added a very basic JavaScript line to the rules page, where it appends the length of the rules.
Only problem is that the length in JavaScript is with a newline counted as \n and it outputs to the node with a newline as \r\n, so there is an offset of 1 byte per line.
But still gives me a good indication whether data is lost, which happens quite a lot when you cross the 1600 bytes
Known issue:
If you try to save and it fails, then the stored rules will be shown (not the one you just tried to submit)
The web arguments may get corrupted sometimes.
This can be due to another request mangling the already parsed arguments, or lack of memory to split the sent arguments into parsed ones.
It appears the events called from rules must be run immediately, but there are some use cases where it can be useful to have async events.
So changed back the behavior for events called from rules, to be executed immediately.
Added the new command AsyncEvent.
A lot of people were running into issues with some commands no longer working after the changes of strict rules parsing.
This flag in the advanced settings may help out a bit.
Also the logs are made a bit more elaborate to describe the issue.
We already had a EventBuffer, which was mainly used by received events from a controller.
This was only 1 element long, so events could be missed.
This is now changed into a queue, which will be processed in the 10/sec call.
Events will now be stored in the queue, unless there is a need for them to be executed immediately (for example if the source is waiting for a reply)
Events generated in the rules by the event command will also be executed immediately.
Until now a lot of ways to handle a command were handling the pre-processing of the command differently.
So the source of the command can make a difference whether system variables can be used for example.
Now all use the same function to pre-process the commands.
The WiFi.disconnect() ensures that the WiFi is working correctly. If this is not done before receiving WiFi connections,
those WiFi connections will take a long time to make or sometimes will not work at all.
Store the last used BSSID and channel in the RTC and use it for initial WiFi connect attempt.
This does speed up the WiFI connection to about 1.8 sec after boot.
Old situation was connected at about 3.9 sec after boot.
When booting from cold boot, the strongest known RSSI is chosen first.
MQTT controller queue handling is now more aggressive in trying to get rid of buffered packets.
It also now accepts the MQTT messages before it is connected to WiFi (or when not yet reconnected)
These builds (especially the custom ones) take quite some time to build and Travis was constantly exceeding max. build time.
Also the 16M builds (14 MB SPIFFS) are hardly useful, since they are way too slow to be practical.
New ASAIR brand DHT11 can support decimal and negative values.
Change conversion coding As same as DHT12.
Old type DHT11 also OK.
DHT11 datasheet. 2017-03-31 V1.3
4. 5.2 temperature parameter list to update the tabular form, measuring
range is 0 to 50 to - 20 to 60 .
CHG: Using a calculation to reduce line content for scrolling pages instead of a while loop
CHG: Using SetBit and GetBit functions to change the content of PCONFIG_LONG(0)
CHG: Memory usage reduced (only P036_DisplayLinesV1 is now used)
CHG: using uint8_t and uint16_t instead of byte and word
CHG: Each line can now have 64 characters (version is saved as Bit23-20 in Settings.TaskDevicePluginConfigLong[event->TaskIndex][0]))
FIX: Overlapping while page scrolling (size of line content for scrolling pages is now limited to 128 pixel)
Create a file named "pio_envlist.txt" next to the Custom.h for Vagrant with the selected env names in it, one per line.
Vagrant will then build all named PIO environments.
The timer to disable AP mode should be set as soon as the AP is started, to make sure it will be disabled.
It only will be increased when a client connects to the AP mode.
When disabling the AP mode, it needs a check to see if the AP mode was actually disabled before clearing the AP off timer.
1. Display commands:
oledframedcmd display [on, off, low, med, high]
turns display on or off or changes contrast (low, med or high)
2. Content commands:
oledframedcmd <line> <text> <mode>
displays <text> in line (1-12), next frame is showing the changed line, mode not implemented yet
CHG: Header content only changed once within display interval. before every second
CHG: more predefined constants to understand the meaning of the values
Set a compile time option to send the String representation of the IR signal back to the conrroller.
Defaults to the old behaviour so it does not brake anything.
CHG: Page scrolling based on Timer (PLUGIN_TIMER_IN) to reduce time for PLUGIN_READ from 700ms to less than 80ms (not as smooth as before but non-blocking!)
[P036] Added pagination to customized header
[P036] Time can be always selected in customized header, even if the time is diplayed by default for 128x68
Fixes: #2704
This is quite a serious bug in comparing values.
The compare was using the wrong values on a compare line when multiple compares had to be made. (with multiple and/or)
[P036] NEW more OLED sizes (128x32, 64x48) added to the original 128x64 size
[P036] NEW Display button can be inverted
[P036] NEW Content of header is adjustable, also the alternating function
[P036] CHG Parameters sorted
event->BaseVarIndex is set only at a few places in the code, so adding checks there is enough to make sure all uses of event->BaseVarIndex are safe.
Especially when computing a userVarIndex from event values (user input) the range should be checked before using it to access an element in the UserVar array.
After finding a number of calls to toString() with only a single parameter, the value would be converted into a bool and then printed.
This will yield in unexpected results without a compiler warning.
Fixed a bug 1 year old (in my own code) in P009 and P019 that was returing a state of 255 instead of -1 in case of state=offline.
The reason of the bug was that the Read function was forced to a byte variable instead of a int8_t variable.
This could generate a loop (and eventually a crash) if the monitor command was set to a pin that was offline. Infact the state returned was 255 and the current state was -1, so they never matched and a new event was created every 1/10 seconds.
This was actually a bug, since only the toString(bool) was forward declared.
Meaning the conversion of a float to a string was not performed as expected when called from a .cpp file instead of a .ino file.
When enabling the FEATURE_SD, something with the define of __FlashStringHelper is not correct anymore.
This needs a lot of changes which were needed anyway.
But also arrays of __FlashStringHelper must be changed.
All done so far, only need to have a look at
static const __FlashStringHelper *gpMenu[8][3] = {
Command format is IRSEND,{"protocol":"<protocol>","data":"<data>","bits":<bits>,"repeats":<repeat>}
It is backwards compatible with the old one (IRSEND,<protocol>,<data>,<bits>,<repeat>)
See #2650
The counter wifi_connect_attempt is being used to determine whether the fallback SSID should be tried.
It is also used to determine whether a "quick reconnect" is possible using the BSSID and channel of the last successful connection.
If the connection is unstable, (last connection was active for over 5 minutes) then the connect attempt counter can be reset.
See #2650.
As long as a client is connected to the node in AP mode, no automatic reconnect should be attempted since it will make it very hard to get connected or remain connected to the AP mode.
The WiFi channel will change during scan which will disconnect the user.
The ESP could sometimes experience a crash when saving the rules.
This was caused mainly on fragmented file systems and a bit longer rules files.
Now the same saveToFile function is used as being used in all other settings file access.
Also the rules were copied in memory, which is useless since they are already present in memory (LWIP code) and passed by const reference.
The changed rules parsing may have added some spaces in replaced variables.
Adding a trim() call to the parseString does remove any existing or added spaces in the parameter.
When using settings containing configuration for a certain plugin which is not included in the actual build, then the plugin must be displayed as "not supported" and not possible to edit.
Also show some indication about the consequences of trying to edit such a task. It will then present a dialog equal to adding a new device to a task.
See #2676
The use of DeviceIndex was not consistent, which may lead to strange issues.
DeviceIndex is the translation between the vector of included plugins and IDs of plugins available.
Rules parsing starts with 2 steps:
- Reading line from rules file
- If read line is no comment line, see if it does match the event block we're looking for.
This second part is done in the ruleMatch function.
This function was doing a bit more than strictly needed.
This optimization is mostly about trying to exit as soon as possible and using less memory allocations in Strings.
Fixes: #2642
Problem was in the conversion to int, which may add a leading space.
The parsing of int and float string values should be able to handle leading spaces, so fixed that.
When starting the ADC plugin at boot, the WiFI connection attempt is already started.
This may offset the average value quite a bit.
This fix will exclude those samples from the values used to compute the average while oversampling.
The check in the code was for #ifndef BUILD_NO_DEBUG.
But even when it is defined as 0, it is still defined.
So the code was still included in the binary.
Specify only a subset of PIO envs to build, to make sure it will build within the 50 minutes time limit, even when the caches are cleared by PlatformIO.
Also add some caches to find task-value names.
Fix some minor issue when referring [var#n] variables. These were always rounded to 2 decimals.
Also added [int#n] to address the same variables as with [var#n] but rounded to integer values, to be used in rules for more reliable comparing.
The clean step may no longer be needed, which makes it more useful to have the last built directories restored from the cache and hopefully reduce build times.
Does not yet act on the new errors, but at least it should be possible in the plugins to detect whether any data was received to see if a device is present.
See also https://github.com/letscontrolit/ESPEasy/issues/2616
The parsetemplate function was almost always shown as function with the lowest free memory when called.
The function did make a lot of memory re-allocations and was very hard to read.
This commit is about reducing the memory allocations and speed up the parsing.
Will also fix [this issue reported on the forum](https://www.letscontrolit.com/forum/viewtopic.php?p=39219#p39219)
Added support for MITSUBISHI KJ series heatpumps / remote control type SG161.
Also added a IR_DEBUG_PACKET define to be able to feedback and debug the IR packet as added text output to a browser, curl or other http request tool.
The conversion was staring after the reading of the temperature
also there was effectively no delay after the conversion for the sensor to do its thing. This 2 factors combined made the ESP report the previus measurment and not the current
The WiFi setup page does set a flag to indicate the connect attempt was initiated from the setup.
But the flag was only reset when the setup page reloaded..
If that did not happen, the node could retry forever to (re)connect to the AP if the channel was changed or the node cannot see the old BSSID anymore (e.g. out of reach when using repeater)
Also the first attempt after changing WiFi settings would also (initially) fail due to retrying with old BSSID/channel combination.
Do not declare static functions in a header file, since everywhere the function signature is called, it will call a copy of the function and thus the function in the header file where it is defined, is never called.
The MemAnalyzer tool was not able to perform a proper analysis of the current builds, since we introduced the `USES_P001` syntax of defines to determine what should be included and what not.
As stated in LWIP documentation:
https://www.nongnu.org/lwip/2_1_x/multithreading.html
"When running in a multithreaded environment, raw API functions MUST only
be called from the core thread since raw API functions are not protected
from concurrent access (aside from pbuf- and memory management
functions). Application threads using the sequential- or socket API
communicate with this main thread through message passing."
https://www.nongnu.org/lwip/2_1_x/netifapi_8h.html
Is not present in current esp-idf / arduino-esp32 builds.
Using existing "private" TCPIP API, create a minimal struct to pass a message
to the LWIP thread instead of calling etharp_gratuitous directly.
Trying to reduce size of the compiled binaries by excluding certain parts of the code if not needed.
See definitions at the end of 'define_plugin_sets.h'
Currently done:
- Casting all controllers that are not included
- Casting all MQTT related code
- Casting all Domoticz related code
The last page of the wizard now shows the network info, just like in the sysinfo page and has a button at the bottom which links to the IP address of the node on the normal network
This last page of the setup also has the menu bar at the top and also the default template now shows a warning when you're connected via AP mode.
This allows for easier setup, since you don't have to switch networks anymore
Move WiFi/Network related functions into separate files to keep them organized and easier to locate.
Also added lots of comments and some documentation on the state machine handling WiFi connect and reconnects.
Simplified the WiFi connect state machine.
Fixed setup of initial WiFi configuration.
AP mode is now kept as long as client is connected.
AP mode will be started immediately if there are no valid WiFi credentials, or after 20 seconds of no wifi connection.
AP mode will be disabled 60 seconds after starting it, or after the last client disconnected from the AP.
This makes it easier to adapt settings, since platform and build_flags both depend on the same variable section.
Thus it makes sense to have them on consecutive lines.
Makes the rest of the decoder.js a lot simpler.
Also changed the GPS lat/long into 3 bytes again, saving 2 bytes in the packet length.
GPS outputs now 7 values using 18 bytes (incl. header)
This does allow uploading even more parameters than the 4 supported by ESPeasy, since encoder and decoder can be tailored to the specific plugin.
For example the GPS plugin can now upload 7 parameters in only 20 bytes.
Still to do: Why can the decoder not handle encoding per 24 bit? (lat/lon do fit perfectly fine in 24 bit).
For LoRa, it may take a while to send out samples of different plugins.
This makes it hard to match samples belonging to the same set after receiving them.
The Sample Set Initiator is a task index which should always be considered as the first of a set samples sent to the controller.
For example when triggering to send a set of samples from rules, its order can be always the same.
Setting the initiator to the first one of the sequence, the same sample set counter will be sent along with the samples.
Normally a controller uses a hostname or IP to connect to.
But a LoRa node does not connect to any specific host, but does broadcast messages using its own unique dev addr.
This will be shown as host description in the Controller overview page.
Move loading and saving of controller settings to separate functions per item.
Also string generation is now done in a function to keep internal strings in sync.
The flag to signal a successful boot was only set when there was a successful WiFi connection.
But this can lead to step by step disabling of plugins when the accesspoint is unreachable for a long time.
Some plugins and controllers were writing to TXBuffer.buf directly.
This should not happen, since then the memory usage of that buffer will increase and never decrease again.
Also C011 Generic HTTP advanced was not using existing functions for displaying config page.
The node delivering the data for a plugin is now shown on the device page in the "Port" column.
Also added a fix to only allow updates from 1 node to a remote node.
Previously it was possible to have several nodes writing to the same remote p2p shared plugin.
This could lead to very strange results.
This also means that a remote installed plugin must now be deleted and re-installed to allow receiving data from a remote host if the remote host unit id has changed.
For example a stream at 38400 bps can fill up the serial buffer over 27x a second.
This means that receiving data strings over 128 bytes (buffer size) may already be corrupted when reading at 10x a sec.
Just an initial skeleton to build the new Serial Proxy plugin.
It will fetch data and move it to a controller.
This will be the first plugin to handle something other than float values.
As described by @davidgraeff openHAB is supporting Home Assistant MQTT convention, so C005 should have Home Assistant in name.
Arguments:
openHAB is following HA convention
this will help new users (like me) to setup ESPEasy with Home Assisnant
Since there are not that much PRs open and in progress, this is maybe the least intrusive moment to cleanup some code using the given uncrustify.cfg
If there is a PR merge issue, checkout the PR and perform an uncrustify first before trying to merge.
The Dallas 1wire sensor can get into some error state.
To signal an error state, a NaN was ouput, but that may be hard to use in rules.
This selector allows to set a fixed value to signal an error state.
Also removed a lot of redundant code and make sure no data is shared among other active instances of the same plugin.
Auto gain will switch on/off the gain to extend the range of the sensor.
The 16x gain will be turned on below 10 Lux.
It will be off at 1/16th of the full range of the ADC.
On top of that there is also an option to extend the range of the sensor to about 130'000 lux.
The ratio ch1/ch0 will be stored as long as no ADC is clipping. This ratio will be applied to the measured ch1 (IR part) of the measured data when the ch0 value is clipping.
For example meauring direct sunlight may give upto 130'000 Lux of light intensity, but the sensor itself can only handle upto about 30'000 Lux without clipping.
Saturation level of the CH0 and CH1 ADCs is not at 65535 for all integration time settings.
For an integration time less than 178 msec, the max ADC value is less. This fix does detect those saturation levels.
The Uncrustify package in VS code does look in the project dir for a config file.
When it is present, there is hardly any configuration needed. Therefore I moved it and updated it a bit to behave more uniform than the cfg file we already had.
Just for testing/debugging purposes, the last executed task from the scheduled is logged into RTC memory.
This decoded string is also logged at boot and shown in the system info page.
It still demands quite some expertise to interpret but maybe we can find some pattern to where the crashes occur most often.
-Extended command example:
IRSENDAC,"protocol":"GREE","power":"off","mode":"heat","temp":21,"fanspeed":"max","swingv":"middle","swingh":"off"}
-Refactored and simplified code based on new libary updates
-1M IR build does not support Extended AC commands
-Usage instructions added
-Also added back the ability to have arbitrary bits to the IR send command. Reflected that also in the received signal decoding. Using 0 bits as an argument the ir send command will still use the default protocol bits
ref: https://www.letscontrolit.com/forum/viewtopic.php?f=4&t=6452&p=37373#p37373
Core 2.5.2 does contain a lot of fixes.
If this core version does seem to appear stable in the next few weeks, we will use it as the standard core for nightly builds.
Since Release mega-20190215, the plugin “ P065_DRF0299_MP3.ino “ wasn’t functioning on GPIO16.
With this small change, it’s operational once again and also available to connect other serial (non-critical) devices on GPIO16.
It is now possible to select different values for output.
A new output will be given when either the Interval time has passed, or a set minimal traveled distance is exceeded.
This can then be used in rules to trigger other samples.
There was still a hard-coded delay left in the process modbus command function.
Now it returns as soon as a valid reply is received.
This will make the PLUGIN_READ call of SenseAir S8 take 45.1 msec instead of 59.1 msec on average.
The calibration is now presented more clear.
Added an option to clear the logged data in the AccuEnergy sensor
Fixed an inconsistency in reported Watt and Wh.
Added display of imported/exported/net/total energy.
For example the SysInfo plugin should be made more flexible in the number of outputs.
Also the SenseAir plugin now supports multiple outputs to be able to get CO2 and sensor temperature for example. (temp reading is not yet correct)
Debouncing was no real debouncer before, this is fixed now.
Instead of setting a delay after a change occured during this the counter is "blind" the counter now waits for the next edge in the pulse signal and calculates then the time that the last state was active.
Only if the debounce threshold is exceeded the counter will be increased.
The SPIFFS may become fragmented, so it is possible a file cannot be appended to even though there is room on the file system.
So there has to be a proper check to see if writing fails and also delete oldest file(s) when needed + call to the garbage collector.
See also https://github.com/esp8266/Arduino/issues/5987
- hook for CPLUGIN_GOT_CONNECTED placed correctly
- hook for CPLUGIN_GOT_INVALID placed + added log
- fixed return values
- some log fixes
- cleaned up code
issues
I Think MQTTclient_should_reconnect=true does not reconnect if there is a working connection. In case of CPLUGIN_GOT_INVALID success a MQTTDisconnect(); function added.
The last read values were only saved when the device enters sleep mode, not when new values are read.
So after a reboot (as a result of a crash) the values were at their initial values.
P016_TIMEOUT is set now to 50 instead of 90 as a compromise between stability of decoding and accomodating large IR signals.
Also added breaks to mitigate unstability with long operations that might starve the ESP from backround tasks
Reverted and made compatible and optional the old style of the irsend command that supported also repeats
Both commands
IRSEND,NEC,ASDF123
and
IRSEND,NEC,ASDF123,0,0
will produce the same result.
to repeat the signal 1 time the command is
IRSEND,NEC,ASDF123,0,1
Create a much bigger CSV using 12*4 value columns with all labels on top.
6000 samples takes about 35 - 80 seconds depending on the number of 0.0 values (more zeroes, less time, smaller size)
The size of the CSV ranges between 900 and 2600 kByte for 6000 samples.
Export speed is 70 - 160 samples per second.
Calling `/dumpcache' will generate a CSV file of all logged data.
This may block the ESP for a while, since it outputs about 250 samples per second.
So 480'000 bytes of flash storage takes roughly 70 seconds to dump to a 1.6 MByte CSV. (20'000 samples)
Some settings have char arrays. Make sure these are 0-terminated when stored or loaded.
For example the ExtraTaskSettings were used without these checks
Use a state to process reading temp and hum or keep error.
The state is handled in the 10/sec call and when a new measurement is ready it will schedule itself to read the new values.
See #2407
There may be some unexpected responses after the reset.
So do not reset the sensor unless > 10 unknown responses were seen and also do not reset within 3 minutes after sensor reset.
Apparently the last update broke handling of unexpected response to commands.
According to the datasheet, the sensor should not give a response to some commands, but it does.
These responses should not lead to a reset of the sensor.
This will allow to reduce code duplication, reduce strings used in binary and makes code better readable.
This is a project which may take some time to cover all code.
Saves 20K of flash memmory. They provide no functionality other than giving log stirngs of that short:
"Mesg Desc.: Power: On, Fan: 5 (AUTO), Mode: 3 (HEAT), Temp: 22C, Zone Follow: Off, Sensor Temp: Ignored"
When using 'Oversampling' the Analog input plugin is simply summing all samples and upon calling the read function it will divide this sum by the number of samples.
This added filtering is keeping track of the lowest and highest value measured in this loop and excludes these extremes.
This makes the reading a lot more stable, since it is often only a single extreme value which causes noise in the reported values.
Also added a note to the setup page near the calibration points to make it easier to add calibration values. It shows the current raw value + its calibrated equivalent (if enabled).
Saves 20K of flash memmory. They provide no functionality other than giving log stirngs of that short:
"Mesg Desc.: Power: On, Fan: 5 (AUTO), Mode: 3 (HEAT), Temp: 22C, Zone Follow: Off, Sensor Temp: Ignored"
Eco mode will call delay() from scheduler during idle loops. (significant energy reduction of up-to 0.25 Watt)
WiFi_NONE_SLEEP will keep wifi on continously (max energy consumption)
Gratuitous ARP will be sent to keep the MAC tables in switches know about the MAC of the ESP node.
The interval for sending ARP messages is dynamic. The interval between these ARP's is increasing up-to 60 seconds interval, so we're not flooding the network.
But on some occasions this interval time is reset to 100 msec (and doubled each next interval step), so we're announcing ourselves a bit more often.
Known issue:
- WiFi always on does seem to miss some packets (unstable RF due to heat?)
- UDP packets sent for ESPeasy p2p do seem to be missed more often as soon as the power consumption of the node is actually reducing.
- Eco mode may take some time to actually reduce power consumption of the node. It is like the underlying core library is dynamically increasing/decreasing the power consumption of the node. (core 2.6.0, SDK2.2.1)
This will reduce the loop counter and even cause some inverse effect. Higher loop count means the node has more work to do (less scheduled tasks which are not yet due for work)
Initial tests show a significant lower power consumption and thus hopefully a more stable wifi connection.
The average used delay during idle calls can be seen in the timing stats (likely around 2.5 msec per idle loop)
The CPU load (in %) is still the same as before this patch, but the node feels a bit more 'snappy' and the extremes in the timing stats are lower.
In the backgroundtasks and also for a number of other network related operations there was no check for connectivity.
This could lead to various timeouts and maybe hanging processes. (Hardware watchdog resets)
Also:
- included core 2.6.0 alpha build with SDK2.2.1
- included core 2.6.0 alpha build with SDK3.0.0-dev
- Made memory size in bin filenames consistent (_4M instead of _4096)
- There were some unicode characters
- JPG file had wrong image type
- Documented the needed packages to build LaTeX documentation in Linux (still fails to build PDF dus to chapter count overflow)
For ways to *support* us, see [this announcement on the forum](https://www.letscontrolit.com/forum/viewtopic.php?f=14&t=5787), or have a look at the [Patreon](https://www.patreon.com/GrovkillenTDer), [Ko-Fi](https://ko-fi.com/grovkillentder) or [PayPal](https://www.paypal.me/espeasy) links above.
@@ -12,7 +12,6 @@ Introduction and wiki: https://www.letscontrolit.com/wiki/index.php/ESPEasy#Intr
**MEGA**
:warning:This is the development branch of ESPEasy. All new untested features go into this branch. If you want to do a bugfix, do it on the stable branch, we will merge the fix to the development branch as well.:warning:
Next stable branch: https://github.com/letscontrolit/ESPEasy/tree/v2.0 (bug fixes only, since oct 2017))
Check here to learn how to use this branch and help us improving ESPEasy: http://www.letscontrolit.com/wiki/index.php/ESPEasy#Source_code_development
@@ -21,24 +20,31 @@ Check here to learn how to use this branch and help us improving ESPEasy: http:/
Every night our build-bot will build a new binary release: https://github.com/letscontrolit/ESPEasy/releases
The releases are named something like 'mega-20180102' (last number is the build date)
The releases are named something like 'mega-20190225' (last number is the build date)
Depending on your needs, we release different types of files:
@@ -22,8 +22,9 @@ Build type can be: (differ in included plugins)
There is also a number of special builds:
- normal_IR => "Normal" + IR receiver/transmitter plugins and library
- hard_xxxxx => Special builds for some off-the-shelf hardware.
- normal_core_241 => "Normal" using core 2.4.1, since 2.4.2 has issues with PWM
- minimal_ESP82xx_1024_OTA => Minimum number of plugins and a limited set of controllers included to be able to perform a 2-step OTA on 1 MB flash nodes.
- minimal_ESP82xx_1M_OTA => Minimum number of plugins and a limited set of controllers included to be able to perform a 2-step OTA on 1 MB flash nodes.
- normal_core_xxx => "Normal" using core xxx (e.g. 2.4.1)
- normal_beta => "Normal" using the staged (beta) branch of the esp8266/Arduino repository.
Chip can be:
- ESP8266 => Most likely option
@@ -31,13 +32,44 @@ Chip can be:
- ESP32 => Experimental support at this moment
MemorySize can be:
- 1024 => 1 MB flash modules (e.g. almost all Sonoff modules)
Many systems provide a simple HTTP API where data can be changed using a HTTP request with a properly constructed querystring.
This Controller allows you to send HTTP GET, POST and PUT Requests to the given webserver.
For every device you have to choose to which Controllers it is sending its data. When configuring the Controller you can access this data and use them to generate your querystring.
You can use this placeholders in http header and in the http body:
*``%systime%`` will be replaced with the local system time
*``%vcc%`` will be replaced with the power supply voltage (if enable in this build)
*``%ip%`` will be replaced with the local ip adress
*``%sysload%`` will be replaced with the system load
*``%uptime%`` will be replaced with the system uptime
*``%CR%`` will be replaced with "\r"
*``%LF%`` will be replaced with "\n" (newline)
*``%sysname%`` will be replaced with the system name
*``%tskname%`` will be replaced with the name of the device which is sending data to this controller
*``%id%`` will be replaced with IDX value.
*``%vname1%`` will be replaced with Valuename 1
*``%vname2%`` will be replaced with Valuename 2
*``%vname3%`` will be replaced with Valuename 3
*``%vname4%`` will be replaced with Valuename 4
*``%val1%`` will be replaced with the value 1 of the device which is sending data to this controller
*``%val2%`` will be replaced with the value 2 of the device which is sending data to this controller
You can also write things like this:
``%1%_some_text_and_placeholder_%/1%`` everything between ``%1%`` and ``%/1%`` will only print when there is a value ``1``
It is possible to share the data collected by a plugin on one node so it can be used on another node.
This data can be used as if it is actually being run on the second node.
For example, a Dallas DS18b20 sensor on Node-1 is shared using the ESPeasy p2p controller.
This plugin can then automatically be setup on Node-2 and using the data collected by Node-1.
This is a rather non-intuitive process to setup.
Prerequisites
^^^^^^^^^^^^^
* Same UDP port must be setup on both nodes. (preferrably UDP port 8266) This can be done in Tools -> Advanced -> UDP port
* Nodes must be rebooted after UDP port has changed. (Builds before 2020-07-19)
* Each node must have an unique unit number. This must not be 0 and not 255, but anything inbetween is fine.
How to share a plugin
^^^^^^^^^^^^^^^^^^^^^
* Check to see if all nodes can see eachother. This will be visible on the main page showing a list of all nodes.
* Enable p2p networking controller on receiving node
* Make sure the receiving node has the spot free which is being used on the 'sending' node (For example slot 12)
* Enable p2p networking controller on sending node
* Set the plugin you want to share to use the p2p controller
Any node that is setup to receive data like this will see a plugin being added if the spot in the device list was still free.
Builds made after 2019/08/08 will show in the device overview page from which unit the shared plugin does get its data.
This also means the plugin must be removed and re-created if the sending node is changed. (e.g. another node or change of unit number)
In later builds there will be added an option to update this node number.
Some tips on trouble shooting
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
* Make sure to reboot the node after changing the UDP port.
* Make sure all nodes have an unique unit number and share the same UDP port.
* If you have ArduinoOTA enabled, use another port for ESPeasy p2p UDP (port suggested in most OTA examples use port 8266)
* Ping the nodes from some other host to keep their WiFi awake.
* Disable "Eco mode" in the advanced settings.
* Sharing a plugin to be auto installed on another node is only sent right after the plugin is set to use the p2p controller. So if you don't see it appear on the other node, save it again on the source node.
* Make sure the same plugin is available in the build on both nodes. (e.g. both supporting Dallas DS18b20, if that's the one you want to share)
* When using the "Guest" feature of an access point, some will not allow direct communication between clients on the same AP. This will also prevent this p2p protocol to share data.
* If updating from builds before 2019/08/08, you may need to remove and add again a plugin receiving data from a remote node.
Sending & Known Nodes
---------------------
@@ -111,10 +163,10 @@ Of each known node the following data is kept:
The key to index this ``NodeStruct`` is the nodes unit number.
ASCII Data
~~~~~~~~~~
^^^^^^^^^^^^^^^^
Command Message
***************
^^^^^^^^^^^^^^^^
First byte is not 0xFF.
@@ -123,19 +175,13 @@ The entire message processed as a command like this:
This controller connects to a MQTT Server providing auto-discover information and a communication protocol according to the Homie convention 3.0.1 and the future development version 4.0.0.
For more information head over to `Homie convention <https://homieiot.github.io/>`_
Idea is to provide an easy way to include ESPEasy in modern home automation systems without any or with as less effort as possible. Imagine your device pops up in openHAB 2.4 or higher as a new device and you only have to pic the values you are interested in. You can immediately see measurements or switch GPIOs without a single line of code.
When a MQTT connection is established after (re-)boot the controller sends auto-discovery information for system services like commands, basic GPIO functions and for all configured devices and there values. When all messages where sent successfully a homie compatible home automation server/hub or other compatible controllers should be able to detect the unit and establish two way communication.
The :ref:`P086_page` plug-in can be used to set values and trigger actions / rules.
MQTT topic scheme
-----------------
A homie topic scheme always starts with the root topic homie followed by the **unit name** (homie uses the term **device**), **device name** (**node** in homie) and a **value name**.
``homie/%unitname%/%devicename%/%valname%``
updates or commands can be sent by appending ``/set`` to the topics for values which can receive data.
``homie/%unitname%/%devicename%/%valname%/set``
Prequesites
-----------
A MQTT server capable of storing messages sent with ``retain=true`` when ``QoS=0``. Due to limitation (intentional not implemented due to low memory footprint and performance considerations) of the MQTT library (pubsubclient) used in ESPEasy it is only possible to send messages with ``QoS=0`` which basically means `fire and forget`. The current MQTT specification says that the server SHOULD store these messages when they arrive via ``QoS=0``. Some servers like the MQTT server currently build into openHAB 2.4 (moquette) is configured to ignore the retain flag and drop the message after delivery to the currently subscribed clients when ``QoS=0``. Mosquito on the other hand store messages when retain flag is set even when they are sent with ``QOS=0``.
Check with a MQTT client like MQTTspy or MQTTfx if the auto-discover messages are stored (retained).
A home automation server/controller capable talking Homie like openHAB since 2.4. (Be aware there are issues in the Homie implementation 2.4 including 2.5M1 milestone release not working as expected after restart). Recent snapshot builds should work.
Setup
-------------
- add the Homie **Homie MQTT (Version 4.0.0 dev)** or **Homie MQTT (Version 3.0.1 dev)** controller to your controller lists depending on your build.
- insert your broker address
- and user credentials if necessary
- the publish scheme is fixed to meet the homie requirements to ``homie/%sysname%/%tskname%/%valname%``
- the subscription scheme can be modified. Current defaults to ``homie/%sysname%/+/+/set`` to reduce incoming traffic to a minimum. Homie only expects messages via the ``homie/%sysname%/%tskname%/%valname%/set`` topic.
- last will topic (LWT) should set to ``homie/%sysname%/$state``
- LWT Connect Message to ``ready``
- LWT Disconnect Message to ``lost``
- save and reboot, best with connected serial monitor or syslog server with debug set to 4 (debug) or greater (alternatively use a MQTT client and subscribe to ``homie/%sysname%/#`` - replace %sysname% by the unit-name shown on the top of the webpage).
..image:: C0014_Setup_0.png
-``homie/%sysname%/$nodes`` enumerating all devices will be sent as final message of the auto-discover header.
- The final event log should look like this:
..code-block::none
5584 : EVENT: MQTT#Connected
5754 : C014 : autodiscover information of 4 Devices and 6 Nodes sent with no errors! (26 messages)
Troubleshoot
------------
The auto-discover information is sent through a big number of messages (usual more than 20). If your controller software not recognize your device or shows errors during the auto-discover process try the following steps:
- For testing purposes start with a basic setup with none or only one device configured and enabled.
- More devices can be added or (re-)enabled later.
- Disable already configured devices (devices without the enabled box ticked will be ignored)
- Check with a MQTT client if all messages are sent. The last message sent is ``$nodes`` attribute listing minimum the ``SYSTEM`` node if no other devices are enabled.
- check your WIFI connection. Perhaps bring your device nearer to your access point. (only necessary during the setup process because the messages should be stored by the broker)
- check via syslog or serial console if the messages are sent successful (you normaly can't see the log output in the web log)
- use the `mqqt-forget <https://www.npmjs.com/package/mqtt-forget>`_ tool to delete unused retained messages from your broker via wildcards
Features
--------
The controller currently supports these features
- send auto-discover nodes for all sending and enabled plug-ins to ``homie/%unitName%/%deviceName%/%valueName%``
- receive commands through the ``homie/%unitName%/SYSTEM/cmd/set`` topic.
- switch GPIOs through ``homie/%unitName%/SYSTEM/gpio#/set`` topic. The GPIO port must be set to **default low** or **default high** in the hardware tab to be included during auto-discover.
- send updates of GPIO ports to ``homie/%unitName%/SYSTEM/gpio#`` regardless from where the change is triggered (to be fully tested).
- in conjunction with :ref:`P086_page` actuators can be used according to the Homie convetion using rules.
- receive values for dummy devices via ``homie/%unitName%/%dummyDeviceName%/%valueName%/set``. From there the values can be processed further by using rules.
- handle ``$state`` attribute (for complete list see attribute table below)
-``init`` during boot process
-``ready`` during normal operation and as a heartbeat every 30sec (to be tested)
-``alert`` currently only if auto-discover fails. But if sending the auto-discover messages fails it is more than likely that sending the alert message will fail to. (ToDo: inform about other error states like low ram or stack available, repeating reboots or failed sensors)
-``sleeping`` sent before deep sleep
-``lost`` configured as LWT
-``disconnected`` sent to the old topic if the unit name changes to inform that the old topic is not valid any more. Auto-discover messages are sent automagically to the new topics afterwards.
- acknowledge received message by the ``homie/%unitName%/%deviceName%/%valueName%/set`` topic to the corresponding value ``homie/%unitName%/%deviceName%/%valueName%`` even if the value was changed by a different source like HTTP or rule to keep the state in your home automation system allays up to date. (Needs further testing)
Future / planned features
-------------------------
- a special Homie Plugin is in devolopment to pass ``\set`` messages to rules for further handling. Here ``$datatype`` and ``$format`` attributes for ``$setable`` values can be specified there. This will enable ESPEasy to handle direct inputs to plug-ins like dimmers (%,0:100), colors (RGB & HSV, 255,255,255), enum devices like remote controls (Play, Pause, Vol+, Vol-, ...). :yellow:`Testing` see :ref:`P086_page`
- Further in field testing with different MQTT brokers and home automation systems.
- Handling units via the ``$unit`` attribute. As ESPEasy is currenty "unitless" this needs a global concept within ESPEasy
- Handling ``$datatype`` attribute. Currenly all values (except cmd and gpio) are defined as ``float``. :yellow:`Testing` see :ref:`P086_page`
- Prepare some "working examples".
Under the hood
--------------
Auto-dicover information is sent by several $attributes
currently the following attributes will be sent during boot
"``$name``", "Friendly name of the device", "EPSEasy#1", "YES", ":green:`required`", "YES", ":green:`required`"
"``$homie``", "The implemented Homie convention version", "4.0.0", "YES",":green:`required`", "YES", ":green:`required`"
"``$state``", "See chapter features", "ready", "YES",":green:`required`", "YES", ":green:`required`"
"``$localip``", "IP of the device on the local network", "192.168.2.10", "YES", ":green:`required`", "NO", ":red:`void`"
"``$mac``", "Mac address of the device network interface.", "A1:B2:C3:D4:E5:F6", "YES", ":green:`required`", "NO", ":red:`void`"
"``$fw/name``", "Name of the firmware running on the device.", "ESPEasy mega", "YES", ":green:`required`", "NO", ":red:`void`"
"``$fw/version``", "Version of the firmware running on the device.", "20103 - Mega", "YES", ":green:`required`", "NO", ":red:`void`"
"``$nodes``", "Nodes which the device exposes separated by commas. Sent at the end for performance reasons.", "SYSTEM,SysInfo", "YES",":green:`required`", "YES", ":green:`required`"
"``$implementation``", "An identifier for the Homie implementation.", "ESP8266", "YES", ":green:`required`", "NO", ":red:`void`"
"``$stats/interval``", "Interval in seconds at which the device refreshes.", "60", "YES", ":green:`required`", "NO", ":red:`void`"
"``$stats/uptime``", "Time elapsed in seconds since the boot of the device.", "12345", "YES", ":green:`required`", "NO", ":red:`void`"
"``$stats/signal``", "Signal strength in %.", "75", "YES", ":blue:`optional`", "NO", ":red:`void`"
"``$name``","Friendly name of the property.","Command", "YES",":green:`required`", "YES",":green:`required`"
"``$datatype``","Describes the format of data. integer/float/boolean/string/enum/color","float", "YES",":green:`required`", "YES",":green:`required`"
"``$settable``","Specifies whether the property is settable (true) or read-only (default false). True for cmd, GPIO and dummy device values.","true", "YES",":yellow:`required true` for settable values", "YES",":yellow:`required true` for settable values"
"``$retained``","Specifies whether the property is retained (true) or non-retained (false).","false", "NO",":green:`required`", "NO",":blue:`optional`"
"``$unit``","A string containing the unit of this property.","°C", "NO",":blue:`optional`", "NO",":blue:`optional`"
"``$format``","Describes what are valid values for this property.","-30:40", "NO",":blue:`optional`", "NO",":blue:`optional`"
`The Things Network (TTN) <https://www.thethingsnetwork.org/>`_ is a global open LoRaWAN network.
LoRaWAN allows low power communication over distances of several km.
A typical use case is a sensor "in the field" which only has to send a few sample values every few minutes.
Such a sensor node does broadcast its message and hopefully one or more gateways may hear the message and route it over the connected network to a server.
The data packets for this kind of cummunication have to be very short (max. 50 bytes) and a sender is only allowed to send for a limited amount of time.
On most frequencies used for the LoRa networks there is a limit of 1% of the time allowed to send.
Such a time limit does also apply for a gateway. This implies that most traffic will be "uplink" data from a node to a gateway.
The analogy here is that the gateway is often mounted as high as possible while the node is at ground level ("in the field")
There is "downlink" traffic possible, for example to notify some change of settings to a node, or simply to help the node to join the network.
In order to communicate with the gateways in the TTN network, you need a LoRa/LoRaWAN radio module.
The radio module does communicate via the LoRa protocol. On top of that you also need a layer for authentication, encryption and routing of data packets.
This layer is called LoRaWAN.
There are several modules available:
- RFM95 & SX127x. These are LoRa modules which needs to have the LoRaWAN stack implemented in software
- Microchip RN2384/RN2903. These are the modules supported in this controller. They have the full LoRaWAN stack present in the module.
Nodes, Gateways, Application
----------------------------
A typical flow of data on The Things Network (TTN) is to have multiple nodes collecting data for a specific use case.
Such a use case is called an "Application" on The Things Network.
For example, a farmer likes to keep track of the feeding machines for his cattle.
So let us call this application "farmer-john-cattle".
For this application, a number of nodes is needed to keep track of the feeding machines in the field.
These nodes are called "Devices" in TTH terms.
For example a device is needed to measure the amount of water in the water tank and one for the food supply.
Such a device must be defined on the TTN console page.
There are two means of authenticating a device to the network (this is called "Join" in TTN terms):
- OTAA - Over-The-Air Authentication
- ABP - activation by personalization
With OTAA, a device broadcasts a join request and one of the gateways in the neighborhood that received this request,
will return a reply with the appropriate application- and network- session keys to handle further communication.
This means the device can only continue if there is a gateway in range at the moment of joining.
It may happen that a gateway does receive the join request, but the device is unable to receive the reply.
When that's happening, the device will not be able to send data to the network since it cannot complete the join.
Another disadvantage of OTAA authenticating is the extra time needed to wait for the reply.
Especially on battery powered devices the extra energy needed may shorten the battery life significantly.
With OTAA, the device is given 3 keys to perform the join:
- Device EUI - An unique 64 bit key on the network.
- Application EUI - An unique 64 bit key generated for the application.
- App Key - A 128 bit key needed to exchange keys with the application.
The result of such an OTAA join is again a set of 3 keys:
- Device Address - An almost unique 32 bit address of your device.
- Network Session Key - 128 bit key to access the network.
- Application Session Key - 128 bit key to encrypt the data for your application.
The other method of authenticating a device is via ABP.
ABP is nothing other than storing the last 3 keys directly on the device itself and thus skipping the OTAA join request.
This means you don't need to receive data on the device and can start sending immediately, and even more important, let your device sleep immediately after sending.
A disadvantage is the deployment of the device. Every device does need to have an unique set of ABP keys generated and stored on the device.
Updating session keys may also be a bit hard to do, since it does need to ask for an update and must also be able to receive that update.
Hybrid OTAA/ABP
---------------
TODO TD-er.
Configure LoRaWAN node for TTN
------------------------------
A LoRaWAN device must join the network in order to be able to route the packets to the right user account.
Prerequisites:
- An user account on the TTN network.
- A TTN gateway in range to send data to (and receive data from)
- Microchip RN2384 or RN2903 LoRaWAN module connected to a node running ESPeasy. (UART connection)
On the TTN network:
- Create an application
- Add a device to the application, either using OTAA or ABP.
In order to create a new device using OTAA, one must either copy the hardware Device EUI key from the device to the TTN console page,
or generate one and enter it into the controller setup page in ESPeasy.
The Application EUI and App Key must be copied from the TTN console page to the ESPeasy controller configuration page.
Using these steps, a device address is generated.
Such an address looks like this: "26 01 20 47"
Also the Network Session Key and Application Session Key can be retrieved from this page and can even be used as if the device is using ABP to join the network.
But keep in mind, these 3 keys will be changed as soon as an OTAA join is performed.
Device configuration with solely an ABP setup are more persistent.
@@ -57,8 +61,17 @@ before WiFi connection is made or during lost connection.
-**Max Queue Depth** - Maximum length of the buffer queue to keep unsent messages.
-**Max Retries** - Maximum number of retries to send a message.
-**Full Queue Action** - How to handle when queue is full, ignore new or delete oldest message.
-**Client Timeout** - Timeout in msec for an network connection used by the controller.
-**Check Reply** - When set to false, a sent message is considered always successful.
-**Client Timeout** - Timeout in msec for an network connection used by the controller.
-**Sample Set Initiator** - Some controllers (e.g. C018 LoRa/TTN) can mark samples to belong to a set of samples. A new sample from set task index will increment this counter.
Especially useful for controllers which cannot send samples in a burst. This makes the receiving time stamp useless to detect what samples were taken around the same time.
The sample set counter value can help matching received samples to a single set.
..note::
Be careful when setting the timeout too high.
For almost all controllers, sending data is a blocking call, so it may halt execution of other code on the node.
With timouts longer than 2 seconds, the ESP may reboot as the software watchdog may step in.
Sample ThingSpeak configuration
@@ -89,3 +102,5 @@ MQTT related settings
-**Controller lwl topic** - Topic to which LWT (Last Will Testament) messages should be sent.
-**LWT Connect Message** - Connection established message.
-**LWT Disconnect Message** - Connection lost message (sent to broker during connect and published by broker when connection is lost)
ESPEasy has some centralized hardware configuration settings, shown in this page, and divided in sections.
---------------
Wifi Status LED
---------------
To display the Wifi acitivity, a pin can be configured to light up a LED when data is transfered via Wifi. Optionally, the LED signal can be 'inverted'.
As many ESP boards have an onboard LED connected to GPIO-2 and inverted, it is shown as a note how to configure that.
..image:: Hardware_Wifistatusled.png
---------
Reset pin
---------
To provide a possible escape from a malfunctioning ESP module, a factory-reset button/feature can be configured by setting up a GPIO-pin for this.
..warning::
**When connecting this pin to ground for ca. 10 seconds the unit will be completely reset, and all settings/configuration irretrievably deleted!**
This feature can be useful in a development/laboratory environment, for when the configuration gets corrupted in some way.
..image:: Hardware_Resetpin.png
-------------
I2C Interface
-------------
When using devices that use the I2C bus (Inter-integrated circuit, also known as IIC, and mostly compatible with SM Bus) (`Wikipedia: I2C <https://en.wikipedia.org/wiki/I%C2%B2C>`_) some pins have to be configured, and initialized during boot, for the SDA and SCL connections. This can be any unused pair of pins on the ESP board.
The pins can be configured here, and will have default values initially (ESP8266: SDA: GPIO-4 (D2), SCL: GPIO-5 (D3), ESP32: SDA: GPIO-22, SCL: GPIO-23). When I2C is not used, these can be set to `- None -`, so the pins are available for other purposes.
The default bus clock speed can also be set here. If only devices supporting 100 kHz are connected (Old/Slow devices), then the value can be set to 100 kHz, by default 400 kHz is configured, that is supported by newer devices, though there are many devices supporting higher frequencies. ESP8266 is able to achieve ca. 400 kHz, while ESP32 allows much higher speeds.
Since build 20110, ESPEasy has a separate setting for Slow I2C devices, and per I2C device this slow clock speed can be selected in the Device edit page. This value is by default set to 100 kHz, but can be set lower or higher if desired.
..image:: Hardware_I2CInterface.png
*Device specific Force Slow I2C speed selection:*
..image:: Device_I2COptionsShort.png
---------------
I2C Multiplexer
---------------
Since build 20110, there is the option of using an I2C multiplexer. This option is not available in all builds, because of the size of the code. It is usually available in the normal, testing and custom builds, but ommitted from minimal, IR and hardware-specific builds.
Possible use-cases for an I2C multiplexer are:
* Connect multiple devices that have fixed or limited I2C addresses (For example, some OLED devices have a single fixed address but you need to connect 2 or more, or connect more than 3 TLS2561 devices, that support only 3 different addresses).
* Connect different devices that have the same I2C address (For example connecting a TSL2561 light/lux sensor and an APDS9960 proximity sensor).
* Connect slow and fast devices, where the speed of the fast device prohibits proper working of the slow device.
..|br|raw:: html
<br>
..note::
If devices with conflicting I2C addresses are to be used, then *none* of them can be connected to the ESP main I2C bus, but they should each be connected to a separate channel of the multiplexer. |br|
Devices that do not conflict with other devices *can* be connected to the ESP main I2C bus, this might improve the performance/responsiveness of these devices.
..note::
When using an I2C Multiplexer, make sure there is no address conflict with any of the devices you intend to connect, f.e. when connecting BME280 sensors, don't set the address of the multiplexer to 0x76 or 0x77.
There are a couple of I2C multiplexer chips available, currently there is support for:
* TCA9546a (4 channels, multiple channel-connections, 8 I2C addresses, with reset, also TCA9545a can be used, but no support for the Interrupt function though)
The TCA9548a, TCA9546a and TCA9543a support connecting multiple channels to the main I2C channel. This can be configured on the Device edit page for I2C devices, once the I2C Multiplexer configuration is enabled by selecting a multiplexer type and an I2C address for the multiplexer.
Also, the TCA9548a, TCA9546a and TCA9543a chips have a connection for a reset signal available. This allows the chip to be reset if it gets stuck by some 'less compatible' or 'badly behaving' devices. Once connected and configured, the multiplexer can be reset from the software, if desired or required. This feature is not yet used in any I2C device plugin.
A TCA9543a board has the advantage of being quite a bit smaller than either TCA9546a or TCA9548a, while being digitally compatible. (But with less channels and only 4 I2C addresses).
All these chips/boards can be found at Adafruit, Aliexpress, Banggood, EBay, etc.
..image:: Hardware_I2CMultiplexerNone.png
*Available multiplexer types:*
..image:: Hardware_I2CMultiplexer_Type.png
*Select the I2C Address for the multiplexer:*
..image:: Hardware_I2CMultiplexer_Address.png
Device configuration
^^^^^^^^^^^^^^^^^^^^
If an I2C multiplexer is configured, every Device edit page for I2C devices will show extra options to select the channel the device is connected on.
There is the default option of Single channel, or, when a TCA9548a, TCA9546a or TCA9543a is configured, Multiple channels.
*Example: A multiplexer is configured, but the device is connected directly on the ESP board I2C channel:*
..image:: Device_I2COptionsMultiplexerNone.png
*Configure a (single) multiplexer channel the device is connected on:*
Above configuration results in channels 0, 4, 5, 6 and 7 being connected to the ESP board I2C bus when this sensor is active via I2C.
NB: Only acceptable channel checkboxes (0-7/0-3/0-1) will be shown, depending on the Multiplexer type configured.
-------------
SPI Interface
-------------
When using devices that are connected via the SPI interface (`Wikipedia: SPI <https://en.wikipedia.org/wiki/Serial_Peripheral_Interface>`_), the interface must be initialized during boot. This can be enabled here. For ESP32 there is the option to select either the Hardware SPI (HSPI) interface or the Virtual SPI (VSPI) interface (software controlled).
The common SPI pins are shown here.
Other SPI pins to be used are device specific, and need to be configured from the corresponding Device edit page.
*For ESP8266:*
..image:: Hardware_SPIInterfaceESP8266.png
*For ESP32, disabled:*
..image:: Hardware_SPIInterfaceESP32.png
*For ESP32, select the desired interface:*
..image:: Hardware_SPIInterfaceESP32_Select.png
NB: When using the VSPI interface and also the I2C interface is used, another pin has to be selected for I2C GPIO -> SCL, as its configuration is fixed for the VSPI setting.
--------
Ethernet
--------
On builds including ``_eth`` in their build name, it is also possible to use ethernet instead of WiFi.
Currently this is only present for ESP32 builds and no plans currently exist to support it for ESP82xx.
N.B. This is still in testing phase, so not all kinds of network communications work right now.
Preferred network medium
^^^^^^^^^^^^^^^^^^^^^^^^
Allows to switch between:
* WiFi (default)
* Ethernet
To activate a new configuration, a reboot is needed.
Ethernet PHY type
^^^^^^^^^^^^^^^^^
Select the used PHY controller type:
* LAN8710 (LAN8720 is also supported, but none of the newer features are supported)
* TLK110
Ethernet PHY Address
^^^^^^^^^^^^^^^^^^^^
The PHY address depends on the hardware and the PHY configuration.
* Espressif's Ethernet board with TLK110 PHY use PHY address 31.
* Common Waveshare LAN8720 PHY breakout use PHY address 1.
* Olimex ESP32 EVB REV B IoT LAN8710 PHY Board with CAN use PHY address 0.
* Other LAN8720 breakouts often use PHY address 0.
If the PHY address is incorrect then the EMAC will initialise but all attempts to read/write configuration registers on the PHY will fail.
GPIO pins
^^^^^^^^^
RMII PHY SMI Wiring
"""""""""""""""""""
Most PHY boards have documented their *RMII PHY SMI Wiring* pins:
***MDC** Output to PHY, usually pin 23
***MDIO** Bidirectional, usually pin 18
Clock sync
""""""""""
The PHY and the ESP need to keep a clock in sync.
This can either be done via an external crystal, which is connected to a GPIO pin.
Another option is to let the ESP provide the clock to the PHY.
* External crystal oscillator
* 50MHz APLL Output on GPIO0
* 50MHz APLL Output on GPIO16
* 50MHz APLL Inverted Output on GPIO17
Power pin
"""""""""
On almost all PHY boards, or ESP boards equiped with an ethernet PHY, it is possible to turn the PHY on or off.
Either to save energy, or to make sure the external clock is not affecting the ESP boot mode when it restarts.
For example the Olimex ESP32-EVB does have the *external crystal oscillator* connected to GPIO-0, which could boot the ESP32 randomly into UART flash mode.
Most boards use a specific GPIO pin to control the power to the PHY.
The Olimex ESP32-EVB does have a specific delay circuit to only allow power to the PHY after boot and therefore does not need to control the PHY power.
For other boards, the default is often GPIO-17, but this may change per board.
RMII PHY Wiring
"""""""""""""""
Apart from these GPIO pins, there is a number of other pins reserved on the ESP32 for RMII PHY Wiring.
Since these GPIO pin assignments cannot be changed, it is also not needed to configure them.
However, they also cannot be used when *RMII PHY* is used.
..include:: ../Reference/Ethernet_PHY_ESP32.rst
-------------------
GPIO boot states
-------------------
For some GPIO pins, the boot state (initial configuration after startup) can be configured.
Some differences exist between ESP8266 and ESP32:
* ESP8266 can't initialize GPIO's 6, 7 and 8 (technical limitation of ESP8266 chip) and 16 (always has pull-down setting)
* ESP32 can't initialize GPIO's from 16 and up (settings storage limitation, could be initialized from Rules in `System#Boot` event)
The files and directories in the ESPEasy file repository are organized in folders.
Some of the choices for folder structure may not look very logical at first sight and may need some explanation to understand.
ESPEasy Project Directories
===========================
Below a list of the most important directories and files used in this project.
*``.pio/`` Working dir for PlatformIO (Ignored by Git)
*``build_output/`` The output directory where all built files are collected.
*``dist/`` Files also includd in the nightly builds (e.g. blank flash files and ESPEasy flasher)
*``docs/`` Documentation tree using Sphinx to build the documents.
*``hooks/`` Used for the continous integration process, used by Travis CI.
*``include/`` PlatformIO's suggested folder for .h files (not yet used)
*``lib/`` Libraries used in this project. Some have patches which make them different from the maintainers version.
*``misc/`` Additional files needed for some use cases, like specialized a firmware for some boards or decoder files for the TTN project.
*``patches/`` Patches we apply during build for core libraries.
*``src/`` The source code of ESPeasy
*``static/`` Static files we use in ESPEasy, like CSS/JS/ICO files.
*``test/`` Test scripts to be used in the continous integration process.
*``tools/`` Tools to help build ESPeasy.
*``tools/pio/pre_custom_esp32.py`` Python helper script for building custom ESP32 binary
*``tools/pio/pre_extra_script.py`` Python helper script for building custom ESP8266 binary
*``venv/`` Directory to store the used Python Virtual Environment. (Ignored by Git)
*``platformio.ini`` Configuration file for PlatformIO to define various build setups.
*``uncrustify.cfg`` Configuration file for Uncrustify, to format source code using some uniform formatting rules.
*``requirements.txt`` List of used Python libraries and their version (result of ``pip freeze`` with Virtual env active)
*``esp32_partition_app1810k_spiffs316k.csv`` Used partition layout in ESP32 builds.
ESPEasy src dir
===============
In order to compile the project using PlatformIO, you need to make sure the ``platformio.ini`` file is in the
root of the project dir opened in the editor.
The ``src/`` directory has the source files of the project.
In this directory, there is another ``src/`` dir, which is needed by ArduinoIDE in order to find files in sub-directories.
Arduino IDE also demands include directives to be relative compared to the file they are used in.
For example: ``#include "../DataStructs/Settings.h"``
We are currently working on converting the core ESPeasy code from .ino files into .h/.cpp files. (see PR #2617 and issue #2621)
The header and source files are organized in a few directories in ``src/src/``.
*``Commands`` Functions to process commands.
*``ControllerQueue`` Mainly macro definitions for the queue system used by controllers.
*``DataStructs`` Data structures used in ESPEasy. Note that some of them are stored in settings files, so take care when changing them.
*``Globals`` Declaration of global variables. Declare them using ``extern`` in .h files and construct them in .cpp files or else you may end up with several instances of the same object with the same name.
*``Static`` C++ encoded version of objects which have to be included in the binary. N.B. JS and CSS files are minified.
The Arduino based .ino files are still in the ``src/`` directory. (and some .h files, which are not yet moved)
In the end, there should be only .ino files left for the plugins and controllers and ``ESPEasy.ino``
All other .ino files used in the ESPEasy core should be converted to .h/.cpp.
This conversion is needed to have full control over ``#define`` statements used to determine what is included in a binary and what not.
This also allows for more flexible control over user defined builds.
ESPEasy 'nightly builds'
========================
On a regular basis we make so called "nightly builds".
These can be found here: `ESPEasy releases download <https://github.com/letscontrolit/ESPEasy/releases>`_ .
See the included ``README.txt`` in the downloaded ZIP file for more detailed information of the content of that build.
We have 2 main build platforms:
* ESP8266/ESP8285
* ESP32
For these platforms we also have a lot of different build setups.
* normal_IR => "Normal" + IR receiver/transmitter plugins and library
* hard_xxxxx => Special builds for some off-the-shelf hardware.
* minimal_ESP82xx_1M_OTA => Minimum number of plugins and a limited set of controllers included to be able to perform a 2-step OTA on 1 MB flash nodes.
* normal_core_xxx => "Normal" using core xxx (e.g. 2.6.3)
* normal_beta => "Normal" using the staged (beta) branch of the esp8266/Arduino repository.
ESP Chip Type
-------------
*``ESP8266`` Most likely option.
*``ESP8285`` Used in some Sonoff modules. This chip has embedded flash, so no extra flash chip.
*``ESP32`` Experimental support at this moment.
Memory Size and Partitioning
----------------------------
*``1M`` 1 MB flash modules (e.g. almost all Sonoff modules)
*``2M`` 2 MB flash modules (e.g. Shelly1/WROOM02)
*``4M`` 4 MB flash modules (e.g. NodeMCU/ESP32)
*``16M`` 16 MB flash modules (e.g. Wemos D1 mini pro)
Please note that the performance of 14MB SPIFFS (16M flash modules) is really slow.
All file access takes a lot longer and since the settings are also read from flash, the entire node will perform slower.
See `Arduino issue - SPIFFS file access slow on 16/14M flash config <https://github.com/esp8266/Arduino/issues/5932>`_
If these speed issues will be fixed, it is very likely the SPIFFS must then be re-partitioned, thus loosing all data in the SPIFFS.
Special memory partitioning:
*``2M256`` 2 MB flash modules (e.g. Shelly1/WROOM02) with 256k SPIFFS (only core 2.5.0 or newer)
*``4M316k`` For ESP32 with 4MB flash, sketch size is set to 1.8 MByte (default: 1.4 MByte)
@@ -22,7 +22,7 @@ RTTTL (Ring Tone [Text] Transfer Language) was developed by Nokia to play more "
After that the actual tune is then created using standard notes (a, b, c, d, e, f, and g), before the note the duration is set, after the note the octave is set:
..code-block::html
..code-block::none
<duration><note><octave>
@@ -35,7 +35,7 @@ Specifications:
Wiring
------
..code-block::html
..code-block::none
ESP Buzzer
GPIO <--> I/O
@@ -55,7 +55,7 @@ Rules examples
From ESP Easy v2.0.0 its possible to play melodies via `RTTTL <https://en.wikipedia.org/wiki/Ring_Tone_Transfer_Language#Technical_specification>`_ (don't forget to remove the spaces and replace # with -, this might be fixed in future releases):
..code-block::html
..code-block::none
http://<ESP IP address>/control?cmd=rtttl,14:d=4,o=5,b=112:8a,8a,a,8a,8a,a,8a,8c6,8f.,16g,2a,8a-,8a-,8a-.,16a-,8a-,8a,8a.,16a,8a,8g,8g,8a,g,c6
@@ -65,7 +65,7 @@ You can also use these from rules. We use it to let our alarm system give feedba
To make a boot-sound on startup, create a rule like this:
..code-block::html
..code-block::none
On System#Boot do
rtttl,14:d=10,o=6,b=180,c,e,g
@@ -75,7 +75,7 @@ To make a boot-sound on startup, create a rule like this:
Besides RTTTL it's also possible to play a single tone on a pin, via a buzzer, speaker or piezo element:
..code-block::html
..code-block::none
http://<ESP IP address>/control?cmd=tone,14,1300,200
@@ -22,7 +22,7 @@ RTTTL (Ring Tone [Text] Transfer Language) was developed by Nokia to play more "
After that the actual tune is then created using standard notes (a, b, c, d, e, f, and g), before the note the duration is set, after the note the octave is set:
..code-block::html
..code-block::none
<duration><note><octave>
@@ -35,7 +35,7 @@ Specifications:
Wiring
------
..code-block::html
..code-block::none
ESP Piezo
GPIO <--> Positive (red)
@@ -52,7 +52,7 @@ Rules examples
From ESP Easy v2.0.0 its possible to play melodies via `RTTTL <https://en.wikipedia.org/wiki/Ring_Tone_Transfer_Language#Technical_specification>`_ (don't forget to remove the spaces and replace # with -, this might be fixed in future releases):
..code-block::html
..code-block::none
http://<ESP IP address>/control?cmd=rtttl,14:d=4,o=5,b=112:8a,8a,a,8a,8a,a,8a,8c6,8f.,16g,2a,8a-,8a-,8a-.,16a-,8a-,8a,8a.,16a,8a,8g,8g,8a,g,c6
@@ -62,7 +62,7 @@ You can also use these from rules. We use it to let our alarm system give feedba
To make a boot-sound on startup, create a rule like this:
..code-block::html
..code-block::none
On System#Boot do
rtttl,14:d=10,o=6,b=180,c,e,g
@@ -72,7 +72,7 @@ To make a boot-sound on startup, create a rule like this:
Besides RTTTL it's also possible to play a single tone on a pin, via a buzzer, speaker or piezo element:
..code-block::html
..code-block::none
http://<ESP IP address>/control?cmd=tone,14,1300,200
@@ -22,7 +22,7 @@ RTTTL (Ring Tone [Text] Transfer Language) was developed by Nokia to play more "
After that the actual tune is then created using standard notes (a, b, c, d, e, f, and g), before the note the duration is set, after the note the octave is set:
..code-block::html
..code-block::none
<duration><note><octave>
@@ -35,7 +35,7 @@ Specifications:
Wiring
------
..code-block::html
..code-block::none
ESP Speaker
GPIO <--> Positive (red)
@@ -52,7 +52,7 @@ Rules examples
From ESP Easy v2.0.0 its possible to play melodies via `RTTTL <https://en.wikipedia.org/wiki/Ring_Tone_Transfer_Language#Technical_specification>`_ (don't forget to remove the spaces and replace # with -, this might be fixed in future releases):
..code-block::html
..code-block::none
http://<ESP IP address>/control?cmd=rtttl,14:d=4,o=5,b=112:8a,8a,a,8a,8a,a,8a,8c6,8f.,16g,2a,8a-,8a-,8a-.,16a-,8a-,8a,8a.,16a,8a,8g,8g,8a,g,c6
@@ -62,7 +62,7 @@ You can also use these from rules. We use it to let our alarm system give feedba
To make a boot-sound on startup, create a rule like this:
..code-block::html
..code-block::none
On System#Boot do
rtttl,14:d=10,o=6,b=180,c,e,g
@@ -72,7 +72,7 @@ To make a boot-sound on startup, create a rule like this:
Besides RTTTL it's also possible to play a single tone on a pin, via a buzzer, speaker or piezo element:
..code-block::html
..code-block::none
http://<ESP IP address>/control?cmd=tone,14,1300,200
Create an event, it's possible to send a float value along as well.
See event syntax below..."
Event command
~~~~~~~~~~~~~
The event command is a special command used to trigger an event. This event can then be acted upon from the rules.
You can send 0..4 event values along with the event.
.. csv-table::
:header: "Event / Info"
:widths: 1
"
``Event,SingleEvent``
The event (triggered by any of the launch ways) will make the unit publish a message.
**Rules example**
.. code-block:: html
on SingleEvent do
Publish,%sysname%/Info,A single event has been triggered!
endon
"
"
``Event,SingleValue=123``
The event value ``123`` is intercepted and published.
**Rules example**
.. code-block:: html
on SingleValue do
Publish,%sysname%/Info,An event has been sent (%eventvalue%)!
endon
"
"
``Event,Multi=1,2,3,99``
The event value ``99`` (4) is intercepted and the rule ``TaskValueSet...`` is
triggered, value of task 12 value 1 is then ``1 + 2`` = ``3`` or ``1 - 2`` = ``-1``.
**Rules example**
.. code-block:: html
on Multi do
if %eventvalue4%=99
TaskValueSet,12,1,[%eventvalue1%+%eventvalue2%]
else
TaskValueSet,12,1,[%eventvalue3%-%eventvalue2%]
endif
endon
"
**TODO** : Check commands M..Z and check for all commands whether the "class" is still valid.
.. csv-table::
:header: "Command", "Class", "Purpose / Syntax"
:widths: 8, 5, 30
"
AsyncEvent","
:blue:`Special`","
Schedule an event, it's possible to send a float value along as well.
This is the same as a regular event, but it will not be executed immediately.
Instead it will be added to an event queue.
Use this to keep rules execution times as short as possible.
N.B. New values sent by a task will also be of this type.
See event syntax below..."
"
AccessInfo","
:red:`Internal`","
Show allowed IP range for the web interface.
``AccessInfo``
Example output: ``Allowed IP range : 192.168.10.0 - 192.168.10.255``"
"
Background","
:red:`Internal`","
Process background tasks.
``Background``"
"
Build","
:red:`Internal`","
Get or set build information. This will not be stored, so only valid until reboot.
``Build``
``Build,12345``
Example output: ``Build:20104``"
"
ClearAccessBlock","
:red:`Internal`","
Clear allowed IP range for the web interface for the current session.
See also ``AccessInfo``.
``ClearAccessBlock``"
"
ClearRTCram","
:red:`Internal`","
Clear all (cached) data from the RTC memory.
This data is persistent as long as the node is powered and thus survives a reboot or crash.
``ClearRTCram``"
"
Config","
:red:`Internal`","
Remote config of a task. TODO: Describe command syntax.
``Config``"
"
ControllerDisable","
:red:`Internal`","
Disable a controller.
This will not save the settings, but if the settings get saved anyway the controller will remain disabled at reboot.
``ControllerDisable,<controller nr>``"
"
ControllerEnable","
:red:`Internal`","
Enable a controller. (Only possible when a protocol is assigned to the controller index)
This will not save the settings, but if the settings get saved anyway the controller will remain enabled at reboot.
``ControllerEnable,<controller nr>``"
"
DateTime","
:red:`Internal`","
Get or set the date and time (optional).
Usage: ``Datetime[,YYYY-MM-DD[,hh:mm:ss]]``
Examples:
* ``Datetime,2020-02-29,00:23:00``
* ``Datetime,2020-02-29`` - set node time '2020-02-29 00:00:00'
* ``Datetime`` - get current node time
Time source will be set to ``Manual_set`` until the time will be updated via another source. (e.g. GPS or NTP)"
"
Debug","
:red:`Internal`","
Change Serial port debug level
``Debug,<1-4>``"
"
DeepSleep","
:red:`Internal`","
Switch the node to deep sleep.
Max sleep time depends on library version and differs from roughly 71 minutes to 3h46.
If you specify a Min sleep time of 0, you'll have to wake the device yourself by pulling RST to GND.
``DeepSleep,<sleep time in seconds>``"
"
Delay","
:green:`Rules`","
Delay rule processing. Warning: Do not use this as it may cause all kinds of issues.
``Delay,<delay in milliSeconds>``"
"
DNS","
:red:`Internal`","
Get or set DNS configuration.
``DNS``
``DNS,8.8.8.8``
Example output: ``DNS:192.168.88.1(DHCP)``"
"
DST","
:red:`Internal`","
Get or set Daylight Saving Time.
``DST``
``DST,0`` to disable, ``DST,1`` to enable
Example output: ``DST:true``"
"
EraseSDKwifi","
:red:`Internal`","
Erase WiFi settings that may have been stored in the SDK wifi settings area.
``EraseSDKwifi``"
"
Event","
:blue:`Special`","
Create an event, it's possible to send a float value along as well.
See event syntax below..."
"
ExecuteRules","
:red:`Internal`","
Execute the rules in a specific file on the file system.
``ExecuteRules,<filename>``"
"
Gateway","
:red:`Internal`","
Get or set the gateway configuration
``Gateway``
``Gateway,192.168.1.1``
Example output: ``Gateway:192.168.10.254(DHCP)``"
"
I2Cscanner","
:red:`Internal`","
Run I2C scanner to find connected I2C chips. Output will be sent to the serial port.
``I2Cscanner``
Example output:
.. code-block:: none
4500043 : Info : Command: i2cscanner
I2C : Found 0x3c
I2C : Found 0x40
I2C : Found 0x5a
"
"
IP","
:red:`Internal`","
Get or set IP address
``IP``
``IP,<IP address>``
Example output: ``IP:192.168.10.86(DHCP)``"
"
Let","
:red:`Internal`","
Set the value of n (1..16).
``Let,<n>,<value>``"
"
Load","
:red:`Internal`","
Load (reload) the stored settings.
``Load``"
"
LogEntry","
:red:`Internal`","
Add string to log
``LogEntry,<string>``"
"
LogPortStatus","
:red:`Internal`","
Display status information about all ports
``LogPortStatus``"
"
LoopTimerSet
LoopTimerSet_ms","
:green:`Rules`","
Start a sequence of timed events
* ``LoopTimerSet,<timernr>,<timeInSeconds>``
* ``LoopTimerSet_ms,<timernr>,<time in msec>``
* ``LoopTimerSet,<timernr>,<timeInSeconds>,<nr of loops>``
* ``LoopTimerSet_ms,<timernr>,<time in msec>,<nr of loops>``
* ``LoopTimerSet,<timernr>,0`` (disables the timer)
The 3rd value is optional and can be used to set a fixed number of loops.
When possible, try using the ``LoopTimerSet`` funxtion (or its msec equivalent) to get a consistent schedule interval.
A loop timer is basing its next scheduled time on the previous scheduled time and not the moment when it is actually executed.
On a typical setup, calling ``TimerSet`` from the rules every time a timer has expired, may cause a delay of at least 20 msec.
The actual jitter introduced here depends on the load of the node and the length of the rules.
Please note, the execution time in the rules may differ, but as long as a loop timer is used, the scheduled time to run is always a fixed interval from when it was set. (even when a timer interval was missed)
The ``Rules#Timer`` event generated by a timer has 2 event values. (since build 2020/08/12):
* ``%eventvalue1%`` has the timer number (1 ... max timer ID)
* ``%eventvalue2%`` has the loop count for loop timers (since build 2020/08/12)
See also ``TimerSet``.
N.B. the timernr is shared between ``TimerSet`` and ``LoopTimerSet``"
"
meminfo","
:red:`Internal`","
Will send summary of struct sizes to the serial port.
``meminfo``
Example output:
.. code-block:: none
4306250 : Info : Command: meminfo
SecurityStruct | 593
SettingsStruct | 1228
ExtraTaskSettingsStruct| 472
DeviceStruct | 12
"
"
meminfoDetail","
:red:`Internal`","
Will enable extra detailed information on the internal structure of the settings file.
This is displayed graphically in the system info page.
This state is not stored, so only active until reboot.
A detailed summary is also sent to the serial port.
``meminfoDetail``"
"
Name","
:red:`Internal`","
Set the name of the unit
``Name,<new name>``"
"
Password","
:red:`Internal`","
Set the password of the unit
``Password,<new password>``"
"
Publish","
:green:`Rules`","
Send command using MQTT broker service
``Publish,<topic>,<value>``"
"
Reboot","
:red:`Internal`","
Reboot the ESP
``Reboot``"
"
Reset","
:red:`Internal`","
Reset config to factory default. Caution, all settings will be lost!
As described already, each task can produced one or more events, one for each measured value. You should not name your devices and value names so that the combination equals to any of the below listed system events!
","
.. code-block:: html
.. code-block:: none
on DHT11Outside#Temperature>20 do
GPIO,2,1
@@ -19,7 +19,7 @@
Triggered after power on.
","
.. code-block:: html
.. code-block:: none
on System#Wake do
GPIO,15,1
@@ -31,7 +31,7 @@
Triggered at boot time.
","
.. code-block:: html
.. code-block:: none
on System#Boot do
GPIO,2,1
@@ -44,7 +44,7 @@
Triggered just before the ESP goes to deep sleep.
","
.. code-block:: html
.. code-block:: none
on System#Sleep do
GPIO,2,0
@@ -56,7 +56,7 @@
Triggered when the ESP has connected to broker.
","
.. code-block:: html
.. code-block:: none
on MQTT#Connected do
Publish,%sysname%/status,First message!
@@ -68,7 +68,7 @@
Triggered when the ESP has disconnected from the broker.
","
.. code-block:: html
.. code-block:: none
on MQTT#Disconnected do
Reboot
@@ -80,7 +80,7 @@
Triggered when the ESP has connected to broker (the MQTT Import plugin uses a separate connection than the generic one).
","
.. code-block:: html
.. code-block:: none
on MQTTimport#Connected do
Publish,%sysname%/status,MQTT Import is now operational
@@ -92,7 +92,7 @@
Triggered when the ESP has disconnected from the broker (the MQTT Import plugin uses a separate connection than the generic one).
Triggered when the ESP has changed to access point, will also trigger first time the unit connects to the Wi-Fi.
","
.. code-block:: html
.. code-block:: none
on WiFi#ChangedAccesspoint do
Publish,%sysname%/status,AP changed
endon
"
"
``WiFi#ChangedWiFichannel``
Triggered when the ESP is connected to the AP on a different channel, will also trigger first time the unit connects to the Wi-Fi.
This has been added in build mega-20190910
","
.. code-block:: none
on WiFi#ChangedWiFichannel do
Publish,%sysname%/status,channel changed
endon
"
"
``WiFi#APmodeEnabled``
@@ -130,7 +143,7 @@
N.B. Sending a publish command may not be very useful on this event, since this will mainly happen when there is no WiFi connection.
","
.. code-block:: html
.. code-block:: none
on WiFi#APmodeEnabled do
... // Some command
@@ -143,7 +156,7 @@
This can happen some time (default 60 seconds) after a WiFi connection has been made. Or disabled using some command.
","
.. code-block:: html
.. code-block:: none
on WiFi#APmodeDisabled do
Publish,%sysname%/status,AP disabled
@@ -155,7 +168,7 @@
Triggered when (someone) has tried to login to a ESP unit with admin password enabled, but have failed to enter correct password.
","
.. code-block:: html
.. code-block:: none
on Login#Failed do
Publish,%sysname%/warning,Intruder alert!
@@ -167,7 +180,7 @@
Triggered the first time (after boot) NTP is updating the unit.
","
.. code-block:: html
.. code-block:: none
on Time#Initialized do
Publish,%sysname%/Time,%systime%
@@ -179,7 +192,7 @@
Triggered when the time is set by an update from NTP.
","
.. code-block:: html
.. code-block:: none
on Time#Set do
Publish,%sysname%/Time,%systime%
@@ -192,7 +205,7 @@
As described already, triggered when a rules timer ends (setting a timer to 0 will disable the timer).
","
.. code-block:: html
.. code-block:: none
on Rules#Timer=1 do
GPIO,2,1
@@ -204,7 +217,7 @@
Triggered every minute with day and time like: Mon,12:30 or Tue,14:45. You can define triggers on specific days or all days using 'All' for days indicator. You can also use wildcards in the time setting like All,**:00 to run every hour.
","
.. code-block:: html
.. code-block:: none
on Clock#Time=All,12:00 do //will run once a day at noon
GPIO,2,1
@@ -224,7 +237,7 @@
If the command 'Monitor' is used to monitor a given pin you will receive an event for that GPIO as soon as it's state changes. As seen in the example you can always use the square brackets together with the task/value name of ``Plugin#GPIO#Pinstate#N`` to get the state, but to trigger events you need to add the monitor command (preferably at boot).
This one can be set either to measure the Vdd pin (supplied voltage to the ESP) or to ``TOUT``, so it can measure the voltage on the ``A0`` pin.
The ESP32 has 18 pins that can be used as ADC. It also has a Hall Effect sensor included.
See the `ESP32 API reference <https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/adc.html>`_ for more detailed information on the features and limitations of these pins.
Hall Effect Sensor (ESP32)
--------------------------
The ESP32 has a Hall Effect Sensor included, to measure a magnetic field.
N.B. This value can also be negative, if the polarity of the magnetic field is swapped.
Note that even the hall sensor is internal to ESP32, reading from it uses channels 0 and 3 of ADC1 (GPIO 36 and 39).
Do not connect anything else to these pins and do not change their configuration. Otherwise it may affect the measurement of low value signal from the sensor.
WiFi activity and ADC
---------------------
The ADC on the ESP8266 is also used during WiFi RF calibration.
This can result in incorrect readings of the ADC while a WiFi connection attempt is in progress.
ESP32 has 2 ADCs present.
``ADC1`` and ``ADC2``
Since the ``ADC2`` is shared with the WIFI module, which has higher priority, reading operation of ``adc2_get_raw()`` may fail between ``esp_wifi_start()`` and ``esp_wifi_stop()``.
Oversampling
------------
When ``Oversampling`` is enabled, the plugin will take a reading 10 times a second.
This reading is averaged over the entire interval time as set in the task configuration.
The highest and lowest values are subtracted from the recorded values, to filter out single flukes.
Measured values which are clipped either on the lower range or higher range are only added once per interval as they may occur for more than a single sample per interval.
This is done to prevent a relative large offset in the averaging due to clipping or maybe unforceen interaction of the WiFi chip on the ADC measurements.
Calibration
-----------
The plugin supports a 2-point calibration.
The user can set these to convert the raw values into the desired unit of measure.
When set, the configuration screen also displays the minimum, maximum and step size values based on the calibration settings.
Supported hardware
------------------
@@ -42,8 +96,7 @@ Change log
..versionchanged:: 2.0
...
|added|
Major overhaul for 2.0 release.
|improved| 2020-04-25 Added support for ESP32 ADC pins + Hall Effect Sensor.
The Wiegand plugin reads the Wiegand protocol, either the 26 or 34 bit variant, transmitted over a 2-wire serial connection. The RFID reader or keypad has to be connected to two GPIO pins on the ESP module. The plugin uses an interrupt routine to decode the bitstream. A RFID reader will send a message containing the unique RFID Tag ID. A keypad will send the input after pressing the #, or another configured, confirmation key.
Data is transmitted in hexadecimal format.
For numeric keypads an option is provided to transform the hex value into a decimal representation, so that when entering value 1234# (# is the confirmation key here), not the result 4660 (0x1234) is made available, but actually 1234. This for easier processing/validating of the entered value. Any input of A-F is replaced by 0 when this option is enabled! It should not be enabled when using a RFID reader, as the Tag ID won't be correct.
The value is placed in the Tag variable (this name can be changed).
The Framed OLED plugin does allow a bit more fancy look and feel compared to P023 OLED.
The plugin allows to show several "pages" of information.
The number of pages depends on the number of set lines of text and the font size.
Switching between pages can be "instant" or "scrolling".
Please note that scrolling may need more resources of the ESP, which can have an effect on other active tasks of the node.
Setting up a Display Button, allows to configure a Display Timeout and wake the display on demand. Inversed Logic should be checked when using a button that connects the input to ground when pressed.
When enabling "Step through pages with Display button", the button can also be used to step through the pages, when having multiple pages, to display the content on demand. If this option is unchecked, then, when available, the next page will be displayed after Interval seconds have passed. Pressing the button restarts the Display Timeout timer. When holding the button pressed, the next page will be shown after a 1 second delay.
The Display Timeout setting sets the numbers of seconds after which the display is turned off. When set to 0 no timeout is active.
The plugin allows for a header and footer line, which may show some user selectable information.
Checkbox 'Wake display on receiving text' (default: on) allows to not wake up the display when a text is sent from a remote source, and Display Timeout is set.
All user defined texts may contain references to system variables or task values which will be interpreted when displayed on screen.
OLED displays will age quite fast, so it is not adviced to run them continously at max brightness.
Some displays do not accept all brightness levels and some also make a quite high pitch coil whine noise when running on some brightness levels.
So different levels of brightness can also be of help on those displays.
The display controller itself does support more brightness levels, but these are chosen to give noticable change in brightness levels and also to help in choosing the best values for the 2 brightness control registers.
As there are 2 brightness control registers, there is some overlap in their range, but some combinations may lead to issues like coil whining noise or sometimes not even working displays as not all of these displays are wired to support both controls to be used.
"
"
``oledframedcmd,<line>,<text>``
","
The <line> parameter corresponds with the same lines as the plugin configuration has.
The <text> parameter must be a single command parameter.
Meaning, it must be wrapped in quotes when using a space or comma as text.
If double quote characters are needed, wrap the parameter in single quotes or back quotes.
The updated line text is not stored in the settings itself, but kept in memory.
After a reboot the stored plugin settings will be used.
All template notations can be used, like system variables, or reference to a task value.
After receiving text this way, the frame where the text is placed is shown, if the setting for 'Wake display on receiving text' is checked.
"
"
``oledframedcmd,frame[,<framenr>]``
","
This command is to display a specific frame (aka page), or the next frame. When reaching the last frame, a 'next' (0) will display the first frame.
The <framenr> parameter corresponds to the desired frame (1..<number of frames>) to display. The number of frames is determined by dividing the lines in use (at least one line in that frame with some data), by the number of Lines per Frame. So practically, the range is 1..3 when all lines are used and 4 Lines per Frame is set, or 1..12 if Line per frames is set to 1. The number of frames is updated if a frame would initially be empty, and an external source places text on a line of that frame (see above).
When omitting <framenr>, or providing 0, the next frame is displayed.
When the display is off, because a 'Display Timeout' is set and the timer has expired or it is turned off by the off command (see above), then it is turned on, and, when set, the timer is started again.
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.