New library: esp8266_web_settings, simple settings/status Web server

It's inspired by existing libraries like WiFiManager, but provides a relatively simple (and, I hope, efficient) mechanism for a device page that allows both dynamic information (i.e. updates) and settings. It uses AsyncWebServer under the hood.

Github URL: GitHub - grmcdorman/esp8266_web_settings: General, non-specific classes for ESP8266 (possibly usable for other Arduino-class boards). - a simple example is included there in the README.md file.

Only built for ESP8266, since that's the only platform I have. There's no particular reason it shouldn't work on other devices, though.

Does not yet have a libraries.properties file; working on that now. One issue is that the Arduino library format does not seem to support the common standard of include files in subdirectories; specifically, this library is formatted with an 'include' directory, and all header files are in the 'grmcdorman' subdirectory. Thus, the include statement is #include <grmcdorman/WebServer.h>. (FYI, this is the equivalent of namespaces in C++).

Feel free to post bug reports if you find issues, or create branches/PRs to improve the code.

A screenshot of working code:

1 Like

You can put them under the src subdirectory:
https://arduino.github.io/arduino-cli/latest/library-specification/#source-code
You can use any directory structure you like under src. However, you do need to have at least one header file directly under src. Once you have an #include for a header in the root, you are able to specify paths to subfolders as you like.

Aren't namespaces the equivalent of namespaces in C++?

How about a PR to add GitHub Actions workflows that ensure the project is considered valid by the Arduino development software?

Examples:

Aren't namespaces the equivalent of namespaces in C++?

Not for include files. The issue with include files at the root is that there's nothing to qualify the name to help prevent ambiguity. You will find a lot of modern C++ add-on libraries use paths like this for the include files; look at the Boost C++ libraries for an example. In general, if a class is in namespace 'mynamespace', the header file should have that namespace as part of the path. The one exception is the standard libraries bundled with the compiler.

In particular, I would need either a header file like 'esp8266_web_settings_webserver.h' (or equivalent Camel Case) or some other long name to be sure that my header file doesn't conflict with anyone else's. I have seen far too many cases where the header file conflicts with some other similar library.

How about a PR to add GitHub Actions workflows that ensure the project is considered valid by the Arduino development software?

Wasn't aware of those, I will take a look. Thank you.

Tried to add those actions. Compile examples is failing; this project uses ESPAsyncWebServer, which as near as I can tell isn't available in the Library Manager. Am I wrong in this?

However, as a result of this:

  • There is now an example sketch, which does compile and run with Platform.IO. I don't know about the Arduino UI, given that it seems to be more restrictive.
  • There is a header file in the src directory named as per the requirements by the linter. It does not include all header files, this is contrary to my philosophy (although admittedly there are only two of them required in this library).

Great work!

You are not wrong:

However, that is not a serious problem for the CI system because, in addition to Library Manager and local path, the arduino/compile-sketches GitHub Actions action also supports sourcing libraries from Git repositories or archive downloads.

One question though: you link to this repository: https://github.com/me-no-dev/ESPAsyncWebServer, but I see that your PlatformIO metadata indicates a fork:
https://github.com/esphome/ESPAsyncWebServer
Which of the two do you want the CI workflow to install before compiling the example sketch?

I'm very glad to see that. I think the Arduino users will find it very helpful.

And of course compiling it via the CI system provides a useful "smoke test" on every push and PR, not only of the sketch itself, but also of the library.

This is one of the reasons I suggested the idea of the sketch compilation workflow. I'm guessing that you use PlatformIO primarily, which means it will be easy for you to introduce changes that are accepted by PlatformIO, but give Arduino users a bad day.

The arduino/compile-sketches action uses Arduino CLI under the hood, which is also used by classic Arduino IDE, Arduino IDE 2.x, and Arduino Web Editor. So if the action can compile the sketch there is a fairly good assurance that all the Arduino development software can work with it. So the automation can make the Arduino support less of a burden on you.

Excellent :wink:

What, I can't have both? :stuck_out_tongue: Oops. Probably the main repo; PlatformIO library manager showed two with no apparent distinction in the description, and I didn't really dig farther at the time.

Yes, examples are almost essential. There's an example in the READMEmd, but that's not as easy to use (and not guaranteed to work, either).

