Category Archives: node red ui

Another LCD

LCD colours by Peter ScargillWhen writing that last blog entry about an LCD with time and date display and programmable temperature for Node-Red Dashboard, it occurred to me that it would be worthwhile making a simple one-liner (6*1) LCD with a 20-character display. At the same time I wanted to simplify it right down and here’s the result. Should make a good starting point for anyone wanting to develop their own.


In this case you simply fire a message at the template node. You only need one font for this from the ones used in the previous entry (really you should read the previous article to understand how to load the fonts in – trivial).

I’ve done a check on msg.payload and if the first character is a period I then use the remainder of the message to select colour – hence…


And that really is it – really simple to use – make the template 6*1,insert the code, make sure the font is in place and when you run it – you can select the sample text or play with the colours – enjoy.

LCD colours by Peter Scargill

LCD colours by Peter Scargill

LCD colours by Peter Scargill

[{"id":"7744e0e4.38986","type":"inject","z":"c552e8d2.712b48","name":"","topic":"","payload":"Hello there","payloadType":"str","repeat":"","crontab":"","once":false,"x":800,"y":1180,"wires":[["864d97a5.30d348"]]},{"id":"543d4cba.38a7a4","type":"inject","z":"c552e8d2.712b48","name":"green","topic":"","payload":".blackOnGreen","payloadType":"str","repeat":"","crontab":"","once":false,"x":790,"y":1220,"wires":[["864d97a5.30d348"]]},{"id":"658a2f15.d95bc","type":"inject","z":"c552e8d2.712b48","name":"orange","topic":"","payload":".blackOnOrange","payloadType":"str","repeat":"","crontab":"","once":false,"x":790,"y":1260,"wires":[["864d97a5.30d348"]]},{"id":"b60e3a3f.931078","type":"inject","z":"c552e8d2.712b48","name":"blue","topic":"","payload":".blackOnBlue","payloadType":"str","repeat":"","crontab":"","once":false,"x":790,"y":1300,"wires":[["864d97a5.30d348"]]},{"id":"62767df.a99d984","type":"inject","z":"c552e8d2.712b48","name":"yellow","topic":"","payload":".blackOnYellow","payloadType":"str","repeat":"","crontab":"","once":false,"x":790,"y":1340,"wires":[["864d97a5.30d348"]]},{"id":"ad983ec0.bd2ed","type":"inject","z":"c552e8d2.712b48","name":"white","topic":"","payload":".blackOnWhite","payloadType":"str","repeat":"","crontab":"","once":false,"x":790,"y":1380,"wires":[["864d97a5.30d348"]]},{"id":"a046dc0e.953ea","type":"inject","z":"c552e8d2.712b48","name":"pink","topic":"","payload":".blackOnPink","payloadType":"str","repeat":"","crontab":"","once":false,"x":790,"y":1420,"wires":[["864d97a5.30d348"]]},{"id":"8372ff69.e0a4c","type":"inject","z":"c552e8d2.712b48","name":"red and light text","topic":"","payload":".yellowOnRed","payloadType":"str","repeat":"","crontab":"","once":false,"x":820,"y":1460,"wires":[["864d97a5.30d348"]]},{"id":"5fcd3b1d.a64954","type":"inject","z":"c552e8d2.712b48","name":"cyan and white","topic":"","payload":".whiteOnCyan","payloadType":"str","repeat":"","crontab":"","once":false,"x":820,"y":1500,"wires":[["864d97a5.30d348"]]},{"id":"a81aab9f.8f78a8","type":"inject","z":"c552e8d2.712b48","name":"lime on black","topic":"","payload":".limeOnBlack","payloadType":"str","repeat":"","crontab":"","once":false,"x":810,"y":1540,"wires":[["864d97a5.30d348"]]},{"id":"864d97a5.30d348","type":"ui_template","z":"c552e8d2.712b48","group":"33279d5b.72b122","name":"LCD","order":0,"width":"6","height":"1","format":"<script>\n    var LCDColours={\n    \"blackOnOrange\": {items:[\"#222\",\"#fb7c00\"]},    \n    \"blackOnGreen\" : {items:[\"#222\",\"#66ac66\"]},\n    \"blackOnBlue\" : {items:[\"#222\",\"#8888ff\"]},\n    \"blackOnYellow\" : {items:[\"#222\",\"#bbbb44\"]},\n    \"blackOnWhite\" : {items:[\"#222\",\"#aaaaaa\"]},\n    \"blackOnPink\" : {items:[\"#222\",\"#ff8888\"]},\n    \"yellowOnRed\" : {items:[\"#ccaa22\",\"#aa2222\"]},\n    \"whiteOnCyan\" : {items:[\"#dddddd\",\"#227777\"]},\n    \"orangeOnBlack\" : {items:[\"#ff8800\",\"#000000\"]},  \n    \"limeOnBlack\" : {items:[\"#00cc55\",\"#000000\"]} \n    } ;\n\n   (function(scope){ \n            scope.$watch('msg', function(msg) {\n                if (typeof(msg.payload) != \"undefined\") \n                        {\n                            if (msg.payload.substring(0,1)!=\".\") $(\"#LCDTextBody\").text(msg.payload);  \n                            else\n                            {\n                              msg.payload=msg.payload.substring(1);\n                              $(\".LCDWrapper\").css('background-color', LCDColours[msg.payload].items[1]);  $(\".LCDTextFront\").css('color', LCDColours[msg.payload].items[0]); \n                              if (LCDColours[msg.payload].items[1]==\"#000000\") $(\".LCDTextBack\").css('color',\"rgba(255,255,255,0.15)\"); else  $(\".LCDTextBack\").css('color',\"rgba(0,0,0,0.1)\");                                \n                                \n                            }\n                        }   \n            });\n    })(scope);\n\n</script>\n\n<style type=\"text/css\">\n@font-face {\n  font-family: \"D14MI\";\n  src: url(\"/myfonts/DSEG14Modern-Italic.woff\") format('woff');\n}\n\n\n.LCDWrapper{\n\tposition:relative;\n\tborder:3px solid #000;\n\tborder-radius:8px;\n\theight:66px;\n\twidth:304px;\n\tcolor: 0;\n    font-family: \"D14MI\";\n\tbackground-color:#66ac66;\n\tbox-shadow: 3px 3px 10px 0px rgba(0,0,0,0.3) inset; \n}\n\n.LCDTextBack{\n\tz-index:50; color:rgba(0,0,0,0.1); \n}\n\n.LCDTextFront{\n\tz-index:51; color:rgba(0,0,0,1);\n}\n\n.LCDTextBack,.LCDTextFront {\n   \tposition:absolute;\n\ttop:3px;\n\tleft:6px; \n\tfont-size:18px;\n}\n\n</style>\n\n<div class=\"LCDWrapper\">\n\t<span class=\"LCDTextBack\">~~~~~~~~~~~~~~~~~~~~</span>\n\t<span class=\"LCDTextFront\" id=\"LCDTextBody\" ></span>\n\n</div>\n","storeOutMessages":false,"fwdInMessages":false,"x":990,"y":1320,"wires":[[]]},{"id":"8e623ee.81f9bc","type":"inject","z":"c552e8d2.712b48","name":"","topic":"","payload":"Goodbye","payloadType":"str","repeat":"","crontab":"","once":false,"x":800,"y":1140,"wires":[["864d97a5.30d348"]]},{"id":"33279d5b.72b122","type":"ui_group","z":"","name":"LCD Test","tab":"34cddaf3.8a9cd6","disp":true,"width":"6"},{"id":"34cddaf3.8a9cd6","type":"ui_tab","z":"","name":"testz","icon":"dashboard"}]

