UIBuilder + Bootstrap.Vue.js - Visor de archivo de datos

Este flujo que utiliza UIBuilder y Bootstrap-Vue.js, permite mostrar en una interface grafica diferente del dashboard - node red, los datos de un archivo de texto plano que corresponden a una base de datos. Los datos incluyen fotos, tanto archivo de datos como carpeta de fotos se encuentran en Dropbox.

canariosinjectdropboxcsvfotoswitchimagebase64fotoiniciodropbox-------Canarios_prueba.txt------đź“” Fotos_canariosestructura regitro de datosanillo.color.anilloPadre.colorPadre.anilloMadre.colorMadre.sexo.observ.El servidor node red puede ejecutarse en un pc, tablet o celular.Para crear el cliente usamos UIBuilder y Bootstrap-Vue.jsEl cliente (interface grafica) se ejecuta en cualquier buscador que se ejecute en un pc, tablet o celular.Este visor de archivo es parte de un programa..El archivo de datos y la carpeta de fotos estan en Dropbox.debugDebe copiarse los archivos HTML y java.scripten el nodo UIBuilderHTMLjava.script
Flow 1
[{"id":"6b3b5a4ca30fa8d1","type":"uibuilder","z":"407037fe.d66c18","name":"canarios","topic":"","url":"canarios","fwdInMessages":false,"allowScripts":false,"allowStyles":false,"copyIndex":true,"templateFolder":"blank","extTemplate":"","showfolder":false,"useSecurity":false,"sessionLength":432000,"tokenAutoExtend":false,"reload":false,"sourceFolder":"src","x":920,"y":2700,"wires":[["724a6f422d9197af"],["fe59236a23dd2a55"]]},{"id":"8ddd458a28f28228","type":"inject","z":"407037fe.d66c18","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payloadType":"date","x":120,"y":2660,"wires":[["fe59236a23dd2a55"]]},{"id":"ef2b05656b7b80b2","type":"dropbox","z":"407037fe.d66c18","dropbox":"","filename":"","name":"","x":440,"y":2660,"wires":[["7cc23d93e8fc8991"]]},{"id":"51b86a7d3280ea93","type":"csv","z":"407037fe.d66c18","name":"","sep":".","hdrin":true,"hdrout":"none","multi":"mult","ret":"\\n","temp":"","skip":"0","strings":false,"include_empty_strings":"","include_null_values":true,"x":750,"y":2660,"wires":[["6b3b5a4ca30fa8d1"]]},{"id":"724a6f422d9197af","type":"function","z":"407037fe.d66c18","name":"foto","func":"msg.filename = \"Fotos_canarios/\" + msg.payload.substring(0,11) + \".jpg\";\nmsg.topic = \"foto\";\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1050,"y":2600,"wires":[["ef2b05656b7b80b2","9bec5b69e6044f55"]]},{"id":"7cc23d93e8fc8991","type":"switch","z":"407037fe.d66c18","name":"","property":"topic","propertyType":"msg","rules":[{"t":"eq","v":"canarios","vt":"str"},{"t":"eq","v":"foto","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":590,"y":2660,"wires":[["51b86a7d3280ea93"],["0bead597eb2bcf95"]]},{"id":"056ad493a150398f","type":"image","z":"407037fe.d66c18","name":"","width":160,"data":"payload","dataType":"msg","thumbnail":false,"active":true,"pass":false,"outputs":0,"x":700,"y":2800,"wires":[]},{"id":"0bead597eb2bcf95","type":"base64","z":"407037fe.d66c18","name":"","action":"","property":"payload","x":600,"y":2740,"wires":[["7d63d45a1939e97c","056ad493a150398f"]]},{"id":"7d63d45a1939e97c","type":"change","z":"407037fe.d66c18","name":"foto","rules":[{"t":"change","p":"payload","pt":"msg","from":"^(.*)$","fromt":"re","to":"data:image/x-icon;base64,$1","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":750,"y":2740,"wires":[["6b3b5a4ca30fa8d1"]]},{"id":"fe59236a23dd2a55","type":"change","z":"407037fe.d66c18","name":"inicio","rules":[{"t":"set","p":"filename","pt":"msg","to":"Canarios_prueba.txt","tot":"str"},{"t":"set","p":"topic","pt":"msg","to":"canarios","tot":"str"},{"t":"delete","p":"uibuilderCtrl","pt":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":290,"y":2720,"wires":[["ef2b05656b7b80b2"]]},{"id":"dbee40e9add316c9","type":"comment","z":"407037fe.d66c18","name":"dropbox \\n -------Canarios_prueba.txt \\n ------đź“” Fotos_canarios","info":"","x":250,"y":3060,"wires":[]},{"id":"42ab4aefa7146bea","type":"comment","z":"407037fe.d66c18","name":"estructura regitro de datos \\n anillo.color.anilloPadre.colorPadre.anilloMadre.colorMadre.sexo.observ.","info":"","x":390,"y":3140,"wires":[]},{"id":"6391626a850ffa53","type":"comment","z":"407037fe.d66c18","name":"El servidor node red puede ejecutarse en un pc, tablet o celular. \\n Para crear el cliente usamos UIBuilder y Bootstrap-Vue.js \\n El cliente (interface grafica) se ejecuta en cualquier buscador que se ejecute en un pc, tablet o celular.\\n Este visor de archivo es parte de un programa..\\n El archivo de datos y la carpeta de fotos estan en Dropbox.","info":"","x":490,"y":2940,"wires":[]},{"id":"9bec5b69e6044f55","type":"debug","z":"407037fe.d66c18","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1150,"y":2820,"wires":[]},{"id":"118d9cdada1cc1b9","type":"comment","z":"407037fe.d66c18","name":"Debe copiarse los archivos HTML y java.script \\n en el nodo UIBuilder ","info":"","x":1226,"y":2924,"wires":[]},{"id":"8bfa92dfedddc57d","type":"comment","z":"407037fe.d66c18","name":"HTML","info":"<!doctype html><html lang=\"en\"><head>\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n    \n    <link type=\"text/css\" rel=\"stylesheet\" href=\"../uibuilder/vendor/bootstrap/dist/css/bootstrap.min.css\" />\n    <link type=\"text/css\" rel=\"stylesheet\" href=\"../uibuilder/vendor/bootstrap-vue@latest/dist/bootstrap-vue.css\" />\n\n    <link rel=\"icon\" href=\"./images/node-blue.ico\">\n    <link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/npm/bootstrap-icons@1.8.1/font/bootstrap-icons.css\">\n\n    <!-- Put your own custom styles in here -->\n    <link rel=\"stylesheet\" href=\"./index.css\" media=\"all\">\n\n</head><body>\n    \n   <div id=\"app\">\n\t<b-container id=\"app_container\">\n\n    <b-navbar toggleable=\"lg\" type=\"dark\" variant=\"info\">\n    <b-navbar-brand href=\"#\"><img src=\"/home/pi/el_asistente.jpg\" width=\"30\" height=\"30\">  el_asistente</b-navbar-brand>\n\n    <b-navbar-toggle target=\"nav-collapse\"></b-navbar-toggle>\n\n    </b-navbar>\n    <template>\n\t  <div>\n        <b-table striped hover margin :items=\"itemsCanarios\" selectable @row-selected=\"onRowSelected\" :fields=\"fieldsCan\" style=\"background: rgb(255, 255, 255); font-size: 10px;\">\n          <template #cell(sexo)=\"data\">\n            <span v-html=\"data.value\"></span>\n          </template>\n        </b-table>\n      </div>\n    </template>\n\n\t<b-modal v-model=\"showCanario\" hide-footer>\n      <div class=\"card\" v-for=\"select in selected\">\n        <img v-if=\"foto !== ''\" class=\"card-img-top\" :src=\"foto\">\n        <div class=\"card-header\">\n          <h4 class=\"card-title\">{{select.anillo}}</h4>\n          <h5 class=\"card-title\">{{select.color}}</h5>\n        </div>\n        <div class=\"card-body\">\n            <h5 class=\"card-text\"><i class=\"bi bi-gender-male\"></i> Padre</h5>\n            <p class=\"card-text\">{{select.anilloPadre}}</p>\n            <p class=\"card-text\">{{select.colorPadre}}</p>\n            <p></p>\n            <h5 class=\"card-text\"><i class=\"bi bi-gender-female\"></i> Madre</h5>\n            <p class=\"card-text\">{{select.anilloMadre}}</p>\n            <p class=\"card-text\">{{select.colorMadre}}</p>\n            <p></p>\n            <h5 class=\"mb-0\">{{select.sexo}}</h5>\n        </div>\n      </div>\n    </b-modal>\n    \n      </b-container>\n    </div>\n\n    <!-- Vendor Libraries - Load in the right order -->\n    <script src=\"../uibuilder/vendor/socket.io/socket.io.js\"></script>\n    <script src=\"../uibuilder/vendor/vue/dist/vue.min.js\"></script>\n    \n    <script src=\"../uibuilder/vendor/bootstrap-vue/dist/bootstrap-vue.js\"></script>\n    <script src=\"../uibuilder/vendor/http-vue-loader/src/httpVueLoader.js\"></script>\n    <script src=\"../uibuilder/vendor/vuex/dist/vuex.js\"></script>\n\n    <!-- REQUIRED: Sets up Socket listeners, the uibuilder and msg objects -->\n    <script src=\"./uibuilderfe.min.js\"></script>\n\n    <!-- Put your own custom code in here -->\n    <script src=\"./index.js\"></script>\n\n</body></html>","x":1210,"y":2660,"wires":[]},{"id":"fd1fe1b09ede3af8","type":"comment","z":"407037fe.d66c18","name":"java.script","info":"/* jshint browser: true, esversion: 5, asi: true */\n/*globals Vue, uibuilder */\n// @ts-nocheck\n/*\n  Built on the great foundational work of others, free to use, but at your own risk\n*/\n'use strict'\n\n/** @see https://github.com/TotallyInformation/node-red-contrib-uibuilder/wiki/Front-End-Library---available-properties-and-methods */\n\n// eslint-disable-next-line no-unused-vars\nvar app1 = new Vue({\n    el: '#app',\n    data: {\n        foto : '',\n        showCanario : false,\n        itemsCanarios : [],\n        fieldsCanarios : [\n            {   key: 'anillo', label: 'Anillo Canario', class: 'border-right text-center',},\n            {   key: 'color', label: 'Color Canario', class: 'border-right text-center',},\n            {   key: 'anilloPadre', label: 'Anillo Padre', class: 'border-right text-center',},\n            {   key: 'colorPadre', label: 'Color Padre', class: 'border-right text-center',},\n            {   key: 'anilloMadre', label: 'Anillo Madre', class: 'border-right text-center',},\n            {   key: 'colorMadre', label: 'Color Madre', class: 'border-right text-center',},\n            {   key: 'sexo', label: 'Sexo', class: 'border-right text-center',},\n        ],\n        fieldsCan : [\n            {   key: 'sexo', label: 'Sexo', class: 'text-center', formatter: value => {\n              if(value == 'M'){return '<img src=\"/home/pi/Macho.jpg\" width=\"20\" height=\"20\">';}\n              else{return '<img src=\"/home/pi/Hembra.jpg\" width=\"20\" height=\"20\">';}\n            }},\n            {   key: 'anillo', label: 'Anillo', class: 'text-center',},\n            {   key: 'color', label: 'Color', class: 'text-center',},\n        ],\n        selected : []\n    }, // --- End of data --- //\n    // computed: dynamic data, used as {{ cName }} - cached\n    computed: {\n    }, // --- End of computed --- //\n    // methods:\n    methods: {\n        onRowSelected(canario) {\n            this.selected = canario\n            this.showCanario = true\n            uibuilder.send({'topic':'foto','payload':this.selected[0].anillo})\n        },\n        // return formatted HTML version of JSON object\n        syntaxHighlight: function(json) {\n            json = JSON.stringify(json, undefined, 4)\n            json = json.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');\n            return json.replace(/(\"(\\\\u[a-zA-Z0-9]{4}|\\\\[^u]|[^\\\\\"])*\"(\\s*:)?|\\b(true|false|null)\\b|-?\\d+(?:\\.\\d*)?(?:[eE][+\\-]?\\d+)?)/g, function (match) {\n                var cls = 'number'\n                if (/^\"/.test(match)) {\n                    if (/:$/.test(match)) {\n                        cls = 'key'\n                    } else {\n                        cls = 'string'\n                    }\n                } else if (/true|false/.test(match)) {\n                    cls = 'boolean'\n                } else if (/null/.test(match)) {\n                    cls = 'null'\n                }\n                return '<span class=\"' + cls + '\">' + match + '</span>'\n            })\n        } // --- End of syntaxHighlight --- //\n\n    }, // --- End of methods --- //\n\n    // Available hooks: init,mounted,updated,destroyed\n    mounted: function(){\n        uibuilder.start()\n\n        var vueApp = this\n        \n        vueApp.feVersion = uibuilder.get('version')\n\n        // Start countdown. If lastUpdate not updated in 2 minutes, show a warning.\n    //    vueApp.hTimer = vueApp.heatingUpdTimer()\n\n        // On-load Reset the current tab to the one saved in session storage - strange, stored as number but retrieves as a string\n    //    vueApp.tabIndex =  Number(sessionStorage.currentTab)\n\n        // If msg changes - msg is updated when a standard msg is received from Node-RED over Socket.IO\n        // Note that you can also listen for 'msgsReceived' as they are updated at the same time\n        // but newVal relates to the attribute being listened to.\n        uibuilder.onChange('msg', function(newVal){\n            //console.debug('Vue:mounted:UIBUILDER: property msg changed! ', newVal)\n            if(newVal.topic == 'canarios'){\n                vueApp.itemsCanarios = newVal.payload\n            }\n             else if(msg.topic == 'foto'){\n                vueApp.foto = msg.payload;\n                this.showCanario = true\n             }\n        }) // ---- End of uibuilder.onChange() watcher function ---- //\n\n    } // --- End of mounted hook --- //\n\n}) // --- End of app1 --- //\n\n// EOF","x":1220,"y":2700,"wires":[]}]

Flow Info

Created 3 years, 3 months ago
Rating: not yet rated

Owner

Actions

Node Types

Core
  • change (x2)
  • comment (x6)
  • csv (x1)
  • debug (x1)
  • function (x1)
  • inject (x1)
  • switch (x1)
Other

Tags

  • uibuilder
  • dropbox
Copy this flow JSON to your clipboard and then import into Node-RED using the Import From > Clipboard (Ctrl-I) menu option