PR pre-commit actions are essential. I may even add some unit tests, although writing unit tests is not near as much fun as writing core code...

Absolutely. I'm used to Visual Studio Code, although most of my colleagues are still stuck in Visual Studio itself; tried to use Arduino UI at first but found it awkward. None the less, the broader support the better.

As you may have noticed from the screen shot, what I actually have is an Ikea Vindriktning air quality sensor and an SHT11-D temperature/humidity sensor wired up to a ESP8266 D1 Mini. The current code I've got bears little resemblance to the original Vindriktning repo; I like modularity :slight_smile:

Once this library is stable, I plan to also create a Git repo for the sensor module code; the intent there is to basically have a compile-time pluggable system (using this settings stuff as the base) that allows straightforward (and mostly isolated) handling of sensors by basically just dropping in one of the sensor objects. Sort of like ESP Home, but purely in code at compile time.

(quotes mangled in the interest of keeping links out because I'm a poor newbie :stuck_out_tongue: )

Would you like to pin it to a specific ref (such as https://github.com/me-no-dev/ESPAsyncWebServer/commit/7949d83e917af001c8cb0a8b4eb74eda2e2beb29), or do you want to use the tip of the master branch each time?

I think the tip, that repo doesn't seem to do tags or releases. Pointing to a specific untagged ref doesn't seem the right way to do things, and certainly won't be what most users do.

Oh, and forgot to ask: Any advice on the library.properties file? Can't find anything that indicates depends can take a Git repo instead of a library manager name.

I agree. I think most Arduino users will use the "Code > Download ZIP" button to download the archive of the repository from the tip of the master branch and then the Arduino IDE's "Sketch > Include Library > Add .ZIP Library..." to install it. So compiling against the tip of the default branch will provide a good simulation of the average user's environment.

That is correct. You can see the specification here:
https://arduino.github.io/arduino-cli/latest/library-specification/#libraryproperties-file-format

This field only supports the name of libraries that are available from Library Manager. For other dependencies, the best bet is to clearly document the need for the user to install them manually.

1 Like

Thanks, in0. Were you the one that just submitted a PR on my branch?

Unfortunately, with that fixed the example can't find DNSServer.h. Can't find that in Library Manager, looks like it's in ESPCore. Perhaps the architectures in the compile need to be fixed?

Got the example compiling. Oddly, this include worked:

#include <esp8266_web_settings.h>

which just contains

#include "grmcdorman/WebSettings.h"

but using the latter include directly fails.

Otherwise everything is good. I'm going to tag this as my 1.0 release.

Thank you for your help.

The library discovery process only looks at the headers in the root of the library source folder. However, once the library has been discovered, it is added to the compiler include search path (-I), so you can then provide additional #include directives for headers in subfolders.

For example:

#include <esp8266_web_settings.h>
#include <grmcdorman/WebSettings.h>

So the tool is scanning source for #include statements?

Marginally odd, but if that's the way it works. It's "good enough for government work", as they say.

So on to my next bit...

Again, thanks for your prompt help. It really made setting up the Git repo easier.

No, that is not it. It is the compiler error output being parsed, not the source code.

The approach is explained here in the the Arduino CLI tool used under the hood by all the Arduino development software:

Interesting. Amounts to the same in a practical sense, though.

In theory, the scanner might be able to extract the path on the #include from the error message. Maybe somebody ambitious could look into that; not I, though. I've got something "good enough" working.

New release: version 1.1.0; improves web page performance and verifies multiple browser support.

Changes:

  • Tabs (settings sets) now have identifiers that are distinct from the name (the name being the label).
  • The URL /settings/get query parameters can now explicitly request multiple settings rather than just one
  • The main page includes styles and JavaScript inline; this improves performance (both memory and load) on the ESP8266.
  • The response to the /settings/get has a Cache-Control: No-Cache header to prevent browsers caching the reply.
  • Periodic update only updates the currently displayed tab instead of all of them.
  • Tested working in Chrome, Firefox, IE 9+, Edge. (Old versions of IE are not supported).

Perhaps, but it may not be so straightforward as it seems. For example:

#include <foo.h>
#if BAR
#include <baz.h>
#if __has_include(<qux.h>)
#include <qux.h>
#endif
#endif