Skip to content
Rui Azevedo edited this page Jan 7, 2019 · 5 revisions

(not tested with arduino-ide yet, anyone?)

The library provides esp8266 drivers to serve the menu as a web-page, automating menu navigation and values input/output. The web-page uses Web-Sockets to update field values without refreshing the page, with a fall back of common web-link that will refresh the page when needed.

There is also a JSON IO available for web-sockets and http.

All HTTP output (not web-sockets) are streamed to the client minimizing memory usage.

The example uses JQuery + bootstrap to provide a smooth experience across client platforms and device types with a responsive UI.

note: you need to upload a file system image to esp8266 in adddition to normal sketch upload.

Client requirements

  • Client-side xslt translation, modern browsers, including mobile, support it.
  • JavaScript, without it links works but fields are not updated

Access

assuming webmenu is a device name.

http://webmenu/ serves a static web cover page, you can customize this page.

http://webmenu/menu?at=/ access the auto-generated menu pages, on this case the root.

http://webmenu/json?at=/ access the JSON output with root page state

all above modes accept a menu path parameter to activate options, update fields or set navigation state. The same path control is available for web-sockets, with JSON output

menu path

the http at parameter or the websocket string sent should contain a menu path using character / as a separator.

/ menu main page (root)
/0 use first option

  • if its a sub-menu, navigate into it, path can continue into submenus by separating indexes with / ex: /0/1/3
  • execute some action if its a regular prompt
  • change value if it its a toggle option
  • ignored on other controls

Setting values

lets say /0 is a toggle field, we can toggle it by calling its path, but we can also set it to enumerated values, lets say it has values "No"/"Yes", then:

/0/0 will set it to "No"

/0/1 will set it to "Yes"

The same technique can be used to update text or numeric fields.

web-sockets should send a null terminated string.

while issuing menu requests a response is provided that can, depending on the output device, be translated to and html page or a JSON response.

JSON Response

This is an JSON output example for a menu root.

while on a menu page you can use the browser console and the function menu(...) to send web-socket requests.

{
  "output":"",
  "menu":{"title":{"prompt":"Main menu"},
  "path":"","sel":"0",
  "items":[
    {"idx":"0","enabled":"1","selStart":">","prompt":"Led: ","value":"Off","options":["On","Off"]},
    {"idx":"1","enabled":"1","selStart":" ","prompt":"Action A"},
    {"idx":"2","enabled":"1","selStart":" ","prompt":"Action B"},
    {"idx":"3","enabled":"1","selStart":" ","prompt":"On" ,"field":"50","range":            
    {"low":"0","high":"100","step":"10","tune":"1"},"unit":"ms"},
    {"idx":"4","enabled":"1","selStart":" ","prompt":"Select" ,"select":"Zero","options":["Zero","One","Two"]},
    {"idx":"5","enabled":"1","selStart":" ","prompt":"Choose" ,"choose":"Last","options":            
    ["First","Second","Third","Last"]}
  ]
  }
}

.menu.title.prompt current menu prompt

.menu.path path of current menu page

.menu.sel current selection (not important on async interfaces as web)

.menu.items list of menu items (prompts/fields/pads)

sub-menus display as single prompts and form a new menu page/state when activated

note: Choose fields not yet implemented on web-page side.

Menu prompts

all items have some common info with prompts

ex:

{"idx":"1","enabled":"1","selStart":" ","prompt":"Action A"}

.idx option/field path index number
.enable 0/1 disabled/enabled
.prompt option title, can be empty

[.cursor] cursor character optional and not relevant for web
[.selStart] cursor start, optional and not relevant for web
[.selEnd] cursor end, optional and not relevant for web

Fields

ex:

{
  "idx":"1",
  "enabled":"1",
  "cursor":" ",
  "prompt":"",
  "field":"0.00",
  "range":{
    "low":"0.00",
    "high":"100.00",
    "step":"10.00",
    "tune":"1.00"
  },
  "unit":"%"
}

complements prompt info with:
.field current value of the field
.range and object containing field boundaries and update info
.unit field unit text to draw after the field value

Field Range

.low minimum value allowed, DO NOT SET OUTSIDE RANGE
.high maximum value
.step normal value adjust step
.tune tuning value adjust step

Text fields

ex:

{"idx":"1","enabled":"1","selStart":" ","prompt":"Key","editCursor":" ","text":"XXXXXX"}

complements prompt info with:
.text current text value .editCursor not important for web

Toggle/Select/Choose field

ex:

{
  "idx":"6",
  "enabled":"1",
  "selStart":" ",
  "prompt":"Demo:",
  "value":"Off",
  "options":["Off","On"]
}

complements prompt info with:
.value the current field value text, the actual value is an index of options list
.option a list of possible value strings ordered by index, start at 0

Pad options

Pads are groups of options (sub-menus) that are drawn together as a single option

ex:

{
  "idx":"0",
  "enabled":"1",
  "selStart":">",
  "prompt":"",
  "pad":[
    {"idx":"0","enabled":"1","cursor":" ","prompt":"" ,"field":"1","range":
    {"low":"1","high":"31","step":"1","tune":"0"},"unit":"/"},
    {"idx":"1","enabled":"1","cursor":" ","prompt":"" ,"field":"1","range":            
    {"low":"1","high":"12","step":"1","tune":"0"},"unit":"/"},
    {"idx":"2","enabled":"1","cursor":" ","prompt":"" ,"field":"2000","range":
    {"low":"2000","high":"2100","step":"10","tune":"1"},"unit":""}
  ]
}

they complement the prompt with:
.pad a list of prompts/fields

Customizing web-page menu

On the example the esp8266 is serving static files from the file system image (flash partition), with a couple of special handlers. You can customize all files here.

http requests

  • an http request to the root will serve the static index.html page
  • /menu outputs xml with a xslt translation page (dynamic content)
  • /json raw json output (dynamic content)

Static files like .css, images, .xslt and .js can be customized as needed. On the example we use jquery + bootstrap to produce a nice page. You can include as many as needed, with no extra code to handle them.

XML responses are translated to HTML on the client side by a static xslt translation sheet. This, just as the .css, can be customized. By default it translates the raw XML emitted by the menu into a complete HTML page with some nicer bootstrap controls.

Enumerated fields are on this example translated very freely to drop-down boxes or button groups on the client side.

Numeric fields can present them selves as regular html input fields or as a slider control, depending on some analysis of range done by the xslt style-sheet, so the menu structure type is not mandatory.

Mobile-Apps

JSON output is adequate to feed mobile apps, specially if requested by web-sockets instead of http, however can use both.

The JSON output provides a map to the served menu structure with all info needed to draw each page, so a generic mobile app can be build around this (hint: help needed)

beware that web-socket JSON output still uses buffers (no streaming).

There is a prototype javascript system to update page values based on a web-socket json refresh... it is still a protype.