2021年10月15日 星期五

Node-Red 使用 UI Dashboard Tables 節點

 Node-Red 使用 UI Dashboard Tables 節點

參考來源https://bloggedin.co.uk/creating-tables-in-node-red/

 







http://api.open-notify.org/astros.json

{"message": "success", "number": 10, "people": [{"craft": "ISS", "name": "Mark Vande Hei"}, {"craft": "ISS", "name": "Oleg Novitskiy"}, {"craft": "ISS", "name": "Pyotr Dubrov"}, {"craft": "ISS", "name": "Thomas Pesquet"}, {"craft": "ISS", "name": "Megan McArthur"}, {"craft": "ISS", "name": "Shane Kimbrough"}, {"craft": "ISS", "name": "Akihiko Hoshide"}, {"craft": "ISS", "name": "Anton Shkaplerov"}, {"craft": "ISS", "name": "Klim Shipenko"}, {"craft": "ISS", "name": "Yulia Pereslid"}]}

 

http://api.open-notify.org/iss-pass.json?lat=53.391991&lon=-3.178860

{
  "message": "success", 
  "request": {
    "altitude": 100, 
    "datetime": 1634301753, 
    "latitude": 53.391991, 
    "longitude": -3.17886, 
    "passes": 5
  }, 
  "response": [
    {
      "duration": 630, 
      "risetime": 1634305257
    }, 
    {
      "duration": 500, 
      "risetime": 1634311086
    }, 
    {
      "duration": 548, 
      "risetime": 1634371510
    }, 
    {
      "duration": 640, 
      "risetime": 1634377235
    }, 
    {
      "duration": 653, 
      "risetime": 1634383026
    }
  ]
}

 

var data = [

            {

                "name":"Dave",

                "age":35,

                "favourite colour":"red",

                "star rating": 3,

                "progress": "75",

                "traffic": 32

            },

            {

                "name":"Fred",

                "age":45,

                "favourite colour":"orange",

                "star rating": 5,

                "progress": "50",

                "traffic": 65

            },

            {

                "name":"Jane",

                "age":32,

                "favourite colour":"yellow",

                "star rating": 4,

                "progress": "98",

                "traffic": 84

            }

            ];

msg.payload = data;

           

           

return msg;

 

Example 1 with added sound, well just because we can

Diagram

Description automatically generated

In this flow I have added in some additional unnecessary items to improve the operation, such as a button I can use to refresh the table. For some quirky fun I have also thrown in an audio out to read out our table.

As always we have a simple timestamp at the start so that we can manually trigger the flow, I also have placed a button here as the UI exists on another address from your flow so it just makes it easier to trigger the flow when viewing the output screen.

UI nodes must be added to a group on your dashboard, you can do this by using the pencil to edit and assign a group name (for UI’s further groups can be made on the same page to separate out widgets). 

Graphical user interface, text, application, email

Description automatically generated

We have created a group called crew for our UI widgets. Next, we need some data, for our simple table I thought it would be good to get some real world data via an API (one we have used before as we know it returns JSON) http://api.open-notify.org/astros.json. To acquire the data, we need to send a GET request to the API and to do this we use a http request node with the following configuration:

Graphical user interface, text, application

Description automatically generated

Note we have set the node to return a parsed JSON object. If you pass the output of this node to a debug node, we can see the data structure.

A picture containing graphical user interface

Description automatically generated

Picking out the array from the payload

Because we need an array for the table node, we are only interested in the “people” part of the payload. To isolate the data returned we need a function node.

Graphical user interface, text, application, email

Description automatically generated

This function is simply reducing the payload down to the array we want, which we can now pass directly into the table node. If you look back at our JSON output we have 7 objects in the array addressable by craft and name, it is the latter we shall add to our table.

Graphical user interface

Description automatically generated

The table UI node also has to be assigned to your group to show on the UI dashboard, I have changed the size on this node too as they default to auto which sometimes hides the full view of the table. The key part to this node configuration is the add button at the bottom of the node. We use this button to add references for our columns that match the object name in our JSON array item. In this case we add name to the property and the title is free to customise. 

With no other settings adjusted the output on the dashboard (<yourIP>:1880/ui) should look like the following once deployed:

The result

Graphical user interface, text, application, table

Description automatically generated

How to add the sound

If at this stage you have never used the audio out and would like the table read out the data, the following nodes can be added onto the “get crew array” function.

