Compare commits

..

310 Commits

Author SHA1 Message Date
TommyXin 120553f8c0 replay double markArea 2021-07-01 21:25:06 +08:00
TommyXin e50f2b5efc realtime elite unit 2021-07-01 20:07:34 +08:00
TommyXin c780fd7a57 realtime unit 2021-07-01 19:59:43 +08:00
TommyXin bd298b73bc interval & task config stimulate 2021-07-01 19:40:43 +08:00
TommyXin c3e2f7f6e5 task config 2021-07-01 13:54:26 +08:00
TommyXin c8c1abc2a5 [update] api opt 2021-06-27 23:42:17 +08:00
TommyXin dd5a8bfe27 Merge remote-tracking branch 'origin/master' into opt_ui_1 2021-06-19 11:50:39 +08:00
peterlu14 ac889e5410 Merge remote-tracking branch 'origin/feature/replay' 2021-06-16 02:24:31 +08:00
Jordan Hsu 9584d751fe [update] replay change log scale logic 2021-06-11 22:43:17 +08:00
Jordan Hsu fd31d41bdb [fix] elite cycle bug 2021-06-11 13:09:29 +08:00
peterlu14 9087f6776b Merge remote-tracking branch 'origin/feature/replay' 2021-06-10 18:48:26 +08:00
peterlu14 2cdd14d97d [update] elite download 2021-06-10 18:32:12 +08:00
Jordan Hsu fca7f1a093 [add] filetable delete selected files 2021-06-10 18:03:31 +08:00
Jordan Hsu e63e40caad Merge branch 'master' into feature/replay 2021-06-10 17:22:04 +08:00
peterlu14 68bf3cda73 [fix] elite range parameter mouse leave 2021-06-10 17:18:21 +08:00
Jordan Hsu fed196a0da [fix] elite overview bug 2021-06-10 14:35:44 +08:00
peterlu14 557629fb8c [fix] replay series data wrong index 2021-06-10 14:17:45 +08:00
Jordan Hsu 60f4e0fd10 [add] elite two mode 2021-06-10 10:22:15 +08:00
Jordan Hsu c72a55fd5a change parameter word style 2021-06-09 22:27:37 +08:00
Jordan Hsu da242910f6 [add] elite parameter and update UI layout 2021-06-09 22:02:01 +08:00
Jordan Hsu 3e62775857 remove redundant code 2021-06-09 20:06:42 +08:00
Jordan Hsu 2723d4dbb1 remove redundant code 2021-06-09 18:43:44 +08:00
Jordan Hsu f2b828b8af [add] check if show overview chart and update UI 2021-06-09 18:26:07 +08:00
Jordan Hsu 0954c8a778 [update] elite replay UI and fix change axis bug 2021-06-09 18:05:25 +08:00
Jordan Hsu 61616dead0 [update] change cycle logic and unit ohm default value 2021-06-09 17:58:36 +08:00
peterlu14 e9c339450f [update] y-interval default value 2021-06-09 14:10:03 +08:00
peterlu14 5ef75b972f [update] filename repeat & both button & replay download 2021-06-09 14:05:59 +08:00
Jordan Hsu dccc30df3d [add] change cycle vue 2021-06-09 14:03:39 +08:00
Jordan Hsu 90f78d2c24 [init] elite replay 2021-06-08 22:30:36 +08:00
Jordan Hsu 94c265da5d adjust elite parameter recording cycle min from 0 to 1 2021-06-08 18:29:54 +08:00
peterlu14 df52ad3ff9 Merge remote-tracking branch 'origin/feature/replay' 2021-06-08 17:55:14 +08:00
Jordan Hsu 341035f8c4 [hotfix] neulive UI layout bug 2021-06-08 17:05:19 +08:00
peterlu14 25740a6c82 Merge remote-tracking branch 'origin/feature/aboutPage' 2021-06-08 10:03:20 +08:00
peterlu14 c378dc5749 Merge branch 'feature/download-rebuild' 2021-06-08 10:01:32 +08:00
peterlu14 85be4bb558 Merge remote-tracking branch 'origin/opt_ui_1' 2021-06-08 10:01:24 +08:00
peterlu14 7f18bd4672 Merge remote-tracking branch 'origin/feature/replay' 2021-06-08 10:01:12 +08:00
peterlu14 a88833bf87 [update] file system restruct in vuex 2021-06-08 09:59:04 +08:00
TommyXin 30b4d3c76b [add] x-interval & y-interval 2021-06-07 21:14:56 +08:00
Jordan Hsu 74c58b131f [modify] adjust neulive UI layout 2021-06-07 19:02:02 +08:00
Jordan Hsu 266a227b47 [6/7] neulive replay, only wait for download function 2021-06-07 14:33:31 +08:00
Jordan Hsu 86f965a445 typo 2021-06-07 13:37:11 +08:00
Jordan Hsu 18fa86820d [add] replay toolbox: change scale (linear/log), [fix] small bug 2021-06-06 23:01:58 +08:00
Jordan Hsu c29dded14f [add] change min max panel position and remove redundant code 2021-06-06 09:40:47 +08:00
Jordan Hsu b72977b35f [fix] press button won't recover automatically 2021-06-04 18:08:55 +08:00
Jordan Hsu 7391e0a5a0 [add] neulive sti parameter illustration 2021-06-04 18:07:01 +08:00
Jordan Hsu e1a0d996ad [add] replay toolbox: set min/max and show param and use for neulive replay 2021-06-04 14:22:32 +08:00
Jordan Hsu 2ba5fb2683 [add] replay toolbox and use for neulive replay top panel 2021-06-03 22:57:04 +08:00
TommyXin 671b8ad668 [feature] multiple file replay 2021-06-02 03:11:05 +08:00
TommyXin 0de6d455a0 neulive replay opt 2021-06-02 02:28:07 +08:00
peterlu14 9d4836ee28 [update] sample rate 20K 2021-05-31 13:41:01 +08:00
peterlu14 d49dbfda43 [fix] neulive amp gain wrong index 2021-05-26 02:40:43 +08:00
peterlu14 73edf21824 [update] controller & device info setting page 2021-05-20 03:59:25 +08:00
peterlu14 486fc067ea Merge branch 'fix/replay_mini_no_data' 2021-05-14 00:15:20 +08:00
peterlu14 ad404819b3 Merge branch 'fix/replay_mini_no_data' into feature/aboutPage 2021-05-12 11:46:16 +08:00
peterlu14 8732386d45 [update] remove formula & filename duplicate 2021-05-12 11:44:08 +08:00
TommyXin bed8e72340 clear neulive replay 2021-05-10 20:05:26 +08:00
peterlu14 67a397c27d [fix] edit filename & change accS & side bar hide & per sampleRate 2021-05-09 23:14:49 +08:00
peterlu14 51dfcfd335 [fix] replay ch+1 & download format & RF & STI_T3 2021-05-06 15:34:53 +08:00
peterlu14 49896d3465 Merge remote-tracking branch 'origin/fix/neulive_bugs' into fix/replay_mini_no_data 2021-05-03 09:04:54 +08:00
TommyXin f05581dcf9 change data stream format 2021-04-29 20:14:43 +08:00
peterlu14 ed526604b9 Merge branch 'feature/download_temp' into fix/replay_mini_no_data 2021-04-29 18:11:46 +08:00
peterlu14 94e6e1153f [update] replay not showing 2021-04-29 18:10:23 +08:00
peterlu14 5a4c91e5bc [fix] NaN time 2021-04-28 11:08:15 +08:00
peterlu14 7ea36c565e [update] about page white list connect 2021-04-28 11:06:20 +08:00
peterlu14 bc38b1bcc8 [fix] download error 2021-04-27 10:43:17 +08:00
peterlu14 fe6622b86c Merge remote-tracking branch 'origin/fix/neulive_bugs' 2021-04-26 22:01:38 +08:00
TommyXin b12332eaac Merge remote-tracking branch 'origin/fix/neulive_bugs' into fix/neulive_bugs 2021-04-26 22:01:10 +08:00
TommyXin 8267dbd302 update 4/26 2021-04-26 22:00:52 +08:00
peterlu14 5653c4d3de [update] about content & add new api and factory 2021-04-22 11:32:11 +08:00
peterlu14 227d61d8e4 [update] about page vuex 2021-04-22 11:31:14 +08:00
peterlu14 94b0a795e4 [update] download split file temp 2021-04-20 16:44:40 +08:00
peterlu14 d09405755f Merge remote-tracking branch 'origin/master_sps' 2021-04-19 16:21:00 +08:00
Roy 9c83b6e4f8 RT receive resister in denomination of mOhm 2021-04-19 15:56:26 +08:00
peterlu14 38bd091d44 [update] broadcast stop remove streambuffer 2021-04-16 21:09:52 +08:00
peterlu14 4bf2e529c0 Merge remote-tracking branch 'origin/master_sps' 2021-04-16 16:06:02 +08:00
Roy 0803b2b8ab remove Data_Resolution_Scan, and use SAMPLE_RATE only 2021-04-16 13:03:25 +08:00
royluo c6436b205d remove ADC_Test and Cyclic Voltammetry-hi-cycles mode 2021-04-14 15:43:06 +08:00
royluo 0796621f3b Merge remote-tracking branch 'origin/master' into master_sps 2021-04-14 13:45:25 +08:00
peterlu14 af87e9b122 [fix] neulive replay split-number replace max-min 2021-04-13 18:57:54 +08:00
royluo 184ce1af5f new sps on IT.VT.RT.CC.VOUT mode 2021-04-13 11:21:46 +08:00
peterlu14 2dced2922a [fix] elite replay worng channel data 2021-04-13 10:40:44 +08:00
peterlu14 fd06ce3018 Merge branch 'fix/neulive_bugs' 2021-04-09 15:08:39 +08:00
peterlu14 6a4db3512e Merge remote-tracking branch 'origin/feature/elite_display' 2021-04-09 15:08:32 +08:00
peterlu14 24d1ac3438 [fix] replay splice spread 2021-04-08 19:32:42 +08:00
Jordan Hsu 7749d33105 [modify] neulive replay show time fixed to h m s 2021-04-08 17:29:51 +08:00
Jordan Hsu 7dd8d5eb77 [add] elite replay resample rate 2021-04-08 16:26:43 +08:00
Jordan Hsu 2d0c865e13 [add] both replay delete button 2021-04-08 16:15:42 +08:00
Jordan Hsu a6300e8e40 [add] both replay download button 2021-04-08 15:31:19 +08:00
Jordan Hsu e45ef9d8de remove redundant code 2021-04-08 14:33:31 +08:00
Jordan Hsu e6ef637c97 [fix] elite replay hover edge unit bug 2021-04-08 13:45:03 +08:00
Jordan Hsu 49cf46fe44 [add] elite replay change filename button 2021-04-08 13:19:17 +08:00
Jordan Hsu c7add6f7da [fix] elite replay graph blank bug 2021-04-08 13:01:23 +08:00
Jordan Hsu 4c562e720a [add and fix elite] add auto detect mode and change x y, fix Resistance bug 2021-04-08 11:57:29 +08:00
peterlu14 05e55d4dbf [update] download speed increase 2021-04-08 11:34:06 +08:00
Jordan Hsu f24f5f6636 [add] neulive replay can change filename 2021-04-01 14:54:10 +08:00
Jordan Hsu 6441e5d2ec [modify] filename and param display to vuex style 2021-04-01 13:22:31 +08:00
Jordan Hsu c75089f10e [fix] button color won't recover in scan and stop all 2021-03-31 11:58:07 +08:00
Jordan Hsu d28538cebe [fix] button color won't recover by adding no-dark-style-va-button class 2021-03-31 11:28:26 +08:00
Jordan Hsu 5cb9924e7d [fix] elite axis unit won't change with axis bug 2021-03-31 10:47:48 +08:00
Jordan Hsu eab9ee944a Merge remote-tracking branch 'origin/fix/neulive_bugs' into feature/elite_display 2021-03-31 10:42:56 +08:00
peterlu14 076469e270 [fix] onchange & hide detect 2021-03-31 00:25:09 +08:00
peterlu14 950c5dcc55 [update] stimulate & fast settle buttons 2021-03-31 00:24:25 +08:00
peterlu14 0831873136 [fix] replay data only has scale 1 cause error 2021-03-30 15:28:19 +08:00
peterlu14 d9700b96d3 [update] time scale && time formatter 2021-03-29 17:01:01 +08:00
peterlu14 7234692e67 [fix] onchange input 2021-03-29 16:57:04 +08:00
peterlu14 ca12e1858c [update] size-time float to string 2021-03-29 16:38:59 +08:00
peterlu14 fae9308bed Merge remote-tracking branch 'origin/feature/elite_display' 2021-03-29 16:33:02 +08:00
Jordan Hsu 6b1fee3f5f [fix] zoom bug 2021-03-25 17:51:27 +08:00
Jordan Hsu 5834172d96 [fix and todo] fix: distribute function axis bug, todo: but zoom in will show nothing 2021-03-25 17:23:43 +08:00
Jordan Hsu 598fe285bf [add] hide grid function 2021-03-25 16:41:12 +08:00
Jordan Hsu 0580a15e25 Merge remote-tracking branch 'origin/master' into feature/elite_display 2021-03-25 14:29:37 +08:00
peterlu14 dece25f2ff [fix] devices list hide start not working 2021-03-24 16:48:05 +08:00
peterlu14 2e58d1d9f6 [fix] sti pattern time error & hide detect 2021-03-24 11:45:01 +08:00
Jordan Hsu 6fe57af6bd [to test] neulive replay double click bug 2021-03-19 19:30:47 +08:00
Jordan Hsu 35b5c7681b [modify] neulive channelID -> id 2021-03-19 15:19:06 +08:00
Jordan Hsu bd0517c8d1 [modify] adjust elite display min max function UI panel 2021-03-19 15:19:06 +08:00
Jordan Hsu fd08f45278 [remove] neulive replay redundant code 2021-03-19 15:19:06 +08:00
peterlu14 f0a06f0370 Merge branch 'feature/neulive_bugs' 2021-03-19 14:58:59 +08:00
peterlu14 4001bb8f58 [fix] recoring & stimulate bugs 2021-03-19 14:57:46 +08:00
peterlu14 fc9140115b [fix] cycle data bug 2021-03-19 12:10:44 +08:00
Jordan Hsu 18800cc142 [modify] neulive valueRange id from string to int 2021-03-18 18:13:30 +08:00
Jordan Hsu f3aeb8931f [fix] elite replay max min bug 2021-03-18 18:09:45 +08:00
Jordan Hsu 6543dc07fa [modify] neulive remove mapMultiRowFields 2021-03-18 17:53:50 +08:00
Jordan Hsu 841a2f1f85 [fix] neulive replay max min bug 2021-03-18 17:35:52 +08:00
Jordan Hsu 805a582b5d [fix] elite replay watch small bug 2021-03-18 16:43:43 +08:00
Jordan Hsu 6e3548eca0 [fix] neulive replay to vuex error 2021-03-18 16:41:35 +08:00
Jordan Hsu b676987f29 Merge remote-tracking branch 'origin/feature/elite_display' into feature/elite_display 2021-03-18 16:32:56 +08:00
Jordan Hsu 74aba10199 [add] vuex-map-field package and elite replay to vuex 2021-03-18 16:30:37 +08:00
Jordan Hsu 23f0130564 [codeReview] convert partial elite replay code to vuex style 2021-03-18 16:07:39 +08:00
Jordan Hsu 69b2d8b3bd [codeReview] convert partial neulive replay code to vuex style 2021-03-18 16:07:39 +08:00
peterlu14 55e7f9b857 [fix] replay scale bug 2021-03-18 16:03:34 +08:00
Jordan Hsu a4fe50898a [codeReview] convert partial elite replay code to vuex style 2021-03-18 14:26:13 +08:00
Jordan Hsu b290093ad9 [codeReview] convert partial neulive replay code to vuex style 2021-03-18 14:25:19 +08:00
peterlu14 675aa7001c [fix] elite replay get empty scale 2021-03-18 10:14:23 +08:00
Jordan Hsu e9d343461a Merge branch 'feature/elite_display' 2021-03-18 09:53:27 +08:00
Jordan Hsu 987a840923 [fix] neulive bug 2021-03-18 09:51:40 +08:00
peterlu14 f0c811e402 [recover] controller_id 2021-03-16 10:21:23 +08:00
peterlu14 8e87c4492e Merge remote-tracking branch 'origin/master_detect' 2021-03-16 10:16:34 +08:00
peterlu14 1e39d25cff Merge branch 'fix/replay_bug' 2021-03-16 10:15:47 +08:00
peterlu14 ff855de99a [update] elite replay get all data 2021-03-16 10:15:14 +08:00
peterlu14 3a2ae1703f [update] n-replay get all data & default second 2021-03-16 10:14:16 +08:00
peterlu14 56421aca14 [update] new api & get mini files change ways 2021-03-16 10:12:54 +08:00
peterlu14 50ae46a8f2 [fix] file path reassign 2021-03-16 10:11:27 +08:00
peterlu14 33dd3c6cc8 Merge remote-tracking branch 'origin/feature/elite_display' into fix/replay_bug 2021-03-14 23:51:58 +08:00
Jordan Hsu cd52ca351c [modify] ui layout 2021-03-12 19:00:21 +08:00
Jordan Hsu debe6acd73 [modify] neulive display valueRange to vuex and bug fix 2021-03-12 17:22:51 +08:00
Jordan Hsu fa4539efc6 [add] current scale 2021-03-12 15:17:07 +08:00
Jordan Hsu 3086b2781d [fix] [modify] neulive replay y axis show only 3 interval 2021-03-11 15:58:04 +08:00
Jordan Hsu e05893d606 [modify] neulive replay y axis show only 3 interval 2021-03-11 14:12:45 +08:00
Jordan Hsu 487d830cd0 Merge remote-tracking branch 'origin/fix/replay_bug' into feature/elite_display 2021-03-11 10:34:04 +08:00
royluo 7b2d2a7375 Merge remote-tracking branch 'origin/fix/replay_bug' into master_detect 2021-03-10 16:07:32 +08:00
royluo af3b3fd18f update sample rate button 2021-03-10 15:44:53 +08:00
royluo cdac8ed871 update feature of detection 2021-03-10 09:26:54 +08:00
royluo e0bdf00e81 update feature of detection 2021-03-09 16:42:20 +08:00
royluo b716058f91 update feature of detection 2021-03-09 14:52:52 +08:00
royluo af405c951f new feature of detection 2021-03-09 10:02:40 +08:00
peterlu14 adee49335c [update] replay open new window 2021-03-09 01:38:40 +08:00
peterlu14 725413dbe3 [update] sample rate ui 2021-03-09 01:34:18 +08:00
peterlu14 890d0aa888 [update] series.data splice according to library 2021-03-09 01:33:43 +08:00
peterlu14 7788bde9be [update] disable file component keepAlive 2021-03-09 01:32:32 +08:00
peterlu14 22afaf746f [update] remove fixed scale 2021-03-02 20:14:06 +08:00
peterlu14 01ed8df633 [update] instruction diff from library 2021-03-02 15:50:49 +08:00
peterlu14 03662d8762 [update] instruction recover 2021-03-02 11:52:49 +08:00
peterlu14 6e811fafef [update] start button replace record button 2021-03-02 11:26:18 +08:00
peterlu14 4ed1b45eb1 Merge remote-tracking branch 'origin/feature/elite_display' 2021-02-28 16:56:04 +08:00
peterlu14 2329d9f40f Merge remote-tracking branch 'origin/master_update1.5UI' 2021-02-28 16:55:58 +08:00
Jordan Hsu 7b832fa5b2 [add] elite grid x, y min and max 2021-02-27 00:07:55 +08:00
Jordan Hsu 11233ffbf6 [add] neulive select x and y unit 2021-02-26 22:04:25 +08:00
Jordan Hsu 53492b5373 [add] neulive control each grid y min and max 2021-02-26 20:21:07 +08:00
Jordan Hsu 1c36aae2ff [add] elite display parameter panel 2021-02-26 17:05:53 +08:00
Jordan Hsu c501485ecd [add] neulive filename 2021-02-25 21:57:14 +08:00
Jordan Hsu d2cd90b593 [add] elite display x y axis format 2021-02-25 21:49:54 +08:00
royluo 92dc397d39 [update] fix start/stop/start all/stop all 2021-02-25 18:38:11 +08:00
Jordan Hsu 483bc7e2c9 Merge remote-tracking branch 'origin/feature/neulive3.0-sti' into feature/elite_display 2021-02-25 17:28:35 +08:00
Jordan Hsu 4ebe429130 [add] after edit, delete then go to same page 2021-02-25 17:13:20 +08:00
Jordan Hsu 7dabbac852 [add] when previous page, not refresh 2021-02-25 16:04:23 +08:00
Jordan Hsu f62e8d6d5b [add] replay to neulive or elite 2021-02-25 16:03:49 +08:00
Jordan Hsu 2efa3c50f3 [bugfix] consider may have no cycle channel data (channelCycleID) 2021-02-25 14:03:15 +08:00
royluo 58308232d7 [update] fix button of Mode(out of control) 2021-02-25 13:12:36 +08:00
royluo 88a41d1376 [update] default chart for LSV & CA mode 2021-02-24 18:07:53 +08:00
royluo b851476ec1 [update] fix button of MilliVoltRange 2021-02-24 17:13:28 +08:00
royluo b11dff070f [update] fix button of MicroAmpereRange 2021-02-24 15:03:39 +08:00
royluo 0ae7dd57c9 [update] fix button of voltrange 2021-02-24 12:08:44 +08:00
royluo 1d78071615 [update] fix button of voltrange 2021-02-24 11:07:18 +08:00
peterlu14 5a1fd1d769 [update] channel 8 -> 16 && scale fixed 2021-02-23 18:00:34 +08:00
royluo 7d838b591a [update] fix button of cycle & resolution & scanrate 2021-02-23 17:22:13 +08:00
royluo 5fae7722d9 [update] fix button of cycle & resolution 2021-02-23 15:54:26 +08:00
royluo 392302e297 [update] fix button of cycle 2021-02-23 11:25:51 +08:00
peterlu14 77519a2898 [update] start button replace record button 2021-02-20 23:01:13 +08:00
peterlu14 c9278a96c6 [update] stimulate amplitude fixed 2021-02-20 22:59:20 +08:00
peterlu14 c5a02ab3de Merge branch 'release/merge_all_features' 2021-02-20 22:41:22 +08:00
peterlu14 9f41788605 [update] elite replay time * 1000 & filename repeat 2021-02-20 22:08:01 +08:00
peterlu14 3d69393be7 Merge remote-tracking branch 'origin/feature/practice_for_project_scheduler' into release/merge_all_features 2021-02-20 19:12:13 +08:00
peterlu14 ef3c656ded Merge branch 'feature/elite_display_ui' into release/merge_all_features 2021-02-20 19:10:32 +08:00
peterlu14 15f442207d Merge branch 'master-with-axis' into release/merge_all_features 2021-02-20 19:08:57 +08:00
peterlu14 49509301ab Merge branch 'feature/bash_script' into 'master'
[add] burn to raspberry script

See merge request bioproscientific/bioprovue!1
2021-02-20 09:21:25 +00:00
Jordan Hsu 870cc6117d Merge branch 'develop' into feature/elite_display_ui 2021-02-19 21:43:10 +08:00
Jordan Hsu d9ad286f02 Merge branch 'feature/file_system' into develop 2021-02-19 21:36:21 +08:00
Jordan Hsu b084ce762d [fix] start all time bug 2021-02-19 21:02:48 +08:00
Jordan Hsu ea534a230b [modify] filename check duplicate 2021-02-19 20:35:11 +08:00
Jordan Hsu 20df0040fc [add] burn to raspberry script 2021-02-19 19:12:24 +08:00
Jordan Hsu 818009ad78 [modify] burn target id 2021-02-19 19:11:00 +08:00
Jordan Hsu 2130d43a78 ready to test file delete, wait for api fix 2021-02-19 18:09:06 +08:00
Jordan Hsu 036d09fa90 backup 2021-02-19 17:25:33 +08:00
Jordan Hsu 5e24f2775a [modify] re-align x y button 2021-02-19 15:12:37 +08:00
peterlu14 189e9b4507 [update] scale in time splice data fixed 2021-02-19 14:31:18 +08:00
peterlu14 17317f90a0 [update] ms -> us & M-Axis & download fix & series data splice changed 2021-02-19 14:21:00 +08:00
Jordan Hsu 8efa76b789 [add] log scale setting 2021-02-18 19:50:23 +08:00
Jordan Hsu d4ff7e7d70 elite display ui bug fix 2021-02-18 14:43:17 +08:00
royluo 64a3c7a788 [update] recovery controller id 2021-02-17 15:07:49 +08:00
Jordan Hsu 78ba7af72c [Done] Elite UI single chart 2021-02-05 23:08:17 +08:00
Jordan Hsu b589ad8e18 [add] single chart with cycle selection and bug fix 2021-02-05 21:52:44 +08:00
Jordan Hsu b487ec2c32 [add] single chart with default I-V chart 2021-02-05 20:51:00 +08:00
Jordan Hsu 6215e6faea backup for single chart 2021-02-05 15:42:10 +08:00
royluo f4a1fcedb8 [update] update dev mode 2021-02-05 15:05:35 +08:00
peterlu14 9f20d040f7 [update] axis_data 2021-02-05 13:31:28 +08:00
Jordan Hsu b3ff304882 [modify] implement all [todo] 2021-02-04 18:28:48 +08:00
Jordan Hsu 09b6504b6a [init] elite replay UI 2021-02-04 18:04:22 +08:00
Jordan Hsu 45c8021203 [add] start time date and time picker 2021-02-04 12:32:55 +08:00
Jordan Hsu 2cf7a95ed9 [modify] decouple param panel 2021-02-03 17:58:18 +08:00
royluo 78f38d0e1a [update] new dev mode 2021-02-03 16:27:19 +08:00
Jordan Hsu f3d890fe69 [add] maxcycle, addtask, stimulate & record checkbox 2021-02-03 14:22:58 +08:00
Jordan Hsu 5ff367ba26 [fix] condition template update bug 2021-01-29 16:42:52 +08:00
Jordan Hsu 3a24f1c3d0 [add] condition setting to global and finish condition template
[TODO] condition template update bug
2021-01-29 16:10:57 +08:00
Jordan Hsu ae9f34bcc5 remove some redundant 2021-01-28 21:39:31 +08:00
Jordan Hsu 8d5ad18726 [add] device setting to global, [TODO] forceUpdate 2021-01-28 19:05:46 +08:00
Jordan Hsu 16b2ac54c7 tmp 2021-01-28 11:24:39 +08:00
Jordan Hsu 2fd311fac1 [fix] add param check if no any setting 2021-01-27 15:00:38 +08:00
Jordan Hsu 0872253ceb [add] can update device param mapping 2021-01-27 14:52:27 +08:00
Jordan Hsu 588b863c5e fix 2021-01-20 21:32:20 +08:00
Jordan Hsu 4a0f6e4c8f [fix] some ui error 2021-01-20 19:40:32 +08:00
Jordan Hsu 42a6cc7222 [Done] output json 2021-01-20 18:54:15 +08:00
Jordan Hsu 468208697f [TODO] ready to generate json 2021-01-20 17:22:07 +08:00
Jordan Hsu 046821b7d3 [modify] redundant code 2021-01-20 12:13:50 +08:00
Jordan Hsu af5a31289b [done] mapping panel 2021-01-19 18:45:53 +08:00
Jordan Hsu 3978815f9c [modify] device mapping panel to button with modal 2021-01-19 16:02:31 +08:00
Jordan Hsu d376a8399b [add] id generator 2021-01-19 00:37:56 +08:00
Jordan Hsu 9a5d1a9007 [TODO] map action with condition and instructions 2021-01-18 19:23:42 +08:00
Jordan Hsu 1a03ca4fee [modify] Param json add key recording and stimulation 2021-01-18 16:35:11 +08:00
peterlu14 c09d79a6f5 [update] export channel fixed 2021-01-18 15:05:04 +08:00
peterlu14 33b9ce8f01 [update] fileName and parent fixed 2021-01-18 15:04:03 +08:00
peterlu14 b004434bf9 [update] record button fix event 2021-01-18 14:06:16 +08:00
Jordan Hsu ecc977cb73 [TODO] device map param data store to state 2021-01-17 23:15:36 +08:00
Jordan Hsu 7c372c35f9 [done] param panel dataflow 2021-01-17 16:27:02 +08:00
Jordan Hsu d58941fa41 [done] param panel ui
[TODO] vuex dataflow
2021-01-17 13:17:49 +08:00
Jordan Hsu 56ac5630d0 [TODO] amp gain 2021-01-16 21:34:15 +08:00
Jordan Hsu 230cc98dab try to add param panel 2021-01-16 17:11:44 +08:00
peterlu14 eb734aa645 [update] recover recording channels 2021-01-15 16:56:26 +08:00
peterlu14 3173e349fb [update] add accelerometer & record button 2021-01-15 16:53:38 +08:00
peterlu14 7bb8378762 [update] download and export new format data & add meta info 2021-01-14 16:45:38 +08:00
TommyXin b4c9e04075 Merge remote-tracking branch 'origin/master' 2021-01-13 18:10:53 +08:00
TommyXin 4fab05da44 [update] change datastream buffer into format 2021-01-13 18:10:42 +08:00
peterlu14 ba11499d80 [update] Neulive record & connect update calibration 2021-01-12 15:38:00 +08:00
TommyXin 2a09132a16 [update] try to use new data real time format 2021-01-11 20:12:47 +08:00
peterlu14 08061eb23e [update] delete TaskInfoFormat and add parameter 2021-01-11 15:00:54 +08:00
peterlu14 4c3f36010c Merge branch 'develop/elite1.5' 2021-01-11 14:53:57 +08:00
royluo 700cb94dd5 [update] update button:E-init 2021-01-08 14:33:57 +08:00
TommyXin a91e4862c8 [vuex] [replay] add rec & meta to store 2021-01-06 22:41:53 +08:00
TommyXin 8efb8d4dc0 [update] [vuex] replay 2021-01-04 21:19:58 +08:00
TommyXin 96f8a9ad96 [update] [replay] [vuex] add type path 2020-12-30 22:14:28 +08:00
TommyXin 9cba5e2d0e [update] [replay] optimize replay vuex format 2020-12-30 22:10:40 +08:00
royluo b0a3f51cd0 [update] solve Rounding problem of Volt 2020-12-29 10:27:33 +08:00
TommyXin a5c7133b84 [update] [replay] delete chartmanament.js 2020-12-28 22:48:26 +08:00
TommyXin 97889af002 [update] [replay] import vuex & apply to replay/neulive 2020-12-28 22:40:32 +08:00
TommyXin 37159bad12 [update] delete taskInfoFormat 2020-12-28 19:03:58 +08:00
TommyXin 49859eae05 [update] add factories to manage data format 2020-12-28 19:02:42 +08:00
royluo 84557194e4 [update] fix stop button's instruction(auto stop) 2020-12-28 17:25:23 +08:00
royluo 1ad639e2a0 [update] new component ResolutionRange 2020-12-28 15:36:08 +08:00
royluo 952b04ffe2 [update] new component ResolutionRange 2020-12-28 14:38:32 +08:00
royluo 9705b2045c [update] new component ScanRateRange 2020-12-28 11:21:24 +08:00
royluo 419b3d323f [update] new component (not ready) 2020-12-28 09:27:36 +08:00
royluo becedd0fa7 [update] new component OppLevelButton 2020-12-24 18:26:12 +08:00
royluo 1578a72dee [update] new component LevelRange 2020-12-24 09:25:54 +08:00
TommyXin 504eee4d73 [update] optimize replay chart 2020-12-23 20:00:25 +08:00
royluo 02a811ecfb [update] new component LevelRange 2020-12-23 18:29:14 +08:00
royluo ab6d52e50b [update] new component MilliVoltRange 2020-12-23 14:43:24 +08:00
TommyXin 6c96b40e4b [update] [task] parameter item component sample 2020-12-22 18:07:53 +08:00
royluo e28271249c change project to task in 'ParameterWindow' 2020-12-22 16:19:19 +08:00
TommyXin 1751af9c31 Merge branch 'master' into develop/elite1.5 2020-12-22 16:12:04 +08:00
royluo 4b599e06ca [update] new elite1.5 UI 2020-12-22 16:01:06 +08:00
peterlu14 750a466707 [update] filename refresh & data last entry empty error & left grid space 2020-12-21 17:11:07 +08:00
royluo 06c2e70cb7 [update] new elite1.5 UI(I-V Curve) 2020-12-18 17:50:49 +08:00
royluo e1da25b549 [update] new elite1.5 UI(I-V Curve) 2020-12-18 17:40:50 +08:00
royluo b28dbc6e27 [update] new elite1.5 UI 2020-12-17 17:46:34 +08:00
peterlu14 e951426d7a [update] [fix] create collection error & not export last line data 2020-12-17 17:07:06 +08:00
peterlu14 cb86d14144 [update] fix search error & fix export file end_time != -1 2020-12-17 17:06:09 +08:00
peterlu14 f6df94228c Merge branch 'project-to-task' 2020-12-17 16:52:51 +08:00
TommyXin cb563b3510 [update] [replay] fix end_time <0 2020-12-16 19:36:34 +08:00
TommyXin a1ef860b8f [update] remove scan1 2020-12-16 18:39:03 +08:00
peterlu14 f68ea5c1a5 [update] rename project into task 2020-12-15 20:20:32 +08:00
peterlu14 29eb4f8736 [update] recover Vuemqtt setting & device filename fixed while running 2020-12-15 18:44:37 +08:00
TommyXin 93660d66ad [update] data replay default max scale 2020-12-15 16:14:24 +08:00
peterlu14 6ae3bbf066 [update] filename & mqtt connection 2020-12-14 14:52:11 +08:00
peterlu14 4cc29e7c93 [update] file name init & locale time 2020-12-11 11:45:39 +08:00
peterlu14 b639689a5b [update] replay chart style change & destroy fix 2020-12-10 23:20:38 +08:00
peterlu14 9d531d083f [update] file direct to replay & axios baseURL & replay destroy 2020-12-10 22:39:03 +08:00
peterlu14 942574f859 [update] filenameControl & export & download 2020-12-10 17:43:51 +08:00
TommyXin 551d49ceb1 [update] data replay TIME x-axis 2020-12-10 04:32:06 +08:00
TommyXin 316c3b0146 [update] replay data register 2020-12-09 15:03:29 +08:00
peterlu14 8d9f812a85 [update] optimize download rawData and miniData api 2020-12-04 03:19:55 +08:00
TommyXin 381891693b Merge remote-tracking branch 'origin/master' 2020-12-03 03:06:52 +08:00
TommyXin dacb9e9c13 [update] api & data replay 2020-12-03 03:06:41 +08:00
peterlu14 8c88df519b [update] update get raw api 2020-12-03 02:58:38 +08:00
TommyXin 6c08e07148 Auto stash before merge of "master" and "origin/master" 2020-12-03 02:56:14 +08:00
peterlu14 092709e54f [update] add get raw and mini api 2020-12-03 01:57:46 +08:00
TommyXin 37865c137e [update] chart management 2020-12-03 00:56:35 +08:00
TommyXin 695745433c Merge remote-tracking branch 'origin/master' 2020-12-01 21:31:09 +08:00
TommyXin a8c9d5d7fc [update] data replay param 2020-12-01 21:30:57 +08:00
peterlu14 cdb9966c99 [update] add download data api 2020-12-01 20:04:47 +08:00
peterlu14 08c4731f20 Merge commit 'adfab9f9fe5485527fa3baf45e9a1fe94eb72a9e' 2020-12-01 19:18:55 +08:00
211 changed files with 17661 additions and 4036 deletions
+204 -137
View File
@@ -3012,11 +3012,18 @@
"dev": true
},
"axios": {
"version": "0.19.2",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz",
"integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==",
"version": "0.21.1",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz",
"integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==",
"requires": {
"follow-redirects": "1.5.10"
"follow-redirects": "^1.10.0"
},
"dependencies": {
"follow-redirects": {
"version": "1.13.3",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.3.tgz",
"integrity": "sha512-DUgl6+HDzB0iEptNQEXLx/KhTmDb8tZUHSeLqpnjpknR70H0nC2t9N73BK6fN4hOvJ84pKlIQVQ4k5FFlBedKA=="
}
}
},
"babel-code-frame": {
@@ -3465,9 +3472,9 @@
}
},
"bl": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz",
"integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==",
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/bl/-/bl-1.2.3.tgz",
"integrity": "sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww==",
"requires": {
"readable-stream": "^2.3.5",
"safe-buffer": "^5.1.1"
@@ -5114,9 +5121,9 @@
"dev": true
},
"copy-webpack-plugin": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-5.1.1.tgz",
"integrity": "sha512-P15M5ZC8dyCjQHWwd4Ia/dm0SgVvZJMYeykVIVYXbGyqO4dWB5oyPHp9i7wjwo5LhtlhKbiBCdS2NvM07Wlybg==",
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-5.1.2.tgz",
"integrity": "sha512-Uh7crJAco3AjBvgAy9Z75CjK8IG+gxaErro71THQ+vv/bl4HaQcpkexAY8KVW/T6D2W2IRr+couF/knIRkZMIQ==",
"dev": true,
"requires": {
"cacache": "^12.0.3",
@@ -5129,7 +5136,7 @@
"normalize-path": "^3.0.0",
"p-limit": "^2.2.1",
"schema-utils": "^1.0.0",
"serialize-javascript": "^2.1.2",
"serialize-javascript": "^4.0.0",
"webpack-log": "^2.0.0"
},
"dependencies": {
@@ -5180,10 +5187,13 @@
}
},
"serialize-javascript": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.2.tgz",
"integrity": "sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ==",
"dev": true
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz",
"integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==",
"dev": true,
"requires": {
"randombytes": "^2.1.0"
}
},
"slash": {
"version": "1.0.0",
@@ -5643,6 +5653,7 @@
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
"dev": true,
"requires": {
"ms": "2.0.0"
}
@@ -6178,11 +6189,11 @@
}
},
"echarts": {
"version": "4.8.0",
"resolved": "https://registry.npmjs.org/echarts/-/echarts-4.8.0.tgz",
"integrity": "sha512-YwShpug8fWngj/RlgxDaYrLBoD+LsZUArrusjNPHpAF+is+gGe38xx4W848AwWMGoi745t3OXM52JedNrv+F6g==",
"version": "4.9.0",
"resolved": "https://registry.npmjs.org/echarts/-/echarts-4.9.0.tgz",
"integrity": "sha512-+ugizgtJ+KmsJyyDPxaw2Br5FqzuBnyOWwcxPKO6y0gc5caYcfnEUIlNStx02necw8jmKmTafmpHhGo4XDtEIA==",
"requires": {
"zrender": "4.3.1"
"zrender": "4.3.2"
}
},
"editorconfig": {
@@ -6248,24 +6259,24 @@
}
},
"elliptic": {
"version": "6.5.3",
"resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz",
"integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==",
"version": "6.5.4",
"resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz",
"integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==",
"dev": true,
"requires": {
"bn.js": "^4.4.0",
"brorand": "^1.0.1",
"bn.js": "^4.11.9",
"brorand": "^1.1.0",
"hash.js": "^1.0.0",
"hmac-drbg": "^1.0.0",
"inherits": "^2.0.1",
"minimalistic-assert": "^1.0.0",
"minimalistic-crypto-utils": "^1.0.0"
"hmac-drbg": "^1.0.1",
"inherits": "^2.0.4",
"minimalistic-assert": "^1.0.1",
"minimalistic-crypto-utils": "^1.0.1"
},
"dependencies": {
"bn.js": {
"version": "4.11.9",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz",
"integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==",
"version": "4.12.0",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
"integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==",
"dev": true
}
}
@@ -7482,15 +7493,6 @@
"reusify": "^1.0.4"
}
},
"faye-websocket": {
"version": "0.10.0",
"resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz",
"integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=",
"dev": true,
"requires": {
"websocket-driver": ">=0.5.1"
}
},
"fb-watchman": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz",
@@ -7691,6 +7693,7 @@
"version": "1.5.10",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz",
"integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==",
"dev": true,
"requires": {
"debug": "=3.1.0"
}
@@ -8478,6 +8481,12 @@
}
}
},
"http-parser-js": {
"version": "0.5.3",
"resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.3.tgz",
"integrity": "sha512-t7hjvef/5HEK7RWTdUzVUhl8zkEu+LlaE0IYzdMuvbSDipxBRpOn4Uhw8ZyECEa808iVT8XCjzo6xmYt4CiLZg==",
"dev": true
},
"http-proxy": {
"version": "1.18.1",
"resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz",
@@ -8660,9 +8669,9 @@
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
"ini": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
"integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==",
"version": "1.3.8",
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
"integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
"dev": true
},
"inquirer": {
@@ -10926,9 +10935,9 @@
}
},
"lodash": {
"version": "4.17.15",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A=="
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
},
"lodash._reinterpolate": {
"version": "3.0.0",
@@ -11635,6 +11644,14 @@
"resolved": "https://registry.npmjs.org/moment/-/moment-2.27.0.tgz",
"integrity": "sha512-al0MUK7cpIcglMv3YF13qSgdAIqxHTO7brRtaz3DlSULbqfazqkc5kEjNrLDOM7fsjshoFIihnU8snrP7zUvhQ=="
},
"moment-range": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/moment-range/-/moment-range-4.0.2.tgz",
"integrity": "sha512-n8sceWwSTjmz++nFHzeNEUsYtDqjgXgcOBzsHi+BoXQU2FW+eU92LUaK8gqOiSu5PG57Q9sYj1Fz4LRDj4FtKA==",
"requires": {
"es6-symbol": "^3.1.0"
}
},
"move-concurrently": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz",
@@ -11806,12 +11823,6 @@
}
}
},
"node-forge": {
"version": "0.9.0",
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.9.0.tgz",
"integrity": "sha512-7ASaDa3pD+lJ3WvXFsxekJQelBKRpne+GOVbLbtHYdd7pFspyeuJHnWfLplGf3SwKGbfs/aYl5V/JCIaHVUKKQ==",
"dev": true
},
"node-gyp": {
"version": "3.8.0",
"resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.8.0.tgz",
@@ -14434,15 +14445,6 @@
"integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=",
"dev": true
},
"selfsigned": {
"version": "1.10.7",
"resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.7.tgz",
"integrity": "sha512-8M3wBCzeWIJnQfl43IKwOmC4H/RAp50S8DF60znzjW5GVqTcSe2vWclt7hmYVPkKPlHWOu5EaWOMZ2Y6W8ZXTA==",
"dev": true,
"requires": {
"node-forge": "0.9.0"
}
},
"semver": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
@@ -14846,57 +14848,6 @@
}
}
},
"sockjs": {
"version": "0.3.20",
"resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.20.tgz",
"integrity": "sha512-SpmVOVpdq0DJc0qArhF3E5xsxvaiqGNb73XfgBpK1y3UD5gs8DSo8aCTsuT5pX8rssdc2NDIzANwP9eCAiSdTA==",
"dev": true,
"requires": {
"faye-websocket": "^0.10.0",
"uuid": "^3.4.0",
"websocket-driver": "0.6.5"
}
},
"sockjs-client": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.4.0.tgz",
"integrity": "sha512-5zaLyO8/nri5cua0VtOrFXBPK1jbL4+1cebT/mmKA1E1ZXOvJrII75bPu0l0k843G/+iAbhEqzyKr0w/eCCj7g==",
"dev": true,
"requires": {
"debug": "^3.2.5",
"eventsource": "^1.0.7",
"faye-websocket": "~0.11.1",
"inherits": "^2.0.3",
"json3": "^3.3.2",
"url-parse": "^1.4.3"
},
"dependencies": {
"debug": {
"version": "3.2.6",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
"integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
"dev": true,
"requires": {
"ms": "^2.1.1"
}
},
"faye-websocket": {
"version": "0.11.3",
"resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.3.tgz",
"integrity": "sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA==",
"dev": true,
"requires": {
"websocket-driver": ">=0.5.1"
}
},
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"dev": true
}
}
},
"sort-keys": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz",
@@ -14906,6 +14857,11 @@
"is-plain-obj": "^1.0.0"
}
},
"sortablejs": {
"version": "1.10.2",
"resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.10.2.tgz",
"integrity": "sha512-YkPGufevysvfwn5rfdlGyrGjt7/CRHwvRPogD/lC+TnvcN29jDpCifKP+rBqf+LRldfXSTh+0CGLcSg0VIxq3A=="
},
"source-list-map": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz",
@@ -15218,6 +15174,11 @@
"resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz",
"integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ=="
},
"streamsaver": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/streamsaver/-/streamsaver-2.0.5.tgz",
"integrity": "sha512-KIWtBvi8A6FiFZGNSyuIZRZM6C8AvnWTiCx/TYa7so420vC5sQwcBKkdqInuGWoWMfeWy/P+/cRqMtWVf4RW9w=="
},
"strict-uri-encode": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz",
@@ -16933,6 +16894,11 @@
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
"dev": true
},
"v-click-outside": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/v-click-outside/-/v-click-outside-2.1.5.tgz",
"integrity": "sha512-VPNCOTZK6WZy73lcWc+R7IW1uaBFEO3/Csrs5CzWVOdvE30V8Y1+BE/BtTlcEmeDGx0eqdE7bSCg55Jj37PMJg=="
},
"v-tooltip": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/v-tooltip/-/v-tooltip-2.0.3.tgz",
@@ -17049,6 +17015,11 @@
"resolved": "https://registry.npmjs.org/vue/-/vue-2.6.11.tgz",
"integrity": "sha512-VfPwgcGABbGAue9+sfrD4PuwFar7gPb1yl1UK1MwXoQPAw0BKSqWfoYCT/ThFrdEVWoI51dBuyCoiNU9bZDZxQ=="
},
"vue-axios": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/vue-axios/-/vue-axios-3.2.0.tgz",
"integrity": "sha512-nBS3uVLT50Qfv7Gmhu0VDkYzTJeDWVc8TOTd4UzG/XS865+As4Updyuo4zWVqQ5ygC7JUBRkgc5merS7PpHMlw=="
},
"vue-bulma-expanding": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/vue-bulma-expanding/-/vue-bulma-expanding-0.0.1.tgz",
@@ -17078,6 +17049,17 @@
"tinycolor2": "^1.1.2"
}
},
"vue-ctk-date-time-picker": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/vue-ctk-date-time-picker/-/vue-ctk-date-time-picker-2.5.0.tgz",
"integrity": "sha512-s4AO+5xnPlX+LD5UPQcjLBnv8MwcEJKlKUnkTLQeXRV0xqpH9pWRe6aJ8N2+506mEN6b7iwhlFox6uKKdtK+gw==",
"requires": {
"moment": "^2.24.0",
"moment-range": "^4.0.1",
"v-click-outside": "^2.0.2",
"vue": "^2.6.9"
}
},
"vue-echarts": {
"version": "5.0.0-beta.0",
"resolved": "https://registry.npmjs.org/vue-echarts/-/vue-echarts-5.0.0-beta.0.tgz",
@@ -17276,6 +17258,14 @@
"resolved": "https://registry.npmjs.org/vue-yandex-maps/-/vue-yandex-maps-0.9.0.tgz",
"integrity": "sha512-6gXec68eXNHvo5d6m43lGCDMShYRpciWWy55VA1RiFtMkLHIDeK4CJzYmkfAec32vpzYEqdcNBJh9b93wqtp8w=="
},
"vuedraggable": {
"version": "2.24.3",
"resolved": "https://registry.npmjs.org/vuedraggable/-/vuedraggable-2.24.3.tgz",
"integrity": "sha512-6/HDXi92GzB+Hcs9fC6PAAozK1RLt1ewPTLjK0anTYguXLAeySDmcnqE8IC0xa7shvSzRjQXq3/+dsZ7ETGF3g==",
"requires": {
"sortablejs": "1.10.2"
}
},
"vuestic-ui": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/vuestic-ui/-/vuestic-ui-0.2.2.tgz",
@@ -17364,6 +17354,11 @@
"resolved": "https://registry.npmjs.org/vuex-i18n/-/vuex-i18n-1.13.1.tgz",
"integrity": "sha512-VTy5QAyMI6BJwpRfN5qncWQT0ohKiAYK+iTRW4JxgV9dkNoPMuKKDqExbOm1fzpitdrIoIipC3Zqr5fJ706VQg=="
},
"vuex-map-fields": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/vuex-map-fields/-/vuex-map-fields-1.4.1.tgz",
"integrity": "sha512-jvIcpvoIPqwvJCOfRkPU9Rj0EbjWuk7GlNC5LXU9mCXVGZph6bWGHZssnoUzpLMxJtXQEHoVyZkKf7YQV+/bnQ=="
},
"vuex-router-sync": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/vuex-router-sync/-/vuex-router-sync-5.0.0.tgz",
@@ -17660,9 +17655,9 @@
}
},
"webpack-dev-server": {
"version": "3.11.0",
"resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.11.0.tgz",
"integrity": "sha512-PUxZ+oSTxogFQgkTtFndEtJIPNmml7ExwufBZ9L2/Xyyd5PnOL5UreWe5ZT7IU25DSdykL9p1MLQzmLh2ljSeg==",
"version": "3.11.2",
"resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.11.2.tgz",
"integrity": "sha512-A80BkuHRQfCiNtGBS1EMf2ChTUs0x+B3wGDFmOeT4rmJOHhHTCH2naNxIHhmkr0/UillP4U3yeIyv1pNp+QDLQ==",
"dev": true,
"requires": {
"ansi-html": "0.0.7",
@@ -17685,11 +17680,11 @@
"p-retry": "^3.0.1",
"portfinder": "^1.0.26",
"schema-utils": "^1.0.0",
"selfsigned": "^1.10.7",
"selfsigned": "^1.10.8",
"semver": "^6.3.0",
"serve-index": "^1.9.1",
"sockjs": "0.3.20",
"sockjs-client": "1.4.0",
"sockjs": "^0.3.21",
"sockjs-client": "^1.5.0",
"spdy": "^4.0.2",
"strip-ansi": "^3.0.1",
"supports-color": "^6.1.0",
@@ -17754,12 +17749,21 @@
}
},
"debug": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
"integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
"integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
"dev": true,
"requires": {
"ms": "^2.1.1"
"ms": "2.1.2"
}
},
"faye-websocket": {
"version": "0.11.3",
"resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.3.tgz",
"integrity": "sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA==",
"dev": true,
"requires": {
"websocket-driver": ">=0.5.1"
}
},
"fsevents": {
@@ -17803,6 +17807,12 @@
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"dev": true
},
"node-forge": {
"version": "0.10.0",
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz",
"integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==",
"dev": true
},
"readdirp": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz",
@@ -17825,12 +17835,57 @@
"ajv-keywords": "^3.1.0"
}
},
"selfsigned": {
"version": "1.10.8",
"resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.8.tgz",
"integrity": "sha512-2P4PtieJeEwVgTU9QEcwIRDQ/mXJLX8/+I3ur+Pg16nS8oNbrGxEso9NyYWy8NAmXiNl4dlAp5MwoNeCWzON4w==",
"dev": true,
"requires": {
"node-forge": "^0.10.0"
}
},
"semver": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"dev": true
},
"sockjs": {
"version": "0.3.21",
"resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.21.tgz",
"integrity": "sha512-DhbPFGpxjc6Z3I+uX07Id5ZO2XwYsWOrYjaSeieES78cq+JaJvVe5q/m1uvjIQhXinhIeCFRH6JgXe+mvVMyXw==",
"dev": true,
"requires": {
"faye-websocket": "^0.11.3",
"uuid": "^3.4.0",
"websocket-driver": "^0.7.4"
}
},
"sockjs-client": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.5.1.tgz",
"integrity": "sha512-VnVAb663fosipI/m6pqRXakEOw7nvd7TUgdr3PlR/8V2I95QIdwT8L4nMxhyU8SmDBHYXU1TOElaKOmKLfYzeQ==",
"dev": true,
"requires": {
"debug": "^3.2.6",
"eventsource": "^1.0.7",
"faye-websocket": "^0.11.3",
"inherits": "^2.0.4",
"json3": "^3.3.3",
"url-parse": "^1.5.1"
},
"dependencies": {
"debug": {
"version": "3.2.7",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
"integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
"dev": true,
"requires": {
"ms": "^2.1.1"
}
}
}
},
"strip-ansi": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
@@ -17849,6 +17904,27 @@
"has-flag": "^3.0.0"
}
},
"url-parse": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.1.tgz",
"integrity": "sha512-HOfCOUJt7iSYzEx/UqgtwKRMC6EU91NFhsCHMv9oM03VJcVo2Qrp8T8kI9D7amFf1cu+/3CEhgb3rF9zL7k85Q==",
"dev": true,
"requires": {
"querystringify": "^2.1.1",
"requires-port": "^1.0.0"
}
},
"websocket-driver": {
"version": "0.7.4",
"resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz",
"integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==",
"dev": true,
"requires": {
"http-parser-js": ">=0.5.1",
"safe-buffer": ">=5.1.0",
"websocket-extensions": ">=0.1.1"
}
},
"ws": {
"version": "6.2.1",
"resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz",
@@ -17897,15 +17973,6 @@
}
}
},
"websocket-driver": {
"version": "0.6.5",
"resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.6.5.tgz",
"integrity": "sha1-XLJVbOuF9Dc8bYI4qmkchFThOjY=",
"dev": true,
"requires": {
"websocket-extensions": ">=0.1.1"
}
},
"websocket-extensions": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz",
@@ -18292,9 +18359,9 @@
"integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ=="
},
"y18n": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",
"integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==",
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz",
"integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==",
"dev": true
},
"yallist": {
@@ -18440,9 +18507,9 @@
}
},
"zrender": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/zrender/-/zrender-4.3.1.tgz",
"integrity": "sha512-CeH2TpJeCdG0TAGYoPSAcFX2ogdug1K7LIn9UO/q9HWqQ54gWhrMAlDP9AwWYMUDhrPe4VeazQ4DW3msD96nUQ=="
"version": "4.3.2",
"resolved": "https://registry.npmjs.org/zrender/-/zrender-4.3.2.tgz",
"integrity": "sha512-bIusJLS8c4DkIcdiK+s13HiQ/zjQQVgpNohtd8d94Y2DnJqgM1yjh/jpDb8DoL6hd7r8Awagw8e3qK/oLaWr3g=="
}
}
}
+8 -3
View File
@@ -18,12 +18,12 @@
"ammap3": "^3.21.14",
"approximate-number": "^2.0.0",
"asva-executors": "^0.1.22",
"axios": "^0.19.0",
"axios": "^0.21.1",
"babel-polyfill": "^6.26.0",
"chart.js": "^2.9.3",
"core-js": "3",
"detect-browser": "^4.8.0",
"echarts": "^4.8.0",
"echarts": "^4.9.0",
"element-resize-detector": "^1.1.15",
"epic-spinners": "^1.1.0",
"extend": "3.0.2",
@@ -32,19 +32,22 @@
"google-maps": "^3.3.0",
"ionicons": "^4.6.3",
"leaflet-map": "^0.2.1",
"lodash": "4.17.15",
"lodash": "^4.17.21",
"medium-editor": "^5.23.3",
"normalize.css": "^8.0.1",
"popper.js": "^1.16.0",
"regenerator-runtime": "^0.13.3",
"register-service-worker": "^1.6.2",
"streamsaver": "^2.0.5",
"v-tooltip": "^2.0.2",
"vee-validate": "^2.2.13",
"vue": "^2.6.10",
"vue-axios": "^3.2.0",
"vue-bulma-expanding": "0.0.1",
"vue-chartjs": "^3.4.0",
"vue-clipboard2": "^0.3.1",
"vue-color": "^2.7.0",
"vue-ctk-date-time-picker": "^2.5.0",
"vue-echarts": "^5.0.0-beta.0",
"vue-epic-bus": "^0.1.2",
"vue-gtm": "^2.2.0",
@@ -52,10 +55,12 @@
"vue-router": "^3.1.3",
"vue-worker": "^1.2.1",
"vue-yandex-maps": "^0.9.0",
"vuedraggable": "^2.24.3",
"vuestic-ui": "~0.2.2",
"vuetable-2": "^1.7.5",
"vuex": "^3.1.2",
"vuex-i18n": "^1.13.1",
"vuex-map-fields": "^1.4.1",
"vuex-router-sync": "^5.0.0"
},
"devDependencies": {
Binary file not shown.

Before

Width:  |  Height:  |  Size: 799 B

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

+1 -1
View File
@@ -8,7 +8,7 @@
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title>Vuestic Admin</title>
<title>BioPro Scientific</title>
</head>
<body>
<div id="app"></div>
+14
View File
@@ -0,0 +1,14 @@
* This is shell_script dir
# 檔案說明
burn_to_raspberry.sh : 用scp複製local npm build好的東西 & burn_to_raspberry_util.sh 去遠端(raspberry),然後在raspberry內execute 複製過去的burn_to_raspberry_util.sh
burn_to_raspberry_util.sh : 給burn_to_raspberry.sh用的,裡面的指令為在raspberry內所有要執行的指令
# Usage
burn_to_raspberry.sh
```shell
sh ./burn_to_raspberry.sh <HOST> <PASSWORD>
e.g. sh ./burn_to_raspberry.sh pi@192.168.3.53 raspberry
```
+15
View File
@@ -0,0 +1,15 @@
#!/bin/bash
# sshpass: https://shazi.info/ssh-%E7%94%A8-sshpass-%E5%8F%96%E4%BB%A3-expect-%E8%87%AA%E5%8B%95%E8%BC%B8%E5%85%A5%E5%AF%86%E7%A2%BC/
HOST=$1 # e.g. "pi@192.168.3.53"
PASSWORD=$2 # e.g. raspberry
SCP_HOST=$HOST":"
cd ..
npm run build
sshpass -p $PASSWORD ssh $HOST "rm -rf dist"
sshpass -p $PASSWORD scp -r dist $SCP_HOST
sshpass -p $PASSWORD scp shell_script/burn_to_raspberry_util.sh $SCP_HOST
sshpass -p $PASSWORD ssh $HOST "sh ./burn_to_raspberry_util.sh"
# sshpass -p raspberry scp -r dist pi@192.168.3.53:
+7
View File
@@ -0,0 +1,7 @@
#!/bin/bash
#run in raspberry
cd
sudo rm -rf /var/www/bioprovuebuild/*
sudo cp -r dist/* /var/www/bioprovuebuild/
+4 -1
View File
@@ -1,6 +1,9 @@
<template>
<div id="app" class="app">
<router-view />
<keep-alive>
<router-view v-if="$route.meta.keepAlive"></router-view>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive"></router-view>
</div>
</template>
+3 -1
View File
@@ -20,6 +20,7 @@ import 'echarts/lib/component/tooltip'
import 'echarts/lib/component/legend'
import 'echarts/lib/component/axisPointer'
import 'echarts/lib/component/grid'
import 'echarts/lib/component/markArea'
import VueMqtt from 'vue-mqtt'
import global_ from '../data/global/global'
@@ -48,8 +49,9 @@ Vue.component('chart', ECharts)
Vue.use(VueWorker)
Vue.use(VueAxios, axios)
Vue.use(VueMqtt, 'ws://52.194.17.114:8083')
// Vue.use(VueMqtt, 'ws://52.194.17.114:8083')
// Vue.use(VueMqtt, 'ws://' + location.href.split('/')[2] + ':8083')
Vue.use(VueMqtt, 'ws://' + '192.168.3.48' + ':8083')
Vue.prototype.GLOBAL = global_
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 202 KiB

+35
View File
@@ -0,0 +1,35 @@
<template>
<div class="about">
<controller-info/>
<device-info/>
</div>
</template>
<script>
import DeviceInfo from './deviceInfo.vue'
import ControllerInfo from './controllerInfo.vue'
export default {
name: 'about-content',
components: {
ControllerInfo,
DeviceInfo,
},
created () {
},
data () {
return {
}
},
computed: {
},
watch: {
},
methods: {
},
async mounted () {
},
destroyed () {
},
}
</script>
+141
View File
@@ -0,0 +1,141 @@
<template>
<div class="controller-info">
<div class="row flex">
<div
class="flex sm12 xl12 md12 xs12 ma-2"
v-for="controller in controllers" :key="controller.mac_address"
>
<va-card
style="border: 5px solid #78ceff; border-radius: 30px; font-size: 1.5rem;"
>
<!-- {{ controller }} -->
<va-item :key="controller.device_mac" class="pa-0 ma-0"
>
<va-item-section avatar class="ml-2 mr-2">
<img
:src="getImageUrl()"
:alt="'BPS-CONTROLLER'"
width="300px"
height="300px"
contain
/>
</va-item-section>
<va-item-section class="ml-4" >
<va-item-label style="font-size: 2rem;">
{{ controller.wifi_name }}
</va-item-label>
<va-item-label>
Mac Address :
{{ controller.mac_address.toUpperCase() }}
</va-item-label>
<va-item-label>
Build Version : #
{{ controller.software_version }}
</va-item-label>
<va-item-label>
Update Time :
{{ GLOBAL.dateToStr(controller.updated_at) }}
</va-item-label>
</va-item-section>
</va-item>
</va-card>
</div>
</div>
</div>
</template>
<script>
import { mapActions, mapGetters, mapMutations } from 'vuex'
import api from '@/data/api/index'
import types from '@/store/modules/about/types'
import eliteImgUrl from '@/assets/img/elite_img.png'
export default {
name: 'controller-info',
components: {
},
// props: {
// data: {
// type: Object,
// default: function () {
// return {}
// },
// },
// cardclass: {
// type: Array,
// default: function () {
// return ['xs12', 'md12', 'xl12', 'sm12']
// },
// },
// cardheight: {
// type: String,
// default: '82vh',
// },
// cardwidth: {
// type: String,
// default: 'auto',
// },
// },
created () {
},
data () {
return {
}
},
computed: {
controllers () {
return this.getAllController()
},
},
watch: {
},
methods: {
getImageUrl () {
return eliteImgUrl
},
...mapActions('about', [types.controller.init]),
...mapMutations('about', [types.controller.set, types.controller.updateByIndex]),
...mapGetters('about', [types.controller.getAll]),
},
async mounted () {
this.initController({ api: api })
console.log(this.getAllController())
},
destroyed () {
},
}
</script>
<style lang="scss">
.area-style {
height: auto;
overflow-y: hidden;
overflow-x: hidden;
@include media-breakpoint-only(xl) {
height: 48vh;
overflow-y: scroll;
overflow-x: hidden;
}
}
.drag-flex {
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
.font-small {
color: rgb(113, 186, 255);
font-size: 16px;
}
.center-medium {
text-align: center;
font-size: 20px;
}
.center-large {
text-align: center;
font-size: 28px;
}
</style>
+166
View File
@@ -0,0 +1,166 @@
<template>
<div class="device-info">
<div class="row flex">
<draggable class="flex d-flex sm12 xl12 md12 xs12" v-model="devices" @start="drag=true" @end="drag=false" >
<div
class="flex d-flex sm12 xl3 md4 xs12 ma-0 area-style "
v-for="(device, index) in devices" :key="device.id"
>
<va-card
:noPadding="true"
style="border: 5px solid #78ceff; border-radius: 30px;"
>
<div class="center-large" >
<div class="flex d-flex sm12 xl12 md12 xs12 ">
<div class="sm11 xl11 md11 xs11 ml-2" style="text-align: start;">
{{ device.name }}
</div>
<div class="sm1 xl1 md1 xs1" style="text-align: right;">
<va-icon
name="ion ion-md-close"
class="mr-1"
color="#babfc2"
style="cursor: pointer;"
@click.native.stop="removeCheck(index, device)"
/>
</div>
</div>
</div>
<div class="center-medium">
<p> {{ device.name }} </p>
</div>
<div class="center-medium">
<p> {{ macArrayToString(device.mac_address) }} </p>
</div>
<div class="mt-4 mb-4" style="text-align: center;">
<img
:src="getImageUrl(device.library)"
:alt="device.name"
width="150px"
height="100px"
contain
/>
</div>
<div class="center-medium">
<p> {{ device.device_version }} </p>
<p> {{ timeStampToLocaleTime(device.updated_at) }} </p>
</div>
<div class="flex sm12 xl12 md12 xs12" style="text-align: center;">
<va-button v-if="device.auto_connect" color="success" @click="autoConnect(index, device)">Auto Connect</va-button>
<va-button v-if="!device.auto_connect" color="#babfc2" @click="autoConnect(index, device)" outline>Auto Connect</va-button>
<va-button >User Guide</va-button>
</div>
</va-card>
</div>
</draggable>
</div>
</div>
</template>
<script>
import { mapActions, mapGetters, mapMutations } from 'vuex'
import api from '@/data/api/index'
import types from '@/store/modules/about/types'
import neuliveImgUrl from '@/assets/img/neulive_img.png'
import eliteImgUrl from '@/assets/img/elite_img.png'
import draggable from 'vuedraggable'
export default {
name: 'device-info',
components: {
draggable,
},
created () {
},
data () {
return {
}
},
computed: {
devices: {
get () {
return this.getAllDevice()
},
set (deviceList) {
this.reorderDevice({ deviceList: deviceList, api: api })
},
},
},
watch: {
},
methods: {
macArrayToString: function (macAddress) {
return this.GLOBAL.transMac(JSON.parse(macAddress))
},
timeStampToLocaleTime: function (time) {
return this.GLOBAL.dateToStr(time)
},
getImageUrl (libraryName) {
if (libraryName !== null) {
if (libraryName.indexOf('Neulive') >= 0) {
return neuliveImgUrl
} else if (libraryName.indexOf('Elite') >= 0) {
return eliteImgUrl
}
}
return null
},
autoConnect (index, device) {
device.auto_connect = !device.auto_connect
this.updateDatabaseByIDDevice({
id: device.id,
request: { auto_connect: device.auto_connect },
api: api,
})
this.updateByIndexDevice({ index: index, item: { auto_connect: device.auto_connect } })
},
removeCheck (index, device) {
/**
* TODO remove modal
*/
this.removeDevice({ id: device.id, index: index, device, deviceList: this.devices, api: api })
},
...mapActions('about', [types.device.init, types.device.remove, types.device.reorder, types.device.updateDatabaseByID]),
...mapMutations('about', [types.device.set, types.device.updateByIndex]),
...mapGetters('about', [types.device.getAll]),
},
async mounted () {
this.initDevice({ api: api })
},
destroyed () {
},
}
</script>
<style lang="scss">
.area-style {
height: auto;
overflow-y: hidden;
overflow-x: hidden;
@include media-breakpoint-only(xl) {
height: 48vh;
overflow-y: scroll;
overflow-x: hidden;
}
}
.drag-flex {
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
.font-small {
color: rgb(113, 186, 255);
font-size: 16px;
}
.center-medium {
text-align: center;
font-size: 20px;
}
.center-large {
text-align: center;
font-size: 28px;
}
</style>
+7 -1
View File
@@ -87,7 +87,7 @@ export default {
},
},
mounted () {
this.minimized = true
},
}
</script>
@@ -134,3 +134,9 @@ export default {
}
}
</style>
<style lang='scss'>
.layout.gutter--xl {
padding: 0.75rem;
}
</style>
@@ -25,7 +25,7 @@
>
<!-- *** icon -->
<!-- <va-icon-vuestic /> -->
<img v-bind:src="'https://www.bioproweb.com/wp-content/uploads/2020/01/BPS-LOGO_60.png'">
<img src='@/assets/img/bps_logo.png'>
</router-link>
</div>
<!-- <img style="height: 40px;" v-bind:src="'https://www.bioproweb.com/wp-content/uploads/2020/01/BPS-LOGO_60.png'"> -->
@@ -96,7 +96,7 @@ export default {
theme: 'info',
items: navigationRoutes.routes,
hoverState: false,
minimized: false,
minimized: true,
}
},
}
@@ -19,8 +19,8 @@ export const navigationRoutes = {
},
},
{
name: 'project-content',
displayName: 'Project',
name: 'task-content',
displayName: 'Task',
meta: {
iconClass: 'vuestic-iconset vuestic-iconset-statistics',
},
@@ -47,6 +47,13 @@ export const navigationRoutes = {
iconClass: 'vuestic-iconset vuestic-iconset-files',
},
},
{
name: 'settings',
displayName: 'Settings',
meta: {
iconClass: 'vuestic-iconset vuestic-iconset-settings',
},
},
// {
// name: 'forms',
// displayName: 'menu.forms',
@@ -1,57 +0,0 @@
<template>
<div class="devices-overview">
<div >
<replay-chart-detail :cardheight="'82vh'"/>
<!-- <va-card class="area-style">
<template slot="header">
<va-icon name="fa fa-hdd-o mr-3" color="primary"/>
</template>
<replay-chart-detail />
</va-card> -->
</div>
</div>
</template>
<script>
import ReplayChartDetail from './ReplayChartDetail.vue'
export default {
name: 'data-replay',
components: {
ReplayChartDetail,
},
created () {
},
data () {
return {
}
},
mqtt: {
},
methods: {
},
watch: {
},
async mounted () {
},
destroyed () {
},
}
</script>
<style lang="scss">
.area-style {
height: auto;
overflow-y: hidden;
overflow-x: hidden;
@include media-breakpoint-only(xl) {
height: 88vh;
overflow-y: scroll;
overflow-x: hidden;
}
}
</style>
@@ -1,60 +0,0 @@
<template>
<div class="flex" :class="cardclass">
<va-card>
<template slot="header">
<!-- <va-icon name="fa fa-area-chart mr-3" color="primary"/> -->
</template>
<chart :ref="'chart_ref'" :style="'width: '+ cardwidth + '; height: ' + cardheight + ';'" :options="data" :auto-resize="true"></chart>
</va-card>
</div>
</template>
<script>
// import { chartData } from '../../../../data/project/ChartsManagement'
export default {
name: 'replay-chart-detail',
components: {
},
props: {
data: {
type: Object,
default: function () {
return {}
},
},
cardclass: {
type: Array,
default: function () {
return ['xs12', 'md12', 'xl12', 'sm12']
},
},
cardheight: {
type: String,
default: '88vh',
},
cardwidth: {
type: String,
default: 'auto',
},
},
created () {
},
data () {
return {
}
},
computed: {
},
watch: {
},
methods: {
},
async mounted () {
},
destroyed () {
},
}
</script>
@@ -0,0 +1,491 @@
<template>
<div>
<div class="row row-equal">
<div class="flex md12 xl3 xs12 sm12 area-style">
<div class="row">
<div class="flex sm12 xl12 md12 xs12">
<va-accordion>
<va-collapse class="mb-2" :isOpenDefault="true">
<span slot="header">Control Panel</span>
<div slot="body">
<div>
<top-control-panel :ref="'top_control_panel'" @refreshChart="setOption" @changeAxis="changeAxis"/>
</div>
</div>
</va-collapse>
</va-accordion>
</div>
</div>
</div>
<div :class="chartAreaClass" class="area-style">
<div class="row" >
<div class="flex sm12 xl12 md12 xs12">
<elite-replay-overview-chart v-show="showOverviewChart" :ref="'chart_overview'" class="mb-1" :cardheight="'7vh'" :data="chartOverviewData" @dataZoomEvent="dataZoomEvent($event)"/>
<elite-replay-chart :ref="'chart_detail'" @dblclick.native="distribute()" :cardheight="'88vh'" :data="chartDetailData" />
<change-channel-value-min-max :ref="'set_min_max'"/>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import { mapActions, mapGetters, mapMutations } from 'vuex'
import EliteReplayChart from './EliteReplayChart.vue'
import TopControlPanel from './TopControlPanel.vue'
import EliteReplayOverviewChart from './EliteReplayOverviewChart.vue'
import ChangeChannelValueMinMax from '@/components/analysis/replay/toolbox/ChangeChannelValueMinMax.vue'
import api from '@/data/api/index'
import { download } from '@/data/download/Download'
import types from '@/store/modules/analysis/replay/types'
import { mapFields } from 'vuex-map-fields'
import { newChartMode } from '@/factories/chart/chartFactory'
export default {
name: 'elite-data-replay',
components: {
TopControlPanel,
EliteReplayChart,
EliteReplayOverviewChart,
ChangeChannelValueMinMax,
},
computed: {
...mapFields('replay', [
'metaList',
'chartData',
'chartOverviewData',
'chartDetailData',
'currentScale',
'axisXDataType',
'axisYDataType',
'startTimeCurrent',
'endTimeCurrent',
]),
},
props: {
},
async created () {
this.chartOverviewData = await this.initChart({
chartAllData: this.chartData,
chartID: 0,
gridLength: 1,
type: 'overview',
device: 'elite',
mode: 0,
})
this.chartDetailData = await this.initChart({
chartAllData: this.chartData,
chartID: 1,
gridLength: 1,
type: 'detail',
device: 'elite',
mode: 0,
})
},
data () {
return {
showOverviewChart: false,
dataInfo: {},
maxTime: 0,
startTime: 0,
endTime: 0,
zoomTime: 0,
initDone: false,
chartAreaClass: ['flex', 'xs12', 'sm12', 'md12', 'xl9', 'pa-0'],
}
},
mqtt: {
},
methods: {
turnOnAxisEventHandler (eventName, query, handler, attr) {
this.$refs.chart_detail.turnOnAxisEventHandler(eventName, query, handler, attr)
},
turnOffAxisEventHandler (eventName, handler, attr) {
this.$refs.chart_detail.turnOffAxisEventHandler(eventName, handler, attr)
},
showMinMaxPanel (params) {
this.$refs.set_min_max.showPanel(params)
},
setOption (options) {
this.$refs.chart_detail.mergeOptions(options)
},
showChartLoading: function (chart) {
const loadStyle = {
text: '',
color: '#cccccc',
maskColor: 'rgba(255, 255, 255, 0.8)',
zlevel: 0,
}
switch (chart) {
case 'overview':
this.$refs.chart_overview.showLoading(loadStyle)
break
case 'detail':
this.$refs.chart_detail.showLoading(loadStyle)
break
default:
this.$refs.chart_overview.showLoading(loadStyle)
this.$refs.chart_detail.showLoading(loadStyle)
break
}
},
hideChartLoading: function () {
this.$refs.chart_overview.hideLoading()
this.$refs.chart_detail.hideLoading()
},
getData: async function (scale, sampleMethod, id, channel, meta) {
if (scale === 1) {
return await download.rawByIDChannels(id, channel, meta)
} else {
if (sampleMethod === 'mean') {
return await download.miniMeanByIDChannel(id, channel, meta)
} else if (sampleMethod === 'random') {
return await download.miniRandomByIDChannel(id, channel, meta)
}
}
},
register: async function () {
// [TODO] support data source from different file
this.updateGridListChart({
chartAllData: this.chartData,
chartID: this.chartDetailData.chartID,
gridLength: this.metaList.length,
})
let _gridNumber = 0
const register = this.metaList.map(meta => {
const setting = newChartMode(meta.parameter_set.MODE)
const xType = setting[0] // Elite or Time
const yType = setting[2] // Elite or Time
const xValue = setting[1] // 1: I, 2: V, 3: R
const yValue = setting[3] // 1: I, 2: V, 3: R
console.log(setting)
this.registerChart({
chartAllData: this.chartData,
chartID: this.chartDetailData.chartID,
gridIndex: _gridNumber,
deviceNameX: xType,
deviceIDX: meta.name,
channelX: xValue,
deviceNameY: yType,
deviceIDY: '',
channelY: yValue,
})
JSON.parse(meta.channels).map(ch => {
this.registerChart({
chartAllData: this.chartData,
chartID: this.chartOverviewData.chartID,
gridIndex: 0,
deviceNameX: 'Time',
deviceNameY: 'Elite',
deviceIDY: meta.name,
channelY: ch,
})
})
this.chartDetailData.xAxis[_gridNumber].axisLabel.show = true
if (this.maxTime < parseInt(meta.time_duration)) {
this.maxTime = parseInt(meta.time_duration)
this.endTime = this.endTimeCurrent = this.maxTime
}
if (xType === 'Time') {
this.chartDetailData.xAxis[_gridNumber].min = 0
this.chartDetailData.xAxis[_gridNumber].max = this.maxTime
} else {
this.chartDetailData.xAxis[_gridNumber].min = 'dataMin'
this.chartDetailData.xAxis[_gridNumber].max = 'dataMax'
}
this.chartDetailData.yAxis[_gridNumber].min = 'dataMin'
this.chartDetailData.yAxis[_gridNumber].max = 'dataMax'
_gridNumber++
})
await Promise.all(register)
this.chartOverviewData.series.forEach((series, index) => { // [TODO]
this.chartOverviewData.xAxis[series.xAxisIndex].min = 0
this.chartOverviewData.xAxis[series.xAxisIndex].max = this.maxTime
})
this.updateDataZoomChart({
chartAllData: this.chartData,
chartID: 0,
})
this.updateDataZoomChart({
chartAllData: this.chartData,
chartID: 1,
})
},
dataZoomEvent: function (e) {
if (e.batch != null) {
// console.log(e.batch)
e.batch.forEach(dataZoom => {
const id = parseInt(dataZoom.dataZoomId.substr(dataZoom.dataZoomId.length - 3, dataZoom.dataZoomId.length - 1))
if (id === 1) {
this.startTime = this.maxTime * dataZoom.start / 100
this.endTime = this.maxTime * dataZoom.end / 100
// console.log(this.startTime, this.endTime)
}
})
} else {
const id = parseInt(e.dataZoomId.substr(e.dataZoomId.length - 3, e.dataZoomId.length - 1))
if (id === 0) {
this.startTime = this.maxTime * e.start / 100
this.endTime = this.maxTime * e.end / 100
// console.log(this.startTime, this.endTime)
}
}
this.zoomTime = 0
},
drawOverviewData: async function () {
this.showChartLoading('overview')
for (const meta in this.dataInfo) {
let metaInfo
this.metaList.forEach(_meta => {
if (parseInt(_meta.id) === parseInt(meta)) {
metaInfo = _meta
}
})
const sampleRate = (80000 / metaInfo.parameter_set.ADC_CLOCK)
let scale = (((metaInfo.time_duration / 100000) * sampleRate) / 4000)
if (scale > 500) {
scale = '1000'
} else if (scale > 200) {
scale = '100'
} else if (scale > 30) {
scale = '10'
} else {
scale = '1'
}
console.log('overview scale:', scale)
const sampleMethod = 'mean'
// download data
const getAllData = async function (_this) {
for (const ch in _this.dataInfo[meta]) {
const dataList = _this.dataInfo[meta][ch][scale]
for (let i = 0; i < dataList.length; i++) {
if (dataList[i].data.length === 0) {
_this.intoDataRec({
index: i,
metaID: meta,
channel: ch,
scale: scale,
data: await _this.getData(parseInt(scale), sampleMethod, dataList[i].id, ch, metaInfo),
})
}
}
}
}
await getAllData(this)
// push downloaded data to chart series
let seriesIndex = 0
for (const ch in this.dataInfo[meta]) {
const dataList = this.dataInfo[meta][ch][scale]
for (let i = 0; i < dataList.length; i++) {
this.chartOverviewData.series[seriesIndex].data.push(...dataList[i].data)
}
seriesIndex++
}
}
this.hideChartLoading()
},
drawDetailData: async function () {
this.showChartLoading('detail')
const timeDur = this.endTimeCurrent - this.startTimeCurrent
let _gridNumber = 0
for (const meta in this.dataInfo) {
let metaInfo
this.metaList.forEach(_meta => {
if (parseInt(_meta.id) === parseInt(meta)) {
metaInfo = _meta
}
})
const sampleRate = (80000 / metaInfo.parameter_set.ADC_CLOCK)
let scale = (((timeDur / 100000) * sampleRate) / 4000)
if (scale > 500) {
scale = '1000'
} else if (scale > 200) {
scale = '100'
} else if (scale > 30) {
scale = '10'
} else {
scale = '1'
}
this.currentScale = scale
const sampleMethod = 'mean'
this.chartDetailData.series[_gridNumber].data.length = 0
let dataListX
const channelX = parseInt(this.axisXDataType.id)
if (this.axisXDataType.description !== 'Time') {
dataListX = this.dataInfo[meta][channelX][scale]
}
const channelY = parseInt(this.axisYDataType.id)
const dataListY = this.dataInfo[meta][channelY][scale]
let startIndex = 0
let endIndex = 0
// get the subfile index
for (let i = 0; i < dataListY.length; i++) {
if (this.startTimeCurrent >= parseInt(dataListY[i].start_time) && this.startTimeCurrent <= parseInt(dataListY[i].end_time)) {
startIndex = i
}
if (this.endTimeCurrent >= parseInt(dataListY[i].start_time) && this.endTimeCurrent <= parseInt(dataListY[i].end_time)) {
endIndex = i
}
}
// download and push into chart
for (let i = startIndex; i <= endIndex; i++) {
const data = await this.getData(parseInt(scale), sampleMethod, dataListY[i].id, channelY, metaInfo)
let dataX
if (this.axisXDataType.description !== 'Time') {
dataX = await this.getData(parseInt(scale), sampleMethod, dataListX[i].id, channelX, metaInfo)
}
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]) >= this.startTimeCurrent && parseInt(data[j][0]) <= this.endTimeCurrent) {
const processedData = JSON.parse(JSON.stringify(data[j]))
if (dataX !== undefined) {
processedData[0] = dataX[j][1]
}
// console.log(data)
this.chartDetailData.series[_gridNumber].data.push(processedData)
}
}
}
// for (let i = 0, len = this.chartDetailData.xAxis.length; i < len; i++) {
// this.chartDetailData.xAxis[i].min = this.startTimeCurrent
// this.chartDetailData.xAxis[i].max = this.endTimeCurrent
// }]
_gridNumber += 1
}
this.hideChartLoading()
},
checkDataZoom: function () {
this.zoomTime++
if (this.zoomTime >= 2) {
if (this.startTimeCurrent !== this.startTime || this.endTimeCurrent !== this.endTime) {
this.startTimeCurrent = this.startTime
this.endTimeCurrent = this.endTime
this.drawDetailData()
}
}
},
changeAxis (gridIndex) {
if (this.initDone) {
let xType
let xValue // 1: I, 2: V, 3: R
if (this.axisXDataType.description === 'Time') {
xType = 'Time'
} else {
xType = 'Elite'
xValue = this.axisXDataType.id + 1
}
this.updateRegisteredChart({
chartAllData: this.chartData,
chartID: this.chartDetailData.chartID,
gridIndex: gridIndex,
deviceNameX: xType,
deviceIDX: this.metaList[gridIndex].name,
channelX: xValue,
deviceNameY: 'Elite',
deviceIDY: '',
channelY: this.axisYDataType.id + 1,
})
}
this.drawDetailData() // reDraw
if (this.axisXDataType.description !== 'Time') {
this.showOverviewChart = false
this.turnOnAxisEventHandler('click', 'xAxis.axisLabel', this.showMinMaxPanel, { axis: 'x' })
} else {
this.showOverviewChart = true
this.turnOffAxisEventHandler('click', this.showMinMaxPanel, { axis: 'x' })
this.turnOnAxisEventHandler('click', 'yAxis.axisLabel', this.showMinMaxPanel, { axis: 'y' })
}
},
distribute: function () {
// if (this.chartDetailData.grid.length === 1) {
// this.chartDetailData.xAxis[0].axisLabel.show = false
// this.updateGridListChart({
// chartAllData: this.chartData,
// chartID: this.chartDetailData.chartID,
// gridLength: this.chartDetailData.series.length,
// })
// this.chartDetailData.series.forEach((series, index) => {
// series.xAxisIndex = index
// series.yAxisIndex = index
// })
// this.chartDetailData.xAxis[this.chartDetailData.xAxis.length - 1].axisLabel.show = true
// } else {
// this.updateGridListChart({
// chartAllData: this.chartData,
// chartID: this.chartDetailData.chartID,
// gridLength: 1,
// })
// this.chartDetailData.series.forEach(series => {
// series.xAxisIndex = 0
// series.yAxisIndex = 0
// })
// this.chartDetailData.xAxis[0].axisLabel.show = true
// }
},
...mapActions('replay', [types.chart.init, types.chart.register, types.chart.clear, types.chart.updateGridList, types.chart.updateDataZoom]),
...mapActions('replay', [types.meta.init]),
...mapActions('replay', [types.rec.init, types.rec.intoData, types.rec.initDisplaySetting, types.rec.updateDisplaySetting]),
...mapMutations('replay', [types.chart.updateRegistered]),
...mapMutations('replay', [types.meta.updateByIndex]),
...mapGetters('replay', [types.meta.getAll]),
...mapGetters('replay', [types.rec.getAll, types.rec.getAllDisplaySetting, types.rec.getDisplaySettingByKey]),
},
// use watch because va-select with @change will have bug
watch: {
},
async mounted () {
this.showChartLoading()
const metaIDList = this.$route.params.metaList.split('-')
await this.initMeta({ metaIDList: metaIDList, api: api })
this.metaList = this.getAllMeta()
await this.initRec({ api: api })
this.dataInfo = this.getAllRec()
console.log(this.metaList)
console.log(this.dataInfo)
await this.register()
this.$refs.top_control_panel.init() // will can changeAxis() here
this.$refs.set_min_max.init()
this.turnOnAxisEventHandler('click', 'yAxis.axisLabel', this.showMinMaxPanel, { axis: 'y' })
this.drawOverviewData()
this.dataZoomTimer = setInterval(this.checkDataZoom, 1000)
this.initDone = true
// console.log(this.chartDetailData)
},
beforeDestroy () {
this.$refs.chart_overview.clear()
this.$refs.chart_detail.clear()
for (const id in this.chartData) {
for (const _series of this.chartData[id].series) {
_series.length = 0
}
delete this.chartData[id]
}
this.clearChart({ chartAllData: this.chartData })
},
destroyed () {
clearInterval(this.dataZoomTimer)
},
}
</script>
<style lang="scss">
.area-style {
height: auto;
overflow-y: hidden;
overflow-x: hidden;
@include media-breakpoint-only(xl) {
height: 88vh;
overflow-y: scroll;
overflow-x: hidden;
}
}
.layout.gutter--xl .row .flex {
padding: 0.4rem 0.5rem 0.1rem 0.5rem;
}
</style>
@@ -0,0 +1,110 @@
<template>
<div class="flex" :class="cardclass">
<va-card :style="'height: ' + cardheight + ';'">
<chart :ref="'chart_ref'" :style="'width: '+ cardwidth + '; height: ' + cardheight + ';'" :options="data" @dataZoom="updateZoom" :auto-resize="true"></chart>
</va-card>
</div>
</template>
<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',
components: {
},
props: {
data: {
type: Object,
default: function () {
return {}
},
},
cardclass: {
type: Array,
default: function () {
return ['xs12', 'md12', 'xl12', 'sm12']
},
},
cardheight: {
type: String,
default: '82vh',
},
cardwidth: {
type: String,
default: 'auto',
},
},
created () {
},
data () {
return {
}
},
computed: {
},
watch: {
},
methods: {
resize: function () {
if (this.$refs.chart_ref != null) {
this.$refs.chart_ref.resize()
}
},
updateZoom: function (e) {
this.$emit('dataZoomEvent', e)
},
mergeOptions (options) {
this.$refs.chart_ref.mergeOptions(options)
},
turnOnAxisEventHandler (eventName, query, handler, attr) {
const chartID = 1
this.updateAxisEventHandlerChart({
chartID: chartID,
axis: attr.axis,
status: 'on',
})
// doc: https://echarts.apache.org/zh/api.html#echartsInstance.on
this.$refs.chart_ref.chart._zr.on(eventName, query, handler)
},
turnOffAxisEventHandler (eventName, handler, attr) {
const chartID = 1
this.updateAxisEventHandlerChart({
chartID: chartID,
axis: attr.axis,
status: 'off',
})
// doc: https://echarts.apache.org/zh/api.html#echartsInstance.off
this.$refs.chart_ref.chart._zr.off(eventName, handler)
},
showLoading (options) {
this.$refs.chart_ref.showLoading(options)
},
hideLoading () {
this.$refs.chart_ref.hideLoading()
},
clear () {
this.$refs.chart_ref.clear()
},
...mapMutations('replay', [types.chart.updateAxisEventHandler]),
},
async mounted () {
this.resizeTimer = setInterval(this.resize, 1000)
},
destroyed () {
clearInterval(this.resizeTimer)
},
}
</script>
<style lang='scss'>
.va-card {
&__body {
padding-top: 0.25rem;
}
}
</style>
@@ -0,0 +1,83 @@
<template>
<div class="flex" :class="cardclass">
<va-card :style="'height: 8vh;'">
<chart :ref="'chart_ref'" :style="'width: '+ cardwidth + '; height: ' + cardheight + ';'" :options="data" @dataZoom="updateZoom" :auto-resize="true"></chart>
</va-card>
</div>
</template>
<script>
// import { chartData } from '../../../../data/task/ChartsManagement'
export default {
name: 'elite-replay-overview-chart',
components: {
},
props: {
data: {
type: Object,
default: function () {
return {}
},
},
cardclass: {
type: Array,
default: function () {
return ['xs12', 'md12', 'xl12', 'sm12']
},
},
cardheight: {
type: String,
default: '82vh',
},
cardwidth: {
type: String,
default: 'auto',
},
},
created () {
},
data () {
return {
}
},
computed: {
},
watch: {
},
methods: {
resize: function () {
if (this.$refs.chart_ref != null) {
this.$refs.chart_ref.resize()
}
},
updateZoom: function (e) {
this.$emit('dataZoomEvent', e)
},
showLoading (options) {
this.$refs.chart_ref.showLoading(options)
},
hideLoading () {
this.$refs.chart_ref.hideLoading()
},
clear () {
this.$refs.chart_ref.clear()
},
},
async mounted () {
this.resizeTimer = setInterval(this.resize, 1000)
},
destroyed () {
clearInterval(this.resizeTimer)
},
}
</script>
<style lang='scss'>
.va-card {
&__body {
padding: 0.75rem;
}
}
</style>
@@ -0,0 +1,105 @@
<template>
<div>
<va-card>
<edit-file-name style="display: inline;" :ref="'edit_file_name'"/>
<download-file style="display: inline;"/>
<delete-file style="display: inline;"/>
<br/>
<change-axis class="box_inline-block" :ref="'change_axis_x'" deviceName="elite" axis="x" @changeAxis="changeAxis" @changeUnit="changeUnit" @clearCycle="clearCycle" @resetScale="resetScale"/>
<change-unit class="box_inline-block" :ref="'change_unit_x'" deviceName="elite" axis="x" @refreshChart="refreshChart"/>
<change-scale class="box_inline-block" :ref="'change_scale_x'" deviceName="elite" axis="x" @refreshChart="refreshChart"/>
<br/>
<change-axis class="box_inline-block" :ref="'change_axis_y'" deviceName="elite" axis="y" @changeAxis="changeAxis" @changeUnit="changeUnit" @clearCycle="clearCycle" @resetScale="resetScale"/>
<change-unit class="box_inline-block" :ref="'change_unit_y'" deviceName="elite" axis="y" @refreshChart="refreshChart"/>
<change-scale class="box_inline-block" :ref="'change_scale_y'" deviceName="elite" axis="y" @refreshChart="refreshChart"/>
<change-cycle style="margin: 3px;" :ref="'change_cycle'" @refreshChart="refreshChart"/>
<show-resample-rate style="margin: 3px;"/>
<show-parameter style="margin: 3px;" :ref="'show_param'" deviceName="elite"/>
</va-card>
</div>
</template>
<script>
import ShowResampleRate from '@/components/analysis/replay/toolbox/ShowResampleRate.vue'
import ChangeAxis from '@/components/analysis/replay/toolbox/ChangeAxis.vue'
import ChangeUnit from '@/components/analysis/replay/toolbox/ChangeUnit.vue'
import ChangeScale from '@/components/analysis/replay/toolbox/ChangeScale.vue'
import ChangeCycle from '@/components/analysis/replay/toolbox/ChangeCycle.vue'
import DownloadFile from '@/components/analysis/replay/toolbox/DownloadFile.vue'
import DeleteFile from '@/components/analysis/replay/toolbox/DeleteFile.vue'
import EditFileName from '@/components/analysis/replay/toolbox/EditFileName.vue'
import ShowParameter from '@/components/analysis/replay/toolbox/ShowParameter.vue'
export default {
name: 'top-control-panel',
components: {
ShowResampleRate,
ChangeAxis,
ChangeUnit,
ChangeScale,
ChangeCycle,
DownloadFile,
DeleteFile,
EditFileName,
ShowParameter,
},
computed: {
},
props: {
},
async created () {
},
data () {
return {
}
},
mqtt: {
},
methods: {
init () {
this.$refs.change_axis_x.init()
this.$refs.change_axis_y.init()
this.$refs.change_unit_x.init()
this.$refs.change_unit_y.init()
this.$refs.change_scale_x.init()
this.$refs.change_scale_y.init()
this.$refs.change_cycle.init()
this.$refs.edit_file_name.init()
this.$refs.show_param.init()
},
refreshChart (options) {
this.$emit('refreshChart', options)
},
changeAxis (gridIndex) {
this.$emit('changeAxis', gridIndex)
},
changeUnit (axis) {
if (axis === 'x') {
this.$refs.change_unit_x.changeUnitByAxis()
} else if (axis === 'y') {
this.$refs.change_unit_y.changeUnitByAxis()
}
},
clearCycle () {
this.$refs.change_cycle.clear()
},
resetScale () {
this.$refs.change_scale_x.reset()
this.$refs.change_scale_y.reset()
},
},
// use watch because va-select with @change will have bug
watch: {
},
mounted () {
},
}
</script>
<style lang="scss">
.box_inline-block {
padding: 2px;
margin: 2px;
display: inline-block;
}
</style>
@@ -0,0 +1,460 @@
<template>
<div>
<div class="row row-equal">
<div class="flex md12 xl3 xs12 sm12 area-style">
<div class="row">
<div class="flex sm12 xl12 md12 xs12">
<va-accordion>
<va-collapse class="mb-2" :isOpenDefault="true">
<span slot="header">Control Panel</span>
<div slot="body">
<div>
<top-control-panel :ref="'top_control_panel'" @refreshChart="setOption"/>
</div>
</div>
</va-collapse>
</va-accordion>
</div>
</div>
</div>
<div :class="chartAreaClass" class="area-style">
<div class="row" >
<div class="flex sm12 xl12 md12 xs12">
<neulive-replay-overview-chart :ref="'chart_overview'" class="mb-1" :cardheight="'7vh'" :data="chartOverviewData" @dataZoomEvent="dataZoomEvent($event)"/>
<neulive-replay-chart :ref="'chart_detail'" @dblclick.native="distribute()" :cardheight="'80vh'" :data="chartDetailData" @dataZoomEvent="updateMarkArea($event)" />
<change-channel-value-min-max :ref="'set_min_max'"/>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import { mapActions, mapGetters, mapMutations } from 'vuex'
import NeuliveReplayChart from './NeuliveReplayChart.vue'
import NeuliveReplayOverviewChart from './NeuliveReplayOverviewChart.vue'
import TopControlPanel from './TopControlPanel.vue'
import ChangeChannelValueMinMax from '@/components/analysis/replay/toolbox/ChangeChannelValueMinMax.vue'
import api from '@/data/api/index'
import { download } from '@/data/download/Download'
import types from '@/store/modules/analysis/replay/types'
import { mapFields } from 'vuex-map-fields'
export default {
name: 'neulive-data-replay',
components: {
NeuliveReplayChart,
NeuliveReplayOverviewChart,
TopControlPanel,
ChangeChannelValueMinMax,
},
computed: {
...mapFields('replay', [
'chartData',
'chartOverviewData',
'chartDetailData',
'currentScale',
'startTimeCurrent',
'endTimeCurrent',
]),
},
props: {
},
async created () {
this.chartOverviewData = await this.initChart({
chartAllData: this.chartData,
chartID: 0,
gridLength: 1,
type: 'overview',
device: 'neulive',
mode: 0,
})
this.chartDetailData = await this.initChart({
chartAllData: this.chartData,
chartID: 1,
gridLength: 1,
type: 'detail',
device: 'neulive',
mode: 0,
})
},
data () {
return {
metaList: null,
dataInfo: {},
maxTime: 0,
startTime: 0,
endTime: 0,
zoomTime: 0,
chartAreaClass: ['flex', 'xs12', 'sm12', 'md12', 'xl9', 'pa-0'],
dataZoomStart: 0,
dataZoomEnd: 100,
}
},
mqtt: {
},
methods: {
turnOnAxisEventHandler (eventName, query, handler, attr) {
this.$refs.chart_detail.turnOnAxisEventHandler(eventName, query, handler, attr)
},
showMinMaxPanel (params) {
this.$refs.set_min_max.showPanel(params)
},
setOption (options) {
this.$refs.chart_detail.mergeOptions(options)
},
showChartLoading: function (chart) {
const loadStyle = {
text: '',
color: '#cccccc',
maskColor: 'rgba(255, 255, 255, 0.8)',
zlevel: 0,
}
switch (chart) {
case 'overview':
this.$refs.chart_overview.showLoading(loadStyle)
break
case 'detail':
this.$refs.chart_detail.showLoading(loadStyle)
break
default:
this.$refs.chart_overview.showLoading(loadStyle)
this.$refs.chart_detail.showLoading(loadStyle)
break
}
},
hideChartLoading: function () {
this.$refs.chart_overview.hideLoading()
this.$refs.chart_detail.hideLoading()
},
getData: async function (scale, sampleMethod, id, channel, meta) {
if (scale === 1) {
return await download.rawByIDChannels(id, channel, meta)
} else {
if (sampleMethod === 'mean') {
return await download.miniMeanByIDChannel(id, channel, meta)
} else if (sampleMethod === 'random') {
return await download.miniRandomByIDChannel(id, channel, meta)
}
}
},
register: async function () {
let chNumber = 0
this.metaList.forEach(meta => {
chNumber += JSON.parse(meta.channels).length
})
this.updateGridListChart({
chartAllData: this.chartData,
chartID: this.chartDetailData.chartID,
gridLength: chNumber,
})
let _chNumber = 0
// console.log(this.chartDetailData)
const register = this.metaList.map(meta => {
this.metaList.map(meta => {
JSON.parse(meta.channels).map(ch => {
this.registerChart({
chartAllData: this.chartData,
chartID: this.chartDetailData.chartID,
gridIndex: _chNumber,
deviceNameX: 'Time',
deviceNameY: 'Neulive',
deviceIDY: meta.name,
channelY: ch,
})
this.registerChart({
chartAllData: this.chartData,
chartID: this.chartOverviewData.chartID,
gridIndex: 0,
deviceNameX: 'Time',
deviceNameY: 'Neulive',
deviceIDY: meta.name,
channelY: ch,
})
_chNumber++
})
})
if (this.maxTime < parseInt(meta.time_duration)) {
this.maxTime = parseInt(meta.time_duration)
this.endTime = this.endTimeCurrent = this.maxTime
}
})
await Promise.all(register)
this.chartDetailData.series.forEach((series, index) => {
this.chartDetailData.xAxis[series.xAxisIndex].min = 0
this.chartDetailData.xAxis[series.xAxisIndex].max = this.maxTime
})
this.chartOverviewData.series.forEach((series, index) => {
this.chartOverviewData.xAxis[series.xAxisIndex].min = 0
this.chartOverviewData.xAxis[series.xAxisIndex].max = this.maxTime
})
this.chartDetailData.xAxis[this.chartDetailData.xAxis.length - 1].axisLabel.show = true
this.updateDataZoomChart({
chartAllData: this.chartData,
chartID: 0,
})
this.updateDataZoomChart({
chartAllData: this.chartData,
chartID: 1,
})
},
updateMarkArea: function (e) {
console.log(e)
if (e.batch != null) {
// console.log(e.batch)
e.batch.forEach(dataZoom => {
const id = parseInt(dataZoom.dataZoomId.substr(dataZoom.dataZoomId.length - 3, dataZoom.dataZoomId.length - 1))
if (id === 1) {
this.dataZoomStart = dataZoom.start
this.dataZoomEnd = dataZoom.end
const startTime = (this.endTime - this.startTime) * dataZoom.start / 100
const endTime = (this.endTime - this.startTime) * dataZoom.end / 100
this.chartOverviewData.series[0].markArea.data[0][0].xAxis = this.startTime + startTime
this.chartOverviewData.series[0].markArea.data[0][1].xAxis = this.startTime + endTime
// console.log(this.startTime, this.endTime)
}
})
} else {
const id = parseInt(e.dataZoomId.substr(e.dataZoomId.length - 3, e.dataZoomId.length - 1))
if (id === 0) {
this.dataZoomStart = e.start
this.dataZoomEnd = e.end
const startTime = (this.endTime - this.startTime) * e.start / 100
const endTime = (this.endTime - this.startTime) * e.end / 100
this.chartOverviewData.series[0].markArea.data[0][0].xAxis = this.startTime + startTime
this.chartOverviewData.series[0].markArea.data[0][1].xAxis = this.startTime + endTime
// console.log(this.startTime, this.endTime)
}
}
},
dataZoomEvent: function (e) {
// console.log(e)
if (e.batch != null) {
// console.log(e.batch)
e.batch.forEach(dataZoom => {
const id = parseInt(dataZoom.dataZoomId.substr(dataZoom.dataZoomId.length - 3, dataZoom.dataZoomId.length - 1))
if (id === 1) {
this.startTime = this.maxTime * dataZoom.start / 100
this.endTime = this.maxTime * dataZoom.end / 100
// console.log(this.startTime, this.endTime)
}
})
} else {
const id = parseInt(e.dataZoomId.substr(e.dataZoomId.length - 3, e.dataZoomId.length - 1))
if (id === 0) {
this.startTime = this.maxTime * e.start / 100
this.endTime = this.maxTime * e.end / 100
// console.log(this.startTime, this.endTime)
}
}
this.chartOverviewData.series[0].markArea.data[0][0].xAxis = this.startTime + ((this.endTime - this.startTime) * (this.dataZoomStart / 100))
this.chartOverviewData.series[0].markArea.data[0][1].xAxis = this.startTime + ((this.endTime - this.startTime) * (this.dataZoomEnd / 100))
this.zoomTime = 0
},
drawOverviewData: async function () {
this.showChartLoading('overview')
for (const meta in this.dataInfo) {
let metaInfo
this.metaList.forEach(_meta => {
if (parseInt(_meta.id) === parseInt(meta)) {
metaInfo = _meta
}
})
const sampleRate = (80000 / metaInfo.parameter_set.ADC_CLOCK)
let scale = (((metaInfo.time_duration / 100000) * sampleRate) / 4000)
if (scale > 500) {
scale = '1000'
} else if (scale > 200) {
scale = '100'
} else if (scale > 30) {
scale = '10'
} else {
scale = '1'
}
console.log('overview scale:', scale)
const sampleMethod = 'mean'
const getAllData = async function (_this) {
for (const ch in _this.dataInfo[meta]) {
const dataList = _this.dataInfo[meta][ch][scale]
for (let i = 0; i < dataList.length; i++) {
if (dataList[i].data.length === 0) {
_this.intoDataRec({
index: i,
metaID: meta,
channel: ch,
scale: scale,
data: await _this.getData(parseInt(scale), sampleMethod, dataList[i].id, ch, metaInfo),
})
}
}
}
}
await getAllData(this)
let seriesIndex = 0
for (const ch in this.dataInfo[meta]) {
const dataList = this.dataInfo[meta][ch][scale]
for (let i = 0; i < dataList.length; i++) {
this.chartOverviewData.series[seriesIndex].data.push(...dataList[i].data)
}
seriesIndex++
}
}
this.hideChartLoading()
},
drawDetailData: async function () {
this.showChartLoading('detail')
const timeDur = this.endTimeCurrent - this.startTimeCurrent
for (const meta in this.dataInfo) {
let metaInfo
this.metaList.forEach(_meta => {
if (parseInt(_meta.id) === parseInt(meta)) {
metaInfo = _meta
}
})
const sampleRate = (80000 / metaInfo.parameter_set.ADC_CLOCK)
let scale = (((timeDur / 100000) * sampleRate) / 4000)
if (scale > 500) {
scale = '1000'
} else if (scale > 200) {
scale = '100'
} else if (scale > 30) {
scale = '10'
} else {
scale = '1'
}
this.currentScale = scale
const sampleMethod = 'mean'
let seriesIndex = 0
for (const ch in this.dataInfo[meta]) {
this.chartDetailData.series[seriesIndex].data.length = 0
const dataList = this.dataInfo[meta][ch][scale]
let startIndex = 0
let endIndex = 0
// get the subfile index
for (let i = 0; i < dataList.length; i++) {
if (this.startTimeCurrent >= parseInt(dataList[i].start_time) && this.startTimeCurrent <= parseInt(dataList[i].end_time)) {
startIndex = i
}
if (this.endTimeCurrent >= parseInt(dataList[i].start_time) && this.endTimeCurrent <= parseInt(dataList[i].end_time)) {
endIndex = i
}
}
// download and push into chart
for (let i = startIndex; i <= endIndex; i++) {
const data = await this.getData(parseInt(scale), sampleMethod, dataList[i].id, ch, metaInfo)
for (let j = 0, len = data.length; j < len; j++) {
if (parseInt(data[j][0]) >= this.startTimeCurrent && parseInt(data[j][0]) <= this.endTimeCurrent) {
this.chartDetailData.series[seriesIndex].data.push(data[j])
}
}
}
for (let i = 0, len = this.chartDetailData.xAxis.length; i < len; i++) {
this.chartDetailData.xAxis[i].min = this.startTimeCurrent
this.chartDetailData.xAxis[i].max = this.endTimeCurrent
}
seriesIndex++
}
}
this.hideChartLoading()
},
checkDataZoom: function () {
this.zoomTime++
if (this.zoomTime >= 2) {
if (this.startTimeCurrent !== this.startTime || this.endTimeCurrent !== this.endTime) {
this.startTimeCurrent = this.startTime
this.endTimeCurrent = this.endTime
this.drawDetailData()
}
}
},
distribute: function () {
if (this.chartDetailData.grid.length === 1) {
this.chartDetailData.xAxis[0].axisLabel.show = false
this.updateGridListChart({
chartAllData: this.chartData,
chartID: this.chartDetailData.chartID,
gridLength: this.chartDetailData.series.length,
})
this.chartDetailData.series.forEach((series, index) => {
series.xAxisIndex = index
series.yAxisIndex = index
})
this.chartDetailData.xAxis[this.chartDetailData.xAxis.length - 1].axisLabel.show = true
} else {
this.updateGridListChart({
chartAllData: this.chartData,
chartID: this.chartDetailData.chartID,
gridLength: 1,
})
this.chartDetailData.series.forEach(series => {
series.xAxisIndex = 0
series.yAxisIndex = 0
})
this.chartDetailData.xAxis[0].axisLabel.show = true
}
},
...mapActions('replay', [types.chart.init, types.chart.register, types.chart.clear, types.chart.updateGridList, types.chart.updateDataZoom]),
...mapActions('replay', [types.meta.init]),
...mapActions('replay', [types.rec.init, types.rec.intoData, types.rec.initDisplaySetting, types.rec.updateDisplaySetting]),
...mapMutations('replay', [types.meta.updateByIndex]),
...mapGetters('replay', [types.meta.getAll]),
...mapGetters('replay', [types.rec.getAll, types.rec.getAllDisplaySetting, types.rec.getDisplaySettingByKey]),
},
// use watch because va-select with @change will have bug
watch: {
},
async mounted () {
this.showChartLoading()
const metaIDList = this.$route.params.metaList.split('-')
await this.initMeta({ metaIDList: metaIDList, api: api })
this.metaList = this.getAllMeta()
await this.initRec({ api: api })
this.dataInfo = this.getAllRec()
console.log(this.dataInfo)
await this.register()
this.drawOverviewData()
this.drawDetailData()
this.dataZoomTimer = setInterval(this.checkDataZoom, 1000)
this.$refs.top_control_panel.init()
this.$refs.set_min_max.init()
this.turnOnAxisEventHandler('click', 'yAxis.axisLabel', this.showMinMaxPanel, { axis: 'y' })
},
beforeDestroy () {
this.$refs.chart_overview.clear()
this.$refs.chart_detail.clear()
for (const id in this.chartData) {
for (const _series of this.chartData[id].series) {
_series.length = 0
}
delete this.chartData[id]
}
this.clearChart({ chartAllData: this.chartData })
},
destroyed () {
clearInterval(this.dataZoomTimer)
},
}
</script>
<style lang="scss">
.area-style {
height: auto;
overflow-y: hidden;
overflow-x: hidden;
@include media-breakpoint-only(xl) {
height: 93vh;
overflow-y: scroll;
overflow-x: hidden;
}
}
.layout.gutter--xl .row .flex {
padding: 0.75rem 0.5rem 0.1rem 0.5rem;
}
</style>
@@ -0,0 +1,110 @@
<template>
<div class="flex" :class="cardclass">
<va-card :style="'height: ' + cardheight + ';'">
<chart :ref="'chart_ref'" :style="'width: '+ cardwidth + '; height: ' + cardheight + ';'" :options="data" @dataZoom="updateZoom" :auto-resize="true"></chart>
</va-card>
</div>
</template>
<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',
components: {
},
props: {
data: {
type: Object,
default: function () {
return {}
},
},
cardclass: {
type: Array,
default: function () {
return ['xs12', 'md12', 'xl12', 'sm12']
},
},
cardheight: {
type: String,
default: '82vh',
},
cardwidth: {
type: String,
default: 'auto',
},
},
created () {
},
data () {
return {
}
},
computed: {
},
watch: {
},
methods: {
resize: function () {
if (this.$refs.chart_ref != null) {
this.$refs.chart_ref.resize()
}
},
updateZoom: function (e) {
this.$emit('dataZoomEvent', e)
},
mergeOptions (options) {
this.$refs.chart_ref.mergeOptions(options)
},
turnOnAxisEventHandler (eventName, query, handler, attr) {
const chartID = 1
this.updateAxisEventHandlerChart({
chartID: chartID,
axis: attr.axis,
status: 'on',
})
// doc: https://echarts.apache.org/zh/api.html#echartsInstance.on
this.$refs.chart_ref.chart._zr.on(eventName, query, handler)
},
turnOffAxisEventHandler (eventName, handler, attr) {
const chartID = 1
this.updateAxisEventHandlerChart({
chartID: chartID,
axis: attr.axis,
status: 'off',
})
// doc: https://echarts.apache.org/zh/api.html#echartsInstance.off
this.$refs.chart_ref.chart._zr.off(eventName, handler)
},
showLoading (options) {
this.$refs.chart_ref.showLoading(options)
},
hideLoading () {
this.$refs.chart_ref.hideLoading()
},
clear () {
this.$refs.chart_ref.clear()
},
...mapMutations('replay', [types.chart.updateAxisEventHandler]),
},
async mounted () {
this.resizeTimer = setInterval(this.resize, 1000)
},
destroyed () {
clearInterval(this.resizeTimer)
},
}
</script>
<style lang='scss'>
.va-card {
&__body {
padding-top: 0.25rem;
}
}
</style>
@@ -0,0 +1,83 @@
<template>
<div class="flex" :class="cardclass">
<va-card :style="'height: 8vh;'">
<chart :ref="'chart_ref'" :style="'width: '+ cardwidth + '; height: ' + cardheight + ';'" :options="data" @dataZoom="updateZoom" :auto-resize="true"></chart>
</va-card>
</div>
</template>
<script>
// import { chartData } from '../../../../data/task/ChartsManagement'
export default {
name: 'neulive-replay-overview-chart',
components: {
},
props: {
data: {
type: Object,
default: function () {
return {}
},
},
cardclass: {
type: Array,
default: function () {
return ['xs12', 'md12', 'xl12', 'sm12']
},
},
cardheight: {
type: String,
default: '82vh',
},
cardwidth: {
type: String,
default: 'auto',
},
},
created () {
},
data () {
return {
}
},
computed: {
},
watch: {
},
methods: {
resize: function () {
if (this.$refs.chart_ref != null) {
this.$refs.chart_ref.resize()
}
},
updateZoom: function (e) {
this.$emit('dataZoomEvent', e)
},
showLoading (options) {
this.$refs.chart_ref.showLoading(options)
},
hideLoading () {
this.$refs.chart_ref.hideLoading()
},
clear () {
this.$refs.chart_ref.clear()
},
},
async mounted () {
this.resizeTimer = setInterval(this.resize, 1000)
},
destroyed () {
clearInterval(this.resizeTimer)
},
}
</script>
<style lang='scss'>
.va-card {
&__body {
padding: 0.75rem;
}
}
</style>
@@ -0,0 +1,70 @@
<template>
<div>
<va-card>
<edit-file-name style="display: inline;" :ref="'edit_file_name'"/>
<download-file style="display: inline;"/>
<delete-file style="display: inline;"/>
<show-resample-rate/>
<change-unit v-show="showXUnit" :ref="'change_unit_x'" deviceName="neulive" axis="x" @refreshChart="refreshChart"/>
<change-unit :ref="'change_unit_y'" deviceName="neulive" axis="y" @refreshChart="refreshChart"/>
<change-scale :ref="'change_scale_y'" deviceName="neulive" axis="y" @refreshChart="refreshChart"/>
<show-parameter :ref="'show_param'" deviceName="neulive"/>
</va-card>
</div>
</template>
<script>
import ShowResampleRate from '@/components/analysis/replay/toolbox/ShowResampleRate.vue'
import ChangeUnit from '@/components/analysis/replay/toolbox/ChangeUnit.vue'
import ChangeScale from '@/components/analysis/replay/toolbox/ChangeScale.vue'
import DownloadFile from '@/components/analysis/replay/toolbox/DownloadFile.vue'
import DeleteFile from '@/components/analysis/replay/toolbox/DeleteFile.vue'
import EditFileName from '@/components/analysis/replay/toolbox/EditFileName.vue'
import ShowParameter from '@/components/analysis/replay/toolbox/ShowParameter.vue'
export default {
name: 'top-control-panel',
components: {
ShowResampleRate,
ChangeUnit,
ChangeScale,
DownloadFile,
DeleteFile,
EditFileName,
ShowParameter,
},
computed: {
},
props: {
},
async created () {
},
data () {
return {
showXUnit: false,
}
},
mqtt: {
},
methods: {
init () {
this.$refs.change_unit_x.init()
this.$refs.change_unit_y.init()
this.$refs.change_scale_y.init()
this.$refs.edit_file_name.init()
this.$refs.show_param.init()
},
refreshChart (options) {
this.$emit('refreshChart', options)
},
},
// use watch because va-select with @change will have bug
watch: {
},
mounted () {
},
}
</script>
<style lang="scss">
</style>
@@ -0,0 +1,166 @@
<template>
<div>
<span> {{ axis }} axis: </span>
<div v-if="axis === 'x'" style="display: inline;">
<select v-model="channelFormat" @change="changeAxis()">
<option v-for="option in channelOptions" :key="option.id" :value="option">
{{ option.description }}
</option>
</select>
</div>
<div v-if="axis === 'y'" style="display: inline;">
<select v-model="channelFormat" @change="changeAxis()">
<option v-for="option in channelYOptions" :key="option.id" :value="option">
{{ option.description }}
</option>
</select>
</div>
</div>
</template>
<script>
import { mapFields } from 'vuex-map-fields'
import { newChartMode } from '@/factories/chart/chartFactory'
export default {
name: 'change-axis',
components: {
},
props: {
deviceName: {
type: String, // elite or neulive
},
axis: {
type: String, // x or y
},
metaIndex: {
type: Number, // which meta file
default: 0,
},
},
created () {
},
computed: {
...mapFields('replay', [
'chartData',
'metaList',
'axisXDataType',
'axisYDataType',
]),
},
methods: {
init () {
if (this.deviceName === 'neulive') {
// now neulive only v-t
if (this.axis === 'x') {
this.axisXDataType = this.channelOptions[3]
} else if (this.axis === 'y') {
this.axisYDataType = this.channelOptions[1]
}
} else if (this.deviceName === 'elite') {
// use state meta to decide which default unit need to be used (like check I-V mode...)
const setting = newChartMode(this.metaList[this.metaIndex].parameter_set.MODE)
const xType = setting[0]
const xValue = setting[1]
const yType = setting[2]
const yValue = setting[3]
let settingType
let settingValue
if (this.axis === 'x') {
settingType = xType
settingValue = xValue
if (settingType === 'Elite') {
// 1: I, 2: V, 3: R
if (settingValue === 1) {
this.axisXDataType = this.channelOptions[0]
} else if (settingValue === 2) {
this.axisXDataType = this.channelOptions[1]
} else if (settingValue === 3) {
this.axisXDataType = this.channelOptions[2]
}
} else if (settingType === 'Time') {
this.axisXDataType = this.channelOptions[3]
}
this.channelFormat = this.axisXDataType
} else if (this.axis === 'y') {
settingType = yType
settingValue = yValue
if (settingType === 'Elite') {
// 1: I, 2: V, 3: R
if (settingValue === 1) {
this.axisYDataType = this.channelOptions[0]
} else if (settingValue === 2) {
this.axisYDataType = this.channelOptions[1]
} else if (settingValue === 3) {
this.axisYDataType = this.channelOptions[2]
}
} else if (settingType === 'Time') {
this.axisYDataType = this.channelOptions[3]
}
this.channelFormat = this.axisYDataType
}
}
if (this.axis === 'y') { // only need to draw once time when init
this.changeAxis()
}
},
changeAxis () {
if (this.axis === 'x') {
this.axisXDataType = this.channelFormat
} else if (this.axis === 'y') {
this.axisYDataType = this.channelFormat
}
if (this.deviceName === 'neulive') {
console.log('(Last updated: 2021/06/07) [TODO] for elite now, cuz neulive now only have v-t graph, for future neulive replay need to adjust')
} else if (this.deviceName === 'elite') {
this.$emit('changeAxis', this.metaIndex) // temporarily use metaIndex for gridIndex
this.$emit('changeUnit', this.axis)
this.$emit('resetScale')
this.$emit('clearCycle')
}
},
},
mounted () {
},
data () {
return {
channelFormat: {},
channelOptions: [
{
id: 0,
description: 'Current',
},
{
id: 1,
description: 'Voltage',
},
{
id: 2,
description: 'Resistance',
},
{
id: 100, // no usage, so assign a large number to avoid conflicting with existing channel data
description: 'Time',
},
],
channelYOptions: [
{
id: 0,
description: 'Current',
},
{
id: 1,
description: 'Voltage',
},
{
id: 2,
description: 'Resistance',
},
],
}
},
destroyed () {
},
}
</script>
@@ -0,0 +1,99 @@
<template>
<div>
<va-modal
class="flex sm12 xl12 md12 xs12"
v-model="showModal.minMaxPanel"
size="small"
:position="position"
:title="'Set min max (if blank, will be auto-set)'"
:okText=" $t('modal.confirm') "
@ok="setMinMax()"
>
<va-input
v-model="minMaxInfo[gridIndex].max"
:label="'Max'"
/>
<va-input
v-model="minMaxInfo[gridIndex].min"
:label="'Min'"
/>
</va-modal>
</div>
</template>
<script>
import { mapMutations } from 'vuex'
import { mapFields } from 'vuex-map-fields'
import types from '@/store/modules/analysis/replay/types'
export default {
name: 'change-channel-value-min-max',
components: {
},
props: {
chartID: {
type: Number,
default: 1, // detail data
},
},
created () {
},
data () {
return {
gridIndex: 0,
axis: 'y',
showModal: {
minMaxPanel: false,
},
minMaxInfo: { 0: { min: '', max: '' } }, // will be set by init()
position: 'center',
}
},
computed: {
...mapFields('replay', [
'chartData',
]),
},
watch: {
},
methods: {
init () {
const len = this.chartData[this.chartID].series.length
for (let i = 0; i < len; i++) {
this.minMaxInfo[i] = { min: '', max: '' }
}
},
showPanel (params) {
if (params.target !== undefined) {
if (params.target.eventData.componentType === 'xAxis' && params.target.eventData.targetType === 'axisLabel') {
this.gridIndex = params.target.eventData.xAxisIndex
this.axis = 'x'
this.position = 'bottom'
} else if (params.target.eventData.componentType === 'yAxis' && params.target.eventData.targetType === 'axisLabel') {
this.gridIndex = params.target.eventData.yAxisIndex
this.axis = 'y'
this.position = 'left'
}
this.showModal.minMaxPanel = true
}
},
setMinMax () {
this.updateAxisValMinMaxChart({
chartID: this.chartID,
axis: this.axis,
axisIndex: this.gridIndex,
minVal: this.minMaxInfo[this.gridIndex].min,
maxVal: this.minMaxInfo[this.gridIndex].max,
})
this.$emit('refreshChart', this.chartData[this.chartID])
},
...mapMutations('replay', [types.chart.updateAxisValMinMax]),
},
mounted () {
},
destroyed () {
},
}
</script>
@@ -0,0 +1,153 @@
<template>
<div v-show="showPanel">
<va-input
v-model="showWhichCycles"
@change="setCycle"
:label="$t('See which cycles')"
/>
</div>
</template>
<script>
import { mapMutations } from 'vuex'
import { mapFields } from 'vuex-map-fields'
import types from '@/store/modules/analysis/replay/types'
export default {
name: 'change-cycle',
components: {
},
props: {
chartID: {
type: Number,
default: 1, // detail data
},
metaIndex: {
type: Number, // which meta file
default: 0,
},
},
created () {
},
data () {
return {
showPanel: true,
metaID: 0,
showWhichCycles: '',
cycleNum: 0,
cycleDataID: 3, // [TODO] manage by data type factory
}
},
computed: {
slices: function () {
const cycleList = this.showWhichCycles.split(',')
if (cycleList.length === 1 && cycleList[0] === '') {
return ''
}
for (let i = 0; i < cycleList.length; i++) {
const element = cycleList[i]
if (element.includes('-')) {
const startIndex = element.split('-')[0]
const endIndex = element.split('-')[1]
cycleList[i] = startIndex
for (let j = endIndex; j >= parseInt(startIndex) + 1; j--) {
cycleList.splice(i + 1, 0, j.toString()) // arr.splice(index, 0, item); will insert item into arr at the specified index (deleting 0 items first, that is, it's just an insert).
}
}
}
// console.log(cycleList)
return cycleList
},
...mapFields('replay', [
'chartData',
'recInfo',
'metaList',
'currentScale',
'axisXDataType',
'axisYDataType',
]),
},
watch: {
},
methods: {
init () {
this.cycleNum = this.metaList[this.metaIndex].parameter_set.CYCLE_NUMBER
this.metaID = this.metaList[this.metaIndex].id
if (this.cycleNum === 0) {
this.showPanel = false
}
},
clear () {
this.showWhichCycles = ''
},
setCycle () {
console.log('setCycle')
if (this.cycleNum !== 0) {
// get cycle data
const allCycleData = this.recInfo[this.metaID][this.cycleDataID][this.currentScale][this.metaIndex].data
var cycleDict = {}
var cycleStartIndex = 0
var cycleEndIndex = 0
var currentCycleIndex = 0
for (let index = 0; index < allCycleData.length; index++) {
const value = allCycleData[index]
const cycleIndex = parseInt(value[1])
if (cycleIndex === currentCycleIndex) {
if (currentCycleIndex in cycleDict) {
cycleEndIndex = index
cycleDict[cycleIndex][1] = cycleEndIndex
} else {
cycleDict[cycleIndex] = [cycleStartIndex, cycleEndIndex]
}
} else {
cycleStartIndex = index
currentCycleIndex++
}
}
// get recording data
let allXData
if (this.axisXDataType.description !== 'Time') {
allXData = this.recInfo[this.metaID][this.axisXDataType.id][this.currentScale][this.metaIndex].data
}
const allYData = this.recInfo[this.metaID][this.axisYDataType.id][this.currentScale][this.metaIndex].data
const data = []
for (let sliceIndex = 0; sliceIndex < this.cycleNum; sliceIndex++) {
// console.log(this.slices)
if (this.slices === '' || this.slices.includes((sliceIndex + 1).toString())) {
// slice data
const value = cycleDict[sliceIndex + 1]
const start = value[0]
const end = value[1] + 1
const sliceYData = allYData.slice(start, end)
const sliceLen = sliceYData.length
if (allXData !== undefined) {
const sliceXData = allXData.slice(start, end)
for (let j = 0; j < sliceLen; j++) {
data.push([sliceXData[j][1], sliceYData[j][1]])
}
} else {
const sliceYData = allYData.slice(start, end)
for (let j = 0; j < sliceLen; j++) {
data.push(sliceYData[j])
}
}
}
}
this.updateSeriesChart({
chartID: this.chartID,
seriesIndex: this.metaIndex,
data: JSON.parse(JSON.stringify(data)),
})
}
this.$emit('refreshChart', this.chartData[this.chartID])
},
...mapMutations('replay', [types.chart.updateSeries]),
},
mounted () {
},
destroyed () {
},
}
</script>
@@ -0,0 +1,149 @@
<template>
<div>
<select v-model="scaleFormat" @change="changeScale()">
<option v-for="option in scaleOptions" :key="option.id" :value="option">
{{ option.description }}
</option>
</select>
</div>
</template>
<script>
import { mapMutations } from 'vuex'
import { mapFields } from 'vuex-map-fields'
import types from '@/store/modules/analysis/replay/types'
export default {
name: 'change-scale',
components: {
},
props: {
deviceName: {
type: String, // elite or neulive
},
chartID: {
type: Number, // detail data
default: 1,
},
axis: {
type: String, // x or y
},
metaIndex: {
type: Number, // which meta file
default: 0,
},
},
created () {
},
computed: {
...mapFields('replay', [
'chartData',
'recInfo',
'metaList',
'axisXLabelScale',
'axisYLabelScale',
'axisXDataType',
'axisYDataType',
'startTimeCurrent',
'endTimeCurrent',
'currentScale',
]),
},
methods: {
init () {
this.metaID = this.metaList[this.metaIndex].id
if (this.axis === 'x') {
this.axisXLabelScale = this.scaleOptions[0] // 0 mean use default unit
this.scaleFormat = this.axisXLabelScale
} else if (this.axis === 'y') {
this.axisYLabelScale = this.scaleOptions[0] // 0 mean use default unit
this.scaleFormat = this.axisYLabelScale
}
},
changeScale () {
if (this.axis === 'x') {
this.axisXLabelScale = this.scaleFormat
} else if (this.axis === 'y') {
this.axisYLabelScale = this.scaleFormat
}
if (this.deviceName === 'neulive') {
const keys = Object.keys(this.metaList[this.metaIndex].mini_data)
for (let gridIndex = 0; gridIndex < keys.length; gridIndex++) {
const key = keys[gridIndex]
if (parseInt(key) < 255) { // 256: x, 257: y, 258: z, 259: mag
this.calculateScaleHelper(gridIndex)
}
}
} else if (this.deviceName === 'elite') {
this.calculateScaleHelper(this.metaIndex)
}
this.$emit('refreshChart', this.chartData[this.chartID])
},
calculateScaleHelper (gridIndex) {
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.log10(Math.abs(seriesData[i][0]))
} else if (this.axis === 'y') {
seriesData[i][1] = Math.log10(Math.abs(seriesData[i][1]))
}
}
} else if (this.scaleFormat.description === 'Linear') {
let allXData
if (this.axisXDataType.description !== 'Time') {
allXData = this.recInfo[this.metaID][this.axisXDataType.id][this.currentScale][gridIndex].data
}
const allYData = this.recInfo[this.metaID][this.axisYDataType.id][this.currentScale][gridIndex].data
seriesData = []
for (let i = 0, len = allYData.length; i < len; i++) {
if (parseInt(allYData[i][0]) >= this.startTimeCurrent && parseInt(allYData[i][0]) <= this.endTimeCurrent) {
const processedData = JSON.parse(JSON.stringify(allYData[i]))
if (allXData !== undefined) {
processedData[0] = allXData[i][1]
}
seriesData.push(processedData)
}
}
}
this.updateSeriesChart({
chartID: this.chartID,
seriesIndex: gridIndex,
data: JSON.parse(JSON.stringify(seriesData)),
})
},
reset () {
if (this.axis === 'x') {
this.axisXLabelScale = this.scaleOptions[0] // 0 mean use default unit
this.scaleFormat = this.axisXLabelScale
} else if (this.axis === 'y') {
this.axisYLabelScale = this.scaleOptions[0] // 0 mean use default unit
this.scaleFormat = this.axisYLabelScale
}
},
...mapMutations('replay', [types.chart.updateSeries]),
},
mounted () {
},
data () {
return {
metaID: 0,
scaleFormat: { id: 0, description: 'Linear' },
scaleOptions: [
{
id: 0,
description: 'Linear',
},
{
id: 1,
description: 'Log',
},
],
}
},
destroyed () {
},
}
</script>
@@ -0,0 +1,224 @@
<template>
<div>
<select v-model="valueFormat" @change="changeUnit()">
<option v-for="option in valueFormatOptions[dataType]" :key="option.id" :value="option">
{{ option.unit }}
</option>
</select>
</div>
</template>
<script>
import { mapMutations } from 'vuex'
import { mapFields } from 'vuex-map-fields'
import types from '@/store/modules/analysis/replay/types'
import { newChartMode } from '@/factories/chart/chartFactory'
export default {
name: 'change-unit',
components: {
},
props: {
deviceName: {
type: String, // elite or neulive
},
axis: {
type: String, // x or y
},
metaIndex: {
type: Number, // which meta file
default: 0,
},
},
created () {
},
computed: {
...mapFields('replay', [
'chartData',
'metaList',
'valueFormatX',
'valueFormatY',
'axisXDataType',
'axisYDataType',
]),
},
methods: {
init () {
if (this.deviceName === 'neulive') {
// now neulive only v-t
if (this.axis === 'x') {
this.dataType = 'time'
} else if (this.axis === 'y') {
this.dataType = 'voltage'
}
} else if (this.deviceName === 'elite') {
// use state meta to decide which default unit need to be used (like check I-V mode...)
const setting = newChartMode(this.metaList[this.metaIndex].parameter_set.MODE)
const xType = setting[0]
const xValue = setting[1]
const yType = setting[2]
const yValue = setting[3]
let settingType
let settingValue
if (this.axis === 'x') {
settingType = xType
settingValue = xValue
} else if (this.axis === 'y') {
settingType = yType
settingValue = yValue
}
if (settingType === 'Elite') {
// 1: I, 2: V, 3: R
if (settingValue === 1) {
this.dataType = 'current'
} else if (settingValue === 2) {
this.dataType = 'voltage'
} else if (settingValue === 3) {
this.dataType = 'resistance'
}
} else if (settingType === 'Time') {
this.dataType = 'time'
}
}
if (this.axis === 'x') {
this.valueFormatX = this.valueFormatOptions[this.dataType][0]
this.valueFormat = this.valueFormatX
} else if (this.axis === 'y') {
this.valueFormatY = this.valueFormatOptions[this.dataType][0] // 0 mean use default unit (i.e. unitScale = 1)
this.valueFormat = this.valueFormatY
}
this.changeUnit()
},
changeUnit () {
if (this.axis === 'x') {
this.valueFormatX = this.valueFormat
} else if (this.axis === 'y') {
this.valueFormatY = this.valueFormat
}
const chartID = 1 // detail data
if (this.deviceName === 'neulive') {
const keys = Object.keys(this.metaList[this.metaIndex].mini_data)
for (let axisIndex = 0; axisIndex < keys.length; axisIndex++) {
const key = keys[axisIndex]
if (parseInt(key) < 255) { // 256: x, 257: y, 258: z, 259: mag
this.updateAxisLabelChart({
chartID: chartID,
axis: this.axis,
axisIndex: axisIndex,
})
}
}
} else if (this.deviceName === 'elite') {
this.updateAxisLabelChart({
chartID: chartID,
axis: this.axis,
axisIndex: this.metaIndex,
})
}
this.$emit('refreshChart', this.chartData[chartID])
},
changeUnitByAxis () {
if (this.axis === 'x') {
if (this.axisXDataType.description === 'Current') {
this.dataType = 'current'
} else if (this.axisXDataType.description === 'Voltage') {
this.dataType = 'voltage'
} else if (this.axisXDataType.description === 'Resistance') {
this.dataType = 'resistance'
} else if (this.axisXDataType.description === 'Time') {
this.dataType = 'time'
}
} else if (this.axis === 'y') {
if (this.axisYDataType.description === 'Current') {
this.dataType = 'current'
} else if (this.axisYDataType.description === 'Voltage') {
this.dataType = 'voltage'
} else if (this.axisYDataType.description === 'Resistance') {
this.dataType = 'resistance'
}
}
this.valueFormat = this.valueFormatOptions[this.dataType][0]
this.changeUnit()
},
// call vuex to mutate chart label formatter by unit and axis
...mapMutations('replay', [types.chart.updateAxisLabel]),
},
mounted () {
},
data () {
return {
dataType: '',
valueFormat: {},
valueFormatOptions: { // below id: 0 mean default
current: [
{
id: 0,
unit: 'nA',
unitScale: 1,
},
{
id: 1,
unit: 'uA',
unitScale: 1000,
},
{
id: 2,
unit: 'mA',
unitScale: 1000000,
},
],
voltage: [ // Voltage
{
id: 0,
unit: 'uV',
unitScale: 1,
},
{
id: 1,
unit: 'mV',
unitScale: 1000,
},
{
id: 2,
unit: 'V',
unitScale: 1000000,
},
],
resistance: [ // Resistance
{
id: 0,
unit: 'mΩ',
unitScale: 1,
},
{
id: 1,
unit: 'Ω',
unitScale: 1000,
},
{
id: 2,
unit: 'kΩ',
unitScale: 1000000,
},
{
id: 3,
unit: 'MΩ',
unitScale: 1000000000,
},
],
time: [ // Time
{
id: 0,
unit: 'auto',
unitScale: 1,
},
],
},
}
},
destroyed () {
},
}
</script>
@@ -0,0 +1,116 @@
<template>
<div>
<va-button flat small class="resize-va-button" color="gray" icon="fa fa-trash" @click.stop="deleteFileConfirm()"/>
<va-modal
v-model="showModal.deleteFile"
size="small"
:title="'DELETE'"
:message="`Delete File?`"
:okText=" $t('modal.confirm') "
@ok="deleteFile()"
>
</va-modal>
</div>
</template>
<script>
import api from '@/data/api/index'
import { mapFields } from 'vuex-map-fields'
export default {
name: 'delete-file',
components: {
},
props: {
},
created () {
},
data () {
return {
showModal: {
deleteFile: false,
},
deleteInfoList: [],
deleteInfoTemplate: {
path: '',
name: '',
metaID: 0, // id will be set later
rawChannelAndIDArrays: [], // list of lists
miniChannelAndIDArrays: [], // list of lists
},
}
},
computed: {
...mapFields('replay', [
'metaList',
]),
},
watch: {
},
methods: {
deleteFileConfirm: function () {
for (let i = 0; i < this.metaList.length; i++) {
const info = this.metaList[i]
this.deleteInfoTemplate.path = info.path
this.deleteInfoTemplate.name = info.name
this.deleteInfoTemplate.metaID = info.id
this.deleteInfoTemplate.rawChannelAndIDArrays = [] // list of lists
this.deleteInfoTemplate.miniChannelAndIDArrays = [] // list of lists
for (const [channel, idArray] of Object.entries(info.raw_data)) {
this.deleteInfoTemplate.rawChannelAndIDArrays.push([channel, idArray[0]])
}
for (const [channel, scaleObject] of Object.entries(info.mini_data)) {
for (const idArray of Object.values(scaleObject)) {
this.deleteInfoTemplate.miniChannelAndIDArrays.push([channel, idArray[0]])
}
}
this.deleteInfoList.push(JSON.parse(JSON.stringify(this.deleteInfoTemplate))) // deep copy data
}
this.showModal.deleteFile = true
},
deleteFile: async function () {
for (let i = 0; i < this.deleteInfoList.length; i++) {
const deleteInfo = this.deleteInfoList[i]
for (const item of deleteInfo.rawChannelAndIDArrays) {
const channel = item[0]
const id = item[1]
await api.raw.update(channel, id, { deleted: true })
await api.raw.clearDel(channel, id)
}
for (const item of deleteInfo.miniChannelAndIDArrays) {
const channel = item[0]
const id = item[1]
await api.mini.update(channel, id, { deleted: true })
await api.mini.clearDel(channel, id)
}
await api.meta.update(deleteInfo.metaID, { deleted: true })
await api.meta.clearDel(deleteInfo.metaID)
}
await this.deleteFileDone()
},
deleteFileDone: async function () {
this.showToast('Deleted success', {
position: 'bottom-right',
})
this.$router.go(-1)
},
},
mounted () {
},
destroyed () {
},
}
</script>
<style lang="scss">
.resize-va-button {
.va-button {
margin: 0.375rem 0.5rem 0.375rem 0.1px;
}
.va-button--small {
padding: 0.1px;
}
}
</style>
@@ -0,0 +1,57 @@
<template>
<div>
<va-button flat small class="resize-va-button" color="gray" icon="fa fa-download" @click.stop="downloadCSV()"/>
</div>
</template>
<script>
// import { download } from '@/data/download/Download'
// import { exportData } from '@/data/export/export'
import { mapFields } from 'vuex-map-fields'
export default {
name: 'download-file',
components: {
},
props: {
},
created () {
},
data () {
return {
}
},
computed: {
...mapFields('replay', [
'metaList',
]),
},
watch: {
},
methods: {
downloadCSV: async function () {
for (let i = 0; i < this.metaList.length; i++) {
const meta = this.metaList[i]
window.open('http://' + location.href.split('/')[2].split(':')[0] + '/#/admin/download/neulive/csv/' + meta.id, '_blank', 'width=500,height=100,left=200,top=200')
}
},
},
mounted () {
},
destroyed () {
},
}
</script>
<style lang="scss">
.resize-va-button {
.va-button {
margin: 0.375rem 0.5rem 0.375rem 0.1px;
}
.va-button--small {
padding: 0.1px;
}
}
</style>
@@ -0,0 +1,153 @@
<template>
<div>
<va-button flat small class="resize-va-button" color="gray" icon="fa fa-file-text-o" @click.stop="editFileConfirm()"> {{ filename }} </va-button>
<va-modal
class="flex sm12 xl12 md12 xs12"
v-model="showModal.editFile"
size="small"
:title="'CHANGE FILE NAME'"
:okText=" $t('modal.confirm') "
@ok="editFile()"
@cancel="undoEdit()"
>
<va-input
:value="editInfo.changedName"
:label="'Name'"
:placeholder="editInfo.name"
:success="editInfo.success"
:error="editInfo.error"
:error-messages="editInfo.errorMessages"
@input="checkFileNameValidate"
removable
/>
</va-modal>
</div>
</template>
<script>
import api from '@/data/api/index'
import { debounce } from 'lodash'
import { file } from '@/data/file/File'
import { mapFields } from 'vuex-map-fields'
export default {
name: 'edit-file-name',
components: {
},
props: {
},
created () {
},
data () {
return {
fileLists: [],
showModal: {
editFile: false,
},
editInfo: {
info: { id: 0 }, // id will be set in init()
changedName: '',
success: false,
error: false,
errorMessagesAll: ['File name contains illegal character', 'File name empty', 'File name exist'],
errorMessages: [],
},
filename: '',
}
},
computed: {
...mapFields('replay', [
'metaList',
]),
},
watch: {
},
methods: {
init () {
// [TODO] 0: not sure future UX design
const meta = this.metaList[0]
this.updateFileLists()
this.filename = meta.name
this.editInfo.changedName = meta.name
this.editInfo.info.id = meta.id
},
editFileConfirm () {
this.updateFileLists()
this.showModal.editFile = true
},
async updateFileLists () {
this.fileLists = []
// [TODO] 0: not sure future UX design
const meta = this.metaList[0]
file.clearFileList()
const files = await api.meta.getCollectionByParent('folder', meta.parent.folder[0])
file.updateFileList(files)
const tmpFiles = file.getFileList()
for (let i = 0; i < tmpFiles.length; i++) {
const tmp = tmpFiles[i]
this.fileLists.push(tmp)
}
},
editFile: async function () {
if (this.editInfo.success === true) {
await api.meta.update(this.editInfo.info.id, { name: this.editInfo.changedName })
this.editInfo.name = this.editInfo.changedName
this.filename = this.editInfo.changedName
}
},
undoEdit: function () {
this.editInfo.success = false
this.editInfo.error = false
this.editInfo.changedName = this.filename
this.editInfo.name = ''
this.editInfo.path = ''
},
checkFileNameValidate: debounce(function (term) {
const illegalChar = term.match(/[^(\w\-)]+/gm)
if (term.length === 0) {
// input text empty
this.editInfo.error = true
this.editInfo.success = false
this.editInfo.errorMessages.pop()
this.editInfo.errorMessages.push(this.editInfo.errorMessagesAll[1])
} else if (illegalChar !== null) {
// input text illegal
this.editInfo.error = true
this.editInfo.success = false
this.editInfo.errorMessages.pop()
this.editInfo.errorMessages.push(this.editInfo.errorMessagesAll[0] + ' ' + illegalChar[0])
} else {
const existedFile = this.fileLists.filter(file => file.name.replace('/', '') === term)
if (existedFile.length === 0) {
this.editInfo.error = false
this.editInfo.success = true
} else {
// file name exist
this.editInfo.error = true
this.editInfo.success = false
this.editInfo.errorMessages.pop()
this.editInfo.errorMessages.push(this.editInfo.errorMessagesAll[2])
}
}
this.editInfo.changedName = term
}, 200),
},
mounted () {
},
destroyed () {
},
}
</script>
<style lang="scss">
.resize-va-button {
.va-button {
margin: 0.375rem 0.5rem 0.375rem 0.1px;
}
.va-button--small {
padding: 0.1px;
}
}
</style>
@@ -0,0 +1,516 @@
<template>
<va-tree-root>
<va-tree-category label="Experiment Setting" :isOpen="false">
<pre><div style="text-transform: none;" class="title mb-3" :style="{color: this.$themes.primary}" v-html="content"></div></pre>
</va-tree-category>
</va-tree-root>
</template>
<script>
import { mapFields } from 'vuex-map-fields'
export default {
name: 'show-parameter',
components: {
},
props: {
deviceName: {
type: String, // elite or neulive
},
metaIndex: {
type: Number, // which meta file
default: 0,
},
},
created () {
},
data () {
return {
content: '',
// [region] for neulive
ampGainOptions: [
{
id: 0,
description: '25',
},
{
id: 1,
description: '100',
},
{
id: 2,
description: '400',
},
{
id: 3,
description: '800',
},
],
neuliveSampleRateOptions: [
{
id: 0,
value: 800,
description: '1k',
},
{
id: 1,
value: 400,
description: '2k',
},
{
id: 2,
value: 200,
description: '4k',
},
{
id: 3,
value: 160,
description: '5k',
},
{
id: 4,
value: 100,
description: '8k',
},
{
id: 5,
value: 80,
description: '10k',
},
],
stimulateElectrodeOptions: [
{
label: 'Monopolar',
value: 0,
},
{
label: 'Bipolar',
value: 1,
},
],
cycleNumberOptions: [
{
label: 'limite',
value: 0,
},
{
label: 'Unlimite',
value: 1,
},
],
patternModeOptions: [
{
label: 'Monophasic',
value: 0,
},
{
label: 'Biphasic',
value: 1,
},
],
unitOptions: [
{
label: 's',
value: 0,
},
{
label: 'ms',
value: 1,
},
{
label: 'us',
value: 2,
},
],
// [Endregion]
// [region] for elite
workingModeOptions: [
{
id: 0,
description: 'I-V Curve',
},
{
id: 1,
description: 'Cycle I-V',
},
{
id: 2,
description: 'Function Generator',
},
{
id: 3,
description: 'R-T Graph',
},
{
id: 4,
description: 'V-T Graph',
},
{
id: 5,
description: 'I-T Graph',
},
{
id: 6,
description: 'ADC_Test',
},
{
id: 7,
description: 'Constant Current',
},
{
id: 8,
description: 'Cyclic Voltammetry',
},
{
id: 9,
description: 'Cyclic Voltammetry-hi-cycles',
},
{
id: 10,
description: 'Linear Sweep Voltammetry',
},
{
id: 11,
description: 'Chronoamperometric Graph',
},
],
currentRangeOptions: [
{
value: 0,
label: '<40 μA',
},
{
value: 1,
label: '30-1350 μA',
},
{
value: 2,
label: '>1000 μA',
},
{
value: 3,
label: 'Auto',
},
],
stepTimeOptions: [
{
value: 0,
label: '0.5s',
},
{
value: 1,
label: '1.0s',
},
{
value: 2,
label: '2.0s',
},
],
resisterRangeOptions: [
{
value: 0,
label: '>50 kΩ',
},
{
value: 1,
label: '2-100 kΩ',
},
{
value: 2,
label: '<10 kΩ',
},
{
value: 3,
label: 'Auto',
},
],
eliteSampleRateOptions: [
{
value: 0,
label: '100',
},
{
value: 1,
label: '10',
},
{
value: 2,
label: '5',
},
{
value: 3,
label: '1',
},
{
value: 4,
label: '0.1',
},
{
value: 5,
label: '0.01',
},
],
chargeOptions: [
{
value: 0,
label: 'Charge',
},
{
value: 1,
label: 'Discharge',
},
],
// [Endregion]
}
},
computed: {
...mapFields('replay', [
'metaList',
]),
},
watch: {
},
methods: {
init () {
const meta = this.metaList[this.metaIndex]
const params = meta.parameter_set
this.content += 'Duration: ' + parseInt(parseInt(meta.time_duration / 1000000) / 60) + ' m ' + parseInt((meta.time_duration % 60000000) / 1000000) + ' s<br/>'
this.content += '<br/>Parameter: <br/>'
this.content += '<br/> Recording: <br/>'
if (this.deviceName === 'neulive') {
// recording param
for (const [key, value] of Object.entries(params)) {
if (!(key.includes('sti') || key.includes('STI'))) {
let showKey = ''
let showValue = value
if (key === 'RECORDING_CH' || key === 'AXIS_CH' || key === 'AMP_GAIN' || key === 'ADC_CLOCK') {
if (key === 'RECORDING_CH') {
showKey = 'Channels'
// convert decimal to binary
const binaryChannelValue = showValue.toString(2)
const channelValue = binaryChannelValue.split('')
showValue = ''
channelValue.forEach(function (value, i) {
if (value === '1') {
showValue += `${i + 1} `
}
})
if (showValue === '') {
showValue = 'None'
}
} else if (key === 'AXIS_CH') {
showKey = '3-AXIS'
// convert decimal to binary
const binaryChannelValue = showValue.toString(2)
const channelValue = binaryChannelValue.split('').reverse()
showValue = ''
channelValue.forEach(function (value, i) {
if (value === '1') {
if (i === 0) {
showValue += 'x '
} else if (i === 1) {
showValue += 'y '
} else if (i === 2) {
showValue += 'z '
} else if (i === 3) {
showValue += 'mag '
}
}
})
if (showValue === '') {
showValue = 'None'
}
} else if (key === 'AMP_GAIN') {
showKey = 'Amp gain'
const targetID = (value + 1) % 4
for (let i = 0; i < this.ampGainOptions.length; i++) {
if (this.ampGainOptions[i].id === targetID) {
showValue = this.ampGainOptions[i].description
}
}
} else if (key === 'ADC_CLOCK') {
showKey = 'Sample Rate'
for (let i = 0; i < this.neuliveSampleRateOptions.length; i++) {
if (this.neuliveSampleRateOptions[i].value === value) {
showValue = this.neuliveSampleRateOptions[i].description
}
}
}
this.content += ' ' + showKey + ': ' + showValue + '<br/>'
}
}
}
// stimulation param
this.content += '<br/> Stimulation: <br/>'
for (const [key, value] of Object.entries(params)) {
if (key.includes('sti') || key.includes('STI')) {
let showKey = ''
let showValue = value
if (key === 'STI_H_BRIDGE' || key === 'STI_CHANNEL' || key === 'STI_POLARITY' || key === 'CONTINUOUS_STI' ||
key === 'STI_AMPLITUDE' || key === 'STI_PATTERN' || key === 'STI_T1' || key === 'STI_T2' || key === 'STI_T3' || key === 'STI_T4') {
if (key === 'STI_H_BRIDGE') {
showKey = 'ELECTRODE'
if (value === true) {
showValue = this.stimulateElectrodeOptions[1].label
} else {
showValue = this.stimulateElectrodeOptions[0].label
}
} else if (key === 'STI_CHANNEL' || key === 'STI_POLARITY') {
if (key === 'STI_CHANNEL') {
showKey = 'Channels'
} else {
showKey = 'Polarity'
}
// convert decimal to binary
const binaryChannelValue = showValue.toString(2)
const channelValue = binaryChannelValue.split('')
showValue = ''
channelValue.forEach(function (value, i) {
if (value === '1') {
showValue += `${i + 1} `
}
})
if (showValue === '') {
showValue = 'None'
}
} else if (key === 'CONTINUOUS_STI') {
showKey = 'CYCLE NUMBER'
if (value === true) {
showValue = this.cycleNumberOptions[1].label
} else {
showValue = this.cycleNumberOptions[0].label
}
} else if (key === 'STI_AMPLITUDE') {
showKey = 'AMPLITUDE (uA)'
showValue = value * 5
} else if (key === 'STI_PATTERN') {
showKey = 'PATTERN'
if (value === true) {
showValue = this.patternModeOptions[1].label
} else {
showValue = this.patternModeOptions[0].label
}
} else if (key === 'STI_T1') {
showKey = 'T1 Range'
showValue = `${value[0] * 10 / 1000} ms` // 10 is cuz 1 value = 10us, [0] is cuz now all values in array are same
} else if (key === 'STI_T2') {
showKey = 'T2 Range'
showValue = `${value[0] * 10 / 1000} ms` // 10 is cuz 1 value = 10us
} else if (key === 'STI_T3') {
showKey = 'T3 Range'
showValue = `${value[0] * 10 / 1000} ms` // 10 is cuz 1 value = 10us
} else if (key === 'STI_T4') {
showKey = 'T4 Range'
showValue = `${value[0] * 10 / 1000} ms` // 10 is cuz 1 value = 10us
}
this.content += ' ' + showKey + ': ' + showValue + '<br/>'
}
}
}
if ('STI_T1' in params && 'STI_T2' in params && 'STI_T3' in params && 'STI_T4' in params) {
const period = (params.STI_T1[0] + params.STI_T2[0] + params.STI_T3[0] + params.STI_T4[0]) * 10 / 1000 // 10 is cuz 1 value = 10us
this.content += ' Frequency: ' + String(1000 / period) + ' Hz' + '<br/>' // 1000 is cuz 1s = 1000ms
this.content += ' Period: ' + String(period) + ' ms' + '<br/>'
}
} else if (this.deviceName === 'elite') {
for (const [key, value] of Object.entries(params)) {
let showKey = ''
let showValue = value
if (key === 'MODE') {
showKey = 'MODE'
for (let i = 0; i < this.workingModeOptions.length; i++) {
if (this.workingModeOptions[i].id === value) {
showValue = this.workingModeOptions[i].description
}
}
} else if (key === 'ADC_LEVEL') {
showKey = 'Current Range'
for (let i = 0; i < this.currentRangeOptions.length; i++) {
if (this.currentRangeOptions[i].value === value) {
showValue = this.currentRangeOptions[i].label
}
}
} else if (key === 'VOLT_ORIGIN') {
showKey = 'Volt start'
showValue = (value / 5000) - 5 + 'V'
} else if (key === 'VOLT_FINAL') {
showKey = 'Volt stop'
showValue = (value / 5000) - 5 + 'V'
} else if (key === 'VOLT_STEP') {
showKey = 'Volt step'
showValue = ((value * 2) + 2) / 10 + 'mV'
} else if (key === 'STEP_TIME') {
showKey = 'Step time'
for (let i = 0; i < this.stepTimeOptions.length; i++) {
if (this.stepTimeOptions[i].value === value) {
showValue = this.stepTimeOptions[i].label
}
}
} else if (key === 'CYCLE_NUMBER') {
showKey = 'Cycle number'
showValue = value
} else if (key === 'DAC_VOLT') {
showKey = 'Volt out'
showValue = (value / 5000) - 5 + 'V'
} else if (key === 'Resister_LEVEL') {
showKey = 'Resister Range'
for (let i = 0; i < this.resisterRangeOptions.length; i++) {
if (this.resisterRangeOptions[i].value === value) {
showValue = this.resisterRangeOptions[i].label
}
}
} else if (key === 'SAMPLE_RATE') {
showKey = 'Sample rate'
for (let i = 0; i < this.eliteSampleRateOptions.length; i++) {
if (this.eliteSampleRateOptions[i].value === value) {
showValue = this.eliteSampleRateOptions[i].label
}
}
} else if (key === 'Const_Current_value') {
showKey = 'Current'
showValue = value + 'μA'
} else if (key === 'VOLTSTOP_MAX') {
showKey = 'Volt max stop'
showValue = (value / 5000) - 5 + 'V'
} else if (key === 'VOLTSTOP_MIN') {
showKey = 'Volt min stop'
showValue = (value / 5000) - 5 + 'V'
} else if (key === 'Charge') {
showKey = 'Charge'
for (let i = 0; i < this.chargeOptions.length; i++) {
if (this.chargeOptions[i].value === value) {
showValue = this.chargeOptions[i].label
}
}
} else if (key === 'VOLT_INITIAL') {
showKey = 'E-Initial'
showValue = (value / 5000) - 5 + 'V'
} else if (key === 'VOLT_MAX') {
showKey = 'Volt max stop'
showValue = (value / 5000) - 5 + 'V'
} else if (key === 'VOLT_MIN') {
showKey = 'Volt min stop'
showValue = (value / 5000) - 5 + 'V'
} else if (key === 'Scan_Rate') {
showKey = 'ScanRate'
showValue = (value / 100) + 0.01 + 'mV/s'
} else if (key === 'Data_Resolution_Scan') {
showKey = 'Resolution'
showValue = (value / 10) + 0.1 + 'sps'
} else if (key === 'VOLT_EFINAL') {
showKey = 'E-Final'
showValue = (value / 5000) - 5 + 'V'
} else if (key === 'VOLT_VSCAN') {
showKey = 'VScan'
showValue = (value / 5000) - 5 + 'V'
} else {
continue
}
this.content += ' ' + showKey + ': ' + showValue + '<br/>'
}
}
},
},
}
</script>
@@ -0,0 +1,37 @@
<template>
<div>
<span> Resample: {{ currentScale }} to 1 </span>
</div>
</template>
<script>
import { mapFields } from 'vuex-map-fields'
export default {
name: 'show-resample-rate',
components: {
},
props: {
},
created () {
},
data () {
return {
}
},
computed: {
...mapFields('replay', [
'currentScale',
]),
},
watch: {
},
methods: {
},
mounted () {
},
destroyed () {
},
}
</script>
+103 -24
View File
@@ -12,7 +12,7 @@
<div v-if="controller.status === 'running'">
<div class="flex xs12 md12 xl12 sm12 mb-3" style="text-align: center;" >
<va-button color="primary" target="_blank" @click="scan(controller.id)" small :disabled="controller.isScan">
<va-button class="no-dark-style-va-button" color="primary" target="_blank" @click="scan(controller.id)" small :disabled="controller.isScan">
SCAN
</va-button>
<va-button color="dark" target="_blank" @click="restartCheck(controller.id, controller.mac)" small>
@@ -53,27 +53,28 @@
<va-badge v-if="device.status == 'scanned'" class="px-1 py-0" color="primary">scanned</va-badge>
<va-badge v-if="device.status == 'connected'" class="px-1 py-0" color="success">connected</va-badge>
</div> -->
<va-item-section avatar class="ml-1">
<va-avatar style="border-radius: 0;">
<img :src="device.pic" :alt="device.name">
</va-avatar>
</va-item-section>
<va-item-section class="ml-3">
<va-item-label>
{{ device.name }}
<va-badge v-if="device.status == 'scanned'" class="px-1 py-0 ml-2 mt-0" color="primary">scanned</va-badge>
<va-badge v-if="device.status == 'connected'" class="px-1 py-0 ml-2 mt-0" color="success">connected</va-badge>
</va-item-label>
<va-item-label caption>
{{ device.addr }}
</va-item-label>
</va-item-section>
<!--<div>
<va-icon name="fa fa-battery-1" style="font-size: 1.5rem;" color="primary"/>
</div>-->
</va-item>
<va-item-section side >
<va-item class="pa-0 ma-0 mt-2">
<va-item-section>
<div v-if="device.loading" class="mr-3">
<fulfilling-bouncing-circle-spinner
:animation-duration="3000"
@@ -82,11 +83,14 @@
>
</fulfilling-bouncing-circle-spinner>
</div>
<va-button @click.stop="connect(controller.id, device)" v-if="device.status == 'scanned' && !device.loading" class="pl-2 pr-2" color="success" small>CONNECT</va-button>
<va-button @click.stop="disconnectCheck(controller.id, device)" :disabled="controller.isScan" v-if="device.status == 'connected' && !device.loading" class="pl-2 pr-2" color="danger" small>DISCONNECT</va-button>
<div>
<va-button style="width: 100px;" @click.stop="connect(controller.id, device)" v-if="device.status == 'scanned' && !device.loading" class="pl-2 pr-2 mt-2" color="success" small>CONNECT</va-button>
<va-button style="width: 100px;" @click.stop="disconnectCheck(controller.id, device)" :disabled="controller.isScan" v-if="device.status == 'connected' && !device.loading" class="pl-2 pr-2 mt-2" color="danger" small>DISCONNECT</va-button>
<va-button id="detectButton" @click.stop="detect(controller.id, device)" :disabled="controller.isScan" v-if="device.status == 'connected' && !device.loading && device.library_name.indexOf('Elite') !== -1" class="pl-2 pr-2 mt-2" color="primary" small>DETECT</va-button>
</div>
</va-item-section>
</va-item>
</va-card>
</div>
</div>
@@ -133,7 +137,8 @@
</template>
<script>
import { projectInfo } from '../../data/project/ProjectInfo'
import api from '@/data/api/index'
import { taskInfo } from '../../data/task/TaskInfo'
import { FulfillingBouncingCircleSpinner } from 'epic-spinners'
export default {
@@ -185,7 +190,7 @@ export default {
library_name: device.library_name,
library_version: device.library_version,
status: device.status,
pic: projectInfo.getDevicePic(device.device_name),
pic: taskInfo.getDevicePic(device.device_name),
loading: false,
}
this.controllerList.forEach(controller => {
@@ -203,14 +208,27 @@ export default {
})
// console.log(this.controllerList)
},
'+/hardware_info/+' (data, topic) {
async '+/hardware_info/+' (data, topic) {
const topicSplit = topic.split('/')
const rawDevices = JSON.parse(String.fromCharCode.apply(null, data)).data
this.controllerList.forEach(controller => {
for (let i = 0; i < this.controllerList.length; i++) {
const controller = this.controllerList[i]
if (controller.id === topicSplit[0]) {
controller.mac = rawDevices.device_mac.toUpperCase()
if (rawDevices.device_mac !== null) {
controller.mac = rawDevices.device_mac.toUpperCase()
// const info = await api.controller.getByMac(controller.mac)
// if (info.data.length === 0) {
// const req = {
// mac_address: controller.mac,
// mqtt_id: controller.id,
// status: controller.status,
// }
// api.controller.create(req)
// }
// console.log(info)
}
}
})
}
// console.log(this.controllerList)
},
'+/hardware_device_connect/+' (data, topic) {
@@ -243,6 +261,10 @@ export default {
controller.status = 'running'
}
})
this.mqttPub(topicSplit[0] + '_user', JSON.stringify({
header: 'hardware_datetime/0',
content: String(Date.now()),
}))
this.mqttPub(topicSplit[0] + '_user', JSON.stringify({
header: 'hardware_device/0',
}))
@@ -262,17 +284,21 @@ export default {
header: 'hardware_device/0',
}))
this.mqttPub(topicSplit[0] + '_user', JSON.stringify({
header: 'device_parent/0',
header: 'device_update_calibration/0',
device: parseInt(mes[1]),
content: {
folder: [0, 1, 3],
},
}))
this.mqttPub(topicSplit[0] + '_user', JSON.stringify({
header: 'device_recording_file_name/0',
device: parseInt(mes[1]),
content: 'qwertyuio',
}))
// this.mqttPub(topicSplit[0] + '_user', JSON.stringify({
// header: 'device_parent/0',
// device: parseInt(mes[1]),
// content: {
// folder: [0, 1, 3],
// },
// }))
// this.mqttPub(topicSplit[0] + '_user', JSON.stringify({
// header: 'device_recording_file_name/0',
// device: parseInt(mes[1]),
// content: 'qwertyuio',
// }))
break
case 'shutdown':
this.controllerList.forEach(controller => {
@@ -342,6 +368,7 @@ export default {
},
pageMqttSub: function () {
this.controllerList.forEach(controller => {
this.mqttSub(controller.id + '/hardware_datetime/+')
this.mqttSub(controller.id + '/hardware_device/+')
this.mqttSub(controller.id + '/hardware_info/+')
this.mqttSub(controller.id + '/hardware_device_connect/+')
@@ -351,6 +378,7 @@ export default {
},
pageMqttUnSub: function () {
this.controllerList.forEach(controller => {
this.mqttUnSub(controller.id + '/hardware_datetime/+')
this.mqttUnSub(controller.id + '/hardware_device/+')
this.mqttUnSub(controller.id + '/hardware_info/+')
this.mqttUnSub(controller.id + '/hardware_device_connect/+')
@@ -360,12 +388,17 @@ export default {
},
pageInitPub: function () {
this.controllerList.forEach(controller => {
this.mqttPub(controller.id + '_user', JSON.stringify({
header: 'hardware_datetime/0',
content: String(Date.now()),
}))
this.mqttPub(controller.id + '_user', JSON.stringify({
header: 'hardware_device/0',
}))
this.mqttPub(controller.id + '_user', JSON.stringify({
header: 'hardware_info/0',
}))
this.createInitialCollection('admin')
})
},
pageToast: function (mes) {
@@ -425,6 +458,21 @@ export default {
device: this.selectDevice.id,
}))
},
detect (controllerID, device) {
this.mqttPub(controllerID + '_user', JSON.stringify({
header: 'device_instruction/0',
device: device.id,
instruction: 'VIS_DEVICE_DETECT',
}))
setTimeout(() => {
this.mqttPub(controllerID + '_user', JSON.stringify({
header: 'device_instruction/0',
device: device.id,
instruction: 'VIS_DEVICE_DONE',
}))
document.getElementById('detectButton').className += ' no-dark-style-va-button'
}, 5000)
},
sleep: function (milliseconds) {
var start = new Date().getTime()
while (1) {
@@ -433,6 +481,29 @@ export default {
}
}
},
createInitialCollection: async function (user) {
const root = await api.collection.getByParentName('folder', 0, 'root')
if (root.data.length === 0) {
await api.collection.create({
name: 'root',
type: 'folder',
parent: { folder: [0] },
size: 0,
})
}
// init check and create collection
const _root = await api.collection.getByName('root')
const USER = await api.collection.getByName(user)
if (USER.data.length === 0) {
api.collection.create({
name: user,
parent: { folder: [_root.data[0].id] },
type: 'folder',
size: 0,
})
}
},
},
watch: {
},
@@ -452,3 +523,11 @@ export default {
}
</script>
<style lang="scss">
.no-dark-style-va-button {
&:focus {
filter: brightness(100%);
}
}
</style>
+83 -84
View File
@@ -135,10 +135,9 @@
<script>
import { file } from '../../data/file/File'
import { downloadTaskManager } from '../../data/download/Download'
import { download } from '../../data/download/Download'
import { exportData } from '../../data/export/export'
import { FulfillingBouncingCircleSpinner } from 'epic-spinners'
import api from '../../data/api/index'
export default {
name: 'Download',
@@ -197,33 +196,33 @@ export default {
return this.loadingPercent + '%'
},
},
mqtt: {
async '+/file_segment/+' (data, topic) {
console.log('file_segment')
console.log(String.fromCharCode.apply(null, data))
// console.log(navigator.connection.downlink)
// console.log(this.fileNum)
// console.log(this.downloadOptionsList.length)
// console.log(JSON.parse(String.fromCharCode.apply(null, data)).data.file_size)
// mqtt: {
// async '+/file_segment/+' (data, topic) {
// console.log('file_segment')
// console.log(String.fromCharCode.apply(null, data))
// // console.log(navigator.connection.downlink)
// // console.log(this.fileNum)
// // console.log(this.downloadOptionsList.length)
// // console.log(JSON.parse(String.fromCharCode.apply(null, data)).data.file_size)
if (this.downloadOptionsList.length > 0) {
await downloadTaskManager.updateFileSegmentInfo(String.fromCharCode.apply(null, data))
this.fileSegmentMax = downloadTaskManager.getFileSegmentMaxIndex()
this.checkFileSegmentGetOrNot()
}
},
async '+/file_segment_get/+' (data, topic) {
console.log('file_segment_get')
console.log(JSON.parse(new TextDecoder('utf-8').decode(data)))
if (this.downloadOptionsList.length > 0) {
const segmentData = atob(JSON.parse(new TextDecoder('utf-8').decode(data)).data.segment)
this.data += segmentData
// if (this.downloadOptionsList.length > 0) {
// await download.updateFileSegmentInfo(String.fromCharCode.apply(null, data))
// this.fileSegmentMax = download.getFileSegmentMaxIndex()
// this.checkFileSegmentGetOrNot()
// }
// },
// async '+/file_segment_get/+' (data, topic) {
// console.log('file_segment_get')
// console.log(JSON.parse(new TextDecoder('utf-8').decode(data)))
// if (this.downloadOptionsList.length > 0) {
// const segmentData = atob(JSON.parse(new TextDecoder('utf-8').decode(data)).data.segment)
// this.data += segmentData
this.fileSegmentIndex += 1
this.checkFileSegmentGetOrNot()
}
},
},
// this.fileSegmentIndex += 1
// this.checkFileSegmentGetOrNot()
// }
// },
// },
methods: {
transTime (timeRange) {
return this.getTimeInFormat(timeRange[0]) + ' - ' + this.getTimeInFormat(timeRange[1])
@@ -237,11 +236,11 @@ export default {
this.showDownload = true
},
channelChecked: function (channelIndex, path) {
downloadTaskManager.getDownloadOptions(path).channel[channelIndex].checked = true
download.getDownloadOptions(path).channel[channelIndex].checked = true
this.refresh()
},
channelUnchecked: function (channelIndex, path) {
downloadTaskManager.getDownloadOptions(path).channel[channelIndex].checked = false
download.getDownloadOptions(path).channel[channelIndex].checked = false
this.refresh()
},
getTimeInFormat: function (time) {
@@ -263,27 +262,42 @@ export default {
getCurrentFullPathName: function () {
return this.currentlyDownloadInfo.previousPath + '/' + this.currentlyDownloadInfo.filenameWithType
},
downloading: async function (info) {
this.$emit('download')
},
addDownloadTask: async function (info) {
console.log(info)
const promises = JSON.parse(info.channels).map(async ch => {
const rawData = await api.getRawFilesByParent(ch, info.id)
return rawData
})
const rawData = await Promise.all(promises)
console.log(rawData)
exportData.exportCSVByAPI(info, rawData)
// if (Array.isArray(downloadPath)) {
// downloadPath.forEach(path => {
// // this.downloadList.push(path.path)
// downloadTaskManager.updateDownloadOptions(path.path)
// })
// } else {
// // this.downloadList.push(downloadPath)
// downloadTaskManager.updateDownloadOptions(downloadPath)
// }
// this.refresh()
// this.showDownloadModal()
// this.confirmDownload()
this.downloading()
/*
** download all
*/
if (parseInt(info.time_duration) < 18e8) {
const rawData = await download.getAllRawDatas(info)
exportData.exportCSV(info, rawData)
} else {
for (const channelID in info.raw_data) {
const rawDataIDList = info.raw_data[channelID]
while (rawDataIDList.length > 1000) {
const _list = rawDataIDList.splice(0, 1000)
const rawData = await download.getIndexRawDatas(info, channelID, _list)
exportData.exportCSV(info, rawData)
}
const rawData = await download.getIndexRawDatas(info, channelID, rawDataIDList)
exportData.exportCSV(info, rawData, channelID)
rawData[channelID].length = 0
// const rawData = await download.getAllRawDatas(info)
// console.timeEnd('download')
}
}
// console.time('download')
// const rawData = await download.getAllRawDatas(info)
// console.timeEnd('download')
// exportData.exportCSV(info, rawData)
/*
** download split
*/
this.downloading()
},
_addDownloadTask: function (downloadPath) {
if (Array.isArray(downloadPath)) {
@@ -298,23 +312,23 @@ export default {
this.confirmDownload()
},
refresh: function () {
this.downloadOptionsList = downloadTaskManager.getDownloadOptionsList()
this.downloadOptionsList = download.getDownloadOptionsList()
console.log(this.downloadOptionsList)
},
confirmDownload: function (path) {
console.log('confirmDownload')
console.log(downloadTaskManager.getDownloadOptionsList())
console.log(downloadTaskManager.isFileDownloading())
console.log(downloadTaskManager.downloadTaskRemain())
if (!downloadTaskManager.isFileDownloading() && downloadTaskManager.downloadTaskRemain()) {
const downloadOptionsIndex = downloadTaskManager.getDownloadOptionsList().findIndex(downloadInfo => downloadInfo.metaPath === path)
console.log(download.getDownloadOptionsList())
console.log(download.isFileDownloading())
console.log(download.downloadTaskRemain())
if (!download.isFileDownloading() && download.downloadTaskRemain()) {
const downloadOptionsIndex = download.getDownloadOptionsList().findIndex(downloadInfo => downloadInfo.metaPath === path)
// this.downloadBlockList[downloadInfoIndex].status = 'downloading'
this.currentlyDownloadInfo = downloadTaskManager.getDownloadOptionsList()[downloadOptionsIndex]
this.currentlyDownloadInfo = download.getDownloadOptionsList()[downloadOptionsIndex]
this.currentlyDownloadInfo.download.status = 'downloading'
console.log(this.currentlyDownloadInfo)
console.log(downloadTaskManager.getDownloadOptionsList())
console.log(download.getDownloadOptionsList())
downloadTaskManager.updateDownloadSubFileList(
download.updateDownloadSubFileList(
this.currentlyDownloadInfo.metaPath,
this.currentlyDownloadInfo.channel,
this.currentlyDownloadInfo.timeRange,
@@ -333,7 +347,7 @@ export default {
},
_confirmDownload: function () {
console.log('confirmDownload')
console.log(downloadTaskManager.getDownloadOptionsList())
console.log(download.getDownloadOptionsList())
// if (this.downloadList.length > 0 && this.currentlyDownloadInfo.status === 'idle') {
// this.showDownload()
// this.updateDownloadSubFileList(this.downloadList[0])
@@ -344,7 +358,7 @@ export default {
},
downloadAllSubFileList: async function (path) {
this.currentlyDownloadInfo = this.downloadInfo
downloadTaskManager.downloadAllSubFileList(path)
download.downloadAllSubFileList(path)
this.subfileListRemain()
},
// updateDownloadInfo: function (path) {
@@ -391,7 +405,7 @@ export default {
}
},
updateMetaDownloadInfo: function () {
downloadTaskManager.updateDownloadSubFileList(
download.updateDownloadSubFileList(
this.currentlyDownloadInfo.metaPath,
this.currentlyDownloadInfo.channel,
this.currentlyDownloadInfo.timeRange,
@@ -404,7 +418,7 @@ export default {
this.currentlyDownloadInfo = this.downloadBlockList[downloadOptionsIndex]
this.updatecurrentlyDownloadInfo()
downloadTaskManager.updateDownloadSubFileList(
download.updateDownloadSubFileList(
this.currentlyDownloadInfo.metaPath,
this.currentlyDownloadInfo.channel,
this.currentlyDownloadInfo.timeRange,
@@ -419,7 +433,7 @@ export default {
this.currentlyDownloadInfo = this.downloadBlockList[downloadOptionsIndex]
// this.updatecurrentlyDownloadInfo()
downloadTaskManager.updateDownloadSubFileList(
download.updateDownloadSubFileList(
this.currentlyDownloadInfo.metaPath,
this.currentlyDownloadInfo.channel,
this.currentlyDownloadInfo.timeRange,
@@ -428,13 +442,8 @@ export default {
},
subfileListRemain: function () {
console.log('subfileListRemain')
if (downloadTaskManager.checkDownloadSubFileList(this.currentlyDownloadInfo.metaPath)) {
this.currentlyDownloadInfo.filenameWithType = downloadTaskManager.getFirstSubfile(this.currentlyDownloadInfo.metaPath)
this.mqttPub('BPS_FF_user', JSON.stringify({
header: 'file_segment/0',
method: 'new',
path: this.getCurrentFullPathName(),
}))
if (download.checkDownloadSubFileList(this.currentlyDownloadInfo.metaPath)) {
this.currentlyDownloadInfo.filenameWithType = download.getFirstSubfile(this.currentlyDownloadInfo.metaPath)
} else {
this.loadingPercent = 100
console.log(this.currentlyDownloadInfo.filenameWithType + ' download complete')
@@ -456,11 +465,6 @@ export default {
this.fileSegmentIndex = 0
this.subfileListRemain()
} else {
this.mqttPub('BPS_FF_user', JSON.stringify({
header: 'file_segment_get/0',
segment: this.fileSegmentIndex,
path: this.getCurrentFullPathName(),
}))
}
},
exportCSV: function () {
@@ -469,12 +473,12 @@ export default {
exportTXT: function () {
},
timeRangeChange: function (timeRange, path) {
downloadTaskManager.getDownloadOptions(path).timeRange = timeRange
download.getDownloadOptions(path).timeRange = timeRange
this.refresh()
},
calculateFileSize: function () {
this.totoalFileSize = file.getFileSize(this.currentlyDownloadInfo.metaPath)
// const allSubfile = downloadTaskManager.getAllSubfile(this.currentlyDownloadInfo.metaPath)
// const allSubfile = download.getAllSubfile(this.currentlyDownloadInfo.metaPath)
// this.fileNum = allSubfile.length
const downlinkSpeed = this.getNetSpeed('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAOEAAADhCAMAAAAJbSJIAAABTVBMVEX////qQzU0qFNChfT7vAU/g/RZlPU5gPT7uQCxyPqXufn/vQDpNCLqQTMwp1D7uADpOCfqPS4fo0bpMiD8wADpLxwopUv0paD1q6b86ObpOiv4/Pn+9/b4xcH2ubX1r6rsXVIre/NwvoOf0qvO6NQzqUm/4cf5zMn739zrSz398O/sVEjvdWz2t7PvenP4ycb7wir96Lf+8tb8zFH93pj+9eH//PD92Yvw9v7+7cP80Xb95q6pxPnq9u1PsmigvvlunvaJyZiGrvjD1vvyl5HtamHoJgzwhH3zmpTtXlLvenHuYSzygCL2mxjsUzDwcSf0jx34phH8z2DxfVHX5P38x0KHvnDOtiGjsjJ0rkLhuRW4tCnS4PyMsDtZq0it2bhmmvbO5OE1noBft3U1pWA/jNc8lLk5nJNBieSSy58+j8t5wIo6mKY2o25FrmBHQXgmAAAIJUlEQVR4nO2b2V/bRhCAhbADxJLQYQvwgcE2PsAhEHK0SUxigoGkTdMj6ZXDTdw2JbT+/x9r+QDZllYra8da85vvKU/yfszszO5IEQQEQRAEQRAEQRAEQRAEQRAEQRAEQRAEQRAEQRDWpLfXSplbqysWq9n1Unk7HfaSmJFey6ycNipGwpDUAZKRSMxt7B6vl7fDXl5QyqvVHdVQk5o8N4osa0nJqDSOSzNrmc7sVlRVk8fl7J4dTbmRXQt7sf5JZ6onkkPknC3VxE52tiJZPtUMjcru0lI1dkthL5uaTMNI0kVvOJLGRnYmCmx2R/IXPpukVFnh3nG9IvkPn81R1bJhKxC5vWME8evHMRO2hitr1URQv65jospp81jRkgz8LJLaStgyDpSfqywC2ENWN7gL48rJpAXUGe3kVthKQ2w3DKZ+c9ZuPOWocZQqrHagHY4yNRuoBbqjaZyc444D90A35AQPmzFdlYD8uorht410Q4UTnJON0A3TOxA15pLE6nUXvOYRlI3wI9gAFZRCFxReQBaZufAjKBwDtgkeioyQZX4UtcFDIyz5PqrJsqYlk2oymdQ8hqhc7MHtih9Ba+4rVTaqp6fHZ2fHp7sNaxDuPk3lQVCo+iijmmQ0zjJr9ncx6e3Syq6WcBk6crAHhVXqTSirJ7sZ53l2unQsGQ6R5GAPCuUT2vCpz28RL7K3q+pIIDlo9B026EYWmlT1vuGVT1X707jYg8IKVauXjQbdDbZctd0wuYjgGtU7peTcOvUTM/KgcPFQZDqnNYo6Khu7fh6ZftENo8yHYCnhLajN+R3NZzsFh489KAg73jk6yZisXNE4EVz3boXG7iSjzrUKH4KC93EtcTzZkzmZAD9a/obsJ0tnYa8xEKm9SPxboqHEwZkrCPuLkUj8JSFRpdOwlxiQg0iH+PJ3boJqNewVBuTOYqSrGH/lLKjtcFIuJuZhz7Dj+L1jldHKYa8wIKnIJfEfHDJVoj+Kcsr+sk1xvG0kZ30T9uvMleNI25DV2fo2zYH7y5FhxZdDhgbfH/vQsL8YGVG0tw15J+z1BefHUcNIPPLqsvsbt8NeX2BSo35DbUPbCHt9wbkzFsJe2+iHkN/P0ai562gYiS9abUPeCHt5DDhwFOy3DZWT62sQ7u+5GVq3DY2bz3sm555zkvYUl38Ke3kM2F92N4wsPqJ8ytKNwLyGMnxAiGFk+T6t4WY0IJtLUIYPSYZ7tE9ZWpgPyMJNKMM3pCR9MD3D6FMgwftxUpLuT89wfh7KkMk2ZGG4CWR4j1RK49SPYWH4FYzh1yTDN1M1BGoXjwhZuvhwqobvYAxdzt09Q+pSysJw4VkIhnevvSHtmY2NIdChhnRom7Lh42tv+AQNJ4OjfRiG4XRraRiG0+2HQJWGnzMNVLcgnksPpmoI1PH5uVtAGXJ0PwQ6efNzx4e6PXEzpwG7AXMzawObYrCalwaftUWhDIkz72XqmffmAg0kwxtQhqT3FrH4z5RPeXeThiOC4cIRlCHh3VPsF0Wpsfyt14QgQh3aBPf3h7HYr6Jo5ln+FGm3QjV8wfXsHYv8Joqicsjyp46i7oZgzcLtPX7sd0W00IsMf4qwDcGG+oLLtxixt2IPpcXul95tuvuBvZixGP+eJhZ5Lw5gGMQj0jYEuv92GfsmKrb34VJQVNrMfmiBtA2Bzt1dRr9r6zQJ0YbeZPQ7pEoanYcrNMJIv+g2iSF0Rj2RVGZAt+Hwwa3XJIZQckx+hXh0Bd2GQ9V00CSGg8gkT28QduH8AtiXGD0ub1Cxtw6CIpOz2xPi7QPs2N2n3/RjsfcOft16mgr6E69JhRTwQ4wBB70M/eAs2DmeBu77xBwFT9JeSxxpEiNbsR7sB0jN3oKNBom98SYxohjokrFEOK/Ng1fSLo/GmwRDxWceEQS8V1whElI0aKI+I1aZTrsHu97bKepehqKem6yiegnCnkmvOPQMYqeiTtIXH296CEb/YO3iTME7iJ1M9n+V8qqinRDCzS+GyZkUivqFv0z9OO8pCDdGHKXmnaZWpio+wpi60D/d8FIEHEGNkqfIUyuMrQLd81J50RS3/vyLrDitXdiFotjQO9bybd16nmL+TVQEe+XkuCiqIHYdD5vk/Vi4UMzB32vrc9S9mi48nY5bH7o87TnquaKLZKpwruj2dNj67x/XMEancZyx0aKopzbJ1nmxVrN5pmq14nnL1EefoihfXBShPk9wpdam24qDlZu6Lh7mLur183r9Itc6FHXddLxDb/3rmKnA4xknaPr+WIDMHopC+PNsfXLqjNPOUYumf0U6ttrjbWNqp5kh6lCKytZo24B7ZUiG5vQ2GVuf5+2bcXrHtRFSfgqqT0V72wAecxMVD8EUTeXL5TwDfvpEUvTVM3wxaBvRKR64HRXBothpG91MhfvPeJSKcHuxd9sIW7CjmINqGt22Eb6gANgXLcWPYdt1aepA9UZRKK/Q4BREkM1otpl+hRSIWgsgUyedugKRZ52pSrD3HwDU2HZGU+RlC9rIk259/lDMOlcZOqCWY5Sq+iGHAexROGTgaJqsvssBoSgGdDTNcy4T1EYzQBwVU6nz0wPdKbbGpoR0fno7Pwt+FoW64jeQiuk+OeaSVDHnMhF10Zud8F3RkRSt2aiHXMdObDVnT69PoZlrm7qzpzUg1s12Ll+YpeR0IFUr5i9abd2iP/M2u/9ut+r5Ym3G7a5IpWqFYrOZt2g2i4VCLXVt3BAEQRAEQRAEQRAEQRAEQRAEQRAEQRAEQRAE4Yf/AZmODCZml4YgAAAAAElFTkSuQmCC', 3)
// this.totoalFileSize = (allSubfile.length) * 1000000
@@ -492,11 +496,6 @@ export default {
// allSubfile.forEach(subfile => {
// console.log(subfile)
// this.currentlyDownloadInfo.filenameWithType = subfile
// this.mqttPub('BPS_FF_user', JSON.stringify({
// header: 'file_segment/0',
// method: 'new',
// path: this.getCurrentFullPathName(),
// }))
// })
},
doProgress () {
@@ -523,7 +522,7 @@ export default {
}, 1000)
},
downloadDone: function () {
downloadTaskManager.getDownloadOptionsList().shift()
download.getDownloadOptionsList().shift()
this.loadingPercent = 0
this.refresh()
this.confirmDownload()
@@ -531,7 +530,7 @@ export default {
getControllerList: async function () {
const update = async () => {
this.controllerList.push({
id: 'BPS_FF',
id: 'tommy_test',
mac: '',
status: 'loading',
isScan: true,
@@ -0,0 +1,159 @@
<template>
<div>
</div>
</template>
<script>
import api from '@/data/api/index'
import types from '@/store/modules/file/elite/csv/types'
import { mapActions, mapGetters, mapMutations } from 'vuex'
// import { FulfillingBouncingCircleSpinner } from 'epic-spinners'
export default {
name: 'Download',
components: {
// FulfillingBouncingCircleSpinner,
},
data: () => {
return {
controllerList: [],
spliceDataNumsLimit: 20,
}
},
computed: {
getByIndex (index) {
return this.getByIndexDownload(index)
},
getDownloading () {
return this.getDownloadingDownload()
},
getRemainIDLength (index) {
return this.getRemainIDLengthDownload(index)
},
},
methods: {
getControllerList: async function () {
const update = async () => {
this.controllerList.push({
id: 'tommy_test',
mac: '',
status: 'loading',
isScan: true,
files: [],
})
}
await update()
},
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 () {
this.controllerList.forEach(controller => {
// this.mqttSub(controller.id + '/broadcast')
this.mqttSub(controller.id + '/file_meta_info/+')
this.mqttSub(controller.id + '/file_segment/+')
this.mqttSub(controller.id + '/file_segment_get/+')
})
},
pageMqttUnSub: function () {
this.controllerList.forEach(controller => {
// this.mqttUnSub(controller.id + '/broadcast')
this.mqttUnSub(controller.id + '/file_meta_info/+')
this.mqttUnSub(controller.id + '/file_segment/+')
this.mqttUnSub(controller.id + '/file_segment_get/+')
})
},
notify (name) {
this.showToast(`done ${name}`, {
position: 'bottom-right',
})
},
...mapActions('eliteCsv',
[
types.download.init,
types.download.rawDataByIDs,
types.export.createHeadersString,
types.export.createTitlesString,
types.export.createDataString,
types.export.closeFileStream,
],
),
...mapMutations('eliteCsv',
[
types.download.setDownloading,
types.download.removeDownloadBuffer,
],
),
...mapGetters('eliteCsv',
[
types.download.getByIndex,
types.download.getDownloading,
types.download.getAll,
types.download.getRemainIDLength,
],
),
},
watch: {
},
async mounted () {
await this.getControllerList()
// TODO authorization
this.pageMqttSub()
const metaIDList = this.$route.params.metaList.split('-')
const recoverData = this.$route.params.recover
await this.initDownload({ metaIDList: metaIDList, api: api })
// let first file download in download List
this.setDownloadingDownload()
const downloadingFile = this.getDownloading
downloadingFile.recoverData = recoverData
let spliceDataNums = 0
// console.log('downloadingFile', downloadingFile)
// console.log(this.getRemainIDLength(0))
// create headers and title
this.createHeadersStringExport()
this.createTitlesStringExport()
// loop until each channel's rawID List empty
while (this.getRemainIDLength(0)) {
// forEach channel in raw_data
for (const channel in downloadingFile.raw_data) {
// get spliceDataNumsLimit numbers of ID to download once time
if (downloadingFile.raw_data[channel].length >= this.spliceDataNumsLimit) {
spliceDataNums = this.spliceDataNumsLimit
} else {
spliceDataNums = downloadingFile.raw_data[channel].length
}
const rawID = downloadingFile.raw_data[channel].splice(0, spliceDataNums)
// console.log('rawID', channel, rawID)
// download data and save into dataBuffer by rawDataIDList
await this.rawDataByIDsDownload({
channel: channel,
rawDataIDList: rawID,
api: api,
})
}
// export data
this.createDataStringExport()
// this.removeDownloadBufferDownload()
}
this.closeFileStreamExport()
},
destroyed () {
this.pageMqttUnSub()
},
}
</script>
<style>
.filter-button {
text-align: center;
}
</style>
@@ -0,0 +1,207 @@
<template>
<div>
</div>
</template>
<script>
import api from '@/data/api/index'
import types from '@/store/modules/file/elite/excel/types'
import { mapActions, mapGetters, mapMutations } from 'vuex'
// import { file } from '../../data/file/File'
// import { download } from '../../data/download/Download'
// import { exportData } from '../../data/export/export'
// import { FulfillingBouncingCircleSpinner } from 'epic-spinners'
export default {
name: 'Download',
components: {
// FulfillingBouncingCircleSpinner,
},
data: () => {
return {
controllerList: [],
}
},
computed: {
getByIndex (index) {
return this.getByIndexDownload(index)
},
getDownloading () {
return this.getDownloadingDownload()
},
getRemainIDLength (index) {
return this.getRemainIDLengthDownload(index)
},
// transTime (min,max) {
// return this.getTimeInFormat(min) + ' - ' + this.getTimeInFormat(max)
// },
loaded () {
return this.loadingPercent + '%'
},
},
methods: {
transTime (timeRange) {
return this.getTimeInFormat(timeRange[0]) + ' - ' + this.getTimeInFormat(timeRange[1])
},
notify (name) {
this.showToast(`done ${name}`, {
position: 'bottom-right',
})
},
getControllerList: async function () {
const update = async () => {
this.controllerList.push({
id: 'tommy_test',
mac: '',
status: 'loading',
isScan: true,
files: [],
})
}
await update()
},
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 () {
this.controllerList.forEach(controller => {
// this.mqttSub(controller.id + '/broadcast')
this.mqttSub(controller.id + '/file_meta_info/+')
this.mqttSub(controller.id + '/file_segment/+')
this.mqttSub(controller.id + '/file_segment_get/+')
})
},
pageMqttUnSub: function () {
this.controllerList.forEach(controller => {
// this.mqttUnSub(controller.id + '/broadcast')
this.mqttUnSub(controller.id + '/file_meta_info/+')
this.mqttUnSub(controller.id + '/file_segment/+')
this.mqttUnSub(controller.id + '/file_segment_get/+')
})
},
...mapActions('eliteExcel',
[
types.download.init,
types.download.rawDataByIDs,
types.export.createHeadersString,
types.export.createTitlesString,
types.export.createDataString,
types.export.closeFileStream,
],
),
...mapMutations('eliteExcel',
[
types.download.setDownloading,
types.download.removeDownloadBuffer,
],
),
...mapGetters('eliteExcel',
[
types.download.getByIndex,
types.download.getDownloading,
types.download.getAll,
types.download.getRemainIDLength,
],
),
},
openPortal () {
this.windowRef = window.open('', '', 'width=600,height=400,left=200,top=200')
this.windowRef.document.body.appendChild(this.$el)
// copyStyles(window.document, this.windowRef.document)
this.windowRef.addEventListener('beforeunload', this.closePortal)
},
closePortal () {
if (this.windowRef) {
this.windowRef.close()
this.windowRef = null
this.$emit('close')
}
},
// watch: {
// loadingPercent(val) {
// if (val >= 100) {
// console.log('complete');
// clearInterval(this.interval)
// }
// }
// },
async mounted () {
await this.getControllerList()
// TODO authorization
this.pageMqttSub()
const metaIDList = this.$route.params.metaList.split('-')
await this.initDownload({ metaIDList: metaIDList, api: api })
this.setDownloadingDownload()
const downloadingFile = this.getDownloading
console.log('downloadingFile', downloadingFile)
console.log(this.getRemainIDLength(0))
// create headers and title
this.createHeadersStringExport()
this.createTitlesStringExport()
// let spliceDataNums = 0
let rowIndex = 0
// let columnIndex = 0
// // while (this.getRemainIDLength(0)) {
while (rowIndex < downloadingFile.needRows) {
for (const channel in downloadingFile.downloadIDList) {
const rawID = downloadingFile.downloadIDList[channel][rowIndex]
// console.log('rawID', channel, rawID)
if (rawID !== undefined) {
await this.rawDataByIDsDownload({
channel: channel,
rawDataIDList: rawID,
api: api,
})
}
}
this.createDataStringExport()
this.removeDownloadBufferDownload()
// console.log('end', downloadingFile)
rowIndex += 1
}
this.closeFileStreamExport()
// }
// if (downloadingFile.raw_data[channel].length >= 10) {
// spliceDataNums = 10
// } else {
// spliceDataNums = downloadingFile.raw_data[channel].length
// }
// const rawID = downloadingFile.raw_data[channel].splice(0, spliceDataNums)
// console.log('rawID', channel, rawID)
// await this.rawDataByIDsDownload({
// channel: channel,
// rawDataIDList: rawID,
// api: api,
// })
// }
// // console.log('end', downloadingFile)
// // export data
// this.createDataStringExport({})
// this.removeDownloadBufferDownload()
// }
// const rawData = await download.getAllRawDatas(meta.data[0])
// exportData.exportCSV(meta.data[0], rawData)
// await this.initMeta({ metaIDList: metaIDList, api: api })
},
destroyed () {
this.pageMqttUnSub()
},
}
</script>
<style>
.filter-button {
text-align: center;
}
</style>
@@ -0,0 +1,159 @@
<template>
<div>
</div>
</template>
<script>
import api from '@/data/api/index'
import types from '@/store/modules/file/neulive/csv/types'
import { mapActions, mapGetters, mapMutations } from 'vuex'
// import { FulfillingBouncingCircleSpinner } from 'epic-spinners'
export default {
name: 'Download',
components: {
// FulfillingBouncingCircleSpinner,
},
data: () => {
return {
controllerList: [],
spliceDataNumsLimit: 20,
}
},
computed: {
getByIndex (index) {
return this.getByIndexDownload(index)
},
getDownloading () {
return this.getDownloadingDownload()
},
getRemainIDLength (index) {
return this.getRemainIDLengthDownload(index)
},
},
methods: {
getControllerList: async function () {
const update = async () => {
this.controllerList.push({
id: 'tommy_test',
mac: '',
status: 'loading',
isScan: true,
files: [],
})
}
await update()
},
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 () {
this.controllerList.forEach(controller => {
// this.mqttSub(controller.id + '/broadcast')
this.mqttSub(controller.id + '/file_meta_info/+')
this.mqttSub(controller.id + '/file_segment/+')
this.mqttSub(controller.id + '/file_segment_get/+')
})
},
pageMqttUnSub: function () {
this.controllerList.forEach(controller => {
// this.mqttUnSub(controller.id + '/broadcast')
this.mqttUnSub(controller.id + '/file_meta_info/+')
this.mqttUnSub(controller.id + '/file_segment/+')
this.mqttUnSub(controller.id + '/file_segment_get/+')
})
},
notify (name) {
this.showToast(`done ${name}`, {
position: 'bottom-right',
})
},
...mapActions('neuliveCsv',
[
types.download.init,
types.download.rawDataByIDs,
types.export.createHeadersString,
types.export.createTitlesString,
types.export.createDataString,
types.export.closeFileStream,
],
),
...mapMutations('neuliveCsv',
[
types.download.setDownloading,
types.download.removeDownloadBuffer,
],
),
...mapGetters('neuliveCsv',
[
types.download.getByIndex,
types.download.getDownloading,
types.download.getAll,
types.download.getRemainIDLength,
],
),
},
watch: {
},
async mounted () {
await this.getControllerList()
// TODO authorization
this.pageMqttSub()
const metaIDList = this.$route.params.metaList.split('-')
const recoverData = this.$route.params.recover
await this.initDownload({ metaIDList: metaIDList, api: api })
// let first file download in download List
this.setDownloadingDownload()
const downloadingFile = this.getDownloading
downloadingFile.recoverData = recoverData
let spliceDataNums = 0
// console.log('downloadingFile', downloadingFile)
// console.log(this.getRemainIDLength(0))
// create headers and title
this.createHeadersStringExport()
this.createTitlesStringExport()
// loop until each channel's rawID List empty
while (this.getRemainIDLength(0)) {
// forEach channel in raw_data
for (const channel in downloadingFile.raw_data) {
// get spliceDataNumsLimit numbers of ID to download once time
if (downloadingFile.raw_data[channel].length >= this.spliceDataNumsLimit) {
spliceDataNums = this.spliceDataNumsLimit
} else {
spliceDataNums = downloadingFile.raw_data[channel].length
}
const rawID = downloadingFile.raw_data[channel].splice(0, spliceDataNums)
// console.log('rawID', channel, rawID)
// download data and save into dataBuffer by rawDataIDList
await this.rawDataByIDsDownload({
channel: channel,
rawDataIDList: rawID,
api: api,
})
}
// export data
this.createDataStringExport()
// this.removeDownloadBufferDownload()
}
this.closeFileStreamExport()
},
destroyed () {
this.pageMqttUnSub()
},
}
</script>
<style>
.filter-button {
text-align: center;
}
</style>
@@ -0,0 +1,207 @@
<template>
<div>
</div>
</template>
<script>
import api from '@/data/api/index'
import types from '@/store/modules/file/neulive/excel/types'
import { mapActions, mapGetters, mapMutations } from 'vuex'
// import { file } from '../../data/file/File'
// import { download } from '../../data/download/Download'
// import { exportData } from '../../data/export/export'
// import { FulfillingBouncingCircleSpinner } from 'epic-spinners'
export default {
name: 'Download',
components: {
// FulfillingBouncingCircleSpinner,
},
data: () => {
return {
controllerList: [],
}
},
computed: {
getByIndex (index) {
return this.getByIndexDownload(index)
},
getDownloading () {
return this.getDownloadingDownload()
},
getRemainIDLength (index) {
return this.getRemainIDLengthDownload(index)
},
// transTime (min,max) {
// return this.getTimeInFormat(min) + ' - ' + this.getTimeInFormat(max)
// },
loaded () {
return this.loadingPercent + '%'
},
},
methods: {
transTime (timeRange) {
return this.getTimeInFormat(timeRange[0]) + ' - ' + this.getTimeInFormat(timeRange[1])
},
notify (name) {
this.showToast(`done ${name}`, {
position: 'bottom-right',
})
},
getControllerList: async function () {
const update = async () => {
this.controllerList.push({
id: 'tommy_test',
mac: '',
status: 'loading',
isScan: true,
files: [],
})
}
await update()
},
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 () {
this.controllerList.forEach(controller => {
// this.mqttSub(controller.id + '/broadcast')
this.mqttSub(controller.id + '/file_meta_info/+')
this.mqttSub(controller.id + '/file_segment/+')
this.mqttSub(controller.id + '/file_segment_get/+')
})
},
pageMqttUnSub: function () {
this.controllerList.forEach(controller => {
// this.mqttUnSub(controller.id + '/broadcast')
this.mqttUnSub(controller.id + '/file_meta_info/+')
this.mqttUnSub(controller.id + '/file_segment/+')
this.mqttUnSub(controller.id + '/file_segment_get/+')
})
},
...mapActions('neuliveExcel',
[
types.download.init,
types.download.rawDataByIDs,
types.export.createHeadersString,
types.export.createTitlesString,
types.export.createDataString,
types.export.closeFileStream,
],
),
...mapMutations('neuliveExcel',
[
types.download.setDownloading,
types.download.removeDownloadBuffer,
],
),
...mapGetters('neuliveExcel',
[
types.download.getByIndex,
types.download.getDownloading,
types.download.getAll,
types.download.getRemainIDLength,
],
),
},
openPortal () {
this.windowRef = window.open('', '', 'width=600,height=400,left=200,top=200')
this.windowRef.document.body.appendChild(this.$el)
// copyStyles(window.document, this.windowRef.document)
this.windowRef.addEventListener('beforeunload', this.closePortal)
},
closePortal () {
if (this.windowRef) {
this.windowRef.close()
this.windowRef = null
this.$emit('close')
}
},
// watch: {
// loadingPercent(val) {
// if (val >= 100) {
// console.log('complete');
// clearInterval(this.interval)
// }
// }
// },
async mounted () {
await this.getControllerList()
// TODO authorization
this.pageMqttSub()
const metaIDList = this.$route.params.metaList.split('-')
await this.initDownload({ metaIDList: metaIDList, api: api })
this.setDownloadingDownload()
const downloadingFile = this.getDownloading
console.log('downloadingFile', downloadingFile)
console.log(this.getRemainIDLength(0))
// create headers and title
this.createHeadersStringExport()
this.createTitlesStringExport()
// let spliceDataNums = 0
let rowIndex = 0
// let columnIndex = 0
// // while (this.getRemainIDLength(0)) {
while (rowIndex < downloadingFile.needRows) {
for (const channel in downloadingFile.downloadIDList) {
const rawID = downloadingFile.downloadIDList[channel][rowIndex]
// console.log('rawID', channel, rawID)
if (rawID !== undefined) {
await this.rawDataByIDsDownload({
channel: channel,
rawDataIDList: rawID,
api: api,
})
}
}
this.createDataStringExport()
this.removeDownloadBufferDownload()
// console.log('end', downloadingFile)
rowIndex += 1
}
this.closeFileStreamExport()
// }
// if (downloadingFile.raw_data[channel].length >= 10) {
// spliceDataNums = 10
// } else {
// spliceDataNums = downloadingFile.raw_data[channel].length
// }
// const rawID = downloadingFile.raw_data[channel].splice(0, spliceDataNums)
// console.log('rawID', channel, rawID)
// await this.rawDataByIDsDownload({
// channel: channel,
// rawDataIDList: rawID,
// api: api,
// })
// }
// // console.log('end', downloadingFile)
// // export data
// this.createDataStringExport({})
// this.removeDownloadBufferDownload()
// }
// const rawData = await download.getAllRawDatas(meta.data[0])
// exportData.exportCSV(meta.data[0], rawData)
// await this.initMeta({ metaIDList: metaIDList, api: api })
},
destroyed () {
this.pageMqttUnSub()
},
}
</script>
<style>
.filter-button {
text-align: center;
}
</style>
+25 -13
View File
@@ -5,7 +5,7 @@
<file-table :ref="'file_ref'" @download="addDownloadTask"/>
</div>
<div class="flex md12 xl12 xs12 sm12" :style="AreaStyle">
<download :ref="'download_ref'"></download>
<!-- <download :ref="'download_ref'" @download="downloadingFile"></download> -->
</div>
</div>
</div>
@@ -13,14 +13,13 @@
<script>
import FileTable from './file-table/FileTable.vue'
import Download from '../download/Download.vue'
// import Download from '../download/Download.vue'
import { file } from '../../data/file/File'
import api from '../../data/api/index'
export default {
components: {
FileTable,
Download,
},
data () {
return {
@@ -36,7 +35,7 @@ export default {
getControllerList: async function () {
const update = async () => {
this.controllerList.push({
id: 'BPS_FF',
id: 'tommy_test',
mac: '',
status: 'loading',
isScan: true,
@@ -63,30 +62,43 @@ export default {
addDownloadTask: function (info) {
this.$refs.download_ref.addDownloadTask(info)
},
pageInitPub: function () {
downloadingFile: function () {
this.$refs.file_ref.loadingFiles = !this.$refs.file_ref.loadingFiles
},
pageInitPub: async function () {
this.controllerList.forEach(async (controller) => {
this.$refs.file_ref.currentPathIndex = file.getPathMaxIndex()
file.clearFileList()
const folders = await api.getCollectionsFoldersByParent(0)
const files = await api.getFolderMetaFileByParent(0)
file.updateFileList(folders)
file.updateFileList(files)
const initCollection = await api.collection.getByName('admin')
this.$refs.file_ref.fileLists = file.getFileList()
this.$refs.file_ref.pathLists = file.getPathList()
this.$refs.file_ref.loadingFiles = false
if (initCollection.data !== 0) {
file.addPath(initCollection.data[0])
this.$refs.file_ref.currentPathIndex = file.getPathMaxIndex()
this.$refs.file_ref.currentInfo = initCollection.data[0]
const folders = await api.collection.getByParent('folder', initCollection.data[0].id)
const files = await api.meta.getCollectionByParent('folder', initCollection.data[0].id)
file.updateFileList(folders)
file.updateFileList(files)
this.$refs.file_ref.fileLists = file.getFileList()
this.$refs.file_ref.pathLists = file.getPathList()
this.$refs.file_ref.loadingFiles = false
}
})
},
},
async mounted () {
await this.getControllerList()
await api.getJwtData()
await api.auth.getJwtData()
this.pageMqttSub()
this.pageInitPub()
},
destroyed () {
this.pageMqttUnSub()
file.clearFileList()
file.clearPathList()
},
}
</script>
+203 -86
View File
@@ -52,16 +52,16 @@
</va-modal>
<va-card class="flex sm12 xl12 md12 xs12">
<!-- <template slot="header">
<template slot="header">
<div class="flex sm12 xl12 md12 xs12" style="text-align: end;">
<va-button class="" color="success" v-if="selected.length" @click="showrefs" target="_blank" small>
<!-- <va-button class="" color="success" v-if="selected.length" @click="downloadSelected" target="_blank" small>
DOWNLOAD
</va-button>
<va-button class="" color="danger" v-if="selected.length" target="_blank" small>
</va-button> -->
<va-button class="" color="danger" v-if="selected.length" @click="deleteSelected" target="_blank" small>
DELETE
</va-button>
</div>
</template> -->
</template>
<!-- SearchField & perPageSelect-->
<div class="row align--center">
@@ -89,7 +89,7 @@
<!-- CreateFolder & FilePath -->
<div class="flex mb-4">
<va-icon
name="fa fa-plus-circle"
name="fa fa-plus"
size="1rem"
class="mr-2"
style="cursor: pointer;"
@@ -137,9 +137,9 @@
v-else
:ref="'datatable_ref'"
>
<!-- <template slot="select" slot-scope="props">
<template slot="select" slot-scope="props">
<va-checkbox :value="props.rowData.checked" @input="select(props.rowData)"/>
</template> -->
</template>
<template slot="name" slot-scope="props">
<va-icon
:name="(props.rowData.type==='folder')?'fa fa-folder':'fa fa-file'"
@@ -163,14 +163,20 @@
{{transDeviceInfo(props.rowData.configuration)}}
</template>
<template slot="actions" slot-scope="props" >
<va-popover :message="`download ${props.rowData.name}`" placement="top">
<va-button flat small color="gray" icon="fa fa-download" v-if="props.rowData.type !== 'folder'" @click.stop="download(props.rowData)"/>
<va-popover :message="`download ${props.rowData.name} in csv format`" placement="top">
<va-button flat small color="gray" icon="fa fa-download" v-if="props.rowData.type !== 'folder'" @click.stop="downloadCsv(props.rowData)"/>
</va-popover>
<va-popover :message="`download ${props.rowData.name} in excel format`" placement="top">
<va-button flat small color="gray" icon="fa fa-download" v-if="props.rowData.type !== 'folder'" @click.stop="downloadExcel(props.rowData)"/>
</va-popover>
<va-popover :message="`replay ${props.rowData.name}`" placement="top">
<va-button flat small color="gray" icon="fa fa-eye" v-if="props.rowData.type !== 'folder'" @click.stop="replay(props.rowData)"/>
</va-popover>
<va-popover :message="`edit ${props.rowData.name}`" placement="top">
<va-button flat small color="gray" icon="fa fa-pencil" @click.stop="editFileConfirm(props.rowData.path, props.rowData.name, props.rowData.type)"/>
<va-button flat small color="gray" icon="fa fa-pencil" @click.stop="editFileConfirm(props.rowData)"/>
</va-popover>
<va-popover :message="`delete ${props.rowData.name}`" placement="top">
<va-button flat small color="gray" icon="fa fa-trash" @click.stop="deleteFileConfirm(props.rowData.path, props.rowData.name)"/>
<va-button flat small color="gray" icon="fa fa-trash" @click.stop="deleteFileConfirm(props.rowData)"/>
</va-popover>
</template>
</va-data-table>
@@ -192,13 +198,14 @@ export default {
data () {
return {
term: null,
perPage: '6',
perPageOptions: ['4', '6', '10', '20'],
perPage: '160',
perPageOptions: ['20', '40', '80', '160'],
fileLists: [],
pathLists: [],
currentPathIndex: -1,
currentPage: 0,
currentInfo: {},
loadingFiles: true,
showModal: {
@@ -216,9 +223,7 @@ export default {
errorMessages: [],
},
editInfo: {
path: '',
name: '',
type: '',
info: {},
changedName: '',
success: false,
error: false,
@@ -228,6 +233,9 @@ export default {
deleteInfo: {
path: '',
name: '',
metaID: '',
rawChannelAndIDArrays: [], // list of lists
miniChannelAndIDArrays: [], // list of lists
},
styleList: {
@@ -241,14 +249,15 @@ export default {
computed: {
fields () {
return [
// {
// name: '__slot:select',
// },
{
name: '__slot:select',
width: '5%',
},
{
name: '__slot:name',
title: 'name',
sortField: 'name',
width: '20%',
width: '15%',
titleClass: 'text-center',
},
// {
@@ -290,7 +299,7 @@ export default {
{
name: '__slot:actions',
dataClass: 'text-right',
width: '15%',
width: '20%',
},
]
},
@@ -299,7 +308,9 @@ export default {
return this.fileLists
}
return this.fileLists.filter(item => {
return item.name.toLowerCase().includes(this.term.toLowerCase())
if (item.name !== null) {
return item.name.toLowerCase().includes(this.term.toLowerCase())
}
})
},
selected () {
@@ -348,9 +359,8 @@ export default {
},
openFile: async function (info) {
console.log('openfile', info)
console.log(this.pathLists)
if (info.type === 'folder') {
this.currentInfo = info
this.loadingFiles = true
// clear file and add path
file.clearFileList()
@@ -358,16 +368,15 @@ export default {
this.currentPathIndex = file.getPathMaxIndex()
// call getfolder api and update
const folders = await api.getCollectionsFoldersByParent(info.id)
const files = await api.getFolderMetaFileByParent(info.id)
const folders = await api.collection.getByParent('folder', info.id)
const files = await api.meta.getCollectionByParent('folder', info.id)
file.updateFileList(folders)
file.updateFileList(files)
this.fileLists = file.getFileList()
this.loadingFiles = false
} else {
// this.fileInfoName = info.name
// this.$emit('showFileInfoTable', info.path)
// TODO file info
}
},
openPath: async function (item, index) {
@@ -377,9 +386,10 @@ export default {
file.clearFileList()
file.slicePathList(index)
this.currentPathIndex = file.getPathMaxIndex()
this.currentInfo = item
// call getfolder api and update
const folders = await api.getCollectionsFoldersByParent(item.id)
const files = await api.getFolderMetaFileByParent(item.id)
const folders = await api.collection.getByParent('folder', item.id)
const files = await api.meta.getCollectionByParent('folder', item.id)
file.updateFileList(folders)
file.updateFileList(files)
@@ -395,43 +405,55 @@ export default {
this.currentPathIndex = -1
// call getfolder api and update
const folders = await api.getCollectionsFoldersByParent(0)
const files = await api.getFolderMetaFileByParent(0)
file.updateFileList(folders)
file.updateFileList(files)
this.fileLists = file.getFileList()
this.loadingFiles = false
const initCollection = await api.collection.getByParentName('folder', 0, 'root')
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.getCollectionByParent('folder', initCollection.data[0].id)
file.updateFileList(folders)
file.updateFileList(files)
this.fileLists = file.getFileList()
this.loadingFiles = false
}
},
createFolderConfirm: function () {
this.inputFieldReset(this.createInfo)
this.createFolder = true
this.showModal.createFolder = true
},
checkFolderNameValidate: debounce(async function (term) {
if (term.length === 0) {
// folder name empty
this.setInputFieldError(this.createInfo.errorMessagesAll[1], this.createInfo)
return false
}
const illegalChar = term.match(/[^(\w\-)]+/gm)
if (illegalChar !== null) {
// folder name contains illegal characters
this.setInputFieldError(this.createInfo.errorMessagesAll[0] + ' ' + illegalChar[0], this.createInfo)
} else {
// folder name existed
const existedFolder = await api.getCollectionsByName(term)
const existedFolder = await api.collection.getByParentName(this.currentInfo.type, this.currentInfo.id, term)
if (existedFolder.data.length === 0) {
this.setInputFieldSuccess(this.createInfo)
} else {
this.setInputFieldError(this.createInfo.errorMessagesAll[2], this.createInfo)
}
}
if (term.length === 0) {
// folder name empty
this.setInputFieldError(this.createInfo.errorMessagesAll[1], this.createInfo)
}
this.createInfo.changedName = term
}, 200),
}, 250),
createFolder: async function () {
const parent = [].concat((this.pathLists.length === 0) ? 0 : this.pathLists[this.pathLists.length - 1].id)
const parent = [].concat((this.pathLists.length === 0) ? this.currentInfo.id : this.pathLists[this.pathLists.length - 1].id)
const type = 'folder'
await api.createCollection(this.createInfo.changedName, parent, type)
this.refreshCurrentPage()
await api.collection.create({
name: this.createInfo.changedName,
parent: { [type]: parent },
type: type,
size: 0,
})
await this.refreshPage()
this.showToast(`Folder ${this.createInfo.changedName} create.`, {
position: 'bottom-right',
})
},
undoCreate: function () {
this.createInfo.success = false
@@ -439,21 +461,22 @@ export default {
this.createInfo.changedName = ''
this.createInfo.name = ''
},
editFileConfirm: function (path, name, type) {
this.editInfo.path = path
this.editInfo.name = name
this.editInfo.type = type
this.editFile = true
editFileConfirm: function (info) {
this.editInfo.info = info
this.editInfo.changedName = info.name
this.showModal.editFile = true
},
editFile: function () {
// this.mqttPub('BPS_FF_user', JSON.stringify({
// header: 'file_rename/0',
// path: this.editInfo.path,
// content: this.editInfo.changedName,
// }))
editFile: async function () {
// TODO editFile
if (this.editInfo.type !== 'folder') {
await api.meta.update(this.editInfo.info.id, { name: this.editInfo.changedName })
} else {
}
await this.editFileDone()
},
checkFileNameValidate: debounce(function (term) {
const illegalChar = term.match(/[^(\w\-)]+/gm)
this.editInfo.changedName = term
if (term.length === 0) {
// input text empty
this.editInfo.error = true
@@ -467,7 +490,13 @@ export default {
this.editInfo.errorMessages.pop()
this.editInfo.errorMessages.push(this.editInfo.errorMessagesAll[0] + ' ' + illegalChar[0])
} else {
const existedFile = this.fileLists.filter(file => file.name.replace('/', '') === term)
const existedFile = this.fileLists.filter((file) => {
if (file.name != null) {
return file.name.replace('/', '') === term
} else {
return false
}
})
if (existedFile.length === 0) {
this.editInfo.error = false
this.editInfo.success = true
@@ -479,14 +508,13 @@ export default {
this.editInfo.errorMessages.push(this.editInfo.errorMessagesAll[2])
}
}
this.editInfo.changedName = term
}, 200),
editFileDone: function () {
this.mqttPub('BPS_FF_user', JSON.stringify({
header: 'file_list/0',
path: file.getPath(),
}))
this.showToast(`file rename ${this.editInfo.name}`, {
editFileDone: async function () {
const tmpCurrentPage = this.$refs.datatable_ref.currentPage
await this.refreshPage()
this.$refs.datatable_ref.currentPage = tmpCurrentPage
this.$refs.datatable_ref.inputPage(tmpCurrentPage)
this.showToast(`${this.editInfo.info.name} -> ${this.editInfo.changedName}`, {
position: 'bottom-right',
})
},
@@ -499,22 +527,52 @@ export default {
},
removeFileFromList: function () {
},
deleteFileConfirm: function (path, name) {
this.deleteInfo.path = path
this.deleteInfo.name = name
this.deleteFile = true
fillDeleteInfo (info) {
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]])
}
}
},
deleteFile: function () {
// this.loadingFiles = true
// this.mqttPub('BPS_FF_user', JSON.stringify({
// header: 'file_delete/0',
// path: this.deleteInfo.path,
// }))
async deleteSingleFileByDeleteInfo () {
for (const item of this.deleteInfo.rawChannelAndIDArrays) {
const channel = item[0]
const id = item[1]
await api.raw.update(channel, id, { deleted: true })
await api.raw.clearDel(channel, id)
}
for (const item of this.deleteInfo.miniChannelAndIDArrays) {
const channel = item[0]
const id = item[1]
await api.mini.update(channel, id, { deleted: true })
await api.mini.clearDel(channel, id)
}
await api.meta.update(this.deleteInfo.metaID, { deleted: true })
await api.meta.clearDel(this.deleteInfo.metaID)
},
deleteFileDone: function () {
deleteFileConfirm: function (info) {
this.fillDeleteInfo(info)
this.showModal.deleteFile = true
},
deleteFile: async function () {
await this.deleteSingleFileByDeleteInfo()
await this.deleteFileDone()
},
deleteFileDone: async function () {
const tmpCurrentPage = this.$refs.datatable_ref.currentPage
// rebuild table
this.fileLists = this.fileLists.filter(file => file.name !== this.deleteInfo.name)
await this.refreshPage()
this.$refs.datatable_ref.currentPage = tmpCurrentPage
this.$refs.datatable_ref.inputPage(tmpCurrentPage)
// this.loadingFiles = false
this.showToast(`deleted ${this.deleteInfo.name}`, {
position: 'bottom-right',
@@ -536,15 +594,74 @@ export default {
info.errorMessages.pop()
info.errorMessages.push(message)
},
refreshCurrentPage: function () {
this.$refs.datatable_ref.refresh()
this.$refs.datatable_ref.currentPage = 1
refreshPage: async function () {
if (this.currentPathIndex === -1) {
this.openHome()
} else {
this.loadingFiles = true
// clear file and add path
file.clearFileList()
// call getfolder api and update
const folders = await api.collection.getByParent('folder', this.currentInfo.id)
const files = await api.meta.getCollectionByParent('folder', this.currentInfo.id)
file.updateFileList(folders)
file.updateFileList(files)
this.fileLists = file.getFileList()
this.loadingFiles = false
}
// this.$refs.datatable_ref.refresh()
// this.$refs.datatable_ref.currentPage = 1
},
showrefs: function () {
this.$emit('download', this.selected)
// downloadSelected: function () {
// for (let i = 0; i < this.selected.length; i++) {
// const meta = this.selected[i]
// this.downloadCsv(meta)
// }
// },
async deleteSelected () {
for (let i = 0; i < this.selected.length; i++) {
const meta = this.selected[i]
this.fillDeleteInfo(meta)
await this.deleteSingleFileByDeleteInfo()
this.showToast(`deleted ${this.deleteInfo.name}`, {
position: 'bottom-right',
})
}
const tmpCurrentPage = this.$refs.datatable_ref.currentPage
await this.refreshPage()
this.$refs.datatable_ref.currentPage = tmpCurrentPage
this.$refs.datatable_ref.inputPage(tmpCurrentPage)
},
download: async function (info) {
this.$emit('download', info)
downloadCsv: async function (meta) {
const href = location.href.split('/')[2]
if (meta.device.library_name.indexOf('Elite') >= 0) {
window.open('http://' + href + '/#/admin/download/elite/csv/' + meta.id, '_blank', 'width=500,height=100,left=200,top=200')
} else if (meta.device.library_name.indexOf('Neulive') >= 0) {
window.open('http://' + href + '/#/admin/download/neulive/csv/' + meta.id, '_blank', 'width=500,height=100,left=200,top=200')
}
},
downloadExcel: async function (meta) {
const href = location.href.split('/')[2]
if (meta.device.library_name.indexOf('Elite') >= 0) {
window.open('http://' + href + '/#/admin/download/elite/excel/' + meta.id, '_blank', 'width=500,height=100,left=200,top=200')
} else if (meta.device.library_name.indexOf('Neulive') >= 0) {
window.open('http://' + href + '/#/admin/download/neulive/csv/' + meta.id + '/true', '_blank', 'width=500,height=100,left=200,top=200')
}
},
replay: function (meta) {
if (meta.device.library_name.includes('Neulive') === true) {
// window.open('http://' + location.href.split('/')[2].split(':')[0] + '/#/admin/data-replay/' + meta.id)
this.$router.push({
path: '/admin/data-replay/' + meta.id,
})
} else if (meta.device.library_name.includes('Elite') === true) {
// window.open('http://' + location.href.split('/')[2].split(':')[0] + '/#/admin/data-replay/elite/' + meta.id)
this.$router.push({
path: '/admin/data-replay/elite/' + meta.id,
})
}
},
},
mounted () {
@@ -18,11 +18,11 @@ export default [
],
},
{
categoryName: 'Project',
categoryName: 'Task',
items: [
{
itemName: 'ProjectContent',
itemLink: '/project/content',
itemName: 'TaskContent',
itemLink: '/task/content',
},
],
},
@@ -38,8 +38,8 @@ export default [
itemLink: '/admin/statistics/progress-bars',
},
// {
// itemName: 'ProjectContent',
// itemLink: '/admin/statistics/project-content',
// itemName: 'TaskContent',
// itemLink: '/admin/statistics/task-content',
// },
],
},
@@ -1,137 +0,0 @@
<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">
<span slot="header" >
<va-item :key="device.id" class="pa-0 ma-0"
>
<va-icon
name="ion ion-md-close"
color="danger"
class="ml-0 mr-3 pa-0 shrink"
style="cursor: pointer;"
@click.native.stop="removeCheck(device)"
/>
<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">
<va-item-label>
{{ device.name }}
<va-button @click.stop="start(device)" v-if="!device.isSync" class="px-2 py-0 mr-0" color="success" small>START</va-button>
<va-button @click.stop="stop(device)" v-if="device.isSync" :disabled="device.stopping" class="px-2 py-0 mr-0" color="danger" small>STOP</va-button>
</va-item-label>
<va-item-label caption>
{{ device.address }}
</va-item-label>
</va-item-section>
</va-item>
</span>
<div slot="body">
<div class="mt-0 mb-0" style="height: 350px; overflow-y: scroll; overflow-x: hidden;" :key="'detail' + device.id">
<div style="text-align: center;">
<va-button @click.stop="generateChart(device)" class="pl-2 pr-2 mr-0" small>GENERATE MAPPING CHART</va-button>
</div>
<div v-if="device.type == 'Elite'">
<elite-parameter-window :ref="'epwindow_ref'" :deviceID="device.id" class="pl-0 pr-0" />
</div>
<div v-if="device.type == 'Neulive'">
<neulive-parameter-window :ref="'npwindow_ref'" :deviceID="device.id" class="pl-0 pr-0" />
</div>
</div>
</div>
</va-collapse>
</va-accordion>
</div>
</template>
<script>
// import NeuliveParameterWindow from '../parameter/NeuliveParameterWindow'
import EliteParameterWindow from '../parameter/EliteParameterWindow'
import NeuliveParameterWindow from '../parameter/NeuliveParameterWindow'
export default {
name: 'ProjectDeviceList',
components: {
EliteParameterWindow,
NeuliveParameterWindow,
},
props: {
deviceList: {
type: Array,
required: true,
},
},
data () {
return {
showDeleteModal: false,
selectDevice: null,
deviceStopping: false,
}
},
computed: {
},
methods: {
removeCheck: function (device) {
this.selectDevice = device
this.showDeleteModal = true
},
remove: function () {
this.$emit('remove', this.selectDevice)
},
start: function (device) {
this.$emit('start', device)
device.stopping = false
this.pageToast('The device ' + device.name + ' has been started.')
},
stop: function (device) {
device.stopping = true
this.$emit('stop', device)
this.pageToast('The device ' + device.name + ' has been stopped.')
},
generateChart: function (device) {
this.$emit('generate', device)
},
refresh: function () {
this.$nextTick(() => {
if (this.$refs.epwindow_ref != null) {
this.$refs.epwindow_ref.forEach(ref => {
ref.refresh()
})
}
if (this.$refs.npwindow_ref != null) {
this.$refs.npwindow_ref.forEach(ref => {
ref.refresh()
})
}
})
},
pageToast: function (mes) {
this.showToast(
mes,
{
icon: 'fa-bell',
position: 'bottom-right',
duration: 4000,
},
)
},
},
}
</script>
@@ -1,227 +0,0 @@
<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">
<project-device-list :ref="'pdlist_ref'" :deviceList="deviceList" @remove="removeDevice($event)" @start="startDevice($event)" @stop="stopDevice($event)" @generate="generateChart($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>
</div>
</template>
<script>
import { FulfillingBouncingCircleSpinner } from 'epic-spinners'
import ProjectDeviceList from './ProjectDeviceList'
import { projectInfo } from '../../../../data/project/ProjectInfo'
import { chartData } from '../../../../data/project/ChartsManagement'
import { dataStreamBuffer } from '../../../../data/project/DataStreamBuffer'
export default {
name: 'ProjectDevices',
components: {
FulfillingBouncingCircleSpinner,
ProjectDeviceList,
},
props: {
cardclass: {
type: Array,
default: function () {
return ['xs12', 'md12', 'xl12', 'sm12']
},
},
},
created () {
},
data () {
return {
deviceSelect: '',
deviceOptions: projectInfo.getDeviceListNotRegister(),
deviceList: projectInfo.getDeviceListRegister(),
state: {
LOADING: false,
},
}
},
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
console.log(this.deviceOptions)
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) {
await chartData.defaultChartGenerator(device.id, null, 'device')
if (!projectInfo.getDeviceInfo(device.id).info.isSync) {
this.mqttPub(projectInfo.getProjectInfo().controllerID + '_user', JSON.stringify({
header: 'device_instruction/0',
device: projectInfo.getRawDeviceID(device.id),
instruction: 'start',
}))
device.isSync = true
this.$emit('refreshSetting')
// ### show device info
console.log(projectInfo.getDeviceInfo(device.id))
}
},
stopDevice: function (device) {
dataStreamBuffer.removeByDevice(projectInfo.getRawDeviceID(device.id))
if (projectInfo.getDeviceInfo(device.id).info.isSync) {
this.mqttPub(projectInfo.getProjectInfo().controllerID + '_user', JSON.stringify({
header: 'device_instruction/0',
device: projectInfo.getRawDeviceID(device.id),
instruction: 'interrupt',
}))
}
// device.isSync = false
},
// addDevice: async function () {
// if (this.deviceSelect.id == null) {
// return false
// }
// await projectInfo.getProjectInfo().deviceAddrList.push(projectInfo.getDeviceInfoByRawID(this.deviceSelect.id).info.device_address)
// await projectInfo.getProjectInfo().projectDeviceID.push(this.deviceSelect.id)
// const _address = this.GLOBAL.transMac(projectInfo.getDeviceInfoByRawID(this.deviceSelect.id).info.device_address)
// const pic = projectInfo.getDevicePic(projectInfo.getDeviceInfoByRawID(this.deviceSelect.id).info.library_name)
// let type = ''
// if (projectInfo.getDeviceInfoByRawID(this.deviceSelect.id).info.library_name.indexOf('Elite') >= 0) {
// type = 'Elite'
// } else if (projectInfo.getDeviceInfoByRawID(this.deviceSelect.id).info.library_name.indexOf('Neulive') >= 0) {
// type = 'Neulive'
// }
// const _device = {
// id: projectInfo.getProjectInfo().projectDeviceID.indexOf(this.deviceSelect.id),
// name: '[' + projectInfo.getProjectInfo().projectDeviceID.indexOf(this.deviceSelect.id) + '] ' + projectInfo.getDeviceInfoByRawID(this.deviceSelect.id).info.device_name,
// addr: projectInfo.getDeviceInfoByRawID(this.deviceSelect.id).info.device_address,
// address: _address,
// picture: pic,
// type: type,
// isSync: projectInfo.getDeviceInfoByRawID(this.deviceSelect.id).info.isSync,
// stopping: false,
// }
// this.deviceList.push(_device)
// this.deviceSelect = ''
// projectInfo.updateAllList()
// this.$emit('add', _device.id)
// },
addDevice: async function (selectID) {
if (selectID == null) {
return false
}
await projectInfo.getProjectInfo().deviceAddrList.push(projectInfo.getDeviceInfoByRawID(selectID).info.device_address)
await projectInfo.getProjectInfo().projectDeviceID.push(selectID)
const _address = this.GLOBAL.transMac(projectInfo.getDeviceInfoByRawID(selectID).info.device_address)
const pic = projectInfo.getDevicePic(projectInfo.getDeviceInfoByRawID(selectID).info.library_name)
let type = ''
if (projectInfo.getDeviceInfoByRawID(selectID).info.library_name.indexOf('Elite') >= 0) {
type = 'Elite'
} else if (projectInfo.getDeviceInfoByRawID(selectID).info.library_name.indexOf('Neulive') >= 0) {
type = 'Neulive'
}
const _device = {
id: projectInfo.getProjectInfo().projectDeviceID.indexOf(selectID),
name: '[' + projectInfo.getProjectInfo().projectDeviceID.indexOf(selectID) + '] ' + projectInfo.getDeviceInfoByRawID(selectID).info.device_name,
addr: projectInfo.getDeviceInfoByRawID(selectID).info.device_address,
address: _address,
picture: pic,
type: type,
isSync: projectInfo.getDeviceInfoByRawID(selectID).info.isSync,
stopping: false,
}
this.deviceList.push(_device)
this.deviceSelect = ''
projectInfo.updateAllList()
this.$emit('add', _device.id)
},
removeDevice: async function (device) {
projectInfo.getProjectInfo().deviceAddrList.forEach(addr => {
if (addr === device.addr) {
projectInfo.getProjectInfo().deviceAddrList.splice(projectInfo.getProjectInfo().deviceAddrList.indexOf(addr), 1)
}
})
projectInfo.getProjectInfo().projectDeviceID.forEach(realID => {
if (realID === device.id) {
projectInfo.getProjectInfo().projectDeviceID.splice(projectInfo.getProjectInfo().projectDeviceID.indexOf(realID), 1)
}
})
this.deviceList.splice(this.deviceList.indexOf(device), 1)
this.deviceSelect = ''
projectInfo.updateAllList()
this.$emit('remove', device.id)
},
generateChart: function (device) {
this.$emit('add', device.id)
},
refresh: function () {
this.$nextTick(() => {
if (this.$refs.pdlist_ref != null) {
this.$refs.pdlist_ref.refresh()
}
})
},
},
async mounted () {
// this.pageMqttSub()
// for (const device in this.deviceOptions) {
// this.deviceSelect = this.deviceOptions[device]
// await this.addDevice()
// }
},
destroyed () {
this.loadingDone()
// this.pageMqttUnSub()
},
watch: {
},
}
</script>
@@ -1,71 +0,0 @@
<template>
<div class="flex mt-0 pt-0">
<div>
<div class="row flex sm12 xl12 md12 xs12">
<div>
<elite-parameter-recording :ref="'rec_ref'" :deviceID="deviceID"/>
</div>
</div>
</div>
</div>
</template>
<script>
import EliteParameterRecording from './EliteParameterRecording'
import { projectInfo } from '../../../../data/project/ProjectInfo'
export default {
name: 'EliteParameterWindow',
components: {
EliteParameterRecording,
},
props: {
deviceID: {
type: Number,
required: true,
},
deviceName: {
type: String,
default: 'Elite',
},
},
data () {
return {
}
},
mqtt: {
},
methods: {
mqttPub: function (topic, mes) {
this.$mqtt.publish(topic, mes)
},
pageInit: function () {
this.mqttPub(projectInfo.getProjectInfo().controllerID + '_user', JSON.stringify({
header: 'get_device_info/0',
device: projectInfo.getRawDeviceID(this.deviceID),
}))
},
refresh: function () {
this.$nextTick(() => {
if (this.$refs.rec_ref != null) {
this.$refs.rec_ref.refresh()
}
})
},
},
mounted () {
this.pageInit()
},
watch: {
deviceID: function (val) {
this.mqttPub(projectInfo.getProjectInfo().controllerID + '_user', JSON.stringify({
header: 'get_device_info/0',
device: projectInfo.getRawDeviceID(val),
}))
},
},
}
</script>
@@ -1,247 +0,0 @@
<template>
<div class="flex" >
<va-tree-root >
<va-tree-category
style="font-size: 20px;"
:label="'Channels'">
<va-tree-node>
<div class="row">
<div class="flex sm12 xl12 md12 xs12">
<div
style='display: inline-block;'
v-for="channel in [1, 2, 3, 4, 5, 6, 7, 8]"
:key="channel"
>
<va-button
class="mx-1 px-1"
v-if="channelList != null && channelList.indexOf(channel) >= 0"
@click="channelClickRemove(channel)"
small
>
{{channel}}
</va-button>
<va-button
class="mx-1 px-1"
v-if="channelList == null || channelList.indexOf(channel) < 0"
@click="channelClickAdd(channel)"
small outline
>
{{channel}}
</va-button>
</div>
</div>
</div>
</va-tree-node>
</va-tree-category>
<va-tree-category
style="font-size: 20px;"
:label="'Amp gain'">
<va-tree-node>
<div class="row">
<div class="flex sm12 xl12 md12 xs12">
<va-select
:on-change="ampGainSelectChange()"
:label="''"
v-model="ampGainSelect"
textBy="description"
:options="ampGainOptions"
/>
</div>
</div>
</va-tree-node>
</va-tree-category>
<va-tree-category
style="font-size: 20px;"
:label="'Sample rate'">
<va-tree-node>
<div class="row">
<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="sampleRateChange(4)">
4
</va-button>
<va-input
@keyup.enter="sampleRateChange(sampleRateInput)"
v-model="sampleRateInput"
class="mb-0"
style="width: 100px;"
>
<p slot="append" style="margin-right: 0;" small>
Hz
</p>
</va-input>
<va-button slot="append" class="ml-2 pa-1 shrink" small @click="sampleRateChange(1000)">
1000
</va-button>
</div>
<va-slider
@mouseup.native="sampleRateChange(sampleRate)"
@mouseleave.native="sampleRateChange(sampleRate)"
@touchend.native="sampleRateChange(sampleRate)"
class="flex sm12 xl12 md12 xs12"
value-visible
v-model="sampleRate"
:min="4"
:max="1000"
/>
</div>
</div>
</va-tree-node>
</va-tree-category>
</va-tree-root>
</div>
</template>
<script>
import { projectInfo } from '../../../../data/project/ProjectInfo'
export default {
name: 'NeuliveParameterRecording',
components: {
},
props: {
deviceID: {
type: Number,
required: true,
},
deviceName: {
type: String,
default: 'Neulive',
},
},
data () {
return {
channelList: [],
ampGainSelect: null,
ampGainOptions: [
{
id: 0,
description: '25',
},
{
id: 1,
description: '100',
},
{
id: 2,
description: '400',
},
{
id: 3,
description: '800',
},
],
sampleRateInput: '1000',
sampleRate: null,
}
},
mqtt: {
},
methods: {
mqttPub: function (topic, mes) {
this.$mqtt.publish(topic, mes)
},
refresh () {
this.channelList.length = 0
const channelSet = projectInfo.getDeviceInfo(this.deviceID).parameterSet.RECORDING_CH.toString(2).split('').reverse()
channelSet.forEach((element, index) => {
if (parseInt(element) > 0) {
this.channelList.push(index + 1)
}
})
this.ampGainSelect = this.ampGainOptions[(projectInfo.getDeviceInfo(this.deviceID).parameterSet.AMP_GAIN + 1) % 4]
this.sampleRate = parseInt(200 / parseFloat(projectInfo.getDeviceInfo(this.deviceID).parameterSet.ADC_CLOCK / 1000))
this.sampleRateInput = String(this.sampleRate)
},
channelClickAdd (val) {
if (this.channelList.indexOf(val) < 0) {
this.channelList.push(val)
let channelSet = ''
for (let i = 8; i >= 1; i--) {
if (this.channelList.indexOf(i) >= 0) {
channelSet += '1'
} else {
channelSet += '0'
}
}
const channelValue = parseInt(channelSet, 2)
if (channelValue !== projectInfo.getDeviceInfo(this.deviceID).RECORDING_CH) {
this.mqttPub(projectInfo.getProjectInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: projectInfo.getRawDeviceID(this.deviceID),
parameter: 'RECORDING_CH',
content: channelValue,
}))
}
}
},
channelClickRemove (val) {
if (this.channelList.indexOf(val) >= 0) {
this.channelList.splice(this.channelList.indexOf(val), 1)
let channelSet = ''
for (let i = 8; i >= 1; i--) {
if (this.channelList.indexOf(i) >= 0) {
channelSet += '1'
} else {
channelSet += '0'
}
}
const channelValue = parseInt(channelSet, 2)
if (channelValue !== projectInfo.getDeviceInfo(this.deviceID).RECORDING_CH) {
this.mqttPub(projectInfo.getProjectInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: projectInfo.getRawDeviceID(this.deviceID),
parameter: 'RECORDING_CH',
content: channelValue,
}))
}
}
},
ampGainSelectChange () {
if (this.ampGainSelect != null && this.ampGainSelect.id !== ((projectInfo.getDeviceInfo(this.deviceID).parameterSet.AMP_GAIN + 1) % 4)) {
this.mqttPub(projectInfo.getProjectInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: projectInfo.getRawDeviceID(this.deviceID),
parameter: 'AMP_GAIN',
content: ((this.ampGainSelect.id + 3) % 4),
}))
}
},
sampleRateChange (val) {
if (this.sampleRate == null) {
return false
}
if (isNaN(val) || parseInt(val) > 1000 || parseInt(val) < 4) {
this.sampleRateInput = '1000'
this.sampleRate = 1000
return false
}
if (parseInt(this.sampleRateInput) !== this.sampleRate || this.sampleRate !== parseInt(val)) {
this.sampleRateInput = String(val)
this.sampleRate = parseInt(val)
}
if (this.sampleRate !== parseInt(200 / parseFloat(projectInfo.getDeviceInfo(this.deviceID).parameterSet.ADC_CLOCK / 1000))) {
this.mqttPub(projectInfo.getProjectInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: projectInfo.getRawDeviceID(this.deviceID),
parameter: 'ADC_CLOCK',
content: parseInt(parseFloat(1 / parseFloat(this.sampleRate / 200)) * 1000),
}))
}
},
},
mounted () {
this.refresh()
},
destroyed () {
},
watch: {
},
}
</script>
@@ -0,0 +1,146 @@
<template>
<div class="modal">
<va-modal
v-model="showModal"
size="small"
:title=" $t('Set condition')"
:okText=" $t('modal.confirm') "
:cancelText=" $t('modal.cancel') "
@ok="sendCondition"
@cancel="cancel"
>
<va-input
v-if="isTmp"
v-model="conditionAlias"
:label="$t('Condition name')"
required
/>
<p v-if="!isTmp"> {{ 'Condition name: '.concat(conditionAlias) }} </p>
<div
v-for="condition in conditions"
:key="condition.id"
>
<div class="flex row align--center">
<va-input
v-model="condition.startTime"
:label="$t('StartTime')"
/>
<va-input
v-model="condition.duration"
:label="$t('Duration')"
/>
<va-icon
name="ion ion-md-close"
color="info"
class="ml-2 pa-1 shrink"
style="cursor: pointer;"
@click.native="removeConditionButton(condition)"
/>
<select class="param-selection" v-model="condition.paramID">
<option v-for="(option, key) in allParams" :key="key" :value="key" >{{ option.paramsSet.alias }}</option>
</select>
</div>
</div>
<va-button class="mb-2" @click="addConditionButton()">
Add new condition
</va-button>
</va-modal>
</div>
</template>
<script>
import { mapActions, mapGetters } from 'vuex'
import types from '@/store/modules/project/content/types'
import { getUniqueID } from '@/data/tool'
export default {
name: 'ConditionWindow',
components: {
},
computed: {
...mapGetters('projectContent', {
allParams: types.params.getAll,
}),
},
props: {
conditionID: {
type: String,
},
conditionName: {
type: String,
default: '',
},
},
data () {
return {
conditionAlias: this.conditionName,
conditions: [],
backupConditions: [],
showModal: false,
isTmp: false,
}
},
mqtt: {
},
methods: {
...mapActions('projectContent', [types.devices.updateSetting]),
...mapActions('projectContent', [types.params.updateTmp]),
backupCondition () {
this.backupConditions = JSON.parse(JSON.stringify(this.conditions)) // deep copy
},
restoreToBackupCondition () {
this.conditions = JSON.parse(JSON.stringify(this.backupConditions)) // deep copy
},
addConditionButton () {
const firstKey = Object.keys(this.allParams)[0]
const id = getUniqueID()
const condition = {
id: id,
startTime: 0,
duration: 0,
paramID: firstKey,
}
this.conditions.push(condition)
},
removeConditionButton (condition) {
this.conditions = this.conditions.filter(conditionToFilter => conditionToFilter.id !== condition.id)
},
async sendCondition () {
await this.updateSettingDevice({ conditionID: this.conditionID, alias: this.conditionAlias, conditions: this.conditions })
this.showModal = false
if (this.isTmp) {
this.conditions = []
this.conditionAlias = ''
this.isTmp = false
}
this.backupCondition()
this.$emit('updateParentView')
},
cancel () {
this.showModal = false
if (this.isTmp) {
this.conditionAlias = ''
this.isTmp = false
}
this.restoreToBackupCondition()
},
pageToast: function (mes) {
this.showToast(
mes,
{
icon: 'fa-bell',
position: 'bottom-right',
duration: 4000,
},
)
},
},
mounted () {
},
destroyed () {
},
watch: {
},
}
</script>
@@ -0,0 +1,181 @@
<template>
<div class="modal">
<va-modal
v-model="showModal"
size="small"
:title=" $t('Set timer and parameters')"
:okText=" $t('modal.confirm') "
:cancelText=" $t('modal.cancel') "
@ok="sendMapping"
@cancel="cancel"
>
Use condition template
<select class="condition-selection" v-model="selectedTemplateID" @change="onChangeTemplate($event)">
<option v-for="(condition, key) in allConditions" :key="key" :value="key" >{{ condition.alias }}</option>
</select>
<br/>
<div
v-for="mapping in mappings"
:key="mapping.id"
>
<div class="flex row align--center">
<va-input
v-model="mapping.startTime"
:label="$t('StartTime')"
/>
<va-input
v-model="mapping.duration"
:label="$t('Duration')"
/>
<va-icon
name="ion ion-md-close"
color="info"
class="ml-2 pa-1 shrink"
style="cursor: pointer;"
@click.native="removeMappingButton(mapping)"
/>
<select class="param-selection" v-model="mapping.paramID">
<option v-for="(option, key) in allParams" :key="key" :value="key" >{{ option.paramsSet.alias }}</option>
</select>
</div>
</div>
<va-button class="mb-2" @click="addMappingButton()">
Add new mapping
</va-button>
</va-modal>
</div>
</template>
<script>
import { mapActions, mapGetters } from 'vuex'
import types from '@/store/modules/project/content/types'
import { getUniqueID } from '@/data/tool'
export default {
name: 'DeviceAndConditionMapping',
components: {
},
computed: {
...mapGetters('projectContent', {
allConditions: types.devices.getAllConditions,
}),
...mapGetters('projectContent', {
allParams: types.params.getAll,
}),
},
props: {
taskID: {
type: String,
required: true,
},
deviceID: {
type: String,
required: true,
},
deviceName: {
type: String,
default: 'Neulive',
},
},
data () {
return {
mappings: [],
backupMappings: [],
showModal: false,
selectedTemplateID: '',
lastSelectedID: '',
}
},
mqtt: {
},
methods: {
...mapActions('projectContent', [types.tasks.updateMapping, types.tasks.deleteMapping]),
...mapActions('projectContent', [types.params.updateTmp]),
getDefaultMapping () {
const firstKey = Object.keys(this.allParams)[0]
const id = getUniqueID()
const startConditionID = getUniqueID()
const durationConditionID = getUniqueID()
const startRecordingID = getUniqueID()
const endRecordingID = getUniqueID()
const startStimulationID = getUniqueID()
const endStimulationID = getUniqueID()
const mapping = {
id: id,
deviceID: this.deviceID,
startTime: 0,
duration: 0,
paramID: firstKey,
startConditionID: startConditionID,
durationConditionID: durationConditionID,
startRecordingID: startRecordingID,
endRecordingID: endRecordingID,
startStimulationID: startStimulationID,
endStimulationID: endStimulationID,
}
return mapping
},
backupMapping () {
this.backupMappings = JSON.parse(JSON.stringify(this.mappings)) // deep copy
},
restoreToBackupMapping () {
this.mappings = JSON.parse(JSON.stringify(this.backupMappings)) // deep copy
},
resetMapping () {
this.mappings = []
},
addMappingButton () {
const mapping = this.getDefaultMapping()
this.mappings.push(mapping)
},
async removeMappingButton (mapping) {
await this.deleteMappingTask({ taskID: this.taskID, mapping: mapping })
this.mappings = this.mappings.filter(mappingToFilter => mappingToFilter.id !== mapping.id)
},
async sendMapping () {
await this.updateMappingTask({ taskID: this.taskID, mappingList: this.mappings })
this.showModal = false
this.backupMapping()
this.lastSelectedID = this.selectedTemplateID
},
cancel () {
this.showModal = false
this.selectedTemplateID = this.lastSelectedID
this.restoreToBackupMapping()
},
onChangeTemplate (event) {
this.resetMapping()
const conditions = this.allConditions[this.selectedTemplateID]
for (const [_key, _value] of Object.entries(conditions)) {
var mapping = this.getDefaultMapping()
if (_key !== 'alias') {
mapping.id = _key
for (const [_k, _v] of Object.entries(_value)) {
mapping[_k] = _v
}
this.mappings.push(mapping)
}
}
this.backupMapping()
},
pageToast: function (mes) {
this.showToast(
mes,
{
icon: 'fa-bell',
position: 'bottom-right',
duration: 4000,
},
)
},
},
mounted () {
},
destroyed () {
},
watch: {
},
}
</script>
@@ -0,0 +1,205 @@
<template>
<div class="flex" >
<div class="row">
<div class="flex sm12 xl12 md12 xs12">
Record
<div
style='display: inline-block;'
v-for="channel in [1, 2, 3, 4, 5, 6, 7, 8]"
:key="channel"
>
<va-button
class="mx-1 px-1"
v-if="channelList != null && channelList.indexOf(channel) >= 0"
@click="channelClickRemove(channel)"
small
>
{{channel}}
</va-button>
<va-button
class="mx-1 px-1"
v-if="channelList == null || channelList.indexOf(channel) < 0"
@click="channelClickAdd(channel)"
small outline
>
{{channel}}
</va-button>
</div>
</div>
</div>
<div class="row">
<div class="flex sm12 xl12 md12 xs12">
<va-select
:on-change="ampGainSelectChange()"
:label="''"
v-model="ampGainSelect"
textBy="description"
:options="ampGainOptions"
/>
</div>
</div>
<div class="row">
<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="sampleRateChange(4)">
4
</va-button>
<va-input
@keyup.enter="sampleRateChange(sampleRateInput)"
v-model="sampleRateInput"
class="mb-0"
style="width: 100px;"
>
<p slot="append" style="margin-right: 0;" small>
Hz
</p>
</va-input>
<va-button slot="append" class="ml-2 pa-1 shrink" small @click="sampleRateChange(1000)">
1000
</va-button>
</div>
<va-slider
@mouseup.native="sampleRateChange(sampleRate)"
@mouseleave.native="sampleRateChange(sampleRate)"
@touchend.native="sampleRateChange(sampleRate)"
class="flex sm12 xl12 md12 xs12"
value-visible
v-model="sampleRate"
:min="4"
:max="1000"
/>
</div>
</div>
</div>
</template>
<script>
import { mapActions } from 'vuex'
import types from '@/store/modules/project/content/types'
export default {
name: 'NeuliveParameterRecording',
components: {
},
data () {
return {
channelList: [],
ampGainOptions: [
{
id: 0,
description: '25',
},
{
id: 1,
description: '100',
},
{
id: 2,
description: '400',
},
{
id: 3,
description: '800',
},
],
ampGainSelect: { id: 2, description: '400' },
sampleRateInput: '1000',
sampleRate: 1000,
tmpParam: {},
}
},
mqtt: {
},
methods: {
...mapActions('projectContent', [types.params.updateTmp]),
init () {
this.tmpParam = { paramsSet: { recording: { RECORDING_CH: 0, AMP_GAIN: 1, ADC_CLOCK: parseInt(parseFloat(1 / parseFloat(this.sampleRate / 200)) * 1000) } } }
},
reset () {
this.tmpParam = { paramsSet: { recording: {} } }
},
async channelClickAdd (val) {
if (this.channelList.indexOf(val) < 0) {
this.channelList.push(val)
let channelSet = ''
for (let i = 8; i >= 1; i--) {
if (this.channelList.indexOf(i) >= 0) {
channelSet += '1'
} else {
channelSet += '0'
}
}
const channelValue = parseInt(channelSet, 2)
this.updateTmp('RECORDING_CH', channelValue)
await this.updateTmpParam(this.tmpParam)
}
},
async channelClickRemove (val) {
if (this.channelList.indexOf(val) >= 0) {
this.channelList.splice(this.channelList.indexOf(val), 1)
let channelSet = ''
for (let i = 8; i >= 1; i--) {
if (this.channelList.indexOf(i) >= 0) {
channelSet += '1'
} else {
channelSet += '0'
}
}
const channelValue = parseInt(channelSet, 2)
this.updateTmp('RECORDING_CH', channelValue)
await this.updateTmpParam(this.tmpParam)
}
},
async ampGainSelectChange () {
if (this.ampGainSelect != null) {
this.updateTmp('AMP_GAIN', (this.ampGainSelect.id + 3) % 4)
await this.updateTmpParam(this.tmpParam)
}
},
async sampleRateChange (val) {
if (this.sampleRate == null) {
return false
}
if (isNaN(val) || parseInt(val) > 1000 || parseInt(val) < 4) {
this.sampleRateInput = '1000'
this.sampleRate = 1000
return false
}
if (parseInt(this.sampleRateInput) !== this.sampleRate || this.sampleRate !== parseInt(val)) {
this.sampleRateInput = String(val)
this.sampleRate = parseInt(val)
}
this.updateTmp('ADC_CLOCK', parseInt(parseFloat(1 / parseFloat(this.sampleRate / 200)) * 1000))
await this.updateTmpParam(this.tmpParam)
},
updateTmp (key, value) {
this.tmpParam.paramsSet.recording[key] = value
},
pageToast: function (mes) {
this.showToast(
mes,
{
icon: 'fa-bell',
position: 'bottom-right',
duration: 4000,
},
)
},
},
async created () {
this.init()
await this.updateTmpParam(this.tmpParam)
},
async destroyed () {
this.reset()
},
watch: {
},
}
</script>
@@ -0,0 +1,678 @@
<template>
<div class="flex">
<div>
Stimulate
<div class="mt-4">
<div class="row sm12 xl12 md12 xs12">
<p class="display-6">ELECTRODE</p>
</div>
<div class="row">
<div class="flex sm12 xl12 md12 xs12">
<va-button-toggle
:on-change="stimulateElectrodeSelectChange()"
small
outline
v-model="stimulateElectrodeSelect"
:options="stimulateElectrodeOptions"
/>
</div>
</div>
</div>
<div class="mt-4">
<div class="row sm12 xl12 md12 xs12">
<p class="display-6">CHANNELS</p>
</div>
<div class="row">
<div class="flex sm12 xl12 md12 xs12">
<div
style='display: inline-block;'
v-for="channel in [1, 2, 3, 4, 5, 6, 7, 8]"
:key="channel"
>
<va-button
class="mx-1 px-2"
color="success"
v-if="posChannelList.indexOf(channel) >= 0 && negChannelList.indexOf(channel) < 0"
@click="channelClick(channel)"
small
>
{{channel}}
</va-button>
<va-button
class="mx-1 px-2"
color="danger"
v-if="posChannelList.indexOf(channel) < 0 && negChannelList.indexOf(channel) >= 0"
@click="channelClick(channel)"
small
>
{{channel}}
</va-button>
<va-button
class="mx-1 px-2"
v-if="posChannelList.indexOf(channel) < 0 && negChannelList.indexOf(channel) < 0"
@click="channelClick(channel)"
small outline
>
{{channel}}
</va-button>
</div>
</div>
</div>
</div>
<div class="mt-4">
<div class="row sm12 xl12 md12 xs12">
<p class="display-6">CYCLE NUMBER</p>
</div>
<div class="row">
<div class="flex sm12 xl12 md12 xs12">
<va-button-toggle
:on-change="cycleNumberSelectChange()"
small
outline
v-model="cycleNumberSelect"
:options="cycleNumberOptions"
/>
</div>
</div>
<div class="row" v-if="cycleNumberSelect==0">
<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="cycleNumberChange(1)">
1
</va-button>
<va-input
@keyup.enter="cycleNumberChange(cycleNumberInput)"
v-model="cycleNumberInput"
class="mb-0"
>
<p slot="append" style="margin-right: 0;" small>
Rounds
</p>
</va-input>
<va-button slot="append" class="ml-2 pa-1 shrink" small @click="cycleNumberChange(256)">
256
</va-button>
</div>
<va-slider
class="flex sm12 xl12 md12 xs12"
@mouseup.native="cycleNumberChange(cycleNumber)"
@mouseleave.native="cycleNumberChange(cycleNumber)"
@touchend.native="cycleNumberChange(cycleNumber)"
value-visible
v-model="cycleNumber"
:min="1"
:max="256"
/>
</div>
</div>
</div>
<div class="mt-4">
<div class="row sm12 xl12 md12 xs12">
<p class="display-6">AMPLITUDE (uA)</p>
</div>
<div class="row">
<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="amplitudeNumberChange(5)">
5
</va-button>
<va-input
@keyup.enter="amplitudeNumberChange(amplitudeNumberInput)"
v-model="amplitudeNumberInput"
class="mb-0"
>
<p slot="append" style="margin-right: 0;" small>
uA
</p>
</va-input>
<va-button slot="append" class="ml-2 pa-1 shrink" small @click="amplitudeNumberChange(4000)">
4000
</va-button>
</div>
<va-slider
class="flex sm12 xl12 md12 xs12"
@mouseup.native="amplitudeNumberChange(amplitudeNumber)"
@mouseleave.native="amplitudeNumberChange(amplitudeNumber)"
@touchend.native="amplitudeNumberChange(amplitudeNumber)"
value-visible
v-model="amplitudeNumber"
:min="5"
:max="4000"
/>
</div>
</div>
</div>
<div class="mt-4">
<div class="row sm12 xl12 md12 xs12">
<p class="display-6">PATTERN</p>
</div>
<div class="row">
<div class="flex sm12 xl12 md12 xs12">
<va-button-toggle
:on-change="patternModeSelectChange()"
small
outline
v-model="patternModeSelect"
:options="patternModeOptions"
/>
</div>
</div>
<div class="row">
<div class="flex sm12 xl12 md12 xs12">
<va-button-toggle
small
outline
v-model="unitSelect"
:options="unitOptions"
@click.native="transUnit()"
/>
</div>
</div>
<div class="row">
<div class="flex sm12 xl12 md12 xs12">
<div class="flex row align--center">
<va-input
v-model="frequencyNumberInput"
class="mb-0"
:label="'Frequency'"
@keyup.enter="frequencyNumberChange(frequencyNumberInput)"
>
<p slot="append" style="margin-right: 0;" small>
Hz
</p>
</va-input>
</div>
</div>
</div>
<div class="row">
<div class="flex sm12 xl12 md12 xs12">
<div class="flex row align--center">
<va-input
v-model="periodNumberInput"
class="mb-0"
:label="'Period'"
@keyup.enter="periodNumberChange(periodNumberInput)"
>
<p slot="append" style="margin-right: 0;" small>
{{unitOptions[unitSelect].label}}
</p>
</va-input>
</div>
</div>
</div>
<div class="row">
<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="patternModeSelect?timeRangeChange(1, 0):timeRangeChange(1, 0)">
0
</va-button>
<va-input
@keyup.enter="timeRangeChange(1, t1RangeInput)"
v-model="t1RangeInput"
class="mb-0"
:label="'T1 RANGE'"
>
<p slot="append" style="margin-right: 0;" small>
{{unitOptions[unitSelect].label}}
</p>
</va-input>
<va-button slot="append" class="ml-2 pa-1 shrink" small @click="timeRangeChange(1, 10.23)">
10.23
</va-button>
</div>
</div>
</div>
<div class="row" v-if="patternModeSelect==1">
<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="timeRangeChange(2, 0)">
0
</va-button>
<va-input
@keyup.enter="timeRangeChange(2, t2RangeInput)"
v-model="t2RangeInput"
class="mb-0"
:label="'T2 RANGE'"
>
<p slot="append" style="margin-right: 0;" small>
{{unitOptions[unitSelect].label}}
</p>
</va-input>
<va-button slot="append" class="ml-2 pa-1 shrink" small @click="timeRangeChange(2, 10.23)">
10.23
</va-button>
</div>
</div>
</div>
<div class="row" v-if="patternModeSelect==1">
<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="timeRangeChange(3, 0)">
0
</va-button>
<va-input
@keyup.enter="timeRangeChange(3, t3RangeInput)"
v-model="t3RangeInput"
class="mb-0"
:label="'T3 RANGE'"
>
<p slot="append" style="margin-right: 0;" small>
{{unitOptions[unitSelect].label}}
</p>
</va-input>
<va-button slot="append" class="ml-2 pa-1 shrink" small @click="timeRangeChange(3, 10.23)">
10.23
</va-button>
</div>
</div>
</div>
<div class="row">
<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="timeRangeChange(4, 0)">
0
</va-button>
<va-input
@keyup.enter="timeRangeChange(4, t4RangeInput)"
v-model="t4RangeInput"
class="mb-0"
:label="'T4 RANGE'"
>
<p slot="append" style="margin-right: 0;" small>
{{unitOptions[unitSelect].label}}
</p>
</va-input>
<va-button slot="append" class="ml-2 pa-1 shrink" small @click="timeRangeChange(4, 1310.71)">
1310.71
</va-button>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import { mapActions } from 'vuex'
import types from '@/store/modules/project/content/types'
export default {
name: 'NeuliveParameterStimulation',
components: {
},
data () {
return {
posChannelList: [2],
negChannelList: [1],
stimulateElectrodeSelect: null,
stimulateElectrodeOptions: [
{
label: 'Monopolar',
value: 0,
},
{
label: 'Bipolar',
value: 1,
},
],
cycleNumberSelect: null,
cycleNumberOptions: [
{
label: 'limite',
value: 0,
},
{
label: 'Unlimite',
value: 1,
},
],
cycleNumberInput: '1',
cycleNumber: 1,
cycleNumberArray: Array(9).fill(1),
amplitudeNumberInput: '50',
amplitudeNumber: 50,
patternModeSelect: null,
patternModeOptions: [
{
label: 'Monophasic',
value: 0,
},
{
label: 'Biphasic',
value: 1,
},
],
unitSelect: 1,
unitOptions: [
{
label: 's',
value: 0,
},
{
label: 'ms',
value: 1,
},
{
label: 'us',
value: 2,
},
],
unitMultiply: 1000,
// period = (t1 + t2 + t3 + t4) * 10
frequencyNumberInput: '0',
frequencyNumber: 0,
periodNumberInput: '0',
periodNumber: 0,
t1RangeInput: '0',
t1Range: 0,
t1RangeArray: Array(9).fill(0),
t2RangeInput: '0',
t2Range: 0,
t2RangeArray: Array(9).fill(0),
t3RangeInput: '0',
t3Range: 0,
t3RangeArray: Array(9).fill(0),
t4RangeInput: '0',
t4Range: 0,
t4RangeArray: Array(9).fill(0),
tmpParam: {},
}
},
computed: {
},
mqtt: {
},
methods: {
...mapActions('projectContent', [types.params.updateTmp]),
refresh () {
console.log('[TODO] stimulation refresh')
},
init () {
this.tmpParam = { paramsSet: { stimulation: { STI_H_BRIDGE: 1, CONTINUOUS_STI: 1, STI_CYCLE_LIST: '0:9=' + this.cycleNumberArray.toString(), STI_AMPLITUDE: 0, STI_PATTERN: 1, STI_CHANNEL: 0, STI_POLARITY: 0, STI_T1: '0:9=' + String(this.t1RangeArray), STI_T2: '0:9=' + String(this.t2RangeArray), STI_T3: '0:9=' + String(this.t3RangeArray), STI_T4: '0:9=' + String(this.t4RangeArray) } } }
},
reset () {
this.tmpParam = { paramsSet: { stimulation: {} } }
},
transUnit () {
if (this.unitSelect === 0) {
this.unitMultiply = 1000000
} else if (this.unitSelect === 1) {
this.unitMultiply = 1000
} else {
this.unitMultiply = 1
}
this.refresh()
},
async stimulateElectrodeSelectChange () {
if (this.stimulateElectrodeSelect == null) {
return false
}
this.updateTmp('STI_H_BRIDGE', this.stimulateElectrodeSelect)
await this.updateTmpParam(this.tmpParam)
},
channelClick (val) {
if (this.posChannelList.indexOf(val) >= 0) {
this.posChannelList.splice(this.posChannelList.indexOf(val), 1)
this.negChannelList.push(val)
} else if (this.negChannelList.indexOf(val) >= 0) {
this.negChannelList.splice(this.negChannelList.indexOf(val), 1)
} else {
this.posChannelList.push(val)
}
this.updateStiChannel()
},
async cycleNumberSelectChange () {
if (this.cycleNumberSelect == null) {
return false
}
this.updateTmp('CONTINUOUS_STI', this.cycleNumberSelect)
await this.updateTmpParam(this.tmpParam)
},
async cycleNumberChange (val) {
if (isNaN(val) || parseInt(val) > 256 || parseInt(val) < 1) {
this.cycleNumberInput = '1'
this.cycleNumber = 1
}
this.cycleNumberInput = String(val)
this.cycleNumber = parseInt(val)
if (this.cycleNumberArray[0] !== this.cycleNumber) {
this.cycleNumberArray.fill(this.cycleNumber, 0)
this.updateTmp('STI_CYCLE_LIST', '0:9=' + this.cycleNumberArray.toString())
await this.updateTmpParam(this.tmpParam)
}
},
async amplitudeNumberChange (val) {
if (this.amplitudeNumber == null) {
return false
}
if (typeof (val) === 'string') {
if (isNaN(val) || parseInt(val) > 4000 || parseInt(val) < 5) {
this.amplitudeNumberInput = '50'
this.amplitudeNumber = 50
}
if (parseInt(this.amplitudeNumberInput) !== parseInt(this.amplitudeNumber)) {
this.amplitudeNumber = parseInt(val)
}
} else {
if (isNaN(val) || parseInt(val) > 4000 || parseInt(val) < 5) {
this.amplitudeNumberInput = '50'
this.samplitudeNumber = 50
}
if (parseInt(this.amplitudeNumberInput) !== parseInt(this.amplitudeNumber) || this.amplitudeNumber !== val) {
this.amplitudeNumberInput = String(val)
this.amplitudeNumber = val
}
}
this.updateTmp('STI_AMPLITUDE', parseInt(this.amplitudeNumber / 5))
await this.updateTmpParam(this.tmpParam)
},
async patternModeSelectChange () {
if (this.patternModeSelect == null) {
return false
}
if (this.patternModeSelect === 0) {
this.t2Range = 0
this.t2RangeInput = '0'
this.t3Range = 0
this.t3RangeInput = '0'
this.t4Range = (this.periodNumber / 10) - this.t1Range
this.t4RangeInput = String((this.t4Range * 10) / this.unitMultiply)
} else {
this.t3Range = this.t1Range
this.t3RangeInput = this.t1RangeInput
this.t4Range = (this.periodNumber / 10) - this.t1Range - this.t2Range - this.t3Range
this.t4RangeInput = String((this.t4Range * 10) / this.unitMultiply)
}
this.updateTmp('STI_PATTERN', this.patternModeSelect)
await this.updateTmpParam(this.tmpParam)
},
frequencyNumberChange (val) {
if (this.frequencyNumberInput == null) {
return false
}
if (typeof (val) === 'string') {
if (isNaN(val) || parseInt(val) < 1 || parseInt(val) > 10000) {
this.frequencyNumberInput = '100'
this.frequencyNumber = 100
}
if (parseInt(this.frequencyNumberInput) !== parseInt(this.frequencyNumber)) {
this.frequencyNumber = parseInt(val)
}
}
this.periodNumber = (1 / this.frequencyNumber * 1e6).toFixed(3)
this.periodNumberInput = String(this.periodNumber / this.unitMultiply)
if (this.t1Range === 0 || this.t3Range === 0) {
this.t1Range = 10
this.t1RangeInput = String((this.t1Range * 10) / this.unitMultiply)
this.t3Range = 10
this.t3RangeInput = String((this.t3Range * 10) / this.unitMultiply)
this.t4Range = (this.periodNumber / 10) - (this.t1Range + this.t2Range + this.t3Range)
this.t4RangeInput = String((this.t4Range * 10) / this.unitMultiply)
} else {
this.t4Range = (this.periodNumber / 10) - (this.t1Range + this.t2Range + this.t3Range)
this.t4RangeInput = String((this.t4Range * 10) / this.unitMultiply)
}
this.updateTimeRange()
},
periodNumberChange (val) {
if (this.periodNumberInput === null) {
return false
}
if (typeof (val) === 'string') {
if (isNaN(val) || parseFloat(val) < 0 || parseFloat(val / this.unitMultiply) > 1) {
this.periodNumber = 1000
this.periodNumberInput = String(this.periodNumber / this.unitMultiply)
}
if (parseInt(this.periodNumberInput) !== parseInt(this.periodNumber)) {
this.periodNumber = parseFloat(val * this.unitMultiply)
this.periodNumberInput = val
}
}
this.frequencyNumber = parseInt(1 / (this.periodNumber * 1e-6))
this.frequencyNumberInput = String(this.frequencyNumber)
if (this.t1Range === 0 || this.t3Range === 0) {
this.t1Range = 10
this.t1RangeInput = String((this.t1Range * 10) / this.unitMultiply)
this.t3Range = 10
this.t3RangeInput = String((this.t3Range * 10) / this.unitMultiply)
this.t4Range = (this.periodNumber / 10) - (this.t1Range + this.t2Range + this.t3Range)
this.t4RangeInput = String((this.t4Range * 10) / this.unitMultiply)
} else {
this.t4Range = (this.periodNumber / 10) - (this.t1Range + this.t2Range + this.t3Range)
this.t4RangeInput = String((this.t4Range * 10) / this.unitMultiply)
}
this.updateTimeRange()
},
timeRangeChange (stiIimeSelect, val) {
switch (stiIimeSelect) {
case 1:
this.t1Range = parseInt((val * this.unitMultiply) / 10)
this.t1RangeInput = val
this.t3Range = parseInt((val * this.unitMultiply) / 10)
this.t3RangeInput = val
break
case 2:
this.t2Range = parseInt((val * this.unitMultiply) / 10)
this.t2RangeInput = val
break
case 3:
this.t1Range = parseInt((val * this.unitMultiply) / 10)
this.t1RangeInput = val
this.t3Range = parseInt((val * this.unitMultiply) / 10)
this.t3RangeInput = val
break
case 4:
this.t4Range = parseInt((val * this.unitMultiply) / 10)
this.t4RangeInput = val
if (this.frequencyNumber > 0) {
this.t2Range = (this.periodNumber / 10) - this.t1Range - this.t3Range - this.t4Range
this.t2RangeInput = String((this.t2Range * 10) / this.unitMultiply)
}
break
}
if (this.frequencyNumber > 0 && stiIimeSelect !== 4) {
this.t4Range = (this.periodNumber / 10) - this.t1Range - this.t2Range - this.t3Range
this.t4RangeInput = String((this.t4Range * 10) / this.unitMultiply)
}
this.updateTimeRange()
},
async updateStiChannel () {
// stiChannelSet (+,-), stiPolaritySet (+)
let stiChannelSet = ''
let stiPolaritySet = ''
for (let i = 8; i >= 1; i--) {
if (this.posChannelList.indexOf(i) >= 0) {
stiChannelSet += '1'
stiPolaritySet += '1'
} else if (this.negChannelList.indexOf(i) >= 0) {
stiChannelSet += '1'
stiPolaritySet += '0'
} else {
stiChannelSet += '0'
stiPolaritySet += '0'
}
}
const stiChannelValue = parseInt(stiChannelSet, 2)
const stiPolarityValue = parseInt(stiPolaritySet, 2)
this.updateTmp('STI_CHANNEL', stiChannelValue)
this.updateTmp('STI_POLARITY', stiPolarityValue)
await this.updateTmpParam(this.tmpParam)
},
async updateTimeRange () {
if (this.t1RangeArray[0] !== this.t1Range) {
this.t1RangeArray.fill(this.t1Range, 0)
this.updateTmp('STI_T1', '0:9=' + String(this.t1RangeArray))
await this.updateTmpParam(this.tmpParam)
}
if (this.t2RangeArray[0] !== this.t2Range) {
this.t2RangeArray.fill(this.t2Range, 0)
this.updateTmp('STI_T2', '0:9=' + String(this.t2RangeArray))
await this.updateTmpParam(this.tmpParam)
}
if (this.t3RangeArray[0] !== this.t3Range) {
this.t3RangeArray.fill(this.t3Range, 0)
this.updateTmp('STI_T3', '0:9=' + String(this.t3RangeArray))
await this.updateTmpParam(this.tmpParam)
}
if (this.t4RangeArray[0] !== this.t4Range) {
this.t4RangeArray.fill(this.t4Range, 0)
this.updateTmp('STI_T4', '0:9=' + String(this.t4RangeArray))
await this.updateTmpParam(this.tmpParam)
}
},
updateTmp (key, value) {
this.tmpParam.paramsSet.stimulation[key] = value
},
pageToast: function (mes) {
this.showToast(
mes,
{
icon: 'fa-bell',
position: 'bottom-right',
duration: 4000,
},
)
},
},
async created () {
this.init()
await this.updateTmpParam(this.tmpParam)
},
async destroyed () {
this.reset()
},
watch: {
},
}
</script>
@@ -0,0 +1,119 @@
<template>
<div class="flex">
<va-modal
v-model="showModal"
size="small"
:title=" $t('Set parameters')"
:okText=" $t('modal.confirm') "
:cancelText=" $t('modal.cancel') "
@ok="AddParams"
@cancel="Cancel"
>
<va-input
@input="paramAliasChange(paramAlias)"
v-model="paramAlias"
:label="$t('Parameter set name')"
required
/>
<va-item>
<va-item-section side>
<va-checkbox v-model="recordingCheck" />
</va-item-section>
<va-item-section>
<va-item-label>
Recording
</va-item-label>
</va-item-section>
</va-item>
<va-item>
<va-item-section side>
<va-checkbox v-model="stimulationCheck" />
</va-item-section>
<va-item-section>
<va-item-label>
Stimulation
</va-item-label>
</va-item-section>
</va-item>
<neulive-parameter-recording v-if="recordingCheck"/>
<br/>
<neulive-parameter-stimulation v-if="stimulationCheck"/>
</va-modal>
</div>
</template>
<script>
import { mapActions, mapGetters } from 'vuex'
import types from '@/store/modules/project/content/types'
import NeuliveParameterRecording from './NeuliveParameterRecording'
import NeuliveParameterStimulation from './NeuliveParameterStimulation'
import { getUniqueID } from '@/data/tool'
export default {
name: 'NeuliveParameterWindow',
components: {
NeuliveParameterRecording,
NeuliveParameterStimulation,
},
computed: {
...mapGetters('projectContent', {
tmpParam: types.params.getTmp,
}),
},
data () {
return {
paramAlias: '',
showModal: false,
recordingCheck: false,
stimulationCheck: false,
}
},
mqtt: {
},
methods: {
...mapActions('projectContent', [types.params.add, types.params.delete, types.params.resetTmp, types.params.deleteTmp, types.params.updateTmp]),
async paramAliasChange () {
await this.updateTmpParam({ paramsSet: { alias: this.paramAlias, desc: '' } })
},
async AddParams () {
if (typeof this.tmpParam !== 'undefined') {
if (typeof this.tmpParam.recording !== 'undefined' || typeof this.tmpParam.stimulation !== 'undefined') {
if (typeof this.tmpParam.alias === 'undefined') {
await this.updateTmpParam({ paramsSet: { alias: getUniqueID() } })
}
await this.updateTmpParam({ paramsSet: { id: getUniqueID() } })
if (!this.recordingCheck) {
await this.deleteTmpParam({ key: 'recording' })
}
if (!this.stimulationCheck) {
await this.deleteTmpParam({ key: 'stimulation' })
}
await this.addParam({ id: getUniqueID(), paramsSet: this.tmpParam })
await this.resetTmpParam()
this.reset()
}
}
this.$emit('updateParentView')
},
async Cancel () {
await this.resetTmpParam()
this.reset()
},
reset () {
this.paramAlias = ''
this.recordingCheck = false
this.stimulationCheck = false
},
printTmpParam: function () {
console.log(this.tmpParam)
},
},
mounted () {
},
destroyed () {
},
}
</script>
+215
View File
@@ -0,0 +1,215 @@
<template>
<div id="Task">
<h3> {{ 'Task: '.concat(String(taskNum)) }} </h3>
<br/>
<p> {{ 'Time settings' }} </p>
<div slot="body">
<va-input
v-model="maxCycle"
:label="$t('Max cycle')"
:readonly="TimeSettingDone"
/>
Start time
<va-checkbox v-model="startImmediatelyCheck" :label="'Right Now'"/>
<VueCtkDateTimePicker v-model="startTimeStringFormat" v-show="!startImmediatelyCheck" :no-button-now=true label='Pick date and time' :disabled="TimeSettingDone" :format="'YYYY-MM-DDTHH:mm:ss'"/>
<br/>
<va-input
v-model="duration"
:label="$t('Duration')"
:readonly="TimeSettingDone"
/>
<va-button @click="SetTaskInit"> Next </va-button>
</div>
<div v-if="TimeSettingDone">
Connected Devices
<va-button v-for="(deviceID, index) in availableDeviceIDs" :key="index" @click="toggleMappingModal(index)">
<!-- {{ getDeviceByID(deviceID).device_name }} -->
{{ 'Neulive' }}
<device-and-condition-mapping :ref="'condition_mapping'" :taskID="taskID" :deviceID="deviceID" :deviceName="getDeviceByID(deviceID).device_name"/>
</va-button>
</div>
<div v-if="TimeSettingDone">
Condition settings
<va-button id='conditionSetting' @click="toggleConditionModal(tmpConditionID, -1)">
+
<condition-window :ref="'new_condition'" :conditionID="tmpConditionID" @updateParentView="updateView"/>
</va-button>
<br/>
<va-button v-for="(value, key, index) in allConditions" :key="key" @click="toggleConditionModal(key, index)">
{{ value.alias }}
<condition-window :ref="'exist_condition'" :conditionID="key" :conditionName="value.alias"/>
</va-button>
</div>
<div v-if="TimeSettingDone">
Parameters settings
<va-button id='paramSetting' @click="toggleParamModal()">
+
<neulive-parameter-window :ref="'parameter_window'" @updateParentView="updateView"/>
</va-button>
</div>
<div
v-for="(param, key) in allParams"
:key="key"
>
<va-list-label :key="key"> {{ processed_param(param) }} </va-list-label>
<!-- <va-icon
name="ion ion-md-close"
color="info"
class="ml-2 pa-1 shrink"
style="cursor: pointer;"
@click.native="removeParamButton(key)"
/> -->
</div>
</div>
</template>
<script>
import { mapActions, mapGetters } from 'vuex'
import types from '@/store/modules/project/content/types'
import NeuliveParameterWindow from './NeuliveParameterWindow'
import ConditionWindow from './ConditionWindow'
import DeviceAndConditionMapping from './DeviceAndConditionMapping'
import { getUniqueID } from '@/data/tool'
import VueCtkDateTimePicker from 'vue-ctk-date-time-picker'
import 'vue-ctk-date-time-picker/dist/vue-ctk-date-time-picker.css'
export default {
name: 'Task',
components: {
NeuliveParameterWindow,
DeviceAndConditionMapping,
ConditionWindow,
VueCtkDateTimePicker,
},
computed: {
...mapGetters('projectContent', {
allTasks: types.tasks.getAll,
}),
...mapGetters('projectContent', {
availableDeviceIDs: types.devices.getAllAvaliable,
getDeviceByID: types.devices.getByID,
allConditions: types.devices.getAllConditions,
}),
...mapGetters('projectContent', {
allParams: types.params.getAll,
tmpParam: types.params.getTmp,
}),
},
props: {
taskID: {
type: String,
required: true,
},
taskNum: {
type: Number,
},
},
async created () {
},
data () {
return {
maxCycle: 1,
startTimeStringFormat: '',
startTime: 0,
startImmediatelyCheck: false,
duration: '',
TimeSettingDone: false,
showParamModal: false,
tmpConditionID: null,
}
},
methods: {
...mapActions('projectContent', [types.tasks.update, types.tasks.setInfo]),
...mapActions('projectContent', [types.devices.add]),
...mapActions('projectContent', [types.params.add, types.params.delete, types.params.resetTmp, types.params.deleteTmp, types.params.updateTmp]),
toggleMappingModal (index) {
this.$refs.condition_mapping[index].showModal = true
},
toggleConditionModal (key, index) {
if (index === -1) {
this.tmpConditionID = getUniqueID()
this.$refs.new_condition.showModal = true
this.$refs.new_condition.isTmp = true
} else {
var oldConditions = []
for (const [_key, _value] of Object.entries(this.allConditions[key])) {
if (_key !== 'alias') {
var condition = Object.assign({}, _value)
condition.id = _key
oldConditions.push(condition)
}
}
this.$refs.exist_condition[index].conditions = oldConditions
this.$refs.exist_condition[index].showModal = true
}
},
toggleParamModal () {
this.$refs.parameter_window.showModal = true
},
pageToast: function (mes) {
this.showToast(
mes,
{
icon: 'fa-bell',
position: 'bottom-right',
duration: 4000,
},
)
},
async SetDuration () {
const dateTime = new Date(this.startTimeStringFormat).getTime()
this.startTime = Math.floor(dateTime / 1000)
if (this.isNumeric(this.startTime) && this.isNumeric(this.duration) && (this.duration > 0)) {
this.TimeSettingDone = true
var conditionID = getUniqueID()
var randomID = getUniqueID()
if (this.startImmediatelyCheck) {
this.startTime = 0
}
await this.setInfoTask({ taskID: this.taskID, infos: { conditions: { [conditionID]: { time: { absolute: { equal: this.startTime } } } }, actions: { [randomID]: { desc: 'task status running', condition: [conditionID], content: { '-1': 'start' } } } } })
conditionID = getUniqueID()
randomID = getUniqueID()
await this.setInfoTask({ taskID: this.taskID, infos: { conditions: { [conditionID]: { time: { relative: { equal: this.duration } } } }, actions: { [randomID]: { desc: 'task status done add cycle', condition: [conditionID], content: { '-1': 'done' } } } } })
} else {
this.pageToast('Please set start and end time correctly')
}
},
async SetTaskInit () {
await this.setInfoTask({ taskID: this.taskID, infos: { max_cycle: this.maxCycle } })
await this.SetDuration()
console.log(this.allTasks)
},
async removeParamButton (key) {
if (Object.keys(this.allParams).length > 1) {
await this.deleteParam({ id: key })
// this.$forceUpdate()
} else {
this.pageToast('[Notice] need to have at least one param setting')
}
},
updateView () {
this.$forceUpdate()
},
processed_param (param) {
const _param = param.paramsSet.alias.concat(': ', JSON.stringify(param.paramsSet))
return _param
},
isNumeric: function (n) {
return !isNaN(parseFloat(n)) && isFinite(n)
},
},
async mounted () {
},
destroyed () {
},
}
</script>
<style lang="scss">
</style>
+101
View File
@@ -0,0 +1,101 @@
<template>
<div id="ProjectContent">
<div class="tasks">
<va-button class="" color="primary" target="_blank" @click="AddTask()" small>
ADD TASK
</va-button>
<va-card stripe='info' :title="$t('AllTasks')" class='flex md12 xl4 xs12 sm12'>
<task v-for="(task, key, index) in allTasks" :key="key" :taskID="key" :taskNum="index+1"/>
</va-card>
</div>
<va-button @click="generateJson"> Generate Json </va-button>
</div>
</template>
<script>
import Task from './items/Task.vue'
import { mapActions, mapGetters } from 'vuex'
import types from '@/store/modules/project/content/types'
import { getUniqueID, getDefaultInstruction } from '@/data/tool'
export default {
name: 'ProjectContent',
components: {
Task,
},
computed: {
...mapGetters('projectContent', {
allTasks: types.tasks.getAll,
}),
...mapGetters('projectContent', {
allDevices: types.devices.getAll,
availableDeviceIDs: types.devices.getAllAvaliable,
}),
...mapGetters('projectContent', {
allParams: types.params.getAll,
}),
},
async created () {
await this.initAll()
},
data () {
return {
devices: [],
}
},
methods: {
...mapActions('projectContent', [types.tasks.init, types.tasks.add]),
...mapActions('projectContent', [types.devices.init]),
...mapActions('projectContent', [types.params.init]),
async initAll () {
await this.initTask({ id: getUniqueID(), desc: 'task description', instructions: getDefaultInstruction() })
await this.initDevice({ availableDevice: ['4'], deviceInfo: { 4: { battery: 0, device_name: '', device_address: [], device_version: '', library_name: '', library_version: '', serial_number: [], status: '', isSync: false, isStimulate: false, parent: '' } } })
await this.initParam({ id: getUniqueID(), paramsSet: { alias: 'default', desc: '', recording: { ADC_CLOCK: 200, AMP_GAIN: 0, RECORDING_CH: 0 } } })
},
async AddTask () {
await this.initAll()
this.$forceUpdate()
},
generateJson () {
var _json = { project: { desc: 'project description', available_device: this.availableDeviceIDs, tasks: {} } }
for (const [taskID, task] of Object.entries(this.allTasks)) {
_json.project.tasks[taskID] = { desc: task.desc, devices: {}, events: {}, triggers: {}, parameter_sets: {}, instructions: {}, actions: {}, conditions: {} }
_json.project.tasks[taskID].start = 'timestamp'
_json.project.tasks[taskID].status = 'prepare'
_json.project.tasks[taskID].max_cycle = 1
_json.project.tasks[taskID].cycle = 0
_json.project.tasks[taskID].devices = this.allDevices
for (const [paramID, param] of Object.entries(this.allParams)) {
_json.project.tasks[taskID].parameter_sets[paramID] = param.paramsSet
}
_json.project.tasks[taskID].instructions = task.instructions
_json.project.tasks[taskID].actions = task.actions
_json.project.tasks[taskID].conditions = task.conditions
}
console.log(_json)
},
pageToast: function (mes) {
this.showToast(
mes,
{
icon: 'fa-bell',
position: 'bottom-right',
duration: 4000,
},
)
},
},
watch: {
},
async mounted () {
},
destroyed () {
},
}
</script>
<style lang="scss">
</style>
@@ -1,5 +1,5 @@
<template>
<div class="project-content">
<div class="task-content">
<va-modal
v-model="showShutdownModal"
@@ -24,11 +24,11 @@
<div v-if="showDeviceSetting" class="flex md12 xl4 xs12 sm12 area-style">
<div class="row">
<div class="flex sm12 xl12 md12 xs12">
<project-devices :ref="'devices_ref'" @add="addDevice($event)" @remove="removeDevice($event)" @refreshSetting="refreshChartSetting($event)" class="pa-0" />
</div>
<div class="flex sm12 xl12 md12 xs12">
<project-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-formula :ref="'formula_ref'" @add="addFormula($event)" @remove="removeFormula($event)" class="pa-0" />
</div> -->
</div>
</div>
@@ -44,19 +44,19 @@
<va-icon name="fa fa-gears mr-3" color="primary"/>
<h5 class="mt-0 mb-0">CONTROL</h5>
</template>
<va-button class="" v-if="!showDeviceSetting" color="primary" target="_blank" @click="showDeviceSettingClick()" small>
<va-button class="no-dark-style-va-button" v-if="!showDeviceSetting" color="primary" target="_blank" @click="showDeviceSettingClick()" small>
SHOW DEVICES
</va-button>
<va-button class="" v-if="showDeviceSetting" color="primary" target="_blank" @click="hideDeviceSettingClick()" small>
<va-button class="no-dark-style-va-button" v-if="showDeviceSetting" color="primary" target="_blank" @click="hideDeviceSettingClick()" small>
HIDE DEVICES
</va-button>
<va-button class="" color="success" target="_blank" @click="startAllClick()" small>
START ALL
</va-button>
<va-button class="" color="danger" target="_blank" @click="stopAllClick()" small>
<va-button class="no-dark-style-va-button" color="danger" target="_blank" @click="stopAllClick()" small>
STOP ALL
</va-button>
<va-button class="" color="primary" target="_blank" @click.stop="addChart()" small>
<va-button class="no-dark-style-va-button" color="primary" target="_blank" @click.stop="addChart()" small>
ADD CHART
</va-button>
</va-card>
@@ -94,25 +94,26 @@
</template>
<script>
import { dataStreamBuffer } from '../../../data/project/DataStreamBuffer'
import { chartData } from '../../../data/project/ChartsManagement'
import { projectInfo } from '../../../data/project/ProjectInfo'
import { dataStreamBuffer } from '../../../data/task/DataStreamBuffer'
import { chartData } from '../../../data/task/ChartsManagement'
import { taskInfo } from '../../../data/task/TaskInfo'
import CanvasChart from './chart/CanvasChart'
import ProjectDevices from './controller/ProjectDevices'
import ProjectFormula from './formula/ProjectFormula'
import TaskDevices from './controller/TaskDevices'
// import api from '../../../data/api'
// import TaskFormula from './formula/TaskFormula'
// TODO change chart data tag format
export default {
name: 'ProjectContent',
name: 'TaskContent',
components: {
CanvasChart,
ProjectDevices,
ProjectFormula,
},
async created () {
await projectInfo.updateProjectInfo(this.$route.params.projectID)
TaskDevices,
// TaskFormula,
},
// async created () {
// await taskInfo.updateTaskInfo(this.$route.params.taskID)
// },
data () {
return {
// modal
@@ -124,27 +125,74 @@ export default {
chartDataAll: chartData.getAllChartsData(),
// chart refresh key
chartKey: 0,
chartNumber: projectInfo.getProjectInfo().chartList.length,
chartNumber: taskInfo.getTaskInfo().chartList.length,
selectChartID: null,
showDeviceSetting: true,
chartAreaClass: ['flex', 'xs12', 'sm12', 'md12', 'xl8', 'pa-0'],
deviceList: {},
}
},
mqtt: {
async '+/get_device_info_all/+' (data, topic) {
await projectInfo.deviceInfo(String.fromCharCode.apply(null, data))
await taskInfo.deviceInfo(String.fromCharCode.apply(null, data))
this.refreshDevicesWindow()
},
async '+/get_device_info/+' (data, topic) {
await projectInfo.deviceInfo(String.fromCharCode.apply(null, data))
await taskInfo.deviceInfo(String.fromCharCode.apply(null, data))
this.refreshDevicesWindow()
},
async '+/device_parameter/+' (data, topic) {
await projectInfo.deviceParameter(String.fromCharCode.apply(null, data))
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()
},
async '+/hardware_device/+' (data, topic) {
await projectInfo.deviceInfo(String.fromCharCode.apply(null, data))
await taskInfo.deviceInfo(String.fromCharCode.apply(null, data))
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()
}
@@ -152,19 +200,20 @@ export default {
// listen datastream [ topic: controllerID/data_server/device_data_stream/deviceID/channel ]
async '+/data_server/device_data_stream/+/+' (data, topic) {
const topicSplit = topic.split('/')
if (!projectInfo.getDeviceInfoByRawID(parseInt(topicSplit[3])).info.isSync) {
projectInfo.deviceStart(parseInt(topicSplit[3]))
chartData.defaultChartGenerator(projectInfo.getDeviceIDByRaw(parseInt(topicSplit[3])), null, 'device')
if (!taskInfo.getDeviceInfoByRawID(parseInt(topicSplit[3])).info.isSync) {
if (chartData.defaultChartGenerator(taskInfo.getDeviceIDByRaw(parseInt(topicSplit[3])), null, 'device')) {
taskInfo.deviceStart(parseInt(topicSplit[3]))
}
}
dataStreamBuffer.into(String.fromCharCode.apply(null, data), parseInt(topicSplit[3]), (parseInt(topicSplit[4]) + 1))
},
'+/device_save_path/+' (data, topic) {
projectInfo.deviceSavePath(String.fromCharCode.apply(null, data))
console.log(projectInfo.getProjectInfo())
taskInfo.deviceSavePath(String.fromCharCode.apply(null, data))
console.log(taskInfo.getTaskInfo())
},
'+/device_save_path_set/+' (data, topic) {
projectInfo.deviceSavePath(String.fromCharCode.apply(null, data))
console.log(projectInfo.getProjectInfo())
taskInfo.deviceSavePath(String.fromCharCode.apply(null, data))
console.log(taskInfo.getTaskInfo())
},
async '+/broadcast' (data, topic) {
const mes = String.fromCharCode.apply(null, data).split(':')
@@ -173,40 +222,45 @@ export default {
case 'state':
switch (mes[1]) {
case 'device_available':
this.mqttPub(projectInfo.getProjectInfo().controllerID + '_user', JSON.stringify({
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'hardware_device/0',
}))
break
}
break
case 'disconnected':
projectInfo.deviceDisconnected(mes[1])
taskInfo.deviceDisconnected(mes[1])
break
case 'connected':
this.mqttPub(projectInfo.getProjectInfo().controllerID + '_user', JSON.stringify({
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'get_device_info/0',
device: parseInt(mes[1]),
}))
projectInfo.deviceConnected(mes[1])
taskInfo.deviceConnected(mes[1])
break
case 'shutdown':
projectInfo.controllerShutdown()
taskInfo.controllerShutdown()
this.showShutdownModal = true
break
case 'start':
projectInfo.deviceStart(parseInt(mes[1]))
taskInfo.deviceStart(parseInt(mes[1]))
break
case 'stop':
if (mes[1] === 'all') {
return false
}
projectInfo.deviceStop(parseInt(mes[1]))
taskInfo.deviceStop(parseInt(mes[1]))
break
case 'device_timeout':
this.pageToast('The device [' + projectInfo.getDeviceIDByRaw(parseInt(mes[1])) + '] is timeout, please check its status or parameters.')
this.pageToast('The device [' + taskInfo.getDeviceIDByRaw(parseInt(mes[1])) + '] is timeout, please check its status or parameters.')
break
case 'device_mission_done':
this.pageToast('The device [' + projectInfo.getDeviceIDByRaw(parseInt(mes[1])) + '] mission is done.')
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_instruction/0',
device: parseInt(mes[1]),
instruction: 'interrupt',
}))
this.pageToast('The device [' + taskInfo.getDeviceIDByRaw(parseInt(mes[1])) + '] mission is done.')
break
default:
break
@@ -230,9 +284,10 @@ export default {
this.mqttSub(id + '/get_device_info_all/+')
this.mqttSub(id + '/get_device_info/+')
this.mqttSub(id + '/device_parameter/+')
this.mqttSub(id + '/device_parameter_value/+')
},
pageMqttUnSub: function (id) {
for (const device in projectInfo.getProjectInfo().deviceList) {
for (const device in taskInfo.getTaskInfo().deviceList) {
this.mqttUnSub(id + '/data_server/device_data_stream/' + device + '/+')
}
this.mqttUnSub(id + '/hardware_device/+')
@@ -240,16 +295,25 @@ export default {
this.mqttUnSub(id + '/get_device_info_all/+')
this.mqttUnSub(id + '/get_device_info/+')
this.mqttUnSub(id + '/device_parameter/+')
this.mqttUnSub(id + '/device_parameter_value/+')
},
pageInit: async function () {
if (await this.$refs.devices_ref != null) {
await this.$refs.devices_ref.loadingStart()
}
this.mqttPub(projectInfo.getProjectInfo().controllerID + '_user', JSON.stringify({
// 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',
// }))
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'hardware_device/0',
}))
await projectInfo.updateChartInfo()
this.chartNumber = projectInfo.getProjectInfo().chartNumber
await taskInfo.updateChartInfo()
this.chartNumber = taskInfo.getTaskInfo().chartNumber
},
pageToast: function (mes) {
this.showToast(
@@ -268,9 +332,13 @@ export default {
}
},
refreshDevicesWindow: function () {
// console.log(taskInfo.getTaskInfo())
if (this.$refs.devices_ref != null) {
this.$refs.devices_ref.refresh()
}
// api.task.update({
// device_config: taskInfo.getTaskInfo().deviceList,
// })
},
addChart: async function () {
const defaultID = {}
@@ -366,8 +434,7 @@ export default {
this.chartAreaClass[3] = 'md12'
this.chartAreaClass[4] = 'xl12'
},
addDevice: async function (deviceID) {
this.mqttSub(projectInfo.getProjectInfo().controllerID + '/data_server/device_data_stream/' + projectInfo.getRawDeviceID(deviceID) + '/+')
addMappingChart: async function (deviceID) {
const chart = await this.addChart()
await this.$nextTick(async () => {
chartData.getAllChartsData()[chart].mappingID = deviceID
@@ -377,13 +444,23 @@ export default {
})
}
})
if (projectInfo.getDeviceInfo(deviceID).info.isSync) {
return chart
},
addDevice: async function (deviceID) {
this.mqttSub(taskInfo.getTaskInfo().controllerID + '/data_server/device_data_stream/' + taskInfo.getRawDeviceID(deviceID) + '/+')
const chart = 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(projectInfo.getProjectInfo().controllerID + '/data_server/device_data_stream/' + projectInfo.getRawDeviceID(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) {
dataStreamBuffer.removeByChart(chart)
@@ -413,33 +490,69 @@ export default {
}
this.pageToast('The formula [' + formulaID + '] has been removed.')
},
startAllClick: function () {
projectInfo.getDeviceListRegister().forEach(device => {
chartData.defaultChartGenerator(device.id, null, 'device')
if (!projectInfo.getDeviceInfo(device.id).info.isSync) {
this.mqttPub(projectInfo.getProjectInfo().controllerID + '_user', JSON.stringify({
header: 'device_instruction/0',
device: projectInfo.getRawDeviceID(device.id),
instruction: 'start',
}))
device.isSync = true
startAllClick: async function () {
for (const device of taskInfo.getDeviceListRegister()) {
if (this.$refs.devices_ref === undefined) {
this.startDevice(device)
} else {
await this.$refs.devices_ref.$refs.pdlist_ref.start(device)
}
})
}
this.refreshDevicesWindow()
this.pageToast('The all devices have been started')
},
stopAllClick: function () {
dataStreamBuffer.removeAll()
projectInfo.getDeviceListRegister().forEach(device => {
if (projectInfo.getDeviceInfo(device.id).info.isSync) {
this.mqttPub(projectInfo.getProjectInfo().controllerID + '_user', JSON.stringify({
startDevice: async function (device) {
chartData.defaultChartGenerator(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: projectInfo.getRawDeviceID(device.id),
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))
}
},
stopAllClick: function () {
for (const device of taskInfo.getDeviceListRegister()) {
if (this.$refs.devices_ref === undefined) {
this.stopDevice(device)
} else {
this.$refs.devices_ref.stopDevice(device)
}
}
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.isSync = false
})
this.pageToast('The all devices have been stopped')
device.stopping = true
}
},
exit: function () {
this.$router.push({
@@ -450,16 +563,16 @@ export default {
watch: {
},
async mounted () {
// await projectInfo.updateProjectInfo(this.$route.params.projectID)
console.log(projectInfo.getProjectInfo())
this.deviceList = await taskInfo.updateTaskInfo(this.$route.params.taskID)
console.log(taskInfo.getTaskInfo())
// this.screenHeight = document.documentElement.clientHeight
this.pageMqttSub(projectInfo.getProjectInfo().controllerID)
this.pageMqttSub(taskInfo.getTaskInfo().controllerID)
console.log(taskInfo.getTaskInfo().controllerID)
await this.pageInit()
// this.chartNumber = projectInfo.getProjectInfo().chartNumber
// this.chartNumber = taskInfo.getTaskInfo().chartNumber
this.dataRefreshTimer = setInterval(this.refreshData, 700)
this.dataRefreshTimer = setInterval(this.refreshData, 100)
// const _this = this
// window.onresize = function () { // define the event of window size changing
@@ -468,12 +581,12 @@ export default {
// }
},
destroyed () {
projectInfo.destroyed()
taskInfo.destroyed()
for (const chart in chartData.getAllChartsData()) {
this.removeChart(chart)
}
clearInterval(this.dataRefreshTimer)
this.pageMqttUnSub(projectInfo.getProjectInfo().controllerID)
this.pageMqttUnSub(taskInfo.getTaskInfo().controllerID)
},
}
@@ -491,4 +604,10 @@ export default {
overflow-x: hidden;
}
}
.no-dark-style-va-button {
&:focus {
filter: brightness(100%);
}
}
</style>
@@ -30,34 +30,73 @@
<div v-else :style="'width: '+ cardwidth + '; height: ' + cardheight + ';'" >
<canvas-chart-setting></canvas-chart-setting>
</div>
<div class="flex row xs12 md12 xl12 sm12" style="text-align: center;" >
<div>
<va-select
class="xs6 md6 xl6 sm6"
<div class="flex row">
<div class="flex row xs12 md12 xl12 sm12" style="text-align: center;" >
<!-- <va-select
class="ma-1"
:on-change="mappingSelectChange()"
small
:label="'MAPPING'"
v-model="mappingSelect"
textBy="name"
:options="mappingOptions"
/>
</div>
<div>
<va-button small @click="init()">INIT</va-button>
/> -->
<va-input
v-if="data.chartXMode === 'time'"
class="ma-1"
@keyup.enter="timeIntervalChange(timeIntervalInput)"
@blur="timeIntervalChange(timeIntervalInput)"
v-model="timeIntervalInput"
:label="'time-interval'"
>
<p slot="append" style="margin-right: 0;" small>
ms
</p>
</va-input>
<va-input
v-if="data.chartXMode === 'value'"
class="ma-1"
@keyup.enter="xIntervalChange(xIntervalInput)"
@blur="xIntervalChange(xIntervalInput)"
v-model="xIntervalInput"
:label="'x-interval'"
>
</va-input>
<va-input
class="ma-1"
@keyup.enter="yIntervalChange(yIntervalInput)"
@blur="yIntervalChange(yIntervalInput)"
v-model="yIntervalInput"
:label="'y-interval'"
>
</va-input>
<va-input
v-if="data.chartDevice === 'neulive'"
class="ma-1"
@keyup.enter="threeAxisIntervalChange(threeAxisIntervalInput)"
@blur="threeAxisIntervalChange(threeAxisIntervalInput)"
v-model="threeAxisIntervalInput"
:label="'3axis-interval'"
>
</va-input>
<va-button class="no-dark-style-va-button" small @click="init()">INIT</va-button>
<va-button small color="dark" @click="remove()">REMOVE</va-button>
</div>
<!-- <div class="xs2 md2 xl2 sm2" style="text-align: center;" >
<va-button class="no-dark-style-va-button" small @click="init()">INIT</va-button>
<va-button small color="dark" @click="remove()">REMOVE</va-button>
</div> -->
</div>
</va-card>
</div>
</template>
<script>
// import { InitChartsData, getChartsData } from '../../../../../data/project/ChartsManagement'
// import { InitChartsData, getChartsData } from '../../../../../data/task/ChartsManagement'
import CanvasChartSetting from './CanvasChartSetting'
import CanvasChartSource from './CanvasChartSource'
import { projectInfo } from '../../../../data/project/ProjectInfo'
import { chartData } from '../../../../data/project/ChartsManagement'
import { taskInfo } from '../../../../data/task/TaskInfo'
import { chartData } from '../../../../data/task/ChartsManagement'
export default {
name: 'CanvasChart',
@@ -95,9 +134,13 @@ export default {
data: chartData.getChartsData(this.chartID),
resizeTimer: null,
mappingSelect: '',
mappingOptions: projectInfo.getMappingList(),
mappingOptions: taskInfo.getMappingList(),
nameCard: chartData.getAllChartsData()[this.chartID].cardName,
initDone: false,
timeIntervalInput: '',
threeAxisIntervalInput: '',
xIntervalInput: '',
yIntervalInput: '',
}
},
computed: {
@@ -105,6 +148,34 @@ export default {
watch: {
},
methods: {
timeIntervalChange: function (val) {
chartData.getAllChartsData()[this.chartID].xAxis.forEach(x => {
if (x.type === 'time') {
x.interval = val * 1000
}
})
},
xIntervalChange: function (val) {
chartData.getAllChartsData()[this.chartID].xAxis.forEach(x => {
if (x.type === 'value') {
x.interval = val * 1
}
})
},
yIntervalChange: function (val) {
chartData.getAllChartsData()[this.chartID].yAxis.forEach(y => {
if (parseInt(y.channel) <= 255) {
y.interval = val * 1
}
})
},
threeAxisIntervalChange: function (val) {
chartData.getAllChartsData()[this.chartID].yAxis.forEach(y => {
if (parseInt(y.channel) >= 255) {
y.interval = val * 1
}
})
},
init: function () {
this.mappingSelect = ''
this.nameCard = 'chart' + this.chartID
@@ -131,7 +202,7 @@ export default {
refreshMappingSelect: async function () {
this.setMappingSelect(chartData.getAllChartsData()[this.chartID].mappingID)
if (chartData.getAllChartsData()[this.chartID].mappingID !== -1 && chartData.getAllChartsData()[this.chartID].mappingID != null) {
projectInfo.getMappingList().forEach(item => {
taskInfo.getMappingList().forEach(item => {
if (item.id === chartData.getAllChartsData()[this.chartID].mappingID) {
this.setChartName(item.name)
}
@@ -169,3 +240,11 @@ export default {
}
</script>
<style lang="scss">
.no-dark-style-va-button {
&:focus {
filter: brightness(100%);
}
}
</style>
@@ -74,10 +74,10 @@
</template>
<script>
// import { getChartsData } from '../../../../../data/project/ChartsManagement'
// import { getChartsData } from '../../../../../data/task/ChartsManagement'
import { projectInfo } from '../../../../data/project/ProjectInfo'
import { chartData } from '../../../../data/project/ChartsManagement'
import { taskInfo } from '../../../../data/task/TaskInfo'
import { chartData } from '../../../../data/task/ChartsManagement'
export default {
name: 'canvas-chart-source',
@@ -112,7 +112,7 @@ export default {
channelSelectDisableY: true,
deviceSelectX: '',
deviceSelectY: '',
deviceOptions: projectInfo.getDeviceList(),
deviceOptions: taskInfo.getDeviceList(),
sourceAddStatus: true,
}
},
@@ -123,10 +123,10 @@ export default {
deviceSelectX: function () {
const channelOptions = []
// console.log(val)
if (projectInfo.getDeviceInfo(this.deviceSelectX.id) == null) {
if (taskInfo.getDeviceInfo(this.deviceSelectX.id) == null) {
this.channelSelectDisableX = true
} else if (projectInfo.getDeviceInfo(this.deviceSelectX.id).info.library_name.indexOf('Neulive') >= 0) {
const channelSet = projectInfo.getDeviceInfo(this.deviceSelectX.id).parameterSet.RECORDING_CH.toString(2).split('').reverse()
} else if (taskInfo.getDeviceInfo(this.deviceSelectX.id).info.library_name.indexOf('Neulive') >= 0) {
const channelSet = taskInfo.getDeviceInfo(this.deviceSelectX.id).parameterSet.RECORDING_CH.toString(2).split('').reverse()
channelSet.forEach((element, index) => {
if (parseInt(element) > 0) {
channelOptions.push({
@@ -136,9 +136,35 @@ export default {
// console.log(index, element)
}
})
const axisChannelSet = taskInfo.getDeviceInfo(this.deviceSelectX.id).parameterSet.AXIS_CH.toString(2).split('').reverse()
axisChannelSet.forEach((element, index) => {
if (parseInt(element) === 1) {
if (index === 0) {
channelOptions.push({
id: 257,
channel: 'X-AXIS',
})
} else if (index === 1) {
channelOptions.push({
id: 258,
channel: 'Y-AXIS',
})
} else if (index === 2) {
channelOptions.push({
id: 259,
channel: 'Z-AXIS',
})
} else if (index === 3) {
channelOptions.push({
id: 260,
channel: 'M-AXIS',
})
}
}
})
this.channelSelectDisableX = false
} else if (projectInfo.getDeviceInfo(this.deviceSelectX.id).info.library_name.indexOf('Elite') >= 0) {
const channelSet = projectInfo.getDeviceInfo(this.deviceSelectX.id).parameterSet.CHANNEL_LABEL
} else if (taskInfo.getDeviceInfo(this.deviceSelectX.id).info.library_name.indexOf('Elite') >= 0) {
const channelSet = taskInfo.getDeviceInfo(this.deviceSelectX.id).parameterSet.CHANNEL_LABEL
// console.log(channelSet)
channelSet.forEach((element, index) => {
channelOptions.push({
@@ -158,10 +184,10 @@ export default {
deviceSelectY: function () {
const channelOptions = []
// console.log(val)
if (projectInfo.getDeviceInfo(this.deviceSelectY.id) == null) {
if (taskInfo.getDeviceInfo(this.deviceSelectY.id) == null) {
this.channelSelectDisableY = true
} else if (projectInfo.getDeviceInfo(this.deviceSelectY.id).info.library_name.indexOf('Neulive') >= 0) {
const channelSet = projectInfo.getDeviceInfo(this.deviceSelectY.id).parameterSet.RECORDING_CH.toString(2).split('').reverse()
} else if (taskInfo.getDeviceInfo(this.deviceSelectY.id).info.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) => {
if (parseInt(element) > 0) {
@@ -172,9 +198,35 @@ export default {
// console.log(index, element)
}
})
const axisChannelSet = taskInfo.getDeviceInfo(this.deviceSelectY.id).parameterSet.AXIS_CH.toString(2).split('').reverse()
axisChannelSet.forEach((element, index) => {
if (parseInt(element) === 1) {
if (index === 0) {
channelOptions.push({
id: 257,
channel: 'X-AXIS',
})
} else if (index === 1) {
channelOptions.push({
id: 258,
channel: 'Y-AXIS',
})
} else if (index === 2) {
channelOptions.push({
id: 259,
channel: 'Z-AXIS',
})
} else if (index === 3) {
channelOptions.push({
id: 260,
channel: 'M-AXIS',
})
}
}
})
this.channelSelectDisableY = false
} else if (projectInfo.getDeviceInfo(this.deviceSelectY.id).info.library_name.indexOf('Elite') >= 0) {
const channelSet = projectInfo.getDeviceInfo(this.deviceSelectY.id).parameterSet.CHANNEL_LABEL
} else if (taskInfo.getDeviceInfo(this.deviceSelectY.id).info.library_name.indexOf('Elite') >= 0) {
const channelSet = taskInfo.getDeviceInfo(this.deviceSelectY.id).parameterSet.CHANNEL_LABEL
console.log(channelSet)
channelSet.forEach((element, index) => {
channelOptions.push({
@@ -0,0 +1,208 @@
<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">
<span slot="header" >
<va-item :key="device.id" class="pa-0 ma-0"
>
<va-icon
name="ion ion-md-close"
color="danger"
class="ml-0 mr-3 pa-0 shrink"
style="cursor: pointer;"
@click.native.stop="removeCheck(device)"
/>
<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">
<va-item-label>
{{ device.name }}
</va-item-label>
<va-item-label caption>
{{ device.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.type == 'Neulive' && !device.isSync && !device.isStimulate) || (device.type == 'Elite' && !device.isSync)" class="px-2 py-0 mr-0" color="success" small>START</va-button>
<va-button @click.stop="stop(device)" v-if="(device.type == 'Neulive' && (device.isSync || device.isStimulate)) || (device.type == 'Elite' && device.isSync)" :disabled="device.stopping" class="px-2 py-0 mr-0" color="danger" small>STOP</va-button>
<va-button id="detectButton" @click.stop="detect(device)" v-if="device.type == 'Elite'" color="primary" class="px-2 py-0 mr-0" small>DETECT</va-button>
<va-button @click.stop="record(device)" v-if="device.type == 'Neulive' && !device.isSync" color="primary" class="px-2 py-0 mr-0 no-dark-style-va-button" small>RECORD</va-button>
<va-button @click.stop="stopRecord(device)" v-if="device.type == 'Neulive' && device.isSync" color="danger" class="px-2 py-0 mr-0 no-dark-style-va-button" small>STOP REC</va-button>
<va-button @click.stop="stimulate(device)" v-if="device.type == 'Neulive' && !device.isStimulate" color="warning" class="px-2 py-0 mr-0 no-dark-style-va-button" small>STIMULATE</va-button>
<va-button @click.stop="stopStimulate(device)" v-if="device.type == 'Neulive' && device.isStimulate" color="danger" class="px-2 py-0 mr-0" small>STOP STI</va-button>
<va-button @click.stop="fastSettle(device)" v-if="device.type == 'Neulive'" color="info" class="px-2 py-0 mr-0 no-dark-style-va-button" small>R</va-button>
</va-item-label>
</va-item-section>
</va-item>
</span>
<div slot="body">
<div class="mt-0 mb-0" style="height: 350px; overflow-y: scroll; overflow-x: hidden;" :key="'detail' + device.id">
<div style="text-align: center;">
<va-button @click.stop="generateChart(device)" class="pl-2 pr-2 mr-0 no-dark-style-va-button" small>GENERATE MAPPING CHART</va-button>
</div>
<div>
<file-control-window :ref="'fcwindow_ref'" :deviceID="device.id" class="pl-0 pr-0" />
</div>
<div v-if="device.type == 'Elite'">
<elite-parameter-window :ref="'epwindow_ref'" :deviceID="device.id" class="pl-0 pr-0" />
</div>
<div v-if="device.type == 'Neulive'">
<neulive-parameter-window :ref="'npwindow_ref'" :deviceID="device.id" class="pl-0 pr-0" @record="record_start(device)" @record_stop="record_stop(device)"/>
</div>
</div>
</div>
</va-collapse>
</va-accordion>
</div>
</template>
<script>
// import NeuliveParameterWindow from '../parameter/NeuliveParameterWindow'
import EliteParameterWindow from '../parameter/EliteParameterWindow'
import NeuliveParameterWindow from '../parameter/NeuliveParameterWindow'
import FileControlWindow from '../meta/FileControlWindow'
export default {
name: 'TaskDeviceList',
components: {
EliteParameterWindow,
NeuliveParameterWindow,
FileControlWindow,
},
props: {
deviceList: {
type: Array,
required: true,
},
},
data () {
return {
showDeleteModal: false,
selectDevice: null,
deviceStopping: false,
}
},
computed: {
},
methods: {
removeCheck: function (device) {
this.selectDevice = device
this.showDeleteModal = true
},
remove: function () {
this.$emit('remove', this.selectDevice)
},
start: function (device) {
this.setArchiveSettings()
// this.$emit('start', device)
setTimeout(() => {
this.$emit('start', device)
}, 500)
this.pageToast('The device ' + device.name + ' has been started.')
},
stop: function (device) {
this.$emit('stop', device)
this.pageToast('The device ' + device.name + ' has been stopped.')
},
record: function (device) {
device.stopping = false
this.setArchiveSettings()
setTimeout(() => {
this.$emit('record', device)
}, 500)
this.pageToast('The device ' + device.name + ' has been started.')
},
stopRecord: function (device) {
device.stopping = true
this.$emit('stopRecord', device)
this.pageToast('The device ' + device.name + ' has been stopped.')
},
generateChart: function (device) {
this.$emit('generate', device)
},
setArchiveSettings: function () {
this.$refs.fcwindow_ref.forEach(ref => {
ref.setArchiveSettings()
})
},
refresh: function () {
this.$nextTick(() => {
if (this.$refs.fcwindow_ref != null) {
this.$refs.fcwindow_ref.forEach(ref => {
ref.refresh()
})
}
if (this.$refs.epwindow_ref != null) {
this.$refs.epwindow_ref.forEach(ref => {
ref.refresh()
})
}
if (this.$refs.npwindow_ref != null) {
this.$refs.npwindow_ref.forEach(ref => {
ref.refresh()
})
}
})
},
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.')
},
stimulate: function (device) {
this.$emit('sti', device)
this.pageToast('The device ' + device.name + ' start stimulate.')
},
stopStimulate: function (device) {
this.$emit('sti_stop', device)
this.pageToast('The device ' + device.name + ' stop stimulate.')
},
fastSettle: function (device) {
this.$emit('fast_settle', device)
this.pageToast('The device ' + device.name + ' fast settle.')
},
recoverDetectButton () {
document.getElementById('detectButton').className += ' no-dark-style-va-button'
},
},
}
</script>
<style lang="scss">
.no-dark-style-va-button {
&:focus {
filter: brightness(100%);
}
}
</style>
@@ -0,0 +1,398 @@
<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
:ref="'pdlist_ref'"
:deviceList="deviceList"
@remove="removeDevice($event)"
@start="startDevice($event)"
@stop="stopDevice($event)"
@record="record($event)"
@stopRecord="stopRecord($event)"
@sti="sti($event)" @sti_stop="stiStop($event)"
@fast_settle="fastSettle($event)"
@generate="generateChart($event)"
@detect="detectDevice($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>
</div>
</template>
<script>
import { FulfillingBouncingCircleSpinner } from 'epic-spinners'
import TaskDeviceList from './TaskDeviceList'
import { taskInfo } from '../../../../data/task/TaskInfo'
import { chartData } from '../../../../data/task/ChartsManagement'
import { dataStreamBuffer } from '../../../../data/task/DataStreamBuffer'
import api from '@/data/api'
export default {
name: 'TaskDevices',
components: {
FulfillingBouncingCircleSpinner,
TaskDeviceList,
},
props: {
cardclass: {
type: Array,
default: function () {
return ['xs12', 'md12', 'xl12', 'sm12']
},
},
},
created () {
},
data () {
return {
deviceSelect: '',
deviceOptions: taskInfo.getDeviceListNotRegister(),
deviceList: taskInfo.getDeviceListRegister(),
state: {
LOADING: false,
},
}
},
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
// 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) {
// }
// }
// }
this.clearDevice()
console.log(this.deviceOptions)
for (let i = 4; i <= 7; i++) {
await this.addDevice(i)
}
// 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) {
await chartData.defaultChartGenerator(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',
}))
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_instruction/0',
device: taskInfo.getRawDeviceID(device.id),
instruction: 'stimulate',
}))
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: taskInfo.getRawDeviceID(device.id),
parameter: 'STIMULATING',
content: 1,
}))
taskInfo.getTaskInfo().deviceList[(taskInfo.getRawDeviceID(device.id)).toString()].parameterSet.STIMULATING = 1
device.isStimulate = true
} 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: 'start',
}))
}
device.stopping = false
device.isSync = true
this.$emit('refreshSetting')
// ### show device info
api.task.update({
device_config: taskInfo.getTaskInfo().deviceList,
})
console.log(taskInfo.getDeviceInfo(device.id))
}
},
stopDevice: async function (device) {
await 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',
}))
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_instruction/0',
device: taskInfo.getRawDeviceID(device.id),
instruction: 'stop_stimulate',
}))
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: taskInfo.getRawDeviceID(device.id),
parameter: 'STIMULATING',
content: 0,
}))
device.isStimulate = false
} 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
}
},
detectDevice: function (device) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_instruction/0',
device: taskInfo.getRawDeviceID(device.id),
instruction: 'VIS_DEVICE_DETECT',
}))
setTimeout(() => {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_instruction/0',
device: taskInfo.getRawDeviceID(device.id),
instruction: 'VIS_DEVICE_DONE',
}))
this.$refs.pdlist_ref.recoverDetectButton()
}, 5000)
},
record: async function (device) {
await chartData.defaultChartGenerator(device.id, null, 'device')
if (!taskInfo.getDeviceInfo(device.id).info.isSync) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_instruction/0',
device: taskInfo.getRawDeviceID(device.id),
instruction: 'record',
}))
device.isSync = true
device.stopping = false
this.$emit('refreshSetting')
api.task.update({
device_config: taskInfo.getTaskInfo().deviceList,
})
// ### show device info
console.log(taskInfo.getDeviceInfo(device.id))
}
},
stopRecord: function (device) {
dataStreamBuffer.removeByDevice(taskInfo.getRawDeviceID(device.id))
if (taskInfo.getDeviceInfo(device.id).info.isSync) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_instruction/0',
device: taskInfo.getRawDeviceID(device.id),
instruction: 'stop_record',
}))
}
device.isSync = false
device.stopping = true
},
sti: function (device) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_instruction/0',
device: taskInfo.getRawDeviceID(device.id),
instruction: 'stimulate',
}))
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: taskInfo.getRawDeviceID(device.id),
parameter: 'STIMULATING',
content: 1,
}))
taskInfo.getTaskInfo().deviceList[(taskInfo.getRawDeviceID(device.id)).toString()].parameterSet.STIMULATING = 1
api.task.update({
device_config: taskInfo.getTaskInfo().deviceList,
})
device.isStimulate = true
},
stiStop: function (device) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_instruction/0',
device: taskInfo.getRawDeviceID(device.id),
instruction: 'stop_stimulate',
}))
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: taskInfo.getRawDeviceID(device.id),
parameter: 'STIMULATING',
content: 0,
}))
device.isStimulate = false
},
fastSettle: function (device) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_instruction/0',
device: taskInfo.getRawDeviceID(device.id),
instruction: 'FAST_SET',
}))
},
// addDevice: async function () {
// if (this.deviceSelect.id == null) {
// return false
// }
// await taskInfo.getTaskInfo().deviceAddrList.push(taskInfo.getDeviceInfoByRawID(this.deviceSelect.id).info.device_address)
// await taskInfo.getTaskInfo().taskDeviceID.push(this.deviceSelect.id)
// const _address = this.GLOBAL.transMac(taskInfo.getDeviceInfoByRawID(this.deviceSelect.id).info.device_address)
// const pic = taskInfo.getDevicePic(taskInfo.getDeviceInfoByRawID(this.deviceSelect.id).info.library_name)
// let type = ''
// if (taskInfo.getDeviceInfoByRawID(this.deviceSelect.id).info.library_name.indexOf('Elite') >= 0) {
// type = 'Elite'
// } else if (taskInfo.getDeviceInfoByRawID(this.deviceSelect.id).info.library_name.indexOf('Neulive') >= 0) {
// type = 'Neulive'
// }
// const _device = {
// id: taskInfo.getTaskInfo().taskDeviceID.indexOf(this.deviceSelect.id),
// name: '[' + taskInfo.getTaskInfo().taskDeviceID.indexOf(this.deviceSelect.id) + '] ' + taskInfo.getDeviceInfoByRawID(this.deviceSelect.id).info.device_name,
// addr: taskInfo.getDeviceInfoByRawID(this.deviceSelect.id).info.device_address,
// address: _address,
// picture: pic,
// type: type,
// isSync: taskInfo.getDeviceInfoByRawID(this.deviceSelect.id).info.isSync,
// stopping: false,
// }
// this.deviceList.push(_device)
// this.deviceSelect = ''
// taskInfo.updateAllList()
// this.$emit('add', _device.id)
// },
addDevice: async function (selectID) {
if (selectID == null) {
return false
}
const addr = taskInfo.getDeviceInfoByRawID(selectID).info.device_address
if (addr.length === 0) {
return false
}
await taskInfo.getTaskInfo().deviceAddrList.push(taskInfo.getDeviceInfoByRawID(selectID).info.device_address)
await taskInfo.getTaskInfo().taskDeviceID.push(selectID)
const _address = this.GLOBAL.transMac(taskInfo.getDeviceInfoByRawID(selectID).info.device_address)
const pic = taskInfo.getDevicePic(taskInfo.getDeviceInfoByRawID(selectID).info.library_name)
let type = ''
if (taskInfo.getDeviceInfoByRawID(selectID).info.library_name.indexOf('Elite') >= 0) {
type = 'Elite'
} else if (taskInfo.getDeviceInfoByRawID(selectID).info.library_name.indexOf('Neulive') >= 0) {
type = 'Neulive'
}
const _device = {
id: taskInfo.getTaskInfo().taskDeviceID.indexOf(selectID),
name: '[' + taskInfo.getTaskInfo().taskDeviceID.indexOf(selectID) + '] ' + taskInfo.getDeviceInfoByRawID(selectID).info.device_name,
addr: taskInfo.getDeviceInfoByRawID(selectID).info.device_address,
address: _address,
picture: pic,
type: type,
isSync: taskInfo.getDeviceInfoByRawID(selectID).info.isSync,
isStimulate: taskInfo.getDeviceInfoByRawID(selectID).info.isStimulate,
stopping: false,
}
this.deviceList.push(_device)
this.deviceSelect = ''
taskInfo.updateAllList()
this.$emit('add', _device.id)
},
removeDevice: async function (device) {
taskInfo.getTaskInfo().deviceAddrList.forEach(addr => {
if (addr === device.addr) {
taskInfo.getTaskInfo().deviceAddrList.splice(taskInfo.getTaskInfo().deviceAddrList.indexOf(addr), 1)
}
})
taskInfo.getTaskInfo().taskDeviceID.forEach(realID => {
if (realID === device.id) {
taskInfo.getTaskInfo().taskDeviceID.splice(taskInfo.getTaskInfo().taskDeviceID.indexOf(realID), 1)
}
})
this.deviceList.splice(this.deviceList.indexOf(device), 1)
this.deviceSelect = ''
taskInfo.updateAllList()
this.$emit('remove', device.id)
},
clearDevice: async function () {
taskInfo.getTaskInfo().deviceAddrList.length = 0
taskInfo.getTaskInfo().taskDeviceID.length = 0
this.deviceList.length = 0
taskInfo.updateAllList()
},
generateChart: function (device) {
this.$emit('add', device.id)
},
setArchiveSettings: function () {
if (this.$refs.pdlist_ref != null) {
this.$refs.pdlist_ref.setArchiveSettings()
}
},
refresh: function () {
this.$nextTick(() => {
if (this.$refs.pdlist_ref != null) {
this.$refs.pdlist_ref.refresh()
}
})
},
},
async mounted () {
// this.pageMqttSub()
// for (const device in this.deviceOptions) {
// this.deviceSelect = this.deviceOptions[device]
// await this.addDevice()
// }
},
destroyed () {
this.loadingDone()
// this.pageMqttUnSub()
},
watch: {
},
}
</script>
@@ -103,11 +103,11 @@
</template>
<script>
import { projectInfo } from '../../../../data/project/ProjectInfo'
import { chartData } from '../../../../data/project/ChartsManagement'
import { taskInfo } from '../../../../data/task/TaskInfo'
import { chartData } from '../../../../data/task/ChartsManagement'
export default {
name: 'ProjectFormula',
name: 'TaskFormula',
components: {
},
props: {
@@ -136,10 +136,10 @@ export default {
isSync: false,
},
],
formulaList: projectInfo.getFormulaList(),
formulaList: taskInfo.getFormulaList(),
formulaNumber: 0,
formulaRemoveSelect: null,
deviceOptions: projectInfo.getDeviceListNoTime(),
deviceOptions: taskInfo.getDeviceListNoTime(),
}
},
mqtt: {
@@ -150,14 +150,14 @@ export default {
},
addFormula: function () {
const _formula = this.formulaSelect
if (projectInfo.getFormulaList().length === 0) {
_formula.id = projectInfo.getFormulaIDStart()
if (taskInfo.getFormulaList().length === 0) {
_formula.id = taskInfo.getFormulaIDStart()
} else {
_formula.id = projectInfo.getFormulaList()[projectInfo.getFormulaList().length - 1].id + 1
_formula.id = taskInfo.getFormulaList()[taskInfo.getFormulaList().length - 1].id + 1
}
_formula.name = '[' + _formula.id + '] ' + _formula.name
projectInfo.addFormula(_formula)
projectInfo.updateAllList()
taskInfo.addFormula(_formula)
taskInfo.updateAllList()
this.formulaNumber++
this.formulaSelect = ''
this.$emit('add', _formula.id)
@@ -167,8 +167,8 @@ export default {
this.showFormulaModal = true
},
remove: function () {
projectInfo.removeFormula(projectInfo.getFormulaList().indexOf(this.formulaRemoveSelect))
projectInfo.updateAllList()
taskInfo.removeFormula(taskInfo.getFormulaList().indexOf(this.formulaRemoveSelect))
taskInfo.updateAllList()
this.formulaNumber--
this.$emit('remove', this.formulaRemoveSelect.id)
},
@@ -0,0 +1,195 @@
<template>
<div class="flex mt-0 pt-0">
<div>
<div class="row flex sm12 xl12 md12 xs12">
<div>
<div class="flex">
<va-tree-root>
<div class="row pt-0 pb-0">
<div class="flex sm12 xl12 md12 xs12">
<va-input
@mouseup.native="fileNameChange(fileNameInput)"
@mouseleave.native="fileNameChange(fileNameInput)"
@touchend.native="fileNameChange(fileNameInput)"
@keyup.enter="fileNameChange(fileNameInput)"
v-model="fileNameInput"
:label="'FILE NAME'"
style="width: 200px;"
>
</va-input>
<va-select
:on-change="directorySelect(directory)"
:label="'DIRECTORY'"
v-model="directory"
textBy="name"
:options="directoryOptions"
noClear
style="width: 200px;"
/>
</div>
</div>
</va-tree-root>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import { taskInfo } from '../../../../data/task/TaskInfo'
import api from '../../../../data/api/index'
export default {
name: 'FileControlWindow',
components: {
},
props: {
deviceID: {
type: Number,
required: true,
},
deviceName: {
type: String,
default: 'Elite',
},
user: {
type: String,
default: 'Admin',
},
},
data () {
return {
fileNameInput: '',
directory: '',
directoryOptions: [],
deviceInfo: null,
enableSetting: false,
enableTimer: null,
}
},
mqtt: {
},
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 (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,
}))
}
}
}
}
},
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],
},
}))
}
}
}
}
},
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
} 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.fileNameChange(this.fileNameInput)
// 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
}
}
}
}
},
getCurrentTime: function () {
const now = new Date()
return [now.getFullYear(), now.getMonth() + 1, now.getDate(), now.getHours(), now.getMinutes(), now.getSeconds(), this.deviceID].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)
},
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>
@@ -214,8 +214,8 @@
<div class="row">
<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="cycleNoNumberChange(0)">
0
<va-button slot="append" class="mr-2 pa-1 shrink" small @click="cycleNoNumberChange(1)">
1
</va-button>
<va-input
@keyup.enter="cycleNoNumberChange(cycleNoNumberInput)"
@@ -235,7 +235,7 @@
class="flex sm12 xl12 md12 xs12"
value-visible
v-model="cycleNoNumber"
:min="0"
:min="1"
:max="249"
/>
</div>
@@ -718,8 +718,8 @@
<div class="row">
<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="cycleNoNumberChange(0)">
0
<va-button slot="append" class="mr-2 pa-1 shrink" small @click="cycleNoNumberChange(1)">
1
</va-button>
<va-input
@keyup.enter="cycleNoNumberChange(cycleNoNumberInput)"
@@ -739,7 +739,7 @@
class="flex sm12 xl12 md12 xs12"
value-visible
v-model="cycleNoNumber"
:min="0"
:min="1"
:max="249"
/>
</div>
@@ -790,7 +790,7 @@
<script>
import { projectInfo } from '../../../../data/project/ProjectInfo'
import { taskInfo } from '../../../../data/task/TaskInfo'
export default {
name: 'EliteParameterRecording',
@@ -1002,52 +1002,52 @@ export default {
this.$mqtt.publish(topic, mes)
},
refresh () {
// console.log(projectInfo.getDeviceInfo(this.deviceID).parameterSet)
this.workingModeSelect = this.workingModeOptions[projectInfo.getDeviceInfo(this.deviceID).parameterSet.MODE]
this.currentRangeSelect = projectInfo.getDeviceInfo(this.deviceID).parameterSet.ADC_LEVEL
this.startVoltNumber = parseInt((-5.00 + parseFloat(projectInfo.getDeviceInfo(this.deviceID).parameterSet.VOLT_ORIGIN) / 5000) * 100)
// console.log(taskInfo.getDeviceInfo(this.deviceID).parameterSet)
this.workingModeSelect = this.workingModeOptions[taskInfo.getDeviceInfo(this.deviceID).parameterSet.MODE]
this.currentRangeSelect = taskInfo.getDeviceInfo(this.deviceID).parameterSet.ADC_LEVEL
this.startVoltNumber = parseInt((-5.00 + parseFloat(taskInfo.getDeviceInfo(this.deviceID).parameterSet.VOLT_ORIGIN) / 5000) * 100)
this.startVoltNumberInput = String(parseFloat(this.startVoltNumber / 100).toFixed(2))
this.stopVoltNumber = parseInt((-5.00 + parseFloat(projectInfo.getDeviceInfo(this.deviceID).parameterSet.VOLT_FINAL) / 5000) * 100)
this.stopVoltNumber = parseInt((-5.00 + parseFloat(taskInfo.getDeviceInfo(this.deviceID).parameterSet.VOLT_FINAL) / 5000) * 100)
this.stopVoltNumberInput = String(parseFloat(this.stopVoltNumber / 100).toFixed(2))
this.stepVoltNumber = parseInt((2 + (projectInfo.getDeviceInfo(this.deviceID).parameterSet.VOLT_STEP * 2)))
this.stepVoltNumber = parseInt((2 + (taskInfo.getDeviceInfo(this.deviceID).parameterSet.VOLT_STEP * 2)))
this.stepVoltNumberInput = String(parseFloat(this.stepVoltNumber / 10).toFixed(1))
this.stepTimeSelect = projectInfo.getDeviceInfo(this.deviceID).parameterSet.STEP_TIME
this.cycleNoNumber = projectInfo.getDeviceInfo(this.deviceID).parameterSet.CYCLE_NUMBER
this.stepTimeSelect = taskInfo.getDeviceInfo(this.deviceID).parameterSet.STEP_TIME
this.cycleNoNumber = taskInfo.getDeviceInfo(this.deviceID).parameterSet.CYCLE_NUMBER
this.cycleNoNumberInput = String(this.cycleNoNumber)
this.outputVoltNumber = parseInt((-5.00 + parseFloat(projectInfo.getDeviceInfo(this.deviceID).parameterSet.DAC_VOLT) / 5000) * 100)
this.outputVoltNumber = parseInt((-5.00 + parseFloat(taskInfo.getDeviceInfo(this.deviceID).parameterSet.DAC_VOLT) / 5000) * 100)
this.outputVoltNumberInput = String(parseFloat(this.outputVoltNumber / 100).toFixed(2))
this.resisterRangeSelect = projectInfo.getDeviceInfo(this.deviceID).parameterSet.Resister_LEVEL
this.sampleRateSelect = projectInfo.getDeviceInfo(this.deviceID).parameterSet.SAMPLE_RATE
this.stopVoltMaxNumber = parseInt((-5.00 + parseFloat(projectInfo.getDeviceInfo(this.deviceID).parameterSet.VOLTSTOP_MAX) / 5000) * 100)
this.resisterRangeSelect = taskInfo.getDeviceInfo(this.deviceID).parameterSet.Resister_LEVEL
this.sampleRateSelect = taskInfo.getDeviceInfo(this.deviceID).parameterSet.SAMPLE_RATE
this.stopVoltMaxNumber = parseInt((-5.00 + parseFloat(taskInfo.getDeviceInfo(this.deviceID).parameterSet.VOLTSTOP_MAX) / 5000) * 100)
this.stopVoltMaxNumberInput = String(parseFloat(this.stopVoltMaxNumber / 100).toFixed(2))
this.stopVoltMinNumber = parseInt((-5.00 + parseFloat(projectInfo.getDeviceInfo(this.deviceID).parameterSet.VOLTSTOP_MIN) / 5000) * 100)
this.stopVoltMinNumber = parseInt((-5.00 + parseFloat(taskInfo.getDeviceInfo(this.deviceID).parameterSet.VOLTSTOP_MIN) / 5000) * 100)
this.stopVoltMinNumberInput = String(parseFloat(this.stopVoltMinNumber / 100).toFixed(2))
this.chargeSelect = (projectInfo.getDeviceInfo(this.deviceID).parameterSet.Charge + 1) % 2
this.currentNumber = projectInfo.getDeviceInfo(this.deviceID).parameterSet.Const_Current_value
this.chargeSelect = (taskInfo.getDeviceInfo(this.deviceID).parameterSet.Charge + 1) % 2
this.currentNumber = taskInfo.getDeviceInfo(this.deviceID).parameterSet.Const_Current_value
this.currentNumberInput = String(parseFloat(this.currentNumber / 100).toFixed(2))
this.voltInitialNumber = parseInt((-5.00 + parseFloat(projectInfo.getDeviceInfo(this.deviceID).parameterSet.VOLT_INITIAL) / 5000) * 100)
this.voltInitialNumber = parseInt((-5.00 + parseFloat(taskInfo.getDeviceInfo(this.deviceID).parameterSet.VOLT_INITIAL) / 5000) * 100)
this.voltInitialNumberInput = String(parseFloat(this.voltInitialNumber / 100).toFixed(2))
this.voltMaxNumber = Math.round((-5.00 + parseFloat(projectInfo.getDeviceInfo(this.deviceID).parameterSet.VOLT_MAX) / 5000) * 100)
this.voltMaxNumber = Math.round((-5.00 + parseFloat(taskInfo.getDeviceInfo(this.deviceID).parameterSet.VOLT_MAX) / 5000) * 100)
this.voltMaxNumberInput = String(parseFloat(this.voltMaxNumber / 100).toFixed(2))
this.voltMinNumber = Math.round((-5.00 + parseFloat(projectInfo.getDeviceInfo(this.deviceID).parameterSet.VOLT_MIN) / 5000) * 100)
this.voltMinNumber = Math.round((-5.00 + parseFloat(taskInfo.getDeviceInfo(this.deviceID).parameterSet.VOLT_MIN) / 5000) * 100)
this.voltMinNumberInput = String(parseFloat(this.voltMinNumber / 100).toFixed(2))
this.voltScanRateNumber = Math.round((0.01 + parseFloat(projectInfo.getDeviceInfo(this.deviceID).parameterSet.Scan_Rate) * 0.01) * 100)
this.voltScanRateNumber = Math.round((0.01 + parseFloat(taskInfo.getDeviceInfo(this.deviceID).parameterSet.Scan_Rate) * 0.01) * 100)
this.voltScanRateNumberInput = String(parseFloat(this.voltScanRateNumber / 100).toFixed(2))
this.resolutionNumber = Math.round((0.1 + parseFloat(projectInfo.getDeviceInfo(this.deviceID).parameterSet.Data_Resolution_Scan) * 0.1) * 100)
this.resolutionNumber = Math.round((0.1 + parseFloat(taskInfo.getDeviceInfo(this.deviceID).parameterSet.Data_Resolution_Scan) * 0.1) * 100)
this.resolutionNumberInput = String(parseFloat(this.resolutionNumber / 100).toFixed(2))
this.highCycleNoNumber = projectInfo.getDeviceInfo(this.deviceID).parameterSet.CYCLE_NUMBER
this.highCycleNoNumber = taskInfo.getDeviceInfo(this.deviceID).parameterSet.CYCLE_NUMBER
this.highCycleNoNumberInput = String(this.highCycleNoNumber * 100)
this.voltEFinalNumber = Math.round((-5.00 + parseFloat(projectInfo.getDeviceInfo(this.deviceID).parameterSet.VOLT_EFINAL) / 5000) * 100)
this.voltEFinalNumber = Math.round((-5.00 + parseFloat(taskInfo.getDeviceInfo(this.deviceID).parameterSet.VOLT_EFINAL) / 5000) * 100)
this.voltEFinalNumberInput = String(parseFloat(this.voltEFinalNumber / 100).toFixed(2))
this.voltVScanNumber = Math.round((-5.00 + parseFloat(projectInfo.getDeviceInfo(this.deviceID).parameterSet.VOLT_VSCAN) / 5000) * 100)
this.voltVScanNumber = Math.round((-5.00 + parseFloat(taskInfo.getDeviceInfo(this.deviceID).parameterSet.VOLT_VSCAN) / 5000) * 100)
this.voltVScanNumberInput = String(parseFloat(this.voltVScanNumber / 100).toFixed(2))
// console.log('1', projectInfo.getDeviceInfo(this.deviceID).parameterSet.VOLT_MAX)
// console.log('2', parseFloat(projectInfo.getDeviceInfo(this.deviceID).parameterSet.VOLT_MAX) / 5000)
// console.log('5',(-5.00 + parseFloat(projectInfo.getDeviceInfo(this.deviceID).parameterSet.VOLT_MAX) / 5000) * 100)
// console.log('1', taskInfo.getDeviceInfo(this.deviceID).parameterSet.VOLT_MAX)
// console.log('2', parseFloat(taskInfo.getDeviceInfo(this.deviceID).parameterSet.VOLT_MAX) / 5000)
// console.log('5',(-5.00 + parseFloat(taskInfo.getDeviceInfo(this.deviceID).parameterSet.VOLT_MAX) / 5000) * 100)
// console.log('3', this.voltMaxNumberInput)
// console.log('4', this.voltMaxNumber)
},
@@ -1056,10 +1056,10 @@ export default {
if (this.workingModeSelect.id === -1) {
return false
}
if (this.workingModeSelect.id !== projectInfo.getDeviceInfo(this.deviceID).parameterSet.MODE) {
this.mqttPub(projectInfo.getProjectInfo().controllerID + '_user', JSON.stringify({
if (this.workingModeSelect.id !== taskInfo.getDeviceInfo(this.deviceID).parameterSet.MODE) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: projectInfo.getRawDeviceID(this.deviceID),
device: taskInfo.getRawDeviceID(this.deviceID),
parameter: 'MODE',
content: this.workingModeSelect.id,
}))
@@ -1069,10 +1069,10 @@ export default {
if (this.currentRangeSelect == null) {
return false
}
if (this.currentRangeSelect !== projectInfo.getDeviceInfo(this.deviceID).parameterSet.ADC_LEVEL) {
this.mqttPub(projectInfo.getProjectInfo().controllerID + '_user', JSON.stringify({
if (this.currentRangeSelect !== taskInfo.getDeviceInfo(this.deviceID).parameterSet.ADC_LEVEL) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: projectInfo.getRawDeviceID(this.deviceID),
device: taskInfo.getRawDeviceID(this.deviceID),
parameter: 'ADC_LEVEL',
content: this.currentRangeSelect,
}))
@@ -1100,10 +1100,10 @@ export default {
this.startVoltNumber = val
}
}
if (parseFloat(this.startVoltNumber / 100).toFixed(2) !== parseFloat(-5.00 + parseFloat(projectInfo.getDeviceInfo(this.deviceID).parameterSet.VOLT_ORIGIN) / 5000).toFixed(2)) {
this.mqttPub(projectInfo.getProjectInfo().controllerID + '_user', JSON.stringify({
if (parseFloat(this.startVoltNumber / 100).toFixed(2) !== parseFloat(-5.00 + parseFloat(taskInfo.getDeviceInfo(this.deviceID).parameterSet.VOLT_ORIGIN) / 5000).toFixed(2)) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: projectInfo.getRawDeviceID(this.deviceID),
device: taskInfo.getRawDeviceID(this.deviceID),
parameter: 'VOLT_ORIGIN',
content: parseInt((parseFloat(this.startVoltNumber / 100) + 5.00) * 5000),
}))
@@ -1131,10 +1131,10 @@ export default {
this.stopVoltNumber = val
}
}
if (parseFloat(this.stopVoltNumber / 100).toFixed(2) !== parseFloat(-5.00 + parseFloat(projectInfo.getDeviceInfo(this.deviceID).parameterSet.VOLT_FINAL) / 5000).toFixed(2)) {
this.mqttPub(projectInfo.getProjectInfo().controllerID + '_user', JSON.stringify({
if (parseFloat(this.stopVoltNumber / 100).toFixed(2) !== parseFloat(-5.00 + parseFloat(taskInfo.getDeviceInfo(this.deviceID).parameterSet.VOLT_FINAL) / 5000).toFixed(2)) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: projectInfo.getRawDeviceID(this.deviceID),
device: taskInfo.getRawDeviceID(this.deviceID),
parameter: 'VOLT_FINAL',
content: parseInt((parseFloat(this.stopVoltNumber / 100) + 5.00) * 5000),
}))
@@ -1162,10 +1162,10 @@ export default {
this.stepVoltNumber = val
}
}
if (parseFloat(this.stepVoltNumber / 10).toFixed(1) !== parseFloat(0.2 + parseFloat(projectInfo.getDeviceInfo(this.deviceID).parameterSet.VOLT_STEP) * 0.2).toFixed(1)) {
this.mqttPub(projectInfo.getProjectInfo().controllerID + '_user', JSON.stringify({
if (parseFloat(this.stepVoltNumber / 10).toFixed(1) !== parseFloat(0.2 + parseFloat(taskInfo.getDeviceInfo(this.deviceID).parameterSet.VOLT_STEP) * 0.2).toFixed(1)) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: projectInfo.getRawDeviceID(this.deviceID),
device: taskInfo.getRawDeviceID(this.deviceID),
parameter: 'VOLT_STEP',
content: (this.stepVoltNumber - 2) / 2,
}))
@@ -1175,10 +1175,10 @@ export default {
if (this.stepTimeSelect == null) {
return false
}
if (this.stepTimeSelect !== projectInfo.getDeviceInfo(this.deviceID).parameterSet.STEP_TIME) {
this.mqttPub(projectInfo.getProjectInfo().controllerID + '_user', JSON.stringify({
if (this.stepTimeSelect !== taskInfo.getDeviceInfo(this.deviceID).parameterSet.STEP_TIME) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: projectInfo.getRawDeviceID(this.deviceID),
device: taskInfo.getRawDeviceID(this.deviceID),
parameter: 'STEP_TIME',
content: this.stepTimeSelect,
}))
@@ -1197,10 +1197,10 @@ export default {
this.cycleNoNumberInput = String(val)
this.cycleNoNumber = parseInt(val)
}
if (this.cycleNoNumber !== projectInfo.getDeviceInfo(this.deviceID).parameterSet.CYCLE_NUMBER) {
this.mqttPub(projectInfo.getProjectInfo().controllerID + '_user', JSON.stringify({
if (this.cycleNoNumber !== taskInfo.getDeviceInfo(this.deviceID).parameterSet.CYCLE_NUMBER) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: projectInfo.getRawDeviceID(this.deviceID),
device: taskInfo.getRawDeviceID(this.deviceID),
parameter: 'CYCLE_NUMBER',
content: this.cycleNoNumber,
}))
@@ -1228,10 +1228,10 @@ export default {
this.outputVoltNumber = val
}
}
if (parseFloat(this.outputVoltNumber / 100).toFixed(2) !== parseFloat(-5.00 + parseFloat(projectInfo.getDeviceInfo(this.deviceID).parameterSet.DAC_VOLT) / 5000).toFixed(2)) {
this.mqttPub(projectInfo.getProjectInfo().controllerID + '_user', JSON.stringify({
if (parseFloat(this.outputVoltNumber / 100).toFixed(2) !== parseFloat(-5.00 + parseFloat(taskInfo.getDeviceInfo(this.deviceID).parameterSet.DAC_VOLT) / 5000).toFixed(2)) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: projectInfo.getRawDeviceID(this.deviceID),
device: taskInfo.getRawDeviceID(this.deviceID),
parameter: 'DAC_VOLT',
content: parseInt((parseFloat(this.outputVoltNumber / 100) + 5.00) * 5000),
}))
@@ -1241,10 +1241,10 @@ export default {
if (this.resisterRangeSelect == null) {
return false
}
if (this.resisterRangeSelect !== projectInfo.getDeviceInfo(this.deviceID).parameterSet.Resister_LEVEL) {
this.mqttPub(projectInfo.getProjectInfo().controllerID + '_user', JSON.stringify({
if (this.resisterRangeSelect !== taskInfo.getDeviceInfo(this.deviceID).parameterSet.Resister_LEVEL) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: projectInfo.getRawDeviceID(this.deviceID),
device: taskInfo.getRawDeviceID(this.deviceID),
parameter: 'Resister_LEVEL',
content: this.resisterRangeSelect,
}))
@@ -1254,10 +1254,10 @@ export default {
if (this.sampleRateSelect == null) {
return false
}
if (this.sampleRateSelect !== projectInfo.getDeviceInfo(this.deviceID).parameterSet.SAMPLE_RATE) {
this.mqttPub(projectInfo.getProjectInfo().controllerID + '_user', JSON.stringify({
if (this.sampleRateSelect !== taskInfo.getDeviceInfo(this.deviceID).parameterSet.SAMPLE_RATE) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: projectInfo.getRawDeviceID(this.deviceID),
device: taskInfo.getRawDeviceID(this.deviceID),
parameter: 'SAMPLE_RATE',
content: this.sampleRateSelect,
}))
@@ -1285,10 +1285,10 @@ export default {
this.currentNumber = val
}
}
if (this.currentNumber !== projectInfo.getDeviceInfo(this.deviceID).parameterSet.Const_Current_value) {
this.mqttPub(projectInfo.getProjectInfo().controllerID + '_user', JSON.stringify({
if (this.currentNumber !== taskInfo.getDeviceInfo(this.deviceID).parameterSet.Const_Current_value) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: projectInfo.getRawDeviceID(this.deviceID),
device: taskInfo.getRawDeviceID(this.deviceID),
parameter: 'Const_Current_value',
content: this.currentNumber,
}))
@@ -1316,10 +1316,10 @@ export default {
this.stopVoltMaxNumber = val
}
}
if (parseFloat(this.stopVoltMaxNumber / 100).toFixed(2) !== parseFloat(-5.00 + parseFloat(projectInfo.getDeviceInfo(this.deviceID).parameterSet.VOLTSTOP_MAX) / 5000).toFixed(2)) {
this.mqttPub(projectInfo.getProjectInfo().controllerID + '_user', JSON.stringify({
if (parseFloat(this.stopVoltMaxNumber / 100).toFixed(2) !== parseFloat(-5.00 + parseFloat(taskInfo.getDeviceInfo(this.deviceID).parameterSet.VOLTSTOP_MAX) / 5000).toFixed(2)) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: projectInfo.getRawDeviceID(this.deviceID),
device: taskInfo.getRawDeviceID(this.deviceID),
parameter: 'VOLTSTOP_MAX',
content: parseInt((parseFloat(this.stopVoltMaxNumber / 100) + 5.00) * 5000),
}))
@@ -1347,10 +1347,10 @@ export default {
this.stopVoltMinNumber = val
}
}
if (parseFloat(this.stopVoltMinNumber / 100).toFixed(2) !== parseFloat(-5.00 + parseFloat(projectInfo.getDeviceInfo(this.deviceID).parameterSet.VOLTSTOP_MIN) / 5000).toFixed(2)) {
this.mqttPub(projectInfo.getProjectInfo().controllerID + '_user', JSON.stringify({
if (parseFloat(this.stopVoltMinNumber / 100).toFixed(2) !== parseFloat(-5.00 + parseFloat(taskInfo.getDeviceInfo(this.deviceID).parameterSet.VOLTSTOP_MIN) / 5000).toFixed(2)) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: projectInfo.getRawDeviceID(this.deviceID),
device: taskInfo.getRawDeviceID(this.deviceID),
parameter: 'VOLTSTOP_MIN',
content: parseInt((parseFloat(this.stopVoltMinNumber / 100) + 5.00) * 5000),
}))
@@ -1366,10 +1366,10 @@ export default {
} else {
_charge = 0
}
if (_charge !== projectInfo.getDeviceInfo(this.deviceID).parameterSet.Charge) {
this.mqttPub(projectInfo.getProjectInfo().controllerID + '_user', JSON.stringify({
if (_charge !== taskInfo.getDeviceInfo(this.deviceID).parameterSet.Charge) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: projectInfo.getRawDeviceID(this.deviceID),
device: taskInfo.getRawDeviceID(this.deviceID),
parameter: 'Charge',
content: _charge,
}))
@@ -1397,10 +1397,10 @@ export default {
this.voltInitialNumber = val
}
}
if (parseFloat(this.voltInitialNumber / 100).toFixed(2) !== parseFloat(-5.00 + parseFloat(projectInfo.getDeviceInfo(this.deviceID).parameterSet.VOLT_INITIAL) / 5000).toFixed(2)) {
this.mqttPub(projectInfo.getProjectInfo().controllerID + '_user', JSON.stringify({
if (parseFloat(this.voltInitialNumber / 100).toFixed(2) !== parseFloat(-5.00 + parseFloat(taskInfo.getDeviceInfo(this.deviceID).parameterSet.VOLT_INITIAL) / 5000).toFixed(2)) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: projectInfo.getRawDeviceID(this.deviceID),
device: taskInfo.getRawDeviceID(this.deviceID),
parameter: 'VOLT_INITIAL',
content: parseInt((parseFloat(this.voltInitialNumber / 100) + 5.00) * 5000),
}))
@@ -1428,10 +1428,10 @@ export default {
this.voltMaxNumber = val
}
}
if (parseFloat(this.voltMaxNumber / 100).toFixed(2) !== parseFloat(-5.00 + parseFloat(projectInfo.getDeviceInfo(this.deviceID).parameterSet.VOLT_MAX) / 5000).toFixed(2)) {
this.mqttPub(projectInfo.getProjectInfo().controllerID + '_user', JSON.stringify({
if (parseFloat(this.voltMaxNumber / 100).toFixed(2) !== parseFloat(-5.00 + parseFloat(taskInfo.getDeviceInfo(this.deviceID).parameterSet.VOLT_MAX) / 5000).toFixed(2)) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: projectInfo.getRawDeviceID(this.deviceID),
device: taskInfo.getRawDeviceID(this.deviceID),
parameter: 'VOLT_MAX',
content: parseInt((parseFloat(this.voltMaxNumber / 100) + 5.00) * 5000),
}))
@@ -1459,10 +1459,10 @@ export default {
this.voltMinNumber = val
}
}
if (parseFloat(this.voltMinNumber / 100).toFixed(2) !== parseFloat(-5.00 + parseFloat(projectInfo.getDeviceInfo(this.deviceID).parameterSet.VOLT_MIN) / 5000).toFixed(2)) {
this.mqttPub(projectInfo.getProjectInfo().controllerID + '_user', JSON.stringify({
if (parseFloat(this.voltMinNumber / 100).toFixed(2) !== parseFloat(-5.00 + parseFloat(taskInfo.getDeviceInfo(this.deviceID).parameterSet.VOLT_MIN) / 5000).toFixed(2)) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: projectInfo.getRawDeviceID(this.deviceID),
device: taskInfo.getRawDeviceID(this.deviceID),
parameter: 'VOLT_MIN',
content: parseInt((parseFloat(this.voltMinNumber / 100) + 5.00) * 5000),
}))
@@ -1490,10 +1490,10 @@ export default {
this.voltScanRateNumber = val
}
}
if (parseFloat(this.voltScanRateNumber / 100).toFixed(2) !== parseFloat(0.01 + parseFloat(projectInfo.getDeviceInfo(this.deviceID).parameterSet.Scan_Rate)).toFixed(2)) {
this.mqttPub(projectInfo.getProjectInfo().controllerID + '_user', JSON.stringify({
if (parseFloat(this.voltScanRateNumber / 100).toFixed(2) !== parseFloat(0.01 + parseFloat(taskInfo.getDeviceInfo(this.deviceID).parameterSet.Scan_Rate)).toFixed(2)) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: projectInfo.getRawDeviceID(this.deviceID),
device: taskInfo.getRawDeviceID(this.deviceID),
parameter: 'Scan_Rate',
content: parseInt((parseFloat(this.voltScanRateNumber) - 0.01)),
}))
@@ -1521,10 +1521,10 @@ export default {
this.resolutionNumber = val
}
}
if (parseFloat(this.resolutionNumber / 100).toFixed(2) !== parseFloat(0.1 + parseFloat(projectInfo.getDeviceInfo(this.deviceID).parameterSet.Data_Resolution_Scan) * 0.1).toFixed(2)) {
this.mqttPub(projectInfo.getProjectInfo().controllerID + '_user', JSON.stringify({
if (parseFloat(this.resolutionNumber / 100).toFixed(2) !== parseFloat(0.1 + parseFloat(taskInfo.getDeviceInfo(this.deviceID).parameterSet.Data_Resolution_Scan) * 0.1).toFixed(2)) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: projectInfo.getRawDeviceID(this.deviceID),
device: taskInfo.getRawDeviceID(this.deviceID),
parameter: 'Data_Resolution_Scan',
content: parseInt((parseFloat(this.resolutionNumber / 100) - 0.1) * 10),
}))
@@ -1552,10 +1552,10 @@ export default {
this.highCycleNoNumber = val
}
}
if (this.highCycleNoNumber !== projectInfo.getDeviceInfo(this.deviceID).parameterSet.CYCLE_NUMBER) {
this.mqttPub(projectInfo.getProjectInfo().controllerID + '_user', JSON.stringify({
if (this.highCycleNoNumber !== taskInfo.getDeviceInfo(this.deviceID).parameterSet.CYCLE_NUMBER) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: projectInfo.getRawDeviceID(this.deviceID),
device: taskInfo.getRawDeviceID(this.deviceID),
parameter: 'CYCLE_NUMBER',
content: this.highCycleNoNumber,
}))
@@ -1583,10 +1583,10 @@ export default {
this.voltEFinalNumber = val
}
}
if (parseFloat(this.voltEFinalNumber / 100).toFixed(2) !== parseFloat(-5.00 + parseFloat(projectInfo.getDeviceInfo(this.deviceID).parameterSet.VOLT_EFINAL) / 5000).toFixed(2)) {
this.mqttPub(projectInfo.getProjectInfo().controllerID + '_user', JSON.stringify({
if (parseFloat(this.voltEFinalNumber / 100).toFixed(2) !== parseFloat(-5.00 + parseFloat(taskInfo.getDeviceInfo(this.deviceID).parameterSet.VOLT_EFINAL) / 5000).toFixed(2)) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: projectInfo.getRawDeviceID(this.deviceID),
device: taskInfo.getRawDeviceID(this.deviceID),
parameter: 'VOLT_EFINAL',
content: parseInt((parseFloat(this.voltEFinalNumber / 100) + 5.00) * 5000),
}))
@@ -1614,27 +1614,27 @@ export default {
this.voltVScanNumber = val
}
}
if (parseFloat(this.voltVScanNumber / 100).toFixed(2) !== parseFloat(-5.00 + parseFloat(projectInfo.getDeviceInfo(this.deviceID).parameterSet.VOLT_VSCAN) / 5000).toFixed(2)) {
this.mqttPub(projectInfo.getProjectInfo().controllerID + '_user', JSON.stringify({
if (parseFloat(this.voltVScanNumber / 100).toFixed(2) !== parseFloat(-5.00 + parseFloat(taskInfo.getDeviceInfo(this.deviceID).parameterSet.VOLT_VSCAN) / 5000).toFixed(2)) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: projectInfo.getRawDeviceID(this.deviceID),
device: taskInfo.getRawDeviceID(this.deviceID),
parameter: 'VOLT_VSCAN',
content: parseInt((parseFloat(this.voltVScanNumber / 100) + 5.00) * 5000),
}))
}
},
measureEoc () {
this.mqttPub(projectInfo.getProjectInfo().controllerID + '_user', JSON.stringify({
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_instruction/0',
device: projectInfo.getRawDeviceID(this.deviceID),
device: taskInfo.getRawDeviceID(this.deviceID),
instruction: 'VIS_CC_ZERO',
}))
this.measureEocButton.status = true
},
measureEocStop () {
this.mqttPub(projectInfo.getProjectInfo().controllerID + '_user', JSON.stringify({
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_instruction/0',
device: projectInfo.getRawDeviceID(this.deviceID),
device: taskInfo.getRawDeviceID(this.deviceID),
instruction: 'interrupt',
}))
this.measureEocButton.status = false
@@ -0,0 +1,794 @@
<template>
<div class="flex">
<va-tree-root>
<div class="row pt-0 pb-0">
<div class="flex sm12 xl12 md12 xs12">
<va-select
@input="workingModeSelectChange(workingModeSelect)"
:label="'WORKING MODE'"
v-model="workingModeSelect"
textBy="description"
:options="workingModeOptions"
noClear
style="width: 200px;"
/>
<va-button
v-if="!measureEocButton.status && workingModeSelect != null && (workingModeSelect.id == 7 || workingModeSelect.id == 8 || workingModeSelect.id == 9)"
color="primary"
target="_blank"
@click="measureEoc()"
small>
{{measureEocButton.start}}
</va-button>
<va-button
v-if="measureEocButton.status && workingModeSelect != null && (workingModeSelect.id == 7 || workingModeSelect.id == 8 || workingModeSelect.id == 9)"
color="danger"
target="_blank"
@click="measureEocStop()"
small>
{{measureEocButton.stop}}
</va-button>
</div>
</div>
<!-- 1.5ui -->
<va-tree-category
v-if="workingModeSelect != null && workingModeSelect.id == 0 || workingModeSelect.id == 1 || workingModeSelect.id == 5 || workingModeSelect.id == 6 || workingModeSelect.id == 7 || workingModeSelect.id == 8 || workingModeSelect.id == 9 || workingModeSelect.id == 11"
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>
<va-tree-category
v-if="workingModeSelect != null && workingModeSelect.id == 0 || workingModeSelect.id == 1 || workingModeSelect.id == 4 ||workingModeSelect.id == 6 || workingModeSelect.id == 7 || workingModeSelect.id == 8 || workingModeSelect.id == 9 || workingModeSelect.id == 11"
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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<va-tree-category
v-if="workingModeSelect != null && workingModeSelect.id == 2"
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>
<va-tree-category
v-if="workingModeSelect != null && workingModeSelect.id == 2 || workingModeSelect.id == 3 || workingModeSelect.id == 4 || workingModeSelect.id == 5 || workingModeSelect.id == 6"
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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<va-tree-category
v-if="workingModeSelect != null && workingModeSelect.id == 12"
style="font-size: 20px;"
:label="'RIS instruction (HEX)'">
<va-card>
<div class="row">
<div class="flex sm12 xl12 md12 xs12">
<div class="flex row align--center">
<va-input
@keyup.enter="instruParameterChange([instru.parameterName, instru.write])"
@blur="instruParameterChange([instru.parameterName, instru.write])"
class="mb-0"
v-model="instru.write"
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()">
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="disabled"
class="mb-0"
v-model="instru.read"
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="instru.notify"
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>
</va-tree-category>
<va-tree-category
v-if="workingModeSelect != null && workingModeSelect.id == 12"
style="font-size: 20px;"
:label="'VIS & CIS instruction'">
<va-card>
<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="instru.read"
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>
<va-button class="mr-2 pa-1" style="width: 4em; height: 2em; font-size: 15px;" small @click="detect()">
Detect
</va-button>
</div>
<div>
<va-button class="mr-2 pa-1" style="width: 4em; height: 2em; font-size: 15px;" small @click="version()">
Version
</va-button>
</div>
<div>
<va-button class="mr-2 pa-1" style="width: 4em; height: 2em; font-size: 15px;" small @click="battery()">
Battery
</va-button>
</div>
</va-card>
</va-tree-category>
</va-tree-root>
</div>
</template>
<script>
import { taskInfo } from '../../../../data/task/TaskInfo'
import VoltRange from '../parameter/item/VoltRange'
import MilliVoltRange from '../parameter/item/MilliVoltRange'
import CycleRange from '../parameter/item/CycleRange'
import LevelButton from '../parameter/item/LevelButton'
import OppLevelButton from '../parameter/item/OppLevelButton'
import MicroAmpereRange from '../parameter/item/MicroAmpereRange'
import ScanRateRange from '../parameter/item/ScanRateRange'
import ResolutionRange from '../parameter/item/ResolutionRange'
export default {
name: 'EliteParameterRecordingElitezm15',
components: {
VoltRange,
MilliVoltRange,
CycleRange,
LevelButton,
OppLevelButton,
MicroAmpereRange,
ScanRateRange,
ResolutionRange,
},
props: {
deviceID: {
type: Number,
required: true,
},
deviceName: {
type: String,
default: 'Elite',
},
},
created () {
},
data () {
return {
workingModeSelect: {
id: -1,
description: 'Init',
},
workingModeOptions: [
{
id: 0,
description: 'I-V Curve',
},
{
id: 1,
description: 'Cycle I-V',
},
{
id: 2,
description: 'Function Generator',
},
{
id: 3,
description: 'R-T Graph',
},
{
id: 4,
description: 'V-T Graph',
},
{
id: 5,
description: 'I-T Graph',
},
{
id: 6,
description: 'Constant Current',
},
{
id: 7,
description: 'Cyclic Voltammetry',
},
{
id: 8,
description: 'Linear Sweep Voltammetry',
},
{
id: 9,
description: 'Chronoamperometric Graph',
},
{
id: 10,
description: 'Cali DAC - test',
},
{
id: 11,
description: 'Cali ADC - test',
},
{
id: 12,
description: 'Dev Mode',
},
],
currentRangeSelect: null,
currentRangeOptions: [
{
value: 0,
label: '<4 μA',
},
{
value: 1,
label: '2.5-100 μA',
},
{
value: 2,
label: '85-2050 μA',
},
{
value: 3,
label: '1800 uA',
},
{
value: 4,
label: 'Auto',
},
],
voltageInRangeSelect: null,
voltageInRangeOptions: [
{
value: 0,
label: '<7 mV',
},
{
value: 1,
label: '5-300 mV',
},
{
value: 2,
label: '>250 mV',
},
{
value: 3,
label: 'Auto',
},
],
caliChannelSelect: null,
caliChannelOptions: [
{
value: 0,
label: 'Iin',
},
{
value: 1,
label: 'Vin',
},
],
startVoltNumber: null,
stopVoltNumber: null,
stepVoltNumber: null,
stepTimeSelect: null,
stepTimeOptions: [
{
value: 0,
label: '0.5s',
},
{
value: 1,
label: '1.0s',
},
{
value: 2,
label: '2.0s',
},
],
cycleNoNumber: null,
outputVoltNumber: null,
sampleRateNumber: null,
chargeSelect: null,
chargeOptions: [
{
value: 0,
label: 'Charge',
},
{
value: 1,
label: 'Discharge',
},
],
highzSelect: null,
highzOptions: [
{
value: 0,
label: 'On',
},
{
value: 1,
label: 'Off',
},
],
currentNumber: null,
stopVoltMaxNumber: null,
stopVoltMinNumber: null,
voltInitialNumber: null,
voltMaxNumber: null,
voltMinNumber: null,
voltScanRateNumber: null,
resolutionNumber: null,
measureEocButton: {
start: 'Measure Eoc',
stop: 'Stop',
status: false,
},
voltEFinalNumber: null,
voltVScanNumber: null,
caliVoltNumber: null,
instru: {
write: '',
read: '',
notify: '',
},
}
},
mqtt: {
},
methods: {
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.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: taskInfo.getRawDeviceID(this.deviceID),
parameter: e[0],
content: e[1],
}))
},
refresh () {
this.workingModeSelect = this.workingModeOptions[taskInfo.getDeviceInfo(this.deviceID).parameterSet.MODE]
if (this.workingModeSelect != null) {
this.workingModeSelectChange(this.workingModeSelect)
}
this.currentRangeSelect = taskInfo.getDeviceInfo(this.deviceID).parameterSet.ADC_LEVEL_I_15
if (this.$refs.currentRangeSelect != null) {
this.$refs.currentRangeSelect.updateLevelButton(this.currentRangeSelect)
}
this.voltageInRangeSelect = taskInfo.getDeviceInfo(this.deviceID).parameterSet.ADC_LEVEL_V_IN_15
if (this.$refs.voltageInRangeSelect != null) {
this.$refs.voltageInRangeSelect.updateLevelButton(this.voltageInRangeSelect)
}
this.highzSelect = taskInfo.getDeviceInfo(this.deviceID).parameterSet.CTRL_HIGH_Z_15
if (this.$refs.highzSelect != null) {
this.$refs.highzSelect.updateLevelButton(this.highzSelect)
}
this.caliChannelSelect = taskInfo.getDeviceInfo(this.deviceID).parameterSet.ADC_DAC_CHANNEL_15
if (this.$refs.caliChannelSelect != null) {
this.$refs.caliChannelSelect.updateLevelButton(this.caliChannelSelect)
}
this.caliVoltNumber = taskInfo.getDeviceInfo(this.deviceID).parameterSet.DAC_VOLT
if (this.$refs.caliVoltNumber != null) {
this.$refs.caliVoltNumber.updateCycleNumber(this.caliVoltNumber)
}
this.startVoltNumber = (taskInfo.getDeviceInfo(this.deviceID).parameterSet.VOLT_ORIGIN - 25000) / 5
if (this.$refs.startVoltNumber != null) {
this.$refs.startVoltNumber.updateVoltNumber(this.startVoltNumber)
}
this.stopVoltNumber = (taskInfo.getDeviceInfo(this.deviceID).parameterSet.VOLT_FINAL - 25000) / 5
if (this.$refs.stopVoltNumber != null) {
this.$refs.stopVoltNumber.updateVoltNumber(this.stopVoltNumber)
}
this.stepVoltNumber = (taskInfo.getDeviceInfo(this.deviceID).parameterSet.VOLT_STEP)
if (this.$refs.stepVoltNumber != null) {
this.$refs.stepVoltNumber.updateStepVoltNumber(this.stepVoltNumber)
}
this.stepTimeSelect = taskInfo.getDeviceInfo(this.deviceID).parameterSet.STEP_TIME
if (this.$refs.stepTimeSelect != null) {
this.$refs.stepTimeSelect.updateLevelButton(this.stepTimeSelect)
}
this.cycleNoNumber = taskInfo.getDeviceInfo(this.deviceID).parameterSet.CYCLE_NUMBER
if (this.$refs.cycleNoNumber != null) {
this.$refs.cycleNoNumber.updateCycleNumber(this.cycleNoNumber)
}
this.outputVoltNumber = (taskInfo.getDeviceInfo(this.deviceID).parameterSet.DAC_VOLT - 25000) / 5
if (this.$refs.outputVoltNumber != null) {
this.$refs.outputVoltNumber.updateVoltNumber(this.outputVoltNumber)
}
this.sampleRateNumber = taskInfo.getDeviceInfo(this.deviceID).parameterSet.SAMPLE_RATE
if (this.$refs.sampleRateNumber != null) {
this.$refs.sampleRateNumber.updateResolutionNumber(this.sampleRateNumber)
}
this.chargeSelect = (taskInfo.getDeviceInfo(this.deviceID).parameterSet.Charge + 1) % 2
if (this.$refs.chargeSelect != null) {
this.$refs.chargeSelect.updateLevelButton(this.chargeSelect)
}
this.currentNumber = taskInfo.getDeviceInfo(this.deviceID).parameterSet.Const_Current_value
if (this.$refs.currentNumber != null) {
this.$refs.currentNumber.updateMicroAmpereNumber(this.currentNumber)
}
this.stopVoltMaxNumber = this.voltInitialNumber = (taskInfo.getDeviceInfo(this.deviceID).parameterSet.VOLTSTOP_MAX - 25000) / 5
if (this.$refs.stopVoltMaxNumber != null) {
this.$refs.stopVoltMaxNumber.updateVoltNumber(this.stopVoltMaxNumber)
}
this.stopVoltMinNumber = (taskInfo.getDeviceInfo(this.deviceID).parameterSet.VOLTSTOP_MIN - 25000) / 5
if (this.$refs.stopVoltMinNumber != null) {
this.$refs.stopVoltMinNumber.updateVoltNumber(this.stopVoltMinNumber)
}
this.voltInitialNumber = (taskInfo.getDeviceInfo(this.deviceID).parameterSet.VOLT_INITIAL - 25000) / 5
if (this.$refs.voltInitialNumber != null) {
this.$refs.voltInitialNumber.updateVoltNumber(this.voltInitialNumber)
}
this.voltMaxNumber = (taskInfo.getDeviceInfo(this.deviceID).parameterSet.VOLT_MAX - 25000) / 5
if (this.$refs.voltMaxNumber != null) {
this.$refs.voltMaxNumber.updateVoltNumber(this.voltMaxNumber)
}
this.voltMinNumber = (taskInfo.getDeviceInfo(this.deviceID).parameterSet.VOLT_MIN - 25000) / 5
if (this.$refs.voltMinNumber != null) {
this.$refs.voltMinNumber.updateVoltNumber(this.voltMinNumber)
}
this.voltEFinalNumber = (taskInfo.getDeviceInfo(this.deviceID).parameterSet.VOLT_EFINAL - 25000) / 5
if (this.$refs.voltEFinalNumber != null) {
this.$refs.voltEFinalNumber.updateVoltNumber(this.voltEFinalNumber)
}
this.voltVScanNumber = (taskInfo.getDeviceInfo(this.deviceID).parameterSet.VOLT_VSCAN - 25000) / 5
if (this.$refs.voltVScanNumber != null) {
this.$refs.voltVScanNumber.updateVoltNumber(this.voltVScanNumber)
}
this.voltScanRateNumber = taskInfo.getDeviceInfo(this.deviceID).parameterSet.Scan_Rate
if (this.$refs.voltScanRateNumber != null) {
this.$refs.voltScanRateNumber.updateVoltScanRateNumber(this.voltScanRateNumber)
}
this.instru.read = (taskInfo.getDeviceInfo(this.deviceID).parameterSet.ADC_VALUE_I).toString(16).toUpperCase()
},
workingModeSelectChange (val) {
if (this.workingModeSelect.id === -1) {
return false
}
this.workingModeSelect = val
if (this.workingModeSelect.id !== taskInfo.getDeviceInfo(this.deviceID).parameterSet.MODE) {
this.deviceParameterChange(['MODE', this.workingModeSelect.id])
console.log(this.workingModeSelect.id, this.workingModeSelect.description)
}
},
measureEoc () {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_instruction/0',
device: taskInfo.getRawDeviceID(this.deviceID),
instruction: 'VIS_CC_ZERO',
}))
this.measureEocButton.status = true
},
measureEocStop () {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_instruction/0',
device: taskInfo.getRawDeviceID(this.deviceID),
instruction: 'interrupt',
}))
this.measureEocButton.status = false
},
instruParameterChange: function (e) {
while (e[1].length <= 33) {
e[1] = e[1] + '0'
}
const sendIns = new Array(17).fill(0)
for (let i = 0; i <= 16; i++) {
const startIndex = i * 2
sendIns[i] = e[1].substring(startIndex, startIndex + 2)
sendIns[i] = parseInt(sendIns[i], 16)
}
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: taskInfo.getRawDeviceID(this.deviceID),
parameter: 'BLE_WRITE',
content: '0:16=' + String(sendIns),
}))
},
sendInstr () {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_instruction/0',
device: taskInfo.getRawDeviceID(this.deviceID),
instruction: 'ble_instru_send',
}))
},
readCisData () {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter_value/0',
device: taskInfo.getRawDeviceID(this.deviceID),
parameter: 'ADC_VALUE_I',
}))
},
detect () {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_instruction/0',
device: taskInfo.getRawDeviceID(this.deviceID),
instruction: 'VIS_DEVICE_DETECT',
}))
setTimeout(() => {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_instruction/0',
device: taskInfo.getRawDeviceID(this.deviceID),
instruction: 'VIS_DEVICE_DONE',
}))
}, 5000)
},
version () {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_instruction/0',
device: taskInfo.getRawDeviceID(this.deviceID),
instruction: 'dev_version',
}))
},
battery () {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_instruction/0',
device: taskInfo.getRawDeviceID(this.deviceID),
instruction: 'dev_battery',
}))
},
},
mounted () {
this.refresh()
},
watch: {
},
destroyed () {
},
}
</script>
@@ -0,0 +1,102 @@
<template>
<div class="flex mt-0 pt-0">
<div>
<div class="row flex sm12 xl12 md12 xs12">
<div v-if="eliteVer=='1'">
<elite-parameter-recording :ref="'rec_ref'" :deviceID="deviceID"/>
</div>
<div v-else-if="eliteVer=='2'">
<elite-parameter-recording-elitezm15 :ref="'rec_ref'" :deviceID="deviceID"/>
<!--<elite-parameter-recording :ref="'rec_ref'" :deviceID="deviceID"/>-->
</div>
<div v-else-if="eliteVer=='3'">
<!--<elite-parameter-recording :ref="'rec_ref'" :deviceID="deviceID"/>-->
</div>
</div>
</div>
</div>
</template>
<script>
import EliteParameterRecording from './EliteParameterRecording'
import EliteParameterRecordingElitezm15 from './EliteParameterRecordingElitezm15'
import { taskInfo } from '../../../../data/task/TaskInfo'
export default {
name: 'EliteParameterWindow',
components: {
EliteParameterRecording,
EliteParameterRecordingElitezm15,
},
props: {
deviceID: {
type: Number,
required: true,
},
deviceName: {
type: String,
default: 'Elite',
},
},
data () {
return {
eliteVer: 0,
}
},
mqtt: {
},
methods: {
compareEliteVer: function (ver) {
if (JSON.stringify(ver.slice(0, 4)) === JSON.stringify([0, 2, 1, 5])) {
this.eliteVer = '1' // 1.4
// console.log('1:', JSON.stringify(ver.slice(0, 4)), ',', JSON.stringify([0, 2, 1, 5]))
} else if (JSON.stringify(ver.slice(0, 4)) === JSON.stringify([0, 2, 1, 6])) {
this.eliteVer = '2' // 1.5
// console.log('2:', JSON.stringify(ver.slice(0, 4)), ',', JSON.stringify([0, 2, 1, 6]))
} else if (JSON.stringify(ver.slice(0, 4)) === JSON.stringify([0, 2, 1, 7])) {
this.eliteVer = '3' // megafly
// console.log('3:', JSON.stringify(ver.slice(0, 4)), ',', JSON.stringify([0, 2, 1, 7]))
}
},
mqttPub: 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 () {
this.$nextTick(() => {
if (this.$refs.rec_ref != null) {
this.$refs.rec_ref.refresh()
}
})
// console.log('window:3,refresh(this.$nextTick:', this.$nextTick, ',this.$refs:', this.$refs, ')')
},
},
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>
@@ -0,0 +1,683 @@
<template>
<div class="flex" >
<!-- <div>
<div class="row sm12 xl12 md12 xs12">
<va-button
class="mx-1 px-2 mb-3"
color="success"
v-if="!recordOn"
@click="recordClick"
small
>
Record
</va-button>
<va-button
class="mx-1 px-2 mb-3"
color="danger"
v-else
@click="recordClick"
small
>
Stop
</va-button>
</div>
</div> -->
<va-tree-root >
<va-tree-category
style="font-size: 20px;"
:label="'Channels'">
<va-tree-node>
<div class="row">
<div class="flex sm12 xl12 md12 xs12">
<div
style='display: inline-block;'
v-for="channel in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]"
:key="channel"
>
<va-button
class="mx-1 px-1"
v-if="channelList != null && channelList.indexOf(channel) >= 0"
@click="channelClickRemove(channel)"
small
>
{{channel}}
</va-button>
<va-button
class="mx-1 px-1"
v-if="channelList == null || channelList.indexOf(channel) < 0"
@click="channelClickAdd(channel)"
small outline
>
{{channel}}
</va-button>
</div>
</div>
</div>
</va-tree-node>
</va-tree-category>
<va-tree-category
style="font-size: 20px;"
:label="'3-AXIS'">
<va-tree-node>
<div class="row">
<div class="flex sm12 xl12 md12 xs12">
<div
style='display: inline-block;'
v-for="axisChannel in ['x','y','z','m']"
:key="axisChannel"
>
<va-button
class="mx-1 px-1"
v-if="axisChannelList != null && axisChannelList.indexOf(axisChannel) >= 0"
@click="axisChannelClickRemove(axisChannel)"
small
>
{{axisChannel}}
</va-button>
<va-button
class="mx-1 px-1"
v-if="axisChannelList == null || axisChannelList.indexOf(axisChannel) < 0"
@click="axisChannelClickAdd(axisChannel)"
small outline
>
{{axisChannel}}
</va-button>
</div>
</div>
</div>
</va-tree-node>
</va-tree-category>
<va-tree-category
style="font-size: 20px;"
:label="'Amp gain'">
<va-tree-node>
<div class="row">
<div class="flex sm12 xl12 md12 xs12">
<va-select
@input="ampGainSelectChange()"
:label="''"
v-model="ampGainSelect"
textBy="description"
:options="ampGainOptions"
/>
</div>
</div>
</va-tree-node>
</va-tree-category>
<va-tree-category
style="font-size: 20px;"
:label="'Sample Rate'">
<va-tree-node>
<div class="row">
<div class="flex sm12 xl12 md12 xs12">
<va-select
@input="sampleRateSelectChange()"
:label="''"
v-model="sampleRateSelect"
textBy="description"
:options="sampleRateOptions"
/>
</div>
</div>
</va-tree-node>
</va-tree-category>
<va-tree-category
style="font-size: 20px;"
:label="'Radio Frequency'">
<va-tree-node>
<div class="row">
<div class="flex sm12 xl12 md12 xs12">
<va-select
@input="radioFrequencySelectChange()"
:label="''"
v-model="radioFrequencySelect"
textBy="description"
:options="radioFrequencyOptions"
/>
</div>
</div>
</va-tree-node>
</va-tree-category>
<va-tree-category
style="font-size: 20px;"
:label="'Led Brightness'">
<va-tree-node>
<div class="row">
<div class="flex sm12 xl12 md12 xs12">
<va-select
@input="ledBrightnessSelectChange()"
:label="''"
v-model="ledBrightnessSelect"
textBy="description"
:options="ledBrightnessOptions"
/>
</div>
</div>
</va-tree-node>
</va-tree-category>
<va-tree-category
style="font-size: 20px;"
:label="'Accelerator Sensitivity'">
<va-tree-node>
<div class="row">
<div class="flex sm12 xl12 md12 xs12">
<va-select
@input="acceleratorSensitivitySelectChange()"
:label="''"
v-model="acceleratorSensitivitySelect"
textBy="description"
:options="acceleratorSensitivityOptions"
/>
</div>
</div>
</va-tree-node>
</va-tree-category>
<!-- <va-tree-category
style="font-size: 20px;"
:label="'Sample rate'">
<va-tree-node>
<div class="row">
<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="sampleRateChange(4)">
4
</va-button>
<va-input
@keyup.enter="sampleRateChange(sampleRateInput)"
v-model="sampleRateInput"
class="mb-0"
style="width: 100px;"
>
<p slot="append" style="margin-right: 0;" small>
Hz
</p>
</va-input>
<va-button slot="append" class="ml-2 pa-1 shrink" small @click="sampleRateChange(1000)">
1000
</va-button>
</div>
<va-slider
@mouseup.native="sampleRateChange(sampleRate)"
@mouseleave.native="sampleRateChange(sampleRate)"
@touchend.native="sampleRateChange(sampleRate)"
class="flex sm12 xl12 md12 xs12"
value-visible
v-model="sampleRate"
:min="4"
:max="1000"
/>
</div>
</div>
</va-tree-node>
</va-tree-category> -->
</va-tree-root>
</div>
</template>
<script>
import { taskInfo } from '../../../../data/task/TaskInfo'
import { chartData } from '../../../../data/task/ChartsManagement'
export default {
name: 'NeuliveParameterRecording',
components: {
},
props: {
deviceID: {
type: Number,
required: true,
},
deviceName: {
type: String,
default: 'Neulive',
},
},
data () {
return {
channelList: [],
ampGainSelect: null,
ampGainOptions: [
// {
// id: 0,
// description: '25',
// },
{
id: 0,
description: '100',
},
{
id: 1,
description: '400',
},
{
id: 2,
description: '800',
},
],
sampleRateSelect: null,
sampleRateOptions: [
{
id: 0,
value: 800,
description: '1k',
},
{
id: 1,
value: 400,
description: '2k',
},
{
id: 2,
value: 200,
description: '4k',
},
{
id: 3,
value: 160,
description: '5k',
},
{
id: 4,
value: 100,
description: '8k',
},
{
id: 5,
value: 80,
description: '10k',
},
{
id: 6,
value: 40,
description: '20k',
},
],
radioFrequencySelect: null,
radioFrequencyOptions: [
{
id: 0,
value: -20,
description: '-20',
},
{
id: 1,
value: -16,
description: '-16',
},
{
id: 2,
value: -12,
description: '-12',
},
{
id: 3,
value: -8,
description: '-8',
},
{
id: 4,
value: -4,
description: '-4',
},
{
id: 5,
value: 0,
description: '0',
},
{
id: 6,
value: 4,
description: '4',
},
{
id: 7,
value: 8,
description: '8',
},
],
ledBrightnessSelect: null,
ledBrightnessOptions: [
{
id: 0,
value: 0,
description: 'off',
},
{
id: 1,
value: 1,
description: 'bright',
},
{
id: 2,
value: 2,
description: 'normal',
},
],
acceleratorSensitivitySelect: null,
acceleratorSensitivityOptions: [
{
id: 0,
value: 3,
description: '2G',
},
{
id: 1,
value: 5,
description: '4G',
},
{
id: 2,
value: 8,
description: '8G',
},
{
id: 3,
value: 12,
description: '16G',
},
],
// sampleRateInput: '1000',
// sampleRate: null,
recordOn: false,
axisChannelList: [],
}
},
mqtt: {
},
methods: {
mqttPub: function (topic, mes) {
this.$mqtt.publish(topic, mes)
},
refresh () {
this.channelList.length = 0
const channelSet = taskInfo.getDeviceInfo(this.deviceID).parameterSet.RECORDING_CH.toString(2).split('').reverse()
channelSet.forEach((element, index) => {
if (parseInt(element) > 0) {
this.channelList.push(index + 1)
}
})
this.ampGainSelect = this.ampGainOptions[(taskInfo.getDeviceInfo(this.deviceID).parameterSet.AMP_GAIN) % 4]
this.sampleRateSelect = this.sampleRateOptions[this.sampleRateOptions.findIndex(ele => ele.value === taskInfo.getDeviceInfo(this.deviceID).parameterSet.ADC_CLOCK)]
this.recordOn = taskInfo.getDeviceInfo(this.deviceID).parameterSet.RECORDING
this.axisChannelList.length = 0
const axisChannelSet = taskInfo.getDeviceInfo(this.deviceID).parameterSet.AXIS_CH.toString(2).split('').reverse()
axisChannelSet.forEach((element, index) => {
if (parseInt(element) === 1) {
if (index === 0) {
this.axisChannelList.push('x')
} else if (index === 1) {
this.axisChannelList.push('y')
} else if (index === 2) {
this.axisChannelList.push('z')
} else if (index === 3) {
this.axisChannelList.push('m')
}
}
})
this.radioFrequencySelect = this.radioFrequencyOptions[taskInfo.getDeviceInfo(this.deviceID).parameterSet.RADIO_FREQUENCY]
this.ledBrightnessSelect = this.ledBrightnessOptions[taskInfo.getDeviceInfo(this.deviceID).parameterSet.LED_BRIGHTNESS]
this.acceleratorSensitivitySelect = this.acceleratorSensitivityOptions[taskInfo.getDeviceInfo(this.deviceID).parameterSet.ACCELERATOR_S]
},
channelClickAdd (val) {
if (this.channelList.indexOf(val) < 0 && this.channelList.length < 15) {
this.channelList.push(val)
let channelSet = ''
for (let i = 16; i >= 1; i--) {
if (this.channelList.indexOf(i) >= 0) {
channelSet += '1'
} else {
channelSet += '0'
}
}
const channelValue = parseInt(channelSet, 2)
if (channelValue !== taskInfo.getDeviceInfo(this.deviceID).RECORDING_CH) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: taskInfo.getRawDeviceID(this.deviceID),
parameter: 'RECORDING_CH',
content: channelValue,
}))
}
} else if (this.channelList.length === 15) {
this.pageToast('Recording channels cannot choose more than 15.')
}
},
channelClickRemove (val) {
if (this.channelList.indexOf(val) >= 0) {
this.channelList.splice(this.channelList.indexOf(val), 1)
let channelSet = ''
for (let i = 16; i >= 1; i--) {
if (this.channelList.indexOf(i) >= 0) {
channelSet += '1'
} else {
channelSet += '0'
}
}
const channelValue = parseInt(channelSet, 2)
if (channelValue !== taskInfo.getDeviceInfo(this.deviceID).RECORDING_CH) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: taskInfo.getRawDeviceID(this.deviceID),
parameter: 'RECORDING_CH',
content: channelValue,
}))
}
}
},
ampGainSelectChange () {
if (this.ampGainSelect != null && this.ampGainSelect.id !== ((taskInfo.getDeviceInfo(this.deviceID).parameterSet.AMP_GAIN) % 4)) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: taskInfo.getRawDeviceID(this.deviceID),
parameter: 'AMP_GAIN',
content: ((this.ampGainSelect.id) % 4),
}))
}
},
sampleRateSelectChange () {
if (this.sampleRateSelect != null && this.sampleRateSelect.value !== ((taskInfo.getDeviceInfo(this.deviceID).parameterSet.ADC_CLOCK))) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: taskInfo.getRawDeviceID(this.deviceID),
parameter: 'ADC_CLOCK',
content: this.sampleRateSelect.value,
}))
}
},
radioFrequencySelectChange () {
if (this.radioFrequencySelect != null && this.radioFrequencySelect.id !== ((taskInfo.getDeviceInfo(this.deviceID).parameterSet.RADIO_FREQUENCY))) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: taskInfo.getRawDeviceID(this.deviceID),
parameter: 'RADIO_FREQUENCY',
content: this.radioFrequencySelect.id,
}))
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_update_radio_frequency/0',
device: taskInfo.getRawDeviceID(this.deviceID),
content: this.radioFrequencySelect.value,
}))
}
},
ledBrightnessSelectChange () {
if (this.ledBrightnessSelect != null && this.ledBrightnessSelect.id !== ((taskInfo.getDeviceInfo(this.deviceID).parameterSet.LED_BRIGHTNESS))) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: taskInfo.getRawDeviceID(this.deviceID),
parameter: 'LED_BRIGHTNESS',
content: this.ledBrightnessSelect.id,
}))
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_update_led_brightness/0',
device: taskInfo.getRawDeviceID(this.deviceID),
content: this.ledBrightnessSelect.value,
}))
}
},
acceleratorSensitivitySelectChange () {
if (this.acceleratorSensitivitySelect != null && this.acceleratorSensitivitySelect.id !== ((taskInfo.getDeviceInfo(this.deviceID).parameterSet.ACCELERATOR_S))) {
let scaleRange
switch (this.acceleratorSensitivitySelect.id) {
case 0:
scaleRange = 200
break
case 1:
scaleRange = 400
break
case 2:
scaleRange = 800
break
case 3:
scaleRange = 1600
break
default:
scaleRange = 0
break
}
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: taskInfo.getRawDeviceID(this.deviceID),
parameter: 'ACCELERATOR_S',
content: this.acceleratorSensitivitySelect.id,
}))
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_update_accelerator_sensitivity/0',
device: taskInfo.getRawDeviceID(this.deviceID),
content: this.acceleratorSensitivitySelect.value,
}))
const charts = chartData.getAllChartsData()
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) {
charts[chartID].yAxis[seriesIndex].min = -scaleRange
charts[chartID].yAxis[seriesIndex].max = scaleRange
}
}
}
}
},
// sampleRateChange (val) {
// if (this.sampleRate == null) {
// return false
// }
// if (isNaN(val) || parseInt(val) > 1000 || parseInt(val) < 4) {
// this.sampleRateInput = '1000'
// this.sampleRate = 1000
// return false
// }
// if (parseInt(this.sampleRateInput) !== this.sampleRate || this.sampleRate !== parseInt(val)) {
// this.sampleRateInput = String(val)
// this.sampleRate = parseInt(val)
// }
// if (this.sampleRate !== parseInt(200 / parseFloat(taskInfo.getDeviceInfo(this.deviceID).parameterSet.ADC_CLOCK / 1000))) {
// this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
// header: 'device_parameter/0',
// device: taskInfo.getRawDeviceID(this.deviceID),
// parameter: 'ADC_CLOCK',
// content: parseInt(parseFloat(1 / parseFloat(this.sampleRate / 200)) * 1000),
// }))
// }
// },
recordClick () {
this.recordOn = !this.recordOn
if (this.recordOn) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_instruction/0',
device: taskInfo.getRawDeviceID(this.deviceID),
instruction: 'record',
}))
this.$emit('record')
} else {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_instruction/0',
device: taskInfo.getRawDeviceID(this.deviceID),
instruction: 'stop_record',
}))
this.$emit('record_stop')
}
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: taskInfo.getRawDeviceID(this.deviceID),
parameter: 'RECORDING',
content: this.recordOn,
}))
},
axisChannelClickAdd (val) {
if (this.axisChannelList.indexOf(val) < 0) {
const axisChannel = ['m', 'z', 'y', 'x']
this.axisChannelList.push(val)
let axisChannelSet = ''
for (const axis of axisChannel) {
if (this.axisChannelList.indexOf(axis) >= 0) {
axisChannelSet += '1'
} else {
axisChannelSet += '0'
}
}
const axisChannelValue = parseInt(axisChannelSet, 2)
if (axisChannelValue !== taskInfo.getDeviceInfo(this.deviceID).AXIS_CH) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: taskInfo.getRawDeviceID(this.deviceID),
parameter: 'AXIS_CH',
content: axisChannelValue,
}))
}
}
},
axisChannelClickRemove (val) {
if (this.axisChannelList.indexOf(val) >= 0) {
const axisChannel = ['m', 'z', 'y', 'x']
this.axisChannelList.splice(this.axisChannelList.indexOf(val), 1)
let axisChannelSet = ''
for (const axis of axisChannel) {
if (this.axisChannelList.indexOf(axis) >= 0) {
axisChannelSet += '1'
} else {
axisChannelSet += '0'
}
}
const axisChannelValue = parseInt(axisChannelSet, 2)
if (axisChannelValue !== taskInfo.getDeviceInfo(this.deviceID).AXIS_CH) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: taskInfo.getRawDeviceID(this.deviceID),
parameter: 'AXIS_CH',
content: axisChannelValue,
}))
}
}
},
pageToast: function (mes) {
this.showToast(
mes,
{
icon: 'fa-bell',
position: 'bottom-right',
duration: 4000,
},
)
},
},
mounted () {
this.refresh()
},
destroyed () {
},
watch: {
},
}
</script>
@@ -1,7 +1,7 @@
<template>
<div class="flex">
<div>
<div>
<!-- <div>
<div class="row sm12 xl12 md12 xs12">
<va-button
class="mx-1 px-2"
@@ -23,16 +23,17 @@
Stop
</va-button>
</div>
</div>
</div> -->
<div class="mt-4">
<div class="row sm12 xl12 md12 xs12">
<p class="display-6">ELECTRODE</p>
<va-button flat color="gray" icon="fa fa-info-circle" style="margin: 0.001rem; padding: 0.001rem;" @click.stop="toggleModal('ELECTRODE')"/>
</div>
<div class="row">
<div class="flex sm12 xl12 md12 xs12">
<va-button-toggle
:on-change="stimulateElectrodeSelectChange()"
@click.native="stimulateElectrodeSelectChange()"
small
outline
v-model="stimulateElectrodeSelect"
@@ -91,7 +92,7 @@
<div class="row">
<div class="flex sm12 xl12 md12 xs12">
<va-button-toggle
:on-change="cycleNumberSelectChange()"
@click.native="cycleNumberSelectChange()"
small
outline
v-model="cycleNumberSelect"
@@ -115,8 +116,8 @@
Rounds
</p>
</va-input>
<va-button slot="append" class="ml-2 pa-1 shrink" small @click="cycleNumberChange(256)">
256
<va-button slot="append" class="ml-2 pa-1 shrink" small @click="cycleNumberChange(255)">
255
</va-button>
</div>
<va-slider
@@ -127,7 +128,7 @@
value-visible
v-model="cycleNumber"
:min="1"
:max="256"
:max="255"
/>
</div>
</div>
@@ -174,16 +175,20 @@
<div class="mt-4">
<div class="row sm12 xl12 md12 xs12">
<p class="display-6">PATTERN</p>
<va-button flat color="gray" icon="fa fa-info-circle" style="margin: 0.001rem; padding: 0.001rem;" @click.stop="toggleModal('PATTERN')"/>
</div>
<div class="row">
<div class="flex sm12 xl12 md12 xs12">
<va-button-toggle
:on-change="patternModeSelectChange()"
@click.native="patternModeSelectChange()"
small
outline
v-model="patternModeSelect"
:options="patternModeOptions"
/>
>
</va-button-toggle>
<img src='@/assets/img/Monophasic.png' v-if="patternModeSelect==0" class="sti_pattern_img">
<img src='@/assets/img/Biphasic.png' v-if="patternModeSelect==1" class="sti_pattern_img">
</div>
</div>
@@ -236,7 +241,7 @@
<div class="row">
<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="patternModeSelect?timeRangeChange(1, 0):timeRangeChange(1, 0)">
<va-button slot="append" class="mr-2 pa-1 shrink" small @click="timeRangeChange(1, 0)">
0
</va-button>
<va-input
@@ -326,13 +331,27 @@
</div>
</div>
</div>
<va-modal
v-model="showGuideLineModal.ELECTRODE"
position="right"
cancelText=""
>
<img src='@/assets/img/sti_user_guide.png' class="sti_guideline">
</va-modal>
<va-modal
v-model="showGuideLineModal.PATTERN"
position="right"
cancelText=""
>
<img src='@/assets/img/sti_user_guide.png' class="sti_guideline">
</va-modal>
</div>
</template>
<script>
import { projectInfo } from '../../../../data/project/ProjectInfo'
import { taskInfo } from '../../../../data/task/TaskInfo'
export default {
name: 'NeuliveParameterStimulation',
@@ -350,6 +369,7 @@ export default {
},
data () {
return {
showGuideLineModal: { ELECTRODE: false, PATTERN: false },
stimulationOn: false,
posChannelList: [2],
negChannelList: [1],
@@ -431,7 +451,7 @@ export default {
// posChannel and negChannel at least one && t1 ~ t4 > 0
const totalStiTime = (this.t1Range + this.t2Range + this.t3Range + this.t4Range) * 10
if (this.t1Range >= 0 && this.t2Range >= 0 && this.t3Range >= 0 && this.t4Range >= 0 && this.periodNumber === totalStiTime) {
return !(this.posChannelList.length > 0 && this.negChannelList.length > 0)
return this.stimulateElectrodeSelect ? !(this.posChannelList.length > 0 && this.negChannelList.length > 0) : !(this.posChannelList.length > 0 || this.negChannelList.length > 0)
} else {
return true
}
@@ -440,15 +460,22 @@ export default {
mqtt: {
},
methods: {
toggleModal (which) {
if (which === 'ELECTRODE') {
this.showGuideLineModal.ELECTRODE = true
} else if (which === 'PATTERN') {
this.showGuideLineModal.PATTERN = true
}
},
mqttPub: function (topic, mes) {
this.$mqtt.publish(topic, mes)
},
refresh () {
this.stimulationOn = projectInfo.getDeviceInfo(this.deviceID).parameterSet.STIMULATING
this.stimulationOn = taskInfo.getDeviceInfo(this.deviceID).parameterSet.STIMULATING
// stichannel (+,-), stiPolarity (+)
const stiChannelSet = projectInfo.getDeviceInfo(this.deviceID).parameterSet.STI_CHANNEL.toString(2).split('').reverse()
const stiPolaritySet = projectInfo.getDeviceInfo(this.deviceID).parameterSet.STI_POLARITY.toString(2).split('').reverse()
const stiChannelSet = taskInfo.getDeviceInfo(this.deviceID).parameterSet.STI_CHANNEL.toString(2).split('').reverse()
const stiPolaritySet = taskInfo.getDeviceInfo(this.deviceID).parameterSet.STI_POLARITY.toString(2).split('').reverse()
// if (stiPolaritySet.length >= stiChannelSet.length) {
this.posChannelList.length = 0
@@ -467,23 +494,27 @@ export default {
// console.log('pol',stiPolaritySet)
// console.log('pos',this.posChannelList)
// console.log('neg',this.negChannelList)
this.stimulateElectrodeSelect = projectInfo.getDeviceInfo(this.deviceID).parameterSet.STI_H_BRIDGE ? 1 : 0
this.cycleNumberSelect = projectInfo.getDeviceInfo(this.deviceID).parameterSet.CONTINUOUS_STI ? 1 : 0
this.cycleNumber = projectInfo.getDeviceInfo(this.deviceID).parameterSet.STI_CYCLE_LIST[0]
this.stimulateElectrodeSelect = taskInfo.getDeviceInfo(this.deviceID).parameterSet.STI_H_BRIDGE ? 1 : 0
this.cycleNumberSelect = taskInfo.getDeviceInfo(this.deviceID).parameterSet.CONTINUOUS_STI ? 1 : 0
this.cycleNumber = taskInfo.getDeviceInfo(this.deviceID).parameterSet.STI_CYCLE_LIST[0]
this.cycleNumberInput = String(this.cycleNumber)
this.cycleNumberArray = projectInfo.getDeviceInfo(this.deviceID).parameterSet.STI_CYCLE_LIST
this.amplitudeNumber = projectInfo.getDeviceInfo(this.deviceID).parameterSet.STI_AMPLITUDE * 5
this.cycleNumberArray = taskInfo.getDeviceInfo(this.deviceID).parameterSet.STI_CYCLE_LIST
this.amplitudeNumber = taskInfo.getDeviceInfo(this.deviceID).parameterSet.STI_AMPLITUDE * 5
this.amplitudeNumberInput = String(this.amplitudeNumber)
this.patternModeSelect = projectInfo.getDeviceInfo(this.deviceID).parameterSet.STI_PATTERN ? 1 : 0
this.t1Range = projectInfo.getDeviceInfo(this.deviceID).parameterSet.STI_T1[0]
this.patternModeSelect = taskInfo.getDeviceInfo(this.deviceID).parameterSet.STI_PATTERN ? 1 : 0
this.t1Range = taskInfo.getDeviceInfo(this.deviceID).parameterSet.STI_T1[0]
this.t1RangeInput = String((this.t1Range * 10) / this.unitMultiply)
this.t2Range = projectInfo.getDeviceInfo(this.deviceID).parameterSet.STI_T2[0]
this.t1RangeArray.fill(this.t1Range, 0)
this.t2Range = taskInfo.getDeviceInfo(this.deviceID).parameterSet.STI_T2[0]
this.t2RangeInput = String((this.t2Range * 10) / this.unitMultiply)
this.t3Range = projectInfo.getDeviceInfo(this.deviceID).parameterSet.STI_T3[0]
this.t2RangeArray.fill(this.t2Range, 0)
this.t3Range = taskInfo.getDeviceInfo(this.deviceID).parameterSet.STI_T3[0]
this.t3RangeInput = String((this.t3Range * 10) / this.unitMultiply)
this.t4Range = projectInfo.getDeviceInfo(this.deviceID).parameterSet.STI_T4[0]
this.t3RangeArray.fill(this.t3Range, 0)
this.t4Range = taskInfo.getDeviceInfo(this.deviceID).parameterSet.STI_T4[0]
this.t4RangeInput = String((this.t4Range * 10) / this.unitMultiply)
this.t4RangeArray.fill(this.t4Range, 0)
if (this.pattternModeSelect === 0) {
this.periodNumber = (this.t1Range + this.t4Range) * 10
@@ -499,10 +530,10 @@ export default {
// console.log('STI_CONTINUOUS', this.cycleNumberSelect)
// console.log('STI_H_BRIDGE', this.stimulateElectrodeSelect)
// console.log('STI_PATTERN', this.patternModeSelect)
// console.log('STI_T1', projectInfo.getDeviceInfo(this.deviceID).parameterSet.STI_T1[0])
// console.log('STI_T2', projectInfo.getDeviceInfo(this.deviceID).parameterSet.STI_T2[0])
// console.log('STI_T3', projectInfo.getDeviceInfo(this.deviceID).parameterSet.STI_T3[0])
// console.log('STI_T4', projectInfo.getDeviceInfo(this.deviceID).parameterSet.STI_T4[0])
// console.log('STI_T1', taskInfo.getDeviceInfo(this.deviceID).parameterSet.STI_T1[0])
// console.log('STI_T2', taskInfo.getDeviceInfo(this.deviceID).parameterSet.STI_T2[0])
// console.log('STI_T3', taskInfo.getDeviceInfo(this.deviceID).parameterSet.STI_T3[0])
// console.log('STI_T4', taskInfo.getDeviceInfo(this.deviceID).parameterSet.STI_T4[0])
// console.log(this.periodNumber)
// console.log(this.periodNumberInput)
// console.log(this.frequencyNumber)
@@ -521,21 +552,21 @@ export default {
stimulateClick () {
this.stimulationOn = !this.stimulationOn
if (this.stimulationOn) {
this.mqttPub(projectInfo.getProjectInfo().controllerID + '_user', JSON.stringify({
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_instruction/0',
device: projectInfo.getRawDeviceID(this.deviceID),
device: taskInfo.getRawDeviceID(this.deviceID),
instruction: 'stimulate',
}))
} else {
this.mqttPub(projectInfo.getProjectInfo().controllerID + '_user', JSON.stringify({
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_instruction/0',
device: projectInfo.getRawDeviceID(this.deviceID),
device: taskInfo.getRawDeviceID(this.deviceID),
instruction: 'stop_stimulate',
}))
}
this.mqttPub(projectInfo.getProjectInfo().controllerID + '_user', JSON.stringify({
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: projectInfo.getRawDeviceID(this.deviceID),
device: taskInfo.getRawDeviceID(this.deviceID),
parameter: 'STIMULATING',
content: this.stimulationOn,
}))
@@ -544,10 +575,10 @@ export default {
if (this.stimulateElectrodeSelect == null) {
return false
}
if (this.stimulateElectrodeSelect !== projectInfo.getDeviceInfo(this.deviceID).parameterSet.STI_H_BRIDGE) {
this.mqttPub(projectInfo.getProjectInfo().controllerID + '_user', JSON.stringify({
if (this.stimulateElectrodeSelect !== taskInfo.getDeviceInfo(this.deviceID).parameterSet.STI_H_BRIDGE) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: projectInfo.getRawDeviceID(this.deviceID),
device: taskInfo.getRawDeviceID(this.deviceID),
parameter: 'STI_H_BRIDGE',
content: this.stimulateElectrodeSelect,
}))
@@ -568,17 +599,17 @@ export default {
if (this.cycleNumberSelect == null) {
return false
}
if (this.cycleNumberSelect !== projectInfo.getDeviceInfo(this.deviceID).parameterSet.CONTINUOUS_STI) {
this.mqttPub(projectInfo.getProjectInfo().controllerID + '_user', JSON.stringify({
if (this.cycleNumberSelect !== taskInfo.getDeviceInfo(this.deviceID).parameterSet.CONTINUOUS_STI) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: projectInfo.getRawDeviceID(this.deviceID),
device: taskInfo.getRawDeviceID(this.deviceID),
parameter: 'CONTINUOUS_STI',
content: this.cycleNumberSelect,
}))
}
},
cycleNumberChange (val) {
if (isNaN(val) || parseInt(val) > 256 || parseInt(val) < 1) {
if (isNaN(val) || parseInt(val) > 255 || parseInt(val) < 1) {
this.cycleNumberInput = '1'
this.cycleNumber = 1
}
@@ -587,9 +618,9 @@ export default {
if (this.cycleNumberArray[0] !== this.cycleNumber) {
this.cycleNumberArray.fill(this.cycleNumber, 0)
this.mqttPub(projectInfo.getProjectInfo().controllerID + '_user', JSON.stringify({
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: projectInfo.getRawDeviceID(this.deviceID),
device: taskInfo.getRawDeviceID(this.deviceID),
parameter: 'STI_CYCLE_LIST',
content: '0:9=' + this.cycleNumberArray.toString(),
}))
@@ -617,12 +648,13 @@ export default {
this.amplitudeNumber = val
}
}
if (parseInt(this.amplitudeNumber / 5) !== parseInt(projectInfo.getDeviceInfo(this.deviceID).parameterSet.STI_AMPLITUDE)) {
this.mqttPub(projectInfo.getProjectInfo().controllerID + '_user', JSON.stringify({
if (parseInt(this.amplitudeNumber / 5) !== parseInt(taskInfo.getDeviceInfo(this.deviceID).parameterSet.STI_AMPLITUDE)) {
const content = parseInt(this.amplitudeNumber / 5)
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: projectInfo.getRawDeviceID(this.deviceID),
parameter: 'STI_AMPLITUDE',
content: parseInt(this.amplitudeNumber / 5),
device: taskInfo.getRawDeviceID(this.deviceID),
parameter: 'STI_AMPLITUDE|STI_AMPLITUDE_H|STI_AMPLITUDE_L',
content: `${content}|${content}|${content}`,
}))
}
},
@@ -643,14 +675,15 @@ export default {
this.t4Range = (this.periodNumber / 10) - this.t1Range - this.t2Range - this.t3Range
this.t4RangeInput = String((this.t4Range * 10) / this.unitMultiply)
}
if (this.patternModeSelect !== projectInfo.getDeviceInfo(this.deviceID).parameterSet.STI_PATTERN) {
this.mqttPub(projectInfo.getProjectInfo().controllerID + '_user', JSON.stringify({
if (this.patternModeSelect !== taskInfo.getDeviceInfo(this.deviceID).parameterSet.STI_PATTERN) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: projectInfo.getRawDeviceID(this.deviceID),
device: taskInfo.getRawDeviceID(this.deviceID),
parameter: 'STI_PATTERN',
content: this.patternModeSelect,
}))
}
this.updateTimeRange()
},
frequencyNumberChange (val) {
if (this.frequencyNumberInput == null) {
@@ -718,8 +751,10 @@ export default {
case 1:
this.t1Range = parseInt((val * this.unitMultiply) / 10)
this.t1RangeInput = val
this.t3Range = parseInt((val * this.unitMultiply) / 10)
this.t3RangeInput = val
if (this.patternModeSelect === 1) {
this.t3Range = parseInt((val * this.unitMultiply) / 10)
this.t3RangeInput = val
}
break
case 2:
this.t2Range = parseInt((val * this.unitMultiply) / 10)
@@ -768,58 +803,46 @@ export default {
const stiChannelValue = parseInt(stiChannelSet, 2)
const stiPolarityValue = parseInt(stiPolaritySet, 2)
if (stiChannelValue !== projectInfo.getDeviceInfo(this.deviceID).STI_CHANNEL) {
this.mqttPub(projectInfo.getProjectInfo().controllerID + '_user', JSON.stringify({
if (stiChannelValue !== taskInfo.getDeviceInfo(this.deviceID).STI_CHANNEL || stiPolarityValue !== taskInfo.getDeviceInfo(this.deviceID).STI_POLARITY) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: projectInfo.getRawDeviceID(this.deviceID),
parameter: 'STI_CHANNEL',
content: stiChannelValue,
}))
}
if (stiPolarityValue !== projectInfo.getDeviceInfo(this.deviceID).STI_POLARITY) {
this.mqttPub(projectInfo.getProjectInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: projectInfo.getRawDeviceID(this.deviceID),
parameter: 'STI_POLARITY',
content: stiPolarityValue,
device: taskInfo.getRawDeviceID(this.deviceID),
parameter: 'STI_CHANNEL|STI_POLARITY',
content: `${stiChannelValue}|${stiPolarityValue}`,
}))
}
},
updateTimeRange () {
let parameter = ''
let content = ''
if (this.t1RangeArray[0] !== this.t1Range) {
this.t1RangeArray.fill(this.t1Range, 0)
this.mqttPub(projectInfo.getProjectInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: projectInfo.getRawDeviceID(this.deviceID),
parameter: 'STI_T1',
content: '0:9=' + String(this.t1RangeArray),
}))
parameter += 'STI_T1|'
content += '0:9=' + String(this.t1RangeArray) + '|'
}
if (this.t2RangeArray[0] !== this.t2Range) {
this.t2RangeArray.fill(this.t2Range, 0)
this.mqttPub(projectInfo.getProjectInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: projectInfo.getRawDeviceID(this.deviceID),
parameter: 'STI_T2',
content: '0:9=' + String(this.t2RangeArray),
}))
parameter += 'STI_T2|'
content += '0:9=' + String(this.t2RangeArray) + '|'
}
if (this.t3RangeArray[0] !== this.t3Range) {
this.t3RangeArray.fill(this.t3Range, 0)
this.mqttPub(projectInfo.getProjectInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: projectInfo.getRawDeviceID(this.deviceID),
parameter: 'STI_T3',
content: '0:9=' + String(this.t3RangeArray),
}))
parameter += 'STI_T3|'
content += '0:9=' + String(this.t3RangeArray) + '|'
}
if (this.t4RangeArray[0] !== this.t4Range) {
this.t4RangeArray.fill(this.t4Range, 0)
this.mqttPub(projectInfo.getProjectInfo().controllerID + '_user', JSON.stringify({
parameter += 'STI_T4|'
content += '0:9=' + String(this.t4RangeArray) + '|'
}
if (parameter.length > 0) {
parameter = parameter.slice(0, -1)
content = content.slice(0, -1)
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: projectInfo.getRawDeviceID(this.deviceID),
parameter: 'STI_T4',
content: '0:9=' + String(this.t4RangeArray),
device: taskInfo.getRawDeviceID(this.deviceID),
parameter: parameter,
content: content,
}))
}
},
@@ -831,3 +854,21 @@ export default {
},
}
</script>
<style lang="scss">
.sti_guideline {
height: 75vh;
width: 65vw;
text-align: left;
justify-content: center;
position: relative;
}
.sti_pattern_img {
height: 22.5vh;
width: 17.5vw;
text-align: center;
justify-content: center;
position: relative;
}
</style>
@@ -7,7 +7,7 @@
:label="'RECORDING'"
>
<va-tree-node>
<neulive-parameter-recording :ref="'rec_ref'" :deviceID="deviceID"/>
<neulive-parameter-recording :ref="'rec_ref'" :deviceID="deviceID" @record="start()" @record_stop="stop()"/>
</va-tree-node>
</va-tree-category>
<va-tree-category
@@ -23,7 +23,7 @@
</template>
<script>
import { projectInfo } from '../../../../data/project/ProjectInfo'
import { taskInfo } from '../../../../data/task/TaskInfo'
import NeuliveParameterRecording from './NeuliveParameterRecording'
import NeuliveParameterStimulation from './NeuliveParameterStimulation'
@@ -54,9 +54,9 @@ export default {
this.$mqtt.publish(topic, mes)
},
pageInit: function () {
this.mqttPub(projectInfo.getProjectInfo().controllerID + '_user', JSON.stringify({
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'get_device_info/0',
device: projectInfo.getRawDeviceID(this.deviceID),
device: taskInfo.getRawDeviceID(this.deviceID),
}))
},
loadingState: function (state) {
@@ -72,15 +72,21 @@ export default {
}
})
},
start: function () {
this.$emit('record')
},
stop: function () {
this.$emit('record_stop')
},
},
mounted () {
this.pageInit()
},
watch: {
deviceID: function (val) {
this.mqttPub(projectInfo.getProjectInfo().controllerID + '_user', JSON.stringify({
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'get_device_info/0',
device: projectInfo.getRawDeviceID(val),
device: taskInfo.getRawDeviceID(val),
}))
},
},
@@ -0,0 +1,104 @@
<template>
<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)">
{{ minValue }}
</va-button>
<va-input
@mouseleave.native="cycleNumberChange(cycleNoNumberInput)"
@keyup.enter="cycleNumberChange(cycleNoNumberInput)"
@blur="cycleNumberChange(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)">
{{ maxValue }}
</va-button>
</div>
<va-slider
@mouseup.native="cycleNumberChange(cycleNoNumber)"
@mouseleave.native="cycleNumberChange(cycleNoNumber)"
@touchend.native="cycleNumberChange(cycleNoNumber)"
@click.native="cycleNumberChange(cycleNoNumber)"
class="flex sm12 xl12 md12 xs12"
v-model="cycleNoNumber"
:min="minValue"
:max="maxValue"
/>
</div>
</div>
</template>
<script>
import { taskInfo } from '../../../../../data/task/TaskInfo'
export default {
name: 'CycleRange',
components: {
},
props: {
deviceID: {
type: Number,
required: true,
},
parameterName: {
type: String,
required: true,
},
minValue: {
type: Number,
default: 1,
},
maxValue: {
type: Number,
default: 250,
},
},
created () {
},
data () {
return {
inputeKey: 0,
cycleNoNumber: taskInfo.getDeviceInfo(this.deviceID).parameterSet[this.parameterName],
cycleNoNumberInput: String(taskInfo.getDeviceInfo(this.deviceID).parameterSet[this.parameterName]),
}
},
mqtt: {
},
methods: {
cycleNumberChange (val) {
this.inputeKey++
if (this.cycleNoNumber == null) {
return false
}
if (isNaN(val) || parseInt(val) > this.maxValue || parseInt(val) < this.minValue) {
this.cycleNoNumber = this.minValue
this.cycleNoNumberInput = String(this.minValue)
return false
}
if (this.cycleNoNumberInput !== this.cycleNoNumber || this.cycleNoNumber !== val) {
this.cycleNoNumberInput = String(val)
this.cycleNoNumber = parseInt(val)
}
if (this.cycleNoNumber !== taskInfo.getDeviceInfo(this.deviceID).parameterSet[this.parameterName]) {
this.$emit('parameterChange', [this.parameterName, this.cycleNoNumber])
}
},
updateCycleNumber (val) {
this.cycleNumberChange(val)
},
},
async mounted () {
},
destroyed () {
},
watch: {
},
}
</script>
@@ -0,0 +1,71 @@
<template>
<div class="row">
<div class="flex sm12 xl12 md12 xs12">
<va-button-toggle
@click.native="levelButtonSelectChange(levelButtonSelect)"
small
outline
v-model="levelButtonSelect"
:options="options"
/>
</div>
</div>
</template>
<script>
import { taskInfo } from '../../../../../data/task/TaskInfo'
export default {
name: 'LevelButton',
components: {
},
props: {
deviceID: {
type: Number,
required: true,
},
parameterName: {
type: String,
required: true,
},
options: {
type: Array,
required: true,
},
},
created () {
},
data () {
return {
levelButtonSelect: taskInfo.getDeviceInfo(this.deviceID).parameterSet[this.parameterName],
}
},
mqtt: {
},
methods: {
levelButtonSelectChange (val) {
if (this.levelButtonSelect == null) {
return false
}
this.levelButtonSelect = val
if (this.levelButtonSelect !== taskInfo.getDeviceInfo(this.deviceID).parameterSet[this.parameterName]) {
this.$emit('parameterChange', [this.parameterName, this.levelButtonSelect])
}
},
updateLevelButton (val) {
this.levelButtonSelectChange(val)
},
},
async mounted () {
},
destroyed () {
},
watch: {
},
}
</script>
@@ -0,0 +1,117 @@
<template>
<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)">
{{ minValue }}
</va-button>
<va-input
@mouseleave.native="currentNumberChange(currentNumberInput)"
@keyup.enter="currentNumberChange(currentNumberInput)"
@blur="currentNumberChange(currentNumberInput)"
v-model="currentNumberInput"
class="mb-0"
style="width: 100px;"
>
<p slot="append" style="margin-right: 0;" small>
μA
</p>
</va-input>
<va-button slot="append" class="ml-2 pa-1 shrink" small @click="currentNumberChange(maxValue*100)">
{{ maxValue }}
</va-button>
</div>
<va-slider
@mouseup.native="currentNumberChange(currentNumber)"
@mouseleave.native="currentNumberChange(currentNumber)"
@touchend.native="currentNumberChange(currentNumber)"
@click.native="currentNumberChange(currentNumber)"
class="flex sm12 xl12 md12 xs12"
v-model="currentNumber"
:min="minValue*100"
:max="maxValue*100"
/>
</div>
</div>
</template>
<script>
import { taskInfo } from '../../../../../data/task/TaskInfo'
export default {
name: 'MicroAmpereRange',
components: {
},
props: {
deviceID: {
type: Number,
required: true,
},
parameterName: {
type: String,
required: true,
},
minValue: {
type: Number,
default: 0.2,
},
maxValue: {
type: Number,
default: 100,
},
},
created () {
},
data () {
return {
inputeKey: 0,
currentNumber: taskInfo.getDeviceInfo(this.deviceID).parameterSet[this.parameterName],
currentNumberInput: String(parseFloat(taskInfo.getDeviceInfo(this.deviceID).parameterSet[this.parameterName] / 100).toFixed(2)),
}
},
mqtt: {
},
methods: {
currentNumberChange (val) {
this.inputeKey++
if (this.currentNumber == null) {
return false
}
if (typeof (val) === 'string') {
if (isNaN(val) || parseFloat(val) > this.maxValue * 100 || parseFloat(val) < this.minValue * 100) {
this.currentNumberInput = '0.00'
this.currentNumber = 0
return false
}
if (parseFloat(this.currentNumberInput) !== parseFloat(this.currentNumber / 100)) {
this.currentNumber = parseInt(parseFloat(val).toFixed(2) * 100)
this.currentNumberInput = String(parseFloat(this.currentNumber / 100).toFixed(2))
}
} else {
if (isNaN(val) || parseFloat(val) > this.maxValue * 100 || parseFloat(val) < this.minValue * 100) {
this.currentNumberInput = '0.00'
this.currentNumber = 0
return false
}
if (parseFloat(this.currentNumberInput) !== parseFloat(this.currentNumber / 100) || this.currentNumber !== val) {
this.currentNumberInput = String(parseFloat(val / 100).toFixed(2))
this.currentNumber = val
}
}
if (this.currentNumber !== taskInfo.getDeviceInfo(this.deviceID).parameterSet[this.parameterName]) {
this.$emit('parameterChange', [this.parameterName, this.currentNumber])
}
},
updateMicroAmpereNumber (val) {
this.currentNumberChange(val)
},
},
async mounted () {
},
destroyed () {
},
watch: {
},
}
</script>
@@ -0,0 +1,126 @@
<template>
<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)">
{{ minValue }}
</va-button>
<va-input
@mouseleave.native="stepVoltNumberChange(voltNumberInput)"
@keyup.enter="stepVoltNumberChange(voltNumberInput)"
@blur="stepVoltNumberChange(voltNumberInput)"
v-model="voltNumberInput"
class="mb-0"
style="width: 100px;"
>
<p slot="append" style="margin-right: 0;" small>
mV
</p>
</va-input>
<va-button slot="append" class="ml-2 pa-1 shrink" small @click="stepVoltNumberChange(maxValue*10)">
{{ maxValue }}
</va-button>
</div>
<va-slider
@mouseup.native="stepVoltNumberChange(voltNumber)"
@mouseleave.native="stepVoltNumberChange(voltNumber)"
@touchend.native="stepVoltNumberChange(voltNumber)"
@click.native="stepVoltNumberChange(voltNumber)"
class="flex sm12 xl12 md12 xs12"
v-model="voltNumber"
:min="minValue*10"
:max="maxValue*10"
/>
</div>
</div>
</template>
<script>
import { taskInfo } from '../../../../../data/task/TaskInfo'
export default {
name: 'MilliVoltRange',
components: {
},
props: {
deviceID: {
type: Number,
required: true,
},
parameterName: {
type: String,
required: true,
},
minValue: {
type: Number,
default: 0.2,
},
maxValue: {
type: Number,
default: 100,
},
},
created () {
},
data () {
return {
inputeKey: 0,
voltNumber: taskInfo.getDeviceInfo(this.deviceID).parameterSet[this.parameterName],
voltNumberInput: String(parseFloat(taskInfo.getDeviceInfo(this.deviceID).parameterSet[this.parameterName] / 10).toFixed(1)),
}
},
mqtt: {
},
methods: {
stepVoltNumberChange (val) {
this.inputeKey++
if (this.voltNumber == null) {
return false
}
if (typeof (val) === 'string') {
if (isNaN(val) || parseFloat(val) > 100 || parseFloat(val) < 0.2) {
this.voltNumberInput = '0.2'
this.voltNumber = 2
return false
}
// console.log('conpare',parseFloat(this.voltNumberInput),parseFloat(this.voltNumber / 10))
if (parseFloat(this.voltNumberInput) !== parseFloat(this.voltNumber / 10)) {
if (Math.floor(parseFloat(val) * 10) % 2 !== 0) { // odd number
this.voltNumber = Math.floor(parseFloat(val) * 10) + 1
this.voltNumberInput = String(parseFloat(this.voltNumber / 10).toFixed(1))
} else {
this.voltNumber = Math.floor(parseFloat(val) * 10)
this.voltNumberInput = String(parseFloat(this.voltNumber / 10).toFixed(1))
}
}
} else {
if (isNaN(val) || parseFloat(val) > 1000 || parseFloat(val) < 2) {
this.voltNumberInput = '0.2'
this.voltNumber = 2
return false
}
if (parseFloat(this.voltNumberInput) !== parseFloat(this.voltNumber / 10) || this.voltNumber !== val) {
if (this.voltNumber % 2 !== 0) { // odd number
val = val + 1
}
this.voltNumberInput = String(parseFloat(val / 10).toFixed(1))
this.voltNumber = val
}
}
if (this.voltNumber !== taskInfo.getDeviceInfo(this.deviceID).parameterSet[this.parameterName]) {
this.$emit('parameterChange', [this.parameterName, this.voltNumber])
}
},
updateStepVoltNumber (val) {
this.stepVoltNumberChange(val)
},
},
async mounted () {
},
destroyed () {
},
watch: {
},
}
</script>
@@ -0,0 +1,78 @@
<template>
<div class="row">
<div class="flex sm12 xl12 md12 xs12">
<va-button-toggle
@click.native="levelButtonSelectChange(levelButtonSelect)"
small
outline
v-model="levelButtonSelect"
:options="options"
/>
</div>
</div>
</template>
<script>
import { taskInfo } from '../../../../../data/task/TaskInfo'
export default {
name: 'LevelButton',
components: {
},
props: {
deviceID: {
type: Number,
required: true,
},
parameterName: {
type: String,
required: true,
},
options: {
type: Array,
required: true,
},
},
created () {
},
data () {
return {
levelButtonSelect: (taskInfo.getDeviceInfo(this.deviceID).parameterSet[this.parameterName] + 1) % 2,
}
},
mqtt: {
},
methods: {
levelButtonSelectChange (val) {
if (this.levelButtonSelect == null) {
return false
}
this.levelButtonSelect = val
let _charge
if (this.levelButtonSelect === 0) {
_charge = 1
} else {
_charge = 0
}
if (_charge !== taskInfo.getDeviceInfo(this.deviceID).parameterSet[this.parameterName]) {
this.$emit('parameterChange', [this.parameterName, _charge])
}
},
updateLevelButton (val) {
this.levelButtonSelectChange(val)
},
},
async mounted () {
},
destroyed () {
},
watch: {
},
}
</script>
@@ -0,0 +1,117 @@
<template>
<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)">
{{ minValue }}
</va-button>
<va-input
@mouseleave.native="resolutionNumberChange(resolutionNumberInput)"
@keyup.enter="resolutionNumberChange(resolutionNumberInput)"
@blur="resolutionNumberChange(resolutionNumberInput)"
v-model="resolutionNumberInput"
class="mb-0"
style="width: 100px;"
>
<p slot="append" style="margin-right: 0;" small>
sps
</p>
</va-input>
<va-button slot="append" class="ml-2 pa-1 shrink" small @click="resolutionNumberChange(maxValue*10)">
{{ maxValue }}
</va-button>
</div>
<va-slider
@mouseup.native="resolutionNumberChange(resolutionNumber)"
@mouseleave.native="resolutionNumberChange(resolutionNumber)"
@touchend.native="resolutionNumberChange(resolutionNumber)"
@click.native="resolutionNumberChange(resolutionNumber)"
class="flex sm12 xl12 md12 xs12"
v-model="resolutionNumber"
:min="minValue*10"
:max="maxValue*10"
/>
</div>
</div>
</template>
<script>
import { taskInfo } from '../../../../../data/task/TaskInfo'
export default {
name: 'ResolutionRange',
components: {
},
props: {
deviceID: {
type: Number,
required: true,
},
parameterName: {
type: String,
required: true,
},
minValue: {
type: Number,
default: 0.2,
},
maxValue: {
type: Number,
default: 100,
},
},
created () {
},
data () {
return {
inputeKey: 0,
resolutionNumber: taskInfo.getDeviceInfo(this.deviceID).parameterSet[this.parameterName],
resolutionNumberInput: String(((taskInfo.getDeviceInfo(this.deviceID).parameterSet[this.parameterName]) / 10).toFixed(1)),
}
},
mqtt: {
},
methods: {
resolutionNumberChange (val) {
this.inputeKey++
if (this.resolutionNumber == null) {
return false
}
if (typeof (val) === 'string') {
if (isNaN(val) || parseFloat(val) > 100 || parseFloat(val) < 0.1) {
this.resolutionNumberInput = '0.1'
this.resolutionNumber = 1
return false
}
if (parseFloat(this.resolutionNumberInput) !== parseFloat(this.resolutionNumber / 10)) {
this.resolutionNumber = parseInt(parseFloat(val) * 10)
this.resolutionNumberInput = String(parseFloat(this.resolutionNumber / 10).toFixed(1))
}
} else {
if (isNaN(val) || parseFloat(val) > 1000 || parseFloat(val) < 1) {
this.resolutionNumberInput = '0.1'
this.resolutionNumber = 1
return false
}
if (parseFloat(this.resolutionNumberInput) !== parseFloat(this.resolutionNumber / 10) || this.resolutionNumber !== val) {
this.resolutionNumberInput = String(parseFloat(val / 10).toFixed(1))
this.resolutionNumber = val
}
}
if ((this.resolutionNumber) !== taskInfo.getDeviceInfo(this.deviceID).parameterSet[this.parameterName]) {
this.$emit('parameterChange', [this.parameterName, this.resolutionNumber])
}
},
updateResolutionNumber (val) {
this.resolutionNumberChange(val)
},
},
async mounted () {
},
destroyed () {
},
watch: {
},
}
</script>
@@ -0,0 +1,117 @@
<template>
<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)">
{{ minValue }}
</va-button>
<va-input
@mouseleave.native="voltScanRateNumberChange(voltScanRateNumberInput)"
@keyup.enter="voltScanRateNumberChange(voltScanRateNumberInput)"
@blur="voltScanRateNumberChange(voltScanRateNumberInput)"
v-model="voltScanRateNumberInput"
class="mb-0"
style="width: 100px;"
>
<p slot="append" style="margin-right: 0;" small>
mV
</p>
</va-input>
<va-button slot="append" class="ml-2 pa-1 shrink" small @click="voltScanRateNumberChange(maxValue*100)">
{{ maxValue }}
</va-button>
</div>
<va-slider
@mouseup.native="voltScanRateNumberChange(voltScanRateNumber)"
@mouseleave.native="voltScanRateNumberChange(voltScanRateNumber)"
@touchend.native="voltScanRateNumberChange(voltScanRateNumber)"
@click.native="voltScanRateNumberChange(voltScanRateNumber)"
class="flex sm12 xl12 md12 xs12"
v-model="voltScanRateNumber"
:min="minValue*100"
:max="maxValue*100"
/>
</div>
</div>
</template>
<script>
import { taskInfo } from '../../../../../data/task/TaskInfo'
export default {
name: 'MicroAmpereRange',
components: {
},
props: {
deviceID: {
type: Number,
required: true,
},
parameterName: {
type: String,
required: true,
},
minValue: {
type: Number,
default: 0.2,
},
maxValue: {
type: Number,
default: 100,
},
},
created () {
},
data () {
return {
inputeKey: 0,
voltScanRateNumber: taskInfo.getDeviceInfo(this.deviceID).parameterSet[this.parameterName],
voltScanRateNumberInput: String(((taskInfo.getDeviceInfo(this.deviceID).parameterSet.Scan_Rate) / 100).toFixed(2)),
}
},
mqtt: {
},
methods: {
voltScanRateNumberChange (val) {
this.inputeKey++
if (this.voltScanRateNumber == null) {
return false
}
if (typeof (val) === 'string') {
if (isNaN(val) || parseFloat(val) > 1000 || parseFloat(val) < 0.01) {
this.voltScanRateNumberInput = '0.01'
this.voltScanRateNumber = 1
return false
}
if (parseFloat(this.voltScanRateNumberInput) !== parseFloat(this.voltScanRateNumber / 100)) {
this.voltScanRateNumber = parseInt((parseFloat(val) * 100).toFixed(0))
this.voltScanRateNumberInput = String(parseFloat(this.voltScanRateNumber / 100).toFixed(2))
}
} else {
if (isNaN(val) || parseFloat(val) > 100000 || parseFloat(val) < 1) {
this.voltScanRateNumberInput = '0.01'
this.voltScanRateNumber = 1
return false
}
if (parseFloat(this.voltScanRateNumberInput) !== parseFloat(this.voltScanRateNumber / 100) || this.voltScanRateNumber !== val) {
this.voltScanRateNumberInput = String(parseFloat(val / 100).toFixed(2))
this.voltScanRateNumber = val
}
}
if (this.voltScanRateNumber !== parseFloat(taskInfo.getDeviceInfo(this.deviceID).parameterSet[this.parameterName])) {
this.$emit('parameterChange', [this.parameterName, this.voltScanRateNumber])
}
},
updateVoltScanRateNumber (val) {
this.voltScanRateNumberChange(val)
},
},
async mounted () {
},
destroyed () {
},
watch: {
},
}
</script>
@@ -0,0 +1,117 @@
<template>
<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)">
{{ minValue }}
</va-button>
<va-input
@mouseleave.native="voltNumberChange(voltNumberInput)"
@keyup.enter="voltNumberChange(voltNumberInput)"
@blur="voltNumberChange(voltNumberInput)"
v-model="voltNumberInput"
class="mb-0"
style="width: 100px;"
>
<p slot="append" style="margin-right: 0;" small>
V
</p>
</va-input>
<va-button slot="append" class="ml-2 pa-1 shrink" small @click="voltNumberChange(maxValue*1000)">
{{ maxValue }}
</va-button>
</div>
<va-slider
@mouseup.native="voltNumberChange(voltNumber)"
@mouseleave.native="voltNumberChange(voltNumber)"
@touchend.native="voltNumberChange(voltNumber)"
@click.native="voltNumberChange(voltNumber)"
class="flex sm12 xl12 md12 xs12"
v-model="voltNumber"
:min="minValue*1000"
:max="maxValue*1000"
/>
</div>
</div>
</template>
<script>
import { taskInfo } from '../../../../../data/task/TaskInfo'
export default {
name: 'VoltRange',
components: {
},
props: {
deviceID: {
type: Number,
required: true,
},
parameterName: {
type: String,
required: true,
},
minValue: {
type: Number,
default: -5,
},
maxValue: {
type: Number,
default: 5,
},
},
created () {
},
data () {
return {
inputeKey: 0,
voltNumber: (taskInfo.getDeviceInfo(this.deviceID).parameterSet[this.parameterName] - 25000) / 5,
voltNumberInput: String(parseFloat((taskInfo.getDeviceInfo(this.deviceID).parameterSet[this.parameterName] - 25000) / 5000).toFixed(3)),
}
},
mqtt: {
},
methods: {
voltNumberChange (val) {
this.inputeKey++
if (this.voltNumber == null) {
return false
}
if (typeof (val) === 'string') {
if (isNaN(val) || parseFloat(val) > 5 || parseFloat(val) < -5) {
this.voltNumberInput = '0.00'
this.voltNumber = 0
return false
}
if (parseFloat(this.voltNumberInput) !== parseFloat(this.voltNumber / 1000)) {
this.voltNumber = parseInt(parseFloat(val).toFixed(3) * 1000)
this.voltNumberInput = String(parseFloat(this.voltNumber / 1000).toFixed(3))
}
} else {
if (isNaN(val) || parseFloat(val) > 5000 || parseFloat(val) < -5000) {
this.voltNumberInput = '0.00'
this.voltNumber = 0
return false
}
if (parseFloat(this.voltNumberInput) !== parseFloat(this.voltNumber / 1000) || this.voltNumber !== val) {
this.voltNumberInput = String(parseFloat(val / 1000).toFixed(3))
this.voltNumber = val
}
}
if (this.voltNumber !== (taskInfo.getDeviceInfo(this.deviceID).parameterSet[this.parameterName] - 25000) / 5) {
this.$emit('parameterChange', [this.parameterName, this.voltNumber * 5 + 25000])
}
},
updateVoltNumber (val) {
this.voltNumberChange(val)
},
},
async mounted () {
},
destroyed () {
},
watch: {
},
}
</script>
@@ -1,669 +0,0 @@
import { projectInfo } from './ProjectInfo'
// generate x axis format
function makeXAxis (gridIndex, type) {
return {
type: type,
gridIndex: gridIndex,
axisLine: { onZero: false, lineStyle: { color: '#aaa' } },
axisTick: { show: false },
axisLabel: { show: true, showMinLabel: false, showMaxLabel: false, color: '#aaa' },
splitLine: { show: false, lineStyle: { color: '#ddd' } },
scale: true,
min: null,
max: null,
}
}
// generate y axis format
function makeYAxis (gridIndex, type) {
return {
type: type,
gridIndex: gridIndex,
axisTick: { show: false },
axisLine: { show: false }, // color: '#ccc' } },
axisLabel: { show: true, color: '#aaa', showMinLabel: false, showMaxLabel: false },
splitLine: { show: true, lineStyle: { color: '#eee' } },
animation: false,
scale: true,
min: null,
max: null,
}
}
// generate grid
function makeGrid (index, length) {
const _height = (80 / length) + '%'
const _top = index * (80 / length) + 1 + '%'
return {
index: index,
top: _top,
height: _height,
series: [],
}
}
// get legend name
function getLegendName (sourceList, formulaID) {
let legendName = ''
if (formulaID == null) {
// source only 2 device
sourceList.forEach(source => {
switch (source.name) {
case 'Time':
legendName += 'T'
break
case 'Neulive':
legendName += 'N' + source.id + 'CH' + source.channel
break
case 'Elite':
switch (source.channel) {
case 1:
legendName += 'E' + source.id + '-I'
break
case 2:
legendName += 'E' + source.id + '-V'
break
case 3:
legendName += 'E' + source.id + '-R'
break
default:
legendName += 'E' + source.id + 'CH' + source.channel
break
}
break
default:
legendName += 'D' + source.id + 'CH' + source.channel
break
}
legendName += '_'
})
legendName = legendName.substr(0, legendName.length - 1)
} else {
legendName = 'T_F' + formulaID
}
return legendName
}
const _chartData = {}
function updateGridList (chartID, length) {
_chartData[chartID].grid = []
for (let i = 0; i < length; i++) {
_chartData[chartID].grid.push(makeGrid(i, length))
}
}
export const chartData = {
// init chartID to chartData
init: (chartID, maxDots, samplingRate, gridLength) => {
if (_chartData[parseInt(chartID)] == null) {
_chartData[parseInt(chartID)] = {
chartID: parseInt(chartID),
cardName: 'chart' + String(chartID),
cardHeight: '500px',
cardWidth: 'auto',
mappingID: -1,
run: false,
rate: samplingRate,
maxDots: maxDots,
timer: 0,
legend: {
data: [],
x: 'center',
y: '88%',
},
tooltip: {},
axisPointer: {
link: [{ xAxisIndex: 'all' }],
snap: true,
},
grid: [],
xAxis: [],
yAxis: [],
dataZoom: [{
type: 'slider',
height: '15px',
bottom: '0%',
handleStyle: {
shadowColor: 'rgba(0, 0, 0, 0)',
},
showDataShadow: false,
showDetail: false,
xAxisIndex: [],
}, {
type: 'inside',
xAxisIndex: [],
},
{
type: 'slider',
height: '80%',
showDataShadow: false,
showDetail: false,
width: '15px',
// right: '5%',
yAxisIndex: [],
}],
series: [],
}
_chartData[chartID].tooltip = {
trigger: 'axis',
backgroundColor: '#fff',
borderColor: 'rgba(0, 0, 200, 0.2)',
borderWidth: 1,
borderRadius: 0,
padding: 10,
formatter: function (params) {
if (params.length) {
if (params[0].seriesName.split('_')[0] === 'T' && params[0].seriesName.split('_')[1] !== 'T') {
params.unshift({ seriesName: 'Time', value: [null, parseFloat(params[0].value[0] / 1000).toFixed(3) + ' s'], color: '#5193f2' })
} else if (params[0].seriesName.split('_')[0] !== 'T' && params[0].seriesName.split('_')[1] === 'T') {
params.unshift({ seriesName: 'Time', value: [null, parseFloat(params[0].value[1] / 1000).toFixed(3) + ' s'], color: '#5193f2' })
} else {
params.unshift({ seriesName: 'Time', value: [null, parseFloat(params[0].value[2] / 1000).toFixed(3) + ' s'], color: '#5193f2' })
}
let tip = ''
for (var i = 0; i < params.length; i++) {
const param = params[i]
const style = 'color: ' + param.color
let value
// console.log(param.value)
if (param.seriesName === 'Time') {
value = param.value[1]
} else if (param.seriesName.split('_')[1] === 'T' && param.seriesName.split('_')[0] !== 'T') {
if (param.seriesName.split('_')[0][param.seriesName.split('_')[0].length - 1] === 'V') {
value = parseFloat(param.value[0]).toFixed(3) + ' μV'
} else if (param.seriesName.split('_')[0][param.seriesName.split('_')[0].length - 1] === 'I') {
value = parseFloat(param.value[0]).toFixed(3) + ' nA'
} else if (param.seriesName.split('_')[0][param.seriesName.split('_')[0].length - 1] === 'R') {
value = parseFloat(param.value[0]).toFixed(3) + ' kΩ'
} else {
value = parseFloat(param.value[0]).toFixed(3)
}
} else if (param.seriesName.split('_')[1] !== 'T' && param.seriesName.split('_')[0] === 'T') {
if (param.seriesName.split('_')[1][param.seriesName.split('_')[1].length - 1] === 'V') {
value = parseFloat(param.value[1]).toFixed(3) + ' μV'
} else if (param.seriesName.split('_')[1][param.seriesName.split('_')[1].length - 1] === 'I') {
value = parseFloat(param.value[1]).toFixed(3) + ' nA'
} else if (param.seriesName.split('_')[1][param.seriesName.split('_')[1].length - 1] === 'R') {
value = parseFloat(param.value[1]).toFixed(3) + ' kΩ'
} else {
value = parseFloat(param.value[1]).toFixed(3)
}
} else {
let value1
let value2
if (param.seriesName.split('_')[0][param.seriesName.split('_')[0].length - 1] === 'V') {
value1 = parseFloat(param.value[0]).toFixed(3) + ' μV'
} else if (param.seriesName.split('_')[0][param.seriesName.split('_')[0].length - 1] === 'I') {
value1 = parseFloat(param.value[0]).toFixed(3) + ' nA'
} else if (param.seriesName.split('_')[0][param.seriesName.split('_')[0].length - 1] === 'R') {
value1 = parseFloat(param.value[0]).toFixed(3) + ' kΩ'
} else {
value1 = parseFloat(param.value[0]).toFixed(3)
}
if (param.seriesName.split('_')[1][param.seriesName.split('_')[1].length - 1] === 'V') {
value2 = parseFloat(param.value[1]).toFixed(3) + ' μV'
} else if (param.seriesName.split('_')[1][param.seriesName.split('_')[1].length - 1] === 'I') {
value2 = parseFloat(param.value[1]).toFixed(3) + ' nA'
} else if (param.seriesName.split('_')[1][param.seriesName.split('_')[1].length - 1] === 'R') {
value2 = parseFloat(param.value[1]).toFixed(3) + ' kΩ'
} else {
value2 = parseFloat(param.value[1]).toFixed(3)
}
value = value1 + ', ' + value2
}
tip += '<span style="' + style + '">' +
param.seriesName +
'</span><span style="' +
style + '">' + value + '</span><br>'
}
return tip
}
},
}
updateGridList(chartID, gridLength)
return _chartData[chartID]
} else {
return _chartData[chartID]
}
},
reset: (chartID, mappingID, cardName) => {
_chartData[chartID].legend.data.length = 0
_chartData[chartID].xAxis.length = 0
_chartData[chartID].yAxis.length = 0
if (_chartData[chartID].series.data != null) {
_chartData[chartID].series.data.length = 0
}
_chartData[chartID].series.length = 0
if (mappingID == null) {
_chartData[chartID].mappingID = -1
}
if (cardName == null) {
_chartData[chartID].cardName = 'chart' + String(chartID)
}
_chartData[chartID].dataZoom = [{
type: 'slider',
height: '15px',
bottom: '0%',
handleStyle: {
shadowColor: 'rgba(0, 0, 0, 0)',
},
showDataShadow: false,
showDetail: false,
xAxisIndex: [],
}, {
type: 'inside',
xAxisIndex: [],
},
{
type: 'slider',
height: '80%',
showDataShadow: false,
showDetail: false,
width: '15px',
// right: '5%',
yAxisIndex: [],
}]
updateGridList(chartID, 1)
},
updateGridList: (chartID, gridLength) => {
updateGridList(chartID, gridLength)
},
// register device-channel to chartData
register: (chartID, gridIndex, deviceNameX, deviceIDX, channelX, deviceNameY, deviceIDY, channelY, formula) => {
return chartRegister(chartID, gridIndex, deviceNameX, deviceIDX, channelX, deviceNameY, deviceIDY, channelY, formula)
},
// remove device-channel from chart TODO
remove: (chartID, legendName) => {
if (_chartData[chartID] == null || _chartData[chartID].legend.data.length === 0) {
return false
}
let _xAxisIndex = -1
let _yAxisIndex = -1
// remove legend
const _legendIndex = _chartData[chartID].legend.data.indexOf(legendName)
console.log(_legendIndex)
if (_legendIndex >= 0) {
_chartData[chartID].legend.data.splice(_chartData[chartID].legend.data.indexOf(legendName), 1)
} else {
return false
}
// remove series
for (let i = 0; i < _chartData[chartID].series.length; i++) {
if (_chartData[chartID].series[i].name === legendName) {
_xAxisIndex = _chartData[chartID].series[i].xAxisIndex
_yAxisIndex = _chartData[chartID].series[i].yAxisIndex
_chartData[chartID].series.splice(i, 1)
break
}
}
// remove grid series name
const _gridIndex = _chartData[chartID].xAxis[_xAxisIndex].gridIndex
for (let i = 0; i < _chartData[chartID].grid[_gridIndex].series.length; i++) {
if (_chartData[chartID].grid[_gridIndex].series[i] === legendName) {
_chartData[chartID].grid[_gridIndex].series.splice(i, 1)
break
}
}
for (let i = 0; i < _chartData[chartID].grid.length; i++) {
if (_chartData[chartID].grid[i].name === legendName) {
_xAxisIndex = _chartData[chartID].series[i].xAxisIndex
_yAxisIndex = _chartData[chartID].series[i].yAxisIndex
_chartData[chartID].series.splice(i, 1)
break
}
}
_chartData[chartID].series.forEach(series => {
if (series.xAxisIndex === _xAxisIndex) {
_xAxisIndex = -1
}
if (series.yAxisIndex === _yAxisIndex) {
_yAxisIndex = -1
}
})
// remove xAxis
if (_xAxisIndex !== -1) {
_chartData[chartID].xAxis.splice(_xAxisIndex, 1)
_chartData[chartID].series.forEach(series => {
if (series.xAxisIndex > _xAxisIndex) {
series.xAxisIndex--
}
})
_chartData[chartID].dataZoom[0].xAxisIndex.pop()
}
// remove yAxis
if (_yAxisIndex !== -1) {
_chartData[chartID].yAxis.splice(_yAxisIndex, 1)
_chartData[chartID].series.forEach(series => {
if (series.yAxisIndex > _yAxisIndex) {
series.yAxisIndex--
}
})
_chartData[chartID].dataZoom[2].yAxisIndex.pop()
}
console.log(_chartData[chartID])
return true
},
defaultChartGenerator: (_itemID, _chartID, _type) => {
let item
projectInfo.getDeviceListRegister().forEach(_device => {
if (_itemID === _device.id) {
item = _device
}
})
projectInfo.getFormulaList().forEach(_formula => {
if (_itemID === _formula.id) {
item = _formula
}
})
if (item == null) {
return false
}
const _chartRegisterDevice = (chartID, device) => {
if (projectInfo.getDeviceInfo(device.id).info.library_name.indexOf('Elite') >= 0) {
switch (projectInfo.getDeviceInfo(device.id).parameterSet.MODE) {
case 0:
chartRegister(chartID, 0, 'Elite', device.id, 2, 'Elite', device.id, 1, null)
break
case 1:
chartRegister(chartID, 0, 'Elite', device.id, 2, 'Elite', device.id, 1, null)
break
case 2:
chartRegister(chartID, 0, 'Time', device.id, 2, 'Elite', device.id, 2, null)
break
case 3:
chartRegister(chartID, 0, 'Time', device.id, 2, 'Elite', device.id, 3, null)
break
case 4:
chartRegister(chartID, 0, 'Time', device.id, 2, 'Elite', device.id, 2, null)
break
case 5:
chartRegister(chartID, 0, 'Time', device.id, 2, 'Elite', device.id, 1, null)
break
case 7:
chartRegister(chartID, 0, 'Time', device.id, 2, 'Elite', device.id, 2, null)
break
case 8:
chartRegister(chartID, 0, 'Elite', device.id, 2, 'Elite', device.id, 1, null)
break
case 9:
chartRegister(chartID, 0, 'Elite', device.id, 2, 'Elite', device.id, 1, null)
break
}
} else if (projectInfo.getDeviceInfo(device.id).info.library_name.indexOf('Neulive') >= 0) {
const channelSet = projectInfo.getDeviceInfo(device.id).parameterSet.RECORDING_CH.toString(2).split('').reverse()
let gridNumber = 0
channelSet.forEach((element, index) => {
if (parseInt(element) > 0) {
gridNumber++
}
})
updateGridList(chartID, gridNumber)
gridNumber = 0
channelSet.forEach((element, index) => {
if (parseInt(element) > 0) {
chartRegister(chartID, gridNumber, 'Time', device.id, 1, 'Neulive', device.id, index + 1, null)
gridNumber++
}
})
}
}
const _chartRegisterFormula = (chartID, formula) => {
switch (formula.type) {
case 'Sheet Resistance':
chartRegister(chartID, 0, 'Elite', formula.I_device.id, 1, 'Elite', formula.V_device.id, 2, formula)
break
}
}
// TODO remove old buffer register
if (_chartID != null) {
// update only one
chartData.reset(_chartID, _chartData[_chartID].mappingID, _chartData[_chartID].cardName)
_chartData[_chartID].mappingID = parseInt(item.id)
switch (_type) {
case 'device':
_chartRegisterDevice(_chartID, item)
break
case 'formula':
_chartRegisterFormula(_chartID, item)
break
}
} else {
// update all
for (const chartID in _chartData) {
if (parseInt(_chartData[chartID].mappingID) === parseInt(item.id)) {
console.log(_chartData[chartID])
chartData.reset(chartID, _chartData[chartID].mappingID, _chartData[chartID].cardName)
console.log(_chartData[chartID])
_chartData[chartID].mappingID = parseInt(item.id)
switch (_type) {
case 'device':
_chartRegisterDevice(chartID, item)
break
case 'formula':
_chartRegisterFormula(chartID, item)
break
}
}
}
}
},
// get chart data by chart ID
getChartsData: (chartID) => {
if (chartID == null || _chartData[chartID] == null) {
return null
}
return _chartData[chartID]
},
// get all chart data
getAllChartsData: () => {
return _chartData
},
}
// register device-channel to chartData
const chartRegister = (chartID, gridIndex, deviceNameX, deviceIDX, channelX, deviceNameY, deviceIDY, channelY, formula) => {
const sourceList = [
{
name: deviceNameX,
id: deviceIDX,
channel: channelX,
},
{
name: deviceNameY,
id: deviceIDY,
channel: channelY,
},
]
if (_chartData[chartID] == null) {
return false
}
let xAxisType
let yAxisType
let xAxisSource
let yAxisSource
// formulaSource
const formulaSource = []
let legendName
if (formula == null) {
legendName = getLegendName(sourceList, formula)
} else {
legendName = getLegendName(sourceList, formula.id)
}
if (formula == null) {
switch (sourceList[0].name) {
case 'Time':
xAxisType = 'time'
xAxisSource = [-1, -1]
break
default:
xAxisType = 'value'
xAxisSource = [sourceList[0].id, sourceList[0].channel]
break
}
switch (sourceList[1].name) {
case 'Time':
yAxisType = 'time'
yAxisSource = [-1, -1]
break
default:
yAxisType = 'value'
yAxisSource = [sourceList[1].id, sourceList[1].channel]
break
}
} else {
sourceList.forEach(source => {
formulaSource.push([source.id, source.channel])
})
xAxisType = 'time'
yAxisType = 'value'
}
// register legendName
if (_chartData[chartID].legend.data.indexOf(legendName) >= 0) {
// have been registered
return false
}
_chartData[chartID].legend.data.push(legendName)
// if AxisIndex != -1 then add new axis into list
let _xAxisIndex = -1
let _yAxisIndex = -1
// the grid have exist, so just use the axis in grid
for (let i = 0; i < _chartData[chartID].xAxis.length; i++) {
if (_chartData[chartID].xAxis[i].gridIndex === gridIndex) {
_xAxisIndex = i
}
}
for (let i = 0; i < _chartData[chartID].yAxis.length; i++) {
if (_chartData[chartID].yAxis[i].gridIndex === gridIndex) {
_yAxisIndex = i
}
}
// create new axis
if (_xAxisIndex === -1) {
_chartData[chartID].xAxis.push(makeXAxis(gridIndex, xAxisType))
_xAxisIndex = _chartData[chartID].xAxis.length - 1
}
if (_yAxisIndex === -1) {
_chartData[chartID].yAxis.push(makeYAxis(gridIndex, yAxisType))
_yAxisIndex = _chartData[chartID].yAxis.length - 1
}
// update dataZoom AxisIndex list
const dataZoomXAxisIndex = Array.apply(null, { length: _chartData[chartID].xAxis.length }).map(Number.call, Number)
const dataZoomYAxisIndex = Array.apply(null, { length: _chartData[chartID].yAxis.length }).map(Number.call, Number)
_chartData[chartID].dataZoom[0].xAxisIndex = dataZoomXAxisIndex
_chartData[chartID].dataZoom[1].xAxisIndex = dataZoomXAxisIndex
_chartData[chartID].dataZoom[2].yAxisIndex = dataZoomYAxisIndex
// register series
_chartData[chartID].series.push({
name: legendName,
type: 'line',
symbol: 'circle',
showSymbol: false,
symbolSize: 2,
sampling: 'average',
// clip the overflow on the coordinate system
// clip: true,
// ignore mouse events
// formula
formula: formula,
formulaSource: formulaSource,
silent: true,
xAxisIndex: _xAxisIndex,
yAxisIndex: _yAxisIndex,
// AxisSource: [deviceID, channel], use it to get data stream from buffer
xAxisSource: xAxisSource,
yAxisSource: yAxisSource,
animation: false,
dataXMax: null,
dataXMin: null,
dataYMax: null,
dataYMin: null,
itemStyle: {
normal: {
},
},
lineStyle: {
width: 2,
},
data: [],
})
// register series into grid
const _axisList = []
if (formula == null) {
sourceList.forEach((source, index) => {
let _axis = 'X'
if (index !== 0) {
_axis = 'Y'
}
switch (source.name) {
case 'Time':
_axisList.push(_axis + ' AXIS = TIME')
break
case 'Neulive':
_axisList.push(_axis + ' AXIS = NEULIVE ' + source.id + ' CHANNEL ' + source.channel)
break
case 'Elite':
switch (source.channel) {
case 1:
_axisList.push(_axis + ' AXIS = ELITE ' + source.id + ' CURRENT')
break
case 2:
_axisList.push(_axis + ' AXIS = ELITE ' + source.id + ' VOLTAGE')
break
case 3:
_axisList.push(_axis + ' AXIS = ELITE ' + source.id + ' RESISTANCE')
break
default:
_axisList.push(_axis + ' AXIS = ELITE ' + source.id + ' CHANNEL ' + source.channel)
break
}
break
default:
_axisList.push(_axis + ' AXIS = DEVICE ' + source.id + ' CHANNEL ' + source.channel)
break
}
})
} else {
_axisList.push('X AXIS = TIME')
_axisList.push('Y AXIS = FORMULA' + formula.id)
}
const _gridSeries = {
name: legendName,
xAxis: _axisList[0],
yAxis: _axisList[1],
}
_chartData[chartID].grid[gridIndex].series.push(_gridSeries)
// console.log(_chartData[chartID])
return _chartData[chartID]
}
+27
View File
@@ -0,0 +1,27 @@
import api from './index'
const _header = {}
function setHeader (header) {
_header.Authorization = 'Bearer ' + header
}
function getHeader () {
if (Object.keys(_header).length === 0) {
getJwtData()
}
return _header
}
async function getJwtData () {
const _jwt = await api.axios.get('/public/auth/get_cookie')
setHeader(_jwt.data)
}
const auth = {
getHeader,
getJwtData,
}
export default auth
+81
View File
@@ -0,0 +1,81 @@
import api from './index'
import auth from './auth'
async function create (attrs) {
const _header = auth.getHeader()
const _data = {
name: attrs.name,
parent: attrs.parent,
type: attrs.type,
size: attrs.size,
}
try {
return await api.axios.post('/api/collection/create', _data, { headers: _header })
} catch (e) {
console.error(e)
return false
}
}
async function getByID (id) {
const _header = auth.getHeader()
try {
return await api.axios.get(`/api/collection/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/collection/get_by_name/${name}`, { headers: _header })
} catch (e) {
console.error(e)
return false
}
}
async function getByParent (type, parent) {
const _header = auth.getHeader()
try {
return await api.axios.get(`/api/collection/get_by_parent/${type}/${parent}`, { headers: _header })
} catch (e) {
console.error(e)
return false
}
}
async function getAll () {
const _header = auth.getHeader()
try {
return await api.axios.get('/api/collection/get/all', { headers: _header })
} catch (e) {
console.error(e)
return false
}
}
async function getByParentName (collectionType, parent, name) {
console.log(collectionType, parent, name)
const _header = auth.getHeader()
try {
return await api.axios.get(`/api/collection/get_by_parent_name/${collectionType}/${parent}/${name}`, { headers: _header })
} catch (e) {
console.error(e)
return false
}
}
const collection = {
create,
getByID,
getByName,
getByParent,
getByParentName,
getAll,
}
export default collection
+52
View File
@@ -0,0 +1,52 @@
import api from './index'
import auth from './auth'
async function create (_data) {
const _header = auth.getHeader()
try {
return await api.axios.post('/api/controller/create/', _data, { headers: _header })
} catch (e) {
console.error(e)
return false
}
}
async function getAll () {
const _header = auth.getHeader()
console.log(_header)
try {
return await api.axios.get('/api/controller/get/all', { headers: _header })
} catch (e) {
console.error(e)
return false
}
}
async function getByMac (mac) {
const _header = auth.getHeader()
try {
return await api.axios.get(`/api/controller/get_by_mac/${mac}`, { headers: _header })
} catch (e) {
console.error(e)
return false
}
}
async function update (attrs) {
const _header = auth.getHeader()
try {
return await api.axios.post('/api/controller/update', attrs, { headers: _header })
} catch (e) {
console.error(e)
return false
}
}
const controller = {
create,
getAll,
getByMac,
update,
}
export default controller
+73
View File
@@ -0,0 +1,73 @@
import api from './index'
import auth from './auth'
async function create (attrs) {
const _header = auth.getHeader()
try {
return await api.axios.post('/api/device/create', attrs, { headers: _header })
} catch (e) {
console.error(e)
return false
}
}
async function updateByID (id, attrs) {
const _header = auth.getHeader()
try {
return await api.axios.post(`/api/device/update_by_id/${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/device/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/device/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/device/get_by_name/${name}`, { headers: _header })
} catch (e) {
console.error(e)
return false
}
}
async function getAll () {
const _header = auth.getHeader()
try {
return await api.axios.get('/api/device/get/all', { headers: _header })
} catch (e) {
console.error(e)
return false
}
}
const device = {
create,
updateByID,
del,
getByID,
getByName,
getAll,
}
export default device
+19 -111
View File
@@ -1,118 +1,26 @@
import axios from 'axios'
import auth from './auth'
import collection from './collection'
import controller from './controller'
import task from './task'
import device from './device'
import meta from './meta'
import raw from './raw'
import mini from './mini'
axios.defaults.baseURL = 'http://192.168.0.110:3000'
const _header = {}
function setHeader (header) {
_header.Authorization = 'Bearer ' + header
}
function getHeader () {
return _header
}
async function getJwtData () {
const _jwt = await axios.get('/public/auth/get_cookie')
setHeader(_jwt.data)
}
async function createCollection (name, parent, type) {
const _header = getHeader()
const _data = {
name: name,
parent: { [type]: parent },
size: 0,
}
try {
return await axios.post('/api/collection/create', _data, { headers: _header })
} catch (e) {
console.error(e)
return false
}
}
async function getCollectionsByID (id) {
const _header = getHeader()
try {
return await axios.get('/api/collection/get_by_id/' + id, { headers: _header })
} catch (e) {
console.error(e)
return false
}
}
async function getCollectionsByName (name) {
const _header = getHeader()
try {
return await axios.get('/api/collection/get_by_name/' + name, { headers: _header })
} catch (e) {
console.error(e)
return false
}
}
async function getCollectionsFoldersByParent (parent) {
const _header = getHeader()
try {
return await axios.get('/api/collection/folder/get_by_parent/' + parent, { headers: _header })
} catch (e) {
console.error(e)
return false
}
}
async function getCollectionsAll (id) {
const _header = getHeader()
try {
return await axios.get('/api/collection/get/all' + id, { headers: _header })
} catch (e) {
console.error(e)
return false
}
}
async function createMetaFile () {
const _header = getHeader()
try {
return await axios.post('/api/file/meta/create', { headers: _header })
} catch (e) {
console.error(e)
return false
}
}
async function getFolderMetaFileByParent (parent) {
const _header = getHeader()
try {
return await axios.get('/api/file/folder/meta/get_by_parent/' + parent, { headers: _header })
} catch (e) {
console.error(e)
return false
}
}
async function getRawFilesByParent (channel, parent) {
const _header = getHeader()
try {
return await axios.get('/api/file/raw/get_by_parent/' + channel + '/' + parent, { responseType: 'json', headers: _header })
} catch (e) {
console.error(e)
return false
}
}
// axios.defaults.baseURL = 'http://192.168.3.53:3000'
axios.defaults.baseURL = 'http://' + location.href.split('/')[2].split(':')[0] + ':3000'
const api = {
getJwtData,
createCollection,
getCollectionsByID,
getCollectionsByName,
getCollectionsFoldersByParent,
getCollectionsAll,
createMetaFile,
getFolderMetaFileByParent,
getRawFilesByParent,
axios,
auth,
collection,
controller,
task,
device,
meta,
raw,
mini,
}
export default api
+74
View File
@@ -0,0 +1,74 @@
import api from './index'
import auth from './auth'
async function create () {
const _header = auth.getHeader()
try {
return await api.axios.post('/api/file/meta/create', { 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/file/meta/update/${id}`, attrs, { headers: _header })
} catch (e) {
console.error(e)
return false
}
}
async function clearDel (id) {
console.log('clearDelete')
const _header = auth.getHeader()
try {
return await api.axios.get(`/api/file/meta/clear_deleted/${id}`, { headers: _header })
} catch (e) {
console.error(e)
return false
}
}
async function getCollectionByParent (type, parent) {
const _header = auth.getHeader()
try {
return await api.axios.get(`/api/file/meta/get_by_parent/${type}/${parent}`, { headers: _header })
} catch (e) {
console.error(e)
return false
}
}
async function getByID (id) {
const _header = auth.getHeader()
try {
return await api.axios.get(`/api/file/meta/get_by_id/${id}`, { responseType: 'json', headers: _header })
} catch (e) {
console.error(e)
return false
}
}
async function getByName (name) {
const _header = auth.getHeader()
try {
return await api.axios.get('/api/file/meta/get_by_name/' + name, { responseType: 'json', headers: _header })
} catch (e) {
console.error(e)
return false
}
}
const meta = {
create,
update,
clearDel,
getCollectionByParent,
getByID,
getByName,
}
export default meta
+95
View File
@@ -0,0 +1,95 @@
import api from './index'
import auth from './auth'
async function update (channel, id, attrs) {
const _header = auth.getHeader()
try {
return await api.axios.post(`/api/file/mini/update/${channel}/${id}`, attrs, { headers: _header })
} catch (e) {
console.error(e)
return false
}
}
async function clearDel (channel, id) {
const _header = auth.getHeader()
try {
return await api.axios.get(`/api/file/mini/clear_deleted/${channel}/${id}`, { headers: _header })
} catch (e) {
console.error(e)
return false
}
}
async function getByID (channel, id) {
const _header = auth.getHeader()
try {
return await api.axios.get(`/api/file/mini/get_by_id/${channel}/${id}`, { responseType: 'json', headers: _header })
} catch (e) {
console.error(e)
return false
}
}
async function getByParent (channel, parent) {
const _header = auth.getHeader()
try {
return await api.axios.get(`/api/file/mini/get_by_parent/${channel}/${parent}`, { responseType: 'json', headers: _header })
} catch (e) {
console.error(e)
return false
}
}
async function getAttrByParent (channel, parent, attr) {
const _header = auth.getHeader()
try {
return await api.axios.get(`/api/file/mini/get_attr_by_parent/${channel}/${parent}/${attr}`, { responseType: 'json', headers: _header })
} catch (e) {
console.error(e)
return false
}
}
async function getAttrByID (channel, id, attr) {
const _header = auth.getHeader()
try {
return await api.axios.get(`/api/file/mini/get_attr_by_id/${channel}/${id}/${attr}`, { responseType: 'json', headers: _header })
} catch (e) {
console.error(e)
return false
}
}
async function getMeanDataByID (channel, id) {
const _header = auth.getHeader()
try {
return await api.axios.get(`/api/file/mini/mean/get_by_id/${channel}/${id}`, { responseType: 'json', headers: _header })
} catch (e) {
console.error(e)
return false
}
}
async function getRandomDataByID (channel, id) {
const _header = auth.getHeader()
try {
return await api.axios.get(`/api/file/mini/random/get_by_id/${channel}/${id}`, { responseType: 'json', headers: _header })
} catch (e) {
console.error(e)
return false
}
}
const mini = {
update,
clearDel,
getByID,
getByParent,
getAttrByParent,
getAttrByID,
getMeanDataByID,
getRandomDataByID,
}
export default mini
+84
View File
@@ -0,0 +1,84 @@
import api from './index'
import auth from './auth'
async function update (channel, id, attrs) {
const _header = auth.getHeader()
try {
return await api.axios.post(`/api/file/raw/update/${channel}/${id}`, attrs, { headers: _header })
} catch (e) {
console.error(e)
return false
}
}
async function clearDel (channel, id) {
const _header = auth.getHeader()
try {
return await api.axios.get(`/api/file/raw/clear_deleted/${channel}/${id}`, { headers: _header })
} catch (e) {
console.error(e)
return false
}
}
async function getByID (channel, id) {
const _header = auth.getHeader()
try {
return await api.axios.get(`/api/file/raw/get_by_id/${channel}/${id}`, { responseType: 'json', headers: _header })
} catch (e) {
console.error(e)
return false
}
}
async function getByIDs (channel, ids) {
const _header = auth.getHeader()
try {
return await api.axios.get(`/api/file/raw/get_by_ids/${channel}/${ids}`, { responseType: 'json', headers: _header })
} catch (e) {
console.error(e)
return false
}
}
async function getAttrByIDs (channel, ids, attr) {
const _header = auth.getHeader()
try {
return await api.axios.get(`/api/file/raw/get_attr_by_ids/${channel}/${ids}/${attr}`, { responseType: 'json', headers: _header })
} catch (e) {
console.error(e)
return false
}
}
async function getByParent (channel, parent) {
const _header = auth.getHeader()
try {
return await api.axios.get(`/api/file/raw/get_by_parent/${channel}/${parent}`, { responseType: 'json', headers: _header })
} catch (e) {
console.error(e)
return false
}
}
async function getAttrByParent (channel, parent, attr) {
const _header = auth.getHeader()
try {
return await api.axios.get(`/api/file/raw/get_attr_by_parent/${channel}/${parent}/${attr}`, { responseType: 'json', headers: _header })
} catch (e) {
console.error(e)
return false
}
}
const raw = {
update,
clearDel,
getByID,
getByIDs,
getAttrByIDs,
getByParent,
getAttrByParent,
}
export default raw
+52
View File
@@ -0,0 +1,52 @@
import api from './index'
import auth from './auth'
async function create (_data) {
const _header = auth.getHeader()
try {
return await api.axios.post('/api/task/create/', _data, { headers: _header })
} catch (e) {
console.error(e)
return false
}
}
async function getAll () {
const _header = auth.getHeader()
console.log(_header)
try {
return await api.axios.get('/api/task/get/all', { headers: _header })
} catch (e) {
console.error(e)
return false
}
}
async function getByID (id) {
const _header = auth.getHeader()
try {
return await api.axios.get(`/api/task/get_by_id/${id}`, { headers: _header })
} catch (e) {
console.error(e)
return false
}
}
async function update (attrs) {
const _header = auth.getHeader()
try {
return await api.axios.post('/api/task/update', attrs, { headers: _header })
} catch (e) {
console.error(e)
return false
}
}
const task = {
create,
getAll,
getByID,
update,
}
export default task
+173 -168
View File
@@ -1,188 +1,193 @@
import { getNewFileSegmentInfoFormat, getNewDownloadOptions } from './DownloadFormat'
import { _fileInfoList, file } from './../file/File'
import streamSaver from 'streamsaver'
// import { inflateSync } from 'zlib'
import api from '../api/index'
const _fileSegmentInfo = getNewFileSegmentInfoFormat()
var fileStream, writer
var encode = TextEncoder.prototype.encode.bind(new TextEncoder())
const _downloadOptions = getNewDownloadOptions()
const _downloadOptionsList = []
export const download = {
writeDataIntoFileStream: function (data, close) {
// const uInt8 = new TextEncoder().encode('StreamSaver is awesome')
// console.log(uInt8)
// console.log(uInt8.byteLength)
// writer.write(uInt8)
// streamSaver.createWriteStream() returns a writable byte stream
// The WritableStream only accepts Uint8Array chunks
// (no other typed arrays, arrayBuffers or strings are allowed)
export const downloadTaskManager = {
updateDownloadSubFileList: function (path, channel, timeRange) {
const fileInfo = _fileInfoList.find(fileInfo => fileInfo.data.path === path)
// channel
const metaChannel = fileInfo.data.meta.channel
// max part per channel
const subfilePerChannel = fileInfo.data.meta['sub-file'].length / metaChannel.length
// timeRange
const timeRangeInMillisecond = timeRange.map(time => time * 1000)
// available channel
const availableChannel = channel
.filter(ch => ch.checked === true)
.map(ch => ch.channel)
// using Response can be a great tool to convert
// mostly anything (blob, string, buffers) into a byte stream
// that can be piped to StreamSaver
//
// You could also use a transform stream that would sit
// between and convert everything to Uint8Arrays
// filter sub-file list to get downloadSubfileList
fileInfo.data.meta['sub-file'].forEach(subFile => {
const subfileArray = subFile.split(/['_.']+/).slice(0, -1)
const subfileChannel = parseInt(subfileArray[subfileArray.length - 2])
const subfilePart = parseInt(subfileArray[subfileArray.length - 1])
const subfileStartTimeIndex = metaChannel.length * subfilePart + metaChannel.indexOf(subfileChannel)
const subfileStartTime = parseInt(fileInfo.data.meta['start-time'][subfileStartTimeIndex])
const subfileEndTime = () => {
if (subfilePerChannel === (subfilePart + 1)) {
return parseInt(fileInfo.data.meta.time_duration)
} else {
return parseInt(fileInfo.data.meta['start-time'][subfileStartTimeIndex + metaChannel.length])
}
if (!fileStream) {
fileStream = streamSaver.createWriteStream('sample.csv')
writer = fileStream.getWriter()
}
data = encode(data)
data && writer.write(data)
// fileStream.locked = false
// new Response(data).body
// .pipeTo(fileStream, { preventClose: !close })
// .then()
},
closeWriter: function () {
writer.close()
},
getAllRawDatas: async function (meta) {
const result = {}
for (const channelID in meta.raw_data) {
let prevLastTime = 0
result[channelID] = []
const rawDataIDList = JSON.parse(JSON.stringify(meta.raw_data[channelID]))
while (rawDataIDList.length >= 1000) {
const _rawDataIDList = rawDataIDList.splice(0, 1000)
const _data = await api.raw.getAttrByIDs(channelID, _rawDataIDList, 'id-channel-size-serial_number-start_time-end_time-data')
prevLastTime = await this.parseRawData(_data.data, prevLastTime, meta, result[channelID])
}
const _data = await api.raw.getAttrByIDs(channelID, rawDataIDList, 'id-channel-size-serial_number-start_time-end_time-data')
prevLastTime = await this.parseRawData(_data.data, prevLastTime, meta, result[channelID])
}
return result
},
getIndexRawDatas: async function (meta, channelID, list) {
const result = {}
const downloadIndex = fileInfo.data.meta.downloadBlockList.findIndex(data => data.name === subFile)
if (downloadIndex === -1) {
const downloadInfo = {
name: subFile,
download: false,
channel: subfileChannel,
part: subfilePart,
start_time: subfileStartTime,
end_time: subfileEndTime(),
data: [],
}
file.pushDownloadInfo(path, downloadInfo)
result[channelID] = []
if (availableChannel.includes(parseInt(subfileChannel))) {
if (timeRangeInMillisecond[0] <= subfileEndTime() && timeRangeInMillisecond[1] >= subfileStartTime) {
file.pushDownloadSubFileList(path, subFile)
const prevLastTime = 0
const _data = await api.raw.getAttrByIDs(channelID, list, 'id-channel-size-serial_number-start_time-end_time-data')
await this.parseRawData(_data.data, prevLastTime, meta, result[channelID])
return result
},
rawByIDChannels: async function (id, channel, meta) {
const data = []
const rawData = await api.raw.getByID(channel, id)
await this.parseRawData(rawData.data, null, meta, data)
return data
},
miniMeanByIDChannel: async function (id, channel, meta) {
const miniData = await api.mini.getByID(channel, id)
return await this.parseMiniData(miniData, 'data_mean', meta)
},
miniRandomByIDChannel: async function (id, channel, meta) {
const rawData = await api.mini.getByID(channel, id)
return await this.parseMiniData(rawData, 'data_random', meta)
},
parseRawData: async function (rawData, prevLastTime, meta, dataArray) {
for (const raw of rawData) {
if (raw.data !== null && raw.data.length > 0) {
const encodedData = raw.data.split('"***"')
const unzipDatas = encodedData.map(ctx => {
return ctx.split(' ')
})
for (let i = 0; i <= unzipDatas.length - 1; i++) {
if (unzipDatas[i].length > 0) {
prevLastTime = this.parseDataWithTimeStamp(unzipDatas[i], prevLastTime, meta, dataArray)
}
}
} else {
// If not yet downloaded, check download status
if (!fileInfo.data.meta.downloadBlockList[downloadIndex].download) {
if (availableChannel.includes(parseInt(subfileChannel))) {
if (timeRangeInMillisecond[0] <= subfileEndTime() && timeRangeInMillisecond[1] >= subfileStartTime) {
file.pushDownloadSubFileList(path, subFile)
}
}
return prevLastTime
},
parseMiniData: async function (miniData, miniType, meta) {
const channelData = []
for (const mini of miniData.data) {
if (mini[miniType] !== null && mini[miniType].length > 0) {
const encodedData = mini[miniType].split('"***"')
// console.log('encodedData', encodedData)
const unzipDatas = encodedData.map(ctx => {
if (ctx.length === 0) {
return ''
}
return ctx.split(' ')
})
// console.log('unzipData', unzipDatas)
for (let i = 0; i <= unzipDatas.length - 1; i++) {
if (unzipDatas[i].length > 0) {
if (unzipDatas[i + 1].length === 0) {
const endTime = (meta && parseInt(mini.end_time) === -1) ? parseInt(meta.time_duration) : parseInt(mini.end_time)
channelData.push(...this.parseDataWithHeadTimeStamp(unzipDatas[i], unzipDatas[i][0], endTime, true))
} else {
channelData.push(...this.parseDataWithHeadTimeStamp(unzipDatas[i], unzipDatas[i][0], unzipDatas[i + 1][0]))
}
}
}
}
})
// console.log(file.getFileInfoList())
},
// Download all datas
downloadAllSubFileList: function (path) {
const fileInfo = _fileInfoList.find(fileInfo => fileInfo.data.path === path)
const metaChannel = fileInfo.data.meta.channel
const subfilePerChannel = fileInfo.data.meta['sub-file'].length / metaChannel.length
fileInfo.data.meta['sub-file'].forEach(subFile => {
const subfileArray = subFile.split(/['_.']+/).slice(0, -1)
const subfileChannel = parseInt(subfileArray[subfileArray.length - 2])
const subfilePart = parseInt(subfileArray[subfileArray.length - 1])
const subfileStartTimeIndex = metaChannel.length * subfilePart + metaChannel.indexOf(subfileChannel)
const subfileStartTime = parseInt(fileInfo.data.meta['start-time'][subfileStartTimeIndex])
const subfileEndTime = () => {
if (subfilePerChannel === (subfilePart + 1)) {
return parseInt(fileInfo.data.meta.time_duration)
} else {
return parseInt(fileInfo.data.meta['start-time'][subfileStartTimeIndex + metaChannel.length])
}
}
const downloadIndex = fileInfo.data.meta.downloadBlockList.findIndex(data => data.name === subFile)
if (downloadIndex === -1) {
const downloadInfo = {
name: subFile,
download: false,
channel: subfileChannel,
part: subfilePart,
start_time: subfileStartTime,
end_time: subfileEndTime(),
data: [],
}
file.pushDownloadInfo(path, downloadInfo)
}
file.pushDownloadSubFileList(path, subFile)
})
// console.log(file.getFileInfoList())
},
checkDownloadSubFileList: function (path) {
const fileInfo = _fileInfoList.find(fileInfo => fileInfo.data.path === path)
return fileInfo.data.meta.downloadSubFileList.length !== 0
},
getFirstSubfile: function (path) {
const fileInfo = _fileInfoList.find(fileInfo => fileInfo.data.path === path)
return fileInfo.data.meta.downloadSubFileList[0]
},
getAllSubfile: function (path) {
const fileInfo = _fileInfoList.find(fileInfo => fileInfo.data.path === path)
return fileInfo.data.meta.downloadSubFileList
},
/* ------- File Segment Info ------- */
updateFileSegmentInfo: async function (mes) {
const mesObj = JSON.parse(mes)
const update = async () => {
for (const item in mesObj.data) {
_fileSegmentInfo[item] = mesObj.data[item]
};
}
await update()
return channelData
},
getFileSegmentMaxIndex: function () {
return _fileSegmentInfo.segment_total
parseDataWithTimeStamp: function (currentData, prevLastTime, meta, dataArray) {
// const transData = []
// let timeSpare = 0
// let channel = 0
// if (meta !== undefined) {
// channel = JSON.parse(meta.channels).length
// if (meta.device.library_name.startsWith('Neulive')) {
// timeSpare = parseInt((1 / (parseInt(meta.parameter_set.ADC_CLOCK) / 200)) * 1000 / 1000)
// } else if (meta.device.library_name.startsWith('Elite')) {
// // TODO Elite
// }
// }
// const realTimeSpare = channel * timeSpare
for (let i = 0; i <= currentData.length - 1; i += 2) {
if (currentData[i].length !== 0) {
const time = parseInt(currentData[i])
// if (prevLastTime && (time - prevLastTime >= 2 * realTimeSpare) && realTimeSpare !== 0) {
// console.log('data loss time', time, prevLastTime)
// let timeDiff = time - prevLastTime
// let timeCorrection = 0
// while (timeDiff > 0) {
// timeCorrection += realTimeSpare
// timeDiff -= realTimeSpare
// if (timeDiff > 0) {
// const _time = parseInt(prevLastTime) + parseInt(timeCorrection)
// const data = 'NaN'
// const tmpData = [_time, data]
// transData.push(tmpData)
// }
// }
// }
if (meta !== undefined) {
if (time <= parseInt(meta.time_duration)) {
const data = currentData[i + 1]
const tmpData = [time, data]
dataArray.push(tmpData)
}
}
prevLastTime = time
}
}
return prevLastTime
},
/* ------- Download Options List ----- */
updateDownloadOptions: function (path) {
const metaInfo = file.getMetaInfo(path)
const downloadOptionsIndex = _downloadOptionsList.findIndex(downloadOptions => downloadOptions.metaPath === path)
if (downloadOptionsIndex === -1) {
_downloadOptions.library = metaInfo.configuration._LIBRARY_
_downloadOptions.channel = metaInfo.channel.map(ch => {
let channel = ''
if (_downloadOptions.library.includes('Elite')) {
channel = (ch === 0) ? 'current' : (ch === 1) ? 'voltage' : (ch === 2) ? 'resistance' : ''
} else {
channel = 'channel' + ch
}
return {
alias: channel,
channel: ch,
checked: true,
}
})
_downloadOptions.metaPath = path
_downloadOptions.previousPath = path.split('/').slice(0, -1).join('/')
_downloadOptions.filename = path.split(/[/.]+/).slice(0, -1).pop()
_downloadOptions.minTime = parseInt([...new Set(metaInfo['start-time'])][0] / 1000)
_downloadOptions.maxTime = parseInt(metaInfo.time_duration / 1000)
_downloadOptions.timeRange = [_downloadOptions.minTime, _downloadOptions.maxTime]
_downloadOptions.download.status = 'idle'
_downloadOptions.download.rate = 0
_downloadOptionsList.push(JSON.parse(JSON.stringify(_downloadOptions)))
parseDataWithHeadTimeStamp: function (currentData, startTime, endTime, last) {
const transData = []
const timeStart = parseInt(startTime)
const timeEnd = endTime
let timeSpare
if (last) {
timeSpare = (timeEnd - timeStart) / (currentData.length - 2)
} else {
for (var item in _downloadOptions) {
_downloadOptions[item] = _downloadOptionsList[downloadOptionsIndex][item]
}
timeSpare = (timeEnd - timeStart) / (currentData.length - 1)
}
return _downloadOptions
for (let i = 1; i <= currentData.length - 1; i++) {
const time = parseInt(timeStart + ((i - 1) * timeSpare))
const data = currentData[i]
const tmpData = [time, data]
transData.push(tmpData)
}
return transData
},
getFisrtDownloadOptions: function () {
return _downloadOptionsList[0]
},
getDownloadOptions: function (path) {
return _downloadOptionsList.find(downloadOption => downloadOption.metaPath === path)
},
getDownloadOptionsList: function () {
return _downloadOptionsList
},
downloadTaskRemain: function () {
return _downloadOptionsList.length !== 0
},
isFileDownloading: function () {
return _downloadOptionsList.filter(downloadOptions => downloadOptions.download.status === 'Downloading').length !== 0
},
shiftDownloadOptions: function () {
_downloadOptionsList.shift()
},
/* TODO couting download percentage */
}
+266 -368
View File
@@ -1,99 +1,207 @@
import { file } from '../file/File'
import { inflateSync } from 'zlib'
import golbalMethods from '../global/global'
let header = []
let title = []
// const oneChannelData = []
const allChannelData = []
// let filterLength = 0
// let fileIndex = 0
let dataIndex = 0
// let blob = new Blob()
// const openEphysData = []
// const openEphysTimestamp = []
const NeuliveParameterOrder = ['RECORDING_CH', 'AMP_GAIN', 'ADC_CLOCK']
const NeuliveAmpGain = [100, 400, 800, 25]
export const exportData = {
exportCSVByAPI: async function (downloadInfo, rawdata) {
// console.log('start export')
// console.log(performance.now())
rawdata.forEach(data => {
data.data.forEach(d => {
const dataDecoded = []
let originDataArray = d.data.split('"***"')
const dataArray = []
let datasArray = []
if (originDataArray.length > 1) {
originDataArray = originDataArray.slice(0, -1)
}
// originDataArray.forEach(ctx => {
// ctx = ctx
// })
console.log('origin', originDataArray)
originDataArray.forEach(ctx => {
// console.log(ctx)
dataArray.push(atob(ctx))
// console.log(dataArray)
})
// if(dataArray.length > 1){
// datasArray = dataArray.slice(0,-1)
// } else {
datasArray = dataArray
// }
console.log('******1', dataArray.length)
// console.log(datasArray)
// decoded compress data
for (let i = 0; i < datasArray.length; i++) {
const buffer = Buffer.from(datasArray[i], 'ascii')
// console.log(i)
// console.log(datasArray[i])
// console.log(buffer)
const decompressData = inflateSync(buffer).toString().split(' ')
dataDecoded.push(decompressData)
}
console.log(dataDecoded)
console.log('******2', dataDecoded.length)
for (let i = 0; i < dataDecoded.length - 1; i++) {
if (i === 0) {
this.transFirstDataIntoTimeDataFormat(dataDecoded[i], d.start_time, dataDecoded[i + 1][0])
createHeadersString: function (headers, channel) {
const device = ['Device', headers.device.device_name, golbalMethods.transMac(headers.device.device_address)]
const library = ['Libaray', headers.device.library_name, headers.device.library_version]
const parameter = []
if (headers.device.library_name.indexOf('Neulive') >= 0) {
NeuliveParameterOrder.forEach(p => {
const value = headers.parameter_set[p]
if (p === 'RECORDING_CH') {
let result = ''
if (channel !== undefined) {
result = String(parseInt(channel) + 1)
} else {
this.transDataIntoTimeDataFormat(dataDecoded[i], dataDecoded[i + 1][0])
const channelList = value.toString(2).split('').reverse()
channelList.forEach((_value, _index) => {
if (_value === '1') {
result = result + `${_index + 1},`
}
})
}
parameter.push(['Record channels', result])
} else if (p === 'AMP_GAIN') {
parameter.push(['Amp gain', NeuliveAmpGain[value]])
} else if (p === 'ADC_CLOCK') {
parameter.push(['Sample Rate', parseInt(8e5 / (value * JSON.parse(headers.channels).length))])
}
})
} else if (headers.device.library_name.indexOf('Elite') >= 0) {
const sortedParameterSet = {}
Object.keys(headers.parameter_set).sort().forEach(key => {
sortedParameterSet[key] = headers.parameter_set[key]
})
for (const p in sortedParameterSet) {
parameter.push([p, headers.parameter_set[p]])
}
}
const headersArray = [device, library, ...parameter]
let headersString = ''
headersArray.forEach(header => {
headersString += header.join(',') + '\r\n'
})
return headersString
},
createTitlesString: function (headers, cycle, channel) {
let channelString = ''
let titleString = ''
let channelList = []
if (channel !== undefined) {
channelList.push(channel)
} else {
channelList = JSON.parse(headers.channels)
}
console.log(channelList)
while (cycle !== -1) {
for (const _ch of channelList) {
if (headers.device.library_name.indexOf('Neulive') >= 0) {
switch (_ch) {
case 256:
channelString += 'channel,X,'
break
case 257:
channelString += 'channel,Y,'
break
case 258:
channelString += 'channel,Z,'
break
case 259:
channelString += 'channel,M,'
break
default:
channelString += `channel,${parseInt(_ch) + 1},`
break
}
titleString += 'Time[us],value[uV],'
} else if (headers.device.library_name.indexOf('Elite') >= 0) {
const _time = 'Time[us]'
let _title = ''
switch (_ch) {
case 0:
_title = 'Current[nA]'
break
case 1:
_title = 'Voltage[uV]'
break
case 2:
_title = 'Resister[mohm]'
break
default:
_title = ''
break
}
// channelString += `channel ${_ch + 1},,`
titleString += _time + ',' + _title + ','
}
}
cycle -= 1
}
if (headers.device.library_name.indexOf('Neulive') >= 0) {
channelString = channelString.slice(0, -1) + '\r\n'
titleString = titleString.slice(0, -1) + '\r\n'
return channelString + titleString
} else if (headers.device.library_name.indexOf('Elite') >= 0) {
titleString = titleString.slice(0, -1) + '\r\n'
return titleString
}
return ''
},
createDatasString: function (headers, data, channel) {
let dataString = ''
let cycle = 0
let idx = 0
let maxLength = 0
if (JSON.parse(headers.channels).length > 0) {
for (const channel of JSON.parse(headers.channels)) {
if (data[channel] && data[channel].length > maxLength) {
maxLength = data[channel].length
}
}
for (const channel of JSON.parse(headers.channels)) {
if (data[channel] && maxLength > data[channel].length) {
let lengthDiff = maxLength - data[channel].length
while (lengthDiff !== 0) {
data[channel].push(['', ''])
lengthDiff -= 1
}
}
this.transLastDataIntoTimeDataFormat(dataDecoded[dataDecoded.length - 1], d.end_time)
dataIndex = 0
})
// console.log('one channel done')
// console.log(performance.now())
// console.log(allChannelData)
})
// console.log('all channel done')
// console.log(performance.now())
}
const stopIndex = maxLength
cycle = parseInt(stopIndex / 1e6)
if (cycle === 0) {
while (stopIndex !== idx) {
const indexData = []
for (const _ch of JSON.parse(headers.channels)) {
if (data[_ch] !== undefined) {
if (data[_ch][idx] !== undefined) {
indexData.push(...data[_ch][idx])
}
}
}
idx = idx + 1
dataString = dataString + indexData.join(',') + '\r\n'
}
} else {
for (let i = 0; i < 1e6; i++) {
const indexData = []
for (let j = 0; j <= cycle; j++) {
for (const _ch of JSON.parse(headers.channels)) {
if (data[_ch] !== undefined) {
if (data[_ch][idx + (j * 1e6)] === undefined) {
indexData.push(...[])
} else {
indexData.push(...data[_ch][idx + (j * 1e6)])
}
}
}
}
idx = idx + 1
dataString = dataString + indexData.join(',') + '\r\n'
}
}
return [dataString, cycle]
}
return ''
},
exportCSV: async function (headers, data, channel) {
console.log('channel', channel)
let fileName, headersString, datasString, cycle, titlesString
if (channel !== undefined) {
fileName = headers.name + '-' + String(channel) + '.csv'
headersString = this.createHeadersString(headers, channel)
const [_datasString, _cycle] = this.createDatasString(headers, data, channel)
datasString = _datasString
cycle = _cycle
titlesString = this.createTitlesString(headers, cycle, channel)
} else {
fileName = headers.name + '.csv'
headersString = this.createHeadersString(headers)
const [_datasString, _cycle] = this.createDatasString(headers, data)
datasString = _datasString
cycle = _cycle
titlesString = this.createTitlesString(headers, cycle)
}
// console.log('data', datasString)
// console.log('header', headersString)
// console.log('title', titlesString)
// console.log('start exporting file')
// console.log(performance.now())
const getCSVFile = async () => {
const headerStr = header.join(',') + '\r\n'
const titleStr = title.join(',') + '\r\n'
const dataStr = this.convertToCSV(allChannelData)
const fileName = `${downloadInfo.name}.csv`
/* TODO decrease create BLOB time spend */
// console.log('create Blob')
// console.log(performance.now())
const blob = new Blob([headerStr + titleStr + dataStr], {
console.log('build blob')
console.time()
const blob = new Blob([headersString, titlesString, datasString], {
type: 'text/csv',
})
// console.log('create Blob Finish')
// console.log(performance.now())
console.timeEnd()
const href = URL.createObjectURL(blob)
let link = document.createElement('a')
@@ -101,299 +209,89 @@ export const exportData = {
link.href = href
link.download = fileName
link.click()
// console.log('Download Finish')
// console.log(performance.now())
// destroy
header.length = 0
title.length = 0
// allChannelData.length = 0
link = null
}
getCSVFile()
// const downloadData = file.getFileInfo(downloadInfo.metaPath).data.meta.downloadBlockList
// const timeRangeInMilliSecond = downloadInfo.timeRange.map(time => time * 1000)
// const availableChannel = downloadInfo.channel.filter(ch =>
// ch.checked === true,
// ).map(ch => {
// return ch.channel
// })
// // filter data with avaliable channel
// const filterData = downloadData.filter(
// data => availableChannel.includes(data.channel) &&
// timeRangeInMilliSecond[0] <= data.end_time &&
// timeRangeInMilliSecond[1] >= data.start_time,
// )
// filterData.forEach(download => {
// header = header.concat(['channel' + download.channel, ''])
// title = title.concat(['Time(ms)', 'Value'])
// const dataDecoded = []
// const originDataArray = download.data.split('line').slice(0, -1)
headersString = ''
titlesString = ''
datasString = ''
},
createDatasString_1: function * (headers, data, cycle) {
// let dataString = ''
// let idx = 0
// const maxLength = 0
// // decoded compress data
// for (let i = 0; i < originDataArray.length; i++) {
// const buffer = Buffer.from(originDataArray[i], 'ascii')
// const decompressData = inflateSync(buffer).toString().split(' ')
// dataDecoded.push(decompressData)
// }
// // trans decoded data to data with time
// for (let i = 0; i < dataDecoded.length - 1; i++) {
// if (i === 0) {
// this.transFirstDataIntoTimeDataFormat(dataDecoded[i], download.start_time, dataDecoded[i + 1][0])
// } else {
// this.transDataIntoTimeDataFormat(dataDecoded[i], dataDecoded[i + 1][0])
for (let j = 0; j < 10; j++) {
let dataString = ''
for (let idx = 0; idx < 100000; idx++) {
// console.log('idx', idx)
const indexData = []
// for (const i in range(cycle)) {
// for (const _ch of JSON.parse(headers.channels)) {
// // console.log('data', data[_ch][i][idx])
// if (data[_ch][i][idx + j * 1e5] === undefined) {
// indexData.push(...[])
// } else {
// indexData.push(...data[_ch][i][idx + j * 1e5])
// }
// }
// // idx = idx + 1
// }
dataString = dataString + indexData.join(',') + '\r\n'
}
// console.log('dataString', dataString)
yield dataString
}
console.log('done')
// if (JSON.parse(headers.channels).length > 0) {
// for (const channel of JSON.parse(headers.channels)) {
// if (data[channel].length > maxLength) {
// maxLength = data[channel].length
// }
// }
// this.transLastDataIntoTimeDataFormat(dataDecoded[dataDecoded.length - 1], download.end_time)
// dataIndex = 0
// })
},
exportCSV: async function (downloadInfo) {
const downloadData = file.getFileInfo(downloadInfo.metaPath).data.meta.downloadBlockList
const timeRangeInMilliSecond = downloadInfo.timeRange.map(time => time * 1000)
const availableChannel = downloadInfo.channel.filter(ch =>
ch.checked === true,
).map(ch => {
return ch.channel
})
// for (const channel of JSON.parse(headers.channels)) {
// if (maxLength > data[channel].length) {
// let lengthDiff = maxLength - data[channel].length
// while (lengthDiff !== 0) {
// data[channel].push(['', ''])
// lengthDiff -= 1
// }
// }
// }
// const stopIndex = maxLength
// cycle = parseInt(stopIndex / 1e6)
// filter data with avaliable channel
const filterData = downloadData.filter(
data => availableChannel.includes(data.channel) &&
timeRangeInMilliSecond[0] <= data.end_time &&
timeRangeInMilliSecond[1] >= data.start_time,
)
filterData.forEach(download => {
header = header.concat(['channel' + download.channel, ''])
title = title.concat(['Time(ms)', 'Value'])
const dataDecoded = []
const originDataArray = download.data.split('line').slice(0, -1)
// decoded compress data
for (let i = 0; i < originDataArray.length; i++) {
const buffer = Buffer.from(originDataArray[i], 'ascii')
const decompressData = inflateSync(buffer).toString().split(' ')
dataDecoded.push(decompressData)
}
// trans decoded data to data with time
for (let i = 0; i < dataDecoded.length - 1; i++) {
if (i === 0) {
this.transFirstDataIntoTimeDataFormat(dataDecoded[i], download.start_time, dataDecoded[i + 1][0])
} else {
this.transDataIntoTimeDataFormat(dataDecoded[i], dataDecoded[i + 1][0])
}
}
this.transLastDataIntoTimeDataFormat(dataDecoded[dataDecoded.length - 1], download.end_time)
dataIndex = 0
})
console.log(allChannelData)
// const getCSVFile = async () => {
// const headerStr = header.join(',') + '\r\n'
// const titleStr = title.join(',') + '\r\n'
// const dataStr = this.convertToCSV(allChannelData)
// console.log(downloadInfo)
// const fileName = `${downloadInfo.filenameWithType.split('.')[0]}.csv`
// /* TODO decrease create BLOB time spend */
// console.log('create Blob')
// console.log(performance.now())
// const blob = new Blob([headerStr + titleStr + dataStr], {
// type: 'text/csv',
// })
// console.log('create Blob Finish')
// console.log(performance.now())
// const href = URL.createObjectURL(blob)
// let link = document.createElement('a')
// document.body.appendChild(link)
// link.href = href
// link.download = fileName
// link.click()
// console.log('Download Finish')
// console.log(performance.now())
// // destroy
// header.length = 0
// title.length = 0
// allChannelData.length = 0
// link = null
// if (cycle === 0) {
// while (stopIndex !== idx) {
// const indexData = []
// for (const _ch of JSON.parse(headers.channels)) {
// indexData.push(...data[_ch][idx])
// }
// idx = idx + 1
// dataString = dataString + indexData.join(',') + '\r\n'
// }
// } else {
// for (let i = 0; i < 1e6; i++) {
// const indexData = []
// for (let j = 0; j <= cycle; j++) {
// for (const _ch of JSON.parse(headers.channels)) {
// if (data[_ch][idx + (j * 1e6)] === undefined) {
// indexData.push(...[])
// } else {
// indexData.push(...data[_ch][idx + (j * 1e6)])
// }
// }
// }
// idx = idx + 1
// dataString = dataString + indexData.join(',') + '\r\n'
// }
// }
// return [dataString, cycle]
// }
// getCSVFile()
},
// exportOpenEphys: async function (downloadInfo) {
// const downloadData = file.getFileInfo(downloadInfo.metaPath).data.meta.downloadBlockList
// const timeRangeInMilliSecond = downloadInfo.timeRange.map(time => time * 1000)
// const availableChannel = downloadInfo.channel.filter(ch =>
// ch.checked === true,
// ).map(ch => {
// return ch.channel
// })
// // filter data with avaliable channel
// const filterData = downloadData.filter(
// data => availableChannel.includes(data.channel) &&
// timeRangeInMilliSecond[0] <= data.end_time &&
// timeRangeInMilliSecond[1] >= data.start_time,
// )
// filterData.forEach(download => {
// header = header.concat(['channel' + download.channel, ''])
// title = title.concat(['Time(ms)', 'Value'])
// const dataDecoded = []
// const originDataArray = download.data.split('line').slice(0, -1)
// // decoded compress data
// for (let i = 0; i < originDataArray.length; i++) {
// const buffer = Buffer.from(originDataArray[i], 'ascii')
// const decompressData = inflateSync(buffer).toString().split(' ')
// dataDecoded.push(decompressData)
// }
// // trans decoded data to data with time
// for (let i = 0; i < dataDecoded.length - 1; i++) {
// if (i === 0) {
// this.transFirstDataIntoTimeDataFormatWithoutSwitchLine(dataDecoded[i], download.start_time, dataDecoded[i + 1][0])
// } else {
// this.transDataIntoTimeDataFormatWithoutSwitchLine(dataDecoded[i], dataDecoded[i + 1][0])
// }
// }
// this.transLastDataIntoTimeDataFormatWithoutSwitchLine(dataDecoded[dataDecoded.length - 1], download.end_time)
// dataIndex = 0
// })
// console.log('openephy data', openEphysData)
// const a = [Int16Array.from(openㄡEphysData)]
// console.log(a)
// const dataStr = this.convertOneLineDataToCSV(openEphysData)
// const timeStr = this.convertOneLineDataToCSV(openEphysTimestamp)
// const fileName = 'continous.dat'
// const fileName1 = 'timestamps.npy'
// const blob = new Blob([dataStr], {
// type: 'application/octet-stream',
// })
// console.log('create Blob Finish')
// console.log(performance.now())
// const blob1 = new Blob([timeStr], {
// type: 'application/octet-stream',
// })
// const href = URL.createObjectURL(blob)
// let link = document.createElement('a')
// document.body.appendChild(link)
// link.href = href
// link.download = fileName
// link.click()
// console.log('Download Finish')
// console.log(performance.now())
// // destroy
// header.length = 0
// title.length = 0
// allChannelData.length = 0
// link = null
// const href1 = URL.createObjectURL(blob1)
// link = document.createElement('a')
// document.body.appendChild(link)
// link.href = href1
// link.download = fileName1
// link.click()
// console.log('Download Finish')
// console.log(performance.now())
// // console.log('openephy timestamp', openEphysTimestamp)
// },
convertToCSV: function (objArray) {
const array = typeof objArray !== 'object' ? JSON.parse(objArray) : objArray
return array.map(e => e.join(',')).join('\r\n')
},
_convertToCSV: function (objArray) {
const array = typeof objArray !== 'object' ? JSON.parse(objArray) : objArray
let str = ''
for (let i = 0; i < array.length; i++) { // eslint-disable-line
let line = ''
for (const index in array[i]) { // eslint-disable-line
if (line !== '') line += ','
line += array[i][index]
}
str += line + '\r\n'; // eslint-disable-line
}
return str
},
convertHeaderToCSV: function (objArray) {
const array = typeof objArray !== 'object' ? JSON.parse(objArray) : objArray
let str = ''
for (let i = 0; i < array.length; i++) { // eslint-disable-line
if (str !== '') str += ','
str += array[i]; // eslint-disable-line
}
return str + '\r\n'
},
convertOneLineDataToCSV: function (objArray) {
const array = typeof objArray !== 'object' ? JSON.parse(objArray) : objArray
let str = ''
for (let i = 0; i < array.length; i++) { // eslint-disable-line
if (str !== '') str += '\r\n'
str += array[i]; // eslint-disable-line
}
return str
},
transDataIntoTimeDataFormat: function (currentData, endTime) {
const timeStart = parseInt(currentData[0])
const timeEnd = endTime
const timeSpare = (timeEnd - timeStart) / (currentData.length - 1)
for (let i = 1; i <= currentData.length - 1; i++) {
const time = parseInt(timeStart + ((i - 1) * timeSpare))
const data = currentData[i]
const tmpData = [time, data]
if (dataIndex >= allChannelData.length) {
allChannelData.push(tmpData)
} else {
allChannelData[dataIndex % 1000000] = allChannelData[dataIndex % 1000000].concat(tmpData)
}
dataIndex += 1
}
},
transFirstDataIntoTimeDataFormat: function (currentData, startTime, endTime) {
const timeStart = parseInt(startTime)
const timeEnd = parseInt(endTime)
const timeSpare = (timeEnd - timeStart) / (currentData.length - 1)
for (let i = 1; i <= currentData.length - 1; i++) {
const time = parseInt(timeStart + ((i - 1) * timeSpare))
const data = currentData[i]
const tmpData = [time, data]
if (dataIndex >= allChannelData.length) {
allChannelData.push(tmpData)
} else {
allChannelData[dataIndex % 1000000] = allChannelData[dataIndex % 1000000].concat(tmpData)
}
dataIndex += 1
}
},
transLastDataIntoTimeDataFormat: function (currentData, endTime) {
const timeStart = parseInt(currentData[0])
const timeEnd = endTime
const timeSpare = (timeEnd - timeStart) / (currentData.length - 2)
for (let i = 1; i <= currentData.length - 1; i++) {
const time = parseInt(timeStart + ((i - 1) * timeSpare))
const data = currentData[i]
const tmpData = [time, data]
if (dataIndex >= allChannelData.length) {
allChannelData.push(tmpData)
} else {
allChannelData[dataIndex % 1000000] = allChannelData[dataIndex % 1000000].concat(tmpData)
}
dataIndex += 1
}
// return ''
},
}
+1 -1
View File
@@ -135,7 +135,7 @@ export const file = {
// pushDownloadInfo: function (path, downloadInfo) {
// _fileInfoList.find(fileInfo => fileInfo.data.path === path).data.meta.downloadBlockList.push(downloadInfo)
// },
// pushDownloadData: function (path, subfile, downldoadData) {
// pushdownloadBuffer: function (path, subfile, downldoadData) {
// const downloadInfo = _fileInfoList
// .find(fileInfo => fileInfo.data.path === path).data.meta.downloadBlockList
// .find(downloadInfo => downloadInfo.name === subfile)
+5
View File
@@ -165,6 +165,11 @@ export const getFileInfoFormat = () => {
VOLT_MIN: 22500,
VOLT_ORIGIN: 25000,
VOLT_STEP: 0,
// Elite1.5
ADC_LEVEL_I_15: 0,
ADC_LEVEL_V_IN_15: 0,
CTRL_HIGH_Z_15: 0,
ADC_DAC_CHANNEL_15: 0,
_DEVICE_ADDR_: '',
_DEVICE_NAME_: '',
_LIBRARY_: '',
+13 -11
View File
@@ -1,5 +1,5 @@
const ProjectTotalSettingView = false
const TaskTotalSettingView = false
const controllerMaxNumber = 8
@@ -44,27 +44,27 @@ const transFileSize = (fileSize) => {
return `${(Math.round(fs * 10) / 10).toString()} ${unit}`
}
const transTime = (millisecond) => {
if (millisecond === undefined) {
return ''
const transTime = (microsecond) => {
if (microsecond === undefined || microsecond === 'None') {
return '0 s'
}
let result = ''
if (millisecond < 1000) {
result = '~ 1 sec'
if (microsecond < 1000000) {
result = '~ 1 s'
} else {
let seconds = Math.round(millisecond / 1000)
let seconds = parseInt(microsecond / 1000000)
if (seconds < 60) {
result = `${seconds} s`
} else {
let minutes = Math.round(seconds / 60)
let minutes = parseInt(seconds / 60)
seconds %= 60
if (minutes < 60) {
result = `${minutes} m ${seconds} s`
} else {
const hours = Math.round(minutes / 60)
const hours = parseInt(minutes / 60)
minutes %= 60
result = `${hours} h ${minutes} m ${seconds} s`
}
@@ -74,7 +74,9 @@ const transTime = (millisecond) => {
}
const dateToStr = (time) => {
return time.split('.')[0].replace('T', ' ')
const _time = new Date(time).toLocaleString('tw', { hour12: false })
return _time
// return time.split('.')[0].replace('T', ' ')
// const [, year, month, day, hours, minutes, seconds] = getTimeInDateTime.exec(time)
// const ft = new Date(`${year}/${month}/${day} ${hours}:${minutes}:${seconds}`)
// return ft.toISOString().split('.')[0].replace('T', ' ')
@@ -86,7 +88,7 @@ export default
transFileSize,
transTime,
dateToStr,
ProjectTotalSettingView,
TaskTotalSettingView,
controllerMaxNumber,
DeviceMaxNumber,
ChannelMaxNumber,
-343
View File
@@ -1,343 +0,0 @@
import { getNewProjectFormat } from './ProjectInfoFormat'
const eliteImgUrl = require('../../assets/img/elite_img.png')
const neuliveImgUrl = require('../../assets/img/neulive_img.png')
// import { chartData } from './ChartsManagement'
const _projectInfo = getNewProjectFormat()
// show the devices which mac is included in project
const _deviceList = []
// show the devices which mac is included in project and do not show Time
const _deviceListNoTime = []
// show the all devices which is not register
const _deviceListNotRegister = []
// show the all devices which connected
const _deviceListAll = []
// show the all item can be mapping
const _mappingList = []
export const deviceListRegister = []
const formulaIDStart = 4
const updateAllList = async () => {
_deviceList.length = 0
_deviceListNoTime.length = 0
_deviceListNotRegister.length = 0
_deviceListAll.length = 0
_mappingList.length = 0
_deviceList.push({
id: -1,
name: 'Time',
})
for (const device in _projectInfo.deviceList) {
if (_projectInfo.deviceList[parseInt(device)].info.status === 'connected') {
let _deviceListNotRegisterAdd = true
_projectInfo.deviceAddrList.forEach(addr => {
if (addr.toString() === _projectInfo.deviceList[parseInt(device)].info.device_address.toString()) {
_deviceList.push({
id: _projectInfo.projectDeviceID.indexOf(parseInt(device)),
name: '[' + _projectInfo.projectDeviceID.indexOf(parseInt(device)) + '] ' + _projectInfo.deviceList[parseInt(device)].info.device_name,
type: _projectInfo.deviceList[parseInt(device)].info.library_name,
})
_deviceListNoTime.push({
id: _projectInfo.projectDeviceID.indexOf(parseInt(device)),
name: '[' + _projectInfo.projectDeviceID.indexOf(parseInt(device)) + '] ' + _projectInfo.deviceList[parseInt(device)].info.device_name,
type: _projectInfo.deviceList[parseInt(device)].info.library_name,
})
_mappingList.push({
id: _projectInfo.projectDeviceID.indexOf(parseInt(device)),
name: '[' + _projectInfo.projectDeviceID.indexOf(parseInt(device)) + '] ' + _projectInfo.deviceList[parseInt(device)].info.device_name,
type: _projectInfo.deviceList[parseInt(device)].info.library_name,
})
_deviceListNotRegisterAdd = false
}
})
if (_deviceListNotRegisterAdd) {
_deviceListNotRegister.push({
id: parseInt(device),
name: '[' + device + '] ' + _projectInfo.deviceList[parseInt(device)].info.device_name,
type: _projectInfo.deviceList[parseInt(device)].info.library_name,
})
}
_deviceListAll.push({
id: _projectInfo.projectDeviceID.indexOf(parseInt(device)),
name: '[' + _projectInfo.projectDeviceID.indexOf(parseInt(device)) + '] ' + _projectInfo.deviceList[parseInt(device)].info.device_name,
type: _projectInfo.deviceList[parseInt(device)].info.library_name,
})
}
}
_projectInfo.formulaList.forEach(formula => {
_mappingList.push({
id: formula.id,
name: formula.name,
type: formula.type,
})
})
return _deviceList
}
export const projectInfo = {
updateProjectInfo: async (projectID) => {
const update = async () => {
_projectInfo.controllerID = 'tommy_test'
}
// _projectInfo.deviceAddrList = [[128, 111, 176, 237, 124, 140], [164, 218, 50, 212, 231, 58], [24, 4, 237, 55, 198, 53]]
// _projectInfo.chartNumber = _projectInfo.deviceAddrList.length
await update()
return _projectInfo
},
destroyed: () => {
_projectInfo.controllerID = ''
_projectInfo.deviceAddrList.length = 0
_projectInfo.projectDeviceID.length = 0
_projectInfo.chartNumber = 0
deviceListRegister.length = 0
for (const device in _projectInfo.deviceList) {
_projectInfo.deviceList[device].info.status = ''
_projectInfo.deviceList[device].info.isSync = false
}
_projectInfo.formulaList.length = 0
},
deviceInfo: async (mes) => {
const mesObj = JSON.parse(mes)
const update = async () => {
try {
if (Array.isArray(mesObj.data)) {
mesObj.data.forEach(device => {
for (const item in device) {
if (parseInt(device.device_id) >= 0) {
if (item !== 'configuration') {
_projectInfo.deviceList[device.device_id].info[item] = device[item]
} else {
for (const parameter in device[item]) {
_projectInfo.deviceList[device.device_id].parameterSet[parameter] = device[item][parameter]
}
}
}
}
})
} else {
for (const item in mesObj.data) {
if (parseInt(mesObj.data.device_id) >= 0) {
if (item !== 'configuration') {
_projectInfo.deviceList[mesObj.data.device_id].info[item] = mesObj.data[item]
} else {
for (const parameter in mesObj.data[item]) {
_projectInfo.deviceList[mesObj.data.device_id].parameterSet[parameter] = mesObj.data[item][parameter]
}
}
}
}
}
} catch (e) {
console.log(e)
return false
}
}
await update()
await updateAllList()
return true
},
deviceSavePath: async (mes) => {
const mesObj = JSON.parse(mes)
const update = async () => {
try {
_projectInfo.deviceList[mesObj.device].info.savePath = mesObj.data
} catch (e) {
console.log(e)
return false
}
}
await update()
return true
},
deviceParameter: async (mes) => {
const mesObj = JSON.parse(mes)
const update = async () => {
try {
for (const parameter in mesObj.data) {
_projectInfo.deviceList[mesObj.device].parameterSet[parameter] = mesObj.data[parameter]
}
} catch (e) {
console.log(e)
return false
}
}
await update()
await updateAllList()
return true
},
deviceConnected: async (id) => {
const update = async () => {
_projectInfo.deviceList[parseInt(id)].info.status = 'connected'
}
await update()
await updateAllList()
},
deviceDisconnected: async (deviceID) => {
const update = async () => {
projectInfo.getProjectInfo().deviceAddrList.splice(_projectInfo.projectDeviceID.indexOf(parseInt(deviceID)), 1)
deviceListRegister.forEach(device => {
if (device.id === _projectInfo.projectDeviceID.indexOf(parseInt(deviceID))) {
deviceListRegister.splice(deviceListRegister.indexOf(device), 1)
}
})
deviceListRegister.forEach(device => {
if (device.id > _projectInfo.projectDeviceID.indexOf(parseInt(deviceID))) {
device.id--
}
})
_projectInfo.projectDeviceID.splice(_projectInfo.projectDeviceID.indexOf(parseInt(deviceID)), 1)
_projectInfo.deviceList[parseInt(deviceID)].info.status = 'disconnected'
}
await update()
await updateAllList()
},
controllerShutdown: async () => {
const update = async () => {
for (const device in _projectInfo.deviceList) {
_projectInfo.deviceList[device].info.status = 'disconnected'
}
for (const chart in _projectInfo.chartList) {
_projectInfo.chartList[chart].run = false
}
deviceListRegister.length = 0
}
await update()
await updateAllList()
},
deviceStart: async (deviceID) => {
const update = async () => {
_projectInfo.deviceList[deviceID].info.isSync = true
deviceListRegister.forEach(device => {
if (device.id === _projectInfo.projectDeviceID.indexOf(parseInt(deviceID))) {
device.isSync = true
}
})
}
await update()
},
deviceStop: async (deviceID) => {
const update = async () => {
_projectInfo.deviceList[deviceID].info.isSync = false
deviceListRegister.forEach(device => {
if (device.id === _projectInfo.projectDeviceID.indexOf(parseInt(deviceID))) {
device.isSync = false
}
})
}
await update()
},
updateChartInfo: async () => {
// for (const chartID in _projectInfo.chartList) {
// if (chartData.getChartsData(chartID) == null) {
// chartData.init(chartID, 2000, 1, 1)
// }
// chartData.getChartsData(chartID).cardName = _projectInfo.chartList[chartID].cardName
// chartData.getChartsData(chartID).run = _projectInfo.chartList[chartID].run
// chartData.getChartsData(chartID).cardHeight = _projectInfo.chartList[chartID].cardHeight
// chartData.getChartsData(chartID).cardWidth = _projectInfo.chartList[chartID].cardWidth
// chartData.getChartsData(chartID).maxDots = _projectInfo.chartList[chartID].maxDots
// chartData.getChartsData(chartID).samplingRate = _projectInfo.chartList[chartID].samplingRate
// chartData.updateGridList(chartID, _projectInfo.chartList[chartID].grids.length)
// for (let i = 0; i < _projectInfo.chartList[chartID].grids.length; i++) {
// _projectInfo.chartList[chartID].grids[i].forEach(line => {
// if (line.x[0] === -1) {
// chartData.register('NeuLive', i, chartID, line.y[0], line.y[1])
// } else {
// chartData.register('Elite', i, chartID, line.x[0], line.x[1], line.y[0], line.y[1])
// }
// })
// }
// }
// return _projectInfo
},
getDevicePic: (libraryName) => {
if (libraryName == null) {
return false
}
if (libraryName.indexOf('Elite') >= 0) {
return eliteImgUrl
} else if (libraryName.indexOf('Neulive') >= 0) {
return neuliveImgUrl
}
},
addFormula: (formula) => {
_projectInfo.formulaList.push(formula)
},
removeFormula: (formula) => {
_projectInfo.formulaList.splice(formula, 1)
},
updateAllList: async () => {
return await updateAllList()
},
getProjectInfo: () => {
return _projectInfo
},
getDeviceIDByRaw: (_deviceID) => {
return _projectInfo.projectDeviceID.indexOf(_deviceID)
},
getRawDeviceID: (_projectDeviceID) => {
return _projectInfo.projectDeviceID[_projectDeviceID]
},
getDeviceInfo: (_projectDeviceID) => {
return _projectInfo.deviceList[_projectInfo.projectDeviceID[_projectDeviceID]]
},
getDeviceInfoByRawID: (_deviceID) => {
return _projectInfo.deviceList[_deviceID]
},
getDeviceList: () => {
return _deviceList
},
getDeviceListNoTime: () => {
return _deviceListNoTime
},
getDeviceListNotRegister: () => {
return _deviceListNotRegister
},
getDeviceListAll: () => {
return _deviceListAll
},
getDeviceListRegister: () => {
return deviceListRegister
},
getMappingList: () => {
return _mappingList
},
getFormulaList: () => {
return _projectInfo.formulaList
},
getFormulaIDStart: () => {
return formulaIDStart
},
}
-495
View File
@@ -1,495 +0,0 @@
export const getNewProjectFormat = () => {
const projectFormat = {
controllerID: '',
deviceAddrList: [],
projectDeviceID: [],
chartNumber: 0,
deviceList: {
4: {
info: {
battery: 0,
device_address: [],
device_id: 4,
device_name: '',
device_version: '',
library_name: '',
library_version: '',
serial_number: [],
status: '',
isSync: false,
},
parameterSet: {
// Neulive
ADC_CLOCK: 0,
ADDRESS: 0,
AMP_GAIN: 0,
CHANNEL: {},
CHOPPER_RATIO: 0,
CONTINUOUS_STI: true,
FREQUENCY: 0,
PERIOD: 0,
RECORDING: false,
RECORDING_CH: 0,
REGISTER: 0,
RIS_PARA: 0,
SAMPLE_RATE: 0,
STI1_CYCLE: 0,
STI2_CYCLE: 0,
STI3_CYCLE: 0,
STI4_CYCLE: 0,
STI5_CYCLE: 0,
STI6_CYCLE: 0,
STI7_CYCLE: 0,
STI8_CYCLE: 0,
STIMULATING: false,
STI_AMPLITUDE: 0,
STI_AMPLITUDE_H: 0,
STI_AMPLITUDE_L: 0,
STI_CHANNEL: 0,
STI_CHANNEL_SET: {},
STI_CLOCK_RATIO: 0,
STI_CYCLE: 0,
STI_CYCLE_LIST: [],
STI_H_BRIDGE: true,
STI_PATTERN: true,
STI_POLARITY: 0,
STI_POLARITY_LIST: [],
STI_REF: false,
STI_SWITCH: false,
STI_T1: [],
STI_T2: [],
STI_T3: [],
STI_T4: [],
STI_T5: [],
SYSTEM_CLK: 0,
StiChNumber: '',
VGRN: 0,
VGRP: 0,
VGR_INT_N: 0,
VGR_INT_OLD: 0,
VGR_INT_P: 0,
ch1: 0,
ch2: 0,
ch3: 0,
ch4: 0,
ch5: 0,
ch6: 0,
ch7: 0,
ch8: 0,
ADC_CHANNEL: 0,
// Eilte
ADC_LEVEL: 0,
ADC_VALUE_I: 0,
ADC_VALUE_V: 0,
CHANNEL_LABEL: [],
CURRNET_LIMIT_VALUE: 1500000,
CYCLE_NUMBER: 0,
Charge: 1,
Const_Current_VStop: 0,
Const_Current_unit: 1,
Const_Current_value: 0,
DAC_VOLT: 25000,
Data_Resolution_Scan: 1000,
MODE: 0,
Resister_LEVEL: 3,
STEP_TIME: 1,
Scan_Rate: 10000,
VOLTSTOP_MAX: 50000,
VOLTSTOP_MIN: 0,
VOLT_EFINAL: 25000,
VOLT_FINAL: 25000,
VOLT_INITIAL: 25000,
VOLT_MAX: 27500,
VOLT_MIN: 22500,
VOLT_ORIGIN: 25000,
VOLT_STEP: 0,
_DEVICE_ADDR_: '',
_DEVICE_NAME_: '',
_LIBRARY_: '',
_VERSION_: '',
},
},
5: {
info: {
battery: 0,
device_address: [],
device_id: 4,
device_name: '',
device_version: '',
library_name: '',
library_version: '',
serial_number: [],
status: '',
isSync: false,
},
parameterSet: {
// Neulive
ADC_CLOCK: 0,
ADDRESS: 0,
AMP_GAIN: 0,
CHANNEL: {},
CHOPPER_RATIO: 0,
CONTINUOUS_STI: true,
FREQUENCY: 0,
PERIOD: 0,
RECORDING: false,
RECORDING_CH: 0,
REGISTER: 0,
RIS_PARA: 0,
SAMPLE_RATE: 0,
STI1_CYCLE: 0,
STI2_CYCLE: 0,
STI3_CYCLE: 0,
STI4_CYCLE: 0,
STI5_CYCLE: 0,
STI6_CYCLE: 0,
STI7_CYCLE: 0,
STI8_CYCLE: 0,
STIMULATING: false,
STI_AMPLITUDE: 0,
STI_AMPLITUDE_H: 0,
STI_AMPLITUDE_L: 0,
STI_CHANNEL: 0,
STI_CHANNEL_SET: {},
STI_CLOCK_RATIO: 0,
STI_CYCLE: 0,
STI_CYCLE_LIST: [],
STI_H_BRIDGE: true,
STI_PATTERN: true,
STI_POLARITY: 0,
STI_POLARITY_LIST: [],
STI_REF: false,
STI_SWITCH: false,
STI_T1: [],
STI_T2: [],
STI_T3: [],
STI_T4: [],
STI_T5: [],
SYSTEM_CLK: 0,
StiChNumber: '',
VGRN: 0,
VGRP: 0,
VGR_INT_N: 0,
VGR_INT_OLD: 0,
VGR_INT_P: 0,
ch1: 0,
ch2: 0,
ch3: 0,
ch4: 0,
ch5: 0,
ch6: 0,
ch7: 0,
ch8: 0,
ADC_CHANNEL: 0,
// Eilte
ADC_LEVEL: 0,
ADC_VALUE_I: 0,
ADC_VALUE_V: 0,
CHANNEL_LABEL: [],
CURRNET_LIMIT_VALUE: 1500000,
CYCLE_NUMBER: 0,
Charge: 1,
Const_Current_VStop: 0,
Const_Current_unit: 1,
Const_Current_value: 0,
DAC_VOLT: 25000,
Data_Resolution_Scan: 1000,
MODE: 0,
Resister_LEVEL: 3,
STEP_TIME: 1,
Scan_Rate: 10000,
VOLTSTOP_MAX: 50000,
VOLTSTOP_MIN: 0,
VOLT_EFINAL: 25000,
VOLT_FINAL: 25000,
VOLT_INITIAL: 25000,
VOLT_MAX: 27500,
VOLT_MIN: 22500,
VOLT_ORIGIN: 25000,
VOLT_STEP: 0,
_DEVICE_ADDR_: '',
_DEVICE_NAME_: '',
_LIBRARY_: '',
_VERSION_: '',
},
},
6: {
info: {
battery: 0,
device_address: [],
device_id: 4,
device_name: '',
device_version: '',
library_name: '',
library_version: '',
serial_number: [],
status: '',
isSync: false,
},
parameterSet: {
// Neulive
ADC_CLOCK: 0,
ADDRESS: 0,
AMP_GAIN: 0,
CHANNEL: {},
CHOPPER_RATIO: 0,
CONTINUOUS_STI: true,
FREQUENCY: 0,
PERIOD: 0,
RECORDING: false,
RECORDING_CH: 0,
REGISTER: 0,
RIS_PARA: 0,
SAMPLE_RATE: 0,
STI1_CYCLE: 0,
STI2_CYCLE: 0,
STI3_CYCLE: 0,
STI4_CYCLE: 0,
STI5_CYCLE: 0,
STI6_CYCLE: 0,
STI7_CYCLE: 0,
STI8_CYCLE: 0,
STIMULATING: false,
STI_AMPLITUDE: 0,
STI_AMPLITUDE_H: 0,
STI_AMPLITUDE_L: 0,
STI_CHANNEL: 0,
STI_CHANNEL_SET: {},
STI_CLOCK_RATIO: 0,
STI_CYCLE: 0,
STI_CYCLE_LIST: [],
STI_H_BRIDGE: true,
STI_PATTERN: true,
STI_POLARITY: 0,
STI_POLARITY_LIST: [],
STI_REF: false,
STI_SWITCH: false,
STI_T1: [],
STI_T2: [],
STI_T3: [],
STI_T4: [],
STI_T5: [],
SYSTEM_CLK: 0,
StiChNumber: '',
VGRN: 0,
VGRP: 0,
VGR_INT_N: 0,
VGR_INT_OLD: 0,
VGR_INT_P: 0,
ch1: 0,
ch2: 0,
ch3: 0,
ch4: 0,
ch5: 0,
ch6: 0,
ch7: 0,
ch8: 0,
ADC_CHANNEL: 0,
// Eilte
ADC_LEVEL: 0,
ADC_VALUE_I: 0,
ADC_VALUE_V: 0,
CHANNEL_LABEL: [],
CURRNET_LIMIT_VALUE: 1500000,
CYCLE_NUMBER: 0,
Charge: 1,
Const_Current_VStop: 0,
Const_Current_unit: 1,
Const_Current_value: 0,
DAC_VOLT: 25000,
Data_Resolution_Scan: 1000,
MODE: 0,
Resister_LEVEL: 3,
STEP_TIME: 1,
Scan_Rate: 10000,
VOLTSTOP_MAX: 50000,
VOLTSTOP_MIN: 0,
VOLT_EFINAL: 25000,
VOLT_FINAL: 25000,
VOLT_INITIAL: 25000,
VOLT_MAX: 27500,
VOLT_MIN: 22500,
VOLT_ORIGIN: 25000,
VOLT_STEP: 0,
_DEVICE_ADDR_: '',
_DEVICE_NAME_: '',
_LIBRARY_: '',
_VERSION_: '',
},
},
7: {
info: {
battery: 0,
device_address: [],
device_id: 4,
device_name: '',
device_version: '',
library_name: '',
library_version: '',
serial_number: [],
status: '',
isSync: false,
},
parameterSet: {
// Neulive
ADC_CLOCK: 0,
ADDRESS: 0,
AMP_GAIN: 0,
CHANNEL: {},
CHOPPER_RATIO: 0,
CONTINUOUS_STI: true,
FREQUENCY: 0,
PERIOD: 0,
RECORDING: false,
RECORDING_CH: 0,
REGISTER: 0,
RIS_PARA: 0,
SAMPLE_RATE: 0,
STI1_CYCLE: 0,
STI2_CYCLE: 0,
STI3_CYCLE: 0,
STI4_CYCLE: 0,
STI5_CYCLE: 0,
STI6_CYCLE: 0,
STI7_CYCLE: 0,
STI8_CYCLE: 0,
STIMULATING: false,
STI_AMPLITUDE: 0,
STI_AMPLITUDE_H: 0,
STI_AMPLITUDE_L: 0,
STI_CHANNEL: 0,
STI_CHANNEL_SET: {},
STI_CLOCK_RATIO: 0,
STI_CYCLE: 0,
STI_CYCLE_LIST: [],
STI_H_BRIDGE: true,
STI_PATTERN: true,
STI_POLARITY: 0,
STI_POLARITY_LIST: [],
STI_REF: false,
STI_SWITCH: false,
STI_T1: [],
STI_T2: [],
STI_T3: [],
STI_T4: [],
STI_T5: [],
SYSTEM_CLK: 0,
StiChNumber: '',
VGRN: 0,
VGRP: 0,
VGR_INT_N: 0,
VGR_INT_OLD: 0,
VGR_INT_P: 0,
ch1: 0,
ch2: 0,
ch3: 0,
ch4: 0,
ch5: 0,
ch6: 0,
ch7: 0,
ch8: 0,
ADC_CHANNEL: 0,
// Eilte
ADC_LEVEL: 0,
ADC_VALUE_I: 0,
ADC_VALUE_V: 0,
CHANNEL_LABEL: [],
CURRNET_LIMIT_VALUE: 1500000,
CYCLE_NUMBER: 0,
Charge: 1,
Const_Current_VStop: 0,
Const_Current_unit: 1,
Const_Current_value: 0,
DAC_VOLT: 25000,
Data_Resolution_Scan: 1000,
MODE: 0,
Resister_LEVEL: 3,
STEP_TIME: 1,
Scan_Rate: 10000,
VOLTSTOP_MAX: 50000,
VOLTSTOP_MIN: 0,
VOLT_EFINAL: 25000,
VOLT_FINAL: 25000,
VOLT_INITIAL: 25000,
VOLT_MAX: 27500,
VOLT_MIN: 22500,
VOLT_ORIGIN: 25000,
VOLT_STEP: 0,
_DEVICE_ADDR_: '',
_DEVICE_NAME_: '',
_LIBRARY_: '',
_VERSION_: '',
},
},
},
chartList: [],
formulaList: [],
// 0: {
// cardName: 'chart0',
// run: false,
// cardHeight: '500px',
// cardWidth: 'auto',
// maxDots: 4000,
// samplingRate: 1,
// grids: [
// [],
// ],
// },
// 1: {
// cardName: 'chart1',
// run: false,
// cardHeight: '500px',
// cardWidth: 'auto',
// maxDots: 4000,
// samplingRate: 1,
// grids: [
// [],
// ],
// },
// 2: {
// cardName: 'chart2',
// run: false,
// cardHeight: '500px',
// cardWidth: 'auto',
// maxDots: 4000,
// samplingRate: 1,
// grids: [
// [],
// ],
// },
// 3: {
// cardName: 'chart3',
// run: false,
// cardHeight: '500px',
// cardWidth: 'auto',
// maxDots: 4000,
// samplingRate: 1,
// grids: [
// [],
// ],
// },
// 4: {
// cardName: 'chart4',
// run: false,
// cardHeight: '500px',
// cardWidth: 'auto',
// maxDots: 4000,
// samplingRate: 1,
// grids: [
// [],
// ],
// },
// 5: {
// cardName: 'chart5',
// run: false,
// cardHeight: '500px',
// cardWidth: 'auto',
// maxDots: 4000,
// samplingRate: 1,
// grids: [
// [],
// ],
// },
}
return projectFormat
}

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