More Node-Red Dashboard Success

Dashboard buttonsWell, it looks like my revelations with hiding the mouse has upset WordPress – the previous blog on the subject makes some people’s mice disappear!  Good job I wasn’t testing a self-destruct button.

It’s been a good day today – I discovered SLACK and I’ve been happily chatting to folk about my Node-Red-Dashboard issues and at the end of it all, not only have the issues gone away but I’m making progress.

So – there are a couple of things to notice and some you won’t.

So firstly – my button experience until now on Node-Red-Dashboard has been blighted by a SWIPE command which meant if you pressed a button near the right of the screen and in any way slid your finger  to the right – the page would change – in the unreleased update to Node-Red-Dashboard (needs just a tad more work and docs apparently) that has gone.  Excellent. I’ve seen this “feature” in other packages and it really does not work if you’re supposed to interact with buttons.

In my last blog on the subject you’ll see I can hide that top menu if needed (the blue menu is great on a phone – not much use on a thermostat)… and today I discovered that desktop TEMPLATES have a spacing round them that DID make it impossible to make your own buttons that would be size compatible with the UI built-in buttons.

That is all now history. So – the built in buttons – no text wrap which make it hard to make small, a visual effect on press that really is hardly noticeable, inability to change colour or indeed anything other than text colour – all problems now history.

