Trying to make winddirection compass gauge with ui_control

I am trying to make a windirection compass with standard ui_gauge and manipulate with ui_control.

I ran into a few issues/questions here.

  • I noticed that the compass needle is not always following correctly. Any reason why?

  • I don't need to see the value of the angle of the wind, but I do want to see the text of the wind direction, so I hide the value with ui_control and use the unit field for display the wind direction in text format. But as you can see the text is rather small, I would like it to be bigger, I found quite some things that you can change with ui_control, but nothing about the units field.

  • I managed to get the compass ring all the way in yellow, but I would like to make the arrow point also yellow or white, how can I do this?

Any help will be appreciated.

[{"id":"eb579d73b2805b6d","type":"function","z":"ececc97e.440b","name":"","func":"var winddegree = msg.payload;\nvar str;\n\nif (winddegree >=   0) { str = \"Noord\"; } \nif (winddegree >  23) { str = \"NoordOost\"; } \nif (winddegree >  68) { str = \"Oost\"; } \nif (winddegree > 112) { str = \"ZuidOost\"; } \nif (winddegree > 157) { str = \"Zuid\"; } \nif (winddegree > 203) { str = \"ZuidWest\"; } \nif (winddegree > 248) { str = \"West\"; } \nif (winddegree > 293) { str = \"NoordWest\"; } \nif (winddegree > 337) { str = \"Noord\"; } \n\nmsg = {payload: winddegree, string: str}\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1080,"y":800,"wires":[["0c72715b5405925f"]]},{"id":"a1823158fae5bf4a","type":"ui_gauge","z":"ececc97e.440b","name":"Wind direction","group":"71919791.fa0748","order":2,"width":4,"height":3,"gtype":"compass","title":"Windrichting","label":"{{msg.string}}","format":"{{value}}","min":0,"max":"360","colors":["#ffff00","#ffff00","#ffff00"],"seg1":"","seg2":"","className":"","x":1480,"y":800,"wires":[]},{"id":"0c72715b5405925f","type":"function","z":"ececc97e.440b","name":"Style Gauge","func":"var msg1 = {}; \nvar msg2 = {}; \n\nvar circleColor = \"yellow\";        \nvar textColor = \"white\";               \n\nmsg1.ui_control = \n{   \"gtype\": \"compass\",\n    \"options\":{\n        \"gaugeColor\": circleColor, \n        \"levelColors\": [\"yellow\",\"yellow\",\"yellow\"],\n        \"hideValue\": true,\n//        \"circleThickness\": 0.03, \n    }\n};\n\nmsg2 = msg;\n\nreturn [msg1, msg2];","outputs":2,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1270,"y":800,"wires":[["a1823158fae5bf4a"],["a1823158fae5bf4a"]]},{"id":"7df0d6ec16c16ffa","type":"ui_slider","z":"ececc97e.440b","name":"","label":"slider","tooltip":"","group":"71919791.fa0748","order":2,"width":0,"height":0,"passthru":false,"outs":"end","topic":"topic","topicType":"msg","min":0,"max":"360","step":1,"className":"","x":910,"y":800,"wires":[["eb579d73b2805b6d"]]},{"id":"71919791.fa0748","type":"ui_group","name":"Actueel weerbericht","tab":"6c1339a6.f07a88","order":1,"disp":true,"width":"8","collapse":false},{"id":"6c1339a6.f07a88","type":"ui_tab","name":"Het weer","icon":"wb_sunny","order":7,"disabled":false,"hidden":false}]

The result I have so far.
afbeelding

See this link...

Also there is this node that may be useful to you.

@dynamicdave , thanks for the suggestion of bartbutenaers, but I would like to stay in same style as other gauges and I think I am almost there. The first link doesn't seem give me any answers to my questions.

In order to make the text label larger and to change the colors, you need to use CSS styles.

This ui-template should make your pointer yellow (I think it actually overrides your "circlecolor").

[
    {
        "id": "acb7fec2841e3f3c",
        "type": "ui_template",
        "z": "edbbfd88fa0e0826",
        "group": "71919791.fa0748",
        "name": "",
        "order": 2,
        "width": 0,
        "height": 0,
        "format": "<style>\n.nr-dashboard-gauge svg path {\nfill: #ffff00;\n}\n</style>",
        "storeOutMessages": true,
        "fwdInMessages": true,
        "resendOnRefresh": true,
        "templateScope": "local",
        "className": "",
        "x": 660,
        "y": 240,
        "wires": [
            []
        ]
    },
    {
        "id": "71919791.fa0748",
        "type": "ui_group",
        "name": "Actueel weerbericht",
        "tab": "6c1339a6.f07a88",
        "order": 1,
        "disp": true,
        "width": "8",
        "collapse": false
    },
    {
        "id": "6c1339a6.f07a88",
        "type": "ui_tab",
        "name": "Het weer",
        "icon": "wb_sunny",
        "order": 7,
        "disabled": false,
        "hidden": false
    }
]

@jbudd . First, I am sorry to react to your answer so late. I had unforseen circumstances so that I could not work on my project.

I have looked at your solution, but I am poorly equiped with knowledge about the details of this solution.
That's why I have following questions,

  • About ui_template, how do I get the id of the template? Do I have to change the "type", "z" and "group" here also?

  • How do I get "id" and "tab" of ui_group?

  • How do I get "id" of ui_tab?

I know how I can get id of 1 ui_node by inspecting the object on the web page.

It would be much easier for me if the solution can be found with ui_control.

So when you looked at it, did you import that node into your flow, check that it is on the same UI tab as your wind rose?
Did it change the colour of the pointer or not?

I'm sorry, I have no idea why you would want the IDs of various entities.

It would be much easier for me if the solution can be found with ui_control

If you find a solution using ui_control, please share it with us.

@jbudd. Ok, I copied the code into a template node, I included this with <style> and </style> , but nothing happens.

Import
Untitled 1


Check tab is correct

Deploy
Untitled 4

@jbudd . Ok, understand now.Sorry.

It works ok, but I have more nodes in this group, so they all change.

afbeelding

1 Like

@jbudd . I think I am getting there by changing the properties of only this one ui_node. I will tell you later when I have more or less succeeded.......

@jbudd. I managed to get there. But I have 1 question left.
The 3th item I want to change is the size of the text field within the wind rose. I don't seem to get that.
See: svg.text.tspan , I guess that should be changed, but what ?
Here is the code + result so far,

<style>
/* Node: Windrichting  */
    [node-id="a1823158fae5bf4a"] path {
        fill: yellow;
    }
    [node-id="a1823158fae5bf4a"] p.label {
        margin-top: -0.8em; 
    }
    [node-id="a1823158fae5bf4a"] svg.text.tspan {
        font-size: 2.0em;
        font-weight: bold;
    }
</style>

afbeelding

Try this

[node-id="a1823158fae5bf4a"] svg text tspan {
        font-size: 2.0em;
        font-weight: bold;
    }

What's the difference? I removed the dots in svg.text.tspan ."text" and "tspan" are tags not classes.

@jbudd . Yes, working perfectly!!!!

Thanks, for me this result is ok. Thanks very much.

afbeelding

@jbudd The only thing left, is that the arrow of the windrose is not always in the right position. Mostly it is!!

Here is my flow for wind monitoring which may be of interest - some of the compass rose is unashamedly plagiarised from others! I think it fits in quite well with other standard gauges.
Arduino translates wind speed, direction etc. from Davis Instruments anemometer and sends via MQTT.
Only slight snag which I haven't solved is erratic behaviour of the compass needle when wind is light and coming from due north.

[{"id":"2dc5586d.f156e","type":"mqtt in","z":"18554eb.6ab9c31","name":"","topic":"wind/MPH","qos":"2","broker":"5f0a4eca.22adb","x":240,"y":650,"wires":[["5b747c02.dc324c","5fd31646.ee702","f155f5f8.b6eb98"]]},{"id":"5b747c02.dc324c","type":"smooth","z":"18554eb.6ab9c31","name":"Max gust","property":"payload","action":"max","count":"23000","round":"0","mult":"single","x":660,"y":710,"wires":[["7d35dead.d830f"]]},{"id":"5fd31646.ee702","type":"smooth","z":"18554eb.6ab9c31","name":"Short term gust","property":"payload","action":"max","count":"20","round":"0","mult":"single","x":660,"y":781,"wires":[["5ff6bd3b.417194"]]},{"id":"e78348c3.20ef8","type":"mqtt in","z":"18554eb.6ab9c31","name":"Wind Direction","topic":"wind/direction","qos":"2","broker":"5f0a4eca.22adb","x":140,"y":561,"wires":[["c00b4506.66ab7"]]},{"id":"c00b4506.66ab7","type":"function","z":"18554eb.6ab9c31","name":"Change payload to degrees:payload","func":"var msg = {\n  payload: {\n           degrees: msg.payload\n           }\n}\nreturn msg;","outputs":1,"noerr":0,"x":390,"y":561,"wires":[["ad14f1c.63bc71"]]},{"id":"3406c9b8.831766","type":"mqtt in","z":"18554eb.6ab9c31","name":"Beaufort","topic":"Force/Beaufort","qos":"2","broker":"5f0a4eca.22adb","x":140,"y":461,"wires":[["392b9cd8.44ac4c"]]},{"id":"bcee69d9.05de58","type":"function","z":"18554eb.6ab9c31","name":"Change payload to msg.Beaufort","func":"var msg = {\n  payload: {\n           Beaufort: msg.payload\n           }\n}\nreturn msg;","outputs":1,"noerr":0,"x":400,"y":521,"wires":[["ad14f1c.63bc71"]]},{"id":"ad14f1c.63bc71","type":"join","z":"18554eb.6ab9c31","name":"Combine Beaufort and Dir","mode":"custom","build":"merged","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":true,"timeout":"1","count":"2","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"","reduceFixup":"","x":720,"y":541,"wires":[["d606d45c.3cf448"]]},{"id":"392b9cd8.44ac4c","type":"change","z":"18554eb.6ab9c31","name":"Calm to CALM","rules":[{"t":"change","p":"payload","pt":"msg","from":"Calm","fromt":"str","to":"CALM","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":360,"y":460,"wires":[["bcee69d9.05de58"]]},{"id":"7d35dead.d830f","type":"ui_text","z":"18554eb.6ab9c31","group":"6549c513.6a736c","order":5,"width":3,"height":2,"name":"Max gust","label":" <font size=\"+1\">MAX GUST (24H)","format":" <font size=\"+1\">{{msg.payload}}mph","layout":"row-center","x":1020,"y":710,"wires":[]},{"id":"f155f5f8.b6eb98","type":"ui_gauge","z":"18554eb.6ab9c31","name":"Wind speed","group":"2609568d.f58f42","order":3,"width":6,"height":5,"gtype":"gage","title":"WIND SPEED","label":"MPH","format":"{{value|number:0}} ","min":0,"max":"60","colors":["#00b500","#e6e600","#ca3838"],"seg1":"","seg2":"","x":1010,"y":650,"wires":[]},{"id":"5ff6bd3b.417194","type":"ui_gauge","z":"18554eb.6ab9c31","name":"Gusts","group":"6549c513.6a736c","order":4,"width":3,"height":3,"gtype":"gage","title":"GUST","label":"MPH","format":"{{value|number:0}} ","min":0,"max":"60","colors":["#00ffff","#00ffff","#00ffff"],"seg1":"","seg2":"","x":1030,"y":781,"wires":[]},{"id":"d606d45c.3cf448","type":"ui_template","z":"18554eb.6ab9c31","group":"2609568d.f58f42","name":"Definitive compass rose","order":2,"width":6,"height":6,"format":"<!--\npass msg.payload.degrees, msg.payload.speed, msg.payload.speed_unit\n-->\n<link href=\"https://fonts.googleapis.com/css?family=Abel\" rel=\"stylesheet\"> \n\n\n\n<script>\n\n\n\n// Derive Beaufort from incoming message\n    (function(scope){\n        scope.$watch('msg', function(msg) {\n           if(typeof(msg) === \"object\"){\n               \n                var Beau = msg.payload.Beaufort;\n                \n                scope.Beaufort = Beau;\n                \n                \n                if(msg.payload.Beaufort  === \"CALM\"){\n                    scope.color = \"rgb(40,40,40)\";\n                }else{\n                    scope.color = \"rgb(200,0,0)\";\n                }\n                \n                \n                \n                \n         }\n    \t});\n    \t\n    \t\n    \t \n    \t\n    \t\n    \t\n    \t\n    \t\n    })(scope);\n\n\n\n     // Hacks to improve the layout and make it scale - not sure this works!!!\n    $(document).ready(function(){\n        setTimeout(function () {\n            // Remove the auto scrolling from the parent node\n            $(\".compass_container\").parent().css(\"overflow\",\"hidden\");\n        \n            // Adjust the color to match the theme base color by looking up the toolbar header background color;\n            //$(\".compass_container .triangle\").css(\"border-bottom-color\",$(\"md-toolbar\").css(\"background-color\"));\n            // Abandoned in favour of colour\n            //$(\".compass_container .compass_headerCENTERBLOB\").css(\"border-color\",$(\"md-toolbar\").css(\"background-color\"));\n            // Scale the compass into the box that it's being rendered in\n            // This CSS hack helps make sure the line & font size scales appropriately\n            // Based on the node's grid size\n            $(\".compass_container\").each(function(k,v){\n                var scaleWidth = $(v).parent().width() / $(v).width()/2;\n                var scaleHeight = $(v).parent().height() / $(v).height()/2;\n        \n                var translateX = ($(v).width() - $(v).parent().width());\n                var translateY = ($(v).height() - $(v).parent().height());\n        \n                $(v).css(\"transform\",\"translate(-\"+translateX+\"px,-\"+translateY+\"px) scale(\"+scaleWidth+\",\"+scaleHeight+\") \");\n            });\n            \n            $(\".compass_container\").css(\"display\",\"block\"); // Unhide it now that it's resized\n        }, 1000);\n    });\n</script>\n           \n<style>\n \n    \n      /*@import url(https://fonts.googleapis.com/css?family=Dosis:200,400,500,600);*/\n     \n     .compass_container{\n        display: none;\n        position: absolute;\n        top: 55px;\n        left: 60px;\n        border: 5px solid rgb(230,230,230);\n        margin: 0px;\n        width: 200px;\n        height: 200px;\n        border-radius: 50%;\n        font-family: 'Abel', sans-serif;\n        font-size: 80px;\n       \n        background-color: #202020;\n     }\n     \n     \n     .compass_container .fancy_border{\n        position: absolute;\n        width: 155%;\n        height: 155%;\n        left:-62px;\n        top: -58px;\n        border: 1px solid rgb(100,100,100);\n        border-radius: 3%;\n        position: absolute;\n        \n     }\n     \n     \n     \n     \n     \n     \n     \n     \n     .compass_container .compass_headerN{\n        font-weight: bold;\n        position: absolute;\n        text-align: center;\n        width: 100%;\n        font-size: 50%;\n        top: -62px\n     }\n     \n     .compass_container .compass_headerW{\n        font-weight: bold;\n        position: absolute;\n       \n        width: 100%;\n        font-size: 50%;\n        left: -55px;\n        top: 75px;\n     }\n     \n     .compass_container .compass_headerS{\n        font-weight: bold;\n        position: absolute;\n        text-align: center;\n        width: 100%;\n        font-size: 50%;\n        top: 205px\n     }\n     \n     .compass_container .compass_headerE{\n        font-weight: bold;\n        position: absolute;\n        \n        width: 100%;\n        font-size: 50%;\n        left: 220px;\n        top: 75px\n     }\n     \n     .compass_container .compass_headerNW{\n        font-weight: bold;\n        position: absolute;\n        \n        width: 100%;\n        font-size: 30%;\n        left: -20px;\n        top: 0px\n     }\n     \n     .compass_container .compass_headerNE{\n        font-weight: bold;\n        position: absolute;\n        \n        width: 100%;\n        font-size: 30%;\n        left: 190px;\n        top: 0px;\n     }\n     \n     .compass_container .compass_headerSW{\n        font-weight: bold;\n        position: absolute;\n        \n        width: 100%;\n        font-size: 30%;\n        left: -20px;\n        top: 175px;\n     }\n     \n     \n     \n     .compass_container .compass_headerSE{\n        font-weight: bold;\n        position: absolute;\n        \n        width: 100%;\n        font-size: 30%;\n        left: 190px;\n        top: 175px;\n     }\n     \n     \n     \n     \n     .compass_container .compass_headerCENTERBLOB{\n        border: 2px solid transparent;\n        border-radius: 50%;\n        background-color: solid green;/*nothing!*/\n        z-index: 2;\n        position: absolute;\n        height: 30%;\n        width: 30%;\n        left: 68px;\n        top: 68px;\n        \n     }\n     \n     \n     .compass_container .compass_headerCENTERTEXT{\n        border: 2px solid rgb(230,230,230);\n        border-radius: 50%;\n        background-color: solid green; /*doesnt do anything!*/\n        font-size: 30%;\n        font-weight: bold;\n        position: absolute;\n        z-index: 3;\n        display: flex;\n        flex-direction: column;\n        justify-content: center;\n        align-items: center;\n        \n        height: 30%;\n        width: 30%;\n        left: 68px;\n        top: 68px;\n     }\n     \n     \n     \n     \n     \n     \n   \n     \n     .compass_container .arrow{\n        transition: 2s ease-in-out;\n        \n        width: 100%;\n        height: 100%;\n        display: block;\n        position: absolute;\n        top: 0;\n        \n     }\n     \n     .compass_container .arrow .triangle{\n        box-sizing: border-box:\n        width: 500px;\n\t\theight: 100px;\n\t\tborder-left: 8px solid transparent;\n\t\tborder-right: 8px solid transparent;\n\t\t\n\t\tborder-top: 5px solid transparent;\n\t\tposition: absolute;\n\t\ttop: -120px;\n\t\tleft: 112px;\n\t\tmargin-left: -20px;\n\t\tz-index:1;\n\t\tborder-bottom: 86px solid {{color}};\n\t\t\n     }\n     \n</style>\n\n<div class=\"compass_container\" style=\"\">\n    <div class=\"fancy_border\"></div>\n    <div class=\"compass_headerN\">N</div>\n    <div class=\"compass_headerW\">W</div>\n    <div class=\"compass_headerS\">S</div>\n    <div class=\"compass_headerE\">E</div>\n    <div class=\"compass_headerNW\">NW</div>\n    <div class=\"compass_headerNE\">NE</div> \n    <div class=\"compass_headerSW\">SW</div>\n    <div class=\"compass_headerSE\">SE</div>\n    <div class=\"compass_headerCENTERBLOB\"></div>\n        \n    <div class=\"compass_headerCENTERTEXT\">{{Beaufort}}</div>\n \n    \n    \n    <div class=\"arrow\" style=\"transform: rotate({{msg.payload.degrees}}deg);\">\n      <div class=\"triangle\"></div>\n    </div>\n    \n</div>","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":false,"templateScope":"local","x":1030,"y":540,"wires":[[]]},{"id":"5f0a4eca.22adb","type":"mqtt-broker","name":"Pi MQTT","broker":"localhost","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","willTopic":"","willQos":"0","willPayload":""},{"id":"6549c513.6a736c","type":"ui_group","name":"HUMIDITY","tab":"2fc2582e.d3d21","order":2,"disp":false,"width":"3","collapse":false},{"id":"2609568d.f58f42","type":"ui_group","name":"WIND","tab":"2fc2582e.d3d21","order":4,"disp":false,"width":"6","collapse":false},{"id":"2fc2582e.d3d21","type":"ui_tab","name":"WEATHER AND UTILITIES","icon":"dashboard","order":1,"disabled":false,"hidden":false}]

@Spinky Thanks for your contribution, but I am sorry to say I get error report when trying to import your flow.

this one was discused last year.
If you try this nodes you must set some values in the function node.
I am getting my infos from open-weather-map

[{"id":"a588d0ce.e953b","type":"ui_template","z":"137e0d5c.29eb63","group":"86527ae3.76b328","name":"Kompas Herrsching","order":2,"width":"4","height":"4","format":"<div style=\"margin:auto\">\n<script src=\"/Canvas-Gauges/gauge.min.js\"></script>\n\n<canvas data-type=\"radial-gauge\"\n    data-width=\"180\"\n    data-height=\"180\"\n    data-min-value=\"0\"\n    data-max-value=\"360\"\n    data-major-ticks=\"N,NE,E,SE,S,SW,W,NW,N\"\n    data-minor-ticks=\"22\"\n    data-ticks-angle=\"360\"\n    data-start-angle=\"180\"\n    data-stroke-ticks=\"false\"\n    data-highlights=\"false\"\n    data-color-plate=\"#5E5E5E\"\n    data-color-major-ticks=\"#f5f5f5\"\n    data-color-minor-ticks=\"#ddd\"\n    data-color-numbers=\"#ccc\"\n    data-color-needle=\"rgba(240, 128, 128, 1)\"\n    data-color-needle-end=\"rgba(255, 160, 122, .9)\"\n    data-value-box=\"false\"\n    data-value-text-shadow=\"false\"\n    data-color-circle-inner=\"#fff\"\n    data-color-needle-circle-outer=\"#ccc\"\n    data-needle-circle-size=\"15\"\n    data-needle-circle-outer=\"false\"\n    data-needle-Type= \"line\"    \n    data-animation-rule=\"linear\"\n    data-needle-start=\"75\"\n    data-needle-end=\"99\"\n    data-needle-width=\"3\"\n    data-borders=\"true\"\n    data-border-inner-width=\"0\"\n    data-border-middle-width=\"0\"\n    data-border-outer-width=\"10\"\n    data-color-border-outer=\"#ccc\"\n    data-color-border-outer-end=\"#ccc\"\n    data-color-needle-shadow-down=\"#222\"\n    data-border-shadow-width=\"0\"\n    data-animation-duration=\"1500\"\n    data-color-Title = \"#f5f5f5\"\n    data-title = {{msg.title}}\n    data-value={{msg.payload}}\n></canvas>\n</div>","storeOutMessages":false,"fwdInMessages":false,"resendOnRefresh":false,"templateScope":"local","x":950,"y":1900,"wires":[[]]},{"id":"f21260a8.44b26","type":"function","z":"137e0d5c.29eb63","name":"","func":"let speed = flow.get('speed-H');\nlet direction = flow.get('direction-H');\nreturn{payload:direction, title:(speed + \" m/s\")}","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":760,"y":1900,"wires":[["a588d0ce.e953b"]]},{"id":"ec9d4a6a.5b3fd8","type":"inject","z":"137e0d5c.29eb63","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"1","crontab":"","once":true,"onceDelay":"3","topic":"","payload":"","payloadType":"date","x":580,"y":1900,"wires":[["f21260a8.44b26"]]},{"id":"86527ae3.76b328","type":"ui_group","name":"Herrsching","tab":"77f377a5.d96238","order":2,"disp":true,"width":"6","collapse":false},{"id":"77f377a5.d96238","type":"ui_tab","name":"Wetter","icon":"dashboard","order":4,"disabled":false,"hidden":false}]

@henkkas That's a shame - I did this about four years ago so will have a look to see if I can spot a problem.

@henkkas

I've edited @Spinky post so the flow imports fine now.

=====
In order to make code readable and usable it is necessary to surround your code with three backticks (also known as a left quote or backquote ```)

``` 
   code goes here 
```

You can edit and correct your post by clicking the pencil :pencil2: icon.

See this post for more details - How to share code or flow json