Auto shift tabs

#1

Hi, folks,

I've just started using Node red and get more and more exided!

My dashboard contains of multiple tabs with different data. There also a few tabs with external content.

I wonder, would it be possible to create automatic shift between the tabs to create some kind of slideshow running on public display, without user interaction?

Kind regards

o

0 Likes

#2

The ui control node can be sent messages to tell it to switch tabs. You could arrange to send it a sequence of messages to do what you want.

1 Like

#3

There is a working flow doing exaclly that in this thread:

0 Likes

#4

This is absolutly great!

But what if different client sould run different shows like:

Client1: Tab1, tab3, tab7
Client2: Tab1, tab4, tab5, tab6, tab7

Ola

0 Likes

#5

I can imagine a couple of different ways to modify the flow for that purpose as long as those users are not using a single instance of Node-RED at the same time, in which case they will visualize the same show.

0 Likes

#6

All accessing the same «node-red-box» so I need to identify the client in some way..

O

0 Likes

#7

Could they self-identify via a text input and if the username is validated, then it launches the proper flow sequence? In any case, this would work only if clients are not accessing at the same time. You can use the ui-control node to monitor when a client "disconnects" and stop the auto tab shifting and return to the login page.

0 Likes

#8

The fact this is possible is exactly why I love Node-RED. Right now I work with a school that has a display screen in their entrance hall, and it uses some arcane server software to pull from different sources and display various data (school blog, twitter, bbc news, etc.)

Unfortunately it's riddled with bugs and barely manageable, so I'm planning on implementing this in Node-RED :slight_smile:

0 Likes

#9

This modified flow is a step towards a better solution. It allows to configure several "show" sequences as well as to trigger them from the editor. Needs to be improved if the idea is to control the tirggering remotely.

[{"id":"21693521.376e0a","type":"tab","label":"UI Control - Dynamic Dashboard Sequencer","disabled":false,"info":""},{"id":"34bd023b.a1d64e","type":"ui_ui_control","z":"21693521.376e0a","name":"","x":1460,"y":180,"wires":[[]]},{"id":"bee4c199.34293","type":"function","z":"21693521.376e0a","name":"Engine","func":"let tabIndex = context.get(\"tabIndex\") || 0;\nlet tabs = msg.tabs;\n \nfunction selectNextTab() \n{\n\n    return tabs[tabIndex++] || (tabIndex=0, tabs[tabIndex++]); \n}\n\nmsg.payload =  {\"tab\" : selectNextTab()};\ncontext.set(\"tabIndex\", tabIndex);\nreturn msg;\n","outputs":1,"noerr":0,"x":1320,"y":180,"wires":[["34bd023b.a1d64e"]]},{"id":"40c3b995.f3baa8","type":"ui_ui_control","z":"21693521.376e0a","name":"","x":820,"y":320,"wires":[[]]},{"id":"c9448a6e.fdd638","type":"function","z":"21693521.376e0a","name":"Cycle","func":"let tabIndex = context.tabIndex || 0;\nlet tabs = flow.get(\"tabs\"); \n\nfunction selectNextTab() \n{\n    return tabs[tabIndex++] || (tabIndex=0, tabs[tabIndex++]); \n}\n\nmsg.payload =  {\"tab\" : selectNextTab()};\ncontext.tabIndex = tabIndex;\nreturn msg;\n","outputs":1,"noerr":0,"x":590,"y":320,"wires":[["c333d695.a60f58","40c3b995.f3baa8"]]},{"id":"c333d695.a60f58","type":"debug","z":"21693521.376e0a","name":"","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"payload","x":830,"y":360,"wires":[]},{"id":"bdf519b2.628e58","type":"trigger","z":"21693521.376e0a","op1":"","op2":"0","op1type":"date","op2type":"str","duration":"-5","extend":false,"units":"s","reset":"false","bytopic":"all","name":"","x":400,"y":320,"wires":[["c9448a6e.fdd638"]]},{"id":"5ca4169a.454768","type":"inject","z":"21693521.376e0a","name":"Stop Show","topic":"","payload":"false","payloadType":"bool","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":160,"y":340,"wires":[["bdf519b2.628e58"]]},{"id":"fd72ec38.49b46","type":"inject","z":"21693521.376e0a","name":"Start Show","topic":"","payload":"true","payloadType":"bool","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":160,"y":300,"wires":[["bdf519b2.628e58"]]},{"id":"d32f8ce6.1f1d9","type":"function","z":"21693521.376e0a","name":"Config","func":"tabConfig = {\n    \"111\" : [1,2,3],\n    \"222\" : [2,3,4],\n    \"333\" : [3,4,5]\n}\n\nlet tab = tabConfig[msg.payload];\nmsg.tab = tab;\nflow.set(\"tabs\", tab);\nreturn msg;","outputs":1,"noerr":0,"x":310,"y":160,"wires":[["656b4297.06ff5c"]]},{"id":"656b4297.06ff5c","type":"debug","z":"21693521.376e0a","name":"","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"tab","targetType":"msg","x":460,"y":160,"wires":[]},{"id":"ca753cf8.98de2","type":"inject","z":"21693521.376e0a","name":"User 2","topic":"","payload":"222","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":150,"y":160,"wires":[["d32f8ce6.1f1d9"]]},{"id":"892aa64c.dff488","type":"inject","z":"21693521.376e0a","name":"User 3","topic":"","payload":"333","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":150,"y":200,"wires":[["d32f8ce6.1f1d9"]]},{"id":"9f79c7b8.ad7f38","type":"inject","z":"21693521.376e0a","name":"User 1","topic":"","payload":"111","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":150,"y":120,"wires":[["d32f8ce6.1f1d9"]]}]
0 Likes

#10

the ui_control will report a socketid of a connecting client - commands sent back with the socketid intact will only go to that client - so you can direct things to a certain client... the trick of course is to associate the random socketid with the required screen.

(There is also socketip which shouldn't change so randomly - but it's the socketid that directs the messages.)

1 Like

#11

Hi,

I just found a way to do this. There is an extension for for Chrome called Tabulus Rotatum. This loads a set of tabs and switches from tab to tab after a configured pattern.

What's really nice is that the configuration can be loaded from web (node-red) http://127.0.0.1:1880/Clientname

By using this flow, a list can be set for each user/client.

[{"id":"61f08841.f4f7b8","type":"http in","z":"c7449229.fac738","name":"","url":"/ClientName","method":"get","upload":false,"swaggerDoc":"","x":270,"y":240,"wires":[["4eb76a2d.e1a624"]]},{"id":"4eb76a2d.e1a624","type":"template","z":"c7449229.fac738","name":"page","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"12;https://liveclock.net/\n10;https://h-a.no\n10;https://ibm.com\n10;https://aftenposten.no\n10;https://nrk.no","x":450,"y":240,"wires":[["93fbb579.e48588"]]},{"id":"93fbb579.e48588","type":"http response","z":"c7449229.fac738","name":"","x":590,"y":240,"wires":[]}]
```
2 Likes