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
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).
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:
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.
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.
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.
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
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.
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.
The audio out node is configured as follows:
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:
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
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.
This time we have added two columns for the properties risetime and duration. The output of which looks so.
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.
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.
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.
(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}]
沒有留言:
張貼留言