Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Web Interface #7

Open
1 of 18 tasks
Mischback opened this issue Apr 11, 2022 · 1 comment
Open
1 of 18 tasks

Web Interface #7

Mischback opened this issue Apr 11, 2022 · 1 comment
Assignees
Labels
type/feature New feature or request
Milestone

Comments

@Mischback
Copy link
Owner

Mischback commented Apr 11, 2022

The application should provide a web interface.

Required Pages

  • System Status:

    • an abstract overview page, containing some (relevant) runtime information
    • [should] player status (e.g. currently played song or not playing, see below!)
    • [should] WiFi status (e.g. in WiFi Management #5 ("Publish WiFi status to other components")
    • [maybe] memory usage statistics, e.g. application image size, RAM usage
  • Player Status/Control:

    • show currently played song, including other meta information (artist, album, time, ...)
    • [maybe] album art
    • Control elements for Play/Pause, Previous Song, Next Song, Volume Control ([map32] Audio Player #21)
  • WiFi Configuration (see WiFi Management #5):

    • provide a form to configure the current WiFi-related settings (SSID, PSK)
    • [should] provide means to manually configure other networking-related settings (static IP, default route, DNS server, ...)
  • RFID Card Management

    • obviously, this page is only required if the project is built (hardware- and software-wise) with support for RFID-modules!
    • assign card ID to an action (e.g. play file, play folder, ...)
    • [should] provide overview of all assigned cards
  • Use (HTTP-compatible) compression techniques!

    • The actual use-case of compression in HTTP is to reduce network traffic, but in this case it also provides smaller file sizes for the resources (that needs embedding on the microcontroller)
    • gzip
    • brotli
    • raw or plain

Implementation

There are several ideas / possibilities to implement this.

One principle should be, to keep the components as loosely coupled as possible. This means: There should be one component to actually provide the HTTP(S)-related functionality (work has already started on min_httpd component).

Basic idea would be: Let other components implement their own parts of the webinterface and register them with min_httpd.

While that idea seems pretty much valid, it leads to several problems down the road, including lots of boilerplate code or repetition of certain fragments in different components.

Plain HTML with standalone html files

  • min_httpd provides the general HTTP(S) daemon, other components implement URI handlers as needed and register them with min_httpd
    • idea: let min_httpd emit a message (esp_event) when URI handlers can be registered. Let app_main() handle registration of the actual URI handlers located in the different components. This would be really loose coupling of components, as only app_main() knows and handles the interdependent parts
    • each component provides its own set of html files
      • fully seperated components vs. code base of the webinterface is split across multiple components
      • common coherent look'n'feel must be enforced elsewhere
      • some boilerplate code is provided in different html files and thus, stored multiple times in the microcontrollers memory/storage (might affect image size drastically!)

Plain HTML with dedicated external assets (e.g. style.css)

  • min_httpd provides the general HTTP(S) daemon, other components implement URI handlers as needed and register them with min_httpd
    • idea: let min_httpd emit a message (esp_event) when URI handlers can be registered. Let app_main() handle registration of the actual URI handlers located in the different components. This would be really loose coupling of components, as only app_main() knows and handles the interdependent parts
    • the functional parts of the web interface are fully seperated, while the coherent look'n'feel is provided by centrally provided static assets
    • boilerplate code is provided once, but it may contain unrequired parts for the interface of the actual component
    • requires centrally provided URI handlers for e.g. /style.css, including some effort to use (client-side) caching, ...

Single Page Application with WebSockets (static)

  • actually one request to the HTTP server to load the SPA, all other communication (transfer of data, commands, ...) can be done by web socket
  • tight coupling of the components, as every component is required to provide its part of the actual html (and/or specific javascript) at build time to build the actual SPA
  • Do modern browsers allow for unsecure web sockets? Otherwise, TLS is required!
  • internal logic of the SPA required
    • frontend (pretty easy): update the bits of the SPA, that are affected by a message
    • backend (hard): which message from the client to the server is to be handled by which component?

Single Page Application with WebSockets (dynamic)

  • parts of the SPA are loaded dynamically, including the related html source, sripts, ...
  • parts of the backedn-logic of the SPA needs to be dynamic ("which message from client to the server is to be handled by which component?")
    • really hard, especially for things that affect more than one component...
  • Do modern browsers allow for unsecure web sockets? Otherwise, TLS is required!
@Mischback Mischback added the type/feature New feature or request label Apr 11, 2022
@Mischback Mischback added this to the Release 1.0.0 milestone Apr 11, 2022
@Mischback Mischback self-assigned this Apr 11, 2022
This was referenced Apr 11, 2022
@Mischback
Copy link
Owner Author

Mischback commented Apr 11, 2022

Implementation Plan

Currently, the WiFi component is the main development effort. That component requires some sort of webinterface, to enable WiFi provisioning (configuration of WiFi credentials) for an actual WiFi network.

This should be kept as simple as possible, meaning:

Initial Implementation

  • implement the required html files stand-alone, as part of the networking component
  • establish workflow to generate optimized, static html source files to be included into the build
    • a.src.html (source file, well indented, including comments, ...) ---> a.html (without comments, without unrequired whitespace, linebreaks, ...)
    • include a.html as described here
    • provide the required implementation of a (or several) URI handler
  • provide min_httpd as a wrapper around ESP-IDF's esp_http_server component, basically just to control the emmitting of events (using esp_event component), in order to allow the networking component to attach the URI handlers to the actual server
  • use app_main() to acutally tie networking and min_httpd together
    • at this point, networking's CMakeList.txt does not specify min_httpd as a dependency; min_httpd does not specify networking as a dependency

Further down the Development Road

In further development, actually provide a webinterface component, which leverages the benefits of "Plain HTML with dedicated external assets (e.g. style.css)".

  • have a dedicated webinterface component, providing
    • required html files for the (other) components are generated
      • fetch a.src.html from (other) component
      • strip common html stuff, just have the bare content
      • insert content into base_template.html, store as a.tpl.html
      • run optimization steps as outlined above to create a.html in webinterface's build directory
      • the (other) component can now skip the generation process as outlined above and copy a.html from webinterface's build directory
    • style.css, probably generated from SCSS source, optmized (purgeCSS) and minified
      • purgeCSS can be run against the webinterface's build directory
    • While the other components still provide their integration into min_httpd (or some other webserver) with their own codebase, the actual asset (*.html) is generated from here. But the URI handlers are still provided by the components' codebases
    • the webinterface component just needs to provde a URI handler for style.css and may follow the same techniques as any other component (see above)

Having said this: This uses a pretty much standard HTTP server, wrapped in min_httpd. If components do require the use of web sockets, they are free to do so. See the initial issue statement for a list of required pages, from a first glance, only the player status and control and the system status pages would require the use of web sockets. Probably both could be combined and provided by the player component.

Further optimization should include the provision of gzip or brotli compressed assets. With the workflow as described above, this should be easily possible.

@Mischback Mischback mentioned this issue Jun 30, 2022
19 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type/feature New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant