Compare commits

...

82 Commits

Author SHA1 Message Date
peterlu14 715f1ef1d0 [update] align controller_id 2021-10-12 17:30:40 +08:00
peterlu14 cc7e2adc81 Merge branch 'feature/add_sd_icon' into feature/spike_UI_enhance 2021-10-12 12:16:05 +08:00
peterlu14 98738bcb10 [update] remove export info 2021-10-12 12:09:02 +08:00
peterlu14 e34605c488 [update] spike update 2021-10-12 11:29:19 +08:00
peterlu14 ed3d8a81ff Merge branch 'feature/neulive3.5-sti-amp' into feature/spike_UI_enhance 2021-10-08 10:14:55 +08:00
peterlu14 87c9cba03c [update] spike data mqtt add 2021-10-08 10:09:25 +08:00
peterlu14 de8fbc9bbe [update] spike button eventproof 2021-10-05 15:33:33 +08:00
peterlu14 403be30139 Merge branch 'release/merge_SD_card_UI_0924_2' into feature/neulive3.5-sti-amp 2021-10-05 11:09:59 +08:00
peterlu14 46017134d8 [update] spike optimize 2021-10-01 14:21:12 +08:00
peterlu14 e2298a6ccc [update] download excel bug fix 2021-09-27 20:21:01 +08:00
peterlu14 5a61e24495 [update] icon usb to sd card & remove ! 2021-09-24 19:37:38 +08:00
peterlu14 c4007b7930 Merge branch 'feature/SD_card_UI' into release/merge_SD_card_UI_0924 2021-09-24 12:52:21 +08:00
peterlu14 2fe1cd6e00 [update] add progress bar & controller sd_uploading check 2021-09-24 12:50:29 +08:00
peterlu14 4cc7b9e12f [update] mac address change & get sync to async 2021-09-22 14:33:06 +08:00
peterlu14 8b4f210f95 Merge commit '1af50d0bfc7ec75a6aaf1aa493b31b29fc20882a' into feature/SD_card_UI 2021-09-22 14:31:46 +08:00
peterlu14 1af50d0bfc [update] databatch 2021-09-17 13:26:36 +08:00
TommyXin 99b2b9dfce remove check param 2021-09-16 17:05:24 +08:00
TommyXin 1004c7075e [update] EIS unit ch4&8, window by elite lib ver. 2021-09-16 17:05:16 +08:00
peterlu14 8f4cbc0eeb Merge remote-tracking branch 'origin/feature/neulive_replay_wish' into release/neulive_elite_0913 2021-09-15 19:07:12 +08:00
TommyXin f741a2d018 fix x-axis unit 2021-09-15 19:06:46 +08:00
TommyXin 008897830d fix source X 2021-09-15 19:06:41 +08:00
TommyXin 5c297687f1 multi channel & unit 2021-09-15 19:06:32 +08:00
Jordan Hsu 213caf9796 [fix] replay window can't zoom bug 2021-09-15 17:10:21 +08:00
peterlu14 0fda2141dd [update] add record_in_sd option 2021-09-15 02:36:16 +08:00
peterlu14 3761493ec1 [update] remove sd card delete 2021-09-15 01:04:18 +08:00
peterlu14 87300e7a43 Merge remote-tracking branch 'origin/feature/SD_card_UI' into release/neulive_elite_0913 2021-09-15 00:59:47 +08:00
peterlu14 85103f5f12 [update] expand action width & change order 2021-09-15 00:56:58 +08:00
Jordan Hsu 1059a98c27 [add] sd button confirm modal before uploading 2021-09-14 15:54:57 +08:00
Jordan Hsu 8150afc624 Merge remote-tracking branch 'origin/feature/SD_card_UI' into feature/SD_card_UI 2021-09-14 14:13:30 +08:00
Jordan Hsu b0de357d89 [add] replay check if sd uploaded 2021-09-14 14:12:53 +08:00
peterlu14 44c1a41d99 Merge branch 'feature/SD_card_UI' into release/neulive_elite_0913 2021-09-14 14:00:28 +08:00
peterlu14 a6a9b64da2 [update] getSDuuidList 2021-09-14 13:05:05 +08:00
Jordan Hsu a4ccee71a8 [fix] sd card UI bug 2021-09-14 11:47:45 +08:00
Jordan Hsu 2cbdab696c Merge branch 'feature/neulive_replay_wish' into release/neulive_elite_0913 2021-09-13 18:48:35 +08:00
Jordan Hsu 3fe5e4af0c adjust UI 2021-09-13 18:42:51 +08:00
Jordan Hsu 577cf09951 [add] replay custom window start and size 2021-09-13 17:48:11 +08:00
peterlu14 0c18ce1829 Merge remote-tracking branch 'origin/feature/elite_replay_down_scale' into release/neulive_0913 2021-09-13 14:52:03 +08:00
peterlu14 7c336d4bd3 Merge remote-tracking branch 'origin/feature/neulive_replay_wish' into release/neulive_0913 2021-09-13 14:51:31 +08:00
Jordan Hsu 95955e23e0 [add] lock button 2021-09-13 14:07:44 +08:00
peterlu14 d387f83f87 [update] setting pic update & display fix 2021-09-10 20:03:13 +08:00
Jordan Hsu 0e1695bb4e [modify] elite replay will detect resample rate and auto down rate 2021-09-10 20:02:53 +08:00
peterlu14 fba42100d8 Merge branch 'feature/setting_update' into devlop/neulive_merge_sd_card 2021-09-10 12:39:56 +08:00
peterlu14 acd1b300d7 Merge branch 'feature/SD_card_UI' into devlop/neulive_merge_sd_card 2021-09-10 12:39:26 +08:00
Jordan Hsu 3f4d5de662 [modify] nprogress color to red 2021-09-10 12:09:49 +08:00
Jordan Hsu 56f4f0274c [remove] elite sd card button 2021-09-10 11:51:31 +08:00
Jordan Hsu e6aeb9203d [fix] sd card UI won't re-render after changing page bug 2021-09-09 21:02:41 +08:00
Jordan Hsu da7581de63 [update] shell script readme 2021-09-09 18:29:14 +08:00
Jordan Hsu 6d9294775d clean up sd card code 2021-09-09 18:08:14 +08:00
Jordan Hsu 3a7d685d31 [fix] monophasic checkpoint bug 2021-09-09 17:50:51 +08:00
peterlu14 16df8514ba [update] setting pic update & display fix 2021-09-09 13:39:21 +08:00
Jordan Hsu a5085cbbe6 sd card UI 2021-09-08 21:29:55 +08:00
peterlu14 1fbf8c0022 [update] download replay data 2021-09-08 20:07:28 +08:00
peterlu14 0f5cbaf778 [update] sd_data download & replay 2021-09-08 16:26:49 +08:00
Jordan Hsu 2b5b42dd61 tmp for api debug 2021-09-08 13:52:59 +08:00
Jordan Hsu 4221a35f00 Merge remote-tracking branch 'origin/develop/neulive_0901' into feature/SD_card_UI 2021-09-08 11:06:41 +08:00
peterlu14 c3fc287b0f [update] add sdcard api & get sd data 2021-09-08 11:02:44 +08:00
Jordan Hsu 047a72e9c6 [add] SD card init func 2021-09-07 16:56:29 +08:00
Jordan Hsu b79a4a2091 [init] SD card UI 2021-09-07 15:44:44 +08:00
Jordan Hsu 4a8be436ce [fix] monophasic bug 2021-09-06 15:53:52 +08:00
peterlu14 102d39b4b5 [update] add sample rate 2021-09-06 14:11:14 +08:00
peterlu14 e8479f80ca [update] support past replay & data:axis 75:1 2021-09-06 13:18:17 +08:00
peterlu14 3aa5db1455 [update] sti channel support 16 channel 2021-09-06 11:44:47 +08:00
peterlu14 2e33ef7abb [update] fix download bug & add 0 ~ 11 device 2021-09-06 11:41:28 +08:00
Jordan Hsu 78ec2fd492 [modify] spike UI with lttb algo. 2021-09-03 21:09:09 +08:00
peterlu14 d12084324a [update] spike ui save 2021-09-03 19:14:18 +08:00
Jordan Hsu b3580bfa76 [modify] neulive replay unit uV and clear redundant code 2021-09-03 16:15:18 +08:00
peterlu14 5b57e40575 [update] remove 3.5 rf & led 2021-09-02 20:26:38 +08:00
peterlu14 14679182df [update] move mem RF & RF & led to setting 2021-09-02 20:20:44 +08:00
peterlu14 db0111d1db [update] amplitude rebuild & fix STI_T4 2021-09-01 10:57:35 +08:00
peterlu14 21cb382a1f [update] replace ADC_CLOCK to SAMPLE_RATE & 3.5 RECORDING_CH 2021-09-01 10:55:58 +08:00
peterlu14 1d8ef94ec6 Merge remote-tracking branch 'origin/feature/spike_UI' into release/0824_test 2021-08-27 19:08:52 +08:00
peterlu14 e49b6fb791 [update] export fix & subplot message & download 2021-08-27 19:07:57 +08:00
peterlu14 52e3d70dc8 [update] neulive ui switch & STI cycle amplitude T1-T4 fix 2021-08-26 16:59:39 +08:00
Roy a33bbd0581 fix current input value 2021-08-26 11:58:43 +08:00
Roy cd97260230 fix volt input value 2021-08-26 11:38:38 +08:00
Roy b9242764ab Merge branch 'e_0824_func_gen_bug' into release/0824_test 2021-08-26 10:46:36 +08:00
TommyXin 433e567e74 neulive 3.5 UI 2021-08-25 20:44:28 +08:00
TommyXin fbbebb3423 fix grid uV 2021-08-25 16:33:40 +08:00
Roy 6f2aab5276 OCP mode add current range button 2021-08-25 16:12:44 +08:00
TommyXin d82b1cb735 grid support input 'auto' 2021-08-25 01:17:07 +08:00
Roy 8aa87d587f update elite1.5 button 2021-08-24 17:40:32 +08:00
TommyXin 38503e198e EIS volt range 2021-08-24 04:35:02 +08:00
71 changed files with 4159 additions and 857 deletions
+5
View File
@@ -12106,6 +12106,11 @@
"set-blocking": "~2.0.0"
}
},
"nprogress": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/nprogress/-/nprogress-0.2.0.tgz",
"integrity": "sha1-y480xTIT2JVyP8urkH6UIq28r7E="
},
"nth-check": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz",
+1
View File
@@ -35,6 +35,7 @@
"lodash": "^4.17.21",
"medium-editor": "^5.23.3",
"normalize.css": "^8.0.1",
"nprogress": "^0.2.0",
"popper.js": "^1.16.0",
"regenerator-runtime": "^0.13.3",
"register-service-worker": "^1.6.2",
+1 -1
View File
@@ -10,5 +10,5 @@ burn_to_raspberry.sh
```shell
sh ./burn_to_raspberry.sh <HOST> <PASSWORD>
e.g. sh ./burn_to_raspberry.sh pi@192.168.3.53 raspberry
e.g. sh ./burn_to_raspberry.sh pi@192.168.2.1 raspberry
```
+1
View File
@@ -31,6 +31,7 @@ import VueWorker from 'vue-worker'
import axios from 'axios'
import VueAxios from 'vue-axios'
import 'nprogress/nprogress.css'
import '../metrics'
import '../registerServiceWorker'
Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 201 KiB

