Compare commits

...

159 Commits

Author SHA1 Message Date
sss28072637 2575a97894 [debug] fix real-time dataZoom bug 2022-08-03 14:45:38 +08:00
sss28072637 566f59e29c fix replay bugs, add integral in I-V mode(replay & realtime) and fix integral bugs 2022-08-01 18:22:01 +08:00
108000207 7fc8d24a71 [update] add replay functional, need to check the time gap 2022-07-27 18:31:52 +08:00
108000207 f2709241d2 [init] add CanvasChartReplayCalculation component 2022-07-27 09:56:20 +08:00
sss28072637 63b627622b [update] use setTimeOut to make the emit from changeScale work 2022-07-26 18:07:30 +08:00
sss28072637 265c363858 fix real-time tooltips 2022-07-25 14:14:26 +08:00
peterlu14 89da594392 Merge remote-tracking branch 'origin/dev/haolung' into release/v1.2.8/realtime-tool 2022-07-22 16:24:33 +08:00
sss28072637 436ed27479 fix button bug 2022-07-22 14:55:42 +08:00
peterlu14 ea14ee2f3e [update] remove redundence code 2022-07-22 14:31:16 +08:00
peterlu14 4416367acf [update] fix replay tooltip problem 2022-07-22 14:31:13 +08:00
peterlu14 e44c1e4c18 [update] fix merge config table problem 2022-07-22 14:31:09 +08:00
peterlu14 4910719aa4 Merge remote-tracking branch 'origin/dev/real_time_value' into release/v1.2.8/realtime-tool 2022-07-22 14:30:32 +08:00
peterlu14 223e898d5e [update] fix config-table rename problem ( download, replay ) 2022-07-22 14:25:05 +08:00
sss28072637 1e80731438 separate the calculation file 2022-07-22 14:17:09 +08:00
peterlu14 d3d080eb08 [update] add EIS mimi 2022-07-22 10:34:07 +08:00
nthu1080112244 0bd84d865f [update] integrate axis unit, tooltip information 2022-07-22 09:41:40 +08:00
sss28072637 b14488cf49 simplify the code (ver1) 2022-07-21 17:08:49 +08:00
peterlu14 4dda2d0a6a [update] switch page remove cache fix 2022-07-21 17:02:16 +08:00
sss28072637 3460a0bfa0 fix time axisLabel 2022-07-21 11:46:47 +08:00
sss28072637 90738611eb (07/20) finish differential, log, integral, add additional function, fix bugs and clear console log 2022-07-20 17:12:30 +08:00
peterlu14 35ba66ddd6 Merge branch 'release/v1.2.5/task_configuration' into release/v1.2.7/scheduler-parameter 2022-07-20 09:53:03 +08:00
peterlu14 4c3c63a0ba [update] schedule parameter fix & config-table add default value 2022-07-20 09:52:40 +08:00
sss28072637 d22653a5a5 clear console error 2022-07-19 16:38:39 +08:00
sss28072637 05cae92b12 finish integral, differential and log 2022-07-19 14:59:08 +08:00
sss28072637 adbf30f08d Merge remote-tracking branch 'origin/release/v1.2.5/task_configuration' into dev/haolung 2022-07-19 11:32:16 +08:00
nthu1080112244 5fe321828a Merge remote-tracking branch 'origin/release/v1.2.5/task_configuration' into dev/real_time_value 2022-07-19 11:30:21 +08:00
peterlu14 ca823d174b [update] reset series data type error fix 2022-07-19 11:26:46 +08:00
nthu1080112244 2e573e2c72 [update] add coment 2022-07-19 11:22:55 +08:00
nthu1080112244 84d136d4cf [update] real time display modularization 2022-07-18 18:28:23 +08:00
nthu1080112244 9b296c45bd [update] complete real time value display 2022-07-18 15:13:16 +08:00
nthu1080112244 ef9db8bee2 Merge commit 'bcf7b51dc6f0c241ab2f8bd3fdffb4173a5e7693' into dev/real_time_value 2022-07-18 14:15:23 +08:00
sss28072637 175f4ef23e Merge remote-tracking branch 'origin/release/v1.2.5/task_configuration' into dev/haolung 2022-07-18 10:28:38 +08:00
sss28072637 eba7c080b4 merge_0718 2022-07-18 09:55:05 +08:00
nthu1080112244 7c4515521d [update] unit correction, real time value bar 2022-07-15 19:40:34 +08:00
peterlu14 3db09734d2 [update] use deviceParameterWindow instead 2022-07-15 10:08:24 +08:00
peterlu14 c0e3a9c61a [update] rename param-table to config-table & add api to config 2022-07-15 10:08:24 +08:00
peterlu14 bcf7b51dc6 [update] mapping unify format string 2022-07-15 10:05:24 +08:00
peterlu14 ba660ac952 [update] fix girdsource not clear problem 2022-07-14 10:21:39 +08:00
sss28072637 1062aea8db fix tooltip constructor parameters, start / stop clicked reset, clear console errors, add differential function, get timeIndex automatically 2022-07-13 16:33:17 +08:00
sss28072637 b1f9edc624 Merge remote-tracking branch 'origin/release/v1.2.5/task_configuration' into dev/haolung 2022-07-13 09:37:41 +08:00
sss28072637 9210646611 add comments 2022-07-12 18:17:38 +08:00
sss28072637 de2315cd5b finish integral and log 2022-07-12 17:33:01 +08:00
sss28072637 ec231aa368 fix stop mode intergration 2022-07-12 15:33:21 +08:00
nthu1080112244 7b6948d027 Merge remote-tracking branch 'origin/release/v1.2.5/task_configuration' into dev/real_time_value 2022-07-12 15:15:12 +08:00
nthu1080112244 28f1aef82c [update] default real time representation 2022-07-12 15:14:31 +08:00
sss28072637 908db19110 finish mode switch button 2022-07-12 14:06:12 +08:00
sss28072637 9520e5102c finish integral of VT_mode 2022-07-12 12:02:58 +08:00
peterlu14 d171d8b572 [update] only refresh chart which device running 2022-07-12 10:41:43 +08:00
peterlu14 1e57bde1df [update] chartID uuid && fix mappingID -1 && reset series data && chart created manual or default 2022-07-12 10:38:04 +08:00
peterlu14 0946b01a41 [update] prop chartID add new type 2022-07-12 10:30:36 +08:00
peterlu14 a25e784fd4 Merge branch 'release/v1.2.4/develop_env_var' 2022-07-07 09:35:39 +08:00
peterlu14 ff18fdd8bd [update] add development env variable to control websocket ip 2022-06-29 15:58:23 +08:00
peterlu14 4c4631e89b [update] add debug page 2022-06-29 11:42:03 +08:00
peterlu14 7480717cac Merge branch 'release/v1.2.2/led_testing&download_all' 2022-06-24 15:11:44 +08:00
peterlu14 a29d32fd0f [update] add download all 2022-06-23 20:01:41 +08:00
peterlu14 942e98199e [update] add developer page with LED testing 2022-06-23 20:00:40 +08:00
peterlu14 482caf9650 Merge branch 'release/v.1.2.1/restruct_taskInfo_and_param' 2022-06-23 17:50:36 +08:00
peterlu14 3dfbf809e0 [update] fix chart source name with memory board 2022-06-23 17:35:11 +08:00
peterlu14 e15b1ea27c [update] add frontend version 2022-06-22 22:01:52 +08:00
peterlu14 5829c6c0f4 [update] cut old new file 2022-06-22 19:24:27 +08:00
peterlu14 eeb0775aa3 [update] replace item with new item 2022-06-22 17:23:29 +08:00
peterlu14 fbf8fe1a19 [update] fix eis replay mode problem (temp) 2022-06-22 16:31:41 +08:00
peterlu14 1172b1220c [update] fix pulse sensing replay parameter 2022-06-22 16:12:07 +08:00
peterlu14 f6ef173edb [update] fix eis equation correction 2022-06-22 13:36:56 +08:00
peterlu14 5d03d156e1 [update] fix unit μ encoding problem 2022-06-22 11:20:16 +08:00
peterlu14 7eaf49e19e [update] fix pulseing download 2022-06-21 16:14:01 +08:00
peterlu14 704b3bf0af [update] remove resource error 2022-06-17 19:49:48 +08:00
peterlu14 a44e96a96c [update] add input range slider component 2022-06-17 19:48:31 +08:00
peterlu14 a69b980684 [update] add pulse sensing mode 2022-06-17 19:48:09 +08:00
peterlu14 280951aa05 [update] remove key && fix isNaN('') equal false problem 2022-06-14 18:04:44 +08:00
peterlu14 f0af54aacd [update] add new component MultiInputField 2022-06-14 18:01:17 +08:00
peterlu14 05dc4d278c [update] recover FREQ component & fix current range option 2022-06-14 18:00:02 +08:00
peterlu14 cab5f91a18 [update] add new component for display and update 2022-06-14 16:59:15 +08:00
peterlu14 cd0665dbb3 [update] add EIS & EliteZM15 DPV mode 2022-06-14 16:58:41 +08:00
peterlu14 9265a45371 [update] fix disable HIGHZ & guide show in ZM15 2022-06-14 16:56:18 +08:00
peterlu14 a8663fc9b9 [update] paramTable MODE_OPTIONS replace local options 2022-06-14 16:51:38 +08:00
peterlu14 5acbab5b37 [update] add memory info 2022-06-07 15:03:39 +08:00
peterlu14 31680a6360 [fix] download export header error 2022-06-07 14:45:02 +08:00
peterlu14 5beaaf2d3d [fix] replay showing parameter errror 2022-06-07 14:44:27 +08:00
peterlu14 8519f70fb3 [update] remove taskInfo use newDeviceList instead & new parameter table 2022-06-07 14:43:52 +08:00
peterlu14 52c391fea1 [update] add new parameter response speed 2022-05-20 14:03:04 +08:00
peterlu14 7cb1286af3 [update] cp mode download timestamp fix 2022-05-18 13:14:33 +08:00
peterlu14 4b7961a388 Merge branch 'feature/time_control' into release/v1.1.4_merge_with_configuration 2022-05-18 10:42:17 +08:00
peterlu14 f3841c1008 [update] add new parameter time_duration 2022-05-18 10:23:44 +08:00
peterlu14 66673ff3cb Merge branch 'feature/merge_with_config' into release/v1.1.4_merge_with_configuration 2022-05-11 19:23:25 +08:00
peterlu14 e222a6a5d4 Revert "[update] fix chart source duplicate problem"
This reverts commit d7d49db966.
2022-05-11 19:23:06 +08:00
peterlu14 6985bf79ba Merge branch 'feature/merge_with_config' into release/1.1.4_merge_with_comfiguration 2022-05-11 18:23:32 +08:00
peterlu14 6fa80c4e47 [update] append formula function in dev mode 2022-05-11 17:57:50 +08:00
peterlu14 0d13a10a99 [update] disable chart show filter & cursor change 2022-05-11 17:57:24 +08:00
peterlu14 5781e7398b [update] change legend & axis label color 2022-05-11 17:56:51 +08:00
peterlu14 d7d49db966 [update] fix chart source duplicate problem 2022-05-11 17:56:07 +08:00
peterlu14 f86c82825e [update] fix html element end tag error 2022-05-11 17:54:33 +08:00
peterlu14 ebdc2355f9 [update] fix merge configuration causing problems 2022-05-11 17:25:54 +08:00
peterlu14 5a56aedfd0 [update] fix header value not follwing unit error 2022-05-10 19:37:06 +08:00
peterlu14 dbaefcb6bb Merge branch 'feature/configuration_1.0' into release/v1.1.3_csv_header 2022-05-10 10:50:19 +08:00
peterlu14 e60e17fa28 [update] fix replay eis unit error 2022-05-09 17:20:11 +08:00
peterlu14 32ee3b815e [update] change cg mode sample rate display 2022-05-09 17:02:28 +08:00
peterlu14 4dbc8bddfd [update] add export controller info 2022-05-09 17:01:58 +08:00
peterlu14 ce376fd5a9 [update] update pulse mode parameter setting 2022-05-09 16:58:38 +08:00
peterlu14 3bfabb8333 [update] update eis parameter table 2022-05-09 16:57:35 +08:00
peterlu14 2232c1e17c [update] header-param & showName enable call func 2022-05-09 16:56:51 +08:00
peterlu14 06386fff2a [update] sample_rate name from string to function 2022-05-09 16:55:12 +08:00
peterlu14 5a45d33d63 [update] change headerParameter from array to func 2022-05-09 16:53:41 +08:00
peterlu14 a27503c09b [update] fix download data spacing problem (when data is not defined) 2022-05-06 21:53:38 +08:00
peterlu14 1282b10c34 [update] add same func to offline (change data scale) & fix empty data error 2022-05-06 21:28:34 +08:00
peterlu14 8f718b7372 [update] add all channel mode & data scale can follow unit in param-table 2022-05-06 21:12:00 +08:00
peterlu14 5714bce5c0 [update] download remove duplicate data (time) 2022-05-06 21:08:58 +08:00
peterlu14 ce374a5a4c [update] add readable header & title with flexiable way 2022-05-06 21:06:29 +08:00
peterlu14 8e493c9ec1 [update] add param-table EliteZM15 key to handle download header issue 2022-05-06 21:00:52 +08:00
peterlu14 ddffa2a212 [update] temp chart label color 2022-05-06 10:48:36 +08:00
peterlu14 bd646fafc0 [update] add cp_mode & change parameter order & change cg mode name 2022-05-06 10:48:10 +08:00
peterlu14 1a69bb5822 [update] disable hover stop 2022-05-04 18:36:08 +08:00
peterlu14 0e2ecc763d [update] split project list into config & running & stop project & add lockMode 2022-05-04 18:34:08 +08:00
peterlu14 8a785ca15a [update] consistency parameter name 2022-05-04 18:16:27 +08:00
peterlu14 e2c5845bb8 [update] add running project list 2022-05-03 17:37:56 +08:00
peterlu14 782176bc29 [update] edit project & task name & styling 2022-04-29 17:09:30 +08:00
peterlu14 cd3a2d66a2 [update] fix multi same devices error 2022-04-29 17:07:28 +08:00
peterlu14 829fce435d [update] show device mac_address 2022-04-29 17:06:51 +08:00
peterlu14 b457aa5496 [update] task name solate from project 2022-04-29 17:01:58 +08:00
peterlu14 0cfa124f00 [update] realtime refresh chart 2022-04-29 13:43:15 +08:00
peterlu14 e8b175de7b [update] add new feature project saving & styling 2022-04-29 13:33:22 +08:00
peterlu14 4c2a398841 [update] add key enter event 2022-04-29 13:30:55 +08:00
peterlu14 8bf5c4befc [update] hide filter with developer mode 2022-04-28 13:01:39 +08:00
peterlu14 57b1dcc8d5 [update] add new font roboto 2022-04-28 11:08:04 +08:00
peterlu14 7140ba345c [update] style format 2022-04-28 11:07:34 +08:00
peterlu14 5905e34697 [update] reorder & remove ocp & fix mode & highz error 2022-04-28 10:59:43 +08:00
peterlu14 40ffe28ac7 [update] fix device status problem 2022-04-27 16:03:41 +08:00
peterlu14 bf3f08629e [update] add broadcast change device status 2022-04-27 15:00:09 +08:00
peterlu14 ed3cd23dc1 [update] disable highz on first & switch mode change highz 2022-04-27 13:52:39 +08:00
peterlu14 2708a5f8bf [update] change mode reset highz 2022-04-26 19:10:19 +08:00
peterlu14 c71e00b89e [update] sample rate default & volt param show error 2022-04-26 16:05:28 +08:00
peterlu14 75bab13768 [update] add new parameter table & remove edit icon 2022-04-26 15:06:54 +08:00
peterlu14 bb4020d2d0 [update] project deviceList into device 2022-04-25 11:58:03 +08:00
peterlu14 7e902c3236 [update] project taskList to task 2022-04-25 11:41:42 +08:00
peterlu14 c7a5689023 [update] add project api 2022-04-25 11:40:50 +08:00
peterlu14 7a303f2da2 [update] add after project & task run & previous task run condition & broadcast mes from backend 2022-04-18 01:46:27 +08:00
peterlu14 e49af9ccbd [update] pair device status in backend 2022-04-17 23:43:43 +08:00
peterlu14 49e5c206dc [update] fix project param show error & able to change & restruct param 2022-04-17 23:43:19 +08:00
peterlu14 0d83011474 [update] add developer mode 2022-04-15 20:11:22 +08:00
peterlu14 229fa15d15 [update] get file meta info faster 2022-04-15 15:21:29 +08:00
peterlu14 ac243f926b [update] improve init filetable & fix delete 2022-04-15 15:13:03 +08:00
peterlu14 b7e1315a1e [update] getParmDone fix 2022-04-13 10:50:40 +08:00
peterlu14 a5804d24e7 [update] replace task page api call & file control change 2022-04-12 13:59:56 +08:00
Jordan Hsu 0ecd2b50dd [fix] configuration refresh bug 2022-02-12 17:17:34 +08:00
Jordan Hsu c984bebf6f [modify] separate chartKey and panelKey 2022-01-14 17:26:13 +08:00
Jordan Hsu 06766f1ac4 [add] can save chart source setting 2022-01-14 15:54:06 +08:00
Jordan Hsu 9981958160 typo 2022-01-12 18:06:11 +08:00
Jordan Hsu e1d6dbd38e fix chart data display bug 2022-01-12 18:01:06 +08:00
Jordan Hsu 96b38e5570 fix cache chart bug 2022-01-12 15:52:23 +08:00
Jordan Hsu ffd246124f tmp 2022-01-10 17:12:27 +08:00
Jordan Hsu 834bcbc4df add missing code 2022-01-10 15:56:25 +08:00
Jordan Hsu 8f6f437f14 [add] missing localforage package dependency 2022-01-10 15:49:17 +08:00
Jordan Hsu e5bc63e5d5 [add] real-time chart add / remove update with cache 2022-01-10 15:38:55 +08:00
Jordan Hsu 5d3dbbac4f [modify] real-time chart data object to vuex 2022-01-10 12:56:35 +08:00
Jordan Hsu 9a77e6dcff [modify] neulive 3.5 sti constraint 2022-01-06 13:09:52 +08:00
peterlu14 5328bd76ba [fix] sd data from api 2022-01-04 14:13:38 +08:00
Jordan Hsu 9d19fd3fc9 add neu 3.1 sample rate option 2022-01-04 11:14:46 +08:00
Alan Lin 1e2bf182bf neu31 update adc_clk ratio formula 2022-01-04 11:03:23 +08:00
Alan Lin 288f9b325c update download SD function 2021-12-27 18:22:03 +08:00
157 changed files with 9792 additions and 4961 deletions
+21
View File
@@ -8595,6 +8595,11 @@
"integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
"dev": true
},
"immediate": {
"version": "3.0.6",
"resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz",
"integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps="
},
"import-cwd": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-2.1.0.tgz",
@@ -10375,6 +10380,14 @@
"type-check": "~0.3.2"
}
},
"lie": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz",
"integrity": "sha1-mkNrLMd0bKWd56QfpGmz77dr2H4=",
"requires": {
"immediate": "~3.0.5"
}
},
"lines-and-columns": {
"version": "1.1.6",
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz",
@@ -10939,6 +10952,14 @@
}
}
},
"localforage": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/localforage/-/localforage-1.10.0.tgz",
"integrity": "sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg==",
"requires": {
"lie": "3.1.1"
}
},
"locate-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
+2 -1
View File
@@ -5,7 +5,7 @@
"description": "Vue.js admin template",
"author": "smartapant <smartapant@gmail.com>",
"scripts": {
"serve": "vue-cli-service serve",
"serve": "vue-cli-service serve --mode development",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint",
"lint:style": "stylelint --fix src/**/*.{vue,htm,html,css,sss,less,scss}",
@@ -35,6 +35,7 @@
"google-maps": "^3.3.0",
"ionicons": "^4.6.3",
"leaflet-map": "^0.2.1",
"localforage": "^1.10.0",
"lodash": "^4.17.21",
"medium-editor": "^5.23.3",
"normalize.css": "^8.0.1",
+21 -5
View File
@@ -36,16 +36,32 @@ import 'nprogress/nprogress.css'
import Toast from 'vue-toastification'
import 'vue-toastification/dist/index.css'
import api from '@/data/api/index'
import localforage from 'localforage'
import '../metrics'
import '../registerServiceWorker'
localforage.config({ name: 'bioprovue' })
let MqttUrl
// for developer
if (process.env.NODE_ENV === 'development') {
MqttUrl = 'ws://192.168.5.66:8083'
// MqttUrl = 'ws://192.168.5.57:8083'
// MqttUrl = 'ws://192.168.5.57:8080'
} else {
// for user
MqttUrl = `ws://${location.href.split('/')[2]}:8083`
}
if (process.env.VUE_APP_BUILD_VERSION) {
// eslint-disable-next-line
const message = `%c${'Build_information:'}\n %c${'Version'}: %c${VERSION},\n %c${'Timestamp'}: %c${TIMESTAMP},\n %c${'Commit'}: %c${COMMIT}`
const message = `%c${'Build_information:'}\n %c${'Version'}: %c${VERSION},\n %c${'Timestamp'}: %c${TIMESTAMP},\n %c${'Commit'}: %c${COMMIT} %c${'Mqtt'}: %c${MqttUrl}`
// eslint-disable-next-line
console.info(
message,
'color: blue;', 'color: red;', 'color: blue;', 'color: red;', 'color: blue;', 'color: red;', 'color: blue;',
'color: blue;', 'color: red;', 'color: blue;', 'color: red;', 'color: blue;', 'color: red;', 'color: blue;', 'color: red;', 'color: blue;',
)
}
@@ -56,12 +72,12 @@ Vue.component('chart', ECharts)
Vue.use(VueWorker)
Vue.use(VueAxios, axios)
Vue.use(Toast)
// Vue.use(VueMqtt, 'ws://52.194.17.114:8083')
Vue.use(VueMqtt, 'ws://' + location.href.split('/')[2] + ':8083')
// Vue.use(VueMqtt, 'ws://' + location.href.split('/')[2] + ':8083')
// Vue.use(VueMqtt, 'ws://' + '192.168.151.125' + ':8083')
// Vue.use(VueMqtt, 'ws://' + '192.168.3.211' + ':8083')
Vue.use(VueMqtt, MqttUrl)
Vue.prototype.API = api
Vue.prototype.GLOBAL = global_
Vue.use(ColorThemePlugin, {
@@ -9,7 +9,7 @@
<span slot="header">Control Panel</span>
<div slot="body">
<div>
<top-control-panel :ref="'top_control_panel'" @refreshChart="setOption" @changeAxis="changeAxis" @changeOverviewDataZoom="changeOverviewDataZoom"/>
<top-control-panel :ref="'top_control_panel'" @refreshChart="setOption" @changeAxis="changeAxis" @changeOverviewDataZoom="changeOverviewDataZoom" @changeFunctional="changeFunctional"/>
</div>
</div>
</va-collapse>
@@ -106,6 +106,8 @@ export default {
zoomTime: 0,
initDone: false,
chartAreaClass: ['flex', 'xs12', 'sm12', 'md12', 'xl9', 'pa-0'],
xfunctional: 'Linear',
yfunctional: 'Linear',
}
},
mqtt: {
@@ -236,7 +238,6 @@ export default {
this.windowLength = this.endTime - this.startTime
this.chartOverviewData.dataZoom[0].start = dataZoom.start
this.chartOverviewData.dataZoom[0].end = dataZoom.end
// console.log(this.startTime, this.endTime)
}
})
} else {
@@ -247,7 +248,6 @@ export default {
this.windowLength = this.endTime - this.startTime
this.chartOverviewData.dataZoom[0].start = e.start
this.chartOverviewData.dataZoom[0].end = e.end
// console.log(this.startTime, this.endTime)
}
}
this.zoomTime = 0
@@ -313,7 +313,6 @@ export default {
if (this.axisXDataType.description === 'Time') {
scale = await this.computeResampleScale(metaInfo, metaInfo.time_duration)
}
console.log('overview scale:', scale)
// download data
const getAllData = async function (_this) {
for (const ch in _this.dataInfo[meta]) {
@@ -419,27 +418,113 @@ export default {
}
}
// download and push into chart
// due to the (endIndex - startIndex) may more than 1, need to record variables outside the loop
var integralResult = 0
var curXData = 0
var curYData = 0
var prevXData = 0
var prevYData = 0
for (let i = startIndex; i <= endIndex; i++) {
const data = await this.getData(parseInt(scale), this.sampleMethod, dataListY[i].id, channelY, metaInfo)
let dataX
if (this.axisXDataType.description !== 'Time') {
dataX = await this.getData(parseInt(scale), this.sampleMethod, dataListX[i].id, channelX, metaInfo)
}
var deltaX = 0
var diffResult = 0
var logZero = false
var lastXinThisTable
for (let j = 0, len = data.length; j < len; j++) {
// check which channel and push processed data (i.e. merge two channel data, now data is (time, value) format)
if (parseInt(data[j][0]) >= _startTime && parseInt(data[j][0]) <= _endTime) {
const processedData = data[j]
logZero = false
// cases without time
if (dataX !== undefined) {
processedData[0] = dataX[j][1]
// add time on the chart
// TODO: not sure the time is right or not?
processedData[2] = parseFloat(dataX[j][0])
}
if (this.displayType.x === 'log' || this.absToggleStatus.x === true) {
// below is the original version for the log
/* if (this.displayType.x === 'log' || this.absToggleStatus.x === true) {
processedData[0] = Math.abs(processedData[0])
}
if (this.displayType.y === 'log' || this.absToggleStatus.y === true) {
processedData[1] = Math.abs(processedData[1])
} */
if (this.xfunctional === 'Log') {
// avoid log10(0) cases
if (Math.abs(processedData[0]) === 0) logZero = true
processedData[0] = Math.log10(Math.abs(processedData[0]))
}
this.chartDetailData.series[_gridNumber].data.push(processedData)
if (this.yfunctional === 'Log') {
if (Math.abs(processedData[1]) === 0) logZero = true
processedData[1] = Math.log10(Math.abs(processedData[1]))
} else if (this.yfunctional === 'Integral') {
if (j === 0) {
// TODO: need to change the series[deviceID]
// TODO: change the time index(dynamic changing)
curYData = parseFloat(processedData[1])
// integral only when I-T & C-A, so writen as [0] directly
prevYData = parseFloat(data[j][1])
// initial integral as 0
if (i === 0) processedData[1] = 0
else {
if (dataX !== undefined) {
// e.g. I-V: deltaX is V
deltaX = parseFloat(dataX[j][1]) - lastXinThisTable
} else {
// e.g. I-T: deltaX is T
deltaX = parseFloat(data[j][0]) - lastXinThisTable
}
integralResult += parseFloat((Math.abs(curYData) + Math.abs(prevYData)) * Math.abs(deltaX) / 2)
processedData[1] = integralResult
}
} else {
curYData = parseFloat(data[j][1])
if (dataX !== undefined) {
// e.g. I-V: deltaX is V
deltaX = parseFloat(dataX[j][1]) - parseFloat(dataX[j - 1][1])
lastXinThisTable = parseFloat(dataX[j][1])
} else {
// e.g. I-T: deltaX is T
deltaX = parseFloat(data[j][0]) - parseFloat(data[j - 1][0])
lastXinThisTable = parseFloat(data[j][0])
}
integralResult += parseFloat((Math.abs(curYData) + Math.abs(prevYData)) * Math.abs(deltaX) / 2)
// assign here is due to the fetch the modify value
prevYData = curYData
processedData[1] = integralResult
}
} else if (this.yfunctional === 'Differential') {
if (j === 0) {
// TODO: need to change the series[deviceID]
// TODO: change the time index(dynamic changing)
curXData = parseFloat(processedData[0])
curYData = parseFloat(processedData[1])
deltaX = parseFloat(dataX[j + 1][0]) - parseFloat(dataX[j][0])
if (i === 0) logZero = true
// due to the limitation of the getData table, the number of page may > 1
else {
diffResult = parseFloat((curYData - prevYData) / (curXData - prevXData))
processedData[0] = curXData
processedData[1] = diffResult
}
prevXData = parseFloat(processedData[0])
prevYData = parseFloat(processedData[1])
} else {
curXData = parseFloat(processedData[0])
curYData = parseFloat(processedData[1])
diffResult = parseFloat((curYData - prevYData) / (curXData - prevXData))
prevXData = curXData
prevYData = curYData
processedData[0] = curXData
processedData[1] = diffResult
}
}
// avoid pushing the infinity data into the chart
if (!logZero) this.chartDetailData.series[_gridNumber].data.push(processedData)
}
}
}
@@ -478,6 +563,13 @@ export default {
}
}
},
changeFunctional (axis, functional) {
if (axis === 'x') {
this.xfunctional = functional
} else {
this.yfunctional = functional
}
},
changeAxis (gridIndex) {
if (this.initDone) {
const libName = this.metaList[gridIndex].device.library_name
@@ -9,7 +9,6 @@
<script>
import { mapMutations } from 'vuex'
import types from '@/store/modules/analysis/replay/types'
// import { chartData } from '../../../../data/task/ChartsManagement'
export default {
name: 'elite-replay-chart',
@@ -7,7 +7,6 @@
</template>
<script>
// import { chartData } from '../../../../data/task/ChartsManagement'
export default {
name: 'elite-replay-overview-chart',
@@ -15,7 +15,7 @@
<div class="flex-container mb-2">
<div class="flex sm2 xl2 md2 xs2 px-0 py-0">
<p class="display-6"> X-axis <p/>
<p class="display-6"> X-axis </p>
</div>
<div class="flex sm5 xl5 md5 xs5 pl-1 pr-0 py-0">
<change-axis :ref="'change_axis_x'" axis="x" @changeAxis="changeAxis" @changeUnit="changeUnit" @clearCycle="clearCycle"/>
@@ -27,7 +27,7 @@
<div class="flex-container mb-2">
<div class="flex sm2 xl2 md2 xs2 px-0 py-0" />
<div class="flex sm5 xl5 md5 xs5 pl-1 pr-0 py-0">
<change-scale :ref="'change_scale_x'" axis="x" @refreshChart="refreshChart" @clearCycle="clearCycle" @changeAxis="changeAxis"/>
<change-scale :ref="'change_scale_x'" axis="x" @refreshChart="refreshChart" @clearCycle="clearCycle" @changeAxis="changeAxis" @changeFunctional="changeFunctional"/>
</div>
<div class="flex sm5 xl5 md5 xs5 px-0 py-0">
<abs-toggle :ref="'abs_x'" axis="x" @changeAxis="changeAxis"/>
@@ -36,7 +36,7 @@
<div class="flex-container mb-2">
<div class="flex sm2 xl2 md2 xs2 px-0 py-0">
<p class="display-6"> Y-axis <p/>
<p class="display-6"> Y-axis </p>
</div>
<div class="flex sm5 xl5 md5 xs5 pl-1 pr-0 py-0">
<change-axis :ref="'change_axis_y'" axis="y" @changeAxis="changeAxis" @changeUnit="changeUnit" @clearCycle="clearCycle"/>
@@ -48,7 +48,7 @@
<div class="flex-container mb-2">
<div class="flex sm2 xl2 md2 xs2 px-0 py-0" />
<div class="flex sm5 xl5 md5 xs5 pl-1 pr-0 py-0">
<change-scale :ref="'change_scale_y'" axis="y" @refreshChart="refreshChart" @clearCycle="clearCycle" @changeAxis="changeAxis"/>
<change-scale :ref="'change_scale_y'" axis="y" @refreshChart="refreshChart" @clearCycle="clearCycle" @changeAxis="changeAxis" @changeFunctional="changeFunctional"/>
</div>
<div class="flex sm5 xl5 md5 xs5 px-0 py-0">
<abs-toggle :ref="'abs_y'" axis="y" @changeAxis="changeAxis"/>
@@ -141,6 +141,9 @@ export default {
refreshChart (options) {
this.$emit('refreshChart', options)
},
changeFunctional (axis, functional) {
this.$emit('changeFunctional', axis, functional)
},
changeAxis (gridIndex) {
this.$emit('changeAxis', gridIndex)
},
@@ -9,7 +9,6 @@
<script>
import { mapMutations } from 'vuex'
import types from '@/store/modules/analysis/replay/types'
// import { chartData } from '../../../../data/task/ChartsManagement'
export default {
name: 'neulive-replay-chart',
@@ -7,7 +7,6 @@
</template>
<script>
// import { chartData } from '../../../../data/task/ChartsManagement'
export default {
name: 'neulive-replay-overview-chart',
@@ -0,0 +1,332 @@
<template>
<div>
<va-button v-if="integralClicked && (mode_name==='Chronoamperometric' || mode_name==='I-T Graph')" color="danger" class="mb-2" @click="clickIntegral" small>
To Raw Mode
</va-button>
<va-button v-if="!integralClicked && (mode_name==='Chronoamperometric' || mode_name==='I-T Graph')" color="primary" class="mb-2" @click="clickIntegral" small>
To Integral Mode
</va-button>
<va-button v-if="xlogClicked && (mode_name==='Linear Sweep Voltammetry' || mode_name==='I-V Curve')" color="danger" class="mb-2" @click="clickXLog" small>
To Raw Mode
</va-button>
<va-button :disabled="disableLog" v-if="!xlogClicked && (mode_name==='Linear Sweep Voltammetry' || mode_name==='I-V Curve')" color="primary" class="mb-2" @click="clickXLog" small>
To log Mode (x-axis)
</va-button>
<va-button v-if="ylogClicked && (mode_name==='Linear Sweep Voltammetry' || mode_name==='I-V Curve')" color="danger" class="mb-2" @click="clickYLog" small>
To Raw Mode
</va-button>
<va-button :disabled="disableLog" v-if="!ylogClicked && (mode_name==='Linear Sweep Voltammetry' || mode_name==='I-V Curve')" color="primary" class="mb-2" @click="clickYLog" small>
To log Mode (y-axis)
</va-button>
<va-button v-if="diffClicked && (mode_name==='Linear Sweep Voltammetry' || mode_name==='I-V Curve')" color="danger" class="mb-2" @click="clickDiff" small>
To Raw Mode
</va-button>
<va-button :disabled="disableDiff" v-if="!diffClicked && (mode_name==='Linear Sweep Voltammetry' || mode_name==='I-V Curve')" color="primary" class="mb-2" @click="clickDiff" small>
To Differential Mode
</va-button>
</div>
</template>
<script>
import { mapFields } from 'vuex-map-fields'
import { mapActions } from 'vuex'
import taskTypes from '@/store/modules/task/content/types'
import paramTable from '@/data/config-table/index'
import { getTimeFormatter } from '@/store/modules/task/content/actions/chartAct'
export default {
name: 'CanvasChartReplayCalculation',
components: {
},
props: {
chartID: {
type: [Number, String],
required: true,
},
},
computed: {
...mapFields('', [
'developer_mode',
]),
...mapFields('taskContent', [
'chartData',
'taskContentChartKey',
'deviceListNew',
]),
},
data () {
return {
info: null,
paramTable: paramTable,
rawData: null,
mode_name: '',
xName: '',
yName: '',
obj: null,
integralClicked: false,
xlogClicked: false,
ylogClicked: false,
diffClicked: false,
disableDiff: false,
disableLog: false,
}
},
// watch rawData is use for detect whether the chartData is changed
watch: {
rawData: {
deep: true,
handler: function () {
// avoid getting null data
if (this.rawData.series.length > 0) {
this.watchHandler()
}
},
},
},
methods: {
// Do arithmetic operations triggered by button(raw, integral, log)
watchHandler: function () {
// this.data need to be deep copy from rawData, since we don't want to modify the source(chartData[])
// this.data = Object.assign({}, this.rawData)
this.data = JSON.parse(JSON.stringify(this.rawData))
this.addSource()
var curXData = 0
var curYData = 0
var prevXData = 0
var prevYData = 0
var timeGap = 0
var curTime = 0
var integralResult = 0
var diffResult = 0
var index = 0
var timeIndex = this.getTimeIndex()
var _data = []
const dataLength = this.data.series[0].data.length
const seriesData = this.data.series[0].data
if (this.integralClicked) {
for (index = 0; index < dataLength; index++) {
if (index === 0) {
// TODO: need to change the series[deviceID]
// TODO: change the time index(dynamic changing)
curYData = parseFloat(seriesData[index][1])
timeGap = seriesData[index + 1][timeIndex] - seriesData[index][timeIndex]
curTime = seriesData[index][timeIndex]
_data.push([curTime, 0])
} else {
prevYData = parseFloat(seriesData[index - 1][1])
curYData = parseFloat(seriesData[index][1])
integralResult += parseFloat((Math.abs(curYData) + Math.abs(prevYData)) * timeGap / 2)
curTime += timeGap
_data.push([curTime, integralResult])
}
}
} else if (this.xlogClicked || this.ylogClicked) {
if (this.xlogClicked && this.ylogClicked) {
for (index = 0; index < dataLength; index++) {
if (index === 0) {
curXData = parseFloat(seriesData[index][0])
curYData = parseFloat(seriesData[index][1])
timeGap = seriesData[index + 1][timeIndex] - seriesData[index][timeIndex]
curTime = seriesData[index][timeIndex]
if (curXData !== 0 && curYData !== 0) {
_data.push([Math.log10(Math.abs(curXData)), Math.log10(Math.abs(curYData)), curTime])
}
} else {
curXData = parseFloat(seriesData[index][0])
curYData = parseFloat(seriesData[index][1])
curTime += timeGap
if (curXData !== 0 && curYData !== 0) {
_data.push([Math.log10(Math.abs(curXData)), Math.log10(Math.abs(curYData)), curTime])
}
}
}
} else if (this.xlogClicked && !(this.ylogClicked)) {
for (index = 0; index < dataLength; index++) {
if (index === 0) {
curXData = parseFloat(seriesData[index][0])
curYData = parseFloat(seriesData[index][1])
timeGap = seriesData[index + 1][timeIndex] - seriesData[index][timeIndex]
curTime = seriesData[index][timeIndex]
if (curXData !== 0) {
_data.push([Math.log10(Math.abs(curXData)), curYData, curTime])
}
} else {
curXData = parseFloat(seriesData[index][0])
curYData = parseFloat(seriesData[index][1])
curTime += timeGap
if (curXData !== 0) {
_data.push([Math.log10(Math.abs(curXData)), curYData, curTime])
}
}
}
} else if (!(this.xlogClicked) && this.ylogClicked) {
for (index = 0; index < dataLength; index++) {
if (index === 0) {
curXData = parseFloat(seriesData[index][0])
curYData = parseFloat(seriesData[index][1])
timeGap = seriesData[index + 1][timeIndex] - seriesData[index][timeIndex]
curTime = seriesData[index][timeIndex]
if (curYData !== 0) {
_data.push([curXData, Math.log10(Math.abs(curYData)), curTime])
}
} else {
curXData = parseFloat(seriesData[index][0])
curYData = parseFloat(seriesData[index][1])
curTime += timeGap
if (curYData !== 0) {
_data.push([curXData, Math.log10(Math.abs(curYData)), curTime])
}
}
}
}
} else if (this.diffClicked) {
for (index = 0; index < dataLength; index++) {
if (index === 0) {
// TODO: need to change the series[deviceID]
// TODO: change the time index(dynamic changing)
curXData = parseFloat(seriesData[index][0])
curYData = parseFloat(seriesData[index][1])
timeGap = seriesData[index + 1][timeIndex] - seriesData[index][timeIndex]
curTime = seriesData[index][timeIndex]
// _data.push([curTime, 0, curTime])
} else {
curXData = parseFloat(seriesData[index][0])
curYData = parseFloat(seriesData[index][1])
prevXData = parseFloat(seriesData[index - 1][0])
prevYData = parseFloat(seriesData[index - 1][1])
curTime += timeGap
diffResult = parseFloat((curYData - prevYData) / (curXData - prevXData))
_data.push([curXData, diffResult, curTime])
}
}
}
// decide feed in raw data / modified one
if (this.integralClicked || this.xlogClicked || this.ylogClicked || this.diffClicked) {
// console.log(_data)
this.data.series[0].data = _data
}
this.data.xAxis[0].type = 'value'
if (this.integralClicked) {
this.$emit('switchModeButton', 'Integral')
} else if (this.xlogClicked || this.ylogClicked) {
this.$emit('switchModeButton', 'log')
} else if (this.diffClicked) {
this.$emit('switchModeButton', 'Differential')
} else {
this.$emit('switchModeButton', '')
}
// TODO: modify the redundant code
if (this.xName === 'TIME') {
this.data.xAxis[0].axisLabel.formatter = function (val) {
return getTimeFormatter(val)
}
}
this.$emit('refreshData', this.data)
},
// resetClicked: function () {
// this.integralClicked = false
// this.xlogClicked = false
// this.ylogClicked = false
// this.diffClicked = false
// this.disableDiff = false
// this.disableLog = false
// },
clickIntegral: function () {
this.integralClicked = !(this.integralClicked)
const device = this.deviceListNew.find(ele => String(ele.memory_board) === String(this.data.mappingID))
if (device !== undefined) {
if (device.status === 0) {
this.watchHandler()
}
}
},
clickXLog: function () {
if (this.xlogClicked) {
this.xlogClicked = false
if (this.ylogClicked) {
this.disableDiff = true
} else {
this.disableDiff = false
}
} else {
this.xlogClicked = true
this.disableDiff = true
}
const device = this.deviceListNew.find(ele => String(ele.memory_board) === String(this.data.mappingID))
if (device !== undefined) {
if (device.status === 0) {
this.watchHandler()
}
}
},
clickYLog: function () {
if (this.ylogClicked) {
this.ylogClicked = false
if (this.xlogClicked) {
this.disableDiff = true
} else {
this.disableDiff = false
}
} else {
this.ylogClicked = true
this.disableDiff = true
}
const device = this.deviceListNew.find(ele => String(ele.memory_board) === String(this.data.mappingID))
if (device !== undefined) {
if (device.status === 0) {
this.watchHandler()
}
}
},
clickDiff: function () {
this.diffClicked = !(this.diffClicked)
this.disableLog = !(this.disableLog)
const device = this.deviceListNew.find(ele => String(ele.memory_board) === String(this.data.mappingID))
if (device !== undefined) {
if (device.status === 0) {
this.watchHandler()
}
}
},
addSource () {
if (this.data.gridSource.length > 0) {
const xAxisName = this.data.gridSource[0][0].xAxis
const yAxisName = this.data.gridSource[0][0].yAxis
this.xName = (xAxisName.split(' ')).pop()
this.yName = (yAxisName.split(' ')).pop()
if ((this.xName === 'VOLTAGE' && this.yName === 'CURRENT') || (this.xName === 'CURRENT' && this.yName === 'VOLTAGE')) {
this.mode_name = 'I-V Curve' // integration
} else if (this.xName === 'TIME' && this.yName === 'CURRENT') {
this.mode_name = 'I-T Graph' // differential and log
}
}
},
// index 0 is for the mode which x-axis is represent time, 2 is for the other mode(s)
getTimeIndex: function () {
let xAxisName = this.rawData.gridSource[0][0].xAxis
xAxisName = (xAxisName.split(' ')).pop()
return (xAxisName === 'TIME') ? 0 : 2
},
// these function below are using for print out the data (debug)
getAlldata: function () {
return this.data.series[0].data[(this.data.series[0].data).length - 1]
},
getXdata: function () {
var value = this.data.series[0].data[(this.data.series[0].data).length - 1][0]
return this.xName + ': ' + value + ' ' + this.xUnit
},
getYdata: function () {
var value = this.data.series[0].data[(this.data.series[0].data).length - 1][1]
return this.yName + ': ' + value + ' ' + this.yUnit
},
...mapActions('taskContent', [
taskTypes.chart.saveToCache,
]),
},
async mounted () {
this.rawData = this.chartData[this.chartID]
},
}
</script>
@@ -4,7 +4,7 @@
<va-select
@input="changeAxis()"
:label="''"
v-if="deviceName!=='EliteEIS'"
v-if="deviceName!=='EliteEIS' || (deviceName==='EliteEIS' && metaList[metaIndex].parameter_set.MODE === 1)"
v-model="channelFormat"
textBy="description"
class="va-select-without-margin"
@@ -14,7 +14,7 @@
<va-select
@input="changeAxis()"
:label="''"
v-if="deviceName==='EliteEIS'"
v-if="deviceName==='EliteEIS' && metaList[metaIndex].parameter_set.MODE !== 1"
v-model="channelFormat"
textBy="description"
class="va-select-without-margin"
@@ -1,3 +1,4 @@
<!-- eslint-disable prefer-const -->
<template>
<div>
<va-select
@@ -92,26 +93,111 @@ export default {
}
},
async calculateScaleHelper (gridIndex, ch) {
let seriesData
if (this.scaleFormat.description === 'Log') {
seriesData = JSON.parse(JSON.stringify(this.chartData[this.chartID].series[gridIndex].data))
for (let i = 0; i < seriesData.length; i++) {
if (this.axis === 'x') {
seriesData[i][0] = Math.abs(seriesData[i][0])
} else if (this.axis === 'y') {
seriesData[i][1] = Math.abs(seriesData[i][1])
// console.log('desc', this.scaleFormat.description)
/* var _dataDiff = []
var _dataIntegral = []
var _dataLog = []
// this.$emit('changeAxis', this.metaIndex)
// this.$emit('clearCycle')
if (this.scaleFormat.description === 'Differential') {
// await this.reDrawChart()
// eslint-disable-next-line prefer-const
let seriesData = JSON.parse(JSON.stringify(this.chartData[this.chartID].series[gridIndex].data))
// console.log('diff')
var curXData = 0
var curYData = 0
var prevXData = 0
var prevYData = 0
var timeGap = 0
var curTime = 0
_dataDiff = []
var diffResult = 0
for (let index = 0; index < seriesData.length; index++) {
if (index === 0) {
curXData = parseFloat(seriesData[index][0])
curYData = parseFloat(seriesData[index][1])
// timeGap = seriesData[index + 1][timeIndex] - seriesData[index][timeIndex]
// curTime = seriesData[index][timeIndex]
// _data.push([curTime, 0, curTime])
} else {
curXData = parseFloat(seriesData[index][0])
curYData = parseFloat(seriesData[index][1])
prevXData = parseFloat(seriesData[index - 1][0])
prevYData = parseFloat(seriesData[index - 1][1])
curTime += timeGap
diffResult = parseFloat((curYData - prevYData) / (curXData - prevXData))
_dataDiff.push([curXData, diffResult])
}
}
this.updateSeriesChart({
chartID: this.chartID,
seriesIndex: gridIndex,
data: seriesData,
data: _dataDiff,
})
} else if (this.scaleFormat.description === 'Integral') {
// await this.reDrawChart()
// eslint-disable-next-line prefer-const
let seriesData = JSON.parse(JSON.stringify(this.chartData[this.chartID].series[gridIndex].data))
var curYDataIntegral = 0
var prevYDataIntegral = 0
var timeGapIntegral = 0
var curTimeIntegral = 0
var integralResult = 0
_dataIntegral = []
for (let index = 0; index < seriesData.length; index++) {
if (index === 0) {
curYDataIntegral = parseFloat(seriesData[index][1])
timeGapIntegral = seriesData[index + 1][0] - seriesData[index][0]
curTimeIntegral = seriesData[index][0]
_dataIntegral.push([curTime, 0])
} else {
prevYDataIntegral = parseFloat(seriesData[index - 1][1])
curYDataIntegral = parseFloat(seriesData[index][1])
integralResult += parseFloat((Math.abs(curYDataIntegral) + Math.abs(prevYDataIntegral)) * timeGapIntegral / 2)
curTimeIntegral += timeGapIntegral
_dataIntegral.push([curTimeIntegral, integralResult])
}
}
this.updateSeriesChart({
chartID: this.chartID,
seriesIndex: gridIndex,
data: _dataIntegral,
})
} else if (this.scaleFormat.description === 'Log') {
await this.reDrawChart()
setTimeout(() => {
// eslint-disable-next-line prefer-const
let seriesData = JSON.parse(JSON.stringify(this.chartData[this.chartID].series[gridIndex].data))
_dataLog = seriesData
for (let i = 0; i < seriesData.length; i++) {
if (this.axis === 'x') {
seriesData[i][0] = parseFloat(seriesData[i][0])
if (seriesData[i][0] !== 0) {
// seriesData[i][0] = Math.log10(Math.abs(seriesData[i][0]))
_dataLog[i][0] = Math.log10(Math.abs(seriesData[i][0]))
}
} else if (this.axis === 'y') {
seriesData[i][1] = parseFloat(seriesData[i][1])
if (seriesData[i][1] !== 0) {
// seriesData[i][1] = Math.log10(Math.abs(seriesData[i][1]))
_dataLog[i][1] = Math.log10(Math.abs(seriesData[i][1]))
}
}
}
this.updateSeriesChart({
chartID: this.chartID,
seriesIndex: gridIndex,
data: _dataLog,
})
console.log('done')
}, 2000)
// eslint-disable-next-line prefer-const
} else if (this.scaleFormat.description === 'Linear') {
// console.log(this.recInfo)
if (this.deviceName.startsWith('Neulive')) {
console.log('inside neulive')
// [Region] get the subfile index
seriesData = []
// eslint-disable-next-line prefer-const
let seriesData = []
const dataYList = this.recInfo[this.metaID][ch][this.currentScale]
let startIndex = 0
let endIndex = 0
@@ -140,12 +226,23 @@ export default {
}
}
} else if (this.deviceName === 'EliteZM15' || this.deviceName === 'EliteEIS') {
this.$emit('changeAxis', this.metaIndex)
this.$emit('clearCycle')
console.log('inside Elite')
// this.$emit('changeAxis', this.metaIndex)
// this.$emit('clearCycle')
this.reDrawChart()
}
}
} */
// console.log('inside changeScale: ', this.scaleFormat.description)
this.reDrawChart()
this.setAxisDisplayChart({ type: this.displayType[this.axis], axis: this.axis, chartID: this.chartID, gridIndex: gridIndex })
},
reDrawChart: function () {
// console.log('die here')
this.$emit('changeFunctional', this.axis, this.scaleFormat.description)
// console.log('reDrawChart: ', this.axis, this.scaleFormat.description)
this.$emit('changeAxis', this.metaIndex)
this.$emit('clearCycle')
},
getData: async function (scale, sampleMethod, id, channel, meta) {
if (scale === 1) {
return await download.rawByIDChannels(id, channel, meta)
@@ -162,6 +259,11 @@ export default {
...mapGetters('replay', [types.rec.getCycleDict]),
},
mounted () {
if (this.axis === 'x') {
this.scaleOptions = this.scaleXOptions
} else if (this.axis === 'y') {
this.scaleOptions = this.scaleYOptions
}
},
data () {
return {
@@ -169,7 +271,8 @@ export default {
metaID: 0,
metaInfo: null,
scaleFormat: { id: 0, description: 'Linear' },
scaleOptions: [
scaleOptions: [],
scaleXOptions: [
{
id: 0,
description: 'Linear',
@@ -179,6 +282,24 @@ export default {
description: 'Log',
},
],
scaleYOptions: [
{
id: 0,
description: 'Linear',
},
{
id: 1,
description: 'Log',
},
{
id: 2,
description: 'Integral',
},
{
id: 3,
description: 'Differential',
},
],
}
},
destroyed () {
@@ -343,6 +343,23 @@ export default {
unitScale: 1e6,
},
],
voltage: [ // Voltage
{
id: 1,
unit: 'mV',
unitScale: 1000,
},
{
id: 0,
unit: 'uV',
unitScale: 1,
},
{
id: 2,
unit: 'V',
unitScale: 1000000,
},
],
frequency: [ // Frequency
{
id: 0,
@@ -80,7 +80,7 @@ export default {
// [TODO] 0: not sure future UX design
const meta = this.metaList[0]
file.clearFileList()
const files = await api.meta.getByParent('folder', meta.parent.folder[0])
const files = await api.meta.getAttrByParent('folder', meta.parent.folder[0], 'id-path-name-parent-description-size-time_duration-uuid-device-channels-created_at')
file.updateFileList(files)
const tmpFiles = file.getFileList()
for (let i = 0; i < tmpFiles.length; i++) {
@@ -8,7 +8,7 @@
<script>
import { mapFields } from 'vuex-map-fields'
import paramTable from '@/data/param-table/index.js'
import paramTable from '@/data/config-table/index.js'
export default {
name: 'show-parameter',
@@ -25,6 +25,7 @@ export default {
data () {
return {
deviceName: '',
mode: -1,
content: '',
showDict: {},
// [region] for neulive
@@ -46,58 +47,6 @@ export default {
description: '800',
},
],
neuliveSampleRateOptions: [
{
id: 0,
value: 1000,
description: '1k',
},
{
id: 1,
value: 2000,
description: '2k',
},
{
id: 2,
value: 4000,
description: '4k',
},
{
id: 3,
value: 5000,
description: '5k',
},
{
id: 4,
value: 8000,
description: '8k',
},
{
id: 5,
value: 10000,
description: '10k',
},
{
id: 6,
value: 20000,
description: '20k',
},
{
id: 7,
value: 40000,
description: '40k',
},
{
id: 8,
value: 80000,
description: '80k',
},
{
id: 9,
value: 100000,
description: '100k',
},
],
stimulateElectrodeOptions: [
{
label: 'Monopolar',
@@ -351,11 +300,7 @@ export default {
}
} else if (key === 'SAMPLE_RATE') {
showKey = 'Sample Rate'
for (let i = 0; i < this.neuliveSampleRateOptions.length; i++) {
if (this.neuliveSampleRateOptions[i].value === value) {
showValue = this.neuliveSampleRateOptions[i].description
}
}
showValue = value
}
this.content += ' ' + showKey + ': ' + showValue + '<br/>'
}
@@ -434,19 +379,20 @@ export default {
this.content += ' Period: ' + String(period) + ' ms' + '<br/>'
}
} else if (this.deviceName === 'EliteZM15' || this.deviceName === 'EliteEIS') {
const mode = params.MODE
const modeName = paramTable[this.deviceName].MODE[mode].name
const showParams = paramTable[this.deviceName].MODE[mode].showParameter
const mode = this.mode = params.MODE
const config = paramTable.getConfig(this.deviceName)
const modeConfig = paramTable.getModeConfig(this.deviceName, mode)
const modeName = modeConfig.name
const showParams = modeConfig.showParameter
this.showDict.MODE = modeName
if (modeName === 'Pulse Sensing') {
const duplicateParam = ['V_initial', 't_pulse', 'CURR_REC_START', 'CURR_REC_END']
const duplicateParam = ['V_initial', 't_pulse', 'CURR_REC']
for (let i = 0; i < 4; i++) {
const key = 'segment_order_' + String(i)
const order = paramTable[this.deviceName][key].rev_func(params[key])
if (parseInt(order) !== 0) { // if === 0, 代表沒有使用這個block
for (let key of duplicateParam) {
key = key + '_' + String(i)
this.fillShowDict(key, params[key])
const key = 'segment_order'
const order = config[key].outputReadabilityData(params[key], 1, i)
if (parseInt(order) >= 0) { // if === -1, 代表沒有使用這個block
for (const key of duplicateParam) {
this.fillShowDict(key, config[key].outputReadabilityData(params[key], 1, i), i)
}
}
}
@@ -464,10 +410,18 @@ export default {
}
this.dump()
},
fillShowDict (key, value) {
const expVal = paramTable[this.deviceName][key].rev_func(value)
const name = paramTable[this.deviceName][key].showName
const unit = paramTable[this.deviceName][key].defaultUnit
fillShowDict (key, value, index = -1) {
const config = paramTable.getConfig(this.deviceName)
const expVal = config[key].defaultUnit
? config[key].outputReadabilityData(value, config[key].unit[config[key].defaultUnit])
: config[key].outputReadabilityData(value)
let name = typeof (config[key].showName) === 'function'
? config[key].showName(this.mode)
: config[key].showName
if (index >= 0) {
name += ` ${index + 1}`
}
const unit = config[key].defaultUnit
this.showDict[name] = unit !== undefined ? expVal.toString() + unit : expVal.toString()
},
dump () {
@@ -9,7 +9,6 @@
<script>
import { mapMutations } from 'vuex'
import types from '@/store/modules/analysis/spike/types'
// import { chartData } from '../../../../data/task/ChartsManagement'
export default {
name: 'spike-replay-chart',
@@ -7,7 +7,6 @@
</template>
<script>
// import { chartData } from '../../../../data/task/ChartsManagement'
export default {
name: 'spike-overview-chart',
+115
View File
@@ -0,0 +1,115 @@
<template>
<va-card class="flex xl3 md3 sm12 xs12" title="MQTT">
<div class="row ma-1 text-center">
<va-button @click="getControllerID">Controller-ID</va-button>
<div class="flex-center">
{{ controllerID }}
</div>
</div>
<div class="row ma-1 text-start" v-if="controllerID !== ''">
<va-button @click="getHardwareInfo">HardwareInfo</va-button>
<div class="">
{{ responseMessage }}
</div>
</div>
</va-card>
</template>
<script>
import api from '@/data/api'
export default {
name: 'Developer',
components: {
},
data () {
return {
controllerID: '',
responseMessage: '',
}
},
mqtt: {
async '+/get_device_info_all/+' (data, topic) {
console.log('get_device_info_all', String.fromCharCode.apply(null, data))
},
async '+/hardware_device/+' (data, topic) {
console.log('hardware_device', String.fromCharCode.apply(null, data))
},
async '+/hardware_datetime/+' (data, topic) {
console.log('hardware_datetime', String.fromCharCode.apply(null, data))
},
async '+/hardware_info/+' (data, topic) {
console.log('hardware_info', String.fromCharCode.apply(null, data))
this.responseMessage = String.fromCharCode.apply(null, data)
},
async '+/broadcast/+' (data, topic) {
console.log('broadcast', String.fromCharCode.apply(null, data))
},
},
methods: {
mqttPub: function (topic, mes) {
this.$mqtt.publish(topic, mes)
},
mqttSub: function (val) {
this.$mqtt.subscribe(val)
},
mqttUnSub: function (val) {
this.$mqtt.unsubscribe(val)
},
pageMqttSub: function (id) {
this.mqttSub(id + '/hardware_datetime/+')
this.mqttSub(id + '/hardware_device/+')
this.mqttSub(id + '/hardware_info/+')
this.mqttSub(id + '/broadcast')
this.mqttSub(id + '/get_device_info_all/+')
},
pageMqttUnSub: function (id) {
this.mqttUnSub(id + '/hardware_datetime/+')
this.mqttUnSub(id + '/hardware_device/+')
this.mqttUnSub(id + '/hardware_info/+')
this.mqttUnSub(id + '/broadcast')
this.mqttUnSub(id + '/get_device_info_all/+')
},
getControllerID: async function () {
try {
const response = await api.controller.getAll()
if (response.status === 200) {
if (response.data.length > 0) {
this.controllerID = response.data[0].mqtt_id
this.pageMqttSub(this.controllerID)
return true
}
this.controllerID = 'No Controller Info'
return false
}
this.controllerID = 'Wrong status ' + response.status
} catch (e) {
console.log(e)
this.controllerID = e
}
},
getHardwareDatetime: function () {
this.mqttPub(this.controllerID + '_user', JSON.stringify({
header: 'hardware_datetime/0',
content: String(Date.now()),
}))
},
getHardwareInfo: function () {
this.mqttPub(this.controllerID + '_user', JSON.stringify({
header: 'hardware_info/0',
}))
},
},
async mounted () {
},
destroyed () {
if (this.controllerID !== '') {
this.pageMqttUnSub(this.controllerID)
}
},
}
</script>
<style>
</style>
+58
View File
@@ -0,0 +1,58 @@
<template>
<va-card class="" title="LED">
<div class="row ma-1">
<va-button v-for="color in colors" :key="color" :color="colorMapping[color]" @click="changeLedColor(color)">
{{color}}
</va-button>
<va-button :color="'gray'" @click="testLed()">test</va-button>
</div>
</va-card>
</template>
<script>
import { taskInfo } from '@/data/task/TaskInfo'
export default {
name: 'Developer',
components: {
},
data () {
return {
colors: ['red', 'orange', 'yellow', 'green', 'blue', 'cyan', 'magenta'],
colorMapping: {
red: 'danger',
orange: 'Orange',
blue: 'primary',
yellow: 'warning',
green: 'success',
cyan: 'info',
magenta: 'violet',
},
}
},
methods: {
mqttPub: function (topic, mes) {
this.$mqtt.publish(topic, mes)
},
testLed: function () {
this.changeLedColor('red')
setTimeout(() => { this.changeLedColor('blue') }, 2000)
setTimeout(() => { this.changeLedColor('green') }, 4000)
},
changeLedColor: function (color) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'hardware_send/0',
command: 'led',
state: color,
}))
},
},
async mounted () {
await taskInfo.updateTaskInfo(this.$route.params.taskID)
},
}
</script>
<style>
</style>
+13 -4
View File
@@ -22,6 +22,7 @@ import { mapFields } from 'vuex-map-fields'
import newDownload from '@/factories/file/downloadFactory'
import newChannel from '@/factories/file/channelFactory'
import { taskInfo } from '@/data/task/TaskInfo'
import configTable from '@/data/config-table/index'
export default {
name: 'Download',
@@ -92,7 +93,8 @@ export default {
async mounted () {
await this.getControllerList()
// TODO authorization
const format = this.$route.params.format
const format = this.$route.params.format.split('-')[0]
const allChannel = this.$route.params.format.split('-')[1]
this.metaList = this.$route.params.metaList.split('-')
const sd = this.$route.params.sd
@@ -106,7 +108,8 @@ export default {
}
if (meta !== undefined) {
this.metaInfo = meta
const channelArray = JSON.parse(this.metaInfo.channels)
const channelParamObj = configTable.getModeConfig(meta.device.library_name, meta.parameter_set.MODE).channels
const channelArray = allChannel === 'all' ? JSON.parse(this.metaInfo.channels) : Object.keys(channelParamObj).filter(ele => ele !== 'time')
const channelList = []
// split to different subfile by channel
@@ -217,14 +220,20 @@ export default {
const response = responseArray[responseIndex]
// console.log('response', response)
const idx = responseIndex % columnNum
// console.log('response', response)
for (const data of response.data) {
const timeUnitScale = channelParamObj.time.unit[channelParamObj.time.downloadUnit]
const channelUnitScale = channelParamObj[data.channel]?.unit[channelParamObj[data.channel]?.downloadUnit]
// console.log('data', data)
const dataArray = data.data.split('"***"').slice(0, -1)
// console.log('dataArray', dataArray)
for (const raw of dataArray) {
const rawArray = raw.split(' ')
this.downloadInfo.channelInfo[data.channel].downloadDataBuffer[idx].push(...rawArray)
const newArray = rawArray[0] === '' ? [] : rawArray.map((ele, index) => {
// console.log((parseInt(ele) / timeUnitScale).toFixed(Math.log10(timeUnitScale)))
return (index % 2 === 0) ? String((parseInt(ele) / timeUnitScale).toFixed(Math.log10(timeUnitScale))) : channelUnitScale ? String((parseInt(ele) / channelUnitScale).toFixed(Math.log10(channelUnitScale))) : ele
})
this.downloadInfo.channelInfo[data.channel].downloadDataBuffer[idx].push(...newArray)
// console.log('rawArray', rawArray)
}
}
+11 -3
View File
@@ -26,6 +26,7 @@ import newDownload from '@/factories/file/downloadFactory'
import newChannel from '@/factories/file/channelFactory'
import progressModal from '@/components/common/progressBarByValueModal/progressModal.vue'
import { taskInfo } from '@/data/task/TaskInfo'
import configTable from '@/data/config-table/index'
export default {
name: 'DownloadOffline',
@@ -97,7 +98,8 @@ export default {
async mounted () {
await this.getControllerList()
// TODO authorization
const format = this.$route.params.format
const format = this.$route.params.format.split('-')[0]
const allChannel = this.$route.params.format.split('-')[1]
this.metaList = this.$route.params.metaList.split('-')
const sd = this.$route.params.sd
@@ -111,7 +113,8 @@ export default {
}
if (meta !== undefined) {
this.metaInfo = meta
const channelArray = JSON.parse(this.metaInfo.channels)
const channelParamObj = configTable.getModeConfig(meta.device.library_name, meta.parameter_set.MODE).channels
const channelArray = allChannel === 'all' ? JSON.parse(this.metaInfo.channels) : Object.keys(channelParamObj).filter(ele => ele !== 'time')
const channelList = []
if (meta.device.library_name.indexOf('Neulive') >= 0) {
@@ -220,12 +223,17 @@ export default {
const idx = responseIndex % columnNum
// console.log('response', response)
for (const data of response.data) {
const timeUnitScale = channelParamObj.time.unit[channelParamObj.time.downloadUnit]
const channelUnitScale = channelParamObj[data.channel]?.unit[channelParamObj[data.channel]?.downloadUnit]
// console.log('data', data)
const dataArray = data.data.split('"***"').slice(0, -1)
// console.log('dataArray', dataArray)
for (const raw of dataArray) {
const rawArray = raw.split(' ')
this.downloadInfo.channelInfo[data.channel].downloadDataBuffer[idx].push(...rawArray)
const newArray = rawArray[0] === '' ? [] : rawArray.map((ele, index) => {
return (index % 2 === 0) ? String((parseInt(ele) / timeUnitScale).toFixed(Math.log10(timeUnitScale))) : channelUnitScale ? String((parseInt(ele) / channelUnitScale).toFixed(Math.log10(channelUnitScale))) : ele
})
this.downloadInfo.channelInfo[data.channel].downloadDataBuffer[idx].push(...newArray)
// console.log('rawArray', rawArray)
}
}
+1 -1
View File
@@ -68,7 +68,7 @@ export default {
this.$refs.file_ref.currentInfo = initCollection.data[0]
const folders = await api.collection.getByParent('folder', initCollection.data[0].id)
const files = await api.meta.getByParent('folder', initCollection.data[0].id)
const files = await api.meta.getAttrByParent('folder', initCollection.data[0].id, 'id-path-name-parent-description-size-time_duration-uuid-device-channels-created_at')
file.updateFileList(folders)
file.updateFileList(files)
+56 -35
View File
@@ -29,6 +29,11 @@
:okText=" $t('modal.confirm') "
@ok="editFile()"
@cancel="undoEdit()"
@keyup.native.enter="() => {
editFile()
showModal.editFile = false
}"
tabindex="0"
>
<va-input
:value="editInfo.changedName"
@@ -37,6 +42,7 @@
:success="editInfo.success"
:error="editInfo.error"
:error-messages="editInfo.errorMessages"
:ref="'edit_input'"
@input="checkFileNameValidate"
removable
/>
@@ -45,28 +51,40 @@
v-model="showModal.deleteFile"
size="small"
:title="'DELETE'"
:message="`Delete File ${deleteInfo.name}?`"
:okText=" $t('modal.confirm') "
@ok="deleteFile()"
@keyup.native.enter="() => {
deleteFile()
showModal.deleteFile = false
}"
tabindex="1"
>
<!-- invisiable to focus on modal -->
<p>Delete File {{ deleteInfo.name }} ? <input type="text" :ref="'delete_input'" style="opacity: 0; line-height: 0;"/></p>
</va-modal>
<va-modal
v-model="showModal.deleteMultiFiles"
size="small"
:title="'DELETE'"
:message="'Delete select files?'"
:okText=" $t('modal.confirm') "
@ok="deleteMultiFiles()"
@keyup.native.enter="() => {
deleteMultiFiles()
showModal.deleteMultiFiles = false
}"
tabindex="2"
>
<!-- invisiable to focus on modal -->
<p>Delete select files? <input type="text" :ref="'delete_multi_input'" style="opacity: 0; line-height: 0;"/></p>
</va-modal>
<va-card class="flex sm12 xl12 md12 xs12">
<template slot="header">
<div class="flex sm12 xl12 md12 xs12" style="text-align: end;">
<!-- <va-button class="" color="success" v-if="selected.length" @click="downloadSelected" target="_blank" small>
<va-button class="" color="success" v-if="selected.length" @click="downloadSelected" target="_blank" small>
DOWNLOAD
</va-button> -->
</va-button>
<va-button class="" color="danger" v-if="selected.length" @click="deleteMultiFilesConfirm" target="_blank" small>
DELETE
</va-button>
@@ -170,7 +188,7 @@
{{transTime(props.rowData.time_duration)}}
</template>
<template slot="device_info" slot-scope="props">
{{transDeviceInfo(props.rowData.configuration)}}
{{transDeviceInfo(props.rowData.device)}}
</template>
<template slot="actions" slot-scope="props" >
<va-popover :message="`sdcard ${props.rowData.name}`" placement="top">
@@ -263,8 +281,6 @@ export default {
path: '',
name: '',
metaID: '',
rawChannelAndIDArrays: [], // list of lists
miniChannelAndIDArrays: [], // list of lists
},
styleList: {
@@ -381,11 +397,11 @@ export default {
return this.GLOBAL.transTime(time)
}
},
transDeviceInfo: function (configuration) {
if (configuration === undefined) {
transDeviceInfo: function (device) {
if (device === undefined) {
return '--'
} else {
return configuration._DEVICE_NAME_ + '\n' + configuration._DEVICE_ADDR_
return device.device_name + '\n' + this.GLOBAL.transMac(device.device_address)
}
},
@@ -400,7 +416,7 @@ export default {
// call getfolder api and update
const folders = await api.collection.getByParent('folder', info.id)
const files = await api.meta.getByParent('folder', info.id)
const files = await api.meta.getAttrByParent('folder', info.id, 'id-path-name-parent-description-size-time_duration-uuid-device-channels-created_at')
file.updateFileList(folders)
file.updateFileList(files)
@@ -420,7 +436,7 @@ export default {
this.currentInfo = item
// call getfolder api and update
const folders = await api.collection.getByParent('folder', item.id)
const files = await api.meta.getByParent('folder', item.id)
const files = await api.meta.getAttrByParent('folder', item.id, 'id-path-name-parent-description-size-time_duration-uuid-device-channels-created_at')
file.updateFileList(folders)
file.updateFileList(files)
@@ -441,7 +457,7 @@ export default {
if (initCollection.data.length === 1) {
this.currentInfo = initCollection.data[0]
const folders = await api.collection.getByParent('folder', initCollection.data[0].id)
const files = await api.meta.getByParent('folder', initCollection.data[0].id)
const files = await api.meta.getAttrByParent('folder', initCollection.data[0].id, 'id-path-name-parent-description-size-time_duration-uuid-device-channels-created_at')
file.updateFileList(folders)
file.updateFileList(files)
this.fileLists = file.getFileList()
@@ -496,6 +512,9 @@ export default {
this.editInfo.info = info
this.editInfo.changedName = info.name
this.showModal.editFile = true
setTimeout(() => {
this.$refs.edit_input.$refs.input.focus()
}, 100)
},
editFile: async function () {
// TODO editFile
@@ -558,7 +577,7 @@ export default {
},
removeFileFromList: function () {
},
fillDeleteInfo (info) {
fillDeleteInfo: function (info) {
if (info.type === 'folder') {
this.deleteInfo.folderID = info.id
this.deleteInfo.name = info.name
@@ -566,32 +585,28 @@ export default {
this.deleteInfo.path = info.path
this.deleteInfo.name = info.name
this.deleteInfo.metaID = info.id
this.deleteInfo.rawChannelAndIDArrays = [] // list of lists
this.deleteInfo.miniChannelAndIDArrays = [] // list of lists
for (const [channel, idArray] of Object.entries(info.raw_data)) {
this.deleteInfo.rawChannelAndIDArrays.push([channel, idArray[0]])
}
for (const [channel, scaleObject] of Object.entries(info.mini_data)) {
for (const idArray of Object.values(scaleObject)) {
this.deleteInfo.miniChannelAndIDArrays.push([channel, idArray[0]])
}
}
}
},
async deleteFolder (id) {
deleteFolder: async function (id) {
await api.collection.update(id, { deleted: true })
await api.collection.clearDel()
},
async deleteSingleFileByDeleteInfo () {
deleteSingleFileByDeleteInfo: async function () {
await api.meta.update(this.deleteInfo.metaID, { deleted: true })
await api.meta.clearDel()
},
deleteFileConfirm: function (info) {
this.fillDeleteInfo(info)
this.showModal.deleteFile = true
setTimeout(() => {
this.$refs.delete_input.focus()
}, 100)
},
deleteFile: async function () {
if (this.deleteInfo.metaID !== undefined) {
this.showToast('deleting file...', {
position: 'bottom-right',
})
if (this.deleteInfo.metaID === undefined) {
await this.deleteFolder(this.deleteInfo.folderID)
} else {
await this.deleteSingleFileByDeleteInfo()
@@ -612,8 +627,14 @@ export default {
},
deleteMultiFilesConfirm: function () {
this.showModal.deleteMultiFiles = true
setTimeout(() => {
this.$refs.delete_multi_input.focus()
}, 100)
},
deleteMultiFiles: async function () {
this.showToast('deleting file...', {
position: 'bottom-right',
})
this.deleteSelected()
},
inputFieldReset: function (info) {
@@ -642,7 +663,7 @@ export default {
// call getfolder api and update
const folders = await api.collection.getByParent('folder', this.currentInfo.id)
const files = await api.meta.getByParent('folder', this.currentInfo.id)
const files = await api.meta.getAttrByParent('folder', this.currentInfo.id, 'id-path-name-parent-description-size-time_duration-uuid-device-channels-created_at')
file.updateFileList(folders)
file.updateFileList(files)
@@ -652,12 +673,12 @@ export default {
// this.$refs.datatable_ref.refresh()
// this.$refs.datatable_ref.currentPage = 1
},
// downloadSelected: function () {
// for (let i = 0; i < this.selected.length; i++) {
// const meta = this.selected[i]
// this.downloadCsv(meta)
// }
// },
downloadSelected: function () {
for (let i = 0; i < this.selected.length; i++) {
const meta = this.selected[i]
this.downloadExcel(meta)
}
},
async deleteSelected () {
for (let i = 0; i < this.selected.length; i++) {
const meta = this.selected[i]
@@ -714,7 +735,7 @@ export default {
if (this.controllerList[0].sd_uploading === false) {
const ret = await api.sdcard.getuuidList()
if (ret.status === 200) {
this.SDuuidList = ret.data.data
this.SDuuidList = ret.data
}
}
}
+74 -2
View File
@@ -10,7 +10,7 @@
: cardStyle.medium
: cardStyle.large
">
<project-view @start_project="startProject($event)" />
<project-view @start_project="startProject($event)" @stop_project="stopProject($event)" @save_project="saveProject($event)"/>
</div>
<div :class="cardStyle.small" v-show="taskViewPanel.show">
<project-task/>
@@ -22,7 +22,9 @@
import ProjectManager from '@/components/project/manager/ProjectManager'
import ProjectView from '@/components/project/view/ProjectView'
import ProjectTask from '@/components/project/task/ProjectTask'
import { mapActions } from 'vuex'
import { mapFields } from 'vuex-map-fields'
import types from '@/store/modules/project/types'
import { taskInfo } from '@/data/task/TaskInfo'
export default {
@@ -34,6 +36,8 @@ export default {
},
computed: {
...mapFields('project', [
'projectConfigList',
'runningProjectList',
'projectManagerPanel',
'taskViewPanel',
'deviceConnectList',
@@ -51,6 +55,7 @@ export default {
},
mqtt: {
async '+/get_device_info_all/+' (data, topic) {
this.deviceConnectList.length = 0
const deviceList = JSON.parse(String.fromCharCode.apply(null, data)).data
for (const device of deviceList) {
@@ -63,8 +68,41 @@ export default {
this.deviceConnectList.push(device)
}
},
async '+/run_project/+' (data, topic) {
const runningProjects = JSON.parse(String.fromCharCode.apply(null, data)).data
this.runningProjectList.push(runningProjects)
},
async '+/get_running_project/+' (data, topic) {
this.runningProjectList.length = 0
const runningProjects = JSON.parse(String.fromCharCode.apply(null, data)).data
this.runningProjectList.push(...runningProjects)
},
async '+/broadcast' (data, topic) {
const mes = String.fromCharCode.apply(null, data).split(':')
// let content
switch (mes[0]) {
case 'project':
this.pageToast(mes.slice(1).join(':'))
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'get_running_project/0',
}))
break
default:
break
}
},
},
methods: {
pageToast: function (mes) {
this.showToast(
mes,
{
icon: 'fa-bell',
position: 'bottom-right',
duration: 10000,
},
)
},
mqttSub: function (val) {
this.$mqtt.subscribe(val)
},
@@ -77,10 +115,14 @@ export default {
pageMqttSub: function (id) {
this.mqttSub(id + '/broadcast')
this.mqttSub(id + '/get_device_info_all/+')
this.mqttSub(id + '/run_project/+')
this.mqttSub(id + '/get_running_project/+')
},
pageMqttUnSub: function (id) {
this.mqttUnSub(id + '/broadcast')
this.mqttUnSub(id + '/get_device_info_all/+')
this.mqttUnSub(id + '/run_project/+')
this.mqttUnSub(id + '/get_running_project/+')
},
initPage: async function () {
await taskInfo.updateTaskInfo()
@@ -94,6 +136,29 @@ export default {
project: project,
}))
},
stopProject: function (project) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'stop_project/0',
project: project.uuid,
}))
},
saveProject: async function (project) {
this.updateProject({ project: project, api: this.API })
this.showToast(
'project update finish',
{
icon: 'fa-bell',
position: 'bottom-right',
duration: 5000,
},
)
},
...mapActions('project',
[
types.project.update,
],
),
},
async mounted () {
await this.initPage()
@@ -103,13 +168,20 @@ export default {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'get_device_info_all/0',
}))
const project = await this.API.project.getAll()
this.projectConfigList.length = 0
this.projectConfigList.push(...project.data)
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'get_running_project/0',
}))
},
}
</script>
<style lang="scss">
.project {
font-size: 12px;
font-size: 16px;
}
.markup-tables {
@@ -1,25 +1,25 @@
<template>
<div>
<va-card style="height: 80vh; overflow: auto; display: block;">
<va-card style="height: 90vh; overflow: auto; display: block;">
<template slot="header">
<va-icon name="fa fa-bluetooth-b mr-3" color="primary"/>
<h5 class="mt-0 mb-0">PROJECTS</h5>
</template>
<div class="flex d-flex m12 xs12 md12 xl12">
<div>
<va-button @click="createProject" icon="fa fa-plus"></va-button>
<va-button @click="createProject({ api: API })" icon="fa fa-plus"></va-button>
</div>
</div>
<div>
<va-tabs v-model="tabValue" style="width: 100%;" grow>
<va-tab v-for="title in tabTitles" :key="title">
<va-tab v-for="(title, index) in tabTitles" :key="title" @click.native="switchProjectCategory(index)">
{{ title }}
</va-tab>
</va-tabs>
</div>
<div class="mt-1">
<project-manager-list v-if='tabValue == 0'/>
<!-- <project-manager-running-table v-if='tabValue == 1'/> -->
<running-project-manager-list v-if='tabValue == 1'/>
</div>
</va-card>
</div>
@@ -27,17 +27,24 @@
<script>
import { mapActions } from 'vuex'
import { mapFields } from 'vuex-map-fields'
import types from '@/store/modules/project/types'
import ProjectManagerList from '@/components/project/manager/ProjectManagerList'
// import ProjectManagerRunningTable from '@/components/project/manager/table/ProjectManagerRunningTable'
import RunningProjectManagerList from '@/components/project/manager/RunningProjectManagerList'
export default {
name: 'project-manager',
components: {
ProjectManagerList,
RunningProjectManagerList,
},
computed: {
...mapFields('project', [
'lockMode',
'projectList',
'projectConfigList',
'runningProjectList',
]),
},
data () {
return {
@@ -46,6 +53,11 @@ export default {
}
},
methods: {
switchProjectCategory: function (title) {
const projectType = ['projectConfigList', 'runningProjectList']
this.projectList = this[projectType[title]]
this.lockMode = Boolean(title)
},
...mapActions('project',
[
types.project.create,
@@ -53,6 +65,7 @@ export default {
),
},
mounted () {
this.projectList = this.projectConfigList
},
}
</script>
@@ -1,14 +1,25 @@
<template>
<div class="row">
<div class="flex xs12 lg12 md12">
<va-item class="mb-1" v-for="(project, index) in projectList" :key="index" @click="selectProject({index: index})" clickable>
<va-item-section>
<va-item-label>
<va-item class="mb-1" v-for="(project, index) in projectConfigList" :key="index" @click="selectProject({index: index})" clickable>
<va-item-section @dblclick.native="switchEdit('name', index)">
<div v-if="projectTable.name == index">
<va-input
v-model="project.name"
style="width: 100px;"
@blur="switchEdit('name', -1, project)"
@keyup.enter="switchEdit('name', -1, project)"
/>
</div>
<div v-else>
{{ project.name }}
</va-item-label>
</div>
<!-- <va-item-label>
{{ project.name }}
</va-item-label> -->
</va-item-section>
<va-item-section side>
<va-icon class="fa fa-close" color="danger" @click.native.stop="deleteProject({index: index})"></va-icon>
<va-icon class="fa fa-close" color="danger" @click.native.stop="deleteProject({ project: project, index: index, api: API })"></va-icon>
</va-item-section>
</va-item>
</div>
@@ -22,21 +33,29 @@ import types from '@/store/modules/project/types'
export default {
name: 'project-manager-list',
computed: {
...mapFields('project', [
'projectList',
'projectConfigList',
]),
},
data () {
return {
projectTable: {
name: -1,
},
}
},
methods: {
switchEdit: function (tag, index, project) {
if (this.projectTable[tag] >= 0) {
this.projectTable[tag] = -1
project && this.API.project.update(project.id, { name: project.name })
} else {
this.projectTable[tag] = index
}
},
...mapActions('project',
[
types.project.select,
types.project.save,
types.project.delete,
],
),
@@ -0,0 +1,67 @@
<template>
<div class="row">
<div class="flex xs12 lg12 md12 sm12">
<va-item class="mb-1" v-for="(project, index) in runningProjectList"
:key="index" @click="selectProject({index: index})"
@mouseenter.native="() => mouse.hover = index"
@mouseleave.native="() => mouse.hover = -1"
>
<va-item-section>
<!-- {{ mouse.hover }} {{ index }} -->
<p>{{ project.name }} </p>
</va-item-section>
<va-item-section v-if="project.status === 1" side>
<!-- <div v-if="mouse.hover === index">
<va-icon class="fa fa-stop-circle-o" ></va-icon>
</div> -->
<div>
<fulfilling-bouncing-circle-spinner
:animation-duration="3000"
:color="'#6c7fee'"
:size="16"
></fulfilling-bouncing-circle-spinner>
</div>
</va-item-section>
<va-item-section v-if="project.status === 2" side>
<va-icon class="fa fa-check" ></va-icon>
</va-item-section>
</va-item>
</div>
</div>
</template>
<script>
import { mapFields } from 'vuex-map-fields'
import { mapActions } from 'vuex'
import types from '@/store/modules/project/types'
import { FulfillingBouncingCircleSpinner } from 'epic-spinners'
export default {
name: 'running-project-manager-list',
components: {
FulfillingBouncingCircleSpinner,
},
computed: {
...mapFields('project', [
'runningProjectList',
]),
},
data () {
return {
mouse: {
hover: -1,
},
}
},
methods: {
...mapActions('project',
[
types.project.select,
types.project.delete,
],
),
},
mounted () {
console.log(this.runningProjectList)
},
}
</script>
+1 -1
View File
@@ -1,6 +1,6 @@
<template>
<div>
<va-card style="height: 80vh; overflow: auto;">
<va-card style="height: 90vh; overflow: auto;">
<project-task-config></project-task-config>
</va-card>
</div>
@@ -130,8 +130,8 @@ export default {
const newAction = this.createAction(actionUUID, this.actionSelect, this.deviceSelect)
// if device not add in task then add in
if (!this.getSelectTask.deviceList.includes(this.deviceSelect)) {
this.getSelectTask.deviceList.push(this.deviceSelect)
if (!this.getSelectTask.device.includes(this.deviceSelect)) {
this.getSelectTask.device.push(this.deviceSelect)
}
for (const key in this.conditionObj) {
@@ -7,7 +7,7 @@
</div>
<div>
<va-list fit class="mb-2">
<va-item v-for="(device, index) in getSelectProject.deviceList" :key="index" >
<va-item v-for="(device, index) in getSelectProject.device" :key="index" >
<va-item-section side>
<va-checkbox
:value="device.isSelect"
@@ -30,7 +30,7 @@
</va-item-label>
<va-item-label caption>
{{ device.mac_address }}
{{ device.connectDevice.device_address }}
</va-item-label>
</va-item-section>
</va-item>
@@ -69,23 +69,23 @@ export default {
if (this.taskSelectKey !== undefined) {
device.isSelect = event
device.isSelect.includes(String(this.taskSelectKey)) === true
? this.getSelectTask.deviceList.push(key)
: this.getSelectTask.deviceList = this.getSelectTask.deviceList.filter(item => item !== key)
? this.getSelectTask.device.push(key)
: this.getSelectTask.device = this.getSelectTask.device.filter(item => item !== key)
} else {
// if select all tasks
if (event.includes('-1')) {
// check all
device.isSelect = ['-1', ...Array(this.getSelectProject.taskList.length).fill().map((_, index) => String(index))]
for (const task of this.getSelectProject.taskList) {
if (!task.deviceList.includes(key)) {
task.deviceList.push(key)
device.isSelect = ['-1', ...Array(this.getSelectProject.task.length).fill().map((_, index) => String(index))]
for (const task of this.getSelectProject.task) {
if (!task.device.includes(key)) {
task.device.push(key)
}
}
} else {
// uncheck all
device.isSelect = []
for (const task of this.getSelectProject.taskList) {
task.deviceList = task.deviceList.filter(item => item !== key)
for (const task of this.getSelectProject.task) {
task.device = task.device.filter(item => item !== key)
}
}
}
@@ -6,29 +6,51 @@
</div>
</div>
<div>
<elite-parameter-window></elite-parameter-window>
<device-parameter-recording
:ref="'device_parameter_ref'"
:parameter="parameter"
:library="'EliteEDC1.5'"
@setParameter="setParameter"
@setParameterWithDebounce="setParameterWithDebounce"
/>
</div>
</div>
</template>
<script>
import { mapFields } from 'vuex-map-fields'
import newCondition from '@/factories/project/conditionFactory'
import EliteParameterWindow from '@/components/project/task/config/parameter/EliteParameterWindow'
import { mapActions, mapGetters } from 'vuex'
import { mapFields } from 'vuex-map-fields'
import types from '@/store/modules/project/types'
import DeviceParameterRecording from '@/components/task/content/parameter/DeviceParameterRecording.vue'
import _ from 'lodash'
import configTable from '@/data/config-table/index'
export default {
name: 'project-task-config-parameter',
components: {
EliteParameterWindow,
DeviceParameterRecording,
},
computed: {
...mapGetters('project', [
types.task.getSelect,
types.task.getParameterSet,
types.project.getDevice,
types.project.getSelect,
]),
...mapFields('project', [
'taskSelect',
'taskViewPanel',
'taskSelectKey',
'deviceSelectKey',
]),
},
data () {
return {
parameter: {},
conditionList: newCondition(),
deviceSelected: null,
parameterUUID: '',
device: null,
config: null,
}
},
methods: {
@@ -38,8 +60,54 @@ export default {
selectCondition: function (condition) {
condition.select = !condition.select
},
setParameter: function (name, value) {
this.parameter = Object.assign({}, this.parameter)
if (this.parameterUUID === '') {
this.parameterUUID = this.GLOBAL.getUUID()
}
this.setParameterSetTask({
parameterSet: {
[name]: value,
target: this.deviceSelectKey,
},
parameterKey: this.parameterUUID,
})
},
setParameterWithDebounce: _.debounce(function (name, value) {
this.setParameter(name, value)
}, 100),
resetParameter: function (mode) {
// get Device
this.device = this.getDeviceProject(this.deviceSelectKey)
// get Config
this.config = configTable.getConfig(this.device.library.value)
// create default parameter
const defaultValue = {}
for (const key in this.config) {
if (this.config[key].defaultValue !== undefined) {
defaultValue[key] = this.config[key].defaultValue
}
}
const parameterSet = this.getParameterSetTask(this.taskSelectKey, this.deviceSelectKey)
this.parameter = { ...defaultValue }
if (parameterSet) {
this.parameterUUID = Object.keys(parameterSet)[0]
const param = Object.values(parameterSet)[0]
const modeOption = this.$refs.device_parameter_ref.workingModeOptions.find(ele => ele.id === param.MODE)
this.$refs.device_parameter_ref.workingModeSelectChange(modeOption)
this.parameter = Object.assign(this.parameter, Object.values(parameterSet)[0])
}
},
...mapActions('project',
[
types.task.setParameterSet,
],
),
},
mounted () {
// init parameter
this.resetParameter()
},
}
</script>
@@ -14,212 +14,274 @@
</div>
<!-- 1.5ui -->
<va-tree-category
v-if="workingModeSelect != null && workingModeSelect.id == 0 || workingModeSelect.id == 1 || workingModeSelect.id == 2 || workingModeSelect.id == 4 || workingModeSelect.id == 5 || workingModeSelect.id == 6 || workingModeSelect.id == 7 || workingModeSelect.id == 8 || workingModeSelect.id == 9 || workingModeSelect.id == 11 || workingModeSelect.id == 13"
style="font-size: 20px;"
:label="'Range ( ' + currentRangeOptions[currentRangeSelect].label + ' )'">
<va-tree-node>
<level-button :ref="'currentRangeSelect'" :deviceID="deviceID" :options="currentRangeOptions" :parameterName="'ADC_LEVEL_I_15'" @parameterChange="deviceParameterChange($event)" />
</va-tree-node>
</va-tree-category>
<div v-show="[0, 1, 2, 4, 5, 6, 7, 8, 9, 11, 13].includes(workingModeSelect.id)">
<p style="font-size: 20px;">Range ( {{ currentRangeOptions[currentRangeSelect].label }} )</p>
<level-button
:ref="'currentRangeSelect'"
:deviceID="deviceID"
:options="currentRangeOptions"
:parameterName="'ADC_LEVEL_I_15'"
@parameterChange="deviceParameterChange($event)"
/>
</div>
<va-tree-category
v-if="workingModeSelect != null && workingModeSelect.id == 0 || workingModeSelect.id == 1 || workingModeSelect.id == 2 || workingModeSelect.id == 4 || workingModeSelect.id == 5 || workingModeSelect.id == 6 || workingModeSelect.id == 7 || workingModeSelect.id == 8 || workingModeSelect.id == 9 || workingModeSelect.id == 11 || workingModeSelect.id == 13"
style="font-size: 20px;"
:label="'Range ( ' + voltageInRangeOptions[voltageInRangeSelect].label + ' )'">
<va-tree-node>
<level-button :ref="'voltageInRangeSelect'" :deviceID="deviceID" :options="voltageInRangeOptions" :parameterName="'ADC_LEVEL_V_IN_15'" @parameterChange="deviceParameterChange($event)" />
</va-tree-node>
</va-tree-category>
<div v-show="[0, 1, 2, 4, 5, 6, 7, 8, 9, 11, 13].includes(workingModeSelect.id)">
<p style="font-size: 20px;">Range ( {{ voltageInRangeOptions[voltageInRangeSelect].label }} )</p>
<level-button
:ref="'voltageInRangeSelect'"
:deviceID="deviceID"
:options="voltageInRangeOptions"
:parameterName="'ADC_LEVEL_V_IN_15'"
@parameterChange="deviceParameterChange($event)"
/>
</div>
<va-tree-category
v-if="workingModeSelect != null && workingModeSelect.id == 0 || workingModeSelect.id == 1 || workingModeSelect.id == 2 || workingModeSelect.id == 3 || workingModeSelect.id == 4 || workingModeSelect.id == 5 || workingModeSelect.id == 6 || workingModeSelect.id == 7 || workingModeSelect.id == 8 || workingModeSelect.id == 9 || workingModeSelect.id == 10"
style="font-size: 20px;"
:label="'HighZ ( ' + highzOptions[highzSelect].label + ' )'">
<va-tree-node>
<level-button :ref="'highzSelect'" :deviceID="deviceID" :options="highzOptions" :parameterName="'CTRL_HIGH_Z_15'" @parameterChange="deviceParameterChange($event)" />
</va-tree-node>
</va-tree-category>
<div v-show="[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10].includes(workingModeSelect.id)">
<p style="font-size: 20px;">HighZ ( {{ highzOptions[highzSelect].label }} )</p>
<level-button
:ref="'highzSelect'"
:deviceID="deviceID"
:options="highzOptions"
:parameterName="'CTRL_HIGH_Z_15'"
@parameterChange="deviceParameterChange($event)"
/>
</div>
<va-tree-category
v-if="workingModeSelect != null && workingModeSelect.id == 11"
style="font-size: 20px;"
:label="'Cali Channel ( ' + caliChannelOptions[caliChannelSelect].label + ' )'">
<va-tree-node>
<level-button :ref="'caliChannelSelect'" :deviceID="deviceID" :options="caliChannelOptions" :parameterName="'ADC_DAC_CHANNEL_15'" @parameterChange="deviceParameterChange($event)" />
</va-tree-node>
</va-tree-category>
<div v-show="[11].includes(workingModeSelect.id)">
<p style="font-size: 20px;">Cali Channel ( {{ caliChannelOptions[caliChannelSelect].label }} )</p>
<level-button
:ref="'caliChannelSelect'"
:deviceID="deviceID"
:options="caliChannelOptions"
:parameterName="'ADC_DAC_CHANNEL_15'"
@parameterChange="deviceParameterChange($event)"
/>
</div>
<va-tree-category
v-if="workingModeSelect != null && workingModeSelect.id == 10"
style="font-size: 20px;"
:label="'cali Volt ( ' + caliVoltNumber + ' )'">
<va-tree-node>
<cycle-range :ref="'caliVoltNumber'" :deviceID="deviceID" :parameterName="'DAC_VOLT'" :minValue="0" :maxValue="65535" @parameterChange="deviceParameterChange($event)" />
</va-tree-node>
</va-tree-category>
<div v-show="[10].includes(workingModeSelect.id)">
<p style="font-size: 20px;">Cali Volt ( {{ caliVoltNumber }} )</p>
<cycle-range
:ref="'caliVoltNumber'"
:deviceID="deviceID"
:parameterName="'DAC_VOLT'"
:minValue="0"
:maxValue="65535"
@parameterChange="deviceParameterChange($event)"
/>
</div>
<va-tree-category
v-if="workingModeSelect != null && workingModeSelect.id == 0 || workingModeSelect.id == 1"
style="font-size: 20px;"
:label="'Volt start ( ' + startVoltNumber/1000 + 'V )'">
<va-tree-node>
<volt-range :ref="'startVoltNumber'" :deviceID="deviceID" :parameterName="'VOLT_ORIGIN'" :minValue="-5" :maxValue="5" @parameterChange="deviceParameterChange($event)" />
</va-tree-node>
</va-tree-category>
<div v-show="[0,1].includes(workingModeSelect.id)">
<p style="font-size: 20px;">Volt Start ( {{ (startVoltNumber - 25000 ) / 5000 }} V )</p>
<volt-range
:ref="'startVoltNumber'"
:deviceID="deviceID"
:parameterName="'VOLT_ORIGIN'"
:minValue="-5"
:maxValue="5"
@parameterChange="deviceParameterChange($event)"
/>
</div>
<va-tree-category
v-if="workingModeSelect != null && workingModeSelect.id == 0 || workingModeSelect.id == 1"
style="font-size: 20px;"
:label="'Volt stop ( ' + stopVoltNumber/1000 + 'V )'">
<va-tree-node>
<volt-range :ref="'stopVoltNumber'" :deviceID="deviceID" :parameterName="'VOLT_FINAL'" :minValue="-5" :maxValue="5" @parameterChange="deviceParameterChange($event)" />
</va-tree-node>
</va-tree-category>
<div v-show="[0,1].includes(workingModeSelect.id)">
<p style="font-size: 20px;">Volt Stop ( {{ (stopVoltNumber - 25000 ) / 5000 }} V )</p>
<volt-range
:ref="'stopVoltNumber'"
:deviceID="deviceID"
:parameterName="'VOLT_FINAL'"
:minValue="-5"
:maxValue="5"
@parameterChange="deviceParameterChange($event)"
/>
</div>
<va-tree-category
v-if="workingModeSelect != null && workingModeSelect.id == 0 || workingModeSelect.id == 1"
style="font-size: 20px;"
:label="'Volt step ( ' + stepVoltNumber/10 + 'mV )'">
<va-tree-node>
<milli-volt-range :ref="'stepVoltNumber'" :deviceID="deviceID" :parameterName="'VOLT_STEP'" :minValue="0.2" :maxValue="100" @parameterChange="deviceParameterChange($event)" />
</va-tree-node>
</va-tree-category>
<div v-show="[0,1].includes(workingModeSelect.id)">
<p style="font-size: 20px;">Volt Step ( {{ stepVoltNumber/10 }} mV )</p>
<milli-volt-range
:ref="'stepVoltNumber'"
:deviceID="deviceID"
:parameterName="'VOLT_STEP'"
:minValue="0.2" :maxValue="100"
@parameterChange="deviceParameterChange($event)"
/>
</div>
<va-tree-category
v-if="workingModeSelect != null && workingModeSelect.id == 0 || workingModeSelect.id == 1"
style="font-size: 20px;"
:label="'Step time ( ' + stepTimeOptions[stepTimeSelect].label + ' )'">
<va-tree-node>
<level-button :ref="'stepTimeSelect'" :deviceID="deviceID" :options="stepTimeOptions" :parameterName="'STEP_TIME'" @parameterChange="deviceParameterChange($event)" />
</va-tree-node>
</va-tree-category>
<div v-show="[0,1].includes(workingModeSelect.id)">
<p style="font-size: 20px;">Step Time ( {{ stepTimeOptions[stepTimeSelect].label }} )</p>
<level-button
:ref="'stepTimeSelect'"
:deviceID="deviceID"
:options="stepTimeOptions"
:parameterName="'STEP_TIME'"
@parameterChange="deviceParameterChange($event)"
/>
</div>
<va-tree-category
v-if="workingModeSelect != null && workingModeSelect.id == 2 || workingModeSelect.id == 3 || workingModeSelect.id == 5"
style="font-size: 20px;"
:label="'Volt out ( ' + outputVoltNumber/1000 + 'V )'">
<va-tree-node>
<volt-range :ref="'outputVoltNumber'" :deviceID="deviceID" :parameterName="'DAC_VOLT'" :minValue="-5" :maxValue="5" @parameterChange="deviceParameterChange($event)" />
</va-tree-node>
</va-tree-category>
<div v-show="[2,3,5].includes(workingModeSelect.id)">
<p style="font-size: 20px;">Volt Out ( {{ (outputVoltNumber - 25000 ) / 5000 }} V )</p>
<volt-range
:ref="'outputVoltNumber'"
:deviceID="deviceID"
:parameterName="'DAC_VOLT'"
:minValue="-5"
:maxValue="5"
@parameterChange="deviceParameterChange($event)"
/>
</div>
<va-tree-category
v-if="workingModeSelect != null && workingModeSelect.id == 0 || workingModeSelect.id == 1 || workingModeSelect.id == 2 || workingModeSelect.id == 3 || workingModeSelect.id == 4 || workingModeSelect.id == 5 || workingModeSelect.id == 6 || workingModeSelect.id == 13"
style="font-size: 20px;"
:label="'Sample rate ( ' + sampleRateNumber/10 + 'sps )'">
<va-tree-node>
<resolution-range :ref="'sampleRateNumber'" :deviceID="deviceID" :parameterName="'SAMPLE_RATE'" :minValue="0.1" :maxValue="100" @parameterChange="deviceParameterChange($event)" />
</va-tree-node>
</va-tree-category>
<div v-show="[0,1,2,3,4,5,6,9,13,16].includes(workingModeSelect.id)">
<p style="font-size: 20px;">Sample Rate ( {{ sampleRateNumber/10 }} sps )</p>
<resolution-range
:ref="'sampleRateNumber'"
:deviceID="deviceID"
:parameterName="'SAMPLE_RATE'"
:minValue="0.1"
:maxValue="100"
@parameterChange="deviceParameterChange($event)"
/>
</div>
<va-tree-category
v-if="workingModeSelect != null && workingModeSelect.id == 6"
style="font-size: 20px;"
:label="'Charge ( ' + chargeOptions[chargeSelect].label + ' )'">
<va-tree-node>
<opp-level-button :ref="'chargeSelect'" :deviceID="deviceID" :options="chargeOptions" :parameterName="'Charge'" @parameterChange="deviceParameterChange($event)" />
</va-tree-node>
</va-tree-category>
<div v-show="[6].includes(workingModeSelect.id)">
<p style="font-size: 20px;">Charge ( {{ chargeOptions[chargeSelect].label }} )</p>
<opp-level-button
:ref="'chargeSelect'"
:deviceID="deviceID"
:options="chargeOptions"
:parameterName="'Charge'"
@parameterChange="deviceParameterChange($event)"
/>
</div>
<va-tree-category
v-if="workingModeSelect != null && workingModeSelect.id == 6"
style="font-size: 20px;"
:label="'Current ( ' + parseFloat(currentNumber / 100) + 'μA )'">
<va-tree-node>
<micro-ampere-range :ref="'currentNumber'" :deviceID="deviceID" :parameterName="'Const_Current_value'" :minValue="0" :maxValue="15000" @parameterChange="deviceParameterChange($event)" />
</va-tree-node>
</va-tree-category>
<div v-show="[6].includes(workingModeSelect.id)">
<p style="font-size: 20px;">Current ( {{ parseFloat(currentNumber / 100) }} μA )</p>
<micro-ampere-range
:ref="'currentNumber'"
:deviceID="deviceID"
:parameterName="'Const_Current_value'"
:minValue="0"
:maxValue="15000"
@parameterChange="deviceParameterChange($event)"
/>
</div>
<va-tree-category
v-if="workingModeSelect != null && workingModeSelect.id == 6"
style="font-size: 20px;"
:label="'Volt max stop ( ' + stopVoltMaxNumber/1000 + 'V )'">
<va-tree-node>
<volt-range :ref="'stopVoltMaxNumber'" :deviceID="deviceID" :parameterName="'VOLTSTOP_MAX'" :minValue="-5" :maxValue="5" @parameterChange="deviceParameterChange($event)" />
</va-tree-node>
</va-tree-category>
<div v-show="[6].includes(workingModeSelect.id)">
<p style="font-size: 20px;">Volt Max Stop ( {{ (stopVoltMaxNumber - 25000 ) / 5000 }} V )</p>
<volt-range
:ref="'stopVoltMaxNumber'"
:deviceID="deviceID"
:parameterName="'VOLTSTOP_MAX'"
:minValue="-5"
:maxValue="5"
@parameterChange="deviceParameterChange($event)"
/>
</div>
<va-tree-category
v-if="workingModeSelect != null && workingModeSelect.id == 6"
style="font-size: 20px;"
:label="'Volt min stop ( ' + stopVoltMinNumber/1000 + 'V )'">
<va-tree-node>
<volt-range :ref="'stopVoltMinNumber'" :deviceID="deviceID" :parameterName="'VOLTSTOP_MIN'" :minValue="-5" :maxValue="5" @parameterChange="deviceParameterChange($event)" />
</va-tree-node>
</va-tree-category>
<div v-show="[6].includes(workingModeSelect.id)">
<p style="font-size: 20px;">Volt Min Stop ( {{ (stopVoltMinNumber - 25000 ) / 5000 }} V )</p>
<volt-range
:ref="'stopVoltMinNumber'"
:deviceID="deviceID"
:parameterName="'VOLTSTOP_MIN'"
:minValue="-5"
:maxValue="5"
@parameterChange="deviceParameterChange($event)"
/>
</div>
<va-tree-category
v-if="workingModeSelect != null && workingModeSelect.id == 7 || workingModeSelect.id == 8"
style="font-size: 20px;"
:label="'E-Initial ( ' + voltInitialNumber/1000 + 'V )'">
<va-tree-node>
<volt-range :ref="'voltInitialNumber'" :deviceID="deviceID" :parameterName="'VOLT_INITIAL'" :minValue="-5" :maxValue="5" @parameterChange="deviceParameterChange($event)" />
</va-tree-node>
</va-tree-category>
<div v-show="[7,8].includes(workingModeSelect.id)">
<p style="font-size: 20px;">E-Initial ( {{ (voltInitialNumber - 25000 ) / 5000 }} V )</p>
<volt-range
:ref="'voltInitialNumber'"
:deviceID="deviceID"
:parameterName="'VOLT_INITIAL'"
:minValue="-5"
:maxValue="5"
@parameterChange="deviceParameterChange($event)"
/>
</div>
<va-tree-category
v-if="workingModeSelect != null && workingModeSelect.id == 7"
style="font-size: 20px;"
:label="'E1 ( ' + voltMaxNumber/1000 + 'V )'">
<va-tree-node>
<volt-range :ref="'voltMaxNumber'" :deviceID="deviceID" :parameterName="'VOLT_MAX'" :minValue="-5" :maxValue="5" @parameterChange="deviceParameterChange($event)" />
</va-tree-node>
</va-tree-category>
<div v-show="[7].includes(workingModeSelect.id)">
<p style="font-size: 20px;">E1 ( {{ (voltMaxNumber - 25000 ) / 5000 }} V )</p>
<volt-range
:ref="'voltMaxNumber'"
:deviceID="deviceID"
:parameterName="'VOLT_MAX'"
:minValue="-5"
:maxValue="5"
@parameterChange="deviceParameterChange($event)"
/>
</div>
<va-tree-category
v-if="workingModeSelect != null && workingModeSelect.id == 7"
style="font-size: 20px;"
:label="'E2 ( ' + voltMinNumber/1000 + 'V )'">
<va-tree-node>
<volt-range :ref="'voltMinNumber'" :deviceID="deviceID" :parameterName="'VOLT_MIN'" :minValue="-5" :maxValue="5" @parameterChange="deviceParameterChange($event)" />
</va-tree-node>
</va-tree-category>
<div v-show="[7].includes(workingModeSelect.id)">
<p style="font-size: 20px;">E2 ( {{ (voltMinNumber - 25000 ) / 5000 }} V )</p>
<volt-range
:ref="'voltMinNumber'"
:deviceID="deviceID"
:parameterName="'VOLT_MIN'"
:minValue="-5"
:maxValue="5"
@parameterChange="deviceParameterChange($event)"
/>
</div>
<va-tree-category
v-if="workingModeSelect != null && workingModeSelect.id == 8"
style="font-size: 20px;"
:label="'E-Final ( ' + voltEFinalNumber/1000 + 'V )'">
<va-tree-node>
<volt-range :ref="'voltEFinalNumber'" :deviceID="deviceID" :parameterName="'VOLT_EFINAL'" :minValue="-5" :maxValue="5" @parameterChange="deviceParameterChange($event)" />
</va-tree-node>
</va-tree-category>
<div v-show="[8].includes(workingModeSelect.id)">
<p style="font-size: 20px;">E-Final ( {{ (voltEFinalNumber - 25000 ) / 5000 }} V )</p>
<volt-range
:ref="'voltEFinalNumber'"
:deviceID="deviceID"
:parameterName="'VOLT_EFINAL'"
:minValue="-5"
:maxValue="5"
@parameterChange="deviceParameterChange($event)"
/>
</div>
<va-tree-category
v-if="workingModeSelect != null && workingModeSelect.id == 9"
style="font-size: 20px;"
:label="'VScan ( ' + voltVScanNumber/1000 + 'V )'">
<va-tree-node>
<volt-range :ref="'voltVScanNumber'" :deviceID="deviceID" :parameterName="'VOLT_VSCAN'" :minValue="-5" :maxValue="5" @parameterChange="deviceParameterChange($event)" />
</va-tree-node>
</va-tree-category>
<div v-show="[9].includes(workingModeSelect.id)">
<p style="font-size: 20px;">VScan ( {{ voltVScanNumber / 1000 }} V )</p>
<volt-range
:ref="'voltVScanNumber'"
:deviceID="deviceID"
:parameterName="'VOLT_VSCAN'"
:minValue="-5"
:maxValue="5"
@parameterChange="deviceParameterChange($event)"
/>
</div>
<va-tree-category
v-if="workingModeSelect != null && workingModeSelect.id == 7 || workingModeSelect.id == 8"
style="font-size: 20px;"
:label="'ScanRate ( ' + voltScanRateNumber/100 + 'mV/s )'">
<va-tree-node>
<scan-rate-range :ref="'voltScanRateNumber'" :deviceID="deviceID" :parameterName="'Scan_Rate'" :minValue="0.01" :maxValue="1000" @parameterChange="deviceParameterChange($event)" />
</va-tree-node>
</va-tree-category>
<div v-show="[7,8].includes(workingModeSelect.id)">
<p style="font-size: 20px;">ScanRate ( {{ voltScanRateNumber/100 }} mV/s )</p>
<scan-rate-range
:ref="'voltScanRateNumber'"
:deviceID="deviceID"
:parameterName="'Scan_Rate'"
:minValue="0.01"
:maxValue="1000"
@parameterChange="deviceParameterChange($event)"
/>
</div>
<va-tree-category
v-if="workingModeSelect != null && workingModeSelect.id == 7 || workingModeSelect.id == 8 || workingModeSelect.id == 9"
style="font-size: 20px;"
:label="'Resolution ( ' + sampleRateNumber/10 + 'sps )'">
<va-tree-node>
<resolution-range :ref="'sampleRateNumber'" :deviceID="deviceID" :parameterName="'SAMPLE_RATE'" :minValue="0.1" :maxValue="100" @parameterChange="deviceParameterChange($event)" />
</va-tree-node>
</va-tree-category>
<div v-show="[7, 8].includes(workingModeSelect.id)">
<p style="font-size: 20px;">Resolution ( {{ sampleRateNumber/10 }} sps )</p>
<resolution-range
:ref="'sampleRateNumber'"
:deviceID="deviceID"
:parameterName="'SAMPLE_RATE'"
:minValue="0.1"
:maxValue="100"
@parameterChange="deviceParameterChange($event)"
/>
</div>
<va-tree-category
v-if="workingModeSelect != null && workingModeSelect.id == 1 || workingModeSelect.id == 7"
style="font-size: 20px;"
:label="'Cycle ( ' + cycleNoNumber + ' )'">
<va-tree-node>
<cycle-range :ref="'cycleNoNumber'" :deviceID="deviceID" :parameterName="'CYCLE_NUMBER'" :minValue="1" :maxValue="50000" @parameterChange="deviceParameterChange($event)" />
</va-tree-node>
</va-tree-category>
<div v-show="[1, 7].includes(workingModeSelect.id)">
<p style="font-size: 20px;">Cycle ( {{ cycleNoNumber }} )</p>
<cycle-range
:ref="'cycleNoNumber'"
:deviceID="deviceID"
:parameterName="'CYCLE_NUMBER'"
:minValue="1"
:maxValue="50000"
@parameterChange="deviceParameterChange($event)"
/>
</div>
<!-- <va-tree-category
v-if="workingModeSelect != null && workingModeSelect.id == 13"
@@ -391,6 +453,7 @@ export default {
},
data () {
return {
incomingData: undefined,
workingModeSelect: {
id: -1,
description: 'Init',
@@ -436,14 +499,14 @@ export default {
id: 9,
description: 'Chronoamperometric Graph',
},
{
id: 10,
description: 'Cali DAC - test',
},
{
id: 11,
description: 'Cali ADC - test',
},
// {
// id: 10,
// description: 'Cali DAC - test',
// },
// {
// id: 11,
// description: 'Cali ADC - test',
// },
// {
// id: 12,
// description: 'Dev Mode',
@@ -578,7 +641,7 @@ export default {
read: '',
notify: '',
},
duration: 0,
duration: null,
timeUnit: null,
timeOptions: [
{
@@ -598,30 +661,110 @@ export default {
label: 'ms',
},
],
emitFlag: true,
paramTransTable: {
// MODE: 'workingModeSelect',
ADC_LEVEL_I_15: 'currentRangeSelect',
ADC_LEVEL_V_IN_15: 'voltageInRangeSelect',
CTRL_HIGH_Z_15: 'highzSelect',
ADC_DAC_CHANNEL_15: 'caliChannelSelect',
DAC_VOLT: ['outputVoltNumber', 'caliVoltNumber'],
// DAC_VOLT: [-1].includes(mode) ? ['outputVoltNumber', 'caliVoltNumber'] : [2, 3, 5].includes(mode) ? 'outputVoltNumber' : [10].includes(mode) ? 'caliVoltNumber' : undefined,
VOLT_ORIGIN: 'startVoltNumber',
VOLT_FINAL: 'stopVoltNumber',
VOLT_STEP: 'stepVoltNumber',
STEP_TIME: 'stepTimeSelect',
SAMPLE_RATE: 'sampleRateNumber',
Charge: 'chargeSelect',
Const_Current_value: 'currentNumber',
VOLTSTOP_MAX: 'stopVoltMaxNumber',
VOLTSTOP_MIN: 'stopVoltMinNumber',
VOLT_INITIAL: 'voltInitialNumber',
VOLT_MAX: 'voltMaxNumber',
VOLT_MIN: 'voltMinNumber',
VOLT_EFINAL: 'voltEFinalNumber',
VOLT_VSCAN: 'voltVScanNumber',
Scan_Rate: 'voltScanRateNumber',
CYCLE_NUMBER: 'cycleNoNumber',
},
paramDefaultTable: {
// MODE: -1,
ADC_LEVEL_I_15: 4,
ADC_LEVEL_V_IN_15: 3,
CTRL_HIGH_Z_15: 1,
ADC_DAC_CHANNEL_15: 0,
DAC_VOLT: 25000,
VOLT_ORIGIN: 25000,
VOLT_FINAL: 25000,
VOLT_STEP: 1000,
STEP_TIME: 1,
SAMPLE_RATE: 1000,
Charge: 1,
Const_Current_value: 0,
VOLTSTOP_MAX: 50000,
VOLTSTOP_MIN: 0,
VOLT_INITIAL: 25000,
VOLT_MAX: 27500,
VOLT_MIN: 22500,
VOLT_EFINAL: 25000,
VOLT_VSCAN: 25000,
Scan_Rate: 10000,
CYCLE_NUMBER: 1,
},
}
},
mqtt: {
},
methods: {
updateSetting: function () {
const data = this.incomingData
// update everything first
this.emitFlag = false
const paramTable = this.paramTransTable
for (const param in paramTable) {
const value = (data && data[param]) || this.paramDefaultTable[param]
// console.log(param, paramTable[param], value)
if (Array.isArray(paramTable[param]) === true) {
for (const paramName of paramTable[param]) {
this[paramName] = value
this.$refs[paramName] && this.$refs[paramName].update(value)
}
} else {
this[paramTable[param]] = value
this.$refs[paramTable[param]] && this.$refs[paramTable[param]].update(value)
// console.log(paramTable[param], this[paramTable[param]])
}
}
this.emitFlag = true
},
mqttPub: function (topic, mes) {
this.$mqtt.publish(topic, mes)
},
// Array[String of Parameter Nmae, Value]
deviceParameterChange: function (e) {
console.log('e[0],e[1]', e[0], ',', e[1])
this.$emit('parameterChange', e)
const param = e[0]
const value = e[1]
// console.log('e[0],e[1]', e[0], ',', e[1])
if (this.emitFlag === true) {
this[this.paramTransTable[param]] = value
this.$emit('parameterChange', e)
}
},
workingModeSelectChange (val) {
if (this.workingModeSelect.id === -1) {
return false
if (typeof val === 'object') {
this.workingModeSelect = val
} else if (typeof val === 'number') {
this.workingModeSelect = this.workingModeOptions[val]
}
this.workingModeSelect = val
this.updateSetting()
this.deviceParameterChange(['MODE', this.workingModeSelect.id])
},
},
mounted () {
// this.updateSetting()
},
watch: {
},
@@ -99,7 +99,14 @@ export default {
},
mounted () {
// init grab new
console.log('getParameter', this.getParameterSetTask(this.deviceSelectKey))
// console.log('getParameter', this.getParameterSetTask(this.taskSelectKey, this.deviceSelectKey))
const parameterSet = this.getParameterSetTask(this.taskSelectKey, this.deviceSelectKey)
if (parameterSet) {
this.parameterUUID = Object.keys(parameterSet)[0]
const param = Object.values(parameterSet)[0]
this.$refs.rec_ref_2.incomingData = param
this.$refs.rec_ref_2.workingModeSelectChange(param.MODE)
}
},
}
</script>
@@ -2,27 +2,27 @@
<div class="row">
<div class="flex sm12 xl12 md12 xs12">
<div class="flex row align--center" :key="inputeKey">
<va-button slot="append" class="mr-2 pa-1 shrink" small @click="cycleNumberChange(minValue)">
<va-button slot="append" class="mr-2 pa-1 shrink" small @click="change(minValue)">
{{ minValue }}
</va-button>
<va-input
@mouseleave.native="cycleNumberChange(cycleNoNumberInput)"
@keyup.enter="cycleNumberChange(cycleNoNumberInput)"
@blur="cycleNumberChange(cycleNoNumberInput)"
@mouseleave.native="change(cycleNoNumberInput)"
@keyup.enter="change(cycleNoNumberInput)"
@blur="change(cycleNoNumberInput)"
v-model="cycleNoNumberInput"
class="mb-0"
style="width: 100px;"
>
</va-input>
<va-button slot="append" class="ml-2 pa-1 shrink" small @click="cycleNumberChange(maxValue)">
<va-button slot="append" class="ml-2 pa-1 shrink" small @click="change(maxValue)">
{{ maxValue }}
</va-button>
</div>
<va-slider
@mouseup.native="cycleNumberChange(cycleNoNumber)"
@mouseleave.native="cycleNumberChange(cycleNoNumber)"
@touchend.native="cycleNumberChange(cycleNoNumber)"
@click.native="cycleNumberChange(cycleNoNumber)"
@mouseup.native="change(cycleNoNumber)"
@mouseleave.native="change(cycleNoNumber)"
@touchend.native="change(cycleNoNumber)"
@click.native="change(cycleNoNumber)"
class="flex sm12 xl12 md12 xs12"
v-model="cycleNoNumber"
:min="minValue"
@@ -71,7 +71,7 @@ export default {
mqtt: {
},
methods: {
cycleNumberChange (val) {
change (val) {
this.inputeKey++
if (this.cycleNoNumber == null) {
return false
@@ -87,8 +87,8 @@ export default {
}
this.$emit('parameterChange', [this.parameterName, this.cycleNoNumber])
},
updateCycleNumber (val) {
this.cycleNumberChange(val)
update (val) {
this.change(val)
},
},
async mounted () {
@@ -2,7 +2,7 @@
<div class="row">
<div class="flex sm12 xl12 md12 xs12">
<va-button-toggle
@click.native="levelButtonSelectChange(levelButtonSelect)"
@click.native="change(levelButtonSelect)"
small
outline
v-model="levelButtonSelect"
@@ -45,7 +45,7 @@ export default {
mqtt: {
},
methods: {
levelButtonSelectChange (val) {
change (val) {
if (this.levelButtonSelect == null) {
return false
}
@@ -54,8 +54,8 @@ export default {
this.$emit('parameterChange', [this.parameterName, this.levelButtonSelect])
},
updateLevelButton (val) {
this.levelButtonSelectChange(val)
update (val) {
this.change(val)
},
},
async mounted () {
@@ -2,13 +2,13 @@
<div class="row">
<div class="flex sm12 xl12 md12 xs12">
<div class="flex row align--center" :key="inputeKey">
<va-button slot="append" class="mr-2 pa-1 shrink" small @click="currentNumberChange(minValue*100)">
<va-button slot="append" class="mr-2 pa-1 shrink" small @click="change(minValue*100)">
{{ minValue }}
</va-button>
<va-input
@mouseleave.native="currentNumberChange(currentNumberInput)"
@keyup.enter="currentNumberChange(currentNumberInput)"
@blur="currentNumberChange(currentNumberInput)"
@mouseleave.native="change(currentNumberInput)"
@keyup.enter="change(currentNumberInput)"
@blur="change(currentNumberInput)"
v-model="currentNumberInput"
class="mb-0"
style="width: 100px;"
@@ -17,15 +17,15 @@
μA
</p>
</va-input>
<va-button slot="append" class="ml-2 pa-1 shrink" small @click="currentNumberChange(maxValue*100)">
<va-button slot="append" class="ml-2 pa-1 shrink" small @click="change(maxValue*100)">
{{ maxValue }}
</va-button>
</div>
<va-slider
@mouseup.native="currentNumberChange(currentNumber)"
@mouseleave.native="currentNumberChange(currentNumber)"
@touchend.native="currentNumberChange(currentNumber)"
@click.native="currentNumberChange(currentNumber)"
@mouseup.native="change(currentNumber)"
@mouseleave.native="change(currentNumber)"
@touchend.native="change(currentNumber)"
@click.native="change(currentNumber)"
class="flex sm12 xl12 md12 xs12"
v-model="currentNumber"
:min="minValue*100"
@@ -74,7 +74,7 @@ export default {
mqtt: {
},
methods: {
currentNumberChange (val) {
change (val) {
this.inputeKey++
if (this.currentNumber == null) {
return false
@@ -102,8 +102,8 @@ export default {
}
this.$emit('parameterChange', [this.parameterName, this.currentNumber])
},
updateMicroAmpereNumber (val) {
this.currentNumberChange(val)
update (val) {
this.change(val)
},
},
async mounted () {
@@ -2,13 +2,13 @@
<div class="row">
<div class="flex sm12 xl12 md12 xs12">
<div class="flex row align--center" :key="inputeKey">
<va-button slot="append" class="mr-2 pa-1 shrink" small @click="stepVoltNumberChange(minValue*10)">
<va-button slot="append" class="mr-2 pa-1 shrink" small @click="change(minValue*10)">
{{ minValue }}
</va-button>
<va-input
@mouseleave.native="stepVoltNumberChange(voltNumberInput)"
@keyup.enter="stepVoltNumberChange(voltNumberInput)"
@blur="stepVoltNumberChange(voltNumberInput)"
@mouseleave.native="change(voltNumberInput)"
@keyup.enter="change(voltNumberInput)"
@blur="change(voltNumberInput)"
v-model="voltNumberInput"
class="mb-0"
style="width: 100px;"
@@ -17,15 +17,15 @@
mV
</p>
</va-input>
<va-button slot="append" class="ml-2 pa-1 shrink" small @click="stepVoltNumberChange(maxValue*10)">
<va-button slot="append" class="ml-2 pa-1 shrink" small @click="change(maxValue*10)">
{{ maxValue }}
</va-button>
</div>
<va-slider
@mouseup.native="stepVoltNumberChange(voltNumber)"
@mouseleave.native="stepVoltNumberChange(voltNumber)"
@touchend.native="stepVoltNumberChange(voltNumber)"
@click.native="stepVoltNumberChange(voltNumber)"
@mouseup.native="change(voltNumber)"
@mouseleave.native="change(voltNumber)"
@touchend.native="change(voltNumber)"
@click.native="change(voltNumber)"
class="flex sm12 xl12 md12 xs12"
v-model="voltNumber"
:min="minValue*10"
@@ -74,7 +74,7 @@ export default {
mqtt: {
},
methods: {
stepVoltNumberChange (val) {
change (val) {
this.inputeKey++
if (this.voltNumber == null) {
return false
@@ -112,8 +112,8 @@ export default {
this.$emit('parameterChange', [this.parameterName, this.voltNumber])
},
updateStepVoltNumber (val) {
this.stepVoltNumberChange(val)
update (val) {
this.change(val)
},
},
async mounted () {
@@ -2,7 +2,7 @@
<div class="row">
<div class="flex sm12 xl12 md12 xs12">
<va-button-toggle
@click.native="levelButtonSelectChange(levelButtonSelect)"
@click.native="change(levelButtonSelect)"
small
outline
v-model="levelButtonSelect"
@@ -45,7 +45,7 @@ export default {
mqtt: {
},
methods: {
levelButtonSelectChange (val) {
change (val) {
if (this.levelButtonSelect == null) {
return false
}
@@ -61,8 +61,8 @@ export default {
this.$emit('parameterChange', [this.parameterName, _charge])
},
updateLevelButton (val) {
this.levelButtonSelectChange(val)
update (val) {
this.change(val)
},
},
async mounted () {
@@ -2,13 +2,13 @@
<div class="row">
<div class="flex sm12 xl12 md12 xs12">
<div class="flex row align--center" :key="inputeKey">
<va-button slot="append" class="mr-2 pa-1 shrink" small @click="resolutionNumberChange(minValue*10)">
<va-button slot="append" class="mr-2 pa-1 shrink" small @click="change(minValue*10)">
{{ minValue }}
</va-button>
<va-input
@mouseleave.native="resolutionNumberChange(resolutionNumberInput)"
@keyup.enter="resolutionNumberChange(resolutionNumberInput)"
@blur="resolutionNumberChange(resolutionNumberInput)"
@mouseleave.native="change(resolutionNumberInput)"
@keyup.enter="change(resolutionNumberInput)"
@blur="change(resolutionNumberInput)"
v-model="resolutionNumberInput"
class="mb-0"
style="width: 100px;"
@@ -17,15 +17,15 @@
sps
</p>
</va-input>
<va-button slot="append" class="ml-2 pa-1 shrink" small @click="resolutionNumberChange(maxValue*10)">
<va-button slot="append" class="ml-2 pa-1 shrink" small @click="change(maxValue*10)">
{{ maxValue }}
</va-button>
</div>
<va-slider
@mouseup.native="resolutionNumberChange(resolutionNumber)"
@mouseleave.native="resolutionNumberChange(resolutionNumber)"
@touchend.native="resolutionNumberChange(resolutionNumber)"
@click.native="resolutionNumberChange(resolutionNumber)"
@mouseup.native="change(resolutionNumber)"
@mouseleave.native="change(resolutionNumber)"
@touchend.native="change(resolutionNumber)"
@click.native="change(resolutionNumber)"
class="flex sm12 xl12 md12 xs12"
v-model="resolutionNumber"
:min="minValue*10"
@@ -51,7 +51,7 @@ export default {
},
defaultValue: {
type: Number,
default: 2,
default: 1000,
},
minValue: {
type: Number,
@@ -68,13 +68,13 @@ export default {
return {
inputeKey: 0,
resolutionNumber: this.defaultValue,
resolutionNumberInput: String(this.defaultValue),
resolutionNumberInput: String(this.defaultValue / 10),
}
},
mqtt: {
},
methods: {
resolutionNumberChange (val) {
change (val) {
this.inputeKey++
if (this.resolutionNumber == null) {
return false
@@ -103,8 +103,8 @@ export default {
this.$emit('parameterChange', [this.parameterName, this.resolutionNumber])
},
updateResolutionNumber (val) {
this.resolutionNumberChange(val)
update (val) {
this.change(val)
},
},
async mounted () {
@@ -2,13 +2,13 @@
<div class="row">
<div class="flex sm12 xl12 md12 xs12">
<div class="flex row align--center" :key="inputeKey">
<va-button slot="append" class="mr-2 pa-1 shrink" small @click="voltScanRateNumberChange(minValue*100)">
<va-button slot="append" class="mr-2 pa-1 shrink" small @click="change(minValue*100)">
{{ minValue }}
</va-button>
<va-input
@mouseleave.native="voltScanRateNumberChange(voltScanRateNumberInput)"
@keyup.enter="voltScanRateNumberChange(voltScanRateNumberInput)"
@blur="voltScanRateNumberChange(voltScanRateNumberInput)"
@mouseleave.native="change(voltScanRateNumberInput)"
@keyup.enter="change(voltScanRateNumberInput)"
@blur="change(voltScanRateNumberInput)"
v-model="voltScanRateNumberInput"
class="mb-0"
style="width: 100px;"
@@ -17,15 +17,15 @@
mV
</p>
</va-input>
<va-button slot="append" class="ml-2 pa-1 shrink" small @click="voltScanRateNumberChange(maxValue*100)">
<va-button slot="append" class="ml-2 pa-1 shrink" small @click="change(maxValue*100)">
{{ maxValue }}
</va-button>
</div>
<va-slider
@mouseup.native="voltScanRateNumberChange(voltScanRateNumber)"
@mouseleave.native="voltScanRateNumberChange(voltScanRateNumber)"
@touchend.native="voltScanRateNumberChange(voltScanRateNumber)"
@click.native="voltScanRateNumberChange(voltScanRateNumber)"
@mouseup.native="change(voltScanRateNumber)"
@mouseleave.native="change(voltScanRateNumber)"
@touchend.native="change(voltScanRateNumber)"
@click.native="change(voltScanRateNumber)"
class="flex sm12 xl12 md12 xs12"
v-model="voltScanRateNumber"
:min="minValue*100"
@@ -74,7 +74,7 @@ export default {
mqtt: {
},
methods: {
voltScanRateNumberChange (val) {
change (val) {
this.inputeKey++
if (this.voltScanRateNumber == null) {
return false
@@ -103,8 +103,8 @@ export default {
this.$emit('parameterChange', [this.parameterName, this.voltScanRateNumber])
},
updateVoltScanRateNumber (val) {
this.voltScanRateNumberChange(val)
update (val) {
this.change(val)
},
},
async mounted () {
@@ -2,13 +2,13 @@
<div class="row">
<div class="flex sm12 xl12 md12 xs12">
<div class="flex row align--center" :key="inputeKey">
<va-button slot="append" class="mr-2 pa-1 shrink" small @click="voltNumberChange(minValue*1000)">
<va-button slot="append" class="mr-2 pa-1 shrink" small @click="change(minValue*1000)">
{{ minValue }}
</va-button>
<va-input
@mouseleave.native="voltNumberChange(voltNumberInput)"
@keyup.enter="voltNumberChange(voltNumberInput)"
@blur="voltNumberChange(voltNumberInput)"
@mouseleave.native="change(voltNumberInput)"
@keyup.enter="change(voltNumberInput)"
@blur="change(voltNumberInput)"
v-model="voltNumberInput"
class="mb-0"
style="width: 100px;"
@@ -17,15 +17,15 @@
V
</p>
</va-input>
<va-button slot="append" class="ml-2 pa-1 shrink" small @click="voltNumberChange(maxValue*1000)">
<va-button slot="append" class="ml-2 pa-1 shrink" small @click="change(maxValue*1000)">
{{ maxValue }}
</va-button>
</div>
<va-slider
@mouseup.native="voltNumberChange(voltNumber)"
@mouseleave.native="voltNumberChange(voltNumber)"
@touchend.native="voltNumberChange(voltNumber)"
@click.native="voltNumberChange(voltNumber)"
@mouseup.native="change(voltNumber)"
@mouseleave.native="change(voltNumber)"
@touchend.native="change(voltNumber)"
@click.native="change(voltNumber)"
class="flex sm12 xl12 md12 xs12"
v-model="voltNumber"
:min="minValue*1000"
@@ -74,7 +74,7 @@ export default {
mqtt: {
},
methods: {
voltNumberChange (val) {
change (val) {
this.inputeKey++
if (this.voltNumber == null) {
return false
@@ -104,8 +104,8 @@ export default {
this.$emit('parameterChange', [this.parameterName, this.voltNumber * 5 + 25000])
},
updateVoltNumber (val) {
this.voltNumberChange(val)
update (val) {
this.change(val)
},
},
async mounted () {
+13 -3
View File
@@ -1,6 +1,6 @@
<template>
<div>
<va-card style="height: 80vh; overflow: auto; display: block;">
<va-card style="height: 90vh; overflow: auto; display: block;">
<template slot="header">
<va-icon name="fa fa-bluetooth-b mr-3" color="primary"/>
<h5 class="mt-0 mb-0"> {{ getSelectProject ? getSelectProject.name : '' }}</h5>
@@ -11,9 +11,13 @@
<div v-else>
<project-menu/>
<project-table/>
<div align="right">
<div align="right" v-if="lockMode === false">
<va-button @click="save">Save</va-button>
<va-button @click="start">Start</va-button>
</div>
<div align="right" v-if="lockMode === true">
<va-button @click="stop">Stop</va-button>
</div>
</div>
</va-card>
</div>
@@ -36,6 +40,7 @@ export default {
types.project.getSelect,
]),
...mapFields('project', [
'lockMode',
'projectList',
'projectSelectIndex',
]),
@@ -46,9 +51,14 @@ export default {
},
methods: {
start: function () {
console.log('finally', this.getSelectProject)
this.$emit('start_project', this.getSelectProject)
},
stop: function () {
this.$emit('stop_project', this.getSelectProject)
},
save: function () {
this.$emit('save_project', this.getSelectProject)
},
},
}
</script>
@@ -84,6 +84,7 @@ export default {
...mapFields('project', [
'deviceConnectList',
'projectLibrary',
]),
},
data () {
@@ -157,6 +158,9 @@ export default {
} else {
await this.setDeviceProject({ device: this.device, index: deviceIndex })
}
if (this.device.library !== undefined) {
this.projectLibrary = this.device.library.value
}
this.hide()
this.resetSetting()
@@ -173,6 +177,7 @@ export default {
this.optionDeviceConnect = this.deviceConnectList
if (device) {
this.device = device
this.projectLibrary = this.device.library.value
}
},
@@ -1,7 +1,7 @@
<template>
<div class="row">
<div class="flex d-flex">
<div v-for="(device, index) in getSelectProject.deviceList" :key="index">
<div v-for="(device, index) in getSelectProject.device" :key="index">
<va-button color="info" @click="showDeviceModal(device)" small>
<va-icon name="fa fa-close" @click.native.stop="deleteDevice(index)"></va-icon>
{{ device.name }} {{ device.connectDevice && device.connectDevice.device_address }}
@@ -12,6 +12,7 @@
</template>
<script>
import { mapFields } from 'vuex-map-fields'
import { mapActions, mapGetters } from 'vuex'
import types from '@/store/modules/project/types'
@@ -23,6 +24,10 @@ export default {
...mapGetters('project', [
types.project.getSelect,
]),
...mapFields('project', [
'projectLibrary',
]),
},
data () {
return {
@@ -42,6 +47,11 @@ export default {
),
},
mounted () {
for (const device in this.getSelectProject.device) {
if (this.projectLibrary === null) {
this.projectLibrary = this.getSelectProject.device[device].library.value
}
}
},
}
</script>
@@ -1,26 +1,33 @@
<template>
<div class="markup-tables flex d-flex sm12 xl12 md12 xs12" id="scro" style="height: 48vh; overflow: auto;">
<div class="markup-tables project-table flex d-flex sm12 xl12 md12 xs12" id="scro" style="height: 66vh; overflow: auto;">
<div class="table-wrapper">
<table class="va-table va-table--hoverable">
<table class="va-table">
<thead>
<tr>
<th>
<va-checkbox v-model="temp"/>
<th v-if="lockMode === false">
<va-checkbox
v-model="tableColumn.checked"
:array-value="'-1'"
@input="selectAll($event)"
/>
</th>
<th align="center">order</th>
<th align="center">name</th>
<th align="center" @click="openConfig(1)">device</th>
<th align="center">action and condition</th>
<th align="center">parameter</th>
<th align="center"> </th>
<th align="center"></th>
</tr>
</thead>
<tbody>
<template v-for="(task, taskIndex) in getSelectProject.taskList">
<tr v-if="task.deviceList.length === 0" :key="taskIndex">
<td>
<va-checkbox v-model="temp"/>
<template v-for="(task, taskIndex) in getSelectProject.task">
<tr v-if="task.device.length === 0" :key="taskIndex" height="80px">
<td v-if="lockMode === false">
<va-checkbox
v-model="tableColumn.checked"
:array-value="String(taskIndex)"
/>
</td>
<td align="center">
{{ taskIndex + 1 }}
@@ -37,68 +44,72 @@
<td align="center">
<va-button :flat="true" @click="openConfig(4, taskIndex)" small>ParameterSet</va-button>
</td>
<td align="center" style="max-height: 50px; overflow: auto;">
<div class="flex d-flex">
<div class="flex-center">
<va-icon class="fa fa-close" @click.native="() => deleteTask({ index: taskIndex})"></va-icon>
</div>
</div>
<td align="center">
<va-icon class="fa fa-close" @click.native="() => deleteTask({ index: taskIndex})"></va-icon>
</td>
</tr>
<tr v-for="(deviceUUID) in task.deviceList" :key="task.name + deviceUUID">
<td>
<va-checkbox v-model="temp"/>
<tr v-for="(deviceUUID) in task.device" :key="taskIndex + deviceUUID" height="80px">
<td v-if="lockMode === false">
<va-checkbox
v-model="tableColumn.checked"
:array-value="String(taskIndex)"
/>
</td>
<td align="center">
{{ taskIndex + 1 }}
</td>
<td align="center">
{{ task.name }}
<td align="center" @dblclick="switchInput('name', taskIndex)">
<div v-if="tableColumn.name == taskIndex && lockMode === false">
<va-input
v-model="task.name"
style="width: 100px;"
@blur="switchInput('name', -1)"
@keyup.enter="switchInput('name', -1)"
/>
</div>
<div v-else>
{{ task.name }}
</div>
</td>
<td align="center">
<td align="center" @click="openConfig(1, taskIndex, deviceUUID)">
<div >
<span>{{ getDeviceProject(deviceUUID).name }} </span>
</div>
<div class="flex-center">
<va-icon class="fa fa-edit" @click.native="openConfig(1, taskIndex, deviceUUID)"></va-icon>
<span>{{ getDeviceProject(deviceUUID) && getDeviceProject(deviceUUID).name }}</span>
</div>
</td>
<td align="center">
<div class="flex d-flex">
<div class="flex">
<div v-for="(action, actionKey) in task.action" :key="actionKey">
<div v-if="action.target === deviceUUID">
<div v-for="conditionKey in action.condition" :key="conditionKey">
{{ action.type }} {{ task.condition[conditionKey].type }} {{ task.condition[conditionKey].value }}
</div>
<td align="center" @click="openConfig(3, taskIndex, deviceUUID)">
<div class="flex">
<div v-for="(action, actionKey) in task.action" :key="actionKey">
<div v-if="action.target === deviceUUID">
<div v-for="conditionKey in action.condition" :key="conditionKey">
{{ action.type }} {{ task.condition[conditionKey].type }} {{ task.condition[conditionKey].value }}
</div>
</div>
</div>
<div class="flex-center">
<va-icon class="fa fa-edit" @click.native="openConfig(3, taskIndex, deviceUUID)"></va-icon>
</div>
</div>
</td>
<td align="center" style="max-height: 50px; overflow: auto;">
<td align="center" @click="openConfig(4, taskIndex, deviceUUID)">
<div class="flex d-flex">
<div class="flex">
<div v-for="(parameterSet, parameterSetKey) in getParameterSetTask(taskIndex, deviceUUID)" :key="parameterSetKey">
<div v-for="(parameter, parameterKey) in parameterSet" :key="parameterKey">
<span v-if="parameterKey !== 'target'">{{ parameterKey }}: {{ parameter }}</span>
<span v-if="parameterKey !== 'target'"> {{ parameterName(parameterKey) }} : {{ parameterValue(parameterKey, parameter) }} </span>
</div>
</div>
</div>
<div class="flex-center">
<va-icon class="fa fa-edit" @click.native="openConfig(4, taskIndex, deviceUUID)"></va-icon>
</div>
</div>
</td>
<td align="center" style="max-height: 50px; overflow: auto;">
<div class="flex d-flex">
<div class="flex-center">
<va-icon class="fa fa-close" @click.native="() => deleteTask({ index: taskIndex})"></va-icon>
</div>
</div>
<td align="center" v-if="lockMode === false">
<va-icon class="fa fa-close" @click.native="() => deleteTask({ index: taskIndex})"></va-icon>
</td>
<td align="center" v-if="lockMode === true">
<!-- {{ task.status }} -->
<fulfilling-bouncing-circle-spinner
v-if="task.status === 1"
:animation-duration="3000"
:color="'#6c7fee'"
:size="16"
></fulfilling-bouncing-circle-spinner>
<va-icon v-if="task.status === 2" class="fa fa-check"></va-icon>
</td>
</tr>
</template>
@@ -111,12 +122,19 @@
import { mapFields } from 'vuex-map-fields'
import { mapActions, mapGetters } from 'vuex'
import types from '@/store/modules/project/types'
import { FulfillingBouncingCircleSpinner } from 'epic-spinners'
import configTable from '@/data/config-table/index'
export default {
name: 'project-table',
components: {
FulfillingBouncingCircleSpinner,
},
computed: {
config () {
return configTable.getConfig(this.projectLibrary)
},
...mapGetters('project', [
types.project.getSelect,
types.project.getDevice,
@@ -129,26 +147,69 @@ export default {
'taskViewPanel',
'taskSelectKey',
'deviceSelectKey',
'lockMode',
'projectLibrary',
]),
},
data () {
return {
temp: false,
tableColumn: {
name: -1,
checked: [],
},
}
},
methods: {
switchInput: function (tag, index) {
this.tableColumn[tag] >= 0
? this.tableColumn[tag] = -1
: this.tableColumn[tag] = index
},
selectAll: function (selectedArray) {
const totalRange = [...Array(this.getSelectProject.task.length).keys()].map(idx => String(idx))
selectedArray.includes('-1')
? (() => {
selectedArray.push(...totalRange)
selectedArray = [...new Set(selectedArray)]
})()
: selectedArray.length = 0
},
openConfig (type, taskIndex, deviceKey) {
console.log(type, taskIndex, deviceKey, this.taskViewPanel.type, this.taskSelectKey, this.deviceSelectKey)
if (this.taskViewPanel.type === type && this.taskSelectKey === taskIndex && this.deviceSelectKey === deviceKey) {
this.taskSelectKey = ''
this.taskViewPanel.type = -1
this.taskViewPanel.show = false
this.deviceSelectKey = ''
} else {
this.taskSelectKey = taskIndex
this.taskViewPanel.type = type
this.taskViewPanel.show = true
this.deviceSelectKey = deviceKey
if (!this.lockMode) {
if (this.taskViewPanel.type === type && this.taskSelectKey === taskIndex && this.deviceSelectKey === deviceKey) {
this.taskSelectKey = ''
this.taskViewPanel.type = -1
this.taskViewPanel.show = false
this.deviceSelectKey = ''
} else {
this.taskSelectKey = taskIndex
this.taskViewPanel.type = type
this.taskViewPanel.show = true
this.deviceSelectKey = deviceKey
}
}
},
parameterName (name) {
if (name === 'MODE') {
return 'Mode'
}
if (typeof this.config[name].showName === 'function') {
return this.config[name].showName()
}
return this.config[name].showName
},
parameterValue (name, value) {
if (name === 'MODE') {
return this.config.MODE[value].name
}
if (this.config[name].type === 'number') {
const scale = this.config[name].unit[this.config[name].defaultUnit]
return `${this.config[name].outputReadabilityData(value, scale)} ${this.config[name].defaultUnit}`
} else if (this.config[name].type === 'array') {
return `${this.config[name].outputReadabilityData(value)}`
} else if (this.config[name].type === 'none') {
return ''
}
},
...mapActions('project', [
@@ -162,12 +223,34 @@ export default {
<style lang="scss">
.markup-tables {
width: 100%;
.table-wrapper {
overflow: auto;
}
}
.va-table {
width: 100%;
.project-table {
td {
padding: 0;
margin: 0;
max-width: fit-content;
max-height: 100px;
overflow: auto;
white-space: nowrap;
font-size: 1.1rem;
}
th {
padding: 0 0 0 0;
margin: 0;
font-size: 1rem;
}
div {
padding: 0;
margin: 0;
}
}
</style>
+7 -1
View File
@@ -29,7 +29,11 @@
{{ controller.mac_address.toUpperCase() }}
</va-item-label>
<va-item-label>
Build Version : #
Frontend Version : #
{{ commit }}
</va-item-label>
<va-item-label>
Backend Version : #
{{ controller.software_version }}
</va-item-label>
<va-item-label>
@@ -79,6 +83,8 @@ export default {
},
data () {
return {
// eslint-disable-next-line no-undef
commit: COMMIT,
}
},
computed: {
+211 -208
View File
@@ -23,12 +23,15 @@
<div class="row row-equal">
<div v-if="showDeviceSetting" class="flex md12 xl4 xs12 sm12">
<div class="row">
<div class="flex sm12 xl12 md12 xs12">
<task-devices :ref="'devices_ref'" @add="addDevice($event)" @remove="removeDevice($event)" @refreshSetting="refreshChartSetting($event)" class="pa-0" />
</div>
<!-- <div class="flex sm12 xl12 md12 xs12">
<task-formula :ref="'formula_ref'" @add="addFormula($event)" @remove="removeFormula($event)" class="pa-0" />
<task-devices :ref="'devices_ref'" @add="addDevice($event)" @remove="removeDevice($event)" @refreshSetting="refreshChartSetting($event)" class="pa-0" />
</div> -->
<div class="flex sm12 xl12 md12 xs12">
<task-devices-new :ref="'devices_ref'" @add="addDevice($event)" @remove="removeDevice($event)" @refreshSetting="refreshChartSetting($event)" class="pa-0" />
</div>
<div class="flex sm12 xl12 md12 xs12" v-if="developer_mode">
<task-formula :ref="'formula_ref'" @add="addFormula($event)" @remove="removeFormula($event)" class="pa-0" />
</div>
</div>
</div>
@@ -57,15 +60,15 @@
<va-button class="no-dark-style-va-button" color="danger" target="_blank" @click="stopAllClick()" small>
STOP ALL
</va-button>
<va-button class="no-dark-style-va-button" color="primary" target="_blank" @click.stop="addChart()" small>
<va-button class="no-dark-style-va-button" color="primary" target="_blank" @click.stop="addChart(false)" small>
ADD CHART
</va-button>
</va-card>
</div>
<div :key="chartKey">
<div :key="taskContentChartPanelKey">
<div
v-for="chart in chartDataAll"
v-for="chart in chartData"
:key="chart.chartID"
>
<canvas-chart
@@ -96,13 +99,16 @@
<script>
import { dataStreamBuffer } from '../../../data/task/DataStreamBuffer'
import { chartData } from '../../../data/task/ChartsManagement'
import { taskInfo } from '../../../data/task/TaskInfo'
import CanvasChart from './chart/CanvasChart'
import TaskDevices from './controller/TaskDevices'
// import TaskDevices from './controller/TaskDevices'
import TaskDevicesNew from './controller/TaskDevicesNew'
// import api from '@/data/api'
import { mapFields } from 'vuex-map-fields'
// import TaskFormula from './formula/TaskFormula'
import { mapActions } from 'vuex'
import taskTypes from '@/store/modules/task/content/types'
import TaskFormula from './formula/TaskFormula'
import { v4 as uuid } from 'uuid'
// TODO change chart data tag format
@@ -110,12 +116,20 @@ export default {
name: 'TaskContent',
components: {
CanvasChart,
TaskDevices,
// TaskFormula,
// TaskDevices,
TaskDevicesNew,
TaskFormula,
},
computed: {
...mapFields('taskContent', [
'deviceList',
'chartData',
'taskContentChartPanelKey',
'taskContentChartNumber',
'deviceListNew',
]),
...mapFields('', [
'developer_mode',
]),
},
data () {
@@ -125,11 +139,7 @@ export default {
showRemoveChartModal: false,
// refresh timer
dataRefreshTimer: null,
// charts data
chartDataAll: chartData.getAllChartsData(),
// chart refresh key
chartKey: 0,
chartNumber: taskInfo.getTaskInfo().chartList.length,
selectChartID: null,
showDeviceSetting: true,
chartAreaClass: ['flex', 'xs12', 'sm12', 'md12', 'xl8', 'pa-0'],
@@ -138,79 +148,67 @@ export default {
},
mqtt: {
async '+/get_device_info_all/+' (data, topic) {
await taskInfo.deviceInfo(String.fromCharCode.apply(null, data), this.deviceList)
this.refreshDevicesWindow()
// console.log('get_device_info_all', String.fromCharCode.apply(null, data))
this.deviceListNew = JSON.parse(String.fromCharCode.apply(null, data)).data
// console.log(this.deviceListNew)
// await taskInfo.deviceInfo(String.fromCharCode.apply(null, data), this.deviceList)
// console.log('this.deviceList 0', this.deviceList)
// this.refreshDevicesWindow()
// console.log('this.$refs.devices_ref', this.$refs.devices_ref)
if (this.$refs.devices_ref != null) {
await this.$refs.devices_ref.loadingDone()
}
await this.taskContentChartInitCustomizedFromCache()
this.getParmDone = true
},
async '+/get_device_info/+' (data, topic) {
await taskInfo.deviceInfo(String.fromCharCode.apply(null, data), this.deviceList)
this.refreshDevicesWindow()
this.getParmDone = true
this.checkStiStatus()
// const dataObj = JSON.parse(String.fromCharCode.apply(null, data))
// await taskInfo.deviceInfo(dataObj, this.deviceList)
// this.refreshDevicesWindow()
// this.checkStiStatus()
// const result = await this.taskContentChartDefaultChartGenerator({
// _deviceList: this.deviceList,
// _itemID: taskInfo.getDeviceIDByRaw(dataObj.data.device_id),
// _chartID: null,
// _type: 'device',
// })
// if (result) {
// taskInfo.deviceStart(dataObj.data.device_id, this.deviceList)
// }
},
async '+/device_parameter/+' (data, topic) {
await taskInfo.deviceParameter(String.fromCharCode.apply(null, data))
this.refreshDevicesWindow()
const res = JSON.parse(String.fromCharCode.apply(null, data))
const device = this.deviceListNew.find((ele) => ele.mac_address === res.device)
for (const key of Object.keys(res.data)) {
device.configuration[key] = res.data[key]
}
// await taskInfo.deviceParameter(String.fromCharCode.apply(null, data))
// this.refreshDevicesWindow()
},
async '+/device_parameter_value/+' (data, topic) {
await taskInfo.deviceParameter(String.fromCharCode.apply(null, data))
this.refreshDevicesWindow()
const res = JSON.parse(String.fromCharCode.apply(null, data))
const device = this.deviceListNew.find((ele) => ele.mac_address === res.device)
for (const key of Object.keys(res.data)) {
device.configuration[key] = res.data[key]
}
},
async '+/hardware_device/+' (data, topic) {
await taskInfo.deviceInfo(String.fromCharCode.apply(null, data), this.deviceList)
// console.log(this.deviceList)
// for (const d1 in taskInfo.getTaskInfo().deviceList) {
// if (taskInfo.getTaskInfo().deviceList[d1].info.device_address.length > 0) {
// const addr1 = taskInfo.getTaskInfo().deviceList[d1].info.device_address.join()
// let parameter, content
// for (const d2 in this.deviceList) {
// const addr2 = this.deviceList[d2].info.device_address.join()
// if (addr1 === addr2) {
// // console.log(this.deviceList[d2].parameterSet)
// for (const p in this.deviceList[d2].parameterSet) {
// if (p !== 'STIMULATING') {
// if (parameter == null) {
// parameter = p
// } else {
// parameter = parameter + '|' + p
// }
// let c
// if (Array.isArray(this.deviceList[d2].parameterSet[p])) {
// c = '0:' + this.deviceList[d2].parameterSet[p].length + '=' + this.deviceList[d2].parameterSet[p]
// } else {
// c = this.deviceList[d2].parameterSet[p]
// }
// if (content == null) {
// content = c
// } else {
// content = content + '|' + c
// }
// }
// }
// // console.log('****', parameter, content)
// // this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
// // header: 'device_parameter/0',
// // device: parseInt(d1),
// // parameter: parameter,
// // content: content,
// // }))
// }
// }
// }
// }
if (this.$refs.devices_ref != null) {
await this.$refs.devices_ref.loadingDone()
await this.taskContentChartInitCustomizedFromCache()
}
},
// listen datastream [ topic: controllerID/data_server/device_data_stream/deviceID/channel ]
async '+/data_server/device_data_stream/+/+' (data, topic) {
const topicSplit = topic.split('/')
if (this.getParmDone & !taskInfo.getDeviceInfoByRawID(parseInt(topicSplit[3])).info.isSync) {
if (chartData.defaultChartGenerator(this.deviceList, taskInfo.getDeviceIDByRaw(parseInt(topicSplit[3])), null, 'device')) {
taskInfo.deviceStart(parseInt(topicSplit[3]), this.deviceList)
}
}
dataStreamBuffer.into(String.fromCharCode.apply(null, data), parseInt(topicSplit[3]), (parseInt(topicSplit[4]) + 1))
const deviceID = parseInt(topicSplit[3])
const channel = parseInt(topicSplit[4])
dataStreamBuffer.into(String.fromCharCode.apply(null, data), deviceID, (channel + 1))
},
'+/device_save_path/+' (data, topic) {
taskInfo.deviceSavePath(String.fromCharCode.apply(null, data))
@@ -232,6 +230,7 @@ export default {
},
async '+/broadcast' (data, topic) {
const mes = String.fromCharCode.apply(null, data).split(':')
let device
// let content
switch (mes[0]) {
case 'state':
@@ -262,18 +261,32 @@ export default {
this.showShutdownModal = true
break
case 'start':
if (!taskInfo.getDeviceInfoByRawID(parseInt(parseInt(mes[1]))).info.isSync) {
taskInfo.deviceStart(parseInt(mes[1]), this.deviceList)
if (chartData.defaultChartGenerator(this.deviceList, taskInfo.getDeviceIDByRaw(parseInt(parseInt(mes[1]))), null, 'device')) {
taskInfo.deviceStart(parseInt(parseInt(mes[1])), this.deviceList)
}
// register default chart again
await this.taskContentChartDefaultChartGenerator({
_deviceList: this.deviceListNew,
_itemID: parseInt(mes[1]),
_chartID: null,
_type: 'device',
})
// remove mapping ID chart series data
for (const chart in this.chartData) {
this.taskContentChartResetSeriesData({
chartID: chart,
mappingID: mes[1],
})
}
device = this.deviceListNew.find((ele) => ele.memory_board === parseInt(mes[1]))
device.status = 1
break
case 'stop':
if (mes[1] === 'all') {
return false
}
taskInfo.deviceStop(parseInt(mes[1]), this.deviceList)
device = this.deviceListNew.find((ele) => ele.memory_board === parseInt(mes[1]))
device.status = 0
await dataStreamBuffer.removeByDevice(parseInt(mes[1]))
break
case 'device_timeout':
this.pageToast('The device [' + taskInfo.getDeviceIDByRaw(parseInt(mes[1])) + '] is timeout, please check its status or parameters.')
@@ -289,7 +302,6 @@ export default {
default:
break
}
// console.log(String.fromCharCode.apply(null, data), topic)
},
},
methods: {
@@ -327,20 +339,12 @@ export default {
if (await this.$refs.devices_ref != null) {
await this.$refs.devices_ref.loadingStart()
}
// let _parameter, _content
// this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
// header: 'device_parameter/0',
// device: 7,
// parameter: 'RECORDING_CH|AXIS_CH',
// content: '7|1',
// }))
console.log(taskInfo.getTaskInfo().controllerID)
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'hardware_device/0',
header: 'get_device_info_all/0',
}))
await taskInfo.updateChartInfo()
this.chartNumber = taskInfo.getTaskInfo().chartNumber
this.taskContentChartNumber = Object.keys(this.chartData).length
},
pageToast: function (mes) {
this.showToast(
@@ -353,9 +357,20 @@ export default {
)
},
refreshData: function () {
// TODO don't need to refresh chart with stop status
for (const chart in this.chartDataAll) {
chartData.refresh(parseInt(chart))
for (const chart in this.chartData) {
// find each chart mappingID with device memory_board
const device = this.deviceListNew.find(ele => String(ele.memory_board) === String(this.chartData[chart].mappingID))
// device not found continue
if (device === undefined) {
continue
}
// device is running refresh chart
if (device.status === 1) {
this.taskContentChartRefreshData({
chartID: chart,
deviceList: this.deviceListNew,
})
}
}
},
refreshDevicesWindow: function () {
@@ -363,24 +378,22 @@ export default {
if (this.$refs.devices_ref != null) {
this.$refs.devices_ref.refresh()
}
// api.task.update({
// device_config: taskInfo.getTaskInfo().deviceList,
// })
},
addChart: async function () {
const defaultID = {}
const update = async () => {
for (const chart in chartData.getAllChartsData()) {
defaultID[chart] = chartData.getAllChartsData()[chart].mappingID
}
chartData.init(this.chartNumber, 4000, 1, 1)
this.chartNumber++
this.chartKey++
}
await update()
addChart: async function (isDefault) {
// create chartID with uuid instead of length of chart list
const newChart = await this.taskContentChartAdd({
chartID: uuid(),
maxDots: 5000,
gridLength: 1,
})
for (const chart in chartData.getAllChartsData()) {
chartData.getAllChartsData()[chart].mappingID = defaultID[chart]
// createby default
if (isDefault === true) {
newChart.createdBy = 'default'
}
// createby manaul
if (isDefault === false) {
newChart.createdBy = 'manual'
}
if (this.$refs.chart_ref != null) {
@@ -388,59 +401,54 @@ export default {
ref.refreshMappingSelect()
})
}
this.taskContentChartRefreshPanel()
// save chart config to web storage
if (!isDefault) {
await this.taskContentChartSaveToCache()
}
this.pageToast('The chart has been added.')
return this.chartNumber - 1
// chartData.updateGridList(0, 4)
return newChart.chartID
},
refreshChartSetting: async function () {
const defaultID = {}
const update = async () => {
for (const chart in chartData.getAllChartsData()) {
defaultID[chart] = chartData.getAllChartsData()[chart].mappingID
}
this.chartKey++
}
await update()
for (const chart in chartData.getAllChartsData()) {
chartData.getAllChartsData()[chart].mappingID = defaultID[chart]
}
if (this.$refs.chart_ref != null) {
this.$refs.chart_ref.forEach(ref => {
ref.refreshMappingSelect()
})
}
this.taskContentChartRefreshPanel()
},
initChart: function (chartID) {
chartData.reset(chartID)
this.taskContentChartReset({
chartID: chartID,
mappingID: null,
cardName: null,
})
this.pageToast('The chart has been Initialized.')
},
removeChartCheck: function (chartID) {
this.selectChartID = chartID
this.showRemoveChartModal = true
},
removeChart: async function (chartID) {
removeChart: async function (chartID, saveCache = true) {
if (chartID == null) {
chartID = this.selectChartID
}
dataStreamBuffer.removeByChart(chartID)
if (chartData.getAllChartsData()[chartID] != null) {
if (this.chartData[chartID] != null) {
const defaultID = {}
const update = async () => {
for (const chart in chartData.getAllChartsData()) {
for (const chart in this.chartData) {
if (chart !== chartID) {
defaultID[chart] = chartData.getAllChartsData()[chart].mappingID
defaultID[chart] = this.chartData[chart].mappingID
}
}
delete chartData.getAllChartsData()[chartID]
this.chartKey++
delete this.chartData[chartID]
}
await update()
for (const chart in chartData.getAllChartsData()) {
chartData.getAllChartsData()[chart].mappingID = defaultID[chart]
for (const chart in this.chartData) {
this.chartData[chart].mappingID = defaultID[chart]
}
if (this.$refs.chart_ref != null) {
@@ -449,6 +457,9 @@ export default {
})
}
}
if (saveCache === true) {
await this.taskContentChartSaveToCache()
}
this.pageToast('The chart has been removed.')
},
showDeviceSettingClick: function () {
@@ -463,14 +474,14 @@ export default {
},
addMappingChart: async function (deviceID) {
// if have chart with device ID
for (const chart in chartData.getAllChartsData()) {
if (chartData.getAllChartsData()[chart].mappingID === deviceID) {
for (const chart in this.chartData) {
if (this.chartData[chart].mappingID === deviceID) {
return false
}
}
const chart = await this.addChart()
const chart = await this.addChart(true)
await this.$nextTick(async () => {
chartData.getAllChartsData()[chart].mappingID = deviceID
this.chartData[chart].mappingID = deviceID
if (this.$refs.chart_ref != null) {
this.$refs.chart_ref.forEach(ref => {
ref.refreshMappingSelect()
@@ -479,23 +490,24 @@ export default {
})
return chart
},
addDevice: async function (deviceID) {
this.mqttSub(taskInfo.getTaskInfo().controllerID + '/data_server/device_data_stream/' + taskInfo.getRawDeviceID(deviceID) + '/+')
this.addMappingChart(deviceID)
// if (taskInfo.getDeviceInfo(deviceID).info.isSync) {
// chartData.defaultChartGenerator(deviceID, chart, 'device')
// }
// console.log(chartData.getAllChartsData())
// console.log(taskInfo.getTaskInfo())
// await api.task.update({
// device_config: taskInfo.getTaskInfo().deviceList,
// })
addDevice: async function (deviceID, memoryBoardID) {
// subscribe datastream when add device
this.mqttSub(`${taskInfo.getTaskInfo().controllerID}/data_server/device_data_stream/${deviceID}/+`)
// add mapping chart
await this.addMappingChart(deviceID)
// register default chart
await this.taskContentChartDefaultChartGenerator({
_deviceList: this.deviceListNew,
_itemID: deviceID,
_chartID: null,
_type: 'device',
})
this.pageToast('The device [' + deviceID + '] has been registered.')
},
removeDevice: function (deviceID) {
this.mqttUnSub(taskInfo.getTaskInfo().controllerID + '/data_server/device_data_stream/' + taskInfo.getRawDeviceID(deviceID) + '/+')
for (const chart in chartData.getAllChartsData()) {
if (chartData.getAllChartsData()[chart].mappingID === deviceID) {
this.mqttUnSub(taskInfo.getTaskInfo().controllerID + '/data_server/device_data_stream/' + deviceID + '/+')
for (const chart in this.chartData) {
if (this.chartData[chart].mappingID === deviceID) {
dataStreamBuffer.removeByChart(chart)
this.removeChart(chart)
}
@@ -503,9 +515,9 @@ export default {
this.pageToast('The device [' + deviceID + '] has been removed.')
},
addFormula: async function (formulaID) {
const chart = await this.addChart()
const chart = await this.addChart(true)
await this.$nextTick(async () => {
chartData.getAllChartsData()[chart].mappingID = formulaID
this.chartData[chart].mappingID = formulaID
if (this.$refs.chart_ref != null) {
this.$refs.chart_ref.forEach(ref => {
ref.refreshMappingSelect()
@@ -515,8 +527,8 @@ export default {
this.pageToast('The formula [' + formulaID + '] has been registered.')
},
removeFormula: function (formulaID) {
for (const chart in chartData.getAllChartsData()) {
if (chartData.getAllChartsData()[chart].mappingID === formulaID) {
for (const chart in this.chartData) {
if (this.chartData[chart].mappingID === formulaID) {
dataStreamBuffer.removeByChart(chart)
this.removeChart(chart)
}
@@ -524,7 +536,7 @@ export default {
this.pageToast('The formula [' + formulaID + '] has been removed.')
},
startAllClick: async function () {
for (const device of this.deviceList) {
for (const device of this.deviceListNew) {
if (this.$refs.devices_ref === undefined) {
this.startDevice(device)
} else {
@@ -535,31 +547,23 @@ export default {
this.pageToast('The all devices have been started')
},
startDevice: async function (device) {
chartData.defaultChartGenerator(this.deviceList, device.id, null, 'device')
if (!taskInfo.getDeviceInfo(device.id).info.isSync) {
if (taskInfo.getDeviceInfo(device.id).info.library_name.startsWith('Neulive')) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_instruction/0',
device: taskInfo.getRawDeviceID(device.id),
instruction: 'record',
}))
} else if (taskInfo.getDeviceInfo(device.id).info.library_name.startsWith('Elite')) {
// console.log('elite')
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_instruction/0',
device: taskInfo.getRawDeviceID(device.id),
instruction: 'start',
}))
}
device.stopping = false
device.isSync = true
// this.$emit('refreshSetting')
// ### show device info
// console.log(taskInfo.getDeviceInfo(device.id))
await this.taskContentChartDefaultChartGenerator({
_deviceList: this.deviceList,
_itemID: device.id,
_chartID: null,
_type: 'device',
})
if (device.status === 0) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_instruction/0',
device: device.memory_board,
instruction: 'start',
}))
device.status = 1
}
},
stopAllClick: function () {
for (const device of this.deviceList) {
for (const device of this.deviceListNew) {
if (this.$refs.devices_ref === undefined) {
this.stopDevice(device)
} else {
@@ -569,22 +573,14 @@ export default {
this.pageToast('The all devices have been stopped')
},
stopDevice: async function (device) {
dataStreamBuffer.removeByDevice(taskInfo.getRawDeviceID(device.id))
if (taskInfo.getDeviceInfo(device.id).info.isSync) {
if (taskInfo.getDeviceInfo(device.id).info.library_name.startsWith('Neulive')) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_instruction/0',
device: taskInfo.getRawDeviceID(device.id),
instruction: 'stop_record',
}))
} else if (taskInfo.getDeviceInfo(device.id).info.library_name.startsWith('Elite')) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_instruction/0',
device: taskInfo.getRawDeviceID(device.id),
instruction: 'interrupt',
}))
}
device.stopping = true
dataStreamBuffer.removeByDevice(device.id)
if (device.status === 1) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_instruction/0',
device: device.memory_board,
instruction: 'interrupt',
}))
device.status = 0
}
},
checkStiStatus: function () {
@@ -595,30 +591,37 @@ export default {
path: '/',
})
},
...mapActions('taskContent', [
taskTypes.chart.initCustomizedFromCache,
taskTypes.chart.saveToCache,
taskTypes.chart.add,
taskTypes.chart.defaultChartGenerator,
taskTypes.chart.reset,
taskTypes.chart.resetSeriesData,
taskTypes.chart.refreshData,
taskTypes.chart.refreshChart,
taskTypes.chart.refreshPanel,
]),
},
watch: {
},
async mounted () {
const devMode = this.$route.params.mode
if (devMode === 'dev') {
this.developer_mode = true
}
await taskInfo.updateTaskInfo(this.$route.params.taskID)
// console.log(taskInfo.getTaskInfo())
// this.screenHeight = document.documentElement.clientHeight
this.pageMqttSub(taskInfo.getTaskInfo().controllerID)
// console.log(taskInfo.getTaskInfo().controllerID)
await this.pageInit()
// this.chartNumber = taskInfo.getTaskInfo().chartNumber
this.dataRefreshTimer = setInterval(this.refreshData, 100)
// const _this = this
// window.onresize = function () { // define the event of window size changing
// // _this.screenWidth = document.documentElement.clientWidth
// _this.screenHeight = document.documentElement.clientHeight
// }
},
destroyed () {
taskInfo.destroyed(this.deviceList)
for (const chart in chartData.getAllChartsData()) {
this.removeChart(chart)
for (const chart in this.chartData) {
this.removeChart(chart, false)
}
clearInterval(this.dataRefreshTimer)
this.pageMqttUnSub(taskInfo.getTaskInfo().controllerID)
+74 -55
View File
@@ -60,7 +60,7 @@
<div :key="chartKey">
<div
v-for="chart in chartDataAll"
v-for="chart in chartData"
:key="chart.chartID"
>
<canvas-chart
@@ -93,33 +93,29 @@
<script>
import { dataStreamBuffer } from '../../../data/task/DataStreamBuffer'
import { chartData } from '../../../data/task/ChartsManagement'
import { taskInfo } from '../../../data/task/TaskInfo'
import CanvasChart from './chart/CanvasChart'
import TaskContentModal from './TaskContentModal.vue'
import { mapFields } from 'vuex-map-fields'
import TaskDevicesGM from './controller/neulive-gimer/TaskDevicesGM.vue'
// import api from '../../../data/api'
// import TaskFormula from './formula/TaskFormula'
import { mapActions } from 'vuex'
import taskTypes from '@/store/modules/task/content/types'
// TODO change chart data tag format
export default {
name: 'TaskContent',
name: 'TaskContentGM',
components: {
CanvasChart,
TaskDevicesGM,
TaskContentModal,
// TaskFormula,
},
// async created () {
// await taskInfo.updateTaskInfo(this.$route.params.taskID)
// },
computed: {
...mapFields('taskContent', [
'deviceList',
'showTaskModal',
'taskModalText',
'chartData',
]),
},
data () {
@@ -129,11 +125,9 @@ export default {
showRemoveChartModal: false,
// refresh timer
dataRefreshTimer: null,
// charts data
chartDataAll: chartData.getAllChartsData(),
// chart refresh key
chartKey: 0,
chartNumber: taskInfo.getTaskInfo().chartList.length,
chartNumber: 0,
selectChartID: null,
showDeviceSetting: true,
chartAreaClass: ['flex', 'xs12', 'sm12', 'md12', 'xl8', 'pa-0'],
@@ -169,7 +163,13 @@ export default {
async '+/data_server/device_data_stream/+/+' (data, topic) {
const topicSplit = topic.split('/')
if (this.getParmDone & !taskInfo.getDeviceInfoByRawID(parseInt(topicSplit[3])).info.isSync) {
if (chartData.defaultChartGenerator(this.deviceList, taskInfo.getDeviceIDByRaw(parseInt(topicSplit[3])), null, 'device')) {
const result = await this.taskContentChartDefaultChartGenerator({
_deviceList: this.deviceList,
_itemID: taskInfo.getDeviceIDByRaw(parseInt(topicSplit[3])),
_chartID: null,
_type: 'device',
})
if (result) {
taskInfo.deviceStart(parseInt(topicSplit[3]), this.deviceList)
}
}
@@ -215,10 +215,16 @@ export default {
this.showShutdownModal = true
break
case 'start':
if (!taskInfo.getDeviceInfoByRawID(parseInt(parseInt(mes[1]))).info.isSync) {
if (!taskInfo.getDeviceInfoByRawID(parseInt(mes[1])).info.isSync) {
taskInfo.deviceStart(parseInt(mes[1]), this.deviceList)
if (chartData.defaultChartGenerator(this.deviceList, taskInfo.getDeviceIDByRaw(parseInt(parseInt(mes[1]))), null, 'device')) {
taskInfo.deviceStart(parseInt(parseInt(mes[1])), this.deviceList)
const result = await this.taskContentChartDefaultChartGenerator({
_deviceList: this.deviceList,
_itemID: taskInfo.getDeviceIDByRaw(parseInt(mes[1])),
_chartID: null,
_type: 'device',
})
if (result) {
taskInfo.deviceStart(parseInt(mes[1]), this.deviceList)
}
}
break
@@ -289,8 +295,8 @@ export default {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'hardware_device/0',
}))
await taskInfo.updateChartInfo()
this.chartNumber = taskInfo.getTaskInfo().chartNumber
this.chartNumber = Object.keys(this.chartData).length
},
pageToast: function (mes) {
this.showToast(
@@ -304,8 +310,10 @@ export default {
},
refreshData: function () {
// TODO don't need to refresh chart with stop status
for (const chart in this.chartDataAll) {
chartData.refresh(parseInt(chart))
for (const chart in this.chartData) {
this.taskContentChartRefreshData({
chartID: parseInt(chart),
})
}
},
refreshDevicesWindow: function () {
@@ -320,17 +328,21 @@ export default {
addChart: async function () {
const defaultID = {}
const update = async () => {
for (const chart in chartData.getAllChartsData()) {
defaultID[chart] = chartData.getAllChartsData()[chart].mappingID
for (const chart in this.chartData) {
defaultID[chart] = this.chartData[chart].mappingID
}
chartData.init(this.chartNumber, 4000, 1, 1)
this.taskContentChartAdd({
chartID: this.chartNumber,
maxDots: 4000,
gridLength: 1,
})
this.chartNumber++
this.chartKey++
}
await update()
for (const chart in chartData.getAllChartsData()) {
chartData.getAllChartsData()[chart].mappingID = defaultID[chart]
for (const chart in this.chartData) {
this.chartData[chart].mappingID = defaultID[chart]
}
if (this.$refs.chart_ref != null) {
@@ -341,20 +353,19 @@ export default {
// this.pageToast('The chart has been added.')
return this.chartNumber - 1
// chartData.updateGridList(0, 4)
},
refreshChartSetting: async function () {
const defaultID = {}
const update = async () => {
for (const chart in chartData.getAllChartsData()) {
defaultID[chart] = chartData.getAllChartsData()[chart].mappingID
for (const chart in this.chartData) {
defaultID[chart] = this.chartData[chart].mappingID
}
this.chartKey++
}
await update()
for (const chart in chartData.getAllChartsData()) {
chartData.getAllChartsData()[chart].mappingID = defaultID[chart]
for (const chart in this.chartData) {
this.chartData[chart].mappingID = defaultID[chart]
}
if (this.$refs.chart_ref != null) {
@@ -364,7 +375,11 @@ export default {
}
},
initChart: function (chartID) {
chartData.reset(chartID)
this.taskContentChartReset({
chartID: chartID,
mappingID: null,
cardName: null,
})
// this.pageToast('The chart has been Initialized.')
},
removeChartCheck: function (chartID) {
@@ -376,21 +391,21 @@ export default {
chartID = this.selectChartID
}
dataStreamBuffer.removeByChart(chartID)
if (chartData.getAllChartsData()[chartID] != null) {
if (this.chartData[chartID] != null) {
const defaultID = {}
const update = async () => {
for (const chart in chartData.getAllChartsData()) {
for (const chart in this.chartData) {
if (chart !== chartID) {
defaultID[chart] = chartData.getAllChartsData()[chart].mappingID
defaultID[chart] = this.chartData[chart].mappingID
}
}
delete chartData.getAllChartsData()[chartID]
delete this.chartData[chartID]
this.chartKey++
}
await update()
for (const chart in chartData.getAllChartsData()) {
chartData.getAllChartsData()[chart].mappingID = defaultID[chart]
for (const chart in this.chartData) {
this.chartData[chart].mappingID = defaultID[chart]
}
if (this.$refs.chart_ref != null) {
@@ -413,14 +428,14 @@ export default {
},
addMappingChart: async function (deviceID) {
// if have chart with device ID
for (const chart in chartData.getAllChartsData()) {
if (chartData.getAllChartsData()[chart].mappingID === deviceID) {
for (const chart in this.chartData) {
if (this.chartData[chart].mappingID === deviceID) {
return false
}
}
const chart = await this.addChart()
await this.$nextTick(async () => {
chartData.getAllChartsData()[chart].mappingID = deviceID
this.chartData[chart].mappingID = deviceID
if (this.$refs.chart_ref != null) {
this.$refs.chart_ref.forEach(ref => {
ref.refreshMappingSelect()
@@ -432,20 +447,12 @@ export default {
addDevice: async function (deviceID) {
this.mqttSub(taskInfo.getTaskInfo().controllerID + '/data_server/device_data_stream/' + taskInfo.getRawDeviceID(deviceID) + '/+')
this.addMappingChart(deviceID)
// if (taskInfo.getDeviceInfo(deviceID).info.isSync) {
// chartData.defaultChartGenerator(deviceID, chart, 'device')
// }
// console.log(chartData.getAllChartsData())
// console.log(taskInfo.getTaskInfo())
// await api.task.update({
// device_config: taskInfo.getTaskInfo().deviceList,
// })
this.pageToast('The device [' + deviceID + '] has been registered.')
},
removeDevice: function (deviceID) {
this.mqttUnSub(taskInfo.getTaskInfo().controllerID + '/data_server/device_data_stream/' + taskInfo.getRawDeviceID(deviceID) + '/+')
for (const chart in chartData.getAllChartsData()) {
if (chartData.getAllChartsData()[chart].mappingID === deviceID) {
for (const chart in this.chartData) {
if (this.chartData[chart].mappingID === deviceID) {
dataStreamBuffer.removeByChart(chart)
this.removeChart(chart)
}
@@ -455,7 +462,7 @@ export default {
addFormula: async function (formulaID) {
const chart = await this.addChart()
await this.$nextTick(async () => {
chartData.getAllChartsData()[chart].mappingID = formulaID
this.chartData[chart].mappingID = formulaID
if (this.$refs.chart_ref != null) {
this.$refs.chart_ref.forEach(ref => {
ref.refreshMappingSelect()
@@ -465,8 +472,8 @@ export default {
this.pageToast('The formula [' + formulaID + '] has been registered.')
},
removeFormula: function (formulaID) {
for (const chart in chartData.getAllChartsData()) {
if (chartData.getAllChartsData()[chart].mappingID === formulaID) {
for (const chart in this.chartData) {
if (this.chartData[chart].mappingID === formulaID) {
dataStreamBuffer.removeByChart(chart)
this.removeChart(chart)
}
@@ -485,7 +492,12 @@ export default {
this.pageToast('The all devices have been started')
},
startDevice: async function (device) {
chartData.defaultChartGenerator(this.deviceList, device.id, null, 'device')
await this.taskContentChartDefaultChartGenerator({
_deviceList: this.deviceList,
_itemID: device.id,
_chartID: null,
_type: 'device',
})
if (!taskInfo.getDeviceInfo(device.id).info.isSync) {
if (taskInfo.getDeviceInfo(device.id).info.library_name.startsWith('Neulive')) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
@@ -542,6 +554,13 @@ export default {
path: '/',
})
},
...mapActions('taskContent', [
taskTypes.chart.add,
taskTypes.chart.refreshData,
taskTypes.chart.defaultChartGenerator,
taskTypes.chart.reset,
]),
},
watch: {
},
@@ -564,7 +583,7 @@ export default {
},
destroyed () {
taskInfo.destroyed(this.deviceList)
for (const chart in chartData.getAllChartsData()) {
for (const chart in this.chartData) {
this.removeChart(chart)
}
clearInterval(this.dataRefreshTimer)
+116 -61
View File
@@ -4,7 +4,7 @@
<template slot="header">
<div class="row flex sm12 xl12 md12 xs12 align--center my-0 py-0">
<div class="flex sm5 xl5 md5 xs5 px-0 mx-0">
<h5 class="mt-0 mb-0"><va-icon name="fa fa-area-chart mr-3" color="primary"/>{{nameCard}}</h5>
<h5 class="mt-0 mb-0"><va-icon name="fa fa-area-chart mr-3" color="primary"/>{{ nameCard }}</h5>
</div>
<div class="flex sm7 xl7 md7 xs7 pa-0 ma-0" style="text-align: right;">
<va-button class="pa-0 ma-0 circle-button" small color="dark" @click="remove()">
@@ -14,26 +14,56 @@
/>
</va-button>
</div>
<!-- <div>
<va-button v-if="integralClicked && (mode_name==='Chronoamperometric' || mode_name==='I-T Graph')" color="danger" class="mb-2" @click="clickIntegral" small>
To Raw Mode
</va-button>
<va-button v-if="!integralClicked && (mode_name==='Chronoamperometric' || mode_name==='I-T Graph')" color="primary" class="mb-2" @click="clickIntegral" small>
To Integral Mode
</va-button>
<va-button v-if="xlogClicked && (mode_name==='Linear Sweep Voltammetry' || mode_name==='I-V Curve')" color="danger" class="mb-2" @click="clickXLog" small>
To Raw Mode
</va-button>
<va-button :disabled="disableLog" v-if="!xlogClicked && (mode_name==='Linear Sweep Voltammetry' || mode_name==='I-V Curve')" color="primary" class="mb-2" @click="clickXLog" small>
To log Mode (x-axis)
</va-button>
<va-button v-if="ylogClicked && (mode_name==='Linear Sweep Voltammetry' || mode_name==='I-V Curve')" color="danger" class="mb-2" @click="clickYLog" small>
To Raw Mode
</va-button>
<va-button :disabled="disableLog" v-if="!ylogClicked && (mode_name==='Linear Sweep Voltammetry' || mode_name==='I-V Curve')" color="primary" class="mb-2" @click="clickYLog" small>
To log Mode (y-axis)
</va-button>
<va-button v-if="diffClicked && (mode_name==='Linear Sweep Voltammetry' || mode_name==='I-V Curve')" color="danger" class="mb-2" @click="clickDiff" small>
To Raw Mode
</va-button>
<va-button :disabled="disableDiff" v-if="!diffClicked && (mode_name==='Linear Sweep Voltammetry' || mode_name==='I-V Curve')" color="primary" class="mb-2" @click="clickDiff" small>
To Differential Mode
</va-button>
</div> -->
<canvas-chart-real-time-calculation :chartID="chartID" @refreshData="refreshData" @switchModeButton="switchModeButton"/>
</div>
</template>
<va-tabs v-model="tabValue" class="mb-3" style="width: 100%; min-width: 100px;">
<va-tab>
{{'CHART'}}
{{ 'CHART' }}
</va-tab>
<va-tab>
{{'SOURCE'}}
{{ 'SOURCE' }}
</va-tab>
</va-tabs>
<div v-if="tabValue == 0" >
<div v-if="data.legend.data.length != 0">
<chart :ref="'chart_ref'" :style="'width: '+ cardwidth + '; height: ' + cardheight + ';'" :options="data" :auto-resize="true"></chart>
<div v-if="chartData[chartID].legend.data.length != 0">
<canvas-chart-real-time-display
:chartID="chartID" ref="CanvasChartRealTimeDisplay"
/>
<!-- chart -->
<chart :key="taskContentChartKey" :ref="'chart_ref'" :style="'width: '+ cardwidth + '; height: ' + cardheight + ';'" :options="data" @dataZoom="updateZoom" :auto-resize="true" @></chart>
</div>
</div>
<div v-else-if="tabValue == 1" :style="'width: '+ cardwidth + '; height: ' + cardheight + ';'" >
<canvas-chart-source :chartID="chartID" :gridInfo="data.grid"></canvas-chart-source>
<canvas-chart-source :chartID="chartID" @addSource="addSource()" />
</div>
<div v-else :style="'width: '+ cardwidth + '; height: ' + cardheight + ';'" >
<!-- <canvas-chart-setting :chartID="chartID"></canvas-chart-setting> -->
</div>
<div v-if="this.$refs.chart_ref != null">
<va-button small class="mb-3" @click="selectAllSeries">
@@ -45,7 +75,7 @@
</div>
<div class="row flex align--left ma-0 pa-0">
<va-input
v-if="data.chartXMode === 'time'"
v-if="chartData[chartID].chartXMode === 'time'"
class="mx-1"
@keyup.enter="timeIntervalChange(timeIntervalInput)"
@blur="timeIntervalChange(timeIntervalInput)"
@@ -57,7 +87,7 @@
</p>
</va-input>
<va-input
v-if="data.chartXMode === 'value'"
v-if="chartData[chartID].chartXMode === 'value'"
class="mx-1"
@keyup.enter="xIntervalChange(xIntervalInput)"
@blur="xIntervalChange(xIntervalInput)"
@@ -65,7 +95,7 @@
:label="'x-grid'"
>
<p slot="append" style="margin-right: 0;" small>
{{data.chartXUnit}}
{{chartData[chartID].chartXUnit}}
</p>
</va-input>
<va-input
@@ -76,11 +106,11 @@
:label="'y-grid'"
>
<p slot="append" style="margin-right: 0;" small>
{{data.chartYUnit}}
{{chartData[chartID].chartYUnit}}
</p>
</va-input>
<va-input
v-if="data.chartDevice === 'neulive'"
v-if="chartData[chartID].chartDevice === 'neulive'"
class="mx-1"
@keyup.enter="threeAxisIntervalChange(threeAxisIntervalInput)"
@blur="threeAxisIntervalChange(threeAxisIntervalInput)"
@@ -92,7 +122,7 @@
</p>
</va-input>
</div>
<div class="row flex ma-0 pa-0">
<div class="row flex ma-0 pa-0" v-if="developer_mode === true">
<canvas-chart-filter :chartID="chartID" :filterIndex="0" />
<canvas-chart-filter :chartID="chartID" :filterIndex="1" />
<canvas-chart-filter :chartID="chartID" :filterIndex="2" />
@@ -103,13 +133,18 @@
</template>
<script>
// import { InitChartsData, getChartsData } from '../../../../../data/task/ChartsManagement'
import CanvasChartFilter from './CanvasChartFilter.vue'
import CanvasChartFilterPopup from './CanvasChartFilterPopup.vue'
// import CanvasChartSetting from './CanvasChartSetting'
import CanvasChartSource from './CanvasChartSource'
import { taskInfo } from '../../../../data/task/TaskInfo'
import { chartData } from '../../../../data/task/ChartsManagement'
import { mapFields } from 'vuex-map-fields'
import CanvasChartRealTimeDisplay from '@/components/task/content/chart/CanvasChartRealTimeDisplay'
import { mapActions } from 'vuex'
import taskTypes from '@/store/modules/task/content/types'
// import paramTable from '@/data/param-table/index'
// import { newTooltip } from '@/factories/chart/tooltipFactory'
// import { getTimeFormatter } from '@/store/modules/task/content/actions/chartAct'
import CanvasChartRealTimeCalculation from './CanvasChartRealTimeCalculation.vue'
export default {
name: 'CanvasChart',
@@ -118,10 +153,12 @@ export default {
CanvasChartSource,
CanvasChartFilter,
CanvasChartFilterPopup,
CanvasChartRealTimeDisplay,
CanvasChartRealTimeCalculation,
},
props: {
chartID: {
type: Number,
type: [Number, String],
required: true,
},
cardclass: {
@@ -139,77 +176,87 @@ export default {
default: 'auto',
},
},
created () {
computed: {
...mapFields('', [
'developer_mode',
]),
...mapFields('taskContent', [
'chartData',
'taskContentChartKey',
'deviceListNew',
]),
},
data () {
return {
// chartData: InitChartsData(this.chartID, 2000, 1, 1),
data: null,
tabValue: 0,
chartKey: 0,
data: chartData.getChartsData(this.chartID),
resizeTimer: null,
mappingSelect: '',
mappingOptions: taskInfo.getMappingList(),
nameCard: chartData.getAllChartsData()[this.chartID].cardName,
nameCard: '',
initDone: false,
timeIntervalInput: 'auto',
threeAxisIntervalInput: 'auto',
xIntervalInput: 'auto',
yIntervalInput: 'auto',
dataZoomStart: 0,
dataZoomEnd: 100,
}
},
computed: {
},
watch: {
},
methods: {
updateZoom: function (e) {
// console.log(e.batch)
this.dataZoomStart = e.batch[0].start
this.dataZoomEnd = e.batch[0].end
},
timeIntervalChange: function (val) {
if (!isNaN(parseInt(val))) {
chartData.getAllChartsData()[this.chartID].xAxis.forEach(x => {
this.chartData[this.chartID].xAxis.forEach(x => {
if (x.type === 'time') {
x.interval = val * 1000
}
})
} else {
this.timeIntervalInput = 'auto'
chartData.getAllChartsData()[this.chartID].xAxis.forEach(x => {
this.chartData[this.chartID].xAxis.forEach(x => {
if (x.type === 'time') {
x.interval = 500 * 1000
}
})
}
},
xIntervalChange: function (val) {
xIntervalChange: async function (val) {
if (!isNaN(parseInt(val))) {
chartData.getAllChartsData()[this.chartID].xAxis.forEach(x => {
this.chartData[this.chartID].xAxis.forEach(x => {
if (x.type === 'value') {
x.interval = val * 1000
}
})
} else {
this.timeIntervalInput = 'auto'
chartData.getAllChartsData()[this.chartID].xAxis.forEach(x => {
this.chartData[this.chartID].xAxis.forEach(x => {
if (x.type === 'value') {
x.interval = null
}
})
}
await this.taskContentChartSaveToCache()
},
yIntervalChange: function (val) {
yIntervalChange: async function (val) {
if (!isNaN(parseInt(val))) {
chartData.getAllChartsData()[this.chartID].yAxis.forEach(y => {
this.chartData[this.chartID].yAxis.forEach(y => {
if (parseInt(y.channel) <= 255) {
if (chartData.getAllChartsData()[this.chartID].chartYUnit === 'uV') {
if (this.chartData[this.chartID].chartYUnit === 'uV') {
y.interval = parseInt(val)
// console.log(y.interval)
} else {
y.interval = val * 1000
}
const maxList = []
const minList = []
// TODO: follow this way to iterate the deviceID
y.seriesIndex.forEach(i => {
maxList.push(Math.max(...chartData.getAllChartsData()[this.chartID].series[i].data.map(p => p[1])))
minList.push(Math.min(...chartData.getAllChartsData()[this.chartID].series[i].data.map(p => p[1])))
maxList.push(Math.max(...this.chartData[this.chartID].series[i].data.map(p => p[1])))
minList.push(Math.min(...this.chartData[this.chartID].series[i].data.map(p => p[1])))
})
const max = Math.max(maxList)
const min = Math.min(minList)
@@ -222,7 +269,7 @@ export default {
})
} else {
this.timeIntervalInput = 'auto'
chartData.getAllChartsData()[this.chartID].yAxis.forEach(y => {
this.chartData[this.chartID].yAxis.forEach(y => {
if (parseInt(y.channel) <= 255) {
y.interval = null
y.max = 'dataMax'
@@ -230,17 +277,18 @@ export default {
}
})
}
await this.taskContentChartSaveToCache()
},
threeAxisIntervalChange: function (val) {
if (!isNaN(parseInt(val))) {
chartData.getAllChartsData()[this.chartID].yAxis.forEach(y => {
this.chartData[this.chartID].yAxis.forEach(y => {
if (parseInt(y.channel) >= 255) {
y.interval = val * 1
}
})
} else {
this.timeIntervalInput = 'auto'
chartData.getAllChartsData()[this.chartID].yAxis.forEach(y => {
this.chartData[this.chartID].yAxis.forEach(y => {
if (parseInt(y.channel) >= 255) {
y.interval = null
}
@@ -266,33 +314,24 @@ export default {
this.mappingOptions.forEach(item => {
if (item.id === itemID) {
this.mappingSelect = item
chartData.getAllChartsData()[this.chartID].mappingID = item.id
this.chartData[this.chartID].mappingID = item.id
}
})
},
refreshMappingSelect: async function () {
this.setMappingSelect(chartData.getAllChartsData()[this.chartID].mappingID)
if (chartData.getAllChartsData()[this.chartID].mappingID !== -1 && chartData.getAllChartsData()[this.chartID].mappingID != null) {
this.setMappingSelect(this.chartData[this.chartID].mappingID)
if (this.chartData[this.chartID].mappingID !== '-1' && this.chartData[this.chartID].mappingID != null) {
taskInfo.getMappingList().forEach(item => {
if (item.id === chartData.getAllChartsData()[this.chartID].mappingID) {
if (item.id === this.chartData[this.chartID].mappingID) {
this.setChartName(item.name)
}
})
}
},
setChartName: function (name) {
chartData.getAllChartsData()[this.chartID].cardName = name
this.chartData[this.chartID].cardName = name
this.nameCard = name
},
mappingSelectChange: function () {
if (this.initDone) {
if (this.mappingSelect.id != null) {
chartData.getAllChartsData()[this.chartID].mappingID = this.mappingSelect.id
} else {
chartData.getAllChartsData()[this.chartID].mappingID = -1
}
}
},
resize: function () {
if (this.$refs.chart_ref != null) {
this.$refs.chart_ref.resize()
@@ -309,12 +348,12 @@ export default {
let index = 0
for (const [gridIndex, value] of Object.values(params.selected).entries()) { // [TODO] 技術債,目前real time chart一個grid只對應一條series
if (value === true) {
this.data.grid[gridIndex].height = (85 / activeLegendLen) + '%'
this.data.grid[gridIndex].top = index * (85 / activeLegendLen) + 1 + '%'
this.chartData[this.chartID].grid[gridIndex].height = (85 / activeLegendLen) + '%'
this.chartData[this.chartID].grid[gridIndex].top = index * (85 / activeLegendLen) + 1 + '%'
index++
} else {
this.data.grid[gridIndex].height = '0%'
this.data.grid[gridIndex].top = '0%'
this.chartData[this.chartID].grid[gridIndex].height = '0%'
this.chartData[this.chartID].grid[gridIndex].top = '0%'
}
}
},
@@ -328,15 +367,31 @@ export default {
type: 'legendInverseSelect',
})
},
refreshData: function (rawData) {
this.data = rawData
// save the start & end of previous dataZoom setting to avoid reset dataZoom
this.data.dataZoom[0].start = this.dataZoomStart
this.data.dataZoom[0].end = this.dataZoomEnd
this.$refs.CanvasChartRealTimeDisplay.updateData(this.data)
},
...mapActions('taskContent', [
taskTypes.chart.saveToCache,
]),
switchModeButton: function (dataMode) {
// console.log('switchModeBtn')
this.$refs.CanvasChartRealTimeDisplay.switchFunctional(String(dataMode))
},
},
async mounted () {
this.data = this.chartData[this.chartID]
// this.data = this.chartData[this.chartID]
this.resizeTimer = setInterval(this.resize, 1000)
this.nameCard = chartData.getAllChartsData()[this.chartID].cardName
this.nameCard = this.chartData[this.chartID].cardName
await this.refreshMappingSelect()
this.initDone = true
if (this.$refs.chart_ref != null) {
this.$refs.chart_ref.chart._zr.on('click', this.showFilterPopup)
this.$refs.chart_ref.chart._zr.on('mousemove', this.setCursor)
// this.$refs.chart_ref.chart._zr.on('click', this.showFilterPopup)
// this.$refs.chart_ref.chart._zr.on('mousemove', this.setCursor)
this.$refs.chart_ref.chart.on('legendselectchanged', this.legendChange)
this.$refs.chart_ref.chart.on('legendselectall', this.legendChange)
this.$refs.chart_ref.chart.on('legendinverseselect', this.legendChange)
@@ -56,7 +56,6 @@
</template>
<script>
import { chartData } from '@/data/task/ChartsManagement'
import { taskInfo } from '@/data/task/TaskInfo'
import api from '@/data/api'
import { mapFields } from 'vuex-map-fields'
@@ -66,7 +65,7 @@ export default {
name: 'canvas-chart-filter',
props: {
chartID: {
type: Number,
type: [Number, String],
required: true,
},
filterIndex: {
@@ -77,23 +76,23 @@ export default {
computed: {
...mapFields('taskContent', [
'filter',
'chartData',
]),
buttonIcon () {
if (this.data.series.length > 0 && this.data.series.every(item => item != null)) {
return this.data.series.every(item => item.filter[this.filterIndex].filter != null) ? 'fa fa-stop' : 'fa fa-play'
if (this.chartData[this.chartID].series.length > 0 && this.chartData[this.chartID].series.every(item => item != null)) {
return this.chartData[this.chartID].series.every(item => item.filter[this.filterIndex].filter != null) ? 'fa fa-stop' : 'fa fa-play'
}
return 'fa fa-play'
},
buttonColor () {
if (this.data.series.length > 0 && this.data.series.every(item => item != null)) {
return this.data.series.every(item => item.filter[this.filterIndex].filter != null) ? 'danger' : 'primary'
if (this.chartData[this.chartID].series.length > 0 && this.chartData[this.chartID].series.every(item => item != null)) {
return this.chartData[this.chartID].series.every(item => item.filter[this.filterIndex].filter != null) ? 'danger' : 'primary'
}
return 'fa fa-play'
return 'primary'
},
},
data () {
return {
data: chartData.getAllChartsData()[this.chartID],
selectFilter: {
id: 1,
name: 'notch',
@@ -129,9 +128,9 @@ export default {
methods: {
async updateFilterInfo (index) {
let closeFilter = false
for (let i = 0; i < this.data.series.length; i++) {
if (this.data.series[i].filter[this.filterIndex].filter != null) {
this.data.series[i].filter[this.filterIndex].filter = null
for (let i = 0; i < this.chartData[this.chartID].series.length; i++) {
if (this.chartData[this.chartID].series[i].filter[this.filterIndex].filter != null) {
this.chartData[this.chartID].series[i].filter[this.filterIndex].filter = null
closeFilter = true
}
}
@@ -140,8 +139,8 @@ export default {
}
let fs = 0
let sos = []
for (let i = 0; i < this.data.series.length; i++) {
const deviceID = this.data.series[i].yAxisSource[0]
for (let i = 0; i < this.chartData[this.chartID].series.length; i++) {
const deviceID = this.chartData[this.chartID].series[i].yAxisSource[0]
// const _fs = taskInfo.getDeviceInfo(deviceID).parameterSet.SAMPLE_RATE
const _fs = 1000
const _chNum = taskInfo.getDeviceInfo(deviceID).parameterSet.CH_NUMBER
@@ -173,17 +172,17 @@ export default {
})
sos = _sos
}
this.data.series[i].filter[index].type = this.selectFilter.name
this.data.series[i].filter[index].order = this.order
this.chartData[this.chartID].series[i].filter[index].type = this.selectFilter.name
this.chartData[this.chartID].series[i].filter[index].order = this.order
// sampling rate changed by channel number
this.data.series[i].filter[index].fs = parseFloat(_fs / _chNum)
this.data.series[i].filter[index].f0 = parseFloat(this.freq0)
this.data.series[i].filter[index].f1 = parseFloat(this.freq1)
this.data.series[i].filter[index].f2 = parseFloat(this.freq2)
this.data.series[i].filter[index].sos = sos
this.data.series[i].filter[index].filter = IIRFilter.init(sos)
this.chartData[this.chartID].series[i].filter[index].fs = parseFloat(_fs / _chNum)
this.chartData[this.chartID].series[i].filter[index].f0 = parseFloat(this.freq0)
this.chartData[this.chartID].series[i].filter[index].f1 = parseFloat(this.freq1)
this.chartData[this.chartID].series[i].filter[index].f2 = parseFloat(this.freq2)
this.chartData[this.chartID].series[i].filter[index].sos = sos
this.chartData[this.chartID].series[i].filter[index].filter = IIRFilter.init(sos)
}
// console.log(this.data)
// console.log(this.chartData[this.chartID])
},
},
}
@@ -19,8 +19,8 @@
</template>
<script>
import { chartData } from '@/data/task/ChartsManagement'
import CanvasChartIndividualFilter from './CanvasChartIndividualFilter.vue'
import { mapFields } from 'vuex-map-fields'
export default {
name: 'canvas-chart-filter-popup',
@@ -29,7 +29,7 @@ export default {
},
props: {
chartID: {
type: Number,
type: [Number, String],
required: true,
},
chartRef: {
@@ -37,21 +37,22 @@ export default {
},
},
computed: {
...mapFields('taskContent', [
'chartData',
]),
},
data () {
return {
showModal: false,
position: 'center',
data: chartData.getAllChartsData()[this.chartID],
gridIndex: 0,
}
},
methods: {
showPanel (params) {
// console.log(this.data)
if (this.chartRef != null) {
let _gridIndex = 0
for (_gridIndex = 0; _gridIndex < this.data.grid.length; _gridIndex++) {
for (_gridIndex = 0; _gridIndex < this.chartData[this.chartID].grid.length; _gridIndex++) {
if (this.chartRef.containPixel({ gridIndex: _gridIndex }, [params.offsetX, params.offsetY])) {
this.position = 'left'
this.showModal = true
@@ -57,7 +57,6 @@
</template>
<script>
import { chartData } from '@/data/task/ChartsManagement'
import { taskInfo } from '@/data/task/TaskInfo'
import api from '@/data/api'
import { mapFields } from 'vuex-map-fields'
@@ -67,7 +66,7 @@ export default {
name: 'canvas-chart-filter-individual-filter',
props: {
chartID: {
type: Number,
type: [Number, String],
required: true,
},
seriesIndex: {
@@ -82,23 +81,23 @@ export default {
computed: {
...mapFields('taskContent', [
'filter',
'chartData',
]),
buttonIcon () {
if (this.data.series[this.seriesIndex] != null) {
return this.data.series[this.seriesIndex].filter[this.filterIndex].filter != null ? 'fa fa-stop' : 'fa fa-play'
if (this.chartData[this.chartID].series[this.seriesIndex] != null) {
return this.chartData[this.chartID].series[this.seriesIndex].filter[this.filterIndex].filter != null ? 'fa fa-stop' : 'fa fa-play'
}
return 'fa fa-play'
},
buttonColor () {
if (this.data.series[this.seriesIndex] != null) {
return this.data.series[this.seriesIndex].filter[this.filterIndex].filter != null ? 'danger' : 'primary'
if (this.chartData[this.chartID].series[this.seriesIndex] != null) {
return this.chartData[this.chartID].series[this.seriesIndex].filter[this.filterIndex].filter != null ? 'danger' : 'primary'
}
return 'fa fa-play'
},
},
data () {
return {
data: chartData.getAllChartsData()[this.chartID],
selectFilter: {
id: 1,
name: 'notch',
@@ -134,8 +133,8 @@ export default {
methods: {
async updateFilterInfo (_filterIndex, _seriesIndex) {
let closeFilter = false
if (this.data.series[_seriesIndex].filter[_filterIndex].filter != null) {
this.data.series[_seriesIndex].filter[_filterIndex].filter = null
if (this.chartData[this.chartID].series[_seriesIndex].filter[_filterIndex].filter != null) {
this.chartData[this.chartID].series[_seriesIndex].filter[_filterIndex].filter = null
closeFilter = true
}
if (closeFilter) {
@@ -143,7 +142,7 @@ export default {
}
let fs = 0
let sos = []
const deviceID = this.data.series[_seriesIndex].yAxisSource[0]
const deviceID = this.chartData[this.chartID].series[_seriesIndex].yAxisSource[0]
// const _fs = taskInfo.getDeviceInfo(deviceID).parameterSet.SAMPLE_RATE
const _fs = 1000
const _chNum = taskInfo.getDeviceInfo(deviceID).parameterSet.CH_NUMBER
@@ -175,22 +174,22 @@ export default {
})
sos = _sos
}
this.data.series[_seriesIndex].filter[_filterIndex].type = this.selectFilter.name
this.data.series[_seriesIndex].filter[_filterIndex].order = this.order
this.chartData[this.chartID].series[_seriesIndex].filter[_filterIndex].type = this.selectFilter.name
this.chartData[this.chartID].series[_seriesIndex].filter[_filterIndex].order = this.order
// sampling rate changed by channel number
this.data.series[_seriesIndex].filter[_filterIndex].fs = parseInt(_fs / _chNum)
this.data.series[_seriesIndex].filter[_filterIndex].f0 = parseInt(this.freq0)
this.data.series[_seriesIndex].filter[_filterIndex].f1 = parseInt(this.freq1)
this.data.series[_seriesIndex].filter[_filterIndex].f2 = parseInt(this.freq2)
this.data.series[_seriesIndex].filter[_filterIndex].sos = sos
this.data.series[_seriesIndex].filter[_filterIndex].filter = IIRFilter.init(sos)
this.chartData[this.chartID].series[_seriesIndex].filter[_filterIndex].fs = parseInt(_fs / _chNum)
this.chartData[this.chartID].series[_seriesIndex].filter[_filterIndex].f0 = parseInt(this.freq0)
this.chartData[this.chartID].series[_seriesIndex].filter[_filterIndex].f1 = parseInt(this.freq1)
this.chartData[this.chartID].series[_seriesIndex].filter[_filterIndex].f2 = parseInt(this.freq2)
this.chartData[this.chartID].series[_seriesIndex].filter[_filterIndex].sos = sos
this.chartData[this.chartID].series[_seriesIndex].filter[_filterIndex].filter = IIRFilter.init(sos)
},
},
mounted () {
this.selectFilter = this.optionFilter.find(item => item.name === this.data.series[this.seriesIndex].filter[this.filterIndex].type)
this.freq0 = this.data.series[this.seriesIndex].filter[this.filterIndex].f0
this.freq1 = this.data.series[this.seriesIndex].filter[this.filterIndex].f1
this.freq2 = this.data.series[this.seriesIndex].filter[this.filterIndex].f2
this.selectFilter = this.optionFilter.find(item => item.name === this.chartData[this.chartID].series[this.seriesIndex].filter[this.filterIndex].type)
this.freq0 = this.chartData[this.chartID].series[this.seriesIndex].filter[this.filterIndex].f0
this.freq1 = this.chartData[this.chartID].series[this.seriesIndex].filter[this.filterIndex].f1
this.freq2 = this.chartData[this.chartID].series[this.seriesIndex].filter[this.filterIndex].f2
},
}
</script>
@@ -0,0 +1,363 @@
<template>
<div>
<va-button v-if="integralClicked && (mode_name==='Chronoamperometric' || mode_name==='I-T Graph' || mode_name==='I-V Curve')" color="danger" class="mb-2" @click="clickIntegral" small>
To Raw Mode
</va-button>
<va-button :disabled="disableInt" v-if="!integralClicked && (mode_name==='Chronoamperometric' || mode_name==='I-T Graph' || mode_name==='I-V Curve')" color="primary" class="mb-2" @click="clickIntegral" small>
To Integral Mode
</va-button>
<va-button v-if="xlogClicked && (mode_name==='Linear Sweep Voltammetry' || mode_name==='I-V Curve')" color="danger" class="mb-2" @click="clickXLog" small>
To Raw Mode
</va-button>
<va-button :disabled="disableLog" v-if="!xlogClicked && (mode_name==='Linear Sweep Voltammetry' || mode_name==='I-V Curve')" color="primary" class="mb-2" @click="clickXLog" small>
To log Mode (x-axis)
</va-button>
<va-button v-if="ylogClicked && (mode_name==='Linear Sweep Voltammetry' || mode_name==='I-V Curve')" color="danger" class="mb-2" @click="clickYLog" small>
To Raw Mode
</va-button>
<va-button :disabled="disableLog" v-if="!ylogClicked && (mode_name==='Linear Sweep Voltammetry' || mode_name==='I-V Curve')" color="primary" class="mb-2" @click="clickYLog" small>
To log Mode (y-axis)
</va-button>
<va-button v-if="diffClicked && (mode_name==='Linear Sweep Voltammetry' || mode_name==='I-V Curve')" color="danger" class="mb-2" @click="clickDiff" small>
To Raw Mode
</va-button>
<va-button :disabled="disableDiff" v-if="!diffClicked && (mode_name==='Linear Sweep Voltammetry' || mode_name==='I-V Curve')" color="primary" class="mb-2" @click="clickDiff" small>
To Differential Mode
</va-button>
</div>
</template>
<script>
// import CanvasChartFilter from './CanvasChartFilter.vue'
// import CanvasChartFilterPopup from './CanvasChartFilterPopup.vue'
// import CanvasChartSource from './CanvasChartSource'
// import { taskInfo } from '../../../../data/task/TaskInfo'
import { mapFields } from 'vuex-map-fields'
import { mapActions } from 'vuex'
import taskTypes from '@/store/modules/task/content/types'
import paramTable from '@/data/config-table/index'
// import newTooltip from '@/factories/chart/tooltipFactory'
import { getTimeFormatter } from '@/store/modules/task/content/actions/chartAct'
export default {
name: 'CanvasChartRealTimeCalculation',
components: {
},
props: {
chartID: {
type: [Number, String],
required: true,
},
},
computed: {
...mapFields('', [
'developer_mode',
]),
...mapFields('taskContent', [
'chartData',
'taskContentChartKey',
'deviceListNew',
]),
},
data () {
return {
info: null,
paramTable: paramTable,
rawData: null,
mode_name: '',
xName: '',
yName: '',
obj: null,
integralClicked: false,
xlogClicked: false,
ylogClicked: false,
diffClicked: false,
disableDiff: false,
disableLog: false,
disableInt: false,
}
},
// watch rawData is use for detect whether the chartData is changed
watch: {
rawData: {
deep: true,
handler: function () {
// avoid getting null data
if (this.rawData.series.length > 0) {
this.watchHandler()
}
},
},
},
methods: {
// Do arithmetic operations triggered by button(raw, integral, log)
watchHandler: function () {
// this.data need to be deep copy from rawData, since we don't want to modify the source(chartData[])
// this.data = Object.assign({}, this.rawData)
this.data = JSON.parse(JSON.stringify(this.rawData))
this.addSource()
var curXData = 0
var curYData = 0
var prevXData = 0
var prevYData = 0
var deltaX = 0
var deltaTime = 0
var curTime = 0
var integralResult = 0
var diffResult = 0
var index = 0
var timeIndex = this.getTimeIndex()
var _data = []
const dataLength = this.data.series[0].data.length
const seriesData = this.data.series[0].data
if (this.integralClicked) {
for (index = 0; index < dataLength; index++) {
// console.log('x: ', seriesData[index][0])
// console.log('y: ', seriesData[index][1])
if (index === 0) {
// TODO: need to change the series[deviceID]
// TODO: change the time index(dynamic changing)
curYData = parseFloat(seriesData[index][1])
// deltaX = seriesData[index + 1][timeIndex] - seriesData[index][timeIndex]
curXData = parseFloat(seriesData[index][0])
curTime = seriesData[index][timeIndex]
if (this.mode_name === 'I-T Graph') {
_data.push([curTime, 0])
} else {
_data.push([curXData, 0, 0])
}
} else {
prevYData = parseFloat(seriesData[index - 1][1])
curYData = parseFloat(seriesData[index][1])
curXData = parseFloat(seriesData[index][0])
deltaX = seriesData[index][0] - seriesData[index - 1][0]
deltaTime = seriesData[index][timeIndex] - seriesData[index - 1][timeIndex]
integralResult += parseFloat((Math.abs(curYData) + Math.abs(prevYData)) * Math.abs(deltaX) / 2)
curTime += deltaTime
if (this.mode_name === 'I-T Graph') {
_data.push([curTime, integralResult])
} else {
_data.push([curXData, integralResult, curTime])
}
}
}
} else if (this.xlogClicked || this.ylogClicked) {
if (this.xlogClicked && this.ylogClicked) {
for (index = 0; index < dataLength; index++) {
if (index === 0) {
curXData = parseFloat(seriesData[index][0])
curYData = parseFloat(seriesData[index][1])
deltaX = seriesData[index + 1][timeIndex] - seriesData[index][timeIndex]
curTime = seriesData[index][timeIndex]
if (curXData !== 0 && curYData !== 0) {
_data.push([Math.log10(Math.abs(curXData)), Math.log10(Math.abs(curYData)), curTime])
}
} else {
curXData = parseFloat(seriesData[index][0])
curYData = parseFloat(seriesData[index][1])
curTime += deltaX
if (curXData !== 0 && curYData !== 0) {
_data.push([Math.log10(Math.abs(curXData)), Math.log10(Math.abs(curYData)), curTime])
}
}
}
} else if (this.xlogClicked && !(this.ylogClicked)) {
for (index = 0; index < dataLength; index++) {
if (index === 0) {
curXData = parseFloat(seriesData[index][0])
curYData = parseFloat(seriesData[index][1])
deltaX = seriesData[index + 1][timeIndex] - seriesData[index][timeIndex]
curTime = seriesData[index][timeIndex]
if (curXData !== 0) {
_data.push([Math.log10(Math.abs(curXData)), curYData, curTime])
}
} else {
curXData = parseFloat(seriesData[index][0])
curYData = parseFloat(seriesData[index][1])
curTime += deltaX
if (curXData !== 0) {
_data.push([Math.log10(Math.abs(curXData)), curYData, curTime])
}
}
}
} else if (!(this.xlogClicked) && this.ylogClicked) {
for (index = 0; index < dataLength; index++) {
if (index === 0) {
curXData = parseFloat(seriesData[index][0])
curYData = parseFloat(seriesData[index][1])
deltaX = seriesData[index + 1][timeIndex] - seriesData[index][timeIndex]
curTime = seriesData[index][timeIndex]
if (curYData !== 0) {
_data.push([curXData, Math.log10(Math.abs(curYData)), curTime])
}
} else {
curXData = parseFloat(seriesData[index][0])
curYData = parseFloat(seriesData[index][1])
curTime += deltaX
if (curYData !== 0) {
_data.push([curXData, Math.log10(Math.abs(curYData)), curTime])
}
}
}
}
} else if (this.diffClicked) {
for (index = 0; index < dataLength; index++) {
if (index === 0) {
// TODO: need to change the series[deviceID]
// TODO: change the time index(dynamic changing)
curXData = parseFloat(seriesData[index][0])
curYData = parseFloat(seriesData[index][1])
deltaX = seriesData[index + 1][timeIndex] - seriesData[index][timeIndex]
curTime = seriesData[index][timeIndex]
// _data.push([curTime, 0, curTime])
} else {
curXData = parseFloat(seriesData[index][0])
curYData = parseFloat(seriesData[index][1])
prevXData = parseFloat(seriesData[index - 1][0])
prevYData = parseFloat(seriesData[index - 1][1])
curTime += deltaX
diffResult = parseFloat((curYData - prevYData) / (curXData - prevXData))
_data.push([curXData, diffResult, curTime])
}
}
}
// console.log(this.data.dataZoom[1])
// decide feed in raw data / modified one
if (this.integralClicked || this.xlogClicked || this.ylogClicked || this.diffClicked) {
this.data.series[0].data = _data
// console.log(this.data.series[0].data[this.data.series[0].data.length - 1])
}
this.data.xAxis[0].type = 'value'
if (this.integralClicked) {
this.$emit('switchModeButton', 'Integral')
} else if (this.xlogClicked || this.ylogClicked) {
this.$emit('switchModeButton', 'log')
} else if (this.diffClicked) {
this.$emit('switchModeButton', 'Differential')
} else {
this.$emit('switchModeButton', '')
}
// TODO: modify the redundant code
if (this.xName === 'TIME') {
this.data.xAxis[0].axisLabel.formatter = function (val) {
return getTimeFormatter(val)
}
}
this.$emit('refreshData', this.data)
},
// resetClicked: function () {
// this.integralClicked = false
// this.xlogClicked = false
// this.ylogClicked = false
// this.diffClicked = false
// this.disableDiff = false
// this.disableLog = false
// },
clickIntegral: function () {
this.integralClicked = !(this.integralClicked)
this.disableDiff = !(this.disableDiff)
this.disableLog = !(this.disableLog)
const device = this.deviceListNew.find(ele => String(ele.memory_board) === String(this.data.mappingID))
if (device !== undefined) {
if (device.status === 0) {
this.watchHandler()
}
}
},
clickXLog: function () {
if (this.xlogClicked) {
this.xlogClicked = false
if (this.ylogClicked) {
this.disableDiff = true
this.disableInt = true
} else {
this.disableDiff = false
this.disableInt = false
}
} else {
this.xlogClicked = true
this.disableDiff = true
this.disableInt = true
}
const device = this.deviceListNew.find(ele => String(ele.memory_board) === String(this.data.mappingID))
if (device !== undefined) {
if (device.status === 0) {
this.watchHandler()
}
}
},
clickYLog: function () {
if (this.ylogClicked) {
this.ylogClicked = false
if (this.xlogClicked) {
this.disableDiff = true
this.disableInt = true
} else {
this.disableDiff = false
this.disableInt = false
}
} else {
this.ylogClicked = true
this.disableDiff = true
this.disableInt = true
}
const device = this.deviceListNew.find(ele => String(ele.memory_board) === String(this.data.mappingID))
if (device !== undefined) {
if (device.status === 0) {
this.watchHandler()
}
}
},
clickDiff: function () {
this.diffClicked = !(this.diffClicked)
this.disableLog = !(this.disableLog)
this.disableInt = !(this.disableInt)
const device = this.deviceListNew.find(ele => String(ele.memory_board) === String(this.data.mappingID))
if (device !== undefined) {
if (device.status === 0) {
this.watchHandler()
}
}
},
addSource () {
if (this.data.gridSource.length > 0) {
const xAxisName = this.data.gridSource[0][0].xAxis
const yAxisName = this.data.gridSource[0][0].yAxis
this.xName = (xAxisName.split(' ')).pop()
this.yName = (yAxisName.split(' ')).pop()
if ((this.xName === 'VOLTAGE' && this.yName === 'CURRENT') || (this.xName === 'CURRENT' && this.yName === 'VOLTAGE')) {
this.mode_name = 'I-V Curve' // integration
} else if (this.xName === 'TIME' && this.yName === 'CURRENT') {
this.mode_name = 'I-T Graph' // differential and log
}
}
},
// index 0 is for the mode which x-axis is represent time, 2 is for the other mode(s)
getTimeIndex: function () {
let xAxisName = this.rawData.gridSource[0][0].xAxis
xAxisName = (xAxisName.split(' ')).pop()
return (xAxisName === 'TIME') ? 0 : 2
},
// these function below are using for print out the data (debug)
getAlldata: function () {
return this.data.series[0].data[(this.data.series[0].data).length - 1]
},
getXdata: function () {
var value = this.data.series[0].data[(this.data.series[0].data).length - 1][0]
return this.xName + ': ' + value + ' ' + this.xUnit
},
getYdata: function () {
var value = this.data.series[0].data[(this.data.series[0].data).length - 1][1]
return this.yName + ': ' + value + ' ' + this.yUnit
},
...mapActions('taskContent', [
taskTypes.chart.saveToCache,
]),
},
async mounted () {
this.rawData = this.chartData[this.chartID]
},
}
</script>
@@ -0,0 +1,234 @@
<template>
<div>
<div v-for="(chart, chartIndex) in realTime" :key="'c'+chartIndex">
<div v-for="(grid, gridIndex) in chart" :key="'s'+gridIndex" class="row ma-0 pa-0">
<div class="col flex xs0 sm0 lg0 md0 xl0 xxl1"/>
<div class="col flex xs2 sm2 lg2 md2 xl2 xxl1" pa-0 ma-0>
<p color="primary" style="text-align: right;">{{ grid.name }}</p>
</div>
<!-- value (y-axis) -->
<div class="col flex sm2 xl2 md2 xs2">
<va-input
label="y-value"
disable="disable"
v-model="grid.yValue"
/>
</div>
<!-- unit (y-axis) -->
<div class="col flex sm2 xl2 md2 xs2">
<va-select
label="y-unit"
v-model="grid.yUnit"
:options="grid.yUnitOption"
noClear
/>
</div>
<div class="col flex sm1 xl1 md1 xs1"></div>
<!-- value (x-axis) -->
<div class="col flex sm2 xl2 md2 xs2">
<va-input
label="x-value"
disable="disable"
v-model="grid.xValue"
/>
</div>
<!-- unit (x-axis) -->
<div class="col flex sm2 xl2 md2 xs2">
<va-select
label="x-unit"
v-model="grid.xUnit"
:options="grid.xUnitOption"
noClear
/>
</div>
</div>
</div>
</div>
</template>
<script>
import { mapFields } from 'vuex-map-fields'
import configTable from '@/data/config-table/index.js'
import newTooltip from '@/factories/chart/tooltipFactory'
export default {
name: 'CanvasChartRealTimeDisplay',
props: {
chartID: {
type: [Number, String],
required: true,
},
},
computed: {
...mapFields('taskContent', [
'chartData',
'deviceListNew',
]),
},
data () {
return {
data: null,
configTable: configTable,
realTime: [[]],
functional: '',
}
},
methods: {
// record the latest data as the real time value
updateValue: function () {
if ((this.realTime.length === 0)) {
return
}
for (let gridIndex = 0; gridIndex < this.realTime.length; gridIndex++) {
for (let channelIndex = 0; channelIndex < this.realTime[gridIndex].length; channelIndex++) {
// miss the source of data -> try to find the source
if (this.realTime[gridIndex][channelIndex].seriesSource === -1) {
this.realTime[gridIndex][channelIndex].seriesSource = this.data.series.findIndex((ele) => ele.name === this.realTime[gridIndex][channelIndex].name)
}
// the device is active now --> update the real time value
if (this.data.series[this.realTime[gridIndex][channelIndex].seriesSource] !== undefined && this.data.series[this.realTime[gridIndex][channelIndex].seriesSource].data !== undefined && this.data.series[this.realTime[gridIndex][channelIndex].seriesSource].data.length > 0) {
this.realTime[gridIndex][channelIndex].xValue = this.data.series[this.realTime[gridIndex][channelIndex].seriesSource].data.at(-1)[0] / this.realTime[gridIndex][channelIndex].xValueScale[this.realTime[gridIndex][channelIndex].xUnit]
this.realTime[gridIndex][channelIndex].yValue = this.data.series[this.realTime[gridIndex][channelIndex].seriesSource].data.at(-1)[1] / this.realTime[gridIndex][channelIndex].yValueScale[this.realTime[gridIndex][channelIndex].yUnit]
}
}
}
},
// change the axis unit of charts
updateUnit: function (functional) {
for (let gridIndex = 0; gridIndex < this.realTime.length; gridIndex++) {
for (let channelIndex = 0; channelIndex < this.realTime[gridIndex].length; channelIndex++) {
if (channelIndex === 0) {
const _xUnit = this.realTime[gridIndex][channelIndex].xUnit
const _yUnit = this.realTime[gridIndex][channelIndex].yUnit
const _xScale = this.realTime[gridIndex][channelIndex].xValueScale[this.realTime[gridIndex][channelIndex].xUnit]
const _yScale = this.realTime[gridIndex][channelIndex].yValueScale[this.realTime[gridIndex][channelIndex].yUnit]
this.data.xAxis[gridIndex].axisLabel.formatter = function (val) {
return parseFloat(val / _xScale).toFixed(2) + _xUnit
}
this.data.yAxis[gridIndex].axisLabel.formatter = function (val) {
return parseFloat(val / _yScale).toFixed(2) + _yUnit
}
// update tooltip
this.data.tooltip.formatter = newTooltip(this.realTime, functional).formatter
}
}
}
},
// for user to choose wanted unit
setUnit: function (gridIndex, channelIndex) {
// find coressponding device for current chart
const device = this.deviceListNew.find(chart => {
return chart.memory_board === parseInt(this.chartData[this.chartID].mappingID)
})
if (!device) {
return
}
// construct realTime object, i.e., record the coressponding value and unit
// the formate imitates the data.gridSource
const modeTable = this.configTable.getModeConfig(device.library_name, device.configuration.MODE)
const _realTime = JSON.parse(JSON.stringify(this.realTime))
const _newChannel = {}
let xAxis = null
let yAxis = null
// find the the data of each axis coming from which channel
if (this.data.series.length > 0) {
_newChannel.name = this.data.gridSource[gridIndex][channelIndex].name
_newChannel.seriesSource = this.data.series.findIndex((ele) => ele.name === _newChannel.name)
xAxis = this.data.series[_newChannel.seriesSource].xAxisSource[1] - 1
yAxis = this.data.series[_newChannel.seriesSource].yAxisSource[1] - 1
xAxis = (xAxis === -2) ? 'time' : xAxis
yAxis = (yAxis === -2) ? 'time' : yAxis
}
// check if xAxis unit has been defined in modeTable
if (Object.prototype.hasOwnProperty.call(modeTable.channels, xAxis)) {
_newChannel.xUnit = modeTable.channels[xAxis].defaultUnit
_newChannel.xValueScale = modeTable.channels[xAxis].unit
_newChannel.xUnitOption = Object.keys(modeTable.channels[xAxis].unit)
} else {
_newChannel.xUnit = 'unvalid'
_newChannel.xValueScale = { unvalid: NaN }
_newChannel.xUnitOption = ['']
}
// check if yAxis unit has been defined in modeTable
if (Object.prototype.hasOwnProperty.call(modeTable.channels, yAxis)) {
_newChannel.yUnit = modeTable.channels[yAxis].defaultUnit
_newChannel.yValueScale = modeTable.channels[yAxis].unit
_newChannel.yUnitOption = Object.keys(modeTable.channels[yAxis].unit)
} else {
_newChannel.yUnit = 'unvalid'
_newChannel.yValueScale = { unvalid: NaN }
_newChannel.yUnitOption = ['']
}
// set real time value = 0 as default
_newChannel.xValue = 0
_newChannel.yValue = 0
// padding
while (gridIndex >= _realTime.length) {
_realTime.push([])
}
while (channelIndex >= _realTime[gridIndex].length) {
_realTime[gridIndex].push({})
}
// merge the additional part into original part
_realTime[gridIndex][channelIndex] = _newChannel
this.realTime = _realTime
},
// for each lines on the charts should have its own real time display
matchChart: function () {
for (let gridIndex = 0; gridIndex < this.data.gridSource.length; gridIndex++) {
if (this.data.gridSource[gridIndex] !== undefined) {
for (let channelIndex = 0; channelIndex < this.data.gridSource[gridIndex].length; channelIndex++) {
if (gridIndex >= this.realTime.length) {
this.setUnit(gridIndex, channelIndex)
} else if (channelIndex >= this.realTime[gridIndex].length) {
this.setUnit(gridIndex, channelIndex)
}
}
}
}
},
switchFunctional: function (newFunctional) {
this.functional = newFunctional
// console.log('functional: ', this.functional)
},
updateData: function (canvasChartData) {
this.data = canvasChartData
},
},
mounted () {
this.data = this.chartData[this.chartID]
// this.data = this.canvasChartData
},
watch: {
data: {
handler: function () {
this.updateValue()
this.matchChart()
},
deep: true,
},
realTime: {
handler: function () {
this.updateUnit(this.functional)
},
deep: true,
},
canvasChartData: {
handler: function () {
this.data = this.canvasChartData
console.log('HIHI', this.data)
},
deep: true,
},
},
}
</script>
@@ -2,10 +2,10 @@
<div>
<div class="row flex sm12 xl12 md12 xs12 align--center my-0 py-0">
<div class="flex sm9 xl9 md9 xs9 px-0 mx-0">
<p class="display-6">filter<p/>
<p class="display-6">filter</p>
</div>
<div class="flex sm3 xl3 md3 xs3 pa-0 ma-0">
<va-toggle v-model="data.filter.open" small @click.native="() => {}"/>
<va-toggle v-model="chartData[chartID].filter.open" small @click.native="() => {}"/>
</div>
<!-- <div class="flex sm12 xl12 md12 xs12 px-0 mx-0">
<p class="display-6">Protect recording channels<p/>
@@ -24,19 +24,23 @@
</template>
<script>
import { chartData } from '../../../../data/task/ChartsManagement'
import { mapFields } from 'vuex-map-fields'
export default {
name: 'canvas-chart-setting',
props: {
chartID: {
type: Number,
type: [Number, String],
required: true,
},
},
computed: {
...mapFields('taskContent', [
'chartData',
]),
},
data () {
return {
data: chartData.getAllChartsData()[this.chartID],
}
},
methods: {
@@ -45,7 +45,6 @@
v-model="gridSelection"
textBy="value"
:options="gridOptions"
@click.enter="updateGridOptions()"
/>
</div>
<va-button :disabled="sourceAddStatus" class="flex md3 xl3 xs3 sm3 pa-1" @click="addRegisterDeviceChannel(gridSelection.id)" >
@@ -56,11 +55,12 @@
<va-tree-root>
<va-tree-category
style="font-size: 20px;"
v-for="grid in grids"
v-for="grid in chartData[chartID].grid"
:key="grid.index"
:label="'Subplot ' + grid.index">
:label="'Subplot ' + grid.index"
>
<va-tree-node
v-for="series in gridSource[grid.index]"
v-for="series in chartData[chartID].gridSource[grid.index]"
:key="series.name"
>
<div class="flex row align--center">
@@ -86,20 +86,16 @@
</template>
<script>
// import { getChartsData } from '../../../../../data/task/ChartsManagement'
import { taskInfo } from '../../../../data/task/TaskInfo'
import { chartData } from '../../../../data/task/ChartsManagement'
import { mapFields } from 'vuex-map-fields'
import { mapActions } from 'vuex'
import taskTypes from '@/store/modules/task/content/types'
export default {
name: 'canvas-chart-source',
props: {
gridInfo: {
type: Array,
required: true,
},
chartID: {
type: Number,
type: [Number, String],
required: true,
},
},
@@ -107,14 +103,7 @@ export default {
return {
error: '',
gridSelection: '',
gridOptions: [
{
id: 0,
value: 0,
},
],
grids: this.gridInfo,
gridSource: chartData.getAllChartsData()[this.chartID].gridSource,
gridOptions: [],
channelSelectX: '',
channelOptionsX: [],
channelSelectY: '',
@@ -123,21 +112,38 @@ export default {
channelSelectDisableY: true,
deviceSelectX: '',
deviceSelectY: '',
deviceOptions: taskInfo.getDeviceList(),
// deviceOptions:,
sourceAddStatus: true,
sourceList: [],
}
},
computed: {
deviceOptions () {
const defaultArray = [{ id: -1, name: 'Time' }]
defaultArray.push(...this.deviceListNew.map(ele => {
return {
name: `[${ele.memory_board}] ${ele.name}`,
id: ele.memory_board,
}
}))
return defaultArray
},
...mapFields('taskContent', [
'chartData',
'deviceListNew',
]),
},
watch: {
deviceOptions: function (val) {
this.clearSelectOptions()
},
deviceSelectX: function () {
const channelOptions = []
const deviceInfo = this.deviceListNew.find(ele => ele.id === this.deviceSelectX.id)
// console.log(val)
if (taskInfo.getDeviceInfo(this.deviceSelectX.id) == null) {
if (deviceInfo == null) {
this.channelSelectDisableX = true
} else if (taskInfo.getDeviceInfo(this.deviceSelectX.id).info.library_name.indexOf('Neulive') >= 0) {
} else if (deviceInfo.library_name.includes('Neulive')) {
const channelSet = taskInfo.getDeviceInfo(this.deviceSelectX.id).parameterSet.RECORDING_CH.toString(2).split('').reverse()
channelSet.forEach((element, index) => {
if (parseInt(element) > 0) {
@@ -175,12 +181,12 @@ export default {
}
})
this.channelSelectDisableX = false
} else if (taskInfo.getDeviceInfo(this.deviceSelectX.id).info.library_name.indexOf('Elite') >= 0) {
} else if (deviceInfo.library_name.includes('Elite')) {
let channelSet
if (taskInfo.getDeviceInfo(this.deviceSelectX.id).info.library_name === 'EliteEIS' && taskInfo.getDeviceInfo(this.deviceSelectX.id).parameterSet.MODE === 0) {
if (deviceInfo.library_name === 'EliteEIS' && deviceInfo.configuration.MODE === 0) {
channelSet = ['Zimag_Raw', 'Zreal_Raw', 'Frequency', 'Cycle', 'Zimag', 'Zreal', 'Impedance', 'Phase', 'Current', 'Level gain']
} else {
channelSet = taskInfo.getDeviceInfo(this.deviceSelectX.id).parameterSet.CHANNEL_LABEL
channelSet = deviceInfo.configuration.CHANNEL_LABEL
}
// console.log(channelSet)
channelSet.forEach((element, index) => {
@@ -200,10 +206,11 @@ export default {
},
deviceSelectY: function () {
const channelOptions = []
const deviceInfo = this.deviceListNew.find(ele => ele.id === this.deviceSelectY.id)
// console.log(val)
if (taskInfo.getDeviceInfo(this.deviceSelectY.id) == null) {
if (deviceInfo == null) {
this.channelSelectDisableY = true
} else if (taskInfo.getDeviceInfo(this.deviceSelectY.id).info.library_name.indexOf('Neulive') >= 0) {
} else if (deviceInfo.library_name.indexOf('Neulive') >= 0) {
const channelSet = taskInfo.getDeviceInfo(this.deviceSelectY.id).parameterSet.RECORDING_CH.toString(2).split('').reverse()
// console.log(channelSet)
channelSet.forEach((element, index) => {
@@ -242,12 +249,12 @@ export default {
}
})
this.channelSelectDisableY = false
} else if (taskInfo.getDeviceInfo(this.deviceSelectY.id).info.library_name.indexOf('Elite') >= 0) {
} else if (deviceInfo.library_name.indexOf('Elite') >= 0) {
let channelSet
if (taskInfo.getDeviceInfo(this.deviceSelectY.id).info.library_name === 'EliteEIS' && taskInfo.getDeviceInfo(this.deviceSelectY.id).parameterSet.MODE === 0) {
if (deviceInfo.library_name === 'EliteEIS' && deviceInfo.configuration.MODE === 0) {
channelSet = ['Zimag_Raw', 'Zreal_Raw', 'Frequency', 'Cycle', 'Zimag', 'Zreal', 'Impedance', 'Phase', 'Current', 'Level gain']
} else {
channelSet = taskInfo.getDeviceInfo(this.deviceSelectY.id).parameterSet.CHANNEL_LABEL
channelSet = deviceInfo.configuration.CHANNEL_LABEL
}
// console.log(channelSet)
channelSet.forEach((element, index) => {
@@ -269,7 +276,7 @@ export default {
methods: {
updateGridOptions () {
this.gridOptions = []
for (let i = 0; i < this.grids.length; i++) {
for (let i = 0; i < this.chartData[this.chartID].grid.length; i++) {
this.gridOptions.push({
id: i,
value: String(i),
@@ -291,7 +298,9 @@ export default {
this.deviceSelectY = ''
this.gridSelection = ''
},
addRegisterDeviceChannel: function (gridIndex) {
async addRegisterDeviceChannel (gridIndex) {
const deviceXInfo = this.deviceListNew.find(ele => ele.id === this.deviceSelectX.id)
const deviceYInfo = this.deviceListNew.find(ele => ele.id === this.deviceSelectY.id)
let deviceNameX
let deviceNameY
const deviceIDX = this.deviceSelectX.id
@@ -301,7 +310,7 @@ export default {
if (this.deviceSelectX.name.indexOf('Neulive') >= 0) {
deviceNameX = 'Neulive'
} else if (this.deviceSelectX.name.indexOf('Elite') >= 0) {
if (taskInfo.getDeviceInfo(this.deviceSelectX.id).info.library_name === 'EliteEIS') {
if (deviceXInfo.library_name === 'EliteEIS') {
deviceNameX = 'EliteEIS'
} else {
deviceNameX = 'Elite'
@@ -312,7 +321,7 @@ export default {
if (this.deviceSelectY.name.indexOf('Neulive') >= 0) {
deviceNameY = 'Neulive'
} else if (this.deviceSelectY.name.indexOf('Elite') >= 0) {
if (taskInfo.getDeviceInfo(this.deviceSelectY.id).info.library_name === 'EliteEIS') {
if (deviceYInfo.library_name === 'EliteEIS') {
deviceNameY = 'EliteEIS'
} else {
deviceNameY = 'Elite'
@@ -320,9 +329,19 @@ export default {
} else if (this.deviceSelectY.name.indexOf('Time') >= 0) {
deviceNameY = 'Time'
}
chartData.register(this.chartID, gridIndex, deviceNameX, deviceIDX, channelX, deviceNameY, deviceIDY, channelY, null)
// console.log(this.chartID, gridIndex, deviceNameX, deviceIDX, channelX, deviceNameY, deviceIDY, channelY, null)
// console.log(this.deviceSelectX, this.channelSelectX, this.deviceSelectY, this.channelSelectY)
this.taskContentChartRegister({
chartID: this.chartID,
gridIndex: gridIndex,
deviceNameX: deviceNameX,
deviceIDX: deviceIDX,
channelX: channelX,
deviceNameY: deviceNameY,
deviceIDY: deviceIDY,
channelY: channelY,
formula: null,
})
console.log('deviceSelectX', this.deviceSelectX)
if (deviceNameX !== 'Time') {
this.sourceList.push([this.deviceSelectX.name, deviceIDX, channelX].toString())
}
@@ -331,19 +350,16 @@ export default {
}
this.sourceAddStatus = true
this.clearSelectOptions()
await this.taskContentChartSaveToCache()
this.$emit('addSource')
},
addGrid () {
chartData.updateGridList(this.chartID, chartData.getAllChartsData()[this.chartID].grid.length + 1)
this.grids = chartData.getAllChartsData()[this.chartID].grid
this.treeKey++
this.gridOptions = []
for (let i = 0; i < this.grids.length; i++) {
this.gridOptions.push({
id: i,
value: String(i),
})
}
// console.log(chartData.getAllChartsData()[this.chartID])
async addGrid () {
this.taskContentChartUpdateGridList({
chartID: this.chartID,
length: this.chartData[this.chartID].grid.length + 1,
})
this.updateGridOptions()
await this.taskContentChartSaveToCache()
},
checkSourceAddStatus () {
if (this.sourceList.indexOf([this.deviceSelectX.name, this.deviceSelectX.id, this.channelSelectX.id].toString()) >= 0) {
@@ -371,17 +387,18 @@ export default {
this.sourceAddStatus = true
}
},
addProduct () {
this.products.push({
id: Math.floor(Math.random() * 100000),
name: 'New product',
})
},
removeProduct (product) {
this.products = this.products.filter(productToFilter => productToFilter !== product)
},
mounted () {
},
...mapActions('taskContent', [
taskTypes.chart.register,
taskTypes.chart.updateGridList,
taskTypes.chart.saveToCache,
]),
},
mounted () {
this.updateGridOptions()
},
}
</script>
@@ -0,0 +1,168 @@
<template>
<div class="flex sm12 xl12 md12 xs12">
<va-modal
v-model="showDeleteModal"
size="small"
:title="'DELETE'"
:message="'The device will be deleted.'"
:okText=" $t('modal.confirm') "
:cancelText=" $t('modal.cancel') "
@ok="remove()"
/>
<va-accordion v-for="device in deviceList" :key="device.id">
<va-collapse class="mb-2" :isOpenDefault='true'>
<span slot="header" >
<va-item :key="device.id" class="pa-0 ma-0"
>
<va-item-section avatar class="ml-0">
<va-avatar style="border-radius: 0;">
<img :src="device.picture" :alt="device.name">
</va-avatar>
</va-item-section>
<va-item-section class="ml-3" caption>
<va-item-label>
{{ `[${device.memory_board}]` }} {{ device.name }}
</va-item-label>
<va-item-label caption>
{{ device.mac_address }}
</va-item-label>
</va-item-section>
</va-item>
<va-item class="pa-0 ma-0 mt-2">
<va-item-section class="ml-3">
<va-item-label>
<va-button @click.stop="start(device)" v-if="device.library_name.includes('Elite') && device.status !== 1" class="px-2 py-0 mr-0" color="success" small>START</va-button>
<va-button @click.stop="stop(device)" v-if="device.library_name.includes('Elite') && device.status === 1" class="px-2 py-0 mr-0" color="danger" small>STOP</va-button>
<va-button id="detectButton" @click.stop="detect(device)" v-if="device.library_name.includes('Elite')" color="primary" class="px-2 py-0 mr-0" small>DETECT</va-button>
</va-item-label>
</va-item-section>
</va-item>
</span>
<div slot="body">
<div>
<file-control-window :ref="'fcwindow_ref'" :device="device" class="pl-0 pr-0" />
</div>
<div>
<device-parameter-window :ref="'epwindow_ref'" :device="device" class="pl-0 pr-0" />
</div>
</div>
</va-collapse>
</va-accordion>
</div>
</template>
<script>
import DeviceParameterWindow from '../parameter/DeviceParameterWindow'
// import EliteParameterWindow from '../parameter/EliteParameterWindow'
// import NeuliveParameterWindow from '../parameter/NeuliveParameterWindow'
import FileControlWindow from '../meta/FileControlWindow'
import { mapActions } from 'vuex'
import types from '@/store/modules/task/content/types'
import { taskInfo } from '../../../../data/task/TaskInfo'
import api from '@/data/api'
// import CanvasChart from '../chart/CanvasChart'
export default {
name: 'TaskDeviceList',
components: {
DeviceParameterWindow,
// EliteParameterWindow,
// NeuliveParameterWindow,
FileControlWindow,
},
props: {
deviceList: {
type: Array,
required: true,
},
},
data () {
return {
showDeleteModal: false,
selectDevice: null,
deviceStopping: false,
}
},
computed: {
},
methods: {
mqttPub: function (topic, mes) {
this.$mqtt.publish(topic, mes)
},
start: async function (device) {
if (device.status === 0) {
await this.setArchiveSettings()
const isDPVMode = device.configuration.MODE === 15
if (isDPVMode) {
const e1 = parseInt((device.configuration.DPV_e_1 - 25000) / 5)
const e2 = parseInt((device.configuration.DPV_e_2 - 25000) / 5)
const eFinal = parseInt((device.configuration.DPV_e_final - 25000) / 5)
if (e1 >= e2 && !(e1 >= eFinal && eFinal >= e2)) {
this.pageToast('[Error] Please set E Final correctly.')
return false
} else if (e2 > e1 && !(e2 >= eFinal && eFinal >= e1)) {
this.pageToast('[Error] Please set E Final correctly.')
return false
}
}
device.status = 1
this.$emit('start', device)
this.pageToast('The device ' + device.name + ' has been started.')
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_instruction/0',
device: device.mac_address,
instruction: 'start',
}))
api.task.update({
device_config: taskInfo.getTaskInfo().deviceListNew,
})
// CanvasChart.methods.resetClicked()
}
},
stop: function (device) {
this.$emit('stop', device)
this.pageToast('The device ' + device.name + ' has been stopped.')
},
setArchiveSettings: async function () {
await this.$refs.fcwindow_ref[0].setArchiveSettings()
},
refresh: function () {
},
pageToast: function (mes) {
this.showToast(
mes,
{
icon: 'fa-bell',
position: 'bottom-right',
duration: 4000,
},
)
},
detect: function (device) {
this.$emit('detect', device)
this.pageToast('The device ' + device.name + ' has been detect.')
},
recoverDetectButton () {
document.getElementById('detectButton').className += ' no-dark-style-va-button'
},
...mapActions('taskContent', [types.param.checkIfRecordingSetDone, types.param.checkIfStimulationSetDone, types.param.checkIfDeviceSetDone]),
},
destroyed () {
},
}
</script>
<style lang="scss">
.no-dark-style-va-button {
&:focus {
filter: brightness(100%);
}
}
</style>
@@ -29,22 +29,6 @@
@detect="detectDevice($event)"
@sd_card_status="sdCardStatus($event)"
/>
<!-- <div class="row flex xs12 md12 xl12 sm12 mt-2" style="text-align: center;">
<div class="xs10 md10 xl10 sm10">
<va-select
small
v-model="deviceSelect"
textBy="name"
:options="deviceOptions"
/>
</div>
<div>
<va-button class="ma-0" color="primary" target="_blank" @click="addDevice(deviceSelect.id)" :disabled="deviceSelect.id == null">
REGISTER
</va-button>
</div>
</div> -->
</div>
</va-card>
@@ -56,10 +40,11 @@ import { FulfillingBouncingCircleSpinner } from 'epic-spinners'
import TaskDeviceList from './TaskDeviceList'
// import TaskDeviceListGM from './neulive-gimer/TaskDeviceListGM'
import { taskInfo } from '../../../../data/task/TaskInfo'
import { chartData } from '../../../../data/task/ChartsManagement'
import { dataStreamBuffer } from '../../../../data/task/DataStreamBuffer'
import api from '@/data/api'
import { mapFields } from 'vuex-map-fields'
import { mapActions } from 'vuex'
import taskTypes from '@/store/modules/task/content/types'
export default {
name: 'TaskDevices',
@@ -108,17 +93,9 @@ export default {
},
loadingDone: async function () {
this.state.LOADING = false
// const ret = await api.task.getAll()
// if (ret.data.length > 0) {
// for (const device in ret.data[0].device_config) {
// if (ret.data[0].device_config[device].device_address) {
// }
// }
// }
// // console.log(this.deviceOptions)
for (let i = 0; i <= 11; i++) {
if (taskInfo.getDeviceInfoByRawID(i).info.status === 'connected') {
for (let i = 0; i <= 11; i++) { // 0~7: memboard, 8~11: usb
if (taskInfo.getDeviceInfoByRawID(i).info.device_status >= 0) {
const index = this.deviceList.findIndex(d => taskInfo.getRawDeviceID(d.id) === i)
if (index < 0) {
await this.addDevice(i)
@@ -137,19 +114,16 @@ export default {
name: 'Time',
})
taskInfo.getDeviceList().push(...this.deviceList)
// // console.log(taskInfo.getDeviceList())
// for (let i = this.deviceOptions.length - 1; i >= 0; i--) {
// this.deviceSelect = this.deviceOptions[i]
// await this.addDevice(this.deviceOptions[i].id)
// // this.sleep(500).then(() => {
// // this.addDevice(this.deviceOptions[i].id)
// // })
// }
},
startDevice: async function (device) {
if (!taskInfo.getDeviceInfo(device.id).info.isSync) {
if (taskInfo.getDeviceInfo(device.id).info.library_name.startsWith('Neulive')) {
await chartData.defaultChartGenerator(this.deviceList, device.id, null, 'device')
await this.taskContentChartDefaultChartGenerator({
_deviceList: this.deviceList,
_itemID: device.id,
_chartID: null,
_type: 'device',
})
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_instruction/0',
device: taskInfo.getRawDeviceID(device.id),
@@ -184,7 +158,12 @@ export default {
}
}
await chartData.defaultChartGenerator(this.deviceList, device.id, null, 'device')
await this.taskContentChartDefaultChartGenerator({
_deviceList: this.deviceList,
_itemID: device.id,
_chartID: null,
_type: 'device',
})
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_instruction/0',
device: taskInfo.getRawDeviceID(device.id),
@@ -193,6 +172,8 @@ export default {
}
// device.stopping = false
device.isSync = true
device.device_status = 1
taskInfo.getDeviceInfo(device.id).info.device_status = 1
this.$emit('refreshSetting')
// ### show device info
api.task.update({
@@ -230,6 +211,8 @@ export default {
}))
}
// device.stopping = true
device.device_status = 0
taskInfo.getDeviceInfo(device.id).info.device_status = 0
}
},
detectDevice: function (device) {
@@ -252,7 +235,12 @@ export default {
this.pageToast('[Recording] Please select recording channels.')
return false
}
await chartData.defaultChartGenerator(this.deviceList, device.id, null, 'device')
await this.taskContentChartDefaultChartGenerator({
_deviceList: this.deviceList,
_itemID: device.id,
_chartID: null,
_type: 'device',
})
if (!taskInfo.getDeviceInfo(device.id).info.isSync) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_instruction/0',
@@ -444,17 +432,10 @@ export default {
},
)
},
},
async mounted () {
// this.pageMqttSub()
// for (const device in this.deviceOptions) {
// this.deviceSelect = this.deviceOptions[device]
// await this.addDevice()
// }
},
destroyed () {
// this.loadingDone()
// this.pageMqttUnSub()
...mapActions('taskContent', [
taskTypes.chart.defaultChartGenerator,
]),
},
watch: {
},
@@ -0,0 +1,157 @@
<template>
<div class="flex" :class="cardclass">
<va-card>
<template slot="header">
<va-icon name="fa fa-bluetooth-b mr-3" color="primary"/>
<h5 class="mt-0 mb-0">DEVICES</h5>
</template>
<div v-if="state.LOADING" class="flex-center spinner-box mt-4 mb-5">
<fulfilling-bouncing-circle-spinner
:animation-duration="3000"
:color="this.$themes.primary"
:size="60"
>
</fulfilling-bouncing-circle-spinner>
</div>
<div v-else class="flex row align--center">
<task-device-list-new
:ref="'pdlist_ref'"
:deviceList="deviceListNew"
@start="startDevice($event)"
@stop="stopDevice($event)"
@detect="detectDevice($event)"
/>
</div>
</va-card>
</div>
</template>
<script>
import { FulfillingBouncingCircleSpinner } from 'epic-spinners'
import TaskDeviceListNew from './TaskDeviceListNew'
import { taskInfo } from '../../../../data/task/TaskInfo'
import { dataStreamBuffer } from '../../../../data/task/DataStreamBuffer'
import { mapFields } from 'vuex-map-fields'
import { mapActions } from 'vuex'
import taskTypes from '@/store/modules/task/content/types'
import eliteImgUrl from '@/assets/img/elite_img.png'
export default {
name: 'TaskDevices',
components: {
FulfillingBouncingCircleSpinner,
TaskDeviceListNew,
},
props: {
cardclass: {
type: Array,
default: function () {
return ['xs12', 'md12', 'xl12', 'sm12']
},
},
},
computed: {
...mapFields('taskContent', [
'deviceList',
'deviceListNew',
]),
},
created () {
},
data () {
return {
deviceSelect: '',
deviceOptions: taskInfo.getDeviceListNotRegister(),
state: {
LOADING: false,
},
stiTimeOut: null,
}
},
mqtt: {
},
methods: {
sleep: async function (time) {
return new Promise((resolve) => setTimeout(resolve, time))
},
mqttPub: function (topic, mes) {
this.$mqtt.publish(topic, mes)
},
loadingStart: async function () {
this.state.LOADING = true
},
loadingDone: async function () {
this.state.LOADING = false
this.createDeviceList()
},
createDeviceList: async function () {
this.deviceListNew = this.deviceListNew.map(ele => {
// ele.id = ele.mac_address
return ele
})
this.deviceListNew.map((ele) => {
ele.picture = eliteImgUrl
})
for (const device of this.deviceListNew) {
this.$emit('add', device.memory_board)
}
},
startDevice: async function (device) {
this.$emit('refreshSetting', device)
},
stopDevice: async function (device) {
await dataStreamBuffer.removeByDevice(device.memory_board)
if (device.library_name.includes('Elite')) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_instruction/0',
device: device.mac_address,
instruction: 'interrupt',
}))
}
device.status = 0
},
detectDevice: function (device) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_instruction/0',
device: device.mac_address,
instruction: 'VIS_DEVICE_DETECT',
}))
setTimeout(() => {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_instruction/0',
device: device.mac_address,
instruction: 'VIS_DEVICE_DONE',
}))
this.$refs.pdlist_ref.recoverDetectButton()
}, 5000)
},
generateChart: function (device) {
this.$emit('add', device.id)
},
setArchiveSettings: function () {
if (this.$refs.pdlist_ref != null) {
this.$refs.pdlist_ref.setArchiveSettings()
}
},
refresh: function () {
},
pageToast: function (mes) {
this.showToast(
mes,
{
icon: 'fa-bell',
position: 'bottom-right',
duration: 4000,
},
)
},
...mapActions('taskContent', [
taskTypes.chart.defaultChartGenerator,
]),
},
watch: {
},
}
</script>
@@ -36,12 +36,11 @@ import { FulfillingBouncingCircleSpinner } from 'epic-spinners'
// import TaskDeviceList from './TaskDeviceList'
import TaskDeviceListGM from './TaskDeviceListGM'
import { taskInfo } from '@/data/task/TaskInfo'
import { chartData } from '@/data/task/ChartsManagement'
import { dataStreamBuffer } from '@/data/task/DataStreamBuffer'
import api from '@/data/api'
import { mapActions } from 'vuex'
import { mapFields } from 'vuex-map-fields'
import types from '@/store/modules/task/content/types'
import taskTypes from '@/store/modules/task/content/types'
export default {
name: 'TaskDevices',
@@ -92,7 +91,7 @@ export default {
this.state.LOADING = false
// console.log(this.deviceOptions)
for (let i = 0; i <= 11; i++) {
if (taskInfo.getDeviceInfoByRawID(i).info.status === 'connected') {
if (taskInfo.getDeviceInfoByRawID(i).iinfo.device_status >= 0) {
const index = this.deviceList.findIndex(d => taskInfo.getRawDeviceID(d.id) === i)
if (index < 0) {
await this.addDevice(i)
@@ -111,14 +110,6 @@ export default {
name: 'Time',
})
taskInfo.getDeviceList().push(...this.deviceList)
// console.log('ppp', taskInfo.getDeviceList(), this.deviceList)
// for (let i = this.deviceOptions.length - 1; i >= 0; i--) {
// this.deviceSelect = this.deviceOptions[i]
// await this.addDevice(this.deviceOptions[i].id)
// // this.sleep(500).then(() => {
// // this.addDevice(this.deviceOptions[i].id)
// // })
// }
},
detectDevice: function (device) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
@@ -154,7 +145,12 @@ export default {
this.pageToast('[Recording] Please select recording channels.')
return false
}
await chartData.defaultChartGenerator(this.deviceList, device.id, null, 'device')
await this.taskContentChartDefaultChartGenerator({
_deviceList: this.deviceList,
_itemID: device.id,
_chartID: null,
_type: 'device',
})
this.deviceList.forEach(_device => {
if (_device.library_name === 'Neulive3.5-STI') {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
@@ -375,19 +371,15 @@ export default {
},
)
},
...mapActions('taskContent', [types.gimer.checkDeviceStatus]),
...mapActions('taskContent', [
taskTypes.gimer.checkDeviceStatus,
taskTypes.chart.defaultChartGenerator,
]),
},
async mounted () {
// console.log('sss', taskInfo.getDeviceList(), this.deviceList)
// this.pageMqttSub()
// for (const device in this.deviceOptions) {
// this.deviceSelect = this.deviceOptions[device]
// await this.addDevice()
// }
},
destroyed () {
// this.loadingDone()
// this.pageMqttUnSub()
},
watch: {
},
@@ -104,7 +104,8 @@
<script>
import { taskInfo } from '../../../../data/task/TaskInfo'
import { chartData } from '../../../../data/task/ChartsManagement'
import { mapActions } from 'vuex'
import taskTypes from '@/store/modules/task/content/types'
export default {
name: 'TaskFormula',
@@ -173,11 +174,16 @@ export default {
this.formulaNumber--
this.$emit('remove', this.formulaRemoveSelect.id)
},
generate: function (formula) {
generate: async function (formula) {
switch (formula.type) {
case 'Sheet Resistance':
formula.dataNow = 0
chartData.defaultChartGenerator(this.deviceList, formula.id, null, 'formula')
await this.taskContentChartDefaultChartGenerator({
_deviceList: this.deviceList,
_itemID: formula.id,
_chartID: null,
_type: 'formula',
})
break
}
this.pageToast('The ' + formula.name + 'has been applied.')
@@ -192,6 +198,10 @@ export default {
},
)
},
...mapActions('taskContent', [
taskTypes.chart.defaultChartGenerator,
]),
},
mounted () {
// this.pageMqttSub()
@@ -12,8 +12,7 @@
</div>
<div class="flex sm6 xl6 md6 xs6">
<va-input
@mouseup.native="fileNameChange(fileNameInput)"
@mouseleave.native="fileNameChange(fileNameInput)"
@blur="fileNameChange(fileNameInput)"
@touchend.native="fileNameChange(fileNameInput)"
@keyup.enter="fileNameChange(fileNameInput)"
v-model="fileNameInput"
@@ -35,8 +34,8 @@ export default {
components: {
},
props: {
deviceID: {
type: Number,
device: {
type: Object,
required: true,
},
deviceName: {
@@ -62,122 +61,92 @@ export default {
},
methods: {
fileNameChange: async function (name) {
if (this.enableSetting) {
if (this.deviceInfo.info.isSync === false) {
let fileNameCount = await api.meta.getByName(name)
if (fileNameCount.data != null) {
let duplicateCount = 1
let fileName = name
while (fileNameCount.data.length !== 0) {
const res = name.split('(')[0]
fileName = `${res}(${duplicateCount})`
fileNameCount = await api.meta.getByName(fileName)
duplicateCount += 1
}
this.fileNameInput = fileName
if (this.device.status === 0) {
if (name === '') {
name = this.getCurrentTime()
}
if (fileName !== this.deviceInfo.info.recording_file_name) {
this.deviceInfo.info.recording_file_name = fileName
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_recording_file_name/0',
device: taskInfo.getRawDeviceID(this.deviceID),
content: fileName,
}))
}
let fileNameCount = await api.meta.getByName(name)
if (fileNameCount.status === 200) {
let duplicateCount = 1
let fileName = name
while (fileNameCount.data.length > 0) {
const res = name.split('(')[0]
fileName = `${res}(${duplicateCount})`
fileNameCount = await api.meta.getByName(fileName)
duplicateCount += 1
}
this.fileNameInput = fileName
if (fileName !== this.device.recording_file_name) {
this.device.recording_file_name = fileName
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_recording_file_name/0',
device: this.device.mac_address,
content: fileName,
}))
}
}
}
},
directorySelect: function (directoryInfo) {
if (this.enableSetting) {
if (typeof directoryInfo === 'object') {
if (this.deviceInfo.info.parent.folder === undefined || this.deviceInfo.info.parent.folder.indexOf(directoryInfo.id) === -1) {
if (this.deviceInfo.info.isSync === false) {
this.deviceInfo.info.parent.folder = []
this.deviceInfo.info.parent.folder.push(directoryInfo.id)
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parent/0',
device: taskInfo.getRawDeviceID(this.deviceID),
content: {
folder: [directoryInfo.id],
},
}))
}
if (typeof directoryInfo === 'object') {
if (this.device.parent.folder === undefined || this.device.parent.folder.indexOf(directoryInfo.id) === -1) {
if (this.device.status === 0) {
this.device.parent.folder = []
this.device.parent.folder.push(directoryInfo.id)
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parent/0',
device: this.device.mac_address,
content: {
folder: [directoryInfo.id],
},
}))
}
}
}
},
enableChangeFile: function () {
this.enableSetting = true
this.setArchiveSettings()
},
setArchiveSettings: async function () {
if (this.enableSetting) {
if (this.deviceInfo === null) {
this.deviceInfo = taskInfo.getDeviceInfo(this.deviceID)
}
const now = this.getCurrentTime()
// filename init
if (this.deviceInfo.info.isSync) {
this.fileNameInput = this.deviceInfo.info.recording_file_name
const now = this.getCurrentTime()
// filename init
if (this.device.status === 1) {
this.fileNameInput = this.device.recording_file_name
} else {
if (this.device.recording_file_name === 'recording_data' || this.device.recording_file_name.split('-').length === 7) {
this.fileNameInput = now
} else {
if (this.deviceInfo.info.recording_file_name === 'recording_data' || this.deviceInfo.info.recording_file_name.split('-').length === 7) {
this.fileNameInput = now
} else {
this.fileNameInput = this.deviceInfo.info.recording_file_name
}
this.fileNameInput = this.device.recording_file_name
}
}
await this.fileNameChange(this.fileNameInput)
this.fileNameChange(this.fileNameInput)
// directory init
const collection = await api.collection.getAll()
this.directoryOptions = collection.data.filter(el => el.name !== 'root')
// directory init
const collection = await api.collection.getAll()
this.directoryOptions = collection.data.filter(el => el.name !== 'root')
if (Object.keys(this.deviceInfo.info.parent).length === 0) {
this.directory = this.directoryOptions[0]
} else {
for (const directory of this.directoryOptions) {
if (this.deviceInfo.info.parent.folder.includes(directory.id)) {
this.directory = directory
}
if (Object.keys(this.device.parent).length === 0) {
this.directory = this.directoryOptions[0]
} else {
for (const directory of this.directoryOptions) {
if (this.device.parent.folder.includes(directory.id)) {
this.directory = directory
}
}
}
},
getCurrentTime: function () {
const now = new Date()
return [now.getFullYear(), now.getMonth() + 1, now.getDate(), now.getHours(), now.getMinutes(), now.getSeconds(), this.deviceID].join('-')
return [now.getFullYear(), now.getMonth() + 1, now.getDate(), now.getHours(), now.getMinutes(), now.getSeconds(), this.device.memory_board].join('-')
},
mqttPub: function (topic, mes) {
this.$mqtt.publish(topic, mes)
},
pageInit: async function () {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'get_device_info/0',
device: taskInfo.getRawDeviceID(this.deviceID),
}))
},
refresh: function () {
this.$nextTick(() => {
this.setArchiveSettings()
})
},
},
mounted () {
this.pageInit()
this.enableTimer = setTimeout(this.enableChangeFile, 1000)
this.setArchiveSettings()
},
destroyed () {
clearTimeout(this.enableTimer)
},
watch: {
deviceID: function (val) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'get_device_info/0',
device: taskInfo.getRawDeviceID(val),
}))
},
},
}
</script>
@@ -0,0 +1,315 @@
<template>
<div class="flex px-0 mx-0 my-0 py-0">
<va-tree-root class="flex sm12 xl12 md12 xs12 px-0 mx-0 my-0 py-0">
<div class="flex sm12 xl12 md12 xs12 px-0 mx-0 my-0 py-0">
<div class="flex row">
<!-- Select Working Mode -->
<div class="flex sm10 xl10 md10 xs10 px-0 mx-0 my-0 py-0">
<va-select
@input="workingModeSelectChange(workingModeSelect)"
:label="'WORKING MODE'"
v-model="workingModeSelect"
textBy="description"
:options="workingModeOptions"
noClear
style="min-width: 50px;"
/>
</div>
<div class="flex sm2 xl2 md2 xs2 px-0 mx-0 my-0 py-0 pl-2">
<va-button class="pa-0 ma-0 mt-2 circle-button" small color="dark" @click="showModal=true">
<va-icon
name="fa fa-info"
color="white"
/>
</va-button>
</div>
</div>
</div>
<!-- split because of styling problem(treenode), combine together furture -->
<!-- EIS -->
<div v-if="library.includes('EIS')">
<component
v-for="name in parameterArrayInMode"
:key="name"
:is="parameterTable[name].componentType"
:templateType=1
:withHeader="true"
:parameterName="name"
:inputValue="parameter[name]"
:disable="name === 'CTRL_HIGH_Z_15' && device && device.status === 0"
v-bind="parameterTable[name]"
@parameterChange="parameterChange"
@getParameter="getParameter"
@sendInstruction="sendInstruction"
/>
</div>
<!-- ZM15-PulseSensingMode -->
<div v-else-if="parameter.MODE === 14">
<EliteParameterRecordingElitePulseSensing
:parameter="parameter"
:device="device"
:parameterTable="parameterTable"
@parameterChange="parameterChange"
@getParameter="getParameter"
@sendInstruction="sendInstruction"
/>
</div>
<!-- ZM15-DPVMode -->
<div v-else-if="parameter.MODE === 15">
<EliteParameterRecordingEliteDPV
:parameter="parameter"
:device="device"
:parameterTable="parameterTable"
@parameterChange="parameterChange"
@getParameter="getParameter"
@sendInstruction="sendInstruction"
/>
</div>
<!-- ZM15-OtherModes -->
<div v-else>
<va-tree-category
v-for="name in parameterArrayInMode"
:key="name"
:label="`${typeof parameterTable[name].showName === 'function'
? parameterTable[name].showName(modeSelection)
: parameterTable[name].showName} ${parameterValue(name)}`"
style="font-size: 20px;"
>
<va-tree-node>
<component
:is="parameterTable[name].componentType"
:parameterName="name"
:inputValue="parameter[name]"
:disable="name === 'CTRL_HIGH_Z_15' && device && device.status === 0"
v-bind="parameterTable[name]"
@parameterChange="parameterChange"
@getParameter="getParameter"
@sendInstruction="sendInstruction"
/>
</va-tree-node>
</va-tree-category>
</div>
</va-tree-root>
<!-- guide picture button -->
<div>
<vue-final-modal
v-if="library.includes('ZM15')"
v-model="showModal"
classes="modal-container"
content-class="modal-content"
:hide-overlay="true"
:click-to-close="true"
:esc-to-close="true"
:drag="true"
:resize="true"
:resize-directions="['tr', 'br', 'bl', 'tl']"
>
<!-- <va-icon class='fa fa-close modal__close' @click="showModal=false"></va-icon>
<span class="modal__title"></span> -->
<div class="modal__content">
<img :src="require('@/assets/img/elite-wire/' + getImageUrl + '.svg')" class="modal_img" alt="No Pic" draggable="false" >
<!-- <img :src="`${pat}`" class="imgaa" alt="No Pic" draggable="false"> -->
</div>
</vue-final-modal>
</div>
</div>
</template>
<script>
import InputRange from '../parameter/itemNew/InputRange'
import InputButtonToggle from '../parameter/itemNew/InputButtonToggle'
import InputField from '../parameter/itemNew/InputField'
import MultiInputField from '../parameter/itemNew/MultiInputField'
import EliteParameterRecordingEliteDPV from '../parameter/itemNew/DPVNew/EliteParameterRecordingEliteDPV'
import DevMode from '../parameter/itemNew/DevMode'
import EliteParameterRecordingElitePulseSensing from '../parameter/itemNew/PulseSensingNew/EliteParameterRecordingElitePulseSensing'
import { VueFinalModal } from 'vue-final-modal'
import { mapFields } from 'vuex-map-fields'
import configTable from '@/data/config-table/index'
export default {
name: 'EliteParameterRecordingElitezm15',
components: {
/* eslint-disable vue/no-unused-components */
EliteParameterRecordingElitePulseSensing,
EliteParameterRecordingEliteDPV,
VueFinalModal,
InputRange,
InputButtonToggle,
InputField,
MultiInputField,
DevMode,
},
props: {
parameter: {
type: Object,
required: true,
},
library: {
type: String,
},
serialNumber: {
type: String,
},
device: {
type: Object,
default: null,
},
},
computed: {
parameterTable () {
if (this.library !== undefined) {
const config = configTable.getConfig(this.library)
if (config !== undefined) {
return config
}
}
if (this.serialNumber !== undefined) {
const config = configTable.getConfig(this.serialNumber)
if (config !== undefined) {
return config
}
}
return null
},
parameterArrayInMode () {
return this.workingModeSelect && this.parameterTable.MODE[this.workingModeSelect.id].parameter
},
modeSelection () {
if (this.parameter.MODE) {
return this.parameter.MODE
}
return this.workingModeSelect.id
},
getImageUrl () {
if (this.workingModeSelect === null) {
return 'IV-Wire'
} else {
return this.workingModeSelect.img_src
}
},
deviceStatus () {
if (this.device === null) {
return false
} else {
return this.device.status === 0
}
},
...mapFields('', [
'developer_mode',
]),
...mapFields('taskContent', [
'deviceListNew',
]),
},
created () {
},
data () {
return {
showModal: false,
workingModeSelect: null,
workingModeOptions: [],
}
},
mqtt: {
},
methods: {
mqttPub: function (topic, mes) {
this.$mqtt.publish(topic, mes)
},
parameterValue (name) {
const value = this.parameter[name]
if (this.parameterTable[name].type === 'number') {
const scale = this.parameterTable[name].unit[this.parameterTable[name].defaultUnit]
return ` ( ${this.parameterTable[name].outputReadabilityData(value, scale)} ${this.parameterTable[name].defaultUnit} )`
} else if (this.parameterTable[name].type === 'array') {
return ` ( ${this.parameterTable[name].outputReadabilityData(value)} )`
} else if (this.parameterTable[name].type === 'none') {
return ''
}
},
parameterChange: function (name, value, debounce = false) {
/** if parameter is equal to value, then don't change, JSON.stringify is for array & object compare */
if (JSON.stringify(value) !== JSON.stringify(this.parameter[name])) {
this.parameter[name] = value
debounce === false
? this.$emit('setParameter', name, value)
: this.$emit('setParameterWithDebounce', name, value)
}
},
refresh () {
},
workingModeSelectChange (val) {
this.workingModeSelect = val
console.log('workingModeSelectChange', this.workingModeSelect.id, this.parameter.MODE)
if (this.workingModeSelect.id !== this.parameter.MODE) {
this.parameterChange('MODE', this.workingModeSelect.id)
// if device is idle, then setting highz when mode switch
if (this.deviceStatus === true && this.workingModeSelect.highz !== undefined) {
this.parameterChange('CTRL_HIGH_Z_15', this.workingModeSelect.highz)
}
}
},
getParameter: function (name) {
this.$emit('getParameter', name)
},
sendInstruction: function (instr) {
this.$emit('sendInstruction', instr)
},
},
mounted () {
// dev mode
// this.developer_mode === true
// ? this.workingModeOptions = this.workingModeDevOptions
// : this.workingModeOptions = this.workingModeNoDevOptions
this.workingModeOptions = this.parameterTable.MODE_OPTIONS
// init mode
this.workingModeSelect = (this.parameter.MODE !== undefined) ? this.workingModeOptions.find(ele => ele.id === this.parameter.MODE) : this.workingModeOptions[0]
},
watch: {
},
destroyed () {
},
}
</script>
<style lang="scss">
.modal-container {
display: flex;
justify-content: center;
align-items: center;
}
.modal-content {
display: flex;
flex-direction: column;
margin: 0 1rem;
padding: 1rem;
border: 1px solid #e2e8f0;
border-radius: 0.5rem;
background: #ffffff;
}
.modal__title {
font-size: 1.5rem;
font-weight: 700;
}
.modal__content {
flex-grow: 1;
overflow-y: auto;
}
.modal_img {
max-width: 100%;
max-height: 640px;
}
.modal__close {
position: absolute;
top: 0.5rem;
right: 0.5rem;
}
</style>
@@ -0,0 +1,78 @@
<template>
<div v-if="device">
<device-parameter-recording
:parameter="device.configuration"
:library="device.library_name"
:serialNumber="device.serial_number"
:device="device"
@sendInstruction="sendInstruction"
@getParameter="getParameter"
@setParameter="setParameter"
@setParameterWithDebounce="setParameterWithDebounce"
/>
</div>
</template>
<script>
import DeviceParameterRecording from './DeviceParameterRecording'
import { taskInfo } from '../../../../data/task/TaskInfo'
import _ from 'lodash'
export default {
name: 'EliteParameterWindow',
components: {
DeviceParameterRecording,
},
props: {
device: {
type: Object,
},
},
data () {
return {
}
},
mqtt: {
},
methods: {
mqttPublish: function (topic, mes) {
this.$mqtt.publish(topic, mes)
},
sendInstruction: function (instruction) {
this.mqttPublish(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_instruction/0',
device: this.device.mac_address,
instruction: instruction,
}))
},
getParameter: function (parameterName) {
this.mqttPublish(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter_value/0',
device: this.device.mac_address,
parameter: parameterName,
}))
},
setParameter: function (parameterName, parameterValue) {
this.mqttPublish(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: this.device.mac_address,
parameter: parameterName,
content: parameterValue,
}))
},
setParameterWithDebounce: _.debounce(function (parameterName, parameterValue) {
this.mqttPublish(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: this.device.mac_address,
parameter: parameterName,
content: parameterValue,
}))
}, 100),
},
mounted () {
},
watch: {
},
}
</script>
File diff suppressed because it is too large Load Diff
@@ -1,32 +1,53 @@
<template>
<div>
<elite-parameter-recording v-if="eliteVer=='1'" :ref="'rec_ref_1'" :deviceID="deviceID"/>
<elite-parameter-recording-elitezm15 v-else-if="eliteVer=='2'" :ref="'rec_ref_2'" :deviceID="deviceID"/>
<elite-parameter-recording-elite-e-i-s v-else-if="eliteVer=='4'" :ref="'rec_ref_4'" :deviceID="deviceID"/>
<!-- <elite-parameter-recording v-if="eliteVer=='1'" :ref="'rec_ref_1'" :deviceID="deviceID"/> -->
<device-parameter-recording
:parameter="device.configuration"
:library="device.library_name"
:device="device"
@sendInstruction="sendInstruction"
@getParameter="getParameter"
@setParameter="setParameter"
@setParameterWithDebounce="setParameterWithDebounce"
/>
<!-- <elite-parameter-recording-elitezm15
:ref="'rec_ref_2'"
:parameter="device.configuration"
:library="device.library_name"
:device="device"
@sendInstruction="sendInstruction"
@getParameter="getParameter"
@setParameter="setParameter"
@setParameterWithDebounce="setParameterWithDebounce"
/> -->
<!-- <elite-parameter-recording-elite-e-i-s v-else-if="eliteVer=='4'" :ref="'rec_ref_4'" :deviceID="deviceID"/>
<elite-parameter-recording-elite-trigger v-else-if="eliteVer=='5'" :ref="'rec_ref_5'" :deviceID="deviceID"/>
<elite-parameter-recording-elite-e-i-s v-else :ref="'rec_ref_4'" :deviceID="deviceID"/>
<elite-parameter-recording-elite-e-i-s v-else :ref="'rec_ref_4'" :deviceID="deviceID"/> -->
</div>
</template>
<script>
import EliteParameterRecording from './EliteParameterRecording'
import EliteParameterRecordingElitezm15 from './EliteParameterRecordingElitezm15'
import EliteParameterRecordingEliteEIS from './EliteParameterRecordingEliteEIS'
import EliteParameterRecordingEliteTrigger from './EliteParameterRecordingEliteTrigger'
import DeviceParameterRecording from './DeviceParameterRecording'
// import EliteParameterRecordingElitezm15 from './EliteParameterRecordingElitezm15'
// import EliteParameterRecording from './EliteParameterRecording'
// import EliteParameterRecordingEliteEIS from './EliteParameterRecordingEliteEIS'
// import EliteParameterRecordingEliteTrigger from './EliteParameterRecordingEliteTrigger'
import { taskInfo } from '../../../../data/task/TaskInfo'
import _ from 'lodash'
export default {
name: 'EliteParameterWindow',
components: {
EliteParameterRecording,
EliteParameterRecordingElitezm15,
EliteParameterRecordingEliteEIS,
EliteParameterRecordingEliteTrigger,
DeviceParameterRecording,
// EliteParameterRecordingElitezm15,
// EliteParameterRecording,
// EliteParameterRecordingEliteEIS,
// EliteParameterRecordingEliteTrigger,
},
props: {
deviceID: {
type: Number,
device: {
type: Object,
required: true,
},
deviceName: {
@@ -42,6 +63,36 @@ export default {
mqtt: {
},
methods: {
sendInstruction: function (instruction) {
this.mqttPublish(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_instruction/0',
device: this.device.mac_address,
instruction: instruction,
}))
},
getParameter: function (parameterName) {
this.mqttPublish(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter_value/0',
device: this.device.mac_address,
parameter: parameterName,
}))
},
setParameter: function (parameterName, parameterValue) {
this.mqttPublish(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: this.device.mac_address,
parameter: parameterName,
content: parameterValue,
}))
},
setParameterWithDebounce: _.debounce(function (parameterName, parameterValue) {
this.mqttPublish(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: this.device.mac_address,
parameter: parameterName,
content: parameterValue,
}))
}, 100),
compareEliteVer: function (ver) {
if (JSON.stringify(ver.slice(0, 4)) === JSON.stringify([0, 2, 1, 5])) {
this.eliteVer = '1' // 1.4
@@ -60,52 +111,43 @@ export default {
this.eliteVer = '4'
}
},
mqttPub: function (topic, mes) {
mqttPublish: function (topic, mes) {
this.$mqtt.publish(topic, mes)
// console.log('window:1,mqttPub(topic:', topic, ',mes:', mes, ')')
},
pageInit: function () {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'get_device_info/0',
device: taskInfo.getRawDeviceID(this.deviceID),
}))
// console.log('window:2,pageInit(taskInfo.getDeviceInfo:', taskInfo.getDeviceInfo(this.deviceID).info.serial_number, ')')
this.compareEliteVer(taskInfo.getDeviceInfo(this.deviceID).info.serial_number)
},
refresh: function () {
// console.log(this.eliteVer)
switch (this.eliteVer) {
case '1':
this.$nextTick(() => {
if (this.$refs.rec_ref_1 != null) {
this.$refs.rec_ref_1.refresh()
}
})
break
case '2':
this.$nextTick(() => {
if (this.$refs.rec_ref_2 != null) {
this.$refs.rec_ref_2.refresh()
}
})
break
case '4':
this.$nextTick(() => {
if (this.$refs.rec_ref_4 != null) {
this.$refs.rec_ref_4.refresh()
}
})
break
case '5':
this.$nextTick(() => {
if (this.$refs.rec_ref_5 != null) {
this.$refs.rec_ref_5.refresh()
}
})
break
}
// // console.log(this.eliteVer)
// switch (this.eliteVer) {
// case '1':
// this.$nextTick(() => {
// if (this.$refs.rec_ref_1 != null) {
// this.$refs.rec_ref_1.refresh()
// }
// })
// break
// case '2':
// this.$nextTick(() => {
// if (this.$refs.rec_ref_2 != null) {
// this.$refs.rec_ref_2.refresh()
// }
// })
// break
// case '4':
// this.$nextTick(() => {
// if (this.$refs.rec_ref_4 != null) {
// this.$refs.rec_ref_4.refresh()
// }
// })
// break
// case '5':
// this.$nextTick(() => {
// if (this.$refs.rec_ref_5 != null) {
// this.$refs.rec_ref_5.refresh()
// }
// })
// break
// }
// this.$nextTick(() => {
// if (this.$refs.rec_ref != null) {
// this.$refs.rec_ref.refresh()
@@ -117,16 +159,8 @@ export default {
},
mounted () {
this.pageInit()
// console.log('window:4,mounted(pageInit)')
},
watch: {
deviceID: function (val) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'get_device_info/0',
device: taskInfo.getRawDeviceID(val),
}))
// console.log('window:5,deviceID(taskInfo:', taskInfo, ')')
},
},
}
</script>
@@ -130,7 +130,7 @@
<script>
import { taskInfo } from '../../../../data/task/TaskInfo'
import { chartData } from '../../../../data/task/ChartsManagement'
import { mapFields } from 'vuex-map-fields'
export default {
name: 'NeuliveParameterRecording',
@@ -146,6 +146,11 @@ export default {
default: 'Neulive',
},
},
computed: {
...mapFields('taskContent', [
'chartData',
]),
},
data () {
return {
channelList: [],
@@ -205,6 +210,16 @@ export default {
value: 20000,
description: '20k',
},
{
id: 7,
value: 25000,
description: '25k',
},
{
id: 8,
value: 31250,
description: '31.25k',
},
],
acceleratorSensitivitySelect: null,
acceleratorSensitivityOptions: [
@@ -333,7 +348,7 @@ export default {
},
sampleRateSelectChange () {
if (this.sampleRateSelect != null && this.sampleRateSelect.value !== ((taskInfo.getDeviceInfo(this.deviceID).parameterSet.SAMPLE_RATE))) {
const adcClock = 8e5 / this.sampleRateSelect.value
const adcClock = 1e6 / this.sampleRateSelect.value
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: taskInfo.getRawDeviceID(this.deviceID),
@@ -374,7 +389,7 @@ export default {
device: taskInfo.getRawDeviceID(this.deviceID),
content: this.acceleratorSensitivitySelect.value,
}))
const charts = chartData.getAllChartsData()
const charts = this.chartData
for (const chartID in charts) {
for (const seriesIndex in charts[chartID].series) {
if (charts[chartID].series[seriesIndex].yAxisSource[1] >= 256 && charts[chartID].series[seriesIndex].yAxisSource[1] <= 260) {
@@ -130,7 +130,7 @@
<script>
import { taskInfo } from '../../../../data/task/TaskInfo'
import { chartData } from '../../../../data/task/ChartsManagement'
import { mapFields } from 'vuex-map-fields'
export default {
name: 'NeuliveParameterRecording',
@@ -146,6 +146,11 @@ export default {
default: 'Neulive',
},
},
computed: {
...mapFields('taskContent', [
'chartData',
]),
},
data () {
return {
channelList: [],
@@ -202,43 +207,43 @@ export default {
},
{
id: 6,
value: 16000,
description: '16k',
},
{
id: 7,
value: 20000,
description: '20k',
},
{
id: 7,
value: 30000,
description: '30k',
id: 8,
value: 25000,
description: '25k',
},
{
id: 8,
id: 9,
value: 32000,
description: '32k',
},
{
id: 10,
value: 40000,
description: '40k',
},
{
id: 9,
id: 11,
value: 50000,
description: '50k',
},
{
id: 10,
value: 60000,
description: '60k',
},
{
id: 11,
value: 70000,
description: '70k',
},
{
id: 12,
value: 80000,
description: '80k',
value: 64000,
description: '64k',
},
{
id: 13,
value: 90000,
description: '90k',
value: 80000,
description: '80k',
},
{
id: 14,
@@ -491,7 +496,7 @@ export default {
device: taskInfo.getRawDeviceID(this.deviceID),
content: this.acceleratorSensitivitySelect.value,
}))
const charts = chartData.getAllChartsData()
const charts = this.chartData
for (const chartID in charts) {
for (const seriesIndex in charts[chartID].series) {
if (charts[chartID].series[seriesIndex].yAxisSource[1] >= 256 && charts[chartID].series[seriesIndex].yAxisSource[1] <= 260) {
@@ -130,7 +130,7 @@
<script>
import { taskInfo } from '../../../../data/task/TaskInfo'
import { chartData } from '../../../../data/task/ChartsManagement'
import { mapFields } from 'vuex-map-fields'
export default {
name: 'NeuliveParameterRecording',
@@ -146,6 +146,11 @@ export default {
default: 'Neulive',
},
},
computed: {
...mapFields('taskContent', [
'chartData',
]),
},
data () {
return {
channelArray: Array.from({ length: 64 }, (_, i) => i + 1),
@@ -468,7 +473,7 @@ export default {
device: taskInfo.getRawDeviceID(this.deviceID),
content: this.acceleratorSensitivitySelect.value,
}))
const charts = chartData.getAllChartsData()
const charts = this.chartData
for (const chartID in charts) {
for (const seriesIndex in charts[chartID].series) {
if (charts[chartID].series[seriesIndex].yAxisSource[1] >= 256 && charts[chartID].series[seriesIndex].yAxisSource[1] <= 260) {
@@ -955,10 +955,10 @@ export default {
return false
}
if (usVal < 60) {
this.periodNumber = 60
this.periodNumberInput = String(60 / this.unitMultiply)
this.pageToast('Reset to 60 us')
if (usVal < 10) {
this.periodNumber = 10
this.periodNumberInput = String(10 / this.unitMultiply)
this.pageToast('Reset to 10 us')
} else if (usVal > 1e6) { // freq: 1 to 20000Hz, so period < 1e6us (1e6/1e6=1)
this.periodNumber = 1e6
this.periodNumberInput = String(1e6 / this.unitMultiply)
@@ -1137,7 +1137,7 @@ export default {
// val unit: us
const val = (this.t1Range + this.t2Range + this.t3Range + this.t4Range) * 10 // UI us
if (val < 80) { // us
if (val < 10) { // us
for (const tRange of [1, 2, 3, 4]) {
this.updateTRangeErrorMsg({ stiIimeSelect: tRange, status: true, msg: 'Period < 0.08ms' })
}
@@ -7,6 +7,7 @@
outline
v-model="levelButtonSelect"
:options="options"
:disabled="disable"
/>
</div>
</div>
@@ -33,6 +34,10 @@ export default {
type: Array,
required: true,
},
disable: {
type: Boolean,
default: false,
},
},
created () {
},
@@ -0,0 +1,122 @@
<template>
<div>
<fieldset>
<va-radio-button
option="0"
v-model="optionValue"
label="AUTO"
@click.native.stop="switchMode(optionValue)"
/>
<va-radio-button
option="1"
v-model="optionValue"
label="ADVANCED"
@click.native.stop="switchMode(optionValue)"
/>
<va-radio-button
option="2"
v-model="optionValue"
label="ENGINEERING"
@click.native.stop="switchMode(optionValue)"
/>
<!-- <div v-for="name in parameterTable.MODE[15].parameter" :key="name">
{{ name }}
{{ parameterTable[name].componentType }}
{{ parameter[name] }}
</div> -->
<component
v-for="name in displayParameterList"
:key="name"
:is="parameterTable[name].componentType"
:withHeader="true"
:withUnitButton="true"
:parameterName="name"
:inputValue="parameter[name]"
:disabled="optionValue === '2' && Boolean(parameter.DPV_engineering_enable) === false && engineerModeDisableList.includes(name)"
v-bind="parameterTable[name]"
@parameterChange="parameterChange"
@getParameter="getParameter"
@sendInstruction="sendInstruction"
/>
</fieldset>
</div>
</template>
<script>
import InputRange from '../InputRange'
import InputOption from '../InputOption'
import InputToggle from '../InputToggle'
import InputDoubleRange from '../InputDoubleRange'
import InputButtonToggle from '../InputButtonToggle'
import InputField from '../InputField'
export default {
name: 'EliteParameterRecordingEliteDPV',
components: {
InputRange,
InputButtonToggle,
InputField,
InputDoubleRange,
InputOption,
InputToggle,
},
props: {
parameter: {
type: Object,
required: true,
},
device: {
type: Object,
default: () => {},
},
parameterTable: {
type: Object,
},
deviceID: {
type: Number,
},
deviceName: {
type: String,
default: 'Elite',
},
},
created () {
},
computed: {
displayParameterList () {
return this.parameterTable.MODE[this.parameter.MODE].parameterInMode[this.optionValue]
},
},
data () {
return {
engineerModeDisableList: ['DPV_e_1', 'DPV_e_2', 'DPV_pulse_option'],
optionValue: String(this.parameter.DPV_mode),
}
},
mqtt: {
},
methods: {
mqttPub: function (topic, mes) {
this.$mqtt.publish(topic, mes)
},
parameterChange: function (name, value, debounce = false) {
this.$emit('parameterChange', name, value, debounce)
},
getParameter: function (name) {
this.$emit('getParameter', name)
},
sendInstruction: function (instr) {
this.$emit('sendInstruction', instr)
},
switchMode (val) {
this.$emit('parameterChange', 'DPV_mode', parseInt(val))
},
},
mounted () {
},
watch: {
},
destroyed () {
},
}
</script>
@@ -0,0 +1,138 @@
<template>
<div>
<va-card>
<div class="row">
<va-button class="mr-2 pa-1" style="width: 4em; height: 2em; font-size: 15px;" small @click="sendDetectInstr">
Detect
</va-button>
<va-button class="mr-2 pa-1" style="width: 4em; height: 2em; font-size: 15px;" small @click="sendInstr('dev_version')">
Version
</va-button>
<va-button class="mr-2 pa-1" style="width: 4em; height: 2em; font-size: 15px;" small @click="sendInstr('dev_battery')">
Battery
</va-button>
</div>
<div class="row">
<div class="flex sm12 xl12 md12 xs12">
<div class="flex row align--center">
<va-input
@keyup.enter="instruParameterChange(inputWrite)"
@blur="instruParameterChange(inputWrite)"
class="mb-0"
v-model="inputWrite"
label="Write value (0x3000FF ... )"
style="width: 100px;"
maxlength="34"
/>
<va-button slot="append" class="mr-2 pa-1 shrink" style="width: 2em; height: 2em; border-radius: 50%; font-size: 20px;" small @click="sendInstr('ble_instru_send')">
W
</va-button>
</div>
</div>
</div>
<div class="row">
<div class="flex sm12 xl12 md12 xs12">
<div class="flex row align--center">
<va-input
:disabled="true"
class="mb-0"
v-model="inputRead"
label="Read value"
style="width: 100px; font-size: 30px;"
/>
<va-button slot="append" class="mr-2 pa-1 shrink" style="width: 2em; height: 2em; border-radius: 50%; font-size: 20px;" small @click="readCisData()">
R
</va-button>
</div>
</div>
</div>
<div class="row">
<div class="flex sm12 xl12 md12 xs12">
<div class="flex row align--center">
<va-input
disabled="disabled"
class="mb-0"
v-model="inputNotify"
label="Notify value"
style="width: 100px;"
/>
<va-button slot="append" class="mr-2 pa-1 shrink" style="width: 2em; height: 2em; border-radius: 50%; font-size: 20px;" small @click="detect()">
N
</va-button>
</div>
</div>
</div>
</va-card>
</div>
</template>
<script>
export default {
name: 'DevMode',
components: {
},
computed: {
inputRead () {
return this.inputValue.toString(16).toUpperCase()
},
},
props: {
inputValue: {
type: Number,
required: true,
},
parameterName: {
type: String,
required: true,
},
},
created () {
},
data () {
return {
inputWrite: '',
inputNotify: '',
}
},
mqtt: {
},
methods: {
sendInstr (instr) {
this.$emit('sendInstruction', instr)
},
sendDetectInstr () {
this.$emit('sendInstruction', 'VIS_DEVICE_DETECT')
setTimeout(() => {
this.$emit('sendInstruction', 'VIS_DEVICE_DONE')
}, 5000)
},
readCisData () {
this.$emit('getParameter', 'ADC_VALUE_I')
},
instruParameterChange (instruction) {
while (instruction.length <= 33) {
instruction += '0'
}
const sendIns = new Array(17).fill(0)
for (let i = 0; i <= 16; i++) {
const startIndex = i * 2
sendIns[i] = instruction.substring(startIndex, startIndex + 2)
sendIns[i] = parseInt(sendIns[i], 16)
}
this.$emit('parameterChange', 'BLE_WRITE', '0:16=' + String(sendIns))
},
},
async mounted () {
},
destroyed () {
},
watch: {
},
}
</script>
@@ -0,0 +1,101 @@
<template>
<div>
<div v-if="templateType === 0" class="row flex sm12 xl12 md12 xs12 align--center my-0 py-0">
<div v-if="withHeader" class="flex sm6 xl6 md6 xs6">
<p class="display-6">{{ showName }}<p/>
</div>
<div class="flex sm12 xl12 md12 xs12">
<va-button-toggle
small
outline
v-model="buttonSelect"
:options="options"
:disabled="disable"
/>
</div>
</div>
<div v-if="templateType === 1" class="row flex sm12 xl12 md12 xs12 align--center my-0 py-0">
<div v-if="withHeader" class="flex sm6 xl6 md6 xs6 px-0 mx-0">
<p class="display-6">{{ showName }}<p/>
</div>
<div class="flex sm6 xl6 md6 xs6 px-0 mx-0">
<va-button-toggle
small
outline
v-model="buttonSelect"
:options="options"
:disabled="disable"
/>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'InputButtonToggle',
components: {
},
computed: {
buttonSelect: {
get () {
return this.inputValue
},
set (val) {
this.buttonSelectChange(val)
},
},
},
props: {
templateType: {
type: Number,
default: 0,
},
withHeader: {
type: Boolean,
default: false,
},
parameterName: {
type: String,
required: true,
},
showName: {
type: String,
},
inputValue: {
type: Number,
required: true,
},
options: {
type: Array,
required: true,
},
disable: {
type: Boolean,
default: false,
},
},
created () {
},
data () {
return {
}
},
mqtt: {
},
methods: {
buttonSelectChange (value) {
this.$emit('parameterChange', this.parameterName, value)
},
},
async mounted () {
// console.log('mount button group', this.parameterName, this.inputValue, this.buttonSelect, this.options, this.disable)
},
destroyed () {
},
watch: {
},
}
</script>
@@ -0,0 +1,124 @@
<template>
<!-- this is range slider which [0,25,50,75] ~ 100(fixed) -->
<div class="row flex">
<div class="flex sm12 xl12 md12 xs12 px-0 mx-0 my-0 py-1">
<p class="display-6">Current Recording -<p/>
</div>
<div class="flex sm6 xl6 md6 xs6 px-0 mx-0 mt-2 py-3">
<p class="display-6">Pre- / Post-Pulse Width<p/>
</div>
<div class="flex sm2 xl2 md2 xs2 px-0 mx-0 mt-2 py-3">
<va-input
@keyup.enter="inputStringChange(inputString)"
@blur="inputStringChange(inputString)"
v-model="inputStringModal"
class="mb-0"
>
<p slot="append" style="margin-right: 0;" small>
%
</p>
</va-input>
</div>
<div class="flex sm12 xl12 md12 xs12 py-0 my-0" >
<va-slider
range
pins
:min="range.min"
:max="range.max"
value-visible
:step="25"
v-model="inputArray"
/>
</div>
</div>
</template>
<script>
export default {
name: 'InputDoubleRange',
components: {
},
props: {
templateType: {
type: Number,
default: 0,
},
withHeader: {
type: Boolean,
default: false,
},
parameterName: {
type: String,
required: true,
},
showName: {
type: [String, Function],
},
range: {
type: Object,
},
inputValue: {
type: Array,
default: () => [0, 100],
},
},
created () {
},
computed: {
inputArray: {
get () {
return this.inputValue
},
set (val) {
this.inputChange(val)
},
},
inputStringModal: {
get () {
return String(this.inputValue[1] - this.inputValue[0])
},
set (val) {
this.inputString = val
},
},
},
data () {
return {
inputString: '',
}
},
methods: {
inputStringChange (val) {
val = parseInt(val)
const remainder = val % 25
if (remainder > 13) {
val += (25 - remainder)
} else {
val -= remainder
}
if (val < 0 || isNaN(val)) {
val = 0
} else if (val > 75) {
val = 75
}
this.$emit('parameterChange', this.parameterName, [100 - val, 100])
},
inputChange (val) {
val[1] = 100 // [2021/10/28] max val is fixed to 100 now
if (val[0] === this.range.max) { // [2021/10/28] min can't equal 100 now
val[0] = this.inputValue[0]
}
this.$emit('parameterChange', this.parameterName, val, true)
},
},
async mounted () {
},
destroyed () {
},
watch: {
},
}
</script>
@@ -0,0 +1,170 @@
<template>
<div class="row flex sm12 xl12 md12 xs12 align--center my-0 py-0">
<div v-if="withHeader" :class="style.header">
<p :style="disabled !== true ? '' : {color: this.$themes.gray}" class="display-6">{{ showName }}<p/>
</div>
<div :class="style.content">
<va-input
@keyup.enter="inputChange(inputString)"
@blur="inputChange(inputString)"
v-model="inputStringModel"
class="mb-0"
:disabled="disabled"
>
<p slot="append" style="margin-right: 0;" small>
{{ unitSelect }}
</p>
</va-input>
</div>
<div v-if="withUnitButton" :class="style.unitButton">
<va-button
@click="unitChange()"
v-model="unitSelect"
class="px-3 py-1"
style="border-radius: 12px;"
:disabled="disabled"
>
{{ unitSelect }}
</va-button>
</div>
</div>
</template>
<script>
export default {
name: 'InputFieldWithHeader',
components: {
},
props: {
templateType: {
type: Number,
default: 0,
},
withHeader: {
type: Boolean,
default: false,
},
withUnitButton: {
type: Boolean,
default: false,
},
parameterName: {
type: String,
required: true,
},
showName: {
type: String,
},
range: {
type: Object,
},
inputValue: {
type: Number,
required: true,
},
defaultUnit: {
type: String,
},
unit: {
type: Object,
},
outputReadabilityData: {
type: Function,
default: (val) => val,
},
outputRawData: {
type: Function,
default: (val) => val,
},
disabled: {
type: Boolean,
default: false,
},
index: {
type: Number,
default: -1,
},
},
created () {
},
computed: {
inputStringModel: {
get () {
return String(this.outputReadabilityData(this.inputValue, this.unit[this.unitSelect]))
},
set (val) {
this.inputString = val
},
},
unitLength () {
return Object.keys(this.unit).length
},
},
data () {
return {
unitSelect: this.defaultUnit,
unitButtonClicked: Object.keys(this.unit).indexOf(this.defaultUnit),
inputString: '',
size: {
12: 'flex sm12 xl12 md12 xs12 px-0 mx-0',
6: 'flex sm6 xl6 md6 xs6 px-0 mx-0',
5: 'flex sm5 xl5 md5 xs5 px-0 mx-0 my-0 py-0',
4: 'flex sm4 xl4 md4 xs4 px-0 mx-0 my-0 py-0',
3: 'flex sm3 xl3 md3 xs3 px-0 mx-0 my-0 py-0',
},
style: {
header: '',
content: '',
unitButton: '',
},
}
},
mqtt: {
},
methods: {
inputChange: function (val) {
/** */
const scale = this.unit[this.unitSelect]
// if change from input field
if (typeof (val) === 'string') {
if (isNaN(val) || val === '') {
return false
}
val = this.outputRawData(val, scale)
if (parseFloat(val) < this.range.min) {
val = this.range.min
} else if (parseFloat(val) > this.range.max) {
val = this.range.max
}
}
/** if parameter is array with index needs to return */
if (this.index === -1) {
this.$emit('parameterChange', this.parameterName, val)
} else {
this.$emit('parameterChangeByIndex', this.parameterName, val, this.index)
}
},
unitChange: function () {
this.unitButtonClicked += 1
this.unitSelect = Object.keys(this.unit)[this.unitButtonClicked % this.unitLength]
},
},
async mounted () {
if (this.withHeader === true && this.withUnitButton === true) {
this.style.header = this.size[5]
this.style.content = this.size[4]
this.style.unitButton = this.size[3]
} else if (this.withHeader === true) {
this.style.header = this.size[6]
this.style.content = this.size[6]
} else {
this.style.content = this.size[12]
}
},
destroyed () {
},
watch: {
},
}
</script>
@@ -0,0 +1,72 @@
<template>
<div class="row flex px-0 mx-0 my-0 py-0">
<div class="flex sm4 xl4 md4 xs4 px-0 mx-0 my-0 py-2">
<p :style="disabled !== true ? '' : {color: this.$themes.gray}" class="display-6">{{ showName }}<p/>
</div>
<div class="flex sm1 xl1 md1 xs1 px-0 mx-0 my-0 py-0">
<va-checkbox v-model="inputOptionModel" :disabled="disabled"/>
</div>
<div class="flex sm7 xl7 md7 xs7 px-0 mx-0 my-0 py-1">
<p :style="{color: this.$themes.gray}" style="font-weight: bold;"> {{ description }} </p>
</div>
</div>
</template>
<script>
export default {
name: 'InputOption',
components: {
},
props: {
parameterName: {
type: String,
required: true,
},
description: {
type: String,
default: '',
},
showName: {
type: String,
},
inputValue: {
type: [Boolean, Number],
required: true,
},
disabled: {
type: Boolean,
default: false,
},
},
created () {
},
computed: {
inputOptionModel: {
get () {
return Boolean(this.inputValue)
},
set (val) {
this.inputChange(val)
},
},
},
data () {
return {
}
},
mqtt: {
},
methods: {
inputChange (val) {
this.$emit('parameterChange', this.parameterName, val)
},
},
async mounted () {
},
destroyed () {
},
watch: {
},
}
</script>
@@ -0,0 +1,141 @@
<template>
<div class="flex row sm12 xl12 md12 xs12 align--center ma-0 pa-0">
<div v-if="withHeader" class="flex sm12 xl12 md12 xs12 pa-0 ma-1">
<p class="display-6">{{ showName }}<p/>
</div>
<div class="flex sm12 xl12 md12 xs12">
<div class="flex row align--center">
<va-button slot="append" class="mr-2 pa-1 shrink" small @click="() => {
inputNumber = range.min
inputChange(range.min)
}">
{{ outputReadabilityData(range.min, unit[selectUnit]) }}
</va-button>
<va-input
@keyup.enter="inputChange(inputString)"
@blur="inputChange(inputString)"
v-model="inputStringModel"
class="mb-0"
style="width: 100px;"
>
<p slot="append" style="margin-right: 0;" small>
{{ defaultUnit }}
</p>
</va-input>
<va-button slot="append" class="ml-2 pa-1 shrink" small @click="() => {
inputNumber = range.max
inputChange(range.max)
}">
{{ outputReadabilityData(range.max, unit[selectUnit]) }}
</va-button>
</div>
<va-slider
class="flex sm12 xl12 md12 xs12 pa-0 ma-0"
v-model="inputNumber"
:min="range.min"
:max="range.max"
/>
</div>
</div>
</template>
<script>
export default {
name: 'RangeInput',
components: {
},
props: {
templateType: {
type: Number,
default: 0,
},
withHeader: {
type: Boolean,
default: false,
},
parameterName: {
type: String,
required: true,
},
showName: {
type: [String, Function],
},
range: {
type: Object,
},
inputValue: {
type: Number,
required: true,
},
defaultUnit: {
type: String,
},
unit: {
type: Object,
},
outputReadabilityData: {
type: Function,
default: (val) => val,
},
outputRawData: {
type: Function,
default: (val) => val,
},
},
created () {
},
computed: {
inputNumber: {
get () {
return this.inputValue
},
set (val) {
this.inputChange(val)
},
},
inputStringModel: {
get () {
return String(this.outputReadabilityData(this.inputValue, this.unit[this.defaultUnit]))
},
set (val) {
this.inputString = val
},
},
},
data () {
return {
inputString: String(this.outputReadabilityData(this.inputValue, this.unit[this.defaultUnit])),
selectUnit: this.defaultUnit, // find key where is 1
}
},
mqtt: {
},
methods: {
inputChange: function (val) {
const scale = this.unit[this.selectUnit]
// if change from input field
if (typeof (val) === 'string') {
if (isNaN(val) || val === '') {
return false
}
val = this.outputRawData(val, scale)
if (parseFloat(val) < this.range.min) {
val = this.range.min
} else if (parseFloat(val) > this.range.max) {
val = this.range.max
}
}
this.$emit('parameterChange', this.parameterName, val, true)
// console.log(this.parameterName, val, typeof (val), this.inputNumber, this.inputString, scale)
},
},
async mounted () {
// console.log(this.templateType, this.parameterName, this.inputValue, this.defaultUnit, this.unit, this.inputChange, this.selectUnit, this.inputNumber, this.inputString)
},
destroyed () {
},
watch: {
},
}
</script>
@@ -0,0 +1,101 @@
<template>
<!-- this is range slider which [0,25,50,75] ~ 100(fixed) -->
<div>
<div class="row flex">
<div class="flex sm8 xl8 md8 xs8 px-0 mx-0">
<p class="display-6">{{ showName }}<p/>
</div>
<div class="flex sm4 xl4 md4 xs4 px-0 mx-0">
{{ `${inputValue[0]} - ${inputValue[1]} %` }}
</div>
</div>
<div class="flex sm12 xl12 md12 xs12 py-0 my-0" >
<va-slider
range
pins
:min="range.min"
:max="range.max"
value-visible
:step="sliderStep"
v-model="inputArray"
/>
</div>
</div>
</template>
<script>
export default {
name: 'inputRangeSlider',
components: {
},
props: {
templateType: {
type: Number,
default: 0,
},
withHeader: {
type: Boolean,
default: false,
},
parameterName: {
type: String,
required: true,
},
showName: {
type: [String, Function],
},
range: {
type: Object,
},
inputValue: {
type: Array,
default: () => [0, 100],
},
sliderStep: {
type: Number,
default: 1,
},
index: {
type: Number,
default: -1,
},
},
created () {
},
computed: {
inputArray: {
get () {
return this.inputValue
},
set (val) {
this.inputChange(val)
},
},
inputStringModal: {
get () {
return String(this.inputValue[1] - this.inputValue[0])
},
set (val) {
this.inputString = val
},
},
},
data () {
return {
inputString: '',
}
},
methods: {
inputChange (val) {
this.$emit('parameterChangeByIndex', this.parameterName, val, this.index, true)
},
},
async mounted () {
},
destroyed () {
},
watch: {
},
}
</script>
@@ -0,0 +1,58 @@
<template>
<div class="row flex px-0 mx-0 my-0 py-0">
<div class="flex sm4 xl4 md4 xs4 px-0 mx-0 my-0 py-2">
<va-toggle class="mt-1" v-model="inputToggleModel" small color="success"/>
</div>
</div>
</template>
<script>
export default {
name: 'InputOption',
components: {
},
props: {
parameterName: {
type: String,
required: true,
},
showName: {
type: String,
},
inputValue: {
type: [Boolean, Number],
required: true,
},
},
created () {
},
computed: {
inputToggleModel: {
get () {
return Boolean(this.inputValue)
},
set (val) {
this.inputToggleChange(val)
},
},
},
data () {
return {
}
},
mqtt: {
},
methods: {
inputToggleChange (val) {
this.$emit('parameterChange', this.parameterName, val)
},
},
async mounted () {
},
destroyed () {
},
watch: {
},
}
</script>
@@ -0,0 +1,183 @@
<template>
<div class="row flex sm12 xl12 md12 xs12 align--center my-0 py-0">
<div v-if="withHeader" :class="style.header">
<p :style="disabled !== true ? '' : {color: this.$themes.gray}" class="display-6">{{ showName }}<p/>
</div>
<div :class="style.content">
<va-input
@keyup.enter="inputChange(inputString, 0)"
@blur="inputChange(inputString, 0)"
v-model="inputStringModel1"
class="mb-0"
:disabled="disabled"
>
<p slot="append" style="margin-right: 0;" small>
{{ unitSelect }}
</p>
</va-input>
<va-input
@keyup.enter="inputChange(inputString, 1)"
@blur="inputChange(inputString, 1)"
v-model="inputStringModel2"
class="mb-0"
:disabled="disabled"
>
<p slot="append" style="margin-right: 0;" small>
{{ unitSelect }}
</p>
</va-input>
</div>
<div v-if="withUnitButton" :class="style.unitButton">
<va-button
@click="unitChange()"
v-model="unitSelect"
class="px-3 py-1"
style="border-radius: 12px;"
:disabled="disabled"
>
{{ unitSelect }}
</va-button>
</div>
</div>
</template>
<script>
export default {
name: 'InputFieldWithHeader',
components: {
},
props: {
templateType: {
type: Number,
default: 0,
},
withHeader: {
type: Boolean,
default: false,
},
withUnitButton: {
type: Boolean,
default: false,
},
parameterName: {
type: String,
required: true,
},
showName: {
type: String,
},
range: {
type: Object,
},
inputValue: {
type: Array,
required: true,
},
defaultUnit: {
type: String,
},
unit: {
type: Object,
},
outputReadabilityData: {
type: Function,
default: (val) => val,
},
outputRawData: {
type: Function,
default: (val) => val,
},
disabled: {
type: Boolean,
default: false,
},
},
created () {
},
computed: {
inputStringModel1: {
get () {
return String(this.outputReadabilityData(this.inputValue[0], this.unit[this.unitSelect]))
},
set (val) {
this.inputString = val
},
},
inputStringModel2: {
get () {
return String(this.outputReadabilityData(this.inputValue[1], this.unit[this.unitSelect]))
},
set (val) {
this.inputString = val
},
},
unitLength () {
return Object.keys(this.unit).length
},
},
data () {
return {
unitSelect: this.defaultUnit,
unitButtonClicked: 0,
inputString: '',
size: {
12: 'flex sm12 xl12 md12 xs12 px-0 mx-0',
6: 'flex sm6 xl6 md6 xs6 px-0 mx-0',
5: 'flex sm5 xl5 md5 xs5 px-0 mx-0 my-0 py-0',
4: 'flex sm4 xl4 md4 xs4 px-0 mx-0 my-0 py-0',
3: 'flex sm3 xl3 md3 xs3 px-0 mx-0 my-0 py-0',
},
style: {
header: '',
content: '',
unitButton: '',
},
}
},
mqtt: {
},
methods: {
inputChange: function (val, index) {
const inputData = [...this.inputValue]
const scale = this.unit[this.unitSelect]
// if change from input field
if (typeof (val) === 'string') {
if (isNaN(val) || val === '') {
return false
}
val = this.outputRawData(val, scale)
if (parseFloat(val) < this.range.min) {
val = this.range.min
} else if (parseFloat(val) > this.range.max) {
val = this.range.max
}
}
inputData[index] = val
this.$emit('parameterChange', this.parameterName, inputData)
// console.log(this.parameterName, val, typeof (val), this.inputNumber, this.inputString, scale)
},
unitChange: function () {
this.unitButtonClicked += 1
this.unitSelect = Object.keys(this.unit)[this.unitButtonClicked % this.unitLength]
},
},
async mounted () {
if (this.withHeader === true && this.withUnitButton === true) {
this.style.header = this.size[3]
this.style.content = this.size[5]
this.style.unitButton = this.size[4]
} else if (this.withHeader === true) {
this.style.header = this.size[6]
this.style.content = this.size[6]
} else {
this.style.content = this.size[12]
}
},
destroyed () {
},
watch: {
},
}
</script>
@@ -0,0 +1,162 @@
<template>
<div>
<SlickList lockAxis="y" class="long-list" :pressDelay='300' v-model="parameter.segment_order" @sort-end="dragEnd">
<SlickItem v-for="(block, i) in parameter.segment_order" :key="i" :index="i">
<div v-if="block >= 0">
<div class="row flex sm12 xl12 md12 xs12 align--center">
<div class="flex sm11 xl11 md11 xs11 px-0 mx-0">
<p class="display-6">- Segment {{ i + 1 }} - <p/>
</div>
<div class="flex sm1 xl1 md1 xs1 px-0 mx-0">
<va-button @click="_deleteSegmentBlock(i)" color="danger" style="margin-right: 0;" small> - </va-button>
</div>
</div>
<component
v-for="name in parameterTable.MODE[parameter.MODE].parameter"
:key="name"
:is="parameterTable[name].componentType"
:withHeader="true"
:withUnitButton="true"
:parameterName="name"
:inputValue="parameter[name][block]"
:index="block"
v-bind="parameterTable[name]"
@parameterChange="parameterChange"
@parameterChangeByIndex="parameterChangeByIndex"
@getParameter="getParameter"
@sendInstruction="sendInstruction"
/>
</div>
</SlickItem>
</SlickList>
<div style="text-align: center;">
<va-button :disabled="parameter.segment_order.indexOf(-1) === -1" @click="_addSegmentBlock">
+
</va-button>
</div>
<!-- <va-tree-root>
<va-tree-category
style="font-size: 20px;"
:label="'Advanced Setting'">
<va-tree-node>
<data-output :ref="'DataOutput'" :deviceID="deviceID" :parameterName="'DATA_OUTPUT'" @parameterChange="deviceParameterChange($event)" />
<cycle-number :ref="'CycleNumber'" :deviceID="deviceID" :parameterName="'CYCLE_NUMBER'" @parameterChange="deviceParameterChange($event)" />
</va-tree-node>
</va-tree-category>
</va-tree-root> -->
</div>
</template>
<script>
import { SlickList, SlickItem } from 'vue-slicksort'
// import _ from 'lodash'
// import InputRange from '../InputRange'
// import InputButtonToggle from '../InputButtonToggle'
import InputRangeSlider from '../InputRangeSlider'
import InputField from '../InputField'
import InputDoubleRange from '../InputDoubleRange'
export default {
name: 'EliteParameterRecordingElitePulseSensing',
components: {
SlickList,
SlickItem,
InputField,
InputDoubleRange,
InputRangeSlider,
},
props: {
parameter: {
type: Object,
required: true,
},
device: {
type: Object,
default: () => {},
},
parameterTable: {
type: Object,
},
deviceID: {
type: Number,
},
deviceName: {
type: String,
default: 'Elite',
},
},
created () {
},
data () {
return {
maxSegment: 4,
numberList: [...Array(this.maxSegment).keys()],
}
},
mqtt: {
},
methods: {
mqttPub: function (topic, mes) {
this.$mqtt.publish(topic, mes)
},
parameterChange: function (name, value, debounce) {
this.$emit('parameterChange', name, value, debounce)
},
parameterChangeByIndex: function (name, value, index, debounce) {
const _value = [...this.parameter[name]]
_value[index] = value
this.$emit('parameterChange', name, _value)
},
getParameter: function (name) {
this.$emit('getParameter', name)
},
sendInstruction: function (instr) {
this.$emit('sendInstruction', instr)
},
_addSegmentBlock () {
for (let i = 0; i < this.maxSegment; i++) {
if (this.parameter.segment_order.indexOf(i) === -1) {
const _segmentOrder = [...this.parameter.segment_order]
const insertIndex = _segmentOrder.indexOf(-1)
_segmentOrder[insertIndex] = i
this.$emit('parameterChange', 'segment_order', _segmentOrder)
return true
}
}
},
_deleteSegmentBlock (index) {
const _segmentOrder = [...this.parameter.segment_order]
_segmentOrder.splice(index, 1)
this.$emit('parameterChange', 'segment_order', [..._segmentOrder, -1])
return true
},
dragEnd (event) {
// console.log('dragEnd', event)
// console.log(this.blockList) // 尚未變換順序前的list
// console.log(event)
// console.log(event.newIndex)
// console.log(event.oldIndex)
// one-line swap two element of array, ref: https://stackoverflow.com/questions/872310/javascript-swap-array-elements
// [this.blockList[event.oldIndex], this.blockList[event.newIndex]] = [this.blockList[event.newIndex], this.blockList[event.oldIndex]]
// this.updateSegmentOrderParam()
},
refresh () {
},
},
mounted () {
},
watch: {
},
destroyed () {
},
}
</script>
<style scoped>
.long-list {
max-height: 100%;
overflow: auto;
}
</style>
@@ -98,7 +98,6 @@
<script>
import { taskInfo } from '@/data/task/TaskInfo'
import { chartData } from '@/data/task/ChartsManagement'
import { mapActions } from 'vuex'
import { mapFields } from 'vuex-map-fields'
import types from '@/store/modules/task/content/types'
@@ -110,6 +109,7 @@ export default {
computed: {
...mapFields('taskContent', [
'deviceList',
'chartData',
]),
},
props: {
@@ -412,7 +412,7 @@ export default {
device: taskInfo.getRawDeviceID(this.deviceID),
content: this.acceleratorSensitivitySelect.value,
}))
const charts = chartData.getAllChartsData()
const charts = this.chartData
for (const chartID in charts) {
for (const seriesIndex in charts[chartID].series) {
if (charts[chartID].series[seriesIndex].yAxisSource[1] >= 256 && charts[chartID].series[seriesIndex].yAxisSource[1] <= 260) {
-1
View File
@@ -79,7 +79,6 @@ async function getAll () {
}
async function getByParentName (collectionType, parent, name) {
console.log(collectionType, parent, name)
const _header = auth.getHeader()
try {
return await api.axios.get(`/api/file/collection/get_by_parent_name/${collectionType}/${parent}/${name}`, { headers: _header })
-1
View File
@@ -13,7 +13,6 @@ async function create (_data) {
async function getAll () {
const _header = auth.getHeader()
console.log(_header)
try {
return await api.axios.get('/api/controller/get/all', { headers: _header })
} catch (e) {
+2
View File
@@ -10,6 +10,7 @@ import mini from './mini'
import analysis from './analysis'
import sdcard from './sdcard'
import connection from './connection'
import project from './project'
// axios.defaults.baseURL = 'http://192.168.3.211:3000'
axios.defaults.baseURL = 'http://' + location.href.split('/')[2].split(':')[0] + ':3000'
@@ -27,6 +28,7 @@ const api = {
analysis,
sdcard,
connection,
project,
}
export default api
+11
View File
@@ -52,6 +52,16 @@ async function getByParent (type, parent) {
}
}
async function getAttrByParent (type, parent, attr) {
const _header = auth.getHeader()
try {
return await api.axios.get(`/api/file/meta/get_attr_by_parent/${type}/${parent}/${attr}`, { responseType: 'json', headers: _header })
} catch (e) {
console.error(e)
return false
}
}
async function getByID (id) {
const _header = auth.getHeader()
try {
@@ -77,6 +87,7 @@ const meta = {
update,
clearDel,
getByParent,
getAttrByParent,
getByParentWithLimit,
getByID,
getByName,
+84
View File
@@ -0,0 +1,84 @@
import api from './index'
import auth from './auth'
async function create (attrs) {
const _header = auth.getHeader()
try {
return await api.axios.post('/api/project/create', attrs, { headers: _header })
} catch (e) {
console.error(e)
return false
}
}
async function update (id, attrs) {
const _header = auth.getHeader()
try {
return await api.axios.post(`/api/project/update/${id}`, attrs, { headers: _header })
} catch (e) {
console.error(e)
return false
}
}
async function del (id) {
const _header = auth.getHeader()
try {
return await api.axios.get(`/api/project/clear_deleted/${id}`, { headers: _header })
} catch (e) {
console.error(e)
return false
}
}
async function getByID (id) {
const _header = auth.getHeader()
try {
return await api.axios.get(`/api/project/get_by_id/${id}`, { headers: _header })
} catch (e) {
console.error(e)
return false
}
}
async function getByName (name) {
const _header = auth.getHeader()
try {
return await api.axios.get(`/api/project/get_by_name/${name}`, { headers: _header })
} catch (e) {
console.error(e)
return false
}
}
async function getByMac (mac) {
const _header = auth.getHeader()
try {
return await api.axios.get(`/api/project/get_by_mac/${mac}`, { headers: _header })
} catch (e) {
console.error(e)
return false
}
}
async function getAll () {
const _header = auth.getHeader()
try {
return await api.axios.get('/api/project/get/all', { headers: _header })
} catch (e) {
console.error(e)
return false
}
}
const project = {
create,
update,
del,
getByID,
getByMac,
getByName,
getAll,
}
export default project
-1
View File
@@ -13,7 +13,6 @@ async function create (_data) {
async function getAll () {
const _header = auth.getHeader()
console.log(_header)
try {
return await api.axios.get('/api/task/get/all', { headers: _header })
} catch (e) {
@@ -1,7 +1,7 @@
export default {
name: 'Cali ADC - test',
parameter: ['ADC_LEVEL_I_15', 'ADC_LEVEL_V_IN_15', 'ADC_DAC_CHANNEL_15'], // 這個mode用到的參數
showParameter: ['ADC_LEVEL_I_15', 'ADC_LEVEL_V_IN_15', 'ADC_DAC_CHANNEL_15'], // 有要秀給user看的參數
parameter: ['DAC_VOLT', 'ADC_LEVEL_I_15', 'ADC_LEVEL_V_IN_15', 'ADC_DAC_CHANNEL_15'], // 這個mode用到的參數
showParameter: ['DAC_VOLT', 'ADC_LEVEL_I_15', 'ADC_LEVEL_V_IN_15', 'ADC_DAC_CHANNEL_15'], // 有要秀給user看的參數
valScales: {
linear: {
func: (val) => {
@@ -25,7 +25,7 @@ export default {
h: 60 * 60 * 1e6,
auto: 1,
},
defaultUnit: 'auto',
defaultUnit: 'us',
},
0: {
name: 'I_in',
@@ -25,7 +25,7 @@ export default {
h: 60 * 60 * 1e6,
auto: 1,
},
defaultUnit: 'auto',
defaultUnit: 'us',
},
0: {
name: 'I_in',
@@ -1,7 +1,8 @@
export default {
name: 'Chronoamperometric Graph',
parameter: ['ADC_LEVEL_I_15', 'ADC_LEVEL_V_IN_15', 'CTRL_HIGH_Z_15', 'VOLT_VSCAN', 'SAMPLE_RATE'], // 這個mode用到的參數
name: 'Chronoamperometric',
parameter: ['VOLT_VSCAN', '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', 'VOLT_VSCAN', 'SAMPLE_RATE'], // 有要秀給user看的參數
headerParameter: () => ['VOLT_VSCAN', 'SAMPLE_RATE', 'ADC_LEVEL_I_15', 'ADC_LEVEL_V_IN_15'], // 有要秀給user看的參數
valScales: {
linear: {
func: (val) => {
@@ -21,11 +22,11 @@ export default {
us: 1,
ms: 1e3,
s: 1e6,
m: 60 * 1e6,
h: 60 * 60 * 1e6,
auto: 1,
minute: 60 * 1e6,
hour: 60 * 60 * 1e6,
},
defaultUnit: 'auto',
defaultUnit: 'ms',
downloadUnit: 'ms',
},
0: {
name: 'I_in',
@@ -34,16 +35,18 @@ export default {
uA: 1e3,
mA: 1e6,
},
defaultUnit: 'uA',
defaultUnit: 'mA',
downloadUnit: 'mA',
},
1: {
name: 'V_out-V_in',
name: 'Potential',
unit: {
uV: 1,
mV: 1e3,
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'mV',
},
2: {
name: 'V_out',
@@ -53,12 +56,13 @@ export default {
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'mV',
},
},
charts: {
default: [
{
name: 'Chronoamperometric Graph',
name: 'Chronoamperometric',
description: '',
subplot: [
{
@@ -0,0 +1,96 @@
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'], // 有要秀給user看的參數
headerParameter: () => ['Charge', 'Const_Current_value', 'SAMPLE_RATE', 'VOLTSTOP_MAX', 'VOLTSTOP_MIN', 'CC_CP_SPEED', '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',
},
},
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,
},
},
],
},
],
},
],
},
}
@@ -1,7 +1,8 @@
export default {
name: 'Constant Current',
parameter: ['ADC_LEVEL_I_15', 'ADC_LEVEL_V_IN_15', 'CTRL_HIGH_Z_15', 'SAMPLE_RATE', 'Charge', 'Const_Current_value', 'VOLTSTOP_MAX', 'VOLTSTOP_MIN'], // 這個mode用到的參數
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'], // 有要秀給user看的參數
headerParameter: () => ['Charge', 'Const_Current_value', 'SAMPLE_RATE', 'VOLTSTOP_MAX', 'VOLTSTOP_MIN', 'CC_CP_SPEED', 'ADC_LEVEL_I_15', 'ADC_LEVEL_V_IN_15'], // 有要秀給user看的參數
valScales: {
linear: {
func: (val) => {
@@ -21,11 +22,11 @@ export default {
us: 1,
ms: 1e3,
s: 1e6,
m: 60 * 1e6,
h: 60 * 60 * 1e6,
auto: 1,
minute: 60 * 1e6,
hour: 60 * 60 * 1e6,
},
defaultUnit: 'auto',
defaultUnit: 'ms',
downloadUnit: 'ms',
},
0: {
name: 'I_in',
@@ -34,7 +35,8 @@ export default {
uA: 1e3,
mA: 1e6,
},
defaultUnit: 'uA',
defaultUnit: 'mA',
downloadUnit: 'mA',
},
1: {
name: 'V_in',
@@ -44,6 +46,7 @@ export default {
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'mV',
},
2: {
name: 'V_out',
@@ -53,6 +56,7 @@ export default {
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'mV',
},
},
charts: {
@@ -1,7 +1,8 @@
export default {
name: 'Cycle I-V',
parameter: ['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'], // 這個mode用到的參數
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) => {
@@ -21,11 +22,11 @@ export default {
us: 1,
ms: 1e3,
s: 1e6,
m: 60 * 1e6,
h: 60 * 60 * 1e6,
auto: 1,
minute: 60 * 1e6,
hour: 60 * 60 * 1e6,
},
defaultUnit: 'auto',
defaultUnit: 'ms',
downloadUnit: 'ms',
},
0: {
name: 'I_in',
@@ -34,7 +35,8 @@ export default {
uA: 1e3,
mA: 1e6,
},
defaultUnit: 'uA',
defaultUnit: 'mA',
downloadUnit: 'mA',
},
1: {
name: 'V_out',
@@ -44,6 +46,7 @@ export default {
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'mV',
},
2: {
name: 'V_in',
@@ -53,13 +56,15 @@ export default {
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'mV',
},
3: {
name: 'Cycle',
name: 'Cycle number',
unit: {
cycle: 1,
},
defaultUnit: 'cycle',
downloadUnit: null,
},
},
charts: {
@@ -1,7 +1,8 @@
export default {
name: 'Cyclic Voltammetry',
parameter: ['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'], // 這個mode用到的參數
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) => {
@@ -23,9 +24,9 @@ export default {
s: 1e6,
m: 60 * 1e6,
h: 60 * 60 * 1e6,
auto: 1,
},
defaultUnit: 'auto',
defaultUnit: 'ms',
downloadUnit: 'ms',
},
0: {
name: 'I_in',
@@ -34,16 +35,18 @@ export default {
uA: 1e3,
mA: 1e6,
},
defaultUnit: 'uA',
defaultUnit: 'mA',
downloadUnit: 'mA',
},
1: {
name: 'V_out-V_in',
name: 'Potential',
unit: {
uV: 1,
mV: 1e3,
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'mV',
},
2: {
name: 'V_out',
@@ -53,13 +56,15 @@ export default {
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'mV',
},
3: {
name: 'Cycle',
name: 'Cycle number',
unit: {
cycle: 1,
},
defaultUnit: 'cycle',
downloadUnit: null,
},
},
charts: {
+110
View File
@@ -0,0 +1,110 @@
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,
},
},
],
},
],
},
],
},
}
@@ -1,6 +1,6 @@
export default {
name: 'Dev Mode',
parameter: [],
parameter: ['ADC_VALUE_I'],
valScales: {
linear: {
func: (val) => {
@@ -1,7 +1,8 @@
export default {
name: 'Function Generator',
parameter: ['ADC_LEVEL_I_15', 'ADC_LEVEL_V_IN_15', 'CTRL_HIGH_Z_15', 'DAC_VOLT', 'SAMPLE_RATE'], // 這個mode用到的參數
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'], // 有要秀給user看的參數
headerParameter: () => ['DAC_VOLT', 'SAMPLE_RATE', 'ADC_LEVEL_I_15', 'ADC_LEVEL_V_IN_15'], // export header的參數
valScales: {
linear: {
func: (val) => {
@@ -21,11 +22,11 @@ export default {
us: 1,
ms: 1e3,
s: 1e6,
m: 60 * 1e6,
h: 60 * 60 * 1e6,
auto: 1,
minute: 60 * 1e6,
hour: 60 * 60 * 1e6,
},
defaultUnit: 'auto',
defaultUnit: 'ms',
downloadUnit: 'ms',
},
0: {
name: 'I_in',
@@ -34,7 +35,8 @@ export default {
uA: 1e3,
mA: 1e6,
},
defaultUnit: 'uA',
defaultUnit: 'mA',
downloadUnit: 'mA',
},
1: {
name: 'V_out',
@@ -44,6 +46,7 @@ export default {
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'mV',
},
2: {
name: 'V_in',
@@ -53,6 +56,7 @@ export default {
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'mV',
},
},
charts: {
@@ -1,7 +1,8 @@
export default {
name: 'I-T Graph',
parameter: ['ADC_LEVEL_I_15', 'ADC_LEVEL_V_IN_15', 'CTRL_HIGH_Z_15', 'DAC_VOLT', 'SAMPLE_RATE'], // 這個mode用到的參數
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'], // 有要秀給user看的參數
headerParameter: () => ['DAC_VOLT', 'SAMPLE_RATE', 'ADC_LEVEL_I_15', 'ADC_LEVEL_V_IN_15'], // export header的參數
valScales: {
linear: {
func: (val) => {
@@ -21,11 +22,11 @@ export default {
us: 1,
ms: 1e3,
s: 1e6,
m: 60 * 1e6,
h: 60 * 60 * 1e6,
auto: 1,
minute: 60 * 1e6,
hour: 60 * 60 * 1e6,
},
defaultUnit: 'auto',
defaultUnit: 'ms',
downloadUnit: 'ms',
},
0: {
name: 'I_in',
@@ -34,7 +35,8 @@ export default {
uA: 1e3,
mA: 1e6,
},
defaultUnit: 'uA',
defaultUnit: 'mA',
downloadUnit: 'mA',
},
1: {
name: 'V_in',
@@ -44,6 +46,7 @@ export default {
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'mV',
},
2: {
name: 'V_out',
@@ -53,6 +56,7 @@ export default {
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'mV',
},
},
charts: {

Some files were not shown because too many files have changed in this diff Show More