-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdemo-vue.html
105 lines (87 loc) · 17.4 KB
/
demo-vue.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>FlowFuse Flow Renderer</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
div.flow-renderer {
width: 100%;
height: 320px;
}
#nr-flow-3 {
width: 100%;
height: 320px;
}
h1, h2, h3, h4, h5 {
margin-top: 20px;
margin-bottom: 4px;
}
</style>
</head>
<body>
<h3>FlowFuse Flow Renderer</h3>
<div>Vue client side demo</div>
<hr>
<div id="app">
<!-- Add a multi-line input with mono font for the user to paste flow -->
<h3>Node-RED Flow</h3>
<textarea v-model="dataFlowJson" rows="6" style="font-family: monospace; width: 100%;"> </textarea>
<br>
<button @click="render()">Render Flows</button>
<button @click="render([])">Clear Flows</button>
<br>
<!-- Demo 1 -->
<h4>Render (grid, images, labels)</h4>
<div ref="f1" class="flow-renderer"></div>
<!-- Demo 2 -->
<h4>Render (no grid, no images, labels)</h4>
<div ref="f2" class="different-class" style="width: auto; height: 320px;"></div>
<!-- Demo 3 -->
<h4>Render (no grid, images, no labels, no auto layout) using data-options</h4>
<div ref="f3" id="nr-flow-3" data-grid-lines="false" data-labels="false" data-images data-auto-zoom="false" data-auto-scroll="false"></div>
</div>
<script type="module">
import { createApp } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js'
// import './index.js'
import FlowRenderer from './index.min.js'
createApp({
mounted() {
this.demoFlow = [{ "id": "6f432348c57a2fda", "type": "tab", "label": "Acme Office Monitoring", "disabled": false, "info": "", "env": [] }, { "id": "d15519de378451ae", "type": "tab", "label": "Sys Info Gathering", "disabled": false, "info": "", "env": [] }, { "id": "mqtt-topic-filter", "type": "subflow", "name": "topic filter", "info": "## MQTT Topic filter\n\n### Description\nFilters messages based on the value of `msg.topic` using standard MQTT topic filter notation.\n* `#` match all\n* `+` match one level\n\n### example filters\n* `home/+/temperature` \n * will match `home/bedroom/temperature`\n * will match `home/livingroom/temperature`\n * will not match `home/room/1/temperature`\n * will not match `room/1/temperature`\n* `home/#` \n * will match `home/location`\n * will match `home/livingroom/temperature`\n * will match `home/livingroom/humidity`\n * will not match `room/1/temperature`\n\n\n### Outputs\n\n#### Output 1 - match\nMessages with a topic that matches the `topic filter` will be sent out this output.\n\n#### Output 2 - no match\nMessages with a topic that does not match the `topic filter` will be sent out this output to permit next level filtering\n", "category": "function", "in": [{ "x": 68, "y": 80, "wires": [{ "id": "c7fc11c3.07902" }] }], "out": [{ "x": 340, "y": 48, "wires": [{ "id": "c7fc11c3.07902", "port": 0 }] }, { "x": 340, "y": 96, "wires": [{ "id": "c7fc11c3.07902", "port": 1 }] }], "env": [{ "name": "filter", "type": "str", "value": "", "ui": { "label": { "en-US": "Topic filter" }, "type": "input", "opts": { "types": ["str"] } } }, { "name": "status", "type": "bool", "value": "true", "ui": { "label": { "en-US": "Show topic" }, "type": "input", "opts": { "types": ["bool"] } } }], "meta": { "type": "mqtt-topic-filter", "version": "1.0.0", "author": "steve-mcl", "desc": "A node to filter MQTT topics", "keywords": "mqtt", "license": "MIT" }, "color": "#D8BFD8", "outputLabels": ["Match", "No Match"], "icon": "font-awesome/fa-filter", "status": { "x": 548, "y": 160, "wires": [{ "id": "519579c5.dfaec8", "port": 0 }, { "id": "4ce4687e.e359a8", "port": 0 }] } }, { "id": "3f7d1b85b6df80e7", "type": "group", "z": "6f432348c57a2fda", "name": "Sub-1", "style": { "stroke": "#3f93cf", "fill": "#bfdbef", "label": true }, "nodes": ["4d7649516480dcd6", "b2ac43ee25b5d22e", "9550399dd7be7346"], "x": 364, "y": 159, "w": 462, "h": 82 }, { "id": "bc14e4582a115cd6", "type": "junction", "z": "6f432348c57a2fda", "x": 360, "y": 120, "wires": [["8abe21f57db87496"]] }, { "id": "8abe21f57db87496", "type": "junction", "z": "6f432348c57a2fda", "x": 500, "y": 120, "wires": [["a570708c83589e95"]] }, { "id": "d7260e109d996e74", "type": "mqtt-broker", "name": "", "broker": "localhost", "port": "1883", "clientid": "", "autoConnect": true, "usetls": false, "protocolVersion": "5", "keepalive": "60", "cleansession": true, "autoUnsubscribe": true, "birthTopic": "", "birthQos": "0", "birthRetain": "false", "birthPayload": "", "birthMsg": {}, "closeTopic": "", "closeQos": "0", "closeRetain": "false", "closePayload": "", "closeMsg": {}, "willTopic": "", "willQos": "0", "willRetain": "false", "willPayload": "", "willMsg": {}, "userProps": "", "sessionExpiry": "" }, { "id": "c7fc11c3.07902", "type": "function", "z": "mqtt-topic-filter", "name": "filter", "func": "var a = msg.topic;\nvar b = env.get(\"filter\") || '#';\n\nif(a===b) { return [msg, null]; }\nif(b==='#') { \n if(a) return [msg, null]; //if topic is something, OK\n return [null, msg];//otherwise, fail!\n}\nvar nameSegments = a.split('/');\nvar filterSegments = b.split('/');\nfor (var i = 0; i < filterSegments.length; i++) {\n var topicSegment = nameSegments[i];\n var patternSegment = filterSegments[i];\n var match = false;\n if(topicSegment === patternSegment) { match = true; }\n if(patternSegment === '+') { match = true; }\n if(patternSegment === '#') { return [msg, null]; }\n if(match === false) { return [null, msg]; }\n}\nif(nameSegments.length !== filterSegments.length) { return [null, msg]; }\n\nreturn [msg, null];\n", "outputs": 2, "noerr": 0, "initialize": "", "finalize": "", "x": 192, "y": 80, "wires": [[], []] }, { "id": "c52c30b1.8341", "type": "inject", "z": "mqtt-topic-filter", "name": "", "props": [{ "p": "payload" }, { "p": "topic", "vt": "str" }], "repeat": "", "crontab": "", "once": true, "onceDelay": 0.1, "topic": "", "payload": "", "payloadType": "date", "x": 148, "y": 160, "wires": [["45ee843e.ec4bbc"]] }, { "id": "519579c5.dfaec8", "type": "function", "z": "mqtt-topic-filter", "name": "", "func": "var b = env.get(\"filter\") || '#';\nnode.status({text:b})\nmsg.payload = b;\nreturn msg;", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "x": 428, "y": 144, "wires": [[]] }, { "id": "45ee843e.ec4bbc", "type": "switch", "z": "mqtt-topic-filter", "name": "", "property": "status", "propertyType": "env", "rules": [{ "t": "true" }, { "t": "else" }], "checkall": "true", "repair": false, "outputs": 2, "x": 290, "y": 160, "wires": [["519579c5.dfaec8"], ["4ce4687e.e359a8"]] }, { "id": "4ce4687e.e359a8", "type": "function", "z": "mqtt-topic-filter", "name": "", "func": "node.status({})\ndelete msg.payload;\nreturn msg;", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "x": 428, "y": 192, "wires": [[]] }, { "id": "e6fdc46c489b1907", "type": "subflow:mqtt-topic-filter", "z": "6f432348c57a2fda", "name": "topic filter: acme/office/+/temperature", "env": [{ "name": "filter", "value": "acme/office/+/temperature", "type": "str" }], "x": 910, "y": 40, "wires": [["bc9be11156983084"], ["90ea33ea087b52a9"]] }, { "id": "a89d83ca0c1d8eae", "type": "subflow:mqtt-topic-filter", "z": "6f432348c57a2fda", "name": "topic filter: acme/office/+/humidity", "env": [{ "name": "filter", "value": "acme/office/+/humidity", "type": "str" }], "x": 900, "y": 120, "wires": [["b097e060d4d522ef"], ["0ddf2631ec5926b9"]] }, { "id": "90ea33ea087b52a9", "type": "debug", "z": "6f432348c57a2fda", "name": "no match", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "payload", "targetType": "msg", "statusVal": "", "statusType": "auto", "x": 1180, "y": 60, "wires": [] }, { "id": "5ea09cf892bf6edc", "type": "inject", "z": "6f432348c57a2fda", "name": "office/main/temperature", "props": [{ "p": "payload" }, { "p": "topic", "vt": "str" }], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "office/main/temperature", "payload": "", "payloadType": "date", "x": 160, "y": 80, "wires": [["bc14e4582a115cd6"]] }, { "id": "4d7649516480dcd6", "type": "link in", "z": "6f432348c57a2fda", "g": "3f7d1b85b6df80e7", "name": "Sub-1", "links": [], "x": 405, "y": 200, "wires": [["9550399dd7be7346"]] }, { "id": "6e31c47c59b692f1", "type": "mqtt in", "z": "6f432348c57a2fda", "name": "", "topic": "acme/office/#", "qos": "2", "datatype": "auto-detect", "broker": "d7260e109d996e74", "nl": false, "rap": true, "rh": 0, "inputs": 0, "x": 430, "y": 40, "wires": [["a570708c83589e95"]] }, { "id": "b2ac43ee25b5d22e", "type": "link out", "z": "6f432348c57a2fda", "g": "3f7d1b85b6df80e7", "name": "link out 1", "mode": "return", "links": [], "x": 785, "y": 200, "wires": [] }, { "id": "0ddf2631ec5926b9", "type": "debug", "z": "6f432348c57a2fda", "name": "no match", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "payload", "targetType": "msg", "statusVal": "", "statusType": "auto", "x": 1180, "y": 140, "wires": [] }, { "id": "7b2fb29046e2f236", "type": "inject", "z": "6f432348c57a2fda", "name": "office/east/temperature", "props": [{ "p": "payload" }, { "p": "topic", "vt": "str" }], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "office/east/temperature", "payload": "", "payloadType": "date", "x": 160, "y": 160, "wires": [["bc14e4582a115cd6"]] }, { "id": "c3e832515cd3d742", "type": "inject", "z": "6f432348c57a2fda", "name": "office/main/humidity", "props": [{ "p": "payload" }, { "p": "topic", "vt": "str" }], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "office/main/humidity", "payload": "", "payloadType": "date", "x": 150, "y": 120, "wires": [["bc14e4582a115cd6"]] }, { "id": "b097e060d4d522ef", "type": "http request", "z": "6f432348c57a2fda", "name": "upload to BMS", "method": "POST", "ret": "txt", "paytoqs": "ignore", "url": "http://localhost:8000/api/monitor", "tls": "", "persist": false, "proxy": "", "insecureHTTPParser": false, "authType": "", "senderr": false, "headers": [], "x": 1200, "y": 100, "wires": [[]] }, { "id": "bc9be11156983084", "type": "project link out", "z": "6f432348c57a2fda", "name": "To remote Node-RED", "mode": "link", "broadcast": false, "project": "c140b5c1-f849-4bf1-afa2-56ff5258606e", "topic": "Send to device", "x": 1220, "y": 20, "wires": [] }, { "id": "5c48ef755b824759", "type": "inject", "z": "6f432348c57a2fda", "name": "office/east/humidity", "props": [{ "p": "payload" }, { "p": "topic", "vt": "str" }], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "office/east/humidity", "payload": "", "payloadType": "date", "x": 150, "y": 200, "wires": [["bc14e4582a115cd6"]] }, { "id": "a570708c83589e95", "type": "link call", "z": "6f432348c57a2fda", "name": "Call Sub-1", "links": ["4d7649516480dcd6"], "linkType": "static", "timeout": "30", "x": 630, "y": 80, "wires": [["e6fdc46c489b1907", "a89d83ca0c1d8eae"]] }, { "id": "9550399dd7be7346", "type": "function", "z": "6f432348c57a2fda", "g": "3f7d1b85b6df80e7", "name": "Update data", "func": "\nreturn msg;", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 590, "y": 200, "wires": [["b2ac43ee25b5d22e"]] }, { "id": "83665dcc09ea7dce", "type": "catch", "z": "6f432348c57a2fda", "name": "", "scope": null, "uncaught": false, "x": 980, "y": 200, "wires": [["a5f9eb21cff43868"]] }, { "id": "a5f9eb21cff43868", "type": "debug", "z": "6f432348c57a2fda", "name": "Error", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "payload", "targetType": "msg", "statusVal": "", "statusType": "auto", "x": 1170, "y": 200, "wires": [] }, { "id": "f20cc195076e206f", "type": "comment", "z": "6f432348c57a2fda", "name": "Test data", "info": "", "x": 220, "y": 40, "wires": [] }, { "id": "a3e0d15e30a38618", "type": "inject", "z": "d15519de378451ae", "name": "Startup info", "props": [{ "p": "payload" }, { "p": "payload.FF_INSTANCE_ID", "v": "FF_INSTANCE_ID", "vt": "env" }, { "p": "payload.FF_INSTANCE_NAME", "v": "FF_INSTANCE_NAME", "vt": "env" }, { "p": "payload.FF_DEVICE_ID", "v": "FF_DEVICE_ID", "vt": "env" }, { "p": "payload.FF_DEVICE_NAME", "v": "FF_DEVICE_NAME", "vt": "env" }], "repeat": "", "crontab": "", "once": true, "onceDelay": 0.1, "topic": "", "payload": "{}", "payloadType": "json", "x": 110, "y": 140, "wires": [["e87eb922a018dfe9"]] }, { "id": "e87eb922a018dfe9", "type": "debug", "z": "d15519de378451ae", "name": "dump vars to console", "active": true, "tosidebar": true, "console": true, "tostatus": false, "complete": "payload", "targetType": "msg", "statusVal": "", "statusType": "auto", "x": 350, "y": 140, "wires": [] }, { "id": "863284b7ee4f2777", "type": "comment", "z": "d15519de378451ae", "name": "System Info Flow v1.1", "info": "", "x": 140, "y": 40, "wires": [] }, { "id": "d0693b302dbdcb80", "type": "inject", "z": "d15519de378451ae", "name": "cloud id", "props": [{ "p": "payload" }, { "p": "topic", "vt": "str" }], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "abcd-1234-abcd-1234-abcd", "payload": "", "payloadType": "date", "x": 130, "y": 220, "wires": [["eca4b082e742449e"]] }, { "id": "1f25cfca1421bfca", "type": "inject", "z": "d15519de378451ae", "name": "device 1 id", "props": [{ "p": "payload" }, { "p": "topic", "vt": "str" }], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "L1xD1xT1x", "payload": "", "payloadType": "date", "x": 120, "y": 260, "wires": [["eca4b082e742449e"]] }, { "id": "a60e36a2ba6be21f", "type": "debug", "z": "d15519de378451ae", "name": "sys info result", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "payload", "targetType": "msg", "statusVal": "", "statusType": "auto", "x": 520, "y": 240, "wires": [] }, { "id": "1c8531ea3430cf50", "type": "switch", "z": "d15519de378451ae", "name": "for me? for device? unknown?", "property": "topic", "propertyType": "msg", "rules": [{ "t": "eq", "v": "FF_INSTANCE_ID", "vt": "env" }, { "t": "eq", "v": "FF_DEVICE_ID", "vt": "env" }, { "t": "else" }], "checkall": "true", "repair": false, "outputs": 3, "x": 370, "y": 80, "wires": [["3dfba4cb62aa0313"], ["3dfba4cb62aa0313"], ["8b9f520c00fbf7ca"]] }, { "id": "3dfba4cb62aa0313", "type": "function", "z": "d15519de378451ae", "name": "getSystemInfo", "func": "function getSystemInfo() {\n const cpuUsage = os.loadavg()[0]; // CPU usage (1-minute average)\n const totalMemory = os.totalmem(); // Total memory in bytes\n const freeMemory = os.freemem(); // Free memory in bytes\n const osName = os.type(); // Operating system name\n const osVersion = os.release(); // Operating system version\n\n return {\n cpuUsage,\n freeMemory,\n totalMemory,\n osName,\n osVersion\n };\n}\nmsg.payload = getSystemInfo()\nreturn msg;", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [{ "var": "os", "module": "os" }], "x": 660, "y": 60, "wires": [["888416a8bb047df7"]] }, { "id": "eca4b082e742449e", "type": "project link call", "z": "d15519de378451ae", "name": "", "project": "caa25e31-24f0-4743-bb69-ff83c179d06d", "topic": "get_details", "timeout": "3", "x": 310, "y": 240, "wires": [["a60e36a2ba6be21f"]] }, { "id": "31b7f2e5961a8261", "type": "project link in", "z": "d15519de378451ae", "name": "↓ get_details", "project": "all", "broadcast": false, "topic": "get_details", "x": 110, "y": 80, "wires": [["1c8531ea3430cf50"]] }, { "id": "888416a8bb047df7", "type": "project link out", "z": "d15519de378451ae", "name": "return ↑", "mode": "return", "broadcast": false, "project": "7db963e4-6794-40f1-831f-b0920b2eba45", "topic": "", "x": 860, "y": 60, "wires": [] }, { "id": "8b9f520c00fbf7ca", "type": "debug", "z": "d15519de378451ae", "name": "unrecognised", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "payload", "targetType": "msg", "statusVal": "", "statusType": "auto", "x": 660, "y": 100, "wires": [] }, { "id": "d7b21f19adc79e82", "type": "comment", "z": "d15519de378451ae", "name": "Manual call to get sys info", "info": "", "x": 350, "y": 200, "wires": [] }]
// render empty flows for initial display
this.clear()
},
data() {
return {
demoFlow: []
}
},
computed: {
dataFlowJson: {
get() {
return JSON.stringify(this.demoFlow, null, 2)
},
set(value) {
this.demoFlow = JSON.parse(value)
}
}
},
methods: {
render(flows) {
console.log('rendering flows')
console.log(FlowRenderer)
const renderer = new FlowRenderer()
const data = flows || this.demoFlow || []
const dataObject = typeof data === 'string' ? JSON.parse(data) : data
renderer.renderFlows(dataObject, { container: this.$refs.f1 })
renderer.renderFlows(dataObject, { container: this.$refs.f2, gridLines: false, images: false })
renderer.renderFlows(dataObject, { container: this.$refs.f3, scope: 'nr-flow-3' })
},
clear() {
this.render([])
},
}
}).mount('#app')
</script>
</body>
</html>