OK, so a very simple example to get you going:
[{"id":"0c2e209c97820977","type":"uibuilder","z":"c51f51da7ee02d68","name":"","topic":"","url":"esp-test","fwdInMessages":false,"allowScripts":false,"allowStyles":false,"copyIndex":true,"templateFolder":"blank","extTemplate":"","showfolder":false,"reload":true,"sourceFolder":"src","deployedVersion":"6.1.0","showMsgUib":false,"x":850,"y":220,"wires":[["2ce8632982fab514"],["79bbf9a8ad263a1f","aad0c61ffd40f302"]]},{"id":"2ce8632982fab514","type":"debug","z":"c51f51da7ee02d68","name":"debug 39","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":985,"y":200,"wires":[],"l":false},{"id":"33730e1ee0c8bd64","type":"http in","z":"c51f51da7ee02d68","name":"","url":"/esp-upd","method":"get","upload":false,"swaggerDoc":"","x":200,"y":160,"wires":[["2471ddd15975e4d1","2be5186355f2c2c0"]]},{"id":"2471ddd15975e4d1","type":"http response","z":"c51f51da7ee02d68","name":"","statusCode":"200","headers":{},"x":380,"y":160,"wires":[]},{"id":"4a266abd843e4796","type":"http request","z":"c51f51da7ee02d68","name":"","method":"GET","ret":"txt","paytoqs":"ignore","url":"http://red.localhost:1880/nr/esp-upd?id=esp001","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[],"x":390,"y":40,"wires":[[]]},{"id":"a9bac14328a9ac69","type":"inject","z":"c51f51da7ee02d68","name":"Simulate ESP call","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":210,"y":40,"wires":[["4a266abd843e4796"]]},{"id":"c8838e7fa63011fa","type":"comment","z":"c51f51da7ee02d68","name":"API endpoint for ESP call","info":"","x":230,"y":120,"wires":[]},{"id":"79bbf9a8ad263a1f","type":"debug","z":"c51f51da7ee02d68","name":"debug 40","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1025,"y":240,"wires":[],"l":false},{"id":"2be5186355f2c2c0","type":"change","z":"c51f51da7ee02d68","name":"Filter .req & .res + set topic","rules":[{"t":"delete","p":"req","pt":"msg"},{"t":"delete","p":"res","pt":"msg"},{"t":"set","p":"topic","pt":"msg","to":"msg-from-esp","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":360,"y":220,"wires":[["b18de733e3d7e4d5"]]},{"id":"b18de733e3d7e4d5","type":"uib-cache","z":"c51f51da7ee02d68","cacheall":false,"cacheKey":"topic","newcache":true,"num":1,"storeName":"default","name":"","storeContext":"context","varName":"uib_cache","x":630,"y":220,"wires":[["0c2e209c97820977"]]},{"id":"0cb298630b1e94a6","type":"link in","z":"c51f51da7ee02d68","name":"link in 2","links":["aad0c61ffd40f302"],"x":465,"y":260,"wires":[["b18de733e3d7e4d5"]]},{"id":"aad0c61ffd40f302","type":"link out","z":"c51f51da7ee02d68","name":"link out 9","mode":"link","links":["0cb298630b1e94a6"],"x":985,"y":260,"wires":[]}]
index.html:
<!doctype html>
<html lang="en"><head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Blank template - Node-RED uibuilder</title>
<meta name="description" content="Node-RED uibuilder - Blank template">
<link rel="icon" href="./images/node-blue.ico">
<!-- Your own CSS (defaults to loading uibuilders css)-->
<link type="text/css" rel="stylesheet" href="./index.css" media="all">
<!-- #region Supporting Scripts. These MUST be in the right order. Note no leading / - socket.io no longer needed -->
<script defer src="../uibuilder/uibuilder.iife.min.js"></script>
<script defer src="./index.js">/* OPTIONAL: Put your custom code in that */</script>
<!-- #endregion -->
</head><body class="uib">
<h1>uibuilder Blank Template - v6.1.0</h1>
<div id="more"><!-- '#more' is used as a parent for dynamic HTML content in examples --></div>
<div style="margin-bottom: 2em;">
ESP 001 Status: <span id="status001"></span>
</div>
<!-- Two different ways to send data back to Node-RED via buttons.
fnSendToNR uses standard `uibuilder.send`.
eventSend includes `data-*` attributes, keyb modifiers, etc. Works with any event. -->
<button onclick="fnSendToNR('A message from the sharp end!')">Send a msg back to Node-RED</button>
<button onclick="uibuilder.eventSend(event)" data-type="eventSend" data-foo="Bah">eventSend</button>
<pre id="msg" class="syntax-highlight">Waiting for a message from Node-RED</pre>
</body></html>
index.js
// @ts-nocheck
/** The simplest use of uibuilder client library
* Note that uibuilder.start() should no longer be needed.
* See the Tech docs if the client doesn't start on its own.
*/
'use strict'
// logLevel 2+ shows more built-in logging. 0=error,1=warn,2=info,3=log,4=debug,5=trace.
// uibuilder.set('logLevel', 2)
// uibuilder.log('info', 'a prefix', 'some info', {any:'data',life:42})
// Helper function to send a message back to Node-RED using the standard send function - see the HTML file for use
window.fnSendToNR = function fnSendToNR(payload) {
uibuilder.send({
'topic': 'msg-from-uibuilder-front-end',
'payload': payload,
})
}
// Listen for incoming messages from Node-RED
uibuilder.onChange('msg', function(msg) {
// Dump the msg as text to the "msg" html element
// either the HTML way or via uibuilder's $ helper function
// const eMsg = document.getElementById('msg')
const eMsg = $('#msg')
if (eMsg) eMsg.innerHTML = uibuilder.syntaxHighlight(msg)
$('#status001').innerText = `I was alive at ${(new Date).toLocaleTimeString()}!`
})
Note that most of the front-end code is boiler-plate from the "blank" example (actually from the next release of uibuilder but it should work just fine with the live 6.0.0 release).
What it does is to use http-in/-out to create the API endpoint (uibuilder can do that too but this is simpler for this simple case). When called, that endpoint passes some data on to uibuilder where you can either process it in node-red before sending or process it in the front-end - or both. It also uses the uib-cache node to retain the last value sent so that a newly connected browser tab gets that value.
You could easily extend the change node to set the topic to the ESP's id so that the last msg from each ESP device was retained.
Note that it took a lot longer to copy/paste and write this text than it did to create a new uibuilder node with the flow and the front-end code!! 