neu-rah / ArduinoMenu

Arduino generic menu/interactivity system
GNU Lesser General Public License v2.1
933 stars 189 forks source link

Updating web interface? #325

Open Riffer opened 3 years ago

Riffer commented 3 years ago

This is a request for help or clarification.

I relate to your example esp8266_WebMenu.

My wish is to use it in combination with alternative input/output devices as OLED or just the serial terminal but currently, the web menu is limited to a full refresh to show the actual values.

My knowledge about web mechanisms is very basic and I had a hard fun time to research how the web page is built up by XSLT and so on, and from my understanding, this and the library at all really is great work!

The code seems not ready to sync the web page from another menu input (or a menu in parallel, that I tried to use in my exploration after trying to combine menu out to serial without the ability to input because the web socket does not support it, I think) or gets any update while values change externally.

I see in the source you set up a JSON-resource that already works fine, but it seems to me, the data is not used in the web page by now, right?

In your example, you have already a WebSocket in use, but you commented off the update function in r-site.js and the server-side function does not send JSON but only a string when connected.

After some research, I changed loop() it to send some JSON via web socket broadcast to the web client but I am stuck because I see no function to get a JSON presentation of the library somehow.

Another way could be to send commands like "refresh now" via web socket and let javascript request the JSON to updated values, but again I struggle because no function says "now its time for an update". I could check the values used in menus for change in replacement, but maybe there is a better way to do?

Maybe I am just on the wrong way, my hope is that you can clarify the current status and help me on the horse.

neu-rah commented 3 years ago

Hi! Thanks for using the library and provide some feedback.

Yes, web menu is missing the reactive part tin order to self update as local devices do...

The web menu introduces/uses some nice technique that should be the way of work of all other devices because it allow much more customizations. Basically it is a composition of a raw communication device and a formatter. It is activated by the presence of MENU_FMT_WRAPS defined at compiler level (or by mcu detection as is the case of esp8266).

When format wraps are active the menu system will call some extra methods on the output device. Those methods are provided by the composition class overlayed on the regular output. This technique is available not only for the web.

At this moment only 2 format overlays have been used:

https://github.com/neu-rah/ArduinoMenu/blob/master/src/menuIO/jsonFmt.h https://github.com/neu-rah/ArduinoMenu/blob/master/src/menuIO/xmlFmt.h

they will wrap text around menu content to fit the desired format, but they can be used to change colors or whatever... still, because the underlying output device is providing the output it is not possible to omit text content on the wrap level, it is only possible to wrap it.

So the web output device is a composition of a layer that provides the output (http, websocket, etc...) with a layer that provides formatting (xml, json,... ) you can build your own HTML format layer if that xml/xslt seems too ugly (i agree, xslt is ugly).

see here an example of a composition to form an output device_ https://github.com/neu-rah/ArduinoMenu/blob/e76c6a033f0e129f5a85ac75e3888d9ec4e9cecf/examples/esp8266_EscControl/EscControl/EscControl.ino#L86

xmlFmt<esp8266_WebServerStreamOut> xml over http jsonFmt<esp8266_WebServerStreamOut> json over http jsonFmt<esp8266BufferedOut> json over websockets

the overlay layer (xmlFmt, jsonFmt) will provide extra functions for this format events/parts https://github.com/neu-rah/ArduinoMenu/blob/0fa227602b29fe9a2c117381194890e453a2472e/src/menuIo.h#L63

now to get a raw html, one just have to base on current json/xml formatters and replace the content to provide html wrapping. The format events/parts will be called in two parts, start and end for proper wrapping.

About the xslt, it allows the output content to be much smaller because its only a state report in xml, and have it translate/expand to an html page on the client side by specifying a xslt style -sheet with rules fir the xml->html transformation. This delegates a lot of work to the client side and allows served page sizes to remain small.

as a note, MENU_ASYNC define will also activate the async API, allowing menu commands to be in the format of numeric indexed paths, ie: /1/2/0/3/125.0

more at https://gitter.im/ArduinoMenu/Lobby enjoy!