Compare commits

...

118 Commits

Author SHA1 Message Date
ROY c4417a6458 [update] update GENERAL_HS_RTIA parameter 2022-11-08 16:13:46 +08:00
ROY 91c02007bc [update] update EIS_AVERAGE_NUM parameter 2022-11-08 15:58:32 +08:00
ROY 023de635fa [update] update EIS_DELAY parameter 2022-11-08 15:45:13 +08:00
ROY 4b410bfb3a [update] update EIS_SCALE parameter 2022-11-08 15:36:40 +08:00
ROY 2c205af6dd [update] update EIS_PPD parameter 2022-11-08 14:49:40 +08:00
ROY e517e9f796 [update] update EIS_AC_AMP parameter 2022-11-08 14:24:41 +08:00
ROY a5a590c007 [update] update EIS_DC_BIAS parameter 2022-11-08 14:18:05 +08:00
ROY 3dae7e644a [update] update EIS_FREQ parameter 2022-11-08 12:07:35 +08:00
ROY 768168c614 [update] delete FREQ_START & FREQ_STOP parameter 2022-11-08 11:05:56 +08:00
ROY 0a4635d648 [update] delete CHANNEL_LABEL parameter 2022-11-08 10:39:16 +08:00
ROY 3eb0e66b01 [update] update RT mode 2022-10-27 17:42:47 +08:00
peterlu14 a44f865d2d [update] disable RT Mode 2022-10-26 13:45:55 +08:00
peterlu14 46cf78cd55 [update] hide scheduler 2022-10-26 10:08:36 +08:00
ROY 200a8d25fa [update] EIS RT Mode 2022-10-25 13:32:37 +08:00
peterlu14 b5908f8815 [update] EIS RT Mode 2022-10-25 10:16:37 +08:00
peterlu14 abf5b0e54b [update] projectTable UI 2022-10-18 11:51:10 +08:00
peterlu14 9637a5365e [update] remove some condition & add device SelectKey in condition & project table UI 2022-10-18 11:42:20 +08:00
peterlu14 2c1e247178 [update&debug] fix rearrange problem & add copy function & auto pair device in task 2022-10-18 11:38:19 +08:00
peterlu14 dbbf30623d [update] task device setting big update & auto register connect device 2022-10-14 17:43:11 +08:00
peterlu14 eeb43694b1 [update] add order property in device 2022-10-14 16:03:42 +08:00
peterlu14 4054a113d0 [update] remove device hide modal 2022-10-14 16:01:15 +08:00
peterlu14 6bcf4b100f [update] remove add device button 2022-10-14 11:10:26 +08:00
peterlu14 a2237aeb0a [update] add detect function 2022-10-14 10:27:55 +08:00
peterlu14 2972fa365c [update] remove old auto get device 2022-10-14 10:14:12 +08:00
peterlu14 75d71099ed [update] device need to pair to run scheduler 2022-10-14 10:13:28 +08:00
peterlu14 2ab96c3bf6 [update] scheduler device big update from array to object & auto pairing 2022-10-14 10:11:17 +08:00
peterlu14 a088b940e6 [update] fix EIS DELAY range & add library EDC EIS 2022-10-14 10:06:13 +08:00
peterlu14 59ce90d348 [update] temp fix many project message error 2022-10-11 10:48:40 +08:00
peterlu14 01f1cf28d5 [update] temp fix project table element key duplicate error 2022-10-11 10:48:08 +08:00
peterlu14 b826442672 [update] fix project copy 2022-10-11 10:47:27 +08:00
ROY 0c385ee212 [update] remove LEVEL_V button and update V_RANGE label name 2022-10-06 16:54:42 +08:00
peterlu14 15eeb513a6 [debug] fix eis replay parameter & eis realtime chart fix 2022-10-05 18:09:11 +08:00
peterlu14 f5f30cbe61 [debug] eis realtime chart source and cache problem 2022-10-05 17:01:58 +08:00
peterlu14 f7dbf43e77 [update] project enable Elite_EDC & Elite_EIS 2022-10-05 12:02:28 +08:00
peterlu14 dba675254d [update] FREQ 13333333 2022-10-05 12:00:28 +08:00
peterlu14 7635f991c1 [update] vt add parameter MEASURE_VIN_RANGE 2022-10-05 11:21:49 +08:00
peterlu14 476a1699a5 [update] add VT_MODE 2022-10-05 10:59:50 +08:00
peterlu14 8131a19e97 [debug] fix copy id 2022-10-04 13:56:47 +08:00
peterlu14 c310cd4253 [update] check action target when create fake action 2022-10-04 13:56:27 +08:00
peterlu14 6c80390917 [debug] dismiss type error 2022-10-04 13:55:00 +08:00
peterlu14 ff0da52db8 [update] remove cycle & text ui & add -> + 2022-09-30 11:37:46 +08:00
peterlu14 4074af8b4f Merge remote-tracking branch 'origin/dev/debug_cp' into release/v1.3.8/cycle 2022-09-30 10:59:53 +08:00
peterlu14 562632e417 [update] replay new page & modal outside-dismiss 2022-09-30 10:42:07 +08:00
peterlu14 782efbf366 [update] project add cycle 2022-09-30 10:40:31 +08:00
ROY 6a1a31d6e3 [update] debug cp 2022-09-20 18:49:49 +08:00
ROY 86c7f2b30d [update] update eis AC_AMP fomula 2022-09-16 10:43:39 +08:00
ROY 97de1cf4e3 [update] update eis AC_AMP & FREQ fomula 2022-09-14 18:22:03 +08:00
peterlu14 91e100319f [update] project parameter duplicate remove 2022-09-14 18:19:29 +08:00
peterlu14 ca3a525332 [update] add slide-out 2022-09-07 09:46:53 +08:00
peterlu14 9d77ba9c01 [update] add fake start action at start & add new action idle & add click css 2022-09-06 19:43:19 +08:00
peterlu14 53ba6ee486 [update] battery 1s -> 1min & Potential force direct to V 2022-09-05 14:48:29 +08:00
peterlu14 cb42635f6a Merge remote-tracking branch 'origin/dev/battery_display' into release/v1.3.6/battery 2022-08-31 10:20:30 +08:00
peterlu14 d43de5927f Merge remote-tracking branch 'origin/dev/sync-parameter' into release/v1.3.5/cached 2022-08-31 10:08:45 +08:00
sss28072637 05ecd69ecd [update] update battery icon & add low battery warning 2022-08-30 18:16:31 +08:00
peterlu14 062938dd0b [update] refresh cache 2022-08-30 15:31:06 +08:00
peterlu14 5e3eb47614 [update] area display fix 2022-08-29 16:48:05 +08:00
peterlu14 1b682421fd [debug] get legend name fail & capture multitimes 2022-08-29 16:36:29 +08:00
peterlu14 aac74382ad Merge remote-tracking branch 'origin/dev/EISReplayFix' into release/v1.3.4/battery&replayEIS 2022-08-29 16:04:11 +08:00
nthu1080112244 0b005638f6 [debug] fix chartAct device undefined 2022-08-29 16:03:43 +08:00
nthu1080112244 f5604b4ad4 [debug] fix typing error 2022-08-29 15:51:03 +08:00
peterlu14 5d772b9d5b Merge remote-tracking branch 'origin/dev/EISReplayFix' into release/v1.3.4/battery&replayEIS 2022-08-29 15:50:26 +08:00
nthu1080112244 857184392c [update] brush delay = 0 2022-08-29 15:46:51 +08:00
nthu1080112244 6c1304bcea [debug] fix specific integral key in bug 2022-08-29 11:40:49 +08:00
nthu1080112244 bcdaecca77 [debug] resolve replay cycle select bug 2022-08-29 11:13:19 +08:00
nthu1080112244 a5330c71dc [debug] fix some typing error 2022-08-29 10:12:41 +08:00
nthu1080112244 a8b6937b72 [update] new setting table, new replay layout 2022-08-26 16:53:23 +08:00
sss28072637 e69e42ac63 [update] adjust the formula of calculating battery, add battery icon & percentage 2022-08-24 17:55:38 +08:00
peterlu14 01f0f45bdd [update] sg_filter scale with sample rate & volt step 2022-08-24 13:27:25 +08:00
ROY 0719284f24 [update] fix VOLT_VSCAN scale 2022-08-23 11:37:02 +08:00
sss28072637 0cecf9abec [update] add battery display 2022-08-22 18:07:06 +08:00
nthu1080112244 93a0ea9b24 Merge branch 'release/v1.3.2/replay_new_function' into dev/EISReplayFix 2022-08-22 17:25:47 +08:00
nthu1080112244 0a7ecfb060 [debug] add comment 2022-08-22 16:40:34 +08:00
nthu1080112244 7642e41d58 [debug] remove annoying console log 2022-08-22 16:16:21 +08:00
nthu1080112244 a0050047d0 [debug] captured chart fix 2022-08-22 16:12:02 +08:00
peterlu14 d3fcf78b45 [refresh] realtime parameter refresh 2022-08-22 11:40:05 +08:00
peterlu14 0d279cb0bf [debug] fix capture data clear problem 2022-08-22 11:38:40 +08:00
peterlu14 44989dd7f7 [debug] fix scheduler parameter not refresh & default MODE = 0 2022-08-22 11:37:56 +08:00
nthu1080112244 07c38de627 [fix] fix real time display 2022-08-22 10:15:12 +08:00
peterlu14 e4c2018e12 Merge remote-tracking branch 'origin/dev/scheduler-function' into release/v1.3.3/merge_scheduler 2022-08-19 18:56:45 +08:00
peterlu14 a0fea97ca7 [update] differential 2022-08-19 18:56:12 +08:00
nthu1080112244 347e1b647f [update] fix add chart option & display bar 2022-08-19 18:16:29 +08:00
108000207 20d94f8c09 [debug] project table library bug (auto connect) 2022-08-19 17:57:06 +08:00
108000207 eb80489c41 [update] scheduler cycle UI 2022-08-19 17:11:37 +08:00
108000207 d337afd7b9 [update] show cycle number on project running 2022-08-19 16:54:20 +08:00
peterlu14 82f46030a3 [update] fix realtime unit function type 2022-08-19 16:17:57 +08:00
peterlu14 8052dfcbf4 [update] file table fix 2022-08-19 15:55:14 +08:00
nthu1080112244 3030b46a64 Merge remote-tracking branch 'origin/dev/source_channel' into dev/repalyControlPanelNew 2022-08-19 14:28:21 +08:00
108000207 ec7edb6bd9 Merge remote-tracking branch 'origin/dev/drag_task' into dev/scheduler-function 2022-08-18 18:25:05 +08:00
unknown eca51be1f8 [update] get source from different mode (some bugs need to be fixed) 2022-08-18 18:21:44 +08:00
108000207 4ac9fe32d1 [update] remove cycle save condition 2022-08-18 18:16:38 +08:00
108000207 46def3dab3 [update] change the UI of scheduler cycle 2022-08-18 17:38:12 +08:00
unknown b560670ada Merge remote-tracking branch 'origin/release/v1.3.2/replay_new_function-hide_project' into dev/drag_task 2022-08-18 14:59:16 +08:00
unknown e7786e6c8c [update] complete drag task function 2022-08-18 14:51:59 +08:00
unknown 60d4b63d6b [update] drag task (remain some bugs need to be fixed) 2022-08-17 17:57:52 +08:00
peterlu14 56559738c4 Revert "[update] realtime chart default unit determine by mode now"
This reverts commit fc269f972a.
2022-08-17 15:37:06 +08:00
peterlu14 7639d495b9 Merge branch 'release/v1.3.2/replay_new_function' into release/v1.3.2/replay_new_function-hide_project 2022-08-17 15:23:26 +08:00
108000207 d08f49548b [update] scheduler cycle v1 ( support nest cycle) 2022-08-17 11:58:32 +08:00
ROY 99f51f4307 Merge remote-tracking branch 'origin/release/v1.3.2/replay_new_function' into dev/sync-parameter 2022-08-17 10:54:29 +08:00
peterlu14 001f7139eb [update] fix file table 2022-08-16 20:27:35 +08:00
peterlu14 27bb612bd8 [update] add eis global mode 2022-08-16 19:51:35 +08:00
peterlu14 f5ce74f308 [update] EIS add VOLT_VSCAN and time_duration 2022-08-16 19:51:31 +08:00
108000207 c85c7b0285 [update] fix cycle count 2022-08-16 14:34:18 +08:00
ROY dec4ad1093 [update] realtime nA support mode [10, 11] 2022-08-16 11:32:14 +08:00
ROY e2735f7782 Merge remote-tracking branch 'origin/release/v1.3.2/replay_new_function' into dev/sync-parameter 2022-08-16 11:30:50 +08:00
108000207 3c14cc552f Merge remote-tracking branch 'origin/dev/scheduler' into dev/scheduler-function 2022-08-16 11:16:58 +08:00
peterlu14 fe723ae897 Merge remote-tracking branch 'origin/dev/delete_actions' into dev/scheduler 2022-08-15 19:10:37 +08:00
peterlu14 fc269f972a [update] realtime chart default unit determine by mode now 2022-08-15 19:06:16 +08:00
sss28072637 c12c4e8fff [update] complete delete actions and the function of swap task 2022-08-15 18:19:50 +08:00
peterlu14 05abfd122a [debug] fix file-table folder show working mode error 2022-08-15 18:12:04 +08:00
JayC319 39bb196db7 message 2022-08-15 17:51:58 +08:00
JayC319 df34998b51 Merge remote-tracking branch 'origin/release/v1.3.2/replay_new_function' into dev/sync-parameter 2022-08-15 17:44:33 +08:00
peterlu14 567d7595cf Merge remote-tracking branch 'origin/dev/delete_actions' into release/v1.3.2/replay_new_function 2022-08-15 14:26:50 +08:00
108000207 a312a32ddc Merge remote-tracking branch 'origin/dev/delete_actions' into dev/scheduler-function 2022-08-15 14:01:48 +08:00
sss28072637 2167f9ef06 [update] complete delete actions, default parameter 2022-08-15 12:01:57 +08:00
108000207 4005961b8a Merge remote-tracking branch 'origin/release/v1.3.2/replay_new_function-hide_project' into dev/scheduler-function 2022-08-15 09:34:37 +08:00
108000207 8cb9ac007e [update] add scheduler cycle at condition, for setting cycle, cycle_next, and cycle_count 2022-08-15 09:31:21 +08:00
108000207 402dd3a66b [debug] fix the bug of project(scheduler): change task but not refresh real-time axis 2022-08-11 15:36:47 +08:00
peterlu14 e2e0b5609a [update] add -sync-parameter 2022-08-09 14:18:38 +08:00
77 changed files with 3136 additions and 1058 deletions
+5
View File
@@ -1217,6 +1217,11 @@
"@hapi/hoek": "^8.3.0"
}
},
"@hyjiacan/vue-slideout": {
"version": "2.5.9",
"resolved": "https://registry.npmjs.org/@hyjiacan/vue-slideout/-/vue-slideout-2.5.9.tgz",
"integrity": "sha512-SSf0QaENGt9B2We8lL5QF+gNK7/pHqUEA8SiwUKtMTDj2rbjhGYFpCD+grV7oAAynGdiEIhQ3b3Mphh9/+keBg=="
},
"@intervolga/optimize-cssnano-plugin": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/@intervolga/optimize-cssnano-plugin/-/optimize-cssnano-plugin-1.0.6.tgz",
+1
View File
@@ -15,6 +15,7 @@
"dependencies": {
"@fontsource/source-code-pro": "^4.5.0",
"@fontsource/source-sans-pro": "^4.5.1",
"@hyjiacan/vue-slideout": "^2.5.9",
"@types/jest": "^24.0.11",
"amcharts3": "^3.21.14",
"ammap3": "^3.21.14",
+3
View File
@@ -2,6 +2,9 @@
<html>
<head>
<meta charset="utf-8">
<!-- <meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0" /> -->
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
+1 -1
View File
@@ -15,7 +15,7 @@ export default {
// Temporary config for 2.1.
contextConfig: {
gradient: true,
shadow: 'lg', // 3 states: 'sm', 'lg', undefined (no shadow).
shadow: 'lg', // 3 states: 'sm', 'sddssslg', undefined (no shadow).
invertedColor: false,
},
}
+7
View File
@@ -30,6 +30,9 @@ import 'vue-toastification/dist/index.css'
import api from '@/data/api/index'
import localforage from 'localforage'
import SlideOut from '@hyjiacan/vue-slideout'
import '@hyjiacan/vue-slideout/lib/slideout.css'
import '../metrics'
import '../registerServiceWorker'
@@ -101,6 +104,10 @@ Vue.use(Toast)
// Vue.use(VueMqtt, 'ws://' + '192.168.151.125' + ':8083')
Vue.use(VueMqtt, MqttUrl)
Vue.use(SlideOut, {
// set default props here
})
Vue.prototype.API = api
Vue.prototype.GLOBAL = global_
@@ -10,6 +10,7 @@
<language-dropdown class="app-navbar-actions__item"/> -->
<license-check-button :ref="'license_check_button_ref'" @updateLicense="updateLicense"/>
<license-update-modal :title="'Update'" :ref="'license_update_modal_ref'" @refresh="refresh"/>
<va-button @click="reload" icon="fa fa-refresh" flat></va-button>
<profile-dropdown class="app-navbar-actions__item app-navbar-actions__item--profile">
<span>{{userName}}</span>
</profile-dropdown>
@@ -70,6 +71,9 @@ export default {
this.$refs.license_check_button_ref.refresh()
this.$refs.license_update_modal_ref.hide()
},
reload () {
window.location.reload(true)
},
},
}
</script>
@@ -380,7 +380,7 @@ export default {
// toolbox: ['rect', 'polygon', 'lineX', 'lineY', 'keep', 'clear'],
xAxisIndex: 0,
throttleType: 'debounce',
throttleDelay: 0.1,
throttleDelay: 0,
}
this.showChartLoading('detail')
const timeDur = this.endTimeCurrent - this.startTimeCurrent
@@ -394,7 +394,7 @@ export default {
})
let scale = '1'
if (this.controlPanel.x.type === 'Time') {
if (this.controlPanel.x.axis.description === 'Time') {
scale = await this.computeResampleScale(metaInfo, timeDur)
}
// elite的sample rate不像neulive這麼高,因此試試scale = 100 or 1000時不要再sampling一次了,不然有些形狀(e.g. peak)會不一樣
@@ -413,11 +413,11 @@ export default {
this.currentScale = scale
this.chartDetailData.series[_gridNumber].data.length = 0
let dataListX
const channelX = parseInt(this.controlPanel.x.channel)
if (this.controlPanel.x.type !== 'Time') {
const channelX = parseInt(this.controlPanel.x.axis.channel)
if (this.controlPanel.x.axis.description !== 'Time') {
dataListX = this.dataInfo[meta][channelX][scale]
}
const channelY = parseInt(this.controlPanel.y.channel)
const channelY = parseInt(this.controlPanel.y.axis.channel)
const dataListY = this.dataInfo[meta][channelY][scale]
const isThisModeHasCycle = this.GLOBAL.hasCycleMode(metaInfo.parameter_set.MODE, metaInfo.device.library_name)
@@ -464,7 +464,7 @@ export default {
for (let i = startIndex; i <= endIndex; i++) {
const data = await this.getData(parseInt(scale), this.sampleMethod, dataListY[i].id, channelY, metaInfo)
let dataX
if (this.controlPanel.x.type !== 'Time') {
if (this.controlPanel.x.axis.description !== 'Time') {
dataX = await this.getData(parseInt(scale), this.sampleMethod, dataListX[i].id, channelX, metaInfo)
}
var deltaX = 0
@@ -566,7 +566,7 @@ export default {
}
}
if (this.controlPanel.x.type === 'Time') {
if (this.controlPanel.x.axis.description === 'Time') {
this.chartDetailData.xAxis[_gridNumber].min = _startTime
this.chartDetailData.xAxis[_gridNumber].max = _endTime
} else {
@@ -576,7 +576,7 @@ export default {
_gridNumber += 1
}
if (this.controlPanel.x.type !== 'Time') {
if (this.controlPanel.x.axis.description !== 'Time') {
this.showOverviewChart = false
this.detailchartheight = '88vh'
// this.$refs.chart_detail.updateChartHeight()
@@ -652,8 +652,8 @@ export default {
// tang
if (this.initDone) {
const libName = this.metaList[gridIndex].device.library_name
const xType = (this.controlPanel.x.type === 'Time') ? 'Time' : ((libName === 'EliteZM15' || libName.includes('Elite_EDC') ? 'Elite' : 'EliteEIS'))
const xChannel = (this.controlPanel.x.channel === -1) ? undefined : this.controlPanel.x.channel + 1
const xType = (this.controlPanel.x.axis.description === 'Time') ? 'Time' : ((libName === 'EliteZM15' || libName.includes('Elite_EDC') ? 'Elite' : 'EliteEIS'))
const xChannel = (this.controlPanel.x.axis.channel === -1) ? undefined : this.controlPanel.x.axis.channel + 1
this.updateRegisteredChart({
chartAllData: this.chartData,
chartID: this.chartDetailData.chartID,
@@ -663,10 +663,10 @@ export default {
channelX: xChannel,
deviceNameY: libName.includes('EIS') ? 'EliteEIS' : 'Elite',
deviceIDY: '',
channelY: this.controlPanel.y.channel + 1,
channelY: this.controlPanel.y.axis.channel + 1,
})
}
if (this.controlPanel.x.type === 'Time') {
if (this.controlPanel.x.axis.description === 'Time') {
this.drawOverviewData()
}
this.drawDetailData() // reDraw
@@ -17,12 +17,16 @@
<p class="display-6"> X-Axis </p>
</div>
<div class="flex sm5 xl5 md5 xs5 pl-1 pr-0 py-0">
<control-axis :ref="'axis_x'" axis="x" @changeAxis="changeAxis"/>
<control-axis
:ref="'axis_x'"
coordinate="x"
@changeAxis="changeAxis"
/>
</div>
<div class="flex sm5 xl5 md5 xs5 pl-1 pr-0 py-0">
<control-unit
:ref="'unit_x'"
axis="x"
coordinate="x"
@changeUnit="changeUnit"
style="width: 75px;"
/>
@@ -31,7 +35,11 @@
<div class="flex-container mb-2">
<div class="flex sm2 xl2 md2 xs2 px-0 py-0" />
<div class="flex sm5 xl5 md5 xs5 pl-1 pr-0 py-0">
<control-funct :ref="'funct_x'" axis="x" @changeFunct="changeFunct"/>
<control-funct
:ref="'funct_x'"
coordinate="x"
@changeFunct="changeFunct"
/>
</div>
</div>
<div class="flex-container mb-2">
@@ -41,14 +49,14 @@
<div class="flex sm5 xl5 md5 xs5 pl-1 pr-0 py-0">
<control-axis
:ref="'axis_y'"
axis="y"
coordinate="y"
@changeAxis="changeAxis"
/>
</div>
<div class="flex sm5 xl5 md5 xs5 pl-1 pr-0 py-0">
<control-unit
:ref="'unit_y'"
axis="y"
coordinate="y"
@changeUnit="changeUnit"
style="width: 75px;"
/>
@@ -59,7 +67,7 @@
<div class="flex sm5 xl5 md5 xs5 pl-1 pr-0 py-0">
<control-funct
:ref="'funct_y'"
axis="y"
coordinate="y"
@changeFunct="changeFunct"/>
</div>
</div>
@@ -95,6 +103,7 @@ import ChangeWindowStartAndSize from '@/components/analysis/replay/toolbox/Chang
import { mapMutations } from 'vuex'
import { mapFields } from 'vuex-map-fields'
import { tableRouter } from '@/components/analysis/replay/toolbox/EliteReplayTable'
import configRouter from '@/components/analysis/replay/toolbox/configTable'
import types from '@/store/modules/analysis/replay/types'
export default {
@@ -123,209 +132,83 @@ export default {
},
data () {
return {
deviceName: '',
libraryName: '',
showCycle: false,
innerCollapse: false,
tableRouter,
configRouter,
}
},
methods: {
...mapMutations('replay', [types.chart.updateAxisLabel]),
// initialize control buttons
init () {
this.deviceName = this.metaList[0].device.library_name
this.initDefaultControlPanel()
this.$refs.axis_x.init()
this.$refs.axis_y.init()
this.$refs.unit_x.init(this.controlPanel.x.type)
this.$refs.unit_y.init(this.controlPanel.y.type)
this.$refs.funct_x.init(this.controlPanel.x.type, this.controlPanel.y.type)
this.$refs.funct_y.init(this.controlPanel.x.type, this.controlPanel.y.type)
// get config information
this.libraryName = this.metaList[0].device.library_name
const setting = this.GLOBAL.getDefaultChartTypeByMode(this.metaList[0].parameter_set.MODE, this.libraryName)
this.controlPanel.x.axis = this.configRouter.getAxis(this.libraryName, setting[0], setting[1])
this.controlPanel.y.axis = this.configRouter.getAxis(this.libraryName, setting[2], setting[3])
this.controlPanel.FSM = this.configRouter.getFSM(this.controlPanel.x.axis.description, this.controlPanel.y.axis.description)
// initialize other blocks
this.$refs.axis_x.init(this.libraryName, setting[0])
this.$refs.axis_y.init(this.libraryName, setting[2])
this.$refs.unit_x.init(this.controlPanel.x.axis.description)
this.$refs.unit_y.init(this.controlPanel.y.axis.description)
this.$refs.funct_x.init(this.controlPanel.x.axis.description, this.controlPanel.y.axis.description)
this.$refs.funct_y.init(this.controlPanel.x.axis.description, this.controlPanel.y.axis.description)
this.$refs.change_cycle.init()
this.$refs.edit_file_name.init()
this.$refs.show_param.init(this.deviceName)
this.$refs.show_param.init(this.libraryName)
this.$refs.change_window_start_and_size.init()
},
// initialize the setting of this control panel
initDefaultControlPanel () {
// use state meta to decide which default unit need to be used (like check I-V mode...)
const setting = this.GLOBAL.getDefaultChartTypeByMode(this.metaList[0].parameter_set.MODE, this.deviceName)
// x-axis
let settingType = setting[0]
let settingValue = setting[1]
if (this.deviceName === 'EliteZM15' || this.deviceName.includes('Elite_EDC')) {
if (settingType === 'Elite') {
// 1: I, 2: V, 3: R, 4: cycle
if (settingValue === 1) {
this.controlPanel.x.type = 'Current'
this.controlPanel.x.channel = 0
} else if (settingValue === 2) {
this.controlPanel.x.type = 'Voltage'
this.controlPanel.x.channel = 1
} else if (settingValue === 3) {
this.controlPanel.x.type = 'Resistance'
this.controlPanel.x.channel = 2
} else if (settingValue === 4) {
this.controlPanel.x.type = 'Cycle'
this.controlPanel.x.channel = 3
}
} else if (settingType === 'Time') {
this.controlPanel.x.type = 'Time'
this.controlPanel.x.channel = undefined
}
} else if (this.deviceName.includes('EIS')) {
if (settingType.includes('EIS')) {
if (settingValue === 3) {
this.controlPanel.x.type = 'Frequency'
this.controlPanel.x.channel = 2
} else if (settingValue === 5 || settingValue === 6 || settingValue === 7) {
this.controlPanel.x.type = 'Impedance'
this.controlPanel.x.channel = 5
} else if (settingValue === 8) {
this.controlPanel.x.type = 'Phase'
this.controlPanel.x.channel = 7
} else if (settingValue === 9) {
this.controlPanel.x.type = 'Current'
this.controlPanel.x.channel = 8
} else if (settingValue === 10) {
this.controlPanel.x.type = 'Default'
this.controlPanel.x.channel = 0
}
} else if (settingType === 'Elite') {
// 1: I, 2: V, 3: R
if (settingValue === 1) {
this.controlPanel.x.type = 'Current'
this.controlPanel.x.channel = 0
} else if (settingValue === 2) {
this.controlPanel.x.type = 'Voltage'
this.controlPanel.x.channel = 1
} else if (settingValue === 3) {
this.controlPanel.x.type = 'Resistance'
this.controlPanel.x.channel = 2
}
} else if (settingType === 'Time') {
this.controlPanel.x.type = 'Time'
this.controlPanel.x.channel = undefined
}
}
// y-axis
settingType = setting[2]
settingValue = setting[3]
if (this.deviceName === 'EliteZM15' || this.deviceName.includes('Elite_EDC')) {
if (settingType === 'Elite') {
// 1: I, 2: V, 3: R, 4: cycle
if (settingValue === 1) {
this.controlPanel.y.type = 'Current'
this.controlPanel.y.channel = 0
} else if (settingValue === 2) {
this.controlPanel.y.type = 'Voltage'
this.controlPanel.y.channel = 1
} else if (settingValue === 3) {
this.controlPanel.y.type = 'Resistance'
this.controlPanel.y.channel = 2
} else if (settingValue === 4) {
this.controlPanel.y.type = 'Cycle'
this.controlPanel.y.channel = 3
}
} else if (settingType === 'Time') {
this.controlPanel.y.type = 'Time'
this.controlPanel.y.channel = undefined
}
} else if (this.deviceName.includes('EIS')) {
if (settingType.includes('EIS')) {
if (settingValue === 3) {
this.controlPanel.y.type = 'Frequency'
this.controlPanel.y.channel = 2
} else if (settingValue === 5 || settingValue === 6 || settingValue === 7) {
this.controlPanel.y.type = 'Impedance'
this.controlPanel.y.channel = 4
} else if (settingValue === 8) {
this.controlPanel.y.type = 'Phase'
this.controlPanel.y.channel = 7
} else if (settingValue === 9) {
this.controlPanel.y.type = 'Current'
this.controlPanel.y.channel = 8
} else if (settingValue === 10) {
this.controlPanel.y.type = 'Default'
this.controlPanel.y.channel = undefined
}
} else if (settingType === 'Elite') {
// 1: I, 2: V, 3: R
if (settingValue === 1) {
this.controlPanel.y.type = 'Current'
this.controlPanel.y.channel = 0
} else if (settingValue === 2) {
this.controlPanel.y.type = 'Voltage'
this.controlPanel.y.channel = 0
} else if (settingValue === 3) {
this.controlPanel.y.type = 'Resistance'
this.controlPanel.y.channel = 0
}
} else if (settingType === 'Time') {
this.controlPanel.y.type = 'Time'
this.controlPanel.y.channel = 0
}
}
this.refreshFormatter('x')
this.refreshFormatter('y')
this.$emit('changeFunctional', 'x', 'Linear')
this.$emit('changeFunctional', 'y', 'Linear')
this.$emit('changeAxis', 0)
this.$refs.specific_integral.checkMeaning(this.controlPanel.x.axis.description, this.controlPanel.y.axis.description)
this.$refs.specific_integral.setDisplayParam(this.controlPanel.x.axis.description, this.controlPanel.x.unit, this.controlPanel.y.axis.description, this.controlPanel.y.unit)
},
/* changeXXX: activate when pressing XXX button */
// trigger when changing the axis type
changeAxis (gridIndex) {
this.$refs.unit_x.init(this.controlPanel.x.type)
this.$refs.unit_y.init(this.controlPanel.y.type)
this.$refs.funct_x.init(this.controlPanel.x.type, this.controlPanel.y.type)
this.$refs.funct_y.init(this.controlPanel.x.type, this.controlPanel.y.type)
this.controlPanel.FSM = this.configRouter.getFSM(this.controlPanel.x.axis.description, this.controlPanel.y.axis.description)
// initialize other blocks
this.$refs.unit_x.init(this.controlPanel.x.axis.description)
this.$refs.unit_y.init(this.controlPanel.y.axis.description)
this.$refs.funct_x.init(this.controlPanel.x.axis.description, this.controlPanel.y.axis.description)
this.$refs.funct_y.init(this.controlPanel.x.axis.description, this.controlPanel.y.axis.description)
this.$refs.change_cycle.init()
this.refreshFormatter('x')
this.refreshFormatter('y')
this.$emit('changeFunctional', 'x', 'Linear')
this.$emit('changeFunctional', 'y', 'Linear')
this.$emit('changeAxis', gridIndex)
this.$refs.specific_integral.checkMean(this.controlPanel.x.type, this.controlPanel.x.funct, this.controlPanel.y.type, this.controlPanel.y.funct)
this.$refs.specific_integral.setDisplayParam(this.controlPanel.x.type, this.controlPanel.x.unit, this.controlPanel.y.type, this.controlPanel.y.unit)
this.$refs.specific_integral.checkMeaning(this.controlPanel.x.axis.description, this.controlPanel.y.axis.description)
this.$refs.specific_integral.setDisplayParam(this.controlPanel.x.axis.description, this.controlPanel.x.unit, this.controlPanel.y.axis.description, this.controlPanel.y.unit)
},
// trigger when changing the unit
changeUnit (axis) {
this.refreshFormatter(axis)
this.$refs.specific_integral.refreshDisplayParam(this.controlPanel.x.type, this.controlPanel.x.unit, this.controlPanel.y.type, this.controlPanel.y.unit)
changeUnit (coordinate) {
this.refreshFormatter(coordinate)
this.$refs.specific_integral.refreshDisplayParam(this.controlPanel.x.axis.description, this.controlPanel.x.unit, this.controlPanel.y.axis.description, this.controlPanel.y.unit)
},
// trigger when press the functional button
changeFunct (axis) {
this.refreshUnit()
this.refreshFormatter(axis)
this.$refs.specific_integral.checkMean(this.controlPanel.x.type, this.controlPanel.x.funct, this.controlPanel.y.type, this.controlPanel.y.funct)
this.$emit('changeFunctional', axis, this.controlPanel[axis].funct)
changeFunct (coordinate) {
if (coordinate === 'y') {
this.controlPanel.y.axis.description = this.controlPanel.FSM[this.controlPanel.y.funct]
this.$refs.unit_y.init(this.controlPanel.y.axis.description)
this.$refs.specific_integral.checkMeaning(this.controlPanel.x.axis.description, this.controlPanel.y.axis.description)
this.refreshFormatter(coordinate)
}
this.$emit('changeFunctional', coordinate, this.controlPanel[coordinate].funct)
this.$emit('changeAxis', 0)
},
/* refreshXXX: passively called by changeXXX function to refresh some setting */
// refresh axis type
refreshAxis () {
const xType = this.controlPanel.x.type
const yType = this.controlPanel.y.type
const xFunct = this.controlPanel.x.funct
const yFunct = this.controlPanel.y.funct
this.$refs.axis_x.refreshAxis(xType, xFunct, yType, yFunct)
this.$refs.axis_y.refreshAxis(xType, xFunct, yType, yFunct)
},
// refresh unit option
refreshUnit (axis) {
const xType = this.controlPanel.x.type
const yType = this.controlPanel.y.type
const xFunct = this.controlPanel.x.funct
const yFunct = this.controlPanel.y.funct
if (axis === 'x') {
this.$refs.unit_x.refreshUnit(xType, xFunct, yType, yFunct)
} else {
this.$refs.unit_y.refreshUnit(xType, xFunct, yType, yFunct)
}
},
// refresh all formatters of charts
refreshFormatter (axis) {
refreshFormatter (coordinate) {
this.updateAxisLabelChart({
chartID: 1,
axis: axis,
axis: coordinate,
type: this.controlPanel[coordinate].axis.description,
axisIndex: 0,
})
},
@@ -78,6 +78,7 @@ export default {
return sortedCycleList
},
init () {
this.showWhichCycles = '1'
this.cycleNum = this.metaList[this.metaIndex].parameter_set.CYCLE_NUMBER
const meta = this.metaList[this.metaIndex]
this.metaID = meta.id
@@ -90,9 +91,6 @@ export default {
this.showPanel = false
}
},
clear () {
this.showWhichCycles = '1'
},
async setCycle () {
if (this.isThisModeHasCycle === true) {
const dataCycleList = this.recInfo[this.metaID][this.cycleDataID][this.currentScale]
@@ -108,15 +106,14 @@ export default {
const cycleDict = this.getCycleDictRec()(cycleDataList)
this.cycleNum = Object.keys(cycleDict).length
let dataXList
if (this.controlPanel.x.type !== 'Time') {
dataXList = this.recInfo[this.metaID][this.controlPanel.x.channel][this.currentScale]
if (this.controlPanel.x.axis.description !== 'Time') {
dataXList = this.recInfo[this.metaID][this.controlPanel.x.axis.channel][this.currentScale]
}
const dataYList = this.recInfo[this.metaID][this.controlPanel.y.channel][this.currentScale]
const dataYList = this.recInfo[this.metaID][this.controlPanel.y.axis.channel][this.currentScale]
const filteredData = []
let counter = 0
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]
@@ -133,9 +130,9 @@ export default {
}
}
for (let i = startIndex; i <= endIndex; i++) {
const dataY = await this.getData(parseInt(this.currentScale), this.sampleMethod, dataYList[i].id, this.controlPanel.y.channel, this.metaList[this.metaIndex])
if (this.controlPanel.x.type !== 'Time') {
const dataX = await this.getData(parseInt(this.currentScale), this.sampleMethod, dataXList[i].id, this.controlPanel.x.channel, this.metaList[this.metaIndex])
const dataY = await this.getData(parseInt(this.currentScale), this.sampleMethod, dataYList[i].id, this.controlPanel.y.axis.channel, this.metaList[this.metaIndex])
if (this.controlPanel.x.axis.description !== 'Time') {
const dataX = await this.getData(parseInt(this.currentScale), this.sampleMethod, dataXList[i].id, this.controlPanel.x.axis.channel, this.metaList[this.metaIndex])
for (let j = 0, len = dataY.length; j < len; j++) {
if (parseInt(dataY[j][0]) >= startTime && parseInt(dataY[j][0]) <= endTime) {
filteredData.push([dataX[j][1], dataY[j][1]])
@@ -155,14 +152,13 @@ export default {
seriesIndex: this.metaIndex,
data: filteredData,
})
if (this.controlPanel.x.type === 'Time') {
if (this.controlPanel.x.axis.description === 'Time') {
if (counter === 0) {
this.chartData[this.chartID].xAxis[this.metaIndex].min = startTime
}
this.chartData[this.chartID].xAxis[this.metaIndex].max = endTime
counter++
}
// this.$emit('refreshChart', this.chartData[this.chartID])
}
}
}
@@ -181,11 +177,6 @@ export default {
...mapMutations('replay', [types.chart.updateSeries]),
...mapGetters('replay', [types.rec.getCycleDict]),
},
mounted () {
},
destroyed () {
},
}
</script>
@@ -1,10 +1,11 @@
<template>
<div>
<va-select
v-model="controlPanel[axis].type"
testBy="name"
v-model="controlPanel[coordinate].axis"
class="va-select-without-margin"
:options="typeOption"
:options="axisOption"
text-by="description"
key-by="description"
:noClear='true'
@input="changeAxis()"
/>
@@ -14,18 +15,20 @@
<script>
import { mapFields } from 'vuex-map-fields'
import { tableRouter } from '@/components/analysis/replay/toolbox/EliteReplayTable'
import configRouter from '@/components/analysis/replay/toolbox/configTable'
export default {
name: 'controlAxis',
props: {
axis: {
coordinate: {
type: String, // x or y
},
},
data () {
return {
typeOption: [],
axisOption: [],
tableRouter,
configRouter,
}
},
computed: {
@@ -34,38 +37,10 @@ export default {
]),
},
methods: {
init (type) {
if (this.axis === 'x') {
this.typeOption = [
'Time',
'Current',
'Voltage',
'Resistance',
]
} else {
this.typeOption = [
'Current',
'Voltage',
'Resistance',
]
}
// init call change Axis
if (this.axis === 'y') {
this.$emit('changeAxis', 0) // temporarily use metaIndex for gridIndex
}
},
refreshAxis (xType, xFunct, yType, yFunct) {
const [xTable, yTable] = this.tableRouter.getTable(xType, xFunct, yType, yFunct)
if (this.axis === 'x') {
this.controlPanel[this.axis].type = xTable.name
this.controlPanel[this.axis].channel = xTable.channel
} else {
this.controlPanel[this.axis].type = yTable.name
this.controlPanel[this.axis].channel = yTable.channel
}
init (library, settingType) {
this.axisOption = this.configRouter.getAxisOption(library, settingType, this.coordinate)
},
changeAxis () {
this.controlPanel[this.axis].channel = tableRouter.getChannel(this.controlPanel[this.axis].type)
this.$emit('changeAxis', 0)
},
},
@@ -2,8 +2,8 @@
<div class="flex row">
<va-radio-button
v-for="(funct, index) in functOption"
v-model="controlPanel[coordinate].funct"
:key="index"
v-model="controlPanel[axis].funct"
:option="funct"
@input="changeFunct()"
@@ -14,11 +14,12 @@
<script>
import { mapFields } from 'vuex-map-fields'
import { tableRouter } from '@/components/analysis/replay/toolbox/EliteReplayTable'
import configRouter from '@/components/analysis/replay/toolbox/configTable'
export default {
name: 'controlFuct',
name: 'controlFunct',
props: {
axis: {
coordinate: {
type: String, // x or y
},
},
@@ -27,6 +28,7 @@ export default {
funct: '',
functOption: [],
tableRouter,
configRouter,
}
},
computed: {
@@ -35,12 +37,12 @@ export default {
]),
},
methods: {
init (xAxis, yAixs) {
this.controlPanel[this.axis].funct = 'Linear'
this.functOption = this.tableRouter.getFunct(xAxis, yAixs, this.axis)
init (xAxis, yAxis) {
this.controlPanel[this.coordinate].funct = 'Linear'
this.functOption = this.configRouter.getFunctOption(xAxis, yAxis, this.coordinate)
},
changeFunct () {
this.$emit('changeFunct', this.axis)
this.$emit('changeFunct', this.coordinate)
},
},
}
@@ -1,11 +1,11 @@
<template>
<div>
<va-select
@input="changeUnit()"
v-model="controlPanel[axis].unit"
v-model="controlPanel[coordinate].unit"
class="va-select-without-margin"
:options="unitOption"
:noClear='true'
@input="changeUnit()"
/>
</div>
</template>
@@ -13,11 +13,12 @@
<script>
import { mapFields } from 'vuex-map-fields'
import { tableRouter } from '@/components/analysis/replay/toolbox/EliteReplayTable'
import configRouter from '@/components/analysis/replay/toolbox/configTable'
export default {
name: 'controlUnit',
props: {
axis: {
coordinate: {
type: String, // x or y
},
},
@@ -26,6 +27,7 @@ export default {
unit: '',
unitOption: [],
tableRouter,
configRouter,
}
},
computed: {
@@ -34,22 +36,12 @@ export default {
]),
},
methods: {
init (type) {
this.controlPanel[this.axis].unit = this.tableRouter.getDefaultUnit(type)
this.unitOption = Object.keys(this.tableRouter.getOption(type))
},
refreshUnit (xType, xFunct, yType, yFunct) {
const [xTable, yTable] = this.tableRouter.getTable(xType, xFunct, yType, yFunct)
if (this.axis === 'x') {
this.controlPanel[this.axis].unit = xTable.defaultUnit
this.unitOption = Object.keys(xTable.option)
} else {
this.controlPanel[this.axis].unit = yTable.defaultUnit
this.unitOption = Object.keys(yTable.option)
}
init (axis) {
this.controlPanel[this.coordinate].unit = this.configRouter.getUnit(axis)
this.unitOption = this.configRouter.getUnitOption(axis)
},
changeUnit () {
this.$emit('changeUnit', this.axis)
this.$emit('changeUnit', this.coordinate)
},
},
}
@@ -1,4 +1,20 @@
const chartTable = {
// library definition
// const libraryInfo = {
// EDC: {
// x: ['Time',
// 'Current',
// 'Voltage',
// 'Resistance',
// ],
// y: ['Current',
// 'Voltage',
// 'Resistance',
// ],
// },
// }
// axis information
const axisInfo = {
// axis type
Time: {
name: 'Time',
@@ -109,34 +125,35 @@ const chartTable = {
downloadUnit: 'none',
},
}
export const tableRouter = {
getChannel: (axis) => {
return chartTable[axis].channel
return axisInfo[axis].channel
},
getDefaultUnit: (axis) => {
return chartTable[axis].defaultUnit
return axisInfo[axis].defaultUnit
},
getOption: (axis) => {
return chartTable[axis].option
return axisInfo[axis].option
},
getTable: (xAxis, xFunct, yAxis, yFunct) => {
var xTable = chartTable[xAxis]
var yTable = chartTable.None
var xTable = axisInfo[xAxis]
var yTable = axisInfo.None
if (yFunct === 'Linear' || yFunct === 'Log') {
yTable = chartTable[yAxis]
yTable = axisInfo[yAxis]
} else if (yFunct === 'Integral') {
if (xAxis === 'Time' && yAxis === 'Current') {
yTable = chartTable.Charge
yTable = axisInfo.Charge
} else if (xAxis === 'Current' && yAxis === 'Voltage') {
yTable = chartTable.Power
yTable = axisInfo.Power
} else if (xAxis === 'Voltage' && yAxis === 'Current') {
yTable = chartTable.Power
yTable = axisInfo.Power
}
} else if (yFunct === 'Differential') {
if (xAxis === 'Current' && yAxis === 'Voltage') {
yTable = chartTable.Resistance
yTable = axisInfo.Resistance
} else if (xAxis === 'Voltage' && yAxis === 'Current') {
yTable = chartTable.Transconductance
yTable = axisInfo.Transconductance
}
}
return [xTable, yTable]
@@ -2,20 +2,24 @@
<div>
<div class="flex-container mb-2">
<div class="flex sm2 xl2 md2 xs2 px-0 py-0">
<p class="display-6" v-if="ifMean"> Area </p>
<p class="display-6" v-if="ifMeaning"> Area </p>
</div>
<div
class="row sm10 xl10 md10 xs10"
v-show="ifMean"
class="row flex sm10 xl10 md10 xs10"
v-show="ifMeaning"
>
<div class="flow xs6 sm6 lg6 xl6">
<div class="xs6 sm6 lg6 xl6">
<va-input
v-model="specificIntegral"
label="Integral value"
disabled
/>
>
<p slot="append" style="margin-right: 0;" small>
{{ integralResult }}
</p>
</va-input>
</div>
<div class="flow xs2 sm2 lg2 xl2">
<div class="xs2 sm2 lg2 xl2">
<va-select
v-model="integralUnit"
:options="integralOption"
@@ -88,6 +92,7 @@
<script>
import { tableRouter } from '@/components/analysis/replay/toolbox/EliteReplayTable'
import configRouter from '@/components/analysis/replay/toolbox/configTable'
export default {
name: 'SpecificIntegral',
data () {
@@ -101,26 +106,28 @@ export default {
yUnit: '',
xScale: '',
yScale: '',
integralResult: '',
integralUnit: '',
integralOption: [],
integralTable: {},
integralScale: '',
ifMean: true,
ifUserEnter: false,
ifMeaning: true,
ifUserKeyIn: false,
tableRouter,
configRouter,
}
},
methods: {
refreshScale () {
this.integralScale = this.integralTable.option[this.integralUnit]
this.integralScale = this.configRouter.getUnitScale(this.integralResult)[this.integralUnit]
},
userEnter () {
this.ifUserEnter = !this.ifUserEnter
this.ifUserKeyIn = !this.ifUserKeyIn
},
getSpecificIntegral (specificIntegral, boundary) {
this.specificIntegral = specificIntegral / this.integralScale
if (!this.ifUserEnter) {
if (!this.ifUserKeyIn) {
this.x_start = (boundary.x_start / this.xScale).toFixed(3)
this.x_end = (boundary.x_end / this.xScale).toFixed(3)
this.y_start = (boundary.y_start / this.yScale).toFixed(3)
@@ -128,6 +135,10 @@ export default {
}
},
setBrushBoundary () {
if (isNaN(this.x_start)) this.x_start = 0
if (isNaN(this.x_end)) this.x_start = 0
if (isNaN(this.xy_start)) this.y_start = 0
if (isNaN(this.y_end)) this.y_end = 0
var boundary = {
x_start: Number(this.x_start) * this.xScale,
x_end: Number(this.x_end) * this.xScale,
@@ -137,38 +148,29 @@ export default {
this.$emit('setBrushBoundary', boundary)
},
setDisplayParam (xAxis, xUnit, yAxis, yUnit) {
const xOption = this.tableRouter.getOption(xAxis)
const yOption = this.tableRouter.getOption(yAxis)
const xScaleOption = this.configRouter.getUnitScale(xAxis)
const yScaleOption = this.configRouter.getUnitScale(yAxis)
const integralResult = this.configRouter.getFSM(xAxis, yAxis).Integral
this.xUnit = xUnit
this.yUnit = yUnit
this.xScale = xOption[xUnit]
this.yScale = yOption[yUnit]
this.integralTable = this.tableRouter.getTable(xAxis, 'Linear', yAxis, 'Integral')
this.integralTable = this.integralTable[1]
this.integralOption = Object.keys(this.integralTable.option)
this.integralUnit = this.integralTable.defaultUnit
this.integralScale = this.integralTable.option[this.integralUnit]
this.xScale = xScaleOption[xUnit]
this.yScale = yScaleOption[yUnit]
this.integralResult = integralResult
this.integralUnit = this.configRouter.getUnit(integralResult)
this.integralOption = this.configRouter.getUnitOption(integralResult)
this.integralScale = this.configRouter.getUnitScale(integralResult)[this.integralUnit]
},
refreshDisplayParam (xAxis, xUnit, yAxis, yUnit) {
const xOption = this.tableRouter.getOption(xAxis)
const yOption = this.tableRouter.getOption(yAxis)
const xScaleOption = this.configRouter.getUnitScale(xAxis)
const yScaleOption = this.configRouter.getUnitScale(yAxis)
this.xUnit = xUnit
this.yUnit = yUnit
this.xScale = xOption[xUnit]
this.yScale = yOption[yUnit]
this.xScale = xScaleOption[xUnit]
this.yScale = yScaleOption[yUnit]
},
checkMean (xAxis, xFunct, yAxis, yFunct) {
if (yFunct === 'Integral' || yFunct === 'Differential') {
this.ifMean = false
} else {
if ((xAxis === 'Voltage' && yAxis === 'Current') ||
(xAxis === 'Current' && yAxis === 'Voltage') ||
(xAxis === 'Time' && yAxis === 'Current')) {
this.ifMean = true
} else {
this.ifMean = false
}
}
checkMeaning (xAxis, yAxis) {
const functOption = this.configRouter.getFunctOption(xAxis, yAxis)
this.ifMeaning = functOption.includes('Integral')
},
},
}
@@ -0,0 +1,405 @@
// object saving library name mapping table
const libraryNameMappingTable = {
EliteZM15: 'EliteEDC',
'Elite_EDC_1.4': null,
'Elite_EDC_1.5': 'EliteEDC',
'Elite_EDC_1.5re': 'EliteEDC',
'Elite_EDC_1.5r2': 'EliteEDC',
'Elite_BAT_1.0': 'EliteEDC',
'Elite_EIS_1.0': 'EliteEIS',
'Elite_EIS_1.1': 'EliteEIS',
'Elite_EIS_MINI_1.0': 'EliteEIS',
'Elite_TRIG_0.1': null,
'Elite_MEGAFLY_0.1': null,
}
// object saving setting type mapping table
const settingTypeMappingTable = {
EliteEDC: {
Time: {
description: 'Time',
channel: undefined,
},
Elite: {
1: {
description: 'Current',
channel: 0,
},
2: {
description: 'Voltage',
channel: 1,
},
3: {
description: 'Resistance',
channel: 2,
},
// 4: {
// description: 'Cycle',
// channel: 3,
// },
},
},
EliteEIS: {
Time: {
description: 'Time',
channel: undefined,
},
Elite: {
1: {
description: 'Current',
channel: 0,
},
2: {
description: 'Voltage',
channel: 1,
},
3: {
description: 'Resistance',
channel: 2,
},
},
EliteEIS: {
3: {
description: 'Frequency',
channel: 2,
},
5: {
description: 'Z_imag',
channel: 4,
},
6: {
description: 'Z_real',
channel: 5,
},
7: {
description: 'Impedance',
channel: 6,
},
8: {
description: 'Phase',
channel: 7,
},
9: {
description: 'Current',
channel: 8,
},
10: {
description: 'Gain_Level',
channel: 9,
},
},
},
}
// object saving unit information mapping table
const unitInfoMappingTable = {
// Time
Time: {
name: 'Time',
channel: -1,
option: {
auto: 1,
us: 1,
ms: 1e3,
s: 1e6,
min: 60 * 1e6,
hour: 3600 * 1e6,
},
defaultUnit: 'auto',
downloadUnit: 'auto',
},
// Elite
Current: {
name: 'Current',
channel: 0,
option: {
nA: 1,
uA: 1e3,
mA: 1e6,
A: 1e9,
},
defaultUnit: 'mA',
downloadUnit: 'A',
},
Voltage: {
name: 'Voltage',
channel: 1,
option: {
uV: 1,
mV: 1e3,
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'V',
},
Resistance: {
name: 'Resistance',
channel: 2,
option: {
: 1,
Ω: 1e3,
: 1e6,
: 1e9,
},
defaultUnit: 'Ω',
downloadUnit: 'Ω',
},
// Elite after Integral
Charge: {
name: 'Charge',
channel: -1,
option: {
nAh: 3600 * 1e6,
uAh: 1600 * 1e9,
mAh: 3600 * 1e12,
Ah: 3600 * 1e15,
},
defaultUnit: 'mAh',
downloadUnit: 'mAh',
},
Power: {
name: 'Power',
channel: -1,
option: {
mW: 1e12,
W: 1e15,
kW: 1e18,
},
defaultUnit: 'W',
downloadUnit: 'W',
},
// Elite after Differential
Transconductance: {
name: 'Transconductance',
channel: -1,
option: {
'mA/V': 1,
'A/V': 1e3,
'kA/V': 1e6,
},
defaultUnit: 'A/V',
downloadUnit: 'A/V',
},
// EliteEIS
Frequency: {
name: 'Frequency',
chanel: 2,
option: {
mHz: 1,
Hz: 1e3,
kHz: 1e6,
MHz: 1e9,
},
downloadUnit: 'Hz',
defaultUnit: 'Hz',
},
Z_imag: {
name: 'Z_imag',
chanel: 4,
option: {
: 1e-3,
Ω: 1,
: 1e3,
: 1e6,
},
downloadUnit: 'Ω',
defaultUnit: 'Ω',
},
Z_real: {
name: 'Z_real',
chanel: 5,
option: {
: 1e-3,
Ω: 1,
: 1e3,
: 1e6,
},
downloadUnit: 'Ω',
defaultUnit: 'Ω',
},
Impedance: {
name: 'Impedance',
chanel: 6,
option: {
: 1e-3,
Ω: 1,
: 1e3,
: 1e6,
},
downloadUnit: 'Ω',
defaultUnit: 'Ω',
},
Phase: {
name: 'Phase',
chanel: 7,
option: {
'°': 1,
},
downloadUnit: '°',
defaultUnit: '°',
},
Gain_Level: {
name: 'Gain Level',
chanel: 9,
option: {
'#': 1,
},
downloadUnit: '#',
defaultUnit: '#',
},
undefined: {
name: 'not support',
channel: -1,
option: {
none: 1,
},
defaultUnit: 'none',
downloadUnit: 'none',
},
}
// object saving specific functional information mapping table
const functInfoMappingTable = {
// Time
Time: {
},
// Elite
Current: {
Time: {
Linear: 'Current',
Log: 'Current',
Integral: 'Charge',
},
Voltage: {
Linear: 'Current',
Log: 'Current',
Integral: 'Power',
Differential: 'Impedance',
},
},
Voltage: {
Current: {
Linear: 'Voltage',
Log: 'Voltage',
Integral: 'Power',
Differential: 'Transconductance',
},
},
Resistance: {
},
// EliteEIS
Frequency: {
},
Z_imag: {
},
Z_real: {
},
Impedance: {
},
Phase: {
},
Gain_Level: {
},
None: {
},
}
/**
* return axis description and channel by library, type and index
* @param {String} library
* @param {String} type
* @param {String} index
* @returns {Object} : configuration
*/
function getAxis (library, type, index) {
// some physical property || Time
return settingTypeMappingTable[libraryNameMappingTable[library]][type][index] || settingTypeMappingTable[libraryNameMappingTable[library]][type]
}
/**
* retrun default unit by physical property
* @param {String} axis
* @returns {Object} : unit
*/
function getUnit (axis) {
return unitInfoMappingTable[axis].defaultUnit
}
/**
* return axis option by library, type
* @param {String} library
* @param {String} type
* @param {String} coordinate
* @returns {Object} : axisOption
*/
function getAxisOption (library, type, coordinate) {
if (type === 'Time') type = 'Elite'
const axisOption = Object.values(settingTypeMappingTable[libraryNameMappingTable[library]][type]).map((setting) => {
return setting
})
if (coordinate === 'x') {
axisOption.unshift({
description: 'Time',
channel: undefined,
})
}
return axisOption
}
/**
* retrun option of unit by physical property
* @param {String} axis
* @returns {Object} : unitOption
*/
function getUnitOption (axis) {
return Object.keys(unitInfoMappingTable[axis].option)
}
/**
* retrun a dictionary of scale corresponding to unit by physical property
* @param {String} axis
* @returns {Object} : unitScale
*/
function getUnitScale (axis) {
return unitInfoMappingTable[axis].option
}
/**
* retrun option of functionl by both axis physical property
* @param {String} xAxis
* @param {String} yAxis
* @param {String} coordinate
* @returns {Object} : functOption
*/
function getFunctOption (xAxis, yAxis, coordinate) {
if (coordinate === 'x') return ['Linear', 'Log']
else if (functInfoMappingTable[yAxis] === undefined) return ['Linear', 'Log']
else if (functInfoMappingTable[yAxis][xAxis] === undefined) return ['Linear', 'Log']
else return Object.keys(functInfoMappingTable[yAxis][xAxis])
}
/**
* retrun functional correponding physics property
* @param {String} xAxis
* @param {String} yAxis
* @returns {Object} : functOption
*/
function getFSM (xAxis, yAxis) {
return functInfoMappingTable[yAxis][xAxis] || {
Linear: yAxis,
Log: yAxis,
}
}
const configRouter = {
getAxis,
getUnit,
getAxisOption,
getUnitOption,
getUnitScale,
getFunctOption,
getFSM,
}
export default configRouter
+1 -1
View File
@@ -1,6 +1,5 @@
<template>
<div class="devices-overview">
<div >
<va-card
v-for="controller in controllerList" :key="controller.id"
@@ -518,6 +517,7 @@ export default {
async mounted () {
await taskInfo.updateTaskInfo()
await this.getControllerList()
this.GLOBAL.refreshCache()
this.pageMqttSub()
this.pageInitPub()
+13 -10
View File
@@ -33,6 +33,7 @@
editFile()
showModal.editFile = false
}"
:noOutsideDismiss="true"
tabindex="0"
>
<va-input
@@ -179,7 +180,7 @@
{{ props.rowData.name }}
</template>
<template slot="parameter_set" slot-scope="props">
{{ getWorkingMode(props.rowData.device.library_name, props.rowData.parameter_set.MODE) }}
{{ getWorkingMode(props.rowData) }}
</template>
<template slot="created_at" slot-scope="props">
{{transDate(props.rowData.created_at)}}
@@ -427,7 +428,7 @@ export default {
// call getfolder api and update
const folders = await api.collection.getByParent('folder', info.id)
const files = await api.meta.getAttrByParent('folder', info.id, 'id-path-name-parent-description-size-time_duration-uuid-device-channels-created_at')
const files = await api.meta.getAttrByParent('folder', info.id, 'id-path-name-parent-description-size-time_duration-uuid-device-channels-parameter_set-created_at')
file.updateFileList(folders)
file.updateFileList(files)
@@ -447,7 +448,7 @@ export default {
this.currentInfo = item
// call getfolder api and update
const folders = await api.collection.getByParent('folder', item.id)
const files = await api.meta.getAttrByParent('folder', item.id, 'id-path-name-parent-description-size-time_duration-uuid-device-channels-created_at')
const files = await api.meta.getAttrByParent('folder', item.id, 'id-path-name-parent-description-size-time_duration-uuid-device-channels-parameter_set-created_at')
file.updateFileList(folders)
file.updateFileList(files)
@@ -468,7 +469,7 @@ export default {
if (initCollection.data.length === 1) {
this.currentInfo = initCollection.data[0]
const folders = await api.collection.getByParent('folder', initCollection.data[0].id)
const files = await api.meta.getAttrByParent('folder', initCollection.data[0].id, 'id-path-name-parent-description-size-time_duration-uuid-device-channels-created_at')
const files = await api.meta.getAttrByParent('folder', initCollection.data[0].id, 'id-path-name-parent-description-size-time_duration-uuid-device-channels-parameter_set-created_at')
file.updateFileList(folders)
file.updateFileList(files)
this.fileLists = file.getFileList()
@@ -752,16 +753,17 @@ export default {
}
},
replay: function (meta) {
const href = location.href.split('/')[2]
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,
})
window.open('http://' + href + '/#/admin/data-replay/elite/' + meta.id)
// this.$router.push({
// path: '/admin/data-replay/elite/' + meta.id,
// })
}
},
spike: function (meta) {
@@ -771,9 +773,10 @@ export default {
})
}
},
getWorkingMode: function (library, mode) {
getWorkingMode: function (rowData) {
try {
return configTable.getModeConfig(library, mode).name
if (rowData.type === 'folder') return ''
return configTable.getModeConfig(rowData.device.library_name, rowData.parameter_set.MODE).name
} catch {
return ''
}
+51 -15
View File
@@ -4,17 +4,21 @@
<project-manager/>
</div>
<div
:class="(taskViewPanel.show || projectManagerPanel.show)
? (taskViewPanel.show && projectManagerPanel.show)
? cardStyle.small
: cardStyle.medium
:class="(projectManagerPanel.show)
? cardStyle.medium
: cardStyle.large
">
<project-view @start_project="startProject($event)" @stop_project="stopProject($event)" @save_project="saveProject($event)"/>
<project-view @start_project="startProject($event)" @stop_project="stopProject($event)" @save_project="saveProject($event)" @detect="detect"/>
</div>
<div :class="cardStyle.small" v-show="taskViewPanel.show">
<slide-out
dock="right"
:mask-color="'rgba(0, 0, 0, 0)'"
:visible.sync="taskViewPanel.show"
:title="(taskViewPanel.type === 1) ? 'Device' : (taskViewPanel.type === 3) ? 'Condition' : (taskViewPanel.type === 4) ? 'Parameter' : ''"
resizable
>
<project-task/>
</div>
</slide-out>
</div>
</template>
@@ -22,7 +26,7 @@
import ProjectManager from '@/components/project/manager/ProjectManager'
import ProjectView from '@/components/project/view/ProjectView'
import ProjectTask from '@/components/project/task/ProjectTask'
import { mapActions } from 'vuex'
import { mapActions, mapGetters } from 'vuex'
import { mapFields } from 'vuex-map-fields'
import types from '@/store/modules/project/types'
import { taskInfo } from '@/data/task/TaskInfo'
@@ -35,6 +39,9 @@ export default {
ProjectTask,
},
computed: {
...mapGetters('project', [
types.project.getSelect,
]),
...mapFields('project', [
'projectConfigList',
'runningProjectList',
@@ -74,7 +81,7 @@ export default {
},
async '+/get_running_project/+' (data, topic) {
this.runningProjectList.length = 0
const runningProjects = JSON.parse(String.fromCharCode.apply(null, data)).data
const runningProjects = JSON.parse(new TextDecoder().decode(data)).data
this.runningProjectList.push(...runningProjects)
},
async '+/broadcast' (data, topic) {
@@ -125,16 +132,28 @@ export default {
this.mqttUnSub(id + '/get_running_project/+')
},
initPage: async function () {
await this.initProject()
await taskInfo.updateTaskInfo()
this.pageMqttSub(taskInfo.getTaskInfo().controllerID)
},
startProject: function (project) {
console.log('start_project', project)
console.log('taskInfo.getTaskInfo().controllerID', taskInfo.getTaskInfo().controllerID)
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'run_project/0',
project: project,
}))
let deviceReady = true
for (const device of Object.values(this.getSelectProject.device)) {
if (device.pairStatus !== 1) {
if (device.pair === null) {
window.alert('Device ' + device.name + ' is not connected yet.')
} else {
window.alert('Device ' + device.pair + ' is not connected yet.')
}
deviceReady = false
}
}
if (deviceReady === true) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'run_project/0',
project: project,
}))
}
},
stopProject: function (project) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
@@ -153,9 +172,24 @@ export default {
},
)
},
detect: async function (device) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_instruction/0',
device: device,
instruction: 'VIS_DEVICE_DETECT',
}))
setTimeout(() => {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_instruction/0',
device: device,
instruction: 'VIS_DEVICE_DONE',
}))
}, 5000)
},
...mapActions('project',
[
types.project.init,
types.project.update,
types.project.addDevice,
],
@@ -170,8 +204,10 @@ export default {
header: 'get_device_info_all/0',
}))
const project = await this.API.project.getAll()
// console.log('project: ', project)
this.projectConfigList.length = 0
this.projectConfigList.push(...project.data)
// console.log('projectConfigList: ', this.projectConfigList)
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'get_running_project/0',
@@ -1,6 +1,6 @@
<template>
<div>
<va-card style="height: 90vh; overflow: auto; display: block;">
<va-card style="height: 88vh; overflow: auto; display: block;">
<template slot="header">
<div class="row">
<div class="flex d-flex xs5 sm5 lg5 xl5">
@@ -19,6 +19,7 @@
</va-item-label> -->
</va-item-section>
<va-item-section side>
<va-icon class="fa fa-copy mr-2" color="bloack" @click.native.stop="copyProject({ project: project, index: index, api: API })"></va-icon>
<va-icon class="fa fa-close" color="danger" @click.native.stop="deleteProject({ project: project, index: index, api: API })"></va-icon>
</va-item-section>
</va-item>
@@ -55,6 +56,7 @@ export default {
},
...mapActions('project',
[
types.project.copy,
types.project.select,
types.project.delete,
],
+1 -1
View File
@@ -1,6 +1,6 @@
<template>
<div>
<va-card style="height: 90vh; overflow: auto;">
<va-card style="height: 88vh; overflow: auto;">
<project-task-config></project-task-config>
</va-card>
</div>
@@ -1,32 +1,16 @@
<template>
<div class="flex sm12 xl12 md12 xs12">
<div class="task-config__header-separator mb-1">
<div class="task-config__header-text">
<span>Action &#38; Condition</span>
<va-button class="circle-button" small color="dark" @click="closePanel">
<va-icon
name="fa fa-times"
color="white"
/>
</va-button>
</div>
</div>
<div>
<!-- <div v-for="(action, actionKey) in this.getSelectTask.action" :key="actionKey">
{{ getDeviceProject(action.target).name }} {{ action.type }} {{ getConditionTask(action.condition[0]).value }}
</div> -->
</div>
<span>Device</span>
<div class="flex d-flex" v-if="Object.keys(registeredDevice).length > 0">
<div v-for="(device, deviceKey) in registeredDevice" :key="deviceKey">
<va-button @click="selectDevice(deviceKey)" small>{{ device.name }}</va-button>
<!-- <span>Device</span>
<div class="row flex sm12 xl12 md12 xs12" v-if="Object.keys(registeredDevice).length > 0">
<div class="flex sm12 xl6 md6 xs12" v-for="(device, key) in registeredDevice" :key="key">
<va-button @click="selectDevice(key)" small>{{ getDeviceShowNameProject(key) }}</va-button>
</div>
</div>
<div align="center" v-else>
No registered device found.
</div>
</div> -->
<div v-if="settingStep >= 1">
<span>Action</span>
<!-- <span>Action</span> -->
<div class="flex d-flex">
<div v-for="action in actionTemplate" :key="action">
<va-button color="info" @click="selectAction(action)" small>{{ action }}</va-button>
@@ -34,12 +18,13 @@
</div>
</div>
<div v-if="settingStep >= 2">
<span>Condition</span>
<!-- <span>Condition</span> -->
<div v-for="(condition, key) in conditionObj" :key="key">
<!-- <div v-if="key === 'cycle' || key === 'cycle_next'" class="flex d-flex align--center"> -->
<div class="flex d-flex align--center">
<va-checkbox v-model="condition.select"></va-checkbox>
<span class="mr-1">{{ condition.prefix }}</span>
<input class="mr-1" :type="condition.type" v-model="condition.value"/>
<input style="width: 100px;" class="mr-1" :type="condition.type" v-model="condition.value"/>
<span>{{ condition.suffix }}</span>
</div>
</div>
@@ -78,16 +63,18 @@ export default {
types.project.getSelect,
types.project.getDevice,
types.project.getAllDevice,
types.project.getDeviceShowName,
]),
...mapFields('project', [
'taskSelectKey',
'taskViewPanel',
'deviceSelectKey',
]),
},
data () {
return {
settingStep: 0,
settingStep: 1,
registeredDevice: {},
deviceSelect: '',
@@ -98,7 +85,11 @@ export default {
conditionTemplate: newConditionTemplate(),
conditionList: [],
taskOptions: {},
taskOptionsKeys: [],
project: {},
device: {},
task: {},
}
},
methods: {
@@ -146,6 +137,18 @@ export default {
for (const key in this.conditionObj) {
if (this.conditionObj[key].select) {
// create fake condition if duplicate type & target
if (Object.values(this.getSelectTask.condition).findIndex(ele => ele.type === 'previous_task_done' && ele.target === this.deviceSelect) === -1) {
// create fake start previous done
const fakeStartActionUUID = this.GLOBAL.getUUID()
const fakeAction = this.createAction(fakeStartActionUUID, 'start', this.deviceSelect)
const fakeConditionUUID = this.GLOBAL.getUUID()
const fakeCondition = this.createCondition(fakeConditionUUID, 'previous_task_done', 'equal', '')
this.setConditionTask({ condition: fakeCondition })
fakeAction[fakeStartActionUUID].condition.push(fakeConditionUUID)
this.setActionTask({ action: fakeAction })
}
const conditionUUID = this.GLOBAL.getUUID()
const newCondition = this.createCondition(conditionUUID, key, 'equal', this.conditionObj[key].value)
@@ -156,21 +159,37 @@ export default {
this.setActionTask({ action: newAction })
this.reset()
},
updateTaskOptions: function () {
for (var idx = 0; idx < this.project.task.length; idx++) {
this.taskOptions[this.project.task[idx].name] = this.project.task[idx].uuid
}
this.taskOptionsKeys = Object.keys(this.taskOptions)
},
...mapActions('project', [
types.task.setCondition,
types.task.setAction,
types.task.setCycle,
]),
},
mounted () {
const project = this.getSelectProject
const device = this.getAllDeviceProject
const task = this.getSelectTask
console.log('project', project)
console.log('task', task)
this.registeredDevice = device
this.project = this.getSelectProject
this.device = this.getAllDeviceProject
this.deviceSelect = this.deviceSelectKey
this.task = this.getSelectTask
for (var idx = 0; idx < this.project.task.length; idx++) {
this.taskOptions[this.project.task[idx].name] = this.project.task[idx].uuid
}
this.taskOptionsKeys = Object.keys(this.taskOptions)
this.registeredDevice = this.device
},
watch: {
// refresh parameter when click different task's parameter
deviceSelectKey: {
handler: function () {
this.deviceSelect = this.deviceSelectKey
},
},
},
}
</script>
@@ -1,54 +1,54 @@
<template>
<div class="flex sm12 xl12 md12 xs12">
<div class="task-config__header-separator mb-1">
<div class="task-config__header-text">
<span> Device </span>
<va-button class="circle-button" small color="dark" @click="closePanel">
<va-icon
name="fa fa-times"
color="white"
/>
</va-button>
</div>
</div>
<div>
<va-list fit class="mb-2">
<va-item v-for="(device, index) in getSelectProject.device" :key="index" >
<va-item-section side>
<va-checkbox
:value="device.isSelect"
:arrayValue="(taskSelectKey != undefined)? String(taskSelectKey) : '-1'"
@input="selectDevice($event, device, index)"
ref="checkbox_ref"
/>
</va-item-section>
<va-list fit class="mb-2 pb-0">
<va-list-label>
Register
</va-list-label>
<va-item-section avatar class="ml-0">
<va-avatar style="border-radius: 0;">
<img
src='@/assets/img/elite_img.png' :alt="device.name">
</va-avatar>
</va-item-section>
<template v-for="(device, index) in deviceListInOrder">
<va-item :class="taskDevice.includes(device[0]) === true ? 'device-list-focus': ''" :key="'register' + String(index)" @click="selectDevice(device, index)" clickable>
<va-item-section avatar>
<va-avatar style="border-radius: 0;">
<img src='@/assets/img/elite_img.png' :alt="device[1].name">
</va-avatar>
</va-item-section>
<va-item-section>
<va-item-label>
{{ device.name }}
</va-item-label>
<va-item-section>
<va-item-label>
{{ getDeviceShowNameProject(device[0]) }}
</va-item-label>
</va-item-section>
</va-item>
</template>
</va-list>
<va-list fit class="mb-2 pb-0">
<va-list-label>
Connect
</va-list-label>
<va-item-label caption>
{{ device.connectDevice.device_address }}
</va-item-label>
</va-item-section>
</va-item>
<template v-for="(device, index) in getNotRegisterDeviceProject()">
<va-item :key="'connect' + index" clickable @click="registerConnectDevice(device)">
<va-item-section avatar>
<va-avatar style="border-radius: 0;">
<img src='@/assets/img/elite_img.png' :alt="device.macAddress">
</va-avatar>
</va-item-section>
<va-item-section>
<va-item-label>
{{ device.macAddress }}
</va-item-label>
</va-item-section>
</va-item>
</template>
</va-list>
</div>
</div>
</template>
<script>
import { mapFields } from 'vuex-map-fields'
import { mapGetters } from 'vuex'
// import eliteImgUrl from '@/assets/img/elite_img.png'
// import neuliveImgUrl from '@/assets/img/neulive_img.png'
import { mapActions, mapGetters } from 'vuex'
import types from '@/store/modules/project/types'
export default {
@@ -56,9 +56,18 @@ export default {
components: {
},
computed: {
deviceListInOrder () {
return Object.entries(this.getSelectProject.device).sort((a, b) => a[1].order - b[1].order)
},
taskDevice () {
return this.getSelectTask.device
},
...mapGetters('project', [
types.project.getSelect,
types.task.getSelect,
types.project.getDeviceShowName,
types.project.getNotRegisterDevice,
]),
...mapFields('project', [
@@ -71,38 +80,55 @@ export default {
}
},
methods: {
selectDevice: function (event, device, key) {
// if select single task
if (this.taskSelectKey !== undefined) {
device.isSelect = event
// console.log('device.isSelect: ', device.isSelect)
device.isSelect.includes(String(this.taskSelectKey)) === true
? this.getSelectTask.device.push(key)
: this.getSelectTask.device = this.getSelectTask.device.filter(item => item !== key)
selectDevice: function (device, index) {
if (this.taskDevice.includes(device[0]) === false) {
this.appendToTask(device[0])
} else {
// if select all tasks
if (event.includes('-1')) {
// check all
device.isSelect = ['-1', ...Array(this.getSelectProject.task.length).fill().map((_, index) => String(index))]
for (const task of this.getSelectProject.task) {
if (!task.device.includes(key)) {
task.device.push(key)
}
}
} else {
// uncheck all
device.isSelect = []
for (const task of this.getSelectProject.task) {
task.device = task.device.filter(item => item !== key)
}
}
this.removeFromTask(device[0])
}
},
resetDevice: function () {
},
registerConnectDevice: async function (device) {
// register device
await this.createDeviceProject({
name: device.name,
library: device.library,
pair: device.macAddress,
pairStatus: 1,
order: this.getDeviceMaxOrderProject,
})
// select device
this.selectDevice(this.deviceListInOrder[this.deviceListInOrder.length - 1])
},
appendToTask: function (key) {
// if select single task
this.getSelectTask.device.push(key)
},
removeFromTask: function (key) {
// if select single task
this.getSelectTask.device = this.getSelectTask.device.filter(item => item !== key)
},
closePanel: function () {
this.taskViewPanel.show = !(this.taskViewPanel.show)
},
...mapActions('project',
[
types.project.createDevice,
],
),
},
mounted () {
},
}
</script>
<style lang="scss">
.device-list-focus {
background: #ebedff;
border: 1px solid #dbdcf0;
box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.25);
border-radius: 5px;
}
</style>
@@ -1,6 +1,6 @@
<template>
<div class="flex sm12 xl12 md12 xs12">
<div class="task-config__header-separator mb-1">
<!-- <div class="task-config__header-separator mb-1">
<div class="task-config__header-text">
<span >Parameter Set</span>
<va-button class="circle-button" small color="dark" @click="closePanel">
@@ -10,12 +10,13 @@
/>
</va-button>
</div>
</div>
</div> -->
<div>
<device-parameter-recording
:ref="'device_parameter_ref'"
:parameter="parameter"
:library="'Elite_EDC_1.5'"
:library="device.library"
:place="'scheduler'"
@setParameter="setParameter"
@setParameterWithDebounce="setParameterWithDebounce"
/>
@@ -90,7 +91,11 @@ export default {
// get Device
this.device = this.getDeviceProject(this.deviceSelectKey)
// get Config
this.config = configTable.getConfig(this.device.library.value)
if (typeof this.device.library === 'string') { // string
this.config = configTable.getConfig(this.device.library)
} else { // object
this.config = configTable.getConfig(this.device.library.value)
}
// create default parameter
const defaultValue = {}
for (const key in this.config) {
@@ -106,6 +111,8 @@ export default {
const modeOption = this.$refs.device_parameter_ref.workingModeOptions.find(ele => ele.id === param.MODE)
this.$refs.device_parameter_ref.workingModeSelectChange(modeOption)
this.parameter = Object.assign(this.parameter, Object.values(parameterSet)[0])
} else {
this.setParameter('MODE', 0)
}
},
...mapActions('project',
@@ -118,5 +125,22 @@ export default {
// init parameter
this.resetParameter()
},
watch: {
// refresh parameter when click different task's parameter
taskSelectKey: {
handler: function () {
this.parameter = {}
this.parameterUUID = ''
this.resetParameter()
},
},
deviceSelectKey: {
handler: function () {
this.parameter = {}
this.parameterUUID = ''
this.resetParameter()
},
},
},
}
</script>
@@ -12,14 +12,14 @@
</div>
<!-- EIS -->
<div v-if="workingModeSelect != null && workingModeSelect.id == 0">
<d-c-volt :ref="'DCVolt'" :deviceID="deviceID" :parameterName="'DC_BIAS'" @parameterChange="deviceParameterChange($event)" />
<a-c-amplitude :ref="'ACAmplitude'" :deviceID="deviceID" :parameterName="'AC_AMP'" @parameterChange="deviceParameterChange($event)" />
<freq-range :ref="'FreqRange'" :deviceID="deviceID" :parameterName="'FREQ'" @parameterChange="deviceParameterChange($event)" />
<points-per-decades :ref="'PointsPerDecades'" :deviceID="deviceID" :parameterName="'PPD'" @parameterChange="deviceParameterChange($event)" />
<point-spacing :ref="'PointSpacing'" :deviceID="deviceID" :parameterName="'SCALE'" @parameterChange="deviceParameterChange($event)" />
<delay :ref="'Delay'" :deviceID="deviceID" :parameterName="'DELAY'" @parameterChange="deviceParameterChange($event)" />
<average :ref="'Average'" :deviceID="deviceID" :parameterName="'AVERAGE_NUM'" @parameterChange="deviceParameterChange($event)" />
<current-range :ref="'CurrentRange'" :deviceID="deviceID" :parameterName="'RTIA'" @parameterChange="deviceParameterChange($event)" />
<d-c-volt :ref="'DCVolt'" :deviceID="deviceID" :parameterName="'EIS_DC_BIAS'" @parameterChange="deviceParameterChange($event)" />
<a-c-amplitude :ref="'ACAmplitude'" :deviceID="deviceID" :parameterName="'EIS_AC_AMP'" @parameterChange="deviceParameterChange($event)" />
<freq-range :ref="'FreqRange'" :deviceID="deviceID" :parameterName="'EIS_FREQ'" @parameterChange="deviceParameterChange($event)" />
<points-per-decades :ref="'PointsPerDecades'" :deviceID="deviceID" :parameterName="'EIS_PPD'" @parameterChange="deviceParameterChange($event)" />
<point-spacing :ref="'PointSpacing'" :deviceID="deviceID" :parameterName="'EIS_SCALE'" @parameterChange="deviceParameterChange($event)" />
<delay :ref="'Delay'" :deviceID="deviceID" :parameterName="'EIS_DELAY'" @parameterChange="deviceParameterChange($event)" />
<average :ref="'Average'" :deviceID="deviceID" :parameterName="'EIS_AVERAGE_NUM'" @parameterChange="deviceParameterChange($event)" />
<current-range :ref="'CurrentRange'" :deviceID="deviceID" :parameterName="'GENERAL_HS_RTIA'" @parameterChange="deviceParameterChange($event)" />
</div>
<!-- CV -->
<div v-if="workingModeSelect != null && workingModeSelect.id == 1">
@@ -283,7 +283,7 @@ export default {
},
],
DCVolt: null,
AC_AMP: null,
EIS_AC_AMP: null,
FreqStart: null,
FreqStop: null,
PointsPerDecades: null,
@@ -395,44 +395,35 @@ export default {
this.measureEocButton.status = false
},
refresh () {
// taskInfo.getDeviceInfo(this.deviceID).parameterSet.CHANNEL_LABEL = ['Z_image_Raw', 'Z_Real_Raw', 'Frequency', 'Cycle', 'Z_imag', 'Z_real', 'Impedance', 'Phase', 'Current', 'Level gain']
this.workingModeSelect = this.workingModeOptions[taskInfo.getDeviceInfo(this.deviceID).parameterSet.MODE]
if (this.workingModeSelect != null) {
this.workingModeSelectChange(this.workingModeSelect)
}
this.ACAmplitude = String(Math.round((taskInfo.getDeviceInfo(this.deviceID).parameterSet.AC_AMP) / 2047 * 800))
this.ACAmplitude = String(Math.round((taskInfo.getDeviceInfo(this.deviceID).parameterSet.EIS_AC_AMP) / 2047 * 800))
if (this.$refs.ACAmplitude != null) {
this.$refs.ACAmplitude.itemChange(this.ACAmplitude)
}
this.Average = taskInfo.getDeviceInfo(this.deviceID).parameterSet.AVERAGE_NUM
this.Average = taskInfo.getDeviceInfo(this.deviceID).parameterSet.EIS_AVERAGE_NUM
if (this.$refs.Average != null) {
this.$refs.Average.itemChange(this.Average)
}
this.CurrentRange = taskInfo.getDeviceInfo(this.deviceID).parameterSet.RTIA
this.CurrentRange = taskInfo.getDeviceInfo(this.deviceID).parameterSet.GENERAL_HS_RTIA
if (this.$refs.CurrentRange != null) {
this.$refs.CurrentRange.itemChange(this.CurrentRange)
}
this.PointSpacing = taskInfo.getDeviceInfo(this.deviceID).parameterSet.SCALE
this.PointSpacing = taskInfo.getDeviceInfo(this.deviceID).parameterSet.EIS_SCALE
if (this.$refs.PointSpacing != null) {
this.$refs.PointSpacing.itemChange(this.PointSpacing)
}
this.DCVolt = String(Math.round((taskInfo.getDeviceInfo(this.deviceID).parameterSet.DC_BIAS) * 2200 / 4095))
this.DCVolt = String(Math.round((taskInfo.getDeviceInfo(this.deviceID).parameterSet.EIS_DC_BIAS) * 2200 / 4095))
if (this.$refs.DCVolt != null) {
this.$refs.DCVolt.itemChange(this.DCVolt)
}
this.Delay = String(parseFloat((taskInfo.getDeviceInfo(this.deviceID).parameterSet.DELAY) / 10).toFixed(1))
this.Delay = String(parseFloat((taskInfo.getDeviceInfo(this.deviceID).parameterSet.EIS_DELAY) / 10).toFixed(1))
if (this.$refs.Delay != null) {
this.$refs.Delay.itemChange(this.Delay)
}
this.FreqStart = String(parseFloat(Math.round(parseFloat((taskInfo.getDeviceInfo(this.deviceID).parameterSet.FREQ_START * 0.0149) * 100)) / 100).toFixed(1)) === '0.0' ? '0.015' : String(parseFloat(Math.round(parseFloat((taskInfo.getDeviceInfo(this.deviceID).parameterSet.FREQ_START * 0.0149) * 100)) / 100).toFixed(1))
if (this.$refs.FreqRange != null) {
this.$refs.FreqRange.itemChangeMax(this.FreqStart)
}
this.FreqStop = String(parseFloat(Math.round(parseFloat((taskInfo.getDeviceInfo(this.deviceID).parameterSet.FREQ_STOP * 0.0149) * 100)) / 100).toFixed(1)) === '0.0' ? '0.015' : String(parseFloat(Math.round(parseFloat((taskInfo.getDeviceInfo(this.deviceID).parameterSet.FREQ_STOP * 0.0149) * 100)) / 100).toFixed(1))
if (this.$refs.FreqRange != null) {
this.$refs.FreqRange.itemChangeMin(this.FreqStop)
}
this.PointsPerDecades = String(Math.round((taskInfo.getDeviceInfo(this.deviceID).parameterSet.PPD)))
this.PointsPerDecades = String(Math.round((taskInfo.getDeviceInfo(this.deviceID).parameterSet.EIS_PPD)))
if (this.$refs.PointsPerDecades != null) {
this.$refs.PointsPerDecades.itemChange(this.PointsPerDecades)
}
@@ -505,7 +505,7 @@ export default {
// },
// {
// id: 11,
// description: 'Cali ADC - test',
// description: 'Cali Mode - test',
// },
// {
// id: 12,
@@ -576,6 +576,10 @@ export default {
value: 1,
label: 'Vin',
},
{
value: 2,
label: 'Vout',
},
],
startVoltNumber: null,
stopVoltNumber: null,
@@ -1,6 +1,6 @@
<template>
<div>
<elite-parameter-recording-elitezm15 :ref="'rec_ref_2'" :deviceID="deviceID" @parameterChange="parameterChange"/>
<elite-parameter-recording-elitezm15 :ref="'rec_ref_2'" :deviceID="deviceID" @parameterChange="parameterChange" :place="'scheduler'"/>
<!-- <elite-parameter-recording v-if="eliteVer=='1'" :ref="'rec_ref_1'" :deviceID="deviceID"/>
<elite-parameter-recording-elitezm15 v-else-if="eliteVer=='2'" :ref="'rec_ref_2'" :deviceID="deviceID"/>
<elite-parameter-recording-elite-e-i-s v-else-if="eliteVer=='4'" :ref="'rec_ref_4'" :deviceID="deviceID"/>
+7 -20
View File
@@ -1,18 +1,16 @@
<template>
<div>
<va-card style="height: 90vh; overflow: auto; display: block;">
<!-- <pre>{{ getSelectProject }} </pre> -->
<va-card style="height: 88vh; overflow: auto; display: block;">
<template slot="header">
<va-icon name="fa fa-bluetooth-b mr-3" color="primary"/>
<h5 class="mt-0 mb-0"> {{ getSelectProject ? getSelectProject.name : '' }}</h5>
</template>
<!-- <pre>
{{ getSelectProject ? getSelectProject: '' }}
</pre> -->
<div v-if="getSelectProject === undefined">
<span>please select project</span>
</div>
<div v-else>
<project-menu/>
<project-menu @detect="detect"/>
<project-table/>
<div align="right" v-if="lockMode === false">
<va-button @click="save">Save</va-button>
@@ -47,6 +45,7 @@ export default {
'projectList',
'deviceConnectList',
'projectSelectIndex',
'projectLibrary',
]),
},
data () {
@@ -63,6 +62,9 @@ export default {
save: function () {
this.$emit('save_project', this.getSelectProject)
},
detect: function (device) {
this.$emit('detect', device)
},
...mapActions('project',
[
types.project.update,
@@ -71,21 +73,6 @@ export default {
),
},
watch: {
projectSelectIndex: {
handler: async function () {
for (const device of this.deviceConnectList) {
var newDevice = {
uuid: this.GLOBAL.getUUID(),
name: device.mac_address,
product: device.device_name,
library: device.library_name,
connectDevice: device,
isSelect: [],
}
await this.addDeviceProject({ device: newDevice })
}
},
},
},
async mounted () {
// console.log('mounted')
@@ -4,54 +4,62 @@
<div class="flex d-flex">
<switch-project/>
<add-task/>
<add-device @showDeviceModal="showDeviceModal"/>
<!-- <clear-task/>
<save-project/>
<import-project/>
<export-project/>
<delete-project/> -->
<!-- <add-device @showDeviceModal="showDeviceModal"/> -->
<va-button @click="showCycleModal" small>+ Cycle</va-button>
</div>
</div>
<project-device @showDeviceModal="showDeviceModal($event)"></project-device>
<device-modal ref="device_modal_ref"></device-modal>
<project-device @showDeviceModal="showDeviceModal"></project-device>
<new-device-modal ref="device_modal_ref" @detect="detect"></new-device-modal>
<cycle-modal ref="cycle_modal_ref" @createCycle="createCycle"></cycle-modal>
</div>
</template>
<script>
import SwitchProject from '@/components/project/view/menu/components/SwitchProject'
import AddTask from '@/components/project/view/menu/components/AddTask'
// import ClearTask from '@/components/project/view/menu/components/ClearTask'
// import ExportProject from '@/components/project/view/menu/components/ExportProject'
// import ImportProject from '@/components/project/view/menu/components/ImportProject'
// import SaveProject from '@/components/project/view/menu/components/SaveProject'
// import DeleteProject from '@/components/project/view/menu/components/DeleteProject'
import AddDevice from '@/components/project/view/menu/components/AddDevice'
// import AddDevice from '@/components/project/view/menu/components/AddDevice'
import ProjectDevice from '@/components/project/view/menu/components/ProjectDevice'
import DeviceModal from '@/components/project/view/menu/components/DeviceModal'
import NewDeviceModal from '@/components/project/view/menu/components/NewDeviceModal'
import CycleModal from '@/components/project/view/menu/components/CycleModal'
import { mapActions } from 'vuex'
import types from '@/store/modules/project/types'
export default {
name: 'project-menu',
components: {
SwitchProject,
AddTask,
AddDevice,
// ClearTask,
// ExportProject,
// ImportProject,
// SaveProject,
// DeleteProject,
// AddDevice,
ProjectDevice,
DeviceModal,
NewDeviceModal,
CycleModal,
},
data () {
return {
}
},
methods: {
showDeviceModal: function (device) {
this.$refs.device_modal_ref.show()
this.$refs.device_modal_ref.initSetting(device)
detect: function (device) {
this.$emit('detect', device)
},
showDeviceModal: function (key, device) {
this.$refs.device_modal_ref.show()
this.$refs.device_modal_ref.initSetting(key, device)
},
createCycle: function (cycleInfo) {
this.createCycleTask({ cycleInfo: cycleInfo })
},
showCycleModal: function () {
this.$refs.cycle_modal_ref.show()
this.$refs.cycle_modal_ref.reset()
},
...mapActions('project',
[
types.task.createCycle,
],
),
},
}
</script>
@@ -1,6 +1,6 @@
<template>
<div>
<va-button @click="addDevice" small>ADD DEVICE</va-button>
<va-button @click="addDevice" small>+ DEVICE</va-button>
</div>
</template>
<script>
@@ -1,6 +1,6 @@
<template>
<div>
<va-button @click="createTask" small>ADD TASK</va-button>
<va-button @click="createTask" small>+ TASK</va-button>
</div>
</template>
<script>
@@ -0,0 +1,258 @@
<template>
<div>
<va-modal
class="flex sm12 xl12 md12 xs12"
v-model="showModal"
size="small"
:noOutsideDismiss="true"
hide-default-actions
>
<template slot="header">
<div class="d-flex mb-3">
<va-icon name="fa fa-bluetooth-b mr-3" color="primary"/>
<h5 v-if="Object.keys(cycleInfo).length == 0" class="mt-0 mb-0">Create Cycle</h5>
<h5 v-else class="mt-0 mb-0">{{ cycleInfo.name }}</h5>
</div>
</template>
<div class="row">
<div class="row flex sm6 xl6 md6 xs6">
<div class="flex sm2 xl2 md2 xs2 pt-2">
<span>Start</span>
</div>
<div class="flex sm8 xl8 md8 xs8">
<va-select
:label="''"
v-model="task.start"
textBy="name"
class="va-select-without-margin"
:options="taskOptions"
:noClear='true'
/>
</div>
</div>
<div class="row flex sm6 xl6 md6 xs6">
<div class="flex sm2 xl2 md2 xs2 pt-2">
<span>End</span>
</div>
<div class="flex sm8 xl8 md8 xs8">
<va-select
:label="''"
v-model="task.end"
textBy="name"
class="va-select-without-margin"
:options="taskOptions"
:noClear='true'
/>
</div>
</div>
<div class="row flex sm12 xl12 md12 xs12">
<div class="flex sm2 xl2 md2 xs2 pt-2">
<span> Cycle No. </span>
</div>
<div class="flex sm2 xl2 md2 xs2">
<va-input v-model="task.cycle"/>
</div>
</div>
<div class="row flex sm12 xl12 md12 xs12" style="height: 40px;">
<div class="flex sm1 xl1 md1 xs1">
<va-checkbox
v-model="task.useID"
/>
</div>
<div class="flex sm4 xl4 md4 xs4">
Use ID As Header
</div>
<div v-if="task.useID" class="flex sm4 xl4 md4 xs4">
<va-input v-model="task.id"></va-input>
</div>
</div>
<!-- <div class="row flex sm12 xl12 md12 xs12">
<div class="flex sm1 xl1 md1 xs1">
<va-checkbox
v-model="task.buttonTrigger"
/>
</div>
<div class="flex sm6 xl6 md6 xs6">
Wait Until Button Press In Next Loop
</div>
</div> -->
</div>
<div class="flex-center sm12 xl12 md12 xs12">
<va-button v-if="Object.keys(cycleInfo).length > 0" @click="removeCycle" color="danger">Remove</va-button>
<va-button @click="hide">Cancel</va-button>
<va-button @click="createCycle" @keyup.native="keyFunction($event,item)">OK</va-button>
</div>
</va-modal>
</div>
</template>
<script>
import { mapFields } from 'vuex-map-fields'
import { mapActions, mapGetters } from 'vuex'
import types from '@/store/modules/project/types'
export default {
name: 'cycle-modal',
components: {
},
computed: {
...mapGetters('project', [
types.project.getSelect,
]),
...mapFields('project', [
'deviceConnectList',
'projectLibrary',
]),
},
data () {
return {
showModal: false,
taskOptions: [],
task: {
id: '',
name: '',
start: -1,
end: -1,
cycle: '1',
useID: false,
buttonTrigger: false,
uuid: '',
},
cycleInfo: {},
}
},
methods: {
show: function () {
this.showModal = true
// window.addEventListener('keydown', (e) => {
// console.log('e', e)
// if (e.keyCode === 13) {
// this.createCycle()
// }
// }, { once: true })
},
hide: function () {
this.showModal = false
},
createCycle: async function () {
this.showModal = false
const project = this.getSelectProject
if (Object.keys(this.cycleInfo).length === 0) {
this.$emit('createCycle', this.task)
}
if (Object.keys(this.cycleInfo).length !== 0) {
this.cycleInfo.max = this.task.cycle
this.cycleInfo.name = this.task.name
this.cycleInfo.useID = this.task.useID
this.cycleInfo.id = this.task.id
const originStartIndex = await this.getIndexTask({ project: project, uuid: this.cycleInfo.range[0] })
const newStartIndex = await this.getIndexTask({ project: project, uuid: this.task.start.value })
if (this.task.useID === true) {
const condition = project.task[originStartIndex].condition
const action = project.task[originStartIndex].action
delete condition[(Object.keys(condition).find(key => condition[key].type === 'after_task_run'))]
const conditionUUID = this.GLOBAL.getUUID()
const newCond = await this.createConditionTask({ uuid: conditionUUID, condition: 'until_button_trigger', compOp: 'equal', value: '' })
project.task[originStartIndex].condition = Object.assign({}, condition, newCond)
action[Object.keys(action).find(key => action[key].type === 'cycle')].condition.push(conditionUUID)
project.task[originStartIndex].name = this.task.name
} else {
const condition = project.task[originStartIndex].condition
const action = project.task[originStartIndex].action
delete condition[(Object.keys(condition).find(key => condition[key].type === 'until_button_trigger'))]
const conditionUUID = this.GLOBAL.getUUID()
const newCond = await this.createConditionTask({ uuid: conditionUUID, condition: 'after_task_run', compOp: 'equal', value: '0' })
project.task[originStartIndex].condition = Object.assign({}, condition, newCond)
action[Object.keys(action).find(key => action[key].type === 'cycle')].condition.push(conditionUUID)
}
if (Number(originStartIndex) + 1 !== Number(newStartIndex)) {
await this.swapTask({ project: project, originIndex: originStartIndex, newIndex: newStartIndex })
}
const originEndIndex = await this.getIndexTask({ project: project, uuid: this.cycleInfo.range[1] })
const newEndIndex = await this.getIndexTask({ project: project, uuid: this.task.end.value })
project.task[originEndIndex].name = this.task.name
if (Number(originEndIndex) - 1 !== Number(newEndIndex)) {
await this.swapTask({ project: project, originIndex: originEndIndex, newIndex: newEndIndex + 1 })
}
}
return true
},
removeCycle: async function () {
const project = this.getSelectProject
// remove project cycle
project.cycle.splice(project.cycle.findIndex(ele => ele.name === this.cycleInfo.name), 1)
// remove left cycle task
const originStartIndex = await this.getIndexTask({ project: project, uuid: this.cycleInfo.range[0] })
await this.deleteTask({ project: project, index: originStartIndex })
// remove right cycle task
const originEndIndex = await this.getIndexTask({ project: project, uuid: this.cycleInfo.range[1] })
await this.deleteTask({ project: project, index: originEndIndex })
this.showModal = false
return true
},
updateTaskOptions: function () {
const taskOptions = []
const project = this.getSelectProject
for (var idx = 0; idx < project.task.length; idx++) {
if (Object.keys(this.cycleInfo).length !== 0) {
if (this.cycleInfo.range.findIndex(ele => ele === project.task[idx].uuid) !== -1) continue
}
taskOptions.push({
id: idx,
name: project.task[idx].name,
value: project.task[idx].uuid,
})
}
this.taskOptions = taskOptions
},
reset: function () {
this.updateTaskOptions()
this.task.start = this.taskOptions[0]
this.task.end = this.taskOptions[this.taskOptions.length - 1]
},
setCycleInfo: async function (project, uuid) {
this.cycleInfo = project.cycle.find(ele => ele.range.find(ele => ele === uuid))
const startIndex = await this.getIndexTask({ project: project, uuid: this.cycleInfo.range[0] }) + 1
const endIndex = await this.getIndexTask({ project: project, uuid: this.cycleInfo.range[1] }) - 1
this.updateTaskOptions()
this.task.start = this.taskOptions[this.taskOptions.findIndex(ele => ele.value === project.task[startIndex].uuid)]
this.task.end = this.taskOptions[this.taskOptions.findIndex(ele => ele.value === project.task[endIndex].uuid)]
this.task.name = this.cycleInfo.name
this.task.cycle = this.cycleInfo.max
this.task.useID = this.cycleInfo.useID
this.task.id = this.cycleInfo.id
},
...mapActions('project',
[
types.project.addDevice,
types.project.findDevice,
types.project.setDevice,
types.task.init,
types.task.create,
types.task.save,
types.task.delete,
types.task.select,
types.task.getIndex,
types.task.swap,
types.task.createCondition,
],
),
},
mounted () {
},
}
</script>
@@ -0,0 +1,153 @@
<template>
<div>
<va-modal
class="flex sm12 xl12 md12 xs12"
v-model="showModal"
size="small"
:noOutsideDismiss="true"
hide-default-actions
>
<template slot="header">
<div class="d-flex mb-3">
<va-icon name="fa fa-bluetooth-b mr-3" color="primary"/>
<h5 class="mt-0 mb-0">Choose Device</h5>
</div>
</template>
<va-list fit class="mb-2 pb-0">
<va-list-label>
Connect
</va-list-label>
<va-item v-if="deviceList.length === 0">
<va-item-section>
There is no connected device.
</va-item-section>
</va-item>
<template v-else v-for="(device, index) in deviceList">
<va-item :class="deviceSelect === index ? 'device-list-focus': ''" :key="'connect-' + index" @click="selectDevice(device, index)" clickable>
<va-item-section avatar>
<va-avatar style="border-radius: 0;">
<img src='@/assets/img/elite_img.png' :alt="device.macAddress">
</va-avatar>
</va-item-section>
<va-item-section>
{{ device.macAddress }}
</va-item-section>
<va-item-section side>
<va-icon name="fa fa-map-marker" color="gray" @click.native="detect(device.macAddress)"/>
</va-item-section>
</va-item>
<!-- <va-list-separator v-if="index < deviceList.length - 1" :key="'separator-' + index" /> -->
</template>
</va-list>
<div class="flex-center sm12 xl12 md12 xs12">
<va-button color='danger' @click="removeDevice">Remove</va-button>
<va-button @click="hide">Cancel</va-button>
<va-button @click="changeDevice">OK</va-button>
</div>
</va-modal>
</div>
</template>
<script>
// import { mapFields } from 'vuex-map-fields'
import { mapActions, mapGetters } from 'vuex'
import types from '@/store/modules/project/types'
export default {
name: 'add-device-modal',
components: {
},
computed: {
optionDeviceVersion () {
return (this.optionDeviceVersionObj[this.device.product.value] !== undefined)
? this.optionDeviceVersionObj[this.device.product.value]
: undefined
},
...mapGetters('project', [
types.project.getSelect,
types.project.getDeviceShowName,
]),
// ...mapFields('project', [
// 'deviceConnectList',
// ]),
},
data () {
return {
showModal: false,
showDisplayDevice: false,
key: '',
device: {},
deviceList: [],
deviceSelect: -1,
}
},
methods: {
show: function () {
this.showModal = true
},
hide: function () {
this.showModal = false
},
detect: function (device) {
if (device) this.$emit('detect', device)
},
selectDevice: function (device, index) {
this.deviceSelect = index
},
changeDevice: function () {
if (this.deviceList[this.deviceSelect]) {
this.device.pair = this.deviceList[this.deviceSelect].macAddress
}
this.hide()
},
removeDevice: function () {
this.deleteDeviceProject({ deviceKey: this.key })
this.hide()
},
getDeviceList: async function (device) {
const deviceList = await this.checkNotRegisterDeviceProject({ library: device.library })
const _device = { macAddress: device.pair, library: device.library }
if (device.pair !== null) {
this.deviceList = [_device, ...deviceList]
} else {
this.deviceList = [...deviceList]
}
},
initSetting: function (key, device) {
this.key = key
this.device = device
this.deviceList = []
this.deviceSelect = 0
this.getDeviceList(device)
},
...mapActions('project',
[
types.project.addDevice,
types.project.findDevice,
types.project.setDevice,
types.project.deleteDevice,
types.project.checkNotRegisterDevice,
types.task.init,
types.task.create,
types.task.save,
types.task.delete,
types.task.select,
],
),
},
mounted () {
},
}
</script>
<style lang="scss">
.device-list-focus {
background: #ebedff;
border: 1px solid #dbdcf0;
box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.25);
border-radius: 5px;
}
</style>
@@ -1,11 +1,20 @@
<template>
<div class="row">
<div class="flex d-flex">
<div v-for="(device, index) in getSelectProject.device" :key="index">
<va-button color="info" @click="showDeviceModal(device)" small>
<va-icon name="fa fa-close" @click.native.stop="deleteDevice(index)"></va-icon>
{{ device.name }} {{ device.connectDevice && device.connectDevice.device_address }}
</va-button>
<div class="flex d-flex" v-if="showLibrary === true">
<va-button small @click="clickShowDevice('EDC')">EDC</va-button>
<va-button small @click="clickShowDevice('EIS')">EIS</va-button>
<va-button small @click="cancelSelectDevice()">X</va-button>
</div>
<div class="flex d-flex" v-if="showDevice === false && showLibrary === false">
<draggable class="flex row" :list="deviceListInOrder" :move="handleMove" @end="handleDragEnd">
<div class="mr-2" v-for="(device, index) in deviceListInOrder" :key="index">
<button :class="device[1].pairStatus === 1 ? 'pair-button mr-2' : 'not-pair-button mr-2'" @click="showDeviceModal(device[0], device[1])">
<span class="pair-button-text">{{ getDeviceShowNameProject(device[0]) }}</span>
</button>
</div>
</draggable>
<div>
<button class="add-button" icon="fa fa-plus" @click="clickShowLibrary"><span class="add-button-text">+</span></button>
</div>
</div>
</div>
@@ -15,46 +24,154 @@
import { mapFields } from 'vuex-map-fields'
import { mapActions, mapGetters } from 'vuex'
import types from '@/store/modules/project/types'
import draggable from 'vuedraggable'
export default {
name: 'project-device',
components: {
draggable,
},
computed: {
deviceListInOrder () {
return Object.entries(this.getSelectProject.device).sort((a, b) => a[1].order - b[1].order)
},
...mapGetters('project', [
types.project.getSelect,
types.project.getDeviceShowName,
types.project.getDeviceMaxOrder,
]),
...mapFields('project', [
'projectLibrary',
'projectSelectIndex',
]),
},
data () {
return {
showDevice: false,
showLibrary: false,
notRegisterDevice: [],
index: -1,
futureIndex: -1,
}
},
methods: {
showDeviceModal: function (device) {
this.$emit('showDeviceModal', device)
clickShowLibrary: async function () {
this.notRegisterDevice = await this.checkNotRegisterDeviceProject({})
if (this.notRegisterDevice.length === 0) {
this.showLibrary = true
return true
}
await this.createDeviceProject({
name: this.notRegisterDevice[0].name,
library: this.notRegisterDevice[0].library,
pair: this.notRegisterDevice[0].macAddress,
pairStatus: 1,
order: this.getDeviceMaxOrderProject,
})
return true
},
clickShowDevice: async function (library) {
this.showLibrary = false
await this.createDeviceProject({
name: library + '-' + String(Object.keys(this.getSelectProject.device).length + 1),
library: library,
pair: null,
pairStatus: 0,
order: this.getDeviceMaxOrderProject,
})
return false
},
cancelSelectDevice: function () {
this.showLibrary = false
},
showDeviceModal: function (key, device) {
this.$emit('showDeviceModal', key, device)
},
deleteDevice: function (deviceIndex) {
this.deleteDeviceProject({ index: deviceIndex })
},
handleMove (e) {
const { index, futureIndex } = e.draggedContext
this.index = index
this.futureIndex = futureIndex
return false // disable sort
},
handleDragEnd () {
const changeList = ['name', 'library', 'pair', 'pairStatus']
const deviceListTemp = JSON.parse(JSON.stringify(this.deviceListInOrder))
const keyOld = deviceListTemp[this.index][0]
const keyNew = deviceListTemp[this.futureIndex][0]
const deviceList = this.getSelectProject.device
for (const key of changeList) {
deviceList[keyOld][key] = deviceListTemp[this.futureIndex][1][key]
deviceList[keyNew][key] = deviceListTemp[this.index][1][key]
}
},
...mapActions('project',
[
types.project.createDevice,
types.project.deleteDevice,
types.project.checkNotRegisterDevice,
types.project.checkPairDeviceExist,
],
),
},
mounted () {
for (const device in this.getSelectProject.device) {
if (this.projectLibrary === null) {
this.projectLibrary = this.getSelectProject.device[device].library.value
}
}
},
watch: {
projectSelectIndex: {
immediate: true,
handler: async function (val) {
console.log('projectSelectIndex', val)
this.checkPairDeviceExistProject()
},
},
},
}
</script>
<style lang="scss">
.add-button {
width: 38px;
height: 36px;
background: #e0e0e0;
border: 2px dashed #b7b7b7;
border-radius: 20px;
}
.add-button-text {
color: white;
font-size: 20px;
font-weight: bold;
}
.pair-button {
width: 100%;
height: 36px;
background: #858dd6;
border: 0;
border-radius: 20px;
}
.not-pair-button {
width: 100%;
height: 36px;
background: #858dd6;
border: 1px #ffffff dashed;
border-radius: 20px;
}
.pair-button-text {
font-family: 'Inter';
font-style: normal;
font-weight: 400;
font-size: 18px;
line-height: 24px;
text-align: center;
color: #ffffff;
}
</style>
@@ -1,6 +1,6 @@
<template>
<div class="markup-tables project-table flex d-flex sm12 xl12 md12 xs12" id="scro" style="height: 66vh; overflow: auto;">
<div class="table-wrapper">
<div class="markup-tables project-table flex d-flex sm12 xl12 md12 xs12 px-0 mx-0" id="scro" style="width: 100%; height: 55vh; overflow: auto;">
<div class="table-wrapper" style="width: 100%;">
<table class="va-table">
<thead>
<tr>
@@ -16,13 +16,62 @@
<th align="center" @click="openConfig(1)">device</th>
<th align="center">action and condition</th>
<th align="center">parameter</th>
<th v-if="lockMode" align="center">cycle</th>
<th align="center"></th>
</tr>
</thead>
<tbody>
<template v-for="(task, taskIndex) in getSelectProject.task">
<tr v-if="task.device.length === 0" :key="taskIndex" height="80px">
<!-- <tbody> -->
<vuedraggable :disabled="lockMode === true" class="draggable" :list="getSelectProject.task" @end="rearrangeTask({ project: getSelectProject })" tag="tbody" animation="500">
<template class="item" v-for="(task, taskIndex) in getSelectProject.task">
<tr v-if="task.type === 'cycle'" :key="'empty' + taskIndex" height="80px" @click="showCycleModal(task.uuid)">
<td v-if="lockMode === false">
<va-checkbox
v-model="tableColumn.checked"
:array-value="String(taskIndex)"
/>
</td>
<td align="center">
{{ taskIndex + 1 }}
</td>
<td align="center" @dblclick="switchInput('name', taskIndex)">
<div v-if="tableColumn.name == taskIndex && getCycleInfo(task.uuid, 'useID') === true && lockMode === true">
<va-input
v-model="inputSaved"
style="width: 100px;"
@blur="switchCycle('name', -1, getSelectProject, task)"
@keyup.enter="switchCycle('name', -1, getSelectProject, task)"
/>
</div>
<div v-else>
<div v-if="getCycleInfo(task.uuid, 'useID') === true">
{{ getCycleInfo(task.uuid, 'id') }}
</div>
<div v-if="getCycleInfo(task.uuid, 'useID') === false">
{{ getCycleInfo(task.uuid, 'name') }}
</div>
</div>
</td>
<td align="center" v-if="getCycleLocation(task.uuid) === 'start'">
{{ getCycleInfo(task.uuid, 'max') }} Rounds
</td>
<td v-if="lockMode === true && getCycleLocation(task.uuid) === 'start'">
{{ getCycleInfo(task.uuid, 'count') }} / {{ getCycleInfo(task.uuid, 'max') }}
</td>
<td v-if="lockMode === true && Object.values(task.condition).findIndex(ele => ele.type == 'until_button_trigger') != -1 && task.status === 1">
<va-button icon="fa fa-play" @click="trigger_button(getSelectProject)" flat></va-button>
<td/>
<td align="center" v-if="lockMode === true">
<!-- {{ task.status }} -->
<fulfilling-bouncing-circle-spinner
v-if="task.status === 1"
:animation-duration="3000"
:color="'#6c7fee'"
:size="16"
></fulfilling-bouncing-circle-spinner>
<!-- <va-icon v-if="task.status === 2" class="fa fa-check"></va-icon> -->
</td>
</tr>
<tr v-else-if="task.device && task.device.length === 0" :key="'empty' + taskIndex" height="80px" @click="() => { focus = taskIndex }">
<td v-if="lockMode === false">
<va-checkbox
v-model="tableColumn.checked"
@@ -36,19 +85,19 @@
{{ task.name }}
</td>
<td align="center">
<va-button :flat="true" @click="openConfig(1, taskIndex)" small>Add device</va-button>
<va-button :flat="true" @click="openConfig(1, taskIndex)" small>+ Device</va-button>
</td>
<td align="center">
<va-button :flat="true" @click="openConfig(3, taskIndex)" small>Add event</va-button>
<va-button :flat="true" @click="openConfig(3, taskIndex)" :disabled="true" small>-</va-button>
</td>
<td align="center">
<va-button :flat="true" @click="openConfig(4, taskIndex)" small>Add parameter</va-button>
<va-button :flat="true" @click="openConfig(4, taskIndex)" :disabled="true" small>-</va-button>
</td>
<td align="center">
<va-icon class="fa fa-close" @click.native="() => deleteTask({ index: taskIndex})"></va-icon>
<va-icon class="fa fa-close" @click.native="() => deleteTask({ project: getSelectProject, index: taskIndex})"></va-icon>
</td>
</tr>
<tr v-for="(deviceUUID) in task.device" :key="taskIndex + deviceUUID" height="80px">
<tr :class="taskIndex === focus ? 'table-row-focus' : ''" v-else v-for="(deviceUUID) in task.device" :key="String(taskIndex) + ' ' + String(deviceUUID)" height="80px" @click="() => { focus = taskIndex }">
<td v-if="lockMode === false">
<va-checkbox
v-model="tableColumn.checked"
@@ -73,14 +122,14 @@
</td>
<!-- device -->
<td align="center">
<div v-if="task.device.length === 0">
<div v-if="task.device && task.device.length === 0">
<va-button :flat="true" @click="openConfig(1, taskIndex, deviceUUID)" small>
Add device
+ Device
</va-button>
</div>
<div v-else>
<va-button :flat="true" @click="openConfig(1, taskIndex, deviceUUID)" small>
<span>{{ getDeviceProject(deviceUUID) && getDeviceProject(deviceUUID).name }}</span>
<span>{{ getDeviceShowNameProject(deviceUUID)}}</span>
</va-button>
</div>
</td>
@@ -89,30 +138,34 @@
<td align="center">
<div v-if="Object.keys(task.action).length === 0">
<va-button :flat="true" @click="openConfig(3, taskIndex, deviceUUID)" small>
Add event
+ Event
</va-button>
</div>
<div v-else class="flex">
<div v-for="(action, actionKey) in task.action" :key="actionKey">
<div v-if="action.target === deviceUUID">
<div v-for="conditionKey in action.condition" :key="conditionKey">
<div small>
<div small v-if="action.type !== 'cycle' && action.type !== 'start'">
{{ action.type }} {{ task.condition[conditionKey].type }} {{ task.condition[conditionKey].value }}
<va-icon class="fa fa-close" @click.native="delAction(action, conditionKey)"/>
<va-icon class="fa fa-close" @click.native="delAction(task, actionKey, conditionKey)"/>
</div>
<div small v-else-if="action.type == 'cycle' && task.condition[conditionKey].type === 'previous_task_done'">
{{ action.type }} go to {{ task.cycle_next }} run {{ task.cycle }} times
<va-icon class="fa fa-close" @click.native="delAction(task, actionKey, conditionKey)"/>
</div>
<va-button :flat="true" @click="openConfig(3, taskIndex, deviceUUID)" small>
+ New Action/Condition
</va-button>
</div>
</div>
</div>
<va-button :flat="true" @click="openConfig(3, taskIndex, deviceUUID)" small>
+ Event
</va-button>
</div>
</td>
<!-- action end -->
<td align="center">
<div v-if="Object.keys(task.parameter_set).length === 0">
<va-button :flat="true" @click="openConfig(4, taskIndex, deviceUUID)" small>
Add parameter
+ Parameter
</va-button>
</div>
<va-button :flat="true" @click="openConfig(4, taskIndex, deviceUUID)" v-else class="flex d-flex">
@@ -121,7 +174,7 @@
<div v-for="(parameter, parameterKey) in parameterSet" :key="parameterKey">
<span v-if="parameterKey !== 'target'">
<div small>
{{ parameterName(parameterKey) }} : {{ parameterValue(parameterKey, parameter) }}
{{ parameterName(parameterKey, deviceUUID) }} : {{ parameterValue(parameterKey, parameter, deviceUUID) }}
</div>
</span>
</div>
@@ -130,8 +183,22 @@
</va-button>
</td>
<td align="center" v-if="lockMode === false">
<va-icon class="fa fa-close" @click.native="() => deleteTask({ index: taskIndex})"></va-icon>
<va-icon v-if="String(taskIndex) !== '0'" class="fa fa-toggle-up" @click.native="swapTask(taskIndex, 0)"/>
<va-icon v-if="parseInt(taskIndex) !== getSelectProject.task.length - 1" class="fa fa-toggle-down" @click.native="swapTask(taskIndex, 1)"/>
<va-icon class="fa fa-copy ml-1" @click.native="() => copyTask({ project: getSelectProject, index: taskIndex})"></va-icon>
<va-icon class="fa fa-close ml-1" @click.native="() => deleteTask({ project: getSelectProject, index: taskIndex})"></va-icon>
</td>
<td align="center" v-if="lockMode === true">
<div v-if="task.cycle > 0 && task.status === 2 && task.cycle_count === 0">
{{ task.cycle }}/{{ task.cycle }}
</div>
<div v-else-if="task.cycle > 0">
{{ task.cycle_count }}/{{ task.cycle }}
</div>
</td>
<td v-if="lockMode === true && Object.values(task.condition).findIndex(ele => ele.type == 'until_button_trigger') != -1 && task.status === 1">
<va-button icon="fa fa-play" @click="trigger_button(getSelectProject)" flat></va-button>
<td/>
<td align="center" v-if="lockMode === true">
<!-- {{ task.status }} -->
<fulfilling-bouncing-circle-spinner
@@ -144,9 +211,13 @@
</td>
</tr>
</template>
</tbody>
</vuedraggable>
<!-- </tbody> -->
</table>
</div>
<div>
<cycle-modal ref="cycle_modal_ref"></cycle-modal>
</div>
</div>
</template>
<script>
@@ -155,11 +226,16 @@ import { mapActions, mapGetters } from 'vuex'
import types from '@/store/modules/project/types'
import { FulfillingBouncingCircleSpinner } from 'epic-spinners'
import configTable from '@/data/config-table/index'
import vuedraggable from 'vuedraggable'
import { taskInfo } from '@/data/task/TaskInfo'
import CycleModal from '@/components/project/view/menu/components/CycleModal'
export default {
name: 'project-table',
components: {
FulfillingBouncingCircleSpinner,
vuedraggable,
CycleModal,
},
computed: {
config () {
@@ -169,6 +245,9 @@ export default {
...mapGetters('project', [
types.project.getSelect,
types.project.getDevice,
types.project.getCycle,
types.project.getDeviceLibrary,
types.project.getDeviceShowName,
types.task.get,
types.task.getCondition,
types.task.getParameterSet,
@@ -188,29 +267,78 @@ export default {
name: -1,
checked: [],
},
inputSaved: '',
focus: -1,
index: -1,
futureIndex: -1,
}
},
methods: {
delAction: function (action, conditionKey) {
// console.log(action.condition)
console.log(action.condition)
// console.log(conditionKey)
// console.log(action.condition[0])
// console.log(action.condition.length)
for (let i = 0; i < action.condition.length; i++) {
if (String(action.condition[i]) === String(conditionKey)) {
delete action.condition[i]
break
}
mqttPub: function (topic, mes) {
this.$mqtt.publish(topic, mes)
},
dragEnd: function (event) {
const newTaskList = JSON.parse(JSON.stringify(this.getSelectProject.task))
const b = newTaskList[event.oldDraggableIndex]
const a = newTaskList[event.newDraggableIndex]
if (b && b.device.length === 0) return
if (a === undefined) return
newTaskList.filter(ele => ele != null)
this.rearrangeTask({ project: this.getSelectProject })
},
swapTask: function (taskIndex, upDown) {
taskIndex = parseInt(taskIndex)
if (upDown === 0) {
const a = this.getSelectProject.task[taskIndex]
this.getSelectProject.task.splice(taskIndex, 1, this.getSelectProject.task[taskIndex - 1])
this.getSelectProject.task.splice(taskIndex - 1, 1, a)
} else {
const a = this.getSelectProject.task[taskIndex]
this.getSelectProject.task.splice(taskIndex, 1, this.getSelectProject.task[taskIndex + 1])
this.getSelectProject.task.splice(taskIndex + 1, 1, a)
}
console.log(action.condition)
// delete action.condition[0]
this.rearrangeTask({ project: this.getSelectProject })
},
delSelected: function () {
for (const indexSelected of this.tableColumn.checked) {
this.deleteTask({ project: this.getSelectProject, index: indexSelected })
}
},
delAction: function (task, actionKey, conditionKey) {
const _action = JSON.parse(JSON.stringify(task.action))
const _condition = JSON.parse(JSON.stringify(task.condition))
delete _action[actionKey]
delete _condition[conditionKey]
task.action = _action
task.condition = _condition
},
trigger_button: function (projectID) {
console.log('project', projectID)
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'set_project/0',
project: projectID.uuid,
content: 'test',
}))
},
switchInput: function (tag, index) {
this.tableColumn[tag] >= 0
? this.tableColumn[tag] = -1
: this.tableColumn[tag] = index
},
switchCycle: function (tag, index, projectID, task) {
this.switchInput(tag, index)
const cycleInfo = this.getCycleProject(task.uuid) // 0: index, 1: location, 2: info
if (this.inputSaved === cycleInfo[2].id) return
cycleInfo[2].id = this.inputSaved
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'set_project_cycle/0',
project: projectID.uuid,
index: cycleInfo[0],
content: { id: this.inputSaved },
}))
},
selectAll: function (selectedArray) {
const totalRange = [...Array(this.getSelectProject.task.length).keys()].map(idx => String(idx))
selectedArray.includes('-1')
@@ -236,30 +364,62 @@ export default {
}
}
},
parameterName (name) {
if (name === 'MODE') {
return 'Mode'
parameterName (name, deviceKey) {
const config = configTable.getConfig(this.getDeviceLibraryProject(deviceKey))
if (config !== undefined && Object.keys(config) !== 0) {
if (name === 'MODE') {
return 'Mode'
}
if (typeof config[name].showName === 'function') {
return config[name].showName()
}
return config[name].showName
}
if (typeof this.config[name].showName === 'function') {
return this.config[name].showName()
}
return this.config[name].showName
},
parameterValue (name, value) {
if (name === 'MODE') {
return this.config.MODE[value].name
parameterValue (name, value, deviceKey) {
const config = configTable.getConfig(this.getDeviceLibraryProject(deviceKey))
if (config !== undefined && Object.keys(config) !== 0) {
if (name === 'MODE') {
return config.MODE[value].name
}
if (config[name].type === 'number') {
const scale = config[name].unit[config[name].defaultUnit]
return `${config[name].outputReadabilityData(value, scale)} ${config[name].defaultUnit}`
} else if (config[name].type === 'array') {
return `${config[name].outputReadabilityData(value)}`
} else if (config[name].type === 'none') {
return ''
}
}
if (this.config[name].type === 'number') {
const scale = this.config[name].unit[this.config[name].defaultUnit]
return `${this.config[name].outputReadabilityData(value, scale)} ${this.config[name].defaultUnit}`
} else if (this.config[name].type === 'array') {
return `${this.config[name].outputReadabilityData(value)}`
} else if (this.config[name].type === 'none') {
return ''
},
showCycleModal: function (uuid) {
if (!this.lockMode) {
this.$refs.cycle_modal_ref.show()
this.$refs.cycle_modal_ref.setCycleInfo(this.getSelectProject, uuid)
}
},
getCycleInfo: function (uuid, attribute) {
const cycleInfo = this.getCycleProject(uuid) // 0: index, 1: location, 2: info
if (cycleInfo.length === 0) return ''
return cycleInfo[2][attribute]
},
getCycleLocation: function (uuid) {
const cycleInfo = this.getCycleProject(uuid) // 0: index, 1: location, 2: info
return cycleInfo[1]
},
handleMove (e) {
const { index, futureIndex } = e.draggedContext
this.index = index
this.futureIndex = futureIndex
return false // disable sort
},
...mapActions('project', [
types.task.copy,
types.task.delete,
types.task.rearrange,
]),
},
mounted () {
@@ -268,6 +428,18 @@ export default {
</script>
<style lang="scss">
.draggable {
width: 500px;
margin: auto;
}
.table-row-focus {
background: #ebedff;
border: 1px solid #dbdcf0;
box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.25);
border-radius: 5px;
}
.markup-tables {
width: 100%;
@@ -143,13 +143,29 @@ export default {
showDeviceSetting: true,
chartAreaClass: ['flex', 'xs12', 'sm12', 'md12', 'xl8', 'pa-0'],
getParmDone: false,
batteryInterval: {},
}
},
mqtt: {
async '+/device_battery/+' (data, topic) {
const deviceBattery = JSON.parse(String.fromCharCode.apply(null, data)).data
const device = this.deviceListNew.find(ele => ele.memory_board === deviceBattery.device)
device.battery = deviceBattery.battery
},
async '+/get_device_info_all/+' (data, topic) {
// console.log('get_device_info_all', String.fromCharCode.apply(null, data))
this.deviceListNew = JSON.parse(String.fromCharCode.apply(null, data)).data
// console.log(this.deviceListNew)
for (let i = 0; i < this.deviceListNew.length; i++) {
const curDevice = this.deviceListNew[i]
if ((curDevice.memory_board in this.batteryInterval) === false) {
this.batteryInterval[curDevice.memory_board] = setInterval(() => { this.getBattery(curDevice) }, 60000)
}
}
// console.log(this.batteryInterval)
// console.log(this.deviceListNew)
// await taskInfo.deviceInfo(String.fromCharCode.apply(null, data), this.deviceList)
// console.log('this.deviceList 0', this.deviceList)
@@ -298,12 +314,25 @@ export default {
}))
this.pageToast('The device [' + taskInfo.getDeviceIDByRaw(parseInt(mes[1])) + '] mission is done.')
break
case 'project':
// refresh real-time page when going to next task
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'get_device_info_all/0',
}))
this.pageToast(mes[1])
break
default:
break
}
},
},
methods: {
getBattery: function (device) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_battery/0',
device: device.memory_board,
}))
},
mqttSub: function (val) {
this.$mqtt.subscribe(val)
},
@@ -321,6 +350,7 @@ export default {
this.mqttSub(id + '/device_parameter/+')
this.mqttSub(id + '/device_parameter_value/+')
this.mqttSub(id + '/device_sd_card_status/+')
this.mqttSub('+/device_battery/+')
},
pageMqttUnSub: function (id) {
for (const device in taskInfo.getTaskInfo().deviceList) {
@@ -333,6 +363,7 @@ export default {
this.mqttUnSub(id + '/device_parameter/+')
this.mqttUnSub(id + '/device_parameter_value/+')
this.mqttUnSub(id + '/device_sd_card_status/+')
this.mqttUnSub('+/device_battery/+')
},
pageInit: async function () {
if (await this.$refs.devices_ref != null) {
@@ -616,6 +647,7 @@ export default {
}
await taskInfo.updateTaskInfo(this.$route.params.taskID)
this.GLOBAL.refreshCache()
this.pageMqttSub(taskInfo.getTaskInfo().controllerID)
await this.pageInit()
@@ -640,6 +672,10 @@ export default {
}
clearInterval(this.dataRefreshTimer)
this.pageMqttUnSub(taskInfo.getTaskInfo().controllerID)
for (var interval in this.batteryInterval) {
clearInterval(this.batteryInterval[interval])
}
},
}
@@ -105,7 +105,7 @@
</div>
</div>
<div v-else-if="tabValue == 1" :style="'width: '+ cardwidth + '; height: ' + cardheight + ';'" >
<canvas-chart-source :chartID="chartID" @addSource="addSource()" />
<canvas-chart-source :chartID="chartID" />
</div>
<div v-else :style="'width: '+ cardwidth + '; height: ' + cardheight + ';'" >
</div>
@@ -214,13 +214,15 @@ export default {
this.calClicked = clicked
},
captureChart: function () {
// count same ID in chartData
const captureTimes = String(Object.keys(this.chartData).filter(ele => ele.includes(String(this.data.chartID))).length)
const newData = Object.assign({}, this.data)
this.chartData[String(newData.chartID) + '-1'] = newData
this.chartData[String(newData.chartID) + '-1'].captured = true
this.chartData[String(newData.chartID) + '-1'].cardName = this.chartData[String(newData.chartID) + '-1'].cardName + ' - captured'
this.chartData[String(newData.chartID) + '-1'].chartID = String(newData.chartID) + '-1'
this.chartData[String(this.data.chartID) + '-' + captureTimes] = newData
this.chartData[String(this.data.chartID) + '-' + captureTimes].captured = true
this.chartData[String(this.data.chartID) + '-' + captureTimes].cardName += ' - captured -' + captureTimes
this.chartData[String(this.data.chartID) + '-' + captureTimes].createdBy = 'capture'
this.chartData[String(this.data.chartID) + '-' + captureTimes].chartID = String(this.data.chartID) + '-' + captureTimes
this.taskContentChartPanelKey++
// console.log(this.chartData[String(newData.chartID) + '-1'])
},
updateZoom: function (e) {
// console.log(e)
@@ -398,7 +400,6 @@ export default {
this.data.dataZoom[0].end = this.dataZoomEnd
this.data.dataZoom[1].start = this.data.dataZoom[0].start
this.data.dataZoom[1].end = this.data.dataZoom[0].end
// console.log(this.data.dataZoom)
this.$refs.CanvasChartRealTimeDisplay.matchData(this.data)
},
switchModeButton: function (dataMode, gridIndex, channelIndex) {
@@ -17,7 +17,7 @@
/>
<va-input
v-if="[1, 2, 3].indexOf(selectFilter.id) >= 0"
:label="'FREQ'"
:label="'EIS_FREQ'"
class="mx-1 freq-input"
v-model="freq2"
>
@@ -17,7 +17,7 @@
/>
<va-input
v-if="[1, 2, 3].indexOf(selectFilter.id) >= 0"
:label="'FREQ'"
:label="'EIS_FREQ'"
class="mx-1 freq-input"
v-model="freq2"
>
@@ -60,7 +60,7 @@
import { mapFields } from 'vuex-map-fields'
import { mapActions } from 'vuex'
import taskTypes from '@/store/modules/task/content/types'
import paramTable from '@/data/config-table/index'
import configTable from '@/data/config-table/index'
// import newTooltip from '@/factories/chart/tooltipFactory'
import { getTimeFormatter } from '@/store/modules/task/content/actions/chartAct'
import sgFilter from '@/data/SGFilter'
@@ -88,7 +88,6 @@ export default {
data () {
return {
info: null,
paramTable: paramTable,
rawData: null,
mode_name: '',
xName: '',
@@ -241,19 +240,23 @@ export default {
const dataX = []
const dataY = []
const time = []
for (index = 0; index < dataLength; index++) {
const dsample = 1
const m = parseInt((this.sgFilterArgument.windowSize - 1) / 2)
for (index = 0; index < dataLength; index += dsample) {
dataX.push(seriesData[index][0])
dataY.push(seriesData[index][1])
dataY.push(seriesData[index][1] * 1e-9)
time.push(seriesData[index][2])
}
// console.log(time[time.length - 1], time[0])
// console.log(dataX.length, time[time.length - 1] - time[0], dataX.length * 1e6 / (time[time.length - 1] - time[0]))
// console.log('dataX', dataX)
// console.log('dataY', dataY)
// console.log('time', time)
const filteredData = sgFilter(dataY, this.sgFilterArgument.windowSize, this.sgFilterArgument.polynomial)
// console.log('filterdData', filteredData)
const filteredData = sgFilter(dataY, this.sgFilterArgument.windowSize, this.sgFilterArgument.polynomial, this.getSampleRate())
for (index = 0; index < dataLength; index++) {
_data.push([dataX[index], filteredData[index], time[index]])
for (index = 0; index < filteredData.length; index++) {
_data.push([dataX[index + m], filteredData[index], time[index + m]])
}
// for (index = 0; index < dataLength; index++) {
@@ -417,13 +420,27 @@ export default {
var value = this.data.series[0].data[(this.data.series[0].data).length - 1][1]
return this.yName + ': ' + value + ' ' + this.yUnit
},
getSampleRate: function () {
try {
const deviceMappingID = this.chartData[this.chartID].mappingID
const device = this.deviceListNew.find(ele => ele.memory_board === deviceMappingID)
const deviceConfig = configTable.getConfig(deviceMappingID)
const voltStep = deviceConfig.VOLT_STEP.outputReadabilityData(device.configuration.VOLT_STEP)
const sampleRate = deviceConfig.SAMPLE_RATE.outputReadabilityData(device.configuration.SAMPLE_RATE)
return (1 / (voltStep / 1000)) * sampleRate
} catch (e) {
console.log('getSampleRateERROR', e)
return 1
}
},
...mapActions('taskContent', [
taskTypes.chart.saveToCache,
]),
},
async mounted () {
this.rawData = this.chartData[this.chartID]
// const test = [3.0, 12.9, 22.6, 32.10000000000001, 41.4, 50.5, 59.400000000000006, 68.1, 76.6, 84.9, 93.0, 100.9, 108.60000000000001, 116.1, 123.39999999999999, 130.5, 137.4, 144.10000000000002, 150.6, 156.9, 163.0, 168.9, 174.60000000000002, 180.10000000000002, 185.4, 190.5, 195.39999999999998, 200.1, 204.59999999999997, 208.90000000000003, 213.0, 216.89999999999998, 220.59999999999997, 224.09999999999997, 227.40000000000003, 230.5, 233.39999999999998, 236.1, 238.6, 240.90000000000003, 243.0, 244.9, 246.6, 248.10000000000002, 249.40000000000003, 250.5, 251.40000000000003, 252.09999999999997, 252.6, 252.9, 253.0, 252.90000000000003, 252.59999999999997, 252.10000000000002, 251.39999999999998, 250.5, 249.39999999999992, 248.09999999999997, 246.60000000000002, 244.89999999999998, 243.0, 240.89999999999992, 238.59999999999997, 236.10000000000002, 233.39999999999992, 230.5, 227.39999999999992, 224.10000000000002, 220.60000000000002, 216.89999999999992, 213.0, 208.89999999999986, 204.5999999999999, 200.10000000000002, 195.39999999999998, 190.5, 185.39999999999998, 180.0999999999999, 174.60000000000002, 168.89999999999998, 163.0, 156.89999999999998, 150.5999999999999, 144.10000000000002, 137.39999999999998, 130.5, 123.40000000000009, 116.10000000000002, 108.60000000000002, 100.89999999999986, 93.0, 84.90000000000009, 76.60000000000002, 68.10000000000002, 59.399999999999864, 50.5, 41.399999999999864, 32.09999999999991, 22.59999999999991, 12.899999999999977]
// console.log('sgFilter', sgFilter(test, 5, 2, 10))
// console.log('x', this.rawData.xAxis.length)
// if (this.mode_name === 'I-V Curve') {
// this.rawData.xAxis[0].boundaryGap = [0, '5%']
@@ -1,84 +1,85 @@
<template>
<div>
<!-- Whole Real-time Display Tool here -->
<div v-for="(plot, plotIndex) in realTime" :key="plotIndex">
<div v-for="(line, lineIndex) in plot" :key="plotIndex + '_' + lineIndex" class="row ma-0 pa-0">
<div v-for="(curve, curveIndex) in plot" :key="plotIndex + '-' + curveIndex" class="row ma-0 pa-0">
<!-- cycle -->
<div class="mt-1" style="width: 75px;"
v-show="data !== null && data.cycle > 0"
>
<div class="mt-1" style="width: 75px;" v-show="data !== null && data.cycle > 0">
<va-input
label="cycle no."
v-model="data.cycle"
:options="line.xUnitOption"
noClear
disabled
/>
</div>
<!-- y-axis -->
<div class="d-flex flex-row mt-1 ml-1">
<!-- value (y-axis) -->
<div style="width: 75px;">
<va-input
label="y-axis"
v-model="line.yValue"
v-model="curve.yValue"
disabled
/>
</div>
<!-- unit (y-axis) -->
<div style="width: 75px;">
<va-select
v-model="line.yUnit"
:options="line.yUnitOption"
@input="changeUnit('y', plotIndex, lineIndex)"
v-model="curve.yUnit"
:options="curve.yUnitOption"
@input="changeUnit('y', plotIndex, curveIndex)"
noClear
/>
</div>
</div>
<!-- x-axis -->
<div class="d-flex flex-row mt-1 ml-1">
<!-- value (x-axis) -->
<div style="width: 75px;">
<va-input
label="x-axis"
v-model="line.xValue"
v-model="curve.xValue"
disabled
/>
</div>
<!-- unit (x-axis) -->
<div style="width: 75px;">
<va-select
v-model="line.xUnit"
:options="line.xUnitOption"
@input="changeUnit('x', plotIndex, lineIndex)"
v-model="curve.xUnit"
:options="curve.xUnitOption"
@input="changeUnit('x', plotIndex, curveIndex)"
noClear
/>
</div>
</div>
<!-- intervel -->
<div class="d-flex flex-row mt-1 ml-1">
<!-- interval (y-axis) -->
<div class="ml-1" style="width: 80px;">
<va-input
v-show="!lineIndex"
v-model="line.yInterval"
v-show="!curveIndex"
v-model="curve.yInterval"
label="y-grid"
@focus="$event.target.select()"
@keyup.enter="setInterval('y', plotIndex, lineIndex, line.yInterval)"
@blur="setInterval('y', plotIndex, lineIndex, line.yInterval)"
@keyup.enter="setInterval('y', plotIndex, curveIndex, curve.yInterval)"
@blur="setInterval('y', plotIndex, curveIndex, curve.yInterval)"
>
<p slot="append" style="margin-right: 0;" small>
{{ line.yUnit }}
{{ curve.yUnit }}
</p>
</va-input>
</div>
<!-- interval (x-axis) -->
<div class="ml-1" style="width: 80px;">
<va-input
v-show="!lineIndex"
v-model="line.xInterval"
v-show="!curveIndex"
v-model="curve.xInterval"
label="x-grid"
@focus="$event.target.select()"
@keyup.enter="setInterval('x', plotIndex, lineIndex, line.xInterval)"
@blur="setInterval('x', plotIndex, lineIndex, line.xInterval)"
@keyup.enter="setInterval('x', plotIndex, curveIndex, curve.xInterval)"
@blur="setInterval('x', plotIndex, curveIndex, curve.xInterval)"
>
<p slot="append" style="margin-right: 0;" small>
{{ line.xUnit }}
{{ curve.xUnit }}
</p>
</va-input>
</div>
@@ -124,123 +125,117 @@ export default {
...mapActions('taskContent', [
taskTypes.chart.saveToCache,
]),
test: function () {},
// for user to choose wanted unit
setUnit: function (gridIndex, channelIndex) {
getDeviceMode: function () {
const device = this.deviceListNew.find(ele => String(ele.memory_board) === String(this.chartData[this.chartID].mappingID))
if (device === undefined) return
return device.configuration.MODE
},
// set a new display tool
setRealTime: function (plotIndex, curveIndex) {
// construct realTime object, i.e., record the coressponding value and unit
// the formate imitates the data.gridSource
if (this.data !== undefined && this.data.gridSource !== undefined) {
const _xPhysicsQuantity = this.data.gridSource[gridIndex][channelIndex].name.split('_')[0].split('-').at(-1)
const _yPhysicsQuantity = this.data.gridSource[gridIndex][channelIndex].name.split('_')[1].split('-').at(-1)
let _xPhysicsQuantity = this.data.gridSource[plotIndex][curveIndex].name.split('_')[0].split('-').at(-1)
let _yPhysicsQuantity = this.data.gridSource[plotIndex][curveIndex].name.split('_')[1].split('-').at(-1)
// Potential
if (_xPhysicsQuantity === 'P') _xPhysicsQuantity = 'V'
if (_yPhysicsQuantity === 'P') _yPhysicsQuantity = 'V'
const [_xAxis, _yAxis] = this.chartRouter.getChartTable(_xPhysicsQuantity, _yPhysicsQuantity)
const _realTime = JSON.parse(JSON.stringify(this.realTime))
const _newChannel = {}
const _newCurve = {}
// set name, sourceIndex in data.series
_newChannel.name = this.data.gridSource[gridIndex][channelIndex].name
_newChannel.seriesSource = this.data.series.findIndex((ele) => ele.name === _newChannel.name)
_newCurve.name = this.data.gridSource[plotIndex][curveIndex].name
_newCurve.seriesSource = this.data.series.findIndex((ele) => ele.name === _newCurve.name)
// set x-axis
_newChannel.xValue = 0
_newChannel.xUnit = _xAxis.default.defaultUnit
_newChannel.xScale = _xAxis.default.unit
_newChannel.xUnitOption = Object.keys(_xAxis.default.unit)
_newChannel.xName = _xAxis.default.name
_newChannel.xInterval = 'auto'
_newCurve.xValue = 0
_newCurve.xUnit = (typeof _xAxis.default.defaultUnit === 'function') ? _xAxis.default.defaultUnit(this.getDeviceMode()) : _xAxis.default.defaultUnit
_newCurve.xScaleOption = _xAxis.default.unit
_newCurve.xUnitOption = Object.keys(_xAxis.default.unit)
_newCurve.xName = _xAxis.default.name
_newCurve.xInterval = 'auto'
// set y-axis
_newChannel.yValue = 0
_newChannel.yUnit = _yAxis.default.defaultUnit
_newChannel.yScale = _yAxis.default.unit
_newChannel.yUnitOption = Object.keys(_yAxis.default.unit)
_newChannel.yName = _yAxis.default.name
_newChannel.yInterval = 'auto'
_newCurve.yValue = 0
_newCurve.yUnit = (typeof _yAxis.default.defaultUnit === 'function') ? _yAxis.default.defaultUnit(this.getDeviceMode()) : _yAxis.default.defaultUnit
_newCurve.yScaleOption = _yAxis.default.unit
_newCurve.yUnitOption = Object.keys(_yAxis.default.unit)
_newCurve.yName = _yAxis.default.name
_newCurve.yInterval = 'auto'
// set functional
_newChannel.functional = 'default'
_newCurve.functional = 'default'
// padding
while (gridIndex >= _realTime.length) {
while (plotIndex >= _realTime.length) {
_realTime.push([])
}
while (channelIndex >= _realTime[gridIndex].length) {
_realTime[gridIndex].push({})
while (curveIndex >= _realTime[plotIndex].length) {
_realTime[plotIndex].push({})
}
// merge the additional part into original part
_realTime[gridIndex][channelIndex] = _newChannel
_realTime[plotIndex][curveIndex] = _newCurve
this.realTime = _realTime
}
},
setInterval: async function (axis, plotIndex, lineIndex, val) {
// set the interval size keyed by user
setInterval: async function (axis, plotIndex, curveIndex, val) {
if (!isNaN(val)) {
const scaleOption = this.realTime[plotIndex][lineIndex][axis + 'Scale']
const unit = this.realTime[plotIndex][lineIndex][axis + 'Unit']
const scaleOption = this.realTime[plotIndex][curveIndex][axis + 'ScaleOption']
const unit = this.realTime[plotIndex][curveIndex][axis + 'Unit']
this.chartData[this.chartID][axis + 'Axis'][plotIndex].interval = val * scaleOption[unit]
} else {
this.chartData[this.chartID][axis + 'Axis'][plotIndex].interval = 'hi' // I know it looks weird, but this one is necessesary
this.chartData[this.chartID][axis + 'Axis'][plotIndex].interval = null
this.realTime[plotIndex][lineIndex][axis + 'Interval'] = 'auto'
this.realTime[plotIndex][curveIndex][axis + 'Interval'] = 'auto'
}
await this.taskContentChartSaveToCache({ controllerID: taskInfo.getTaskInfo().controllerID })
},
updateInterval: async function (axis, plotIndex, lineIndex) {
this.chartData[this.chartID][axis + 'Axis'][plotIndex].interval = null
this.realTime[plotIndex][lineIndex][axis + 'Interval'] = 'auto'
await this.taskContentChartSaveToCache({ controllerID: taskInfo.getTaskInfo().controllerID })
},
// record the latest data as the real time value
updateValue: function () {
if ((this.realTime.length === 0)) {
return
}
for (let gridIndex = 0; gridIndex < this.realTime.length; gridIndex++) {
for (let channelIndex = 0; channelIndex < this.realTime[gridIndex].length; channelIndex++) {
for (let plotIndex = 0; plotIndex < this.realTime.length; plotIndex++) {
for (let curveIndex = 0; curveIndex < this.realTime[plotIndex].length; curveIndex++) {
// miss the source of data -> try to find the source
if (this.realTime[gridIndex][channelIndex].seriesSource === -1) {
this.realTime[gridIndex][channelIndex].seriesSource = this.data.series.findIndex((ele) => ele.name === this.realTime[gridIndex][channelIndex].name)
if (this.realTime[plotIndex][curveIndex].seriesSource === -1) {
this.realTime[plotIndex][curveIndex].seriesSource = this.data.series.findIndex((ele) => ele.name === this.realTime[plotIndex][curveIndex].name)
}
// the device is active now --> update the real time value
if (this.data.series[this.realTime[gridIndex][channelIndex].seriesSource] !== undefined && this.data.series[this.realTime[gridIndex][channelIndex].seriesSource].data !== undefined && this.data.series[this.realTime[gridIndex][channelIndex].seriesSource].data.length > 0) {
this.realTime[gridIndex][channelIndex].xValue = (this.data.series[this.realTime[gridIndex][channelIndex].seriesSource].data.at(-1)[0] / this.realTime[gridIndex][channelIndex].xScale[this.realTime[gridIndex][channelIndex].xUnit]).toFixed(3)
this.realTime[gridIndex][channelIndex].yValue = (this.data.series[this.realTime[gridIndex][channelIndex].seriesSource].data.at(-1)[1] / this.realTime[gridIndex][channelIndex].yScale[this.realTime[gridIndex][channelIndex].yUnit]).toFixed(3)
}
}
}
},
// match the number of real time display bar to data.gridSource
matchChart: function () {
for (let gridIndex = 0; gridIndex < this.data.gridSource.length; gridIndex++) {
if (this.data.gridSource[gridIndex] !== undefined) {
for (let channelIndex = 0; channelIndex < this.data.gridSource[gridIndex].length; channelIndex++) {
if (gridIndex >= this.realTime.length) {
this.setUnit(gridIndex, channelIndex)
} else if (channelIndex >= this.realTime[gridIndex].length) {
this.setUnit(gridIndex, channelIndex)
}
if (this.data.series[this.realTime[plotIndex][curveIndex].seriesSource] !== undefined &&
this.data.series[this.realTime[plotIndex][curveIndex].seriesSource].data !== undefined &&
this.data.series[this.realTime[plotIndex][curveIndex].seriesSource].data.length > 0) {
this.realTime[plotIndex][curveIndex].xValue = (this.data.series[this.realTime[plotIndex][curveIndex].seriesSource].data.at(-1)[0] / this.realTime[plotIndex][curveIndex].xScaleOption[this.realTime[plotIndex][curveIndex].xUnit]).toFixed(3)
this.realTime[plotIndex][curveIndex].yValue = (this.data.series[this.realTime[plotIndex][curveIndex].seriesSource].data.at(-1)[1] / this.realTime[plotIndex][curveIndex].yScaleOption[this.realTime[plotIndex][curveIndex].yUnit]).toFixed(3)
}
}
}
},
// match the formatter to current unit and functional
matchFormatter: function () {
for (let gridIndex = 0; gridIndex < this.realTime.length; gridIndex++) {
for (let channelIndex = 0; channelIndex < this.realTime[gridIndex].length; channelIndex++) {
if (channelIndex === 0) {
const _xUnit = this.realTime[gridIndex][channelIndex].xUnit
const _yUnit = this.realTime[gridIndex][channelIndex].yUnit
const _xScale = this.realTime[gridIndex][channelIndex].xScale[this.realTime[gridIndex][channelIndex].xUnit]
const _yScale = this.realTime[gridIndex][channelIndex].yScale[this.realTime[gridIndex][channelIndex].yUnit]
updateFormatter: function () {
for (let plotIndex = 0; plotIndex < this.realTime.length; plotIndex++) {
for (let curveIndex = 0; curveIndex < this.realTime[plotIndex].length; curveIndex++) {
if (curveIndex === 0) {
const _xUnit = this.realTime[plotIndex][curveIndex].xUnit
const _yUnit = this.realTime[plotIndex][curveIndex].yUnit
const _xScale = this.realTime[plotIndex][curveIndex].xScaleOption[this.realTime[plotIndex][curveIndex].xUnit]
const _yScale = this.realTime[plotIndex][curveIndex].yScaleOption[this.realTime[plotIndex][curveIndex].yUnit]
// update xAxis.formatter
if (this.realTime[gridIndex][channelIndex].xName === 'Time') {
this.data.xAxis[gridIndex].axisLabel.formatter = this.timeFormatter
if (this.realTime[plotIndex][curveIndex].xName === 'Time') {
this.data.xAxis[plotIndex].axisLabel.formatter = this.timeFormatter
} else {
this.data.xAxis[gridIndex].axisLabel.formatter = function (val) {
this.data.xAxis[plotIndex].axisLabel.formatter = function (val) {
return parseFloat(val / _xScale).toFixed(3) + _xUnit
}
}
// update yAxis.formatter
if (this.realTime[gridIndex][channelIndex].yName === 'Time') {
this.data.yAxis[gridIndex].axisLabel.formatter = this.timeFormatter
if (this.realTime[plotIndex][curveIndex].yName === 'Time') {
this.data.yAxis[plotIndex].axisLabel.formatter = this.timeFormatter
} else {
this.data.yAxis[gridIndex].axisLabel.formatter = function (val) {
this.data.yAxis[plotIndex].axisLabel.formatter = function (val) {
return parseFloat(val / _yScale).toFixed(3) + _yUnit
}
}
@@ -250,35 +245,52 @@ export default {
}
}
},
changeUnit: function (axis, plotIndex, lineIndex) {
changeUnit: function (axis, plotIndex, curveIndex) {
this.updateValue()
this.matchFormatter()
this.updateInterval(axis, plotIndex, lineIndex)
this.updateFormatter()
this.setInterval(axis, plotIndex, curveIndex, 'auto')
},
// match the number of real time display bar to data.gridSource
matchChart: function () {
for (let plotIndex = 0; plotIndex < this.data.gridSource.length; plotIndex++) {
if (this.data.gridSource[plotIndex] !== undefined) {
for (let curveIndex = 0; curveIndex < this.data.gridSource[plotIndex].length; curveIndex++) {
if (plotIndex >= this.realTime.length) {
this.setRealTime(plotIndex, curveIndex)
} else if (curveIndex >= this.realTime[plotIndex].length) {
this.setRealTime(plotIndex, curveIndex)
}
}
}
}
},
// match the data to operated data in CanvasChart.vue
matchData: function (canvasChartData) {
this.data = canvasChartData
},
// match the functional to operated data in CanvasChart.vue
matchFunctional: function (newFunctional, gridIndex, channelIndex) {
if (this.realTime[gridIndex][channelIndex] === undefined) return
if (this.realTime[gridIndex][channelIndex].functional === newFunctional) return
const _currChannel = this.realTime[gridIndex][channelIndex]
const _xPhysicsQuantity = this.data.gridSource[gridIndex][channelIndex].name.split('_')[0].split('-').at(-1)
const _yPhysicsQuantity = this.data.gridSource[gridIndex][channelIndex].name.split('_')[1].split('-').at(-1)
matchFunctional: function (newFunctional, plotIndex, curveIndex) {
if (this.realTime[plotIndex][curveIndex] === undefined) return
if (this.realTime[plotIndex][curveIndex].functional === newFunctional) return
const _currCurve = this.realTime[plotIndex][curveIndex]
let _xPhysicsQuantity = this.data.gridSource[plotIndex][curveIndex].name.split('_')[0].split('-').at(-1)
let _yPhysicsQuantity = this.data.gridSource[plotIndex][curveIndex].name.split('_')[1].split('-').at(-1)
// Potential
if (_xPhysicsQuantity === 'P') _xPhysicsQuantity = 'V'
if (_yPhysicsQuantity === 'P') _yPhysicsQuantity = 'V'
const [_xAxis, _yAxis] = this.chartRouter.getChartTable(_xPhysicsQuantity, _yPhysicsQuantity)
_currChannel.functional = newFunctional
_currCurve.functional = newFunctional
// set x-axis
_currChannel.xUnit = _xAxis.default.defaultUnit
_currChannel.xScale = _xAxis.default.unit
_currChannel.xUnitOption = Object.keys(_xAxis.default.unit)
_currChannel.xName = _xAxis.default.name
_currCurve.xUnit = (typeof _xAxis.default.defaultUnit === 'function') ? _xAxis.default.defaultUnit(this.getDeviceMode()) : _xAxis.default.defaultUnit
_currCurve.xScaleOption = _xAxis.default.unit
_currCurve.xUnitOption = Object.keys(_xAxis.default.unit)
_currCurve.xName = _xAxis.default.name
// set y-axis
_currChannel.yUnit = _yAxis[newFunctional].defaultUnit
_currChannel.yScale = _yAxis[newFunctional].unit
_currChannel.yUnitOption = Object.keys(_yAxis[newFunctional].unit)
_currChannel.yName = _yAxis[newFunctional].name
_currCurve.yUnit = (typeof _yAxis[newFunctional].defaultUnit === 'function') ? _yAxis[newFunctional].defaultUnit(this.getDeviceMode()) : _yAxis[newFunctional].defaultUnit
_currCurve.yScaleOption = _yAxis[newFunctional].unit
_currCurve.yUnitOption = Object.keys(_yAxis[newFunctional].unit)
_currCurve.yName = _yAxis[newFunctional].name
},
timeFormatter: function (val) {
let label = ''
@@ -310,17 +322,16 @@ export default {
this.data = this.chartData[this.chartID]
},
watch: {
data: {
'data.series': {
handler: function () {
this.updateValue()
this.matchChart()
},
deep: true,
},
realTime: {
'data.gridSource': {
handler: function () {
this.updateValue()
this.matchFormatter()
this.matchChart()
this.updateFormatter()
},
deep: true,
},
@@ -90,6 +90,7 @@ import { taskInfo } from '../../../../data/task/TaskInfo'
import { mapFields } from 'vuex-map-fields'
import { mapActions } from 'vuex'
import taskTypes from '@/store/modules/task/content/types'
import configTable from '../../../../data/config-table'
export default {
name: 'canvas-chart-source',
@@ -140,7 +141,8 @@ export default {
deviceSelectX: function () {
const channelOptions = []
const deviceInfo = this.deviceListNew.find(ele => ele.id === this.deviceSelectX.id)
// console.log(val)
// console.log('deviceInfo', deviceInfo.library_name, deviceInfo.configuration.MODE)
// console.log('sourceObj', Object.keys(sourceObj))
if (deviceInfo == null) {
this.channelSelectDisableX = true
} else if (deviceInfo.library_name.includes('Neulive')) {
@@ -182,11 +184,19 @@ export default {
})
this.channelSelectDisableX = false
} else if (deviceInfo.library_name.includes('Elite')) {
const sourceObj = configTable.getChannelConfig(String(deviceInfo.library_name), deviceInfo.configuration.MODE) // [{id:0 channel:'Current'}, {id:1, channel:'Voltage'}, ]
let channelSet
if (deviceInfo.library_name.includes('EIS') && deviceInfo.configuration.MODE === 0) {
channelSet = ['Zimag_Raw', 'Zreal_Raw', 'Frequency', 'Cycle', 'Zimag', 'Zreal', 'Impedance', 'Phase', 'Current', 'Level gain']
} else {
channelSet = deviceInfo.configuration.CHANNEL_LABEL
channelSet = []
const keys = Object.keys(sourceObj)
for (let i = 0; i < keys.length; i++) {
const item = keys[i]
if (sourceObj[item].name !== 'Time' && sourceObj[item].name !== 'Cycle number') {
channelSet.push(String(sourceObj[item].name))
}
}
}
// console.log(channelSet)
channelSet.forEach((element, index) => {
@@ -250,11 +260,19 @@ export default {
})
this.channelSelectDisableY = false
} else if (deviceInfo.library_name.indexOf('Elite') >= 0) {
const sourceObj = configTable.getChannelConfig(String(deviceInfo.library_name), deviceInfo.configuration.MODE) // [{id:0 channel:'Current'}, {id:1, channel:'Voltage'}, ]
let channelSet
if (deviceInfo.library_name.includes('EIS') && deviceInfo.configuration.MODE === 0) {
channelSet = ['Zimag_Raw', 'Zreal_Raw', 'Frequency', 'Cycle', 'Zimag', 'Zreal', 'Impedance', 'Phase', 'Current', 'Level gain']
} else {
channelSet = deviceInfo.configuration.CHANNEL_LABEL
channelSet = []
const keys = Object.keys(sourceObj)
for (let i = 0; i < keys.length; i++) {
const item = keys[i]
if (sourceObj[item].name !== 'Time' && sourceObj[item].name !== 'Cycle number') {
channelSet.push(String(sourceObj[item].name))
}
}
}
// console.log(channelSet)
channelSet.forEach((element, index) => {
@@ -329,7 +347,6 @@ export default {
} else if (this.deviceSelectY.name.indexOf('Time') >= 0) {
deviceNameY = 'Time'
}
this.taskContentChartRegister({
chartID: this.chartID,
gridIndex: gridIndex,
@@ -57,20 +57,20 @@ const chartTable = {
mA: 1e6,
A: 1e9,
},
defaultUnit: 'mA',
defaultUnit: (Mode) => { return (Mode === 10 || Mode === 11) ? 'nA' : 'mA' },
downloadUnit: 'mA',
},
// Q = ∫ I dt
integral: {
name: 'Charge',
unit: {
nC: 1e6,
uC: 1e9,
mC: 1e12,
C: 1e15,
nAh: 3600 * 1e6,
uAh: 1600 * 1e9,
mAh: 3600 * 1e12,
Ah: 3600 * 1e15,
},
defaultUnit: 'mC',
downloadUnit: 'mC',
defaultUnit: 'mAh',
downloadUnit: 'mAh',
},
},
],
@@ -105,6 +105,34 @@ const chartTable = {
},
},
],
V_V: [
// 0
{
default: {
name: 'Voltage',
unit: {
uV: 1,
mV: 1e3,
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'mV',
},
},
// 1
{
default: {
name: 'Voltage',
unit: {
uV: 1,
mV: 1e3,
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'mV',
},
},
],
V_I: [
// 0
{
@@ -152,19 +180,18 @@ const chartTable = {
mA: 1e6,
A: 1e9,
},
defaultUnit: 'mA',
defaultUnit: (Mode) => { return (Mode === 10 || Mode === 11) ? 'nA' : 'mA' },
downloadUnit: 'mA',
},
// Gm = dI/dV
differential: {
name: 'Transconductance',
unit: {
'mA/V': 1,
'A/V': 1e3,
'kA/V': 1e6,
'mA/mV': 1e-3,
'A/mV': 1,
},
defaultUnit: 'A/V',
downloadUnit: 'A/V',
defaultUnit: 'mA/mV',
downloadUnit: 'A',
},
// Power = ∫ I dv
integral: {
@@ -179,7 +206,65 @@ const chartTable = {
},
},
],
Zreal_Zimag: [
V_R: [
// 0
{
default: {
name: 'Voltage',
unit: {
uV: 1,
mV: 1e3,
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'mV',
},
},
// 1
{
default: {
name: 'Resistance',
unit: {
: 1,
Ω: 1e3,
: 1e6,
: 1e9,
},
defaultUnit: 'Ω',
downloadUnit: 'Ω',
},
},
],
I_R: [
// 0
{
default: {
name: 'Voltage',
unit: {
uV: 1,
mV: 1e3,
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'mV',
},
},
// 1
{
default: {
name: 'Current',
unit: {
nA: 1,
uA: 1e3,
mA: 1e6,
A: 1e9,
},
defaultUnit: (Mode) => { return (Mode === 10) ? 'nA' : 'mA' },
downloadUnit: 'mA',
},
},
],
ZReal_ZImag: [
// 0
{
default: {
@@ -21,9 +21,26 @@
</va-item-section>
<va-item-section class="ml-3" caption>
<va-item-label>
{{ `[${device.memory_board}]` }} {{ device.name }}
<!-- <va-button @click="getBattery(device)"> get battery </va-button> -->
<!-- <pre> {{ device.battery }} </pre> -->
<va-item-label v-if="parseInt((device.battery - 2900) / 10) >= 75">
{{ `[${device.memory_board}]` }} {{ device.name }} <va-icon class="ml-3 fa fa-battery-full" color="#5BC236"/> {{ (parseInt((device.battery - 2900) / 10) > 100 ? 100 : parseInt((device.battery - 2900) / 10)) + '%' }}
</va-item-label>
<va-item-label v-else-if="parseInt((device.battery - 2900) / 10) >= 50">
{{ `[${device.memory_board}]` }} {{ device.name }} <va-icon class="ml-3 fa fa-battery-three-quarters" color="#5BC236"/> {{ parseInt((device.battery - 2900) / 10) + '%' }}
</va-item-label>
<va-item-label v-else-if="parseInt((device.battery - 2900) / 10) >= 25">
{{ `[${device.memory_board}]` }} {{ device.name }} <va-icon class="ml-3 fa fa-battery-half" color="#F6B431"/> {{ parseInt((device.battery - 2900) / 10) + '%' }}
</va-item-label>
<va-item-label v-else-if="parseInt((device.battery - 2900) / 10) > 10">
{{ `[${device.memory_board}]` }} {{ device.name }} <va-icon class="ml-3 fa fa-battery-quarter" color="#DA244B"/> {{ parseInt((device.battery - 2900) / 10) + '%' }}
</va-item-label>
<va-item-label v-else>
{{ `[${device.memory_board}]` }} {{ device.name }} <va-icon class="ml-3 fa fa-battery-empty" color="#DA244B"/> <span style="color: red;"> low battery </span>
</va-item-label>
<!-- <va-item-label v-else>
{{ `[${device.memory_board}]` }} {{ device.name }} <va-icon class="ml-3 fa fa-battery-empty" color="#DA244B"/> {{ '0%' }}
</va-item-label> -->
<va-item-label caption>
{{ device.mac_address.toUpperCase() }}
</va-item-label>
@@ -16,7 +16,7 @@
/>
</div>
<div class="flex sm2 xl2 md2 xs2 px-0 mx-0 my-0 py-0 pl-2">
<va-button class="pa-0 ma-0 mt-2 circle-button" small color="dark" @click="showModal=true">
<va-button v-if="place != 'scheduler'" class="pa-0 ma-0 mt-2 circle-button" small color="dark" @click="showModal=true">
<va-icon
name="fa fa-info"
color="white"
@@ -81,6 +81,7 @@
:parameterName="name"
:inputValue="parameter[name]"
:disable="name === 'CTRL_HIGH_Z_15' && device && device.status === 0"
:syncParameter="parameterTable[name].syncParameter"
v-bind="parameterTable[name]"
@parameterChange="parameterChange"
@getParameter="getParameter"
@@ -156,6 +157,10 @@ export default {
type: Object,
default: null,
},
place: {
type: String,
default: '',
},
},
computed: {
parameterTable () {
@@ -221,6 +226,7 @@ export default {
parameterValue (name) {
const value = this.parameter[name]
if (this.parameterTable[name].type === 'number') {
if (this.parameterTable[name].defaultUnit === undefined) return ''
const scale = this.parameterTable[name].unit[this.parameterTable[name].defaultUnit]
return ` ( ${this.parameterTable[name].outputReadabilityData(value, scale)} ${this.parameterTable[name].defaultUnit} )`
} else if (this.parameterTable[name].type === 'array') {
@@ -248,11 +254,18 @@ export default {
this.parameterChange('MODE', this.workingModeSelect.id)
// if device is idle, then setting highz when mode switch
if (this.deviceStatus === true && this.workingModeSelect.highz !== undefined) {
this.parameterChange('CTRL_HIGH_Z_15', this.workingModeSelect.highz)
if (this.deviceStatus === true) {
if (this.workingModeSelect.highz !== undefined) {
this.parameterChange('CTRL_HIGH_Z_15', this.workingModeSelect.highz)
}
}
}
},
resetWorkingMode () {
this.workingModeOptions = this.parameterTable.MODE_OPTIONS
this.workingModeSelect = (this.parameter.MODE !== undefined) ? this.workingModeOptions.find(ele => ele.id === this.parameter.MODE) : this.workingModeOptions[0]
console.log(this.workingModeOptions, this.workingModeSelect)
},
getParameter: function (name) {
this.$emit('getParameter', name)
},
@@ -270,6 +283,13 @@ export default {
this.workingModeSelect = (this.parameter.MODE !== undefined) ? this.workingModeOptions.find(ele => ele.id === this.parameter.MODE) : this.workingModeOptions[0]
},
watch: {
parameter: {
deep: true,
handler: function () {
// refresh real time parameter
this.workingModeSelect = (this.parameter.MODE !== undefined) ? this.workingModeOptions.find(ele => ele.id === this.parameter.MODE) : this.workingModeOptions[0]
},
},
},
destroyed () {
},
@@ -12,14 +12,14 @@
</div>
<!-- EIS -->
<div v-if="workingModeSelect != null && workingModeSelect.id == 0">
<d-c-volt :ref="'DCVolt'" :deviceID="deviceID" :parameterName="'DC_BIAS'" @parameterChange="deviceParameterChange($event)" />
<a-c-amplitude :ref="'ACAmplitude'" :deviceID="deviceID" :parameterName="'AC_AMP'" @parameterChange="deviceParameterChange($event)" />
<freq-range :ref="'FreqRange'" :deviceID="deviceID" :parameterName="'FREQ'" @parameterChange="deviceParameterChange($event)" />
<points-per-decades :ref="'PointsPerDecades'" :deviceID="deviceID" :parameterName="'PPD'" @parameterChange="deviceParameterChange($event)" />
<point-spacing :ref="'PointSpacing'" :deviceID="deviceID" :parameterName="'SCALE'" @parameterChange="deviceParameterChange($event)" />
<delay :ref="'Delay'" :deviceID="deviceID" :parameterName="'DELAY'" @parameterChange="deviceParameterChange($event)" />
<average :ref="'Average'" :deviceID="deviceID" :parameterName="'AVERAGE_NUM'" @parameterChange="deviceParameterChange($event)" />
<current-range :ref="'CurrentRange'" :deviceID="deviceID" :parameterName="'RTIA'" @parameterChange="deviceParameterChange($event)" />
<d-c-volt :ref="'DCVolt'" :deviceID="deviceID" :parameterName="'EIS_DC_BIAS'" @parameterChange="deviceParameterChange($event)" />
<a-c-amplitude :ref="'ACAmplitude'" :deviceID="deviceID" :parameterName="'EIS_AC_AMP'" @parameterChange="deviceParameterChange($event)" />
<freq-range :ref="'FreqRange'" :deviceID="deviceID" :parameterName="'EIS_FREQ'" @parameterChange="deviceParameterChange($event)" />
<points-per-decades :ref="'PointsPerDecades'" :deviceID="deviceID" :parameterName="'EIS_PPD'" @parameterChange="deviceParameterChange($event)" />
<point-spacing :ref="'PointSpacing'" :deviceID="deviceID" :parameterName="'EIS_SCALE'" @parameterChange="deviceParameterChange($event)" />
<delay :ref="'Delay'" :deviceID="deviceID" :parameterName="'EIS_DELAY'" @parameterChange="deviceParameterChange($event)" />
<average :ref="'Average'" :deviceID="deviceID" :parameterName="'EIS_AVERAGE_NUM'" @parameterChange="deviceParameterChange($event)" />
<current-range :ref="'CurrentRange'" :deviceID="deviceID" :parameterName="'GENERAL_HS_RTIA'" @parameterChange="deviceParameterChange($event)" />
</div>
<!-- CV -->
<div v-if="workingModeSelect != null && workingModeSelect.id == 1">
@@ -283,7 +283,7 @@ export default {
},
],
DCVolt: null,
AC_AMP: null,
EIS_AC_AMP: null,
FreqStart: null,
FreqStop: null,
PointsPerDecades: null,
@@ -395,45 +395,36 @@ export default {
this.measureEocButton.status = false
},
refresh () {
// taskInfo.getDeviceInfo(this.deviceID).parameterSet.CHANNEL_LABEL = ['Z_image_Raw', 'Z_Real_Raw', 'Frequency', 'Cycle', 'Z_imag', 'Z_real', 'Impedance', 'Phase', 'Current', 'Level gain']
this.workingModeSelect = this.workingModeOptions[taskInfo.getDeviceInfo(this.deviceID).parameterSet.MODE]
if (this.workingModeSelect != null) {
this.workingModeSelectChange(this.workingModeSelect)
}
this.ACAmplitude = String(Math.round((taskInfo.getDeviceInfo(this.deviceID).parameterSet.AC_AMP) / 2047 * 800))
this.ACAmplitude = String(Math.round((taskInfo.getDeviceInfo(this.deviceID).parameterSet.EIS_AC_AMP) / 2047 * 800))
if (this.$refs.ACAmplitude != null) {
this.$refs.ACAmplitude.itemChange(this.ACAmplitude)
}
this.Average = taskInfo.getDeviceInfo(this.deviceID).parameterSet.AVERAGE_NUM
this.Average = taskInfo.getDeviceInfo(this.deviceID).parameterSet.EIS_AVERAGE_NUM
if (this.$refs.Average != null) {
this.$refs.Average.itemChange(this.Average)
}
this.CurrentRange = taskInfo.getDeviceInfo(this.deviceID).parameterSet.RTIA
this.CurrentRange = taskInfo.getDeviceInfo(this.deviceID).parameterSet.GENERAL_HS_RTIA
if (this.$refs.CurrentRange != null) {
this.$refs.CurrentRange.itemChange(this.CurrentRange)
}
this.PointSpacing = taskInfo.getDeviceInfo(this.deviceID).parameterSet.SCALE
this.PointSpacing = taskInfo.getDeviceInfo(this.deviceID).parameterSet.EIS_SCALE
if (this.$refs.PointSpacing != null) {
this.$refs.PointSpacing.itemChange(this.PointSpacing)
}
this.DCVolt = (taskInfo.getDeviceInfo(this.deviceID).parameterSet.DC_BIAS - 15000) / 10
this.DCVolt = (taskInfo.getDeviceInfo(this.deviceID).parameterSet.EIS_DC_BIAS - 15000) / 10
if (this.$refs.DCVolt != null) {
this.$refs.DCVolt.itemChange(this.DCVolt)
}
this.Delay = String(parseFloat((taskInfo.getDeviceInfo(this.deviceID).parameterSet.DELAY) / 10).toFixed(1))
this.Delay = String(parseFloat((taskInfo.getDeviceInfo(this.deviceID).parameterSet.EIS_DELAY) / 10).toFixed(1))
if (this.$refs.Delay != null) {
this.$refs.Delay.itemChange(this.Delay)
}
this.FreqStart = String(parseFloat(Math.round(parseFloat((taskInfo.getDeviceInfo(this.deviceID).parameterSet.FREQ_START * 0.0149) * 100)) / 100).toFixed(1)) === '0.0' ? '0.015' : String(parseFloat(Math.round(parseFloat((taskInfo.getDeviceInfo(this.deviceID).parameterSet.FREQ_START * 0.0149) * 100)) / 100).toFixed(1))
if (this.$refs.FreqRange != null) {
this.$refs.FreqRange.itemChangeMax(this.FreqStart)
}
this.FreqStop = String(parseFloat(Math.round(parseFloat((taskInfo.getDeviceInfo(this.deviceID).parameterSet.FREQ_STOP * 0.0149) * 100)) / 100).toFixed(1)) === '0.0' ? '0.015' : String(parseFloat(Math.round(parseFloat((taskInfo.getDeviceInfo(this.deviceID).parameterSet.FREQ_STOP * 0.0149) * 100)) / 100).toFixed(1))
if (this.$refs.FreqRange != null) {
this.$refs.FreqRange.itemChangeMin(this.FreqStop)
}
this.PointsPerDecades = String(Math.round((taskInfo.getDeviceInfo(this.deviceID).parameterSet.PPD)))
this.PointsPerDecades = String(Math.round((taskInfo.getDeviceInfo(this.deviceID).parameterSet.EIS_PPD)))
if (this.$refs.PointsPerDecades != null) {
this.$refs.PointsPerDecades.itemChange(this.PointsPerDecades)
}
@@ -75,6 +75,10 @@ export default {
type: Boolean,
default: false,
},
syncParameter: {
type: Object,
default: () => {},
},
},
created () {
},
@@ -87,6 +91,13 @@ export default {
methods: {
buttonSelectChange (value) {
this.$emit('parameterChange', this.parameterName, value)
this.syncParameter && Object.keys(this.syncParameter).forEach(element => {
if (String(element) === String(value)) {
this.syncParameter[value].forEach(element => {
this.$emit('parameterChange', element[0], element[1])
})
}
})
},
},
async mounted () {
+12 -11
View File
@@ -75,7 +75,7 @@ function sgFilter (data, windowSize, k) {
// return list
}
function sgFilterGetDifferential (data, windowSize, polynomial) {
function sgFilterGetDifferential (data, windowSize, polynomial, sampleRate = 1) {
// self
const arr = []
const m = parseInt((windowSize - 1) / 2)
@@ -96,23 +96,24 @@ function sgFilterGetDifferential (data, windowSize, polynomial) {
// use index 1 row in matrix
const rowOneInB = row(B, 1)._data[0]
const start = []
const end = []
// const start = []
// const end = []
const list = []
// eslint-disable-next-line no-unused-vars
for (const _ of range(0, m)) {
start.push(data[0])
end.push(data[data.length - 1])
}
const _data = [...start, ...data, ...end]
// for (const _ of range(0, m)) {
// start.push(data[0])
// end.push(data[data.length - 1])
// }
// const _data = [...start, ...data, ...end]
// const _data = [...data]
// m ... data_length - m - 1
for (const i of range(m, _data.length - m)) {
for (const i of range(m, data.length - m)) {
const arra = []
// -m ... 0 ... m
for (const j of range(-m, m + 1)) {
arra.push(_data[i.value + j.value])
arra.push(data[i.value + j.value])
}
let sum = 0
@@ -120,7 +121,7 @@ function sgFilterGetDifferential (data, windowSize, polynomial) {
sum += (arra[index] * rowOneInB[index])
}
list.push(sum)
list.push(sum * sampleRate)
}
return list
}
+5 -4
View File
@@ -1,7 +1,8 @@
export default {
name: 'Cali ADC - test',
parameter: ['DAC_VOLT', 'ADC_LEVEL_I_15', 'ADC_LEVEL_V_IN_15', 'ADC_DAC_CHANNEL_15'], // 這個mode用到的參數
showParameter: ['DAC_VOLT', 'ADC_LEVEL_I_15', 'ADC_LEVEL_V_IN_15', 'ADC_DAC_CHANNEL_15'], // 有要秀給user看的參數
name: 'Cali Mode - test',
parameter: ['ADC_DAC_CHANNEL_15', 'ADC_LEVEL_I_15', 'ADC_LEVEL_V_IN_15', 'DAC_LEVEL_V_OUT_15', 'DAC_VOLT_BUTTON'], // 這個mode用到的參數
showParameter: ['ADC_DAC_CHANNEL_15', 'ADC_LEVEL_I_15', 'ADC_LEVEL_V_IN_15', 'DAC_LEVEL_V_OUT_15', 'DAC_VOLT_BUTTON'], // 有要秀給user看的參數
headerParameter: () => ['ADC_DAC_CHANNEL_15', 'ADC_LEVEL_I_15', 'ADC_LEVEL_V_IN_15', 'DAC_LEVEL_V_OUT_15', 'DAC_VOLT_BUTTON'], // export header的參數
valScales: {
linear: {
func: (val) => {
@@ -52,7 +53,7 @@ export default {
charts: {
default: [
{
name: 'Cali ADC - test',
name: 'Cali Mode - test',
description: '',
subplot: [
{
@@ -58,6 +58,46 @@ export default {
defaultUnit: 'mV',
downloadUnit: 'mV',
},
3: {
name: 'sum_cnt',
unit: {
uV: 1,
mV: 1e3,
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'uV',
},
4: {
name: 'sum_adc_delta_Iin',
unit: {
uV: 1,
mV: 1e3,
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'uV',
},
5: {
name: 'sum_adc_delta_Voutin',
unit: {
uV: 1,
mV: 1e3,
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'uV',
},
6: {
name: 'resis',
unit: {
uV: 1,
mV: 1e3,
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'uV',
},
},
charts: {
default: [
@@ -45,7 +45,7 @@ export default {
downloadUnit: 'ms',
},
0: {
name: 'pul1_I_in',
name: 'I_in_pul1',
unit: {
nA: 1,
uA: 1e3,
@@ -55,7 +55,7 @@ export default {
downloadUnit: 'mA',
},
1: {
name: 'pul2_I_in',
name: 'I_in_pul2',
unit: {
nA: 1,
uA: 1e3,
+71 -4
View File
@@ -162,17 +162,24 @@ const EliteZM15 = {
options: [
{ value: 0, label: 'Iin' },
{ value: 1, label: 'Vin' },
{ value: 2, label: 'Vout' },
],
range: ['Iin', 'Vin'],
range: ['Iin', 'Vin', 'Vout'],
defaultValue: 0,
outputRawData: (val) => {
const caliChannelArr = ['Iin', 'Vin']
const caliChannelArr = ['Iin', 'Vin', 'Vout']
return caliChannelArr.indexOf(val.toString())
},
outputReadabilityData: (idx) => {
const caliChannelArr = ['Iin', 'Vin']
const caliChannelArr = ['Iin', 'Vin', 'Vout']
return caliChannelArr[parseInt(idx)]
},
syncParameter: {
0: [['ADC_LEVEL_V_IN_15', 3], ['ADC_LEVEL_I_15', 0], ['DAC_LEVEL_V_OUT_15', 2]],
1: [['ADC_LEVEL_V_IN_15', 0], ['ADC_LEVEL_I_15', 0], ['DAC_LEVEL_V_OUT_15', 2]],
2: [['ADC_LEVEL_V_IN_15', 3], ['ADC_LEVEL_I_15', 4], ['DAC_LEVEL_V_OUT_15', 0]],
},
},
VOLT_ORIGIN: {
type: 'number',
@@ -255,6 +262,26 @@ const EliteZM15 = {
},
downloadUnit: 's',
},
DAC_LEVEL_V_OUT_15: {
type: 'array',
showName: 'DAC range',
componentType: 'input-button-toggle',
options: [
{ value: 0, label: '0' },
{ value: 1, label: '1' },
{ value: 2, label: 'Auto' },
],
range: ['0', '1', 'Auto'],
defaultValue: 2,
outputRawData: (val) => {
const caliChannelArr = ['0', '1', 'Auto']
return caliChannelArr.indexOf(val.toString())
},
outputReadabilityData: (idx) => {
const caliChannelArr = ['0', '1', 'Auto']
return caliChannelArr[parseInt(idx)]
},
},
DAC_VOLT: {
type: 'number',
showName: 'Volt out',
@@ -274,6 +301,46 @@ const EliteZM15 = {
return parseInt((parseFloat(val) - 25000) / 5) / scale
},
},
DAC_VOLT_SCROLL: {
type: 'number',
showName: 'DAC code',
componentType: 'input-range',
range: Object.freeze({ min: 0, max: 60000 }),
defaultValue: 25000,
defaultUnit: '',
downloadUnit: 'mV',
unit: {
mV: 1,
V: 1e3,
},
outputRawData: (val, scale = 1) => {
return parseInt(parseFloat(val))
},
outputReadabilityData: (val, scale = 0) => {
return parseInt(parseFloat(val))
},
},
DAC_VOLT_BUTTON: {
type: 'array',
showName: 'DAC code',
componentType: 'input-button-toggle',
options: [
{ value: 0, label: '10000' },
{ value: 1, label: '25000' },
{ value: 2, label: '50000' },
{ value: 3, label: '60000' },
],
range: ['10000', '25000', '50000', '60000'],
defaultValue: 1,
outputRawData: (val) => {
const caliChannelArr = ['10000', '25000', '50000', '60000']
return caliChannelArr.indexOf(val.toString())
},
outputReadabilityData: (idx) => {
const caliChannelArr = ['10000', '25000', '50000', '60000']
return caliChannelArr[parseInt(idx)]
},
},
SAMPLE_RATE: {
type: 'number',
componentType: 'input-range',
@@ -981,7 +1048,7 @@ const EliteZM15 = {
},
{
id: 11,
description: 'Cali ADC - test',
description: 'Cali Mode - test',
img_src: 'CADC-Wire',
},
],
@@ -1,9 +1,8 @@
export default {
name: 'Potentiostatic Electrochemical Impedance Spectroscopy',
parameter: ['DC_BIAS', 'AC_AMP', 'FREQ', 'PPD', 'SCALE', 'DELAY', 'AVERAGE_NUM', 'RTIA'],
// parameter: ['DC_BIAS', 'AC_AMP', 'FREQ_START', 'FREQ_STOP', 'PPD', 'SCALE', 'DELAY', 'AVERAGE_NUM', 'RTIA'], // 這個mode用到的參數
showParameter: ['DC_BIAS', 'AC_AMP', 'FREQ_START', 'FREQ_STOP', 'PPD', 'SCALE', 'DELAY', 'AVERAGE_NUM', 'RTIA'], // 有要秀給user看的參數
headerParameter: () => ['DC_BIAS', 'AC_AMP', 'FREQ_START', 'FREQ_STOP', 'PPD', 'SCALE', 'DELAY', 'AVERAGE_NUM', 'RTIA'], // 有要秀給user看的參數
parameter: ['EIS_DC_BIAS', 'EIS_AC_AMP', 'EIS_FREQ', 'EIS_PPD', 'EIS_SCALE', 'EIS_DELAY', 'EIS_AVERAGE_NUM', 'GENERAL_HS_RTIA'], // 這個mode用到的參數
showParameter: ['EIS_DC_BIAS', 'EIS_AC_AMP', 'EIS_FREQ', 'EIS_PPD', 'EIS_SCALE', 'EIS_DELAY', 'EIS_AVERAGE_NUM', 'GENERAL_HS_RTIA'], // 有要秀給user看的參數
headerParameter: () => ['EIS_DC_BIAS', 'EIS_AC_AMP', 'EIS_FREQ', 'EIS_PPD', 'EIS_SCALE', 'EIS_DELAY', 'EIS_AVERAGE_NUM', 'GENERAL_HS_RTIA'], // 有要秀給user看的參數
valScales: {
linear: {
func: (val) => {
@@ -31,7 +30,7 @@ export default {
downloadUnit: 'ms',
},
0: {
name: 'Z_imag_Raw',
name: 'Z_Imag_Raw',
unit: {
ohm: 1,
},
@@ -65,7 +64,7 @@ export default {
// downloadUnit: null,
// },
4: {
name: 'Z_imag',
name: 'Z_Imag',
unit: {
mohm: 1e-3,
: 1e-3,
@@ -80,7 +79,7 @@ export default {
defaultUnit: 'Ω',
},
5: {
name: 'Z_real',
name: 'Z_Real',
unit: {
mohm: 1e-3,
: 1e-3,
+102
View File
@@ -0,0 +1,102 @@
export default {
name: 'R-T Graph',
parameter: ['RT_VOLT_SET', 'SAMPLE_RATE', 'CTRL_HIGH_Z_15', 'TIME_DURATION'], // 這個mode用到的參數
showParameter: ['RT_VOLT_SET', 'SAMPLE_RATE', 'CTRL_HIGH_Z_15', 'TIME_DURATION'], // 有要秀給user看的參數
headerParameter: () => ['RT_VOLT_SET', 'SAMPLE_RATE', 'ADC_LEVEL_I_15', 'ADC_LEVEL_V_IN_15', 'TIME_DURATION'], // export header的參數
valScales: {
linear: {
func: (val) => {
return val
},
},
log: {
func: (val) => {
return Math.log10(Math.abs(val))
},
},
},
channels: {
time: {
name: 'Time',
unit: {
us: 1,
ms: 1e3,
s: 1e6,
minute: 60 * 1e6,
hour: 60 * 60 * 1e6,
},
defaultUnit: 'ms',
downloadUnit: 'ms',
},
0: {
name: 'I_in',
unit: {
nA: 1,
uA: 1e3,
mA: 1e6,
},
defaultUnit: 'mA',
downloadUnit: 'mA',
},
1: {
name: 'V_out',
unit: {
uV: 1,
mV: 1e3,
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'mV',
},
2: {
name: 'Resistor',
unit: {
: 1,
mohm: 1,
Ω: 1e3,
ohm: 1e3,
: 1e6,
kohm: 1e6,
: 1e9,
Mohm: 1e9,
},
defaultUnit: 'Ω',
downloadUnit: 'ohm',
},
},
charts: {
default: [
{
name: 'R-T Graph',
description: '',
subplot: [
{
x1: {
type: 'time',
valScale: 'linear',
min: 'dataMin',
max: 'dataMax',
},
y1: {
type: 'value',
valScale: 'linear',
min: 'dataMin',
max: 'dataMax',
},
data: [
{
legend: 'RT',
x1: {
channel: 'time',
},
y1: {
channel: 2,
},
},
],
},
],
},
],
},
}
+87
View File
@@ -0,0 +1,87 @@
export default {
name: 'V-T Graph',
parameter: ['SAMPLE_RATE', 'MEASURE_VIN_RANGE', 'ADC_LEVEL_I_15', 'CTRL_HIGH_Z_15', 'TIME_DURATION'], // 這個mode用到的參數
showParameter: ['SAMPLE_RATE', 'MEASURE_VIN_RANGE', 'ADC_LEVEL_I_15', 'CTRL_HIGH_Z_15', 'TIME_DURATION'], // 有要秀給user看的參數
headerParameter: () => ['SAMPLE_RATE', 'MEASURE_VIN_RANGE', 'ADC_LEVEL_I_15', 'TIME_DURATION'], // export header的參數
valScales: {
linear: {
func: (val) => {
return val
},
},
log: {
func: (val) => {
return Math.log10(Math.abs(val))
},
},
},
channels: {
time: {
name: 'Time',
unit: {
us: 1,
ms: 1e3,
s: 1e6,
minute: 60 * 1e6,
hour: 60 * 60 * 1e6,
},
defaultUnit: 'ms',
downloadUnit: 'ms',
},
0: {
name: 'I_in',
unit: {
nA: 1,
uA: 1e3,
mA: 1e6,
},
defaultUnit: 'mA',
downloadUnit: 'mA',
},
1: {
name: 'V_in',
unit: {
uV: 1,
mV: 1e3,
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'mV',
},
},
charts: {
default: [
{
name: 'V-T Graph',
description: '',
subplot: [
{
x1: {
type: 'time',
valScale: 'linear',
min: 'dataMin',
max: 'dataMax',
},
y1: {
type: 'value',
valScale: 'linear',
min: 'dataMin',
max: 'dataMax',
},
data: [
{
legend: 'VT',
x1: {
channel: 'time',
},
y1: {
channel: 1,
},
},
],
},
],
},
],
},
}
+122 -45
View File
@@ -2,14 +2,35 @@ import PotentiostaticEIS from './PotentiostaticEIS'
import CyclicVoltammetry from './CyclicVoltammetry'
import DevMode from './DevMode'
import Chronoamperometry from './Chronoamperometry'
import VT from './VT'
import RT from './RT'
const EliteEIS = {
VOLT_VSCAN: {
type: 'number',
showName: 'Volt (v.s. ref)',
componentType: 'input-range',
range: Object.freeze({ min: 2500, max: 50000 }),
outputRawData: (val, scale = 1) => {
return parseInt(parseFloat(val) * scale * 12.5 + 25000)
},
outputReadabilityData: (val, scale = 1) => {
return parseInt((parseFloat(val) - 25000) / 12.5) / scale
},
defaultValue: 25000,
defaultUnit: 'V',
downloadUnit: 'mV',
unit: {
mV: 1,
V: 1e3,
},
},
ADC_VALUE_I: {
type: 'none',
showName: 'Instruction',
componentType: 'dev-mode',
},
DC_BIAS: {
EIS_DC_BIAS: {
type: 'number',
showName: 'DC Volt',
componentType: 'input-field',
@@ -20,6 +41,7 @@ const EliteEIS = {
outputReadabilityData: (val, scale = 1) => {
return Math.round(parseInt(val - 25000) / 12.5) / scale
},
defaultValue: 25000,
defaultUnit: 'mV',
downloadUnit: 'mV',
unit: {
@@ -27,7 +49,7 @@ const EliteEIS = {
V: 1e3,
},
},
AC_AMP: {
EIS_AC_AMP: {
type: 'number',
showName: 'AC Amp',
componentType: 'input-field',
@@ -38,62 +60,32 @@ const EliteEIS = {
outputReadabilityData: (val, scale = 1) => {
return Math.round(parseInt(val) / 2047 * 800) / scale
},
defaultValue: 25,
defaultUnit: 'mV',
downloadUnit: 'mV',
unit: {
mV: 1,
},
},
FREQ: {
EIS_FREQ: {
type: 'array',
showName: 'Frequency',
componentType: 'multi-input-field',
range: Object.freeze({ min: 1, max: 4294967296 }),
range: Object.freeze({ min: 1, max: 13333333 }),
outputRawData: (val) => {
return parseFloat(val) < 0.1 ? 1 : Math.round(parseFloat(val) / 0.0149)
return parseFloat(val) < 0.1 ? Math.round(0.1 / 0.015) : Math.round(parseFloat(val) / 0.015)
},
outputReadabilityData: (val) => {
return String(parseFloat(Math.round(parseFloat((val * 0.0149) * 100)) / 100).toFixed(1)) === '0.0' ? 0.015 : parseFloat(Math.round(parseFloat((val * 0.0149) * 100)) / 100).toFixed(1)
return (parseFloat(val) * 0.015).toFixed(1)
},
defaultValue: [13333333, 7],
defaultUnit: 'Hz',
downloadUnit: 'Hz',
unit: {
Hz: 1,
},
},
FREQ_START: {
type: 'number',
showName: 'Freq max',
range: Object.freeze({ min: 0.015, max: 200000 }),
outputRawData: (val) => {
return parseFloat(val) < 0.1 ? 1 : Math.round(parseFloat(val) / 0.0149)
},
outputReadabilityData: (val) => {
return String(parseFloat(Math.round(parseFloat((val * 0.0149) * 100)) / 100).toFixed(1)) === '0.0' ? 0.015 : parseFloat(Math.round(parseFloat((val * 0.0149) * 100)) / 100).toFixed(1)
},
defaultUnit: 'Hz',
downloadUnit: 'Hz',
unit: {
Hz: 1,
},
},
FREQ_STOP: {
type: 'number',
showName: 'Freq min',
range: Object.freeze({ min: 0.015, max: 200000 }),
outputRawData: (val) => {
return parseFloat(val) < 0.1 ? 1 : Math.round(parseFloat(val) / 0.0149)
},
outputReadabilityData: (val) => {
return String(parseFloat(Math.round(parseFloat((val * 0.0149) * 100)) / 100).toFixed(1)) === '0.0' ? 0.015 : parseFloat(Math.round(parseFloat((val * 0.0149) * 100)) / 100).toFixed(1)
},
defaultUnit: 'Hz',
downloadUnit: 'Hz',
unit: {
Hz: 1,
},
},
PPD: {
EIS_PPD: {
type: 'number',
showName: 'Points per decades',
componentType: 'input-field',
@@ -104,13 +96,14 @@ const EliteEIS = {
outputReadabilityData: (val) => {
return parseInt(val)
},
defaultValue: 10,
defaultUnit: 'points',
downloadUnit: null,
unit: {
points: 1,
},
},
SCALE: {
EIS_SCALE: {
type: 'array',
showName: 'Point spacing',
componentType: 'input-button-toggle',
@@ -119,6 +112,7 @@ const EliteEIS = {
{ value: 1, label: 'Linear' },
],
range: ['Logarithm', 'Linear'],
defaultValue: 0,
outputRawData: (val) => {
const scaleArr = ['Logarithm', 'Linear']
return scaleArr.indexOf(val.toString())
@@ -128,24 +122,25 @@ const EliteEIS = {
return scaleArr[parseInt(idx)]
},
},
DELAY: {
EIS_DELAY: {
type: 'number',
showName: 'DELAY',
componentType: 'input-field',
range: Object.freeze({ min: 1, max: 100 }),
range: Object.freeze({ min: 0, max: 100 }),
outputRawData: (val) => {
return parseInt(parseFloat(val) * 10)
},
outputReadabilityData: (val) => {
return parseFloat((val / 10)).toFixed(1)
},
defaultValue: 0,
defaultUnit: 'points',
downloadUnit: null,
unit: {
points: 1,
},
},
AVERAGE_NUM: {
EIS_AVERAGE_NUM: {
type: 'array',
showName: 'Average',
componentType: 'input-button-toggle',
@@ -156,6 +151,7 @@ const EliteEIS = {
{ value: 3, label: '8' },
],
range: ['2', '4', '6', '8'],
defaultValue: 3,
outputRawData: (val) => {
const numArr = ['2', '4', '6', '8']
return numArr.indexOf(val.toString())
@@ -165,7 +161,7 @@ const EliteEIS = {
return numArr[parseInt(idx)]
},
},
RTIA: {
GENERAL_HS_RTIA: {
type: 'array',
showName: 'Current range',
componentType: 'input-button-toggle',
@@ -177,6 +173,7 @@ const EliteEIS = {
{ value: 4, label: 'Auto' },
],
range: ['1', '2', '3', '4', 'Auto'],
defaultValue: 4,
outputRawData: (val) => {
const numArr = ['1', '2', '3', '4', 'Auto']
return numArr.indexOf(val.toString())
@@ -198,6 +195,7 @@ const EliteEIS = {
{ value: 4, label: 'Auto' },
],
range: ['<1.5 uA', '1-60 uA', '40-175 uA', '>120 uA', 'Auto'],
defaultValue: 4,
outputRawData: (val) => {
const currentRangeArr = ['<1.5 uA', '1-60 uA', '40-175 uA', '>120 uA', 'Auto']
return currentRangeArr.indexOf(val.toString())
@@ -218,6 +216,7 @@ const EliteEIS = {
{ value: 3, label: 'Auto' },
],
range: ['1', '2', '3', 'Auto'],
defaultValue: 3,
outputRawData: (val) => {
const voltageInRangeArr = ['1', '2', '3', 'Auto']
return voltageInRangeArr.indexOf(val.toString())
@@ -227,6 +226,48 @@ const EliteEIS = {
return voltageInRangeArr[parseInt(idx)]
},
},
MEASURE_VIN_RANGE: {
type: 'array',
showName: 'Vin Range',
componentType: 'input-button-toggle',
options: [
{ value: 0, label: '0~2V' },
{ value: 1, label: '-1~1V' },
{ value: 2, label: '-2~0V' },
{ value: 3, label: 'Auto' },
],
range: ['1', '2', '3', 'Auto'],
defaultValue: 0,
outputRawData: (val) => {
const voltageInRangeArr = ['1', '2', '3', 'Auto']
return voltageInRangeArr.indexOf(val.toString())
},
outputReadabilityData: (idx) => {
const voltageInRangeArr = ['1', '2', '3', 'Auto']
return voltageInRangeArr[parseInt(idx)]
},
},
TIME_DURATION: {
type: 'number',
showName: 'Time duration',
componentType: 'input-range',
range: Object.freeze({ min: 0, max: 86400 }), // UI上能輸入的最大最小值
defaultValue: 0,
defaultUnit: 's',
downloadUnit: 's',
unit: {
ms: 1e-3,
s: 1,
m: 60,
h: 3600,
},
outputRawData: (val) => {
return parseInt(parseFloat(val))
},
outputReadabilityData: (val) => {
return parseInt(parseFloat(val))
},
},
CTRL_HIGH_Z_15: {
type: 'array',
showName: 'HighZ',
@@ -236,6 +277,7 @@ const EliteEIS = {
{ value: 1, label: 'Off' },
],
range: ['On', 'Off'],
defaultValue: 1,
outputRawData: (val) => {
const highzArr = ['On', 'Off']
return highzArr.indexOf(val.toString())
@@ -256,6 +298,7 @@ const EliteEIS = {
outputReadabilityData: (val, scale = 1) => {
return parseInt((parseFloat(val) - 25000) / 12.5) / scale
},
defaultValue: 25000,
defaultUnit: 'V',
downloadUnit: 'mV',
unit: {
@@ -274,6 +317,7 @@ const EliteEIS = {
outputReadabilityData: (val, scale = 1) => {
return parseInt((parseFloat(val) - 25000) / 12.5) / scale
},
defaultValue: 25000,
defaultUnit: 'V',
downloadUnit: 'mV',
unit: {
@@ -292,6 +336,7 @@ const EliteEIS = {
outputReadabilityData: (val, scale = 1) => {
return parseInt((parseFloat(val) - 25000) / 12.5) / scale
},
defaultValue: 25000,
defaultUnit: 'V',
downloadUnit: 'mV',
unit: {
@@ -310,6 +355,7 @@ const EliteEIS = {
outputReadabilityData: (val) => {
return parseFloat(val) / 100
},
defaultValue: 10000,
defaultUnit: 'mV/s',
downloadUnit: 'mV/s',
unit: {
@@ -327,6 +373,7 @@ const EliteEIS = {
outputReadabilityData: (val, scale = 1) => {
return parseFloat(val) / 10
},
defaultValue: 1000,
defaultUnit: 'sps',
downloadUnit: 'sps',
unit: {
@@ -344,12 +391,32 @@ const EliteEIS = {
outputReadabilityData: (val) => {
return parseInt(val)
},
defaultValue: 1,
defaultUnit: 'cycle',
downloadUnit: null,
unit: {
cycle: 1,
},
},
RT_VOLT_SET: {
type: 'number',
showName: 'Volt out',
componentType: 'input-range',
range: Object.freeze({ min: 2500, max: 50000 }),
defaultValue: 37500,
defaultUnit: 'V',
downloadUnit: 'mV',
unit: {
mV: 1,
V: 1e3,
},
outputRawData: (val, scale = 1) => {
return parseInt(parseFloat(val) * scale * 12.5 + 25000)
},
outputReadabilityData: (val, scale = 1) => {
return parseInt((parseFloat(val) - 25000) / 12.5) / scale
},
},
MODE_OPTIONS: [
{
@@ -366,6 +433,14 @@ const EliteEIS = {
},
{
id: 3,
description: 'VT',
},
{
id: 4,
description: 'RT',
},
{
id: 5,
description: 'Dev Tools',
},
],
@@ -373,7 +448,9 @@ const EliteEIS = {
0: PotentiostaticEIS,
1: CyclicVoltammetry,
2: Chronoamperometry,
3: DevMode,
3: VT,
4: RT,
5: DevMode,
},
}
+12 -1
View File
@@ -1,14 +1,17 @@
import EliteEDC from './EliteEDC/index'
import EliteEIS from './EliteEIS/index'
import store from '@/store/index'
// object saving library name mapping table
const libraryNameMappingTable = {
EDC: EliteEDC,
EliteZM15: EliteEDC,
'Elite_EDC_1.4': null,
'Elite_EDC_1.5': EliteEDC,
'Elite_EDC_1.5re': EliteEDC,
'Elite_EDC_1.5r2': EliteEDC,
'Elite_BAT_1.0': EliteEDC,
EIS: EliteEIS,
'Elite_EIS_1.0': EliteEIS,
'Elite_EIS_1.1': EliteEIS,
'Elite_EIS_MINI_1.0': EliteEIS,
@@ -53,11 +56,19 @@ const serialNumberMappingTable = {
}
/**
* return config table by libray or serial number (type)
* return config table by library or serial number (type)
* @param {String | Object} type
* @returns {Object} : config
*/
function getConfig (type) {
if (typeof type === 'number') {
const deviceList = store.getters.getField('taskContent').deviceListNew
if (deviceList === undefined) return
const device = deviceList.find(ele => ele.memory_board === type)
if (device === undefined) return
return libraryNameMappingTable[device.library_name]
}
// library name
if (typeof type === 'string') {
return libraryNameMappingTable[type]
-1
View File
@@ -143,7 +143,6 @@ export const getFileInfoFormat = () => {
ADC_LEVEL: 0,
ADC_VALUE_I: 0,
ADC_VALUE_V: 0,
CHANNEL_LABEL: [],
CURRNET_LIMIT_VALUE: 1500000,
CYCLE_NUMBER: 0,
Charge: 1,
+29 -1
View File
@@ -1,4 +1,7 @@
/* eslint-disable no-undef */
import { v4 as uuidv4 } from 'uuid'
import localforage from 'localforage'
import { taskInfo } from '@/data/task/TaskInfo'
const TaskTotalSettingView = false
@@ -47,7 +50,9 @@ const getDefaultChartTypeByMode = (mode, lib) => {
const settings = {}
settings[0] = ['EliteEIS', 6, 'EliteEIS', 5]
settings[1] = ['Elite', 2, 'Elite', 1]
settings[2] = ['Time', 2, 'Elite', 2]
settings[2] = ['Time', 2, 'Elite', 1]
settings[3] = ['Time', 2, 'Elite', 2]
settings[4] = ['Time', 2, 'Elite', 3]
return settings[mode]
} else if (lib === 'Elite_TRI') {
// const settings = {}
@@ -141,6 +146,28 @@ const objectFilter = function (mainObject, filterFunction) {
.reduce((cur, key) => { return Object.assign(cur, { [key]: mainObject[key] }) }, {})
}
const refreshCache = async () => {
const checkRet = await checkControllerID()
const checkRet1 = await checkVersion()
if (checkRet && checkRet1) return
window.location.reload(true)
}
async function checkControllerID () {
const controllerID = await localforage.getItem('controllerID')
if (taskInfo.getTaskInfo().controllerID === undefined) return true
if (controllerID === taskInfo.getTaskInfo().controllerID) return true
localforage.setItem('controllerID', taskInfo.getTaskInfo().controllerID)
return false
}
async function checkVersion () {
const version = await localforage.getItem('version')
if (version === COMMIT) return true
localforage.setItem('version', COMMIT)
return false
}
export default
{
hasCycleMode,
@@ -155,4 +182,5 @@ export default
ChannelMaxNumber,
getUUID,
objectFilter,
refreshCache,
}
+10 -9
View File
@@ -1,4 +1,4 @@
import { tableRouter } from '@/components/analysis/replay/toolbox/EliteReplayTable'
import configRouter from '@/components/analysis/replay/toolbox/configTable'
function getTime (val) {
let label = ''
@@ -44,9 +44,10 @@ function newTooltip (controlPanel) {
let value // value on cursor
const param = params[0]// find coressonding parameter to the channel
const style = 'color: ' + param.color
const [xTable, yTable] = tableRouter.getTable(controlPanel.x.type, controlPanel.x.funct, controlPanel.y.type, controlPanel.y.funct) // unit is store in this object
const xScale = configRouter.getUnitScale(controlPanel.x.axis.description)
const yScale = configRouter.getUnitScale(controlPanel.y.axis.description)
// (Default) Time
if (controlPanel.x.type === 'Time') {
if (controlPanel.x.axis.description === 'Time') {
value = getTime(parseFloat(param.value[0]))
} else {
value = getTime(parseFloat(param.value[2]))
@@ -54,13 +55,13 @@ function newTooltip (controlPanel) {
tip += '<span style="color: #000000">' + 'Time: ' + value + '</span><br>'
// (Manual) Voltage, Current, Resistance
tip += '<span style="' + style + '">' + param.seriesName + ':<ul style = "list-style-type: disc; list-style-position: inside">'
if (controlPanel.x.type !== 'Time') {
value = parseFloat(param.value[0] / xTable.option[controlPanel.x.unit]).toFixed(3) + ' ' + controlPanel.x.unit
tip += '<li>' + xTable.name + ' = ' + value + '</li>'
if (controlPanel.x.axis.description !== 'Time') {
value = parseFloat(param.value[0] / xScale[controlPanel.x.unit]).toFixed(3) + ' ' + controlPanel.x.unit
tip += '<li>' + controlPanel.x.axis.description + ' = ' + value + '</li>'
}
if (controlPanel.y.type !== 'Time') {
value = parseFloat(param.value[1] / yTable.option[controlPanel.y.unit]).toFixed(3) + ' ' + controlPanel.y.unit
tip += '<li>' + yTable.name + ' = ' + value + '</li>'
if (controlPanel.y.axis.description !== 'Time') {
value = parseFloat(param.value[1] / yScale[controlPanel.y.unit]).toFixed(3) + ' ' + controlPanel.y.unit
tip += '<li>' + controlPanel.y.axis.description + ' = ' + value + '</li>'
}
tip += '</ul></span>'
+2 -2
View File
@@ -62,11 +62,11 @@ function newTooltip (realTime, dataMode) {
tip += '<span style="' + style + '">' + param.seriesName + ':<ul style = "list-style-type: disc; list-style-position: inside">'
if (unitTable.xName !== 'Time') {
value = parseFloat(param.value[0] / unitTable.xScale[unitTable.xUnit]).toFixed(3) + ' ' + unitTable.xUnit
value = parseFloat(param.value[0] / unitTable.xScaleOption[unitTable.xUnit]).toFixed(3) + ' ' + unitTable.xUnit
tip += '<li>' + unitTable.xName + ' = ' + value + '</li>'
}
if (unitTable.yName !== 'Time') {
value = parseFloat(param.value[1] / unitTable.yScale[unitTable.yUnit]).toFixed(3) + ' ' + unitTable.yUnit
value = parseFloat(param.value[1] / unitTable.yScaleOption[unitTable.yUnit]).toFixed(3) + ' ' + unitTable.yUnit
tip += '<li>' + unitTable.yName + ' = ' + value + '</li>'
}
tip += '</ul></span>'
+3 -1
View File
@@ -1,7 +1,9 @@
function newActionTemplate () {
return [
'start',
// 'start',
'stop',
// 'cycle',
'idle',
]
}
+50 -18
View File
@@ -26,7 +26,7 @@ function newConditionTemplate (action) {
select: false,
type: 'hidden',
prefix: 'When previous task done',
suffix: 'done',
suffix: '',
value: '',
},
// device: {
@@ -45,25 +45,25 @@ function newConditionTemplate (action) {
// },
},
stop: {
absolute_time: {
select: false,
type: 'datetime-local',
prefix: 'At',
suffix: '',
value: '',
},
after_project_run: {
select: false,
type: 'text',
prefix: 'After project run',
suffix: 'secs',
value: '',
},
// absolute_time: {
// select: false,
// type: 'datetime-local',
// prefix: 'At',
// suffix: '',
// value: '',
// },
// after_project_run: {
// select: false,
// type: 'text',
// prefix: 'After project run',
// suffix: 'secs',
// value: '',
// },
after_task_run: {
select: false,
select: true,
type: 'text',
prefix: 'After task run',
suffix: 'secs',
prefix: 'when task run for',
suffix: 'seconds',
value: '',
},
// task: {
@@ -88,6 +88,38 @@ function newConditionTemplate (action) {
// value: '',
// },
},
// cycle: {
// cycle_next: {
// select: false,
// type: 'text',
// prefix: 'Cycle next go to:',
// suffix: '',
// value: '',
// },
// cycle: {
// select: false,
// type: 'text',
// prefix: 'Run',
// suffix: 'times',
// value: '0',
// },
// },
idle: {
after_task_run: {
select: false,
type: 'text',
prefix: 'for',
suffix: 'secs',
value: '',
},
until_button_trigger: {
select: false,
type: 'hidden',
prefix: 'until button press',
suffix: '',
value: '',
},
},
}
}
+5 -4
View File
@@ -1,10 +1,11 @@
function newDevice (uuid = '', name = '', product = 0, library = 0, connectDevice = {}) {
function newDevice (order = -1, name = '', library = '', device = null) {
return {
order: order,
name: name,
product: product,
library: library,
uuid: uuid,
connectDevice: connectDevice,
pair: device,
pairStatus: -1,
locked: false,
isSelect: [],
}
}
@@ -61,7 +61,7 @@ function newAction () {
},
{
id: 11,
description: 'Cali ADC - test',
description: 'Cali Mode - test',
select: false,
},
{
@@ -54,7 +54,7 @@ function newEliteZm15Parameter () {
// },
// {
// id: 11,
// description: 'Cali ADC - test',
// description: 'Cali Mode - test',
// },
// {
// id: 12,
+2 -1
View File
@@ -3,10 +3,11 @@ function newProject (name, uuid) {
name: name,
desc: '',
task: [],
device: [],
device: {},
uuid: uuid,
select: false,
status: -1,
cycle: [],
}
}
+5 -2
View File
@@ -1,9 +1,9 @@
function newTask (name, uuid) {
function newTask (name, uuid, type = '') {
return {
id: -1,
name: name,
next: [],
type: '',
type: type,
desc: '',
device: [],
action: {},
@@ -12,6 +12,9 @@ function newTask (name, uuid) {
select: false,
status: -1,
cycle: -1,
cycle_count: 0,
cycle_next: '',
cycle_next_uuid: '',
uuid: uuid,
}
}
+7 -10
View File
@@ -162,7 +162,6 @@ function newParameterSet () {
ADC_LEVEL: 0,
ADC_VALUE_I: 0,
ADC_VALUE_V: 0,
CHANNEL_LABEL: [],
CURRNET_LIMIT_VALUE: 1500000,
CYCLE_NUMBER: 0,
Charge: 1,
@@ -231,15 +230,13 @@ function newParameterSet () {
DPV_mode: 0, // Auto / Advanced / Engineering
DPV_engineering_enable: 0,
// Elite EIS
FREQ_START: 0,
FREQ_STOP: 0,
DELAY: 1,
AVERAGE_NUM: 2,
DC_BIAS: 0,
AC_AMP: 0,
SCALE: 0,
PPD: 0,
RTIA: 0,
EIS_DC_BIAS: 0,
EIS_AC_AMP: 0,
EIS_PPD: 0,
EIS_SCALE: 0,
EIS_DELAY: 1,
EIS_AVERAGE_NUM: 2,
GENERAL_HS_RTIA: 0,
// Elite Trigger
ACC_a_out0: 0,
ACC_a_out0_current: 0,
@@ -1,5 +1,5 @@
import types from '@/store/modules/analysis/replay/types'
import { tableRouter } from '@/components/analysis/replay/toolbox/EliteReplayTable'
import configRouter from '@/components/analysis/replay/toolbox/configTable'
const typePath = types.chart
@@ -91,6 +91,30 @@ function getLegendName (sourceList) {
return legendName
}
function autoTimeFormatter (val) {
let label = ''
const hour = parseInt(val / 3.6e9)
const minute = parseInt((val % 3.6e9) / 1000000 / 60)
const second = parseInt((val % 6e7) / 1000000)
const millisecond = parseInt((val % 1e6) / 1000)
if (hour > 0) {
label += hour + ' h '
}
if (minute > 0) {
label += minute + ' m '
}
if (second > 0) {
label += second + ' s '
}
if (millisecond > 0) {
label += millisecond + ' ms '
}
if (hour === 0 && minute === 0 && second === 0 && millisecond === 0) {
label += ' 0 ms '
}
return label
}
const chartMutations = {
/**
* update label formatter
@@ -166,33 +190,20 @@ const chartMutations = {
// return label
// }
// }
// tang: try here
[typePath.updateAxisLabel]: (state, payload) => {
let axisLabel
let unitScale
const unit = state.controlPanel[payload.axis].unit
const [xTable, yTable] = tableRouter.getTable(state.controlPanel.x.type, state.controlPanel.x.funct, state.controlPanel.y.type, state.controlPanel.y.funct)
if (payload.axis === 'x') {
axisLabel = state.chartData[payload.chartID].xAxis[payload.axisIndex].axisLabel
unitScale = xTable.option[unit]
} else {
axisLabel = state.chartData[payload.chartID].yAxis[payload.axisIndex].axisLabel
unitScale = yTable.option[unit]
}
const unitScale = configRouter.getUnitScale(payload.type)
const axisLabel = state.chartData[payload.chartID][payload.axis + 'Axis'][payload.axisIndex].axisLabel
const _axisLabel = JSON.parse(JSON.stringify(axisLabel))
if (unit === 'auto') {
_axisLabel.formatter = tableRouter.autoTimeFormatter
_axisLabel.formatter = autoTimeFormatter
} else {
_axisLabel.formatter = function (val) {
const label = (val / unitScale).toFixed(3) + unit
const label = (val / unitScale[unit]).toFixed(3) + unit
return label
}
}
if (payload.axis === 'x') {
state.chartData[payload.chartID].xAxis[payload.axisIndex].axisLabel = _axisLabel
} else {
state.chartData[payload.chartID].yAxis[payload.axisIndex].axisLabel = _axisLabel
}
state.chartData[payload.chartID][payload.axis + 'Axis'][payload.axisIndex].axisLabel = _axisLabel
},
/**
+3 -4
View File
@@ -37,17 +37,16 @@ function newState () {
isLockDataZoom: false,
controlPanel: {
x: {
type: null,
channel: null,
axis: null,
unit: null,
funct: null,
},
y: {
type: null,
channel: null,
axis: null,
unit: null,
funct: null,
},
FSM: {},
},
}
}
@@ -60,7 +60,7 @@ const exportActs = {
const parameterValue = [modeObj.name]
const outputValue = []
Object.keys(meta.parameter_set).sort().forEach(key => {
if (!['BLE_WRITE', 'CHANNEL', 'CHANNEL_LABEL'].includes(key)) {
if (!['BLE_WRITE', 'CHANNEL'].includes(key)) {
parameterName.push(key)
parameterValue.push(meta.parameter_set[key])
}
+137 -17
View File
@@ -1,6 +1,8 @@
import types from '@/store/modules/project/types'
import newProject from '@/factories/project/projectFactory'
import newDevice from '@/factories/project/deviceFactory'
import { v4 as uuidv4 } from 'uuid'
import Vue from 'vue'
const typePath = types.project
@@ -26,6 +28,14 @@ const projectActs = {
* @param {}
*/
[typePath.init]: async ({ state, getters, commit }, payload) => {
state.projectSelectIndex = -1
state.taskSelectKey = ''
state.deviceSelectKey = ''
state.lockMode = false
state.taskViewPanel = {
show: false,
type: '',
}
},
/**
* create project
@@ -67,7 +77,11 @@ const projectActs = {
[typePath.select]: async ({ state, getters, commit }, payload) => {
state.projectSelectIndex = payload.index
// initial default device library
state.projectLibrary = state.projectList[payload.index].device[0]?.library.value
if (typeof state.projectList[payload.index].device[0]?.library === 'object') {
state.projectLibrary = state.projectList[payload.index].device[0]?.library.value
} else {
state.projectLibrary = state.projectList[payload.index].device[0]?.library
}
},
/**
@@ -80,25 +94,56 @@ const projectActs = {
await api.project.update(project.id, { deleted: true })
await api.project.del()
state.projectList.splice(index, 1)
state.projectSelectIndex = -1
return true
},
/**
* delete device
*
* @param {number} deviceIndex
*/
[typePath.copy]: async ({ state, getters, commit }, payload) => {
const { project, api } = payload
const copyProject = JSON.parse(JSON.stringify(project))
copyProject.name += ' copy'
copyProject.uuid = uuidv4()
// create project need to remove
delete copyProject.id
const response = await api.project.create(copyProject)
copyProject.id = response.data.id
state.projectList.push(copyProject)
},
/**
* register device
*
* @param {object} device
*/
[typePath.addDevice]: async ({ state, getters, commit }, payload) => {
const { device } = payload
// console.log(getters.getSelectProject.device)
let flag = false
for (const eachDevice of getters.getSelectProject.device) {
if (device.connectDevice.mac_address === eachDevice.connectDevice.mac_address) {
flag = true
break
}
}
if (!flag) getters.getSelectProject.device.push(device)
[typePath.appendDevice]: async ({ state, getters, commit }, payload) => {
const { key, device } = payload
Vue.set(getters.getSelectProject.device, key, device)
return true
},
/**
* create device
*
* @param {object} device
*/
[typePath.createDevice]: async ({ state, getters, commit, dispatch }, payload) => {
const { name, library, pair, pairStatus, order } = payload
const uuid = uuidv4()
const device = newDevice()
device.name = name
device.library = library
device.pair = pair
device.order = order
if (pairStatus) device.pairStatus = pairStatus
await dispatch(typePath.appendDevice, { key: uuid, device: device })
return true
},
/**
@@ -121,20 +166,95 @@ const projectActs = {
[typePath.setDevice]: async ({ state, getters, commit }, payload) => {
const { device, index } = payload
const deviceList = getters.getSelectProject.device
deviceList[index] = device
if (index) {
deviceList[index] = device
return true
}
deviceList.push(device)
return true
},
/**
* delete device
*
* @param {number} deviceIndex
* @param {string} deviceKey
* @param {string} macAddress
*/
[typePath.deleteDevice]: async ({ state, getters, commit }, payload) => {
const { deviceIndex } = payload
getters.getSelectProject.device.splice(deviceIndex, 1)
[typePath.deleteDevice]: async ({ state, getters, commit, dispatch }, payload) => {
const { deviceKey } = payload
// delete project register device
if (deviceKey) {
Vue.delete(getters.getSelectProject.device, deviceKey)
}
// delete task device
await dispatch('deleteDeviceTask', { deviceKey: deviceKey })
return true
},
/**
* find devices that is connected but not register in project
*
* @param {string} library
*/
[typePath.checkNotRegisterDevice]: async ({ state, getters, commit }, payload) => {
const library = payload.library
const deviceList = []
const connectedDevices = state.deviceConnectList
const registeredDevices = getters.getSelectProject?.device
// if there is not connect device then return
if (connectedDevices.length === 0) return deviceList
// if there is registered device, need to remove cause duplicate device
if (registeredDevices) {
for (const device of connectedDevices) {
if (Object.values(registeredDevices).findIndex(ele => {
return ele.pair === device.mac_address
}) === -1) {
// if no metion which library
if (library === undefined) {
deviceList.push({ macAddress: device.mac_address, library: device.library_name })
}
// if library is assign then need to be same library
if (library && device.library_name.includes(library)) {
deviceList.push({ macAddress: device.mac_address, library: device.library_name })
}
}
}
}
return deviceList
},
/**
* find devices that is register in project but not connected
*
* @param {number} deviceIndex
*/
[typePath.checkPairDeviceExist]: async ({ state, getters, commit, dispatch }, payload) => {
const deviceList = getters.getSelectProject.device
// check project each device is connected(exist) or not
for (const device in deviceList) {
const _device = deviceList[device]
_device.pairStatus = 0
let deviceExist = false
for (const connectDevice of state.deviceConnectList) {
if (deviceList[device].pair === connectDevice.mac_address) {
_device.pairStatus = 1
deviceExist = true
}
}
// if not exist then check if there is connected device is idle and not register in project
if (deviceExist === false) {
const passDevice = await dispatch(typePath.checkNotRegisterDevice, { library: deviceList[device].library })
if (passDevice.length > 0) {
_device.pairStatus = 1
deviceList[device].pair = passDevice[0].macAddress
}
if (passDevice.length === 0) {
_device.pairStatus = 0
}
}
}
},
}
export default projectActs
+197 -19
View File
@@ -1,6 +1,8 @@
import types from '@/store/modules/project/types'
import newTask from '@/factories/project/taskFactory'
import { v4 as uuidv4 } from 'uuid'
import global from '@/data/global/global.js'
import Vue from 'vue'
const typePath = types.task
@@ -17,33 +19,147 @@ const taskActs = {
*
* @param {}
*/
[typePath.create]: async ({ state, getters, commit }, payload) => {
[typePath.create]: async ({ state, getters, commit, dispatch }, payload) => {
const selectProject = getters.getSelectProject
const name = `task${(selectProject.task.length + 1)}`
const uuid = uuidv4()
const task = newTask(name, uuid)
const prevTask = getters.getTask(selectProject.task.length - 1)
prevTask && prevTask.next.push(uuid)
// check device needs to add auto
if (Object.keys(getters.getSelectProject.device).length === 1) {
task.device.push(Object.keys(getters.getSelectProject.device)[0])
}
selectProject.task.push(task)
dispatch(typePath.insert, { project: selectProject, task: task, index: selectProject.task.length })
},
/**
* select task
*
* @param {}
*/
[typePath.select]: async ({ state, getters, commit }, payload) => {
[typePath.createCycle]: async ({ state, getters, commit, dispatch }, payload) => {
const { cycleInfo } = payload
const selectProject = getters.getSelectProject
const start = cycleInfo.start.id
const end = cycleInfo.end.id + 1
const max = cycleInfo.cycle
const useID = cycleInfo.useID
const id = cycleInfo.id
const count = 1
const cycleLength = selectProject.cycle.length + 1
const name = 'Loop' + cycleLength
// create start & end task
const taskStartUUID = global.getUUID()
const taskEndUUID = global.getUUID()
const taskStart = newTask(name, taskStartUUID, 'cycle')
const taskEnd = newTask(name, taskEndUUID, 'cycle')
// create action
const fakeStartActionUUID = global.getUUID()
const fakeAction = await dispatch(typePath.createAction, { uuid: fakeStartActionUUID, action: 'cycle', target: null })
// create start condition
const conditionUUID = global.getUUID()
const newCondition = await dispatch(typePath.createCondition, { uuid: conditionUUID, condition: 'previous_task_done', compOp: 'equal', value: '' })
taskStart.condition = Object.assign({}, taskStart.condition, newCondition)
taskEnd.condition = Object.assign({}, taskEnd.condition, newCondition)
// create stop condition
const conditionUUID1 = global.getUUID()
let newCondition1
if (!useID) {
newCondition1 = await dispatch(typePath.createCondition, { uuid: conditionUUID1, condition: 'after_task_run', compOp: 'equal', value: '0' })
} else {
newCondition1 = await dispatch(typePath.createCondition, { uuid: conditionUUID1, condition: 'until_button_trigger', compOp: 'equal', value: '' })
}
taskStart.condition = Object.assign({}, taskStart.condition, newCondition1)
const conditionUUID2 = global.getUUID()
const newCondition2 = await dispatch(typePath.createCondition, { uuid: conditionUUID2, condition: 'after_task_run', compOp: 'equal', value: '0' })
taskEnd.condition = Object.assign({}, taskEnd.condition, newCondition2)
// assign action & condition
fakeAction[fakeStartActionUUID].condition.push(conditionUUID)
fakeAction[fakeStartActionUUID].condition.push(conditionUUID1)
fakeAction[fakeStartActionUUID].condition.push(conditionUUID2)
taskStart.action = Object.assign({}, taskStart.action, fakeAction)
taskEnd.action = Object.assign({}, taskEnd.action, fakeAction)
taskStart.next.push(await dispatch(typePath.get, { project: selectProject, index: start, attribute: 'uuid' }))
await dispatch(typePath.insert, { project: selectProject, task: taskEnd, index: end })
await dispatch(typePath.insert, { project: selectProject, task: taskStart, index: start })
await dispatch(typePath.rearrange, { project: selectProject })
selectProject.cycle.push({
id: id,
name: name,
range: [taskStartUUID, taskEndUUID],
max: max,
count: count,
useID: useID,
})
},
/**
* save task
*
* @param {}
*/
[typePath.save]: async ({ state, getters, commit }, payload) => {
[typePath.insert]: async ({ state, getters, commit }, payload) => {
const { project, task, index } = payload
project.task.splice(index, 0, task)
if (index !== 0) {
project.task[index - 1].next.length = 0
project.task[index - 1].next.push(task.uuid)
}
if (index !== project.task.length - 1) {
task.next.length = 0
task.next.push(project.task[index + 1].uuid)
}
},
[typePath.copy]: async ({ state, getters, commit, dispatch }, payload) => {
const { project, index } = payload
const copyTask = JSON.parse(JSON.stringify(project.task[index]))
copyTask.name += '-copy'
copyTask.uuid = uuidv4()
project.task.push(copyTask)
await dispatch(typePath.rearrange, { project: project })
},
[typePath.get]: async ({ state, getters, commit }, payload) => {
const { project, index, attribute } = payload
if (attribute) return project.task[index][attribute]
return project.task[index]
},
[typePath.getIndex]: ({ state, getters, commit }, payload) => {
const { project, uuid } = payload
return project.task.findIndex(ele => ele.uuid === uuid)
},
[typePath.swap]: async ({ state, getters, commit, dispatch }, payload) => {
const { project, originIndex, newIndex } = payload
// if swap to higher index insert first then delete
if (originIndex < newIndex) {
const task = project.task[originIndex]
project.task.splice(newIndex, 0, task)
await dispatch(typePath.delete, { project: project, index: originIndex })
}
// if swap to lower index delete first then insert
if (originIndex > newIndex) {
const task = project.task[originIndex]
await dispatch(typePath.delete, { project: project, index: originIndex })
project.task.splice(newIndex, 0, task)
}
await dispatch(typePath.rearrange, { project: project })
return true
},
[typePath.rearrange]: async ({ state, getters, commit, dispatch }, payload) => {
const { project } = payload
project.task = project.task.filter(ele => ele !== undefined)
for (const idx in project.task) {
project.task[idx].next.length = 0
if (Number(idx) === Number(project.task.length - 1)) return
project.task[idx].next.push(project.task[Number(idx) + 1].uuid)
}
},
/**
@@ -51,9 +167,38 @@ const taskActs = {
*
* @param {}
*/
[typePath.delete]: async ({ state, getters, commit }, payload) => {
const selectProject = getters.getSelectProject
selectProject.task.splice(payload.index, 1)
[typePath.delete]: async ({ state, getters, commit, dispatch }, payload) => {
const { project, index } = payload
project.task.splice(index, 1)
await dispatch(typePath.rearrange, { project: project })
},
/**
* delete task
*
* @param {}
*/
[typePath.deleteDevice]: async ({ state, getters, commit, dispatch }, payload) => {
const { deviceKey } = payload
for (const task of getters.getSelectProject.task) {
// delete task device
task.device = task.device.filter(ele => ele !== deviceKey)
// delete task action & condition
for (const [key, value] of Object.entries(task.action)) {
if (value.target === deviceKey) {
for (const condition of value.condition) {
Vue.delete(task.action, condition)
}
Vue.delete(task.action, key)
}
}
// delete task parameter
for (const [key, value] of Object.entries(task.parameter_set)) {
if (value.target === deviceKey) {
Vue.delete(task.parameter_set, key)
}
}
}
},
/**
@@ -76,6 +221,18 @@ const taskActs = {
task.action = Object.assign({}, task.action, payload.action)
},
/**
* set task cycle
*
* @param {}
*/
[typePath.setCycle]: async ({ state, getters, commit }, payload) => {
const task = getters.getSelectTask
task.cycle = payload.cycle
task.cycle_next = payload.cycle_next
task.cycle_next_uuid = payload.cycle_next_uuid
},
/**
* set task paramter
*
@@ -98,6 +255,27 @@ const taskActs = {
}
task.parameter_set = Object.assign({}, task.parameter_set)
},
[typePath.createCondition]: async ({ state, getters, commit }, payload) => {
const { uuid, condition, compOp, value } = payload
return {
[uuid]: {
type: condition,
comparsion: compOp,
value: value,
},
}
},
[typePath.createAction]: async ({ state, getters, commit }, payload) => {
const { uuid, action, target } = payload
return {
[uuid]: {
type: action,
target: target,
condition: [],
},
}
},
}
export default taskActs
@@ -16,13 +16,87 @@ const projectGets = {
return state.projectList[state.projectSelectIndex]
},
[typePath.getDevice]: (state) => (deviceKey) => {
return state.projectList[state.projectSelectIndex].device[deviceKey]
[typePath.getDevice]: (state, getters) => (deviceKey) => {
return getters[typePath.getSelect].device[deviceKey]
},
[typePath.getDeviceNum]: (state, getters) => {
return Object.keys(getters[typePath.getSelect].device).length
},
[typePath.getDeviceLibrary]: (state, getters) => (key) => {
return getters[typePath.getSelect].device[key].library
},
[typePath.getDeviceMaxOrder]: (state, getters) => {
const deviceList = getters[typePath.getSelect].device
if (deviceList.length === 0) return 0
let order = 0
for (const device in deviceList) {
order = Math.max(deviceList[device].order, order)
}
order += 1
return order
},
[typePath.getDeviceShowName]: (state, getters) => (key) => {
if (getters[typePath.getSelect].device[key].pair === null) {
return getters[typePath.getSelect].device[key].name
}
return getters[typePath.getSelect].device[key].pair
},
[typePath.getAllDevice]: (state) => {
return state.projectList[state.projectSelectIndex].device
},
[typePath.getCycle]: (state) => (uuid) => {
// 0: index, 1: location, 2: info
let location
const project = state.projectList[state.projectSelectIndex]
// if no input then reject
if (uuid === undefined) return []
const cycleIndex = project.cycle.findIndex(ele => ele.range.find(ele => ele === uuid))
// if find no index then reject
if (cycleIndex === -1) return []
if (project.cycle[cycleIndex].range[0] === uuid) location = 'start'
if (project.cycle[cycleIndex].range[1] === uuid) location = 'end'
return [cycleIndex, location, project.cycle[cycleIndex]]
},
/**
* find devices that is connected but not register in project
*
* @param {string} library
*/
[typePath.getNotRegisterDevice]: (state, getters) => (library) => {
const deviceList = []
const connectedDevices = state.deviceConnectList
const registeredDevices = getters.getSelectProject.device
// if there is not connect device then return
if (connectedDevices.length === 0) return deviceList
// if there is registered device, need to remove cause duplicate device
if (registeredDevices) {
for (const device of connectedDevices) {
if (Object.values(registeredDevices).findIndex(ele => {
return ele.pair === device.mac_address
}) === -1) {
// if no metion which library
if (library === undefined) {
deviceList.push({ name: device.name, macAddress: device.mac_address, library: device.library_name })
}
// if library is assign then need to be same library
if (library && device.library_name.includes(library)) {
deviceList.push({ name: device.name, macAddress: device.mac_address, library: device.library_name })
}
}
}
}
return deviceList
},
}
export default projectGets
+21 -2
View File
@@ -7,30 +7,49 @@ const types = {
delete: 'deleteProject',
save: 'saveProject',
select: 'selectProject',
copy: 'copyProject',
get: 'getProject',
getSelect: 'getSelectProject',
getDevice: 'getDeviceProject',
getCycle: 'getCycleProject',
getAllDevice: 'getAllDeviceProject',
getDeviceNum: 'getDeviceNumProject',
getDeviceShowName: 'getDeviceShowNameProject',
getDeviceLibrary: 'getDeviceLibraryProject',
getDeviceMaxOrder: 'getDeviceMaxOrderProject',
getNotRegisterDevice: 'getNotRegisterDeviceProject',
addDevice: 'addDeviceProject',
appendDevice: 'appendDeviceProject',
createDevice: 'createDeviceProject',
findDevice: 'findDeviceProject',
setDevice: 'setDeviceProject',
checkNotRegisterDevice: 'checkNotRegisterDeviceProject',
checkPairDeviceExist: 'checkPairDeviceExistProject',
deleteDevice: 'deleteDeviceProject',
},
task: {
init: 'initTask',
create: 'createTask',
createCycle: 'createCycleTask',
createAction: 'createActionTask',
createCondition: 'createConditionTask',
insert: 'insertTask',
swap: 'swapTask',
delete: 'deleteTask',
deleteDevice: 'deleteDeviceTask',
rearrange: 'rearrangeTask',
save: 'saveTask',
select: 'selectTask',
copy: 'copyTask',
setCondition: 'setConditionTask',
setAction: 'setActionTask',
setCycle: 'setCycleTask',
setParameterSet: 'setParameterSetTask',
get: 'getTask',
getIndex: 'getIndexTask',
getSelect: 'getSelectTask',
getCondition: 'getConditionTask',
getParameterSet: 'getParameterSetTask',
@@ -10,6 +10,8 @@ import localforage from 'localforage'
import { IIRFilter } from '@/data/task/filter/IIRFilter.js'
import config from '@/data/config-table/index'
const typePath = types.chart
const chartActs = {
@@ -145,9 +147,9 @@ const chartActs = {
let legendName
if (formula == null) {
legendName = getLegendName(sourceList, formula)
legendName = getLegendName(sourceList, formula, state.deviceListNew)
} else {
legendName = getLegendName(sourceList, formula.id)
legendName = getLegendName(sourceList, formula.id, state.deviceListNew)
}
if (formula == null) {
@@ -338,7 +340,7 @@ const chartActs = {
return parseFloat(val).toFixed(2) + 'uV'
}
}
state.chartData[chartID].chartYUnit = 'uV' // nA * 1000
state.chartData[chartID].chartYUnit = 'uV'
} else if (sourceList[1].name === 'Elite') {
switch (sourceList[1].channel) {
case 1:
@@ -432,44 +434,20 @@ const chartActs = {
}
break
case 'EliteEIS':
if (state.chartData[chartID].chartMode === 0) {
// eslint-disable-next-line no-case-declarations
const device = state.deviceListNew.find((ele) => String(ele.memory_board) === String(source.id))
if (device === undefined) break
if (Number(device.configuration.MODE) === 0) {
state.chartData[chartID].series[state.chartData[chartID].series.length - 1].showSymbol = true
state.chartData[chartID].series[state.chartData[chartID].series.length - 1].showAllSymbol = true
}
dataStreamBuffer.register(chartID, source.id, source.channel)
switch (source.channel) {
case 1:
_axisList.push(_axis + ' AXIS = ELITE ' + source.id + ' ZIMAG_RAW')
break
case 2:
_axisList.push(_axis + ' AXIS = ELITE ' + source.id + ' ZREAL_RAW')
break
case 3:
_axisList.push(_axis + ' AXIS = ELITE ' + source.id + ' FREQ')
break
case 4:
_axisList.push(_axis + ' AXIS = ELITE ' + source.id + ' CYCLE')
break
case 5:
_axisList.push(_axis + ' AXIS = ELITE ' + source.id + ' ZIMAG')
break
case 6:
_axisList.push(_axis + ' AXIS = ELITE ' + source.id + ' ZREAL')
break
case 7:
_axisList.push(_axis + ' AXIS = ELITE ' + source.id + ' IMPEDANCE')
break
case 8:
_axisList.push(_axis + ' AXIS = ELITE ' + source.id + ' PHASE')
break
case 9:
_axisList.push(_axis + ' AXIS = ELITE ' + source.id + ' CURRENT')
break
case 10:
_axisList.push(_axis + ' AXIS = ELITE ' + source.id + ' LEVEL_GAIN')
_axisList.push(_axis + ' AXIS = ELITEEIS ' + source.id + ' CHANNEL ' + source.channel)
break
default:
_axisList.push(_axis + ' AXIS = ELITE ' + source.id + ' CHANNEL ' + source.channel)
_axisList.push(_axis + ' AXIS = ELITEEIS ' + source.id + ' CHANNEL ' + source.channel)
break
}
break
@@ -1133,6 +1111,8 @@ function parseGridSourceAxis (gridSourceAxis) {
break
case 'ELITEEIS':
deviceInfo.deviceName = 'EliteEIS'
deviceInfo.deviceID = parseResult[1]
deviceInfo.channel = Number(parseResult[3])
break
default:
break
@@ -1239,87 +1219,38 @@ function makeGrid (index, length) {
}
// get legend name
function getLegendName (sourceList, formulaID) {
function getLegendName (sourceList, formulaID, deviceList) {
let legendName = ''
if (formulaID == null) {
// source only 2 device
sourceList.forEach(source => {
let device = ''
let channelName = ''
switch (source.name) {
case 'Time':
legendName += 'T'
break
case 'Neulive':
// legendName += 'N' + source.id + 'CH' + source.channel
switch (source.channel) {
case 257:
legendName += 'X'
break
case 258:
legendName += 'Y'
break
case 259:
legendName += 'Z'
break
case 260:
legendName += 'M'
break
default:
legendName += 'CH' + source.channel
break
}
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
}
// eslint-disable-next-line no-case-declarations
device = deviceList.find((ele) => String(ele.memory_board) === String(source.id))
if (device === undefined) break
// eslint-disable-next-line no-case-declarations
channelName = getConfigChannel(device.library_name, device.configuration.MODE, source.channel - 1)
if (!channelName) break
legendName += 'E' + source.id + '-' + channelName.name[0]
break
case 'EliteEIS':
switch (source.channel) {
case 1:
legendName += 'E' + source.id + '-Zimag_raw'
break
case 2:
legendName += 'E' + source.id + '-Zreal_raw'
break
case 3:
legendName += 'E' + source.id + '-Freq'
break
case 4:
legendName += 'E' + source.id + '-Cycle'
break
case 5:
legendName += 'E' + source.id + '-Zimag'
break
case 6:
legendName += 'E' + source.id + '-Zreal'
break
case 7:
legendName += 'E' + source.id + '-Imped'
break
case 8:
legendName += 'E' + source.id + '-Phase'
break
case 9:
legendName += 'E' + source.id + '-Current'
break
case 10:
legendName += 'E' + source.id + '-Level_gain'
break
default:
legendName += 'E' + source.id + 'CH' + source.channel
break
// eslint-disable-next-line no-case-declarations
device = deviceList.find((ele) => String(ele.memory_board) === String(source.id))
if (device === undefined) break
// eslint-disable-next-line no-case-declarations
channelName = getConfigChannel(device.library_name, device.configuration.MODE, source.channel - 1)
if (!channelName) break
if (device.configuration.MODE === 0) {
legendName += 'E' + source.id + '-' + channelName.name.split('_').join('')
break
}
legendName += 'E' + source.id + '-' + channelName.name[0]
break
default:
legendName += 'D' + source.id + 'CH' + source.channel
@@ -1334,6 +1265,10 @@ function getLegendName (sourceList, formulaID) {
return legendName
}
function getConfigChannel (library, mode, channel) {
return config.getChannelConfig(library, mode, channel)
}
export function getTimeFormatter (val) {
const hour = parseInt(val / 3.6e9)
const minute = parseInt((val % 3.6e9) / 1000000 / 60)