@@ -22,7 +22,7 @@
<div class="row" >
<div class="flex sm12 xl12 md12 xs12">
<elite-replay-overview-chart v-show="showOverviewChart" :ref="'chart_overview'" class="mb-1" :cardheight="'7vh'" :data="chartOverviewData" @dataZoomEvent="dataZoomEvent($event)"/>
<elite-replay-chart :ref="'chart_detail'" @dblclick.native="distribute()" :cardheight="'88vh'" :chartheight="detailchartheight" :data="chartDetailData" />
<elite-replay-chart :ref="'chart_detail'" :cardheight="'88vh'" :chartheight="detailchartheight" :data="chartDetailData" />
<change-channel-value-min-max :ref="'set_min_max'"/>
</div>
</div>
@@ -235,6 +235,49 @@ export default {
}
this.zoomTime = 0
},
async computeResampleScale (meta, duration) {
const sampleRate = meta.parameter_set.SAMPLE_RATE / 10
const dataPointNum = (parseInt(duration) / 1e6) * sampleRate // us -> s: /1e6
let scale
if (dataPointNum > 2e6) { // 2000 (points) * 1000 (resample) = 2e6
scale = '1000'
} else if (dataPointNum > 2e5) { // 2000 (points) * 100 (resample) = 2e5
scale = '100'
} else if (dataPointNum > 2e4) { // 2000 (points) * 10 (resample) = 2e4
scale = '10'
} else {
scale = '1'
}
let dataExist = false
while (dataExist === false) {
if (scale === '1') {
break
} else {
let status
for (const ch in Object.keys(meta.mini_data)) {
let earlyStopFlag = false
const dataIDArray = meta.mini_data[ch][scale]
for (let i = 0; i < dataIDArray.length; i++) {
const dataID = dataIDArray[i]
const result = await download.getMiniExistOrNotByID(dataID, ch)
status = result.data
if (status === false) {
earlyStopFlag = true
scale = String(parseInt(scale) / 10)
break
}
}
if (earlyStopFlag === true) {
break
}
}
if (status === true) {
dataExist = true // break
}
}
}
return scale
},
drawOverviewData: async function () {
this.showChartLoading('overview')
for (const meta in this.dataInfo) {
@@ -244,21 +287,9 @@ export default {
metaInfo = _meta
}
})
let scale = '100'
let scale = '1'
if (this.axisXDataType.description === 'Time') {
const sampleRate = metaInfo.parameter_set.SAMPLE_RATE / 10
const dataPointNum = (parseInt(metaInfo.time_duration) / 1e6) * sampleRate // us -> s: /1e6
if (dataPointNum > 2e6) { // 2000 (points) * 1000 (resample) = 2e6
scale = '1000'
} else if (dataPointNum > 2e5) { // 2000 (points) * 100 (resample) = 2e5
scale = '100'
} else if (dataPointNum > 2e4) { // 2000 (points) * 10 (resample) = 2e4
scale = '10'
} else {
scale = '1'
}
} else {
scale = '1' // [TODO] select by user
scale = await this.computeResampleScale(metaInfo, metaInfo.time_duration)
}
console.log('overview scale:', scale)
// download data
@@ -303,21 +334,9 @@ export default {
}
})
let scale = '100'
let scale = '1'
if (this.axisXDataType.description === 'Time') {
const sampleRate = metaInfo.parameter_set.SAMPLE_RATE / 10
const dataPointNum = (parseInt(timeDur) / 1e6) * sampleRate // us -> s: /1e6
if (dataPointNum > 2e6) { // 2000 (points) * 1000 (resample) = 2e6
scale = '1000'
} else if (dataPointNum > 2e5) { // 2000 (points) * 100 (resample) = 2e5
scale = '100'
} else if (dataPointNum > 2e4) { // 2000 (points) * 10 (resample) = 2e4
scale = '10'
} else {
scale = '1'
}
} else {
scale = '1' // [TODO] select by user
scale = await this.computeResampleScale(metaInfo, timeDur)
}
// elite的sample rate不像neulive這麼高,因此試試scale = 100 or 1000時不要再sampling一次了,不然有些形狀(e.g. peak)會不一樣
if (scale === '100' || scale === '1000') {
@@ -448,32 +467,6 @@ export default {
}
this.drawDetailData() // reDraw
},
distribute: function () {
// if (this.chartDetailData.grid.length === 1) {
// this.chartDetailData.xAxis[0].axisLabel.show = false
// this.updateGridListChart({
// chartAllData: this.chartData,
// chartID: this.chartDetailData.chartID,
// gridLength: this.chartDetailData.series.length,
// })
// this.chartDetailData.series.forEach((series, index) => {
// series.xAxisIndex = index
// series.yAxisIndex = index
// })
// this.chartDetailData.xAxis[this.chartDetailData.xAxis.length - 1].axisLabel.show = true
// } else {
// this.updateGridListChart({
// chartAllData: this.chartData,
// chartID: this.chartDetailData.chartID,
// gridLength: 1,
// })
// this.chartDetailData.series.forEach(series => {
// series.xAxisIndex = 0
// series.yAxisIndex = 0
// })
// this.chartDetailData.xAxis[0].axisLabel.show = true
// }
},
...mapActions('replay', [types.chart.init, types.chart.register, types.chart.clear, types.chart.updateGridList, types.chart.updateDataZoom]),
...mapActions('replay', [types.meta.init]),
...mapActions('replay', [types.rec.init, types.rec.intoData, types.rec.initDisplaySetting, types.rec.updateDisplaySetting]),
@@ -484,9 +477,6 @@ export default {
...mapGetters('replay', [types.meta.getAll]),
...mapGetters('replay', [types.rec.getAll, types.rec.getCycleDict]),
},
// use watch because va-select with @change will have bug
watch: {
},
async mounted () {
this.showChartLoading()
const metaIDList = this.$route.params.metaList.split('-')
@@ -106,12 +106,6 @@ export default {
</script>
<style lang="scss">
.box_inline-block {
padding: 2px;
margin: 2px;
display: inline-block;
}
.flex-container {
display: flex;
}
@@ -9,7 +9,7 @@
<span slot="header">Control Panel</span>
<div slot="body">
<div>
<top-control-panel :ref="'top_control_panel'" @refreshChart="setOption"/>
<top-control-panel :ref="'top_control_panel'" @refreshChart="setOption" @changeOverviewDataZoom="changeOverviewDataZoom"/>
</div>
</div>
</va-collapse>
@@ -56,9 +56,13 @@ export default {
'chartOverviewData',
'chartDetailData',
'currentScale',
'startTime',
'endTime',
'windowLength',
'startTimeCurrent',
'endTimeCurrent',
'sampleMethod',
'useSdCardData',
]),
},
props: {
@@ -86,8 +90,6 @@ export default {
metaList: null,
dataInfo: {},
maxTime: 0,
startTime: 0,
endTime: 0,
zoomTime: 0,
chartAreaClass: ['flex', 'xs12', 'sm12', 'md12', 'xl9', 'pa-0'],
dataZoomStart: 0,
@@ -133,7 +135,12 @@ export default {
},
getData: async function (scale, sampleMethod, id, channel, meta) {
if (scale === 1) {
return await download.rawByIDChannels(id, channel, meta)
// [TODO] 0: assume first meta temporarily
if (this.useSdCardData && (this.metaList[0].sd_data_uploaded === true)) {
return await download.rawSdDataByIDChannels(id, channel, meta)
} else {
return await download.rawByIDChannels(id, channel, meta)
}
} else {
if (sampleMethod === 'mean') {
return await download.miniMeanByIDChannel(id, channel, meta)
@@ -204,7 +211,7 @@ export default {
})
},
updateMarkArea: function (e) {
console.log(e)
// console.log(e)
if (e.batch != null) {
// console.log(e.batch)
e.batch.forEach(dataZoom => {
@@ -239,16 +246,22 @@ export default {
e.batch.forEach(dataZoom => {
const id = parseInt(dataZoom.dataZoomId.substr(dataZoom.dataZoomId.length - 3, dataZoom.dataZoomId.length - 1))
if (id === 1) {
this.startTime = this.maxTime * dataZoom.start / 100
this.endTime = this.maxTime * dataZoom.end / 100
this.startTime = parseInt(this.maxTime * dataZoom.start / 100)
this.endTime = parseInt(this.maxTime * dataZoom.end / 100)
this.windowLength = this.endTime - this.startTime
this.chartOverviewData.dataZoom[0].start = dataZoom.start
this.chartOverviewData.dataZoom[0].end = dataZoom.end
// console.log(this.startTime, this.endTime)
}
})
} else {
const id = parseInt(e.dataZoomId.substr(e.dataZoomId.length - 3, e.dataZoomId.length - 1))
if (id === 0) {
this.startTime = this.maxTime * e.start / 100
this.endTime = this.maxTime * e.end / 100
this.startTime = parseInt(this.maxTime * e.start / 100)
this.endTime = parseInt(this.maxTime * e.end / 100)
this.windowLength = this.endTime - this.startTime
this.chartOverviewData.dataZoom[0].start = e.start
this.chartOverviewData.dataZoom[0].end = e.end
// console.log(this.startTime, this.endTime)
}
}
@@ -256,6 +269,13 @@ export default {
this.chartOverviewData.series[0].markArea.data[0][1].xAxis = this.startTime + ((this.endTime - this.startTime) * (this.dataZoomEnd / 100))
this.zoomTime = 0
},
changeOverviewDataZoom () {
this.chartOverviewData.dataZoom[0].start = this.startTime * 100 / this.maxTime
this.chartOverviewData.dataZoom[0].end = this.endTime * 100 / this.maxTime
this.chartOverviewData.series[0].markArea.data[0][0].xAxis = this.startTime + ((this.endTime - this.startTime) * (this.dataZoomStart / 100))
this.chartOverviewData.series[0].markArea.data[0][1].xAxis = this.startTime + ((this.endTime - this.startTime) * (this.dataZoomEnd / 100))
this.$refs.chart_overview.mergeOptions(this.chartOverviewData)
},
drawInitData: async function () {
this.showChartLoading('overview')
for (const meta in this.dataInfo) {
@@ -266,7 +286,7 @@ export default {
}
})
let scale = '1000'
const sampleRate = (800000 / metaInfo.parameter_set.ADC_CLOCK) // Hz
const sampleRate = (metaInfo.parameter_set.SAMPLE_RATE === 0) ? parseInt(8e5 / metaInfo.parameter_set.ADC_CLOCK) : metaInfo.parameter_set.SAMPLE_RATE // Hz
const dataPointNum = (parseInt(metaInfo.time_duration) / 1e6) * sampleRate // us -> s: /1e6
if (dataPointNum > 2e6) { // 2000 (points) * 1000 (resample) = 2e6
scale = '1000'
@@ -312,7 +332,7 @@ export default {
}
})
let scale = '1000'
const sampleRate = (800000 / metaInfo.parameter_set.ADC_CLOCK) // Hz
const sampleRate = (metaInfo.parameter_set.SAMPLE_RATE === 0) ? parseInt(8e5 / metaInfo.parameter_set.ADC_CLOCK) : metaInfo.parameter_set.SAMPLE_RATE // Hz
const dataPointNum = (timeDur / 1e6) * sampleRate // us -> s: /1e6
if (dataPointNum > 2e6) { // 2000 (points) * 1000 (resample) = 2e6
scale = '1000'
@@ -448,7 +468,7 @@ export default {
...mapActions('replay', [types.meta.init]),
...mapActions('replay', [types.rec.init, types.rec.intoData, types.rec.initDisplaySetting, types.rec.updateDisplaySetting]),
...mapMutations('replay', [types.chart.updateAxisLabel, types.chart.updateChartSampling]),
...mapMutations('replay', [types.chart.updateAxisLabel, types.chart.updateChartSampling, types.chart.setOverviewDataZoomStartAndEnd]),
...mapMutations('replay', [types.meta.updateByIndex]),
...mapGetters('replay', [types.meta.getAll]),
@@ -467,6 +487,7 @@ export default {
console.log(this.metaList)
console.log(this.dataInfo)
await this.register()
this.setOverviewDataZoomStartAndEndChart()
await this.drawInitData()
this.dataZoomTimer = setInterval(this.checkDataZoom, 1000)
this.$refs.top_control_panel.init()
@@ -54,6 +54,9 @@ export default {
updateZoom: function (e) {
this.$emit('dataZoomEvent', e)
},
mergeOptions (options) {
this.$refs.chart_ref.mergeOptions(options)
},
showLoading (options) {
this.$refs.chart_ref.showLoading(options)
},
@@ -1,15 +1,22 @@
<template>
<div>
<va-card>
<edit-file-name style="display: inline;" :ref="'edit_file_name'"/>
<download-file style="display: inline;"/>
<delete-file style="display: inline;"/>
<div class="flex-container">
<edit-file-name class="flex-child" :ref="'edit_file_name'"/>
<download-file class="flex-child2"/>
<delete-file class="flex-child2"/>
</div>
<show-resample-rate/>
<div class="flex-container">
<change-window-start-and-size class="flex-child" :ref="'change_window_start_and_size'" @changeOverviewDataZoom="changeOverviewDataZoom"/>
<lock-data-zoom class="flex-child2" :chartID="0"/>
</div>
<change-axis v-show="showXAxis" :ref="'change_axis_x'" deviceName="neulive" axis="x"/>
<change-axis v-show="showYAxis" :ref="'change_axis_y'" deviceName="neulive" axis="y"/>
<change-unit v-show="showXUnit" :ref="'change_unit_x'" deviceName="neulive" axis="x" @refreshChart="refreshChart"/>
<change-unit :ref="'change_unit_y'" deviceName="neulive" axis="y" @refreshChart="refreshChart"/>
<change-scale :ref="'change_scale_y'" deviceName="neulive" axis="y"/>
<change-unit :ref="'change_unit_y'" class="box_inline-block" deviceName="neulive" axis="y" @refreshChart="refreshChart"/>
<change-scale :ref="'change_scale_y'" class="box_inline-block" deviceName="neulive" axis="y"/>
<sd-card-toggle :ref="'sd_card_toggle'" :metaIndex="0"/>
<show-parameter :ref="'show_param'" deviceName="neulive"/>
</va-card>
</div>
@@ -24,6 +31,9 @@ import DownloadFile from '@/components/analysis/replay/toolbox/DownloadFile.vue'
import DeleteFile from '@/components/analysis/replay/toolbox/DeleteFile.vue'
import EditFileName from '@/components/analysis/replay/toolbox/EditFileName.vue'
import ShowParameter from '@/components/analysis/replay/toolbox/ShowParameter.vue'
import SdCardToggle from '@/components/analysis/replay/toolbox/SdCardToggle.vue'
import LockDataZoom from '@/components/analysis/replay/toolbox/LockDataZoom.vue'
import ChangeWindowStartAndSize from '@/components/analysis/replay/toolbox/ChangeWindowStartAndSize.vue'
export default {
name: 'top-control-panel',
@@ -36,11 +46,12 @@ export default {
DeleteFile,
EditFileName,
ShowParameter,
SdCardToggle,
LockDataZoom,
ChangeWindowStartAndSize,
},
computed: {
},
props: {
},
async created () {
},
data () {
@@ -61,6 +72,11 @@ export default {
this.$refs.change_scale_y.init()
this.$refs.edit_file_name.init()
this.$refs.show_param.init()
this.$refs.change_window_start_and_size.init()
this.$refs.sd_card_toggle.init()
},
changeOverviewDataZoom () {
this.$emit('changeOverviewDataZoom')
},
refreshChart (options) {
this.$emit('refreshChart', options)
@@ -78,4 +94,29 @@ export default {
</script>
<style lang="scss">
.box_inline-block {
padding: 2px;
margin: 2px;
display: inline-block;
}
.flex-container {
display: flex;
}
.flex-child {
flex: 2;
}
.flex-child1 {
flex: 1;
}
.flex-child2 {
flex: 0;
}
.flex-child:first-child {
margin-right: 1px;
}
</style>
@@ -42,6 +42,21 @@ export default {
]),
},
methods: {
initDefaultUnit (axis) {
if (this.deviceName === 'neulive') {
if (axis === 'x') {
return this.valueFormatOptions[this.dataType].find(function (item, index, array) {
return item.unit === 'auto'
})
} else if (axis === 'y') {
return this.valueFormatOptions[this.dataType].find(function (item, index, array) {
return item.unit === 'uV'
})
}
} else if (this.deviceName === 'elite') {
return this.valueFormatOptions[this.dataType][0]
}
},
init () {
if (this.deviceName === 'neulive') {
// now neulive only v-t
@@ -81,10 +96,10 @@ export default {
}
}
if (this.axis === 'x') {
this.valueFormatX = this.valueFormatOptions[this.dataType][0]
this.valueFormatX = this.initDefaultUnit(this.axis)
this.valueFormat = this.valueFormatX
} else if (this.axis === 'y') {
this.valueFormatY = this.valueFormatOptions[this.dataType][0] // 0 mean use default unit
this.valueFormatY = this.initDefaultUnit(this.axis)
this.valueFormat = this.valueFormatY
}
this.changeUnit()
@@ -0,0 +1,60 @@
<template>
<div class="row flex sm12 xl12 md12 xs12 align--center my-0 py-0">
<div class="flex sm4 xl4 md4 xs4 px-0 mx-0">
<p class="display-6">Window size<p/>
</div>
<div class="flex sm8 xl8 md8 xs8 px-0 mx-0">
<va-input
@keyup.enter="itemChange(windowSize)"
@blur="itemChange(windowSize)"
v-model="windowSize"
class="mb-0"
>
<p slot="append" style="margin-right: 0;" small>
µs
</p>
</va-input>
</div>
</div>
</template>
<script>
import { mapFields } from 'vuex-map-fields'
export default {
name: 'ChangeWindowSize',
components: {
},
computed: {
...mapFields('replay', [
'startTimeCurrent',
'endTimeCurrent',
'windowSize',
]),
},
props: {
},
created () {
},
data () {
return {
}
},
mqtt: {
},
methods: {
itemChange (val) {
this.windowSize = parseInt(val)
// this.endTimeCurrent = this.startTimeCurrent + parseInt(val)
// this.$emit('reDraw')
},
},
async mounted () {
},
destroyed () {
},
watch: {
},
}
</script>
@@ -0,0 +1,95 @@
<template>
<div class="row flex sm12 xl12 md12 xs12 align--center my-0 py-0">
<div class="flex sm6 xl6 md6 xs6 px-0 mx-0">
Window Start
<va-input
@mouseleave.native="itemChange(startTime)"
@keyup.enter="itemChange(startTime)"
@blur="itemChange(startTime)"
v-model="startTime"
class="mb-0 flex-child"
>
<p slot="append" style="margin-right: 0;" small>
µs
</p>
</va-input>
</div>
<div class="flex sm6 xl6 md6 xs6 px-0 mx-0">
Window Size
<va-input
@mouseleave.native="itemChange(windowLength)"
@keyup.enter="itemChange(windowLength)"
@blur="itemChange(windowLength)"
v-model="windowLength"
class="mb-0 flex-child"
>
<p slot="append" style="margin-right: 0;" small>
µs
</p>
</va-input>
</div>
</div>
</template>
<script>
import { mapFields } from 'vuex-map-fields'
export default {
name: 'change-window-start-and-size',
components: {
},
props: {
},
computed: {
...mapFields('replay', [
'startTime',
'endTime',
'windowLength',
]),
},
created () {
},
data () {
return {
}
},
mqtt: {
},
methods: {
init () {
this.windowLength = parseInt(this.endTime) - parseInt(this.startTime)
},
itemChange (val) {
this.startTime = parseInt(this.startTime)
this.windowLength = parseInt(this.windowLength)
this.endTime = this.startTime + this.windowLength
this.$emit('changeOverviewDataZoom')
},
},
async mounted () {
},
destroyed () {
},
watch: {
},
}
</script>
<style lang="scss">
.flex-container {
display: flex;
}
.flex-child {
flex: 2;
}
.flex-child2 {
flex: 0;
}
.flex-child:first-child {
margin-right: 1px;
}
</style>
@@ -0,0 +1,60 @@
<template>
<div>
<va-button :icon="icon" @click="lockDataZoom"/>
</div>
</template>
<script>
import { mapMutations } from 'vuex'
import types from '@/store/modules/analysis/replay/types'
import { mapFields } from 'vuex-map-fields'
export default {
name: 'lock-data-zoom',
components: {
},
props: {
chartID: {
type: Number, // detail data
default: 0,
},
},
created () {
},
data () {
return {
icon: 'fa fa-unlock',
}
},
computed: {
...mapFields('replay', [
'chartData',
'isLockDataZoom',
]),
},
watch: {
},
methods: {
lockDataZoom () {
this.isLockDataZoom = !this.isLockDataZoom
this.lockDataZoomChart({
chartAllData: this.chartData,
chartID: 0,
zoomLock: this.isLockDataZoom,
})
if (this.isLockDataZoom === true) {
this.icon = 'fa fa-lock'
} else if (this.isLockDataZoom === false) {
this.icon = 'fa fa-unlock'
}
},
...mapMutations('replay', [types.chart.lockDataZoom]),
},
mounted () {
},
destroyed () {
},
}
</script>
@@ -0,0 +1,62 @@
<template>
<div>
<span class="box_inline-block"> use SD card data </span>
<va-toggle :disable="disableToggle" flat small class="box_inline-block" v-model="useSdCardData"/>
</div>
</template>
<script>
import { mapFields } from 'vuex-map-fields'
export default {
name: 'SdCardToggle',
components: {
},
computed: {
...mapFields('replay', [
'metaList',
'useSdCardData',
]),
},
props: {
metaIndex: {
type: Number,
default: 0,
},
},
created () {
},
data () {
return {
disableToggle: true,
}
},
mqtt: {
},
methods: {
init () {
if (this.metaList[this.metaIndex].sd_data_uploaded === true) {
this.disableToggle = false
} else {
this.disableToggle = true
this.useSdCardData = false
}
},
},
async mounted () {
},
destroyed () {
},
watch: {
},
}
</script>
<style lang="scss">
.box_inline-block {
padding: 1px;
margin: 1px;
display: inline-block;
}
</style>
@@ -49,34 +49,54 @@ export default {
neuliveSampleRateOptions: [
{
id: 0,
value: 800,
value: 1000,
description: '1k',
},
{
id: 1,
value: 400,
value: 2000,
description: '2k',
},
{
id: 2,
value: 200,
value: 4000,
description: '4k',
},
{
id: 3,
value: 160,
value: 5000,
description: '5k',
},
{
id: 4,
value: 100,
value: 8000,
description: '8k',
},
{
id: 5,
value: 80,
value: 10000,
description: '10k',
},
{
id: 6,
value: 20000,
description: '20k',
},
{
id: 7,
value: 40000,
description: '40k',
},
{
id: 8,
value: 80000,
description: '80k',
},
{
id: 9,
value: 100000,
description: '100k',
},
],
stimulateElectrodeOptions: [
{
@@ -283,7 +303,7 @@ export default {
if (!(key.includes('sti') || key.includes('STI'))) {
let showKey = ''
let showValue = value
if (key === 'RECORDING_CH' || key === 'AXIS_CH' || key === 'AMP_GAIN' || key === 'ADC_CLOCK') {
if (key === 'RECORDING_CH' || key === 'AXIS_CH' || key === 'AMP_GAIN' || key === 'SAMPLE_RATE') {
if (key === 'RECORDING_CH') {
showKey = 'Channels'
// convert decimal to binary
@@ -328,7 +348,7 @@ export default {
showValue = this.ampGainOptions[i].description
}
}
} else if (key === 'ADC_CLOCK') {
} else if (key === 'SAMPLE_RATE') {
showKey = 'Sample Rate'
for (let i = 0; i < this.neuliveSampleRateOptions.length; i++) {
if (this.neuliveSampleRateOptions[i].value === value) {
+22 -3
View File
@@ -7,6 +7,7 @@
<p :style="{color: this.$themes.primary}" class="display-6"> High pass filter </p>
<cutoff-freq/>
<filter-order/>
<filter-button ref="filterButtonRef" @loadFilterData="loadFilterData"/>
<p :style="{color: this.$themes.danger}" class="display-6"> Threshold </p>
<threshold/>
<br/>
@@ -14,7 +15,7 @@
<wave-length/>
<prethreshold/>
<refractory-period/>
<detect-button @loadChartData="loadChartData"/>
<detect-button ref="detectButtonRef" @loadThresholdData="loadThresholdData"/>
</va-card>
</div>
</template>
@@ -28,6 +29,7 @@ import RefractoryPeriod from '@/components/analysis/spike/item/RefractoryPeriod.
import Threshold from '@/components/analysis/spike/item/Threshold.vue'
import WaveLength from '@/components/analysis/spike/item/WaveLength.vue'
import DetectButton from '@/components/analysis/spike/item/DetectButton.vue'
import FilterButton from '@/components/analysis/spike/item/FilterButton.vue'
export default {
name: 'control-panel',
@@ -35,6 +37,7 @@ export default {
Channels,
CutoffFreq,
FilterOrder,
FilterButton,
Prethreshold,
RefractoryPeriod,
Threshold,
@@ -53,12 +56,28 @@ export default {
},
methods: {
init () {
this.enableFilterButton()
},
refreshChart (options) {
this.$emit('refreshChart', options)
},
loadChartData () {
this.$emit('loadChartData')
loadThresholdData () {
this.$emit('loadThresholdData')
},
loadFilterData () {
this.$emit('loadFilterData')
},
enableFilterButton () {
this.$refs.filterButtonRef.enableButton()
},
disableFilterButton () {
this.$refs.filterButtonRef.disableButton()
},
enableDetectButton () {
this.$refs.detectButtonRef.enableButton()
},
disableDetectButton () {
this.$refs.detectButtonRef.disableButton()
},
},
// use watch because va-select with @change will have bug
+200 -119
View File
@@ -9,7 +9,11 @@
<span slot="header">Control Panel</span>
<div slot="body">
<div>
<control-panel :ref="'control_panel'" @loadChartData="drawSpikeData"/>
<control-panel
:ref="'control_panel'"
@loadFilterData="loadFilterData"
@loadThresholdData="loadThresholdData"
/>
</div>
</div>
</va-collapse>
@@ -55,6 +59,7 @@ export default {
'metaList',
'selectedChannel',
'cutoffFreq',
'filterOrder',
'selectedThreshold',
'upperThreshold',
'lowerThreshold',
@@ -88,11 +93,63 @@ export default {
dataInfo: {},
maxTime: 0,
chartAreaClass: ['flex', 'xs12', 'sm12', 'md12', 'xl9', 'pa-0'],
randomColorArray: [],
controllerList: [],
}
},
mqtt: {
async '+/analysis/spike_detect/+/+/+' (data, topic) {
const topicSplitArray = topic.split('/')
if (this.metaList.some(e => e.id === parseInt(topicSplitArray[4]))) {
if (topicSplitArray[3] === 'data') {
const utf8decoder = new TextDecoder()
const dataStr = utf8decoder.decode(data)
const dataArray = JSON.parse(dataStr)
this.chartOverviewData.series[0].data.push(...dataArray)
} else if (topicSplitArray[3] === 'time_mark') {
const utf8decoder = new TextDecoder()
const timeMarkStr = utf8decoder.decode(data)
const timeMarkObj = timeMarkStr.split(' ')
this.drawTimeMark(timeMarkObj)
} else if (topicSplitArray[3] === 'detect_signal') {
const utf8decoder = new TextDecoder()
const detectSignalStr = utf8decoder.decode(data)
const detectSignalObj = Object.values(JSON.parse(detectSignalStr))
this.drawThresholdData(detectSignalObj)
}
}
},
},
methods: {
getControllerList: async function () {
const update = async () => {
this.controllerList.push({
id: 'tommy_test',
mac: '',
status: 'loading',
isScan: true,
})
}
await update()
},
mqttSub: function (val) {
this.$mqtt.subscribe(val)
},
mqttUnSub: function (val) {
this.$mqtt.unsubscribe(val)
},
mqttPub: function (topic, mes) {
this.$mqtt.publish(topic, mes)
},
pageMqttSub: function (id) {
this.mqttSub(id + '/analysis/spike_detect/+/+/+')
},
pageMqttUnSub: function (id) {
this.mqttUnSub(id + '/analysis/spike_detect/+/+')
},
showChartLoading: function (chart) {
const loadStyle = {
text: '',
@@ -179,23 +236,40 @@ export default {
})
}
this.updateChartSamplingChart({ chartID: this.chartOverviewData.chartID, seriesIndex: 0, method: function (frame) { return frame[0] } })
// this.updateChartSamplingChart({ chartID: this.chartOverviewData.chartID, seriesIndex: 0, method: function (frame) { return frame[0] } })
this.chartOverviewData.xAxis[0].min = 0
this.chartOverviewData.xAxis[0].max = this.maxTime
},
drawSpikeData: async function () {
loadFilterData: async function () {
this.showChartLoading('overview')
this.showChartLoading('detail')
for (const meta in this.dataInfo) {
let metaInfo
this.metaList.forEach(_meta => {
if (parseInt(_meta.id) === parseInt(meta)) {
metaInfo = _meta
}
})
const sampleRate = (800000 / metaInfo.parameter_set.ADC_CLOCK) / JSON.parse(metaInfo.channels).length // Hz
const period = 1e6 / sampleRate
this.$refs.chart_detail.clear()
this.$refs.control_panel.disableDetectButton()
for (const meta in this.dataInfo) {
// reset overview chart
this.chartOverviewData.series[0].data.length = 0
this.chartOverviewData.series[0].markArea.data.length = 0
this.chartOverviewData.color = ['#000000'] // black
await api.analysis.spikeDetect({
controller_id: this.controllerList[0].id,
meta_id: meta,
channel: this.selectedChannel,
filter_order: this.filterOrder,
cut_off_freq: this.cutoffFreq,
data_type: 'filter_data',
})
this.hideChartLoading('overview')
this.$refs.control_panel.enableDetectButton()
console.log(this.chartOverviewData)
}
},
loadThresholdData: async function () {
this.showChartLoading('detail')
for (const meta in this.dataInfo) {
let thresholdValue
if (this.selectedThreshold === 'over') {
thresholdValue = this.upperThreshold
@@ -203,117 +277,120 @@ export default {
thresholdValue = this.lowerThreshold
}
const randomColorArray = []
// [Region] whole processed signal
const allSpikeData = await api.analysis.spikeDetect({
id: meta,
channel: this.selectedChannel,
cut_off_freq: this.cutoffFreq,
threshold: [
`'${this.selectedThreshold}'`,
thresholdValue,
],
waveForm: [this.waveLength, this.preThreshold, this.refractoryPeriod],
ret_data_type: 'all',
})
this.chartOverviewData.series[0].data.length = 0
this.chartOverviewData.color = ['#000000'] // black
const splitData = allSpikeData.data.split('\n')
const allTimeArray = splitData[0].split(' ')
const allTimeArrayLength = allTimeArray.length
const allSignalArray = splitData[1].split(' ')
const allTimeMarkIndexArray = splitData[2].split(' ')
for (let i = 0; i < allTimeArrayLength; i++) {
this.chartOverviewData.series[0].data.push([parseInt(allTimeArray[i]), allSignalArray[i]])
}
this.chartOverviewData.xAxis[0].min = parseInt(allTimeArray[0])
this.chartOverviewData.xAxis[0].max = parseInt(allTimeArray[allTimeArrayLength - 1])
this.chartOverviewData.xAxis[0].axisLabel.show = true
this.chartOverviewData.series[0].markArea.data.length = 0
for (let i = 0; i < allTimeMarkIndexArray.length; i++) {
// generate color array for overview markArea and detail chart series
const randomColor = '#' + Math.floor(Math.random() * 16777215).toString(16) // ref: https://css-tricks.com/snippets/javascript/random-hex-color/
randomColorArray.push(randomColor)
if (Number.isInteger(parseInt(allTimeMarkIndexArray[i]))) { // cuz maybe is '' if no any match after filtering
const timeMarkIndex = parseInt(allTimeMarkIndexArray[i])
const start = parseInt(this.chartOverviewData.series[0].data[timeMarkIndex - parseInt(this.preThreshold / period)][0])
const end = parseInt(this.chartOverviewData.series[0].data[timeMarkIndex + parseInt(this.refractoryPeriod / period)][0])
this.chartOverviewData.series[0].markArea.data.push([
{
itemStyle: {
color: randomColor,
},
name: String(i + 1),
xAxis: start,
},
{
xAxis: end,
},
])
}
}
// [EndRegion]
// [Region] each detailed signal piece
const spikeData = await api.analysis.spikeDetect({
id: meta,
channel: this.selectedChannel,
cut_off_freq: this.cutoffFreq,
threshold: [
`'${this.selectedThreshold}'`,
thresholdValue,
],
waveForm: [this.waveLength, this.preThreshold, this.refractoryPeriod],
ret_data_type: 'partial',
})
for (let i = 0; i < this.chartDetailData.series.length; i++) {
this.chartDetailData.series[i].name = ''
this.chartDetailData.series[i].data.length = 0
}
const detailSignalArray = Object.values(spikeData.data)
if (detailSignalArray.length <= 8) {
this.chartDetailData.tooltip.show = true
} else {
this.chartDetailData.tooltip.show = false
}
this.chartDetailData.legend.data.length = 0
this.chartDetailData.legend.type = 'scroll'
this.chartDetailData.legend.top = '0.25%'
// this.chartDetailData.legendpageButtonPosition = 'start'
this.chartDetailData.animation = false
this.chartDetailData.color = []
for (let i = 0; i < detailSignalArray.length; i++) {
const detailSignal = detailSignalArray[i].split(' ')
const arrayLength = detailSignal.length
const step = parseInt(this.waveLength) / (arrayLength - 1)
const xAxisIndex = 0
const yAxisIndex = 0
const legendName = 'T_' + String(i + 1)
if (this.chartDetailData.series.length <= i) {
const _series = newSeries('line', legendName, xAxisIndex, yAxisIndex, [-1, -1], [metaInfo.name, this.selectedChannel], null, null)
this.chartDetailData.series.push(_series)
}
for (let j = 0; j < arrayLength; j++) {
this.chartDetailData.series[i].data.push([j * step, detailSignal[j]])
}
// push legendName
this.chartDetailData.legend.data.push(legendName)
this.chartDetailData.series[i].name = legendName
// set legend and series color
this.chartDetailData.color.push(randomColorArray[i])
}
this.chartDetailData.xAxis[0].min = 0
this.chartDetailData.xAxis[0].max = parseInt(this.waveLength)
this.chartDetailData.xAxis[0].axisLabel.show = true
// [EndRegion]
await api.analysis.spikeDetect({
controller_id: this.controllerList[0].id,
meta_id: meta,
channel: this.selectedChannel,
cut_off_freq: this.cutoffFreq,
filter_order: this.filterOrder,
threshold: [
`'${this.selectedThreshold}'`,
thresholdValue,
],
waveForm: [this.waveLength, this.preThreshold, this.refractoryPeriod],
ret_data_type: 'threshold_data',
})
}
this.hideChartLoading('detail')
},
drawThresholdData (detailSignalArray) {
if (detailSignalArray.length <= 8) {
this.chartDetailData.tooltip.show = true
} else {
this.chartDetailData.tooltip.show = false
}
this.chartDetailData.legend.data.length = 0
this.chartDetailData.legend.type = 'scroll'
this.chartDetailData.legend.top = '0.25%'
// this.chartDetailData.legendpageButtonPosition = 'start'
this.chartDetailData.animation = false
this.chartDetailData.color = []
for (let i = 0; i < detailSignalArray.length; i++) {
const detailSignal = detailSignalArray[i].split(' ')
const arrayLength = detailSignal.length
const step = parseInt(this.waveLength) / (arrayLength - 1)
const xAxisIndex = 0
const yAxisIndex = 0
const legendName = 'T_' + String(i + 1)
if (this.chartDetailData.series.length <= i) {
const _series = newSeries('line', legendName, xAxisIndex, yAxisIndex, [-1, -1], ['metaInfo.name', this.selectedChannel], null, null)
this.chartDetailData.series.push(_series)
}
for (let j = 0; j < arrayLength; j++) {
this.chartDetailData.series[i].data.push([j * step, detailSignal[j]])
}
// push legendName
this.chartDetailData.legend.data.push(legendName)
this.chartDetailData.series[i].name = legendName
// set legend and series color
this.chartDetailData.color.push(this.randomColorArray[i])
}
this.chartDetailData.xAxis[0].min = 0
this.chartDetailData.xAxis[0].max = parseInt(this.waveLength)
this.chartDetailData.xAxis[0].axisLabel.show = true
},
drawTimeMark (timeMarkArray, period) {
// reset overview
this.chartOverviewData.series[0].markArea.data.length = 0
const timeMarkLength = timeMarkArray.length
for (let i = 0; i < timeMarkLength; i++) {
// generate color array for overview markArea and detail chart series
const randomColor = '#' + Math.floor(Math.random() * 16777215).toString(16) // ref: https://css-tricks.com/snippets/javascript/random-hex-color/
this.randomColorArray.push(randomColor)
if (Number.isInteger(parseInt(timeMarkArray[i]))) { // cuz maybe is '' if no any match after filtering
const timeMark = parseInt(timeMarkArray[i])
let startTime = timeMark - parseInt(this.preThreshold)
let endTime = timeMark + parseInt(this.refractoryPeriod)
if (startTime < 0) {
startTime = 0
}
if (endTime > timeMark) {
endTime = timeMark
}
const overviewSignal = this.chartOverviewData.series[0].data
let startIndex = 0
let endIndex = 0
for (let i = 0; i < overviewSignal.length; i++) {
if (startTime <= overviewSignal[i][0]) {
startIndex = i
break
}
}
for (let i = 0; i < overviewSignal.length; i++) {
if (endTime <= overviewSignal[i][0]) {
endIndex = i
break
}
}
this.chartOverviewData.series[0].markArea.data.push([
{
itemStyle: {
color: randomColor,
borderColor: randomColor,
borderWidth: 1,
},
name: String(i + 1),
xAxis: overviewSignal[startIndex][0],
},
{
xAxis: overviewSignal[endIndex][0],
},
])
}
}
this.hideChartLoading()
console.log(this.chartOverviewData)
console.log(this.chartDetailData)
},
...mapActions('spike', [types.chart.init, types.chart.initSelectedChannel, types.chart.register, types.chart.clear, types.chart.updateGridList, types.chart.updateDataZoom]),
...mapActions('spike', [types.meta.init]),
@@ -329,6 +406,9 @@ export default {
watch: {
},
async mounted () {
this.getControllerList()
this.pageMqttSub(this.controllerList[0].id)
const metaIDList = this.$route.params.metaList.split('-')
await this.initMeta({ metaIDList: metaIDList, api: api })
this.metaList = this.getAllMeta()
@@ -341,6 +421,7 @@ export default {
this.$refs.control_panel.init()
},
beforeDestroy () {
this.pageMqttUnSub(this.controllerList[0].id)
this.$refs.chart_detail.clear()
for (const id in this.chartData) {
for (const _series of this.chartData[id].series) {
@@ -1,6 +1,6 @@
<template>
<div>
<va-button class="right" small @click="startDetect">
<va-button class="right" small @click="startDetect" :disabled="isDisable">
Start Detect
</va-button>
</div>
@@ -29,13 +29,20 @@ export default {
},
data () {
return {
isDisable: true,
}
},
mqtt: {
},
methods: {
startDetect () {
this.$emit('loadChartData')
this.$emit('loadThresholdData')
},
enableButton () {
this.isDisable = false
},
disableButton () {
this.isDisable = true
},
...mapMutations('spike', [types.chart.updateAxisLabel]),
},
@@ -0,0 +1,56 @@
<template>
<div class="flex xl12 md12 sm12 xs12 mb-4">
<va-button class="right" small @click="startFilter" :disabled="isDisable">
Start Filter
</va-button>
</div>
</template>
<script>
import types from '@/store/modules/analysis/spike/types'
import { mapFields } from 'vuex-map-fields'
import { mapMutations } from 'vuex'
export default {
name: 'FilterButton',
components: {
},
computed: {
...mapFields('spike', [
'chartDetailData',
'selectedChannel',
'waveLength',
]),
},
props: {
},
created () {
},
data () {
return {
isDisable: true,
}
},
mqtt: {
},
methods: {
startFilter () {
this.$emit('loadFilterData')
},
enableButton () {
this.isDisable = false
},
disableButton () {
this.isDisable = true
},
...mapMutations('spike', [types.chart.updateAxisLabel]),
},
async mounted () {
},
destroyed () {
},
watch: {
},
}
</script>
@@ -0,0 +1,54 @@
<template>
<va-card
class="horizontal-bars"
>
<div class="row">
<div class="flex md12 xs12">
<va-progress-bar
:value="progressValue"
>
{{ progressValue }} %
</va-progress-bar>
</div>
</div>
</va-card>
</template>
<script>
export default {
name: 'progress-bar',
data () {
return {
progressValue: 0,
timeInterval: null,
}
},
props: {
// unit: sec
time: {
type: String,
required: true,
},
},
methods: {
animateValues () {
this.timeInterval = setInterval(() => {
this.progressValue += 1
if (this.progressValue === 99) {
clearInterval(this.timeInterval)
}
}, parseInt(this.time * 10))
},
progressDone () {
this.progressValue = 100
},
},
mounted () {
this.animateValues()
},
destroyed () {
clearInterval(this.timeInterval)
},
}
</script>
@@ -0,0 +1,52 @@
<template>
<va-modal
class="flex sm12 xl12 md12 xs12"
v-model="showProgressModal"
size="small"
:title="title"
hide-default-actions
>
<progressBar
:time="time"
:ref="'progressBarRef'"
/>
</va-modal>
</template>
<script>
import progressBar from '@/components/common/progressBarModal/progressBar.vue'
export default {
name: 'progress-bar-modal',
components: {
progressBar,
},
props: {
title: {
type: String,
default: '',
},
// unit: sec
time: {
type: String,
required: true,
},
},
data () {
return {
showProgressModal: false,
}
},
methods: {
show () {
this.showProgressModal = true
},
hide () {
this.showProgressModal = false
},
progressDone () {
this.$refs.progressBarRef.progressDone()
this.hide()
},
},
}
</script>
@@ -189,6 +189,7 @@ export default {
battery: device.battery,
library_name: device.library_name,
library_version: device.library_version,
record_in_sd: device.record_in_sd,
status: device.status,
pic: taskInfo.getDevicePic(device.device_name),
loading: false,
+18 -7
View File
@@ -60,6 +60,7 @@ export default {
...mapActions('download',
[
types.raw.rawDataByID,
types.raw.rawSdDataByID,
types.export.setHeader,
types.export.setTitle,
types.export.setData,
@@ -81,6 +82,7 @@ export default {
// TODO authorization
const format = this.$route.params.format
this.metaList = this.$route.params.metaList.split('-')
const sd = this.$route.params.sd
while (this.metaList.length !== 0) {
let meta
@@ -117,7 +119,7 @@ export default {
this.downloadInfo.device = [meta.device.library_name.slice(0, 7), meta.device.library_name.slice(7)]
if (this.downloadInfo.channel.some(el => el >= 256 && el <= 259)) {
this.downloadInfo.filename = meta.name + '-accerlate-' + format
this.downloadInfo.size = parseInt(parseInt(meta.size) / 78)
this.downloadInfo.size = parseInt(parseInt(meta.size) / 76)
} else {
this.downloadInfo.filename = meta.name + '-' + format
this.downloadInfo.size = parseInt(meta.size)
@@ -159,12 +161,21 @@ export default {
const rawID = this.downloadInfo.channelInfo[channel].downloadIDList[_idx][rowIndex]
// console.log(rowIndex, _idx, rawID)
if (rawID !== undefined) {
await this.rawDataByIDRaw({
channel: channel,
rawID: rawID,
idx: _idx,
api: api,
})
if (sd === 'sd') {
await this.rawSdDataByIDRaw({
channel: channel,
rawID: rawID,
idx: _idx,
api: api,
})
} else {
await this.rawDataByIDRaw({
channel: channel,
rawID: rawID,
idx: _idx,
api: api,
})
}
}
}
}
+49 -8
View File
@@ -173,17 +173,30 @@
{{transDeviceInfo(props.rowData.configuration)}}
</template>
<template slot="actions" slot-scope="props" >
<va-popover :message="`sdcard ${props.rowData.name}`" placement="top">
<sd-card-button
v-if="props.rowData.type !== 'folder' && props.rowData.device.library_name.indexOf('Neulive') >= 0 && SDuuidList.includes(props.rowData.uuid)"
:meta="props.rowData"
:uuidList="SDuuidList"
:controller="controllerList[0]"
@refreshPage="refreshPage"
@downloadSdCard="downloadSdCard"
/>
</va-popover>
<va-popover :message="`download ${props.rowData.name} in csv format`" placement="top">
<va-button flat small color="gray" icon="fa fa-download" v-if="props.rowData.type !== 'folder' && props.rowData.device.library_name.indexOf('Neulive') >= 0" @click.stop="downloadCsv(props.rowData)"/>
</va-popover>
<va-popover :message="`download ${props.rowData.name} in excel format`" placement="top">
<va-button flat small color="gray" icon="fa fa-download" v-if="props.rowData.type !== 'folder'" @click.stop="downloadExcel(props.rowData)"/>
<va-button flat small color="gray" icon="fa fa-download" v-if="props.rowData.type !== 'folder' && props.rowData.device.library_name.indexOf('Elite') >= 0" @click.stop="downloadExcel(props.rowData)"/>
</va-popover>
<va-popover :message="`download ${props.rowData.name} in csv-edf format`" placement="top">
<va-button flat small color="gray" icon="fa fa-download" v-if="props.rowData.type !== 'folder' && props.rowData.device.library_name.indexOf('Neulive') >= 0" @click.stop="downloadExcel(props.rowData)"/>
</va-popover>
<va-popover :message="`replay ${props.rowData.name}`" placement="top">
<va-button flat small color="gray" icon="fa fa-eye" v-if="props.rowData.type !== 'folder'" @click.stop="replay(props.rowData)"/>
</va-popover>
<va-popover :message="`spike ${props.rowData.name}`" placement="top">
<va-button flat small color="gray" icon="fa fa-filter" v-if="props.rowData.type !== 'folder'" @click.stop="spike(props.rowData)"/>
<va-button flat small color="gray" icon="fa fa-filter" v-if="props.rowData.type !== 'folder' && props.rowData.device.library_name.indexOf('Neulive') >= 0" @click.stop="spike(props.rowData)"/>
</va-popover>
<va-popover :message="`edit ${props.rowData.name}`" placement="top">
<va-button flat small color="gray" icon="fa fa-pencil" @click.stop="editFileConfirm(props.rowData)"/>
@@ -202,16 +215,18 @@ import { debounce } from 'lodash'
import { file } from '../../../data/file/File'
import { FulfillingBouncingCircleSpinner } from 'epic-spinners'
import api from '../../../data/api/index'
import SdCardButton from '../sdcard/SdCardButton.vue'
export default {
name: 'FileTable',
components: {
FulfillingBouncingCircleSpinner,
SdCardButton,
},
data () {
return {
term: null,
perPage: '160',
perPage: '80',
perPageOptions: ['20', '40', '80', '160'],
fileLists: [],
@@ -258,6 +273,8 @@ export default {
height: '2rem',
},
},
SDuuidList: [],
controllerList: [],
}
},
computed: {
@@ -313,7 +330,7 @@ export default {
{
name: '__slot:actions',
dataClass: 'text-right',
width: '20%',
width: '25%',
},
]
},
@@ -658,6 +675,25 @@ export default {
window.open('http://' + href + '/#/download/csv-edf/' + meta.id)
}
},
downloadSdCard: async function (meta) {
const href = location.href.split('/')[2]
if (meta.device.library_name.indexOf('Neulive') >= 0) {
window.open('http://' + href + '/#/download/csv/' + meta.id + '/sd')
}
},
async getSDuuidList () {
// const uuidList = ['32abdb14-fc0c-11eb-9aa8-dca6326cbc6b', '940ca938-f662-11eb-8a41-dca6326cbc6b']
if (this.controllerList.length > 0) {
if (this.controllerList[0].sd_uploading === false) {
api.sdcard.getuuidList().then((response) => {
console.log('uuidList', response)
this.SDuuidList = response.split(' ')
}).catch(error => {
console.log(error)
})
}
}
},
replay: function (meta) {
if (meta.device.library_name.includes('Neulive') === true) {
// window.open('http://' + location.href.split('/')[2].split(':')[0] + '/#/admin/data-replay/' + meta.id)
@@ -672,12 +708,17 @@ export default {
}
},
spike: function (meta) {
this.$router.push({
path: '/admin/data-spike/' + meta.id,
})
if (meta.device.library_name.includes('Neulive') === true) {
this.$router.push({
path: '/admin/data-spike/' + meta.id,
})
}
},
},
mounted () {
async mounted () {
const controllerList = await api.controller.getAll()
this.controllerList = controllerList.data
this.getSDuuidList()
},
destroyed () {
},
@@ -0,0 +1,87 @@
<template>
<div/>
</template>
<script>
import { apiManager } from './apiManager'
export default {
name: 'SdCardApiAction',
components: {
},
props: {
},
data () {
return {
metaID: '',
mac_address: '',
uuid: '',
}
},
mqtt: {
},
methods: {
initMetaInfo (meta) {
this.metaID = meta.id
// bytes array to hex string formamt
this.mac_address = meta.device.device_address.map(data =>
data.toString(16)
.padStart(2, '0')
.toUpperCase()).join(':')
this.uuid = meta.uuid
},
// async checkInSD (meta) {
// this.initMetaInfo(meta)
// this.pageToast('Start checking in SD card...')
// apiManager.startProgressBar()
// const result = await apiManager.call('Check_in_SD', this.metaID, this.mac_address, this.uuid)
// this.checkSDresult = result.data
// this.pageToast('In SD card: ' + this.checkSDresult)
// apiManager.endProgressBar()
// return result.data
// },
async moveToDB (meta, controller) {
this.initMetaInfo(meta)
this.pageToast('Start Moving to database...')
apiManager.startProgressBar()
await apiManager.call('Move_to_DB', controller.id, this.metaID, this.mac_address, this.uuid)
apiManager.endProgressBar()
},
async deleteSDCard (meta, controller) {
this.initMetaInfo(meta)
this.pageToast('Start deleting in SD card...')
apiManager.startProgressBar()
await apiManager.call('Delete_SD', controller.id, this.metaID, this.mac_address, this.uuid)
apiManager.endProgressBar()
},
pageToast: function (mes) {
this.showToast(
mes,
{
icon: 'fa-bell',
position: 'bottom-right',
duration: 4000,
},
)
},
},
async mounted () {
},
destroyed () {
},
watch: {
},
}
</script>
<style lang="scss">
#nprogress .bar {
background: red;
}
#nprogress .spinner-icon {
border-top-color: red;
border-left-color: red;
}
</style>
+126
View File
@@ -0,0 +1,126 @@
<template>
<div>
<!-- recorded = false, no icon; recorded = true, gray icon; uploaded = true, blue icon; in uuid list: gray icon + red exclam -->
<va-button
class="va-button--with-left-icon va-button--without-title"
v-show="meta.sd_data_record === true"
:icon="meta.sd_data_uploaded === true ? 'fa fa-download' : ''"
:color="this.$themes.primary"
@click.stop="performButtonAction()"
flat
small
>
<va-icon
v-if="meta.sd_data_uploaded === false"
class="va-button__content__icon va-button__content__icon-left"
name="material-icons"
color="grey"
@click.native.stop="performButtonAction()"
small
fixed-width
> sd_card
</va-icon>
</va-button>
<sd-card-api-action :ref="'sd_card_api'"/>
<va-modal
class="flex sm12 xl12 md12 xs12"
v-model="moveToDBModal"
size="small"
:title="'UPLOAD SD CARD DATA'"
:okText=" $t('modal.confirm') "
@ok="moveToDB()"
/>
<progress-modal
title="SD card data uploading"
:time="(parseInt(meta.time_duration) / 2e6).toString()"
:ref="'progressModalRef'"
/>
</div>
</template>
<script>
import SdCardApiAction from './SdCardApiAction.vue'
import progressModal from '@/components/common/progressBarModal/progressModal.vue'
export default {
name: 'SdCardButton',
components: {
SdCardApiAction,
progressModal,
},
props: {
controller: {
type: Object,
required: true,
},
uuidList: {
type: Array,
required: true,
},
meta: {
type: Object,
required: true,
},
},
data () {
return {
isSdCardDataLoaded: false,
moveToDBModal: false,
checkSDresult: '',
metaID: '',
mac_address: '',
uuid: '',
icon: 'fa fa-usb',
}
},
mqtt: {
},
methods: {
init () {
this.metaID = this.meta.id
this.mac_address = this.meta.device.device_address.map(data =>
data.toString(16)
.padStart(2, '0')
.toUpperCase()).join(':')
this.uuid = this.meta.uuid
},
async performButtonAction () {
const recorded = this.meta.sd_data_record // true or false
const uploaded = this.meta.sd_data_uploaded // true or false
if (recorded === true) {
if (uploaded !== true) {
this.moveToDBModal = true
} else {
this.executeDownload()
}
}
},
async moveToDB () {
this.$refs.progressModalRef.show()
await this.executeUpload()
this.$emit('refreshPage')
},
// async executeCheckInSD () {
// return await this.$refs.sd_card_api.checkInSD(this.meta)
// },
async executeUpload () {
await this.$refs.sd_card_api.moveToDB(this.meta, this.controller)
this.$refs.progressModalRef.progressDone()
// remove delete sd card first, still have problem.
// await this.$refs.sd_card_api.deleteSDCard(this.meta, this.controller)
},
executeDownload () {
this.$emit('downloadSdCard', this.meta)
},
},
async mounted () {
this.init()
},
watch: { // cuz data table will not call mounted
meta: function (val) {
this.init()
},
},
}
</script>
+35
View File
@@ -0,0 +1,35 @@
import api from '@/data/api/index'
import nProgress from 'nprogress'
export const apiManager = {
call: async (instruction, controllerID, metaID, macAddress, uuid) => {
if (instruction === 'Check_in_SD') {
return await api.sdcard.exist({
controllerID: controllerID,
metaID: metaID,
mac: macAddress,
uuid: uuid,
})
} else if (instruction === 'Delete_SD') {
return await api.sdcard.deleted({
controllerID: controllerID,
metaID: metaID,
mac: macAddress,
uuid: uuid,
})
} else if (instruction === 'Move_to_DB') {
return await api.sdcard.upload({
controllerID: controllerID,
metaID: metaID,
mac: macAddress,
uuid: uuid,
})
}
},
startProgressBar: () => {
nProgress.start()
},
endProgressBar: () => {
nProgress.done()
},
}
+2 -2
View File
@@ -47,7 +47,7 @@
import { mapActions, mapGetters, mapMutations } from 'vuex'
import api from '@/data/api/index'
import types from '@/store/modules/setting/types'
import eliteImgUrl from '@/assets/img/elite_img.png'
import controllerImgUrl from '@/assets/img/controller.png'
export default {
name: 'controller-info',
@@ -90,7 +90,7 @@ export default {
},
methods: {
getImageUrl () {
return eliteImgUrl
return controllerImgUrl
},
...mapActions('setting', [types.controller.init]),
...mapMutations('setting', [types.controller.set, types.controller.updateByIndex]),
+14 -7
View File
@@ -1,9 +1,10 @@
<template>
<div class="device-info">
<div class="row flex">
<draggable class="flex d-flex sm12 xl12 md12 xs12" v-model="devicesList" @start="drag=true" @end="drag=false" >
<div class="flex-wrap-setting sm12 xl12 md12 xs12">
<!-- <draggable class="flex d-flex sm12 xl12 md12 xs12" v-model="devicesList" @start="drag=true" @end="drag=false" > -->
<div
class="flex d-flex sm12 xl3 md4 xs12 ma-0 area-style-setting-device "
class="flex d-flex sm12 xl3 md6 xs12 ma-0"
v-for="(device, index) in devicesList" :key="device.id"
>
<va-card
@@ -30,7 +31,7 @@
<p> {{ device.name }} </p>
</div>
<div class="center-medium">
<p> {{ macArrayToString(device.mac_address) }} </p>
<p> {{ device.mac_address }} </p>
</div>
<div class="mt-4 mb-4" style="text-align: center;">
<img
@@ -52,7 +53,8 @@
</div>
</va-card>
</div>
</draggable>
</div>
<!-- </draggable> -->
</div>
</div>
</template>
@@ -62,13 +64,12 @@ import { mapFields } from 'vuex-map-fields'
import api from '@/data/api/index'
import types from '@/store/modules/setting/types'
import neuliveImgUrl from '@/assets/img/neulive_img.png'
import eliteImgUrl from '@/assets/img/elite_img.png'
import draggable from 'vuedraggable'
import eliteImgUrl from '@/assets/img/elite_img_v2.png'
// import draggable from 'vuedraggable'
export default {
name: 'device-info',
components: {
draggable,
},
created () {
},
@@ -163,4 +164,10 @@ export default {
text-align: center;
font-size: 28px;
}
.flex-wrap-setting {
display: flex;
flex-direction: horizontal;
flex-wrap: wrap;
}
</style>
+10 -2
View File
@@ -1,7 +1,15 @@
<template>
<div class="about">
<controller-info/>
<device-info/>
<div class="row">
<div class="flex sm12 xl12 md12 xs12">
<controller-info/>
</div>
</div>
<div class="row">
<div class="flex sm12 xl12 md12 xs12">
<device-info/>
</div>
</div>
</div>
</template>
<script>
@@ -158,58 +158,88 @@ export default {
},
methods: {
timeIntervalChange: function (val) {
chartData.getAllChartsData()[this.chartID].xAxis.forEach(x => {
if (x.type === 'time') {
x.interval = val * 1000
}
})
if (!isNaN(parseInt(val))) {
chartData.getAllChartsData()[this.chartID].xAxis.forEach(x => {
if (x.type === 'time') {
x.interval = val * 1000
}
})
} else {
this.timeIntervalInput = 'auto'
chartData.getAllChartsData()[this.chartID].xAxis.forEach(x => {
if (x.type === 'time') {
x.interval = 500 * 1000
}
})
}
},
xIntervalChange: function (val) {
chartData.getAllChartsData()[this.chartID].xAxis.forEach(x => {
if (x.type === 'value') {
x.interval = val * 1000
// const maxList = []
// const minList = []
// x.seriesIndex.forEach(i => {
// maxList.push(Math.max(...chartData.getAllChartsData()[this.chartID].series[i].data.map(p => p[0])))
// minList.push(Math.min(...chartData.getAllChartsData()[this.chartID].series[i].data.map(p => p[0])))
// })
// const max = Math.max(maxList)
// const min = Math.min(minList)
// const center = (max + min) / 2
// x.max = center + (max - min)
// x.min = center - (max - min)
// x.max = (parseInt(x.max / (val * 1000)) + 1) * (val * 1000)
// x.min = (parseInt(x.min / (val * 1000)) - 1) * (val * 1000)
}
})
if (!isNaN(parseInt(val))) {
chartData.getAllChartsData()[this.chartID].xAxis.forEach(x => {
if (x.type === 'value') {
x.interval = val * 1000
}
})
} else {
this.timeIntervalInput = 'auto'
chartData.getAllChartsData()[this.chartID].xAxis.forEach(x => {
if (x.type === 'value') {
x.interval = null
}
})
}
},
yIntervalChange: function (val) {
chartData.getAllChartsData()[this.chartID].yAxis.forEach(y => {
if (parseInt(y.channel) <= 255) {
y.interval = val * 1000
const maxList = []
const minList = []
y.seriesIndex.forEach(i => {
maxList.push(Math.max(...chartData.getAllChartsData()[this.chartID].series[i].data.map(p => p[1])))
minList.push(Math.min(...chartData.getAllChartsData()[this.chartID].series[i].data.map(p => p[1])))
})
const max = Math.max(maxList)
const min = Math.min(minList)
const center = (max + min) / 2
y.max = center + (max - min)
y.min = center - (max - min)
y.max = (parseInt(y.max / (val * 1000)) + 1) * (val * 1000)
y.min = (parseInt(y.min / (val * 1000)) - 1) * (val * 1000)
}
})
if (!isNaN(parseInt(val))) {
chartData.getAllChartsData()[this.chartID].yAxis.forEach(y => {
if (parseInt(y.channel) <= 255) {
if (chartData.getAllChartsData()[this.chartID].chartYUnit === 'uV') {
y.interval = parseInt(val)
console.log(y.interval)
} else {
y.interval = val * 1000
}
const maxList = []
const minList = []
y.seriesIndex.forEach(i => {
maxList.push(Math.max(...chartData.getAllChartsData()[this.chartID].series[i].data.map(p => p[1])))
minList.push(Math.min(...chartData.getAllChartsData()[this.chartID].series[i].data.map(p => p[1])))
})
const max = Math.max(maxList)
const min = Math.min(minList)
const center = (max + min) / 2
y.max = center + (max - min)
y.min = center - (max - min)
y.max = (parseInt(y.max / y.interval) + 1) * y.interval
y.min = (parseInt(y.min / y.interval) - 1) * y.interval
}
})
} else {
this.timeIntervalInput = 'auto'
chartData.getAllChartsData()[this.chartID].yAxis.forEach(y => {
if (parseInt(y.channel) <= 255) {
y.interval = null
y.max = 'dataMax'
y.min = 'dataMin'
}
})
}
},
threeAxisIntervalChange: function (val) {
chartData.getAllChartsData()[this.chartID].yAxis.forEach(y => {
if (parseInt(y.channel) >= 255) {
y.interval = val * 1
}
})
if (!isNaN(parseInt(val))) {
chartData.getAllChartsData()[this.chartID].yAxis.forEach(y => {
if (parseInt(y.channel) >= 255) {
y.interval = val * 1
}
})
} else {
this.timeIntervalInput = 'auto'
chartData.getAllChartsData()[this.chartID].yAxis.forEach(y => {
if (parseInt(y.channel) >= 255) {
y.interval = null
}
})
}
},
init: function () {
this.mappingSelect = ''
@@ -268,8 +298,8 @@ export default {
this.nameCard = chartData.getAllChartsData()[this.chartID].cardName
await this.refreshMappingSelect()
this.initDone = true
this.timeIntervalInput = '500'
this.timeIntervalChange('500')
// this.timeIntervalInput = '500'
// this.timeIntervalChange('500')
},
destroyed () {
clearInterval(this.resizeTimer)
@@ -176,7 +176,12 @@ export default {
})
this.channelSelectDisableX = false
} else if (taskInfo.getDeviceInfo(this.deviceSelectX.id).info.library_name.indexOf('Elite') >= 0) {
const channelSet = taskInfo.getDeviceInfo(this.deviceSelectX.id).parameterSet.CHANNEL_LABEL
let channelSet
if (taskInfo.getDeviceInfo(this.deviceSelectX.id).info.library_name === 'EliteEIS' && taskInfo.getDeviceInfo(this.deviceSelectX.id).parameterSet.MODE === 0) {
channelSet = ['Zimag_Raw', 'Zreal_Raw', 'Frequency', 'Cycle', 'Zimag', 'Zreal', 'Impedance', 'Phase', 'Current', 'Level gain']
} else {
channelSet = taskInfo.getDeviceInfo(this.deviceSelectX.id).parameterSet.CHANNEL_LABEL
}
// console.log(channelSet)
channelSet.forEach((element, index) => {
channelOptions.push({
@@ -238,7 +243,12 @@ export default {
})
this.channelSelectDisableY = false
} else if (taskInfo.getDeviceInfo(this.deviceSelectY.id).info.library_name.indexOf('Elite') >= 0) {
const channelSet = taskInfo.getDeviceInfo(this.deviceSelectY.id).parameterSet.CHANNEL_LABEL
let channelSet
if (taskInfo.getDeviceInfo(this.deviceSelectY.id).info.library_name === 'EliteEIS' && taskInfo.getDeviceInfo(this.deviceSelectY.id).parameterSet.MODE === 0) {
channelSet = ['Zimag_Raw', 'Zreal_Raw', 'Frequency', 'Cycle', 'Zimag', 'Zreal', 'Impedance', 'Phase', 'Current', 'Level gain']
} else {
channelSet = taskInfo.getDeviceInfo(this.deviceSelectY.id).parameterSet.CHANNEL_LABEL
}
console.log(channelSet)
channelSet.forEach((element, index) => {
channelOptions.push({
@@ -291,14 +301,22 @@ export default {
if (this.deviceSelectX.name.indexOf('Neulive') >= 0) {
deviceNameX = 'Neulive'
} else if (this.deviceSelectX.name.indexOf('Elite') >= 0) {
deviceNameX = 'Elite'
if (taskInfo.getDeviceInfo(this.deviceSelectX.id).info.library_name === 'EliteEIS') {
deviceNameX = 'EliteEIS'
} else {
deviceNameX = 'Elite'
}
} else if (this.deviceSelectX.name.indexOf('Time') >= 0) {
deviceNameX = 'Time'
}
if (this.deviceSelectY.name.indexOf('Neulive') >= 0) {
deviceNameY = 'Neulive'
} else if (this.deviceSelectY.name.indexOf('Elite') >= 0) {
deviceNameY = 'Elite'
if (taskInfo.getDeviceInfo(this.deviceSelectY.id).info.library_name === 'EliteEIS') {
deviceNameY = 'EliteEIS'
} else {
deviceNameY = 'Elite'
}
} else if (this.deviceSelectY.name.indexOf('Time') >= 0) {
deviceNameY = 'Time'
}
@@ -329,13 +347,13 @@ export default {
},
checkSourceAddStatus () {
if (this.sourceList.indexOf([this.deviceSelectX.name, this.deviceSelectX.id, this.channelSelectX.id].toString()) >= 0) {
this.error = 'some source have been registered'
this.error = 'The same source has been selected in a subplot.'
this.sourceAddStatus = true
return
}
if (this.sourceList.indexOf([this.deviceSelectY.name, this.deviceSelectY.id, this.channelSelectY.id].toString()) >= 0) {
this.sourceAddStatus = true
this.error = 'some source have been registered'
this.error = 'The same source has been selected in a subplot.'
return
}
this.error = ''
@@ -39,6 +39,15 @@
</va-item-section>
<va-item-section class="ml-1" v-if="device.type == 'Neulive'">
<va-icon
name="material-icons"
:color="(device.record_in_sd === true) ? 'primary' : 'grey'"
@click.native.stop="recordInSd(device)"
> sd_card
</va-icon>
</va-item-section>
</va-item>
<va-item class="pa-0 ma-0 mt-2">
@@ -108,6 +117,13 @@ export default {
computed: {
},
methods: {
recordInSd: function (device) {
device.record_in_sd = !device.record_in_sd
this.$emit('record_in_sd', {
id: device.id,
recordInSd: device.record_in_sd,
})
},
removeCheck: function (device) {
this.selectDevice = device
this.showDeleteModal = true
@@ -116,46 +132,42 @@ export default {
this.$emit('remove', this.selectDevice)
},
start: async function (device) {
const checkParam = await this.checkIfDeviceSetDoneParam({ device: device })
const status = checkParam.status
const message = checkParam.message
if (status === true) {
this.setArchiveSettings()
// this.$emit('start', device)
setTimeout(() => {
this.$emit('start', device)
}, 500)
this.pageToast('The device ' + device.name + ' has been started.')
} else {
this.pageToast('The device cannot be started because:' + message)
}
// const checkParam = await this.checkIfDeviceSetDoneParam({ device: device })
// const status = checkParam.status
// const message = checkParam.message
// if (status === true) {
this.setArchiveSettings()
// this.$emit('start', device)
setTimeout(() => {
this.$emit('start', device)
}, 500)
this.pageToast('The device ' + device.name + ' has been started.')
// } else {
// this.pageToast('The device cannot be started because:' + message)
// }
},
stop: function (device) {
if (!device.stopping) {
this.$emit('stop', device)
this.pageToast('The device ' + device.name + ' has been stopped.')
}
this.$emit('stop', device)
this.pageToast('The device ' + device.name + ' has been stopped.')
},
record: async function (device) {
const checkParam = await this.checkIfRecordingSetDoneParam({ device: device })
const status = checkParam.status
const message = checkParam.message
if (status === true) {
device.stopping = false
this.setArchiveSettings()
setTimeout(() => {
this.$emit('record', device)
}, 500)
this.pageToast('The device ' + device.name + ' has been started.')
} else {
this.pageToast('Recording cannot be started because:' + message)
}
// const checkParam = await this.checkIfRecordingSetDoneParam({ device: device })
// const status = checkParam.status
// const message = checkParam.message
// if (status === true) {
// device.stopping = false
this.setArchiveSettings()
setTimeout(() => {
this.$emit('record', device)
}, 500)
this.pageToast('The device ' + device.name + ' has been started.')
// } else {
// this.pageToast('Recording cannot be started because:' + message)
// }
},
stopRecord: function (device) {
if (!device.stopping) {
this.$emit('stopRecord', device)
this.pageToast('The device ' + device.name + ' has been stopped.')
}
this.$emit('stopRecord', device)
this.pageToast('The device ' + device.name + ' has been stopped.')
},
generateChart: function (device) {
this.$emit('generate', device)
@@ -22,10 +22,12 @@
@stop="stopDevice($event)"
@record="record($event)"
@stopRecord="stopRecord($event)"
@sti="sti($event)" @sti_stop="stiStop($event)"
@sti="sti($event)"
@sti_stop="stiStop($event)"
@fast_settle="fastSettle($event)"
@generate="generateChart($event)"
@detect="detectDevice($event)"
@record_in_sd="recordInSd($event)"
/>
<!-- <div class="row flex xs12 md12 xl12 sm12 mt-2" style="text-align: center;">
@@ -106,7 +108,7 @@ export default {
// }
// }
console.log(this.deviceOptions)
for (let i = 4; i <= 7; i++) {
for (let i = 0; i <= 11; i++) {
if (taskInfo.getDeviceInfoByRawID(i).info.status === 'connected') {
const index = this.deviceList.findIndex(d => taskInfo.getRawDeviceID(d.id) === i)
if (index < 0) {
@@ -167,7 +169,7 @@ export default {
instruction: 'start',
}))
}
device.stopping = false
// device.stopping = false
device.isSync = true
this.$emit('refreshSetting')
// ### show device info
@@ -205,7 +207,7 @@ export default {
instruction: 'interrupt',
}))
}
device.stopping = true
// device.stopping = true
}
},
detectDevice: function (device) {
@@ -232,7 +234,7 @@ export default {
instruction: 'record',
}))
device.isSync = true
device.stopping = false
// device.stopping = false
this.$emit('refreshSetting')
api.task.update({
device_config: taskInfo.getTaskInfo().deviceList,
@@ -243,18 +245,16 @@ export default {
}
},
stopRecord: function (device) {
if (!device.stopping) {
dataStreamBuffer.removeByDevice(taskInfo.getRawDeviceID(device.id))
if (taskInfo.getDeviceInfo(device.id).info.isSync) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_instruction/0',
device: taskInfo.getRawDeviceID(device.id),
instruction: 'stop_record',
}))
}
device.isSync = false
device.stopping = true
dataStreamBuffer.removeByDevice(taskInfo.getRawDeviceID(device.id))
if (taskInfo.getDeviceInfo(device.id).info.isSync) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_instruction/0',
device: taskInfo.getRawDeviceID(device.id),
instruction: 'stop_record',
}))
}
device.isSync = false
// device.stopping = true
},
sti: function (device) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
@@ -296,37 +296,13 @@ export default {
instruction: 'FAST_SET',
}))
},
// addDevice: async function () {
// if (this.deviceSelect.id == null) {
// return false
// }
// await taskInfo.getTaskInfo().deviceAddrList.push(taskInfo.getDeviceInfoByRawID(this.deviceSelect.id).info.device_address)
// await taskInfo.getTaskInfo().taskDeviceID.push(this.deviceSelect.id)
// const _address = this.GLOBAL.transMac(taskInfo.getDeviceInfoByRawID(this.deviceSelect.id).info.device_address)
// const pic = taskInfo.getDevicePic(taskInfo.getDeviceInfoByRawID(this.deviceSelect.id).info.library_name)
// let type = ''
// if (taskInfo.getDeviceInfoByRawID(this.deviceSelect.id).info.library_name.indexOf('Elite') >= 0) {
// type = 'Elite'
// } else if (taskInfo.getDeviceInfoByRawID(this.deviceSelect.id).info.library_name.indexOf('Neulive') >= 0) {
// type = 'Neulive'
// }
// const _device = {
// id: taskInfo.getTaskInfo().taskDeviceID.indexOf(this.deviceSelect.id),
// name: '[' + taskInfo.getTaskInfo().taskDeviceID.indexOf(this.deviceSelect.id) + '] ' + taskInfo.getDeviceInfoByRawID(this.deviceSelect.id).info.device_name,
// addr: taskInfo.getDeviceInfoByRawID(this.deviceSelect.id).info.device_address,
// address: _address,
// picture: pic,
// type: type,
// isSync: taskInfo.getDeviceInfoByRawID(this.deviceSelect.id).info.isSync,
// stopping: false,
// }
// this.deviceList.push(_device)
// this.deviceSelect = ''
// taskInfo.updateAllList()
// this.$emit('add', _device.id)
// },
recordInSd: function (device) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_record_in_sd/0',
device: taskInfo.getRawDeviceID(device.id),
content: device.recordInSd,
}))
},
addDevice: async function (selectID) {
if (selectID == null) {
return false
@@ -355,11 +331,14 @@ export default {
name: '[' + taskInfo.getTaskInfo().taskDeviceID.indexOf(selectID) + '] ' + taskInfo.getDeviceInfoByRawID(selectID).info.device_name,
addr: taskInfo.getDeviceInfoByRawID(selectID).info.device_address,
address: _address,
library_name: taskInfo.getDeviceInfoByRawID(selectID).info.library_name,
library_version: taskInfo.getDeviceInfoByRawID(selectID).info.library_version,
record_in_sd: taskInfo.getDeviceInfoByRawID(selectID).info.record_in_sd,
picture: pic,
type: type,
isSync: taskInfo.getDeviceInfoByRawID(selectID).info.isSync,
isStimulate: taskInfo.getDeviceInfoByRawID(selectID).info.isStimulate,
stopping: false,
// stopping: false,
}
this.deviceList.push(_device)
this.deviceSelect = ''
@@ -41,71 +41,71 @@
<div class="flex sm12 xl12 md12 xs12 pa-0 ma-0">
<p class="display-6">Current Range<p/>
</div>
<div class="flex sm12 xl12 md12 xs12 pa-0 ma-0" >
<div class="flex sm12 xl12 md12 xs12 pa-0 ma-1" >
<level-button :ref="'currentRangeSelect'" :deviceID="deviceID" :options="currentRangeOptions" :parameterName="'ADC_LEVEL_I_15'" @parameterChange="deviceParameterChange($event)" />
</div>
</div>
<div class="flex row mt-0 pt-0 sm12 xl12 md12 xs12 align--center">
<div class="flex sm4 xl4 md4 xs4 pa-0 ma-0">
<div class="flex sm12 xl12 md12 xs12 pa-0 ma-0">
<p class="display-6">Voltage Range<p/>
</div>
<div class="flex sm6 xl6 md6 xs6 pa-0 ma-0" >
<div class="flex sm12 xl12 md12 xs12 pa-0 ma-1" >
<level-button :ref="'voltageInRangeSelect'" :deviceID="deviceID" :options="voltageInRangeOptions" :parameterName="'ADC_LEVEL_V_IN_15'" @parameterChange="deviceParameterChange($event)" />
</div>
</div>
<div class="flex row mt-0 pt-0 sm12 xl12 md12 xs12 align--center">
<div class="flex sm4 xl4 md4 xs4 pa-0 ma-0">
<div class="flex sm12 xl12 md12 xs12 pa-0 ma-0">
<p class="display-6">High Z<p/>
</div>
<div class="flex sm6 xl6 md6 xs6 pa-0 ma-0" >
<div class="flex sm12 xl12 md12 xs12 pa-0 ma-1" >
<level-button :ref="'highzSelect'" :deviceID="deviceID" :options="highzOptions" :parameterName="'CTRL_HIGH_Z_15'" @parameterChange="deviceParameterChange($event)" />
</div>
</div>
<div class="flex row mt-0 pt-0 sm12 xl12 md12 xs12 align--center">
<div class="flex sm4 xl4 md4 xs4 pa-0 ma-0">
<p class="display-6">Voltage Initial<p/>
<div class="flex sm12 xl12 md12 xs12 pa-0 ma-0">
<p class="display-6">E Initial<p/>
</div>
<div class="flex sm6 xl6 md6 xs6 pa-0 ma-0" >
<volt-range :ref="'voltInitialNumber'" :deviceID="deviceID" :parameterName="'VOLT_INITIAL'" :minValue="-5" :maxValue="5" @parameterChange="deviceParameterChange($event)" />
<div class="flex sm12 xl12 md12 xs12 pa-0 ma-1" >
<volt-range :ref="'voltInitialNumber'" :deviceID="deviceID" :parameterName="'VOLT_INITIAL'" :minValue="-1.8" :maxValue="2" @parameterChange="deviceParameterChange($event)" />
</div>
</div>
<div class="flex row mt-0 pt-0 sm12 xl12 md12 xs12 align--center">
<div class="flex sm4 xl4 md4 xs4 pa-0 ma-0">
<p class="display-6">Voltage Max<p/>
<div class="flex sm12 xl12 md12 xs12 pa-0 ma-0">
<p class="display-6">E1<p/>
</div>
<div class="flex sm6 xl6 md6 xs6 pa-0 ma-0" >
<volt-range :ref="'voltMaxNumber'" :deviceID="deviceID" :parameterName="'VOLT_MAX'" :minValue="-5" :maxValue="5" @parameterChange="deviceParameterChange($event)" />
<div class="flex sm12 xl12 md12 xs12 pa-0 ma-1" >
<volt-range :ref="'voltMaxNumber'" :deviceID="deviceID" :parameterName="'VOLT_MAX'" :minValue="-1.8" :maxValue="2" @parameterChange="deviceParameterChange($event)" />
</div>
</div>
<div class="flex row mt-0 pt-0 sm12 xl12 md12 xs12 align--center">
<div class="flex sm4 xl4 md4 xs4 pa-0 ma-0">
<p class="display-6">Voltage Min<p/>
<div class="flex sm12 xl12 md12 xs12 pa-0 ma-0">
<p class="display-6">E2<p/>
</div>
<div class="flex sm6 xl6 md6 xs6 pa-0 ma-0" >
<volt-range :ref="'voltMinNumber'" :deviceID="deviceID" :parameterName="'VOLT_MIN'" :minValue="-5" :maxValue="5" @parameterChange="deviceParameterChange($event)" />
<div class="flex sm12 xl12 md12 xs12 pa-0 ma-1" >
<volt-range :ref="'voltMinNumber'" :deviceID="deviceID" :parameterName="'VOLT_MIN'" :minValue="-1.8" :maxValue="2" @parameterChange="deviceParameterChange($event)" />
</div>
</div>
<div class="flex row mt-0 pt-0 sm12 xl12 md12 xs12 align--center">
<div class="flex sm4 xl4 md4 xs4 pa-0 ma-0">
<div class="flex sm12 xl12 md12 xs12 pa-0 ma-0">
<p class="display-6">Voltage Scan Rate<p/>
</div>
<div class="flex sm6 xl6 md6 xs6 pa-0 ma-0" >
<div class="flex sm12 xl12 md12 xs12 pa-0 ma-1" >
<scan-rate-range :ref="'voltScanRateNumber'" :deviceID="deviceID" :parameterName="'Scan_Rate'" :minValue="0.01" :maxValue="1000" @parameterChange="deviceParameterChange($event)" />
</div>
</div>
<div class="flex row mt-0 pt-0 sm12 xl12 md12 xs12 align--center">
<div class="flex sm4 xl4 md4 xs4 pa-0 ma-0">
<div class="flex sm12 xl12 md12 xs12 pa-0 ma-0">
<p class="display-6">Resolution<p/>
</div>
<div class="flex sm6 xl6 md6 xs6 pa-0 ma-0" >
<div class="flex sm12 xl12 md12 xs12 pa-0 ma-1" >
<resolution-range :ref="'sampleRateNumber'" :deviceID="deviceID" :parameterName="'SAMPLE_RATE'" :minValue="0.1" :maxValue="100" @parameterChange="deviceParameterChange($event)" />
</div>
</div>
<div class="flex row mt-0 pt-0 sm12 xl12 md12 xs12 align--center">
<div class="flex sm4 xl4 md4 xs4 pa-0 ma-0">
<div class="flex sm12 xl12 md12 xs12 pa-0 ma-0">
<p class="display-6">Cycle<p/>
</div>
<div class="flex sm6 xl6 md6 xs6 pa-0 ma-0" >
<div class="flex sm12 xl12 md12 xs12 pa-0 ma-1" >
<cycle-range :ref="'cycleNoNumber'" :deviceID="deviceID" :parameterName="'CYCLE_NUMBER'" :minValue="1" :maxValue="50000" @parameterChange="deviceParameterChange($event)" />
</div>
</div>
@@ -395,6 +395,7 @@ 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)
@@ -33,7 +33,7 @@
<!-- 1.5ui -->
<va-tree-category
v-if="workingModeSelect != null && workingModeSelect.id == 0 || workingModeSelect.id == 1 || workingModeSelect.id == 5 || workingModeSelect.id == 6 || workingModeSelect.id == 7 || workingModeSelect.id == 8 || workingModeSelect.id == 9 || workingModeSelect.id == 11"
v-if="workingModeSelect != null && workingModeSelect.id == 0 || workingModeSelect.id == 1 || workingModeSelect.id == 2 || workingModeSelect.id == 4 || workingModeSelect.id == 5 || workingModeSelect.id == 6 || workingModeSelect.id == 7 || workingModeSelect.id == 8 || workingModeSelect.id == 9 || workingModeSelect.id == 11 || workingModeSelect.id == 13"
style="font-size: 20px;"
:label="'Range ( ' + currentRangeOptions[currentRangeSelect].label + ' )'">
<va-tree-node>
@@ -42,7 +42,7 @@
</va-tree-category>
<va-tree-category
v-if="workingModeSelect != null && workingModeSelect.id == 0 || workingModeSelect.id == 1 || workingModeSelect.id == 4 ||workingModeSelect.id == 6 || workingModeSelect.id == 7 || workingModeSelect.id == 8 || workingModeSelect.id == 9 || workingModeSelect.id == 11 || workingModeSelect.id == 13"
v-if="workingModeSelect != null && workingModeSelect.id == 0 || workingModeSelect.id == 1 || workingModeSelect.id == 2 || workingModeSelect.id == 4 || workingModeSelect.id == 5 || workingModeSelect.id == 6 || workingModeSelect.id == 7 || workingModeSelect.id == 8 || workingModeSelect.id == 9 || workingModeSelect.id == 11 || workingModeSelect.id == 13"
style="font-size: 20px;"
:label="'Range ( ' + voltageInRangeOptions[voltageInRangeSelect].label + ' )'">
<va-tree-node>
@@ -1,11 +1,11 @@
<template>
<div>
<elite-parameter-recording v-if="eliteVer=='1'" :ref="'rec_ref'" :deviceID="deviceID"/>
<elite-parameter-recording v-if="eliteVer=='1'" :ref="'rec_ref_1'" :deviceID="deviceID"/>
<!-- <elite-parameter-recording-elitezm15 :ref="'rec_ref'" :deviceID="deviceID"/> -->
<!--<elite-parameter-recording :ref="'rec_ref'" :deviceID="deviceID"/>-->
<elite-parameter-recording-elitezm15 v-else-if="eliteVer=='2'" :ref="'rec_ref'" :deviceID="deviceID"/>
<elite-parameter-recording-elite-e-i-s v-else :ref="'rec_ref'" :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 :ref="'rec_ref_4'" :deviceID="deviceID"/>
<!--<elite-parameter-recording :ref="'rec_ref'" :deviceID="deviceID"/>-->
</div>
@@ -53,6 +53,8 @@ export default {
} else if (JSON.stringify(ver.slice(0, 4)) === JSON.stringify([0, 2, 1, 7])) {
this.eliteVer = '3' // megafly
// console.log('3:', JSON.stringify(ver.slice(0, 4)), ',', JSON.stringify([0, 2, 1, 7]))
} else {
this.eliteVer = '4'
}
},
mqttPub: function (topic, mes) {
@@ -70,11 +72,35 @@ export default {
this.compareEliteVer(taskInfo.getDeviceInfo(this.deviceID).info.serial_number)
},
refresh: function () {
this.$nextTick(() => {
if (this.$refs.rec_ref != null) {
this.$refs.rec_ref.refresh()
}
})
// console.log(this.eliteVer)
switch (this.eliteVer) {
case '1':
this.$nextTick(() => {
if (this.$refs.rec_ref_1 != null) {
this.$refs.rec_ref_1.refresh()
}
})
break
case '2':
this.$nextTick(() => {
if (this.$refs.rec_ref_2 != null) {
this.$refs.rec_ref_2.refresh()
}
})
break
case '4':
this.$nextTick(() => {
if (this.$refs.rec_ref_4 != null) {
this.$refs.rec_ref_4.refresh()
}
})
break
}
// this.$nextTick(() => {
// if (this.$refs.rec_ref != null) {
// this.$refs.rec_ref.refresh()
// }
// })
// console.log('window:3,refresh(this.$nextTick:', this.$nextTick, ',this.$refs:', this.$refs, ')')
},
@@ -1,28 +1,5 @@
<template>
<div class="flex" >
<!-- <div>
<div class="row sm12 xl12 md12 xs12">
<va-button
class="mx-1 px-2 mb-3"
color="success"
v-if="!recordOn"
@click="recordClick"
small
>
Record
</va-button>
<va-button
class="mx-1 px-2 mb-3"
color="danger"
v-else
@click="recordClick"
small
>
Stop
</va-button>
</div>
</div> -->
<va-tree-root >
<va-tree-category
style="font-size: 20px;"
@@ -128,62 +105,6 @@
</va-tree-node>
</va-tree-category>
<va-tree-category
style="font-size: 20px;"
:label="'Radio Frequency'">
<va-tree-node>
<div class="row">
<div class="flex sm12 xl12 md12 xs12">
<va-select
@input="radioFrequencySelectChange()"
:label="''"
v-model="radioFrequencySelect"
textBy="description"
:options="radioFrequencyOptions"
:noClear='true'
/>
</div>
</div>
</va-tree-node>
</va-tree-category>
<va-tree-category
style="font-size: 20px;"
:label="'Mem Radio Frequency'">
<va-tree-node>
<div class="row">
<div class="flex sm12 xl12 md12 xs12">
<va-select
@input="memRadioFrequencySelectChange()"
:label="''"
v-model="memRadioFrequencySelect"
textBy="description"
:options="memRadioFrequencyOptions"
/>
</div>
</div>
</va-tree-node>
</va-tree-category>
<va-tree-category
style="font-size: 20px;"
:label="'Led Brightness'">
<va-tree-node>
<div class="row">
<div class="flex sm12 xl12 md12 xs12">
<va-select
@input="ledBrightnessSelectChange()"
:label="''"
v-model="ledBrightnessSelect"
textBy="description"
:options="ledBrightnessOptions"
:noClear='true'
/>
</div>
</div>
</va-tree-node>
</va-tree-category>
<va-tree-category
style="font-size: 20px;"
:label="'Accelerator Sensitivity'">
@@ -202,47 +123,7 @@
</div>
</va-tree-node>
</va-tree-category>
<!-- <va-tree-category
style="font-size: 20px;"
:label="'Sample rate'">
<va-tree-node>
<div class="row">
<div class="flex sm12 xl12 md12 xs12">
<div class="flex row align--center">
<va-button slot="append" class="mr-2 pa-1 shrink" small @click="sampleRateChange(4)">
4
</va-button>
<va-input
@keyup.enter="sampleRateChange(sampleRateInput)"
v-model="sampleRateInput"
class="mb-0"
style="width: 100px;"
>
<p slot="append" style="margin-right: 0;" small>
Hz
</p>
</va-input>
<va-button slot="append" class="ml-2 pa-1 shrink" small @click="sampleRateChange(1000)">
1000
</va-button>
</div>
<va-slider
@mouseup.native="sampleRateChange(sampleRate)"
@mouseleave.native="sampleRateChange(sampleRate)"
@touchend.native="sampleRateChange(sampleRate)"
class="flex sm12 xl12 md12 xs12"
value-visible
v-model="sampleRate"
:min="4"
:max="1000"
/>
</div>
</div>
</va-tree-node>
</va-tree-category> -->
</va-tree-root>
</div>
</template>
@@ -290,144 +171,40 @@ export default {
sampleRateOptions: [
{
id: 0,
value: 800,
value: 1000,
description: '1k',
},
{
id: 1,
value: 400,
value: 2000,
description: '2k',
},
{
id: 2,
value: 200,
value: 4000,
description: '4k',
},
{
id: 3,
value: 160,
value: 5000,
description: '5k',
},
{
id: 4,
value: 100,
value: 8000,
description: '8k',
},
{
id: 5,
value: 80,
value: 10000,
description: '10k',
},
{
id: 6,
value: 40,
value: 20000,
description: '20k',
},
],
radioFrequencySelect: null,
radioFrequencyOptions: [
{
id: 0,
value: -20,
description: '-20',
},
{
id: 1,
value: -16,
description: '-16',
},
{
id: 2,
value: -12,
description: '-12',
},
{
id: 3,
value: -8,
description: '-8',
},
{
id: 4,
value: -4,
description: '-4',
},
{
id: 5,
value: 0,
description: '0',
},
{
id: 6,
value: 4,
description: '4',
},
{
id: 7,
value: 8,
description: '8',
},
],
memRadioFrequencySelect: null,
memRadioFrequencyOptions: [
{
id: 0,
value: -20,
description: '-20',
},
{
id: 1,
value: -16,
description: '-16',
},
{
id: 2,
value: -12,
description: '-12',
},
{
id: 3,
value: -8,
description: '-8',
},
{
id: 4,
value: -4,
description: '-4',
},
{
id: 5,
value: 0,
description: '0',
},
{
id: 6,
value: 4,
description: '4',
},
{
id: 7,
value: 8,
description: '8',
},
],
ledBrightnessSelect: null,
ledBrightnessOptions: [
{
id: 0,
value: 0,
description: 'off',
},
{
id: 1,
value: 1,
description: 'bright',
},
{
id: 2,
value: 2,
description: 'normal',
},
],
acceleratorSensitivitySelect: null,
acceleratorSensitivityOptions: [
{
@@ -472,7 +249,7 @@ export default {
}
})
this.ampGainSelect = this.ampGainOptions[(taskInfo.getDeviceInfo(this.deviceID).parameterSet.AMP_GAIN) % 4]
this.sampleRateSelect = this.sampleRateOptions[this.sampleRateOptions.findIndex(ele => ele.value === taskInfo.getDeviceInfo(this.deviceID).parameterSet.ADC_CLOCK)]
this.sampleRateSelect = this.sampleRateOptions[this.sampleRateOptions.findIndex(ele => ele.value === taskInfo.getDeviceInfo(this.deviceID).parameterSet.SAMPLE_RATE)]
this.recordOn = taskInfo.getDeviceInfo(this.deviceID).parameterSet.RECORDING
this.axisChannelList.length = 0
const axisChannelSet = taskInfo.getDeviceInfo(this.deviceID).parameterSet.AXIS_CH.toString(2).split('').reverse()
@@ -489,10 +266,6 @@ export default {
}
}
})
this.radioFrequencySelect = this.radioFrequencyOptions[taskInfo.getDeviceInfo(this.deviceID).parameterSet.RADIO_FREQUENCY]
this.memRadioFrequencySelect = this.memRadioFrequencyOptions[taskInfo.getDeviceInfo(this.deviceID).parameterSet.MEM_RADIO_FREQUENCY]
this.ledBrightnessSelect = this.ledBrightnessOptions[taskInfo.getDeviceInfo(this.deviceID).parameterSet.LED_BRIGHTNESS]
this.acceleratorSensitivitySelect = this.acceleratorSensitivityOptions[taskInfo.getDeviceInfo(this.deviceID).parameterSet.ACCELERATOR_S]
},
channelClickAdd (val) {
@@ -554,57 +327,13 @@ export default {
}
},
sampleRateSelectChange () {
if (this.sampleRateSelect != null && this.sampleRateSelect.value !== ((taskInfo.getDeviceInfo(this.deviceID).parameterSet.ADC_CLOCK))) {
if (this.sampleRateSelect != null && this.sampleRateSelect.value !== ((taskInfo.getDeviceInfo(this.deviceID).parameterSet.SAMPLE_RATE))) {
const adcClock = 8e5 / this.sampleRateSelect.value
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: taskInfo.getRawDeviceID(this.deviceID),
parameter: 'ADC_CLOCK',
content: this.sampleRateSelect.value,
}))
}
},
radioFrequencySelectChange () {
if (this.radioFrequencySelect != null && this.radioFrequencySelect.id !== ((taskInfo.getDeviceInfo(this.deviceID).parameterSet.RADIO_FREQUENCY))) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: taskInfo.getRawDeviceID(this.deviceID),
parameter: 'RADIO_FREQUENCY',
content: this.radioFrequencySelect.id,
}))
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_update_radio_frequency/0',
device: taskInfo.getRawDeviceID(this.deviceID),
content: this.radioFrequencySelect.value,
}))
}
},
memRadioFrequencySelectChange () {
if (this.memRadioFrequencySelect != null && this.memRadioFrequencySelect.id !== ((taskInfo.getDeviceInfo(this.deviceID).parameterSet.MEM_RADIO_FREQUENCY))) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: taskInfo.getRawDeviceID(this.deviceID),
parameter: 'MEM_RADIO_FREQUENCY',
content: this.memRadioFrequencySelect.id,
}))
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_set_central_rf/0',
device: taskInfo.getRawDeviceID(this.deviceID),
content: this.memRadioFrequencySelect.value,
}))
}
},
ledBrightnessSelectChange () {
if (this.ledBrightnessSelect != null && this.ledBrightnessSelect.id !== ((taskInfo.getDeviceInfo(this.deviceID).parameterSet.LED_BRIGHTNESS))) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: taskInfo.getRawDeviceID(this.deviceID),
parameter: 'LED_BRIGHTNESS',
content: this.ledBrightnessSelect.id,
}))
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_update_led_brightness/0',
device: taskInfo.getRawDeviceID(this.deviceID),
content: this.ledBrightnessSelect.value,
parameter: 'SAMPLE_RATE|ADC_CLOCK',
content: `${this.sampleRateSelect.value}|${String(adcClock)}`,
}))
}
},
@@ -656,28 +385,6 @@ export default {
}
}
},
// sampleRateChange (val) {
// if (this.sampleRate == null) {
// return false
// }
// if (isNaN(val) || parseInt(val) > 1000 || parseInt(val) < 4) {
// this.sampleRateInput = '1000'
// this.sampleRate = 1000
// return false
// }
// if (parseInt(this.sampleRateInput) !== this.sampleRate || this.sampleRate !== parseInt(val)) {
// this.sampleRateInput = String(val)
// this.sampleRate = parseInt(val)
// }
// if (this.sampleRate !== parseInt(200 / parseFloat(taskInfo.getDeviceInfo(this.deviceID).parameterSet.ADC_CLOCK / 1000))) {
// this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
// header: 'device_parameter/0',
// device: taskInfo.getRawDeviceID(this.deviceID),
// parameter: 'ADC_CLOCK',
// content: parseInt(parseFloat(1 / parseFloat(this.sampleRate / 200)) * 1000),
// }))
// }
// },
recordClick () {
this.recordOn = !this.recordOn
if (this.recordOn) {
@@ -0,0 +1,589 @@
<template>
<div class="flex" >
<va-tree-root >
<va-tree-category
style="font-size: 20px;"
:label="'Channels'">
<va-tree-node>
<div class="row">
<div class="flex sm12 xl12 md12 xs12">
<div
style='display: inline-block;'
v-for="channel in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32]"
:key="channel"
>
<va-button
class="mx-1 px-1"
v-if="channelList != null && channelList.indexOf(channel) >= 0"
@click="channelClickRemove(channel)"
small
>
{{channel}}
</va-button>
<va-button
class="mx-1 px-1"
v-if="channelList == null || channelList.indexOf(channel) < 0"
@click="channelClickAdd(channel)"
small outline
>
{{channel}}
</va-button>
</div>
</div>
</div>
</va-tree-node>
</va-tree-category>
<va-tree-category
style="font-size: 20px;"
:label="'3-AXIS'">
<va-tree-node>
<div class="row">
<div class="flex sm12 xl12 md12 xs12">
<div
style='display: inline-block;'
v-for="axisChannel in ['x','y','z','m']"
:key="axisChannel"
>
<va-button
class="mx-1 px-1"
v-if="axisChannelList != null && axisChannelList.indexOf(axisChannel) >= 0"
@click="axisChannelClickRemove(axisChannel)"
small
>
{{axisChannel}}
</va-button>
<va-button
class="mx-1 px-1"
v-if="axisChannelList == null || axisChannelList.indexOf(axisChannel) < 0"
@click="axisChannelClickAdd(axisChannel)"
small outline
>
{{axisChannel}}
</va-button>
</div>
</div>
</div>
</va-tree-node>
</va-tree-category>
<va-tree-category
style="font-size: 20px;"
:label="'Amp gain'">
<va-tree-node>
<div class="row">
<div class="flex sm12 xl12 md12 xs12">
<va-select
@input="ampGainSelectChange()"
:label="''"
v-model="ampGainSelect"
textBy="description"
:options="ampGainOptions"
:noClear='true'
/>
</div>
</div>
</va-tree-node>
</va-tree-category>
<va-tree-category
style="font-size: 20px;"
:label="'Sample Rate'">
<va-tree-node>
<div class="row">
<div class="flex sm12 xl12 md12 xs12">
<va-select
@input="sampleRateSelectChange()"
:label="''"
v-model="sampleRateSelect"
textBy="description"
:options="sampleRateOptions"
:noClear='true'
/>
</div>
</div>
</va-tree-node>
</va-tree-category>
<va-tree-category
style="font-size: 20px;"
:label="'Accelerator Sensitivity'">
<va-tree-node>
<div class="row">
<div class="flex sm12 xl12 md12 xs12">
<va-select
@input="acceleratorSensitivitySelectChange()"
:label="''"
v-model="acceleratorSensitivitySelect"
textBy="description"
:options="acceleratorSensitivityOptions"
:noClear='true'
/>
</div>
</div>
</va-tree-node>
</va-tree-category>
</va-tree-root>
</div>
</template>
<script>
import { taskInfo } from '../../../../data/task/TaskInfo'
import { chartData } from '../../../../data/task/ChartsManagement'
export default {
name: 'NeuliveParameterRecording',
components: {
},
props: {
deviceID: {
type: Number,
required: true,
},
deviceName: {
type: String,
default: 'Neulive',
},
},
data () {
return {
channelList: [],
ampGainSelect: null,
ampGainOptions: [
// {
// id: 0,
// description: '25',
// },
{
id: 0,
description: '100',
},
{
id: 1,
description: '400',
},
{
id: 2,
description: '800',
},
],
sampleRateSelect: null,
sampleRateOptions: [
{
id: 0,
value: 1000,
description: '1k',
},
{
id: 1,
value: 2000,
description: '2k',
},
{
id: 2,
value: 4000,
description: '4k',
},
{
id: 3,
value: 5000,
description: '5k',
},
{
id: 4,
value: 8000,
description: '8k',
},
{
id: 5,
value: 10000,
description: '10k',
},
{
id: 6,
value: 20000,
description: '20k',
},
{
id: 7,
value: 30000,
description: '30k',
},
{
id: 8,
value: 40000,
description: '40k',
},
{
id: 9,
value: 50000,
description: '50k',
},
{
id: 10,
value: 60000,
description: '60k',
},
{
id: 11,
value: 70000,
description: '70k',
},
{
id: 12,
value: 80000,
description: '80k',
},
{
id: 13,
value: 90000,
description: '90k',
},
{
id: 14,
value: 100000,
description: '100k',
},
],
acceleratorSensitivitySelect: null,
acceleratorSensitivityOptions: [
{
id: 0,
value: 3,
description: '2G',
},
{
id: 1,
value: 5,
description: '4G',
},
{
id: 2,
value: 8,
description: '8G',
},
{
id: 3,
value: 12,
description: '16G',
},
],
// sampleRateInput: '1000',
// sampleRate: null,
recordOn: false,
axisChannelList: [],
}
},
mqtt: {
},
methods: {
mqttPub: function (topic, mes) {
this.$mqtt.publish(topic, mes)
},
refresh () {
this.channelList.length = 0
// todo RECORDING_CH to RECORDING_CH_H & L
const channelSetLow = taskInfo.getDeviceInfo(this.deviceID).parameterSet.RECORDING_CH_L.toString(2).split('').reverse()
channelSetLow.forEach((element, index) => {
if (parseInt(element) > 0) {
this.channelList.push(index + 1)
}
})
const channelSetHight = taskInfo.getDeviceInfo(this.deviceID).parameterSet.RECORDING_CH_H.toString(2).split('').reverse()
channelSetHight.forEach((element, index) => {
if (parseInt(element) > 0) {
this.channelList.push(index + 17)
}
})
this.ampGainSelect = this.ampGainOptions[(taskInfo.getDeviceInfo(this.deviceID).parameterSet.AMP_GAIN) % 4]
this.sampleRateSelect = this.sampleRateOptions[this.sampleRateOptions.findIndex(ele => ele.value === taskInfo.getDeviceInfo(this.deviceID).parameterSet.SAMPLE_RATE)]
this.recordOn = taskInfo.getDeviceInfo(this.deviceID).parameterSet.RECORDING
this.axisChannelList.length = 0
const axisChannelSet = taskInfo.getDeviceInfo(this.deviceID).parameterSet.AXIS_CH.toString(2).split('').reverse()
axisChannelSet.forEach((element, index) => {
if (parseInt(element) === 1) {
if (index === 0) {
this.axisChannelList.push('x')
} else if (index === 1) {
this.axisChannelList.push('y')
} else if (index === 2) {
this.axisChannelList.push('z')
} else if (index === 3) {
this.axisChannelList.push('m')
}
}
})
this.acceleratorSensitivitySelect = this.acceleratorSensitivityOptions[taskInfo.getDeviceInfo(this.deviceID).parameterSet.ACCELERATOR_S]
},
channelClickAdd (val) {
if (this.channelList.indexOf(val) < 0 && val <= 16 && val > 0) {
this.channelList.push(val)
let channelSet = ''
for (let i = 16; i >= 1; i--) {
if (this.channelList.indexOf(i) >= 0) {
channelSet += '1'
} else {
channelSet += '0'
}
}
const channelValue = parseInt(channelSet, 2)
if (channelValue !== taskInfo.getDeviceInfo(this.deviceID).RECORDING_CH_L) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: taskInfo.getRawDeviceID(this.deviceID),
parameter: 'RECORDING_CH_L',
content: channelValue,
}))
}
this.recordingChannelReset(this.channelList)
} else if (this.channelList.indexOf(val) < 0 && val <= 32 && val > 16) {
this.channelList.push(val)
let channelSet = ''
for (let i = 32; i >= 17; i--) {
if (this.channelList.indexOf(i) >= 0) {
channelSet += '1'
} else {
channelSet += '0'
}
}
const channelValue = parseInt(channelSet, 2)
if (channelValue !== taskInfo.getDeviceInfo(this.deviceID).RECORDING_CH_H) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: taskInfo.getRawDeviceID(this.deviceID),
parameter: 'RECORDING_CH_H',
content: channelValue,
}))
}
this.recordingChannelReset(this.channelList)
} else {
this.pageToast('Recording channels cannot choose more than 32.')
}
},
channelClickRemove (val) {
if (this.channelList.indexOf(val) >= 0 && val <= 16 && val > 0) {
this.channelList.splice(this.channelList.indexOf(val), 1)
let channelSet = ''
for (let i = 16; i >= 1; i--) {
if (this.channelList.indexOf(i) >= 0) {
channelSet += '1'
} else {
channelSet += '0'
}
}
const channelValue = parseInt(channelSet, 2)
if (channelValue !== taskInfo.getDeviceInfo(this.deviceID).RECORDING_CH_L) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: taskInfo.getRawDeviceID(this.deviceID),
parameter: 'RECORDING_CH_L',
content: channelValue,
}))
}
this.recordingChannelReset(this.channelList)
} else if (this.channelList.indexOf(val) >= 0 && val <= 32 && val > 16) {
this.channelList.splice(this.channelList.indexOf(val), 1)
let channelSet = ''
for (let i = 32; i >= 17; i--) {
if (this.channelList.indexOf(i) >= 0) {
channelSet += '1'
} else {
channelSet += '0'
}
}
const channelValue = parseInt(channelSet, 2)
if (channelValue !== taskInfo.getDeviceInfo(this.deviceID).RECORDING_CH_H) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: taskInfo.getRawDeviceID(this.deviceID),
parameter: 'RECORDING_CH_H',
content: channelValue,
}))
}
this.recordingChannelReset(this.channelList)
}
},
recordingChannelReset (channelList) {
let channelSet = ''
for (let i = 32; i >= 1; i--) {
if (channelList.indexOf(i) >= 0) {
channelSet += '1'
} else {
channelSet += '0'
}
}
const channelValue = parseInt(channelSet, 2)
if (channelValue !== taskInfo.getDeviceInfo(this.deviceID).RECORDING_CH) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: taskInfo.getRawDeviceID(this.deviceID),
parameter: 'RECORDING_CH',
content: channelValue,
}))
}
},
ampGainSelectChange () {
if (this.ampGainSelect != null && this.ampGainSelect.id !== ((taskInfo.getDeviceInfo(this.deviceID).parameterSet.AMP_GAIN) % 4)) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: taskInfo.getRawDeviceID(this.deviceID),
parameter: 'AMP_GAIN',
content: ((this.ampGainSelect.id) % 4),
}))
}
},
sampleRateSelectChange () {
if (this.sampleRateSelect != null && this.sampleRateSelect.value !== ((taskInfo.getDeviceInfo(this.deviceID).parameterSet.SAMPLE_RATE))) {
const adcClock = 8e6 / this.sampleRateSelect.value
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: taskInfo.getRawDeviceID(this.deviceID),
parameter: 'SAMPLE_RATE|ADC_CLOCK',
content: `${this.sampleRateSelect.value}|${String(adcClock)}`,
}))
}
},
acceleratorSensitivitySelectChange () {
if (this.acceleratorSensitivitySelect != null && this.acceleratorSensitivitySelect.id !== ((taskInfo.getDeviceInfo(this.deviceID).parameterSet.ACCELERATOR_S))) {
let scaleRange
switch (this.acceleratorSensitivitySelect.id) {
case 0:
scaleRange = 200
break
case 1:
scaleRange = 400
break
case 2:
scaleRange = 800
break
case 3:
scaleRange = 1600
break
default:
scaleRange = 0
break
}
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: taskInfo.getRawDeviceID(this.deviceID),
parameter: 'ACCELERATOR_S',
content: this.acceleratorSensitivitySelect.id,
}))
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_update_accelerator_sensitivity/0',
device: taskInfo.getRawDeviceID(this.deviceID),
content: this.acceleratorSensitivitySelect.value,
}))
const charts = chartData.getAllChartsData()
for (const chartID in charts) {
for (const seriesIndex in charts[chartID].series) {
if (charts[chartID].series[seriesIndex].yAxisSource[1] >= 256 && charts[chartID].series[seriesIndex].yAxisSource[1] <= 260) {
if (parseInt(charts[chartID].series[seriesIndex].yAxisSource[1]) === 260) {
charts[chartID].yAxis[seriesIndex].min = 0
charts[chartID].yAxis[seriesIndex].max = Math.ceil(Math.sqrt(Math.pow(scaleRange, 2) * 3))
} else {
charts[chartID].yAxis[seriesIndex].min = -scaleRange
charts[chartID].yAxis[seriesIndex].max = scaleRange
}
}
}
}
}
},
recordClick () {
this.recordOn = !this.recordOn
if (this.recordOn) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_instruction/0',
device: taskInfo.getRawDeviceID(this.deviceID),
instruction: 'record',
}))
this.$emit('record')
} else {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_instruction/0',
device: taskInfo.getRawDeviceID(this.deviceID),
instruction: 'stop_record',
}))
this.$emit('record_stop')
}
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: taskInfo.getRawDeviceID(this.deviceID),
parameter: 'RECORDING',
content: this.recordOn,
}))
},
axisChannelClickAdd (val) {
if (this.axisChannelList.indexOf(val) < 0) {
const axisChannel = ['m', 'z', 'y', 'x']
this.axisChannelList.push(val)
let axisChannelSet = ''
for (const axis of axisChannel) {
if (this.axisChannelList.indexOf(axis) >= 0) {
axisChannelSet += '1'
} else {
axisChannelSet += '0'
}
}
const axisChannelValue = parseInt(axisChannelSet, 2)
if (axisChannelValue !== taskInfo.getDeviceInfo(this.deviceID).AXIS_CH) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: taskInfo.getRawDeviceID(this.deviceID),
parameter: 'AXIS_CH',
content: axisChannelValue,
}))
}
}
},
axisChannelClickRemove (val) {
if (this.axisChannelList.indexOf(val) >= 0) {
const axisChannel = ['m', 'z', 'y', 'x']
this.axisChannelList.splice(this.axisChannelList.indexOf(val), 1)
let axisChannelSet = ''
for (const axis of axisChannel) {
if (this.axisChannelList.indexOf(axis) >= 0) {
axisChannelSet += '1'
} else {
axisChannelSet += '0'
}
}
const axisChannelValue = parseInt(axisChannelSet, 2)
if (axisChannelValue !== taskInfo.getDeviceInfo(this.deviceID).AXIS_CH) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: taskInfo.getRawDeviceID(this.deviceID),
parameter: 'AXIS_CH',
content: axisChannelValue,
}))
}
}
},
pageToast: function (mes) {
this.showToast(
mes,
{
icon: 'fa-bell',
position: 'bottom-right',
duration: 4000,
},
)
},
},
mounted () {
this.refresh()
},
destroyed () {
},
watch: {
},
}
</script>
@@ -0,0 +1,264 @@
<template>
<div class="flex" >
<va-tree-root >
<va-tree-category
style="font-size: 20px;"
:label="'Radio Frequency'">
<va-tree-node>
<div class="row">
<div class="flex sm12 xl12 md12 xs12">
<va-select
@input="radioFrequencySelectChange()"
:label="''"
v-model="radioFrequencySelect"
textBy="description"
:options="radioFrequencyOptions"
:noClear='true'
/>
</div>
</div>
</va-tree-node>
</va-tree-category>
<va-tree-category
style="font-size: 20px;"
:label="'Mem Radio Frequency'">
<va-tree-node>
<div class="row">
<div class="flex sm12 xl12 md12 xs12">
<va-select
@input="memRadioFrequencySelectChange()"
:label="''"
v-model="memRadioFrequencySelect"
textBy="description"
:options="memRadioFrequencyOptions"
/>
</div>
</div>
</va-tree-node>
</va-tree-category>
<va-tree-category
style="font-size: 20px;"
:label="'Led Brightness'">
<va-tree-node>
<div class="row">
<div class="flex sm12 xl12 md12 xs12">
<va-select
@input="ledBrightnessSelectChange()"
:label="''"
v-model="ledBrightnessSelect"
textBy="description"
:options="ledBrightnessOptions"
:noClear='true'
/>
</div>
</div>
</va-tree-node>
</va-tree-category>
</va-tree-root>
</div>
</template>
<script>
import { taskInfo } from '../../../../data/task/TaskInfo'
export default {
name: 'NeuliveParameterRecording',
components: {
},
props: {
deviceID: {
type: Number,
required: true,
},
deviceName: {
type: String,
default: 'Neulive',
},
},
data () {
return {
radioFrequencySelect: null,
radioFrequencyOptions: [
{
id: 0,
value: -20,
description: '-20',
},
{
id: 1,
value: -16,
description: '-16',
},
{
id: 2,
value: -12,
description: '-12',
},
{
id: 3,
value: -8,
description: '-8',
},
{
id: 4,
value: -4,
description: '-4',
},
{
id: 5,
value: 0,
description: '0',
},
{
id: 6,
value: 4,
description: '4',
},
{
id: 7,
value: 8,
description: '8',
},
],
memRadioFrequencySelect: null,
memRadioFrequencyOptions: [
{
id: 0,
value: -20,
description: '-20',
},
{
id: 1,
value: -16,
description: '-16',
},
{
id: 2,
value: -12,
description: '-12',
},
{
id: 3,
value: -8,
description: '-8',
},
{
id: 4,
value: -4,
description: '-4',
},
{
id: 5,
value: 0,
description: '0',
},
{
id: 6,
value: 4,
description: '4',
},
{
id: 7,
value: 8,
description: '8',
},
],
ledBrightnessSelect: null,
ledBrightnessOptions: [
{
id: 0,
value: 0,
description: 'off',
},
{
id: 1,
value: 1,
description: 'bright',
},
{
id: 2,
value: 2,
description: 'normal',
},
],
}
},
mqtt: {
},
methods: {
mqttPub: function (topic, mes) {
this.$mqtt.publish(topic, mes)
},
refresh () {
this.radioFrequencySelect = this.radioFrequencyOptions[taskInfo.getDeviceInfo(this.deviceID).parameterSet.RADIO_FREQUENCY]
this.memRadioFrequencySelect = this.memRadioFrequencyOptions[taskInfo.getDeviceInfo(this.deviceID).parameterSet.MEM_RADIO_FREQUENCY]
this.ledBrightnessSelect = this.ledBrightnessOptions[taskInfo.getDeviceInfo(this.deviceID).parameterSet.LED_BRIGHTNESS]
},
radioFrequencySelectChange () {
if (this.radioFrequencySelect != null && this.radioFrequencySelect.id !== ((taskInfo.getDeviceInfo(this.deviceID).parameterSet.RADIO_FREQUENCY))) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: taskInfo.getRawDeviceID(this.deviceID),
parameter: 'RADIO_FREQUENCY',
content: this.radioFrequencySelect.id,
}))
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_update_radio_frequency/0',
device: taskInfo.getRawDeviceID(this.deviceID),
content: this.radioFrequencySelect.value,
}))
}
},
memRadioFrequencySelectChange () {
if (this.memRadioFrequencySelect != null && this.memRadioFrequencySelect.id !== ((taskInfo.getDeviceInfo(this.deviceID).parameterSet.MEM_RADIO_FREQUENCY))) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: taskInfo.getRawDeviceID(this.deviceID),
parameter: 'MEM_RADIO_FREQUENCY',
content: this.memRadioFrequencySelect.id,
}))
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_set_central_rf/0',
device: taskInfo.getRawDeviceID(this.deviceID),
content: this.memRadioFrequencySelect.value,
}))
}
},
ledBrightnessSelectChange () {
if (this.ledBrightnessSelect != null && this.ledBrightnessSelect.id !== ((taskInfo.getDeviceInfo(this.deviceID).parameterSet.LED_BRIGHTNESS))) {
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_parameter/0',
device: taskInfo.getRawDeviceID(this.deviceID),
parameter: 'LED_BRIGHTNESS',
content: this.ledBrightnessSelect.id,
}))
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
header: 'device_update_led_brightness/0',
device: taskInfo.getRawDeviceID(this.deviceID),
content: this.ledBrightnessSelect.value,
}))
}
},
pageToast: function (mes) {
this.showToast(
mes,
{
icon: 'fa-bell',
position: 'bottom-right',
duration: 4000,
},
)
},
},
mounted () {
this.refresh()
},
destroyed () {
},
watch: {
},
}
</script>
@@ -205,7 +205,7 @@
</div>
<div class="row">
<div class="flex sm12 xl12 md12 xs12">
<div class="flex sm12 xl6 md6 xs12">
<div class="flex row align--center">
<va-input
v-model="frequencyNumberInput"
@@ -219,10 +219,7 @@
</va-input>
</div>
</div>
</div>
<div class="row">
<div class="flex sm12 xl12 md12 xs12">
<div class="flex sm12 xl6 md6 xs12">
<div class="flex row align--center">
<va-input
v-model="periodNumberInput"
@@ -692,8 +689,13 @@ export default {
}
this.autoComputeT4()
const check1 = this.checkIndividualTRange(1, this.t1Range)
const check2 = this.checkIndividualTRange(2, this.t2Range)
const check3 = this.checkIndividualTRange(3, this.t3Range)
const check4 = this.checkIndividualTRange(4, this.t4Range)
if (check4) {
// if pass, call this.updateTimeRange(), if any fail, call updateErrorMsg in this.checkIndividualTRange()
if (check1 === true && check2 === true && check3 === true && check4 === true) {
this.updateTimeRange()
}
this.updateStiTRangeCheckParam()
@@ -719,14 +721,15 @@ export default {
this.periodNumber = (1e6 / this.frequencyNumber).toFixed(3) // us
this.periodNumberInput = String(this.periodNumber / this.unitMultiply)
this.autoResetAllTRange()
this.autoComputeT4()
const check1 = this.checkIndividualTRange(1, this.t1Range)
const check2 = this.checkIndividualTRange(2, this.t2Range)
const check3 = this.checkIndividualTRange(3, this.t3Range)
const check4 = this.checkIndividualTRange(4, this.t4Range)
// if pass, call this.updateTimeRange(), if any fail, call updateErrorMsg in this.checkIndividualTRange()
if (check1 && check2 && check3 && check4) {
if (check1 === true && check2 === true && check3 === true && check4 === true) {
this.updateTimeRange()
}
this.updateStiTRangeCheckParam()
@@ -753,14 +756,15 @@ export default {
this.frequencyNumber = parseInt(1e6 / this.periodNumber)
this.frequencyNumberInput = String(this.frequencyNumber)
this.autoResetAllTRange()
this.autoComputeT4()
const check1 = this.checkIndividualTRange(1, this.t1Range)
const check2 = this.checkIndividualTRange(2, this.t2Range)
const check3 = this.checkIndividualTRange(3, this.t3Range)
const check4 = this.checkIndividualTRange(4, this.t4Range)
// if pass, call this.updateTimeRange(), if any fail, call updateErrorMsg in this.checkIndividualTRange()
if (check1 && check2 && check3 && check4) {
if (check1 === true && check2 === true && check3 === true && check4 === true) {
this.updateTimeRange()
}
this.updateStiTRangeCheckParam()
@@ -829,7 +833,11 @@ export default {
autoComputeT4 () {
this.t4Range = (this.periodNumber / 10) - this.t1Range - this.t2Range - this.t3Range
this.t4RangeInput = String((this.t4Range * 10) / this.unitMultiply)
this.pageToast('Auto complete T4 value')
if (this.t4Range >= 0) {
this.pageToast(`T4 = ${(this.t4Range / 100).toFixed(1)} ms`)
} else {
this.pageToast('T4 can not be negative. Please check T1~T3 setting.')
}
},
// [SubRegion] check sti T range setting helper function
@@ -848,7 +856,7 @@ export default {
// val unit: us
val = parseFloat(val) * 10 // UI us
if (val < 0 || isNaN(val)) {
this.updateTRangeErrorMsg({ stiIimeSelect: stiIimeSelect, status: true, msg: 'T > 0' })
this.updateTRangeErrorMsg({ stiIimeSelect: stiIimeSelect, status: true, msg: `T${stiIimeSelect} can not be negative. Please check your setting.` })
return false
}
@@ -857,23 +865,42 @@ export default {
if (val < 100 || val > 10230) { // us
this.updateTRangeErrorMsg({ stiIimeSelect: stiIimeSelect, status: true, msg: '0.1ms <= T1 <= 10.23ms' })
return false
} else if (val > this.periodNumber) {
this.updateTRangeErrorMsg({ stiIimeSelect: stiIimeSelect, status: true, msg: 'T1 > PERIOD' })
return false
} else {
this.updateTRangeErrorMsg({ stiIimeSelect: stiIimeSelect, status: false, msg: '' })
return true
}
case 2:
if (val < 0 || val > 10230) { // us
this.updateTRangeErrorMsg({ stiIimeSelect: stiIimeSelect, status: true, msg: '0ms <= T2 <= 10.23ms' })
return false
} else {
if (this.patternModeSelect === 1) { // biphasic
if (val < 0 || val > 10230) { // us
this.updateTRangeErrorMsg({ stiIimeSelect: stiIimeSelect, status: true, msg: '0ms <= T2 <= 10.23ms' })
return false
} else if (val > this.periodNumber) {
this.updateTRangeErrorMsg({ stiIimeSelect: stiIimeSelect, status: true, msg: 'T2 > PERIOD' })
return false
} else {
this.updateTRangeErrorMsg({ stiIimeSelect: stiIimeSelect, status: false, msg: '' })
return true
}
} else { // monophasic not need t2
this.updateTRangeErrorMsg({ stiIimeSelect: stiIimeSelect, status: false, msg: '' })
return true
}
case 3:
if (val < 100 || val > 10230) { // us
this.updateTRangeErrorMsg({ stiIimeSelect: stiIimeSelect, status: true, msg: '0.1ms <= T3 <= 10.23ms' })
return false
} else {
if (this.patternModeSelect === 1) { // biphasic
if (val < 100 || val > 10230) { // us
this.updateTRangeErrorMsg({ stiIimeSelect: stiIimeSelect, status: true, msg: '0.1ms <= T3 <= 10.23ms' })
return false
} else if (val > this.periodNumber) {
this.updateTRangeErrorMsg({ stiIimeSelect: stiIimeSelect, status: true, msg: 'T3 > PERIOD' })
return false
} else {
this.updateTRangeErrorMsg({ stiIimeSelect: stiIimeSelect, status: false, msg: '' })
return true
}
} else { // monophasic not need t3
this.updateTRangeErrorMsg({ stiIimeSelect: stiIimeSelect, status: false, msg: '' })
return true
}
File diff suppressed because it is too large Load Diff
@@ -7,7 +7,27 @@
:label="'RECORDING'"
>
<va-tree-node>
<neulive-parameter-recording :ref="'rec_ref'" :deviceID="deviceID" @record="start()" @record_stop="stop()"/>
<neulive-parameter-recording
v-if="
(device)
? (device.info.library_name.indexOf('3.0') !== -1 || device.info.library_name.indexOf('3.1') !== -1)
: false
"
:ref="'rec_ref'" :deviceID="deviceID"
@record="start()"
@record_stop="stop()"
/>
<neulive-parameter-recording35
v-if="
(device)
? (device.info.library_name.indexOf('3.5') !== -1)
: false
"
:ref="'rec_ref'"
:deviceID="deviceID"
@record="start()"
@record_stop="stop()"
/>
</va-tree-node>
</va-tree-category>
<va-tree-category
@@ -15,7 +35,35 @@
:label="'STIMULATION'"
>
<va-tree-node>
<neulive-parameter-stimulation :ref="'sti_ref'" :deviceID="deviceID"/>
<neulive-parameter-stimulation
v-if="
(device)
? (device.info.library_name.indexOf('3.0') !== -1 || device.info.library_name.indexOf('3.1') !== -1)
: false
"
:ref="'sti_ref'"
:deviceID="deviceID"
/>
<neulive-parameter-stimulation35
v-if="
(device)
? (device.info.library_name.indexOf('3.5') !== -1)
: false
"
:ref="'sti_ref'"
:deviceID="deviceID"
/>
</va-tree-node>
</va-tree-category>
<va-tree-category
style="font-size: 20px;"
:label="'SETTING'"
>
<va-tree-node>
<neulive-parameter-setting
:ref="'set_ref'"
:deviceID="deviceID"
/>
</va-tree-node>
</va-tree-category>
</va-tree-root>
@@ -26,12 +74,18 @@
import { taskInfo } from '../../../../data/task/TaskInfo'
import NeuliveParameterRecording from './NeuliveParameterRecording'
import NeuliveParameterStimulation from './NeuliveParameterStimulation'
import NeuliveParameterRecording35 from './NeuliveParameterRecording35'
import NeuliveParameterStimulation35 from './NeuliveParameterStimulation35'
import NeuliveParameterSetting from './NeuliveParameterSetting'
export default {
name: 'NeuliveParameterWindow',
components: {
NeuliveParameterRecording,
NeuliveParameterStimulation,
NeuliveParameterRecording35,
NeuliveParameterStimulation35,
NeuliveParameterSetting,
},
props: {
deviceID: {
@@ -45,6 +99,7 @@ export default {
},
data () {
return {
device: null,
}
},
mqtt: {
@@ -70,6 +125,9 @@ export default {
if (this.$refs.sti_ref != null) {
this.$refs.sti_ref.refresh()
}
if (this.$refs.set_ref != null) {
this.$refs.set_ref.refresh()
}
})
},
start: function () {
@@ -81,6 +139,8 @@ export default {
},
mounted () {
this.pageInit()
this.device = taskInfo.getDeviceInfo(this.deviceID)
console.log(taskInfo.getDeviceInfo(this.deviceID).info)
},
watch: {
deviceID: function (val) {
@@ -85,7 +85,7 @@ export default {
return false
}
if (parseFloat(this.currentNumberInput) !== parseFloat(this.currentNumber / 100)) {
this.currentNumber = parseInt(parseFloat(val).toFixed(2) * 100)
this.currentNumber = parseInt((parseFloat(val) * 100).toFixed(2))
this.currentNumberInput = String(parseFloat(this.currentNumber / 100).toFixed(2))
}
} else {
@@ -85,7 +85,7 @@ export default {
return false
}
if (parseFloat(this.voltNumberInput) !== parseFloat(this.voltNumber / 1000)) {
this.voltNumber = parseInt(parseFloat(val).toFixed(3) * 1000)
this.voltNumber = parseInt((parseFloat(val) * 1000).toFixed(3))
this.voltNumberInput = String(parseFloat(this.voltNumber / 1000).toFixed(3))
}
} else {
@@ -98,6 +98,7 @@ export default {
this.voltNumberInput = String(parseFloat(val / 1000).toFixed(3))
this.voltNumber = val
}
console.log('____val:', val, 'voltNumberInput:', this.voltNumberInput, 'voltNumber:', this.voltNumber)
}
if (this.voltNumber !== (taskInfo.getDeviceInfo(this.deviceID).parameterSet[this.parameterName] - 25000) / 5) {
this.$emit('parameterChange', [this.parameterName, this.voltNumber * 5 + 25000])
+22
View File
@@ -22,6 +22,16 @@ async function getAll () {
}
}
async function getByName (name) {
const _header = auth.getHeader()
try {
return await api.axios.get(`/api/controller/get_by_name/${name}`, { headers: _header })
} catch (e) {
console.error(e)
return false
}
}
async function getByMac (mac) {
const _header = auth.getHeader()
try {
@@ -32,6 +42,16 @@ async function getByMac (mac) {
}
}
async function getByMqttId (mqttId) {
const _header = auth.getHeader()
try {
return await api.axios.get(`/api/controller/get_by_mqtt_id/${mqttId}`, { headers: _header })
} catch (e) {
console.error(e)
return false
}
}
async function update (attrs) {
const _header = auth.getHeader()
try {
@@ -45,7 +65,9 @@ async function update (attrs) {
const controller = {
create,
getAll,
getByName,
getByMac,
getByMqttId,
update,
}
+2
View File
@@ -8,6 +8,7 @@ import meta from './meta'
import raw from './raw'
import mini from './mini'
import analysis from './analysis'
import sdcard from './sdcard'
// axios.defaults.baseURL = 'http://192.168.3.53:3000'
axios.defaults.baseURL = 'http://' + location.href.split('/')[2].split(':')[0] + ':3000'
@@ -23,6 +24,7 @@ const api = {
raw,
mini,
analysis,
sdcard,
}
export default api
+11
View File
@@ -31,6 +31,16 @@ async function getByID (channel, id) {
}
}
async function getExistOrNotByID (channel, id) {
const _header = auth.getHeader()
try {
return await api.axios.get(`/api/file/mini/get_exist_or_not_by_id/${channel}/${id}`, { responseType: 'json', headers: _header })
} catch (e) {
console.error(e)
return false
}
}
async function getByParent (channel, parent) {
const _header = auth.getHeader()
try {
@@ -85,6 +95,7 @@ const mini = {
update,
clearDel,
getByID,
getExistOrNotByID,
getByParent,
getAttrByParent,
getAttrByID,
+43
View File
@@ -0,0 +1,43 @@
import api from './index'
import auth from './auth'
async function exist (attrs) {
const _header = auth.getHeader()
try {
return await api.axios.post('/api/file/sdcard/exist', attrs, { headers: _header })
} catch (e) {
console.error(e)
}
}
async function deleted (attrs) {
const _header = auth.getHeader()
try {
return await api.axios.post('/api/file/sdcard/delete', attrs, { headers: _header })
} catch (e) {
console.error(e)
}
}
async function upload (attrs) {
const _header = auth.getHeader()
try {
return await api.axios.post('/api/file/sdcard/upload', attrs, { headers: _header })
} catch (e) {
console.error(e)
}
}
async function getuuidList () {
const _header = auth.getHeader()
return api.axios.get('/api/file/sdcard/get', { headers: _header }).then(response => response.data)
}
const sdcard = {
exist,
deleted,
upload,
getuuidList,
}
export default sdcard
+27
View File
@@ -66,12 +66,22 @@ export const download = {
await this.parseRawData(_data.data, prevLastTime, meta, result[channelID])
return result
},
getMiniExistOrNotByID: async function (id, channel) {
const result = await api.mini.getExistOrNotByID(channel, id)
return result
},
rawByIDChannels: async function (id, channel, meta) {
const data = []
const rawData = await api.raw.getByID(channel, id)
await this.parseRawData(rawData.data, null, meta, data)
return data
},
rawSdDataByIDChannels: async function (id, channel, meta) {
const data = []
const rawSdData = await api.raw.getByID(channel, id)
await this.parseRawSdData(rawSdData.data, null, meta, data)
return data
},
miniMeanByIDChannel: async function (id, channel, meta) {
const miniData = await api.mini.getByID(channel, id)
return await this.parseMiniData(miniData, 'data_mean', meta)
@@ -97,6 +107,23 @@ export const download = {
}
return prevLastTime
},
parseRawSdData: async function (rawData, prevLastTime, meta, dataArray) {
for (const raw of rawData) {
if (raw.sd_data !== null && raw.sd_data.length > 0) {
const encodedData = raw.sd_data.split('"***"').slice(0, -1)
const unzipDatas = encodedData.map(ctx => {
return ctx.split(' ')
})
for (let i = 0; i <= unzipDatas.length - 1; i++) {
if (unzipDatas[i].length > 0) {
prevLastTime = this.parseDataWithTimeStamp(unzipDatas[i], prevLastTime, meta, dataArray)
}
}
}
}
return prevLastTime
},
parseMiniData: async function (miniData, miniType, meta) {
const channelData = []
+3 -3
View File
@@ -1,6 +1,6 @@
import golbalMethods from '../global/global'
const NeuliveParameterOrder = ['RECORDING_CH', 'AMP_GAIN', 'ADC_CLOCK']
const NeuliveParameterOrder = ['RECORDING_CH', 'AMP_GAIN', 'SAMPLE_RATE']
const NeuliveAmpGain = [100, 400, 800, 25]
export const exportData = {
@@ -26,8 +26,8 @@ export const exportData = {
parameter.push(['Record channels', result])
} else if (p === 'AMP_GAIN') {
parameter.push(['Amp gain', NeuliveAmpGain[value]])
} else if (p === 'ADC_CLOCK') {
parameter.push(['Sample Rate', parseInt(8e5 / (value * JSON.parse(headers.channels).length))])
} else if (p === 'SAMPLE_RATE') {
parameter.push(['Sample Rate', parseInt(value / (JSON.parse(headers.channels).length))])
}
})
} else if (headers.device.library_name.indexOf('Elite') >= 0) {
+26 -19
View File
@@ -16,25 +16,32 @@ const hasCycleMode = (mode) => {
return false
}
const getDefaultChartTypeByMode = (mode) => {
// 1: I, 2: V, 3: R
const settings = {}
settings[0] = ['Elite', 2, 'Elite', 1]
settings[1] = ['Elite', 2, 'Elite', 1]
settings[2] = ['Time', 2, 'Elite', 2]
settings[3] = ['Time', 2, 'Elite', 3]
settings[4] = ['Time', 2, 'Elite', 2]
settings[5] = ['Time', 2, 'Elite', 1]
settings[6] = ['Time', 2, 'Elite', 2]
settings[7] = ['Elite', 2, 'Elite', 1]
settings[8] = ['Elite', 2, 'Elite', 1]
settings[9] = ['Time', 2, 'Elite', 1]
settings[10] = ['Elite', 2, 'Elite', 1]
settings[11] = ['Time', 2, 'Elite', 1]
settings[13] = ['Time', 2, 'Elite', 2]
settings[14] = ['Time', 2, 'Elite', 2]
settings[15] = ['Elite', 2, 'Elite', 1]
return settings[mode]
const getDefaultChartTypeByMode = (mode, lab) => {
if (lab !== 'EliteEIS') {
const settings = {}
settings[0] = ['Elite', 2, 'Elite', 1]
settings[1] = ['Elite', 2, 'Elite', 1]
settings[2] = ['Time', 2, 'Elite', 2]
settings[3] = ['Time', 2, 'Elite', 3]
settings[4] = ['Time', 2, 'Elite', 2]
settings[5] = ['Time', 2, 'Elite', 1]
settings[6] = ['Time', 2, 'Elite', 2]
settings[7] = ['Elite', 2, 'Elite', 1]
settings[8] = ['Elite', 2, 'Elite', 1]
settings[9] = ['Time', 2, 'Elite', 1]
settings[10] = ['Elite', 2, 'Elite', 1]
settings[11] = ['Time', 2, 'Elite', 1]
settings[13] = ['Time', 2, 'Elite', 2]
settings[14] = ['Time', 2, 'Elite', 2]
settings[15] = ['Elite', 2, 'Elite', 1]
return settings[mode]
} else {
const settings = {}
settings[0] = ['EliteEIS', 6, 'EliteEIS', 5]
settings[1] = ['Elite', 2, 'Elite', 1]
settings[2] = ['Time', 2, 'Elite', 2]
return settings[mode]
}
}
const transMac = (rawAddr) => {
+216 -27
View File
@@ -150,6 +150,43 @@ function getLegendName (sourceList, formulaID) {
break
}
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
}
break
default:
legendName += 'D' + source.id + 'CH' + source.channel
break
@@ -684,7 +721,7 @@ export const chartData = {
const _chartRegisterDevice = (chartID, device) => {
if (taskInfo.getDeviceInfo(device.id).info.library_name.indexOf('Elite') >= 0) {
const setting = global_.getDefaultChartTypeByMode(taskInfo.getDeviceInfo(device.id).parameterSet.MODE)
const setting = global_.getDefaultChartTypeByMode(taskInfo.getDeviceInfo(device.id).parameterSet.MODE, taskInfo.getDeviceInfo(device.id).info.library_name)
console.log(setting)
const xType = setting[0]
const xValue = setting[1]
@@ -693,31 +730,68 @@ export const chartData = {
chartRegister(chartID, 0, xType, device.id, xValue, yType, device.id, yValue, null)
_chartData[chartID].chartDevice = 'elite'
_chartData[chartID].chartMode = taskInfo.getDeviceInfo(device.id).parameterSet.MODE
switch (xValue) {
case 1:
_chartData[chartID].chartXUnit = 'uA' // nA * 1000
break
case 2:
_chartData[chartID].chartXUnit = 'mV' // uV * 1000
break
case 3:
_chartData[chartID].chartXUnit = 'Ω' // mOhm * 1000
break
default:
break
}
switch (yValue) {
case 1:
_chartData[chartID].chartYUnit = 'uA'
break
case 2:
_chartData[chartID].chartYUnit = 'mV'
break
case 3:
_chartData[chartID].chartYUnit = 'Ω'
break
default:
break
if (taskInfo.getDeviceInfo(device.id).info.library_name === 'EliteEIS') {
switch (xValue) {
case 3:
_chartData[chartID].chartXUnit = 'mHz'
break
case 4:
_chartData[chartID].chartXUnit = 'cycle'
break
case 8:
_chartData[chartID].chartXUnit = '˚'
break
case 9:
_chartData[chartID].chartXUnit = 'nA'
break
default:
_chartData[chartID].chartXUnit = 'ohm'
break
}
switch (yValue) {
case 3:
_chartData[chartID].chartYUnit = 'mHz'
break
case 4:
_chartData[chartID].chartYUnit = 'cycle'
break
case 8:
_chartData[chartID].chartYUnit = '˚'
break
case 9:
_chartData[chartID].chartYUnit = 'nA'
break
default:
_chartData[chartID].chartYUnit = 'ohm'
break
}
} else {
switch (xValue) {
case 1:
_chartData[chartID].chartXUnit = 'uA' // nA * 1000
break
case 2:
_chartData[chartID].chartXUnit = 'mV' // uV * 1000
break
case 3:
_chartData[chartID].chartXUnit = 'Ω' // mOhm * 1000
break
default:
break
}
switch (yValue) {
case 1:
_chartData[chartID].chartYUnit = 'uA'
break
case 2:
_chartData[chartID].chartYUnit = 'mV'
break
case 3:
_chartData[chartID].chartYUnit = 'Ω'
break
default:
break
}
}
} else if (taskInfo.getDeviceInfo(device.id).info.library_name.indexOf('Neulive') >= 0) {
const channelSet = taskInfo.getDeviceInfo(device.id).parameterSet.RECORDING_CH.toString(2).split('').reverse()
@@ -968,6 +1042,7 @@ const chartRegister = (chartID, gridIndex, deviceNameX, deviceIDX, channelX, dev
// const label = parseInt(parseInt(val / 1000000) / 60) + ' m ' + parseInt((val % 60000000) / 1000000) + ' s'
return label
}
_chartData[chartID].xAxis[_xAxisIndex].interval = 500 * 1000
} else if (sourceList[0].name === 'Elite') {
// _chartData[chartID].series[_chartData[chartID].series.length - 1].sampling = false
switch (sourceList[0].channel) {
@@ -992,6 +1067,39 @@ const chartRegister = (chartID, gridIndex, deviceNameX, deviceIDX, channelX, dev
default:
break
}
} else if (sourceList[0].name === 'EliteEIS') {
switch (sourceList[0].channel) {
case 3:
_chartData[chartID].xAxis[_xAxisIndex].axisLabel.formatter = function (val) {
return val + 'mHz'
}
_chartData[chartID].chartXUnit = 'mHz' // nA * 1000
break
case 4:
_chartData[chartID].xAxis[_xAxisIndex].axisLabel.formatter = function (val) {
return val + 'cycle'
}
_chartData[chartID].chartXUnit = 'cycle' // nA * 1000
break
case 8:
_chartData[chartID].xAxis[_xAxisIndex].axisLabel.formatter = function (val) {
return val + '˚'
}
_chartData[chartID].chartXUnit = '˚' // nA * 1000
break
case 9:
_chartData[chartID].xAxis[_xAxisIndex].axisLabel.formatter = function (val) {
return val + 'nA'
}
_chartData[chartID].chartXUnit = 'nA'
break
default:
_chartData[chartID].xAxis[_xAxisIndex].axisLabel.formatter = function (val) {
return val + 'ohm'
}
_chartData[chartID].chartXUnit = 'ohm'
break
}
}
// set yAxis format
@@ -1056,6 +1164,39 @@ const chartRegister = (chartID, gridIndex, deviceNameX, deviceIDX, channelX, dev
default:
break
}
} else if (sourceList[1].name === 'EliteEIS') {
switch (sourceList[1].channel) {
case 3:
_chartData[chartID].yAxis[_yAxisIndex].axisLabel.formatter = function (val) {
return val + 'mHz'
}
_chartData[chartID].chartYUnit = 'mHz' // nA * 1000
break
case 4:
_chartData[chartID].yAxis[_yAxisIndex].axisLabel.formatter = function (val) {
return val + 'cycle'
}
_chartData[chartID].chartYUnit = 'cycle' // nA * 1000
break
case 8:
_chartData[chartID].yAxis[_yAxisIndex].axisLabel.formatter = function (val) {
return val + '˚'
}
_chartData[chartID].chartYUnit = '˚' // nA * 1000
break
case 9:
_chartData[chartID].yAxis[_yAxisIndex].axisLabel.formatter = function (val) {
return val + 'nA'
}
_chartData[chartID].chartYUnit = 'nA'
break
default:
_chartData[chartID].yAxis[_yAxisIndex].axisLabel.formatter = function (val) {
return val + 'ohm'
}
_chartData[chartID].chartYUnit = 'ohm'
break
}
}
// register series into grid
@@ -1092,6 +1233,46 @@ const chartRegister = (chartID, gridIndex, deviceNameX, deviceIDX, channelX, dev
break
}
break
case 'EliteEIS':
_chartData[chartID].series[_chartData[chartID].series.length - 1].showSymbol = true
_chartData[chartID].series[_chartData[chartID].series.length - 1].showAllSymbol = true
dataStreamBuffer.register(chartID, taskInfo.getRawDeviceID(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')
break
default:
_axisList.push(_axis + ' AXIS = ELITE ' + source.id + ' CHANNEL ' + source.channel)
break
}
break
default:
dataStreamBuffer.register(chartID, taskInfo.getRawDeviceID(source.id), source.channel)
_axisList.push(_axis + ' AXIS = DEVICE ' + source.id + ' CHANNEL ' + source.channel)
@@ -1114,7 +1295,15 @@ const chartRegister = (chartID, gridIndex, deviceNameX, deviceIDX, channelX, dev
if (_chartData[chartID].gridSource[gridIndex] == null) {
_chartData[chartID].gridSource[gridIndex] = []
}
_chartData[chartID].gridSource[gridIndex].push(_gridSeries)
let repeat = false
_chartData[chartID].gridSource[gridIndex].forEach(s => {
if (s.name === _gridSeries.name) {
repeat = true
}
})
if (!repeat) {
_chartData[chartID].gridSource[gridIndex].push(_gridSeries)
}
// console.log(_chartData[chartID])
return _chartData[chartID]
+2 -2
View File
@@ -97,8 +97,8 @@ export const dataStreamBuffer = {
// }
// lastTime = samplingTime
// })
_dataStreamBuffer[chart][currentDeviceID][currentChannel].push(dataBatch)
const _dataBatch = Array.from(dataBatch)
_dataStreamBuffer[chart][currentDeviceID][currentChannel].push(_dataBatch)
if (_dataStreamBuffer[chart][currentDeviceID][currentChannel].length > _dataStreamBufferSize) {
_dataStreamBuffer[chart][currentDeviceID][currentChannel].shift()
}
+1
View File
@@ -6,6 +6,7 @@ function newDataZoom () {
height: '10px',
// realtime: false,
bottom: '8%',
zoomLock: false,
handleStyle: {
shadowColor: 'rgba(0, 0, 0, 0)',
},
+1 -1
View File
@@ -5,7 +5,7 @@ function newSeries (type, legendName, xAxisIndex, yAxisIndex, xAxisSource, yAxis
// symbol: 'circle',
showSymbol: false,
showAllSymbol: false,
symbolSize: 2,
symbolSize: 4,
// [modified 2021/08/10] sampling method managed by vuex
// sampling: 'average',
// sampling: function (frame) {
+87
View File
@@ -60,6 +60,93 @@ function newParameterSet () {
ADC_CHANNEL: 0,
// Neulive3.0
AXIS_CH: 0,
// Neulive3.5
STI_T1_CH0: 0,
STI_T2_CH0: 0,
STI_T3_CH0: 0,
STI_T4_CH0: 0,
STI_T5_CH0: 0,
STI_T1_CH1: 0,
STI_T2_CH1: 0,
STI_T3_CH1: 0,
STI_T4_CH1: 0,
STI_T5_CH1: 0,
STI_T1_CH2: 0,
STI_T2_CH2: 0,
STI_T3_CH2: 0,
STI_T4_CH2: 0,
STI_T5_CH2: 0,
STI_T1_CH3: 0,
STI_T2_CH3: 0,
STI_T3_CH3: 0,
STI_T4_CH3: 0,
STI_T5_CH3: 0,
STI_T1_CH4: 0,
STI_T2_CH4: 0,
STI_T3_CH4: 0,
STI_T4_CH4: 0,
STI_T5_CH4: 0,
STI_T1_CH5: 0,
STI_T2_CH5: 0,
STI_T3_CH5: 0,
STI_T4_CH5: 0,
STI_T5_CH5: 0,
STI_T1_CH6: 0,
STI_T2_CH6: 0,
STI_T3_CH6: 0,
STI_T4_CH6: 0,
STI_T5_CH6: 0,
STI_T1_CH7: 0,
STI_T2_CH7: 0,
STI_T3_CH7: 0,
STI_T4_CH7: 0,
STI_T5_CH7: 0,
STI_T1_CH8: 0,
STI_T2_CH8: 0,
STI_T3_CH8: 0,
STI_T4_CH8: 0,
STI_T5_CH8: 0,
STI_T1_CH9: 0,
STI_T2_CH9: 0,
STI_T3_CH9: 0,
STI_T4_CH9: 0,
STI_T5_CH9: 0,
STI_T1_CH10: 0,
STI_T2_CH10: 0,
STI_T3_CH10: 0,
STI_T4_CH10: 0,
STI_T5_CH10: 0,
STI_T1_CH11: 0,
STI_T2_CH11: 0,
STI_T3_CH11: 0,
STI_T4_CH11: 0,
STI_T5_CH11: 0,
STI_T1_CH12: 0,
STI_T2_CH12: 0,
STI_T3_CH12: 0,
STI_T4_CH12: 0,
STI_T5_CH12: 0,
STI_T1_CH13: 0,
STI_T2_CH13: 0,
STI_T3_CH13: 0,
STI_T4_CH13: 0,
STI_T5_CH13: 0,
STI_T1_CH14: 0,
STI_T2_CH14: 0,
STI_T3_CH14: 0,
STI_T4_CH14: 0,
STI_T5_CH14: 0,
STI_T1_CH15: 0,
STI_T2_CH15: 0,
STI_T3_CH15: 0,
STI_T4_CH15: 0,
STI_T5_CH15: 0,
STI_AMPLITUDE_H1: 0,
STI_AMPLITUDE_L1: 0,
STI_AMPLITUDE_H2: 0,
STI_AMPLITUDE_L2: 0,
RECORDING_CH_L: 0,
RECORDING_CH_H: 0,
// Eilte
ADC_LEVEL: 0,
ADC_VALUE_I: 0,
+8
View File
@@ -7,10 +7,18 @@ function newTask () {
taskDeviceID: [],
chartNumber: 0,
deviceList: {
0: newDevice(0),
1: newDevice(1),
2: newDevice(2),
3: newDevice(3),
4: newDevice(4),
5: newDevice(5),
6: newDevice(6),
7: newDevice(7),
8: newDevice(8),
9: newDevice(9),
10: newDevice(10),
11: newDevice(11),
},
chartList: [],
formulaList: [],
+1 -1
View File
@@ -76,7 +76,7 @@ export default new Router({
children: [
{
name: 'download',
path: ':format/:metaList',
path: ':format/:metaList/:sd?',
component: () => import('../components/download/Download.vue'),
},
],
@@ -330,6 +330,29 @@ const chartMutations = {
state.chartData[payload.chartID].series[payload.seriesIndex].sampling = payload.method
},
/**
* lock dataZoom
*
* @param {object} chartAllData
* @param {int} chartID
* @param {bool} zoomLock
*/
[typePath.lockDataZoom]: (state, payload) => {
if (payload.zoomLock === true || payload.zoomLock === false) {
payload.chartAllData[payload.chartID].dataZoom[0].zoomLock = payload.zoomLock
}
},
/**
* for manually set datazoom start and end
*
*/
[typePath.setOverviewDataZoomStartAndEnd]: (state, payload) => {
if (state.chartOverviewData.dataZoom != null) {
state.chartOverviewData.dataZoom[0].start = 0
state.chartOverviewData.dataZoom[0].end = 100
}
},
}
export default chartMutations
@@ -17,6 +17,9 @@ function newState () {
chartData: {},
chartOverviewData: {},
chartDetailData: {},
startTime: 0,
endTime: 0,
windowLength: 0,
startTimeCurrent: 0,
endTimeCurrent: 0,
currentScale: '0',
@@ -28,6 +31,8 @@ function newState () {
valueFormatX: {},
valueFormatY: {},
showCyclePanel: false,
useSdCardData: false,
isLockDataZoom: false,
}
}
@@ -32,6 +32,8 @@ const types = {
updateRegistered: 'updateRegisteredChart',
updateAxisSplitNumber: 'updateAxisSplitNumberChart',
updateChartSampling: 'updateChartSamplingChart',
lockDataZoom: 'lockDataZoomChart',
setOverviewDataZoomStartAndEnd: 'setOverviewDataZoomStartAndEndChart',
},
meta: {
init: 'initMeta',
@@ -97,7 +97,7 @@ const chartMutations = {
axisLabel.formatter = function (val) {
let label
if (payload.channel < 256) {
const num = String(val)
const num = String(val.toFixed(2))
label = num + 'µV'
} else {
label = String(val.toFixed(2))
+14 -11
View File
@@ -5,7 +5,7 @@ const typePath = types.export
const typePathDownload = types.download
const typePathDownloadStream = types.downloadStream
const NeuliveParameterOrder = ['RECORDING_CH', 'AXIS_CH', 'AMP_GAIN', 'ADC_CLOCK']
const NeuliveParameterOrder = ['RECORDING_CH', 'AXIS_CH', 'AMP_GAIN', 'SAMPLE_RATE']
const NeuliveAmpGain = [100, 400, 800]
const exportActs = {
@@ -20,17 +20,17 @@ const exportActs = {
NeuliveParameterOrder.forEach(p => {
const value = meta.parameter_set[p]
if (p === 'RECORDING_CH') {
let result = '"'
let result = ''
const channelList = value.toString(2).split('').reverse()
channelList.forEach((_value, _index) => {
if (_value === '1') {
result = result + `${_index + 1},`
}
})
result = result.slice(0, -1) + '"'
result = result.slice(0, -1)
parameter.push(['Record channels', result])
} else if (p === 'AXIS_CH') {
let result = '"'
let result = ''
const channelList = value.toString(2).split('').reverse()
channelList.forEach((_value, _index) => {
if (_value === '1') {
@@ -48,13 +48,12 @@ const exportActs = {
if (result.length !== 1) {
result = result.slice(0, -1)
}
result += '"'
parameter.push(['Accelrator channels', result])
} else if (p === 'AMP_GAIN') {
parameter.push(['Amp gain', NeuliveAmpGain[value]])
} else if (p === 'ADC_CLOCK') {
} else if (p === 'SAMPLE_RATE') {
const recordChannel = JSON.parse(meta.channels).filter(ch => parseInt(ch) < 256)
parameter.push(['Sample Rate', parseInt(8e5 / (value * recordChannel.length))])
parameter.push(['Sample Rate', parseInt(value / recordChannel.length)])
}
})
} else if (device[0] === 'Elite') {
@@ -196,14 +195,18 @@ const exportActs = {
for (let row = 0; row < dataLength; row++) {
const rowData = []
for (const [chIndex, channel] of channels.entries()) {
const dataBuffer = downloadInfo.channelInfo[channel].downloadDataBuffer
for (const index in dataBuffer) {
const columnArray = [...Array(downloadInfo.maxColumns).keys()]
for (const index in columnArray) {
for (const [chIndex, channel] of channels.entries()) {
const dataBuffer = downloadInfo.channelInfo[channel].downloadDataBuffer
if (dataBuffer[index][row] === undefined) {
if (downloadInfo.format === 'csv-edf' && payload.last) {
dataBuffer[index][row] = []
if (row === 0) {
break
}
if (chIndex === 0) {
dataBuffer[index][row].push(((dataBuffer[index][row - 1][0] + downloadInfo.channelInfo[channel].timeInterval) / 1e6).toFixed(6))
dataBuffer[index][row].push((parseFloat(dataBuffer[index][row - 1][0]) + (downloadInfo.channelInfo[channel].timeInterval / 1e6)).toFixed(6))
}
dataBuffer[index][row].push(dataBuffer[index][row - 1][1])
rowData.push(...dataBuffer[index][row])
+55 -39
View File
@@ -14,19 +14,24 @@ const rawActs = {
*/
[typePath.rawDataByID]: async ({ state, getters, commit, dispatch }, payload) => {
const { channel, rawID, idx, api } = payload
const dataArray = []
const rawDataRes = await api.raw.getAttrByID(channel, rawID, 'id-channel-size-serial_number-start_time-end_time-data')
if (rawDataRes.data !== null) {
dispatch(typePath.parseRawData, { channel: channel, dataArray: dataArray, rawData: rawDataRes }).then(response => {
if (state.downloadInfo === undefined) {
return response
} else {
if (state.downloadInfo.channelInfo[channel].downloadDataBuffer[idx] === undefined) {
state.downloadInfo.channelInfo[channel].downloadDataBuffer[idx] = []
}
state.downloadInfo.channelInfo[channel].downloadDataBuffer[idx].push(...response)
}
})
if (state.downloadInfo.channelInfo[channel].downloadDataBuffer[idx] === undefined) {
state.downloadInfo.channelInfo[channel].downloadDataBuffer[idx] = []
}
dispatch(typePath.parseRawData, { channel: channel, idx: idx, rawData: rawDataRes })
}
},
[typePath.rawSdDataByID]: async ({ state, getters, commit, dispatch }, payload) => {
const { channel, rawID, idx, api } = payload
const rawDataRes = await api.raw.getAttrByID(channel, rawID, 'id-channel-size-serial_number-start_time-end_time-sd_data')
if (rawDataRes.data !== null) {
if (state.downloadInfo.channelInfo[channel].downloadDataBuffer[idx] === undefined) {
state.downloadInfo.channelInfo[channel].downloadDataBuffer[idx] = []
}
dispatch(typePath.parseRawSdData, { channel: channel, idx: idx, rawData: rawDataRes })
}
},
@@ -51,8 +56,7 @@ const rawActs = {
},
[typePath.parseRawData]: function ({ state, getters, commit, dispatch }, payload) {
const { channel, rawData } = payload
const dataArray = []
const { channel, rawData, idx } = payload
for (const raw of rawData.data) {
if (raw.data !== null && raw.data.length > 0) {
const encodedData = raw.data.split('"***"').slice(0, -1)
@@ -63,24 +67,41 @@ const rawActs = {
for (let i = 0; i <= unzipDatas.length - 1; i++) {
if (unzipDatas[i].length > 0) {
if (state.downloadInfo === undefined) {
dispatch(typePath.parseData, { channel: channel, rawData: unzipDatas[i] }).then(response => {
dataArray.push(...response)
}).catch(e => {
console.log(e)
})
dispatch(typePath.parseData, { channel: channel, rawData: unzipDatas[i], idx: idx })
} else {
if (state.downloadInfo.format === 'csv-edf') {
dispatch(typePath.parseFixedData, { channel: channel, rawData: unzipDatas[i] }).then(response => {
dataArray.push(...response)
}).catch(e => {
console.log(e)
})
dispatch(typePath.parseFixedData, { channel: channel, rawData: unzipDatas[i], idx: idx })
} else {
dispatch(typePath.parseData, { channel: channel, rawData: unzipDatas[i] }).then(response => {
dataArray.push(...response)
}).catch(e => {
console.log(e)
})
dispatch(typePath.parseData, { channel: channel, rawData: unzipDatas[i], idx: idx })
}
}
}
}
encodedData.length = 0
unzipDatas.length = 0
}
}
delete payload.rawData
},
[typePath.parseRawSdData]: function ({ state, getters, commit, dispatch }, payload) {
const { channel, rawData, idx } = payload
for (const raw of rawData.data) {
if (raw.sd_data !== null && raw.sd_data.length > 0) {
const encodedData = raw.sd_data.split('"***"').slice(0, -1)
const unzipDatas = encodedData.map(ctx => {
return ctx.split(' ')
})
for (let i = 0; i <= unzipDatas.length - 1; i++) {
if (unzipDatas[i].length > 0) {
if (state.downloadInfo === undefined) {
dispatch(typePath.parseData, { channel: channel, rawData: unzipDatas[i], idx: idx })
} else {
if (state.downloadInfo.format === 'csv-edf') {
dispatch(typePath.parseFixedData, { channel: channel, rawData: unzipDatas[i], idx: idx })
} else {
dispatch(typePath.parseData, { channel: channel, rawData: unzipDatas[i], idx: idx })
}
}
}
@@ -90,13 +111,11 @@ const rawActs = {
}
}
delete payload.rawData
return dataArray
},
[typePath.parseData]: function ({ state, getters, commit }, payload) {
const { channel, rawData } = payload
const { channel, rawData, idx } = payload
const meta = state.metaInfo
const dataArray = []
for (let i = 0; i <= rawData.length - 1; i += 2) {
if (rawData[i].length !== 0) {
@@ -105,20 +124,18 @@ const rawActs = {
if (time <= parseInt(meta.time_duration)) {
const tmpData = [time, data]
dataArray.push(tmpData)
state.downloadInfo.channelInfo[channel].downloadDataBuffer[idx].push(tmpData)
}
}
}
delete payload.rawData
return dataArray
},
[typePath.parseFixedData]: function ({ state, getters, commit }, payload) {
const { channel, rawData } = payload
const { channel, rawData, idx } = payload
const meta = state.metaInfo
const downloadInfo = state.downloadInfo
const timeInterval = state.downloadInfo.channelInfo[channel].timeInterval
const dataArray = []
for (let i = 0; i <= rawData.length - 1; i += 2) {
if (rawData[i].length !== 0) {
@@ -129,7 +146,7 @@ const rawActs = {
const timeDiffOrigin = timeDiff
const dataDiff = parseInt(data) - parseInt(downloadInfo.channelInfo[channel].prevData)
if (timeDiff >= 1.5 * timeInterval && downloadInfo.channelInfo[channel].prevTime > 0) {
console.log('data-recover', timeDiff)
// console.log('data-recover', timeDiff)
let timeCorrection = 0
let dataIndex = 1
@@ -139,20 +156,19 @@ const rawActs = {
if (timeDiff > 0) {
const _time = parseInt(downloadInfo.channelInfo[channel].prevTime) + parseInt(timeCorrection)
const _data = (parseInt(downloadInfo.channelInfo[channel].prevData) + (timeCorrection / timeDiffOrigin) * (dataDiff)).toFixed(3)
dataArray.push([_time, _data])
state.downloadInfo.channelInfo[channel].downloadDataBuffer[idx].push([_time, _data])
dataIndex = dataIndex + 1
}
}
}
if (time <= parseInt(meta.time_duration) && time !== downloadInfo.channelInfo[channel].prevTime) {
dataArray.push([time, data])
state.downloadInfo.channelInfo[channel].downloadDataBuffer[idx].push([time, data])
}
downloadInfo.channelInfo[channel].prevTime = time
downloadInfo.channelInfo[channel].prevData = data
}
}
delete payload.rawData
return dataArray
},
}
@@ -27,10 +27,10 @@ const downloadMutations = {
if (device[0] === 'Neulive') {
if (channel < 256) {
sampleRate = parseInt(800000 / parseInt(meta.configuration.ADC_CLOCK))
sampleRate = meta.configuration.SAMPLE_RATE
sampleRateDivideNum = state.downloadInfo.channel.length
} else if (channel >= 256 && channel <= 259) {
sampleRate = parseInt(800000 / parseInt(meta.configuration.ADC_CLOCK) / 78)
sampleRate = parseInt(meta.configuration.SAMPLE_RATE / 76)
}
} else if (device[0] === 'Elite') {
if (device[1] === 'ZM15') {
+2
View File
@@ -12,7 +12,9 @@ const types = {
},
raw: {
rawDataByID: 'rawDataByIDRaw',
rawSdDataByID: 'rawSdDataByIDRaw',
parseRawData: 'parseRawDataRaw',
parseRawSdData: 'parseRawSdDataRaw',
parseData: 'parseDataRaw',
parseFixedData: 'parseFixedDataRaw',
},
@@ -8,17 +8,21 @@ const paramActs = {
const device = payload.device
let status = true
let message = ''
const channelList = []
const channelSet = taskInfo.getDeviceInfo(device.id).parameterSet.RECORDING_CH.toString(2).split('').reverse()
channelSet.forEach((element, index) => {
if (parseInt(element) > 0) {
channelList.push(index + 1)
if (device.library_name.indexOf('Neulive') !== -1) {
if (device.library_version.indexOf('3.0') !== -1 || device.library_version.indexOf('3.1') !== -1) {
if (taskInfo.getDeviceInfo(device.id).parameterSet.RECORDING_CH <= 0) {
status = false
message += '\nRecording need at least one channel,'
}
}
if (device.library_version.indexOf('3.5') !== -1) {
if (taskInfo.getDeviceInfo(device.id).parameterSet.RECORDING_CH_L <= 0 && taskInfo.getDeviceInfo(device.id).parameterSet.RECORDING_CH_H <= 0) {
status = false
message += '\nRecording need at least one channel,'
}
}
})
if (channelList.length <= 0) {
status = false
message += '\nRecording need at least one channel,'
}
return { status: status, message: message }
},
[typePath.checkIfStimulationSetDone]: async ({ state, getters, commit }, payload) => {
@@ -0,0 +1,83 @@
import types from '@/store/modules/task/content/types'
// import taskInfo from '@/data/task/TaskInfo.js'
const typePath = types.param
const paramGet = {
/**
* get if recording param is set done
* @param {string} : deviceType
*
* @return {object} : {status, message}
*/
[typePath.getIsRecordingParamSetDone]: (state) => (deviceType) => {
let status = true
let message = ''
if (deviceType === 'Neulive') {
if (state.channelList.length <= 0) {
status = false
message += '\nRecording need at least one channel,'
}
}
// else Elite: TODO
return { status: status, message: message }
},
/**
* get if stimulation param is set done
*
* @return {object} : {status, message}
*/
[typePath.getIsStimulationParamSetDone]: (state) => {
let status = true
let message = ''
if (state.stimulateElectrodeSelect === 0) { // monopolar
if (state.posChannelList.length + state.negChannelList.length <= 0) { // 至少有選一個ch
status = false
message += '\nMonopolar need at least one channel,'
}
} else if (state.stimulateElectrodeSelect === 1) { // bipolar
if (state.posChannelList.length + state.negChannelList.length <= 1) { // 至少要選2個channel
status = false
message += '\nBipolar need at least two channel,'
}
if (state.posChannelList.length <= 0 || state.negChannelList.length <= 0) { // 且要有正有負
status = false
message += '\nBipolar need at least one positive and one negative channel,'
}
}
const tRangeLength = state.TRangeErrorMsgList.length
for (let i = 0; i < tRangeLength; i++) {
if (state.TRangeErrorMsgList[i].showError === true) {
status = false
message += '\nStimulation T ranges are not set correctly'
break
}
}
return { status: status, message: message }
},
/**
* get if param is set done
* @param {string} : deviceType
*
* @return {object} : {status, message}
*/
[typePath.getIsParamSetDone]: (state, getters) => (deviceType) => {
let status = true
let message = ''
if (deviceType === 'Neulive') {
let checkParam = getters.getIsRecordingParamSetDoneParam(deviceType)
status = checkParam.status && status
message += checkParam.message
checkParam = getters.getIsStimulationParamSetDoneParam
status = checkParam.status && status
message += checkParam.message
}
// else Elite: TODO
return { status: status, message: message }
},
}
export default paramGet