Project changed from mockup to dev
This commit is contained in:
423
package-lock.json
generated
423
package-lock.json
generated
@@ -10,6 +10,9 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fontsource/roboto": "5.2.7",
|
"@fontsource/roboto": "5.2.7",
|
||||||
"@mdi/font": "7.4.47",
|
"@mdi/font": "7.4.47",
|
||||||
|
"@ygoe/msgpack": "^1.0.3",
|
||||||
|
"axios": "^1.12.2",
|
||||||
|
"pinia": "^3.0.3",
|
||||||
"vue": "^3.5.21",
|
"vue": "^3.5.21",
|
||||||
"vuetify": "^3.10.1"
|
"vuetify": "^3.10.1"
|
||||||
},
|
},
|
||||||
@@ -1256,6 +1259,39 @@
|
|||||||
"@vue/shared": "3.5.22"
|
"@vue/shared": "3.5.22"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@vue/devtools-api": {
|
||||||
|
"version": "7.7.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-7.7.7.tgz",
|
||||||
|
"integrity": "sha512-lwOnNBH2e7x1fIIbVT7yF5D+YWhqELm55/4ZKf45R9T8r9dE2AIOy8HKjfqzGsoTHFbWbr337O4E0A0QADnjBg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@vue/devtools-kit": "^7.7.7"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@vue/devtools-kit": {
|
||||||
|
"version": "7.7.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-7.7.7.tgz",
|
||||||
|
"integrity": "sha512-wgoZtxcTta65cnZ1Q6MbAfePVFxfM+gq0saaeytoph7nEa7yMXoi6sCPy4ufO111B9msnw0VOWjPEFCXuAKRHA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@vue/devtools-shared": "^7.7.7",
|
||||||
|
"birpc": "^2.3.0",
|
||||||
|
"hookable": "^5.5.3",
|
||||||
|
"mitt": "^3.0.1",
|
||||||
|
"perfect-debounce": "^1.0.0",
|
||||||
|
"speakingurl": "^14.0.1",
|
||||||
|
"superjson": "^2.2.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@vue/devtools-shared": {
|
||||||
|
"version": "7.7.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-7.7.7.tgz",
|
||||||
|
"integrity": "sha512-+udSj47aRl5aKb0memBvcUG9koarqnxNM5yjuREvqwK6T3ap4mn3Zqqc17QrBFTqSMjr3HK1cvStEZpMDpfdyw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"rfdc": "^1.4.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@vue/reactivity": {
|
"node_modules/@vue/reactivity": {
|
||||||
"version": "3.5.22",
|
"version": "3.5.22",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.22.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.22.tgz",
|
||||||
@@ -1320,6 +1356,12 @@
|
|||||||
"vuetify": "^3.0.0"
|
"vuetify": "^3.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@ygoe/msgpack": {
|
||||||
|
"version": "1.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@ygoe/msgpack/-/msgpack-1.0.3.tgz",
|
||||||
|
"integrity": "sha512-Sjp0O/sNgOJxTOO1c2Zuu7nsHRIGu2iGPYyhUedKKbcHyUl73jbCaomEFJZHNb/6i94B+ZNZHVnFgpo0ENSXxQ==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/acorn": {
|
"node_modules/acorn": {
|
||||||
"version": "8.15.0",
|
"version": "8.15.0",
|
||||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
|
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
|
||||||
@@ -1347,6 +1389,23 @@
|
|||||||
"node": ">= 8"
|
"node": ">= 8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/asynckit": {
|
||||||
|
"version": "0.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||||
|
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/axios": {
|
||||||
|
"version": "1.12.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/axios/-/axios-1.12.2.tgz",
|
||||||
|
"integrity": "sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"follow-redirects": "^1.15.6",
|
||||||
|
"form-data": "^4.0.4",
|
||||||
|
"proxy-from-env": "^1.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/binary-extensions": {
|
"node_modules/binary-extensions": {
|
||||||
"version": "2.3.0",
|
"version": "2.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
|
||||||
@@ -1360,6 +1419,15 @@
|
|||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/birpc": {
|
||||||
|
"version": "2.6.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/birpc/-/birpc-2.6.1.tgz",
|
||||||
|
"integrity": "sha512-LPnFhlDpdSH6FJhJyn4M0kFO7vtQ5iPw24FnG0y21q09xC7e8+1LeR31S1MAIrDAHp4m7aas4bEkTDTvMAtebQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/antfu"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/braces": {
|
"node_modules/braces": {
|
||||||
"version": "3.0.3",
|
"version": "3.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
|
||||||
@@ -1380,6 +1448,19 @@
|
|||||||
"devOptional": true,
|
"devOptional": true,
|
||||||
"license": "MIT/X11"
|
"license": "MIT/X11"
|
||||||
},
|
},
|
||||||
|
"node_modules/call-bind-apply-helpers": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"es-errors": "^1.3.0",
|
||||||
|
"function-bind": "^1.1.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/chokidar": {
|
"node_modules/chokidar": {
|
||||||
"version": "4.0.3",
|
"version": "4.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz",
|
||||||
@@ -1403,6 +1484,18 @@
|
|||||||
"devOptional": true,
|
"devOptional": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/combined-stream": {
|
||||||
|
"version": "1.0.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||||
|
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"delayed-stream": "~1.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/confbox": {
|
"node_modules/confbox": {
|
||||||
"version": "0.2.2",
|
"version": "0.2.2",
|
||||||
"resolved": "https://registry.npmjs.org/confbox/-/confbox-0.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/confbox/-/confbox-0.2.2.tgz",
|
||||||
@@ -1410,6 +1503,21 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/copy-anything": {
|
||||||
|
"version": "3.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-3.0.5.tgz",
|
||||||
|
"integrity": "sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"is-what": "^4.1.8"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12.13"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/mesqueeb"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/csstype": {
|
"node_modules/csstype": {
|
||||||
"version": "3.1.3",
|
"version": "3.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
|
||||||
@@ -1434,6 +1542,15 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/delayed-stream": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/detect-libc": {
|
"node_modules/detect-libc": {
|
||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
|
||||||
@@ -1447,6 +1564,20 @@
|
|||||||
"node": ">=0.10"
|
"node": ">=0.10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/dunder-proto": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"call-bind-apply-helpers": "^1.0.1",
|
||||||
|
"es-errors": "^1.3.0",
|
||||||
|
"gopd": "^1.2.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/entities": {
|
"node_modules/entities": {
|
||||||
"version": "4.5.0",
|
"version": "4.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
|
||||||
@@ -1459,6 +1590,51 @@
|
|||||||
"url": "https://github.com/fb55/entities?sponsor=1"
|
"url": "https://github.com/fb55/entities?sponsor=1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/es-define-property": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/es-errors": {
|
||||||
|
"version": "1.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
|
||||||
|
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/es-object-atoms": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"es-errors": "^1.3.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/es-set-tostringtag": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"es-errors": "^1.3.0",
|
||||||
|
"get-intrinsic": "^1.2.6",
|
||||||
|
"has-tostringtag": "^1.0.2",
|
||||||
|
"hasown": "^2.0.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/esbuild": {
|
"node_modules/esbuild": {
|
||||||
"version": "0.25.10",
|
"version": "0.25.10",
|
||||||
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.10.tgz",
|
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.10.tgz",
|
||||||
@@ -1554,6 +1730,42 @@
|
|||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/follow-redirects": {
|
||||||
|
"version": "1.15.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz",
|
||||||
|
"integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "individual",
|
||||||
|
"url": "https://github.com/sponsors/RubenVerborgh"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"debug": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/form-data": {
|
||||||
|
"version": "4.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz",
|
||||||
|
"integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"asynckit": "^0.4.0",
|
||||||
|
"combined-stream": "^1.0.8",
|
||||||
|
"es-set-tostringtag": "^2.1.0",
|
||||||
|
"hasown": "^2.0.2",
|
||||||
|
"mime-types": "^2.1.12"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/fsevents": {
|
"node_modules/fsevents": {
|
||||||
"version": "2.3.3",
|
"version": "2.3.3",
|
||||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
|
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
|
||||||
@@ -1568,6 +1780,52 @@
|
|||||||
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
|
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/function-bind": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
|
||||||
|
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/get-intrinsic": {
|
||||||
|
"version": "1.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
|
||||||
|
"integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"call-bind-apply-helpers": "^1.0.2",
|
||||||
|
"es-define-property": "^1.0.1",
|
||||||
|
"es-errors": "^1.3.0",
|
||||||
|
"es-object-atoms": "^1.1.1",
|
||||||
|
"function-bind": "^1.1.2",
|
||||||
|
"get-proto": "^1.0.1",
|
||||||
|
"gopd": "^1.2.0",
|
||||||
|
"has-symbols": "^1.1.0",
|
||||||
|
"hasown": "^2.0.2",
|
||||||
|
"math-intrinsics": "^1.1.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/get-proto": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"dunder-proto": "^1.0.1",
|
||||||
|
"es-object-atoms": "^1.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/glob-parent": {
|
"node_modules/glob-parent": {
|
||||||
"version": "5.1.2",
|
"version": "5.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
|
||||||
@@ -1581,6 +1839,18 @@
|
|||||||
"node": ">= 6"
|
"node": ">= 6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/gopd": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
|
||||||
|
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/has-flag": {
|
"node_modules/has-flag": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
|
||||||
@@ -1591,6 +1861,51 @@
|
|||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/has-symbols": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/has-tostringtag": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"has-symbols": "^1.0.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/hasown": {
|
||||||
|
"version": "2.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
|
||||||
|
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"function-bind": "^1.1.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/hookable": {
|
||||||
|
"version": "5.5.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/hookable/-/hookable-5.5.3.tgz",
|
||||||
|
"integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/immutable": {
|
"node_modules/immutable": {
|
||||||
"version": "5.1.3",
|
"version": "5.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.3.tgz",
|
||||||
@@ -1644,6 +1959,18 @@
|
|||||||
"node": ">=0.12.0"
|
"node": ">=0.12.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/is-what": {
|
||||||
|
"version": "4.1.16",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-what/-/is-what-4.1.16.tgz",
|
||||||
|
"integrity": "sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12.13"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/mesqueeb"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/local-pkg": {
|
"node_modules/local-pkg": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-1.1.2.tgz",
|
||||||
@@ -1671,6 +1998,15 @@
|
|||||||
"@jridgewell/sourcemap-codec": "^1.5.5"
|
"@jridgewell/sourcemap-codec": "^1.5.5"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/math-intrinsics": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/merge2": {
|
"node_modules/merge2": {
|
||||||
"version": "1.4.1",
|
"version": "1.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
|
||||||
@@ -1695,6 +2031,33 @@
|
|||||||
"node": ">=8.6"
|
"node": ">=8.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/mime-db": {
|
||||||
|
"version": "1.52.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
|
||||||
|
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/mime-types": {
|
||||||
|
"version": "2.1.35",
|
||||||
|
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
|
||||||
|
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"mime-db": "1.52.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/mitt": {
|
||||||
|
"version": "3.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz",
|
||||||
|
"integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/mlly": {
|
"node_modules/mlly": {
|
||||||
"version": "1.8.0",
|
"version": "1.8.0",
|
||||||
"resolved": "https://registry.npmjs.org/mlly/-/mlly-1.8.0.tgz",
|
"resolved": "https://registry.npmjs.org/mlly/-/mlly-1.8.0.tgz",
|
||||||
@@ -1776,6 +2139,12 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/perfect-debounce": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/picocolors": {
|
"node_modules/picocolors": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
|
||||||
@@ -1795,6 +2164,27 @@
|
|||||||
"url": "https://github.com/sponsors/jonschlinkert"
|
"url": "https://github.com/sponsors/jonschlinkert"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/pinia": {
|
||||||
|
"version": "3.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/pinia/-/pinia-3.0.3.tgz",
|
||||||
|
"integrity": "sha512-ttXO/InUULUXkMHpTdp9Fj4hLpD/2AoJdmAbAeW2yu1iy1k+pkFekQXw5VpC0/5p51IOR/jDaDRfRWRnMMsGOA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@vue/devtools-api": "^7.7.2"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/posva"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"typescript": ">=4.4.4",
|
||||||
|
"vue": "^2.7.0 || ^3.5.11"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"typescript": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/pkg-types": {
|
"node_modules/pkg-types": {
|
||||||
"version": "2.3.0",
|
"version": "2.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-2.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-2.3.0.tgz",
|
||||||
@@ -1835,6 +2225,12 @@
|
|||||||
"node": "^10 || ^12 || >=14"
|
"node": "^10 || ^12 || >=14"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/proxy-from-env": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/quansync": {
|
"node_modules/quansync": {
|
||||||
"version": "0.2.11",
|
"version": "0.2.11",
|
||||||
"resolved": "https://registry.npmjs.org/quansync/-/quansync-0.2.11.tgz",
|
"resolved": "https://registry.npmjs.org/quansync/-/quansync-0.2.11.tgz",
|
||||||
@@ -1898,6 +2294,12 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/rfdc": {
|
||||||
|
"version": "1.4.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz",
|
||||||
|
"integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/rollup": {
|
"node_modules/rollup": {
|
||||||
"version": "4.52.4",
|
"version": "4.52.4",
|
||||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.52.4.tgz",
|
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.52.4.tgz",
|
||||||
@@ -2335,6 +2737,27 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/speakingurl": {
|
||||||
|
"version": "14.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/speakingurl/-/speakingurl-14.0.1.tgz",
|
||||||
|
"integrity": "sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==",
|
||||||
|
"license": "BSD-3-Clause",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/superjson": {
|
||||||
|
"version": "2.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/superjson/-/superjson-2.2.2.tgz",
|
||||||
|
"integrity": "sha512-5JRxVqC8I8NuOUjzBbvVJAKNM8qoVuH0O77h4WInc/qC2q5IreqKxYwgkga3PfA22OayK2ikceb/B26dztPl+Q==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"copy-anything": "^3.0.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/supports-color": {
|
"node_modules/supports-color": {
|
||||||
"version": "8.1.1",
|
"version": "8.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
|
||||||
|
|||||||
@@ -11,6 +11,9 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fontsource/roboto": "5.2.7",
|
"@fontsource/roboto": "5.2.7",
|
||||||
"@mdi/font": "7.4.47",
|
"@mdi/font": "7.4.47",
|
||||||
|
"@ygoe/msgpack": "^1.0.3",
|
||||||
|
"axios": "^1.12.2",
|
||||||
|
"pinia": "^3.0.3",
|
||||||
"vue": "^3.5.21",
|
"vue": "^3.5.21",
|
||||||
"vuetify": "^3.10.1"
|
"vuetify": "^3.10.1"
|
||||||
},
|
},
|
||||||
|
|||||||
60
src/App.vue
60
src/App.vue
@@ -1,6 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<v-app>
|
<v-app>
|
||||||
<v-app-bar title="CMBlu BMS">
|
<v-app-bar title="CMBlu BMS">
|
||||||
|
<v-btn @click.prevent="changeTheme" icon="mdi-theme-light-dark"></v-btn>
|
||||||
<v-app-bar-nav-icon><v-icon>mdi-account</v-icon></v-app-bar-nav-icon>
|
<v-app-bar-nav-icon><v-icon>mdi-account</v-icon></v-app-bar-nav-icon>
|
||||||
</v-app-bar>
|
</v-app-bar>
|
||||||
<v-navigation-drawer expand-on-hover permanent rail>
|
<v-navigation-drawer expand-on-hover permanent rail>
|
||||||
@@ -27,37 +28,68 @@
|
|||||||
></v-list-item>
|
></v-list-item>
|
||||||
</v-list>
|
</v-list>
|
||||||
</v-navigation-drawer>
|
</v-navigation-drawer>
|
||||||
<v-main class="d-flex justify-center align-center">
|
<v-main>
|
||||||
<v-container class="d-flex w-auto h-auto">
|
<v-container fluid class="pa-6">
|
||||||
<!-- <HelloWorld /> -->
|
<v-row>
|
||||||
<!-- <businesscard></businesscard> -->
|
<!-- <v-col cols="12" md="4">
|
||||||
<automatic-mode
|
<automatic-mode
|
||||||
:can-change-mode="canChangeMode"
|
:max-power="18000"
|
||||||
:max-power="18000"
|
:min-power="-18000"
|
||||||
:min-power="-18000"
|
node-id-can-change-mode="ns=4;s=GVL_SCADA.xCanChangeControlMode"
|
||||||
></automatic-mode>
|
node-id-current-control-mode="ns=4;s=GVL_SCADA.eCurrentControlMode"
|
||||||
<battery-state></battery-state>
|
class="ma-2"
|
||||||
|
></automatic-mode>
|
||||||
|
</v-col> -->
|
||||||
|
<v-col cols="12">
|
||||||
|
<!-- <battery-state class="ma-2"></battery-state> -->
|
||||||
|
<!-- <module-view
|
||||||
|
module-base-node-id="ns=4;s=GVL_SCADA.stHMIInterface[1].stHMIInterfaceModule1"
|
||||||
|
/> -->
|
||||||
|
<events-table />
|
||||||
|
<!-- <test-table /> -->
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
</v-container>
|
</v-container>
|
||||||
</v-main>
|
</v-main>
|
||||||
</v-app>
|
</v-app>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Businesscard from "@/components/Businesscard.vue";
|
|
||||||
import AutomaticMode from "@/components/AutomaticMode.vue";
|
import AutomaticMode from "@/components/AutomaticMode.vue";
|
||||||
import BatteryState from "@/components/BatteryState.vue";
|
import BatteryState from "@/components/BatteryState.vue";
|
||||||
|
import ModuleSemiAuto from "@/components/ModuleSemiAuto.vue";
|
||||||
|
import ModuleView from "./components/ModuleView.vue";
|
||||||
|
import ValveControl from "./components/BaseComponents/ValveControl.vue";
|
||||||
|
|
||||||
|
import { mapStores } from "pinia";
|
||||||
|
import { useOpcuaStore } from "@/stores/opcua";
|
||||||
|
import EventsTable from "./components/EventsTable.vue";
|
||||||
|
import TestTable from "./components/TestTable.vue";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
name: "App",
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
msg: "Hello World!",
|
currentPage: "EventView",
|
||||||
canChangeMode: true,
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
Businesscard,
|
|
||||||
AutomaticMode,
|
AutomaticMode,
|
||||||
BatteryState,
|
BatteryState,
|
||||||
|
ModuleView,
|
||||||
|
EventsTable,
|
||||||
|
TestTable
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapStores(useOpcuaStore),
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.opcuaStore.connect();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
changeTheme() {
|
||||||
|
this.$vuetify.theme.toggle();
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,82 +0,0 @@
|
|||||||
<template>
|
|
||||||
<v-footer
|
|
||||||
app
|
|
||||||
height="40"
|
|
||||||
>
|
|
||||||
<a
|
|
||||||
v-for="item in items"
|
|
||||||
:key="item.title"
|
|
||||||
class="d-inline-block mx-2 social-link"
|
|
||||||
:href="item.href"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
target="_blank"
|
|
||||||
:title="item.title"
|
|
||||||
>
|
|
||||||
<v-icon
|
|
||||||
:icon="item.icon"
|
|
||||||
:size="item.icon === '$vuetify' ? 24 : 16"
|
|
||||||
/>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="text-caption text-disabled"
|
|
||||||
style="position: absolute; right: 16px;"
|
|
||||||
>
|
|
||||||
© 2016-{{ (new Date()).getFullYear() }} <span class="d-none d-sm-inline-block">Vuetify, LLC</span>
|
|
||||||
—
|
|
||||||
<a
|
|
||||||
class="text-decoration-none on-surface"
|
|
||||||
href="https://vuetifyjs.com/about/licensing/"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
target="_blank"
|
|
||||||
>
|
|
||||||
MIT License
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</v-footer>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
const items = [
|
|
||||||
{
|
|
||||||
title: 'Vuetify Documentation',
|
|
||||||
icon: `$vuetify`,
|
|
||||||
href: 'https://vuetifyjs.com/',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Vuetify Support',
|
|
||||||
icon: 'mdi-shield-star-outline',
|
|
||||||
href: 'https://support.vuetifyjs.com/',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Vuetify X',
|
|
||||||
icon: ['M2.04875 3.00002L9.77052 13.3248L1.99998 21.7192H3.74882L10.5519 14.3697L16.0486 21.7192H22L13.8437 10.8137L21.0765 3.00002H19.3277L13.0624 9.76874L8.0001 3.00002H2.04875ZM4.62054 4.28821H7.35461L19.4278 20.4308H16.6937L4.62054 4.28821Z'],
|
|
||||||
href: 'https://x.com/vuetifyjs',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Vuetify GitHub',
|
|
||||||
icon: `mdi-github`,
|
|
||||||
href: 'https://github.com/vuetifyjs/vuetify',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Vuetify Discord',
|
|
||||||
icon: ['M22,24L16.75,19L17.38,21H4.5A2.5,2.5 0 0,1 2,18.5V3.5A2.5,2.5 0 0,1 4.5,1H19.5A2.5,2.5 0 0,1 22,3.5V24M12,6.8C9.32,6.8 7.44,7.95 7.44,7.95C8.47,7.03 10.27,6.5 10.27,6.5L10.1,6.33C8.41,6.36 6.88,7.53 6.88,7.53C5.16,11.12 5.27,14.22 5.27,14.22C6.67,16.03 8.75,15.9 8.75,15.9L9.46,15C8.21,14.73 7.42,13.62 7.42,13.62C7.42,13.62 9.3,14.9 12,14.9C14.7,14.9 16.58,13.62 16.58,13.62C16.58,13.62 15.79,14.73 14.54,15L15.25,15.9C15.25,15.9 17.33,16.03 18.73,14.22C18.73,14.22 18.84,11.12 17.12,7.53C17.12,7.53 15.59,6.36 13.9,6.33L13.73,6.5C13.73,6.5 15.53,7.03 16.56,7.95C16.56,7.95 14.68,6.8 12,6.8M9.93,10.59C10.58,10.59 11.11,11.16 11.1,11.86C11.1,12.55 10.58,13.13 9.93,13.13C9.29,13.13 8.77,12.55 8.77,11.86C8.77,11.16 9.28,10.59 9.93,10.59M14.1,10.59C14.75,10.59 15.27,11.16 15.27,11.86C15.27,12.55 14.75,13.13 14.1,13.13C13.46,13.13 12.94,12.55 12.94,11.86C12.94,11.16 13.45,10.59 14.1,10.59Z'],
|
|
||||||
href: 'https://community.vuetifyjs.com/',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Vuetify Reddit',
|
|
||||||
icon: `mdi-reddit`,
|
|
||||||
href: 'https://reddit.com/r/vuetifyjs',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="sass">
|
|
||||||
.social-link :deep(.v-icon)
|
|
||||||
color: rgba(var(--v-theme-on-background), var(--v-disabled-opacity))
|
|
||||||
text-decoration: none
|
|
||||||
transition: .2s ease-in-out
|
|
||||||
|
|
||||||
&:hover
|
|
||||||
color: rgba(25, 118, 210, 1)
|
|
||||||
</style>
|
|
||||||
@@ -1,19 +1,22 @@
|
|||||||
<template>
|
<template>
|
||||||
<v-card width="354" title="Battery Control">
|
<v-card width="250" title="Battery Control">
|
||||||
<v-card-text>
|
<v-card-text>
|
||||||
<v-form>
|
<v-form>
|
||||||
<v-row>
|
<v-row>
|
||||||
<v-col cols="12" class="d-flex flex-column">
|
<v-col cols="12" class="d-flex flex-column">
|
||||||
<v-select
|
<v-select
|
||||||
label="Operation mode"
|
label="Operation mode"
|
||||||
:items="['Auto remote', 'Auto local', 'Manual', 'Safetytest']"
|
v-model="opcuaStore.values[nodeIdCurrentControlMode]"
|
||||||
:disabled="!canChangeMode"
|
:items="modes"
|
||||||
|
item-title="title"
|
||||||
|
item-value="value"
|
||||||
|
:disabled="!opcuaStore.values[nodeIdCanChangeMode]"
|
||||||
></v-select>
|
></v-select>
|
||||||
<v-text-field
|
<v-text-field
|
||||||
v-model="requestedPower"
|
v-model="requestedPower"
|
||||||
:rules="checkReqPower"
|
:rules="checkReqPower"
|
||||||
:disabled="inLocalAutoMode"
|
|
||||||
:reverse="true"
|
:reverse="true"
|
||||||
|
:disabled="opcuaStore.values[nodeIdCurrentControlMode] != 2"
|
||||||
prefix="W"
|
prefix="W"
|
||||||
@focus="$event.target.select()"
|
@focus="$event.target.select()"
|
||||||
@keyup.enter="$event.target.blur()"
|
@keyup.enter="$event.target.blur()"
|
||||||
@@ -24,14 +27,26 @@
|
|||||||
</v-form>
|
</v-form>
|
||||||
</v-card-text>
|
</v-card-text>
|
||||||
<v-card-actions>
|
<v-card-actions>
|
||||||
<v-btn @click.prevent="">Start</v-btn>
|
<v-btn
|
||||||
<v-btn @click.prevent="">Stop</v-btn>
|
@click.prevent=""
|
||||||
|
:disabled="opcuaStore.values[nodeIdCurrentControlMode] != 2"
|
||||||
|
>Start</v-btn
|
||||||
|
>
|
||||||
|
<v-btn
|
||||||
|
@click.prevent=""
|
||||||
|
:disabled="opcuaStore.values[nodeIdCurrentControlMode] != 2"
|
||||||
|
>Stop</v-btn
|
||||||
|
>
|
||||||
</v-card-actions>
|
</v-card-actions>
|
||||||
</v-card>
|
</v-card>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { useOpcuaStore } from "@/stores/opcua";
|
||||||
|
import { mapStores } from "pinia";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
name: "AutomaticMode",
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
requestedPower: 0,
|
requestedPower: 0,
|
||||||
@@ -44,6 +59,19 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
modes: [
|
||||||
|
{ title: "Auto Remote", value: 1 },
|
||||||
|
{ title: "Auto local", value: 2 },
|
||||||
|
{ title: "Safetycheck", value: 3 },
|
||||||
|
{ title: "Capacity test", value: 4 },
|
||||||
|
{ title: "Manual", value: 5 },
|
||||||
|
{ title: "Balancing", value: 6 },
|
||||||
|
{ title: "Cycling", value: 7 },
|
||||||
|
{ title: "Precharge", value: 8 },
|
||||||
|
{ title: "Doppelhöcker", value: 9 },
|
||||||
|
{ title: "Semi Auto", value: 10 },
|
||||||
|
],
|
||||||
|
selectedMode: null,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@@ -51,20 +79,9 @@ export default {
|
|||||||
event.target.active = false;
|
event.target.active = false;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
computed: {
|
|
||||||
modeDisabled() {
|
|
||||||
return !this.canChangeMode;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
props: {
|
props: {
|
||||||
canChangeMode: {
|
nodeIdCurrentControlMode: String,
|
||||||
type: Boolean,
|
nodeIdCanChangeMode: String,
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
inLocalAutoMode: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
minPower: {
|
minPower: {
|
||||||
type: Number,
|
type: Number,
|
||||||
required: true,
|
required: true,
|
||||||
@@ -74,5 +91,17 @@ export default {
|
|||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
...mapStores(useOpcuaStore),
|
||||||
|
currentControlMode() {
|
||||||
|
return this.opcuaStore.values[this.nodeIdCurrentControlMode];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.opcuaStore.subscribe([
|
||||||
|
this.nodeIdCurrentControlMode,
|
||||||
|
this.nodeIdCanChangeMode,
|
||||||
|
]);
|
||||||
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
51
src/components/BaseComponents/ControlButton.vue
Normal file
51
src/components/BaseComponents/ControlButton.vue
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
<template>
|
||||||
|
<v-btn
|
||||||
|
:disabled="!this.opcuaStore.values[this.cbReleaseNodeId]"
|
||||||
|
:class="{'bg-primary': isActive}"
|
||||||
|
@click="onClick"
|
||||||
|
>
|
||||||
|
<slot></slot>
|
||||||
|
</v-btn>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { mapStores } from "pinia";
|
||||||
|
import { useOpcuaStore } from "@/stores/opcua";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "ControlButton",
|
||||||
|
computed: {
|
||||||
|
...mapStores(useOpcuaStore),
|
||||||
|
cbFeedbackNodeId() {
|
||||||
|
return `${this.controlButtonBaseNodeId}.eFeedback`;
|
||||||
|
},
|
||||||
|
cbReleaseNodeId() {
|
||||||
|
return `${this.controlButtonBaseNodeId}.xRelease`;
|
||||||
|
},
|
||||||
|
cbRequestNodeId() {
|
||||||
|
return `${this.controlButtonBaseNodeId}.xRequest`;
|
||||||
|
},
|
||||||
|
isActive() {
|
||||||
|
return this.opcuaStore.values[this.cbFeedbackNodeId];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
controlButtonBaseNodeId: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
onClick() {
|
||||||
|
this.opcuaStore.sendCommand({
|
||||||
|
nodeId: this.cbRequestNodeId,
|
||||||
|
nodeValue: true,
|
||||||
|
nodeType: this.opcuaStore.opcuaDatatypes.Boolean,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.opcuaStore.subscribe([this.cbFeedbackNodeId, this.cbReleaseNodeId]);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
123
src/components/BaseComponents/MotorControl.vue
Normal file
123
src/components/BaseComponents/MotorControl.vue
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
<template>
|
||||||
|
<v-card :title="motorName" max-width="300" w-auto>
|
||||||
|
<v-card-text>
|
||||||
|
<v-row justify="center">
|
||||||
|
<v-col cols="6">
|
||||||
|
<v-text-field
|
||||||
|
:rules="checkSetpoint"
|
||||||
|
:reverse="true"
|
||||||
|
:disabled="opcuaStore.values[currentControlModeNodeId] != 2"
|
||||||
|
:prefix="opcuaStore.values[spUnitNodeId]"
|
||||||
|
@focus="$event.target.select()"
|
||||||
|
@keyup.enter="$event.target.blur()"
|
||||||
|
label="Setpoint"
|
||||||
|
></v-text-field>
|
||||||
|
</v-col>
|
||||||
|
<v-col cols="6">
|
||||||
|
<h1>/ {{ processValue }}</h1>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
<v-row>
|
||||||
|
<v-col cols="6">
|
||||||
|
<control-button block :control-button-base-node-id="startCBNodeId">
|
||||||
|
Start
|
||||||
|
</control-button>
|
||||||
|
</v-col>
|
||||||
|
<v-col cosl="6">
|
||||||
|
<control-button block :control-button-base-node-id="stopCBNodeId">
|
||||||
|
Stop
|
||||||
|
</control-button>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
</v-card-text>
|
||||||
|
</v-card>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { mapStores } from "pinia";
|
||||||
|
import { useOpcuaStore } from "@/stores/opcua";
|
||||||
|
import ControlButton from "./ControlButton.vue";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "MotorControl",
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
checkSetpoint: [
|
||||||
|
(value) => {
|
||||||
|
if (
|
||||||
|
value <= this.opcuaStore.values[this.spMaxValueNodeId] &&
|
||||||
|
value >= this.opcuaStore.values[this.spMinValueNodeId]
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return `Setpoint must be <= ${this.opcuaStore.values[this.spMaxValueNodeId]} and >= ${this.opcuaStore.values[this.spMinValueNodeId]}`;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapStores(useOpcuaStore),
|
||||||
|
startCBNodeId() {
|
||||||
|
return `${this.motorNodeId}.stStartButton`;
|
||||||
|
},
|
||||||
|
stopCBNodeId() {
|
||||||
|
return `${this.motorNodeId}.stStopButton`;
|
||||||
|
},
|
||||||
|
spNodeId() {
|
||||||
|
return `${this.motorNodeId}.stSetpoint.rValue`;
|
||||||
|
},
|
||||||
|
currentControlModeNodeId() {
|
||||||
|
return `${this.motorNodeId}.iCurrentMode`;
|
||||||
|
},
|
||||||
|
spMinValueNodeId() {
|
||||||
|
return `${this.motorNodeId}.stSetpoint.rMin`;
|
||||||
|
},
|
||||||
|
spMaxValueNodeId() {
|
||||||
|
return `${this.motorNodeId}.stSetpoint.rMax`;
|
||||||
|
},
|
||||||
|
spUnitNodeId() {
|
||||||
|
return `${this.motorNodeId}.stSetpoint.sUnit`;
|
||||||
|
},
|
||||||
|
pvUnitNodeId() {
|
||||||
|
return `${this.motorNodeId}.stProcessValue.sUnit`;
|
||||||
|
},
|
||||||
|
pvNodeId() {
|
||||||
|
return `${this.motorNodeId}.stProcessValue.rValue`;
|
||||||
|
},
|
||||||
|
processValue() {
|
||||||
|
const value = Number(this.opcuaStore.values[this.pvNodeId]).toFixed(
|
||||||
|
this.numDecimals
|
||||||
|
);
|
||||||
|
const unit = this.opcuaStore.values[this.pvUnitNodeId];
|
||||||
|
return `${value} ${unit}`;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
ControlButton,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
motorNodeId: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
motorName: {
|
||||||
|
type: String,
|
||||||
|
},
|
||||||
|
numDecimals: {
|
||||||
|
type: Number,
|
||||||
|
default: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.opcuaStore.subscribe([
|
||||||
|
this.currentControlModeNodeId,
|
||||||
|
this.spMinValueNodeId,
|
||||||
|
this.spMaxValueNodeId,
|
||||||
|
this.spUnitNodeId,
|
||||||
|
this.pvUnitNodeId,
|
||||||
|
this.pvNodeId,
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
83
src/components/BaseComponents/ProcessValue.vue
Normal file
83
src/components/BaseComponents/ProcessValue.vue
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
<template>
|
||||||
|
<v-card class="mx-auto">
|
||||||
|
<v-card-item :title="this.valueTitle">
|
||||||
|
<!-- <template v-slot:subtitle>
|
||||||
|
<v-icon
|
||||||
|
class="me-1 pb-1"
|
||||||
|
color="error"
|
||||||
|
icon="mdi-alert"
|
||||||
|
size="18"
|
||||||
|
></v-icon>
|
||||||
|
|
||||||
|
Extreme Weather Alert
|
||||||
|
</template> -->
|
||||||
|
</v-card-item>
|
||||||
|
|
||||||
|
<v-card-text>
|
||||||
|
<v-row align="end" no-gutters>
|
||||||
|
<v-col class="text-h4" cols="12">
|
||||||
|
<div class="">
|
||||||
|
{{ formattedString }}
|
||||||
|
</div>
|
||||||
|
</v-col>
|
||||||
|
|
||||||
|
<!-- <v-col class="text-right" cols="6">
|
||||||
|
<v-icon color="error" icon="mdi-weather-hurricane" size="88"></v-icon>
|
||||||
|
</v-col> -->
|
||||||
|
</v-row>
|
||||||
|
</v-card-text>
|
||||||
|
|
||||||
|
<!-- <div class="d-flex py-3 justify-space-between">
|
||||||
|
<v-list-item density="compact" prepend-icon="mdi-weather-windy">
|
||||||
|
<v-list-item-subtitle>123 km/h</v-list-item-subtitle>
|
||||||
|
</v-list-item>
|
||||||
|
|
||||||
|
<v-list-item density="compact" prepend-icon="mdi-weather-pouring">
|
||||||
|
<v-list-item-subtitle>48%</v-list-item-subtitle>
|
||||||
|
</v-list-item>
|
||||||
|
</div> -->
|
||||||
|
</v-card>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { mapStores } from "pinia";
|
||||||
|
import { useOpcuaStore } from "@/stores/opcua";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "ProcessValue",
|
||||||
|
computed: {
|
||||||
|
...mapStores(useOpcuaStore),
|
||||||
|
formattedString() {
|
||||||
|
const value = Number(this.opcuaStore.values[this.nodeIdValue]).toFixed(
|
||||||
|
this.numDecimals
|
||||||
|
);
|
||||||
|
const unit = this.opcuaStore.values[this.nodeIdUnit];
|
||||||
|
return `${value} ${unit}`;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
numDecimals: {
|
||||||
|
type: Number,
|
||||||
|
default: 1,
|
||||||
|
},
|
||||||
|
valueTitle: {
|
||||||
|
type: String,
|
||||||
|
},
|
||||||
|
nodeIdValue: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
nodeIdUnit: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.opcuaStore.subscribe([this.nodeIdValue, this.nodeIdUnit]);
|
||||||
|
},
|
||||||
|
// unmounted() {
|
||||||
|
// console.log("Unsubscribed");
|
||||||
|
// this.opcuaStore.unsubscribe([this.nodeIdValue, this.nodeIdUnit]);
|
||||||
|
// },
|
||||||
|
};
|
||||||
|
</script>
|
||||||
49
src/components/BaseComponents/ValveControl.vue
Normal file
49
src/components/BaseComponents/ValveControl.vue
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
<template>
|
||||||
|
<v-card :title="valveName">
|
||||||
|
<v-card-text>
|
||||||
|
<v-row>
|
||||||
|
<v-col cols="6">
|
||||||
|
<control-button block :control-button-base-node-id="openCBNodeId">
|
||||||
|
Open
|
||||||
|
</control-button>
|
||||||
|
</v-col>
|
||||||
|
<v-col>
|
||||||
|
<control-button block :control-button-base-node-id="closeCBNodeId">
|
||||||
|
Close
|
||||||
|
</control-button>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
</v-card-text>
|
||||||
|
</v-card>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { mapStores } from "pinia";
|
||||||
|
import { useOpcuaStore } from "@/stores/opcua";
|
||||||
|
import ControlButton from "./ControlButton.vue";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "ValveControl",
|
||||||
|
computed: {
|
||||||
|
...mapStores(useOpcuaStore),
|
||||||
|
openCBNodeId() {
|
||||||
|
return `${this.valveNodeId}.stOpenButton`;
|
||||||
|
},
|
||||||
|
closeCBNodeId() {
|
||||||
|
return `${this.valveNodeId}.stCloseButton`;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
ControlButton,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
valveNodeId: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
valveName: {
|
||||||
|
type: String,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
@@ -32,6 +32,7 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
|
name: "BatteryState",
|
||||||
props: {
|
props: {
|
||||||
currentState: {
|
currentState: {
|
||||||
type: Number,
|
type: Number,
|
||||||
|
|||||||
42
src/components/EventsTable.vue
Normal file
42
src/components/EventsTable.vue
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
<template>
|
||||||
|
<v-table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="text-left" width="100">Type</th>
|
||||||
|
<th class="text-left">Message</th>
|
||||||
|
<th class="text-left">Raised</th>
|
||||||
|
<th class="text-left">Cleared</th>
|
||||||
|
<th class="text-left">Confirmed</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<!-- <tbody>
|
||||||
|
<tr v-for="(value, index) in this.opcuaStore["opcuaEvents"]" :key="index">
|
||||||
|
<td>
|
||||||
|
<v-icon v-if="value.type === 750" color="error" icon="mdi-alert-circle"></v-icon>
|
||||||
|
<v-icon v-else="value.type === 500" color="warning" icon="mdi-alert"></v-icon>
|
||||||
|
</td>
|
||||||
|
<td>{{ value.message }}</td>
|
||||||
|
<td>{{ value.raised }}</td>
|
||||||
|
<td>{{ value.cleared }}</td>
|
||||||
|
<td>{{ value.confirmed }}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody> -->
|
||||||
|
</v-table>
|
||||||
|
<p>{{ opcuaStore["opcuaEvents"] }}</p>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { mapStores } from "pinia";
|
||||||
|
import { useOpcuaStore } from "@/stores/opcua";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "EventTable",
|
||||||
|
computed: {
|
||||||
|
...mapStores(useOpcuaStore),
|
||||||
|
arrayFromMap() {
|
||||||
|
const test = Array.from(this.opcuaStore["opcuaEvents"].values());
|
||||||
|
return test;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
@@ -1,90 +0,0 @@
|
|||||||
<template>
|
|
||||||
<v-container class="fill-height" max-width="900">
|
|
||||||
<div>
|
|
||||||
<v-img
|
|
||||||
class="mb-4"
|
|
||||||
height="150"
|
|
||||||
src="@/assets/logo.png"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div class="mb-8 text-center">
|
|
||||||
<div class="text-body-2 font-weight-light mb-n1">Welcome to</div>
|
|
||||||
<h1 class="text-h2 font-weight-bold">Vuetify</h1>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<v-row>
|
|
||||||
<v-col cols="12">
|
|
||||||
<v-card
|
|
||||||
class="py-4"
|
|
||||||
color="surface-variant"
|
|
||||||
image="https://cdn.vuetifyjs.com/docs/images/one/create/feature.png"
|
|
||||||
prepend-icon="mdi-rocket-launch-outline"
|
|
||||||
rounded="lg"
|
|
||||||
variant="tonal"
|
|
||||||
>
|
|
||||||
<template #image>
|
|
||||||
<v-img position="top right" />
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<template #title>
|
|
||||||
<h2 class="text-h5 font-weight-bold">
|
|
||||||
Get started
|
|
||||||
</h2>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<template #subtitle>
|
|
||||||
<div class="text-subtitle-1">
|
|
||||||
Change this page by updating <v-kbd>{{ `<HelloWorld />` }}</v-kbd> in <v-kbd>components/HelloWorld.vue</v-kbd>.
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</v-card>
|
|
||||||
</v-col>
|
|
||||||
|
|
||||||
<v-col v-for="link in links" :key="link.href" cols="6">
|
|
||||||
<v-card
|
|
||||||
append-icon="mdi-open-in-new"
|
|
||||||
class="py-4"
|
|
||||||
color="surface-variant"
|
|
||||||
:href="link.href"
|
|
||||||
:prepend-icon="link.icon"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
rounded="lg"
|
|
||||||
:subtitle="link.subtitle"
|
|
||||||
target="_blank"
|
|
||||||
:title="link.title"
|
|
||||||
variant="tonal"
|
|
||||||
/>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
|
||||||
</div>
|
|
||||||
</v-container>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
const links = [
|
|
||||||
{
|
|
||||||
href: 'https://vuetifyjs.com/',
|
|
||||||
icon: 'mdi-text-box-outline',
|
|
||||||
subtitle: 'Learn about all things Vuetify in our documentation.',
|
|
||||||
title: 'Documentation',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
href: 'https://vuetifyjs.com/introduction/why-vuetify/#feature-guides',
|
|
||||||
icon: 'mdi-star-circle-outline',
|
|
||||||
subtitle: 'Explore available framework Features.',
|
|
||||||
title: 'Features',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
href: 'https://vuetifyjs.com/components/all',
|
|
||||||
icon: 'mdi-widgets-outline',
|
|
||||||
subtitle: 'Discover components in the API Explorer.',
|
|
||||||
title: 'Components',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
href: 'https://discord.vuetifyjs.com',
|
|
||||||
icon: 'mdi-account-group-outline',
|
|
||||||
subtitle: 'Connect with Vuetify developers.',
|
|
||||||
title: 'Community',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
</script>
|
|
||||||
67
src/components/ModuleSemiAuto.vue
Normal file
67
src/components/ModuleSemiAuto.vue
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
<template>
|
||||||
|
<v-card width="250">
|
||||||
|
<v-card-title>Module {{ modNumber }}</v-card-title>
|
||||||
|
<v-card-text>
|
||||||
|
<v-switch
|
||||||
|
v-for="(unitTag, index) in this.unitTags"
|
||||||
|
:key="unitTag"
|
||||||
|
:model-value="this.opcuaStore.values[unitTag]"
|
||||||
|
:label="`Unit ${index+1}`"
|
||||||
|
@click.prevent="onClick(index, $event)"
|
||||||
|
></v-switch>
|
||||||
|
</v-card-text>
|
||||||
|
</v-card>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import axios from "axios";
|
||||||
|
import { useOpcuaStore } from "@/stores/opcua";
|
||||||
|
import { mapStores } from "pinia";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "SemiAutoControl",
|
||||||
|
computed: {
|
||||||
|
...mapStores(useOpcuaStore),
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.opcuaStore.subscribe(this.unitTags);
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async onSwitchChange(unit) {
|
||||||
|
let value = this.opcuaStore.values[this.unitTags[unit]]
|
||||||
|
console.log(`Unit: ${unit}`)
|
||||||
|
try {
|
||||||
|
const semiAutoData = {
|
||||||
|
string: this.strng,
|
||||||
|
module: this.modNumber,
|
||||||
|
unit: unit,
|
||||||
|
enable: !value,
|
||||||
|
};
|
||||||
|
const response = await axios.post(
|
||||||
|
"http://127.0.0.1:8000/semiAuto",
|
||||||
|
semiAutoData
|
||||||
|
);
|
||||||
|
console.log(response);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error:", error);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async onClick(unitIndex, event) {
|
||||||
|
let value = this.opcuaStore.values[this.unitTags[unitIndex]]
|
||||||
|
event.target.loading="warning"
|
||||||
|
this.opcuaStore.sendCommand({"nodeId": this.unitTags[unitIndex], "nodeValue": !value, "nodeType": this.opcuaStore.opcuaDatatypes.Boolean})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
modNumber: {
|
||||||
|
type: Number,
|
||||||
|
default: 1,
|
||||||
|
},
|
||||||
|
strng: {
|
||||||
|
type: Number,
|
||||||
|
default: 1,
|
||||||
|
},
|
||||||
|
unitTags: Array,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
43
src/components/ModuleView.vue
Normal file
43
src/components/ModuleView.vue
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
<template>
|
||||||
|
<v-container fluid>
|
||||||
|
<v-row>
|
||||||
|
<v-col cols="6">
|
||||||
|
<unit-control-view :unit-number="1" :unit-base-node-id="`${moduleBaseNodeId}.stHMIInterfaceUnit1`" />
|
||||||
|
</v-col>
|
||||||
|
|
||||||
|
<v-col cols="6">
|
||||||
|
<unit-control-view :unit-number="2" :unit-base-node-id="`${moduleBaseNodeId}.stHMIInterfaceUnit2`" />
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
|
||||||
|
<v-row>
|
||||||
|
<v-col cols="6">
|
||||||
|
<unit-control-view :unit-number="3" :unit-base-node-id="`${moduleBaseNodeId}.stHMIInterfaceUnit3`" />
|
||||||
|
</v-col>
|
||||||
|
|
||||||
|
<v-col cols="6">
|
||||||
|
<unit-control-view :unit-number="4" :unit-base-node-id="`${moduleBaseNodeId}.stHMIInterfaceUnit4`" />
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
</v-container>
|
||||||
|
<!-- `${unitBaseNodeId}.stHMIInterfaceUnit1`-->
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import UnitControlView from './UnitControlView.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "ModuleView",
|
||||||
|
components: {
|
||||||
|
UnitControlView,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
moduleBaseNodeId: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
63
src/components/TestTable.vue
Normal file
63
src/components/TestTable.vue
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
<template>
|
||||||
|
<div class="p-4">
|
||||||
|
<h2 class="text-xl font-bold mb-4">Test Data Table</h2>
|
||||||
|
<table class="min-w-full border border-gray-300">
|
||||||
|
<thead class="bg-gray-100">
|
||||||
|
<tr>
|
||||||
|
<th class="px-4 py-2 border">Severity</th>
|
||||||
|
<th class="px-4 py-2 border">Message</th>
|
||||||
|
<th class="px-4 py-2 border">Active State</th>
|
||||||
|
<th class="px-4 py-2 border">Confirmed State</th>
|
||||||
|
<th class="px-4 py-2 border">Retain</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr
|
||||||
|
v-for="(item, index) in test_data"
|
||||||
|
:key="index"
|
||||||
|
class="text-center hover:bg-gray-50"
|
||||||
|
>
|
||||||
|
<td class="border px-4 py-2">{{ item.Severity }}</td>
|
||||||
|
<td class="border px-4 py-2">{{ item.Message }}</td>
|
||||||
|
<td class="border px-4 py-2">{{ item.ActiveState ? '✅' : '❌' }}</td>
|
||||||
|
<td class="border px-4 py-2">{{ item.ConfirmedState ? '✅' : '❌' }}</td>
|
||||||
|
<td class="border px-4 py-2">{{ item.Retain ? '✅' : '❌' }}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "TestDataTable",
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
test_data: [
|
||||||
|
{
|
||||||
|
Severity: 750,
|
||||||
|
Message: "Es ist ein Fehler aufgetreten",
|
||||||
|
ActiveState: true,
|
||||||
|
ConfirmedState: false,
|
||||||
|
Retain: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Severity: 500,
|
||||||
|
Message: "Es ist eine Warnung aufgetreten",
|
||||||
|
ActiveState: true,
|
||||||
|
ConfirmedState: false,
|
||||||
|
Retain: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
table {
|
||||||
|
border-collapse: collapse;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
97
src/components/UnitControl.vue
Normal file
97
src/components/UnitControl.vue
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
<template>
|
||||||
|
<v-sheet fluid class="pa-6 border-thin">
|
||||||
|
<v-row>
|
||||||
|
<v-col cols="12">
|
||||||
|
<v-card title="Semi auto">
|
||||||
|
<!-- Semi auto enable -->
|
||||||
|
<v-card-text>
|
||||||
|
<v-row>
|
||||||
|
<v-col cols="6">
|
||||||
|
<control-button block :controlButtonBaseNodeId="semiAutoCBEnableNodeId">Enable</control-button>
|
||||||
|
</v-col>
|
||||||
|
<v-col cols="6">
|
||||||
|
<control-button block :controlButtonBaseNodeId="semiAutoCBDisableNodeId">Disable</control-button>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
</v-card-text>
|
||||||
|
</v-card>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
<v-row>
|
||||||
|
<v-col cols="6">
|
||||||
|
<!-- Posolyt valve -->
|
||||||
|
<valve-control
|
||||||
|
valve-name="Posolyt valve"
|
||||||
|
:valve-node-id="`${this.unitBaseNodeId}.stNS12`"
|
||||||
|
/>
|
||||||
|
</v-col>
|
||||||
|
<v-col cols="6">
|
||||||
|
<!-- Negolyt valve -->
|
||||||
|
<valve-control
|
||||||
|
valve-name="Negolyt valve"
|
||||||
|
:valve-node-id="`${this.unitBaseNodeId}.stNS22`"
|
||||||
|
/>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
<v-row>
|
||||||
|
<v-col cols="6">
|
||||||
|
<!-- Posolyt pump -->
|
||||||
|
<motor-control motor-name="Posolyt Pump" :num-decimals="0" :motor-node-id="posolytPumpNodeId"/>
|
||||||
|
</v-col>
|
||||||
|
<v-col cols="6">
|
||||||
|
<!-- Negolyt pump -->
|
||||||
|
<motor-control motor-name="Negolyt Pump" :num-decimals="0" :motor-node-id="negolytPumpNodeId" />
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
</v-sheet>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { useOpcuaStore } from "@/stores/opcua";
|
||||||
|
import { mapStores } from "pinia";
|
||||||
|
import ValveControl from "./BaseComponents/ValveControl.vue";
|
||||||
|
import ControlButton from "./BaseComponents/ControlButton.vue";
|
||||||
|
import MotorControl from "./BaseComponents/MotorControl.vue";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "UnitControl",
|
||||||
|
components: {
|
||||||
|
ValveControl,
|
||||||
|
ControlButton,
|
||||||
|
MotorControl,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
unitBaseNodeId: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapStores(useOpcuaStore),
|
||||||
|
valveUnitNodeId(unit) {
|
||||||
|
return `${this.unitBaseNodeId}.`;
|
||||||
|
},
|
||||||
|
semiAutoCBEnableNodeId() {
|
||||||
|
return `${this.unitBaseNodeId}.stButtonSemiAutoEnable`;
|
||||||
|
},
|
||||||
|
semiAutoCBDisableNodeId() {
|
||||||
|
return `${this.unitBaseNodeId}.stButtonSemiAutoDisable`;
|
||||||
|
},
|
||||||
|
posolytPumpNodeId() {
|
||||||
|
return `${this.unitBaseNodeId}.stNS11`;
|
||||||
|
},
|
||||||
|
negolytPumpNodeId() {
|
||||||
|
return `${this.unitBaseNodeId}.stNS21`;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async onClick(enable) {
|
||||||
|
this.opcuaStore.sendCommand({
|
||||||
|
nodeId: this.semiAutoEnabledNodeId,
|
||||||
|
nodeValue: enable,
|
||||||
|
nodeType: this.opcuaStore.opcuaDatatypes.Boolean,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
40
src/components/UnitControlView.vue
Normal file
40
src/components/UnitControlView.vue
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
<template>
|
||||||
|
<v-sheet class="border-thin pa-6">
|
||||||
|
<v-row class="text-center">
|
||||||
|
<v-col cols="12">
|
||||||
|
<h1>Unit {{ unitNumber }}</h1>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
<v-row>
|
||||||
|
<v-col cols="6">
|
||||||
|
<unit-state :unit-number="1" :unitBaseNodeId="unitBaseNodeId" />
|
||||||
|
</v-col>
|
||||||
|
<v-col cols="6">
|
||||||
|
<unit-control :unit-base-node-id="unitBaseNodeId" />
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
</v-sheet>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import UnitState from "./UnitState.vue";
|
||||||
|
import UnitControl from "./UnitControl.vue";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "UnitcontrolView",
|
||||||
|
components: {
|
||||||
|
UnitState,
|
||||||
|
UnitControl,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
unitNumber: {
|
||||||
|
type: Number,
|
||||||
|
default: 1,
|
||||||
|
},
|
||||||
|
unitBaseNodeId: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
137
src/components/UnitState.vue
Normal file
137
src/components/UnitState.vue
Normal file
@@ -0,0 +1,137 @@
|
|||||||
|
<template>
|
||||||
|
<v-sheet fluid class="pa-6 border-thin" max-width="650">
|
||||||
|
<v-row>
|
||||||
|
<v-col cols="12">
|
||||||
|
<process-value
|
||||||
|
value-title="Voltage"
|
||||||
|
:node-Id-Value="voltageValueNodeId"
|
||||||
|
:node-id-unit="voltageUnitNodeId"
|
||||||
|
:num-decimals="1"
|
||||||
|
/>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
<v-row>
|
||||||
|
<v-col cols="6">
|
||||||
|
<process-value
|
||||||
|
value-title="Posolyt Inlet Pressure"
|
||||||
|
:node-Id-Value="posPresSegValueNodeId"
|
||||||
|
:node-id-unit="posPresSegUnitNodeId"
|
||||||
|
:num-decimals="0"
|
||||||
|
/>
|
||||||
|
</v-col>
|
||||||
|
<v-col cols="6">
|
||||||
|
<process-value
|
||||||
|
value-title="Negolyt Inlet Pressure"
|
||||||
|
:node-Id-Value="negPresSegValueNodeId"
|
||||||
|
:node-id-unit="negPresSegUnitNodeId"
|
||||||
|
:num-decimals="0"
|
||||||
|
/>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
<v-row>
|
||||||
|
<v-col cols="6">
|
||||||
|
<process-value
|
||||||
|
value-title="Posolyt Tank Pressure"
|
||||||
|
:node-Id-Value="posPresTankValueNodeId"
|
||||||
|
:node-id-unit="posPresTankUnitNodeId"
|
||||||
|
:num-decimals="0"
|
||||||
|
/>
|
||||||
|
</v-col>
|
||||||
|
<v-col cols="6">
|
||||||
|
<process-value
|
||||||
|
value-title="Negolyt Tank Pressure"
|
||||||
|
:node-Id-Value="negPresTankValueNodeId"
|
||||||
|
:node-id-unit="negPresTankUnitNodeId"
|
||||||
|
:num-decimals="0"
|
||||||
|
/>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
<v-row>
|
||||||
|
<v-col cols="6">
|
||||||
|
<process-value
|
||||||
|
value-title="Posolyt Temp"
|
||||||
|
:node-Id-Value="posTempValueNodeId"
|
||||||
|
:node-id-unit="posTempUnitNodeId"
|
||||||
|
:num-decimals="1"
|
||||||
|
/>
|
||||||
|
</v-col>
|
||||||
|
<v-col cols="6">
|
||||||
|
<process-value
|
||||||
|
value-title="Negolyt Temp"
|
||||||
|
:node-Id-Value="negTempValueNodeId"
|
||||||
|
:node-id-unit="negTempUnitNodeId"
|
||||||
|
:num-decimals="1"
|
||||||
|
/>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
</v-sheet>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { mapStores } from "pinia";
|
||||||
|
import { useOpcuaStore } from "@/stores/opcua";
|
||||||
|
import ProcessValue from "./BaseComponents/ProcessValue.vue";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "UnitState",
|
||||||
|
components: {
|
||||||
|
ProcessValue,
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapStores(useOpcuaStore),
|
||||||
|
voltageValueNodeId() {
|
||||||
|
return `${this.unitBaseNodeId}.stE31.rValue`;
|
||||||
|
},
|
||||||
|
voltageUnitNodeId() {
|
||||||
|
return `${this.unitBaseNodeId}.stE31.sUnit`;
|
||||||
|
},
|
||||||
|
posPresSegValueNodeId() {
|
||||||
|
return `${this.unitBaseNodeId}.stP11.rValue`;
|
||||||
|
},
|
||||||
|
posPresSegUnitNodeId() {
|
||||||
|
return `${this.unitBaseNodeId}.stP11.sUnit`;
|
||||||
|
},
|
||||||
|
negPresSegValueNodeId() {
|
||||||
|
return `${this.unitBaseNodeId}.stP21.rValue`;
|
||||||
|
},
|
||||||
|
negPresSegUnitNodeId() {
|
||||||
|
return `${this.unitBaseNodeId}.stP21.sUnit`;
|
||||||
|
},
|
||||||
|
posPresTankValueNodeId() {
|
||||||
|
return `${this.unitBaseNodeId}.stP12.rValue`;
|
||||||
|
},
|
||||||
|
posPresTankUnitNodeId() {
|
||||||
|
return `${this.unitBaseNodeId}.stP12.sUnit`;
|
||||||
|
},
|
||||||
|
negPresTankValueNodeId() {
|
||||||
|
return `${this.unitBaseNodeId}.stP22.rValue`;
|
||||||
|
},
|
||||||
|
negPresTankUnitNodeId() {
|
||||||
|
return `${this.unitBaseNodeId}.stP22.sUnit`;
|
||||||
|
},
|
||||||
|
posTempValueNodeId() {
|
||||||
|
return `${this.unitBaseNodeId}.stT11.rValue`;
|
||||||
|
},
|
||||||
|
posTempUnitNodeId() {
|
||||||
|
return `${this.unitBaseNodeId}.stT11.sUnit`;
|
||||||
|
},
|
||||||
|
negTempValueNodeId() {
|
||||||
|
return `${this.unitBaseNodeId}.stT21.rValue`;
|
||||||
|
},
|
||||||
|
negTempUnitNodeId() {
|
||||||
|
return `${this.unitBaseNodeId}.stT21.sUnit`;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
unitBaseNodeId: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
unitNumber: {
|
||||||
|
type: Number,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!-- ns=4;s=GVL_SCADA.stHMIInterface[1].stHMIInterfaceModule2.stHMIInterfaceUnit1.stE31.rValue -->
|
||||||
@@ -12,12 +12,15 @@ import App from './App.vue'
|
|||||||
|
|
||||||
// Composables
|
// Composables
|
||||||
import { createApp } from 'vue'
|
import { createApp } from 'vue'
|
||||||
|
import { createPinia } from 'pinia'
|
||||||
|
|
||||||
// Styles
|
// Styles
|
||||||
import 'unfonts.css'
|
import 'unfonts.css'
|
||||||
|
|
||||||
|
const pinia = createPinia()
|
||||||
const app = createApp(App)
|
const app = createApp(App)
|
||||||
|
|
||||||
registerPlugins(app)
|
registerPlugins(app)
|
||||||
|
|
||||||
|
app.use(pinia)
|
||||||
app.mount('#app')
|
app.mount('#app')
|
||||||
|
|||||||
169
src/stores/opcua.js
Normal file
169
src/stores/opcua.js
Normal file
@@ -0,0 +1,169 @@
|
|||||||
|
import { defineStore } from "pinia";
|
||||||
|
import msgpack from "@ygoe/msgpack";
|
||||||
|
|
||||||
|
export const useOpcuaStore = defineStore("opcua", {
|
||||||
|
state: () => ({
|
||||||
|
values: {},
|
||||||
|
opcuaEvents: new Map(),
|
||||||
|
ws: null,
|
||||||
|
connected: false,
|
||||||
|
subscriptions: new Set(),
|
||||||
|
opcuaDatatypes: {
|
||||||
|
Null: 0,
|
||||||
|
Boolean: 1,
|
||||||
|
SByte: 2,
|
||||||
|
Byte: 3,
|
||||||
|
Int16: 4,
|
||||||
|
UInt16: 5,
|
||||||
|
Int32: 6,
|
||||||
|
UInt32: 7,
|
||||||
|
Int64: 8,
|
||||||
|
UInt64: 9,
|
||||||
|
Float: 10,
|
||||||
|
Double: 11,
|
||||||
|
String: 12,
|
||||||
|
DateTime: 13,
|
||||||
|
Guid: 14,
|
||||||
|
ByteString: 15,
|
||||||
|
XmlElement: 16,
|
||||||
|
NodeId: 17,
|
||||||
|
ExpandedNodeId: 18,
|
||||||
|
StatusCode: 19,
|
||||||
|
QualifiedName: 20,
|
||||||
|
LocalizedText: 21,
|
||||||
|
ExtensionObject: 22,
|
||||||
|
DataValue: 23,
|
||||||
|
Variant: 24,
|
||||||
|
DiagnosticInfo: 25,
|
||||||
|
},
|
||||||
|
reconnectTimeout: null,
|
||||||
|
}),
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
connect() {
|
||||||
|
this.ws = new WebSocket("ws://localhost:8000/ws");
|
||||||
|
this.ws.binaryType = "arraybuffer";
|
||||||
|
|
||||||
|
this.ws.onopen = () => {
|
||||||
|
this.connected = true;
|
||||||
|
// Initiale Subscriptions senden
|
||||||
|
const msg = msgpack.encode({
|
||||||
|
subscribe: Array.from(this.subscriptions),
|
||||||
|
});
|
||||||
|
this.ws.send(msg);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.ws.onmessage = (event) => {
|
||||||
|
const data = msgpack.decode(new Uint8Array(event.data));
|
||||||
|
|
||||||
|
if (data.initial) {
|
||||||
|
Object.entries(data.initial.values).forEach(([tag, val]) => {
|
||||||
|
this.values[tag] = val;
|
||||||
|
});
|
||||||
|
Object.entries(data.initial.events).forEach(([tag, val]) => {
|
||||||
|
this.opcuaEvents.set(tag, val);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.u) {
|
||||||
|
Object.entries(data.u).forEach(([nodeId, val]) => {
|
||||||
|
this.values[nodeId] = val;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.e) {
|
||||||
|
console.log(data.e);
|
||||||
|
Object.entries(data.e).forEach(([nodeId, event]) => {
|
||||||
|
// Event is still relevant
|
||||||
|
if (event.Retain) {
|
||||||
|
let entry = {};
|
||||||
|
|
||||||
|
// If we already have an event with the same nodeId
|
||||||
|
if (this.opcuaEvents.has(nodeId)) {
|
||||||
|
entry = this.opcuaEventsget(nodeId);
|
||||||
|
entry.type = event.Severity;
|
||||||
|
//entry.message = event.message;
|
||||||
|
// check if it is still active
|
||||||
|
if (event.ActiveState) {
|
||||||
|
entry.raised = new Date(event.ActiveStateTransTime).toLocaleString("de-DE");
|
||||||
|
} else {
|
||||||
|
// If not, write the time to cleared
|
||||||
|
entry.cleared = new Date(event.ActiveStateTransTime).toLocaleString("de-DE");
|
||||||
|
}
|
||||||
|
if (event.ConfirmedState) {
|
||||||
|
entry.confirmed = new Date(event.ConfirmedStateTransTime).toLocaleString("de-DE");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
entry = {
|
||||||
|
type: event.Severity,
|
||||||
|
message: event.Message,
|
||||||
|
raised: new Date(event.ActiveStateTransTime).toLocaleString("de-DE"),
|
||||||
|
cleared: event.ActiveState ? "" : new Date(event.ActiveStateTransTime).toLocaleString("de-DE"),
|
||||||
|
confirmed: event.ConfirmedState ? new Date(event.ConfirmedStateTransTime).toLocaleString("de-DE") : "",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
this.opcuaEvents.set(nodeId, entry);
|
||||||
|
} else {
|
||||||
|
this.opcuaEvents.delete(nodeId);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Object.entries(data.e).forEach(([nodeId, val]) => {
|
||||||
|
// Event is not yet cleared
|
||||||
|
// if (val.Retain)
|
||||||
|
// {
|
||||||
|
// console.log(val)
|
||||||
|
// //this.opcuaEvents.set(nodeId) = val;
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// if (this.opcuaEvents.has(nodeId)) {
|
||||||
|
// this.opcuaEvents.delete(nodeId);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.ws.onclose = () => {
|
||||||
|
//this.reconnect();
|
||||||
|
this.connected = false;
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
reconnect() {
|
||||||
|
if (this.reconnectTimeout) return; // Verhindert mehrfachen Reconnect
|
||||||
|
this.reconnectTimeout = setTimeout(() => {
|
||||||
|
this.reconnectTimeout = null;
|
||||||
|
this.connect();
|
||||||
|
}, 3000);
|
||||||
|
},
|
||||||
|
|
||||||
|
subscribe(tags) {
|
||||||
|
tags.forEach((tag) => this.subscriptions.add(tag));
|
||||||
|
if (this.connected && this.ws) {
|
||||||
|
const msg = msgpack.encode({ subscribe: tags });
|
||||||
|
this.ws.send(msg);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
unsubscribe(tags) {
|
||||||
|
tags.forEach((tag) => this.subscriptions.delete(tag));
|
||||||
|
if (this.connected && this.ws) {
|
||||||
|
const msg = msgpack.encode({ unsubscribe: tags });
|
||||||
|
this.ws.send(msg);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
sendCommand(command) {
|
||||||
|
if (this.ws && this.connected) {
|
||||||
|
const msg = msgpack.encode({ command: command });
|
||||||
|
this.ws.send(msg);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
getValue(tag) {
|
||||||
|
return this.values[tag];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user