Diagram

Description automatically generated

In the function node we have a little JavaScript to loop over the names and assign them to a new payload which we pass in during a loop execution.

Graphical user interface, text, application

Description automatically generated

The audio out node is configured as follows:

Graphical user interface, application, email

Description automatically generated

Note it is also assigned to the same group and you can choose different languages / voices should you wish to.

Example 2 a table of ISS fly overs

Let us look at a second example that requires some data to be formatted prior to being cast into the table. For this we will use the following flow:

A screenshot of a computer

Description automatically generated with medium confidence

In the request we shall use another of the open notify API’s

http://api.open-notify.org/iss-pass.json?lat=53.391991&lon=-3.178860 (note this API uses latitude and longitude values as part of the URL, it is best to search for your values if you are reproducing this example). This API returns data relating to the passover times of the International Space Station, but the data typically returns time in a Unix reference.

Note that the data we are interested in resides in the response part of the JSON and for completion we need to format that date stamp for our table. We can grab the data we want and format the time stamp in one function.

Making sense of Unix time stamps with JavaScript

Graphical user interface, text, application

Description automatically generated

With this JavaScript we are essentially assigning the response of the existing payload into the current payload, we then iterate over this and convert the time to a human readable format before re-assigning it back to the risetime of the payload.

With the data collected and processed we pass it into a UI table.

Graphical user interface

Description automatically generated

This time we have added two columns for the properties risetime and duration. The output of which looks so.

Table

Description automatically generated

Flow export

[{"id":"945bff71.1f7588","type":"http request","z":"47e6e479.ba7bec","name":"","method":"GET","ret":"obj","paytoqs":"ignore","url":"http://api.open-notify.org/iss-pass.json?lat=53.391991&lon=-3.178860","tls":"","persist":false,"proxy":"","authType":"","x":330,"y":520,"wires":[["d9cbeaf9.84d6"]]},{"id":"3592a600.0d5e6a","type":"inject","z":"47e6e479.ba7bec","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":140,"y":560,"wires":[["945bff71.1f7588"]]},{"id":"d9cbeaf9.84d6","type":"function","z":"47e6e479.ba7bec","name":"","func":"\nmsg.payload = msg.payload.response;\nfor (var i = 0; i < msg.payload.length; i++)\n{\n    var toconvert = msg.payload[i].risetime;\n    \n    var milliseconds = toconvert * 1000;\n    var dateObject = new Date(milliseconds)\n    var humanDateFormat = dateObject.toLocaleString() \n    formattedDate = humanDateFormat;\n    msg.payload[i].risetime = formattedDate;\n    \n}\n\nreturn msg;\n","outputs":1,"noerr":0,"initialize":"","finalize":"","x":500,"y":520,"wires":[["c98a9c0a.2fbcc"]]},{"id":"c98a9c0a.2fbcc","type":"ui_table","z":"47e6e479.ba7bec","group":"b6426123.0e6ec8","name":"ISS Flyovers","order":1,"width":"6","height":"6","columns":[{"field":"risetime","title":"Risetime","width":"","align":"left","formatter":"plaintext","formatterParams":{"target":"_blank"}},{"field":"duration","title":"Duration","width":"","align":"left","formatter":"plaintext","formatterParams":{"target":"_blank"}}],"outputs":0,"cts":false,"x":690,"y":520,"wires":[]},{"id":"f16c17a8.22b53","type":"ui_button","z":"47e6e479.ba7bec","name":"","group":"b6426123.0e6ec8","order":2,"width":0,"height":0,"passthru":false,"label":"Update Flyovers","tooltip":"","color":"","bgcolor":"","icon":"","payload":"","payloadType":"date","topic":"topic","topicType":"msg","x":120,"y":500,"wires":[["945bff71.1f7588"]]},{"id":"b6426123.0e6ec8","type":"ui_group","name":"Fly Overs","tab":"bc4280d7.6fb1e8","order":2,"disp":true,"width":"6","collapse":false},{"id":"bc4280d7.6fb1e8","type":"ui_tab","name":"Flyovers","icon":"dashboard","disabled":false,"hidden":false}]

Nothing fancy so far, let’s see what this node can really do

So far we have produced a nice sortable table in the UI. However, this node is capable of much more let us look at a further example and dig a little deeper into the column settings we can configure for the table.