The garish red, green and blue buttons you see above – note the rounded edges you control, there is an attractive and obvious colour change pm press (and return to original colour after press without you having to program it ), audible feedback on press (on phones with vibrators), wrap on text – indeed you can put anything in there - icons etc.

This is due to a combination on my insistence on having flexibility – my own experience and lots of help from several guys on the web today – thanks everyone for filling in the missing bits! The end result of all of this – I really DO think that Dashboard is able to take on the big boys and I’m currently backing away from the alternatives.

So – the enabling technology here is the node-red-dashboard template – this has LOTS of potential and it is now easy to accept incoming information – and send out a value on press or whatever. You’ll note elsewhere that I’ve used this to make whole pages with colour-changing icons etc., well here I’m using one template per button – but that’s just for the purpose of demonstration.

Things that needed considering – CSS for button sizing, JS to get the button colour and change it while pressing then change it back – I was not going to get into setting each and every button press colour etc. More CSS for styling. All described below and trivial to implement.

SO it turns out that if you put a template on a page – make sure it is the first one – you can put nothing but JS and CSS in it – and it will not do anything VISIBLE – but will supply your functions and CSS for the whole page – isn’t that HANDY!!!

tmp3513Let’s take a look at what is driving the display up there (again ignoring the text at the top – start with the buttons). To the left you see a template all on it’s own – then 3 templates – then 3 buttons – not connected to anything as this is merely a demo.

So – the FIRST template has info we need – CSS and JS to make everything work – you just need this once for any page. The light blue buttons are there just to show you what buttons look like in Dashboard (i.e. not as good as they could be) – and the three templates are the three new coloured buttons you see above right – which react to being pressed both visually and with haptic feedback.

