33 Commits

Author SHA1 Message Date
peterlu14 5af4215562 Merge remote-tracking branch 'origin/10-test' into dev/file_modal 2023-01-06 13:41:44 +08:00
peterlu14 4f94fcf541 [update] temp get all files 2023-01-06 13:40:59 +08:00
peterlu14 22afbab8ff [update] fix vue-router deploy apache problem 2023-01-06 13:40:16 +08:00
lai8928 ef22f1d20b [update]button link 2023-01-06 13:05:52 +08:00
peterlu14 99f401bac0 [update] router default page direct to data-analysis 2023-01-06 11:13:42 +08:00
peterlu14 3d751f746b [debug] temp fix typescript error 2023-01-06 11:12:49 +08:00
peterlu14 2df4ccf13c [update] fix channel 2023-01-06 10:42:20 +08:00
lai8928 0786113589 Merge remote-tracking branch 'origin/dev/file_modal' into 10-test 2023-01-04 10:19:33 +08:00
lai8928 7499f34dc7 change controller id 2023-01-04 10:17:52 +08:00
peterlu14 a65fea33a9 [update] change control panel to script setup & fix style error 2023-01-04 10:15:11 +08:00
peterlu14 90ba4b448a Merge remote-tracking branch 'origin/10-test' into dev/file_modal 2023-01-03 17:33:42 +08:00
lai8928 dfb3a96f84 [update] merge file modal 2023-01-03 16:50:40 +08:00
lai8928 58eecd80ae Merge remote-tracking branch 'origin/dev/file_modal' into 10-test 2022-12-30 15:58:27 +08:00
peterlu14 ec29b2fbc7 [update] show info 2022-12-30 15:20:11 +08:00
peterlu14 b8a7b39b62 [update] pass fileview-select & channel by create pinia store 2022-12-30 15:17:43 +08:00
peterlu14 4e041645a8 [update] channel X & Y select and emit 2022-12-30 09:53:35 +08:00
peterlu14 5fe5a64140 [update] import config table 2022-12-30 09:51:23 +08:00
peterlu14 746f4d98ec [update] restruct Device type & add getMetaFile 2022-12-30 09:48:47 +08:00
lai8928 4e8254e2d7 add csv download test 2022-12-29 14:09:05 +08:00
peterlu14 7043581335 [update] change-note 2022-12-29 11:42:35 +08:00
peterlu14 a0d8020787 [update] reformat file.ts & fileModal 2022-12-29 11:41:28 +08:00
peterlu14 6144b60541 [update] update change-note 2022-12-29 10:52:44 +08:00
peterlu14 42f5a37e4d [update] build file system for data analysis 2022-12-29 10:49:19 +08:00
lai8928 a9c59953f4 [fix] package.json lint command error 2022-12-09 11:12:30 +08:00
lai8928 93badd5ecf add mode input form 2022-12-09 11:09:13 +08:00
peterlu14 2b4f9bb90c [update] concat data from callback to charts & start button emit 2022-12-06 15:32:22 +08:00
peterlu14 63d0b4d79a [update] add chart api setOption & appendData & markLine & Loading 2022-12-06 14:13:02 +08:00
peterlu14 d7675c0b6a [update] add markLineComponent 2022-12-06 14:11:00 +08:00
peterlu14 1fc202c785 [update] add chart structure 2022-12-06 14:10:18 +08:00
peterlu14 804d95d493 [update] add line chart 2022-12-01 11:52:04 +08:00
peterlu14 8925bbe343 [update] add mqtt method publish & unique client_id 2022-12-01 10:33:19 +08:00
peterlu14 a64f0d93da [update] create new page data analysis 2022-12-01 09:56:15 +08:00
peterlu14 ac3b303b2e [update] import mqtt & echarts 2022-12-01 09:54:55 +08:00
63 changed files with 6521 additions and 7 deletions
+16
View File
@@ -0,0 +1,16 @@
### 2022.12.30
- file system
### 2022.12.06
- e-chart
- mqtt
- new page data-analysis
### 2022.11.30
- setup environment
- vite config add path
- import windicss
- add vue-shim.d.ts file (TS2307)
+288 -3
View File
@@ -1315,6 +1315,30 @@
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
"integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA=="
},
"bl": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
"integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
"dev": true,
"requires": {
"buffer": "^5.5.0",
"inherits": "^2.0.4",
"readable-stream": "^3.4.0"
},
"dependencies": {
"readable-stream": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
"integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
"dev": true,
"requires": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
"util-deprecate": "^1.0.1"
}
}
}
},
"boolbase": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
@@ -1395,6 +1419,16 @@
"update-browserslist-db": "^1.0.0"
}
},
"buffer": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
"integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
"dev": true,
"requires": {
"base64-js": "^1.3.1",
"ieee754": "^1.1.13"
}
},
"buffer-equal": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-0.0.1.tgz",
@@ -1555,6 +1589,16 @@
"integrity": "sha512-hv95iU5uXPbK83mjrJKuZyFM/LBAoCV/XhVGkS5Je6tl7sxr6A0ITMw5WoRV46/UaJ46Nllm3Xt7IaJhXTIkzw==",
"dev": true
},
"commist": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/commist/-/commist-1.1.0.tgz",
"integrity": "sha512-rraC8NXWOEjhADbZe9QBNzLAN5Q3fsTPQtBV+fEVj6xKIgDgNiEVE6ZNfHpZOqfQ21YUzfVNUXLOEZquYvQPPg==",
"dev": true,
"requires": {
"leven": "^2.1.0",
"minimist": "^1.1.0"
}
},
"concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
@@ -2029,6 +2073,31 @@
"readable-stream": "^2.0.2"
}
},
"duplexify": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.2.tgz",
"integrity": "sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==",
"dev": true,
"requires": {
"end-of-stream": "^1.4.1",
"inherits": "^2.0.3",
"readable-stream": "^3.1.1",
"stream-shift": "^1.0.0"
},
"dependencies": {
"readable-stream": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
"integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
"dev": true,
"requires": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
"util-deprecate": "^1.0.1"
}
}
}
},
"earcut": {
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/earcut/-/earcut-2.2.3.tgz",
@@ -2040,6 +2109,24 @@
"integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
"dev": true
},
"echarts": {
"version": "5.4.0",
"resolved": "https://registry.npmjs.org/echarts/-/echarts-5.4.0.tgz",
"integrity": "sha512-uPsO9VRUIKAdFOoH3B0aNg7NRVdN7aM39/OjovjO9MwmWsAkfGyeXJhK+dbRi51iDrQWliXV60/XwLA7kg3z0w==",
"dev": true,
"requires": {
"tslib": "2.3.0",
"zrender": "5.4.0"
},
"dependencies": {
"tslib": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz",
"integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==",
"dev": true
}
}
},
"electron-to-chromium": {
"version": "1.4.167",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.167.tgz",
@@ -2052,6 +2139,15 @@
"integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
"dev": true
},
"end-of-stream": {
"version": "1.4.4",
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
"integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
"dev": true,
"requires": {
"once": "^1.4.0"
}
},
"epic-spinners": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/epic-spinners/-/epic-spinners-2.0.0.tgz",
@@ -2685,9 +2781,9 @@
"dev": true
},
"follow-redirects": {
"version": "1.15.1",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz",
"integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA=="
"version": "1.15.2",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
"integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA=="
},
"form-data": {
"version": "4.0.0",
@@ -2855,6 +2951,29 @@
"integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
"dev": true
},
"help-me": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/help-me/-/help-me-3.0.0.tgz",
"integrity": "sha512-hx73jClhyk910sidBB7ERlnhMlFsJJIBqSVMFDwPN8o2v9nmp5KgLq1Xz1Bf1fCMMZ6mPrX159iG0VLy/fPMtQ==",
"dev": true,
"requires": {
"glob": "^7.1.6",
"readable-stream": "^3.6.0"
},
"dependencies": {
"readable-stream": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
"integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
"dev": true,
"requires": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
"util-deprecate": "^1.0.1"
}
}
}
},
"human-signals": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-3.0.1.tgz",
@@ -3027,6 +3146,12 @@
"integrity": "sha512-L3BJStEf5NAqNuzrpfbN71dp43mYIcBUlCRea/vdyv5dW/AYa1d4bpelko4SHdY3I6eN9Wzyasxirj1/vv5kmg==",
"dev": true
},
"js-sdsl": {
"version": "4.1.4",
"resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.4.tgz",
"integrity": "sha512-Y2/yD55y5jteOAmY50JbUZYwk3CP3wnLPEZnlR1w9oKhITrBEtAxwuWKebFf8hMrPMgbYwFoWK/lH2sBkErELw==",
"dev": true
},
"js-yaml": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
@@ -3132,6 +3257,12 @@
}
}
},
"leven": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz",
"integrity": "sha512-nvVPLpIHUxCUoRLrFqTgSxXJ614d8AgQoWl7zPe/2VadE8+1dpU3LBhowRuBAcuwruWtOdD8oYC9jDNJjXDPyA==",
"dev": true
},
"levn": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
@@ -3428,6 +3559,67 @@
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
"integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q=="
},
"mqtt": {
"version": "4.3.7",
"resolved": "https://registry.npmjs.org/mqtt/-/mqtt-4.3.7.tgz",
"integrity": "sha512-ew3qwG/TJRorTz47eW46vZ5oBw5MEYbQZVaEji44j5lAUSQSqIEoul7Kua/BatBW0H0kKQcC9kwUHa1qzaWHSw==",
"dev": true,
"requires": {
"commist": "^1.0.0",
"concat-stream": "^2.0.0",
"debug": "^4.1.1",
"duplexify": "^4.1.1",
"help-me": "^3.0.0",
"inherits": "^2.0.3",
"lru-cache": "^6.0.0",
"minimist": "^1.2.5",
"mqtt-packet": "^6.8.0",
"number-allocator": "^1.0.9",
"pump": "^3.0.0",
"readable-stream": "^3.6.0",
"reinterval": "^1.1.0",
"rfdc": "^1.3.0",
"split2": "^3.1.0",
"ws": "^7.5.5",
"xtend": "^4.0.2"
},
"dependencies": {
"concat-stream": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz",
"integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==",
"dev": true,
"requires": {
"buffer-from": "^1.0.0",
"inherits": "^2.0.3",
"readable-stream": "^3.0.2",
"typedarray": "^0.0.6"
}
},
"readable-stream": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
"integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
"dev": true,
"requires": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
"util-deprecate": "^1.0.1"
}
}
}
},
"mqtt-packet": {
"version": "6.10.0",
"resolved": "https://registry.npmjs.org/mqtt-packet/-/mqtt-packet-6.10.0.tgz",
"integrity": "sha512-ja8+mFKIHdB1Tpl6vac+sktqy3gA8t9Mduom1BA75cI+R9AHnZOiaBQwpGiWnaVJLDGRdNhQmFaAqd7tkKSMGA==",
"dev": true,
"requires": {
"bl": "^4.0.2",
"debug": "^4.1.1",
"process-nextick-args": "^2.0.1"
}
},
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
@@ -3504,6 +3696,16 @@
"boolbase": "^1.0.0"
}
},
"number-allocator": {
"version": "1.0.12",
"resolved": "https://registry.npmjs.org/number-allocator/-/number-allocator-1.0.12.tgz",
"integrity": "sha512-sGB0qoQGmKimery9JubBQ9pQUr1V/LixJAk3Ygp7obZf6mpSXime8d7XHEobbIimkdZpgjkNlLt6G7LPEWFYWg==",
"dev": true,
"requires": {
"debug": "^4.3.1",
"js-sdsl": "4.1.4"
}
},
"object-inspect": {
"version": "1.12.2",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz",
@@ -3721,6 +3923,16 @@
"resolved": "https://registry.npmjs.org/protocol-buffers-schema/-/protocol-buffers-schema-3.6.0.tgz",
"integrity": "sha512-TdDRD+/QNdrCGCE7v8340QyuXd4kIWIgapsE2+n/SaGiSSbomYl4TjHlvIoCWRpE7wFt02EpB35VVA2ImcBVqw=="
},
"pump": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
"integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
"dev": true,
"requires": {
"end-of-stream": "^1.1.0",
"once": "^1.3.1"
}
},
"punycode": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
@@ -3796,6 +4008,18 @@
"resolved": "https://registry.npmjs.org/regression/-/regression-2.0.1.tgz",
"integrity": "sha512-A4XYsc37dsBaNOgEjkJKzfJlE394IMmUPlI/p3TTI9u3T+2a+eox5Pr/CPUqF0eszeWZJPAc6QkroAhuUpWDJQ=="
},
"reinterval": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/reinterval/-/reinterval-1.1.0.tgz",
"integrity": "sha512-QIRet3SYrGp0HUHO88jVskiG6seqUGC5iAG7AwI/BV4ypGcuqk9Du6YQBUOUqm9c8pw1eyLoIaONifRua1lsEQ==",
"dev": true
},
"resize-detector": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/resize-detector/-/resize-detector-0.3.0.tgz",
"integrity": "sha512-R/tCuvuOHQ8o2boRP6vgx8hXCCy87H1eY9V5imBYeVNyNVpuL9ciReSccLj2gDcax9+2weXy3bc8Vv+NRXeEvQ==",
"dev": true
},
"resolve": {
"version": "1.22.1",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
@@ -4026,6 +4250,28 @@
"resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz",
"integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA=="
},
"split2": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz",
"integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==",
"dev": true,
"requires": {
"readable-stream": "^3.0.0"
},
"dependencies": {
"readable-stream": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
"integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
"dev": true,
"requires": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
"util-deprecate": "^1.0.1"
}
}
}
},
"ssf": {
"version": "0.11.2",
"resolved": "https://registry.npmjs.org/ssf/-/ssf-0.11.2.tgz",
@@ -4073,6 +4319,12 @@
}
}
},
"stream-shift": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz",
"integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==",
"dev": true
},
"string-argv": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz",
@@ -4352,6 +4604,16 @@
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.13.4.tgz",
"integrity": "sha512-KP4lq9uSz0KZbaqCllRhnxMV3mYRsRWJfdsAhZyt5bV5O1RTpoeDptBRV9NOa/JgOpfaA9ane88VF7OjWNK/DA=="
},
"vue-echarts": {
"version": "6.2.3",
"resolved": "https://registry.npmjs.org/vue-echarts/-/vue-echarts-6.2.3.tgz",
"integrity": "sha512-xHzUvgsgk/asJTcNa8iVVwoovZU3iEUHvmBa3bzbiP3Y6OMxM1YXsoWOKVmVVaUusGs4ob4pSwjwNy2FemAz9w==",
"dev": true,
"requires": {
"resize-detector": "^0.3.0",
"vue-demi": "^0.13.2"
}
},
"vue-eslint-parser": {
"version": "8.3.0",
"resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-8.3.0.tgz",
@@ -4512,6 +4774,12 @@
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
"dev": true
},
"ws": {
"version": "7.5.9",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz",
"integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==",
"dev": true
},
"xlsx": {
"version": "0.18.5",
"resolved": "https://registry.npmjs.org/xlsx/-/xlsx-0.18.5.tgz",
@@ -4575,6 +4843,23 @@
"dev": true
}
}
},
"zrender": {
"version": "5.4.0",
"resolved": "https://registry.npmjs.org/zrender/-/zrender-5.4.0.tgz",
"integrity": "sha512-rOS09Z2HSVGFs2dn/TuYk5BlCaZcVe8UDLLjj1ySYF828LATKKdxuakSZMvrDz54yiKPDYVfjdKqcX8Jky3BIA==",
"dev": true,
"requires": {
"tslib": "2.3.0"
},
"dependencies": {
"tslib": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz",
"integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==",
"dev": true
}
}
}
}
}
+4 -1
View File
@@ -8,7 +8,7 @@
"build": "npm run lint && vue-tsc --noEmit && vite build",
"build:ci": "vite build",
"prelint": "npm run format",
"lint": "eslint --fix './src/**/*.{ts,js,vue}'",
"lint": "eslint --fix \"./src/**/*.{ts,js,vue}\"",
"format": "prettier --write .",
"preview": "vite preview"
},
@@ -52,16 +52,19 @@
"@vue/eslint-config-prettier": "^7.0.0",
"@vue/eslint-config-typescript": "^10.0.0",
"autoprefixer": "^10.4.4",
"echarts": "^5.4.0",
"eslint": "^8.13.0",
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-vue": "^8.7.0",
"husky": "^8.0.1",
"lint-staged": "^13.0.1",
"mqtt": "^4.3.7",
"postcss": "^8.4.12",
"prettier": "^2.6.2",
"typescript": "^4.5.4",
"vite": "^2.9.9",
"vite-plugin-windicss": "^1.8.8",
"vue-echarts": "^6.2.3",
"vue-eslint-parser": "^8.3.0",
"vue-tsc": "^1.0.10",
"windicss": "^3.5.6"
@@ -0,0 +1,96 @@
<template>
<div>
<va-card class="h-full">
<va-card-content>
<va-select
v-model="simpleSelectModel"
:label="'Filter Mode'"
text-by="description"
track-by="id"
:options="simpleOptions"
/>
<va-card-content>
<div v-if="simpleSelectModel.id === 1">
<va-slider v-model="VTModeModel" label="percentage(%)" track-label-visible :min="0" :max="50" />
</div>
<div v-else-if="simpleSelectModel.id === 2">
<va-slider v-model="slopModeModel" label="1D window" track-label-visible :min="1" :max="50" />
</div>
<div v-else></div>
<div>
<p>{{ channel.xAxis }}</p>
<p>{{ channel.yAxis }}</p>
<p>{{ fileView.filesSelected }}</p>
</div>
</va-card-content>
<va-button class="mt-2" @click="filterData">Start</va-button>
<!-- <div v-if="simpleSelectModel.id === 1">
<va-button>test</va-button>
<va-input></va-input>
</div> -->
</va-card-content>
</va-card>
</div>
</template>
<script setup lang="ts">
import { useChannelStore } from '@/stores/data-analysis/channel'
import { useFileViewStore } from '@/stores/data-analysis/file-view'
import { Ref, ref, defineEmits, defineExpose } from 'vue'
// define emit
// const emit = defineEmits({
// 'filter-data': ({ mode, data_id, data_channel, data }) => {
// return { mode, data_id, data_channel, data }
// },
// })
const emit = defineEmits(['filter-data'])
const channel = useChannelStore()
const fileView = useFileViewStore()
const VTModeModel = ref(10)
const slopModeModel = ref(20)
const simpleSelectModel: Ref<{ id: number; description: string } | Record<string, never>> = ref({})
const simpleOptions = ref([
{
id: 1,
description: 'V-T Mode',
},
{
id: 2,
description: '1st Order Differential',
},
{
id: 3,
description: 'Third option',
},
])
const filterData = function () {
console.log(VTModeModel.value)
const a = 0
console.log(a)
// switch(simpleSelectModel.value.id) {
// case 1:
// const return_data = { mode: 1, data_id: 166, data: { persentage: 0 } };
// case 2:
// const return_data = { mode: 2, data_id: 166, data: { persentage: 0 } };
// default:
// }
// console.log(return_data)
emit('filter-data', {
mode: simpleSelectModel.value.id,
data_id: fileView.filesSelected,
data_channel: [channel.xAxis.id, channel.yAxis.id],
data: { persentage: VTModeModel.value, window: slopModeModel.value },
})
}
defineExpose({
simpleSelectModel,
simpleOptions,
VTModeModel,
slopModeModel,
filterData,
})
</script>
<style lang=""></style>
@@ -0,0 +1,31 @@
<template>
<va-card class="">
<div class="h-200px">
<va-button @click="showModal">FILE</va-button>
<p>Meta: {{ fileView.filesSelected }}</p>
<p>X: {{ channel.xAxis }}</p>
<p>Y: {{ channel.yAxis }}</p>
<Suspense>
<FileModal ref="file_modal_ref"></FileModal>
</Suspense>
</div>
</va-card>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { useChannelStore } from '@/stores/data-analysis/channel'
import { useFileViewStore } from '@/stores/data-analysis/file-view'
import FileModal from '@/components/data-analysis/FileModal.vue'
const channel = useChannelStore()
const fileView = useFileViewStore()
/* File Modal Handling */
let file_modal_ref = ref<InstanceType<typeof FileModal> | null>(null)
const showModal = function () {
file_modal_ref.value?.showModal()
}
defineExpose({ file_modal_ref, showModal })
</script>
+212
View File
@@ -0,0 +1,212 @@
<template>
<div>
<va-modal v-model="show" :fixed-layout="true" size="large" @before-open="initLoad">
<!-- File Container-->
<div class="h-[75vh] w-[50vw]">
<!-- Control Bar -->
<div class="d-flex align-center">
<va-input v-model="filter" placeholder="Filter..." class="mr-3" style="flex: 0 200px" clearable />
<va-checkbox v-model="isFilterCaseSensitive" class="mr-3" label="Case sensitive" />
<va-button-group class="mr-3">
<va-button @click="changeFileView('time')">Time</va-button>
<va-button @click="changeFileView('folder')">Folder</va-button>
<va-button @click="changeFileView('project')">Project</va-button>
</va-button-group>
<va-button-group>
<va-button @click="expandAll(true)">Expand</va-button>
<va-button @click="expandAll(false)">Close</va-button>
</va-button-group>
</div>
<!-- File Window-->
<div class="grid grid-cols-4 gap-6">
<!-- File View-->
<div class="h-full col-span-3">
<va-tree-view
v-model:checked="selectedNodes"
v-model:expanded="expanedNodes"
:nodes="treeNodes"
class="customizable-content"
:filter="filter"
:filter-method="customFilterMethod"
:track-by="'idType'"
:value-by="'idType'"
selectable
>
<template #content="node">
<div class="align-center">
<va-icon v-if="node.type === 'Folder' && node.expanded === false" class="fas fa-folder mr-2" />
<va-icon v-if="node.type === 'Folder' && node.expanded === true" class="fas fa-folder-open mr-2" />
<va-icon v-if="node.type === 'MetaFile'" class="fas fa-file mr-2" />
<template v-if="node.type !== 'MetaFile'">{{ node.name }}</template>
<template v-if="node.type === 'MetaFile'">
{{ node.name }}
</template>
</div>
</template>
</va-tree-view>
</div>
<!-- Channel & Group setting-->
<div class="h-full col-span-1">
<div>
X-Axis
<va-select v-model="channel.xAxis" :text-by="'name'" :options="options"></va-select>
</div>
<div>
Y-Axis
<va-select v-model="channel.yAxis" :text-by="'name'" :options="options"></va-select>
</div>
</div>
</div>
</div>
</va-modal>
</div>
</template>
<script setup lang="ts">
import { Ref, ref, computed, watch } from 'vue'
import { FileView, Project, MetaFile, Folder, Time } from '@/utils/file'
import configTable from '@/data/config-table/index'
import { useChannelStore } from '@/stores/data-analysis/channel'
import { useFileViewStore } from '@/stores/data-analysis/file-view'
// emit
const emit = defineEmits({
filesSelected: ({ metas, channel }) => {
return { metas, channel }
},
})
function emitFilesSelected(meta: string[], channel: { x: object; y: object }) {
emit('filesSelected', { meta, channel })
}
// filter function
const customFilterMethod = computed(() => {
return (node: Project | MetaFile, filterText: string) => {
// console.log('customFilterMethod', node, filterText, key, node.name.includes(filterText))
return node.name.includes(filterText)
}
})
// handling show modal
let show = ref(false)
const showModal = function () {
show.value = !show.value
}
// handling fileView
const fileViewStore = useFileViewStore()
const fileView = new FileView()
// handling tree-view
const filter = ref('')
const isFilterCaseSensitive = ref(false)
const selectedNodes: Ref<(never | string)[]> = ref([])
const expanedNodes: Ref<(never | string)[]> = ref([])
const treeNodes: Ref<(never | Project | Folder | Time | MetaFile)[]> = ref([])
const initLoad = async function () {
if (treeNodes.value.length === 0) {
await initLoadFileView()
initLoadNodes()
}
}
const initLoadFileView = async function () {
await fileView.appendChildren(1)
}
const initLoadNodes = function () {
const files = fileView.getChildren()
if (files.length > 0) {
treeNodes.value.push(...files)
expanedNodes.value.push(treeNodes.value[0].idType)
}
}
const reset = function () {
resetFileView()
resetNodes()
}
const resetFileView = function () {
fileView.reset()
}
const resetNodes = function () {
selectedNodes.value.length = 0
expanedNodes.value.length = 0
treeNodes.value.length = 0
}
// handling modal header
const changeFileView = async function (view: string) {
// reset fileView
fileView.changeView(view)
await fileView.appendChildren(1)
// reset treeNodes & expandedNodes & selectedNodes
treeNodes.value.length = 0
treeNodes.value.push(...fileView.getChildren())
expanedNodes.value.length = 0
expanedNodes.value.push(treeNodes.value[0].idType)
// selectedNodes.value.length = 0
}
const expandAll = function (expandOrNot: boolean) {
expanedNodes.value.length = 0
if (!expandOrNot) return
for (const node of treeNodes.value) {
expanedNodes.value.push(node.idType)
}
}
// handling channel options
const channel = useChannelStore()
let options: any[] = []
// watch selectedNodes to decide axis options
watch(selectedNodes, (newSelectedNodes, oldSelectedNodes) => {
// update fileViewStore.filesSelected
fileViewStore.filesSelected.length = 0
fileViewStore.filesSelected.push(...newSelectedNodes.filter((x) => x.includes('MetaFile')))
// 新的要filter掉舊的沒有的
const newNodes = newSelectedNodes.filter((x) => x.includes('MetaFile') && !oldSelectedNodes.includes(x))
const MetFileList = []
for (const node of newNodes) {
const meta = fileView.getMetaFile(node)
MetFileList.push(meta)
}
console.log('MetFileList', MetFileList)
if (MetFileList[0]) {
// console.log(MetFileList[0].device.library_name, MetFileList[0].parameter.MODE)
// console.log(configTable.getConfig(MetFileList[0].device.library_name))
const config: any = configTable.getModeConfig(MetFileList[0].device.library_name, MetFileList[0].parameter.MODE)
const channel = Object.values(config.channels)
const channelOptions = channel.map((v: any, idx) => {
v.id = idx
return v
})
console.log('channelOptions', channelOptions)
options.length = 0
options.push(...channelOptions)
}
})
defineExpose({
emitFilesSelected,
show,
showModal,
changeFileView,
expandAll,
reset,
initLoad,
treeNodes,
expanedNodes,
selectedNodes,
})
</script>
<style lang="scss"></style>
@@ -0,0 +1,63 @@
<template>
<div>
<va-card class="h-full">
<va-card-content class="h-full w-full">
<EChart ref="chart_ref" :option="option" :autoresize="true" :loading="loading" />
</va-card-content>
</va-card>
</div>
</template>
<script setup lang="ts">
import LineChart from '@/data/echart/composables/LineChart'
import { EChartsCoreOption } from 'echarts'
import { ref } from 'vue'
const loading = ref(false)
const { chart_ref, option } = LineChart()
const setOption = function (option: EChartsCoreOption) {
chart_ref.value?.setOption(option)
}
const appendData = function (seriesIndex: number, data: Array<number | string>) {
chart_ref.value?.appendData({
seriesIndex: seriesIndex,
data: data,
})
chart_ref.value?.resize()
}
const markLine = function (
seriesIndex: number,
markLineIndex: number,
header: string,
value: number | Array<number> | string,
) {
chart_ref.value?.setOption({
series: [
{
markLine: {
data: [{ name: header, yAxis: value }],
},
},
],
})
}
const startLoading = function () {
loading.value = true
}
const stopLoading = function () {
loading.value = false
}
defineExpose({
startLoading,
stopLoading,
setOption,
appendData,
markLine,
})
</script>
<style lang=""></style>
+37
View File
@@ -0,0 +1,37 @@
import MQTT from '@/utils/mqtt'
import type { OnMessageCallback } from 'mqtt'
import { onUnmounted, ref } from 'vue'
export default function useMqtt() {
const PublicMqtt = ref<MQTT | null>(null)
const startMqtt = (val: string, callback: OnMessageCallback) => {
// set mqtt topic
PublicMqtt.value = new MQTT(val)
// init mqtt
PublicMqtt.value.init()
// link mqtt
PublicMqtt.value.link()
getMessage(callback)
}
const publish = (topic: string, message: string) => {
PublicMqtt.value?.publish(topic, message)
}
const getMessage = (callback: OnMessageCallback) => {
// PublicMqtt.value?.client.on('message', callback);
PublicMqtt.value?.get(callback)
}
onUnmounted(() => {
if (PublicMqtt.value) {
PublicMqtt.value.unsubscribes()
PublicMqtt.value.over()
}
})
return {
startMqtt,
publish,
}
}
+13
View File
@@ -0,0 +1,13 @@
import axios, { Axios } from 'axios'
export const setBaseURL = function (baseURL: string) {
if (baseURL) {
axios.defaults.baseURL = `http://${baseURL}:3000`
}
}
setBaseURL(location.href.split('/')[2].split(':')[0])
export const getAxios = function (): Axios {
return axios
}
+20
View File
@@ -0,0 +1,20 @@
export default {
name: 'Idle',
parameter: [], // 這個mode用到的參數
showParameter: [], // 有要秀給user看的參數
headerParameter: () => [], // export header的參數
valScales: {
linear: {
func: (val) => {
return val
},
},
log: {
func: (val) => {
return Math.log10(Math.abs(val))
},
},
},
channels: {},
charts: {},
}
+94
View File
@@ -0,0 +1,94 @@
export default {
name: 'Cali Mode - test',
parameter: ['ADC_DAC_CHANNEL_15', 'ADC_LEVEL_I_15', 'ADC_LEVEL_V_IN_15', 'DAC_LEVEL_V_OUT_15', 'DAC_VOLT_BUTTON'], // 這個mode用到的參數
showParameter: ['ADC_DAC_CHANNEL_15', 'ADC_LEVEL_I_15', 'ADC_LEVEL_V_IN_15', 'DAC_LEVEL_V_OUT_15', 'DAC_VOLT_BUTTON'], // 有要秀給user看的參數
headerParameter: () => [
'ADC_DAC_CHANNEL_15',
'ADC_LEVEL_I_15',
'ADC_LEVEL_V_IN_15',
'DAC_LEVEL_V_OUT_15',
'DAC_VOLT_BUTTON',
], // export header的參數
valScales: {
linear: {
func: (val) => {
return val
},
},
log: {
func: (val) => {
return Math.log10(Math.abs(val))
},
},
},
channels: {
time: {
name: 'Time',
unit: {
us: 1,
ms: 1e3,
s: 1e6,
m: 60 * 1e6,
h: 60 * 60 * 1e6,
auto: 1,
},
defaultUnit: 'us',
},
0: {
name: 'I_in',
unit: {
nA: 1,
},
defaultUnit: 'nA',
},
1: {
name: 'V_in/V_out',
unit: {
uV: 1,
},
defaultUnit: 'uV',
},
2: {
name: 'Gain',
unit: {
default: 1,
},
defaultUnit: 'default',
},
},
charts: {
default: [
{
name: 'Cali Mode - test',
description: '',
subplot: [
{
x1: {
type: 'time',
valScale: 'linear',
min: 'dataMin',
max: 'dataMax',
},
y1: {
type: 'value',
valScale: 'linear',
min: 'dataMin',
max: 'dataMax',
},
data: [
{
legend: 'ADC',
x1: {
channel: 'time',
},
y1: {
channel: 0,
},
},
],
},
],
},
],
},
}
+87
View File
@@ -0,0 +1,87 @@
export default {
name: 'Cali DAC - test',
parameter: ['CTRL_HIGH_Z_15', 'DAC_VOLT'], // 這個mode用到的參數
showParameter: ['CTRL_HIGH_Z_15', 'DAC_VOLT'], // 有要秀給user看的參數
valScales: {
linear: {
func: (val) => {
return val
},
},
log: {
func: (val) => {
return Math.log10(Math.abs(val))
},
},
},
channels: {
time: {
name: 'Time',
unit: {
us: 1,
ms: 1e3,
s: 1e6,
m: 60 * 1e6,
h: 60 * 60 * 1e6,
auto: 1,
},
defaultUnit: 'us',
},
0: {
name: 'I_in',
unit: {
nA: 1,
},
defaultUnit: 'nA',
},
1: {
name: 'V_in/V_out',
unit: {
uV: 1,
},
defaultUnit: 'uV',
},
2: {
name: 'Gain',
unit: {
default: 1,
},
defaultUnit: 'default',
},
},
charts: {
default: [
{
name: 'Cali DAC - test',
description: '',
subplot: [
{
x1: {
type: 'time',
valScale: 'linear',
min: 'dataMin',
max: 'dataMax',
},
y1: {
type: 'value',
valScale: 'linear',
min: 'dataMin',
max: 'dataMax',
},
data: [
{
legend: 'DAC',
x1: {
channel: 'time',
},
y1: {
channel: 0,
},
},
],
},
],
},
],
},
}
@@ -0,0 +1,97 @@
export default {
name: 'Chronoamperometry',
parameter: ['CA_VOLT', 'SAMPLE_RATE', 'ADC_LEVEL_I_15', 'ADC_LEVEL_V_IN_15', 'CTRL_HIGH_Z_15', 'TIME_DURATION'], // 這個mode用到的參數
showParameter: ['ADC_LEVEL_I_15', 'ADC_LEVEL_V_IN_15', 'CTRL_HIGH_Z_15', 'CA_VOLT', 'SAMPLE_RATE', 'TIME_DURATION'], // 有要秀給user看的參數
headerParameter: () => ['CA_VOLT', 'SAMPLE_RATE', 'ADC_LEVEL_I_15', 'ADC_LEVEL_V_IN_15', 'TIME_DURATION'], // 有要秀給user看的參數
valScales: {
linear: {
func: (val) => {
return val
},
},
log: {
func: (val) => {
return Math.log10(Math.abs(val))
},
},
},
channels: {
time: {
name: 'Time',
unit: {
us: 1,
ms: 1e3,
s: 1e6,
minute: 60 * 1e6,
hour: 60 * 60 * 1e6,
},
defaultUnit: 'ms',
downloadUnit: 'ms',
},
0: {
name: 'I_in',
unit: {
nA: 1,
uA: 1e3,
mA: 1e6,
},
defaultUnit: 'mA',
downloadUnit: 'mA',
},
1: {
name: 'Potential',
unit: {
uV: 1,
mV: 1e3,
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'mV',
},
2: {
name: 'V_out',
unit: {
uV: 1,
mV: 1e3,
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'mV',
},
},
charts: {
default: [
{
name: 'Chronoamperometric',
description: '',
subplot: [
{
x1: {
type: 'time',
valScale: 'linear',
min: 'dataMin',
max: 'dataMax',
},
y1: {
type: 'value',
valScale: 'linear',
min: 'dataMin',
max: 'dataMax',
},
data: [
{
legend: 'chrono',
x1: {
channel: 'time',
},
y1: {
channel: 0,
},
},
],
},
],
},
],
},
}
@@ -0,0 +1,167 @@
export default {
name: 'Chronopotentiometry',
parameter: [
'Charge',
'Const_Current_value',
'SAMPLE_RATE',
'VOLTSTOP_MAX',
'VOLTSTOP_MIN',
'CC_CP_SPEED',
'ADC_LEVEL_I_15',
'ADC_LEVEL_V_IN_15',
'TIME_DURATION',
], // 這個mode用到的參數
showParameter: [
'ADC_LEVEL_I_15',
'ADC_LEVEL_V_IN_15',
'CTRL_HIGH_Z_15',
'SAMPLE_RATE',
'Charge',
'Const_Current_value',
'VOLTSTOP_MAX',
'VOLTSTOP_MIN',
'TIME_DURATION',
], // 有要秀給user看的參數
headerParameter: () => [
'Charge',
'Const_Current_value',
'SAMPLE_RATE',
'VOLTSTOP_MAX',
'VOLTSTOP_MIN',
'CC_CP_SPEED',
'ADC_LEVEL_I_15',
'ADC_LEVEL_V_IN_15',
'TIME_DURATION',
], // 有要秀給user看的參數
valScales: {
linear: {
func: (val) => {
return val
},
},
log: {
func: (val) => {
return Math.log10(Math.abs(val))
},
},
},
channels: {
time: {
name: 'Time',
unit: {
us: 1,
ms: 1e3,
s: 1e6,
minute: 60 * 1e6,
hour: 60 * 60 * 1e6,
},
defaultUnit: 'ms',
downloadUnit: 'ms',
},
0: {
name: 'I_in',
unit: {
nA: 1,
uA: 1e3,
mA: 1e6,
},
defaultUnit: 'mA',
downloadUnit: 'mA',
},
1: {
name: 'Potential',
unit: {
uV: 1,
mV: 1e3,
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'mV',
},
2: {
name: 'V_out',
unit: {
uV: 1,
mV: 1e3,
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'mV',
},
3: {
name: 'sum_cnt',
unit: {
uV: 1,
mV: 1e3,
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'uV',
},
4: {
name: 'sum_adc_delta_Iin',
unit: {
uV: 1,
mV: 1e3,
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'uV',
},
5: {
name: 'sum_adc_delta_Voutin',
unit: {
uV: 1,
mV: 1e3,
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'uV',
},
6: {
name: 'resis',
unit: {
uV: 1,
mV: 1e3,
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'uV',
},
},
charts: {
default: [
{
name: 'Chronopotentiometry',
description: '',
subplot: [
{
x1: {
type: 'time',
valScale: 'linear',
min: 'dataMin',
max: 'dataMax',
},
y1: {
type: 'value',
valScale: 'linear',
min: 'dataMin',
max: 'dataMax',
},
data: [
{
legend: 'CP',
x1: {
channel: 'time',
},
y1: {
channel: 1,
},
},
],
},
],
},
],
},
}
@@ -0,0 +1,127 @@
export default {
name: 'Constant Current',
parameter: [
'Charge',
'Const_Current_value',
'SAMPLE_RATE',
'VOLTSTOP_MAX',
'VOLTSTOP_MIN',
'CC_CP_SPEED',
'ADC_LEVEL_I_15',
'ADC_LEVEL_V_IN_15',
'TIME_DURATION',
], // 這個mode用到的參數
showParameter: [
'ADC_LEVEL_I_15',
'ADC_LEVEL_V_IN_15',
'CTRL_HIGH_Z_15',
'SAMPLE_RATE',
'Charge',
'Const_Current_value',
'VOLTSTOP_MAX',
'VOLTSTOP_MIN',
'TIME_DURATION',
], // 有要秀給user看的參數
headerParameter: () => [
'Charge',
'Const_Current_value',
'SAMPLE_RATE',
'VOLTSTOP_MAX',
'VOLTSTOP_MIN',
'CC_CP_SPEED',
'ADC_LEVEL_I_15',
'ADC_LEVEL_V_IN_15',
'TIME_DURATION',
], // 有要秀給user看的參數
valScales: {
linear: {
func: (val) => {
return val
},
},
log: {
func: (val) => {
return Math.log10(Math.abs(val))
},
},
},
channels: {
time: {
name: 'Time',
unit: {
us: 1,
ms: 1e3,
s: 1e6,
minute: 60 * 1e6,
hour: 60 * 60 * 1e6,
},
defaultUnit: 'ms',
downloadUnit: 'ms',
},
0: {
name: 'I_in',
unit: {
nA: 1,
uA: 1e3,
mA: 1e6,
},
defaultUnit: 'mA',
downloadUnit: 'mA',
},
1: {
name: 'V_in',
unit: {
uV: 1,
mV: 1e3,
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'mV',
},
2: {
name: 'V_out',
unit: {
uV: 1,
mV: 1e3,
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'mV',
},
},
charts: {
default: [
{
name: 'Constant Current',
description: '',
subplot: [
{
x1: {
type: 'time',
valScale: 'linear',
min: 'dataMin',
max: 'dataMax',
},
y1: {
type: 'value',
valScale: 'linear',
min: 'dataMin',
max: 'dataMax',
},
data: [
{
legend: 'CC',
x1: {
channel: 'time',
},
y1: {
channel: 1,
},
},
],
},
],
},
],
},
}
+134
View File
@@ -0,0 +1,134 @@
export default {
name: 'Cycle I-V',
parameter: [
'VOLT_ORIGIN',
'VOLT_FINAL',
'VOLT_STEP',
'STEP_TIME',
'SAMPLE_RATE',
'CYCLE_NUMBER',
'ADC_LEVEL_I_15',
'ADC_LEVEL_V_IN_15',
'CTRL_HIGH_Z_15',
], // 這個mode用到的參數
showParameter: [
'ADC_LEVEL_I_15',
'ADC_LEVEL_V_IN_15',
'CTRL_HIGH_Z_15',
'VOLT_ORIGIN',
'VOLT_FINAL',
'VOLT_STEP',
'STEP_TIME',
'SAMPLE_RATE',
'CYCLE_NUMBER',
], // 有要秀給user看的參數
headerParameter: () => [
'VOLT_ORIGIN',
'VOLT_FINAL',
'VOLT_STEP',
'STEP_TIME',
'SAMPLE_RATE',
'CYCLE_NUMBER',
'ADC_LEVEL_I_15',
'ADC_LEVEL_V_IN_15',
], // export header的參數
valScales: {
linear: {
func: (val) => {
return val
},
},
log: {
func: (val) => {
return Math.log10(Math.abs(val))
},
},
},
channels: {
time: {
name: 'Time',
unit: {
us: 1,
ms: 1e3,
s: 1e6,
minute: 60 * 1e6,
hour: 60 * 60 * 1e6,
},
defaultUnit: 'ms',
downloadUnit: 'ms',
},
0: {
name: 'I_in',
unit: {
nA: 1,
uA: 1e3,
mA: 1e6,
},
defaultUnit: 'mA',
downloadUnit: 'mA',
},
1: {
name: 'V_out',
unit: {
uV: 1,
mV: 1e3,
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'mV',
},
2: {
name: 'V_in',
unit: {
uV: 1,
mV: 1e3,
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'mV',
},
3: {
name: 'Cycle number',
unit: {
cycle: 1,
},
defaultUnit: 'cycle',
downloadUnit: null,
},
},
charts: {
default: [
{
name: 'Cycle I-V',
description: '',
subplot: [
{
x1: {
type: 'value',
valScale: 'linear',
min: 'dataMin',
max: 'dataMax',
},
y1: {
type: 'value',
valScale: 'linear',
min: 'dataMin',
max: 'dataMax',
},
data: [
{
legend: 'CycleIV',
x1: {
channel: 1,
},
y1: {
channel: 0,
},
},
],
},
],
},
],
},
}
@@ -0,0 +1,134 @@
export default {
name: 'Cyclic Voltammetry',
parameter: [
'VOLT_INITIAL',
'VOLT_MAX',
'VOLT_MIN',
'Scan_Rate',
'SAMPLE_RATE',
'CYCLE_NUMBER',
'ADC_LEVEL_I_15',
'ADC_LEVEL_V_IN_15',
'CTRL_HIGH_Z_15',
], // 這個mode用到的參數
showParameter: [
'ADC_LEVEL_I_15',
'ADC_LEVEL_V_IN_15',
'CTRL_HIGH_Z_15',
'VOLT_INITIAL',
'VOLT_MAX',
'VOLT_MIN',
'Scan_Rate',
'SAMPLE_RATE',
'CYCLE_NUMBER',
], // 有要秀給user看的參數
headerParameter: () => [
'VOLT_INITIAL',
'VOLT_MAX',
'VOLT_MIN',
'Scan_Rate',
'SAMPLE_RATE',
'CYCLE_NUMBER',
'ADC_LEVEL_I_15',
'ADC_LEVEL_V_IN_15',
], // 有要秀給user看的參數
valScales: {
linear: {
func: (val) => {
return val
},
},
log: {
func: (val) => {
return Math.log10(Math.abs(val))
},
},
},
channels: {
time: {
name: 'Time',
unit: {
us: 1,
ms: 1e3,
s: 1e6,
m: 60 * 1e6,
h: 60 * 60 * 1e6,
},
defaultUnit: 'ms',
downloadUnit: 'ms',
},
0: {
name: 'I_in',
unit: {
nA: 1,
uA: 1e3,
mA: 1e6,
},
defaultUnit: 'mA',
downloadUnit: 'mA',
},
1: {
name: 'Potential',
unit: {
uV: 1,
mV: 1e3,
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'mV',
},
2: {
name: 'V_out',
unit: {
uV: 1,
mV: 1e3,
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'mV',
},
3: {
name: 'Cycle number',
unit: {
cycle: 1,
},
defaultUnit: 'cycle',
downloadUnit: null,
},
},
charts: {
default: [
{
name: 'Cyclic Voltammetry',
description: '',
subplot: [
{
x1: {
type: 'value',
valScale: 'linear',
min: 'dataMin',
max: 'dataMax',
},
y1: {
type: 'value',
valScale: 'linear',
min: 'dataMin',
max: 'dataMax',
},
data: [
{
legend: 'CV',
x1: {
channel: 1,
},
y1: {
channel: 0,
},
},
],
},
],
},
],
},
}
+135
View File
@@ -0,0 +1,135 @@
export default {
name: 'Differential Pulse Voltammetry',
parameter: ['DPV_e_init', 'DPV_e_final', 'DPV_increment', 'DPV_amp', 'DPV_pul_width', 'DPV_step_time'], // 這個mode用到的參數
parameterInMode: {
0: ['DPV_e_init', 'DPV_e_final', 'DPV_increment', 'DPV_amp', 'DPV_pul_width', 'DPV_step_time'],
1: [
'DPV_e_init',
'DPV_e_1',
'DPV_e_2',
'DPV_e_final',
'DPV_increment',
'DPV_amp',
'DPV_pul_width',
'DPV_step_time',
'CYCLE_NUMBER',
'DPV_pulse_option',
'DPV_curr_rec',
],
2: [
'DPV_e_init',
'DPV_e_final',
'DPV_increment',
'DPV_amp',
'DPV_pul_width',
'DPV_step_time',
'CYCLE_NUMBER',
'DPV_notify_rate',
'DPV_engineering_enable',
'DPV_e_1',
'DPV_e_2',
'DPV_pulse_option',
],
}, // 這個mode用到的參數
showParameter: [], // 有要秀給user看的參數
headerParameter: () => [], // export header的參數
valScales: {
linear: {
func: (val) => {
return val
},
},
log: {
func: (val) => {
return Math.log10(Math.abs(val))
},
},
},
channels: {
time: {
name: 'Time',
unit: {
us: 1,
ms: 1e3,
s: 1e6,
minute: 60 * 1e6,
hour: 60 * 60 * 1e6,
},
defaultUnit: 'ms',
downloadUnit: 'ms',
},
0: {
name: 'I_in',
unit: {
nA: 1,
uA: 1e3,
mA: 1e6,
},
defaultUnit: 'mA',
downloadUnit: 'mA',
},
1: {
name: 'Potential',
unit: {
uV: 1,
mV: 1e3,
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'mV',
},
2: {
name: 'V_out',
unit: {
uV: 1,
mV: 1e3,
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'mV',
},
3: {
name: 'Cycle number',
unit: {
cycle: 1,
},
defaultUnit: 'cycle',
downloadUnit: null,
},
},
charts: {
default: [
{
name: 'Open Circuit Potential',
description: '',
subplot: [
{
x1: {
type: 'time',
valScale: 'linear',
min: 'dataMin',
max: 'dataMax',
},
y1: {
type: 'value',
valScale: 'linear',
min: 'dataMin',
max: 'dataMax',
},
data: [
{
legend: 'OCP',
x1: {
channel: 'time',
},
y1: {
channel: 1,
},
},
],
},
],
},
],
},
}
+93
View File
@@ -0,0 +1,93 @@
export default {
name: 'Dev Mode',
parameter: ['ADC_VALUE_I'],
valScales: {
linear: {
func: (val) => {
return val
},
},
log: {
func: (val) => {
return Math.log10(Math.abs(val))
},
},
},
channels: {
time: {
name: 'Time',
unit: {
us: 1,
ms: 1e3,
s: 1e6,
m: 60 * 1e6,
h: 60 * 60 * 1e6,
auto: 1,
},
defaultUnit: 'auto',
},
0: {
name: '0',
unit: {
default: 1,
},
defaultUnit: 'default',
},
1: {
name: '1',
unit: {
default: 1,
},
defaultUnit: 'default',
},
2: {
name: '2',
unit: {
default: 1,
},
defaultUnit: 'default',
},
3: {
name: '3',
unit: {
default: 1,
},
defaultUnit: 'default',
},
},
charts: {
default: [
{
name: 'Dev Mode',
description: '',
subplot: [
{
x1: {
type: 'time',
valScale: 'linear',
min: 'dataMin',
max: 'dataMax',
},
y1: {
type: 'value',
valScale: 'linear',
min: 'dataMin',
max: 'dataMax',
},
data: [
{
legend: 'dev',
x1: {
channel: 'time',
},
y1: {
channel: 1,
},
},
],
},
],
},
],
},
}
@@ -0,0 +1,97 @@
export default {
name: 'Function Generator',
parameter: ['DAC_VOLT', 'SAMPLE_RATE', 'ADC_LEVEL_I_15', 'ADC_LEVEL_V_IN_15', 'CTRL_HIGH_Z_15', 'TIME_DURATION'], // 這個mode用到的參數
showParameter: ['ADC_LEVEL_I_15', 'ADC_LEVEL_V_IN_15', 'CTRL_HIGH_Z_15', 'DAC_VOLT', 'SAMPLE_RATE', 'TIME_DURATION'], // 有要秀給user看的參數
headerParameter: () => ['DAC_VOLT', 'SAMPLE_RATE', 'ADC_LEVEL_I_15', 'ADC_LEVEL_V_IN_15', 'TIME_DURATION'], // export header的參數
valScales: {
linear: {
func: (val) => {
return val
},
},
log: {
func: (val) => {
return Math.log10(Math.abs(val))
},
},
},
channels: {
time: {
name: 'Time',
unit: {
us: 1,
ms: 1e3,
s: 1e6,
minute: 60 * 1e6,
hour: 60 * 60 * 1e6,
},
defaultUnit: 'ms',
downloadUnit: 'ms',
},
0: {
name: 'I_in',
unit: {
nA: 1,
uA: 1e3,
mA: 1e6,
},
defaultUnit: 'mA',
downloadUnit: 'mA',
},
1: {
name: 'V_out',
unit: {
uV: 1,
mV: 1e3,
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'mV',
},
2: {
name: 'V_in',
unit: {
uV: 1,
mV: 1e3,
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'mV',
},
},
charts: {
default: [
{
name: 'Function Generator',
description: '',
subplot: [
{
x1: {
type: 'time',
valScale: 'linear',
min: 'dataMin',
max: 'dataMax',
},
y1: {
type: 'value',
valScale: 'linear',
min: 'dataMin',
max: 'dataMax',
},
data: [
{
legend: 'FuncGen',
x1: {
channel: 'time',
},
y1: {
channel: 1,
},
},
],
},
],
},
],
},
}
+97
View File
@@ -0,0 +1,97 @@
export default {
name: 'I-T Graph',
parameter: ['DAC_VOLT', 'SAMPLE_RATE', 'ADC_LEVEL_I_15', 'ADC_LEVEL_V_IN_15', 'CTRL_HIGH_Z_15', 'TIME_DURATION'], // 這個mode用到的參數
showParameter: ['ADC_LEVEL_I_15', 'ADC_LEVEL_V_IN_15', 'CTRL_HIGH_Z_15', 'DAC_VOLT', 'SAMPLE_RATE', 'TIME_DURATION'], // 有要秀給user看的參數
headerParameter: () => ['DAC_VOLT', 'SAMPLE_RATE', 'ADC_LEVEL_I_15', 'ADC_LEVEL_V_IN_15', 'TIME_DURATION'], // export header的參數
valScales: {
linear: {
func: (val) => {
return val
},
},
log: {
func: (val) => {
return Math.log10(Math.abs(val))
},
},
},
channels: {
time: {
name: 'Time',
unit: {
us: 1,
ms: 1e3,
s: 1e6,
minute: 60 * 1e6,
hour: 60 * 60 * 1e6,
},
defaultUnit: 'ms',
downloadUnit: 'ms',
},
0: {
name: 'I_in',
unit: {
nA: 1,
uA: 1e3,
mA: 1e6,
},
defaultUnit: 'mA',
downloadUnit: 'mA',
},
1: {
name: 'V_in',
unit: {
uV: 1,
mV: 1e3,
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'mV',
},
2: {
name: 'V_out',
unit: {
uV: 1,
mV: 1e3,
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'mV',
},
},
charts: {
default: [
{
name: 'I-T Graph',
description: '',
subplot: [
{
x1: {
type: 'time',
valScale: 'linear',
min: 'dataMin',
max: 'dataMax',
},
y1: {
type: 'value',
valScale: 'linear',
min: 'dataMin',
max: 'dataMax',
},
data: [
{
legend: 'IT',
x1: {
channel: 'time',
},
y1: {
channel: 0,
},
},
],
},
],
},
],
},
}
+123
View File
@@ -0,0 +1,123 @@
export default {
name: 'I-V Curve',
parameter: [
'VOLT_ORIGIN',
'VOLT_FINAL',
'VOLT_STEP',
'STEP_TIME',
'SAMPLE_RATE',
'ADC_LEVEL_I_15',
'ADC_LEVEL_V_IN_15',
'CTRL_HIGH_Z_15',
], // 這個mode用到的參數
showParameter: [
'ADC_LEVEL_I_15',
'ADC_LEVEL_V_IN_15',
'CTRL_HIGH_Z_15',
'VOLT_ORIGIN',
'VOLT_FINAL',
'VOLT_STEP',
'STEP_TIME',
'SAMPLE_RATE',
], // 有要秀給user看的參數
headerParameter: () => [
'VOLT_ORIGIN',
'VOLT_FINAL',
'VOLT_STEP',
'STEP_TIME',
'SAMPLE_RATE',
'ADC_LEVEL_I_15',
'ADC_LEVEL_V_IN_15',
], // export header的參數
valScales: {
linear: {
func: (val) => {
return val
},
},
log: {
func: (val) => {
return Math.log10(Math.abs(val))
},
},
},
channels: {
time: {
name: 'Time',
unit: {
us: 1,
ms: 1e3,
s: 1e6,
minute: 60 * 1e6,
hour: 60 * 60 * 1e6,
},
defaultUnit: 'ms',
downloadUnit: 'ms',
},
0: {
name: 'I_in',
unit: {
nA: 1,
uA: 1e3,
mA: 1e6,
},
defaultUnit: 'mA',
downloadUnit: 'mA',
},
1: {
name: 'V_out',
unit: {
uV: 1,
mV: 1e3,
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'mV',
},
2: {
name: 'V_in',
unit: {
uV: 1,
mV: 1e3,
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'mV',
},
},
charts: {
default: [
{
name: 'I-V Curve',
description: '',
subplot: [
{
x1: {
type: 'value',
valScale: 'linear',
min: 'dataMin',
max: 'dataMax',
},
y1: {
type: 'value',
valScale: 'linear',
min: 'dataMin',
max: 'dataMax',
},
data: [
{
legend: 'IV',
x1: {
channel: 1,
},
y1: {
channel: 0,
},
},
],
},
],
},
],
},
}
@@ -0,0 +1,120 @@
export default {
name: 'Linear Sweep Voltammetry',
parameter: [
'VOLT_INITIAL',
'VOLT_EFINAL',
'Scan_Rate',
'SAMPLE_RATE',
'ADC_LEVEL_I_15',
'ADC_LEVEL_V_IN_15',
'CTRL_HIGH_Z_15',
], // 這個mode用到的參數
showParameter: [
'ADC_LEVEL_I_15',
'ADC_LEVEL_V_IN_15',
'CTRL_HIGH_Z_15',
'VOLT_INITIAL',
'VOLT_EFINAL',
'Scan_Rate',
'SAMPLE_RATE',
], // 有要秀給user看的參數
headerParameter: () => [
'VOLT_INITIAL',
'VOLT_EFINAL',
'Scan_Rate',
'SAMPLE_RATE',
'ADC_LEVEL_I_15',
'ADC_LEVEL_V_IN_15',
], // 有要秀給user看的參數
valScales: {
linear: {
func: (val) => {
return val
},
},
log: {
func: (val) => {
return Math.log10(Math.abs(val))
},
},
},
channels: {
time: {
name: 'Time',
unit: {
us: 1,
ms: 1e3,
s: 1e6,
minute: 60 * 1e6,
hour: 60 * 60 * 1e6,
},
defaultUnit: 'ms',
downloadUnit: 'ms',
},
0: {
name: 'I_in',
unit: {
nA: 1,
uA: 1e3,
mA: 1e6,
},
defaultUnit: 'mA',
downloadUnit: 'mA',
},
1: {
name: 'Potential',
unit: {
uV: 1,
mV: 1e3,
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'mV',
},
2: {
name: 'V_out',
unit: {
uV: 1,
mV: 1e3,
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'mV',
},
},
charts: {
default: [
{
name: 'Linear Sweep Voltammetry',
description: '',
subplot: [
{
x1: {
type: 'value',
valScale: 'linear',
min: 'dataMin',
max: 'dataMax',
},
y1: {
type: 'value',
valScale: 'linear',
min: 'dataMin',
max: 'dataMax',
},
data: [
{
legend: 'LSV',
x1: {
channel: 1,
},
y1: {
channel: 0,
},
},
],
},
],
},
],
},
}
+97
View File
@@ -0,0 +1,97 @@
export default {
name: 'Open Circuit Potential',
parameter: ['SAMPLE_RATE', 'ADC_LEVEL_I_15', 'ADC_LEVEL_V_IN_15', 'TIME_DURATION'], // 這個mode用到的參數
showParameter: ['ADC_LEVEL_I_15', 'ADC_LEVEL_V_IN_15', 'SAMPLE_RATE', 'TIME_DURATION'], // 有要秀給user看的參數
headerParameter: () => ['SAMPLE_RATE', 'ADC_LEVEL_I_15', 'ADC_LEVEL_V_IN_15', 'TIME_DURATION'], // export header的參數
valScales: {
linear: {
func: (val) => {
return val
},
},
log: {
func: (val) => {
return Math.log10(Math.abs(val))
},
},
},
channels: {
time: {
name: 'Time',
unit: {
us: 1,
ms: 1e3,
s: 1e6,
minute: 60 * 1e6,
hour: 60 * 60 * 1e6,
},
defaultUnit: 'ms',
downloadUnit: 'ms',
},
0: {
name: 'I_in',
unit: {
nA: 1,
uA: 1e3,
mA: 1e6,
},
defaultUnit: 'mA',
downloadUnit: 'mA',
},
1: {
name: 'Potential',
unit: {
uV: 1,
mV: 1e3,
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'mV',
},
2: {
name: 'V_in',
unit: {
uV: 1,
mV: 1e3,
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'mV',
},
},
charts: {
default: [
{
name: 'Open Circuit Potential',
description: '',
subplot: [
{
x1: {
type: 'time',
valScale: 'linear',
min: 'dataMin',
max: 'dataMax',
},
y1: {
type: 'value',
valScale: 'linear',
min: 'dataMin',
max: 'dataMax',
},
data: [
{
legend: 'OCP',
x1: {
channel: 'time',
},
y1: {
channel: 1,
},
},
],
},
],
},
],
},
}
@@ -0,0 +1,103 @@
export default {
name: 'Pulse Sensing',
parameter: ['V_initial', 't_pulse', 'CURR_REC'],
// parameter: ['V_initial', 't_pulse', 'CURR_REC_START', 'CURR_REC_END', 'segment_ui_order', 'segment_order', 'DATA_OUTPUT', 'CYCLE_NUMBER'], // 這個mode用到的參數
showParameter: ['V_initial', 't_pulse', 'CURR_REC'], // 有要秀給user看的參數
headerParameter: (parameterSet) => {
// [
// 'V_initial_0', 't_pulse_0', 'CURR_REC_START_0', 'CURR_REC_END_0',
// 'V_initial_1', 't_pulse_1', 'CURR_REC_START_1', 'CURR_REC_END_1',
// 'V_initial_2', 't_pulse_2', 'CURR_REC_START_2', 'CURR_REC_END_2',
// 'V_initial_3', 't_pulse_3', 'CURR_REC_START_3', 'CURR_REC_END_3',
// ]
const defaultParameter = ['V_initial', 't_pulse', 'CURR_REC']
const ret = []
for (let index = 0; index < 4; index++) {
if (parameterSet.segment_order[index] !== -1) {
ret.push(...defaultParameter.map((ele) => [ele, index]))
}
}
return ret
}, // export header的參數
valScales: {
linear: {
func: (val) => {
return val
},
},
log: {
func: (val) => {
return Math.log10(Math.abs(val))
},
},
},
channels: {
time: {
name: 'Time',
unit: {
us: 1,
ms: 1e3,
s: 1e6,
minute: 60 * 1e6,
hour: 60 * 60 * 1e6,
},
defaultUnit: 'ms',
downloadUnit: 'ms',
},
0: {
name: 'I_in_pul1',
unit: {
nA: 1,
uA: 1e3,
mA: 1e6,
},
defaultUnit: 'mA',
downloadUnit: 'mA',
},
1: {
name: 'I_in_pul2',
unit: {
nA: 1,
uA: 1e3,
mA: 1e6,
},
defaultUnit: 'mA',
downloadUnit: 'mA',
},
},
charts: {
default: [
{
name: 'Pulse Sensing',
description: '',
subplot: [
{
x1: {
type: 'time',
valScale: 'linear',
min: 'dataMin',
max: 'dataMax',
},
y1: {
type: 'value',
valScale: 'linear',
min: 'dataMin',
max: 'dataMax',
},
data: [
{
legend: 'PulseSensing',
x1: {
channel: 'time',
},
y1: {
channel: 1,
},
},
],
},
],
},
],
},
}
+102
View File
@@ -0,0 +1,102 @@
export default {
name: 'R-T Graph',
parameter: ['DAC_VOLT', 'SAMPLE_RATE', 'CTRL_HIGH_Z_15', 'TIME_DURATION'], // 這個mode用到的參數
showParameter: ['CTRL_HIGH_Z_15', 'DAC_VOLT', 'SAMPLE_RATE', 'TIME_DURATION'], // 有要秀給user看的參數
headerParameter: () => ['DAC_VOLT', 'SAMPLE_RATE', 'ADC_LEVEL_I_15', 'ADC_LEVEL_V_IN_15', 'TIME_DURATION'], // export header的參數
valScales: {
linear: {
func: (val) => {
return val
},
},
log: {
func: (val) => {
return Math.log10(Math.abs(val))
},
},
},
channels: {
time: {
name: 'Time',
unit: {
us: 1,
ms: 1e3,
s: 1e6,
minute: 60 * 1e6,
hour: 60 * 60 * 1e6,
},
defaultUnit: 'ms',
downloadUnit: 'ms',
},
0: {
name: 'I_in',
unit: {
nA: 1,
uA: 1e3,
mA: 1e6,
},
defaultUnit: 'mA',
downloadUnit: 'mA',
},
1: {
name: 'V_out',
unit: {
uV: 1,
mV: 1e3,
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'mV',
},
2: {
name: 'Resistor',
unit: {
: 1,
mohm: 1,
Ω: 1e3,
ohm: 1e3,
: 1e6,
kohm: 1e6,
: 1e9,
Mohm: 1e9,
},
defaultUnit: 'Ω',
downloadUnit: 'ohm',
},
},
charts: {
default: [
{
name: 'R-T Graph',
description: '',
subplot: [
{
x1: {
type: 'time',
valScale: 'linear',
min: 'dataMin',
max: 'dataMax',
},
y1: {
type: 'value',
valScale: 'linear',
min: 'dataMin',
max: 'dataMax',
},
data: [
{
legend: 'RT',
x1: {
channel: 'time',
},
y1: {
channel: 2,
},
},
],
},
],
},
],
},
}
+87
View File
@@ -0,0 +1,87 @@
export default {
name: 'V-T Graph',
parameter: ['SAMPLE_RATE', 'ADC_LEVEL_I_15', 'ADC_LEVEL_V_IN_15', 'CTRL_HIGH_Z_15', 'TIME_DURATION'], // 這個mode用到的參數
showParameter: ['ADC_LEVEL_I_15', 'ADC_LEVEL_V_IN_15', 'CTRL_HIGH_Z_15', 'SAMPLE_RATE', 'TIME_DURATION'], // 有要秀給user看的參數
headerParameter: () => ['SAMPLE_RATE', 'ADC_LEVEL_I_15', 'ADC_LEVEL_V_IN_15', 'TIME_DURATION'], // export header的參數
valScales: {
linear: {
func: (val) => {
return val
},
},
log: {
func: (val) => {
return Math.log10(Math.abs(val))
},
},
},
channels: {
time: {
name: 'Time',
unit: {
us: 1,
ms: 1e3,
s: 1e6,
minute: 60 * 1e6,
hour: 60 * 60 * 1e6,
},
defaultUnit: 'ms',
downloadUnit: 'ms',
},
0: {
name: 'I_in',
unit: {
nA: 1,
uA: 1e3,
mA: 1e6,
},
defaultUnit: 'mA',
downloadUnit: 'mA',
},
1: {
name: 'V_in',
unit: {
uV: 1,
mV: 1e3,
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'mV',
},
},
charts: {
default: [
{
name: 'V-T Graph',
description: '',
subplot: [
{
x1: {
type: 'time',
valScale: 'linear',
min: 'dataMin',
max: 'dataMax',
},
y1: {
type: 'value',
valScale: 'linear',
min: 'dataMin',
max: 'dataMax',
},
data: [
{
legend: 'VT',
x1: {
channel: 'time',
},
y1: {
channel: 1,
},
},
],
},
],
},
],
},
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,97 @@
export default {
name: 'Chronoamperometry',
parameter: ['CA_VOLT', 'SAMPLE_RATE', 'GENERAL_LP_RTIA', 'CTRL_HIGH_Z_15', 'TIME_DURATION'], // 這個mode用到的參數
showParameter: ['GENERAL_LP_RTIA', 'CTRL_HIGH_Z_15', 'CA_VOLT', 'SAMPLE_RATE', 'TIME_DURATION'], // 有要秀給user看的參數
headerParameter: () => ['CA_VOLT', 'SAMPLE_RATE', 'GENERAL_LP_RTIA', 'TIME_DURATION'], // 有要秀給user看的參數
valScales: {
linear: {
func: (val) => {
return val
},
},
log: {
func: (val) => {
return Math.log10(Math.abs(val))
},
},
},
channels: {
time: {
name: 'Time',
unit: {
us: 1,
ms: 1e3,
s: 1e6,
minute: 60 * 1e6,
hour: 60 * 60 * 1e6,
},
defaultUnit: 'ms',
downloadUnit: 'ms',
},
0: {
name: 'I_in',
unit: {
nA: 1,
uA: 1e3,
mA: 1e6,
},
defaultUnit: 'mA',
downloadUnit: 'mA',
},
1: {
name: 'Potential',
unit: {
uV: 1,
mV: 1e3,
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'mV',
},
2: {
name: 'V_out',
unit: {
uV: 1,
mV: 1e3,
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'mV',
},
},
charts: {
default: [
{
name: 'Chronoamperometric',
description: '',
subplot: [
{
x1: {
type: 'time',
valScale: 'linear',
min: 'dataMin',
max: 'dataMax',
},
y1: {
type: 'value',
valScale: 'linear',
min: 'dataMin',
max: 'dataMax',
},
data: [
{
legend: 'chrono',
x1: {
channel: 'time',
},
y1: {
channel: 0,
},
},
],
},
],
},
],
},
}
@@ -0,0 +1,273 @@
export default {
name: 'Constant Frequency',
parameter: [
'CF_DC_BIAS',
'CF_AC_AMP',
'CF_FREQ',
'CF_PPD',
'CF_SCALE',
'CF_DELAY',
'CF_AVERAGE_NUM',
'GENERAL_HS_RTIA',
], // 這個mode用到的參數
showParameter: [
'CF_DC_BIAS',
'CF_AC_AMP',
'CF_FREQ',
'CF_PPD',
'CF_SCALE',
'CF_DELAY',
'CF_AVERAGE_NUM',
'GENERAL_HS_RTIA',
], // 有要秀給user看的參數
headerParameter: () => [
'CF_DC_BIAS',
'CF_AC_AMP',
'CF_FREQ',
'CF_PPD',
'CF_SCALE',
'CF_DELAY',
'CF_AVERAGE_NUM',
'GENERAL_HS_RTIA',
], // 有要秀給user看的參數
valScales: {
linear: {
func: (val) => {
return val
},
},
log: {
func: (val) => {
return Math.log10(Math.abs(val))
},
},
},
channels: {
time: {
name: 'Time',
unit: {
us: 1,
ms: 1e3,
s: 1e6,
m: 60 * 1e6,
h: 60 * 60 * 1e6,
auto: 1,
},
defaultUnit: 'auto',
downloadUnit: 'ms',
},
0: {
name: 'Z_Imag_Raw',
unit: {
ohm: 1,
},
downloadUnit: 'ohm',
defaultUnit: 'ohm',
},
1: {
name: 'Z_Real_Raw',
unit: {
default: 1,
},
downloadUnit: 'ohm',
defaultUnit: 'ohm',
},
2: {
name: 'Frequency',
unit: {
mHz: 1,
Hz: 1e3,
kHz: 1e6,
},
downloadUnit: 'mHz',
defaultUnit: 'mHz',
},
// 3: {
// name: 'Cycle',
// unit: {
// cycle: 1,
// },
// defaultUnit: 'cycle',
// downloadUnit: null,
// },
4: {
name: 'Z_Imag',
unit: {
mohm: 1e-3,
: 1e-3,
ohm: 1,
Ω: 1,
kohm: 1e3,
: 1e3,
Mohm: 1e6,
: 1e6,
},
downloadUnit: 'ohm',
defaultUnit: 'Ω',
},
5: {
name: 'Z_Real',
unit: {
mohm: 1e-3,
: 1e-3,
ohm: 1,
Ω: 1,
kohm: 1e3,
: 1e3,
Mohm: 1e6,
: 1e6,
},
downloadUnit: 'ohm',
defaultUnit: 'Ω',
},
6: {
name: 'Impedance',
unit: {
mohm: 1e-3,
: 1e-3,
ohm: 1,
Ω: 1,
kohm: 1e3,
: 1e3,
Mohm: 1e6,
: 1e6,
},
downloadUnit: 'ohm',
defaultUnit: 'Ω',
},
7: {
name: 'Phase',
unit: {
millidegree: 1,
'°': 1e3,
},
downloadUnit: 'millidegree',
defaultUnit: '°',
},
8: {
name: 'Current',
unit: {
nA: 1,
uA: 1e3,
mA: 1e6,
},
downloadUnit: 'nA',
defaultUnit: 'nA',
},
9: {
name: 'Level gain',
unit: {
default: 1,
},
downloadUnit: null,
defaultUnit: 'default',
},
10: {
name: 'notify_one',
unit: {
default: 1,
},
downloadUnit: null,
defaultUnit: 'default',
},
11: {
name: 'notify_two',
unit: {
default: 1,
},
downloadUnit: null,
defaultUnit: 'default',
},
12: {
name: 'notify_three',
unit: {
default: 1,
},
downloadUnit: null,
defaultUnit: 'default',
},
13: {
name: 'debug_amp[mV]',
unit: {
default: 1,
},
downloadUnit: null,
defaultUnit: 'default',
},
},
charts: {
default: [
{
name: 'Nyquist',
description: '',
subplot: [
{
x1: {
type: 'value',
valScale: 'linear',
min: 'dataMin',
max: 'dataMax',
},
y1: {
type: 'value',
valScale: 'linear',
min: 'dataMin',
max: 'dataMax',
},
data: [
{
legend: 'Nyquist',
x1: {
channel: 5,
},
y1: {
channel: 4,
},
},
],
},
],
},
{
name: 'Bode',
description: '',
subplot: [
{
x1: {
type: 'value',
valScale: 'log',
min: 'dataMin',
max: 'dataMax',
},
y1: {
type: 'value',
valScale: 'linear',
min: 'dataMin',
max: 'dataMax',
},
y2: {
type: 'value',
valScale: 'linear',
min: 'dataMin',
max: 'dataMax',
},
data: [
{
legend: 'Bode',
x1: {
channel: 2,
},
y1: {
channel: 6,
},
y2: {
channel: 7,
},
},
],
},
],
},
],
},
}
@@ -0,0 +1,123 @@
export default {
name: 'Cyclic Voltammetry',
parameter: ['CV_E_INITIAL', 'CV_E1', 'CV_E2', 'CV_SCAN_RATE', 'SAMPLE_RATE', 'CYCLE_NUMBER', 'GENERAL_LP_RTIA'], // 這個mode用到的參數
showParameter: [
'GENERAL_LP_RTIA',
'CTRL_HIGH_Z_15',
'CV_E_INITIAL',
'CV_E1',
'CV_E2',
'CV_SCAN_RATE',
'SAMPLE_RATE',
'CYCLE_NUMBER',
], // 有要秀給user看的參數
headerParameter: () => [
'CV_E_INITIAL',
'CV_E1',
'CV_E2',
'CV_SCAN_RATE',
'SAMPLE_RATE',
'CYCLE_NUMBER',
'GENERAL_LP_RTIA',
], // 有要秀給user看的參數
valScales: {
linear: {
func: (val) => {
return val
},
},
log: {
func: (val) => {
return Math.log10(Math.abs(val))
},
},
},
channels: {
time: {
name: 'Time',
unit: {
us: 1,
ms: 1e3,
s: 1e6,
m: 60 * 1e6,
h: 60 * 60 * 1e6,
auto: 1,
},
defaultUnit: 'auto',
downloadUnit: 'ms',
},
0: {
name: 'I_in',
unit: {
nA: 1,
uA: 1e3,
mA: 1e6,
},
defaultUnit: 'uA',
downloadUnit: 'mA',
},
1: {
name: 'V_out-V_in',
unit: {
uV: 1,
mV: 1e3,
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'mV',
},
2: {
name: 'V_out',
unit: {
uV: 1,
mV: 1e3,
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'mV',
},
3: {
name: 'Cycle',
unit: {
cycle: 1,
},
defaultUnit: 'cycle',
downloadUnit: null,
},
},
charts: {
default: [
{
name: 'Cyclic Voltammetry',
description: '',
subplot: [
{
x1: {
type: 'value',
valScale: 'linear',
min: 'dataMin',
max: 'dataMax',
},
y1: {
type: 'value',
valScale: 'linear',
min: 'dataMin',
max: 'dataMax',
},
data: [
{
legend: 'CV',
x1: {
channel: 1,
},
y1: {
channel: 0,
},
},
],
},
],
},
],
},
}
+93
View File
@@ -0,0 +1,93 @@
export default {
name: 'Dev Mode',
parameter: ['ADC_VALUE_I'],
valScales: {
linear: {
func: (val) => {
return val
},
},
log: {
func: (val) => {
return Math.log10(Math.abs(val))
},
},
},
channels: {
time: {
name: 'Time',
unit: {
us: 1,
ms: 1e3,
s: 1e6,
m: 60 * 1e6,
h: 60 * 60 * 1e6,
auto: 1,
},
defaultUnit: 'us',
},
0: {
name: '0',
unit: {
default: 1,
},
defaultUnit: 'default',
},
1: {
name: '1',
unit: {
default: 1,
},
defaultUnit: 'default',
},
2: {
name: '2',
unit: {
default: 1,
},
defaultUnit: 'default',
},
3: {
name: '3',
unit: {
default: 1,
},
defaultUnit: 'default',
},
},
charts: {
default: [
{
name: 'Dev Mode',
description: '',
subplot: [
{
x1: {
type: 'time',
valScale: 'linear',
min: 'dataMin',
max: 'dataMax',
},
y1: {
type: 'value',
valScale: 'linear',
min: 'dataMin',
max: 'dataMax',
},
data: [
{
legend: 'dev',
x1: {
channel: 'time',
},
y1: {
channel: 1,
},
},
],
},
],
},
],
},
}
@@ -0,0 +1,275 @@
export default {
name: 'EIS',
parameter: [
'EIS_DC_BIAS',
'EIS_AC_AMP',
'EIS_FREQ',
'EIS_PPD',
'EIS_SCALE',
'EIS_DELAY',
'EIS_AVERAGE_NUM',
'GENERAL_HS_RTIA',
], // 這個mode用到的參數
showParameter: [
'EIS_DC_BIAS',
'EIS_AC_AMP',
'EIS_FREQ',
'EIS_PPD',
'EIS_SCALE',
'EIS_DELAY',
'EIS_AVERAGE_NUM',
'GENERAL_HS_RTIA',
], // 有要秀給user看的參數
headerParameter: () => [
'EIS_DC_BIAS',
'EIS_AC_AMP',
'EIS_FREQ',
'EIS_PPD',
'EIS_SCALE',
'EIS_DELAY',
'EIS_AVERAGE_NUM',
'GENERAL_HS_RTIA',
], // 有要秀給user看的參數
valScales: {
linear: {
func: (val) => {
return val
},
},
log: {
func: (val) => {
return Math.log10(Math.abs(val))
},
},
},
channels: {
time: {
name: 'Time',
unit: {
us: 1,
ms: 1e3,
s: 1e6,
m: 60 * 1e6,
h: 60 * 60 * 1e6,
auto: 1,
},
defaultUnit: 'auto',
downloadUnit: 'ms',
},
0: {
name: 'Z_Imag_Raw',
unit: {
ohm: 1,
},
downloadUnit: 'ohm',
defaultUnit: 'ohm',
},
1: {
name: 'Z_Real_Raw',
unit: {
default: 1,
},
downloadUnit: 'ohm',
defaultUnit: 'ohm',
},
2: {
name: 'Frequency',
unit: {
mHz: 1,
Hz: 1e3,
kHz: 1e6,
},
downloadUnit: 'mHz',
defaultUnit: 'mHz',
},
// 3: {
// name: 'Cycle',
// unit: {
// cycle: 1,
// },
// defaultUnit: 'cycle',
// downloadUnit: null,
// },
4: {
name: 'Z_Imag',
unit: {
mohm: 1e-3,
: 1e-3,
ohm: 1,
Ω: 1,
kohm: 1e3,
: 1e3,
Mohm: 1e6,
: 1e6,
},
downloadUnit: 'ohm',
defaultUnit: 'Ω',
},
5: {
name: 'Z_Real',
unit: {
mohm: 1e-3,
: 1e-3,
ohm: 1,
Ω: 1,
kohm: 1e3,
: 1e3,
Mohm: 1e6,
: 1e6,
},
downloadUnit: 'ohm',
defaultUnit: 'Ω',
},
6: {
name: 'Impedance',
unit: {
mohm: 1e-3,
: 1e-3,
ohm: 1,
Ω: 1,
kohm: 1e3,
: 1e3,
Mohm: 1e6,
: 1e6,
},
downloadUnit: 'ohm',
defaultUnit: 'Ω',
},
7: {
name: 'Phase',
unit: {
millidegree: 1,
'°': 1e3,
},
downloadUnit: 'millidegree',
defaultUnit: '°',
},
8: {
name: 'Current',
unit: {
nA: 1,
uA: 1e3,
mA: 1e6,
},
downloadUnit: 'nA',
defaultUnit: 'nA',
},
9: {
name: 'Level gain',
unit: {
default: 1,
},
downloadUnit: null,
defaultUnit: 'default',
},
10: {
name: 'notify_one',
unit: {
default: 1,
},
downloadUnit: null,
defaultUnit: 'default',
},
11: {
name: 'notify_two',
unit: {
default: 1,
},
downloadUnit: null,
defaultUnit: 'default',
},
12: {
name: 'notify_three',
unit: {
default: 1,
},
downloadUnit: null,
defaultUnit: 'default',
},
13: {
name: 'debug_amp[mV]',
unit: {
uV: 1,
mV: 1e3,
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'mV',
},
},
charts: {
default: [
{
name: 'Nyquist',
description: '',
subplot: [
{
x1: {
type: 'value',
valScale: 'linear',
min: 'dataMin',
max: 'dataMax',
},
y1: {
type: 'value',
valScale: 'linear',
min: 'dataMin',
max: 'dataMax',
},
data: [
{
legend: 'Nyquist',
x1: {
channel: 5,
},
y1: {
channel: 4,
},
},
],
},
],
},
{
name: 'Bode',
description: '',
subplot: [
{
x1: {
type: 'value',
valScale: 'log',
min: 'dataMin',
max: 'dataMax',
},
y1: {
type: 'value',
valScale: 'linear',
min: 'dataMin',
max: 'dataMax',
},
y2: {
type: 'value',
valScale: 'linear',
min: 'dataMin',
max: 'dataMax',
},
data: [
{
legend: 'Bode',
x1: {
channel: 2,
},
y1: {
channel: 6,
},
y2: {
channel: 7,
},
},
],
},
],
},
],
},
}
+102
View File
@@ -0,0 +1,102 @@
export default {
name: 'R-T Graph',
parameter: ['RT_VOLT_SET', 'SAMPLE_RATE', 'CTRL_HIGH_Z_15', 'TIME_DURATION'], // 這個mode用到的參數
showParameter: ['RT_VOLT_SET', 'SAMPLE_RATE', 'CTRL_HIGH_Z_15', 'TIME_DURATION'], // 有要秀給user看的參數
headerParameter: () => ['RT_VOLT_SET', 'SAMPLE_RATE', 'GENERAL_LP_RTIA', 'TIME_DURATION'], // export header的參數
valScales: {
linear: {
func: (val) => {
return val
},
},
log: {
func: (val) => {
return Math.log10(Math.abs(val))
},
},
},
channels: {
time: {
name: 'Time',
unit: {
us: 1,
ms: 1e3,
s: 1e6,
minute: 60 * 1e6,
hour: 60 * 60 * 1e6,
},
defaultUnit: 'ms',
downloadUnit: 'ms',
},
0: {
name: 'I_in',
unit: {
nA: 1,
uA: 1e3,
mA: 1e6,
},
defaultUnit: 'mA',
downloadUnit: 'mA',
},
1: {
name: 'V_out',
unit: {
uV: 1,
mV: 1e3,
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'mV',
},
2: {
name: 'Resistor',
unit: {
: 1,
mohm: 1,
Ω: 1e3,
ohm: 1e3,
: 1e6,
kohm: 1e6,
: 1e9,
Mohm: 1e9,
},
defaultUnit: 'Ω',
downloadUnit: 'ohm',
},
},
charts: {
default: [
{
name: 'R-T Graph',
description: '',
subplot: [
{
x1: {
type: 'time',
valScale: 'linear',
min: 'dataMin',
max: 'dataMax',
},
y1: {
type: 'value',
valScale: 'linear',
min: 'dataMin',
max: 'dataMax',
},
data: [
{
legend: 'RT',
x1: {
channel: 'time',
},
y1: {
channel: 2,
},
},
],
},
],
},
],
},
}
+87
View File
@@ -0,0 +1,87 @@
export default {
name: 'V-T Graph',
parameter: ['SAMPLE_RATE', 'VT_MEASURE_VIN_RANGE', 'GENERAL_LP_RTIA', 'CTRL_HIGH_Z_15', 'TIME_DURATION'], // 這個mode用到的參數
showParameter: ['SAMPLE_RATE', 'VT_MEASURE_VIN_RANGE', 'GENERAL_LP_RTIA', 'CTRL_HIGH_Z_15', 'TIME_DURATION'], // 有要秀給user看的參數
headerParameter: () => ['SAMPLE_RATE', 'VT_MEASURE_VIN_RANGE', 'GENERAL_LP_RTIA', 'TIME_DURATION'], // export header的參數
valScales: {
linear: {
func: (val) => {
return val
},
},
log: {
func: (val) => {
return Math.log10(Math.abs(val))
},
},
},
channels: {
time: {
name: 'Time',
unit: {
us: 1,
ms: 1e3,
s: 1e6,
minute: 60 * 1e6,
hour: 60 * 60 * 1e6,
},
defaultUnit: 'ms',
downloadUnit: 'ms',
},
0: {
name: 'I_in',
unit: {
nA: 1,
uA: 1e3,
mA: 1e6,
},
defaultUnit: 'mA',
downloadUnit: 'mA',
},
1: {
name: 'V_in',
unit: {
uV: 1,
mV: 1e3,
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'mV',
},
},
charts: {
default: [
{
name: 'V-T Graph',
description: '',
subplot: [
{
x1: {
type: 'time',
valScale: 'linear',
min: 'dataMin',
max: 'dataMax',
},
y1: {
type: 'value',
valScale: 'linear',
min: 'dataMin',
max: 'dataMax',
},
data: [
{
legend: 'VT',
x1: {
channel: 'time',
},
y1: {
channel: 1,
},
},
],
},
],
},
],
},
}
+579
View File
@@ -0,0 +1,579 @@
import PotentiostaticEIS from './PotentiostaticEIS'
import CyclicVoltammetry from './CyclicVoltammetry'
import DevMode from './DevMode'
import Chronoamperometry from './Chronoamperometry'
import VT from './VT'
import RT from './RT'
import ConstantFrequency from './ConstantFrequency'
import Idle from '../Common/Idle'
const EliteEIS = {
TIME_DURATION: {
type: 'number',
showName: 'Time duration',
componentType: 'input-range',
range: Object.freeze({ min: 0, max: 86400 }), // UI上能輸入的最大最小值
defaultValue: 0,
defaultUnit: 's',
downloadUnit: 's',
unit: {
ms: 1e-3,
s: 1,
m: 60,
h: 3600,
},
outputRawData: (val) => {
return parseInt(parseFloat(val))
},
outputReadabilityData: (val) => {
return parseInt(parseFloat(val))
},
},
CTRL_HIGH_Z_15: {
type: 'array',
showName: 'HighZ',
componentType: 'input-button-toggle',
options: [
{ value: 0, label: 'On' },
{ value: 1, label: 'Off' },
],
range: ['On', 'Off'],
defaultValue: 1,
outputRawData: (val) => {
const highzArr = ['On', 'Off']
return highzArr.indexOf(val.toString())
},
outputReadabilityData: (idx) => {
const highzArr = ['On', 'Off']
return highzArr[parseInt(idx)]
},
},
CYCLE_NUMBER: {
type: 'number',
showName: 'Cycle',
componentType: 'input-range',
range: Object.freeze({ min: 1, max: 50000 }),
outputRawData: (val) => {
return parseInt(val)
},
outputReadabilityData: (val) => {
return parseInt(val)
},
defaultValue: 1,
defaultUnit: 'cycle',
downloadUnit: null,
unit: {
cycle: 1,
},
},
SAMPLE_RATE: {
type: 'number',
showName: 'Sample rate',
componentType: 'input-range',
range: Object.freeze({ min: 1, max: 1000 }),
outputRawData: (val, scale = 1) => {
return parseInt(parseFloat(val) * 10)
},
outputReadabilityData: (val, scale = 1) => {
return parseFloat(val) / 10
},
defaultValue: 1000,
defaultUnit: 'sps',
downloadUnit: 'sps',
unit: {
sps: 1,
},
},
GENERAL_HS_RTIA: {
type: 'array',
showName: 'Current range',
componentType: 'input-button-toggle',
options: [
{ value: 0, label: '1' },
{ value: 1, label: '2' },
{ value: 2, label: '3' },
{ value: 3, label: '4' },
{ value: 4, label: 'Auto' },
],
range: ['1', '2', '3', '4', 'Auto'],
defaultValue: 4,
outputRawData: (val) => {
const numArr = ['1', '2', '3', '4', 'Auto']
return numArr.indexOf(val.toString())
},
outputReadabilityData: (idx) => {
const numArr = ['1', '2', '3', '4', 'Auto']
return numArr[parseInt(idx)]
},
},
GENERAL_LP_RTIA: {
type: 'array',
showName: 'Current Range',
componentType: 'input-button-toggle',
options: [
{ value: 0, label: '<1.5 uA' },
{ value: 1, label: '1-60 uA' },
{ value: 2, label: '40-175 uA' },
{ value: 3, label: '>120 uA' },
{ value: 4, label: 'Auto' },
],
range: ['<1.5 uA', '1-60 uA', '40-175 uA', '>120 uA', 'Auto'],
defaultValue: 4,
outputRawData: (val) => {
const currentRangeArr = ['<1.5 uA', '1-60 uA', '40-175 uA', '>120 uA', 'Auto']
return currentRangeArr.indexOf(val.toString())
},
outputReadabilityData: (idx) => {
const currentRangeArr = ['<1.5 uA', '1-60 uA', '40-175 uA', '>120 uA', 'Auto']
return currentRangeArr[parseInt(idx)]
},
},
EIS_DC_BIAS: {
type: 'number',
showName: 'DC Volt',
componentType: 'input-field',
range: Object.freeze({ min: 2500, max: 50000 }), // UI上能輸入的最大最小值
outputRawData: (val, scale = 1) => {
return Math.round(parseInt(val) * 12.5 * scale + 25000)
},
outputReadabilityData: (val, scale = 1) => {
return Math.round(parseInt(val - 25000) / 12.5) / scale
},
defaultValue: 25000,
defaultUnit: 'mV',
downloadUnit: 'mV',
unit: {
mV: 1,
V: 1e3,
},
},
EIS_AC_AMP: {
type: 'number',
showName: 'AC Amp',
componentType: 'input-field',
range: Object.freeze({ min: 0, max: 2047 }),
outputRawData: (val, scale = 1) => {
return Math.round((parseInt(val * scale) / 800) * 2047)
},
outputReadabilityData: (val, scale = 1) => {
return Math.round((parseInt(val) / 2047) * 800) / scale
},
defaultValue: 25,
defaultUnit: 'mV',
downloadUnit: 'mV',
unit: {
mV: 1,
},
},
EIS_FREQ: {
type: 'array',
showName: 'Frequency',
componentType: 'multi-input-field',
range: Object.freeze({ min: 1, max: 13333333 }),
outputRawData: (val) => {
return parseFloat(val) < 0.1 ? Math.round(0.1 / 0.015) : Math.round(parseFloat(val) / 0.015)
},
outputReadabilityData: (val) => {
return (parseFloat(val) * 0.015).toFixed(1)
},
defaultValue: [13333333, 7],
defaultUnit: 'Hz',
downloadUnit: 'Hz',
unit: {
Hz: 1,
},
},
EIS_PPD: {
type: 'number',
showName: 'Points per decades',
componentType: 'input-field',
range: Object.freeze({ min: 1, max: 10 }),
outputRawData: (val) => {
return parseInt(val)
},
outputReadabilityData: (val) => {
return parseInt(val)
},
defaultValue: 10,
defaultUnit: 'points',
downloadUnit: null,
unit: {
points: 1,
},
},
EIS_SCALE: {
type: 'array',
showName: 'Point spacing',
componentType: 'input-button-toggle',
options: [
{ value: 0, label: 'Logarithm' },
{ value: 1, label: 'Linear' },
],
range: ['Logarithm', 'Linear'],
defaultValue: 0,
outputRawData: (val) => {
const scaleArr = ['Logarithm', 'Linear']
return scaleArr.indexOf(val.toString())
},
outputReadabilityData: (idx) => {
const scaleArr = ['Logarithm', 'Linear']
return scaleArr[parseInt(idx)]
},
},
EIS_DELAY: {
type: 'number',
showName: 'DELAY',
componentType: 'input-field',
range: Object.freeze({ min: 0, max: 100 }),
outputRawData: (val) => {
return parseInt(parseFloat(val) * 10)
},
outputReadabilityData: (val) => {
return parseFloat(val / 10).toFixed(1)
},
defaultValue: 0,
defaultUnit: 'points',
downloadUnit: null,
unit: {
points: 1,
},
},
EIS_AVERAGE_NUM: {
type: 'array',
showName: 'Average',
componentType: 'input-button-toggle',
options: [
{ value: 0, label: '2' },
{ value: 1, label: '4' },
{ value: 2, label: '6' },
{ value: 3, label: '8' },
],
range: ['2', '4', '6', '8'],
defaultValue: 0,
outputRawData: (val) => {
const numArr = ['2', '4', '6', '8']
return numArr.indexOf(val.toString())
},
outputReadabilityData: (idx) => {
const numArr = ['2', '4', '6', '8']
return numArr[parseInt(idx)]
},
},
CF_DC_BIAS: {
type: 'number',
showName: 'DC Volt',
componentType: 'input-field',
range: Object.freeze({ min: 2500, max: 50000 }), // UI上能輸入的最大最小值
outputRawData: (val, scale = 1) => {
return Math.round(parseInt(val) * 12.5 * scale + 25000)
},
outputReadabilityData: (val, scale = 1) => {
return Math.round(parseInt(val - 25000) / 12.5) / scale
},
defaultValue: 25000,
defaultUnit: 'mV',
downloadUnit: 'mV',
unit: {
mV: 1,
V: 1e3,
},
},
CF_AC_AMP: {
type: 'number',
showName: 'AC Amp',
componentType: 'input-field',
range: Object.freeze({ min: 0, max: 2047 }),
outputRawData: (val, scale = 1) => {
return Math.round((parseInt(val * scale) / 800) * 2047)
},
outputReadabilityData: (val, scale = 1) => {
return Math.round((parseInt(val) / 2047) * 800) / scale
},
defaultValue: 25,
defaultUnit: 'mV',
downloadUnit: 'mV',
unit: {
mV: 1,
},
},
CF_FREQ: {
type: 'number',
showName: 'Frequency',
componentType: 'input-field',
range: Object.freeze({ min: 1, max: 13333333 }),
outputRawData: (val) => {
return parseFloat(val) < 0.1 ? Math.round(0.1 / 0.015) : Math.round(parseFloat(val) / 0.015)
},
outputReadabilityData: (val) => {
return (parseFloat(val) * 0.015).toFixed(1)
},
defaultValue: 13333333,
defaultUnit: 'Hz',
downloadUnit: 'Hz',
unit: {
Hz: 1,
},
},
CF_PPD: {
type: 'number',
showName: 'Points per decades',
componentType: 'input-field',
range: Object.freeze({ min: 1, max: 10 }),
outputRawData: (val) => {
return parseInt(val)
},
outputReadabilityData: (val) => {
return parseInt(val)
},
defaultValue: 10,
defaultUnit: 'points',
downloadUnit: null,
unit: {
points: 1,
},
},
CF_SCALE: {
type: 'array',
showName: 'Point spacing',
componentType: 'input-button-toggle',
options: [
{ value: 0, label: 'Logarithm' },
{ value: 1, label: 'Linear' },
],
range: ['Logarithm', 'Linear'],
defaultValue: 0,
outputRawData: (val) => {
const scaleArr = ['Logarithm', 'Linear']
return scaleArr.indexOf(val.toString())
},
outputReadabilityData: (idx) => {
const scaleArr = ['Logarithm', 'Linear']
return scaleArr[parseInt(idx)]
},
},
CF_DELAY: {
type: 'number',
showName: 'DELAY',
componentType: 'input-field',
range: Object.freeze({ min: 0, max: 100 }),
outputRawData: (val) => {
return parseInt(parseFloat(val) * 10)
},
outputReadabilityData: (val) => {
return parseFloat(val / 10).toFixed(1)
},
defaultValue: 0,
defaultUnit: 'points',
downloadUnit: null,
unit: {
points: 1,
},
},
CF_AVERAGE_NUM: {
type: 'array',
showName: 'Average',
componentType: 'input-button-toggle',
options: [
{ value: 0, label: '2' },
{ value: 1, label: '4' },
{ value: 2, label: '6' },
{ value: 3, label: '8' },
],
range: ['2', '4', '6', '8'],
defaultValue: 3,
outputRawData: (val) => {
const numArr = ['2', '4', '6', '8']
return numArr.indexOf(val.toString())
},
outputReadabilityData: (idx) => {
const numArr = ['2', '4', '6', '8']
return numArr[parseInt(idx)]
},
},
CV_E_INITIAL: {
type: 'number',
showName: 'E-Initial',
componentType: 'input-range',
range: Object.freeze({ min: 2500, max: 50000 }),
outputRawData: (val, scale = 1) => {
return parseInt(parseFloat(val) * scale * 12.5 + 25000)
},
outputReadabilityData: (val, scale = 1) => {
return parseInt((parseFloat(val) - 25000) / 12.5) / scale
},
defaultValue: 25000,
defaultUnit: 'V',
downloadUnit: 'mV',
unit: {
mV: 1,
V: 1e3,
},
},
CV_E1: {
type: 'number',
showName: 'E1',
componentType: 'input-range',
range: Object.freeze({ min: 2500, max: 50000 }),
outputRawData: (val, scale = 1) => {
return parseInt(parseFloat(val) * scale * 12.5 + 25000)
},
outputReadabilityData: (val, scale = 1) => {
return parseInt((parseFloat(val) - 25000) / 12.5) / scale
},
defaultValue: 25000,
defaultUnit: 'V',
downloadUnit: 'mV',
unit: {
mV: 1,
V: 1e3,
},
},
CV_E2: {
type: 'number',
showName: 'E2',
componentType: 'input-range',
range: Object.freeze({ min: 2500, max: 50000 }),
outputRawData: (val, scale = 1) => {
return parseInt(parseFloat(val) * scale * 12.5 + 25000)
},
outputReadabilityData: (val, scale = 1) => {
return parseInt((parseFloat(val) - 25000) / 12.5) / scale
},
defaultValue: 25000,
defaultUnit: 'V',
downloadUnit: 'mV',
unit: {
mV: 1,
V: 1e3,
},
},
CV_SCAN_RATE: {
type: 'number',
showName: 'ScanRate',
componentType: 'input-range',
range: Object.freeze({ min: 1, max: 100000 }),
outputRawData: (val) => {
return parseInt(parseFloat(val) * 100)
},
outputReadabilityData: (val) => {
return parseFloat(val) / 100
},
defaultValue: 10000,
defaultUnit: 'mV/s',
downloadUnit: 'mV/s',
unit: {
'mV/s': 1,
},
},
CA_VOLT: {
type: 'number',
showName: 'Volt (v.s. ref)',
componentType: 'input-range',
range: Object.freeze({ min: 2500, max: 50000 }),
outputRawData: (val, scale = 1) => {
return parseInt(parseFloat(val) * scale * 12.5 + 25000)
},
outputReadabilityData: (val, scale = 1) => {
return parseInt((parseFloat(val) - 25000) / 12.5) / scale
},
defaultValue: 25000,
defaultUnit: 'V',
downloadUnit: 'mV',
unit: {
mV: 1,
V: 1e3,
},
},
VT_MEASURE_VIN_RANGE: {
type: 'array',
showName: 'Vin Range',
componentType: 'input-button-toggle',
options: [
{ value: 0, label: '0~2V' },
{ value: 1, label: '-1~1V' },
{ value: 2, label: '-2~0V' },
{ value: 3, label: 'Auto' },
],
range: ['1', '2', '3', 'Auto'],
defaultValue: 0,
outputRawData: (val) => {
const voltageInRangeArr = ['1', '2', '3', 'Auto']
return voltageInRangeArr.indexOf(val.toString())
},
outputReadabilityData: (idx) => {
const voltageInRangeArr = ['1', '2', '3', 'Auto']
return voltageInRangeArr[parseInt(idx)]
},
},
RT_VOLT_SET: {
type: 'number',
showName: 'Volt out',
componentType: 'input-range',
range: Object.freeze({ min: 2500, max: 50000 }),
defaultValue: 37500,
defaultUnit: 'V',
downloadUnit: 'mV',
unit: {
mV: 1,
V: 1e3,
},
outputRawData: (val, scale = 1) => {
return parseInt(parseFloat(val) * scale * 12.5 + 25000)
},
outputReadabilityData: (val, scale = 1) => {
return parseInt((parseFloat(val) - 25000) / 12.5) / scale
},
},
ADC_VALUE_I: {
type: 'none',
showName: 'Instruction',
componentType: 'dev-mode',
},
MODE_OPTIONS: [
{
id: 7,
description: 'Idle',
},
{
id: 0,
description: 'Potentiostatic Electrochemical Impedance Spectroscopy',
},
{
id: 1,
description: 'CV',
},
{
id: 2,
description: 'Chronoamperometry',
},
{
id: 3,
description: 'VT',
},
{
id: 4,
description: 'RT',
},
{
id: 5,
description: 'Constant Frequency',
},
{
id: 6,
description: 'Dev Tools',
},
],
MODE: {
0: PotentiostaticEIS,
1: CyclicVoltammetry,
2: Chronoamperometry,
3: VT,
4: RT,
5: ConstantFrequency,
6: DevMode,
7: Idle,
},
}
export default EliteEIS
+148
View File
@@ -0,0 +1,148 @@
import EliteEDC from './EliteEDC/index'
import EliteEIS from './EliteEIS/index'
// object saving library name mapping table
const libraryNameMappingTable = {
EDC: EliteEDC,
EliteZM15: EliteEDC,
'Elite_EDC_1.4': null,
'Elite_EDC_1.5': EliteEDC,
'Elite_EDC_1.5re': EliteEDC,
'Elite_EDC_1.5r2': EliteEDC,
'Elite_BAT_1.0': EliteEDC,
EIS: EliteEIS,
'Elite_EIS_1.0': EliteEIS,
'Elite_EIS_1.1': EliteEIS,
'Elite_EIS_MINI_1.0': EliteEIS,
'Elite_TRIG_0.1': null,
'Elite_MEGAFLY_0.1': null,
}
// object saving serial number mapping table
const serialNumberMappingTable = {
0: {
2: {
1: {
5: null, // EDC1.4
6: EliteEDC, // EDC1.5
7: EliteEDC, // EDC1.5re
8: EliteEDC, // EDC1.5r2
},
},
3: {
1: {
0: EliteEDC, // BAT1.0
},
},
4: {
1: {
0: EliteEIS, // EIS1.0
1: EliteEIS, // EIS1.1
2: EliteEIS, // EIS1.1mini
},
},
5: {
1: {
0: null, // TRIG0.1
},
},
6: {
1: {
0: null, // MEAGFLY0.1
},
},
},
}
/**
* return config table by library or serial number (type)
* @param {String | Object} type
* @returns {Object} : config
*/
function getConfig(type) {
if (type === undefined || type === null) return
// if (typeof type === 'number') {
// const deviceList = store.getters.getField('taskContent').deviceListNew
// if (deviceList === undefined) return
// const device = deviceList.find((ele) => ele.memory_board === type)
// if (device === undefined) return
// return libraryNameMappingTable[device.library_name]
// }
// library name
if (typeof type === 'string') {
return libraryNameMappingTable[type]
}
// serial number
if (typeof type === 'object') {
return serialNumberMappingTable[type[0]][type[1]][type[2]][type[3]]
}
}
/**
* return mode config table by type and mode
* @param {String | Object} type
* @param {Number} mode
* @returns {Object} : mode-config
*/
function getModeConfig(type, mode) {
return getConfig(type).MODE[mode]
}
/**
* return parameter config table by type and parameter name
* @param {String | Object} type
* @param {String} parameterName
* @returns {Object} : parameter-config
*/
function getParameterConfig(deviceType, parameterName) {
return getConfig(deviceType)[parameterName]
}
/**
* return channel config table by type and mode
* @param {String | Object} type
* @param {String} mode
* @param {String | Number} channel
* @returns {Object} : channel-config
*/
function getChannelConfig(type, mode, channel) {
if (channel === undefined) {
return getModeConfig(type, mode).channels
}
return getModeConfig(type, mode).channels[channel]
}
/**
* return chart config table by type and mode and chartType
* @param {String | Object} type
* @param {String} mode
* @param {String} chartType
* @returns {Object} : chart-config
*/
function getChartConfig(type, mode, chartType = 'default') {
return getModeConfig(type, mode).charts[chartType]
}
/**
* return mode's parameter list
* @param {String | Object} type
* @param {String} mode
* @returns {Object} : parameter list
*/
function getModeParameter(type, mode) {
return getModeConfig(type, mode).parameter
}
const configTable = {
getConfig,
getModeConfig,
getChannelConfig,
getParameterConfig,
getChartConfig,
getModeParameter,
EliteEDC,
EliteEIS,
}
export default configTable
+20
View File
@@ -0,0 +1,20 @@
import { EChartsOption } from 'echarts'
import { generateLegend } from './legend'
import { generateGrid } from './grid'
import { generateXAxis } from './xAxis'
import { generateYAxis } from './yAxis'
import { generateTooltip } from './tooltip'
import { generateSeries } from './series'
import { generateDataZoom } from './datazoom'
export const generateChart = function (): EChartsOption {
return {
legend: generateLegend(),
tooltip: generateTooltip(),
grid: [generateGrid()],
xAxis: [generateXAxis()],
yAxis: [generateYAxis()],
series: [generateSeries('')],
dataZoom: generateDataZoom(),
}
}
+10
View File
@@ -0,0 +1,10 @@
import { ref } from 'vue'
import { ECharts } from 'echarts'
import { generateChart } from '@/data/echart/chart'
export default function lineChart() {
const chart_ref = ref<ECharts | null>(null)
const option = generateChart()
return { option, chart_ref }
}
+20
View File
@@ -0,0 +1,20 @@
import { DataZoomComponentOption } from 'echarts'
export const generateDataZoom = function (): DataZoomComponentOption | DataZoomComponentOption[] {
return [
{
show: true,
realtime: true,
start: 0,
end: 100,
xAxisIndex: [0, 1],
},
{
type: 'inside',
realtime: true,
start: 0,
end: 100,
xAxisIndex: [0, 1],
},
]
}
+5
View File
@@ -0,0 +1,5 @@
import { TooltipComponentFormatterCallbackParams } from 'echarts'
export const generateFormatter = function (params: any): string {
return String(params[0].value)
}
+18
View File
@@ -0,0 +1,18 @@
import { GridComponentOption } from 'echarts'
export const generateGrid = function (): GridComponentOption {
const index = 0
const length = 1
// const chartID = 1
const _height = 82 / length - 2 + '%'
const _top = index * (82 / length) + 1 + '%'
const _left = '8%'
const _right = '8%'
return {
top: _top,
height: _height,
left: _left,
right: _right,
}
}
+14
View File
@@ -0,0 +1,14 @@
import { LegendComponentOption } from 'echarts'
export const generateLegend = function (): LegendComponentOption {
return {
type: 'scroll',
data: [],
// x: 'center',
// y: '-10%',
bottom: '0%',
textStyle: {
color: '#34495e',
},
}
}
+19
View File
@@ -0,0 +1,19 @@
import { MarkLineComponentOption } from 'echarts'
export const generateMarkLine = function (): MarkLineComponentOption {
return {
symbol: ['none', 'none'],
// cannot create empty mark line data
data: [
// {
// name: 'ceiling',
// },
// {
// name: 'ground',
// },
// {
// name: 'middle',
// },
],
}
}
+36
View File
@@ -0,0 +1,36 @@
import { LineSeriesOption } from 'echarts'
import { generateMarkLine } from './markLine'
export const generateSeries = function (name: string): LineSeriesOption {
return {
type: 'line',
name: name || '',
showSymbol: false,
// silent: true,
data: [],
// markLine: {
// data: [
// {
// // 固定起点的 x 像素位置,用于模拟一条指向最大值的水平线
// name: 'test',
// yAxis: '200',
// },
// ],
// },
// xAxisIndex: xAxisIndex,
// yAxisIndex: yAxisIndex,
// AxisSource: [deviceID, channel], use it to get data stream from buffer
// xAxisSource: xAxisSource,
// yAxisSource: yAxisSource,
animation: false,
// dataXMax: null,
// dataXMin: null,
// dataYMax: null,
// dataYMin: null,
// itemStyle: {},
// lineStyle: {
// width: 1.5,
// },
markLine: generateMarkLine(),
}
}
+15
View File
@@ -0,0 +1,15 @@
import { TooltipComponentOption } from 'echarts'
import { generateFormatter } from './formatter'
export const generateTooltip = function (): TooltipComponentOption {
return {
padding: 10,
backgroundColor: '#fff',
borderColor: 'rgba(0, 0, 200, 0.2)',
borderWidth: 1,
borderRadius: 0,
trigger: 'axis',
hideDelay: 5000,
formatter: generateFormatter,
}
}
+35
View File
@@ -0,0 +1,35 @@
import { XAXisComponentOption } from 'echarts'
declare const AXIS_TYPES: {
readonly value: 1
readonly category: 1
readonly time: 1
readonly log: 1
}
declare type OptionAxisType = keyof typeof AXIS_TYPES
export const generateXAxis = function (
type?: OptionAxisType,
gridIndex?: number,
// boundaryGap?: [string | number, string | number],
): XAXisComponentOption {
return {
type: type || 'value',
show: true,
gridIndex: gridIndex || 0,
// scale: true,
// boundaryGap: true,
axisLine: { onZero: false, lineStyle: { color: '#aaa' } },
axisTick: { show: false },
axisLabel: {
show: true,
showMinLabel: false,
showMaxLabel: false,
color: '#34495e',
},
splitLine: { show: true, lineStyle: { color: '#aaa' } },
min: 'dataMin',
max: 'dataMax',
// interval: undefined,
}
}
+35
View File
@@ -0,0 +1,35 @@
import { YAXisComponentOption } from 'echarts'
declare const AXIS_TYPES: {
readonly value: 1
readonly category: 1
readonly time: 1
readonly log: 1
}
declare type OptionAxisType = keyof typeof AXIS_TYPES
export const generateYAxis = function (
type?: OptionAxisType,
gridIndex?: number,
// boundaryGap?: [string | number, string | number],
): YAXisComponentOption {
return {
type: type || 'value',
show: true,
gridIndex: gridIndex || 0,
// scale: true,
// boundaryGap: true,
axisLine: { onZero: false, lineStyle: { color: '#aaa' } },
axisTick: { show: false },
axisLabel: {
show: true,
showMinLabel: false,
showMaxLabel: false,
color: '#34495e',
},
splitLine: { show: true, lineStyle: { color: '#aaa' } },
min: 'dataMin',
max: 'dataMax',
// interval: undefined,
}
}
+29
View File
@@ -0,0 +1,29 @@
import { getAxios } from '@/data/axios'
import { AxiosResponse } from 'axios'
const axios = getAxios()
const FOLDER_TYPE = 'folder'
const getCollection = async function (
parent: number,
offset: number,
limit: number,
order: Array<string>,
): Promise<AxiosResponse<any, any>> {
let url = `api/file/collection/get?type=${FOLDER_TYPE}&`
if (parent) url += `parent=${parent}&`
if (offset) url += `offset=${offset}&`
if (limit) url += `limit=${limit}&`
if (order) {
const _order = order?.join('-')
url += `order=${_order}`
}
const result = await axios.get(url)
return result
}
const meta = {
getCollection,
}
export default meta
+11
View File
@@ -0,0 +1,11 @@
import meta from './meta'
import collection from './collection'
import project from './project'
const api = {
collection,
meta,
project,
}
export default api
+51
View File
@@ -0,0 +1,51 @@
import { getAxios } from '@/data/axios'
import { AxiosResponse } from 'axios'
const FOLDER_TYPE = 'folder'
const axios = getAxios()
const getMetaWithTypeFolder = async function (
parent: number,
offset?: number,
limit?: number,
order?: Array<string>,
): Promise<AxiosResponse<any, any>> {
let url = `api/file/meta/get?type=${FOLDER_TYPE}&`
if (parent) url += `parent=${parent}&`
if (offset) url += `offset=${offset}&`
if (limit) url += `limit=${limit}&`
if (order) {
const _order = order?.join('-')
url += `order=${_order}`
}
const result = await axios.get(url)
return result
}
const getMetaByTime = async function (time: string): Promise<AxiosResponse<any, any>> {
const url = `api/file/meta/get?time=${time}`
const result = await axios.get(url)
return result
}
const getMetaGroupByTime = async function (): Promise<AxiosResponse<any, any>> {
const url = `api/file/meta/get?group=time`
const result = await axios.get(url)
return result
}
const getMetaByProject = async function (uuid: string): Promise<AxiosResponse<any, any>> {
const url = `api/file/meta/get?type=project&project=${uuid}`
const result = await axios.get(url)
return result
}
const meta = {
getMetaWithTypeFolder,
getMetaByTime,
getMetaByProject,
getMetaGroupByTime,
}
export default meta
+17
View File
@@ -0,0 +1,17 @@
import { getAxios } from '@/data/axios'
import { AxiosResponse } from 'axios'
const axios = getAxios()
const getProjectGroup = async function (attrs?: Array<string>): Promise<AxiosResponse<any, any>> {
let url = `api/project/report/get?`
if (attrs) url += `attrs=${attrs.join('-')}`
const result = await axios.get(url)
return result
}
const project = {
getProjectGroup,
}
export default project
+38
View File
@@ -9,6 +9,40 @@ import vuesticGlobalConfig from './services/vuestic-ui/global-config'
import App from './App.vue'
import 'virtual:windi.css'
// import ECharts modules
import ECharts from 'vue-echarts'
import { use } from 'echarts/core'
// import ECharts modules manually to reduce bundle size
import { CanvasRenderer } from 'echarts/renderers'
import { LineChart, BarChart, PieChart } from 'echarts/charts'
import {
TitleComponent,
LegendComponent,
GridComponent,
TooltipComponent,
DataZoomComponent,
MarkLineComponent,
ToolboxComponent,
BrushComponent,
} from 'echarts/components'
use([
CanvasRenderer,
LineChart,
PieChart,
BarChart,
GridComponent,
TooltipComponent,
TitleComponent,
LegendComponent,
DataZoomComponent,
ToolboxComponent,
BrushComponent,
MarkLineComponent,
])
import serverApi from '@/data/server-api'
const app = createApp(App)
app.use(stores)
@@ -16,6 +50,10 @@ app.use(router)
app.use(i18n)
app.use(createVuestic({ config: vuesticGlobalConfig }))
app.component('EChart', ECharts)
app.provide('server-api', serverApi)
if (import.meta.env.VITE_APP_GTM_ENABLED) {
app.use(
createGtm({
@@ -0,0 +1,87 @@
<template>
<div class="h-[88vh] grid grid-cols-3 gap-6">
<div class="h-full col-span-1">
<div class="h-1/3">
<FileContainer class="h-9/10"></FileContainer>
</div>
<div class="h-2/3">
<ControlPanel class="h-9/10" @filter-data="filterData"></ControlPanel>
</div>
</div>
<LineChartContainer ref="linechart_ref" class="h-[50%] col-span-2"></LineChartContainer>
</div>
</template>
<script setup lang="ts">
import useMqtt from '@/composables/utils/useMqtt'
import FileContainer from '@/components/data-analysis/FileContainer.vue'
import ControlPanel from '@/components/data-analysis/ControlPanel.vue'
import LineChartContainer from '@/components/data-analysis/LineChartContainer.vue'
import { onMounted, ref } from 'vue'
// mqtt init
const { startMqtt, publish } = useMqtt()
const controllerID = 'dc:a6:32:0f:56:9d'
// define subscribe and callback
startMqtt(`${controllerID}/data_analysis/#`, (topic: string, message: ArrayBuffer) => {
// [data, data, ceiling, ground]
const msg = JSON.parse(message.toString())
const name = 'test'
const url = `http://192.168.2.1:3000/api/analysis/get/csv?name=${name}`
const a = document.createElement('a')
a.href = url
document.body.appendChild(a)
a.click()
document.body.removeChild(a)
// try draw line
// msg.push(1500000, -1500000)
// reformat data
const _msg = []
for (let i = 0; i < msg[0].length; i++) {
_msg.push([msg[0][i], msg[1][i]])
}
// append Data
linechart_ref.value?.appendData(0, _msg)
// stop loading
linechart_ref.value?.stopLoading()
// draw line
// draw line
if (msg.length < 3) return true
let yAxis_list = msg[2].map((x: any) => ({ yAxis: x }))
let coord_list = [{ coord: [msg[3][0][0], msg[3][0][1]] }, { coord: [msg[3][1][0], msg[3][1][1]] }]
// yAxis_list.append([{ coord:[ msg[3][0][0],msg[3][0][1]]},{ coord:[ msg[3][1][0], msg[3][1][1]]}])
yAxis_list.push(coord_list)
console.log('yAxis_list', yAxis_list)
linechart_ref.value.setOption({
series: [
{
markLine: {
data: yAxis_list,
},
},
],
})
})
// reference
const linechart_ref = ref()
// ControlPanel handling
const filterData = function (e: any) {
linechart_ref.value?.startLoading()
console.log(linechart_ref)
console.log(e)
publish(`${controllerID}_data_analysis/get_analysis_data`, JSON.stringify({ e }))
}
defineExpose({ linechart_ref, filterData })
</script>
<style></style>
+8 -3
View File
@@ -1,4 +1,4 @@
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'
import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router'
import AuthLayout from '../layouts/AuthLayout.vue'
import AppLayout from '../layouts/AppLayout.vue'
@@ -10,7 +10,7 @@ import UIRoute from '../pages/admin/ui/route'
const routes: Array<RouteRecordRaw> = [
{
path: '/:catchAll(.*)',
redirect: { name: 'dashboard' },
redirect: { name: 'data-analysis' },
},
{
name: 'admin',
@@ -22,6 +22,11 @@ const routes: Array<RouteRecordRaw> = [
path: 'dashboard',
component: () => import('../pages/admin/dashboard/Dashboard.vue'),
},
{
name: 'data-analysis',
path: 'data-analysis',
component: () => import('../pages/admin/data-analysis/DataAnalysis.vue'),
},
{
name: 'statistics',
path: 'statistics',
@@ -212,7 +217,7 @@ const routes: Array<RouteRecordRaw> = [
]
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
history: createWebHashHistory(import.meta.env.BASE_URL),
// mode: process.env.VUE_APP_ROUTER_MODE_HISTORY === 'true' ? 'history' : 'hash',
routes,
})
+14
View File
@@ -0,0 +1,14 @@
import { defineStore } from 'pinia'
export const useCounterStore = defineStore('counter', {
state: () => {
return { count: 0 }
},
// could also be defined as
// state: () => ({ count: 0 })
actions: {
increment() {
this.count++
},
},
})
+23
View File
@@ -0,0 +1,23 @@
import { defineStore } from 'pinia'
interface AxisType {
id: number
name: string
unit: object
defaultUnit: string
downloadUnit: string
}
interface ChannelState {
xAxis: AxisType | Record<string, never>
yAxis: AxisType | Record<string, never>
}
export const useChannelStore = defineStore('data-analysis-channel', {
state: (): ChannelState => ({
xAxis: {},
yAxis: {},
}),
getters: {},
actions: {},
})
View File
+22
View File
@@ -0,0 +1,22 @@
import { defineStore } from 'pinia'
import { FileView } from '@/utils/file'
interface FileViewState {
fileView: FileView
filesSelected: (string | never)[]
}
export const useFileViewStore = defineStore('data-analysis-file-view', {
state: (): FileViewState => ({
fileView: new FileView(),
filesSelected: [],
}),
// could also be defined as
// state: () => ({ count: 0 })
getters: {},
actions: {
setFilesSelect(fileSelect: string[]) {
this.filesSelected.push(...fileSelect)
},
},
})
+12
View File
@@ -0,0 +1,12 @@
interface collection {
id: number
name: string
parent: object
controller_id: number
size: number
type: string
description: string
deleted: bool
}
export { collection }
+396
View File
@@ -0,0 +1,396 @@
import api from '@/data/server-api'
declare type FolderType = {
file: number
collection: number
}
class FileView {
children: Array<Project | Folder | Time | MetaFile>
viewBy: string
offset: number
limit: number
constructor() {
this.children = []
this.viewBy = 'time'
this.offset = 0
this.limit = 20
}
init() {
this.children.length = 0
this.offset = 0
this.limit = 20
}
reset() {
this.children.length = 0
this.offset = 0
this.limit = 20
}
changeView(viewBy: string) {
this.reset()
this.viewBy = viewBy
}
async appendChildren(id: number) {
if (this.viewBy === 'folder') {
// append children folder
const folderResult = await this.getCollectionsFromServer(id)
for (const _data of folderResult.rows) {
const folder = new Folder(_data.id, _data.name)
// console.log('folder', folder)
await folder.init()
this.children.push(folder)
}
} else if (this.viewBy == 'time') {
const timeGroup = await this.getTimeGroupFromServer()
for (const time in timeGroup) {
const timeInstance = new Time(time, timeGroup[time]?.date)
await timeInstance.appendChildren()
this.children.push(timeInstance)
}
} else if (this.viewBy == 'project') {
const projectGroup = await this.getProjectGroupFromServer(['id', 'name', 'uuid', 'created_at'])
for (const project of projectGroup) {
const projectInstance = new Project(project.id, project.name, project.uuid, project.created_at)
await projectInstance.appendChildren()
this.children.push(projectInstance)
}
}
// console.log('children', this.children)
}
async getCollectionsFromServer(id: number, order: string[] = ['id', 'desc']) {
const result = await api.collection.getCollection(id, this.offset, this.limit, order)
return result.data
}
async getFilesByIdFromServer(id: number, order: string[] = ['id', 'desc']) {
const result = await api.meta.getMetaWithTypeFolder(id, this.offset, this.limit, order)
return result.data
}
async getTimeGroupFromServer() {
const result = await api.meta.getMetaGroupByTime()
return result.data
}
async getProjectGroupFromServer(attrs: string[]) {
const result = await api.project.getProjectGroup(attrs)
return result.data
}
getChildren() {
return this.children
}
getMetaFile(idType: string) {
for (const child of this.children) {
if (!(child instanceof MetaFile)) {
const result = child.getMetaFile(idType)
if (result) return result
}
}
}
}
class Time {
id: string
type: string
idType: string
name: string
children: Array<Time | MetaFile>
offset: number
limit: number
maxFiles: number
constructor(id: string, date: string) {
this.id = id
this.type = 'Time'
this.idType = 'Time-' + id
this.name = date
this.children = []
this.offset = 0
this.limit = 20
this.maxFiles = 0
}
async getFilesFromServer(id: string) {
const result = await api.meta.getMetaByTime(id)
return result.data
}
async appendChildren() {
const metaFile = await this.getFilesFromServer(this.name)
for (const _metaFile of metaFile) {
const channels =
_metaFile.channels === null || _metaFile.channels === '' ? _metaFile.channels : JSON.parse(_metaFile.channels)
const meta = new MetaFile(
_metaFile.id,
_metaFile.uuid,
_metaFile.name,
channels,
_metaFile.parent,
_metaFile.device,
_metaFile.parameter_set,
_metaFile.raw_data,
_metaFile.mini_data,
_metaFile.size,
_metaFile.time_duration,
_metaFile.created_at,
)
this.children.push(meta)
// console.log('time', meta)
}
}
getChildren() {
return this.children
}
getMetaFile(idType: string) {
for (const child of this.children) {
if (child instanceof MetaFile) {
if (child.idType === idType) return child
}
}
}
}
class Project {
id: string
type: string
idType: string
name: string
uuid: string
created_at: Date
children: Array<Project | MetaFile>
offset: number
limit: number
maxFiles: number
constructor(id: string, name: string, uuid: string, created_at: Date) {
this.id = id
this.type = 'Project'
this.idType = 'Project-' + id
this.name = name
this.uuid = uuid
this.created_at = created_at
this.children = []
this.offset = 0
this.limit = 20
this.maxFiles = 0
}
async getFilesFromServer(id: string) {
const result = await api.meta.getMetaByProject(id)
return result.data
}
async appendChildren() {
const metaFile = await this.getFilesFromServer(this.uuid)
for (const _metaFile of metaFile) {
const channels =
_metaFile.channels === null || _metaFile.channels === '' ? _metaFile.channels : JSON.parse(_metaFile.channels)
const meta = new MetaFile(
_metaFile.id,
_metaFile.uuid,
_metaFile.name,
channels,
_metaFile.parent,
_metaFile.device,
_metaFile.parameter_set,
_metaFile.raw_data,
_metaFile.mini_data,
_metaFile.size,
_metaFile.time_duration,
_metaFile.created_at,
)
this.children.push(meta)
// console.log('project', meta)
}
}
getChildren() {
return this.children
}
getMetaFile(idType: string) {
for (const child of this.children) {
if (child instanceof MetaFile) {
if (child.idType === idType) return child
}
}
}
}
class Folder {
id: number
idType: string
name: string
children: Array<Folder | MetaFile>
offset: FolderType
limit: FolderType
maxNumber: FolderType
type: string
constructor(id: number, name: string) {
this.id = id
this.type = 'Folder'
this.idType = 'Folder' + id
this.name = name
this.children = []
this.offset = { file: 0, collection: 0 }
this.limit = { file: 20, collection: 20 }
this.maxNumber = { file: 0, collection: 0 }
}
async init() {
await this.appendChildren()
}
async getFilesFromServer(id: number, offset?: number, limit?: number, order: Array<string> = ['id', 'desc']) {
const result = await api.meta.getMetaWithTypeFolder(id, offset, limit, order)
return result
}
async getCollectionsFromServer(id: number, offset: number, limit: number, order: Array<string> = ['id', 'desc']) {
const result = await api.collection.getCollection(id, offset, limit, order)
return result
}
async appendChildren() {
// append children folder
await this.appendFolder()
// append children file
await this.appendFile()
}
async appendFolder() {
const folder = await this.getCollectionsFromServer(this.id, this.offset.collection, this.limit.collection)
for (const _data of folder.data.rows) {
const folder = new Folder(_data.id, _data.name)
await folder.appendChildren()
this.children.push(folder)
}
this.maxNumber.collection = folder.data.count
this.offset.collection += this.limit.collection
}
async appendFile() {
const metaFile = await this.getFilesFromServer(this.id)
for (const _metaFile of metaFile.data.rows) {
const channels =
_metaFile.channels === null || _metaFile.channels === '' ? _metaFile.channels : JSON.parse(_metaFile.channels)
const meta = new MetaFile(
_metaFile.id,
_metaFile.uuid,
_metaFile.name,
channels,
_metaFile.parent,
_metaFile.device,
_metaFile.parameter_set,
_metaFile.raw_data,
_metaFile.mini_data,
_metaFile.size,
_metaFile.time_duration,
_metaFile.created_at,
)
this.children.push(meta)
// console.log('folder', meta)
}
this.maxNumber.file = metaFile.data.count
this.offset.file += this.limit.file
}
getChildren() {
return this.children
}
getMetaFile(idType: string) {
for (const child of this.children) {
if (child instanceof MetaFile) {
if (child.idType === idType) return child
}
}
}
}
class MetaFile {
id: number
idType: string
uuid: string
name: string
channels: Array<number>
parent: object
device: Device
parameter: any
rawData: Array<Array<number>>
miniData: Array<Array<number>>
size: string
time: string
created_at: Date
type: string
constructor(
id: number,
uuid: string,
name: string,
channels: Array<number>,
parent: object,
device: Device,
parameter: any,
rawData: Array<Array<number>>,
miniData: Array<Array<number>>,
size: string,
time: string,
created_at: Date,
) {
this.id = id
this.type = 'MetaFile'
this.idType = 'MetaFile-' + id
this.uuid = uuid
this.name = name
this.channels = channels
this.parent = parent
this.device = device
this.parameter = parameter
this.rawData = rawData
this.miniData = miniData
this.size = size
this.time = time
this.created_at = created_at
}
getMetaInfo() {
return {
id: this.id,
uuid: this.uuid,
name: this.name,
channels: this.channels,
parent: this.parent,
device: this.device,
parameter: this.parameter,
rawData: this.rawData,
miniData: this.miniData,
size: this.size,
time: this.time,
created: this.created_at,
}
}
}
interface Device {
id: number
name: string
version: string
mac_address: string
memory_board: number
serial_number: Array<number>
library_name: string
library_version: string
status: number
}
export { FileView, Project, MetaFile, Folder, Time }
+1
View File
@@ -0,0 +1 @@
declare module 'mqtt/dist/mqtt.min.js'
+67
View File
@@ -0,0 +1,67 @@
import type { MqttClient, OnMessageCallback } from 'mqtt'
import * as mqtt from 'mqtt/dist/mqtt.min.js'
class MQTT {
url: string
topic: string
client!: MqttClient
constructor(topic: string) {
this.topic = topic
this.url = 'ws://192.168.2.1:8083'
}
// init mqtt
init() {
const options = {
clean: true,
clientId: 'mqttjs_' + Math.random().toString(16).substring(2, 8),
// password: '111',
// username: '1111',
connectTimeout: 4000,
}
this.client = mqtt.connect(this.url, options)
this.client.on('error', (error: any) => {
console.log(error)
})
this.client.on('reconnect', (error: Error) => {
console.log(error)
})
}
// unsubscribes
unsubscribes() {
this.client.unsubscribe(this.topic, (error: Error) => {
if (!error) {
console.log(this.topic, 'cancel subscribe success')
} else {
console.log(this.topic, 'cancel subscribe fail')
}
})
}
// subscribe
link() {
this.client.on('connect', () => {
this.client.subscribe(this.topic, (error: any) => {
if (!error) {
console.log('subscribe success')
} else {
console.log('subscribe fail')
}
})
})
}
// publish
publish(topic: string, message: string) {
this.client.publish(topic, message)
}
// message callback
get(callback: OnMessageCallback) {
this.client.on('message', callback)
}
// close client
over() {
this.client.end()
}
}
export default MQTT