A picture containing timeline

Description automatically generated

Making JSON array

This time we won’t use an API and create our own data for the table, all of which is done in the function node.

A picture containing text

Description automatically generated

With a little JavaScript we have created a JSON of our own which acts as our array for the table node. As you can see from the data structure, we have 6 fields of data per entry for which we will need to add 6 columns to the table.

Fancy formatting inside a table?

This is where the table UI node can shine, there are different ways of showing our tabulated data for the columns to make the table more at home on a dashboard rather than just a sortable table.

The first two columns for name and age are left as plain text like our previous examples, however for the favourite colour, star rating, progress and traffic we can explore the other features.

By changing the drop down for format, we can express the data in the table so that colours are rendered (works for standard HTML named colours or hex refs). Star rating is shown like star ratings on a website, progress is akin to a progress bar and the traffic shows up as a traffic light based on the limit values.

Chart, waterfall chart

Description automatically generated

(note I have increased the size properties of the widget to show a larger table).

Now this is a fantastic way of presenting data as opposed to your traditional tables and relatively easy to set up too.

[{"id":"4a861da0.4af1e4","type":"inject","z":"47e6e479.ba7bec","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":160,"y":740,"wires":[["74a7dfd2.11eca8"]]},{"id":"74a7dfd2.11eca8","type":"function","z":"47e6e479.ba7bec","name":"","func":"var data = [\n            {\n                \"name\":\"Dave\",\n                \"age\":35,\n                \"favourite colour\":\"red\",\n                \"star rating\": 3,\n                \"progress\": \"75\",\n                \"traffic\": 32\n            },\n            {\n                \"name\":\"Fred\",\n                \"age\":45,\n                \"favourite colour\":\"orange\",\n                \"star rating\": 5,\n                \"progress\": \"50\",\n                \"traffic\": 65\n            },\n            {\n                \"name\":\"Jane\",\n                \"age\":32,\n                \"favourite colour\":\"yellow\",\n                \"star rating\": 4,\n                \"progress\": \"98\",\n                \"traffic\": 84\n            }\n            ];\nmsg.payload = data;\n            \n            \nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":420,"y":680,"wires":[["7c73928f.f46d94"]]},{"id":"7c73928f.f46d94","type":"ui_table","z":"47e6e479.ba7bec","group":"d1e1d0fe.3493f8","name":"","order":1,"width":"12","height":"6","columns":[{"field":"name","title":"Name","width":"","align":"left","formatter":"plaintext","formatterParams":{"target":"_blank"}},{"field":"age","title":"Age","width":"","align":"left","formatter":"plaintext","formatterParams":{"target":"_blank"}},{"field":"favourite colour","title":"Favourite Colour","width":"","align":"left","formatter":"color","formatterParams":{"target":"_blank"}},{"field":"star rating","title":"Rating","width":"","align":"left","formatter":"star","formatterParams":{"target":"_blank"}},{"field":"progress","title":"Progress","width":"","align":"left","formatter":"progress","formatterParams":{"target":"_blank"}},{"field":"traffic","title":"Traffic Light","width":"","align":"center","formatter":"traffic","formatterParams":{"target":"_blank"}}],"outputs":0,"cts":false,"x":690,"y":680,"wires":[]},{"id":"a1de758b.9ffcf","type":"ui_button","z":"47e6e479.ba7bec","name":"","group":"d1e1d0fe.3493f8","order":2,"width":0,"height":0,"passthru":false,"label":"Update table","tooltip":"","color":"","bgcolor":"","icon":"","payload":"","payloadType":"str","topic":"topic","topicType":"msg","x":140,"y":640,"wires":[["74a7dfd2.11eca8"]]},{"id":"d1e1d0fe.3493f8","type":"ui_group","name":"Table Example","tab":"f64eb6be.3adcd8","order":1,"disp":true,"width":"12","collapse":false},{"id":"f64eb6be.3adcd8","type":"ui_tab","name":"Table Example","icon":"dashboard","disabled":false,"hidden":false}]

沒有留言:

張貼留言

Messaging API作為替代方案

  LINE超好用功能要沒了!LINE Notify明年3月底終止服務,有什麼替代方案? LINE Notify將於2025年3月31日結束服務,官方建議改用Messaging API作為替代方案。 //CHANNEL_ACCESS_TOKEN = 'Messaging ...