Let’s take a look at the FIRST template which makes it all possible. It looks easy now but trust me it has taken some head scratching to get this far.

  .filled { 
      height: 100% !important;

      padding: 0 !important;
      margin: 0 !important;
  .nr-dashboard-template {
      padding: 0;
      margin: 0;
  .rounded {
  border-radius: 15px 15px 15px 15px;
  font-size: 18px;

$('.vibrate').on('click', function() {

function restore_bg(x) {
            $(this).css("background-color", x);

$('.touched').on('mousedown', function() {
    var x= $(this).css("background-color");
    $(this).css("background-color", "yellow");

NOTE: At the time of writing this colour change works on Chrome etc on a PC and Android phone – it does NOT work on Firefox/Chromium on a Pi – this needs resolving.

The class FILLED is important - this is the one that gets rid of the padding that both buttons and template use by default - to make the button fill to the size of the template. nr-dashboard-template is also involved. None of this seems to affect other items on the screen.

ROUNDED is simply a means of forcing rounding on buttons - you can adjust that radius to suit or eliminate it if you like.

The scripts - well VIBRATE merely invokes the haptic feedback when you press a button - easy when you know how.

TOUCHED and it's associated restore function are variations on the ones I used with images. The class allows on press for a button to store it's colour - change it's colour - wait for a while - and change it back - all without having to have individual colour control on the actual button  - which simply has the default colour you select.

Now let's take a look at once of those templates. Oh and I got those subtle colours from here -

<md-button class="vibrate filled touched rounded" style="background-color:#c0392b" ng-click="send({payload: 'Hello World'})"> 

Simple? Yes because the previous code makes it so. A button in a template - auto stretched by the code above and all it has added is the background colour - which the above code can manipulate - and the classes. That's it. The ng_click is what happens when you press the button - the template outputs a payload of whatever you've set. No, really that is it.  so on that output, msg.payload will be whatever you set it to be.

With background colour control, RGB and related buttons become simple - a page full of colours for RGB controls becomes possible.  Note in the class ROUNDED I changed the font size - well you could separate that off to a separate class - and create classes (say) BIGTEXT and LITTLETEXT for example - suitable for different size buttons.

When you grasp this - if you're not there already, immediately all sorts of ideas should come to mind -it's a bit like opening a new door to see all the things behind it. Within days my demo screen will look utterly amateurish as I start adding icons etc but today was important as it was, for me a confirmation that there really is not a lot you can't do with node-red-dashboard – so many congratulations to the original developer and the guys at IBM and everyone contributing. 

If you go to the ANGULAR site and look at their examples - most of them work no problem - changing these rectangular buttons to round ones is a snap!

Oh, talking of improving things  - here’s a snapshot hours later as things progress…NICE!

new buttons


Oh – here…  - if you want a play…. and YES that template uses a little white space – but next Node-Red-Dashboard release it will NOT – css and scripts only will NOT use up screen real estate – all coming together VERY well right now.


A successful Techy Day

So much going on today I thought I’d put the lot into one blog entry.

So, I’ve spent the day with my pal playing with one of several IOT solutions – familiar to regular readers – node-red-contrib-ui. This just keeps getting better.

tmp6D4ASo we spent our afternoon getting to grips with the new “template” node which Andrei the designer has been improving recently. We wanted an RGB controller which the UI does not (did not) currently feature. Getting to grips with Angular and how it interfaces with the UI is proving a challenge but the long and short of it is (I know a couple of you are about to get excited) – we have a working RGB controller.

Here it is. Just ignore my FREDDY experiments and the pretty coloured line of buttons…

Well, no, don’t ignore the buttons – I’m finding increasingly frustrating to have to use the big but still limited range of ANGULAR icons – so I’m about to write off to Andrei to see if we can maybe trap HTTP in the icon description to allow us to use any arbitrary online PNG file – preferably transparent ones – imagine you have a row of buttons for +, minus and auto.  The Angular icons do + and -  but how on earth do you represent “AUTO” – I could think of a 1000 examples where you just can’t do it with a limited set of icons… so that needs work…

Update 31/12/2015 – It is now my understanding that soon we will have the ability to use our own images as well as an expanded library – that is just excellent!!!

However I digress – see the bottom line – RED GREEN AND BLUE controllers (ignore the yellow, I’m experimenting). On the right is a BLACK BLOCK which changes colour as you move the sliders. So this TEMPLATE node in Node-Red UI- and this is all down to Andrei, has an input and an output – the output puts out  JSON string with R G B values…. the input expects msg.payload.r, msg.payload.g etc… well I didn’t have a CLUE how to do that so again Andrei helped. So here I will show you an example of use –, the template node and the input to manually set the controls. I CAN CONFIRM that all of this mirrors perfectly if for example you have this running on 2 phones at once – they remain in sync perfectly!!!!  This is just so good!


So above you see an inject (ignore the timestamp) – the function will set up 3 values to put into the template to affect the sliders – so for example you can set up initial conditions.

msg.payload = {
  r: 10,
  g: 50,
  b: 100

return msg;

So there’s an incoming payload which we’re going to ignore – the bit I was not sure about was adding new stuff – ie msg.payload.r  and again Andrei came to the rescue – you’ll see I’ve initialised RGB values and then proven to myself that you can quickly alter them before sending MSG off to the template node. The output of the template node goes off in this case to a DEBUG node and there’s a JSON string with RGB values going out (that might be used to populate a global variable and off via MQTT to some RGB lighting).

Here is the content of the template.

<div layout="row" layout-align="space-between center">
    <md-slider ng-model="msg.payload.r" ng-change="send(msg)" flex="30" min="0" max="255" class="slider-red">
    <md-slider ng-model="msg.payload.g" ng-change="send(msg)" flex="30" min="0" max="255" class="slider-green">
    <md-slider ng-model="msg.payload.b" ng-change="send(msg)" flex="30" min="0" max="255" class="slider-blue">
    <div style="width: 32px; height: 32px;" ng-style="{'background-color': ('rgb(%d, %d, %d)'|sprintf:msg.payload.r:msg.payload.g:msg.payload.b)}">

(function(scope) {
    scope.$watch('msg.payload', function (v) {
        if (!v) scope.msg ={ payload: {r:0, g:0, b:0} };

    .slider-green .md-track-fill {
        background-color: green !important;
    .slider-green .md-thumb:after {
        background-color: green !important;
        border-color: green !important;
    .slider-blue .md-track-fill {
        background-color: blue !important;
    .slider-blue .md-thumb:after {
        background-color: blue !important;
        border-color: blue !important;

What you have there is not only the RGB controls – but all you need to know in order to make any custom system you like which has INPUTS and OUTPUTS. This is so very useful.

So there you go – a great new UI gadget.

Strangely enough – I needed that bit of knowledge about adding stuff to MSG as today another pal of mine pointed me to an ANDROID/IOS App called OWNTRACKS. It has a lot of uses but one of it’s features allows you to set up your phone to send regular LONGITUDE/LATITUDE messages to your own MQTT server.

Now, I went off on a crawl and found a NODE-RED node to do GEOFENCING – here it is.


So the ORANGE node is a node called GEOFENCE (node-red-contrib-geofence).  This is marvellous – so you feed it longitude and latitude and it compares against a set area and either passes the message through – or not.

On the left you see my MQTT node picking up a topic which I set on the phone. Next you see me convert the data to the right vars – exactly the same issue I had above so I killed 2 birds with one stone – here’s the function.

var fred=JSON.parse(msg.payload);

msg.location = {
  lon: 0,
  lat: 50

return msg;

So from my incoming MQTT in a format decided by the App, not me I’ve created 2 items which the geofence node understands – regular updates as to where I am.

Here’s the winner – the Geofence admin page when you click on the orange Geofence node.


This is so good I’m betting I don’t have to explain how it works – you simply put a square, circle or shape around a location, town, house or whatever – and if the incoming coordinates are in that area the whole message just gets passed through – if not, nothing gets passed through. There are other options!!

The obvious next move is a function with a check to ensure you were OUT of the area and coming IN and the string “I’m nearly home, get the kettle on” – passed to the speech system I showed you in my last blog. In my case I’d likely get beaten up for doing that but I’m sure you understand the MASSIVE potential for this.

Put welcome lights on when coming home, alarm the house when leaving etc etc etc… actually with an ESP8266 you could put the kettle on yourself!!! HEY that’s a good idea.

All of this takes only minutes to get going when you have info like this (I had to kind of fumble through much of it). You could use multiple nodes from the same MQTT input to do all sorts of analysis on movement. What’s needed next it really tmpFED7cheap GPS transmitters for the cats!! Just so many possibilities.

So – that was that – then when I got home tonight – the post was waiting for me.  This little number arrived in the post.. This bare board was less than £2 on Ebay…

Ok, it needs 2 MOSFETS, a couple of resistors (SMT) and a regulator and an ESP-12 and you have yourself a handy 0.1” centres development board – only for true soldering iron enthusiasts but I thought it would be worth having.

tmpD4F5As well as that, SEED STUDIOS sent me their LinkIT SMART 7699 board and a nice adaptor to go with it… I’ll have to write this up later when I get enough time to do it justice but on the left you see one of the little boards – it has 2 micro-USB sockets – 3 buttons (reset, program, user) and a WIFI module with lots of IO – the accompanying breakout board lets you do the whole thing with wires and connectors without going anywhere near a soldering iron.

Unlike ESPs (which are of course cheaper) these little devils run Linux!! Anyway, it’s late but here’s a link for interested parties..


And that is about it for one day. I’ve just found a cheap TIMER unit for my upstairs radiators so I can turn them off when we’re sleeping downstairs and by the time that turns up I’ll have a very pretty mobile application for my good lady to control the heating with.

Good night, all.


Node Red UI Mysteries

Yes I did think when writing the title that it reminded me of “Ruth Rendell Mysteries”.

There are times when I consider taking up a new career in bricklaying and this is one of them.

So I’m working with Node-Red and the UI (node-red-contrib-ui) which has a FUNCTION node which lets you use a weird combination of JavaScript and something called “Angular”.  I am failing to get to grips with this one..

So right now the UI has a button – and it has a text box – but not on the same line – and this to me seems like an obvious marriage.


So Imagine the scenario.. you press the button which merely returns “1” to Node-Red so you know it has been pressed.  Either as a result of that action or for other reasons you want the text on the right (or icons representing the text) to say – for the sake of example “Active”, “Sleep”,”Standby” – in other words an arbitrary message which is affected by the button press.

So here was my first attempt – using the “template” node in the UI.

<div layout="row" layout-align="space-between">
<md-button class="md-raised" ng-click="send({payload: '1'})">
</md-button >

tmp878AIt all seemed obvious to me – you press the button and it sends “1” – you send an input to the node and it prints the incoming message.

At this point you will get a clear picture of just how far off the mark I am here – could be too much Christmas cheer or course.

Pressing the button returned “1” to Node-Red alright  - however it also set the text on the right. Worse, sending a message “Active” to the node input put up the message as I needed – but ALSO sent that to the output. It just is NOT making sense to me. I want the button press to go back out – but incoming messages to go to that text area ONLY.

Here is my kluge to get around all of this.


The inject node on the left sends “Active” when pressed. The function (2nd left) copies this from msg.payload to msg2.payload. The modified template uses msg.payload2 for it’s text section.

<div layout="row" layout-align="space-between">
<md-button class="md-raised" ng-click="send({payload: '1'})">
</md-button >

And the last function only passes the message if it sees “1” in msg.payload.

Update: Even THAT doesn’t work… press the button – fine – press the inject – fine – press the button – it wipes the panel on the right!!

The template node in node-red-contrib-ui is clearly very powerful for creating user interface elements but I suspect it is going to take a variety of examples to give some of us the mental tools we need to make best use of it.

Any more takers on the above – there has to be a way to get this to work properly!


More Node Red UI

Updated 01/11/2016: Node-Red-UI is of course now Node Red Dashboard - you might want to check out the updates

Andrei has now added the gauges below natively to node-red-contrib-ui so my code below is of use only if you want to add something different – though the LEDs are still useful until he adds something to the package to do pretty lights.

In my last blog I touched the surface of Node-Red-Contrib-UI  - an add-in for the increasingly popular Node-Red – in my case running on a simple Raspberry Pi (but of course you can run it on a PC etc).

node-red-contrib-uiThe UI software comes in at a time when several vendors and enthusiasts alike are scrambling to come up with a mobile interface for IOT – the Internet of Things. Every last one of them has benefits and issues. NETIO is a venerable interface which is currently languishing or so it seems with no new features of any significance for some time. It does, however have some nice widgets.

jQuery Mobile presents some options – and that is fairly easy to implement though much more DIY than others. Blynk is coming along and offers a VERY pleasant interface – but it is UTTERLY non-user-expandable and I’m not 100% sure I believe that it will continue to develop at the current page forever – until now it was my current “best hope” and possibly still is – but I cannot yet get 100% reliability using it with Node-Red – and some widgets I think are relevant are on the back boiler for the designers. Who can tell which will succeed.

And then one of our readers had me take another look at node-red-contrib-ui – I won’t go into that as it is in the last blog entry (I suggest you read that first).

Something that caught my eye was a node called “paragraph” which would let you put in html – and which would accept parameters. It has all the makings of a useable “block” to make your own widgets and that is how I like it – the designer was MORE than helpful when I came up with newbie (dumb) questions and that for me builds a little loyalty.

So – the PARAGRAPH node basically opens up and lets you put in your own code with limitations which will hopefully go away. In the last blog I showed how to put a LED indicator and description into a node – and also discussed pulling in information from a web page with parameters.

And this is where jUSTGAGE comes in.

Go to their website and you will see a beautiful gauge – and a deceptively simple web page (which I will call gauge.html) to display it.

Clearly having the code on your own computer is best so I grabbed the ZIP file and put the contents in a directory called justgage under the main UI folder (see last blog). I took their example and put it into a web page in the main ui (/dist) directory. I ran it and… nothing.  The version numbers for includes were wrong – and indeed just different so watch out for that – this is what i finally ended up with…

<script src="justgage/raphael-2.1.4.min.js"></script>
<script src="justgage/justgage-1.1.0.min.js"></script>
<div id="gauge" class="200x160px"></div>
var g = new JustGage({
id: "gauge",
value: 67,
min: 0,
max: 100,
title: "Visitors"

And that’s all well and good – if you like a fixed gauge that doesn’t do anything  Smile

The next stage was to add in the code which would let me modify parameters… but first what doe this look like when you put it into a PARAGRAPH NODE. This isn’t as complicated as it looks – I needed to pass the title for the gauge, the min and max values and the actual value.

Here’s the code for the “gauge” node below (in a paragraph node)…

<iframe frameborder=0 scrolling="no" height="200px" ng-src="{{'gauge.html?min=0&max=40&title=Inside Temperature&val=' + msg.payload}}"></iframe>

The paragraph editor puts a red cross on this – but trust me it works – and if anyone knows how to get rid of the editor objection, let me know.

Of course the web page code now needs to be able to handle those parameters (in this case “val”, “min” etc)

Here is a modified version of the above code in the page “gauge.html” to handle parameters.

<script src=""></script>
<script src="justgage/raphael-2.1.4.min.js"></script>
<script src="justgage/justgage-1.1.0.min.js"></script>
<div id="gauge"></div>
var getUrlParameter = function getUrlParameter(sParam) {
var sPageURL = decodeURIComponent(,
sURLVariables = sPageURL.split('&'),
for (i = 0; i < sURLVariables.length; i++) {
sParameterName = sURLVariables[i].split('=');

if (sParameterName[0] === sParam) {
return sParameterName[1] === undefined ? true : sParameterName[1];

var g = new JustGage({
id: "gauge",
value: getUrlParameter('val'),
min: getUrlParameter('min'),
max: getUrlParameter('max'),
title: getUrlParameter('title')

tmpE1C8You could go chose to use a local copy of jQuery – I chose to use an online version (after all if the Internet connection isn’t working – you’re not going to be able to access this anyway!)

And it works – the sky is the limit – BUT the iframe is not ideal – the gauge refreshes completely every time you put a NEW (changed) value in – NOT satisfying – if nothing else however I may have given others some ideas – who can come back to me with a “much better way”.

In the case of a gauge we really need this built into node-red-contrib-ui along with input value, title and colour values along with min (which should optionally be minus) and max.

Scargill test node-red-contrib-ui moduleI did ask if any of you CSS types know where to look to slightly reduce the gaps between items. If you look at the display below – there’s a lot of wasted space.. I believe this has now been fixed by Andrei – the author of nod-red-contrib-ui

I’m showing here on the left my first attempt at actually doing something useful with this – thankfully on my thermostat system I keep all live information in a global object so it is easy to access on any page.  The panel on the left is actually working – adjusting the temperature up and down reflects in my Nextion LCD panel as well – so already this is a usable App.

This is VERY much a work in progress but to get the imagery you see on the left and an additional graph – I’m showing my flow page for node-red-config-ui as it stands.



Peter Scargill experimenting with Node-Red-Contrib-UI