Compare commits
89 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6f2aab5276 | |||
| 8aa87d587f | |||
| 38503e198e | |||
| 94feff568a | |||
| 06336bbd61 | |||
| 33b041a31b | |||
| 14dda58fac | |||
| 6b20902c74 | |||
| ced0362910 | |||
| 467016140f | |||
| f6e642cd5f | |||
| 7c5aed4dbc | |||
| c069354415 | |||
| 738b58fded | |||
| f7c89585ac | |||
| 36ed59816d | |||
| 516d20333c | |||
| 74b8472c1d | |||
| ecb9e02610 | |||
| 74dea74476 | |||
| 588a791bc1 | |||
| cd3e6f08f5 | |||
| 1370e5659e | |||
| e18fa916b5 | |||
| b5a920338a | |||
| 6c4660966c | |||
| 0db13d3404 | |||
| 8b96a7308c | |||
| d7e69e250e | |||
| 14217aa1ea | |||
| 506080c518 | |||
| 794b71cc9f | |||
| 7e355448e0 | |||
| 1bcf0d99e9 | |||
| af094ad93a | |||
| 062023bd95 | |||
| fcef23b199 | |||
| 56051c881a | |||
| 9bc027b445 | |||
| 06528addc7 | |||
| 279a1056f4 | |||
| 0ef305c434 | |||
| 2161b37932 | |||
| 6b63b2b406 | |||
| ccdc193067 | |||
| 2ba4644a78 | |||
| 72dbb2abf5 | |||
| 7f498c01ed | |||
| d9f7813a3c | |||
| 35c436ee67 | |||
| 2f82138097 | |||
| e4d2186d86 | |||
| 749fd86c65 | |||
| 95bb4afa49 | |||
| 6c5c832fde | |||
| 256070ae76 | |||
| 7edde3d7b2 | |||
| 8ba6bcb8cb | |||
| 1398ffad4c | |||
| e82d17ab4f | |||
| d116c9951a | |||
| d3e02ee4db | |||
| 2f9cd9fae0 | |||
| cfca599408 | |||
| fecbd4e4da | |||
| 08fcba3f58 | |||
| e4da226a03 | |||
| b68471eff6 | |||
| 5cf83f18c4 | |||
| 11f4793a7a | |||
| 7d615e0e53 | |||
| 589727142c | |||
| 230fb4f8a4 | |||
| 058057dca4 | |||
| e5ff49333d | |||
| 2b70a54a07 | |||
| 9b64a5484e | |||
| e6dcb0d389 | |||
| 8a2f001f28 | |||
| 4fa122c754 | |||
| 1ebfa0b343 | |||
| e786ce437d | |||
| 8b841a8524 | |||
| fabeca30b6 | |||
| cee179b1f7 | |||
| 758aac1909 | |||
| cf648fe862 | |||
| d3610b3430 | |||
| 054a8a6382 |
+2
-1
@@ -51,7 +51,8 @@ Vue.use(VueAxios, axios)
|
||||
|
||||
// Vue.use(VueMqtt, 'ws://52.194.17.114:8083')
|
||||
// Vue.use(VueMqtt, 'ws://' + location.href.split('/')[2] + ':8083')
|
||||
Vue.use(VueMqtt, 'ws://' + '192.168.3.48' + ':8083')
|
||||
// Vue.use(VueMqtt, 'ws://' + '192.168.151.125' + ':8083')
|
||||
Vue.use(VueMqtt, 'ws://' + '192.168.151.125' + ':8083')
|
||||
|
||||
Vue.prototype.GLOBAL = global_
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ export default {
|
||||
data () {
|
||||
return {
|
||||
isTopBar: false,
|
||||
minimized: false,
|
||||
minimized: true,
|
||||
mobileWidth: 767,
|
||||
}
|
||||
},
|
||||
@@ -136,7 +136,7 @@ export default {
|
||||
</style>
|
||||
|
||||
<style lang='scss'>
|
||||
.layout.gutter--xl {
|
||||
padding: 0.75rem;
|
||||
}
|
||||
// .layout.gutter--xl {
|
||||
// padding: 0.5rem;
|
||||
// }
|
||||
</style>
|
||||
|
||||
@@ -29,7 +29,7 @@ export default {
|
||||
},
|
||||
updateSidebarState () {
|
||||
if (this.checkIsDesktop()) {
|
||||
this.$emit('update:minimized', false)
|
||||
this.$emit('update:minimized', true)
|
||||
} else {
|
||||
this.$emit('update:minimized', true)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="row row-equal">
|
||||
<div class="flex md12 xl3 xs12 sm12 area-style">
|
||||
<div class="flex md12 xl3 xs12 sm12">
|
||||
<div class="row">
|
||||
<div class="flex sm12 xl12 md12 xs12">
|
||||
<va-accordion>
|
||||
@@ -18,11 +18,11 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div :class="chartAreaClass" class="area-style">
|
||||
<div :class="chartAreaClass">
|
||||
<div class="row" >
|
||||
<div class="flex sm12 xl12 md12 xs12">
|
||||
<elite-replay-overview-chart v-show="showOverviewChart" :ref="'chart_overview'" class="mb-1" :cardheight="'7vh'" :data="chartOverviewData" @dataZoomEvent="dataZoomEvent($event)"/>
|
||||
<elite-replay-chart :ref="'chart_detail'" @dblclick.native="distribute()" :cardheight="'88vh'" :data="chartDetailData" />
|
||||
<elite-replay-chart :ref="'chart_detail'" @dblclick.native="distribute()" :cardheight="'88vh'" :chartheight="detailchartheight" :data="chartDetailData" />
|
||||
<change-channel-value-min-max :ref="'set_min_max'"/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -41,7 +41,6 @@ import api from '@/data/api/index'
|
||||
import { download } from '@/data/download/Download'
|
||||
import types from '@/store/modules/analysis/replay/types'
|
||||
import { mapFields } from 'vuex-map-fields'
|
||||
import { newChartMode } from '@/factories/chart/chartFactory'
|
||||
|
||||
export default {
|
||||
name: 'elite-data-replay',
|
||||
@@ -62,6 +61,7 @@ export default {
|
||||
'axisYDataType',
|
||||
'startTimeCurrent',
|
||||
'endTimeCurrent',
|
||||
'sampleMethod',
|
||||
]),
|
||||
},
|
||||
props: {
|
||||
@@ -87,6 +87,7 @@ export default {
|
||||
data () {
|
||||
return {
|
||||
showOverviewChart: false,
|
||||
detailchartheight: '88vh',
|
||||
dataInfo: {},
|
||||
maxTime: 0,
|
||||
startTime: 0,
|
||||
@@ -155,7 +156,7 @@ export default {
|
||||
})
|
||||
let _gridNumber = 0
|
||||
const register = this.metaList.map(meta => {
|
||||
const setting = newChartMode(meta.parameter_set.MODE)
|
||||
const setting = this.GLOBAL.getDefaultChartTypeByMode(meta.parameter_set.MODE)
|
||||
const xType = setting[0] // Elite or Time
|
||||
const yType = setting[2] // Elite or Time
|
||||
const xValue = setting[1] // 1: I, 2: V, 3: R
|
||||
@@ -246,12 +247,12 @@ export default {
|
||||
let scale = '100'
|
||||
if (this.axisXDataType.description === 'Time') {
|
||||
const sampleRate = metaInfo.parameter_set.SAMPLE_RATE / 10
|
||||
scale = (((metaInfo.time_duration / 100000) * sampleRate) / 4000) * 0.1
|
||||
if (scale > 500) {
|
||||
const dataPointNum = (parseInt(metaInfo.time_duration) / 1e6) * sampleRate // us -> s: /1e6
|
||||
if (dataPointNum > 2e6) { // 2000 (points) * 1000 (resample) = 2e6
|
||||
scale = '1000'
|
||||
} else if (scale > 200) {
|
||||
} else if (dataPointNum > 2e5) { // 2000 (points) * 100 (resample) = 2e5
|
||||
scale = '100'
|
||||
} else if (scale > 30) {
|
||||
} else if (dataPointNum > 2e4) { // 2000 (points) * 10 (resample) = 2e4
|
||||
scale = '10'
|
||||
} else {
|
||||
scale = '1'
|
||||
@@ -260,7 +261,6 @@ export default {
|
||||
scale = '1' // [TODO] select by user
|
||||
}
|
||||
console.log('overview scale:', scale)
|
||||
const sampleMethod = 'mean'
|
||||
// download data
|
||||
const getAllData = async function (_this) {
|
||||
for (const ch in _this.dataInfo[meta]) {
|
||||
@@ -272,7 +272,7 @@ export default {
|
||||
metaID: meta,
|
||||
channel: ch,
|
||||
scale: scale,
|
||||
data: await _this.getData(parseInt(scale), sampleMethod, dataList[i].id, ch, metaInfo),
|
||||
data: await _this.getData(parseInt(scale), _this.sampleMethod, dataList[i].id, ch, metaInfo),
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -302,15 +302,16 @@ export default {
|
||||
metaInfo = _meta
|
||||
}
|
||||
})
|
||||
|
||||
let scale = '100'
|
||||
if (this.axisXDataType.description === 'Time') {
|
||||
const sampleRate = metaInfo.parameter_set.SAMPLE_RATE / 10
|
||||
scale = (((timeDur / 100000) * sampleRate) / 4000) * 0.1
|
||||
if (scale > 500) {
|
||||
const dataPointNum = (parseInt(timeDur) / 1e6) * sampleRate // us -> s: /1e6
|
||||
if (dataPointNum > 2e6) { // 2000 (points) * 1000 (resample) = 2e6
|
||||
scale = '1000'
|
||||
} else if (scale > 200) {
|
||||
} else if (dataPointNum > 2e5) { // 2000 (points) * 100 (resample) = 2e5
|
||||
scale = '100'
|
||||
} else if (scale > 30) {
|
||||
} else if (dataPointNum > 2e4) { // 2000 (points) * 10 (resample) = 2e4
|
||||
scale = '10'
|
||||
} else {
|
||||
scale = '1'
|
||||
@@ -318,8 +319,14 @@ export default {
|
||||
} else {
|
||||
scale = '1' // [TODO] select by user
|
||||
}
|
||||
// elite的sample rate不像neulive這麼高,因此試試scale = 100 or 1000時不要再sampling一次了,不然有些形狀(e.g. peak)會不一樣
|
||||
if (scale === '100' || scale === '1000') {
|
||||
this.updateChartSamplingChart({ chartID: this.chartDetailData.chartID, seriesIndex: _gridNumber, method: null })
|
||||
} else {
|
||||
this.updateChartSamplingChart({ chartID: this.chartDetailData.chartID, seriesIndex: _gridNumber, method: 'lttb' })
|
||||
}
|
||||
|
||||
this.currentScale = scale
|
||||
const sampleMethod = 'mean'
|
||||
this.chartDetailData.series[_gridNumber].data.length = 0
|
||||
let dataListX
|
||||
const channelX = parseInt(this.axisXDataType.id)
|
||||
@@ -328,50 +335,51 @@ export default {
|
||||
}
|
||||
const channelY = parseInt(this.axisYDataType.id)
|
||||
const dataListY = this.dataInfo[meta][channelY][scale]
|
||||
|
||||
const isThisModeHasCycle = this.GLOBAL.hasCycleMode(metaInfo.parameter_set.MODE)
|
||||
let startTime
|
||||
let endTime
|
||||
if (isThisModeHasCycle === true && this.axisXDataType.description !== 'Time') { // if有cycle的mode且目前x軸不為時間,抓出第一圈所在的時間段,初始化時先畫第一圈就好,加快初始時間
|
||||
const cycleDataID = 3 // recorded cycle 所在的channel index
|
||||
const dataCycleList = this.dataInfo[meta][cycleDataID][this.currentScale]
|
||||
const cycleDataList = []
|
||||
for (let i = 0; i < dataCycleList.length; i++) {
|
||||
if (dataCycleList[i].data.length === 0) {
|
||||
const data = await this.getData(parseInt(this.currentScale), this.sampleMethod, dataCycleList[i].id, cycleDataID, metaInfo)
|
||||
cycleDataList.push({ data: data })
|
||||
} else {
|
||||
cycleDataList.push({ data: dataCycleList[i].data })
|
||||
}
|
||||
}
|
||||
const cycleDict = this.getCycleDictRec()(cycleDataList)
|
||||
startTime = cycleDict[1][0] // [1]: 第一圈
|
||||
endTime = cycleDict[1][1] // [1]: 第一圈
|
||||
} else {
|
||||
startTime = this.startTimeCurrent
|
||||
endTime = this.endTimeCurrent
|
||||
}
|
||||
|
||||
let startIndex = 0
|
||||
let endIndex = 0
|
||||
// get the subfile index
|
||||
for (let i = 0; i < dataListY.length; i++) {
|
||||
if (this.startTimeCurrent >= parseInt(dataListY[i].start_time) && this.startTimeCurrent <= parseInt(dataListY[i].end_time)) {
|
||||
if (startTime >= parseInt(dataListY[i].start_time) && startTime <= parseInt(dataListY[i].end_time)) {
|
||||
startIndex = i
|
||||
}
|
||||
if (this.endTimeCurrent >= parseInt(dataListY[i].start_time) && this.endTimeCurrent <= parseInt(dataListY[i].end_time)) {
|
||||
if (endTime >= parseInt(dataListY[i].start_time) && endTime <= parseInt(dataListY[i].end_time)) {
|
||||
endIndex = i
|
||||
}
|
||||
}
|
||||
// download and push into chart
|
||||
for (let i = startIndex; i <= endIndex; i++) {
|
||||
let data
|
||||
if (dataListY[i].data.length === 0) {
|
||||
data = await this.getData(parseInt(scale), sampleMethod, dataListY[i].id, channelY, metaInfo)
|
||||
this.intoDataRec({
|
||||
index: i,
|
||||
metaID: meta,
|
||||
channel: channelY,
|
||||
scale: scale,
|
||||
data: data,
|
||||
})
|
||||
} else {
|
||||
data = JSON.parse(JSON.stringify(this.dataInfo[meta][channelY][scale][i].data))
|
||||
}
|
||||
const data = await this.getData(parseInt(scale), this.sampleMethod, dataListY[i].id, channelY, metaInfo)
|
||||
let dataX
|
||||
if (this.axisXDataType.description !== 'Time') {
|
||||
if (dataListX[i].data.length === 0) {
|
||||
dataX = await this.getData(parseInt(scale), sampleMethod, dataListX[i].id, channelX, metaInfo)
|
||||
this.intoDataRec({
|
||||
index: i,
|
||||
metaID: meta,
|
||||
channel: channelX,
|
||||
scale: scale,
|
||||
data: dataX,
|
||||
})
|
||||
} else {
|
||||
dataX = JSON.parse(JSON.stringify(this.dataInfo[meta][channelX][scale][i].data))
|
||||
}
|
||||
dataX = await this.getData(parseInt(scale), this.sampleMethod, dataListX[i].id, channelX, metaInfo)
|
||||
}
|
||||
for (let j = 0, len = data.length; j < len; j++) {
|
||||
// check which channel and push processed data (i.e. merge two channel data, now data is (time, value) format)
|
||||
if (parseInt(data[j][0]) >= this.startTimeCurrent && parseInt(data[j][0]) <= this.endTimeCurrent) {
|
||||
if (parseInt(data[j][0]) >= startTime && parseInt(data[j][0]) <= endTime) {
|
||||
const processedData = JSON.parse(JSON.stringify(data[j]))
|
||||
if (dataX !== undefined) {
|
||||
processedData[0] = dataX[j][1]
|
||||
@@ -381,6 +389,7 @@ export default {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this.axisXDataType.description === 'Time') {
|
||||
this.chartDetailData.xAxis[_gridNumber].min = this.startTimeCurrent
|
||||
this.chartDetailData.xAxis[_gridNumber].max = this.endTimeCurrent
|
||||
@@ -390,7 +399,18 @@ export default {
|
||||
}
|
||||
_gridNumber += 1
|
||||
}
|
||||
console.log(this.chartDetailData)
|
||||
|
||||
if (this.axisXDataType.description !== 'Time') {
|
||||
this.showOverviewChart = false
|
||||
this.detailchartheight = '88vh'
|
||||
// this.$refs.chart_detail.updateChartHeight()
|
||||
this.turnOnAxisEventHandler('click', 'xAxis.axisLabel', this.showMinMaxPanel, { axis: 'x' })
|
||||
} else {
|
||||
this.showOverviewChart = true
|
||||
this.detailchartheight = '80vh'
|
||||
this.turnOffAxisEventHandler('click', this.showMinMaxPanel, { axis: 'x' })
|
||||
this.turnOnAxisEventHandler('click', 'yAxis.axisLabel', this.showMinMaxPanel, { axis: 'y' })
|
||||
}
|
||||
this.hideChartLoading()
|
||||
},
|
||||
checkDataZoom: function () {
|
||||
@@ -427,14 +447,6 @@ export default {
|
||||
})
|
||||
}
|
||||
this.drawDetailData() // reDraw
|
||||
if (this.axisXDataType.description !== 'Time') {
|
||||
this.showOverviewChart = false
|
||||
this.turnOnAxisEventHandler('click', 'xAxis.axisLabel', this.showMinMaxPanel, { axis: 'x' })
|
||||
} else {
|
||||
this.showOverviewChart = true
|
||||
this.turnOffAxisEventHandler('click', this.showMinMaxPanel, { axis: 'x' })
|
||||
this.turnOnAxisEventHandler('click', 'yAxis.axisLabel', this.showMinMaxPanel, { axis: 'y' })
|
||||
}
|
||||
},
|
||||
distribute: function () {
|
||||
// if (this.chartDetailData.grid.length === 1) {
|
||||
@@ -466,11 +478,11 @@ 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.updateRegistered]),
|
||||
...mapMutations('replay', [types.chart.updateRegistered, types.chart.updateAxisSplitNumber, types.chart.updateChartSampling]),
|
||||
...mapMutations('replay', [types.meta.updateByIndex]),
|
||||
|
||||
...mapGetters('replay', [types.meta.getAll]),
|
||||
...mapGetters('replay', [types.rec.getAll]),
|
||||
...mapGetters('replay', [types.rec.getAll, types.rec.getCycleDict]),
|
||||
},
|
||||
// use watch because va-select with @change will have bug
|
||||
watch: {
|
||||
@@ -487,10 +499,13 @@ export default {
|
||||
await this.register()
|
||||
this.$refs.top_control_panel.init() // will call changeAxis() here
|
||||
this.$refs.set_min_max.init()
|
||||
this.turnOnAxisEventHandler('click', 'yAxis.axisLabel', this.showMinMaxPanel, { axis: 'y' })
|
||||
this.drawOverviewData()
|
||||
this.turnOnAxisEventHandler('click', 'yAxis.axisLabel', this.showMinMaxPanel, { axis: 'y' })
|
||||
this.updateAxisSplitNumberChart({ chartID: this.chartDetailData.chartID, axis: 'x' })
|
||||
this.updateAxisSplitNumberChart({ chartID: this.chartDetailData.chartID, axis: 'y' })
|
||||
this.dataZoomTimer = setInterval(this.checkDataZoom, 1000)
|
||||
this.initDone = true
|
||||
console.log(this.chartOverviewData)
|
||||
console.log(this.chartDetailData)
|
||||
},
|
||||
beforeDestroy () {
|
||||
@@ -509,21 +524,3 @@ export default {
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.area-style {
|
||||
height: auto;
|
||||
overflow-y: hidden;
|
||||
overflow-x: hidden;
|
||||
|
||||
@include media-breakpoint-only(xl) {
|
||||
height: 88vh;
|
||||
overflow-y: scroll;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
.layout.gutter--xl .row .flex {
|
||||
padding: 0.4rem 0.5rem 0.1rem 0.5rem;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="flex" :class="cardclass">
|
||||
<va-card :style="'height: ' + cardheight + ';'">
|
||||
<chart :ref="'chart_ref'" :style="'width: '+ cardwidth + '; height: ' + cardheight + ';'" :options="data" @dataZoom="updateZoom" :auto-resize="true"></chart>
|
||||
<chart :ref="'chart_ref'" :style="'width: '+ cardwidth + '; height: ' + chartheight + ';'" :options="data" @dataZoom="updateZoom" :auto-resize="true"></chart>
|
||||
</va-card>
|
||||
</div>
|
||||
</template>
|
||||
@@ -30,12 +30,16 @@ export default {
|
||||
},
|
||||
cardheight: {
|
||||
type: String,
|
||||
default: '82vh',
|
||||
default: '88vh',
|
||||
},
|
||||
cardwidth: {
|
||||
type: String,
|
||||
default: 'auto',
|
||||
},
|
||||
chartheight: {
|
||||
type: String,
|
||||
default: '88vh',
|
||||
},
|
||||
},
|
||||
created () {
|
||||
},
|
||||
|
||||
@@ -1,18 +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;"/>
|
||||
<br/>
|
||||
<change-axis class="box_inline-block" :ref="'change_axis_x'" deviceName="elite" axis="x" @changeAxis="changeAxis" @changeUnit="changeUnit" @clearCycle="clearCycle" @resetScale="resetScale"/>
|
||||
<change-unit class="box_inline-block" :ref="'change_unit_x'" deviceName="elite" axis="x" @refreshChart="refreshChart"/>
|
||||
<change-scale class="box_inline-block" :ref="'change_scale_x'" deviceName="elite" axis="x" @refreshChart="refreshChart"/>
|
||||
<br/>
|
||||
<change-axis class="box_inline-block" :ref="'change_axis_y'" deviceName="elite" axis="y" @changeAxis="changeAxis" @changeUnit="changeUnit" @clearCycle="clearCycle" @resetScale="resetScale"/>
|
||||
<change-unit class="box_inline-block" :ref="'change_unit_y'" deviceName="elite" axis="y" @refreshChart="refreshChart"/>
|
||||
<change-scale class="box_inline-block" :ref="'change_scale_y'" deviceName="elite" axis="y" @refreshChart="refreshChart"/>
|
||||
<change-cycle style="margin: 3px;" :ref="'change_cycle'" @refreshChart="refreshChart"/>
|
||||
<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>
|
||||
<div class="flex-container">
|
||||
<change-axis class="flex-child" :ref="'change_axis_x'" deviceName="elite" axis="x" @changeAxis="changeAxis" @changeUnit="changeUnit" @clearCycle="clearCycle" @resetScale="resetScale"/>
|
||||
<change-unit class="flex-child2" :ref="'change_unit_x'" deviceName="elite" axis="x" @refreshChart="refreshChart"/>
|
||||
<change-scale class="flex-child1" :ref="'change_scale_x'" deviceName="elite" axis="x" @refreshChart="refreshChart" @clearCycle="clearCycle"/>
|
||||
</div>
|
||||
<div class="flex-container">
|
||||
<change-axis class="flex-child" :ref="'change_axis_y'" deviceName="elite" axis="y" @changeAxis="changeAxis" @changeUnit="changeUnit" @clearCycle="clearCycle" @resetScale="resetScale"/>
|
||||
<change-unit class="flex-child2" :ref="'change_unit_y'" deviceName="elite" axis="y" @refreshChart="refreshChart"/>
|
||||
<change-scale class="flex-child1" :ref="'change_scale_y'" deviceName="elite" axis="y" @refreshChart="refreshChart" @clearCycle="clearCycle"/>
|
||||
</div>
|
||||
<change-cycle v-show="showCyclePanel" style="margin: 3px;" :ref="'change_cycle'" @refreshChart="refreshChart"/>
|
||||
<show-resample-rate style="margin: 3px;"/>
|
||||
<show-parameter style="margin: 3px;" :ref="'show_param'" deviceName="elite"/>
|
||||
</va-card>
|
||||
@@ -29,6 +33,7 @@ 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 { mapFields } from 'vuex-map-fields'
|
||||
|
||||
export default {
|
||||
name: 'top-control-panel',
|
||||
@@ -44,6 +49,9 @@ export default {
|
||||
ShowParameter,
|
||||
},
|
||||
computed: {
|
||||
...mapFields('replay', [
|
||||
'showCyclePanel',
|
||||
]),
|
||||
},
|
||||
props: {
|
||||
},
|
||||
@@ -51,6 +59,7 @@ export default {
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
showCycle: false,
|
||||
}
|
||||
},
|
||||
mqtt: {
|
||||
@@ -102,4 +111,24 @@ export default {
|
||||
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>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="row row-equal">
|
||||
<div class="flex md12 xl3 xs12 sm12 area-style">
|
||||
<div class="flex md12 xl3 xs12 sm12">
|
||||
<div class="row">
|
||||
<div class="flex sm12 xl12 md12 xs12">
|
||||
<va-accordion>
|
||||
@@ -18,7 +18,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div :class="chartAreaClass" class="area-style">
|
||||
<div :class="chartAreaClass">
|
||||
<div class="row" >
|
||||
<div class="flex sm12 xl12 md12 xs12">
|
||||
<neulive-replay-overview-chart :ref="'chart_overview'" class="mb-1" :cardheight="'7vh'" :data="chartOverviewData" @dataZoomEvent="dataZoomEvent($event)"/>
|
||||
@@ -58,6 +58,7 @@ export default {
|
||||
'currentScale',
|
||||
'startTimeCurrent',
|
||||
'endTimeCurrent',
|
||||
'sampleMethod',
|
||||
]),
|
||||
},
|
||||
props: {
|
||||
@@ -264,44 +265,39 @@ export default {
|
||||
metaInfo = _meta
|
||||
}
|
||||
})
|
||||
const sampleRate = (800000 / metaInfo.parameter_set.ADC_CLOCK)
|
||||
let scale = (((metaInfo.time_duration / 100000) * sampleRate) / 4000) * 0.1
|
||||
if (scale > 500) {
|
||||
let scale = '1000'
|
||||
const sampleRate = (800000 / metaInfo.parameter_set.ADC_CLOCK) // Hz
|
||||
const dataPointNum = (parseInt(metaInfo.time_duration) / 1e6) * sampleRate // us -> s: /1e6
|
||||
if (dataPointNum > 2e6) { // 2000 (points) * 1000 (resample) = 2e6
|
||||
scale = '1000'
|
||||
} else if (scale > 200) {
|
||||
} else if (dataPointNum > 2e5) { // 2000 (points) * 100 (resample) = 2e5
|
||||
scale = '100'
|
||||
} else if (scale > 30) {
|
||||
} else if (dataPointNum > 2e4) { // 2000 (points) * 10 (resample) = 2e4
|
||||
scale = '10'
|
||||
} else {
|
||||
scale = '1'
|
||||
}
|
||||
this.currentScale = scale
|
||||
console.log('overview scale:', scale)
|
||||
const sampleMethod = 'mean'
|
||||
const getAllData = async function (_this) {
|
||||
let seriesIndex = 0
|
||||
for (const ch in _this.dataInfo[meta]) {
|
||||
const dataList = _this.dataInfo[meta][ch][scale]
|
||||
for (let i = 0; i < dataList.length; i++) {
|
||||
if (dataList[i].data.length === 0) {
|
||||
_this.intoDataRec({
|
||||
index: i,
|
||||
metaID: meta,
|
||||
channel: ch,
|
||||
scale: scale,
|
||||
data: await _this.getData(parseInt(scale), sampleMethod, dataList[i].id, ch, metaInfo),
|
||||
})
|
||||
}
|
||||
_this.intoDataRec({
|
||||
index: i,
|
||||
metaID: meta,
|
||||
channel: ch,
|
||||
scale: scale,
|
||||
data: await _this.getData(parseInt(scale), _this.sampleMethod, dataList[i].id, ch, metaInfo),
|
||||
})
|
||||
_this.chartOverviewData.series[seriesIndex].data.push(...dataList[i].data)
|
||||
_this.chartDetailData.series[seriesIndex].data.push(...dataList[i].data)
|
||||
}
|
||||
seriesIndex++
|
||||
}
|
||||
}
|
||||
await getAllData(this)
|
||||
let seriesIndex = 0
|
||||
for (const ch in this.dataInfo[meta]) {
|
||||
const dataList = this.dataInfo[meta][ch][scale]
|
||||
for (let i = 0; i < dataList.length; i++) {
|
||||
this.chartOverviewData.series[seriesIndex].data.push(...dataList[i].data)
|
||||
}
|
||||
seriesIndex++
|
||||
}
|
||||
}
|
||||
this.hideChartLoading()
|
||||
},
|
||||
@@ -315,20 +311,21 @@ export default {
|
||||
metaInfo = _meta
|
||||
}
|
||||
})
|
||||
const sampleRate = (800000 / metaInfo.parameter_set.ADC_CLOCK)
|
||||
let scale = (((timeDur / 100000) * sampleRate) / 4000) * 0.1
|
||||
if (scale > 500) {
|
||||
let scale = '1000'
|
||||
const sampleRate = (800000 / metaInfo.parameter_set.ADC_CLOCK) // Hz
|
||||
const dataPointNum = (timeDur / 1e6) * sampleRate // us -> s: /1e6
|
||||
if (dataPointNum > 2e6) { // 2000 (points) * 1000 (resample) = 2e6
|
||||
scale = '1000'
|
||||
} else if (scale > 200) {
|
||||
} else if (dataPointNum > 2e5) { // 2000 (points) * 100 (resample) = 2e5
|
||||
scale = '100'
|
||||
} else if (scale > 30) {
|
||||
} else if (dataPointNum > 2e4) { // 2000 (points) * 10 (resample) = 2e4
|
||||
scale = '10'
|
||||
} else {
|
||||
scale = '1'
|
||||
}
|
||||
this.currentScale = scale
|
||||
const sampleMethod = 'mean'
|
||||
let seriesIndex = 0
|
||||
this.updateChartSamplingChart({ chartID: this.chartDetailData.chartID, seriesIndex: seriesIndex, method: function (frame) { return frame[0] } })
|
||||
for (const ch in this.dataInfo[meta]) {
|
||||
this.chartDetailData.series[seriesIndex].data.length = 0
|
||||
const dataList = this.dataInfo[meta][ch][scale]
|
||||
@@ -344,24 +341,22 @@ export default {
|
||||
}
|
||||
}
|
||||
// download and push into chart
|
||||
let endFlag = false // because data is sorted by time, so if current processed data piece exceeds endTimeCurrent, can early stop
|
||||
for (let i = startIndex; i <= endIndex; i++) {
|
||||
let data
|
||||
if (dataList[i].data.length === 0) {
|
||||
data = await this.getData(parseInt(scale), sampleMethod, dataList[i].id, ch, metaInfo)
|
||||
this.intoDataRec({
|
||||
index: i,
|
||||
metaID: meta,
|
||||
channel: ch,
|
||||
scale: scale,
|
||||
data: data,
|
||||
})
|
||||
} else {
|
||||
data = JSON.parse(JSON.stringify(this.dataInfo[meta][ch][scale][i].data))
|
||||
}
|
||||
const data = await this.getData(parseInt(scale), this.sampleMethod, dataList[i].id, ch, metaInfo)
|
||||
for (let j = 0, len = data.length; j < len; j++) {
|
||||
if (parseInt(data[j][0]) >= this.startTimeCurrent && parseInt(data[j][0]) <= this.endTimeCurrent) {
|
||||
this.chartDetailData.series[seriesIndex].data.push(data[j])
|
||||
}
|
||||
// early stop
|
||||
if (parseInt(data[j][0]) > this.endTimeCurrent) {
|
||||
endFlag = true
|
||||
break
|
||||
}
|
||||
}
|
||||
// early stop
|
||||
if (endFlag === true) {
|
||||
break
|
||||
}
|
||||
}
|
||||
for (let i = 0, len = this.chartDetailData.xAxis.length; i < len; i++) {
|
||||
@@ -453,7 +448,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]),
|
||||
...mapMutations('replay', [types.chart.updateAxisLabel, types.chart.updateChartSampling]),
|
||||
...mapMutations('replay', [types.meta.updateByIndex]),
|
||||
|
||||
...mapGetters('replay', [types.meta.getAll]),
|
||||
@@ -472,12 +467,12 @@ export default {
|
||||
console.log(this.metaList)
|
||||
console.log(this.dataInfo)
|
||||
await this.register()
|
||||
this.drawOverviewData()
|
||||
this.drawDetailData()
|
||||
await this.drawOverviewData()
|
||||
this.dataZoomTimer = setInterval(this.checkDataZoom, 1000)
|
||||
this.$refs.top_control_panel.init()
|
||||
this.$refs.set_min_max.init()
|
||||
this.turnOnAxisEventHandler('click', 'yAxis.axisLabel', this.showMinMaxPanel, { axis: 'y' })
|
||||
console.log(this.chartOverviewData)
|
||||
console.log(this.chartDetailData)
|
||||
},
|
||||
beforeDestroy () {
|
||||
@@ -496,21 +491,3 @@ export default {
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.area-style {
|
||||
height: auto;
|
||||
overflow-y: hidden;
|
||||
overflow-x: hidden;
|
||||
|
||||
@include media-breakpoint-only(xl) {
|
||||
height: 93vh;
|
||||
overflow-y: scroll;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
.layout.gutter--xl .row .flex {
|
||||
padding: 0.75rem 0.5rem 0.1rem 0.5rem;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<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" @refreshChart="refreshChart"/>
|
||||
<change-scale :ref="'change_scale_y'" deviceName="neulive" axis="y"/>
|
||||
<show-parameter :ref="'show_param'" deviceName="neulive"/>
|
||||
</va-card>
|
||||
</div>
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
|
||||
<script>
|
||||
import { mapFields } from 'vuex-map-fields'
|
||||
import { newChartMode } from '@/factories/chart/chartFactory'
|
||||
|
||||
export default {
|
||||
name: 'change-axis',
|
||||
@@ -46,6 +45,7 @@ export default {
|
||||
'metaList',
|
||||
'axisXDataType',
|
||||
'axisYDataType',
|
||||
'showCyclePanel',
|
||||
]),
|
||||
},
|
||||
methods: {
|
||||
@@ -59,7 +59,7 @@ export default {
|
||||
}
|
||||
} else if (this.deviceName === 'elite') {
|
||||
// use state meta to decide which default unit need to be used (like check I-V mode...)
|
||||
const setting = newChartMode(this.metaList[this.metaIndex].parameter_set.MODE)
|
||||
const setting = this.GLOBAL.getDefaultChartTypeByMode(this.metaList[this.metaIndex].parameter_set.MODE)
|
||||
const xType = setting[0]
|
||||
const xValue = setting[1]
|
||||
const yType = setting[2]
|
||||
@@ -107,13 +107,18 @@ export default {
|
||||
changeAxis () {
|
||||
if (this.deviceName === 'neulive') {
|
||||
// for elite now, cuz neulive now only have v-t graph, for future neulive replay need to adjust'
|
||||
console.log('(Last updated: 2021/06/19)')
|
||||
// console.log('(Last updated: 2021/06/19)')
|
||||
} else if (this.deviceName === 'elite') {
|
||||
if (this.axis === 'x') {
|
||||
this.axisXDataType = this.channelFormat
|
||||
} else if (this.axis === 'y') {
|
||||
this.axisYDataType = this.channelFormat
|
||||
}
|
||||
if (this.axisXDataType.description !== 'Time' && this.metaList[this.metaIndex].parameter_set.CYCLE_NUMBER > 0) {
|
||||
this.showCyclePanel = true
|
||||
} else {
|
||||
this.showCyclePanel = false
|
||||
}
|
||||
this.$emit('changeAxis', this.metaIndex) // temporarily use metaIndex for gridIndex
|
||||
this.$emit('changeUnit', this.axis)
|
||||
this.$emit('resetScale')
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div v-show="showPanel">
|
||||
<div v-if="showPanel">
|
||||
<va-input
|
||||
v-model="showWhichCycles"
|
||||
@change="setCycle"
|
||||
@@ -9,9 +9,10 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapMutations } from 'vuex'
|
||||
import { mapMutations, mapGetters } from 'vuex'
|
||||
import { mapFields } from 'vuex-map-fields'
|
||||
import types from '@/store/modules/analysis/replay/types'
|
||||
import { download } from '@/data/download/Download'
|
||||
|
||||
export default {
|
||||
name: 'change-cycle',
|
||||
@@ -31,9 +32,9 @@ export default {
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
showPanel: true,
|
||||
showPanel: false,
|
||||
metaID: 0,
|
||||
showWhichCycles: '',
|
||||
showWhichCycles: '1',
|
||||
cycleNum: 0,
|
||||
cycleDataID: 3, // [TODO] manage by data type factory
|
||||
}
|
||||
@@ -55,106 +56,133 @@ export default {
|
||||
}
|
||||
}
|
||||
}
|
||||
// console.log(cycleList)
|
||||
return cycleList
|
||||
const cycleSet = new Set(cycleList)
|
||||
const sortedCycleList = [...cycleSet].sort() // ref: https://stackoverflow.com/questions/33089695/how-can-i-sort-an-es6-set
|
||||
// console.log(sortedCycleList)
|
||||
return sortedCycleList
|
||||
},
|
||||
...mapFields('replay', [
|
||||
'chartData',
|
||||
'recInfo',
|
||||
'metaList',
|
||||
'currentScale',
|
||||
'sampleMethod',
|
||||
'axisXDataType',
|
||||
'axisYDataType',
|
||||
'axisXLabelScale',
|
||||
'axisYLabelScale',
|
||||
]),
|
||||
},
|
||||
watch: {
|
||||
},
|
||||
methods: {
|
||||
init () {
|
||||
this.isThisModeHasCycle = this.GLOBAL.hasCycleMode(this.metaList[this.metaIndex].parameter_set.MODE)
|
||||
this.cycleNum = this.metaList[this.metaIndex].parameter_set.CYCLE_NUMBER
|
||||
this.metaID = this.metaList[this.metaIndex].id
|
||||
if (this.cycleNum === 0) {
|
||||
if (this.isThisModeHasCycle === true) {
|
||||
this.showPanel = true
|
||||
} else {
|
||||
this.showPanel = false
|
||||
}
|
||||
},
|
||||
clear () {
|
||||
this.showWhichCycles = ''
|
||||
this.showWhichCycles = '1'
|
||||
},
|
||||
setCycle () {
|
||||
async setCycle () {
|
||||
console.log('setCycle')
|
||||
if (this.cycleNum !== 0) {
|
||||
// get cycle data
|
||||
const scaleDataNum = this.recInfo[this.metaID][this.cycleDataID][this.currentScale].length
|
||||
// console.log(scaleDataNum)
|
||||
let allCycleData = []
|
||||
for (let i = 0; i < scaleDataNum; i++) {
|
||||
const cycleDataArray = this.recInfo[this.metaID][this.cycleDataID][this.currentScale][i].data
|
||||
allCycleData = allCycleData.concat(cycleDataArray)
|
||||
}
|
||||
var cycleDict = {}
|
||||
var cycleStartIndex = 0
|
||||
var cycleEndIndex = 0
|
||||
var currentCycleIndex = 0
|
||||
for (let index = 0; index < allCycleData.length; index++) {
|
||||
const value = allCycleData[index]
|
||||
const cycleIndex = parseInt(value[1])
|
||||
if (cycleIndex === currentCycleIndex) {
|
||||
if (currentCycleIndex in cycleDict) {
|
||||
cycleEndIndex = index
|
||||
cycleDict[cycleIndex][1] = cycleEndIndex
|
||||
} else {
|
||||
cycleDict[cycleIndex] = [cycleStartIndex, cycleEndIndex]
|
||||
}
|
||||
if (this.isThisModeHasCycle === true) {
|
||||
const dataCycleList = this.recInfo[this.metaID][this.cycleDataID][this.currentScale]
|
||||
const cycleDataList = []
|
||||
for (let i = 0; i < dataCycleList.length; i++) {
|
||||
if (dataCycleList[i].data.length === 0) {
|
||||
const data = await this.getData(parseInt(this.currentScale), this.sampleMethod, dataCycleList[i].id, this.cycleDataID, this.metaList[this.metaIndex])
|
||||
cycleDataList.push({ data: data })
|
||||
} else {
|
||||
cycleStartIndex = index
|
||||
currentCycleIndex++
|
||||
cycleDataList.push({ data: dataCycleList[i].data })
|
||||
}
|
||||
}
|
||||
// get recording data
|
||||
let allXData = []
|
||||
if (this.axisXDataType.description !== 'Time') {
|
||||
for (let i = 0; i < scaleDataNum; i++) {
|
||||
const xDataArray = this.recInfo[this.metaID][this.axisXDataType.id][this.currentScale][i].data
|
||||
allXData = allXData.concat(xDataArray)
|
||||
}
|
||||
}
|
||||
let allYData = []
|
||||
for (let i = 0; i < scaleDataNum; i++) {
|
||||
const cycleDataArray = this.recInfo[this.metaID][this.axisYDataType.id][this.currentScale][i].data
|
||||
allYData = allYData.concat(cycleDataArray)
|
||||
}
|
||||
const data = []
|
||||
const cycleDict = this.getCycleDictRec()(cycleDataList)
|
||||
|
||||
const dataXList = this.recInfo[this.metaID][this.axisXDataType.id][this.currentScale]
|
||||
const dataYList = this.recInfo[this.metaID][this.axisYDataType.id][this.currentScale]
|
||||
const filteredData = []
|
||||
for (let sliceIndex = 0; sliceIndex < this.cycleNum; sliceIndex++) {
|
||||
// console.log(this.slices)
|
||||
if (this.slices === '' || this.slices.includes((sliceIndex + 1).toString())) {
|
||||
// slice data
|
||||
const value = cycleDict[sliceIndex + 1]
|
||||
const start = value[0]
|
||||
const end = value[1] + 1
|
||||
const sliceYData = allYData.slice(start, end)
|
||||
const sliceLen = sliceYData.length
|
||||
if (allXData.length !== 0) {
|
||||
const sliceXData = allXData.slice(start, end)
|
||||
for (let j = 0; j < sliceLen; j++) {
|
||||
data.push([sliceXData[j][1], sliceYData[j][1]])
|
||||
const startTime = value[0]
|
||||
const endTime = value[1]
|
||||
let startIndex = 0
|
||||
let endIndex = 0
|
||||
for (let i = 0; i < dataYList.length; i++) {
|
||||
if (startTime >= parseInt(dataYList[i].start_time) && startTime <= parseInt(dataYList[i].end_time)) {
|
||||
startIndex = i
|
||||
}
|
||||
} else {
|
||||
const sliceYData = allYData.slice(start, end)
|
||||
for (let j = 0; j < sliceLen; j++) {
|
||||
data.push(sliceYData[j])
|
||||
if (endTime >= parseInt(dataYList[i].start_time) && endTime <= parseInt(dataYList[i].end_time)) {
|
||||
endIndex = i
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = startIndex; i <= endIndex; i++) {
|
||||
const dataY = await this.getData(parseInt(this.currentScale), this.sampleMethod, dataYList[i].id, this.axisYDataType.id, this.metaList[this.metaIndex])
|
||||
if (this.axisXDataType.description !== 'Time') {
|
||||
const dataX = await this.getData(parseInt(this.currentScale), this.sampleMethod, dataXList[i].id, this.axisXDataType.id, this.metaList[this.metaIndex])
|
||||
for (let j = 0, len = dataY.length; j < len; j++) {
|
||||
if (parseInt(dataY[j][0]) >= startTime && parseInt(dataY[j][0]) <= endTime) {
|
||||
let x
|
||||
let y
|
||||
if (this.axisXLabelScale.description === 'Log') {
|
||||
x = Math.log10(Math.abs(dataX[j][1]))
|
||||
} else if (this.axisXLabelScale.description === 'Linear') {
|
||||
x = dataX[j][1]
|
||||
}
|
||||
if (this.axisYLabelScale.description === 'Log') {
|
||||
y = Math.log10(Math.abs(dataY[j][1]))
|
||||
} else if (this.axisYLabelScale.description === 'Linear') {
|
||||
y = dataY[j][1]
|
||||
}
|
||||
filteredData.push([x, y])
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (let j = 0, len = dataY.length; j < len; j++) {
|
||||
if (parseInt(dataY[j][0]) >= startTime && parseInt(dataY[j][0]) <= endTime) {
|
||||
if (this.axisYLabelScale.description === 'Log') {
|
||||
dataY[j][1] = Math.log10(Math.abs(dataY[j][1]))
|
||||
} else if (this.axisYLabelScale.description === 'Linear') {
|
||||
// do nothing
|
||||
}
|
||||
filteredData.push(dataY[j])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.updateSeriesChart({
|
||||
chartID: this.chartID,
|
||||
seriesIndex: this.metaIndex,
|
||||
data: filteredData,
|
||||
})
|
||||
// this.$emit('refreshChart', this.chartData[this.chartID])
|
||||
}
|
||||
}
|
||||
this.updateSeriesChart({
|
||||
chartID: this.chartID,
|
||||
seriesIndex: this.metaIndex,
|
||||
data: JSON.parse(JSON.stringify(data)),
|
||||
})
|
||||
}
|
||||
this.$emit('refreshChart', this.chartData[this.chartID])
|
||||
},
|
||||
getData: async function (scale, sampleMethod, id, channel, meta) {
|
||||
if (scale === 1) {
|
||||
return await download.rawByIDChannels(id, channel, meta)
|
||||
} else {
|
||||
if (sampleMethod === 'mean') {
|
||||
return await download.miniMeanByIDChannel(id, channel, meta)
|
||||
} else if (sampleMethod === 'random') {
|
||||
return await download.miniRandomByIDChannel(id, channel, meta)
|
||||
}
|
||||
}
|
||||
},
|
||||
...mapMutations('replay', [types.chart.updateSeries]),
|
||||
...mapGetters('replay', [types.rec.getCycleDict]),
|
||||
},
|
||||
mounted () {
|
||||
|
||||
|
||||
@@ -9,9 +9,10 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapMutations } from 'vuex'
|
||||
import { mapMutations, mapGetters } from 'vuex'
|
||||
import { mapFields } from 'vuex-map-fields'
|
||||
import types from '@/store/modules/analysis/replay/types'
|
||||
import { download } from '@/data/download/Download'
|
||||
|
||||
export default {
|
||||
name: 'change-scale',
|
||||
@@ -47,11 +48,13 @@ export default {
|
||||
'startTimeCurrent',
|
||||
'endTimeCurrent',
|
||||
'currentScale',
|
||||
'sampleMethod',
|
||||
]),
|
||||
},
|
||||
methods: {
|
||||
init () {
|
||||
this.metaID = this.metaList[this.metaIndex].id
|
||||
this.metaInfo = this.metaList[this.metaIndex]
|
||||
this.metaID = this.metaInfo.id
|
||||
if (this.axis === 'x') {
|
||||
this.axisXLabelScale = this.scaleOptions[0] // 0 mean use default unit
|
||||
this.scaleFormat = this.axisXLabelScale
|
||||
@@ -67,7 +70,7 @@ export default {
|
||||
this.axisYLabelScale = this.scaleFormat
|
||||
}
|
||||
if (this.deviceName === 'neulive') {
|
||||
const keys = Object.keys(this.metaList[this.metaIndex].mini_data)
|
||||
const keys = Object.keys(this.metaInfo.mini_data)
|
||||
for (let gridIndex = 0; gridIndex < keys.length; gridIndex++) {
|
||||
const ch = keys[gridIndex]
|
||||
if (parseInt(ch) < 256) { // 256: x, 257: y, 258: z, 259: mag
|
||||
@@ -77,10 +80,8 @@ export default {
|
||||
} else if (this.deviceName === 'elite') {
|
||||
this.calculateScaleHelper(this.metaIndex, -1) // [TODO] elite tmp use metaIndex for grid index
|
||||
}
|
||||
this.$emit('refreshChart', this.chartData[this.chartID])
|
||||
},
|
||||
calculateScaleHelper (gridIndex, ch) {
|
||||
// console.log(this.recInfo)
|
||||
async calculateScaleHelper (gridIndex, ch) {
|
||||
let seriesData
|
||||
if (this.scaleFormat.description === 'Log') {
|
||||
seriesData = JSON.parse(JSON.stringify(this.chartData[this.chartID].series[gridIndex].data))
|
||||
@@ -92,34 +93,11 @@ export default {
|
||||
}
|
||||
}
|
||||
} else if (this.scaleFormat.description === 'Linear') {
|
||||
// console.log(this.recInfo)
|
||||
if (this.deviceName === 'neulive') {
|
||||
// [Region] get the subfile index
|
||||
const dataList = this.recInfo[this.metaID][ch][this.currentScale]
|
||||
let startIndex = 0
|
||||
let endIndex = 0
|
||||
for (let i = 0; i < dataList.length; i++) {
|
||||
if (this.startTimeCurrent >= parseInt(dataList[i].start_time) && this.startTimeCurrent <= parseInt(dataList[i].end_time)) {
|
||||
startIndex = i
|
||||
}
|
||||
if (this.endTimeCurrent >= parseInt(dataList[i].start_time) && this.endTimeCurrent <= parseInt(dataList[i].end_time)) {
|
||||
endIndex = i
|
||||
}
|
||||
}
|
||||
// [EndRegion]
|
||||
const allYData = []
|
||||
for (let i = startIndex; i <= endIndex; i++) {
|
||||
const data = dataList[i].data
|
||||
for (let j = 0, len = data.length; j < len; j++) {
|
||||
if (parseInt(data[j][0]) >= this.startTimeCurrent && parseInt(data[j][0]) <= this.endTimeCurrent) {
|
||||
allYData.push(data[j])
|
||||
}
|
||||
}
|
||||
}
|
||||
// [TODO] for future, neulive may need to change x axis
|
||||
seriesData = JSON.parse(JSON.stringify(allYData))
|
||||
} else if (this.deviceName === 'elite') {
|
||||
// [Region] get the subfile index
|
||||
const dataYList = this.recInfo[this.metaID][this.axisYDataType.id][this.currentScale]
|
||||
seriesData = []
|
||||
const dataYList = this.recInfo[this.metaID][ch][this.currentScale]
|
||||
let startIndex = 0
|
||||
let endIndex = 0
|
||||
for (let i = 0; i < dataYList.length; i++) {
|
||||
@@ -131,32 +109,81 @@ export default {
|
||||
}
|
||||
}
|
||||
// [EndRegion]
|
||||
const allXData = []
|
||||
const allYData = []
|
||||
for (let i = startIndex; i <= endIndex; i++) {
|
||||
if (this.axisXDataType.description !== 'Time') {
|
||||
const dataX = this.recInfo[this.metaID][this.axisXDataType.id][this.currentScale][i].data
|
||||
for (let j = 0, len = dataX.length; j < len; j++) {
|
||||
if (parseInt(dataX[j][0]) >= this.startTimeCurrent && parseInt(dataX[j][0]) <= this.endTimeCurrent) {
|
||||
allXData.push(dataX[j])
|
||||
const data = await this.getData(parseInt(this.currentScale), this.sampleMethod, dataYList[i].id, ch, this.metaInfo)
|
||||
for (let j = 0, len = data.length; j < len; j++) {
|
||||
if (parseInt(data[j][0]) >= this.startTimeCurrent && parseInt(data[j][0]) <= this.endTimeCurrent) {
|
||||
const processedData = data[j]
|
||||
if (this.axisXLabelScale.description === 'Log') {
|
||||
processedData[0] = Math.log10(Math.abs(processedData[0]))
|
||||
}
|
||||
}
|
||||
}
|
||||
const dataY = this.recInfo[this.metaID][this.axisYDataType.id][this.currentScale][i].data
|
||||
for (let j = 0, len = dataY.length; j < len; j++) {
|
||||
if (parseInt(dataY[j][0]) >= this.startTimeCurrent && parseInt(dataY[j][0]) <= this.endTimeCurrent) {
|
||||
allYData.push(dataY[j])
|
||||
if (this.axisYLabelScale.description === 'Log') {
|
||||
processedData[1] = Math.log10(Math.abs(processedData[1]))
|
||||
}
|
||||
seriesData.push(processedData)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (this.deviceName === 'elite') {
|
||||
seriesData = []
|
||||
for (let i = 0, len = allYData.length; i < len; i++) {
|
||||
if (parseInt(allYData[i][0]) >= this.startTimeCurrent && parseInt(allYData[i][0]) <= this.endTimeCurrent) {
|
||||
const processedData = JSON.parse(JSON.stringify(allYData[i]))
|
||||
if (allXData.length !== 0) {
|
||||
processedData[0] = allXData[i][1]
|
||||
|
||||
const isThisModeHasCycle = this.GLOBAL.hasCycleMode(this.metaInfo.parameter_set.MODE)
|
||||
let startTime
|
||||
let endTime
|
||||
if (isThisModeHasCycle === true && this.axisXDataType.description !== 'Time') { // if有cycle的mode且目前x軸不為時間,抓出第一圈所在的時間段,初始化時先畫第一圈就好,加快初始時間
|
||||
const cycleDataID = 3 // recorded cycle 所在的channel index
|
||||
const dataCycleList = this.recInfo[this.metaID][cycleDataID][this.currentScale]
|
||||
const cycleDataList = []
|
||||
for (let i = 0; i < dataCycleList.length; i++) {
|
||||
if (dataCycleList[i].data.length === 0) {
|
||||
const data = await this.getData(parseInt(this.currentScale), this.sampleMethod, dataCycleList[i].id, cycleDataID, this.metaInfo)
|
||||
cycleDataList.push({ data: data })
|
||||
} else {
|
||||
cycleDataList.push({ data: dataCycleList[i].data })
|
||||
}
|
||||
}
|
||||
const cycleDict = this.getCycleDictRec()(cycleDataList)
|
||||
startTime = cycleDict[1][0] // [1]: 第一圈
|
||||
endTime = cycleDict[1][1] // [1]: 第一圈
|
||||
this.$emit('clearCycle')
|
||||
} else {
|
||||
startTime = this.startTimeCurrent
|
||||
endTime = this.endTimeCurrent
|
||||
}
|
||||
|
||||
const dataYList = this.recInfo[this.metaID][this.axisYDataType.id][this.currentScale]
|
||||
let startIndex = 0
|
||||
let endIndex = 0
|
||||
for (let i = 0; i < dataYList.length; i++) {
|
||||
if (startTime >= parseInt(dataYList[i].start_time) && startTime <= parseInt(dataYList[i].end_time)) {
|
||||
startIndex = i
|
||||
}
|
||||
if (endTime >= parseInt(dataYList[i].start_time) && endTime <= parseInt(dataYList[i].end_time)) {
|
||||
endIndex = i
|
||||
}
|
||||
}
|
||||
// [EndRegion]
|
||||
for (let i = startIndex; i <= endIndex; i++) {
|
||||
const dataY = await this.getData(parseInt(this.currentScale), this.sampleMethod, dataYList[i].id, this.axisYDataType.id, this.metaInfo)
|
||||
let dataX
|
||||
if (this.axisXDataType.description !== 'Time') {
|
||||
const dataXList = this.recInfo[this.metaID][this.axisXDataType.id][this.currentScale]
|
||||
dataX = await this.getData(parseInt(this.currentScale), this.sampleMethod, dataXList[i].id, this.axisXDataType.id, this.metaInfo)
|
||||
}
|
||||
for (let j = 0, len = dataY.length; j < len; j++) {
|
||||
if (parseInt(dataY[j][0]) >= startTime && parseInt(dataY[j][0]) <= endTime) {
|
||||
const processedData = dataY[j]
|
||||
if (this.axisXDataType.description !== 'Time') {
|
||||
processedData[0] = dataX[j][1]
|
||||
}
|
||||
if (this.axisXLabelScale.description === 'Log') {
|
||||
processedData[0] = Math.log10(Math.abs(processedData[0]))
|
||||
}
|
||||
if (this.axisYLabelScale.description === 'Log') {
|
||||
processedData[1] = Math.log10(Math.abs(processedData[1]))
|
||||
}
|
||||
seriesData.push(processedData)
|
||||
}
|
||||
seriesData.push(processedData)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -164,7 +191,7 @@ export default {
|
||||
this.updateSeriesChart({
|
||||
chartID: this.chartID,
|
||||
seriesIndex: gridIndex,
|
||||
data: JSON.parse(JSON.stringify(seriesData)),
|
||||
data: seriesData,
|
||||
})
|
||||
},
|
||||
reset () {
|
||||
@@ -176,13 +203,26 @@ export default {
|
||||
this.scaleFormat = this.axisYLabelScale
|
||||
}
|
||||
},
|
||||
getData: async function (scale, sampleMethod, id, channel, meta) {
|
||||
if (scale === 1) {
|
||||
return await download.rawByIDChannels(id, channel, meta)
|
||||
} else {
|
||||
if (sampleMethod === 'mean') {
|
||||
return await download.miniMeanByIDChannel(id, channel, meta)
|
||||
} else if (sampleMethod === 'random') {
|
||||
return await download.miniRandomByIDChannel(id, channel, meta)
|
||||
}
|
||||
}
|
||||
},
|
||||
...mapMutations('replay', [types.chart.updateSeries]),
|
||||
...mapGetters('replay', [types.rec.getCycleDict]),
|
||||
},
|
||||
mounted () {
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
metaID: 0,
|
||||
metaInfo: null,
|
||||
scaleFormat: { id: 0, description: 'Linear' },
|
||||
scaleOptions: [
|
||||
{
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
import { mapMutations } from 'vuex'
|
||||
import { mapFields } from 'vuex-map-fields'
|
||||
import types from '@/store/modules/analysis/replay/types'
|
||||
import { newChartMode } from '@/factories/chart/chartFactory'
|
||||
|
||||
export default {
|
||||
name: 'change-unit',
|
||||
@@ -53,7 +52,7 @@ export default {
|
||||
}
|
||||
} else if (this.deviceName === 'elite') {
|
||||
// use state meta to decide which default unit need to be used (like check I-V mode...)
|
||||
const setting = newChartMode(this.metaList[this.metaIndex].parameter_set.MODE)
|
||||
const setting = this.GLOBAL.getDefaultChartTypeByMode(this.metaList[this.metaIndex].parameter_set.MODE)
|
||||
const xType = setting[0]
|
||||
const xValue = setting[1]
|
||||
const yType = setting[2]
|
||||
@@ -85,7 +84,7 @@ export default {
|
||||
this.valueFormatX = this.valueFormatOptions[this.dataType][0]
|
||||
this.valueFormat = this.valueFormatX
|
||||
} else if (this.axis === 'y') {
|
||||
this.valueFormatY = this.valueFormatOptions[this.dataType][0] // 0 mean use default unit (i.e. unitScale = 1)
|
||||
this.valueFormatY = this.valueFormatOptions[this.dataType][0] // 0 mean use default unit
|
||||
this.valueFormat = this.valueFormatY
|
||||
}
|
||||
this.changeUnit()
|
||||
@@ -152,16 +151,16 @@ export default {
|
||||
valueFormat: {},
|
||||
valueFormatOptions: { // below id: 0 mean default
|
||||
current: [
|
||||
{
|
||||
id: 0,
|
||||
unit: 'nA',
|
||||
unitScale: 1,
|
||||
},
|
||||
{
|
||||
id: 1,
|
||||
unit: 'uA',
|
||||
unitScale: 1000,
|
||||
},
|
||||
{
|
||||
id: 0,
|
||||
unit: 'nA',
|
||||
unitScale: 1,
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
unit: 'mA',
|
||||
@@ -169,16 +168,16 @@ export default {
|
||||
},
|
||||
],
|
||||
voltage: [ // Voltage
|
||||
{
|
||||
id: 0,
|
||||
unit: 'uV',
|
||||
unitScale: 1,
|
||||
},
|
||||
{
|
||||
id: 1,
|
||||
unit: 'mV',
|
||||
unitScale: 1000,
|
||||
},
|
||||
{
|
||||
id: 0,
|
||||
unit: 'uV',
|
||||
unitScale: 1,
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
unit: 'V',
|
||||
@@ -186,16 +185,16 @@ export default {
|
||||
},
|
||||
],
|
||||
resistance: [ // Resistance
|
||||
{
|
||||
id: 0,
|
||||
unit: 'mΩ',
|
||||
unitScale: 1,
|
||||
},
|
||||
{
|
||||
id: 1,
|
||||
unit: 'Ω',
|
||||
unitScale: 1000,
|
||||
},
|
||||
{
|
||||
id: 0,
|
||||
unit: 'mΩ',
|
||||
unitScale: 1,
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
unit: 'kΩ',
|
||||
|
||||
@@ -71,20 +71,8 @@ export default {
|
||||
deleteFile: async function () {
|
||||
for (let i = 0; i < this.deleteInfoList.length; i++) {
|
||||
const deleteInfo = this.deleteInfoList[i]
|
||||
for (const item of deleteInfo.rawChannelAndIDArrays) {
|
||||
const channel = item[0]
|
||||
const id = item[1]
|
||||
await api.raw.update(channel, id, { deleted: true })
|
||||
await api.raw.clearDel(channel, id)
|
||||
}
|
||||
for (const item of deleteInfo.miniChannelAndIDArrays) {
|
||||
const channel = item[0]
|
||||
const id = item[1]
|
||||
await api.mini.update(channel, id, { deleted: true })
|
||||
await api.mini.clearDel(channel, id)
|
||||
}
|
||||
await api.meta.update(deleteInfo.metaID, { deleted: true })
|
||||
await api.meta.clearDel(deleteInfo.metaID)
|
||||
await api.meta.clearDel()
|
||||
}
|
||||
await this.deleteFileDone()
|
||||
},
|
||||
|
||||
@@ -32,7 +32,11 @@ export default {
|
||||
downloadCSV: async function () {
|
||||
for (let i = 0; i < this.metaList.length; i++) {
|
||||
const meta = this.metaList[i]
|
||||
window.open('http://' + location.href.split('/')[2].split(':')[0] + '/#/admin/download/neulive/csv/' + meta.id, '_blank', 'width=500,height=100,left=200,top=200')
|
||||
if (meta.device.library_name.indexOf('Elite') >= 0) {
|
||||
window.open('http://' + location.href.split('/')[2].split(':')[0] + '/#/download/excel/' + meta.id)
|
||||
} else if (meta.device.library_name.indexOf('Neulive') >= 0) {
|
||||
window.open('http://' + location.href.split('/')[2].split(':')[0] + '/#/download/csv/' + meta.id)
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
@@ -80,7 +80,7 @@ export default {
|
||||
// [TODO] 0: not sure future UX design
|
||||
const meta = this.metaList[0]
|
||||
file.clearFileList()
|
||||
const files = await api.meta.getCollectionByParent('folder', meta.parent.folder[0])
|
||||
const files = await api.meta.getByParent('folder', meta.parent.folder[0])
|
||||
file.updateFileList(files)
|
||||
const tmpFiles = file.getFileList()
|
||||
for (let i = 0; i < tmpFiles.length; i++) {
|
||||
|
||||
@@ -1,143 +1,26 @@
|
||||
<template>
|
||||
<div>
|
||||
<va-modal
|
||||
class="flex sm12 xl12 md12 xs12 pa-0 ma-0"
|
||||
v-model="showDownload"
|
||||
size="small"
|
||||
:hideDefaultActions="true"
|
||||
:mobileFullscreen="false"
|
||||
>
|
||||
<template slot="header">
|
||||
<div class="row mb-2">
|
||||
<va-icon name="fa fa-download mr-3 " color="primary"/>
|
||||
<h5 class="mt-0 mb-0">{{'Download'}}</h5>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<div class="downloadOptionsList">
|
||||
<template v-for="(downloadOptions, i) in downloadOptionsList">
|
||||
<va-accordion :key="downloadOptions.filename">
|
||||
<va-collapse>
|
||||
<va-item :key="downloadOptions.filename" slot="header" clickable>
|
||||
<va-item-section avatar>
|
||||
<va-item-label>
|
||||
{{ downloadOptions.filename }}
|
||||
</va-item-label>
|
||||
</va-item-section>
|
||||
|
||||
<va-item-section>
|
||||
<!-- <va-item-label>
|
||||
{{ downloadInfo.minTime }}
|
||||
</va-item-label>
|
||||
|
||||
<va-item-label caption>
|
||||
{{ downloadInfo.maxTime }}
|
||||
</va-item-label> -->
|
||||
</va-item-section>
|
||||
|
||||
<va-item-section v-if="downloadOptions.download.status == 'idle'" side>
|
||||
<va-icon name="fa fa-play" color="gray" @click.native.stop="confirmDownload(downloadOptions.metaPath)"/>
|
||||
</va-item-section>
|
||||
<va-item-section v-else side class="md4 offset--md8">
|
||||
<div class="row flex sm12 xl12 md12 xs12">
|
||||
<div class="flex-center spinner-box">
|
||||
<fulfilling-bouncing-circle-spinner
|
||||
:animation-duration="3000"
|
||||
:color="'#6c7fee'"
|
||||
:size="20"
|
||||
>
|
||||
</fulfilling-bouncing-circle-spinner>
|
||||
<span class="ml-3">{{loaded}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</va-item-section>
|
||||
|
||||
</va-item>
|
||||
<div slot="body">
|
||||
<div v-if="downloadOptions.download.status == 'downloading'" class="row flex sm12 xl12 md12 xs12">
|
||||
<div class="row flex sm12 xl12 md12 xs12">
|
||||
<div class="flex-center spinner-box mt-4 mb-5">
|
||||
<fulfilling-bouncing-circle-spinner
|
||||
:animation-duration="3000"
|
||||
:color="'#6c7fee'"
|
||||
:size="60"
|
||||
>
|
||||
</fulfilling-bouncing-circle-spinner>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else>
|
||||
<div class="mb-5">
|
||||
<va-item class="flex sm12 xl12 md12 xs12 mr-1 pa-0">
|
||||
<va-icon
|
||||
class="flex sm1 xl1 md1 xs1 start "
|
||||
name="glyphicon glyphicon-filter"
|
||||
size="1.0rem"
|
||||
:fixedWidth = "Boolean('true')"
|
||||
/>
|
||||
<div class="flex sm11 xl11 md11 xs11 row">
|
||||
<div v-for="(item,index) in downloadOptions.channel" :key="item.channel" class="filter-button">
|
||||
<va-button
|
||||
class="mx-1 px-1"
|
||||
v-if="item.checked"
|
||||
@click="channelUnchecked(index,downloadOptions.metaPath)"
|
||||
small
|
||||
>
|
||||
{{item.alias}}
|
||||
</va-button>
|
||||
<va-button
|
||||
class="mx-1 px-1"
|
||||
v-else
|
||||
@click="channelChecked(index,downloadOptions.metaPath)"
|
||||
small outline
|
||||
>
|
||||
{{item.alias}}
|
||||
</va-button>
|
||||
</div>
|
||||
</div>
|
||||
</va-item>
|
||||
</div>
|
||||
<div class="mb-5">
|
||||
<va-item class="flex sm12 xl12 md12 xs12 pa-0">
|
||||
<va-icon
|
||||
class="flex sm1 xl1 md1 xs1 mr-4"
|
||||
:fixedWidth="true"
|
||||
name="va-icon glyphicon glyphicon-time"
|
||||
size="1.0rem"
|
||||
/>
|
||||
<div class="flex">
|
||||
<va-slider
|
||||
class="flex sm11 xl11 md11 xs11 filter-button"
|
||||
value-visible
|
||||
range
|
||||
v-model="downloadOptions.timeRange"
|
||||
@click.native="timeRangeChange(downloadOptions.timeRange,downloadOptions.metaPath)"
|
||||
@mouseup.native="timeRangeChange(downloadOptions.timeRange,downloadOptions.metaPath)"
|
||||
@mouseleave.native="timeRangeChange(downloadOptions.timeRange,downloadOptions.metaPath)"
|
||||
@touchend.native="timeRangeChange(downloadOptions.timeRange,downloadOptions.metaPath)"
|
||||
:min="downloadOptions.minTime"
|
||||
:max="downloadOptions.maxTime"
|
||||
/>
|
||||
<span> {{ transTime(downloadOptions.timeRange) }} </span>
|
||||
</div>
|
||||
</va-item>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</va-collapse>
|
||||
</va-accordion>
|
||||
<va-list-separator v-if="i < downloadOptionsList.length - 1" :key="'separator' + downloadOptions.filename" />
|
||||
</template>
|
||||
<div class="row flex sm12 xl12 md12 xs12" style="height: 100vh;">
|
||||
<div class="flex-center spinner-box mt-4 mb-5">
|
||||
<fulfilling-bouncing-circle-spinner
|
||||
:animation-duration="3000"
|
||||
:color="'#6c7fee'"
|
||||
:size="60"
|
||||
>
|
||||
</fulfilling-bouncing-circle-spinner>
|
||||
</div>
|
||||
</va-modal>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { file } from '../../data/file/File'
|
||||
import { download } from '../../data/download/Download'
|
||||
import { exportData } from '../../data/export/export'
|
||||
import api from '@/data/api/index'
|
||||
import types from '@/store/modules/download/types'
|
||||
import { mapActions, mapMutations } from 'vuex'
|
||||
import { FulfillingBouncingCircleSpinner } from 'epic-spinners'
|
||||
import { mapFields } from 'vuex-map-fields'
|
||||
import newDownload from '@/factories/file/downloadFactory'
|
||||
import newChannel from '@/factories/file/channelFactory'
|
||||
|
||||
export default {
|
||||
name: 'Download',
|
||||
@@ -146,387 +29,17 @@ export default {
|
||||
},
|
||||
data: () => {
|
||||
return {
|
||||
showDownload: false,
|
||||
controllerList: [],
|
||||
downloadList: [],
|
||||
downloadListRecord: [],
|
||||
downloadOptionsList: [],
|
||||
// downloadInfo: {
|
||||
// metaPath: '',
|
||||
// previousPath: '',
|
||||
// filenameWithType: '',
|
||||
// filename: '',
|
||||
// channel: [],
|
||||
// timeRange: [0, 0],
|
||||
// minTime: 0,
|
||||
// maxTime: 0,
|
||||
// status: 'idle',
|
||||
// device: '',
|
||||
// },
|
||||
currentlyDownloadInfo: {
|
||||
metaPath: '',
|
||||
previousPath: '',
|
||||
filenameWithType: '',
|
||||
filename: '',
|
||||
channel: [],
|
||||
timeRange: [0, 0],
|
||||
minTime: 0,
|
||||
maxTime: 0,
|
||||
download: {
|
||||
status: 'idle',
|
||||
rate: 0,
|
||||
},
|
||||
device: '',
|
||||
},
|
||||
estimatedTime: 0,
|
||||
fileSegmentIndex: 0,
|
||||
fileSegmentMax: 0,
|
||||
totoalFileSize: 0,
|
||||
loadingPercent: 0,
|
||||
loadTime: 0,
|
||||
interval: null,
|
||||
data: '',
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
// transTime (min,max) {
|
||||
// return this.getTimeInFormat(min) + ' - ' + this.getTimeInFormat(max)
|
||||
// },
|
||||
loaded () {
|
||||
return this.loadingPercent + '%'
|
||||
},
|
||||
...mapFields('download', [
|
||||
'metaList',
|
||||
'downloadInfo',
|
||||
'metaInfo',
|
||||
]),
|
||||
},
|
||||
// mqtt: {
|
||||
// async '+/file_segment/+' (data, topic) {
|
||||
// console.log('file_segment')
|
||||
// console.log(String.fromCharCode.apply(null, data))
|
||||
// // console.log(navigator.connection.downlink)
|
||||
// // console.log(this.fileNum)
|
||||
// // console.log(this.downloadOptionsList.length)
|
||||
// // console.log(JSON.parse(String.fromCharCode.apply(null, data)).data.file_size)
|
||||
|
||||
// if (this.downloadOptionsList.length > 0) {
|
||||
// await download.updateFileSegmentInfo(String.fromCharCode.apply(null, data))
|
||||
// this.fileSegmentMax = download.getFileSegmentMaxIndex()
|
||||
// this.checkFileSegmentGetOrNot()
|
||||
// }
|
||||
// },
|
||||
// async '+/file_segment_get/+' (data, topic) {
|
||||
// console.log('file_segment_get')
|
||||
// console.log(JSON.parse(new TextDecoder('utf-8').decode(data)))
|
||||
// if (this.downloadOptionsList.length > 0) {
|
||||
// const segmentData = atob(JSON.parse(new TextDecoder('utf-8').decode(data)).data.segment)
|
||||
// this.data += segmentData
|
||||
|
||||
// this.fileSegmentIndex += 1
|
||||
// this.checkFileSegmentGetOrNot()
|
||||
// }
|
||||
// },
|
||||
// },
|
||||
methods: {
|
||||
transTime (timeRange) {
|
||||
return this.getTimeInFormat(timeRange[0]) + ' - ' + this.getTimeInFormat(timeRange[1])
|
||||
},
|
||||
notify (name) {
|
||||
this.showToast(`done ${name}`, {
|
||||
position: 'bottom-right',
|
||||
})
|
||||
},
|
||||
showDownloadModal: function () {
|
||||
this.showDownload = true
|
||||
},
|
||||
channelChecked: function (channelIndex, path) {
|
||||
download.getDownloadOptions(path).channel[channelIndex].checked = true
|
||||
this.refresh()
|
||||
},
|
||||
channelUnchecked: function (channelIndex, path) {
|
||||
download.getDownloadOptions(path).channel[channelIndex].checked = false
|
||||
this.refresh()
|
||||
},
|
||||
getTimeInFormat: function (time) {
|
||||
if (time < 60) {
|
||||
const second = time
|
||||
return `${second}s`
|
||||
} else if (time < 3600) {
|
||||
const second = time % 60
|
||||
const minute = parseInt(time / 60)
|
||||
return `${minute}m${second}s`
|
||||
} else {
|
||||
const hour = parseInt(time / 3600)
|
||||
const hourRemain = time % 3600
|
||||
const minute = parseInt(hourRemain / 60)
|
||||
const second = hourRemain % 60
|
||||
return `${hour}h${minute}m${second}s`
|
||||
}
|
||||
},
|
||||
getCurrentFullPathName: function () {
|
||||
return this.currentlyDownloadInfo.previousPath + '/' + this.currentlyDownloadInfo.filenameWithType
|
||||
},
|
||||
downloading: async function (info) {
|
||||
this.$emit('download')
|
||||
},
|
||||
addDownloadTask: async function (info) {
|
||||
this.downloading()
|
||||
/*
|
||||
** download all
|
||||
*/
|
||||
if (parseInt(info.time_duration) < 18e8) {
|
||||
const rawData = await download.getAllRawDatas(info)
|
||||
exportData.exportCSV(info, rawData)
|
||||
} else {
|
||||
for (const channelID in info.raw_data) {
|
||||
const rawDataIDList = info.raw_data[channelID]
|
||||
|
||||
while (rawDataIDList.length > 1000) {
|
||||
const _list = rawDataIDList.splice(0, 1000)
|
||||
const rawData = await download.getIndexRawDatas(info, channelID, _list)
|
||||
exportData.exportCSV(info, rawData)
|
||||
}
|
||||
const rawData = await download.getIndexRawDatas(info, channelID, rawDataIDList)
|
||||
exportData.exportCSV(info, rawData, channelID)
|
||||
rawData[channelID].length = 0
|
||||
// const rawData = await download.getAllRawDatas(info)
|
||||
// console.timeEnd('download')
|
||||
}
|
||||
}
|
||||
// console.time('download')
|
||||
// const rawData = await download.getAllRawDatas(info)
|
||||
// console.timeEnd('download')
|
||||
// exportData.exportCSV(info, rawData)
|
||||
|
||||
/*
|
||||
** download split
|
||||
*/
|
||||
this.downloading()
|
||||
},
|
||||
_addDownloadTask: function (downloadPath) {
|
||||
if (Array.isArray(downloadPath)) {
|
||||
downloadPath.forEach(path => {
|
||||
this.downloadList.push(path.path)
|
||||
this.updateDownloadInfo(path.path)
|
||||
})
|
||||
} else {
|
||||
this.downloadList.push(downloadPath)
|
||||
this.updateDownloadInfo(downloadPath)
|
||||
}
|
||||
this.confirmDownload()
|
||||
},
|
||||
refresh: function () {
|
||||
this.downloadOptionsList = download.getDownloadOptionsList()
|
||||
console.log(this.downloadOptionsList)
|
||||
},
|
||||
confirmDownload: function (path) {
|
||||
console.log('confirmDownload')
|
||||
console.log(download.getDownloadOptionsList())
|
||||
console.log(download.isFileDownloading())
|
||||
console.log(download.downloadTaskRemain())
|
||||
if (!download.isFileDownloading() && download.downloadTaskRemain()) {
|
||||
const downloadOptionsIndex = download.getDownloadOptionsList().findIndex(downloadInfo => downloadInfo.metaPath === path)
|
||||
// this.downloadBlockList[downloadInfoIndex].status = 'downloading'
|
||||
this.currentlyDownloadInfo = download.getDownloadOptionsList()[downloadOptionsIndex]
|
||||
this.currentlyDownloadInfo.download.status = 'downloading'
|
||||
console.log(this.currentlyDownloadInfo)
|
||||
console.log(download.getDownloadOptionsList())
|
||||
|
||||
download.updateDownloadSubFileList(
|
||||
this.currentlyDownloadInfo.metaPath,
|
||||
this.currentlyDownloadInfo.channel,
|
||||
this.currentlyDownloadInfo.timeRange,
|
||||
)
|
||||
this.calculateFileSize(this.currentlyDownloadInfo.metaPath)
|
||||
console.log('getactualsize')
|
||||
this.subfileListRemain()
|
||||
}
|
||||
// if (this.downloadList.length > 0 && this.currentlyDownloadInfo.status === 'idle') {
|
||||
// this.showDownload()
|
||||
// this.updateDownloadSubFileList(this.downloadList[0])
|
||||
// } else {
|
||||
// /* TODO If file downloading then waiting */
|
||||
// console.log('no download task or file downloading')
|
||||
// }
|
||||
},
|
||||
_confirmDownload: function () {
|
||||
console.log('confirmDownload')
|
||||
console.log(download.getDownloadOptionsList())
|
||||
// if (this.downloadList.length > 0 && this.currentlyDownloadInfo.status === 'idle') {
|
||||
// this.showDownload()
|
||||
// this.updateDownloadSubFileList(this.downloadList[0])
|
||||
// } else {
|
||||
// /* TODO If file downloading then waiting */
|
||||
// console.log('no download task or file downloading')
|
||||
// }
|
||||
},
|
||||
downloadAllSubFileList: async function (path) {
|
||||
this.currentlyDownloadInfo = this.downloadInfo
|
||||
download.downloadAllSubFileList(path)
|
||||
this.subfileListRemain()
|
||||
},
|
||||
// updateDownloadInfo: function (path) {
|
||||
// console.log(path)
|
||||
// const metaInfo = file.getMetaInfo(path)
|
||||
// const downloadInfoIndex = this.downloadBlockList.findIndex(downloadInfo => downloadInfo.metaPath === path)
|
||||
|
||||
// if (downloadInfoIndex === -1) {
|
||||
// this.downloadInfo.library = metaInfo.configuration._LIBRARY_
|
||||
// this.downloadInfo.channel = metaInfo.channel.map(ch => {
|
||||
// let channel = ''
|
||||
// if (this.downloadInfo.library.includes('Elite')) {
|
||||
// channel = (ch === 0) ? 'current' : (ch === 1) ? 'voltage' : (ch === 2) ? 'resistance' : ''
|
||||
// } else {
|
||||
// channel = 'channel' + ch
|
||||
// }
|
||||
// return {
|
||||
// alias: channel,
|
||||
// channel: ch,
|
||||
// checked: true,
|
||||
// }
|
||||
// })
|
||||
|
||||
// this.downloadInfo.metaPath = path
|
||||
// this.downloadInfo.previousPath = path.split('/').slice(0, -1).join('/')
|
||||
// this.downloadInfo.filename = path.split(/[\/.]+/).slice(0, -1).pop()
|
||||
// this.downloadInfo.minTime = parseInt([...new Set(metaInfo['start-time'])][0] / 1000)
|
||||
// this.downloadInfo.maxTime = parseInt(metaInfo.time_duration / 1000)
|
||||
// this.downloadInfo.timeRange = [this.downloadInfo.minTime, this.downloadInfo.maxTime]
|
||||
// this.downloadInfo.status = 'idle'
|
||||
// this.downloadBlockList.push(JSON.parse(JSON.stringify(this.downloadInfo)))
|
||||
// } else {
|
||||
// for (var item in this.downloadInfo) {
|
||||
// this.downloadInfo[item] = this.downloadBlockList[downloadInfoIndex][item]
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
updatecurrentlyDownloadInfo: function () {
|
||||
const downloadInfoIndex = this.downloadBlockList.findIndex(downloadInfo => downloadInfo.metaPath === this.currentlyDownloadInfo.metaPath)
|
||||
if (downloadInfoIndex !== -1) {
|
||||
for (var item in this.downloadBlockList[downloadInfoIndex]) {
|
||||
this.downloadBlockList[downloadInfoIndex][item] = this.currentlyDownloadInfo[item]
|
||||
}
|
||||
}
|
||||
},
|
||||
updateMetaDownloadInfo: function () {
|
||||
download.updateDownloadSubFileList(
|
||||
this.currentlyDownloadInfo.metaPath,
|
||||
this.currentlyDownloadInfo.channel,
|
||||
this.currentlyDownloadInfo.timeRange,
|
||||
)
|
||||
},
|
||||
updateDownloadSubFileList: function (path) {
|
||||
console.log('updateDownloadSubFileList')
|
||||
const downloadOptionsIndex = this.downloadBlockList.findIndex(downloadInfo => downloadInfo.metaPath === path)
|
||||
this.downloadBlockList[downloadOptionsIndex].status = 'downloading'
|
||||
this.currentlyDownloadInfo = this.downloadBlockList[downloadOptionsIndex]
|
||||
this.updatecurrentlyDownloadInfo()
|
||||
|
||||
download.updateDownloadSubFileList(
|
||||
this.currentlyDownloadInfo.metaPath,
|
||||
this.currentlyDownloadInfo.channel,
|
||||
this.currentlyDownloadInfo.timeRange,
|
||||
)
|
||||
this.subfileListRemain()
|
||||
},
|
||||
_updateDownloadSubFileList: function (path) {
|
||||
console.log(path)
|
||||
console.log(this.downloadInfo)
|
||||
const downloadOptionsIndex = this.downloadBlockList.findIndex(downloadInfo => downloadInfo.metaPath === path)
|
||||
this.downloadBlockList[downloadOptionsIndex].status = 'downloading'
|
||||
this.currentlyDownloadInfo = this.downloadBlockList[downloadOptionsIndex]
|
||||
// this.updatecurrentlyDownloadInfo()
|
||||
|
||||
download.updateDownloadSubFileList(
|
||||
this.currentlyDownloadInfo.metaPath,
|
||||
this.currentlyDownloadInfo.channel,
|
||||
this.currentlyDownloadInfo.timeRange,
|
||||
)
|
||||
this.subfileListRemain()
|
||||
},
|
||||
subfileListRemain: function () {
|
||||
console.log('subfileListRemain')
|
||||
if (download.checkDownloadSubFileList(this.currentlyDownloadInfo.metaPath)) {
|
||||
this.currentlyDownloadInfo.filenameWithType = download.getFirstSubfile(this.currentlyDownloadInfo.metaPath)
|
||||
} else {
|
||||
this.loadingPercent = 100
|
||||
console.log(this.currentlyDownloadInfo.filenameWithType + ' download complete')
|
||||
console.log(performance.now())
|
||||
this.exportCSV()
|
||||
this.test(this.downloadDone)
|
||||
// this.currentlyDownloadInfo.status = this.currentlyDownloadInfo.status = 'idle'
|
||||
// this.updatecurrentlyDownloadInfo()
|
||||
// this.loadingPercent = 0
|
||||
}
|
||||
},
|
||||
checkFileSegmentGetOrNot: function () {
|
||||
console.log('checkFileSegmentGetOrNot')
|
||||
if (this.fileSegmentIndex >= this.fileSegmentMax) {
|
||||
const subfile = file.shiftDownloadSubFileList(this.currentlyDownloadInfo.metaPath)
|
||||
file.pushDownloadData(this.currentlyDownloadInfo.metaPath, subfile, this.data)
|
||||
|
||||
this.data = ''
|
||||
this.fileSegmentIndex = 0
|
||||
this.subfileListRemain()
|
||||
} else {
|
||||
}
|
||||
},
|
||||
exportCSV: function () {
|
||||
exportData.exportCSV(this.currentlyDownloadInfo)
|
||||
},
|
||||
exportTXT: function () {
|
||||
},
|
||||
timeRangeChange: function (timeRange, path) {
|
||||
download.getDownloadOptions(path).timeRange = timeRange
|
||||
this.refresh()
|
||||
},
|
||||
calculateFileSize: function () {
|
||||
this.totoalFileSize = file.getFileSize(this.currentlyDownloadInfo.metaPath)
|
||||
// const allSubfile = download.getAllSubfile(this.currentlyDownloadInfo.metaPath)
|
||||
// this.fileNum = allSubfile.length
|
||||
const downlinkSpeed = this.getNetSpeed('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAOEAAADhCAMAAAAJbSJIAAABTVBMVEX////qQzU0qFNChfT7vAU/g/RZlPU5gPT7uQCxyPqXufn/vQDpNCLqQTMwp1D7uADpOCfqPS4fo0bpMiD8wADpLxwopUv0paD1q6b86ObpOiv4/Pn+9/b4xcH2ubX1r6rsXVIre/NwvoOf0qvO6NQzqUm/4cf5zMn739zrSz398O/sVEjvdWz2t7PvenP4ycb7wir96Lf+8tb8zFH93pj+9eH//PD92Yvw9v7+7cP80Xb95q6pxPnq9u1PsmigvvlunvaJyZiGrvjD1vvyl5HtamHoJgzwhH3zmpTtXlLvenHuYSzygCL2mxjsUzDwcSf0jx34phH8z2DxfVHX5P38x0KHvnDOtiGjsjJ0rkLhuRW4tCnS4PyMsDtZq0it2bhmmvbO5OE1noBft3U1pWA/jNc8lLk5nJNBieSSy58+j8t5wIo6mKY2o25FrmBHQXgmAAAIJUlEQVR4nO2b2V/bRhCAhbADxJLQYQvwgcE2PsAhEHK0SUxigoGkTdMj6ZXDTdw2JbT+/x9r+QDZllYra8da85vvKU/yfszszO5IEQQEQRAEQRAEQRAEQRAEQRAEQRAEQRAEQRAEQRDWpLfXSplbqysWq9n1Unk7HfaSmJFey6ycNipGwpDUAZKRSMxt7B6vl7fDXl5QyqvVHdVQk5o8N4osa0nJqDSOSzNrmc7sVlRVk8fl7J4dTbmRXQt7sf5JZ6onkkPknC3VxE52tiJZPtUMjcru0lI1dkthL5uaTMNI0kVvOJLGRnYmCmx2R/IXPpukVFnh3nG9IvkPn81R1bJhKxC5vWME8evHMRO2hitr1URQv65jospp81jRkgz8LJLaStgyDpSfqywC2ENWN7gL48rJpAXUGe3kVthKQ2w3DKZ+c9ZuPOWocZQqrHagHY4yNRuoBbqjaZyc444D90A35AQPmzFdlYD8uorht410Q4UTnJON0A3TOxA15pLE6nUXvOYRlI3wI9gAFZRCFxReQBaZufAjKBwDtgkeioyQZX4UtcFDIyz5PqrJsqYlk2oymdQ8hqhc7MHtih9Ba+4rVTaqp6fHZ2fHp7sNaxDuPk3lQVCo+iijmmQ0zjJr9ncx6e3Syq6WcBk6crAHhVXqTSirJ7sZ53l2unQsGQ6R5GAPCuUT2vCpz28RL7K3q+pIIDlo9B026EYWmlT1vuGVT1X707jYg8IKVauXjQbdDbZctd0wuYjgGtU7peTcOvUTM/KgcPFQZDqnNYo6Khu7fh6ZftENo8yHYCnhLajN+R3NZzsFh489KAg73jk6yZisXNE4EVz3boXG7iSjzrUKH4KC93EtcTzZkzmZAD9a/obsJ0tnYa8xEKm9SPxboqHEwZkrCPuLkUj8JSFRpdOwlxiQg0iH+PJ3boJqNewVBuTOYqSrGH/lLKjtcFIuJuZhz7Dj+L1jldHKYa8wIKnIJfEfHDJVoj+Kcsr+sk1xvG0kZ30T9uvMleNI25DV2fo2zYH7y5FhxZdDhgbfH/vQsL8YGVG0tw15J+z1BefHUcNIPPLqsvsbt8NeX2BSo35DbUPbCHt9wbkzFsJe2+iHkN/P0ai562gYiS9abUPeCHt5DDhwFOy3DZWT62sQ7u+5GVq3DY2bz3sm555zkvYUl38Ke3kM2F92N4wsPqJ8ytKNwLyGMnxAiGFk+T6t4WY0IJtLUIYPSYZ7tE9ZWpgPyMJNKMM3pCR9MD3D6FMgwftxUpLuT89wfh7KkMk2ZGG4CWR4j1RK49SPYWH4FYzh1yTDN1M1BGoXjwhZuvhwqobvYAxdzt09Q+pSysJw4VkIhnevvSHtmY2NIdChhnRom7Lh42tv+AQNJ4OjfRiG4XRraRiG0+2HQJWGnzMNVLcgnksPpmoI1PH5uVtAGXJ0PwQ6efNzx4e6PXEzpwG7AXMzawObYrCalwaftUWhDIkz72XqmffmAg0kwxtQhqT3FrH4z5RPeXeThiOC4cIRlCHh3VPsF0Wpsfyt14QgQh3aBPf3h7HYr6Jo5ln+FGm3QjV8wfXsHYv8Joqicsjyp46i7oZgzcLtPX7sd0W00IsMf4qwDcGG+oLLtxixt2IPpcXul95tuvuBvZixGP+eJhZ5Lw5gGMQj0jYEuv92GfsmKrb34VJQVNrMfmiBtA2Bzt1dRr9r6zQJ0YbeZPQ7pEoanYcrNMJIv+g2iSF0Rj2RVGZAt+Hwwa3XJIZQckx+hXh0Bd2GQ9V00CSGg8gkT28QduH8AtiXGD0ub1Cxtw6CIpOz2xPi7QPs2N2n3/RjsfcOft16mgr6E69JhRTwQ4wBB70M/eAs2DmeBu77xBwFT9JeSxxpEiNbsR7sB0jN3oKNBom98SYxohjokrFEOK/Ng1fSLo/GmwRDxWceEQS8V1whElI0aKI+I1aZTrsHu97bKepehqKem6yiegnCnkmvOPQMYqeiTtIXH296CEb/YO3iTME7iJ1M9n+V8qqinRDCzS+GyZkUivqFv0z9OO8pCDdGHKXmnaZWpio+wpi60D/d8FIEHEGNkqfIUyuMrQLd81J50RS3/vyLrDitXdiFotjQO9bybd16nmL+TVQEe+XkuCiqIHYdD5vk/Vi4UMzB32vrc9S9mi48nY5bH7o87TnquaKLZKpwruj2dNj67x/XMEancZyx0aKopzbJ1nmxVrN5pmq14nnL1EefoihfXBShPk9wpdam24qDlZu6Lh7mLur183r9Itc6FHXddLxDb/3rmKnA4xknaPr+WIDMHopC+PNsfXLqjNPOUYumf0U6ttrjbWNqp5kh6lCKytZo24B7ZUiG5vQ2GVuf5+2bcXrHtRFSfgqqT0V72wAecxMVD8EUTeXL5TwDfvpEUvTVM3wxaBvRKR64HRXBothpG91MhfvPeJSKcHuxd9sIW7CjmINqGt22Eb6gANgXLcWPYdt1aepA9UZRKK/Q4BREkM1otpl+hRSIWgsgUyedugKRZ52pSrD3HwDU2HZGU+RlC9rIk259/lDMOlcZOqCWY5Sq+iGHAexROGTgaJqsvssBoSgGdDTNcy4T1EYzQBwVU6nz0wPdKbbGpoR0fno7Pwt+FoW64jeQiuk+OeaSVDHnMhF10Zud8F3RkRSt2aiHXMdObDVnT69PoZlrm7qzpzUg1s12Ll+YpeR0IFUr5i9abd2iP/M2u/9ut+r5Ym3G7a5IpWqFYrOZt2g2i4VCLXVt3BAEQRAEQRAEQRAEQRAEQRAEQRAEQRAEQRAE4Yf/AZmODCZml4YgAAAAAElFTkSuQmCC', 3)
|
||||
// this.totoalFileSize = (allSubfile.length) * 1000000
|
||||
console.log(downlinkSpeed)
|
||||
console.log(this.totoalFileSize)
|
||||
this.estimatedTime = this.totoalFileSize / (downlinkSpeed * 1024)
|
||||
if (this.totoalFileSize >= 1 * 1024 * 1024) {
|
||||
console.log('size big')
|
||||
this.estimatedTime = this.estimatedTime * 10
|
||||
}
|
||||
console.log(this.estimatedTime)
|
||||
this.loadTime = parseInt((this.estimatedTime / 1000) % 60) * 100
|
||||
console.log(this.loadTime)
|
||||
this.doProgress()
|
||||
// allSubfile.forEach(subfile => {
|
||||
// console.log(subfile)
|
||||
// this.currentlyDownloadInfo.filenameWithType = subfile
|
||||
// })
|
||||
},
|
||||
doProgress () {
|
||||
const step = this.estimatedTime / 100 * 1000
|
||||
this.interval = setInterval(() => {
|
||||
if (this.loadingPercent >= 99) {
|
||||
console.log('complete')
|
||||
clearInterval(this.interval)
|
||||
this.estimatedTime = 0
|
||||
} else {
|
||||
this.loadingPercent++
|
||||
}
|
||||
}, step)
|
||||
},
|
||||
getNetSpeed (url, times) {
|
||||
const connection = window.navigator.connection
|
||||
if (connection && connection.downlink) {
|
||||
return connection.downlink * 1024 / 8
|
||||
}
|
||||
},
|
||||
test: async function (fn) {
|
||||
return await setTimeout(async function () {
|
||||
await fn()
|
||||
}, 1000)
|
||||
},
|
||||
downloadDone: function () {
|
||||
download.getDownloadOptionsList().shift()
|
||||
this.loadingPercent = 0
|
||||
this.refresh()
|
||||
this.confirmDownload()
|
||||
},
|
||||
getControllerList: async function () {
|
||||
const update = async () => {
|
||||
this.controllerList.push({
|
||||
@@ -539,43 +52,131 @@ export default {
|
||||
}
|
||||
await update()
|
||||
},
|
||||
mqttPub: function (topic, mes) {
|
||||
this.$mqtt.publish(topic, mes)
|
||||
},
|
||||
mqttSub: function (val) {
|
||||
this.$mqtt.subscribe(val)
|
||||
},
|
||||
mqttUnSub: function (val) {
|
||||
this.$mqtt.unsubscribe(val)
|
||||
},
|
||||
pageMqttSub: function () {
|
||||
this.controllerList.forEach(controller => {
|
||||
// this.mqttSub(controller.id + '/broadcast')
|
||||
this.mqttSub(controller.id + '/file_meta_info/+')
|
||||
this.mqttSub(controller.id + '/file_segment/+')
|
||||
this.mqttSub(controller.id + '/file_segment_get/+')
|
||||
})
|
||||
},
|
||||
pageMqttUnSub: function () {
|
||||
this.controllerList.forEach(controller => {
|
||||
// this.mqttUnSub(controller.id + '/broadcast')
|
||||
this.mqttUnSub(controller.id + '/file_meta_info/+')
|
||||
this.mqttUnSub(controller.id + '/file_segment/+')
|
||||
this.mqttUnSub(controller.id + '/file_segment_get/+')
|
||||
notify (name) {
|
||||
this.showToast(`done ${name}`, {
|
||||
position: 'bottom-right',
|
||||
})
|
||||
},
|
||||
...mapActions('download',
|
||||
[
|
||||
types.raw.rawDataByID,
|
||||
types.export.setHeader,
|
||||
types.export.setTitle,
|
||||
types.export.setData,
|
||||
types.downloadStream.writerClose,
|
||||
types.downloadStream.setDownloadStream,
|
||||
],
|
||||
),
|
||||
...mapMutations('download',
|
||||
[
|
||||
types.download.setSampleRate,
|
||||
types.download.setdownloadIdList,
|
||||
],
|
||||
),
|
||||
},
|
||||
watch: {
|
||||
},
|
||||
// watch: {
|
||||
// loadingPercent(val) {
|
||||
// if (val >= 100) {
|
||||
// console.log('complete');
|
||||
// clearInterval(this.interval)
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
async mounted () {
|
||||
await this.getControllerList()
|
||||
this.pageMqttSub()
|
||||
// TODO authorization
|
||||
const format = this.$route.params.format
|
||||
this.metaList = this.$route.params.metaList.split('-')
|
||||
|
||||
while (this.metaList.length !== 0) {
|
||||
let meta
|
||||
const metaID = this.metaList.pop()
|
||||
const ret = await api.meta.getByID(metaID)
|
||||
|
||||
if (ret.status === 200) {
|
||||
meta = ret.data[0]
|
||||
}
|
||||
if (meta !== undefined) {
|
||||
this.metaInfo = meta
|
||||
const channelArray = JSON.parse(this.metaInfo.channels)
|
||||
const channelList = []
|
||||
|
||||
if (meta.device.library_name.indexOf('Neulive') >= 0) {
|
||||
if (channelArray.some(el => el >= 256)) {
|
||||
channelList.push(channelArray.filter(el => el < 256))
|
||||
channelList.push(channelArray.filter(el => (el >= 256 && el <= 259)))
|
||||
} else {
|
||||
channelList.push(channelArray)
|
||||
}
|
||||
} else if (meta.device.library_name.indexOf('Elite') >= 0) {
|
||||
channelList.push(channelArray)
|
||||
}
|
||||
while (channelList.length > 0) {
|
||||
this.downloadInfo = newDownload()
|
||||
this.downloadInfo.channel = channelList.pop()
|
||||
|
||||
// download format
|
||||
this.downloadInfo.format = format
|
||||
|
||||
// download device and filename
|
||||
if (meta.device.library_name.indexOf('Neulive') >= 0) {
|
||||
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)
|
||||
} else {
|
||||
this.downloadInfo.filename = meta.name + '-' + format
|
||||
this.downloadInfo.size = parseInt(meta.size)
|
||||
}
|
||||
} else if (meta.device.library_name.indexOf('Elite') >= 0) {
|
||||
this.downloadInfo.device = [meta.device.library_name.slice(0, 5), meta.device.library_name.slice(5)]
|
||||
this.downloadInfo.filename = meta.name + '-' + format
|
||||
this.downloadInfo.size = parseInt(meta.size)
|
||||
}
|
||||
|
||||
// init
|
||||
|
||||
// get sampleRate && downloadList
|
||||
for (const channel of this.downloadInfo.channel) {
|
||||
this.downloadInfo.channelInfo[channel] = newChannel()
|
||||
this.setSampleRateDownload({ channel: channel })
|
||||
this.setdownloadIdListDownload({ channel: channel })
|
||||
}
|
||||
|
||||
// create writer
|
||||
this.setDownloadStream()
|
||||
|
||||
console.log(this.downloadInfo)
|
||||
console.log(this.metaInfo)
|
||||
|
||||
// set Header
|
||||
if (this.downloadInfo.format !== 'csv-edf') {
|
||||
this.setHeaderExport()
|
||||
}
|
||||
this.setTitleExport()
|
||||
|
||||
// start download data
|
||||
let rowIndex = 0
|
||||
|
||||
while (rowIndex < this.downloadInfo.maxRows) {
|
||||
for (const channel of this.downloadInfo.channel) {
|
||||
for (const idx in this.downloadInfo.channelInfo[channel].downloadIDList) {
|
||||
const _idx = parseInt(idx)
|
||||
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,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
this.setDataExport({ last: (rowIndex === this.downloadInfo.maxRows - 1) })
|
||||
rowIndex += 1
|
||||
}
|
||||
this.writerCloseDownloadStream()
|
||||
}
|
||||
}
|
||||
}
|
||||
await new Promise(resolve => setTimeout(resolve, 2000)) // sleep
|
||||
window.close()
|
||||
},
|
||||
destroyed () {
|
||||
this.pageMqttUnSub()
|
||||
|
||||
@@ -0,0 +1,589 @@
|
||||
<template>
|
||||
<div>
|
||||
<va-modal
|
||||
class="flex sm12 xl12 md12 xs12 pa-0 ma-0"
|
||||
v-model="showDownload"
|
||||
size="small"
|
||||
:hideDefaultActions="true"
|
||||
:mobileFullscreen="false"
|
||||
>
|
||||
<template slot="header">
|
||||
<div class="row mb-2">
|
||||
<va-icon name="fa fa-download mr-3 " color="primary"/>
|
||||
<h5 class="mt-0 mb-0">{{'Download'}}</h5>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<div class="downloadOptionsList">
|
||||
<template v-for="(downloadOptions, i) in downloadOptionsList">
|
||||
<va-accordion :key="downloadOptions.filename">
|
||||
<va-collapse>
|
||||
<va-item :key="downloadOptions.filename" slot="header" clickable>
|
||||
<va-item-section avatar>
|
||||
<va-item-label>
|
||||
{{ downloadOptions.filename }}
|
||||
</va-item-label>
|
||||
</va-item-section>
|
||||
|
||||
<va-item-section>
|
||||
<!-- <va-item-label>
|
||||
{{ downloadInfo.minTime }}
|
||||
</va-item-label>
|
||||
|
||||
<va-item-label caption>
|
||||
{{ downloadInfo.maxTime }}
|
||||
</va-item-label> -->
|
||||
</va-item-section>
|
||||
|
||||
<va-item-section v-if="downloadOptions.download.status == 'idle'" side>
|
||||
<va-icon name="fa fa-play" color="gray" @click.native.stop="confirmDownload(downloadOptions.metaPath)"/>
|
||||
</va-item-section>
|
||||
<va-item-section v-else side class="md4 offset--md8">
|
||||
<div class="row flex sm12 xl12 md12 xs12">
|
||||
<div class="flex-center spinner-box">
|
||||
<fulfilling-bouncing-circle-spinner
|
||||
:animation-duration="3000"
|
||||
:color="'#6c7fee'"
|
||||
:size="20"
|
||||
>
|
||||
</fulfilling-bouncing-circle-spinner>
|
||||
<span class="ml-3">{{loaded}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</va-item-section>
|
||||
|
||||
</va-item>
|
||||
<div slot="body">
|
||||
<div v-if="downloadOptions.download.status == 'downloading'" class="row flex sm12 xl12 md12 xs12">
|
||||
<div class="row flex sm12 xl12 md12 xs12">
|
||||
<div class="flex-center spinner-box mt-4 mb-5">
|
||||
<fulfilling-bouncing-circle-spinner
|
||||
:animation-duration="3000"
|
||||
:color="'#6c7fee'"
|
||||
:size="60"
|
||||
>
|
||||
</fulfilling-bouncing-circle-spinner>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else>
|
||||
<div class="mb-5">
|
||||
<va-item class="flex sm12 xl12 md12 xs12 mr-1 pa-0">
|
||||
<va-icon
|
||||
class="flex sm1 xl1 md1 xs1 start "
|
||||
name="glyphicon glyphicon-filter"
|
||||
size="1.0rem"
|
||||
:fixedWidth = "Boolean('true')"
|
||||
/>
|
||||
<div class="flex sm11 xl11 md11 xs11 row">
|
||||
<div v-for="(item,index) in downloadOptions.channel" :key="item.channel" class="filter-button">
|
||||
<va-button
|
||||
class="mx-1 px-1"
|
||||
v-if="item.checked"
|
||||
@click="channelUnchecked(index,downloadOptions.metaPath)"
|
||||
small
|
||||
>
|
||||
{{item.alias}}
|
||||
</va-button>
|
||||
<va-button
|
||||
class="mx-1 px-1"
|
||||
v-else
|
||||
@click="channelChecked(index,downloadOptions.metaPath)"
|
||||
small outline
|
||||
>
|
||||
{{item.alias}}
|
||||
</va-button>
|
||||
</div>
|
||||
</div>
|
||||
</va-item>
|
||||
</div>
|
||||
<div class="mb-5">
|
||||
<va-item class="flex sm12 xl12 md12 xs12 pa-0">
|
||||
<va-icon
|
||||
class="flex sm1 xl1 md1 xs1 mr-4"
|
||||
:fixedWidth="true"
|
||||
name="va-icon glyphicon glyphicon-time"
|
||||
size="1.0rem"
|
||||
/>
|
||||
<div class="flex">
|
||||
<va-slider
|
||||
class="flex sm11 xl11 md11 xs11 filter-button"
|
||||
value-visible
|
||||
range
|
||||
v-model="downloadOptions.timeRange"
|
||||
@click.native="timeRangeChange(downloadOptions.timeRange,downloadOptions.metaPath)"
|
||||
@mouseup.native="timeRangeChange(downloadOptions.timeRange,downloadOptions.metaPath)"
|
||||
@mouseleave.native="timeRangeChange(downloadOptions.timeRange,downloadOptions.metaPath)"
|
||||
@touchend.native="timeRangeChange(downloadOptions.timeRange,downloadOptions.metaPath)"
|
||||
:min="downloadOptions.minTime"
|
||||
:max="downloadOptions.maxTime"
|
||||
/>
|
||||
<span> {{ transTime(downloadOptions.timeRange) }} </span>
|
||||
</div>
|
||||
</va-item>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</va-collapse>
|
||||
</va-accordion>
|
||||
<va-list-separator v-if="i < downloadOptionsList.length - 1" :key="'separator' + downloadOptions.filename" />
|
||||
</template>
|
||||
</div>
|
||||
</va-modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { file } from '../../data/file/File'
|
||||
import { download } from '../../data/download/Download'
|
||||
import { exportData } from '../../data/export/export'
|
||||
import { FulfillingBouncingCircleSpinner } from 'epic-spinners'
|
||||
|
||||
export default {
|
||||
name: 'Download',
|
||||
components: {
|
||||
FulfillingBouncingCircleSpinner,
|
||||
},
|
||||
data: () => {
|
||||
return {
|
||||
showDownload: false,
|
||||
controllerList: [],
|
||||
downloadList: [],
|
||||
downloadListRecord: [],
|
||||
downloadOptionsList: [],
|
||||
// downloadInfo: {
|
||||
// metaPath: '',
|
||||
// previousPath: '',
|
||||
// filenameWithType: '',
|
||||
// filename: '',
|
||||
// channel: [],
|
||||
// timeRange: [0, 0],
|
||||
// minTime: 0,
|
||||
// maxTime: 0,
|
||||
// status: 'idle',
|
||||
// device: '',
|
||||
// },
|
||||
currentlyDownloadInfo: {
|
||||
metaPath: '',
|
||||
previousPath: '',
|
||||
filenameWithType: '',
|
||||
filename: '',
|
||||
channel: [],
|
||||
timeRange: [0, 0],
|
||||
minTime: 0,
|
||||
maxTime: 0,
|
||||
download: {
|
||||
status: 'idle',
|
||||
rate: 0,
|
||||
},
|
||||
device: '',
|
||||
},
|
||||
estimatedTime: 0,
|
||||
fileSegmentIndex: 0,
|
||||
fileSegmentMax: 0,
|
||||
totoalFileSize: 0,
|
||||
loadingPercent: 0,
|
||||
loadTime: 0,
|
||||
interval: null,
|
||||
data: '',
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
// transTime (min,max) {
|
||||
// return this.getTimeInFormat(min) + ' - ' + this.getTimeInFormat(max)
|
||||
// },
|
||||
loaded () {
|
||||
return this.loadingPercent + '%'
|
||||
},
|
||||
},
|
||||
// mqtt: {
|
||||
// async '+/file_segment/+' (data, topic) {
|
||||
// console.log('file_segment')
|
||||
// console.log(String.fromCharCode.apply(null, data))
|
||||
// // console.log(navigator.connection.downlink)
|
||||
// // console.log(this.fileNum)
|
||||
// // console.log(this.downloadOptionsList.length)
|
||||
// // console.log(JSON.parse(String.fromCharCode.apply(null, data)).data.file_size)
|
||||
|
||||
// if (this.downloadOptionsList.length > 0) {
|
||||
// await download.updateFileSegmentInfo(String.fromCharCode.apply(null, data))
|
||||
// this.fileSegmentMax = download.getFileSegmentMaxIndex()
|
||||
// this.checkFileSegmentGetOrNot()
|
||||
// }
|
||||
// },
|
||||
// async '+/file_segment_get/+' (data, topic) {
|
||||
// console.log('file_segment_get')
|
||||
// console.log(JSON.parse(new TextDecoder('utf-8').decode(data)))
|
||||
// if (this.downloadOptionsList.length > 0) {
|
||||
// const segmentData = atob(JSON.parse(new TextDecoder('utf-8').decode(data)).data.segment)
|
||||
// this.data += segmentData
|
||||
|
||||
// this.fileSegmentIndex += 1
|
||||
// this.checkFileSegmentGetOrNot()
|
||||
// }
|
||||
// },
|
||||
// },
|
||||
methods: {
|
||||
transTime (timeRange) {
|
||||
return this.getTimeInFormat(timeRange[0]) + ' - ' + this.getTimeInFormat(timeRange[1])
|
||||
},
|
||||
notify (name) {
|
||||
this.showToast(`done ${name}`, {
|
||||
position: 'bottom-right',
|
||||
})
|
||||
},
|
||||
showDownloadModal: function () {
|
||||
this.showDownload = true
|
||||
},
|
||||
channelChecked: function (channelIndex, path) {
|
||||
download.getDownloadOptions(path).channel[channelIndex].checked = true
|
||||
this.refresh()
|
||||
},
|
||||
channelUnchecked: function (channelIndex, path) {
|
||||
download.getDownloadOptions(path).channel[channelIndex].checked = false
|
||||
this.refresh()
|
||||
},
|
||||
getTimeInFormat: function (time) {
|
||||
if (time < 60) {
|
||||
const second = time
|
||||
return `${second}s`
|
||||
} else if (time < 3600) {
|
||||
const second = time % 60
|
||||
const minute = parseInt(time / 60)
|
||||
return `${minute}m${second}s`
|
||||
} else {
|
||||
const hour = parseInt(time / 3600)
|
||||
const hourRemain = time % 3600
|
||||
const minute = parseInt(hourRemain / 60)
|
||||
const second = hourRemain % 60
|
||||
return `${hour}h${minute}m${second}s`
|
||||
}
|
||||
},
|
||||
getCurrentFullPathName: function () {
|
||||
return this.currentlyDownloadInfo.previousPath + '/' + this.currentlyDownloadInfo.filenameWithType
|
||||
},
|
||||
downloading: async function (info) {
|
||||
this.$emit('download')
|
||||
},
|
||||
addDownloadTask: async function (info) {
|
||||
this.downloading()
|
||||
/*
|
||||
** download all
|
||||
*/
|
||||
if (parseInt(info.time_duration) < 18e8) {
|
||||
const rawData = await download.getAllRawDatas(info)
|
||||
exportData.exportCSV(info, rawData)
|
||||
} else {
|
||||
for (const channelID in info.raw_data) {
|
||||
const rawDataIDList = info.raw_data[channelID]
|
||||
|
||||
while (rawDataIDList.length > 1000) {
|
||||
const _list = rawDataIDList.splice(0, 1000)
|
||||
const rawData = await download.getIndexRawDatas(info, channelID, _list)
|
||||
exportData.exportCSV(info, rawData)
|
||||
}
|
||||
const rawData = await download.getIndexRawDatas(info, channelID, rawDataIDList)
|
||||
exportData.exportCSV(info, rawData, channelID)
|
||||
rawData[channelID].length = 0
|
||||
// const rawData = await download.getAllRawDatas(info)
|
||||
// console.timeEnd('download')
|
||||
}
|
||||
}
|
||||
// console.time('download')
|
||||
// const rawData = await download.getAllRawDatas(info)
|
||||
// console.timeEnd('download')
|
||||
// exportData.exportCSV(info, rawData)
|
||||
|
||||
/*
|
||||
** download split
|
||||
*/
|
||||
this.downloading()
|
||||
},
|
||||
_addDownloadTask: function (downloadPath) {
|
||||
if (Array.isArray(downloadPath)) {
|
||||
downloadPath.forEach(path => {
|
||||
this.downloadList.push(path.path)
|
||||
this.updateDownloadInfo(path.path)
|
||||
})
|
||||
} else {
|
||||
this.downloadList.push(downloadPath)
|
||||
this.updateDownloadInfo(downloadPath)
|
||||
}
|
||||
this.confirmDownload()
|
||||
},
|
||||
refresh: function () {
|
||||
this.downloadOptionsList = download.getDownloadOptionsList()
|
||||
console.log(this.downloadOptionsList)
|
||||
},
|
||||
confirmDownload: function (path) {
|
||||
console.log('confirmDownload')
|
||||
console.log(download.getDownloadOptionsList())
|
||||
console.log(download.isFileDownloading())
|
||||
console.log(download.downloadTaskRemain())
|
||||
if (!download.isFileDownloading() && download.downloadTaskRemain()) {
|
||||
const downloadOptionsIndex = download.getDownloadOptionsList().findIndex(downloadInfo => downloadInfo.metaPath === path)
|
||||
// this.downloadBlockList[downloadInfoIndex].status = 'downloading'
|
||||
this.currentlyDownloadInfo = download.getDownloadOptionsList()[downloadOptionsIndex]
|
||||
this.currentlyDownloadInfo.download.status = 'downloading'
|
||||
console.log(this.currentlyDownloadInfo)
|
||||
console.log(download.getDownloadOptionsList())
|
||||
|
||||
download.updateDownloadSubFileList(
|
||||
this.currentlyDownloadInfo.metaPath,
|
||||
this.currentlyDownloadInfo.channel,
|
||||
this.currentlyDownloadInfo.timeRange,
|
||||
)
|
||||
this.calculateFileSize(this.currentlyDownloadInfo.metaPath)
|
||||
console.log('getactualsize')
|
||||
this.subfileListRemain()
|
||||
}
|
||||
// if (this.downloadList.length > 0 && this.currentlyDownloadInfo.status === 'idle') {
|
||||
// this.showDownload()
|
||||
// this.updateDownloadSubFileList(this.downloadList[0])
|
||||
// } else {
|
||||
// /* TODO If file downloading then waiting */
|
||||
// console.log('no download task or file downloading')
|
||||
// }
|
||||
},
|
||||
_confirmDownload: function () {
|
||||
console.log('confirmDownload')
|
||||
console.log(download.getDownloadOptionsList())
|
||||
// if (this.downloadList.length > 0 && this.currentlyDownloadInfo.status === 'idle') {
|
||||
// this.showDownload()
|
||||
// this.updateDownloadSubFileList(this.downloadList[0])
|
||||
// } else {
|
||||
// /* TODO If file downloading then waiting */
|
||||
// console.log('no download task or file downloading')
|
||||
// }
|
||||
},
|
||||
downloadAllSubFileList: async function (path) {
|
||||
this.currentlyDownloadInfo = this.downloadInfo
|
||||
download.downloadAllSubFileList(path)
|
||||
this.subfileListRemain()
|
||||
},
|
||||
// updateDownloadInfo: function (path) {
|
||||
// console.log(path)
|
||||
// const metaInfo = file.getMetaInfo(path)
|
||||
// const downloadInfoIndex = this.downloadBlockList.findIndex(downloadInfo => downloadInfo.metaPath === path)
|
||||
|
||||
// if (downloadInfoIndex === -1) {
|
||||
// this.downloadInfo.library = metaInfo.configuration._LIBRARY_
|
||||
// this.downloadInfo.channel = metaInfo.channel.map(ch => {
|
||||
// let channel = ''
|
||||
// if (this.downloadInfo.library.includes('Elite')) {
|
||||
// channel = (ch === 0) ? 'current' : (ch === 1) ? 'voltage' : (ch === 2) ? 'resistance' : ''
|
||||
// } else {
|
||||
// channel = 'channel' + ch
|
||||
// }
|
||||
// return {
|
||||
// alias: channel,
|
||||
// channel: ch,
|
||||
// checked: true,
|
||||
// }
|
||||
// })
|
||||
|
||||
// this.downloadInfo.metaPath = path
|
||||
// this.downloadInfo.previousPath = path.split('/').slice(0, -1).join('/')
|
||||
// this.downloadInfo.filename = path.split(/[\/.]+/).slice(0, -1).pop()
|
||||
// this.downloadInfo.minTime = parseInt([...new Set(metaInfo['start-time'])][0] / 1000)
|
||||
// this.downloadInfo.maxTime = parseInt(metaInfo.time_duration / 1000)
|
||||
// this.downloadInfo.timeRange = [this.downloadInfo.minTime, this.downloadInfo.maxTime]
|
||||
// this.downloadInfo.status = 'idle'
|
||||
// this.downloadBlockList.push(JSON.parse(JSON.stringify(this.downloadInfo)))
|
||||
// } else {
|
||||
// for (var item in this.downloadInfo) {
|
||||
// this.downloadInfo[item] = this.downloadBlockList[downloadInfoIndex][item]
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
updatecurrentlyDownloadInfo: function () {
|
||||
const downloadInfoIndex = this.downloadBlockList.findIndex(downloadInfo => downloadInfo.metaPath === this.currentlyDownloadInfo.metaPath)
|
||||
if (downloadInfoIndex !== -1) {
|
||||
for (var item in this.downloadBlockList[downloadInfoIndex]) {
|
||||
this.downloadBlockList[downloadInfoIndex][item] = this.currentlyDownloadInfo[item]
|
||||
}
|
||||
}
|
||||
},
|
||||
updateMetaDownloadInfo: function () {
|
||||
download.updateDownloadSubFileList(
|
||||
this.currentlyDownloadInfo.metaPath,
|
||||
this.currentlyDownloadInfo.channel,
|
||||
this.currentlyDownloadInfo.timeRange,
|
||||
)
|
||||
},
|
||||
updateDownloadSubFileList: function (path) {
|
||||
console.log('updateDownloadSubFileList')
|
||||
const downloadOptionsIndex = this.downloadBlockList.findIndex(downloadInfo => downloadInfo.metaPath === path)
|
||||
this.downloadBlockList[downloadOptionsIndex].status = 'downloading'
|
||||
this.currentlyDownloadInfo = this.downloadBlockList[downloadOptionsIndex]
|
||||
this.updatecurrentlyDownloadInfo()
|
||||
|
||||
download.updateDownloadSubFileList(
|
||||
this.currentlyDownloadInfo.metaPath,
|
||||
this.currentlyDownloadInfo.channel,
|
||||
this.currentlyDownloadInfo.timeRange,
|
||||
)
|
||||
this.subfileListRemain()
|
||||
},
|
||||
_updateDownloadSubFileList: function (path) {
|
||||
console.log(path)
|
||||
console.log(this.downloadInfo)
|
||||
const downloadOptionsIndex = this.downloadBlockList.findIndex(downloadInfo => downloadInfo.metaPath === path)
|
||||
this.downloadBlockList[downloadOptionsIndex].status = 'downloading'
|
||||
this.currentlyDownloadInfo = this.downloadBlockList[downloadOptionsIndex]
|
||||
// this.updatecurrentlyDownloadInfo()
|
||||
|
||||
download.updateDownloadSubFileList(
|
||||
this.currentlyDownloadInfo.metaPath,
|
||||
this.currentlyDownloadInfo.channel,
|
||||
this.currentlyDownloadInfo.timeRange,
|
||||
)
|
||||
this.subfileListRemain()
|
||||
},
|
||||
subfileListRemain: function () {
|
||||
console.log('subfileListRemain')
|
||||
if (download.checkDownloadSubFileList(this.currentlyDownloadInfo.metaPath)) {
|
||||
this.currentlyDownloadInfo.filenameWithType = download.getFirstSubfile(this.currentlyDownloadInfo.metaPath)
|
||||
} else {
|
||||
this.loadingPercent = 100
|
||||
console.log(this.currentlyDownloadInfo.filenameWithType + ' download complete')
|
||||
console.log(performance.now())
|
||||
this.exportCSV()
|
||||
this.test(this.downloadDone)
|
||||
// this.currentlyDownloadInfo.status = this.currentlyDownloadInfo.status = 'idle'
|
||||
// this.updatecurrentlyDownloadInfo()
|
||||
// this.loadingPercent = 0
|
||||
}
|
||||
},
|
||||
checkFileSegmentGetOrNot: function () {
|
||||
console.log('checkFileSegmentGetOrNot')
|
||||
if (this.fileSegmentIndex >= this.fileSegmentMax) {
|
||||
const subfile = file.shiftDownloadSubFileList(this.currentlyDownloadInfo.metaPath)
|
||||
file.pushDownloadData(this.currentlyDownloadInfo.metaPath, subfile, this.data)
|
||||
|
||||
this.data = ''
|
||||
this.fileSegmentIndex = 0
|
||||
this.subfileListRemain()
|
||||
} else {
|
||||
}
|
||||
},
|
||||
exportCSV: function () {
|
||||
exportData.exportCSV(this.currentlyDownloadInfo)
|
||||
},
|
||||
exportTXT: function () {
|
||||
},
|
||||
timeRangeChange: function (timeRange, path) {
|
||||
download.getDownloadOptions(path).timeRange = timeRange
|
||||
this.refresh()
|
||||
},
|
||||
calculateFileSize: function () {
|
||||
this.totoalFileSize = file.getFileSize(this.currentlyDownloadInfo.metaPath)
|
||||
// const allSubfile = download.getAllSubfile(this.currentlyDownloadInfo.metaPath)
|
||||
// this.fileNum = allSubfile.length
|
||||
const downlinkSpeed = this.getNetSpeed('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAOEAAADhCAMAAAAJbSJIAAABTVBMVEX////qQzU0qFNChfT7vAU/g/RZlPU5gPT7uQCxyPqXufn/vQDpNCLqQTMwp1D7uADpOCfqPS4fo0bpMiD8wADpLxwopUv0paD1q6b86ObpOiv4/Pn+9/b4xcH2ubX1r6rsXVIre/NwvoOf0qvO6NQzqUm/4cf5zMn739zrSz398O/sVEjvdWz2t7PvenP4ycb7wir96Lf+8tb8zFH93pj+9eH//PD92Yvw9v7+7cP80Xb95q6pxPnq9u1PsmigvvlunvaJyZiGrvjD1vvyl5HtamHoJgzwhH3zmpTtXlLvenHuYSzygCL2mxjsUzDwcSf0jx34phH8z2DxfVHX5P38x0KHvnDOtiGjsjJ0rkLhuRW4tCnS4PyMsDtZq0it2bhmmvbO5OE1noBft3U1pWA/jNc8lLk5nJNBieSSy58+j8t5wIo6mKY2o25FrmBHQXgmAAAIJUlEQVR4nO2b2V/bRhCAhbADxJLQYQvwgcE2PsAhEHK0SUxigoGkTdMj6ZXDTdw2JbT+/x9r+QDZllYra8da85vvKU/yfszszO5IEQQEQRAEQRAEQRAEQRAEQRAEQRAEQRAEQRAEQRDWpLfXSplbqysWq9n1Unk7HfaSmJFey6ycNipGwpDUAZKRSMxt7B6vl7fDXl5QyqvVHdVQk5o8N4osa0nJqDSOSzNrmc7sVlRVk8fl7J4dTbmRXQt7sf5JZ6onkkPknC3VxE52tiJZPtUMjcru0lI1dkthL5uaTMNI0kVvOJLGRnYmCmx2R/IXPpukVFnh3nG9IvkPn81R1bJhKxC5vWME8evHMRO2hitr1URQv65jospp81jRkgz8LJLaStgyDpSfqywC2ENWN7gL48rJpAXUGe3kVthKQ2w3DKZ+c9ZuPOWocZQqrHagHY4yNRuoBbqjaZyc444D90A35AQPmzFdlYD8uorht410Q4UTnJON0A3TOxA15pLE6nUXvOYRlI3wI9gAFZRCFxReQBaZufAjKBwDtgkeioyQZX4UtcFDIyz5PqrJsqYlk2oymdQ8hqhc7MHtih9Ba+4rVTaqp6fHZ2fHp7sNaxDuPk3lQVCo+iijmmQ0zjJr9ncx6e3Syq6WcBk6crAHhVXqTSirJ7sZ53l2unQsGQ6R5GAPCuUT2vCpz28RL7K3q+pIIDlo9B026EYWmlT1vuGVT1X707jYg8IKVauXjQbdDbZctd0wuYjgGtU7peTcOvUTM/KgcPFQZDqnNYo6Khu7fh6ZftENo8yHYCnhLajN+R3NZzsFh489KAg73jk6yZisXNE4EVz3boXG7iSjzrUKH4KC93EtcTzZkzmZAD9a/obsJ0tnYa8xEKm9SPxboqHEwZkrCPuLkUj8JSFRpdOwlxiQg0iH+PJ3boJqNewVBuTOYqSrGH/lLKjtcFIuJuZhz7Dj+L1jldHKYa8wIKnIJfEfHDJVoj+Kcsr+sk1xvG0kZ30T9uvMleNI25DV2fo2zYH7y5FhxZdDhgbfH/vQsL8YGVG0tw15J+z1BefHUcNIPPLqsvsbt8NeX2BSo35DbUPbCHt9wbkzFsJe2+iHkN/P0ai562gYiS9abUPeCHt5DDhwFOy3DZWT62sQ7u+5GVq3DY2bz3sm555zkvYUl38Ke3kM2F92N4wsPqJ8ytKNwLyGMnxAiGFk+T6t4WY0IJtLUIYPSYZ7tE9ZWpgPyMJNKMM3pCR9MD3D6FMgwftxUpLuT89wfh7KkMk2ZGG4CWR4j1RK49SPYWH4FYzh1yTDN1M1BGoXjwhZuvhwqobvYAxdzt09Q+pSysJw4VkIhnevvSHtmY2NIdChhnRom7Lh42tv+AQNJ4OjfRiG4XRraRiG0+2HQJWGnzMNVLcgnksPpmoI1PH5uVtAGXJ0PwQ6efNzx4e6PXEzpwG7AXMzawObYrCalwaftUWhDIkz72XqmffmAg0kwxtQhqT3FrH4z5RPeXeThiOC4cIRlCHh3VPsF0Wpsfyt14QgQh3aBPf3h7HYr6Jo5ln+FGm3QjV8wfXsHYv8Joqicsjyp46i7oZgzcLtPX7sd0W00IsMf4qwDcGG+oLLtxixt2IPpcXul95tuvuBvZixGP+eJhZ5Lw5gGMQj0jYEuv92GfsmKrb34VJQVNrMfmiBtA2Bzt1dRr9r6zQJ0YbeZPQ7pEoanYcrNMJIv+g2iSF0Rj2RVGZAt+Hwwa3XJIZQckx+hXh0Bd2GQ9V00CSGg8gkT28QduH8AtiXGD0ub1Cxtw6CIpOz2xPi7QPs2N2n3/RjsfcOft16mgr6E69JhRTwQ4wBB70M/eAs2DmeBu77xBwFT9JeSxxpEiNbsR7sB0jN3oKNBom98SYxohjokrFEOK/Ng1fSLo/GmwRDxWceEQS8V1whElI0aKI+I1aZTrsHu97bKepehqKem6yiegnCnkmvOPQMYqeiTtIXH296CEb/YO3iTME7iJ1M9n+V8qqinRDCzS+GyZkUivqFv0z9OO8pCDdGHKXmnaZWpio+wpi60D/d8FIEHEGNkqfIUyuMrQLd81J50RS3/vyLrDitXdiFotjQO9bybd16nmL+TVQEe+XkuCiqIHYdD5vk/Vi4UMzB32vrc9S9mi48nY5bH7o87TnquaKLZKpwruj2dNj67x/XMEancZyx0aKopzbJ1nmxVrN5pmq14nnL1EefoihfXBShPk9wpdam24qDlZu6Lh7mLur183r9Itc6FHXddLxDb/3rmKnA4xknaPr+WIDMHopC+PNsfXLqjNPOUYumf0U6ttrjbWNqp5kh6lCKytZo24B7ZUiG5vQ2GVuf5+2bcXrHtRFSfgqqT0V72wAecxMVD8EUTeXL5TwDfvpEUvTVM3wxaBvRKR64HRXBothpG91MhfvPeJSKcHuxd9sIW7CjmINqGt22Eb6gANgXLcWPYdt1aepA9UZRKK/Q4BREkM1otpl+hRSIWgsgUyedugKRZ52pSrD3HwDU2HZGU+RlC9rIk259/lDMOlcZOqCWY5Sq+iGHAexROGTgaJqsvssBoSgGdDTNcy4T1EYzQBwVU6nz0wPdKbbGpoR0fno7Pwt+FoW64jeQiuk+OeaSVDHnMhF10Zud8F3RkRSt2aiHXMdObDVnT69PoZlrm7qzpzUg1s12Ll+YpeR0IFUr5i9abd2iP/M2u/9ut+r5Ym3G7a5IpWqFYrOZt2g2i4VCLXVt3BAEQRAEQRAEQRAEQRAEQRAEQRAEQRAEQRAE4Yf/AZmODCZml4YgAAAAAElFTkSuQmCC', 3)
|
||||
// this.totoalFileSize = (allSubfile.length) * 1000000
|
||||
console.log(downlinkSpeed)
|
||||
console.log(this.totoalFileSize)
|
||||
this.estimatedTime = this.totoalFileSize / (downlinkSpeed * 1024)
|
||||
if (this.totoalFileSize >= 1 * 1024 * 1024) {
|
||||
console.log('size big')
|
||||
this.estimatedTime = this.estimatedTime * 10
|
||||
}
|
||||
console.log(this.estimatedTime)
|
||||
this.loadTime = parseInt((this.estimatedTime / 1000) % 60) * 100
|
||||
console.log(this.loadTime)
|
||||
this.doProgress()
|
||||
// allSubfile.forEach(subfile => {
|
||||
// console.log(subfile)
|
||||
// this.currentlyDownloadInfo.filenameWithType = subfile
|
||||
// })
|
||||
},
|
||||
doProgress () {
|
||||
const step = this.estimatedTime / 100 * 1000
|
||||
this.interval = setInterval(() => {
|
||||
if (this.loadingPercent >= 99) {
|
||||
console.log('complete')
|
||||
clearInterval(this.interval)
|
||||
this.estimatedTime = 0
|
||||
} else {
|
||||
this.loadingPercent++
|
||||
}
|
||||
}, step)
|
||||
},
|
||||
getNetSpeed (url, times) {
|
||||
const connection = window.navigator.connection
|
||||
if (connection && connection.downlink) {
|
||||
return connection.downlink * 1024 / 8
|
||||
}
|
||||
},
|
||||
test: async function (fn) {
|
||||
return await setTimeout(async function () {
|
||||
await fn()
|
||||
}, 1000)
|
||||
},
|
||||
downloadDone: function () {
|
||||
download.getDownloadOptionsList().shift()
|
||||
this.loadingPercent = 0
|
||||
this.refresh()
|
||||
this.confirmDownload()
|
||||
},
|
||||
getControllerList: async function () {
|
||||
const update = async () => {
|
||||
this.controllerList.push({
|
||||
id: 'tommy_test',
|
||||
mac: '',
|
||||
status: 'loading',
|
||||
isScan: true,
|
||||
files: [],
|
||||
})
|
||||
}
|
||||
await update()
|
||||
},
|
||||
mqttPub: function (topic, mes) {
|
||||
this.$mqtt.publish(topic, mes)
|
||||
},
|
||||
mqttSub: function (val) {
|
||||
this.$mqtt.subscribe(val)
|
||||
},
|
||||
mqttUnSub: function (val) {
|
||||
this.$mqtt.unsubscribe(val)
|
||||
},
|
||||
pageMqttSub: function () {
|
||||
this.controllerList.forEach(controller => {
|
||||
// this.mqttSub(controller.id + '/broadcast')
|
||||
this.mqttSub(controller.id + '/file_meta_info/+')
|
||||
this.mqttSub(controller.id + '/file_segment/+')
|
||||
this.mqttSub(controller.id + '/file_segment_get/+')
|
||||
})
|
||||
},
|
||||
pageMqttUnSub: function () {
|
||||
this.controllerList.forEach(controller => {
|
||||
// this.mqttUnSub(controller.id + '/broadcast')
|
||||
this.mqttUnSub(controller.id + '/file_meta_info/+')
|
||||
this.mqttUnSub(controller.id + '/file_segment/+')
|
||||
this.mqttUnSub(controller.id + '/file_segment_get/+')
|
||||
})
|
||||
},
|
||||
},
|
||||
// watch: {
|
||||
// loadingPercent(val) {
|
||||
// if (val >= 100) {
|
||||
// console.log('complete');
|
||||
// clearInterval(this.interval)
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
async mounted () {
|
||||
await this.getControllerList()
|
||||
this.pageMqttSub()
|
||||
},
|
||||
destroyed () {
|
||||
this.pageMqttUnSub()
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.filter-button {
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
@@ -1,159 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import api from '@/data/api/index'
|
||||
import types from '@/store/modules/file/elite/csv/types'
|
||||
import { mapActions, mapGetters, mapMutations } from 'vuex'
|
||||
// import { FulfillingBouncingCircleSpinner } from 'epic-spinners'
|
||||
|
||||
export default {
|
||||
name: 'Download',
|
||||
components: {
|
||||
// FulfillingBouncingCircleSpinner,
|
||||
},
|
||||
data: () => {
|
||||
return {
|
||||
controllerList: [],
|
||||
spliceDataNumsLimit: 20,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
getByIndex (index) {
|
||||
return this.getByIndexDownload(index)
|
||||
},
|
||||
getDownloading () {
|
||||
return this.getDownloadingDownload()
|
||||
},
|
||||
getRemainIDLength (index) {
|
||||
return this.getRemainIDLengthDownload(index)
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
getControllerList: async function () {
|
||||
const update = async () => {
|
||||
this.controllerList.push({
|
||||
id: 'tommy_test',
|
||||
mac: '',
|
||||
status: 'loading',
|
||||
isScan: true,
|
||||
files: [],
|
||||
})
|
||||
}
|
||||
await update()
|
||||
},
|
||||
mqttPub: function (topic, mes) {
|
||||
this.$mqtt.publish(topic, mes)
|
||||
},
|
||||
mqttSub: function (val) {
|
||||
this.$mqtt.subscribe(val)
|
||||
},
|
||||
mqttUnSub: function (val) {
|
||||
this.$mqtt.unsubscribe(val)
|
||||
},
|
||||
pageMqttSub: function () {
|
||||
this.controllerList.forEach(controller => {
|
||||
// this.mqttSub(controller.id + '/broadcast')
|
||||
this.mqttSub(controller.id + '/file_meta_info/+')
|
||||
this.mqttSub(controller.id + '/file_segment/+')
|
||||
this.mqttSub(controller.id + '/file_segment_get/+')
|
||||
})
|
||||
},
|
||||
pageMqttUnSub: function () {
|
||||
this.controllerList.forEach(controller => {
|
||||
// this.mqttUnSub(controller.id + '/broadcast')
|
||||
this.mqttUnSub(controller.id + '/file_meta_info/+')
|
||||
this.mqttUnSub(controller.id + '/file_segment/+')
|
||||
this.mqttUnSub(controller.id + '/file_segment_get/+')
|
||||
})
|
||||
},
|
||||
notify (name) {
|
||||
this.showToast(`done ${name}`, {
|
||||
position: 'bottom-right',
|
||||
})
|
||||
},
|
||||
...mapActions('eliteCsv',
|
||||
[
|
||||
types.download.init,
|
||||
types.download.rawDataByIDs,
|
||||
types.export.createHeadersString,
|
||||
types.export.createTitlesString,
|
||||
types.export.createDataString,
|
||||
types.export.closeFileStream,
|
||||
],
|
||||
),
|
||||
...mapMutations('eliteCsv',
|
||||
[
|
||||
types.download.setDownloading,
|
||||
types.download.removeDownloadBuffer,
|
||||
],
|
||||
),
|
||||
...mapGetters('eliteCsv',
|
||||
[
|
||||
types.download.getByIndex,
|
||||
types.download.getDownloading,
|
||||
types.download.getAll,
|
||||
types.download.getRemainIDLength,
|
||||
],
|
||||
),
|
||||
},
|
||||
watch: {
|
||||
},
|
||||
async mounted () {
|
||||
await this.getControllerList()
|
||||
// TODO authorization
|
||||
this.pageMqttSub()
|
||||
|
||||
const metaIDList = this.$route.params.metaList.split('-')
|
||||
const recoverData = this.$route.params.recover
|
||||
await this.initDownload({ metaIDList: metaIDList, api: api })
|
||||
|
||||
// let first file download in download List
|
||||
this.setDownloadingDownload()
|
||||
|
||||
const downloadingFile = this.getDownloading
|
||||
downloadingFile.recoverData = recoverData
|
||||
let spliceDataNums = 0
|
||||
// console.log('downloadingFile', downloadingFile)
|
||||
// console.log(this.getRemainIDLength(0))
|
||||
|
||||
// create headers and title
|
||||
this.createHeadersStringExport()
|
||||
this.createTitlesStringExport()
|
||||
// loop until each channel's rawID List empty
|
||||
while (this.getRemainIDLength(0)) {
|
||||
// forEach channel in raw_data
|
||||
for (const channel in downloadingFile.raw_data) {
|
||||
// get spliceDataNumsLimit numbers of ID to download once time
|
||||
if (downloadingFile.raw_data[channel].length >= this.spliceDataNumsLimit) {
|
||||
spliceDataNums = this.spliceDataNumsLimit
|
||||
} else {
|
||||
spliceDataNums = downloadingFile.raw_data[channel].length
|
||||
}
|
||||
const rawID = downloadingFile.raw_data[channel].splice(0, spliceDataNums)
|
||||
// console.log('rawID', channel, rawID)
|
||||
// download data and save into dataBuffer by rawDataIDList
|
||||
await this.rawDataByIDsDownload({
|
||||
channel: channel,
|
||||
rawDataIDList: rawID,
|
||||
api: api,
|
||||
})
|
||||
}
|
||||
// export data
|
||||
this.createDataStringExport()
|
||||
// this.removeDownloadBufferDownload()
|
||||
}
|
||||
this.closeFileStreamExport()
|
||||
},
|
||||
destroyed () {
|
||||
this.pageMqttUnSub()
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.filter-button {
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
@@ -1,207 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import api from '@/data/api/index'
|
||||
import types from '@/store/modules/file/elite/excel/types'
|
||||
import { mapActions, mapGetters, mapMutations } from 'vuex'
|
||||
// import { file } from '../../data/file/File'
|
||||
// import { download } from '../../data/download/Download'
|
||||
// import { exportData } from '../../data/export/export'
|
||||
// import { FulfillingBouncingCircleSpinner } from 'epic-spinners'
|
||||
|
||||
export default {
|
||||
name: 'Download',
|
||||
components: {
|
||||
// FulfillingBouncingCircleSpinner,
|
||||
},
|
||||
data: () => {
|
||||
return {
|
||||
controllerList: [],
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
getByIndex (index) {
|
||||
return this.getByIndexDownload(index)
|
||||
},
|
||||
getDownloading () {
|
||||
return this.getDownloadingDownload()
|
||||
},
|
||||
getRemainIDLength (index) {
|
||||
return this.getRemainIDLengthDownload(index)
|
||||
},
|
||||
// transTime (min,max) {
|
||||
// return this.getTimeInFormat(min) + ' - ' + this.getTimeInFormat(max)
|
||||
// },
|
||||
loaded () {
|
||||
return this.loadingPercent + '%'
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
transTime (timeRange) {
|
||||
return this.getTimeInFormat(timeRange[0]) + ' - ' + this.getTimeInFormat(timeRange[1])
|
||||
},
|
||||
notify (name) {
|
||||
this.showToast(`done ${name}`, {
|
||||
position: 'bottom-right',
|
||||
})
|
||||
},
|
||||
getControllerList: async function () {
|
||||
const update = async () => {
|
||||
this.controllerList.push({
|
||||
id: 'tommy_test',
|
||||
mac: '',
|
||||
status: 'loading',
|
||||
isScan: true,
|
||||
files: [],
|
||||
})
|
||||
}
|
||||
await update()
|
||||
},
|
||||
mqttPub: function (topic, mes) {
|
||||
this.$mqtt.publish(topic, mes)
|
||||
},
|
||||
mqttSub: function (val) {
|
||||
this.$mqtt.subscribe(val)
|
||||
},
|
||||
mqttUnSub: function (val) {
|
||||
this.$mqtt.unsubscribe(val)
|
||||
},
|
||||
pageMqttSub: function () {
|
||||
this.controllerList.forEach(controller => {
|
||||
// this.mqttSub(controller.id + '/broadcast')
|
||||
this.mqttSub(controller.id + '/file_meta_info/+')
|
||||
this.mqttSub(controller.id + '/file_segment/+')
|
||||
this.mqttSub(controller.id + '/file_segment_get/+')
|
||||
})
|
||||
},
|
||||
pageMqttUnSub: function () {
|
||||
this.controllerList.forEach(controller => {
|
||||
// this.mqttUnSub(controller.id + '/broadcast')
|
||||
this.mqttUnSub(controller.id + '/file_meta_info/+')
|
||||
this.mqttUnSub(controller.id + '/file_segment/+')
|
||||
this.mqttUnSub(controller.id + '/file_segment_get/+')
|
||||
})
|
||||
},
|
||||
|
||||
...mapActions('eliteExcel',
|
||||
[
|
||||
types.download.init,
|
||||
types.download.rawDataByIDs,
|
||||
types.export.createHeadersString,
|
||||
types.export.createTitlesString,
|
||||
types.export.createDataString,
|
||||
types.export.closeFileStream,
|
||||
],
|
||||
),
|
||||
...mapMutations('eliteExcel',
|
||||
[
|
||||
types.download.setDownloading,
|
||||
types.download.removeDownloadBuffer,
|
||||
],
|
||||
),
|
||||
...mapGetters('eliteExcel',
|
||||
[
|
||||
types.download.getByIndex,
|
||||
types.download.getDownloading,
|
||||
types.download.getAll,
|
||||
types.download.getRemainIDLength,
|
||||
],
|
||||
),
|
||||
},
|
||||
openPortal () {
|
||||
this.windowRef = window.open('', '', 'width=600,height=400,left=200,top=200')
|
||||
this.windowRef.document.body.appendChild(this.$el)
|
||||
// copyStyles(window.document, this.windowRef.document)
|
||||
this.windowRef.addEventListener('beforeunload', this.closePortal)
|
||||
},
|
||||
closePortal () {
|
||||
if (this.windowRef) {
|
||||
this.windowRef.close()
|
||||
this.windowRef = null
|
||||
this.$emit('close')
|
||||
}
|
||||
},
|
||||
// watch: {
|
||||
// loadingPercent(val) {
|
||||
// if (val >= 100) {
|
||||
// console.log('complete');
|
||||
// clearInterval(this.interval)
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
async mounted () {
|
||||
await this.getControllerList()
|
||||
// TODO authorization
|
||||
this.pageMqttSub()
|
||||
|
||||
const metaIDList = this.$route.params.metaList.split('-')
|
||||
await this.initDownload({ metaIDList: metaIDList, api: api })
|
||||
this.setDownloadingDownload()
|
||||
|
||||
const downloadingFile = this.getDownloading
|
||||
|
||||
console.log('downloadingFile', downloadingFile)
|
||||
console.log(this.getRemainIDLength(0))
|
||||
|
||||
// create headers and title
|
||||
this.createHeadersStringExport()
|
||||
this.createTitlesStringExport()
|
||||
|
||||
// let spliceDataNums = 0
|
||||
let rowIndex = 0
|
||||
// let columnIndex = 0
|
||||
// // while (this.getRemainIDLength(0)) {
|
||||
while (rowIndex < downloadingFile.needRows) {
|
||||
for (const channel in downloadingFile.downloadIDList) {
|
||||
const rawID = downloadingFile.downloadIDList[channel][rowIndex]
|
||||
// console.log('rawID', channel, rawID)
|
||||
if (rawID !== undefined) {
|
||||
await this.rawDataByIDsDownload({
|
||||
channel: channel,
|
||||
rawDataIDList: rawID,
|
||||
api: api,
|
||||
})
|
||||
}
|
||||
}
|
||||
this.createDataStringExport()
|
||||
this.removeDownloadBufferDownload()
|
||||
// console.log('end', downloadingFile)
|
||||
rowIndex += 1
|
||||
}
|
||||
this.closeFileStreamExport()
|
||||
// }
|
||||
// if (downloadingFile.raw_data[channel].length >= 10) {
|
||||
// spliceDataNums = 10
|
||||
// } else {
|
||||
// spliceDataNums = downloadingFile.raw_data[channel].length
|
||||
// }
|
||||
// const rawID = downloadingFile.raw_data[channel].splice(0, spliceDataNums)
|
||||
// console.log('rawID', channel, rawID)
|
||||
// await this.rawDataByIDsDownload({
|
||||
// channel: channel,
|
||||
// rawDataIDList: rawID,
|
||||
// api: api,
|
||||
// })
|
||||
// }
|
||||
// // console.log('end', downloadingFile)
|
||||
// // export data
|
||||
// this.createDataStringExport({})
|
||||
// this.removeDownloadBufferDownload()
|
||||
// }
|
||||
// const rawData = await download.getAllRawDatas(meta.data[0])
|
||||
// exportData.exportCSV(meta.data[0], rawData)
|
||||
// await this.initMeta({ metaIDList: metaIDList, api: api })
|
||||
},
|
||||
destroyed () {
|
||||
this.pageMqttUnSub()
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.filter-button {
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
@@ -1,174 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="row flex sm12 xl12 md12 xs12" style="height: 100vh;">
|
||||
<div class="flex-center spinner-box mt-4 mb-5">
|
||||
<fulfilling-bouncing-circle-spinner
|
||||
:animation-duration="3000"
|
||||
:color="'#6c7fee'"
|
||||
:size="60"
|
||||
>
|
||||
</fulfilling-bouncing-circle-spinner>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import api from '@/data/api/index'
|
||||
import types from '@/store/modules/file/neulive/csv/types'
|
||||
import { mapActions, mapGetters, mapMutations } from 'vuex'
|
||||
import { FulfillingBouncingCircleSpinner } from 'epic-spinners'
|
||||
|
||||
export default {
|
||||
name: 'Download',
|
||||
components: {
|
||||
FulfillingBouncingCircleSpinner,
|
||||
},
|
||||
data: () => {
|
||||
return {
|
||||
controllerList: [],
|
||||
spliceDataNumsLimit: 1,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
getByIndex (index) {
|
||||
return this.getByIndexDownload(index)
|
||||
},
|
||||
getDownloading () {
|
||||
return this.getDownloadingDownload()
|
||||
},
|
||||
getRemainIDLength (index) {
|
||||
return this.getRemainIDLengthDownload(index)
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
getControllerList: async function () {
|
||||
const update = async () => {
|
||||
this.controllerList.push({
|
||||
id: 'tommy_test',
|
||||
mac: '',
|
||||
status: 'loading',
|
||||
isScan: true,
|
||||
files: [],
|
||||
})
|
||||
}
|
||||
await update()
|
||||
},
|
||||
mqttPub: function (topic, mes) {
|
||||
this.$mqtt.publish(topic, mes)
|
||||
},
|
||||
mqttSub: function (val) {
|
||||
this.$mqtt.subscribe(val)
|
||||
},
|
||||
mqttUnSub: function (val) {
|
||||
this.$mqtt.unsubscribe(val)
|
||||
},
|
||||
pageMqttSub: function () {
|
||||
this.controllerList.forEach(controller => {
|
||||
// this.mqttSub(controller.id + '/broadcast')
|
||||
this.mqttSub(controller.id + '/file_meta_info/+')
|
||||
this.mqttSub(controller.id + '/file_segment/+')
|
||||
this.mqttSub(controller.id + '/file_segment_get/+')
|
||||
})
|
||||
},
|
||||
pageMqttUnSub: function () {
|
||||
this.controllerList.forEach(controller => {
|
||||
// this.mqttUnSub(controller.id + '/broadcast')
|
||||
this.mqttUnSub(controller.id + '/file_meta_info/+')
|
||||
this.mqttUnSub(controller.id + '/file_segment/+')
|
||||
this.mqttUnSub(controller.id + '/file_segment_get/+')
|
||||
})
|
||||
},
|
||||
notify (name) {
|
||||
this.showToast(`done ${name}`, {
|
||||
position: 'bottom-right',
|
||||
})
|
||||
},
|
||||
...mapActions('neuliveCsv',
|
||||
[
|
||||
types.download.init,
|
||||
types.download.rawDataByIDs,
|
||||
types.export.createHeadersString,
|
||||
types.export.createTitlesString,
|
||||
types.export.createDataString,
|
||||
types.export.closeFileStream,
|
||||
],
|
||||
),
|
||||
...mapMutations('neuliveCsv',
|
||||
[
|
||||
types.download.setDownloading,
|
||||
types.download.removeDownloadBuffer,
|
||||
],
|
||||
),
|
||||
...mapGetters('neuliveCsv',
|
||||
[
|
||||
types.download.getByIndex,
|
||||
types.download.getDownloading,
|
||||
types.download.getAll,
|
||||
types.download.getRemainIDLength,
|
||||
],
|
||||
),
|
||||
},
|
||||
watch: {
|
||||
},
|
||||
async mounted () {
|
||||
await this.getControllerList()
|
||||
// TODO authorization
|
||||
this.pageMqttSub()
|
||||
|
||||
const metaIDList = this.$route.params.metaList.split('-')
|
||||
const recoverData = this.$route.params.recover
|
||||
await this.initDownload({ metaIDList: metaIDList, api: api })
|
||||
|
||||
// let first file download in download List
|
||||
this.setDownloadingDownload()
|
||||
|
||||
const downloadingFile = this.getDownloading
|
||||
downloadingFile.recoverData = recoverData
|
||||
let spliceDataNums = 0
|
||||
// console.log('downloadingFile', downloadingFile)
|
||||
// console.log(this.getRemainIDLength(0))
|
||||
|
||||
// create headers and title
|
||||
this.createHeadersStringExport()
|
||||
this.createTitlesStringExport()
|
||||
// loop until each channel's rawID List empty
|
||||
while (this.getRemainIDLength(0)) {
|
||||
const lastPartData = ((this.getRemainIDLength(0) - this.spliceDataNumsLimit) <= 0)
|
||||
// forEach channel in raw_data
|
||||
for (const channel in downloadingFile.raw_data) {
|
||||
// get spliceDataNumsLimit numbers of ID to download once time
|
||||
if (downloadingFile.raw_data[channel].length >= this.spliceDataNumsLimit) {
|
||||
spliceDataNums = this.spliceDataNumsLimit
|
||||
} else {
|
||||
spliceDataNums = downloadingFile.raw_data[channel].length
|
||||
}
|
||||
const rawID = downloadingFile.raw_data[channel].splice(0, spliceDataNums)
|
||||
// console.log('rawID', channel, rawID)
|
||||
// download data and save into dataBuffer by rawDataIDList
|
||||
await this.rawDataByIDsDownload({
|
||||
channel: channel,
|
||||
rawDataIDList: rawID,
|
||||
api: api,
|
||||
})
|
||||
}
|
||||
// export data
|
||||
this.createDataStringExport({ lastPartData: lastPartData })
|
||||
if (this.spliceDataNumsLimit <= 10) {
|
||||
this.spliceDataNumsLimit += 1
|
||||
}
|
||||
// console.log('removeNeuliveCSV')
|
||||
// this.removeDownloadBufferDownload()
|
||||
}
|
||||
this.closeFileStreamExport()
|
||||
},
|
||||
destroyed () {
|
||||
this.pageMqttUnSub()
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.filter-button {
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
@@ -1,207 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import api from '@/data/api/index'
|
||||
import types from '@/store/modules/file/neulive/excel/types'
|
||||
import { mapActions, mapGetters, mapMutations } from 'vuex'
|
||||
// import { file } from '../../data/file/File'
|
||||
// import { download } from '../../data/download/Download'
|
||||
// import { exportData } from '../../data/export/export'
|
||||
// import { FulfillingBouncingCircleSpinner } from 'epic-spinners'
|
||||
|
||||
export default {
|
||||
name: 'Download',
|
||||
components: {
|
||||
// FulfillingBouncingCircleSpinner,
|
||||
},
|
||||
data: () => {
|
||||
return {
|
||||
controllerList: [],
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
getByIndex (index) {
|
||||
return this.getByIndexDownload(index)
|
||||
},
|
||||
getDownloading () {
|
||||
return this.getDownloadingDownload()
|
||||
},
|
||||
getRemainIDLength (index) {
|
||||
return this.getRemainIDLengthDownload(index)
|
||||
},
|
||||
// transTime (min,max) {
|
||||
// return this.getTimeInFormat(min) + ' - ' + this.getTimeInFormat(max)
|
||||
// },
|
||||
loaded () {
|
||||
return this.loadingPercent + '%'
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
transTime (timeRange) {
|
||||
return this.getTimeInFormat(timeRange[0]) + ' - ' + this.getTimeInFormat(timeRange[1])
|
||||
},
|
||||
notify (name) {
|
||||
this.showToast(`done ${name}`, {
|
||||
position: 'bottom-right',
|
||||
})
|
||||
},
|
||||
getControllerList: async function () {
|
||||
const update = async () => {
|
||||
this.controllerList.push({
|
||||
id: 'tommy_test',
|
||||
mac: '',
|
||||
status: 'loading',
|
||||
isScan: true,
|
||||
files: [],
|
||||
})
|
||||
}
|
||||
await update()
|
||||
},
|
||||
mqttPub: function (topic, mes) {
|
||||
this.$mqtt.publish(topic, mes)
|
||||
},
|
||||
mqttSub: function (val) {
|
||||
this.$mqtt.subscribe(val)
|
||||
},
|
||||
mqttUnSub: function (val) {
|
||||
this.$mqtt.unsubscribe(val)
|
||||
},
|
||||
pageMqttSub: function () {
|
||||
this.controllerList.forEach(controller => {
|
||||
// this.mqttSub(controller.id + '/broadcast')
|
||||
this.mqttSub(controller.id + '/file_meta_info/+')
|
||||
this.mqttSub(controller.id + '/file_segment/+')
|
||||
this.mqttSub(controller.id + '/file_segment_get/+')
|
||||
})
|
||||
},
|
||||
pageMqttUnSub: function () {
|
||||
this.controllerList.forEach(controller => {
|
||||
// this.mqttUnSub(controller.id + '/broadcast')
|
||||
this.mqttUnSub(controller.id + '/file_meta_info/+')
|
||||
this.mqttUnSub(controller.id + '/file_segment/+')
|
||||
this.mqttUnSub(controller.id + '/file_segment_get/+')
|
||||
})
|
||||
},
|
||||
|
||||
...mapActions('neuliveExcel',
|
||||
[
|
||||
types.download.init,
|
||||
types.download.rawDataByIDs,
|
||||
types.export.createHeadersString,
|
||||
types.export.createTitlesString,
|
||||
types.export.createDataString,
|
||||
types.export.closeFileStream,
|
||||
],
|
||||
),
|
||||
...mapMutations('neuliveExcel',
|
||||
[
|
||||
types.download.setDownloading,
|
||||
types.download.removeDownloadBuffer,
|
||||
],
|
||||
),
|
||||
...mapGetters('neuliveExcel',
|
||||
[
|
||||
types.download.getByIndex,
|
||||
types.download.getDownloading,
|
||||
types.download.getAll,
|
||||
types.download.getRemainIDLength,
|
||||
],
|
||||
),
|
||||
},
|
||||
openPortal () {
|
||||
this.windowRef = window.open('', '', 'width=600,height=400,left=200,top=200')
|
||||
this.windowRef.document.body.appendChild(this.$el)
|
||||
// copyStyles(window.document, this.windowRef.document)
|
||||
this.windowRef.addEventListener('beforeunload', this.closePortal)
|
||||
},
|
||||
closePortal () {
|
||||
if (this.windowRef) {
|
||||
this.windowRef.close()
|
||||
this.windowRef = null
|
||||
this.$emit('close')
|
||||
}
|
||||
},
|
||||
// watch: {
|
||||
// loadingPercent(val) {
|
||||
// if (val >= 100) {
|
||||
// console.log('complete');
|
||||
// clearInterval(this.interval)
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
async mounted () {
|
||||
await this.getControllerList()
|
||||
// TODO authorization
|
||||
this.pageMqttSub()
|
||||
|
||||
const metaIDList = this.$route.params.metaList.split('-')
|
||||
await this.initDownload({ metaIDList: metaIDList, api: api })
|
||||
this.setDownloadingDownload()
|
||||
|
||||
const downloadingFile = this.getDownloading
|
||||
|
||||
console.log('downloadingFile', downloadingFile)
|
||||
console.log(this.getRemainIDLength(0))
|
||||
|
||||
// create headers and title
|
||||
this.createHeadersStringExport()
|
||||
this.createTitlesStringExport()
|
||||
|
||||
// let spliceDataNums = 0
|
||||
let rowIndex = 0
|
||||
// let columnIndex = 0
|
||||
// // while (this.getRemainIDLength(0)) {
|
||||
while (rowIndex < downloadingFile.needRows) {
|
||||
for (const channel in downloadingFile.downloadIDList) {
|
||||
const rawID = downloadingFile.downloadIDList[channel][rowIndex]
|
||||
// console.log('rawID', channel, rawID)
|
||||
if (rawID !== undefined) {
|
||||
await this.rawDataByIDsDownload({
|
||||
channel: channel,
|
||||
rawDataIDList: rawID,
|
||||
api: api,
|
||||
})
|
||||
}
|
||||
}
|
||||
this.createDataStringExport()
|
||||
this.removeDownloadBufferDownload()
|
||||
// console.log('end', downloadingFile)
|
||||
rowIndex += 1
|
||||
}
|
||||
this.closeFileStreamExport()
|
||||
// }
|
||||
// if (downloadingFile.raw_data[channel].length >= 10) {
|
||||
// spliceDataNums = 10
|
||||
// } else {
|
||||
// spliceDataNums = downloadingFile.raw_data[channel].length
|
||||
// }
|
||||
// const rawID = downloadingFile.raw_data[channel].splice(0, spliceDataNums)
|
||||
// console.log('rawID', channel, rawID)
|
||||
// await this.rawDataByIDsDownload({
|
||||
// channel: channel,
|
||||
// rawDataIDList: rawID,
|
||||
// api: api,
|
||||
// })
|
||||
// }
|
||||
// // console.log('end', downloadingFile)
|
||||
// // export data
|
||||
// this.createDataStringExport({})
|
||||
// this.removeDownloadBufferDownload()
|
||||
// }
|
||||
// const rawData = await download.getAllRawDatas(meta.data[0])
|
||||
// exportData.exportCSV(meta.data[0], rawData)
|
||||
// await this.initMeta({ metaIDList: metaIDList, api: api })
|
||||
},
|
||||
destroyed () {
|
||||
this.pageMqttUnSub()
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.filter-button {
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
@@ -1,13 +1,6 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="row">
|
||||
<div class="flex md12 xl12 xs12 sm12" :style="AreaStyle">
|
||||
<file-table :ref="'file_ref'" @download="addDownloadTask"/>
|
||||
</div>
|
||||
<div class="flex md12 xl12 xs12 sm12" :style="AreaStyle">
|
||||
<!-- <download :ref="'download_ref'" @download="downloadingFile"></download> -->
|
||||
</div>
|
||||
</div>
|
||||
<file-table :ref="'file_ref'"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -24,11 +17,6 @@ export default {
|
||||
data () {
|
||||
return {
|
||||
controllerList: [],
|
||||
AreaStyle: {
|
||||
height: 'auto',
|
||||
'overflow-y': 'hidden',
|
||||
'overflow-x': 'hidden',
|
||||
},
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@@ -78,7 +66,7 @@ export default {
|
||||
this.$refs.file_ref.currentInfo = initCollection.data[0]
|
||||
|
||||
const folders = await api.collection.getByParent('folder', initCollection.data[0].id)
|
||||
const files = await api.meta.getCollectionByParent('folder', initCollection.data[0].id)
|
||||
const files = await api.meta.getByParent('folder', initCollection.data[0].id)
|
||||
file.updateFileList(folders)
|
||||
file.updateFileList(files)
|
||||
|
||||
@@ -92,6 +80,7 @@ export default {
|
||||
async mounted () {
|
||||
await this.getControllerList()
|
||||
await api.auth.getJwtData()
|
||||
console.log(await api.meta.getByParentWithLimit('folder', 2, 5, 0, 'DESC'))
|
||||
this.pageMqttSub()
|
||||
this.pageInitPub()
|
||||
},
|
||||
@@ -102,5 +91,3 @@ export default {
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style lang="scss">
|
||||
</style>
|
||||
|
||||
@@ -45,19 +45,29 @@
|
||||
v-model="showModal.deleteFile"
|
||||
size="small"
|
||||
:title="'DELETE'"
|
||||
:message="`Delete File ${deleteInfo.name}.`"
|
||||
:message="`Delete File ${deleteInfo.name}?`"
|
||||
:okText=" $t('modal.confirm') "
|
||||
@ok="deleteFile()"
|
||||
>
|
||||
</va-modal>
|
||||
|
||||
<va-modal
|
||||
v-model="showModal.deleteMultiFiles"
|
||||
size="small"
|
||||
:title="'DELETE'"
|
||||
:message="'Delete select files?'"
|
||||
:okText=" $t('modal.confirm') "
|
||||
@ok="deleteMultiFiles()"
|
||||
>
|
||||
</va-modal>
|
||||
|
||||
<va-card class="flex sm12 xl12 md12 xs12">
|
||||
<template slot="header">
|
||||
<div class="flex sm12 xl12 md12 xs12" style="text-align: end;">
|
||||
<!-- <va-button class="" color="success" v-if="selected.length" @click="downloadSelected" target="_blank" small>
|
||||
DOWNLOAD
|
||||
</va-button> -->
|
||||
<va-button class="" color="danger" v-if="selected.length" @click="deleteSelected" target="_blank" small>
|
||||
<va-button class="" color="danger" v-if="selected.length" @click="deleteMultiFilesConfirm" target="_blank" small>
|
||||
DELETE
|
||||
</va-button>
|
||||
</div>
|
||||
@@ -164,7 +174,7 @@
|
||||
</template>
|
||||
<template slot="actions" slot-scope="props" >
|
||||
<va-popover :message="`download ${props.rowData.name} in csv format`" placement="top">
|
||||
<va-button flat small color="gray" icon="fa fa-download" v-if="props.rowData.type !== 'folder'" @click.stop="downloadCsv(props.rowData)"/>
|
||||
<va-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)"/>
|
||||
@@ -211,6 +221,7 @@ export default {
|
||||
showModal: {
|
||||
createFolder: false,
|
||||
deleteFile: false,
|
||||
deleteMultiFiles: false,
|
||||
editFile: false,
|
||||
},
|
||||
|
||||
@@ -327,7 +338,7 @@ export default {
|
||||
// },
|
||||
select: function (file) {
|
||||
event.stopPropagation()
|
||||
const idx = this.fileLists.findIndex(f => f.name === file.name)
|
||||
const idx = this.fileLists.findIndex(f => f.id === file.id)
|
||||
this.fileLists[idx].checked = !this.fileLists[idx].checked
|
||||
},
|
||||
search: debounce(function (term) {
|
||||
@@ -369,7 +380,7 @@ export default {
|
||||
|
||||
// call getfolder api and update
|
||||
const folders = await api.collection.getByParent('folder', info.id)
|
||||
const files = await api.meta.getCollectionByParent('folder', info.id)
|
||||
const files = await api.meta.getByParent('folder', info.id)
|
||||
file.updateFileList(folders)
|
||||
file.updateFileList(files)
|
||||
|
||||
@@ -389,7 +400,7 @@ export default {
|
||||
this.currentInfo = item
|
||||
// call getfolder api and update
|
||||
const folders = await api.collection.getByParent('folder', item.id)
|
||||
const files = await api.meta.getCollectionByParent('folder', item.id)
|
||||
const files = await api.meta.getByParent('folder', item.id)
|
||||
file.updateFileList(folders)
|
||||
file.updateFileList(files)
|
||||
|
||||
@@ -410,7 +421,7 @@ export default {
|
||||
if (initCollection.data.length === 1) {
|
||||
this.currentInfo = initCollection.data[0]
|
||||
const folders = await api.collection.getByParent('folder', initCollection.data[0].id)
|
||||
const files = await api.meta.getCollectionByParent('folder', initCollection.data[0].id)
|
||||
const files = await api.meta.getByParent('folder', initCollection.data[0].id)
|
||||
file.updateFileList(folders)
|
||||
file.updateFileList(files)
|
||||
this.fileLists = file.getFileList()
|
||||
@@ -543,20 +554,8 @@ export default {
|
||||
}
|
||||
},
|
||||
async deleteSingleFileByDeleteInfo () {
|
||||
for (const item of this.deleteInfo.rawChannelAndIDArrays) {
|
||||
const channel = item[0]
|
||||
const id = item[1]
|
||||
await api.raw.update(channel, id, { deleted: true })
|
||||
await api.raw.clearDel(channel, id)
|
||||
}
|
||||
for (const item of this.deleteInfo.miniChannelAndIDArrays) {
|
||||
const channel = item[0]
|
||||
const id = item[1]
|
||||
await api.mini.update(channel, id, { deleted: true })
|
||||
await api.mini.clearDel(channel, id)
|
||||
}
|
||||
await api.meta.update(this.deleteInfo.metaID, { deleted: true })
|
||||
await api.meta.clearDel(this.deleteInfo.metaID)
|
||||
await api.meta.clearDel()
|
||||
},
|
||||
deleteFileConfirm: function (info) {
|
||||
this.fillDeleteInfo(info)
|
||||
@@ -578,6 +577,12 @@ export default {
|
||||
position: 'bottom-right',
|
||||
})
|
||||
},
|
||||
deleteMultiFilesConfirm: function () {
|
||||
this.showModal.deleteMultiFiles = true
|
||||
},
|
||||
deleteMultiFiles: async function () {
|
||||
this.deleteSelected()
|
||||
},
|
||||
inputFieldReset: function (info) {
|
||||
info.name = ''
|
||||
info.changedName = ''
|
||||
@@ -604,7 +609,7 @@ export default {
|
||||
|
||||
// call getfolder api and update
|
||||
const folders = await api.collection.getByParent('folder', this.currentInfo.id)
|
||||
const files = await api.meta.getCollectionByParent('folder', this.currentInfo.id)
|
||||
const files = await api.meta.getByParent('folder', this.currentInfo.id)
|
||||
file.updateFileList(folders)
|
||||
file.updateFileList(files)
|
||||
|
||||
@@ -637,17 +642,17 @@ export default {
|
||||
downloadCsv: async function (meta) {
|
||||
const href = location.href.split('/')[2]
|
||||
if (meta.device.library_name.indexOf('Elite') >= 0) {
|
||||
window.open('http://' + href + '/#/admin/download/elite/csv/' + meta.id)
|
||||
window.open('http://' + href + '/#/download/csv/' + meta.id)
|
||||
} else if (meta.device.library_name.indexOf('Neulive') >= 0) {
|
||||
window.open('http://' + href + '/#/download/neulive/csv/' + meta.id)
|
||||
window.open('http://' + href + '/#/download/csv/' + meta.id)
|
||||
}
|
||||
},
|
||||
downloadExcel: async function (meta) {
|
||||
const href = location.href.split('/')[2]
|
||||
if (meta.device.library_name.indexOf('Elite') >= 0) {
|
||||
window.open('http://' + href + '/#/admin/download/elite/excel/' + meta.id, '_blank', 'width=500,height=100,left=200,top=200')
|
||||
window.open('http://' + href + '/#/download/excel/' + meta.id)
|
||||
} else if (meta.device.library_name.indexOf('Neulive') >= 0) {
|
||||
window.open('http://' + href + '/#/admin/download/neulive/csv/' + meta.id + '/true', '_blank', 'width=500,height=100,left=200,top=200')
|
||||
window.open('http://' + href + '/#/download/csv-edf/' + meta.id)
|
||||
}
|
||||
},
|
||||
replay: function (meta) {
|
||||
|
||||
@@ -1,146 +0,0 @@
|
||||
<template>
|
||||
<div class="modal">
|
||||
<va-modal
|
||||
v-model="showModal"
|
||||
size="small"
|
||||
:title=" $t('Set condition')"
|
||||
:okText=" $t('modal.confirm') "
|
||||
:cancelText=" $t('modal.cancel') "
|
||||
@ok="sendCondition"
|
||||
@cancel="cancel"
|
||||
>
|
||||
<va-input
|
||||
v-if="isTmp"
|
||||
v-model="conditionAlias"
|
||||
:label="$t('Condition name')"
|
||||
required
|
||||
/>
|
||||
<p v-if="!isTmp"> {{ 'Condition name: '.concat(conditionAlias) }} </p>
|
||||
<div
|
||||
v-for="condition in conditions"
|
||||
:key="condition.id"
|
||||
>
|
||||
<div class="flex row align--center">
|
||||
<va-input
|
||||
v-model="condition.startTime"
|
||||
:label="$t('StartTime')"
|
||||
/>
|
||||
<va-input
|
||||
v-model="condition.duration"
|
||||
:label="$t('Duration')"
|
||||
/>
|
||||
<va-icon
|
||||
name="ion ion-md-close"
|
||||
color="info"
|
||||
class="ml-2 pa-1 shrink"
|
||||
style="cursor: pointer;"
|
||||
@click.native="removeConditionButton(condition)"
|
||||
/>
|
||||
<select class="param-selection" v-model="condition.paramID">
|
||||
<option v-for="(option, key) in allParams" :key="key" :value="key" >{{ option.paramsSet.alias }}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<va-button class="mb-2" @click="addConditionButton()">
|
||||
Add new condition
|
||||
</va-button>
|
||||
</va-modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapActions, mapGetters } from 'vuex'
|
||||
import types from '@/store/modules/project/content/types'
|
||||
import { getUniqueID } from '@/data/tool'
|
||||
|
||||
export default {
|
||||
name: 'ConditionWindow',
|
||||
components: {
|
||||
},
|
||||
computed: {
|
||||
...mapGetters('projectContent', {
|
||||
allParams: types.params.getAll,
|
||||
}),
|
||||
},
|
||||
props: {
|
||||
conditionID: {
|
||||
type: String,
|
||||
},
|
||||
conditionName: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
conditionAlias: this.conditionName,
|
||||
conditions: [],
|
||||
backupConditions: [],
|
||||
showModal: false,
|
||||
isTmp: false,
|
||||
}
|
||||
},
|
||||
mqtt: {
|
||||
},
|
||||
methods: {
|
||||
...mapActions('projectContent', [types.devices.updateSetting]),
|
||||
...mapActions('projectContent', [types.params.updateTmp]),
|
||||
backupCondition () {
|
||||
this.backupConditions = JSON.parse(JSON.stringify(this.conditions)) // deep copy
|
||||
},
|
||||
restoreToBackupCondition () {
|
||||
this.conditions = JSON.parse(JSON.stringify(this.backupConditions)) // deep copy
|
||||
},
|
||||
addConditionButton () {
|
||||
const firstKey = Object.keys(this.allParams)[0]
|
||||
const id = getUniqueID()
|
||||
const condition = {
|
||||
id: id,
|
||||
startTime: 0,
|
||||
duration: 0,
|
||||
paramID: firstKey,
|
||||
}
|
||||
this.conditions.push(condition)
|
||||
},
|
||||
removeConditionButton (condition) {
|
||||
this.conditions = this.conditions.filter(conditionToFilter => conditionToFilter.id !== condition.id)
|
||||
},
|
||||
async sendCondition () {
|
||||
await this.updateSettingDevice({ conditionID: this.conditionID, alias: this.conditionAlias, conditions: this.conditions })
|
||||
this.showModal = false
|
||||
if (this.isTmp) {
|
||||
this.conditions = []
|
||||
this.conditionAlias = ''
|
||||
this.isTmp = false
|
||||
}
|
||||
this.backupCondition()
|
||||
this.$emit('updateParentView')
|
||||
},
|
||||
cancel () {
|
||||
this.showModal = false
|
||||
if (this.isTmp) {
|
||||
this.conditionAlias = ''
|
||||
this.isTmp = false
|
||||
}
|
||||
this.restoreToBackupCondition()
|
||||
},
|
||||
|
||||
pageToast: function (mes) {
|
||||
this.showToast(
|
||||
mes,
|
||||
{
|
||||
icon: 'fa-bell',
|
||||
position: 'bottom-right',
|
||||
duration: 4000,
|
||||
},
|
||||
)
|
||||
},
|
||||
},
|
||||
mounted () {
|
||||
},
|
||||
destroyed () {
|
||||
},
|
||||
watch: {
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -1,181 +0,0 @@
|
||||
<template>
|
||||
<div class="modal">
|
||||
<va-modal
|
||||
v-model="showModal"
|
||||
size="small"
|
||||
:title=" $t('Set timer and parameters')"
|
||||
:okText=" $t('modal.confirm') "
|
||||
:cancelText=" $t('modal.cancel') "
|
||||
@ok="sendMapping"
|
||||
@cancel="cancel"
|
||||
>
|
||||
Use condition template
|
||||
<select class="condition-selection" v-model="selectedTemplateID" @change="onChangeTemplate($event)">
|
||||
<option v-for="(condition, key) in allConditions" :key="key" :value="key" >{{ condition.alias }}</option>
|
||||
</select>
|
||||
<br/>
|
||||
<div
|
||||
v-for="mapping in mappings"
|
||||
:key="mapping.id"
|
||||
>
|
||||
<div class="flex row align--center">
|
||||
<va-input
|
||||
v-model="mapping.startTime"
|
||||
:label="$t('StartTime')"
|
||||
/>
|
||||
<va-input
|
||||
v-model="mapping.duration"
|
||||
:label="$t('Duration')"
|
||||
/>
|
||||
<va-icon
|
||||
name="ion ion-md-close"
|
||||
color="info"
|
||||
class="ml-2 pa-1 shrink"
|
||||
style="cursor: pointer;"
|
||||
@click.native="removeMappingButton(mapping)"
|
||||
/>
|
||||
<select class="param-selection" v-model="mapping.paramID">
|
||||
<option v-for="(option, key) in allParams" :key="key" :value="key" >{{ option.paramsSet.alias }}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<va-button class="mb-2" @click="addMappingButton()">
|
||||
Add new mapping
|
||||
</va-button>
|
||||
</va-modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapActions, mapGetters } from 'vuex'
|
||||
import types from '@/store/modules/project/content/types'
|
||||
import { getUniqueID } from '@/data/tool'
|
||||
|
||||
export default {
|
||||
name: 'DeviceAndConditionMapping',
|
||||
components: {
|
||||
},
|
||||
computed: {
|
||||
...mapGetters('projectContent', {
|
||||
allConditions: types.devices.getAllConditions,
|
||||
}),
|
||||
...mapGetters('projectContent', {
|
||||
allParams: types.params.getAll,
|
||||
}),
|
||||
},
|
||||
props: {
|
||||
taskID: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
deviceID: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
deviceName: {
|
||||
type: String,
|
||||
default: 'Neulive',
|
||||
},
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
mappings: [],
|
||||
backupMappings: [],
|
||||
showModal: false,
|
||||
selectedTemplateID: '',
|
||||
lastSelectedID: '',
|
||||
}
|
||||
},
|
||||
mqtt: {
|
||||
},
|
||||
methods: {
|
||||
...mapActions('projectContent', [types.tasks.updateMapping, types.tasks.deleteMapping]),
|
||||
...mapActions('projectContent', [types.params.updateTmp]),
|
||||
getDefaultMapping () {
|
||||
const firstKey = Object.keys(this.allParams)[0]
|
||||
const id = getUniqueID()
|
||||
const startConditionID = getUniqueID()
|
||||
const durationConditionID = getUniqueID()
|
||||
const startRecordingID = getUniqueID()
|
||||
const endRecordingID = getUniqueID()
|
||||
const startStimulationID = getUniqueID()
|
||||
const endStimulationID = getUniqueID()
|
||||
const mapping = {
|
||||
id: id,
|
||||
deviceID: this.deviceID,
|
||||
startTime: 0,
|
||||
duration: 0,
|
||||
paramID: firstKey,
|
||||
startConditionID: startConditionID,
|
||||
durationConditionID: durationConditionID,
|
||||
startRecordingID: startRecordingID,
|
||||
endRecordingID: endRecordingID,
|
||||
startStimulationID: startStimulationID,
|
||||
endStimulationID: endStimulationID,
|
||||
}
|
||||
return mapping
|
||||
},
|
||||
backupMapping () {
|
||||
this.backupMappings = JSON.parse(JSON.stringify(this.mappings)) // deep copy
|
||||
},
|
||||
restoreToBackupMapping () {
|
||||
this.mappings = JSON.parse(JSON.stringify(this.backupMappings)) // deep copy
|
||||
},
|
||||
resetMapping () {
|
||||
this.mappings = []
|
||||
},
|
||||
addMappingButton () {
|
||||
const mapping = this.getDefaultMapping()
|
||||
this.mappings.push(mapping)
|
||||
},
|
||||
async removeMappingButton (mapping) {
|
||||
await this.deleteMappingTask({ taskID: this.taskID, mapping: mapping })
|
||||
this.mappings = this.mappings.filter(mappingToFilter => mappingToFilter.id !== mapping.id)
|
||||
},
|
||||
async sendMapping () {
|
||||
await this.updateMappingTask({ taskID: this.taskID, mappingList: this.mappings })
|
||||
this.showModal = false
|
||||
this.backupMapping()
|
||||
this.lastSelectedID = this.selectedTemplateID
|
||||
},
|
||||
cancel () {
|
||||
this.showModal = false
|
||||
this.selectedTemplateID = this.lastSelectedID
|
||||
this.restoreToBackupMapping()
|
||||
},
|
||||
|
||||
onChangeTemplate (event) {
|
||||
this.resetMapping()
|
||||
const conditions = this.allConditions[this.selectedTemplateID]
|
||||
for (const [_key, _value] of Object.entries(conditions)) {
|
||||
var mapping = this.getDefaultMapping()
|
||||
if (_key !== 'alias') {
|
||||
mapping.id = _key
|
||||
for (const [_k, _v] of Object.entries(_value)) {
|
||||
mapping[_k] = _v
|
||||
}
|
||||
this.mappings.push(mapping)
|
||||
}
|
||||
}
|
||||
this.backupMapping()
|
||||
},
|
||||
|
||||
pageToast: function (mes) {
|
||||
this.showToast(
|
||||
mes,
|
||||
{
|
||||
icon: 'fa-bell',
|
||||
position: 'bottom-right',
|
||||
duration: 4000,
|
||||
},
|
||||
)
|
||||
},
|
||||
},
|
||||
mounted () {
|
||||
},
|
||||
destroyed () {
|
||||
},
|
||||
watch: {
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -1,205 +0,0 @@
|
||||
<template>
|
||||
<div class="flex" >
|
||||
<div class="row">
|
||||
<div class="flex sm12 xl12 md12 xs12">
|
||||
Record
|
||||
<div
|
||||
style='display: inline-block;'
|
||||
v-for="channel in [1, 2, 3, 4, 5, 6, 7, 8]"
|
||||
:key="channel"
|
||||
>
|
||||
<va-button
|
||||
class="mx-1 px-1"
|
||||
v-if="channelList != null && channelList.indexOf(channel) >= 0"
|
||||
@click="channelClickRemove(channel)"
|
||||
small
|
||||
>
|
||||
{{channel}}
|
||||
</va-button>
|
||||
<va-button
|
||||
class="mx-1 px-1"
|
||||
v-if="channelList == null || channelList.indexOf(channel) < 0"
|
||||
@click="channelClickAdd(channel)"
|
||||
small outline
|
||||
>
|
||||
{{channel}}
|
||||
</va-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="flex sm12 xl12 md12 xs12">
|
||||
<va-select
|
||||
:on-change="ampGainSelectChange()"
|
||||
:label="''"
|
||||
v-model="ampGainSelect"
|
||||
textBy="description"
|
||||
:options="ampGainOptions"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="flex sm12 xl12 md12 xs12">
|
||||
<div class="flex row align--center">
|
||||
<va-button slot="append" class="mr-2 pa-1 shrink" small @click="sampleRateChange(4)">
|
||||
4
|
||||
</va-button>
|
||||
<va-input
|
||||
@keyup.enter="sampleRateChange(sampleRateInput)"
|
||||
v-model="sampleRateInput"
|
||||
class="mb-0"
|
||||
style="width: 100px;"
|
||||
>
|
||||
<p slot="append" style="margin-right: 0;" small>
|
||||
Hz
|
||||
</p>
|
||||
</va-input>
|
||||
<va-button slot="append" class="ml-2 pa-1 shrink" small @click="sampleRateChange(1000)">
|
||||
1000
|
||||
</va-button>
|
||||
</div>
|
||||
<va-slider
|
||||
@mouseup.native="sampleRateChange(sampleRate)"
|
||||
@mouseleave.native="sampleRateChange(sampleRate)"
|
||||
@touchend.native="sampleRateChange(sampleRate)"
|
||||
class="flex sm12 xl12 md12 xs12"
|
||||
value-visible
|
||||
v-model="sampleRate"
|
||||
:min="4"
|
||||
:max="1000"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapActions } from 'vuex'
|
||||
import types from '@/store/modules/project/content/types'
|
||||
|
||||
export default {
|
||||
name: 'NeuliveParameterRecording',
|
||||
components: {
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
channelList: [],
|
||||
ampGainOptions: [
|
||||
{
|
||||
id: 0,
|
||||
description: '25',
|
||||
},
|
||||
{
|
||||
id: 1,
|
||||
description: '100',
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
description: '400',
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
description: '800',
|
||||
},
|
||||
],
|
||||
ampGainSelect: { id: 2, description: '400' },
|
||||
sampleRateInput: '1000',
|
||||
sampleRate: 1000,
|
||||
|
||||
tmpParam: {},
|
||||
}
|
||||
},
|
||||
mqtt: {
|
||||
},
|
||||
methods: {
|
||||
...mapActions('projectContent', [types.params.updateTmp]),
|
||||
|
||||
init () {
|
||||
this.tmpParam = { paramsSet: { recording: { RECORDING_CH: 0, AMP_GAIN: 1, ADC_CLOCK: parseInt(parseFloat(1 / parseFloat(this.sampleRate / 200)) * 1000) } } }
|
||||
},
|
||||
reset () {
|
||||
this.tmpParam = { paramsSet: { recording: {} } }
|
||||
},
|
||||
async channelClickAdd (val) {
|
||||
if (this.channelList.indexOf(val) < 0) {
|
||||
this.channelList.push(val)
|
||||
|
||||
let channelSet = ''
|
||||
for (let i = 8; i >= 1; i--) {
|
||||
if (this.channelList.indexOf(i) >= 0) {
|
||||
channelSet += '1'
|
||||
} else {
|
||||
channelSet += '0'
|
||||
}
|
||||
}
|
||||
const channelValue = parseInt(channelSet, 2)
|
||||
this.updateTmp('RECORDING_CH', channelValue)
|
||||
await this.updateTmpParam(this.tmpParam)
|
||||
}
|
||||
},
|
||||
async channelClickRemove (val) {
|
||||
if (this.channelList.indexOf(val) >= 0) {
|
||||
this.channelList.splice(this.channelList.indexOf(val), 1)
|
||||
let channelSet = ''
|
||||
for (let i = 8; i >= 1; i--) {
|
||||
if (this.channelList.indexOf(i) >= 0) {
|
||||
channelSet += '1'
|
||||
} else {
|
||||
channelSet += '0'
|
||||
}
|
||||
}
|
||||
const channelValue = parseInt(channelSet, 2)
|
||||
this.updateTmp('RECORDING_CH', channelValue)
|
||||
await this.updateTmpParam(this.tmpParam)
|
||||
}
|
||||
},
|
||||
async ampGainSelectChange () {
|
||||
if (this.ampGainSelect != null) {
|
||||
this.updateTmp('AMP_GAIN', (this.ampGainSelect.id + 3) % 4)
|
||||
await this.updateTmpParam(this.tmpParam)
|
||||
}
|
||||
},
|
||||
async sampleRateChange (val) {
|
||||
if (this.sampleRate == null) {
|
||||
return false
|
||||
}
|
||||
if (isNaN(val) || parseInt(val) > 1000 || parseInt(val) < 4) {
|
||||
this.sampleRateInput = '1000'
|
||||
this.sampleRate = 1000
|
||||
return false
|
||||
}
|
||||
if (parseInt(this.sampleRateInput) !== this.sampleRate || this.sampleRate !== parseInt(val)) {
|
||||
this.sampleRateInput = String(val)
|
||||
this.sampleRate = parseInt(val)
|
||||
}
|
||||
this.updateTmp('ADC_CLOCK', parseInt(parseFloat(1 / parseFloat(this.sampleRate / 200)) * 1000))
|
||||
await this.updateTmpParam(this.tmpParam)
|
||||
},
|
||||
updateTmp (key, value) {
|
||||
this.tmpParam.paramsSet.recording[key] = value
|
||||
},
|
||||
|
||||
pageToast: function (mes) {
|
||||
this.showToast(
|
||||
mes,
|
||||
{
|
||||
icon: 'fa-bell',
|
||||
position: 'bottom-right',
|
||||
duration: 4000,
|
||||
},
|
||||
)
|
||||
},
|
||||
},
|
||||
async created () {
|
||||
this.init()
|
||||
await this.updateTmpParam(this.tmpParam)
|
||||
},
|
||||
async destroyed () {
|
||||
this.reset()
|
||||
},
|
||||
watch: {
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -1,678 +0,0 @@
|
||||
<template>
|
||||
<div class="flex">
|
||||
<div>
|
||||
Stimulate
|
||||
<div class="mt-4">
|
||||
<div class="row sm12 xl12 md12 xs12">
|
||||
<p class="display-6">ELECTRODE</p>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="flex sm12 xl12 md12 xs12">
|
||||
<va-button-toggle
|
||||
:on-change="stimulateElectrodeSelectChange()"
|
||||
small
|
||||
outline
|
||||
v-model="stimulateElectrodeSelect"
|
||||
:options="stimulateElectrodeOptions"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-4">
|
||||
<div class="row sm12 xl12 md12 xs12">
|
||||
<p class="display-6">CHANNELS</p>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="flex sm12 xl12 md12 xs12">
|
||||
<div
|
||||
style='display: inline-block;'
|
||||
v-for="channel in [1, 2, 3, 4, 5, 6, 7, 8]"
|
||||
:key="channel"
|
||||
>
|
||||
<va-button
|
||||
class="mx-1 px-2"
|
||||
color="success"
|
||||
v-if="posChannelList.indexOf(channel) >= 0 && negChannelList.indexOf(channel) < 0"
|
||||
@click="channelClick(channel)"
|
||||
small
|
||||
>
|
||||
{{channel}}
|
||||
</va-button>
|
||||
<va-button
|
||||
class="mx-1 px-2"
|
||||
color="danger"
|
||||
v-if="posChannelList.indexOf(channel) < 0 && negChannelList.indexOf(channel) >= 0"
|
||||
@click="channelClick(channel)"
|
||||
small
|
||||
>
|
||||
{{channel}}
|
||||
</va-button>
|
||||
<va-button
|
||||
class="mx-1 px-2"
|
||||
v-if="posChannelList.indexOf(channel) < 0 && negChannelList.indexOf(channel) < 0"
|
||||
@click="channelClick(channel)"
|
||||
small outline
|
||||
>
|
||||
{{channel}}
|
||||
</va-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-4">
|
||||
<div class="row sm12 xl12 md12 xs12">
|
||||
<p class="display-6">CYCLE NUMBER</p>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="flex sm12 xl12 md12 xs12">
|
||||
<va-button-toggle
|
||||
:on-change="cycleNumberSelectChange()"
|
||||
small
|
||||
outline
|
||||
v-model="cycleNumberSelect"
|
||||
:options="cycleNumberOptions"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row" v-if="cycleNumberSelect==0">
|
||||
<div class="flex sm12 xl12 md12 xs12">
|
||||
<div class="flex row align--center">
|
||||
<va-button slot="append" class="mr-2 pa-1 shrink" small @click="cycleNumberChange(1)">
|
||||
1
|
||||
</va-button>
|
||||
<va-input
|
||||
@keyup.enter="cycleNumberChange(cycleNumberInput)"
|
||||
v-model="cycleNumberInput"
|
||||
class="mb-0"
|
||||
>
|
||||
<p slot="append" style="margin-right: 0;" small>
|
||||
Rounds
|
||||
</p>
|
||||
</va-input>
|
||||
<va-button slot="append" class="ml-2 pa-1 shrink" small @click="cycleNumberChange(256)">
|
||||
256
|
||||
</va-button>
|
||||
</div>
|
||||
<va-slider
|
||||
class="flex sm12 xl12 md12 xs12"
|
||||
@mouseup.native="cycleNumberChange(cycleNumber)"
|
||||
@mouseleave.native="cycleNumberChange(cycleNumber)"
|
||||
@touchend.native="cycleNumberChange(cycleNumber)"
|
||||
value-visible
|
||||
v-model="cycleNumber"
|
||||
:min="1"
|
||||
:max="256"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-4">
|
||||
<div class="row sm12 xl12 md12 xs12">
|
||||
<p class="display-6">AMPLITUDE (uA)</p>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="flex sm12 xl12 md12 xs12">
|
||||
<div class="flex row align--center">
|
||||
<va-button slot="append" class="mr-2 pa-1 shrink" small @click="amplitudeNumberChange(5)">
|
||||
5
|
||||
</va-button>
|
||||
<va-input
|
||||
@keyup.enter="amplitudeNumberChange(amplitudeNumberInput)"
|
||||
v-model="amplitudeNumberInput"
|
||||
class="mb-0"
|
||||
>
|
||||
<p slot="append" style="margin-right: 0;" small>
|
||||
uA
|
||||
</p>
|
||||
</va-input>
|
||||
<va-button slot="append" class="ml-2 pa-1 shrink" small @click="amplitudeNumberChange(4000)">
|
||||
4000
|
||||
</va-button>
|
||||
</div>
|
||||
<va-slider
|
||||
class="flex sm12 xl12 md12 xs12"
|
||||
@mouseup.native="amplitudeNumberChange(amplitudeNumber)"
|
||||
@mouseleave.native="amplitudeNumberChange(amplitudeNumber)"
|
||||
@touchend.native="amplitudeNumberChange(amplitudeNumber)"
|
||||
value-visible
|
||||
v-model="amplitudeNumber"
|
||||
:min="5"
|
||||
:max="4000"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-4">
|
||||
<div class="row sm12 xl12 md12 xs12">
|
||||
<p class="display-6">PATTERN</p>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="flex sm12 xl12 md12 xs12">
|
||||
<va-button-toggle
|
||||
:on-change="patternModeSelectChange()"
|
||||
small
|
||||
outline
|
||||
v-model="patternModeSelect"
|
||||
:options="patternModeOptions"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="flex sm12 xl12 md12 xs12">
|
||||
<va-button-toggle
|
||||
small
|
||||
outline
|
||||
v-model="unitSelect"
|
||||
:options="unitOptions"
|
||||
@click.native="transUnit()"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="flex sm12 xl12 md12 xs12">
|
||||
<div class="flex row align--center">
|
||||
<va-input
|
||||
v-model="frequencyNumberInput"
|
||||
class="mb-0"
|
||||
:label="'Frequency'"
|
||||
@keyup.enter="frequencyNumberChange(frequencyNumberInput)"
|
||||
>
|
||||
<p slot="append" style="margin-right: 0;" small>
|
||||
Hz
|
||||
</p>
|
||||
</va-input>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="flex sm12 xl12 md12 xs12">
|
||||
<div class="flex row align--center">
|
||||
<va-input
|
||||
v-model="periodNumberInput"
|
||||
class="mb-0"
|
||||
:label="'Period'"
|
||||
@keyup.enter="periodNumberChange(periodNumberInput)"
|
||||
>
|
||||
<p slot="append" style="margin-right: 0;" small>
|
||||
{{unitOptions[unitSelect].label}}
|
||||
</p>
|
||||
</va-input>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="flex sm12 xl12 md12 xs12">
|
||||
<div class="flex row align--center">
|
||||
<va-button slot="append" class="mr-2 pa-1 shrink" small @click="patternModeSelect?timeRangeChange(1, 0):timeRangeChange(1, 0)">
|
||||
0
|
||||
</va-button>
|
||||
<va-input
|
||||
@keyup.enter="timeRangeChange(1, t1RangeInput)"
|
||||
v-model="t1RangeInput"
|
||||
class="mb-0"
|
||||
:label="'T1 RANGE'"
|
||||
>
|
||||
<p slot="append" style="margin-right: 0;" small>
|
||||
{{unitOptions[unitSelect].label}}
|
||||
</p>
|
||||
</va-input>
|
||||
<va-button slot="append" class="ml-2 pa-1 shrink" small @click="timeRangeChange(1, 10.23)">
|
||||
10.23
|
||||
</va-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row" v-if="patternModeSelect==1">
|
||||
<div class="flex sm12 xl12 md12 xs12">
|
||||
<div class="flex row align--center">
|
||||
<va-button slot="append" class="mr-2 pa-1 shrink" small @click="timeRangeChange(2, 0)">
|
||||
0
|
||||
</va-button>
|
||||
<va-input
|
||||
@keyup.enter="timeRangeChange(2, t2RangeInput)"
|
||||
v-model="t2RangeInput"
|
||||
class="mb-0"
|
||||
:label="'T2 RANGE'"
|
||||
>
|
||||
<p slot="append" style="margin-right: 0;" small>
|
||||
{{unitOptions[unitSelect].label}}
|
||||
</p>
|
||||
</va-input>
|
||||
<va-button slot="append" class="ml-2 pa-1 shrink" small @click="timeRangeChange(2, 10.23)">
|
||||
10.23
|
||||
</va-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row" v-if="patternModeSelect==1">
|
||||
<div class="flex sm12 xl12 md12 xs12">
|
||||
<div class="flex row align--center">
|
||||
<va-button slot="append" class="mr-2 pa-1 shrink" small @click="timeRangeChange(3, 0)">
|
||||
0
|
||||
</va-button>
|
||||
<va-input
|
||||
@keyup.enter="timeRangeChange(3, t3RangeInput)"
|
||||
v-model="t3RangeInput"
|
||||
class="mb-0"
|
||||
:label="'T3 RANGE'"
|
||||
>
|
||||
<p slot="append" style="margin-right: 0;" small>
|
||||
{{unitOptions[unitSelect].label}}
|
||||
</p>
|
||||
</va-input>
|
||||
<va-button slot="append" class="ml-2 pa-1 shrink" small @click="timeRangeChange(3, 10.23)">
|
||||
10.23
|
||||
</va-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="flex sm12 xl12 md12 xs12">
|
||||
<div class="flex row align--center">
|
||||
<va-button slot="append" class="mr-2 pa-1 shrink" small @click="timeRangeChange(4, 0)">
|
||||
0
|
||||
</va-button>
|
||||
<va-input
|
||||
@keyup.enter="timeRangeChange(4, t4RangeInput)"
|
||||
v-model="t4RangeInput"
|
||||
class="mb-0"
|
||||
:label="'T4 RANGE'"
|
||||
>
|
||||
<p slot="append" style="margin-right: 0;" small>
|
||||
{{unitOptions[unitSelect].label}}
|
||||
</p>
|
||||
</va-input>
|
||||
<va-button slot="append" class="ml-2 pa-1 shrink" small @click="timeRangeChange(4, 1310.71)">
|
||||
1310.71
|
||||
</va-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapActions } from 'vuex'
|
||||
import types from '@/store/modules/project/content/types'
|
||||
|
||||
export default {
|
||||
name: 'NeuliveParameterStimulation',
|
||||
components: {
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
posChannelList: [2],
|
||||
negChannelList: [1],
|
||||
stimulateElectrodeSelect: null,
|
||||
stimulateElectrodeOptions: [
|
||||
{
|
||||
label: 'Monopolar',
|
||||
value: 0,
|
||||
},
|
||||
{
|
||||
label: 'Bipolar',
|
||||
value: 1,
|
||||
},
|
||||
],
|
||||
cycleNumberSelect: null,
|
||||
cycleNumberOptions: [
|
||||
{
|
||||
label: 'limite',
|
||||
value: 0,
|
||||
},
|
||||
{
|
||||
label: 'Unlimite',
|
||||
value: 1,
|
||||
},
|
||||
],
|
||||
cycleNumberInput: '1',
|
||||
cycleNumber: 1,
|
||||
cycleNumberArray: Array(9).fill(1),
|
||||
amplitudeNumberInput: '50',
|
||||
amplitudeNumber: 50,
|
||||
patternModeSelect: null,
|
||||
patternModeOptions: [
|
||||
{
|
||||
label: 'Monophasic',
|
||||
value: 0,
|
||||
},
|
||||
{
|
||||
label: 'Biphasic',
|
||||
value: 1,
|
||||
},
|
||||
],
|
||||
unitSelect: 1,
|
||||
unitOptions: [
|
||||
{
|
||||
label: 's',
|
||||
value: 0,
|
||||
},
|
||||
{
|
||||
label: 'ms',
|
||||
value: 1,
|
||||
},
|
||||
{
|
||||
label: 'us',
|
||||
value: 2,
|
||||
},
|
||||
],
|
||||
unitMultiply: 1000,
|
||||
// period = (t1 + t2 + t3 + t4) * 10
|
||||
frequencyNumberInput: '0',
|
||||
frequencyNumber: 0,
|
||||
periodNumberInput: '0',
|
||||
periodNumber: 0,
|
||||
t1RangeInput: '0',
|
||||
t1Range: 0,
|
||||
t1RangeArray: Array(9).fill(0),
|
||||
t2RangeInput: '0',
|
||||
t2Range: 0,
|
||||
t2RangeArray: Array(9).fill(0),
|
||||
t3RangeInput: '0',
|
||||
t3Range: 0,
|
||||
t3RangeArray: Array(9).fill(0),
|
||||
t4RangeInput: '0',
|
||||
t4Range: 0,
|
||||
t4RangeArray: Array(9).fill(0),
|
||||
|
||||
tmpParam: {},
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
},
|
||||
mqtt: {
|
||||
},
|
||||
methods: {
|
||||
...mapActions('projectContent', [types.params.updateTmp]),
|
||||
|
||||
refresh () {
|
||||
console.log('[TODO] stimulation refresh')
|
||||
},
|
||||
init () {
|
||||
this.tmpParam = { paramsSet: { stimulation: { STI_H_BRIDGE: 1, CONTINUOUS_STI: 1, STI_CYCLE_LIST: '0:9=' + this.cycleNumberArray.toString(), STI_AMPLITUDE: 0, STI_PATTERN: 1, STI_CHANNEL: 0, STI_POLARITY: 0, STI_T1: '0:9=' + String(this.t1RangeArray), STI_T2: '0:9=' + String(this.t2RangeArray), STI_T3: '0:9=' + String(this.t3RangeArray), STI_T4: '0:9=' + String(this.t4RangeArray) } } }
|
||||
},
|
||||
reset () {
|
||||
this.tmpParam = { paramsSet: { stimulation: {} } }
|
||||
},
|
||||
transUnit () {
|
||||
if (this.unitSelect === 0) {
|
||||
this.unitMultiply = 1000000
|
||||
} else if (this.unitSelect === 1) {
|
||||
this.unitMultiply = 1000
|
||||
} else {
|
||||
this.unitMultiply = 1
|
||||
}
|
||||
this.refresh()
|
||||
},
|
||||
async stimulateElectrodeSelectChange () {
|
||||
if (this.stimulateElectrodeSelect == null) {
|
||||
return false
|
||||
}
|
||||
this.updateTmp('STI_H_BRIDGE', this.stimulateElectrodeSelect)
|
||||
await this.updateTmpParam(this.tmpParam)
|
||||
},
|
||||
channelClick (val) {
|
||||
if (this.posChannelList.indexOf(val) >= 0) {
|
||||
this.posChannelList.splice(this.posChannelList.indexOf(val), 1)
|
||||
this.negChannelList.push(val)
|
||||
} else if (this.negChannelList.indexOf(val) >= 0) {
|
||||
this.negChannelList.splice(this.negChannelList.indexOf(val), 1)
|
||||
} else {
|
||||
this.posChannelList.push(val)
|
||||
}
|
||||
this.updateStiChannel()
|
||||
},
|
||||
async cycleNumberSelectChange () {
|
||||
if (this.cycleNumberSelect == null) {
|
||||
return false
|
||||
}
|
||||
this.updateTmp('CONTINUOUS_STI', this.cycleNumberSelect)
|
||||
await this.updateTmpParam(this.tmpParam)
|
||||
},
|
||||
async cycleNumberChange (val) {
|
||||
if (isNaN(val) || parseInt(val) > 256 || parseInt(val) < 1) {
|
||||
this.cycleNumberInput = '1'
|
||||
this.cycleNumber = 1
|
||||
}
|
||||
this.cycleNumberInput = String(val)
|
||||
this.cycleNumber = parseInt(val)
|
||||
|
||||
if (this.cycleNumberArray[0] !== this.cycleNumber) {
|
||||
this.cycleNumberArray.fill(this.cycleNumber, 0)
|
||||
this.updateTmp('STI_CYCLE_LIST', '0:9=' + this.cycleNumberArray.toString())
|
||||
await this.updateTmpParam(this.tmpParam)
|
||||
}
|
||||
},
|
||||
async amplitudeNumberChange (val) {
|
||||
if (this.amplitudeNumber == null) {
|
||||
return false
|
||||
}
|
||||
if (typeof (val) === 'string') {
|
||||
if (isNaN(val) || parseInt(val) > 4000 || parseInt(val) < 5) {
|
||||
this.amplitudeNumberInput = '50'
|
||||
this.amplitudeNumber = 50
|
||||
}
|
||||
if (parseInt(this.amplitudeNumberInput) !== parseInt(this.amplitudeNumber)) {
|
||||
this.amplitudeNumber = parseInt(val)
|
||||
}
|
||||
} else {
|
||||
if (isNaN(val) || parseInt(val) > 4000 || parseInt(val) < 5) {
|
||||
this.amplitudeNumberInput = '50'
|
||||
this.samplitudeNumber = 50
|
||||
}
|
||||
if (parseInt(this.amplitudeNumberInput) !== parseInt(this.amplitudeNumber) || this.amplitudeNumber !== val) {
|
||||
this.amplitudeNumberInput = String(val)
|
||||
this.amplitudeNumber = val
|
||||
}
|
||||
}
|
||||
|
||||
this.updateTmp('STI_AMPLITUDE', parseInt(this.amplitudeNumber / 5))
|
||||
await this.updateTmpParam(this.tmpParam)
|
||||
},
|
||||
async patternModeSelectChange () {
|
||||
if (this.patternModeSelect == null) {
|
||||
return false
|
||||
}
|
||||
if (this.patternModeSelect === 0) {
|
||||
this.t2Range = 0
|
||||
this.t2RangeInput = '0'
|
||||
this.t3Range = 0
|
||||
this.t3RangeInput = '0'
|
||||
this.t4Range = (this.periodNumber / 10) - this.t1Range
|
||||
this.t4RangeInput = String((this.t4Range * 10) / this.unitMultiply)
|
||||
} else {
|
||||
this.t3Range = this.t1Range
|
||||
this.t3RangeInput = this.t1RangeInput
|
||||
this.t4Range = (this.periodNumber / 10) - this.t1Range - this.t2Range - this.t3Range
|
||||
this.t4RangeInput = String((this.t4Range * 10) / this.unitMultiply)
|
||||
}
|
||||
|
||||
this.updateTmp('STI_PATTERN', this.patternModeSelect)
|
||||
await this.updateTmpParam(this.tmpParam)
|
||||
},
|
||||
frequencyNumberChange (val) {
|
||||
if (this.frequencyNumberInput == null) {
|
||||
return false
|
||||
}
|
||||
if (typeof (val) === 'string') {
|
||||
if (isNaN(val) || parseInt(val) < 1 || parseInt(val) > 10000) {
|
||||
this.frequencyNumberInput = '100'
|
||||
this.frequencyNumber = 100
|
||||
}
|
||||
if (parseInt(this.frequencyNumberInput) !== parseInt(this.frequencyNumber)) {
|
||||
this.frequencyNumber = parseInt(val)
|
||||
}
|
||||
}
|
||||
this.periodNumber = (1 / this.frequencyNumber * 1e6).toFixed(3)
|
||||
this.periodNumberInput = String(this.periodNumber / this.unitMultiply)
|
||||
|
||||
if (this.t1Range === 0 || this.t3Range === 0) {
|
||||
this.t1Range = 10
|
||||
this.t1RangeInput = String((this.t1Range * 10) / this.unitMultiply)
|
||||
this.t3Range = 10
|
||||
this.t3RangeInput = String((this.t3Range * 10) / this.unitMultiply)
|
||||
this.t4Range = (this.periodNumber / 10) - (this.t1Range + this.t2Range + this.t3Range)
|
||||
this.t4RangeInput = String((this.t4Range * 10) / this.unitMultiply)
|
||||
} else {
|
||||
this.t4Range = (this.periodNumber / 10) - (this.t1Range + this.t2Range + this.t3Range)
|
||||
this.t4RangeInput = String((this.t4Range * 10) / this.unitMultiply)
|
||||
}
|
||||
|
||||
this.updateTimeRange()
|
||||
},
|
||||
periodNumberChange (val) {
|
||||
if (this.periodNumberInput === null) {
|
||||
return false
|
||||
}
|
||||
if (typeof (val) === 'string') {
|
||||
if (isNaN(val) || parseFloat(val) < 0 || parseFloat(val / this.unitMultiply) > 1) {
|
||||
this.periodNumber = 1000
|
||||
this.periodNumberInput = String(this.periodNumber / this.unitMultiply)
|
||||
}
|
||||
if (parseInt(this.periodNumberInput) !== parseInt(this.periodNumber)) {
|
||||
this.periodNumber = parseFloat(val * this.unitMultiply)
|
||||
this.periodNumberInput = val
|
||||
}
|
||||
}
|
||||
this.frequencyNumber = parseInt(1 / (this.periodNumber * 1e-6))
|
||||
this.frequencyNumberInput = String(this.frequencyNumber)
|
||||
|
||||
if (this.t1Range === 0 || this.t3Range === 0) {
|
||||
this.t1Range = 10
|
||||
this.t1RangeInput = String((this.t1Range * 10) / this.unitMultiply)
|
||||
this.t3Range = 10
|
||||
this.t3RangeInput = String((this.t3Range * 10) / this.unitMultiply)
|
||||
this.t4Range = (this.periodNumber / 10) - (this.t1Range + this.t2Range + this.t3Range)
|
||||
this.t4RangeInput = String((this.t4Range * 10) / this.unitMultiply)
|
||||
} else {
|
||||
this.t4Range = (this.periodNumber / 10) - (this.t1Range + this.t2Range + this.t3Range)
|
||||
this.t4RangeInput = String((this.t4Range * 10) / this.unitMultiply)
|
||||
}
|
||||
|
||||
this.updateTimeRange()
|
||||
},
|
||||
timeRangeChange (stiIimeSelect, val) {
|
||||
switch (stiIimeSelect) {
|
||||
case 1:
|
||||
this.t1Range = parseInt((val * this.unitMultiply) / 10)
|
||||
this.t1RangeInput = val
|
||||
this.t3Range = parseInt((val * this.unitMultiply) / 10)
|
||||
this.t3RangeInput = val
|
||||
break
|
||||
case 2:
|
||||
this.t2Range = parseInt((val * this.unitMultiply) / 10)
|
||||
this.t2RangeInput = val
|
||||
break
|
||||
case 3:
|
||||
this.t1Range = parseInt((val * this.unitMultiply) / 10)
|
||||
this.t1RangeInput = val
|
||||
this.t3Range = parseInt((val * this.unitMultiply) / 10)
|
||||
this.t3RangeInput = val
|
||||
break
|
||||
case 4:
|
||||
this.t4Range = parseInt((val * this.unitMultiply) / 10)
|
||||
this.t4RangeInput = val
|
||||
if (this.frequencyNumber > 0) {
|
||||
this.t2Range = (this.periodNumber / 10) - this.t1Range - this.t3Range - this.t4Range
|
||||
this.t2RangeInput = String((this.t2Range * 10) / this.unitMultiply)
|
||||
}
|
||||
break
|
||||
}
|
||||
if (this.frequencyNumber > 0 && stiIimeSelect !== 4) {
|
||||
this.t4Range = (this.periodNumber / 10) - this.t1Range - this.t2Range - this.t3Range
|
||||
this.t4RangeInput = String((this.t4Range * 10) / this.unitMultiply)
|
||||
}
|
||||
|
||||
this.updateTimeRange()
|
||||
},
|
||||
async updateStiChannel () {
|
||||
// stiChannelSet (+,-), stiPolaritySet (+)
|
||||
let stiChannelSet = ''
|
||||
let stiPolaritySet = ''
|
||||
|
||||
for (let i = 8; i >= 1; i--) {
|
||||
if (this.posChannelList.indexOf(i) >= 0) {
|
||||
stiChannelSet += '1'
|
||||
stiPolaritySet += '1'
|
||||
} else if (this.negChannelList.indexOf(i) >= 0) {
|
||||
stiChannelSet += '1'
|
||||
stiPolaritySet += '0'
|
||||
} else {
|
||||
stiChannelSet += '0'
|
||||
stiPolaritySet += '0'
|
||||
}
|
||||
}
|
||||
const stiChannelValue = parseInt(stiChannelSet, 2)
|
||||
const stiPolarityValue = parseInt(stiPolaritySet, 2)
|
||||
|
||||
this.updateTmp('STI_CHANNEL', stiChannelValue)
|
||||
this.updateTmp('STI_POLARITY', stiPolarityValue)
|
||||
await this.updateTmpParam(this.tmpParam)
|
||||
},
|
||||
|
||||
async updateTimeRange () {
|
||||
if (this.t1RangeArray[0] !== this.t1Range) {
|
||||
this.t1RangeArray.fill(this.t1Range, 0)
|
||||
this.updateTmp('STI_T1', '0:9=' + String(this.t1RangeArray))
|
||||
await this.updateTmpParam(this.tmpParam)
|
||||
}
|
||||
if (this.t2RangeArray[0] !== this.t2Range) {
|
||||
this.t2RangeArray.fill(this.t2Range, 0)
|
||||
this.updateTmp('STI_T2', '0:9=' + String(this.t2RangeArray))
|
||||
await this.updateTmpParam(this.tmpParam)
|
||||
}
|
||||
if (this.t3RangeArray[0] !== this.t3Range) {
|
||||
this.t3RangeArray.fill(this.t3Range, 0)
|
||||
this.updateTmp('STI_T3', '0:9=' + String(this.t3RangeArray))
|
||||
await this.updateTmpParam(this.tmpParam)
|
||||
}
|
||||
if (this.t4RangeArray[0] !== this.t4Range) {
|
||||
this.t4RangeArray.fill(this.t4Range, 0)
|
||||
this.updateTmp('STI_T4', '0:9=' + String(this.t4RangeArray))
|
||||
await this.updateTmpParam(this.tmpParam)
|
||||
}
|
||||
},
|
||||
|
||||
updateTmp (key, value) {
|
||||
this.tmpParam.paramsSet.stimulation[key] = value
|
||||
},
|
||||
|
||||
pageToast: function (mes) {
|
||||
this.showToast(
|
||||
mes,
|
||||
{
|
||||
icon: 'fa-bell',
|
||||
position: 'bottom-right',
|
||||
duration: 4000,
|
||||
},
|
||||
)
|
||||
},
|
||||
},
|
||||
async created () {
|
||||
this.init()
|
||||
await this.updateTmpParam(this.tmpParam)
|
||||
},
|
||||
async destroyed () {
|
||||
this.reset()
|
||||
},
|
||||
watch: {
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -1,119 +0,0 @@
|
||||
<template>
|
||||
<div class="flex">
|
||||
<va-modal
|
||||
v-model="showModal"
|
||||
size="small"
|
||||
:title=" $t('Set parameters')"
|
||||
:okText=" $t('modal.confirm') "
|
||||
:cancelText=" $t('modal.cancel') "
|
||||
@ok="AddParams"
|
||||
@cancel="Cancel"
|
||||
>
|
||||
<va-input
|
||||
@input="paramAliasChange(paramAlias)"
|
||||
v-model="paramAlias"
|
||||
:label="$t('Parameter set name')"
|
||||
required
|
||||
/>
|
||||
<va-item>
|
||||
<va-item-section side>
|
||||
<va-checkbox v-model="recordingCheck" />
|
||||
</va-item-section>
|
||||
<va-item-section>
|
||||
<va-item-label>
|
||||
Recording
|
||||
</va-item-label>
|
||||
</va-item-section>
|
||||
</va-item>
|
||||
<va-item>
|
||||
<va-item-section side>
|
||||
<va-checkbox v-model="stimulationCheck" />
|
||||
</va-item-section>
|
||||
<va-item-section>
|
||||
<va-item-label>
|
||||
Stimulation
|
||||
</va-item-label>
|
||||
</va-item-section>
|
||||
</va-item>
|
||||
|
||||
<neulive-parameter-recording v-if="recordingCheck"/>
|
||||
<br/>
|
||||
<neulive-parameter-stimulation v-if="stimulationCheck"/>
|
||||
</va-modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapActions, mapGetters } from 'vuex'
|
||||
import types from '@/store/modules/project/content/types'
|
||||
import NeuliveParameterRecording from './NeuliveParameterRecording'
|
||||
import NeuliveParameterStimulation from './NeuliveParameterStimulation'
|
||||
import { getUniqueID } from '@/data/tool'
|
||||
|
||||
export default {
|
||||
name: 'NeuliveParameterWindow',
|
||||
components: {
|
||||
NeuliveParameterRecording,
|
||||
NeuliveParameterStimulation,
|
||||
},
|
||||
computed: {
|
||||
...mapGetters('projectContent', {
|
||||
tmpParam: types.params.getTmp,
|
||||
}),
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
paramAlias: '',
|
||||
showModal: false,
|
||||
recordingCheck: false,
|
||||
stimulationCheck: false,
|
||||
}
|
||||
},
|
||||
mqtt: {
|
||||
},
|
||||
methods: {
|
||||
...mapActions('projectContent', [types.params.add, types.params.delete, types.params.resetTmp, types.params.deleteTmp, types.params.updateTmp]),
|
||||
|
||||
async paramAliasChange () {
|
||||
await this.updateTmpParam({ paramsSet: { alias: this.paramAlias, desc: '' } })
|
||||
},
|
||||
|
||||
async AddParams () {
|
||||
if (typeof this.tmpParam !== 'undefined') {
|
||||
if (typeof this.tmpParam.recording !== 'undefined' || typeof this.tmpParam.stimulation !== 'undefined') {
|
||||
if (typeof this.tmpParam.alias === 'undefined') {
|
||||
await this.updateTmpParam({ paramsSet: { alias: getUniqueID() } })
|
||||
}
|
||||
await this.updateTmpParam({ paramsSet: { id: getUniqueID() } })
|
||||
if (!this.recordingCheck) {
|
||||
await this.deleteTmpParam({ key: 'recording' })
|
||||
}
|
||||
if (!this.stimulationCheck) {
|
||||
await this.deleteTmpParam({ key: 'stimulation' })
|
||||
}
|
||||
await this.addParam({ id: getUniqueID(), paramsSet: this.tmpParam })
|
||||
await this.resetTmpParam()
|
||||
this.reset()
|
||||
}
|
||||
}
|
||||
this.$emit('updateParentView')
|
||||
},
|
||||
async Cancel () {
|
||||
await this.resetTmpParam()
|
||||
this.reset()
|
||||
},
|
||||
reset () {
|
||||
this.paramAlias = ''
|
||||
this.recordingCheck = false
|
||||
this.stimulationCheck = false
|
||||
},
|
||||
printTmpParam: function () {
|
||||
console.log(this.tmpParam)
|
||||
},
|
||||
},
|
||||
mounted () {
|
||||
},
|
||||
destroyed () {
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -1,215 +0,0 @@
|
||||
<template>
|
||||
<div id="Task">
|
||||
<h3> {{ 'Task: '.concat(String(taskNum)) }} </h3>
|
||||
<br/>
|
||||
<p> {{ 'Time settings' }} </p>
|
||||
<div slot="body">
|
||||
<va-input
|
||||
v-model="maxCycle"
|
||||
:label="$t('Max cycle')"
|
||||
:readonly="TimeSettingDone"
|
||||
/>
|
||||
Start time
|
||||
<va-checkbox v-model="startImmediatelyCheck" :label="'Right Now'"/>
|
||||
<VueCtkDateTimePicker v-model="startTimeStringFormat" v-show="!startImmediatelyCheck" :no-button-now=true label='Pick date and time' :disabled="TimeSettingDone" :format="'YYYY-MM-DDTHH:mm:ss'"/>
|
||||
<br/>
|
||||
<va-input
|
||||
v-model="duration"
|
||||
:label="$t('Duration')"
|
||||
:readonly="TimeSettingDone"
|
||||
/>
|
||||
<va-button @click="SetTaskInit"> Next </va-button>
|
||||
</div>
|
||||
|
||||
<div v-if="TimeSettingDone">
|
||||
Connected Devices
|
||||
<va-button v-for="(deviceID, index) in availableDeviceIDs" :key="index" @click="toggleMappingModal(index)">
|
||||
<!-- {{ getDeviceByID(deviceID).device_name }} -->
|
||||
{{ 'Neulive' }}
|
||||
<device-and-condition-mapping :ref="'condition_mapping'" :taskID="taskID" :deviceID="deviceID" :deviceName="getDeviceByID(deviceID).device_name"/>
|
||||
</va-button>
|
||||
</div>
|
||||
|
||||
<div v-if="TimeSettingDone">
|
||||
Condition settings
|
||||
<va-button id='conditionSetting' @click="toggleConditionModal(tmpConditionID, -1)">
|
||||
+
|
||||
<condition-window :ref="'new_condition'" :conditionID="tmpConditionID" @updateParentView="updateView"/>
|
||||
</va-button>
|
||||
<br/>
|
||||
<va-button v-for="(value, key, index) in allConditions" :key="key" @click="toggleConditionModal(key, index)">
|
||||
{{ value.alias }}
|
||||
<condition-window :ref="'exist_condition'" :conditionID="key" :conditionName="value.alias"/>
|
||||
</va-button>
|
||||
</div>
|
||||
|
||||
<div v-if="TimeSettingDone">
|
||||
Parameters settings
|
||||
<va-button id='paramSetting' @click="toggleParamModal()">
|
||||
+
|
||||
<neulive-parameter-window :ref="'parameter_window'" @updateParentView="updateView"/>
|
||||
</va-button>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-for="(param, key) in allParams"
|
||||
:key="key"
|
||||
>
|
||||
<va-list-label :key="key"> {{ processed_param(param) }} </va-list-label>
|
||||
<!-- <va-icon
|
||||
name="ion ion-md-close"
|
||||
color="info"
|
||||
class="ml-2 pa-1 shrink"
|
||||
style="cursor: pointer;"
|
||||
@click.native="removeParamButton(key)"
|
||||
/> -->
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapActions, mapGetters } from 'vuex'
|
||||
import types from '@/store/modules/project/content/types'
|
||||
import NeuliveParameterWindow from './NeuliveParameterWindow'
|
||||
import ConditionWindow from './ConditionWindow'
|
||||
import DeviceAndConditionMapping from './DeviceAndConditionMapping'
|
||||
import { getUniqueID } from '@/data/tool'
|
||||
import VueCtkDateTimePicker from 'vue-ctk-date-time-picker'
|
||||
import 'vue-ctk-date-time-picker/dist/vue-ctk-date-time-picker.css'
|
||||
|
||||
export default {
|
||||
name: 'Task',
|
||||
components: {
|
||||
NeuliveParameterWindow,
|
||||
DeviceAndConditionMapping,
|
||||
ConditionWindow,
|
||||
VueCtkDateTimePicker,
|
||||
},
|
||||
computed: {
|
||||
...mapGetters('projectContent', {
|
||||
allTasks: types.tasks.getAll,
|
||||
}),
|
||||
...mapGetters('projectContent', {
|
||||
availableDeviceIDs: types.devices.getAllAvaliable,
|
||||
getDeviceByID: types.devices.getByID,
|
||||
allConditions: types.devices.getAllConditions,
|
||||
}),
|
||||
...mapGetters('projectContent', {
|
||||
allParams: types.params.getAll,
|
||||
tmpParam: types.params.getTmp,
|
||||
}),
|
||||
},
|
||||
props: {
|
||||
taskID: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
taskNum: {
|
||||
type: Number,
|
||||
},
|
||||
},
|
||||
async created () {
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
maxCycle: 1,
|
||||
startTimeStringFormat: '',
|
||||
startTime: 0,
|
||||
startImmediatelyCheck: false,
|
||||
duration: '',
|
||||
TimeSettingDone: false,
|
||||
showParamModal: false,
|
||||
tmpConditionID: null,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapActions('projectContent', [types.tasks.update, types.tasks.setInfo]),
|
||||
...mapActions('projectContent', [types.devices.add]),
|
||||
...mapActions('projectContent', [types.params.add, types.params.delete, types.params.resetTmp, types.params.deleteTmp, types.params.updateTmp]),
|
||||
|
||||
toggleMappingModal (index) {
|
||||
this.$refs.condition_mapping[index].showModal = true
|
||||
},
|
||||
toggleConditionModal (key, index) {
|
||||
if (index === -1) {
|
||||
this.tmpConditionID = getUniqueID()
|
||||
this.$refs.new_condition.showModal = true
|
||||
this.$refs.new_condition.isTmp = true
|
||||
} else {
|
||||
var oldConditions = []
|
||||
for (const [_key, _value] of Object.entries(this.allConditions[key])) {
|
||||
if (_key !== 'alias') {
|
||||
var condition = Object.assign({}, _value)
|
||||
condition.id = _key
|
||||
oldConditions.push(condition)
|
||||
}
|
||||
}
|
||||
this.$refs.exist_condition[index].conditions = oldConditions
|
||||
this.$refs.exist_condition[index].showModal = true
|
||||
}
|
||||
},
|
||||
toggleParamModal () {
|
||||
this.$refs.parameter_window.showModal = true
|
||||
},
|
||||
pageToast: function (mes) {
|
||||
this.showToast(
|
||||
mes,
|
||||
{
|
||||
icon: 'fa-bell',
|
||||
position: 'bottom-right',
|
||||
duration: 4000,
|
||||
},
|
||||
)
|
||||
},
|
||||
async SetDuration () {
|
||||
const dateTime = new Date(this.startTimeStringFormat).getTime()
|
||||
this.startTime = Math.floor(dateTime / 1000)
|
||||
if (this.isNumeric(this.startTime) && this.isNumeric(this.duration) && (this.duration > 0)) {
|
||||
this.TimeSettingDone = true
|
||||
var conditionID = getUniqueID()
|
||||
var randomID = getUniqueID()
|
||||
if (this.startImmediatelyCheck) {
|
||||
this.startTime = 0
|
||||
}
|
||||
await this.setInfoTask({ taskID: this.taskID, infos: { conditions: { [conditionID]: { time: { absolute: { equal: this.startTime } } } }, actions: { [randomID]: { desc: 'task status running', condition: [conditionID], content: { '-1': 'start' } } } } })
|
||||
conditionID = getUniqueID()
|
||||
randomID = getUniqueID()
|
||||
await this.setInfoTask({ taskID: this.taskID, infos: { conditions: { [conditionID]: { time: { relative: { equal: this.duration } } } }, actions: { [randomID]: { desc: 'task status done add cycle', condition: [conditionID], content: { '-1': 'done' } } } } })
|
||||
} else {
|
||||
this.pageToast('Please set start and end time correctly')
|
||||
}
|
||||
},
|
||||
async SetTaskInit () {
|
||||
await this.setInfoTask({ taskID: this.taskID, infos: { max_cycle: this.maxCycle } })
|
||||
await this.SetDuration()
|
||||
console.log(this.allTasks)
|
||||
},
|
||||
async removeParamButton (key) {
|
||||
if (Object.keys(this.allParams).length > 1) {
|
||||
await this.deleteParam({ id: key })
|
||||
// this.$forceUpdate()
|
||||
} else {
|
||||
this.pageToast('[Notice] need to have at least one param setting')
|
||||
}
|
||||
},
|
||||
updateView () {
|
||||
this.$forceUpdate()
|
||||
},
|
||||
processed_param (param) {
|
||||
const _param = param.paramsSet.alias.concat(': ', JSON.stringify(param.paramsSet))
|
||||
return _param
|
||||
},
|
||||
isNumeric: function (n) {
|
||||
return !isNaN(parseFloat(n)) && isFinite(n)
|
||||
},
|
||||
},
|
||||
async mounted () {
|
||||
},
|
||||
destroyed () {
|
||||
},
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
</style>
|
||||
@@ -1,101 +0,0 @@
|
||||
<template>
|
||||
<div id="ProjectContent">
|
||||
<div class="tasks">
|
||||
<va-button class="" color="primary" target="_blank" @click="AddTask()" small>
|
||||
ADD TASK
|
||||
</va-button>
|
||||
<va-card stripe='info' :title="$t('AllTasks')" class='flex md12 xl4 xs12 sm12'>
|
||||
<task v-for="(task, key, index) in allTasks" :key="key" :taskID="key" :taskNum="index+1"/>
|
||||
</va-card>
|
||||
</div>
|
||||
<va-button @click="generateJson"> Generate Json </va-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Task from './items/Task.vue'
|
||||
import { mapActions, mapGetters } from 'vuex'
|
||||
import types from '@/store/modules/project/content/types'
|
||||
import { getUniqueID, getDefaultInstruction } from '@/data/tool'
|
||||
|
||||
export default {
|
||||
name: 'ProjectContent',
|
||||
components: {
|
||||
Task,
|
||||
},
|
||||
computed: {
|
||||
...mapGetters('projectContent', {
|
||||
allTasks: types.tasks.getAll,
|
||||
}),
|
||||
...mapGetters('projectContent', {
|
||||
allDevices: types.devices.getAll,
|
||||
availableDeviceIDs: types.devices.getAllAvaliable,
|
||||
}),
|
||||
...mapGetters('projectContent', {
|
||||
allParams: types.params.getAll,
|
||||
}),
|
||||
},
|
||||
async created () {
|
||||
await this.initAll()
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
devices: [],
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapActions('projectContent', [types.tasks.init, types.tasks.add]),
|
||||
...mapActions('projectContent', [types.devices.init]),
|
||||
...mapActions('projectContent', [types.params.init]),
|
||||
|
||||
async initAll () {
|
||||
await this.initTask({ id: getUniqueID(), desc: 'task description', instructions: getDefaultInstruction() })
|
||||
await this.initDevice({ availableDevice: ['4'], deviceInfo: { 4: { battery: 0, device_name: '', device_address: [], device_version: '', library_name: '', library_version: '', serial_number: [], status: '', isSync: false, isStimulate: false, parent: '' } } })
|
||||
await this.initParam({ id: getUniqueID(), paramsSet: { alias: 'default', desc: '', recording: { ADC_CLOCK: 200, AMP_GAIN: 0, RECORDING_CH: 0 } } })
|
||||
},
|
||||
async AddTask () {
|
||||
await this.initAll()
|
||||
this.$forceUpdate()
|
||||
},
|
||||
|
||||
generateJson () {
|
||||
var _json = { project: { desc: 'project description', available_device: this.availableDeviceIDs, tasks: {} } }
|
||||
for (const [taskID, task] of Object.entries(this.allTasks)) {
|
||||
_json.project.tasks[taskID] = { desc: task.desc, devices: {}, events: {}, triggers: {}, parameter_sets: {}, instructions: {}, actions: {}, conditions: {} }
|
||||
_json.project.tasks[taskID].start = 'timestamp'
|
||||
_json.project.tasks[taskID].status = 'prepare'
|
||||
_json.project.tasks[taskID].max_cycle = 1
|
||||
_json.project.tasks[taskID].cycle = 0
|
||||
_json.project.tasks[taskID].devices = this.allDevices
|
||||
for (const [paramID, param] of Object.entries(this.allParams)) {
|
||||
_json.project.tasks[taskID].parameter_sets[paramID] = param.paramsSet
|
||||
}
|
||||
_json.project.tasks[taskID].instructions = task.instructions
|
||||
_json.project.tasks[taskID].actions = task.actions
|
||||
_json.project.tasks[taskID].conditions = task.conditions
|
||||
}
|
||||
console.log(_json)
|
||||
},
|
||||
pageToast: function (mes) {
|
||||
this.showToast(
|
||||
mes,
|
||||
{
|
||||
icon: 'fa-bell',
|
||||
position: 'bottom-right',
|
||||
duration: 4000,
|
||||
},
|
||||
)
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
},
|
||||
async mounted () {
|
||||
},
|
||||
destroyed () {
|
||||
},
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
</style>
|
||||
+9
-10
@@ -11,16 +11,16 @@
|
||||
<!-- {{ controller }} -->
|
||||
<va-item :key="controller.device_mac" class="pa-0 ma-0"
|
||||
>
|
||||
<va-item-section avatar class="ml-2 mr-2">
|
||||
<va-item-section avatar class="ml-4 mr-4">
|
||||
<img
|
||||
:src="getImageUrl()"
|
||||
:alt="'BPS-CONTROLLER'"
|
||||
width="300px"
|
||||
height="300px"
|
||||
width="200px"
|
||||
height="200px"
|
||||
contain
|
||||
/>
|
||||
</va-item-section>
|
||||
<va-item-section class="ml-4" >
|
||||
<va-item-section class="ml-5 mr-4" >
|
||||
<va-item-label style="font-size: 2rem;">
|
||||
{{ controller.wifi_name }}
|
||||
</va-item-label>
|
||||
@@ -46,7 +46,7 @@
|
||||
<script>
|
||||
import { mapActions, mapGetters, mapMutations } from 'vuex'
|
||||
import api from '@/data/api/index'
|
||||
import types from '@/store/modules/about/types'
|
||||
import types from '@/store/modules/setting/types'
|
||||
import eliteImgUrl from '@/assets/img/elite_img.png'
|
||||
|
||||
export default {
|
||||
@@ -92,9 +92,9 @@ export default {
|
||||
getImageUrl () {
|
||||
return eliteImgUrl
|
||||
},
|
||||
...mapActions('about', [types.controller.init]),
|
||||
...mapMutations('about', [types.controller.set, types.controller.updateByIndex]),
|
||||
...mapGetters('about', [types.controller.getAll]),
|
||||
...mapActions('setting', [types.controller.init]),
|
||||
...mapMutations('setting', [types.controller.set, types.controller.updateByIndex]),
|
||||
...mapGetters('setting', [types.controller.getAll]),
|
||||
},
|
||||
async mounted () {
|
||||
this.initController({ api: api })
|
||||
@@ -106,13 +106,12 @@ export default {
|
||||
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.area-style {
|
||||
.area-style-setting-controller {
|
||||
height: auto;
|
||||
overflow-y: hidden;
|
||||
overflow-x: hidden;
|
||||
|
||||
@include media-breakpoint-only(xl) {
|
||||
height: 48vh;
|
||||
overflow-y: scroll;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
<template>
|
||||
<div class="device-info">
|
||||
<div class="row flex">
|
||||
<draggable class="flex d-flex sm12 xl12 md12 xs12" v-model="devices" @start="drag=true" @end="drag=false" >
|
||||
<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 "
|
||||
v-for="(device, index) in devices" :key="device.id"
|
||||
class="flex d-flex sm12 xl3 md4 xs12 ma-0 area-style-setting-device "
|
||||
v-for="(device, index) in devicesList" :key="device.id"
|
||||
>
|
||||
<va-card
|
||||
:noPadding="true"
|
||||
@@ -21,7 +21,7 @@
|
||||
class="mr-1"
|
||||
color="#babfc2"
|
||||
style="cursor: pointer;"
|
||||
@click.native.stop="removeCheck(index, device)"
|
||||
@click.native.stop="remove(index, device)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -58,8 +58,9 @@
|
||||
</template>
|
||||
<script>
|
||||
import { mapActions, mapGetters, mapMutations } from 'vuex'
|
||||
import { mapFields } from 'vuex-map-fields'
|
||||
import api from '@/data/api/index'
|
||||
import types from '@/store/modules/about/types'
|
||||
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'
|
||||
@@ -76,6 +77,9 @@ export default {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapFields('setting', [
|
||||
'devicesList',
|
||||
]),
|
||||
devices: {
|
||||
get () {
|
||||
return this.getAllDevice()
|
||||
@@ -94,7 +98,7 @@ export default {
|
||||
timeStampToLocaleTime: function (time) {
|
||||
return this.GLOBAL.dateToStr(time)
|
||||
},
|
||||
getImageUrl (libraryName) {
|
||||
getImageUrl: function (libraryName) {
|
||||
if (libraryName !== null) {
|
||||
if (libraryName.indexOf('Neulive') >= 0) {
|
||||
return neuliveImgUrl
|
||||
@@ -104,40 +108,36 @@ export default {
|
||||
}
|
||||
return null
|
||||
},
|
||||
autoConnect (index, device) {
|
||||
autoConnect: async function (index, device) {
|
||||
device.auto_connect = !device.auto_connect
|
||||
this.updateDatabaseByIDDevice({
|
||||
id: device.id,
|
||||
request: { auto_connect: device.auto_connect },
|
||||
api: api,
|
||||
})
|
||||
this.updateByIndexDevice({ index: index, item: { auto_connect: device.auto_connect } })
|
||||
await api.device.updateByID(device.id, { auto_connect: device.auto_connect })
|
||||
},
|
||||
removeCheck (index, device) {
|
||||
/**
|
||||
* TODO remove modal
|
||||
*/
|
||||
this.removeDevice({ id: device.id, index: index, device, deviceList: this.devices, api: api })
|
||||
remove (index, device) {
|
||||
console.log('removeDevcie', index, device)
|
||||
this.removeDevice({ id: device.id, index: index, api: api })
|
||||
},
|
||||
...mapActions('about', [types.device.init, types.device.remove, types.device.reorder, types.device.updateDatabaseByID]),
|
||||
...mapMutations('about', [types.device.set, types.device.updateByIndex]),
|
||||
...mapGetters('about', [types.device.getAll]),
|
||||
...mapActions('setting', [types.device.init, types.device.remove, types.device.reorder]),
|
||||
...mapMutations('setting', [types.device.set, types.device.updateByIndex]),
|
||||
...mapGetters('setting', [types.device.getAll]),
|
||||
},
|
||||
async mounted () {
|
||||
this.initDevice({ api: api })
|
||||
const devices = await api.device.getAll()
|
||||
if (devices.status === 200) {
|
||||
this.devicesList = devices.data
|
||||
}
|
||||
},
|
||||
destroyed () {
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.area-style {
|
||||
.area-style-setting-device {
|
||||
height: auto;
|
||||
overflow-y: hidden;
|
||||
overflow-x: hidden;
|
||||
|
||||
@include media-breakpoint-only(xl) {
|
||||
height: 48vh;
|
||||
height: auto;
|
||||
overflow-y: scroll;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
@@ -21,7 +21,7 @@
|
||||
/>
|
||||
|
||||
<div class="row row-equal">
|
||||
<div v-if="showDeviceSetting" class="flex md12 xl4 xs12 sm12 area-style">
|
||||
<div v-if="showDeviceSetting" class="flex md12 xl4 xs12 sm12">
|
||||
<div class="row">
|
||||
<div class="flex sm12 xl12 md12 xs12">
|
||||
<task-devices :ref="'devices_ref'" @add="addDevice($event)" @remove="removeDevice($event)" @refreshSetting="refreshChartSetting($event)" class="pa-0" />
|
||||
@@ -33,7 +33,7 @@
|
||||
|
||||
</div>
|
||||
|
||||
<div :class="chartAreaClass" class="area-style">
|
||||
<div :class="chartAreaClass">
|
||||
<div class="row" >
|
||||
<div class="flex sm12 xl12 md12 xs12">
|
||||
<div class="flex sm12 xl12 md12 xs12" style="text-align: center;">
|
||||
@@ -130,6 +130,8 @@ export default {
|
||||
showDeviceSetting: true,
|
||||
chartAreaClass: ['flex', 'xs12', 'sm12', 'md12', 'xl8', 'pa-0'],
|
||||
|
||||
getParmDone: false,
|
||||
|
||||
deviceList: {},
|
||||
}
|
||||
},
|
||||
@@ -141,6 +143,7 @@ export default {
|
||||
async '+/get_device_info/+' (data, topic) {
|
||||
await taskInfo.deviceInfo(String.fromCharCode.apply(null, data))
|
||||
this.refreshDevicesWindow()
|
||||
this.getParmDone = true
|
||||
},
|
||||
async '+/device_parameter/+' (data, topic) {
|
||||
await taskInfo.deviceParameter(String.fromCharCode.apply(null, data))
|
||||
@@ -152,47 +155,47 @@ export default {
|
||||
},
|
||||
async '+/hardware_device/+' (data, topic) {
|
||||
await taskInfo.deviceInfo(String.fromCharCode.apply(null, data))
|
||||
console.log(this.deviceList)
|
||||
for (const d1 in taskInfo.getTaskInfo().deviceList) {
|
||||
if (taskInfo.getTaskInfo().deviceList[d1].info.device_address.length > 0) {
|
||||
const addr1 = taskInfo.getTaskInfo().deviceList[d1].info.device_address.join()
|
||||
let parameter, content
|
||||
for (const d2 in this.deviceList) {
|
||||
const addr2 = this.deviceList[d2].info.device_address.join()
|
||||
if (addr1 === addr2) {
|
||||
console.log(this.deviceList[d2].parameterSet)
|
||||
for (const p in this.deviceList[d2].parameterSet) {
|
||||
if (p !== 'STIMULATING') {
|
||||
if (parameter == null) {
|
||||
parameter = p
|
||||
} else {
|
||||
parameter = parameter + '|' + p
|
||||
}
|
||||
let c
|
||||
if (Array.isArray(this.deviceList[d2].parameterSet[p])) {
|
||||
c = '0:' + this.deviceList[d2].parameterSet[p].length + '=' + this.deviceList[d2].parameterSet[p]
|
||||
} else {
|
||||
c = this.deviceList[d2].parameterSet[p]
|
||||
}
|
||||
// console.log(this.deviceList)
|
||||
// for (const d1 in taskInfo.getTaskInfo().deviceList) {
|
||||
// if (taskInfo.getTaskInfo().deviceList[d1].info.device_address.length > 0) {
|
||||
// const addr1 = taskInfo.getTaskInfo().deviceList[d1].info.device_address.join()
|
||||
// let parameter, content
|
||||
// for (const d2 in this.deviceList) {
|
||||
// const addr2 = this.deviceList[d2].info.device_address.join()
|
||||
// if (addr1 === addr2) {
|
||||
// console.log(this.deviceList[d2].parameterSet)
|
||||
// for (const p in this.deviceList[d2].parameterSet) {
|
||||
// if (p !== 'STIMULATING') {
|
||||
// if (parameter == null) {
|
||||
// parameter = p
|
||||
// } else {
|
||||
// parameter = parameter + '|' + p
|
||||
// }
|
||||
// let c
|
||||
// if (Array.isArray(this.deviceList[d2].parameterSet[p])) {
|
||||
// c = '0:' + this.deviceList[d2].parameterSet[p].length + '=' + this.deviceList[d2].parameterSet[p]
|
||||
// } else {
|
||||
// c = this.deviceList[d2].parameterSet[p]
|
||||
// }
|
||||
|
||||
if (content == null) {
|
||||
content = c
|
||||
} else {
|
||||
content = content + '|' + c
|
||||
}
|
||||
}
|
||||
}
|
||||
console.log('****', parameter, content)
|
||||
// this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
|
||||
// header: 'device_parameter/0',
|
||||
// device: parseInt(d1),
|
||||
// parameter: parameter,
|
||||
// content: content,
|
||||
// }))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// if (content == null) {
|
||||
// content = c
|
||||
// } else {
|
||||
// content = content + '|' + c
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// console.log('****', parameter, content)
|
||||
// // this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
|
||||
// // header: 'device_parameter/0',
|
||||
// // device: parseInt(d1),
|
||||
// // parameter: parameter,
|
||||
// // content: content,
|
||||
// // }))
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
if (this.$refs.devices_ref != null) {
|
||||
await this.$refs.devices_ref.loadingDone()
|
||||
}
|
||||
@@ -200,7 +203,7 @@ export default {
|
||||
// listen datastream [ topic: controllerID/data_server/device_data_stream/deviceID/channel ]
|
||||
async '+/data_server/device_data_stream/+/+' (data, topic) {
|
||||
const topicSplit = topic.split('/')
|
||||
if (!taskInfo.getDeviceInfoByRawID(parseInt(topicSplit[3])).info.isSync) {
|
||||
if (this.getParmDone & !taskInfo.getDeviceInfoByRawID(parseInt(topicSplit[3])).info.isSync) {
|
||||
if (chartData.defaultChartGenerator(taskInfo.getDeviceIDByRaw(parseInt(topicSplit[3])), null, 'device')) {
|
||||
taskInfo.deviceStart(parseInt(topicSplit[3]))
|
||||
}
|
||||
@@ -230,6 +233,10 @@ export default {
|
||||
break
|
||||
case 'disconnected':
|
||||
taskInfo.deviceDisconnected(mes[1])
|
||||
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
|
||||
header: 'get_device_info/0',
|
||||
device: parseInt(mes[1]),
|
||||
}))
|
||||
break
|
||||
case 'connected':
|
||||
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
|
||||
@@ -243,7 +250,12 @@ export default {
|
||||
this.showShutdownModal = true
|
||||
break
|
||||
case 'start':
|
||||
taskInfo.deviceStart(parseInt(mes[1]))
|
||||
if (!taskInfo.getDeviceInfoByRawID(parseInt(parseInt(mes[1]))).info.isSync) {
|
||||
taskInfo.deviceStart(parseInt(mes[1]))
|
||||
if (chartData.defaultChartGenerator(taskInfo.getDeviceIDByRaw(parseInt(parseInt(mes[1]))), null, 'device')) {
|
||||
taskInfo.deviceStart(parseInt(parseInt(mes[1])))
|
||||
}
|
||||
}
|
||||
break
|
||||
case 'stop':
|
||||
if (mes[1] === 'all') {
|
||||
@@ -435,6 +447,12 @@ export default {
|
||||
this.chartAreaClass[4] = 'xl12'
|
||||
},
|
||||
addMappingChart: async function (deviceID) {
|
||||
// if have chart with device ID
|
||||
for (const chart in chartData.getAllChartsData()) {
|
||||
if (chartData.getAllChartsData()[chart].mappingID === deviceID) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
const chart = await this.addChart()
|
||||
await this.$nextTick(async () => {
|
||||
chartData.getAllChartsData()[chart].mappingID = deviceID
|
||||
@@ -448,10 +466,10 @@ export default {
|
||||
},
|
||||
addDevice: async function (deviceID) {
|
||||
this.mqttSub(taskInfo.getTaskInfo().controllerID + '/data_server/device_data_stream/' + taskInfo.getRawDeviceID(deviceID) + '/+')
|
||||
const chart = this.addMappingChart(deviceID)
|
||||
if (taskInfo.getDeviceInfo(deviceID).info.isSync) {
|
||||
chartData.defaultChartGenerator(deviceID, chart, 'device')
|
||||
}
|
||||
this.addMappingChart(deviceID)
|
||||
// if (taskInfo.getDeviceInfo(deviceID).info.isSync) {
|
||||
// chartData.defaultChartGenerator(deviceID, chart, 'device')
|
||||
// }
|
||||
// console.log(chartData.getAllChartsData())
|
||||
// console.log(taskInfo.getTaskInfo())
|
||||
// await api.task.update({
|
||||
@@ -592,17 +610,17 @@ export default {
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.area-style {
|
||||
height: auto;
|
||||
overflow-y: hidden;
|
||||
overflow-x: hidden;
|
||||
// .area-style {
|
||||
// height: 100%;
|
||||
// overflow-y: hidden;
|
||||
// overflow-x: hidden;
|
||||
|
||||
@include media-breakpoint-only(xl) {
|
||||
height: 88vh;
|
||||
overflow-y: scroll;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
}
|
||||
// @include media-breakpoint-only(xl) {
|
||||
// height: 94vh;
|
||||
// overflow-y: scroll;
|
||||
// overflow-x: hidden;
|
||||
// }
|
||||
// }
|
||||
|
||||
.no-dark-style-va-button {
|
||||
&:focus {
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<chart :ref="'chart_ref'" :style="'width: '+ cardwidth + '; height: ' + cardheight + ';'" :options="data" :auto-resize="true"></chart>
|
||||
</div>
|
||||
<div v-else>
|
||||
Please add the source or choose a item to mapping.
|
||||
Please add the source from device.
|
||||
</div>
|
||||
</div>
|
||||
<div v-else-if="tabValue == 1" :style="'width: '+ cardwidth + '; height: ' + cardheight + ';'" >
|
||||
@@ -59,7 +59,7 @@
|
||||
@keyup.enter="xIntervalChange(xIntervalInput)"
|
||||
@blur="xIntervalChange(xIntervalInput)"
|
||||
v-model="xIntervalInput"
|
||||
:label="'x-interval'"
|
||||
:label="'x-grid'"
|
||||
>
|
||||
<p slot="append" style="margin-right: 0;" small>
|
||||
{{data.chartXUnit}}
|
||||
@@ -70,7 +70,7 @@
|
||||
@keyup.enter="yIntervalChange(yIntervalInput)"
|
||||
@blur="yIntervalChange(yIntervalInput)"
|
||||
v-model="yIntervalInput"
|
||||
:label="'y-interval'"
|
||||
:label="'y-grid'"
|
||||
>
|
||||
<p slot="append" style="margin-right: 0;" small>
|
||||
{{data.chartYUnit}}
|
||||
@@ -84,8 +84,11 @@
|
||||
v-model="threeAxisIntervalInput"
|
||||
:label="'3axis-interval'"
|
||||
>
|
||||
<p slot="append" style="margin-right: 0;" small>
|
||||
g
|
||||
</p>
|
||||
</va-input>
|
||||
<va-button class="no-dark-style-va-button" small @click="init()">INIT</va-button>
|
||||
<!-- <va-button class="no-dark-style-va-button" small @click="init()">INIT</va-button> -->
|
||||
<va-button small color="dark" @click="remove()">REMOVE</va-button>
|
||||
</div>
|
||||
<!-- <div class="xs2 md2 xl2 sm2" style="text-align: center;" >
|
||||
@@ -143,10 +146,10 @@ export default {
|
||||
mappingOptions: taskInfo.getMappingList(),
|
||||
nameCard: chartData.getAllChartsData()[this.chartID].cardName,
|
||||
initDone: false,
|
||||
timeIntervalInput: '',
|
||||
threeAxisIntervalInput: '',
|
||||
xIntervalInput: '',
|
||||
yIntervalInput: '',
|
||||
timeIntervalInput: 'auto',
|
||||
threeAxisIntervalInput: 'auto',
|
||||
xIntervalInput: 'auto',
|
||||
yIntervalInput: 'auto',
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -164,14 +167,40 @@ export default {
|
||||
xIntervalChange: function (val) {
|
||||
chartData.getAllChartsData()[this.chartID].xAxis.forEach(x => {
|
||||
if (x.type === 'value') {
|
||||
x.interval = val * 1
|
||||
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)
|
||||
}
|
||||
})
|
||||
},
|
||||
yIntervalChange: function (val) {
|
||||
chartData.getAllChartsData()[this.chartID].yAxis.forEach(y => {
|
||||
if (parseInt(y.channel) <= 255) {
|
||||
y.interval = val * 1
|
||||
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)
|
||||
}
|
||||
})
|
||||
},
|
||||
@@ -239,6 +268,8 @@ export default {
|
||||
this.nameCard = chartData.getAllChartsData()[this.chartID].cardName
|
||||
await this.refreshMappingSelect()
|
||||
this.initDone = true
|
||||
this.timeIntervalInput = '500'
|
||||
this.timeIntervalChange('500')
|
||||
},
|
||||
destroyed () {
|
||||
clearInterval(this.resizeTimer)
|
||||
|
||||
@@ -1,75 +1,87 @@
|
||||
<template>
|
||||
<div style="height: 350px; overflow-y: scroll; overflow-x: hidden;">
|
||||
<div>
|
||||
<div class="flex row align--center">
|
||||
<div class="flex md3 xl3 xs3 sm3">
|
||||
<va-select
|
||||
small
|
||||
:label="'X SOURCE'"
|
||||
v-model="deviceSelectX"
|
||||
textBy="name"
|
||||
:options="deviceOptions"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex md3 xl3 xs3 sm3">
|
||||
<va-select
|
||||
:on-change="channelSelectXChange()"
|
||||
:label="'X CHANNEL'"
|
||||
v-model="channelSelectX"
|
||||
textBy="channel"
|
||||
:options="channelOptionsX"
|
||||
:disabled="channelSelectDisableX"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex md3 xl3 xs3 sm3">
|
||||
<va-select
|
||||
:label="'Y SOURCE'"
|
||||
v-model="deviceSelectY"
|
||||
textBy="name"
|
||||
:options="deviceOptions"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex md3 xl3 xs3 sm3">
|
||||
<va-select
|
||||
:on-change="channelSelectYChange()"
|
||||
:label="'Y CHANNEL'"
|
||||
v-model="channelSelectY"
|
||||
textBy="channel"
|
||||
:options="channelOptionsY"
|
||||
:disabled="channelSelectDisableY"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex md3 xl3 xs3 sm3">
|
||||
<va-select
|
||||
:label="'SubPlot'"
|
||||
v-model="gridSelection"
|
||||
textBy="value"
|
||||
:options="gridOptions"
|
||||
@click.enter="updateGridOptions()"
|
||||
/>
|
||||
</div>
|
||||
<va-button :disabled="sourceAddStatus" class="flex md3 xl3 xs3 sm3 pa-1" @click="addRegisterDeviceChannel(gridSelection.id)" >
|
||||
Add
|
||||
</va-button><span class="ml-2" style="color: red;">{{error}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<va-tree-root>
|
||||
<va-tree-category
|
||||
style="font-size: 20px;"
|
||||
v-for="grid in grids"
|
||||
:key="grid.index"
|
||||
:label="'GRID ' + grid.index">
|
||||
:label="'Subplot ' + grid.index">
|
||||
<va-tree-node
|
||||
v-for="series in grid.series"
|
||||
v-for="series in gridSource[grid.index]"
|
||||
:key="series.name"
|
||||
>
|
||||
<div class="flex row align--center">
|
||||
<va-badge class="mb-0" style="font-size: 14px;" color="primary">{{series.name}}</va-badge>
|
||||
<va-badge class="mb-0" style="font-size: 14px;" color="primary" outline>{{series.xAxis}}</va-badge>
|
||||
<va-badge class="mb-0" style="font-size: 14px;" color="primary" outline>{{series.yAxis}}</va-badge>
|
||||
<va-icon
|
||||
<!-- <va-icon
|
||||
name="ion ion-md-close"
|
||||
color="info"
|
||||
class="ml-2 pa-1 shrink"
|
||||
style="cursor: pointer;"
|
||||
@click.native="removeProduct(product)"
|
||||
/>
|
||||
</div>
|
||||
</va-tree-node>
|
||||
<va-tree-node>
|
||||
<div class="flex row align--center">
|
||||
<div class="flex md6 xl6 xs6 sm6">
|
||||
<va-select
|
||||
small
|
||||
:label="'X DEVICE'"
|
||||
v-model="deviceSelectX"
|
||||
textBy="name"
|
||||
:options="deviceOptions"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex md6 xl6 xs6 sm6">
|
||||
<va-select
|
||||
:on-change="channelSelectXChange()"
|
||||
:label="'X CHANNEL'"
|
||||
v-model="channelSelectX"
|
||||
textBy="channel"
|
||||
:options="channelOptionsX"
|
||||
:disabled="channelSelectDisableX"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex md6 xl6 xs6 sm6">
|
||||
<va-select
|
||||
:label="'Y DEVICE'"
|
||||
v-model="deviceSelectY"
|
||||
textBy="name"
|
||||
:options="deviceOptions"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex md6 xl6 xs6 sm6">
|
||||
<va-select
|
||||
:on-change="channelSelectYChange()"
|
||||
:label="'Y CHANNEL'"
|
||||
v-model="channelSelectY"
|
||||
textBy="channel"
|
||||
:options="channelOptionsY"
|
||||
:disabled="channelSelectDisableY"
|
||||
/>
|
||||
</div>
|
||||
<va-button :disabled="sourceAddStatus" class="flex md6 xl6 xs6 sm6 pa-1" @click="addRegisterDeviceChannel(grid.index)" >
|
||||
Add
|
||||
</va-button>
|
||||
/> -->
|
||||
</div>
|
||||
</va-tree-node>
|
||||
</va-tree-category>
|
||||
|
||||
</va-tree-root>
|
||||
<va-button @click="addGrid()">
|
||||
Add Subplot
|
||||
</va-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -93,17 +105,16 @@ export default {
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
error: '',
|
||||
gridSelection: '',
|
||||
gridOptions: [
|
||||
{
|
||||
id: 0,
|
||||
value: 0,
|
||||
},
|
||||
],
|
||||
grids: this.gridInfo,
|
||||
electronics: [
|
||||
{ id: 1, name: 'Cellphones' },
|
||||
{ id: 2, name: 'Camera Body Kits' },
|
||||
{ id: 3, name: 'External HDDs' },
|
||||
],
|
||||
products: [
|
||||
{ id: 4, name: 'Cables' },
|
||||
{ id: 5, name: 'Monitors' },
|
||||
{ id: 6, name: 'Keyboards' },
|
||||
],
|
||||
gridSource: chartData.getAllChartsData()[this.chartID].gridSource,
|
||||
channelSelectX: '',
|
||||
channelOptionsX: [],
|
||||
channelSelectY: '',
|
||||
@@ -114,6 +125,7 @@ export default {
|
||||
deviceSelectY: '',
|
||||
deviceOptions: taskInfo.getDeviceList(),
|
||||
sourceAddStatus: true,
|
||||
sourceList: [],
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
@@ -245,6 +257,15 @@ export default {
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
updateGridOptions () {
|
||||
this.gridOptions = []
|
||||
for (let i = 0; i < this.grids.length; i++) {
|
||||
this.gridOptions.push({
|
||||
id: i,
|
||||
value: String(i),
|
||||
})
|
||||
}
|
||||
},
|
||||
channelSelectYChange: function () {
|
||||
this.checkSourceAddStatus()
|
||||
},
|
||||
@@ -258,6 +279,7 @@ export default {
|
||||
this.channelOptionsY = []
|
||||
this.deviceSelectX = ''
|
||||
this.deviceSelectY = ''
|
||||
this.gridSelection = ''
|
||||
},
|
||||
addRegisterDeviceChannel: function (gridIndex) {
|
||||
let deviceNameX
|
||||
@@ -281,11 +303,46 @@ export default {
|
||||
deviceNameY = 'Time'
|
||||
}
|
||||
chartData.register(this.chartID, gridIndex, deviceNameX, deviceIDX, channelX, deviceNameY, deviceIDY, channelY, null)
|
||||
console.log(this.chartID, gridIndex, deviceNameX, deviceIDX, channelX, deviceNameY, deviceIDY, channelY, null)
|
||||
console.log(this.deviceSelectX, this.channelSelectX, this.deviceSelectY, this.channelSelectY)
|
||||
if (deviceNameX !== 'Time') {
|
||||
this.sourceList.push([this.deviceSelectX.name, deviceIDX, channelX].toString())
|
||||
}
|
||||
if (deviceNameY !== 'Time') {
|
||||
this.sourceList.push([this.deviceSelectY.name, deviceIDY, channelY].toString())
|
||||
}
|
||||
this.sourceAddStatus = true
|
||||
this.clearSelectOptions()
|
||||
},
|
||||
addGrid () {
|
||||
chartData.updateGridList(this.chartID, chartData.getAllChartsData()[this.chartID].grid.length + 1)
|
||||
this.grids = chartData.getAllChartsData()[this.chartID].grid
|
||||
this.treeKey++
|
||||
this.gridOptions = []
|
||||
for (let i = 0; i < this.grids.length; i++) {
|
||||
this.gridOptions.push({
|
||||
id: i,
|
||||
value: String(i),
|
||||
})
|
||||
}
|
||||
console.log(chartData.getAllChartsData()[this.chartID])
|
||||
},
|
||||
checkSourceAddStatus () {
|
||||
if (this.sourceList.indexOf([this.deviceSelectX.name, this.deviceSelectX.id, this.channelSelectX.id].toString()) >= 0) {
|
||||
this.error = 'some source have been registered'
|
||||
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'
|
||||
return
|
||||
}
|
||||
this.error = ''
|
||||
if (this.gridSelection.id == null) {
|
||||
this.sourceAddStatus = true
|
||||
return
|
||||
}
|
||||
if (this.channelSelectX.id != null && this.channelSelectY.id != null) {
|
||||
this.sourceAddStatus = false
|
||||
} else if (this.channelSelectX.id != null && this.deviceSelectY.id < 0) {
|
||||
@@ -305,6 +362,8 @@ export default {
|
||||
removeProduct (product) {
|
||||
this.products = this.products.filter(productToFilter => productToFilter !== product)
|
||||
},
|
||||
mounted () {
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -14,13 +14,13 @@
|
||||
<span slot="header" >
|
||||
<va-item :key="device.id" class="pa-0 ma-0"
|
||||
>
|
||||
<va-icon
|
||||
<!-- <va-icon
|
||||
name="ion ion-md-close"
|
||||
color="danger"
|
||||
class="ml-0 mr-3 pa-0 shrink"
|
||||
style="cursor: pointer;"
|
||||
@click.native.stop="removeCheck(device)"
|
||||
/>
|
||||
/> -->
|
||||
|
||||
<va-item-section avatar class="ml-0">
|
||||
<va-avatar style="border-radius: 0;">
|
||||
@@ -45,7 +45,7 @@
|
||||
<va-item-section class="ml-3">
|
||||
<va-item-label>
|
||||
<va-button @click.stop="start(device)" v-if="(device.type == 'Neulive' && !device.isSync && !device.isStimulate) || (device.type == 'Elite' && !device.isSync)" class="px-2 py-0 mr-0" color="success" small>START</va-button>
|
||||
<va-button @click.stop="stop(device)" v-if="(device.type == 'Neulive' && (device.isSync || device.isStimulate)) || (device.type == 'Elite' && device.isSync)" :disabled="device.stopping" class="px-2 py-0 mr-0" color="danger" small>STOP</va-button>
|
||||
<va-button @click.stop="stop(device)" v-if="(device.type == 'Neulive' && (device.isSync || device.isStimulate)) || (device.type == 'Elite' && device.isSync)" class="px-2 py-0 mr-0" color="danger" small>STOP</va-button>
|
||||
<va-button id="detectButton" @click.stop="detect(device)" v-if="device.type == 'Elite'" color="primary" class="px-2 py-0 mr-0" small>DETECT</va-button>
|
||||
<va-button @click.stop="record(device)" v-if="device.type == 'Neulive' && !device.isSync" color="primary" class="px-2 py-0 mr-0 no-dark-style-va-button" small>RECORD</va-button>
|
||||
<va-button @click.stop="stopRecord(device)" v-if="device.type == 'Neulive' && device.isSync" color="danger" class="px-2 py-0 mr-0 no-dark-style-va-button" small>STOP REC</va-button>
|
||||
@@ -82,7 +82,7 @@
|
||||
import EliteParameterWindow from '../parameter/EliteParameterWindow'
|
||||
import NeuliveParameterWindow from '../parameter/NeuliveParameterWindow'
|
||||
import FileControlWindow from '../meta/FileControlWindow'
|
||||
import { mapGetters } from 'vuex'
|
||||
import { mapActions } from 'vuex'
|
||||
import types from '@/store/modules/task/content/types'
|
||||
|
||||
export default {
|
||||
@@ -115,8 +115,8 @@ export default {
|
||||
remove: function () {
|
||||
this.$emit('remove', this.selectDevice)
|
||||
},
|
||||
start: function (device) {
|
||||
const checkParam = this.getIsParamSetDoneParam()(device.type)
|
||||
start: async function (device) {
|
||||
const checkParam = await this.checkIfDeviceSetDoneParam({ device: device })
|
||||
const status = checkParam.status
|
||||
const message = checkParam.message
|
||||
if (status === true) {
|
||||
@@ -131,11 +131,13 @@ export default {
|
||||
}
|
||||
},
|
||||
stop: function (device) {
|
||||
this.$emit('stop', device)
|
||||
this.pageToast('The device ' + device.name + ' has been stopped.')
|
||||
if (!device.stopping) {
|
||||
this.$emit('stop', device)
|
||||
this.pageToast('The device ' + device.name + ' has been stopped.')
|
||||
}
|
||||
},
|
||||
record: function (device) {
|
||||
const checkParam = this.getIsRecordingParamSetDoneParam()(device.type)
|
||||
record: async function (device) {
|
||||
const checkParam = await this.checkIfRecordingSetDoneParam({ device: device })
|
||||
const status = checkParam.status
|
||||
const message = checkParam.message
|
||||
if (status === true) {
|
||||
@@ -150,9 +152,10 @@ export default {
|
||||
}
|
||||
},
|
||||
stopRecord: function (device) {
|
||||
device.stopping = true
|
||||
this.$emit('stopRecord', device)
|
||||
this.pageToast('The device ' + device.name + ' has been stopped.')
|
||||
if (!device.stopping) {
|
||||
this.$emit('stopRecord', device)
|
||||
this.pageToast('The device ' + device.name + ' has been stopped.')
|
||||
}
|
||||
},
|
||||
generateChart: function (device) {
|
||||
this.$emit('generate', device)
|
||||
@@ -195,8 +198,8 @@ export default {
|
||||
this.$emit('detect', device)
|
||||
this.pageToast('The device ' + device.name + ' has been detect.')
|
||||
},
|
||||
stimulate: function (device) {
|
||||
const checkParam = this.getIsStimulationParamSetDoneParam()
|
||||
stimulate: async function (device) {
|
||||
const checkParam = await this.checkIfStimulationSetDoneParam({ device: device })
|
||||
const status = checkParam.status
|
||||
const message = checkParam.message
|
||||
if (status === true) {
|
||||
@@ -217,7 +220,7 @@ export default {
|
||||
recoverDetectButton () {
|
||||
document.getElementById('detectButton').className += ' no-dark-style-va-button'
|
||||
},
|
||||
...mapGetters('taskContent', [types.param.getIsRecordingParamSetDone, types.param.getIsStimulationParamSetDone, types.param.getIsParamSetDone]),
|
||||
...mapActions('taskContent', [types.param.checkIfRecordingSetDone, types.param.checkIfStimulationSetDone, types.param.checkIfDeviceSetDone]),
|
||||
},
|
||||
destroyed () {
|
||||
this.deviceList.length = 0
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="flex" :class="cardclass">
|
||||
<va-card>
|
||||
<va-card style="height: 88vh; overflow: auto;">
|
||||
<template slot="header">
|
||||
<va-icon name="fa fa-bluetooth-b mr-3" color="primary"/>
|
||||
<h5 class="mt-0 mb-0">DEVICES</h5>
|
||||
@@ -18,7 +18,6 @@
|
||||
<task-device-list
|
||||
:ref="'pdlist_ref'"
|
||||
:deviceList="deviceList"
|
||||
@remove="removeDevice($event)"
|
||||
@start="startDevice($event)"
|
||||
@stop="stopDevice($event)"
|
||||
@record="record($event)"
|
||||
@@ -29,7 +28,7 @@
|
||||
@detect="detectDevice($event)"
|
||||
/>
|
||||
|
||||
<div class="row flex xs12 md12 xl12 sm12 mt-2" style="text-align: center;">
|
||||
<!-- <div class="row flex xs12 md12 xl12 sm12 mt-2" style="text-align: center;">
|
||||
<div class="xs10 md10 xl10 sm10">
|
||||
<va-select
|
||||
small
|
||||
@@ -43,7 +42,7 @@
|
||||
REGISTER
|
||||
</va-button>
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
</div>
|
||||
|
||||
</va-card>
|
||||
@@ -106,11 +105,30 @@ export default {
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
this.clearDevice()
|
||||
console.log(this.deviceOptions)
|
||||
for (let i = 4; i <= 7; i++) {
|
||||
await this.addDevice(i)
|
||||
if (taskInfo.getDeviceInfoByRawID(i).info.status === 'connected') {
|
||||
const index = this.deviceList.findIndex(d => taskInfo.getRawDeviceID(d.id) === i)
|
||||
if (index < 0) {
|
||||
await this.addDevice(i)
|
||||
}
|
||||
} else {
|
||||
console.log(this.deviceList)
|
||||
const index = this.deviceList.findIndex(d => taskInfo.getRawDeviceID(d.id) === i)
|
||||
console.log(index)
|
||||
if (index > 0) {
|
||||
await this.removeDevice(this.deviceList[index])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
taskInfo.getDeviceList().length = 0
|
||||
taskInfo.getDeviceList().push({
|
||||
id: -1,
|
||||
name: 'Time',
|
||||
})
|
||||
taskInfo.getDeviceList().push(...this.deviceList)
|
||||
console.log(taskInfo.getDeviceList())
|
||||
// for (let i = this.deviceOptions.length - 1; i >= 0; i--) {
|
||||
// this.deviceSelect = this.deviceOptions[i]
|
||||
// await this.addDevice(this.deviceOptions[i].id)
|
||||
@@ -225,16 +243,18 @@ export default {
|
||||
}
|
||||
},
|
||||
stopRecord: function (device) {
|
||||
dataStreamBuffer.removeByDevice(taskInfo.getRawDeviceID(device.id))
|
||||
if (taskInfo.getDeviceInfo(device.id).info.isSync) {
|
||||
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
|
||||
header: 'device_instruction/0',
|
||||
device: taskInfo.getRawDeviceID(device.id),
|
||||
instruction: 'stop_record',
|
||||
}))
|
||||
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
|
||||
}
|
||||
device.isSync = false
|
||||
device.stopping = true
|
||||
},
|
||||
sti: function (device) {
|
||||
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
|
||||
@@ -315,6 +335,9 @@ export default {
|
||||
if (addr.length === 0) {
|
||||
return false
|
||||
}
|
||||
if (taskInfo.getTaskInfo().taskDeviceID.indexOf(selectID) > 0) {
|
||||
return false
|
||||
}
|
||||
await taskInfo.getTaskInfo().deviceAddrList.push(taskInfo.getDeviceInfoByRawID(selectID).info.device_address)
|
||||
await taskInfo.getTaskInfo().taskDeviceID.push(selectID)
|
||||
const _address = this.GLOBAL.transMac(taskInfo.getDeviceInfoByRawID(selectID).info.device_address)
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
<template>
|
||||
<div>
|
||||
<fieldset>
|
||||
<va-radio-button
|
||||
option="Auto"
|
||||
v-model="optionValue"
|
||||
label="Auto"
|
||||
/>
|
||||
<br v-if="optionValue === 'Auto'"/>
|
||||
<auto-block v-if="optionValue === 'Auto'" :ref="'AutoBlock'" :deviceID="deviceID"/>
|
||||
<va-radio-button
|
||||
option="Advanced"
|
||||
v-model="optionValue"
|
||||
label="Advanced"
|
||||
/>
|
||||
<br v-if="optionValue === 'Advanced'"/>
|
||||
<advanced-block v-if="optionValue === 'Advanced'" :ref="'AdvancedBlock'" :deviceID="deviceID"/>
|
||||
</fieldset>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import { taskInfo } from '../../../../data/task/TaskInfo'
|
||||
import AutoBlock from '../parameter/item/DPV/AutoBlock'
|
||||
import AdvancedBlock from '../parameter/item/DPV/AdvancedBlock'
|
||||
|
||||
export default {
|
||||
name: 'EliteParameterRecordingEliteDPV',
|
||||
components: {
|
||||
AutoBlock,
|
||||
AdvancedBlock,
|
||||
},
|
||||
props: {
|
||||
deviceID: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
deviceName: {
|
||||
type: String,
|
||||
default: 'Elite',
|
||||
},
|
||||
},
|
||||
created () {
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
optionValue: 'Auto',
|
||||
}
|
||||
},
|
||||
mqtt: {
|
||||
},
|
||||
methods: {
|
||||
mqttPub: function (topic, mes) {
|
||||
this.$mqtt.publish(topic, mes)
|
||||
},
|
||||
// Array[String of Parameter Nmae, Value]
|
||||
deviceParameterChange: function (e) {
|
||||
console.log('e[0],e[1]', e[0], ',', e[1])
|
||||
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
|
||||
header: 'device_parameter/0',
|
||||
device: taskInfo.getRawDeviceID(this.deviceID),
|
||||
parameter: e[0],
|
||||
content: e[1],
|
||||
}))
|
||||
},
|
||||
refresh () {
|
||||
if (this.$refs.AutoBlock != null) {
|
||||
this.$refs.AutoBlock.refresh()
|
||||
}
|
||||
if (this.$refs.AdvancedBlock != null) {
|
||||
this.$refs.AdvancedBlock.refresh()
|
||||
}
|
||||
},
|
||||
},
|
||||
mounted () {
|
||||
},
|
||||
watch: {
|
||||
},
|
||||
destroyed () {
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -10,30 +10,229 @@
|
||||
noClear
|
||||
/>
|
||||
</div>
|
||||
<d-c-volt :ref="'DCVolt'" :deviceID="deviceID" :parameterName="'DC_BIAS'" @parameterChange="deviceParameterChange($event)" />
|
||||
<a-c-amplitude :ref="'ACAmplitude'" :deviceID="deviceID" :parameterName="'AC_AMP'" @parameterChange="deviceParameterChange($event)" />
|
||||
<freq-range :ref="'FreqRange'" :deviceID="deviceID" :parameterName="'FREQ'" @parameterChange="deviceParameterChange($event)" />
|
||||
<points-per-decades :ref="'PointsPerDecades'" :deviceID="deviceID" :parameterName="'PPD'" @parameterChange="deviceParameterChange($event)" />
|
||||
<point-spacing :ref="'PointSpacing'" :deviceID="deviceID" :parameterName="'SCALE'" @parameterChange="deviceParameterChange($event)" />
|
||||
<delay :ref="'PointsPerDecades'" :deviceID="deviceID" :parameterName="'DELAY'" @parameterChange="deviceParameterChange($event)" />
|
||||
<average :ref="'Average'" :deviceID="deviceID" :parameterName="'AVERAGE_NUM'" @parameterChange="deviceParameterChange($event)" />
|
||||
<current-range :ref="'CurrentRange'" :deviceID="deviceID" :parameterName="'RTIA'" @parameterChange="deviceParameterChange($event)" />
|
||||
<!-- EIS -->
|
||||
<div v-if="workingModeSelect != null && workingModeSelect.id == 0">
|
||||
<d-c-volt :ref="'DCVolt'" :deviceID="deviceID" :parameterName="'DC_BIAS'" @parameterChange="deviceParameterChange($event)" />
|
||||
<a-c-amplitude :ref="'ACAmplitude'" :deviceID="deviceID" :parameterName="'AC_AMP'" @parameterChange="deviceParameterChange($event)" />
|
||||
<freq-range :ref="'FreqRange'" :deviceID="deviceID" :parameterName="'FREQ'" @parameterChange="deviceParameterChange($event)" />
|
||||
<points-per-decades :ref="'PointsPerDecades'" :deviceID="deviceID" :parameterName="'PPD'" @parameterChange="deviceParameterChange($event)" />
|
||||
<point-spacing :ref="'PointSpacing'" :deviceID="deviceID" :parameterName="'SCALE'" @parameterChange="deviceParameterChange($event)" />
|
||||
<delay :ref="'Delay'" :deviceID="deviceID" :parameterName="'DELAY'" @parameterChange="deviceParameterChange($event)" />
|
||||
<average :ref="'Average'" :deviceID="deviceID" :parameterName="'AVERAGE_NUM'" @parameterChange="deviceParameterChange($event)" />
|
||||
<current-range :ref="'CurrentRange'" :deviceID="deviceID" :parameterName="'RTIA'" @parameterChange="deviceParameterChange($event)" />
|
||||
</div>
|
||||
<!-- CV -->
|
||||
<div v-if="workingModeSelect != null && workingModeSelect.id == 1">
|
||||
<va-button
|
||||
color="primary"
|
||||
target="_blank"
|
||||
@click="measureEoc()"
|
||||
small>
|
||||
{{measureEocButton.start}}
|
||||
</va-button>
|
||||
<va-button
|
||||
color="danger"
|
||||
target="_blank"
|
||||
@click="measureEocStop()"
|
||||
small>
|
||||
{{measureEocButton.stop}}
|
||||
</va-button>
|
||||
<div class="flex row mt-3 pt-0 sm12 xl12 md12 xs12 align--center">
|
||||
<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-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 sm12 xl12 md12 xs12 pa-0 ma-0">
|
||||
<p class="display-6">Voltage Range<p/>
|
||||
</div>
|
||||
<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 sm12 xl12 md12 xs12 pa-0 ma-0">
|
||||
<p class="display-6">High Z<p/>
|
||||
</div>
|
||||
<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 sm12 xl12 md12 xs12 pa-0 ma-0">
|
||||
<p class="display-6">E Initial<p/>
|
||||
</div>
|
||||
<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 sm12 xl12 md12 xs12 pa-0 ma-0">
|
||||
<p class="display-6">E1<p/>
|
||||
</div>
|
||||
<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 sm12 xl12 md12 xs12 pa-0 ma-0">
|
||||
<p class="display-6">E2<p/>
|
||||
</div>
|
||||
<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 sm12 xl12 md12 xs12 pa-0 ma-0">
|
||||
<p class="display-6">Voltage Scan Rate<p/>
|
||||
</div>
|
||||
<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 sm12 xl12 md12 xs12 pa-0 ma-0">
|
||||
<p class="display-6">Resolution<p/>
|
||||
</div>
|
||||
<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 sm12 xl12 md12 xs12 pa-0 ma-0">
|
||||
<p class="display-6">Cycle<p/>
|
||||
</div>
|
||||
<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>
|
||||
</div>
|
||||
|
||||
<!-- DEV -->
|
||||
<va-tree-category
|
||||
v-if="workingModeSelect != null && workingModeSelect.id == 2"
|
||||
style="font-size: 20px;"
|
||||
:label="'RIS instruction (HEX)'">
|
||||
<div class="row">
|
||||
<div class="flex sm12 xl12 md12 xs12">
|
||||
<div class="flex row align--center">
|
||||
<va-input
|
||||
@keyup.enter="instruParameterChange([instru.parameterName, instru.write])"
|
||||
@blur="instruParameterChange([instru.parameterName, instru.write])"
|
||||
class="mb-0"
|
||||
v-model="instru.write"
|
||||
label="Write value (0x3000FF ... )"
|
||||
style="width: 100px;"
|
||||
maxlength="34"
|
||||
/>
|
||||
<va-button slot="append" class="mr-2 pa-1 shrink" style="width: 2em; height: 2em; border-radius: 50%; font-size: 20px;" small @click="sendInstr()">
|
||||
W
|
||||
</va-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="flex sm12 xl12 md12 xs12">
|
||||
<div class="flex row align--center">
|
||||
<va-input
|
||||
disabled="disabled"
|
||||
class="mb-0"
|
||||
v-model="instru.read"
|
||||
label="Read value"
|
||||
style="width: 100px; font-size: 30px;"
|
||||
/>
|
||||
<va-button slot="append" class="mr-2 pa-1 shrink" style="width: 2em; height: 2em; border-radius: 50%; font-size: 20px;" small @click="readCisData()">
|
||||
R
|
||||
</va-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="flex sm12 xl12 md12 xs12">
|
||||
<div class="flex row align--center">
|
||||
<va-input
|
||||
disabled="disabled"
|
||||
class="mb-0"
|
||||
v-model="instru.notify"
|
||||
label="Notify value"
|
||||
style="width: 100px;"
|
||||
/>
|
||||
<va-button slot="append" class="mr-2 pa-1 shrink" style="width: 2em; height: 2em; border-radius: 50%; font-size: 20px;" small @click="detect()">
|
||||
N
|
||||
</va-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</va-tree-category>
|
||||
|
||||
<va-tree-category
|
||||
v-if="workingModeSelect != null && workingModeSelect.id == 2"
|
||||
style="font-size: 20px;"
|
||||
:label="'VIS & CIS instruction'">
|
||||
<va-card>
|
||||
<div class="row">
|
||||
<div class="flex sm12 xl12 md12 xs12">
|
||||
<div class="flex row align--center">
|
||||
<va-input
|
||||
disabled="disabled"
|
||||
class="mb-0"
|
||||
v-model="instru.read"
|
||||
label="Read value"
|
||||
style="width: 100px; font-size: 30px;"
|
||||
/>
|
||||
<va-button slot="append" class="mr-2 pa-1 shrink" style="width: 2em; height: 2em; border-radius: 50%; font-size: 20px;" small @click="readCisData()">
|
||||
R
|
||||
</va-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<va-button class="mr-2 pa-1" style="width: 4em; height: 2em; font-size: 15px;" small @click="detect()">
|
||||
Detect
|
||||
</va-button>
|
||||
</div>
|
||||
<div>
|
||||
<va-button class="mr-2 pa-1" style="width: 4em; height: 2em; font-size: 15px;" small @click="version()">
|
||||
Version
|
||||
</va-button>
|
||||
</div>
|
||||
<div>
|
||||
<va-button class="mr-2 pa-1" style="width: 4em; height: 2em; font-size: 15px;" small @click="battery()">
|
||||
Battery
|
||||
</va-button>
|
||||
</div>
|
||||
|
||||
</va-card>
|
||||
</va-tree-category>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import { taskInfo } from '../../../../data/task/TaskInfo'
|
||||
import DCVolt from '../parameter/item/EIS/DCVolt'
|
||||
import ACAmplitude from '../parameter/item/EIS/ACAmplitude'
|
||||
import FreqRange from '../parameter/item/EIS/FreqRange'
|
||||
import PointsPerDecades from '../parameter/item/EIS/PointsPerDecades'
|
||||
import PointSpacing from '../parameter/item/EIS/PointSpacing'
|
||||
import Delay from '../parameter/item/EIS/Delay'
|
||||
import Average from '../parameter/item/EIS/Average'
|
||||
import CurrentRange from '../parameter/item/EIS/CurrentRange'
|
||||
import { taskInfo } from '../../../../data/task/TaskInfo.js'
|
||||
import DCVolt from '../parameter/item/EIS/DCVolt.vue'
|
||||
import ACAmplitude from '../parameter/item/EIS/ACAmplitude.vue'
|
||||
import FreqRange from '../parameter/item/EIS/FreqRange.vue'
|
||||
import PointsPerDecades from '../parameter/item/EIS/PointsPerDecades.vue'
|
||||
import PointSpacing from '../parameter/item/EIS/PointSpacing.vue'
|
||||
import Delay from '../parameter/item/EIS/Delay.vue'
|
||||
import Average from '../parameter/item/EIS/Average.vue'
|
||||
import CurrentRange from '../parameter/item/EIS/CurrentRange.vue'
|
||||
// import SingalMode from '../parameter/item/EIS/SingalMode'
|
||||
|
||||
// CV
|
||||
import LevelButton from '../parameter/item/LevelButton.vue'
|
||||
import VoltRange from '../parameter/item/EIS/VoltRange.vue'
|
||||
import ScanRateRange from '../parameter/item/ScanRateRange.vue'
|
||||
import ResolutionRange from '../parameter/item/ResolutionRange.vue'
|
||||
import CycleRange from '../parameter/item/CycleRange.vue'
|
||||
|
||||
export default {
|
||||
name: 'EliteParameterRecordingEliteEIS',
|
||||
components: {
|
||||
@@ -45,6 +244,11 @@ export default {
|
||||
Delay,
|
||||
Average,
|
||||
CurrentRange,
|
||||
LevelButton,
|
||||
VoltRange,
|
||||
ScanRateRange,
|
||||
ResolutionRange,
|
||||
CycleRange,
|
||||
},
|
||||
props: {
|
||||
deviceID: {
|
||||
@@ -69,6 +273,14 @@ export default {
|
||||
id: 0,
|
||||
description: 'Potentiostatic Electrochemical Impedance Spectroscopy',
|
||||
},
|
||||
{
|
||||
id: 1,
|
||||
description: 'CV',
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
description: 'Dev Tools',
|
||||
},
|
||||
],
|
||||
DCVolt: null,
|
||||
AC_AMP: null,
|
||||
@@ -79,7 +291,75 @@ export default {
|
||||
Delay: null,
|
||||
Average: null,
|
||||
CurrentRange: null,
|
||||
|
||||
instru: {
|
||||
write: '',
|
||||
read: '',
|
||||
notify: '',
|
||||
},
|
||||
measureEocButton: {
|
||||
start: 'OCP',
|
||||
stop: 'Stop',
|
||||
status: false,
|
||||
},
|
||||
// CV
|
||||
currentRangeSelect: null,
|
||||
currentRangeOptions: [
|
||||
{
|
||||
value: 0,
|
||||
label: '<1.5 μA',
|
||||
},
|
||||
{
|
||||
value: 1,
|
||||
label: '1-60 μA',
|
||||
},
|
||||
{
|
||||
value: 2,
|
||||
label: '40-175 μA',
|
||||
},
|
||||
{
|
||||
value: 3,
|
||||
label: '>120 uA',
|
||||
},
|
||||
{
|
||||
value: 4,
|
||||
label: 'Auto',
|
||||
},
|
||||
],
|
||||
voltageInRangeSelect: null,
|
||||
voltageInRangeOptions: [
|
||||
{
|
||||
value: 0,
|
||||
label: '1',
|
||||
},
|
||||
{
|
||||
value: 1,
|
||||
label: '2',
|
||||
},
|
||||
{
|
||||
value: 2,
|
||||
label: '3',
|
||||
},
|
||||
{
|
||||
value: 3,
|
||||
label: 'Auto',
|
||||
},
|
||||
],
|
||||
highzSelect: null,
|
||||
highzOptions: [
|
||||
{
|
||||
value: 0,
|
||||
label: 'On',
|
||||
},
|
||||
{
|
||||
value: 1,
|
||||
label: 'Off',
|
||||
},
|
||||
],
|
||||
voltInitialNumber: null,
|
||||
stopVoltMaxNumber: null,
|
||||
stopVoltMinNumber: null,
|
||||
voltScanRateNumber: null,
|
||||
sampleRateNumber: null,
|
||||
}
|
||||
},
|
||||
mqtt: {
|
||||
@@ -98,6 +378,22 @@ export default {
|
||||
content: e[1],
|
||||
}))
|
||||
},
|
||||
measureEoc () {
|
||||
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
|
||||
header: 'device_instruction/0',
|
||||
device: taskInfo.getRawDeviceID(this.deviceID),
|
||||
instruction: 'VIS_CC_ZERO',
|
||||
}))
|
||||
this.measureEocButton.status = true
|
||||
},
|
||||
measureEocStop () {
|
||||
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
|
||||
header: 'device_instruction/0',
|
||||
device: taskInfo.getRawDeviceID(this.deviceID),
|
||||
instruction: 'interrupt',
|
||||
}))
|
||||
this.measureEocButton.status = false
|
||||
},
|
||||
refresh () {
|
||||
this.workingModeSelect = this.workingModeOptions[taskInfo.getDeviceInfo(this.deviceID).parameterSet.MODE]
|
||||
if (this.workingModeSelect != null) {
|
||||
@@ -119,7 +415,7 @@ export default {
|
||||
if (this.$refs.PointSpacing != null) {
|
||||
this.$refs.PointSpacing.itemChange(this.PointSpacing)
|
||||
}
|
||||
this.DCVolt = String(Math.round((taskInfo.getDeviceInfo(this.deviceID).parameterSet.DC_BIAS) * 0.537 + 200))
|
||||
this.DCVolt = String(Math.round((taskInfo.getDeviceInfo(this.deviceID).parameterSet.DC_BIAS) * 2200 / 4095))
|
||||
if (this.$refs.DCVolt != null) {
|
||||
this.$refs.DCVolt.itemChange(this.DCVolt)
|
||||
}
|
||||
@@ -127,11 +423,11 @@ export default {
|
||||
if (this.$refs.Delay != null) {
|
||||
this.$refs.Delay.itemChange(this.Delay)
|
||||
}
|
||||
this.FreqStart = String(parseFloat(Math.round(parseFloat((taskInfo.getDeviceInfo(this.deviceID).parameterSet.FREQ_START * 67.1 + 0.015) * 100)) / 100).toFixed(2))
|
||||
this.FreqStart = String(parseFloat(Math.round(parseFloat((taskInfo.getDeviceInfo(this.deviceID).parameterSet.FREQ_START * 0.0149) * 100)) / 100).toFixed(1)) === '0.0' ? '0.015' : String(parseFloat(Math.round(parseFloat((taskInfo.getDeviceInfo(this.deviceID).parameterSet.FREQ_START * 0.0149) * 100)) / 100).toFixed(1))
|
||||
if (this.$refs.FreqRange != null) {
|
||||
this.$refs.FreqRange.itemChangeMin(this.FreqStart)
|
||||
}
|
||||
this.FreqStop = String(parseFloat(Math.round(parseFloat((taskInfo.getDeviceInfo(this.deviceID).parameterSet.FREQ_STOP * 67.1 + 0.015) * 100)) / 100).toFixed(2))
|
||||
this.FreqStop = String(parseFloat(Math.round(parseFloat((taskInfo.getDeviceInfo(this.deviceID).parameterSet.FREQ_STOP * 0.0149) * 100)) / 100).toFixed(1)) === '0.0' ? '0.015' : String(parseFloat(Math.round(parseFloat((taskInfo.getDeviceInfo(this.deviceID).parameterSet.FREQ_STOP * 0.0149) * 100)) / 100).toFixed(1))
|
||||
if (this.$refs.FreqRange != null) {
|
||||
this.$refs.FreqRange.itemChangeMax(this.FreqStop)
|
||||
}
|
||||
@@ -139,6 +435,49 @@ export default {
|
||||
if (this.$refs.PointsPerDecades != null) {
|
||||
this.$refs.PointsPerDecades.itemChange(this.PointsPerDecades)
|
||||
}
|
||||
|
||||
// CV
|
||||
this.currentRangeSelect = taskInfo.getDeviceInfo(this.deviceID).parameterSet.ADC_LEVEL_I_15
|
||||
if (this.$refs.currentRangeSelect != null) {
|
||||
this.$refs.currentRangeSelect.updateLevelButton(this.currentRangeSelect)
|
||||
}
|
||||
|
||||
this.voltageInRangeSelect = taskInfo.getDeviceInfo(this.deviceID).parameterSet.ADC_LEVEL_V_IN_15
|
||||
if (this.$refs.voltageInRangeSelect != null) {
|
||||
this.$refs.voltageInRangeSelect.updateLevelButton(this.voltageInRangeSelect)
|
||||
}
|
||||
|
||||
this.highzSelect = taskInfo.getDeviceInfo(this.deviceID).parameterSet.CTRL_HIGH_Z_15
|
||||
if (this.$refs.highzSelect != null) {
|
||||
this.$refs.highzSelect.updateLevelButton(this.highzSelect)
|
||||
}
|
||||
|
||||
this.stopVoltMaxNumber = this.voltInitialNumber = (taskInfo.getDeviceInfo(this.deviceID).parameterSet.VOLTSTOP_MAX - 25000) / 5
|
||||
if (this.$refs.stopVoltMaxNumber != null) {
|
||||
this.$refs.stopVoltMaxNumber.updateVoltNumber(this.stopVoltMaxNumber)
|
||||
}
|
||||
|
||||
this.stopVoltMinNumber = (taskInfo.getDeviceInfo(this.deviceID).parameterSet.VOLTSTOP_MIN - 25000) / 5
|
||||
if (this.$refs.stopVoltMinNumber != null) {
|
||||
this.$refs.stopVoltMinNumber.updateVoltNumber(this.stopVoltMinNumber)
|
||||
}
|
||||
|
||||
this.voltInitialNumber = (taskInfo.getDeviceInfo(this.deviceID).parameterSet.VOLT_INITIAL - 25000) / 5
|
||||
if (this.$refs.voltInitialNumber != null) {
|
||||
this.$refs.voltInitialNumber.updateVoltNumber(this.voltInitialNumber)
|
||||
}
|
||||
|
||||
this.voltScanRateNumber = taskInfo.getDeviceInfo(this.deviceID).parameterSet.Scan_Rate
|
||||
if (this.$refs.voltScanRateNumber != null) {
|
||||
this.$refs.voltScanRateNumber.updateVoltScanRateNumber(this.voltScanRateNumber)
|
||||
}
|
||||
|
||||
this.sampleRateNumber = taskInfo.getDeviceInfo(this.deviceID).parameterSet.SAMPLE_RATE
|
||||
if (this.$refs.sampleRateNumber != null) {
|
||||
this.$refs.sampleRateNumber.updateResolutionNumber(this.sampleRateNumber)
|
||||
}
|
||||
|
||||
this.instru.read = (taskInfo.getDeviceInfo(this.deviceID).parameterSet.ADC_VALUE_I).toString(16).toUpperCase()
|
||||
},
|
||||
workingModeSelectChange (val) {
|
||||
if (this.workingModeSelect.id === -1) {
|
||||
@@ -152,6 +491,67 @@ export default {
|
||||
console.log(this.workingModeSelect.id, this.workingModeSelect.description)
|
||||
}
|
||||
},
|
||||
instruParameterChange: function (e) {
|
||||
while (e[1].length <= 33) {
|
||||
e[1] = e[1] + '0'
|
||||
}
|
||||
|
||||
const sendIns = new Array(17).fill(0)
|
||||
for (let i = 0; i <= 16; i++) {
|
||||
const startIndex = i * 2
|
||||
sendIns[i] = e[1].substring(startIndex, startIndex + 2)
|
||||
sendIns[i] = parseInt(sendIns[i], 16)
|
||||
}
|
||||
|
||||
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
|
||||
header: 'device_parameter/0',
|
||||
device: taskInfo.getRawDeviceID(this.deviceID),
|
||||
parameter: 'BLE_WRITE',
|
||||
content: '0:16=' + String(sendIns),
|
||||
}))
|
||||
},
|
||||
sendInstr () {
|
||||
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
|
||||
header: 'device_instruction/0',
|
||||
device: taskInfo.getRawDeviceID(this.deviceID),
|
||||
instruction: 'ble_instru_send',
|
||||
}))
|
||||
},
|
||||
readCisData () {
|
||||
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
|
||||
header: 'device_parameter_value/0',
|
||||
device: taskInfo.getRawDeviceID(this.deviceID),
|
||||
parameter: 'ADC_VALUE_I',
|
||||
}))
|
||||
},
|
||||
detect () {
|
||||
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
|
||||
header: 'device_instruction/0',
|
||||
device: taskInfo.getRawDeviceID(this.deviceID),
|
||||
instruction: 'VIS_DEVICE_DETECT',
|
||||
}))
|
||||
setTimeout(() => {
|
||||
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
|
||||
header: 'device_instruction/0',
|
||||
device: taskInfo.getRawDeviceID(this.deviceID),
|
||||
instruction: 'VIS_DEVICE_DONE',
|
||||
}))
|
||||
}, 5000)
|
||||
},
|
||||
version () {
|
||||
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
|
||||
header: 'device_instruction/0',
|
||||
device: taskInfo.getRawDeviceID(this.deviceID),
|
||||
instruction: 'dev_version',
|
||||
}))
|
||||
},
|
||||
battery () {
|
||||
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
|
||||
header: 'device_instruction/0',
|
||||
device: taskInfo.getRawDeviceID(this.deviceID),
|
||||
instruction: 'dev_battery',
|
||||
}))
|
||||
},
|
||||
},
|
||||
mounted () {
|
||||
this.refresh()
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
<va-tree-node>
|
||||
<!-- <data-number :ref="'DataNumber'" :deviceID="deviceID" :parameterName="'DataNumber'" @parameterChange="deviceParameterChange($event)" /> -->
|
||||
<data-output :ref="'DataOutput'" :deviceID="deviceID" :parameterName="'DATA_OUTPUT'" @parameterChange="deviceParameterChange($event)" />
|
||||
<cycle-number :ref="'CycleNumber'" :deviceID="deviceID" :parameterName="'NUM_OF_CYCLES'" @parameterChange="deviceParameterChange($event)" />
|
||||
<cycle-number :ref="'CycleNumber'" :deviceID="deviceID" :parameterName="'CYCLE_NUMBER'" @parameterChange="deviceParameterChange($event)" />
|
||||
</va-tree-node>
|
||||
</va-tree-category>
|
||||
</va-tree-root>
|
||||
|
||||
@@ -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>
|
||||
@@ -362,6 +362,10 @@
|
||||
<div v-if="workingModeSelect != null && workingModeSelect.id == 14">
|
||||
<elite-parameter-recording-elite-pulse-sensing :ref="'PulseSensingMode'" :deviceID="deviceID" :deviceName="deviceName"/>
|
||||
</div>
|
||||
|
||||
<div v-if="workingModeSelect != null && workingModeSelect.id == 15">
|
||||
<elite-parameter-recording-elite-d-p-v :ref="'DPVMode'" :deviceID="deviceID" :deviceName="deviceName"/>
|
||||
</div>
|
||||
</va-tree-root>
|
||||
</div>
|
||||
</template>
|
||||
@@ -378,6 +382,7 @@ import MicroAmpereRange from '../parameter/item/MicroAmpereRange'
|
||||
import ScanRateRange from '../parameter/item/ScanRateRange'
|
||||
import ResolutionRange from '../parameter/item/ResolutionRange'
|
||||
import EliteParameterRecordingElitePulseSensing from './EliteParameterRecordingElitePulseSensing'
|
||||
import EliteParameterRecordingEliteDPV from './EliteParameterRecordingEliteDPV'
|
||||
|
||||
export default {
|
||||
name: 'EliteParameterRecordingElitezm15',
|
||||
@@ -391,6 +396,7 @@ export default {
|
||||
ScanRateRange,
|
||||
ResolutionRange,
|
||||
EliteParameterRecordingElitePulseSensing,
|
||||
EliteParameterRecordingEliteDPV,
|
||||
},
|
||||
props: {
|
||||
deviceID: {
|
||||
@@ -471,6 +477,10 @@ export default {
|
||||
id: 14,
|
||||
description: 'Pulse Sensing',
|
||||
},
|
||||
{
|
||||
id: 15,
|
||||
description: 'Differential Pulse Voltammetry (DPV)',
|
||||
},
|
||||
],
|
||||
currentRangeSelect: null,
|
||||
currentRangeOptions: [
|
||||
@@ -753,6 +763,10 @@ export default {
|
||||
if (this.$refs.PulseSensingMode != null) {
|
||||
this.$refs.PulseSensingMode.refresh()
|
||||
}
|
||||
|
||||
if (this.$refs.DPVMode != null) {
|
||||
this.$refs.DPVMode.refresh()
|
||||
}
|
||||
},
|
||||
workingModeSelectChange (val) {
|
||||
if (this.workingModeSelect.id === -1) {
|
||||
|
||||
@@ -147,6 +147,24 @@
|
||||
</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'">
|
||||
@@ -231,7 +249,6 @@
|
||||
<script>
|
||||
import { taskInfo } from '../../../../data/task/TaskInfo'
|
||||
import { chartData } from '../../../../data/task/ChartsManagement'
|
||||
import { mapFields } from 'vuex-map-fields'
|
||||
|
||||
export default {
|
||||
name: 'NeuliveParameterRecording',
|
||||
@@ -249,6 +266,7 @@ export default {
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
channelList: [],
|
||||
ampGainSelect: null,
|
||||
ampGainOptions: [
|
||||
// {
|
||||
@@ -349,6 +367,49 @@ export default {
|
||||
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: [
|
||||
{
|
||||
@@ -396,11 +457,6 @@ export default {
|
||||
axisChannelList: [],
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapFields('taskContent', [
|
||||
'channelList',
|
||||
]),
|
||||
},
|
||||
mqtt: {
|
||||
},
|
||||
methods: {
|
||||
@@ -435,6 +491,7 @@ 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]
|
||||
},
|
||||
@@ -521,6 +578,21 @@ export default {
|
||||
}))
|
||||
}
|
||||
},
|
||||
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({
|
||||
@@ -572,8 +644,13 @@ export default {
|
||||
for (const chartID in charts) {
|
||||
for (const seriesIndex in charts[chartID].series) {
|
||||
if (charts[chartID].series[seriesIndex].yAxisSource[1] >= 256 && charts[chartID].series[seriesIndex].yAxisSource[1] <= 260) {
|
||||
charts[chartID].yAxis[seriesIndex].min = -scaleRange
|
||||
charts[chartID].yAxis[seriesIndex].max = scaleRange
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -241,22 +241,24 @@
|
||||
<div class="row">
|
||||
<div class="flex sm12 xl12 md12 xs12">
|
||||
<div class="flex row align--center">
|
||||
<va-button slot="append" class="mr-2 pa-1 shrink" small @click="timeRangeChange(1, 0)">
|
||||
<!-- <va-button slot="append" class="mr-2 pa-1 shrink" small @click="timeRangeChange(1, 0.1)">
|
||||
0.1
|
||||
</va-button>
|
||||
</va-button> -->
|
||||
<va-input
|
||||
@keyup.enter="timeRangeChange(1, t1RangeInput)"
|
||||
v-model="t1RangeInput"
|
||||
class="mb-0"
|
||||
:label="'T1 RANGE'"
|
||||
:error="TRangeErrorMsgList[0].showError"
|
||||
:error-messages="TRangeErrorMsgList[0].errorMsg"
|
||||
>
|
||||
<p slot="append" style="margin-right: 0;" small>
|
||||
{{unitOptions[unitSelect].label}}
|
||||
</p>
|
||||
</va-input>
|
||||
<va-button slot="append" class="ml-2 pa-1 shrink" small @click="timeRangeChange(1, 10.23)">
|
||||
<!-- <va-button slot="append" class="ml-2 pa-1 shrink" small @click="timeRangeChange(1, 10.23)">
|
||||
10.23
|
||||
</va-button>
|
||||
</va-button> -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -264,22 +266,24 @@
|
||||
<div class="row" v-if="patternModeSelect==1">
|
||||
<div class="flex sm12 xl12 md12 xs12">
|
||||
<div class="flex row align--center">
|
||||
<va-button slot="append" class="mr-2 pa-1 shrink" small @click="timeRangeChange(2, 0)">
|
||||
<!-- <va-button slot="append" class="mr-2 pa-1 shrink" small @click="timeRangeChange(2, 0)">
|
||||
0
|
||||
</va-button>
|
||||
</va-button> -->
|
||||
<va-input
|
||||
@keyup.enter="timeRangeChange(2, t2RangeInput)"
|
||||
v-model="t2RangeInput"
|
||||
class="mb-0"
|
||||
:label="'T2 RANGE'"
|
||||
:error="TRangeErrorMsgList[1].showError"
|
||||
:error-messages="TRangeErrorMsgList[1].errorMsg"
|
||||
>
|
||||
<p slot="append" style="margin-right: 0;" small>
|
||||
{{unitOptions[unitSelect].label}}
|
||||
</p>
|
||||
</va-input>
|
||||
<va-button slot="append" class="ml-2 pa-1 shrink" small @click="timeRangeChange(2, 10.23)">
|
||||
<!-- <va-button slot="append" class="ml-2 pa-1 shrink" small @click="timeRangeChange(2, 10.23)">
|
||||
10.23
|
||||
</va-button>
|
||||
</va-button> -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -287,22 +291,24 @@
|
||||
<div class="row" v-if="patternModeSelect==1">
|
||||
<div class="flex sm12 xl12 md12 xs12">
|
||||
<div class="flex row align--center">
|
||||
<va-button slot="append" class="mr-2 pa-1 shrink" small @click="timeRangeChange(3, 0)">
|
||||
<!-- <va-button slot="append" class="mr-2 pa-1 shrink" small @click="timeRangeChange(3, 0.1)">
|
||||
0.1
|
||||
</va-button>
|
||||
</va-button> -->
|
||||
<va-input
|
||||
@keyup.enter="timeRangeChange(3, t3RangeInput)"
|
||||
v-model="t3RangeInput"
|
||||
class="mb-0"
|
||||
:label="'T3 RANGE'"
|
||||
:error="TRangeErrorMsgList[2].showError"
|
||||
:error-messages="TRangeErrorMsgList[2].errorMsg"
|
||||
>
|
||||
<p slot="append" style="margin-right: 0;" small>
|
||||
{{unitOptions[unitSelect].label}}
|
||||
</p>
|
||||
</va-input>
|
||||
<va-button slot="append" class="ml-2 pa-1 shrink" small @click="timeRangeChange(3, 10.23)">
|
||||
<!-- <va-button slot="append" class="ml-2 pa-1 shrink" small @click="timeRangeChange(3, 10.23)">
|
||||
10.23
|
||||
</va-button>
|
||||
</va-button> -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -310,22 +316,25 @@
|
||||
<div class="row">
|
||||
<div class="flex sm12 xl12 md12 xs12">
|
||||
<div class="flex row align--center">
|
||||
<va-button slot="append" class="mr-2 pa-1 shrink" small @click="timeRangeChange(4, 0)">
|
||||
<!-- <va-button slot="append" class="mr-2 pa-1 shrink" small @click="timeRangeChange(4, 0)">
|
||||
0
|
||||
</va-button>
|
||||
</va-button> -->
|
||||
<va-input
|
||||
@keyup.enter="timeRangeChange(4, t4RangeInput)"
|
||||
readonly
|
||||
v-model="t4RangeInput"
|
||||
class="mb-0"
|
||||
:label="'T4 RANGE'"
|
||||
:error="TRangeErrorMsgList[3].showError"
|
||||
:error-messages="TRangeErrorMsgList[3].errorMsg"
|
||||
>
|
||||
<p slot="append" style="margin-right: 0;" small>
|
||||
{{unitOptions[unitSelect].label}}
|
||||
</p>
|
||||
</va-input>
|
||||
<va-button slot="append" class="ml-2 pa-1 shrink" small @click="timeRangeChange(4, 1310.71)">
|
||||
<!-- <va-button slot="append" class="ml-2 pa-1 shrink" small @click="timeRangeChange(4, 1310.71)">
|
||||
1310.71
|
||||
</va-button>
|
||||
</va-button> -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -352,7 +361,6 @@
|
||||
|
||||
<script>
|
||||
import { taskInfo } from '../../../../data/task/TaskInfo'
|
||||
import { mapFields } from 'vuex-map-fields'
|
||||
|
||||
export default {
|
||||
name: 'NeuliveParameterStimulation',
|
||||
@@ -372,6 +380,9 @@ export default {
|
||||
return {
|
||||
showGuideLineModal: { ELECTRODE: false, PATTERN: false },
|
||||
stimulationOn: false,
|
||||
posChannelList: [2],
|
||||
negChannelList: [1],
|
||||
stimulateElectrodeSelect: null,
|
||||
stimulateElectrodeOptions: [
|
||||
{
|
||||
label: 'Monopolar',
|
||||
@@ -382,6 +393,7 @@ export default {
|
||||
value: 1,
|
||||
},
|
||||
],
|
||||
TRangeErrorMsgList: [{ id: 1, showError: false, errorMsg: [''] }, { id: 2, showError: false, errorMsg: [''] }, { id: 3, showError: false, errorMsg: [''] }, { id: 4, showError: false, errorMsg: [''] }],
|
||||
cycleNumberSelect: null,
|
||||
cycleNumberOptions: [
|
||||
{
|
||||
@@ -445,11 +457,6 @@ export default {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapFields('taskContent', [
|
||||
'posChannelList',
|
||||
'negChannelList',
|
||||
'stimulateElectrodeSelect',
|
||||
]),
|
||||
stimulateDisable () {
|
||||
// posChannel and negChannel at least one && t1 ~ t4 > 0
|
||||
const totalStiTime = (this.t1Range + this.t2Range + this.t3Range + this.t4Range) * 10
|
||||
@@ -459,6 +466,20 @@ export default {
|
||||
return true
|
||||
}
|
||||
},
|
||||
TRangeStatusCheck () {
|
||||
let flag = true
|
||||
for (let i = 0; i < this.TRangeErrorMsgList.length; i++) {
|
||||
if (this.TRangeErrorMsgList[i].showError === true) {
|
||||
flag = false
|
||||
break
|
||||
}
|
||||
}
|
||||
if (flag === true) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
},
|
||||
},
|
||||
mqtt: {
|
||||
},
|
||||
@@ -475,24 +496,22 @@ export default {
|
||||
},
|
||||
refreshPattern () {
|
||||
this.patternModeSelect = taskInfo.getDeviceInfo(this.deviceID).parameterSet.STI_PATTERN ? 1 : 0
|
||||
this.t1Range = taskInfo.getDeviceInfo(this.deviceID).parameterSet.STI_T1[0]
|
||||
this.t1RangeInput = String((this.t1Range * 10) / this.unitMultiply)
|
||||
this.t1RangeArray.fill(this.t1Range, 0)
|
||||
this.t2Range = taskInfo.getDeviceInfo(this.deviceID).parameterSet.STI_T2[0]
|
||||
this.t2RangeInput = String((this.t2Range * 10) / this.unitMultiply)
|
||||
this.t2RangeArray.fill(this.t2Range, 0)
|
||||
this.t3Range = taskInfo.getDeviceInfo(this.deviceID).parameterSet.STI_T3[0]
|
||||
this.t3RangeInput = String((this.t3Range * 10) / this.unitMultiply)
|
||||
this.t3RangeArray.fill(this.t3Range, 0)
|
||||
this.t4Range = taskInfo.getDeviceInfo(this.deviceID).parameterSet.STI_T4[0]
|
||||
this.t4RangeInput = String((this.t4Range * 10) / this.unitMultiply)
|
||||
this.t4RangeArray.fill(this.t4Range, 0)
|
||||
|
||||
if (this.pattternModeSelect === 0) {
|
||||
this.periodNumber = (this.t1Range + this.t4Range) * 10
|
||||
} else {
|
||||
this.periodNumber = (this.t1Range + this.t2Range + this.t3Range + this.t4Range) * 10
|
||||
if (this.TRangeStatusCheck === true) { // if t1~t4 is not valid input, not need to refresh
|
||||
this.t1Range = taskInfo.getDeviceInfo(this.deviceID).parameterSet.STI_T1[0]
|
||||
this.t1RangeInput = String((this.t1Range * 10) / this.unitMultiply)
|
||||
this.t1RangeArray.fill(this.t1Range, 0)
|
||||
this.t2Range = taskInfo.getDeviceInfo(this.deviceID).parameterSet.STI_T2[0]
|
||||
this.t2RangeInput = String((this.t2Range * 10) / this.unitMultiply)
|
||||
this.t2RangeArray.fill(this.t2Range, 0)
|
||||
this.t3Range = taskInfo.getDeviceInfo(this.deviceID).parameterSet.STI_T3[0]
|
||||
this.t3RangeInput = String((this.t3Range * 10) / this.unitMultiply)
|
||||
this.t3RangeArray.fill(this.t3Range, 0)
|
||||
this.t4Range = taskInfo.getDeviceInfo(this.deviceID).parameterSet.STI_T4[0]
|
||||
this.t4RangeInput = String((this.t4Range * 10) / this.unitMultiply)
|
||||
this.t4RangeArray.fill(this.t4Range, 0)
|
||||
}
|
||||
|
||||
this.periodNumber = (this.t1Range + this.t2Range + this.t3Range + this.t4Range) * 10
|
||||
this.periodNumberInput = String((this.periodNumber) / this.unitMultiply)
|
||||
|
||||
if (this.periodNumber !== 0) {
|
||||
@@ -519,11 +538,6 @@ export default {
|
||||
}
|
||||
}
|
||||
})
|
||||
// }
|
||||
// console.log('cha',stiChannelSet)
|
||||
// console.log('pol',stiPolaritySet)
|
||||
// console.log('pos',this.posChannelList)
|
||||
// console.log('neg',this.negChannelList)
|
||||
this.stimulateElectrodeSelect = taskInfo.getDeviceInfo(this.deviceID).parameterSet.STI_H_BRIDGE ? 1 : 0
|
||||
this.cycleNumberSelect = taskInfo.getDeviceInfo(this.deviceID).parameterSet.CONTINUOUS_STI ? 1 : 0
|
||||
this.cycleNumber = taskInfo.getDeviceInfo(this.deviceID).parameterSet.STI_CYCLE_LIST[0]
|
||||
@@ -533,24 +547,13 @@ export default {
|
||||
this.amplitudeNumberInput = String(this.amplitudeNumber)
|
||||
|
||||
this.refreshPattern()
|
||||
// console.log('STI_CONTINUOUS', this.cycleNumberSelect)
|
||||
// console.log('STI_H_BRIDGE', this.stimulateElectrodeSelect)
|
||||
// console.log('STI_PATTERN', this.patternModeSelect)
|
||||
// console.log('STI_T1', taskInfo.getDeviceInfo(this.deviceID).parameterSet.STI_T1[0])
|
||||
// console.log('STI_T2', taskInfo.getDeviceInfo(this.deviceID).parameterSet.STI_T2[0])
|
||||
// console.log('STI_T3', taskInfo.getDeviceInfo(this.deviceID).parameterSet.STI_T3[0])
|
||||
// console.log('STI_T4', taskInfo.getDeviceInfo(this.deviceID).parameterSet.STI_T4[0])
|
||||
// console.log(this.periodNumber)
|
||||
// console.log(this.periodNumberInput)
|
||||
// console.log(this.frequencyNumber)
|
||||
// console.log(this.frequencyNumberInput)
|
||||
},
|
||||
transUnit () {
|
||||
if (this.unitSelect === 0) {
|
||||
if (this.unitSelect === 0) { // s
|
||||
this.unitMultiply = 1000000
|
||||
} else if (this.unitSelect === 1) {
|
||||
} else if (this.unitSelect === 1) { // ms
|
||||
this.unitMultiply = 1000
|
||||
} else {
|
||||
} else { // us
|
||||
this.unitMultiply = 1
|
||||
}
|
||||
this.refresh()
|
||||
@@ -665,197 +668,228 @@ export default {
|
||||
}))
|
||||
}
|
||||
},
|
||||
checkDivisible (x, y) { // 檢查是否整除
|
||||
if (Number.isInteger(y / x)) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
},
|
||||
|
||||
// [Region] Neulive sti pattern block
|
||||
patternModeSelectChange () {
|
||||
if (this.patternModeSelect == null) {
|
||||
return false
|
||||
}
|
||||
this.t1Range = 10
|
||||
this.t1RangeInput = String((this.t1Range * 10) / this.unitMultiply)
|
||||
|
||||
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
|
||||
header: 'device_parameter/0',
|
||||
device: taskInfo.getRawDeviceID(this.deviceID),
|
||||
parameter: 'STI_PATTERN',
|
||||
content: this.patternModeSelect,
|
||||
}))
|
||||
|
||||
if (this.patternModeSelect === 0) {
|
||||
this.t2Range = 0
|
||||
this.t2RangeInput = '0'
|
||||
this.t3Range = 0
|
||||
this.t3RangeInput = '0'
|
||||
this.t4Range = (this.periodNumber / 10) - this.t1Range
|
||||
this.t4RangeInput = String((this.t4Range * 10) / this.unitMultiply)
|
||||
} else {
|
||||
this.t3Range = this.t1Range
|
||||
this.t3RangeInput = this.t1RangeInput
|
||||
this.t4Range = (this.periodNumber / 10) - this.t1Range - this.t2Range - this.t3Range
|
||||
this.t4RangeInput = String((this.t4Range * 10) / this.unitMultiply)
|
||||
}
|
||||
|
||||
if (this.t4Range < 0) {
|
||||
this.refreshPattern()
|
||||
this.pageToast('T4 Range will be negative, so reset')
|
||||
} else {
|
||||
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
|
||||
header: 'device_parameter/0',
|
||||
device: taskInfo.getRawDeviceID(this.deviceID),
|
||||
parameter: 'STI_PATTERN',
|
||||
content: this.patternModeSelect,
|
||||
}))
|
||||
this.updateTimeRange()
|
||||
}
|
||||
},
|
||||
frequencyNumberChange (val) {
|
||||
if (this.frequencyNumberInput == null) {
|
||||
return false
|
||||
}
|
||||
if (typeof (val) === 'string') {
|
||||
if (isNaN(val) || parseInt(val) < 1 || parseInt(val) > 10000) {
|
||||
this.frequencyNumberInput = '100'
|
||||
this.frequencyNumber = 100
|
||||
}
|
||||
if (parseInt(this.frequencyNumberInput) !== parseInt(this.frequencyNumber)) {
|
||||
this.frequencyNumber = parseInt(val)
|
||||
}
|
||||
}
|
||||
|
||||
this.periodNumber = (1 / this.frequencyNumber * 1e6).toFixed(3)
|
||||
this.periodNumberInput = String(this.periodNumber / this.unitMultiply)
|
||||
if (this.checkDivisible(this.unitMultiply, this.periodNumber)) {
|
||||
this.t1Range = 10
|
||||
this.t1RangeInput = String((this.t1Range * 10) / this.unitMultiply)
|
||||
if (this.patternModeSelect === 0) {
|
||||
this.t3Range = 0
|
||||
} else if (this.patternModeSelect === 1) {
|
||||
this.t3Range = 10
|
||||
}
|
||||
this.t3RangeInput = String((this.t3Range * 10) / this.unitMultiply)
|
||||
this.t4Range = (this.periodNumber / 10) - (this.t1Range + this.t2Range + this.t3Range)
|
||||
this.t4RangeInput = String((this.t4Range * 10) / this.unitMultiply)
|
||||
|
||||
if (this.t4Range < 0) {
|
||||
this.refreshPattern()
|
||||
this.pageToast('T4 Range will be negative, so reset')
|
||||
} else {
|
||||
this.updateTimeRange()
|
||||
}
|
||||
} else {
|
||||
this.refreshPattern()
|
||||
this.pageToast('Frequency cannot be divided by 1s, so reset')
|
||||
}
|
||||
},
|
||||
periodNumberChange (val) {
|
||||
if (this.periodNumberInput === null) {
|
||||
return false
|
||||
}
|
||||
if (typeof (val) === 'string') {
|
||||
if (isNaN(val) || parseFloat(val) < 0 || parseFloat(val / this.unitMultiply) > 1) {
|
||||
this.periodNumber = 1000
|
||||
this.periodNumberInput = String(this.periodNumber / this.unitMultiply)
|
||||
}
|
||||
if (parseInt(this.periodNumberInput) !== parseInt(this.periodNumber)) {
|
||||
this.periodNumber = parseFloat(val * this.unitMultiply)
|
||||
this.periodNumberInput = val
|
||||
}
|
||||
}
|
||||
this.frequencyNumber = parseInt(1 / (this.periodNumber * 1e-6))
|
||||
this.frequencyNumberInput = String(this.frequencyNumber)
|
||||
|
||||
this.t1Range = 10
|
||||
this.t1RangeInput = String((this.t1Range * 10) / this.unitMultiply)
|
||||
if (this.patternModeSelect === 0) {
|
||||
this.t3Range = 0
|
||||
} else if (this.patternModeSelect === 1) {
|
||||
this.t2Range = 0
|
||||
this.t3Range = 10
|
||||
this.t3RangeInput = String((this.t3Range * 10) / this.unitMultiply)
|
||||
}
|
||||
this.t3RangeInput = String((this.t3Range * 10) / this.unitMultiply)
|
||||
this.t4Range = (this.periodNumber / 10) - (this.t1Range + this.t2Range + this.t3Range)
|
||||
this.t4RangeInput = String((this.t4Range * 10) / this.unitMultiply)
|
||||
|
||||
if (this.t4Range < 0) {
|
||||
this.refreshPattern()
|
||||
this.pageToast('T4 Range will be negative, so reset')
|
||||
} else {
|
||||
this.autoComputeT4()
|
||||
const check4 = this.checkIndividualTRange(4, this.t4Range)
|
||||
if (check4) {
|
||||
this.updateTimeRange()
|
||||
}
|
||||
this.updateStiTRangeCheckParam()
|
||||
},
|
||||
timeRangeChange (stiIimeSelect, val) {
|
||||
if (parseInt(val) < 0) {
|
||||
this.refreshPattern()
|
||||
this.pageToast('Value cannot be negative, so reset')
|
||||
frequencyNumberChange (val) {
|
||||
if (this.frequencyNumberInput == null || isNaN(val)) {
|
||||
return false
|
||||
}
|
||||
val = parseInt(val)
|
||||
if (val < 1) {
|
||||
this.frequencyNumberInput = '1'
|
||||
this.frequencyNumber = 1
|
||||
this.pageToast('Reset to 1 Hz')
|
||||
} else if (val > 20000) {
|
||||
this.frequencyNumberInput = '20000'
|
||||
this.frequencyNumber = 20000
|
||||
this.pageToast('Reset to 20000 Hz')
|
||||
} else {
|
||||
this.frequencyNumberInput = val.toString()
|
||||
this.frequencyNumber = val
|
||||
}
|
||||
|
||||
this.periodNumber = (1e6 / this.frequencyNumber).toFixed(3) // us
|
||||
this.periodNumberInput = String(this.periodNumber / this.unitMultiply)
|
||||
|
||||
this.autoResetAllTRange()
|
||||
|
||||
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) {
|
||||
this.updateTimeRange()
|
||||
}
|
||||
this.updateStiTRangeCheckParam()
|
||||
},
|
||||
periodNumberChange (val) {
|
||||
const usVal = parseFloat(val * this.unitMultiply) // us
|
||||
if (this.periodNumberInput == null || isNaN(usVal)) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (usVal < 50) { // freq: 1 to 20000Hz, so period > 50us (1e6/50=20000)
|
||||
this.periodNumber = 50
|
||||
this.periodNumberInput = String(50 / this.unitMultiply)
|
||||
this.pageToast('Reset to 50 us')
|
||||
} else if (usVal > 1e6) { // freq: 1 to 20000Hz, so period < 1e6us (1e6/1e6=1)
|
||||
this.periodNumber = 1e6
|
||||
this.periodNumberInput = String(1e6 / this.unitMultiply)
|
||||
this.pageToast('Reset to 1 s')
|
||||
} else {
|
||||
this.periodNumber = usVal
|
||||
this.periodNumberInput = val
|
||||
}
|
||||
|
||||
this.frequencyNumber = parseInt(1e6 / this.periodNumber)
|
||||
this.frequencyNumberInput = String(this.frequencyNumber)
|
||||
|
||||
this.autoResetAllTRange()
|
||||
|
||||
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) {
|
||||
this.updateTimeRange()
|
||||
}
|
||||
this.updateStiTRangeCheckParam()
|
||||
},
|
||||
timeRangeChange (stiIimeSelect, inputVal) {
|
||||
inputVal = parseFloat(inputVal)
|
||||
|
||||
switch (stiIimeSelect) {
|
||||
case 1:
|
||||
if (parseInt(val) === 0) {
|
||||
this.t1Range = 10
|
||||
this.t1RangeInput = String((this.t1Range * 10) / this.unitMultiply)
|
||||
if (this.patternModeSelect === 1) {
|
||||
this.t3Range = 10
|
||||
this.t3RangeInput = String((this.t3Range * 10) / this.unitMultiply)
|
||||
}
|
||||
} else {
|
||||
this.t1Range = parseInt((val * this.unitMultiply) / 10)
|
||||
this.t1RangeInput = val
|
||||
if (this.patternModeSelect === 1) {
|
||||
this.t3Range = parseInt((val * this.unitMultiply) / 10)
|
||||
this.t3RangeInput = val
|
||||
}
|
||||
}
|
||||
this.t1RangeInput = inputVal
|
||||
this.t1Range = parseFloat((inputVal * this.unitMultiply) / 10)
|
||||
this.autoComputeT4()
|
||||
break
|
||||
case 2:
|
||||
this.t2Range = parseInt((val * this.unitMultiply) / 10)
|
||||
this.t2RangeInput = val
|
||||
this.t2RangeInput = inputVal
|
||||
this.t2Range = parseFloat((inputVal * this.unitMultiply) / 10)
|
||||
this.autoComputeT4()
|
||||
break
|
||||
case 3:
|
||||
if (parseInt(val) === 0) {
|
||||
this.t1Range = 10
|
||||
this.t1RangeInput = String((this.t1Range * 10) / this.unitMultiply)
|
||||
this.t3Range = 10
|
||||
this.t3RangeInput = String((this.t3Range * 10) / this.unitMultiply)
|
||||
} else {
|
||||
this.t1Range = parseInt((val * this.unitMultiply) / 10)
|
||||
this.t1RangeInput = val
|
||||
this.t3Range = parseInt((val * this.unitMultiply) / 10)
|
||||
this.t3RangeInput = val
|
||||
}
|
||||
this.t3RangeInput = inputVal
|
||||
this.t3Range = parseFloat((inputVal * this.unitMultiply) / 10)
|
||||
this.autoComputeT4()
|
||||
break
|
||||
case 4:
|
||||
this.t4Range = parseInt((val * this.unitMultiply) / 10)
|
||||
this.t4RangeInput = val
|
||||
if (this.frequencyNumber > 0) {
|
||||
if (this.patternModeSelect === 0) {
|
||||
this.t2Range = 0
|
||||
this.t3Range = 0
|
||||
this.t1Range = (this.periodNumber / 10) - this.t2Range - this.t3Range - this.t4Range
|
||||
this.t1RangeInput = String((this.t1Range * 10) / this.unitMultiply)
|
||||
if (parseInt(this.t1Range) < 0) {
|
||||
this.refreshPattern()
|
||||
this.pageToast('T1 value will be negative, so reset')
|
||||
return
|
||||
}
|
||||
} else if (this.patternModeSelect === 1) {
|
||||
this.t2Range = (this.periodNumber / 10) - this.t1Range - this.t3Range - this.t4Range
|
||||
this.t2RangeInput = String((this.t2Range * 10) / this.unitMultiply)
|
||||
if (parseInt(this.t2Range) < 0) {
|
||||
this.refreshPattern()
|
||||
this.pageToast('T2 value will be negative, so reset')
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
this.t4RangeInput = inputVal
|
||||
this.t4Range = parseFloat((inputVal * this.unitMultiply) / 10)
|
||||
break
|
||||
}
|
||||
if (this.frequencyNumber > 0 && stiIimeSelect !== 4) {
|
||||
this.t4Range = (this.periodNumber / 10) - this.t1Range - this.t2Range - this.t3Range
|
||||
this.t4RangeInput = String((this.t4Range * 10) / this.unitMultiply)
|
||||
}
|
||||
|
||||
if (this.t4Range < 0) {
|
||||
this.refreshPattern()
|
||||
this.pageToast('T4 Range will be negative, so reset')
|
||||
} else {
|
||||
const status1 = this.checkIndividualTRange(1, this.t1Range)
|
||||
const status2 = this.checkIndividualTRange(2, this.t2Range)
|
||||
const status3 = this.checkIndividualTRange(3, this.t3Range)
|
||||
const status4 = this.checkIndividualTRange(4, this.t4Range)
|
||||
if (status1 && status2 && status3 && status4) {
|
||||
this.resetAllTRangeErrorMsg({ totalT: 4 })
|
||||
this.updateTimeRange()
|
||||
}
|
||||
this.updateStiTRangeCheckParam()
|
||||
},
|
||||
|
||||
updateStiTRangeCheckParam () {
|
||||
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
|
||||
header: 'device_parameter/0',
|
||||
device: taskInfo.getRawDeviceID(this.deviceID),
|
||||
parameter: 'sti_trange_set_done',
|
||||
content: this.TRangeStatusCheck,
|
||||
}))
|
||||
},
|
||||
autoResetAllTRange () {
|
||||
if (this.patternModeSelect === 0) { // Monophasic
|
||||
this.t1Range = 10
|
||||
this.t1RangeInput = String((this.t1Range * 10) / this.unitMultiply)
|
||||
this.t4Range = this.periodNumber / 10 - this.t1Range
|
||||
this.t4RangeInput = String((this.t4Range * 10) / this.unitMultiply)
|
||||
} else if (this.patternModeSelect === 1) { // Biphasic
|
||||
this.t1Range = 10
|
||||
this.t1RangeInput = String((this.t1Range * 10) / this.unitMultiply)
|
||||
this.t2Range = 10
|
||||
this.t2RangeInput = String((this.t2Range * 10) / this.unitMultiply)
|
||||
this.t3Range = 10
|
||||
this.t3RangeInput = String((this.t3Range * 10) / this.unitMultiply)
|
||||
this.t4Range = this.periodNumber / 10 - this.t1Range - this.t2Range - this.t3Range
|
||||
this.t4RangeInput = String((this.t4Range * 10) / this.unitMultiply)
|
||||
}
|
||||
},
|
||||
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')
|
||||
},
|
||||
|
||||
// [SubRegion] check sti T range setting helper function
|
||||
// update individual t range error msg
|
||||
updateTRangeErrorMsg (payload) {
|
||||
const index = payload.stiIimeSelect - 1
|
||||
this.TRangeErrorMsgList[index].showError = payload.status
|
||||
this.TRangeErrorMsgList[index].errorMsg[0] = payload.msg
|
||||
},
|
||||
resetAllTRangeErrorMsg (payload) {
|
||||
for (let i = 1; i <= payload.totalT; i++) {
|
||||
this.updateTRangeErrorMsg({ stiIimeSelect: i, status: false, msg: '' })
|
||||
}
|
||||
},
|
||||
checkIndividualTRange (stiIimeSelect, val) {
|
||||
// val unit: us
|
||||
val = parseFloat(val) * 10 // UI us
|
||||
if (val < 0 || isNaN(val)) {
|
||||
this.updateTRangeErrorMsg({ stiIimeSelect: stiIimeSelect, status: true, msg: 'T > 0' })
|
||||
return false
|
||||
}
|
||||
|
||||
switch (stiIimeSelect) {
|
||||
case 1:
|
||||
if (val < 100 || val > 10230) { // us
|
||||
this.updateTRangeErrorMsg({ stiIimeSelect: stiIimeSelect, status: true, msg: '0.1ms <= T1 <= 10.23ms' })
|
||||
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 {
|
||||
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 {
|
||||
this.updateTRangeErrorMsg({ stiIimeSelect: stiIimeSelect, status: false, msg: '' })
|
||||
return true
|
||||
}
|
||||
case 4:
|
||||
if (val < 0 || val > 1310710) { // us
|
||||
this.updateTRangeErrorMsg({ stiIimeSelect: stiIimeSelect, status: true, msg: '0ms <= T4 <= 1310.71ms' })
|
||||
return false
|
||||
} else {
|
||||
this.updateTRangeErrorMsg({ stiIimeSelect: stiIimeSelect, status: false, msg: '' })
|
||||
return true
|
||||
}
|
||||
}
|
||||
},
|
||||
// [EndSubRegion]
|
||||
// [EndRegion]
|
||||
|
||||
updateStiChannel () {
|
||||
// stiChannelSet (+,-), stiPolaritySet (+)
|
||||
let stiChannelSet = ''
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
<template>
|
||||
<div>
|
||||
<e-initial :ref="'EInitial'" :deviceID="deviceID" :parameterName="'E_initial'" @parameterChange="deviceParameterChange($event)" />
|
||||
<e-1 :ref="'E1'" :deviceID="deviceID" :parameterName="'E1'" @parameterChange="deviceParameterChange($event)" />
|
||||
<e-2 :ref="'E2'" :deviceID="deviceID" :parameterName="'E1'" @parameterChange="deviceParameterChange($event)" />
|
||||
<e-final :ref="'EFinal'" :deviceID="deviceID" :parameterName="'E_final'" @parameterChange="deviceParameterChange($event)" />
|
||||
<pulse-amp :ref="'PulseAmp'" :deviceID="deviceID" :parameterName="'Pulse_Amp'" @parameterChange="deviceParameterChange($event)" />
|
||||
<pulse-width :ref="'PulseWidth'" :deviceID="deviceID" :parameterName="'Pulse_Width'" @parameterChange="deviceParameterChange($event)" />
|
||||
<increment :ref="'Increment'" :deviceID="deviceID" :parameterName="'Increment'" @parameterChange="deviceParameterChange($event)" />
|
||||
<step-time :ref="'StepTime'" :deviceID="deviceID" :parameterName="'Step_time'" @parameterChange="deviceParameterChange($event)" />
|
||||
<current-recording-period :ref="'CURR_REC'" :deviceID="deviceID" :parameterName="'CURR_REC_'" @parameterChange="deviceParameterChange($event)" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import { taskInfo } from '@/data/task/TaskInfo'
|
||||
import EInitial from './EInitial'
|
||||
import E1 from './E1'
|
||||
import E2 from './E2'
|
||||
import EFinal from './EFinal'
|
||||
import PulseAmp from './PulseAmp'
|
||||
import PulseWidth from './PulseWidth'
|
||||
import Increment from './Increment'
|
||||
import StepTime from './StepTime'
|
||||
import CurrentRecordingPeriod from './CurrentRecordingPeriod'
|
||||
|
||||
export default {
|
||||
name: 'SegmentBlock',
|
||||
components: {
|
||||
EInitial,
|
||||
E1,
|
||||
E2,
|
||||
EFinal,
|
||||
PulseAmp,
|
||||
PulseWidth,
|
||||
Increment,
|
||||
StepTime,
|
||||
CurrentRecordingPeriod,
|
||||
},
|
||||
props: {
|
||||
deviceID: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
created () {
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
}
|
||||
},
|
||||
mqtt: {
|
||||
},
|
||||
methods: {
|
||||
mqttPub: function (topic, mes) {
|
||||
this.$mqtt.publish(topic, mes)
|
||||
},
|
||||
// Array[String of Parameter Name, Value]
|
||||
deviceParameterChange: function (e) {
|
||||
console.log('e[0],e[1]', e[0], ',', e[1])
|
||||
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
|
||||
header: 'device_parameter/0',
|
||||
device: taskInfo.getRawDeviceID(this.deviceID),
|
||||
parameter: e[0],
|
||||
content: e[1],
|
||||
}))
|
||||
},
|
||||
refresh () {
|
||||
if (this.$refs.EInitial != null) {
|
||||
this.$refs.EInitial.refresh()
|
||||
}
|
||||
if (this.$refs.EFinal != null) {
|
||||
this.$refs.EFinal.refresh()
|
||||
}
|
||||
if (this.$refs.PulseAmp != null) {
|
||||
this.$refs.PulseAmp.refresh()
|
||||
}
|
||||
if (this.$refs.PulseWidth != null) {
|
||||
this.$refs.PulseWidth.refresh()
|
||||
}
|
||||
if (this.$refs.Increment != null) {
|
||||
this.$refs.Increment.refresh()
|
||||
}
|
||||
if (this.$refs.StepTime != null) {
|
||||
this.$refs.StepTime.refresh()
|
||||
}
|
||||
},
|
||||
},
|
||||
mounted () {
|
||||
this.refresh()
|
||||
},
|
||||
watch: {
|
||||
},
|
||||
destroyed () {
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,89 @@
|
||||
<template>
|
||||
<div>
|
||||
<e-initial :ref="'EInitial'" :deviceID="deviceID" :parameterName="'E_initial'" @parameterChange="deviceParameterChange($event)" />
|
||||
<e-final :ref="'EFinal'" :deviceID="deviceID" :parameterName="'E_final'" @parameterChange="deviceParameterChange($event)" />
|
||||
<pulse-amp :ref="'PulseAmp'" :deviceID="deviceID" :parameterName="'Pulse_Amp'" @parameterChange="deviceParameterChange($event)" />
|
||||
<pulse-width :ref="'PulseWidth'" :deviceID="deviceID" :parameterName="'Pulse_Width'" @parameterChange="deviceParameterChange($event)" />
|
||||
<increment :ref="'Increment'" :deviceID="deviceID" :parameterName="'Increment'" @parameterChange="deviceParameterChange($event)" />
|
||||
<step-time :ref="'StepTime'" :deviceID="deviceID" :parameterName="'Step_time'" @parameterChange="deviceParameterChange($event)" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import { taskInfo } from '@/data/task/TaskInfo'
|
||||
import EInitial from './EInitial'
|
||||
import EFinal from './EFinal'
|
||||
import PulseAmp from './PulseAmp'
|
||||
import PulseWidth from './PulseWidth'
|
||||
import Increment from './Increment'
|
||||
import StepTime from './StepTime'
|
||||
|
||||
export default {
|
||||
name: 'SegmentBlock',
|
||||
components: {
|
||||
EInitial,
|
||||
EFinal,
|
||||
PulseAmp,
|
||||
PulseWidth,
|
||||
Increment,
|
||||
StepTime,
|
||||
},
|
||||
props: {
|
||||
deviceID: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
created () {
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
}
|
||||
},
|
||||
mqtt: {
|
||||
},
|
||||
methods: {
|
||||
mqttPub: function (topic, mes) {
|
||||
this.$mqtt.publish(topic, mes)
|
||||
},
|
||||
// Array[String of Parameter Name, Value]
|
||||
deviceParameterChange: function (e) {
|
||||
console.log('e[0],e[1]', e[0], ',', e[1])
|
||||
this.mqttPub(taskInfo.getTaskInfo().controllerID + '_user', JSON.stringify({
|
||||
header: 'device_parameter/0',
|
||||
device: taskInfo.getRawDeviceID(this.deviceID),
|
||||
parameter: e[0],
|
||||
content: e[1],
|
||||
}))
|
||||
},
|
||||
refresh () {
|
||||
if (this.$refs.EInitial != null) {
|
||||
this.$refs.EInitial.refresh()
|
||||
}
|
||||
if (this.$refs.EFinal != null) {
|
||||
this.$refs.EFinal.refresh()
|
||||
}
|
||||
if (this.$refs.PulseAmp != null) {
|
||||
this.$refs.PulseAmp.refresh()
|
||||
}
|
||||
if (this.$refs.PulseWidth != null) {
|
||||
this.$refs.PulseWidth.refresh()
|
||||
}
|
||||
if (this.$refs.Increment != null) {
|
||||
this.$refs.Increment.refresh()
|
||||
}
|
||||
if (this.$refs.StepTime != null) {
|
||||
this.$refs.StepTime.refresh()
|
||||
}
|
||||
},
|
||||
},
|
||||
mounted () {
|
||||
this.refresh()
|
||||
},
|
||||
watch: {
|
||||
},
|
||||
destroyed () {
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,101 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="row flex sm12 xl12 md12 xs12 align--center">
|
||||
<div class="flex sm9 xl9 md9 xs9 px-0 mx-0">
|
||||
<p class="display-6">Current Recording Period<p/>
|
||||
</div>
|
||||
<div class="flex sm3 xl3 md3 xs3 px-0 mx-0">
|
||||
<p small> {{ itemInput }} ~ 100% </p>
|
||||
<!-- <va-input
|
||||
@mouseleave.native="itemChange(itemInput)"
|
||||
@keyup.enter="itemChange(itemInput)"
|
||||
@blur="itemChange(itemInput)"
|
||||
v-model="itemInput"
|
||||
class="mb-0"
|
||||
>
|
||||
<p slot="append" style="margin-right: 0;" small>
|
||||
%
|
||||
</p>
|
||||
</va-input> -->
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex sm12 xl12 md12 xs12" :key="inputeKey">
|
||||
<va-slider
|
||||
@mouseup.native="itemChange(itemInput)"
|
||||
@mouseleave.native="itemChange(itemInput)"
|
||||
@touchend.native="itemChange(itemInput)"
|
||||
pins
|
||||
:min="0"
|
||||
:max="90"
|
||||
value-visible
|
||||
:step="10"
|
||||
v-model="itemInput"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import { taskInfo } from '@/data/task/TaskInfo'
|
||||
|
||||
export default {
|
||||
name: 'CurrentRecordingPeriod',
|
||||
components: {
|
||||
},
|
||||
props: {
|
||||
deviceID: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
parameterName: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
created () {
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
disableSlider: false,
|
||||
inputeKey: 0,
|
||||
itemInput: Math.round(taskInfo.getDeviceInfo(this.deviceID).parameterSet[this.parameterName]),
|
||||
// duration: Math.round(taskInfo.getDeviceInfo(this.deviceID).parameterSet['t_pulse_' + String(this.segmentID)]) / 10,
|
||||
}
|
||||
},
|
||||
mqtt: {
|
||||
},
|
||||
methods: {
|
||||
itemChange (val) {
|
||||
this.itemInput = val
|
||||
this.$emit('parameterChange', [this.parameterName, val])
|
||||
},
|
||||
checkSliderRange (duration) {
|
||||
if (duration <= 10) {
|
||||
this.disableSlider = true
|
||||
} else {
|
||||
this.disableSlider = false
|
||||
const percent = parseFloat((5 / duration) * 100)
|
||||
if (percent > 5) {
|
||||
this.itemChange([this.itemInputMin, this.itemInputMax])
|
||||
} else if (percent >= 1.1 && percent <= 5) {
|
||||
this.itemChange([this.itemInputMin, this.itemInputMax])
|
||||
} else if (percent < 1.1) {
|
||||
this.itemChange([this.itemInputMin, this.itemInputMax])
|
||||
}
|
||||
}
|
||||
},
|
||||
refresh () {
|
||||
// this.itemInput
|
||||
// this.duration = Math.round(taskInfo.getDeviceInfo(this.deviceID).parameterSet['t_pulse_' + String(this.segmentID)]) / 10
|
||||
},
|
||||
},
|
||||
async mounted () {
|
||||
// this.checkSliderRange(this.duration)
|
||||
},
|
||||
destroyed () {
|
||||
},
|
||||
watch: {
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,121 @@
|
||||
<template>
|
||||
<div class="flex-container">
|
||||
<p class="display-6 flex-child">E 1<p/>
|
||||
<va-input
|
||||
@mouseleave.native="itemChange(itemInput)"
|
||||
@keyup.enter="itemChange(itemInput)"
|
||||
@blur="itemChange(itemInput)"
|
||||
v-model="itemInput"
|
||||
class="mb-0 flex-child1"
|
||||
:error="showError"
|
||||
:error-messages="errorMsg"
|
||||
>
|
||||
</va-input>
|
||||
<va-button
|
||||
@click="unitChange()"
|
||||
v-model="unitSelect"
|
||||
class="px-2 py-0 mr-0 flex-child2"
|
||||
>
|
||||
{{ unitSelect }}
|
||||
</va-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import { taskInfo } from '@/data/task/TaskInfo'
|
||||
|
||||
export default {
|
||||
name: 'E1',
|
||||
components: {
|
||||
},
|
||||
props: {
|
||||
deviceID: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
parameterName: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
created () {
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
inputeKey: 0,
|
||||
itemInput: String(Math.round((taskInfo.getDeviceInfo(this.deviceID).parameterSet[this.parameterName + String(this.segmentID)] - 25000) / 5)),
|
||||
unitSelect: 'mV',
|
||||
unitClickTime: 0,
|
||||
showError: false,
|
||||
errorMsg: [''],
|
||||
}
|
||||
},
|
||||
mqtt: {
|
||||
},
|
||||
methods: {
|
||||
itemChange (val) {
|
||||
this.itemInput = val
|
||||
this.inputeKey++
|
||||
this.showError = false
|
||||
this.errorMsg[0] = ''
|
||||
if (this.unitSelect === 'V') {
|
||||
val = parseFloat(val) * 1000
|
||||
}
|
||||
if (parseInt(val) < -5000 || parseInt(val) > 5000) {
|
||||
this.showError = true
|
||||
this.errorMsg[0] = '-5 ~ 5V'
|
||||
return
|
||||
}
|
||||
if (parseFloat(val) !== Math.round((taskInfo.getDeviceInfo(this.deviceID).parameterSet[this.parameterName + String(this.segmentID)] - 25000) / 5)) {
|
||||
this.$emit('parameterChange', [this.parameterName + String(this.segmentID), parseFloat(val) * 5 + 25000])
|
||||
}
|
||||
},
|
||||
unitChange () {
|
||||
this.unitClickTime += 1
|
||||
if (this.unitClickTime % 2 === 0) {
|
||||
this.unitSelect = 'mV'
|
||||
this.itemInput = String(parseFloat(this.itemInput) * 1000)
|
||||
} else {
|
||||
this.unitSelect = 'V'
|
||||
this.itemInput = String(parseFloat(this.itemInput) / 1000)
|
||||
}
|
||||
},
|
||||
refresh () {
|
||||
let volt = Math.round((taskInfo.getDeviceInfo(this.deviceID).parameterSet[this.parameterName + String(this.segmentID)] - 25000) / 5)
|
||||
if (this.unitSelect === 'V') {
|
||||
volt /= 1000
|
||||
}
|
||||
this.itemInput = String(volt)
|
||||
},
|
||||
},
|
||||
async mounted () {
|
||||
},
|
||||
destroyed () {
|
||||
},
|
||||
watch: {
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.flex-container {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.flex-child {
|
||||
flex: 2;
|
||||
}
|
||||
|
||||
.flex-child1 {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.flex-child2 {
|
||||
flex: 0;
|
||||
}
|
||||
|
||||
.flex-child:first-child {
|
||||
margin-right: 1px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,121 @@
|
||||
<template>
|
||||
<div class="flex-container">
|
||||
<p class="display-6 flex-child">E 2<p/>
|
||||
<va-input
|
||||
@mouseleave.native="itemChange(itemInput)"
|
||||
@keyup.enter="itemChange(itemInput)"
|
||||
@blur="itemChange(itemInput)"
|
||||
v-model="itemInput"
|
||||
class="mb-0 flex-child1"
|
||||
:error="showError"
|
||||
:error-messages="errorMsg"
|
||||
>
|
||||
</va-input>
|
||||
<va-button
|
||||
@click="unitChange()"
|
||||
v-model="unitSelect"
|
||||
class="px-2 py-0 mr-0 flex-child2"
|
||||
>
|
||||
{{ unitSelect }}
|
||||
</va-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import { taskInfo } from '@/data/task/TaskInfo'
|
||||
|
||||
export default {
|
||||
name: 'E2',
|
||||
components: {
|
||||
},
|
||||
props: {
|
||||
deviceID: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
parameterName: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
created () {
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
inputeKey: 0,
|
||||
itemInput: String(Math.round((taskInfo.getDeviceInfo(this.deviceID).parameterSet[this.parameterName + String(this.segmentID)] - 25000) / 5)),
|
||||
unitSelect: 'mV',
|
||||
unitClickTime: 0,
|
||||
showError: false,
|
||||
errorMsg: [''],
|
||||
}
|
||||
},
|
||||
mqtt: {
|
||||
},
|
||||
methods: {
|
||||
itemChange (val) {
|
||||
this.itemInput = val
|
||||
this.inputeKey++
|
||||
this.showError = false
|
||||
this.errorMsg[0] = ''
|
||||
if (this.unitSelect === 'V') {
|
||||
val = parseFloat(val) * 1000
|
||||
}
|
||||
if (parseInt(val) < -5000 || parseInt(val) > 5000) {
|
||||
this.showError = true
|
||||
this.errorMsg[0] = '-5 ~ 5V'
|
||||
return
|
||||
}
|
||||
if (parseFloat(val) !== Math.round((taskInfo.getDeviceInfo(this.deviceID).parameterSet[this.parameterName + String(this.segmentID)] - 25000) / 5)) {
|
||||
this.$emit('parameterChange', [this.parameterName + String(this.segmentID), parseFloat(val) * 5 + 25000])
|
||||
}
|
||||
},
|
||||
unitChange () {
|
||||
this.unitClickTime += 1
|
||||
if (this.unitClickTime % 2 === 0) {
|
||||
this.unitSelect = 'mV'
|
||||
this.itemInput = String(parseFloat(this.itemInput) * 1000)
|
||||
} else {
|
||||
this.unitSelect = 'V'
|
||||
this.itemInput = String(parseFloat(this.itemInput) / 1000)
|
||||
}
|
||||
},
|
||||
refresh () {
|
||||
let volt = Math.round((taskInfo.getDeviceInfo(this.deviceID).parameterSet[this.parameterName + String(this.segmentID)] - 25000) / 5)
|
||||
if (this.unitSelect === 'V') {
|
||||
volt /= 1000
|
||||
}
|
||||
this.itemInput = String(volt)
|
||||
},
|
||||
},
|
||||
async mounted () {
|
||||
},
|
||||
destroyed () {
|
||||
},
|
||||
watch: {
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.flex-container {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.flex-child {
|
||||
flex: 2;
|
||||
}
|
||||
|
||||
.flex-child1 {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.flex-child2 {
|
||||
flex: 0;
|
||||
}
|
||||
|
||||
.flex-child:first-child {
|
||||
margin-right: 1px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,121 @@
|
||||
<template>
|
||||
<div class="flex-container">
|
||||
<p class="display-6 flex-child">E Final<p/>
|
||||
<va-input
|
||||
@mouseleave.native="itemChange(itemInput)"
|
||||
@keyup.enter="itemChange(itemInput)"
|
||||
@blur="itemChange(itemInput)"
|
||||
v-model="itemInput"
|
||||
class="mb-0 flex-child1"
|
||||
:error="showError"
|
||||
:error-messages="errorMsg"
|
||||
>
|
||||
</va-input>
|
||||
<va-button
|
||||
@click="unitChange()"
|
||||
v-model="unitSelect"
|
||||
class="px-2 py-0 mr-0 flex-child2"
|
||||
>
|
||||
{{ unitSelect }}
|
||||
</va-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import { taskInfo } from '@/data/task/TaskInfo'
|
||||
|
||||
export default {
|
||||
name: 'EFinal',
|
||||
components: {
|
||||
},
|
||||
props: {
|
||||
deviceID: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
parameterName: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
created () {
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
inputeKey: 0,
|
||||
itemInput: String(Math.round((taskInfo.getDeviceInfo(this.deviceID).parameterSet[this.parameterName + String(this.segmentID)] - 25000) / 5)),
|
||||
unitSelect: 'mV',
|
||||
unitClickTime: 0,
|
||||
showError: false,
|
||||
errorMsg: [''],
|
||||
}
|
||||
},
|
||||
mqtt: {
|
||||
},
|
||||
methods: {
|
||||
itemChange (val) {
|
||||
this.itemInput = val
|
||||
this.inputeKey++
|
||||
this.showError = false
|
||||
this.errorMsg[0] = ''
|
||||
if (this.unitSelect === 'V') {
|
||||
val = parseFloat(val) * 1000
|
||||
}
|
||||
if (parseInt(val) < -5000 || parseInt(val) > 5000) {
|
||||
this.showError = true
|
||||
this.errorMsg[0] = '-5 ~ 5V'
|
||||
return
|
||||
}
|
||||
if (parseFloat(val) !== Math.round((taskInfo.getDeviceInfo(this.deviceID).parameterSet[this.parameterName + String(this.segmentID)] - 25000) / 5)) {
|
||||
this.$emit('parameterChange', [this.parameterName + String(this.segmentID), parseFloat(val) * 5 + 25000])
|
||||
}
|
||||
},
|
||||
unitChange () {
|
||||
this.unitClickTime += 1
|
||||
if (this.unitClickTime % 2 === 0) {
|
||||
this.unitSelect = 'mV'
|
||||
this.itemInput = String(parseFloat(this.itemInput) * 1000)
|
||||
} else {
|
||||
this.unitSelect = 'V'
|
||||
this.itemInput = String(parseFloat(this.itemInput) / 1000)
|
||||
}
|
||||
},
|
||||
refresh () {
|
||||
let volt = Math.round((taskInfo.getDeviceInfo(this.deviceID).parameterSet[this.parameterName + String(this.segmentID)] - 25000) / 5)
|
||||
if (this.unitSelect === 'V') {
|
||||
volt /= 1000
|
||||
}
|
||||
this.itemInput = String(volt)
|
||||
},
|
||||
},
|
||||
async mounted () {
|
||||
},
|
||||
destroyed () {
|
||||
},
|
||||
watch: {
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.flex-container {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.flex-child {
|
||||
flex: 2;
|
||||
}
|
||||
|
||||
.flex-child1 {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.flex-child2 {
|
||||
flex: 0;
|
||||
}
|
||||
|
||||
.flex-child:first-child {
|
||||
margin-right: 1px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,121 @@
|
||||
<template>
|
||||
<div class="flex-container">
|
||||
<p class="display-6 flex-child">E Initial<p/>
|
||||
<va-input
|
||||
@mouseleave.native="itemChange(itemInput)"
|
||||
@keyup.enter="itemChange(itemInput)"
|
||||
@blur="itemChange(itemInput)"
|
||||
v-model="itemInput"
|
||||
class="mb-0 flex-child1"
|
||||
:error="showError"
|
||||
:error-messages="errorMsg"
|
||||
>
|
||||
</va-input>
|
||||
<va-button
|
||||
@click="unitChange()"
|
||||
v-model="unitSelect"
|
||||
class="px-2 py-0 mr-0 flex-child2"
|
||||
>
|
||||
{{ unitSelect }}
|
||||
</va-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import { taskInfo } from '@/data/task/TaskInfo'
|
||||
|
||||
export default {
|
||||
name: 'EInitial',
|
||||
components: {
|
||||
},
|
||||
props: {
|
||||
deviceID: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
parameterName: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
created () {
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
inputeKey: 0,
|
||||
itemInput: String(Math.round((taskInfo.getDeviceInfo(this.deviceID).parameterSet[this.parameterName + String(this.segmentID)] - 25000) / 5)),
|
||||
unitSelect: 'mV',
|
||||
unitClickTime: 0,
|
||||
showError: false,
|
||||
errorMsg: [''],
|
||||
}
|
||||
},
|
||||
mqtt: {
|
||||
},
|
||||
methods: {
|
||||
itemChange (val) {
|
||||
this.itemInput = val
|
||||
this.inputeKey++
|
||||
this.showError = false
|
||||
this.errorMsg[0] = ''
|
||||
if (this.unitSelect === 'V') {
|
||||
val = parseFloat(val) * 1000
|
||||
}
|
||||
if (parseInt(val) < -5000 || parseInt(val) > 5000) {
|
||||
this.showError = true
|
||||
this.errorMsg[0] = '-5 ~ 5V'
|
||||
return
|
||||
}
|
||||
if (parseFloat(val) !== Math.round((taskInfo.getDeviceInfo(this.deviceID).parameterSet[this.parameterName + String(this.segmentID)] - 25000) / 5)) {
|
||||
this.$emit('parameterChange', [this.parameterName + String(this.segmentID), parseFloat(val) * 5 + 25000])
|
||||
}
|
||||
},
|
||||
unitChange () {
|
||||
this.unitClickTime += 1
|
||||
if (this.unitClickTime % 2 === 0) {
|
||||
this.unitSelect = 'mV'
|
||||
this.itemInput = String(parseFloat(this.itemInput) * 1000)
|
||||
} else {
|
||||
this.unitSelect = 'V'
|
||||
this.itemInput = String(parseFloat(this.itemInput) / 1000)
|
||||
}
|
||||
},
|
||||
refresh () {
|
||||
let volt = Math.round((taskInfo.getDeviceInfo(this.deviceID).parameterSet[this.parameterName + String(this.segmentID)] - 25000) / 5)
|
||||
if (this.unitSelect === 'V') {
|
||||
volt /= 1000
|
||||
}
|
||||
this.itemInput = String(volt)
|
||||
},
|
||||
},
|
||||
async mounted () {
|
||||
},
|
||||
destroyed () {
|
||||
},
|
||||
watch: {
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.flex-container {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.flex-child {
|
||||
flex: 2;
|
||||
}
|
||||
|
||||
.flex-child1 {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.flex-child2 {
|
||||
flex: 0;
|
||||
}
|
||||
|
||||
.flex-child:first-child {
|
||||
margin-right: 1px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,121 @@
|
||||
<template>
|
||||
<div class="flex-container">
|
||||
<p class="display-6 flex-child">Increment<p/>
|
||||
<va-input
|
||||
@mouseleave.native="itemChange(itemInput)"
|
||||
@keyup.enter="itemChange(itemInput)"
|
||||
@blur="itemChange(itemInput)"
|
||||
v-model="itemInput"
|
||||
class="mb-0 flex-child1"
|
||||
:error="showError"
|
||||
:error-messages="errorMsg"
|
||||
>
|
||||
</va-input>
|
||||
<va-button
|
||||
@click="unitChange()"
|
||||
v-model="unitSelect"
|
||||
class="px-2 py-0 mr-0 flex-child2"
|
||||
>
|
||||
{{ unitSelect }}
|
||||
</va-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import { taskInfo } from '@/data/task/TaskInfo'
|
||||
|
||||
export default {
|
||||
name: 'Increment',
|
||||
components: {
|
||||
},
|
||||
props: {
|
||||
deviceID: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
parameterName: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
created () {
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
inputeKey: 0,
|
||||
itemInput: String(Math.round((taskInfo.getDeviceInfo(this.deviceID).parameterSet[this.parameterName + String(this.segmentID)] - 25000) / 5)),
|
||||
unitSelect: 'mV',
|
||||
unitClickTime: 0,
|
||||
showError: false,
|
||||
errorMsg: [''],
|
||||
}
|
||||
},
|
||||
mqtt: {
|
||||
},
|
||||
methods: {
|
||||
itemChange (val) {
|
||||
this.itemInput = val
|
||||
this.inputeKey++
|
||||
this.showError = false
|
||||
this.errorMsg[0] = ''
|
||||
if (this.unitSelect === 'V') {
|
||||
val = parseFloat(val) * 1000
|
||||
}
|
||||
if (parseInt(val) < -5000 || parseInt(val) > 5000) {
|
||||
this.showError = true
|
||||
this.errorMsg[0] = '-5 ~ 5V'
|
||||
return
|
||||
}
|
||||
if (parseFloat(val) !== Math.round((taskInfo.getDeviceInfo(this.deviceID).parameterSet[this.parameterName + String(this.segmentID)] - 25000) / 5)) {
|
||||
this.$emit('parameterChange', [this.parameterName + String(this.segmentID), parseFloat(val) * 5 + 25000])
|
||||
}
|
||||
},
|
||||
unitChange () {
|
||||
this.unitClickTime += 1
|
||||
if (this.unitClickTime % 2 === 0) {
|
||||
this.unitSelect = 'mV'
|
||||
this.itemInput = String(parseFloat(this.itemInput) * 1000)
|
||||
} else {
|
||||
this.unitSelect = 'V'
|
||||
this.itemInput = String(parseFloat(this.itemInput) / 1000)
|
||||
}
|
||||
},
|
||||
refresh () {
|
||||
let volt = Math.round((taskInfo.getDeviceInfo(this.deviceID).parameterSet[this.parameterName + String(this.segmentID)] - 25000) / 5)
|
||||
if (this.unitSelect === 'V') {
|
||||
volt /= 1000
|
||||
}
|
||||
this.itemInput = String(volt)
|
||||
},
|
||||
},
|
||||
async mounted () {
|
||||
},
|
||||
destroyed () {
|
||||
},
|
||||
watch: {
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.flex-container {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.flex-child {
|
||||
flex: 2;
|
||||
}
|
||||
|
||||
.flex-child1 {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.flex-child2 {
|
||||
flex: 0;
|
||||
}
|
||||
|
||||
.flex-child:first-child {
|
||||
margin-right: 1px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,121 @@
|
||||
<template>
|
||||
<div class="flex-container">
|
||||
<p class="display-6 flex-child">Pulse Amplitude<p/>
|
||||
<va-input
|
||||
@mouseleave.native="itemChange(itemInput)"
|
||||
@keyup.enter="itemChange(itemInput)"
|
||||
@blur="itemChange(itemInput)"
|
||||
v-model="itemInput"
|
||||
class="mb-0 flex-child1"
|
||||
:error="showError"
|
||||
:error-messages="errorMsg"
|
||||
>
|
||||
</va-input>
|
||||
<va-button
|
||||
@click="unitChange()"
|
||||
v-model="unitSelect"
|
||||
class="px-2 py-0 mr-0 flex-child2"
|
||||
>
|
||||
{{ unitSelect }}
|
||||
</va-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import { taskInfo } from '@/data/task/TaskInfo'
|
||||
|
||||
export default {
|
||||
name: 'PulseAmp',
|
||||
components: {
|
||||
},
|
||||
props: {
|
||||
deviceID: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
parameterName: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
created () {
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
inputeKey: 0,
|
||||
itemInput: String(Math.round((taskInfo.getDeviceInfo(this.deviceID).parameterSet[this.parameterName + String(this.segmentID)] - 25000) / 5)),
|
||||
unitSelect: 'mV',
|
||||
unitClickTime: 0,
|
||||
showError: false,
|
||||
errorMsg: [''],
|
||||
}
|
||||
},
|
||||
mqtt: {
|
||||
},
|
||||
methods: {
|
||||
itemChange (val) {
|
||||
this.itemInput = val
|
||||
this.inputeKey++
|
||||
this.showError = false
|
||||
this.errorMsg[0] = ''
|
||||
if (this.unitSelect === 'V') {
|
||||
val = parseFloat(val) * 1000
|
||||
}
|
||||
if (parseInt(val) < -5000 || parseInt(val) > 5000) {
|
||||
this.showError = true
|
||||
this.errorMsg[0] = '-5 ~ 5V'
|
||||
return
|
||||
}
|
||||
if (parseFloat(val) !== Math.round((taskInfo.getDeviceInfo(this.deviceID).parameterSet[this.parameterName + String(this.segmentID)] - 25000) / 5)) {
|
||||
this.$emit('parameterChange', [this.parameterName + String(this.segmentID), parseFloat(val) * 5 + 25000])
|
||||
}
|
||||
},
|
||||
unitChange () {
|
||||
this.unitClickTime += 1
|
||||
if (this.unitClickTime % 2 === 0) {
|
||||
this.unitSelect = 'mV'
|
||||
this.itemInput = String(parseFloat(this.itemInput) * 1000)
|
||||
} else {
|
||||
this.unitSelect = 'V'
|
||||
this.itemInput = String(parseFloat(this.itemInput) / 1000)
|
||||
}
|
||||
},
|
||||
refresh () {
|
||||
let volt = Math.round((taskInfo.getDeviceInfo(this.deviceID).parameterSet[this.parameterName + String(this.segmentID)] - 25000) / 5)
|
||||
if (this.unitSelect === 'V') {
|
||||
volt /= 1000
|
||||
}
|
||||
this.itemInput = String(volt)
|
||||
},
|
||||
},
|
||||
async mounted () {
|
||||
},
|
||||
destroyed () {
|
||||
},
|
||||
watch: {
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.flex-container {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.flex-child {
|
||||
flex: 2;
|
||||
}
|
||||
|
||||
.flex-child1 {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.flex-child2 {
|
||||
flex: 0;
|
||||
}
|
||||
|
||||
.flex-child:first-child {
|
||||
margin-right: 1px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,130 @@
|
||||
<template>
|
||||
<div class="flex-container">
|
||||
<p class="display-6 flex-child">Pulse Width<p/>
|
||||
<va-input
|
||||
@mouseleave.native="itemChange(itemInput)"
|
||||
@keyup.enter="itemChange(itemInput)"
|
||||
@blur="itemChange(itemInput)"
|
||||
v-model="itemInput"
|
||||
class="mb-0 flex-child1"
|
||||
:error="showError"
|
||||
:error-messages="errorMsg"
|
||||
>
|
||||
</va-input>
|
||||
<va-button
|
||||
@click="unitChange()"
|
||||
v-model="unitSelect"
|
||||
class="px-2 py-0 mr-0 flex-child2"
|
||||
>
|
||||
{{ unitSelect }}
|
||||
</va-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import { taskInfo } from '@/data/task/TaskInfo'
|
||||
|
||||
export default {
|
||||
name: 'PulseWidth',
|
||||
components: {
|
||||
},
|
||||
props: {
|
||||
deviceID: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
parameterName: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
created () {
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
inputeKey: 0,
|
||||
itemInput: String(Math.round((taskInfo.getDeviceInfo(this.deviceID).parameterSet[this.parameterName + String(this.segmentID)]) / 10)),
|
||||
unitSelect: 'msec',
|
||||
unitClickTime: 0,
|
||||
showError: false,
|
||||
errorMsg: [''],
|
||||
}
|
||||
},
|
||||
mqtt: {
|
||||
},
|
||||
methods: {
|
||||
itemChange (val) {
|
||||
this.itemInput = val
|
||||
this.inputeKey++
|
||||
this.showError = false
|
||||
this.errorMsg[0] = ''
|
||||
if (this.unitSelect === 'sec') {
|
||||
val = parseInt(val) * 1000
|
||||
}
|
||||
|
||||
// 5 ms a step
|
||||
const remainder = parseInt(val) % 5
|
||||
if (remainder !== 0) {
|
||||
val = parseInt(val) + (5 - remainder)
|
||||
}
|
||||
if (parseInt(val) < 1 || parseInt(val) > 100000) {
|
||||
this.showError = true
|
||||
this.errorMsg[0] = '1ms ~ 100s'
|
||||
return
|
||||
}
|
||||
if (parseFloat(val) !== Math.round(taskInfo.getDeviceInfo(this.deviceID).parameterSet[this.parameterName + String(this.segmentID)] / 10)) {
|
||||
this.$emit('parameterChange', [this.parameterName + String(this.segmentID), parseInt(val) * 10])
|
||||
this.$emit('checkCurrentRecording', val)
|
||||
}
|
||||
},
|
||||
unitChange () {
|
||||
this.unitClickTime += 1
|
||||
if (this.unitClickTime % 2 === 0) {
|
||||
this.unitSelect = 'msec'
|
||||
this.itemInput = String(parseFloat(this.itemInput) * 1000)
|
||||
} else {
|
||||
this.unitSelect = 'sec'
|
||||
this.itemInput = String(parseFloat(this.itemInput) / 1000)
|
||||
}
|
||||
},
|
||||
refresh () {
|
||||
if (this.showError === false) {
|
||||
let duration = Math.round((taskInfo.getDeviceInfo(this.deviceID).parameterSet[this.parameterName + String(this.segmentID)]) / 10)
|
||||
if (this.unitSelect === 'sec') {
|
||||
duration /= 1000
|
||||
}
|
||||
this.itemInput = String(duration)
|
||||
}
|
||||
},
|
||||
},
|
||||
async mounted () {
|
||||
},
|
||||
destroyed () {
|
||||
},
|
||||
watch: {
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.flex-container {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.flex-child {
|
||||
flex: 2;
|
||||
}
|
||||
|
||||
.flex-child1 {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.flex-child2 {
|
||||
flex: 0;
|
||||
}
|
||||
|
||||
.flex-child:first-child {
|
||||
margin-right: 1px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,130 @@
|
||||
<template>
|
||||
<div class="flex-container">
|
||||
<p class="display-6 flex-child">Step Time<p/>
|
||||
<va-input
|
||||
@mouseleave.native="itemChange(itemInput)"
|
||||
@keyup.enter="itemChange(itemInput)"
|
||||
@blur="itemChange(itemInput)"
|
||||
v-model="itemInput"
|
||||
class="mb-0 flex-child1"
|
||||
:error="showError"
|
||||
:error-messages="errorMsg"
|
||||
>
|
||||
</va-input>
|
||||
<va-button
|
||||
@click="unitChange()"
|
||||
v-model="unitSelect"
|
||||
class="px-2 py-0 mr-0 flex-child2"
|
||||
>
|
||||
{{ unitSelect }}
|
||||
</va-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import { taskInfo } from '@/data/task/TaskInfo'
|
||||
|
||||
export default {
|
||||
name: 'StepTime',
|
||||
components: {
|
||||
},
|
||||
props: {
|
||||
deviceID: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
parameterName: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
created () {
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
inputeKey: 0,
|
||||
itemInput: String(Math.round((taskInfo.getDeviceInfo(this.deviceID).parameterSet[this.parameterName + String(this.segmentID)]) / 10)),
|
||||
unitSelect: 'msec',
|
||||
unitClickTime: 0,
|
||||
showError: false,
|
||||
errorMsg: [''],
|
||||
}
|
||||
},
|
||||
mqtt: {
|
||||
},
|
||||
methods: {
|
||||
itemChange (val) {
|
||||
this.itemInput = val
|
||||
this.inputeKey++
|
||||
this.showError = false
|
||||
this.errorMsg[0] = ''
|
||||
if (this.unitSelect === 'sec') {
|
||||
val = parseInt(val) * 1000
|
||||
}
|
||||
|
||||
// 5 ms a step
|
||||
const remainder = parseInt(val) % 5
|
||||
if (remainder !== 0) {
|
||||
val = parseInt(val) + (5 - remainder)
|
||||
}
|
||||
if (parseInt(val) < 1 || parseInt(val) > 100000) {
|
||||
this.showError = true
|
||||
this.errorMsg[0] = '1ms ~ 100s'
|
||||
return
|
||||
}
|
||||
if (parseFloat(val) !== Math.round(taskInfo.getDeviceInfo(this.deviceID).parameterSet[this.parameterName + String(this.segmentID)] / 10)) {
|
||||
this.$emit('parameterChange', [this.parameterName + String(this.segmentID), parseInt(val) * 10])
|
||||
this.$emit('checkCurrentRecording', val)
|
||||
}
|
||||
},
|
||||
unitChange () {
|
||||
this.unitClickTime += 1
|
||||
if (this.unitClickTime % 2 === 0) {
|
||||
this.unitSelect = 'msec'
|
||||
this.itemInput = String(parseFloat(this.itemInput) * 1000)
|
||||
} else {
|
||||
this.unitSelect = 'sec'
|
||||
this.itemInput = String(parseFloat(this.itemInput) / 1000)
|
||||
}
|
||||
},
|
||||
refresh () {
|
||||
if (this.showError === false) {
|
||||
let duration = Math.round((taskInfo.getDeviceInfo(this.deviceID).parameterSet[this.parameterName + String(this.segmentID)]) / 10)
|
||||
if (this.unitSelect === 'sec') {
|
||||
duration /= 1000
|
||||
}
|
||||
this.itemInput = String(duration)
|
||||
}
|
||||
},
|
||||
},
|
||||
async mounted () {
|
||||
},
|
||||
destroyed () {
|
||||
},
|
||||
watch: {
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.flex-container {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.flex-child {
|
||||
flex: 2;
|
||||
}
|
||||
|
||||
.flex-child1 {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.flex-child2 {
|
||||
flex: 0;
|
||||
}
|
||||
|
||||
.flex-child:first-child {
|
||||
margin-right: 1px;
|
||||
}
|
||||
</style>
|
||||
@@ -41,24 +41,24 @@ export default {
|
||||
options: [
|
||||
{
|
||||
value: 0,
|
||||
label: 'Auto',
|
||||
},
|
||||
{
|
||||
value: 1,
|
||||
label: '1',
|
||||
},
|
||||
{
|
||||
value: 2,
|
||||
value: 1,
|
||||
label: '2',
|
||||
},
|
||||
{
|
||||
value: 3,
|
||||
value: 2,
|
||||
label: '3',
|
||||
},
|
||||
{
|
||||
value: 4,
|
||||
value: 3,
|
||||
label: '4',
|
||||
},
|
||||
{
|
||||
value: 4,
|
||||
label: 'Auto',
|
||||
},
|
||||
],
|
||||
itemSelect: taskInfo.getDeviceInfo(this.deviceID).parameterSet[this.parameterName],
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ export default {
|
||||
data () {
|
||||
return {
|
||||
inputeKey: 0,
|
||||
itemInput: String(parseInt((taskInfo.getDeviceInfo(this.deviceID).parameterSet[this.parameterName]) * 0.537 + 200)),
|
||||
itemInput: String(Math.round((taskInfo.getDeviceInfo(this.deviceID).parameterSet[this.parameterName]) * 2200 / 4095)),
|
||||
}
|
||||
},
|
||||
mqtt: {
|
||||
@@ -51,8 +51,8 @@ export default {
|
||||
itemChange (val) {
|
||||
this.itemInput = val
|
||||
this.inputeKey++
|
||||
if (parseInt(this.itemInput) !== Math.round(taskInfo.getDeviceInfo(this.deviceID).parameterSet[this.parameterName] * 0.537 + 200)) {
|
||||
this.$emit('parameterChange', [this.parameterName, parseInt((parseInt(this.itemInput) - 200) / 0.537)])
|
||||
if (parseInt(this.itemInput) !== Math.round((taskInfo.getDeviceInfo(this.deviceID).parameterSet[this.parameterName]) * 2200 / 4095)) {
|
||||
this.$emit('parameterChange', [this.parameterName, Math.round((parseInt(this.itemInput) * 4095) / 2200)])
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
@@ -54,8 +54,8 @@ export default {
|
||||
data () {
|
||||
return {
|
||||
inputeKey: 0,
|
||||
itemInputMin: String(parseFloat(Math.round(parseFloat((taskInfo.getDeviceInfo(this.deviceID).parameterSet.FREQ_START * 67.1 + 0.015) * 100)) / 100).toFixed(2)),
|
||||
itemInputMax: String(parseFloat(Math.round(parseFloat((taskInfo.getDeviceInfo(this.deviceID).parameterSet.FREQ_STOP * 67.1 + 0.015) * 100)) / 100).toFixed(2)),
|
||||
itemInputMin: String(parseFloat(Math.round(parseFloat((taskInfo.getDeviceInfo(this.deviceID).parameterSet.FREQ_START * 0.0149) * 100)) / 100).toFixed(1)) === '0.0' ? '0.015' : String(parseFloat(Math.round(parseFloat((taskInfo.getDeviceInfo(this.deviceID).parameterSet.FREQ_START * 0.0149) * 100)) / 100).toFixed(1)),
|
||||
itemInputMax: String(parseFloat(Math.round(parseFloat((taskInfo.getDeviceInfo(this.deviceID).parameterSet.FREQ_STOP * 0.0149) * 100)) / 100).toFixed(1)) === '0.0' ? '0.015' : String(parseFloat(Math.round(parseFloat((taskInfo.getDeviceInfo(this.deviceID).parameterSet.FREQ_STOP * 0.0149) * 100)) / 100).toFixed(1)),
|
||||
|
||||
}
|
||||
},
|
||||
@@ -65,15 +65,23 @@ export default {
|
||||
itemChangeMin (val) {
|
||||
this.itemInputMin = val
|
||||
this.inputeKey++
|
||||
if (parseFloat(this.itemInputMin).toFixed(2) !== parseFloat(Math.round(parseFloat((taskInfo.getDeviceInfo(this.deviceID).parameterSet.FREQ_START * 67.1 + 0.015) * 100)) / 100).toFixed(2)) {
|
||||
this.$emit('parameterChange', [this.parameterName + '_START', Math.round((parseFloat(this.itemInputMin) - 0.015) / 67.1)])
|
||||
if (parseFloat(this.itemInputMin).toFixed(1) !== parseFloat(Math.round(parseFloat((taskInfo.getDeviceInfo(this.deviceID).parameterSet.FREQ_START * 0.0149) * 100)) / 100).toFixed(1)) {
|
||||
if (parseFloat(this.itemInputMin) < 0.1) {
|
||||
this.$emit('parameterChange', [this.parameterName + '_START', 1])
|
||||
} else {
|
||||
this.$emit('parameterChange', [this.parameterName + '_START', Math.round((parseFloat(this.itemInputMin)) / 0.0149)])
|
||||
}
|
||||
}
|
||||
},
|
||||
itemChangeMax (val) {
|
||||
this.itemInputMax = val
|
||||
this.inputeKey++
|
||||
if (parseFloat(this.itemInputMax).toFixed(2) !== parseFloat(Math.round(parseFloat((taskInfo.getDeviceInfo(this.deviceID).parameterSet.FREQ_STOP * 67.1 + 0.015) * 100)) / 100).toFixed(2)) {
|
||||
this.$emit('parameterChange', [this.parameterName + '_STOP', Math.round((parseFloat(this.itemInputMax) - 0.015) / 67.1)])
|
||||
if (parseFloat(this.itemInputMax).toFixed(1) !== parseFloat(Math.round(parseFloat((taskInfo.getDeviceInfo(this.deviceID).parameterSet.FREQ_STOP * 0.0149) * 100)) / 100).toFixed(1)) {
|
||||
if (parseFloat(this.itemInputMax) < 0.1) {
|
||||
this.$emit('parameterChange', [this.parameterName + '_START', 1])
|
||||
} else {
|
||||
this.$emit('parameterChange', [this.parameterName + '_STOP', Math.round((parseFloat(this.itemInputMax)) / 0.0149)])
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
@@ -51,8 +51,8 @@ export default {
|
||||
itemChange (val) {
|
||||
this.itemInput = val
|
||||
this.inputeKey++
|
||||
if (parseInt(this.itemInput) !== Math.round(taskInfo.getDeviceInfo(this.deviceID).parameterSet[this.parameterName])) {
|
||||
this.$emit('parameterChange', [this.parameterName, parseInt(this.itemInputMin)])
|
||||
if (String(this.itemInput) !== String(Math.round(taskInfo.getDeviceInfo(this.deviceID).parameterSet[this.parameterName]))) {
|
||||
this.$emit('parameterChange', [this.parameterName, parseInt(this.itemInput)])
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
+29
-12
@@ -2,10 +2,13 @@
|
||||
<div class="row">
|
||||
<div class="flex sm12 xl12 md12 xs12">
|
||||
<div class="flex row align--center" :key="inputeKey">
|
||||
<va-button slot="append" class="mr-2 pa-1 shrink" small @click="voltNumberChange(minValue*1000)">
|
||||
{{ minValue }}
|
||||
</va-button>
|
||||
<va-input
|
||||
@mouseleave.native="itemChange(voltNumberInput)"
|
||||
@keyup.enter="itemChange(voltNumberInput)"
|
||||
@blur="itemChange(voltNumberInput)"
|
||||
@mouseleave.native="voltNumberChange(voltNumberInput)"
|
||||
@keyup.enter="voltNumberChange(voltNumberInput)"
|
||||
@blur="voltNumberChange(voltNumberInput)"
|
||||
v-model="voltNumberInput"
|
||||
class="mb-0"
|
||||
style="width: 100px;"
|
||||
@@ -14,7 +17,20 @@
|
||||
V
|
||||
</p>
|
||||
</va-input>
|
||||
<va-button slot="append" class="ml-2 pa-1 shrink" small @click="voltNumberChange(maxValue*1000)">
|
||||
{{ maxValue }}
|
||||
</va-button>
|
||||
</div>
|
||||
<va-slider
|
||||
@mouseup.native="voltNumberChange(voltNumber)"
|
||||
@mouseleave.native="voltNumberChange(voltNumber)"
|
||||
@touchend.native="voltNumberChange(voltNumber)"
|
||||
@click.native="voltNumberChange(voltNumber)"
|
||||
class="flex sm12 xl12 md12 xs12"
|
||||
v-model="voltNumber"
|
||||
:min="minValue*1000"
|
||||
:max="maxValue*1000"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -22,8 +38,9 @@
|
||||
<script>
|
||||
|
||||
import { taskInfo } from '@/data/task/TaskInfo'
|
||||
|
||||
export default {
|
||||
name: 'SingalMode',
|
||||
name: 'VoltRange',
|
||||
components: {
|
||||
},
|
||||
props: {
|
||||
@@ -49,20 +66,20 @@ export default {
|
||||
data () {
|
||||
return {
|
||||
inputeKey: 0,
|
||||
voltNumber: (taskInfo.getDeviceInfo(this.deviceID).parameterSet[this.parameterName] - 25000) / 5,
|
||||
voltNumberInput: String(parseFloat((taskInfo.getDeviceInfo(this.deviceID).parameterSet[this.parameterName] - 25000) / 5000).toFixed(3)),
|
||||
voltNumber: (taskInfo.getDeviceInfo(this.deviceID).parameterSet[this.parameterName] - 25000) / 12.5,
|
||||
voltNumberInput: String(parseFloat((taskInfo.getDeviceInfo(this.deviceID).parameterSet[this.parameterName] - 25000) / 12500).toFixed(3)),
|
||||
}
|
||||
},
|
||||
mqtt: {
|
||||
},
|
||||
methods: {
|
||||
itemChange (val) {
|
||||
voltNumberChange (val) {
|
||||
this.inputeKey++
|
||||
if (this.voltNumber == null) {
|
||||
return false
|
||||
}
|
||||
if (typeof (val) === 'string') {
|
||||
if (isNaN(val) || parseFloat(val) > 5 || parseFloat(val) < -5) {
|
||||
if (isNaN(val) || parseFloat(val) > 2 || parseFloat(val) < -1.8) {
|
||||
this.voltNumberInput = '0.00'
|
||||
this.voltNumber = 0
|
||||
return false
|
||||
@@ -72,7 +89,7 @@ export default {
|
||||
this.voltNumberInput = String(parseFloat(this.voltNumber / 1000).toFixed(3))
|
||||
}
|
||||
} else {
|
||||
if (isNaN(val) || parseFloat(val) > 5000 || parseFloat(val) < -5000) {
|
||||
if (isNaN(val) || parseFloat(val) > 2000 || parseFloat(val) < -1800) {
|
||||
this.voltNumberInput = '0.00'
|
||||
this.voltNumber = 0
|
||||
return false
|
||||
@@ -82,12 +99,12 @@ export default {
|
||||
this.voltNumber = val
|
||||
}
|
||||
}
|
||||
if (this.voltNumber !== (taskInfo.getDeviceInfo(this.deviceID).parameterSet[this.parameterName] - 25000) / 5) {
|
||||
this.$emit('parameterChange', [this.parameterName, this.voltNumber * 5 + 25000])
|
||||
if (this.voltNumber !== (taskInfo.getDeviceInfo(this.deviceID).parameterSet[this.parameterName] - 25000) / 12.5) {
|
||||
this.$emit('parameterChange', [this.parameterName, this.voltNumber * 12.5 + 25000])
|
||||
}
|
||||
},
|
||||
updateVoltNumber (val) {
|
||||
this.itemChange(val)
|
||||
this.voltNumberChange(val)
|
||||
},
|
||||
},
|
||||
async mounted () {
|
||||
@@ -53,7 +53,7 @@ export default {
|
||||
data () {
|
||||
return {
|
||||
disableSlider: false,
|
||||
sliderMin: 0,
|
||||
sliderMin: 35,
|
||||
sliderMax: 100,
|
||||
currentRange: [],
|
||||
inputeKey: 0,
|
||||
@@ -123,7 +123,7 @@ export default {
|
||||
}
|
||||
},
|
||||
reset () {
|
||||
this.$emit('parameterChange', [this.parameterName + 'START_' + String(this.segmentID), 5])
|
||||
this.$emit('parameterChange', [this.parameterName + 'START_' + String(this.segmentID), 35])
|
||||
this.$emit('parameterChange', [this.parameterName + 'END_' + String(this.segmentID), 95])
|
||||
},
|
||||
refresh () {
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
<script>
|
||||
|
||||
import { taskInfo } from '@/data/task/TaskInfo'
|
||||
// import { taskInfo } from '@/data/task/TaskInfo'
|
||||
|
||||
export default {
|
||||
name: 'CycleNumber',
|
||||
@@ -55,24 +55,26 @@ export default {
|
||||
mqtt: {
|
||||
},
|
||||
methods: {
|
||||
// [TODO, last modified: 2021/08/06]: pulse mode cycle can't exceed 255, and now cycle default = 0, but other mode cycle number setting will affect this mode
|
||||
itemChange (val) {
|
||||
this.itemInput = val
|
||||
this.inputeKey++
|
||||
if (this.itemInput !== '∞') {
|
||||
if (parseInt(this.itemInput) !== Math.round(taskInfo.getDeviceInfo(this.deviceID).parameterSet[this.parameterName])) {
|
||||
this.$emit('parameterChange', [this.parameterName, parseInt(this.itemInput)])
|
||||
}
|
||||
} else { // infinite: send 0 to elite
|
||||
if (taskInfo.getDeviceInfo(this.deviceID).parameterSet[this.parameterName] !== 0) {
|
||||
this.$emit('parameterChange', [this.parameterName, 0])
|
||||
}
|
||||
}
|
||||
// this.itemInput = val
|
||||
// this.inputeKey++
|
||||
// if (this.itemInput !== '∞') {
|
||||
// if (parseInt(this.itemInput) !== Math.round(taskInfo.getDeviceInfo(this.deviceID).parameterSet[this.parameterName])) {
|
||||
// this.$emit('parameterChange', [this.parameterName, parseInt(this.itemInput)])
|
||||
// }
|
||||
// } else { // infinite: send 0 to elite
|
||||
// if (taskInfo.getDeviceInfo(this.deviceID).parameterSet[this.parameterName] !== 0) {
|
||||
// this.$emit('parameterChange', [this.parameterName, 0])
|
||||
// }
|
||||
// }
|
||||
},
|
||||
setInfinite () {
|
||||
this.itemInput = '∞'
|
||||
},
|
||||
refresh () {
|
||||
let cycle = Math.round(taskInfo.getDeviceInfo(this.deviceID).parameterSet[this.parameterName])
|
||||
// let cycle = Math.round(taskInfo.getDeviceInfo(this.deviceID).parameterSet[this.parameterName])
|
||||
let cycle = 0
|
||||
if (cycle === 0) {
|
||||
cycle = '∞'
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="block">
|
||||
<div class="row flex sm12 xl12 md12 xs12 align--center">
|
||||
<div class="flex sm11 xl11 md11 xs11 px-0 mx-0">
|
||||
<p class="display-6">- Segment {{ segmentIndex + 1 }} - <p/>
|
||||
@@ -104,15 +104,11 @@ export default {
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.flex-container {
|
||||
display: flex;
|
||||
.block {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.flex-child {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.flex-child:first-child {
|
||||
margin-right: 20px;
|
||||
.block:hover {
|
||||
background-color: #d3d3d3;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
import api from './index'
|
||||
import auth from './auth'
|
||||
|
||||
async function spikeDetect (attrs) {
|
||||
const _header = auth.getHeader()
|
||||
try {
|
||||
return await api.axios.post('/api/analysis/spike_detect', attrs, { headers: _header })
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
const analysis = {
|
||||
spikeDetect,
|
||||
}
|
||||
|
||||
export default analysis
|
||||
@@ -11,7 +11,7 @@ async function create (attrs) {
|
||||
}
|
||||
|
||||
try {
|
||||
return await api.axios.post('/api/collection/create', _data, { headers: _header })
|
||||
return await api.axios.post('/api/file/collection/create', _data, { headers: _header })
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
return false
|
||||
@@ -21,7 +21,7 @@ async function create (attrs) {
|
||||
async function getByID (id) {
|
||||
const _header = auth.getHeader()
|
||||
try {
|
||||
return await api.axios.get(`/api/collection/get_by_id/${id}`, { headers: _header })
|
||||
return await api.axios.get(`/api/file/collection/get_by_id/${id}`, { headers: _header })
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
return false
|
||||
@@ -31,7 +31,7 @@ async function getByID (id) {
|
||||
async function getByName (name) {
|
||||
const _header = auth.getHeader()
|
||||
try {
|
||||
return await api.axios.get(`/api/collection/get_by_name/${name}`, { headers: _header })
|
||||
return await api.axios.get(`/api/file/collection/get_by_name/${name}`, { headers: _header })
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
return false
|
||||
@@ -41,7 +41,7 @@ async function getByName (name) {
|
||||
async function getByParent (type, parent) {
|
||||
const _header = auth.getHeader()
|
||||
try {
|
||||
return await api.axios.get(`/api/collection/get_by_parent/${type}/${parent}`, { headers: _header })
|
||||
return await api.axios.get(`/api/file/collection/get_by_parent/${type}/${parent}`, { headers: _header })
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
return false
|
||||
@@ -51,7 +51,7 @@ async function getByParent (type, parent) {
|
||||
async function getAll () {
|
||||
const _header = auth.getHeader()
|
||||
try {
|
||||
return await api.axios.get('/api/collection/get/all', { headers: _header })
|
||||
return await api.axios.get('/api/file/collection/get/all', { headers: _header })
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
return false
|
||||
@@ -62,7 +62,7 @@ async function getByParentName (collectionType, parent, name) {
|
||||
console.log(collectionType, parent, name)
|
||||
const _header = auth.getHeader()
|
||||
try {
|
||||
return await api.axios.get(`/api/collection/get_by_parent_name/${collectionType}/${parent}/${name}`, { headers: _header })
|
||||
return await api.axios.get(`/api/file/collection/get_by_parent_name/${collectionType}/${parent}/${name}`, { headers: _header })
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
return false
|
||||
|
||||
@@ -7,6 +7,7 @@ import device from './device'
|
||||
import meta from './meta'
|
||||
import raw from './raw'
|
||||
import mini from './mini'
|
||||
import analysis from './analysis'
|
||||
|
||||
// axios.defaults.baseURL = 'http://192.168.3.53:3000'
|
||||
axios.defaults.baseURL = 'http://' + location.href.split('/')[2].split(':')[0] + ':3000'
|
||||
@@ -21,6 +22,7 @@ const api = {
|
||||
meta,
|
||||
raw,
|
||||
mini,
|
||||
analysis,
|
||||
}
|
||||
|
||||
export default api
|
||||
|
||||
+15
-4
@@ -21,18 +21,28 @@ async function update (id, attrs) {
|
||||
}
|
||||
}
|
||||
|
||||
async function clearDel (id) {
|
||||
async function clearDel () {
|
||||
console.log('clearDelete')
|
||||
const _header = auth.getHeader()
|
||||
try {
|
||||
return await api.axios.get(`/api/file/meta/clear_deleted/${id}`, { headers: _header })
|
||||
return await api.axios.get('/api/file/meta/clear_deleted', { headers: _header })
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
async function getCollectionByParent (type, parent) {
|
||||
async function getByParentWithLimit (type, parent, limit, offset, order) {
|
||||
const _header = auth.getHeader()
|
||||
try {
|
||||
return await api.axios.get(`/api/file/meta/get_by_parent_with_limit/${type}/${parent}/${limit}/${offset}/${order}`, { headers: _header })
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
async function getByParent (type, parent) {
|
||||
const _header = auth.getHeader()
|
||||
try {
|
||||
return await api.axios.get(`/api/file/meta/get_by_parent/${type}/${parent}`, { headers: _header })
|
||||
@@ -66,7 +76,8 @@ const meta = {
|
||||
create,
|
||||
update,
|
||||
clearDel,
|
||||
getCollectionByParent,
|
||||
getByParent,
|
||||
getByParentWithLimit,
|
||||
getByID,
|
||||
getByName,
|
||||
}
|
||||
|
||||
@@ -31,6 +31,16 @@ async function getByID (channel, id) {
|
||||
}
|
||||
}
|
||||
|
||||
async function getAttrByID (channel, id, attr) {
|
||||
const _header = auth.getHeader()
|
||||
try {
|
||||
return await api.axios.get(`/api/file/raw/get_attr_by_id/${channel}/${id}/${attr}`, { responseType: 'json', headers: _header })
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
async function getByIDs (channel, ids) {
|
||||
const _header = auth.getHeader()
|
||||
try {
|
||||
@@ -75,6 +85,7 @@ const raw = {
|
||||
update,
|
||||
clearDel,
|
||||
getByID,
|
||||
getAttrByID,
|
||||
getByIDs,
|
||||
getAttrByIDs,
|
||||
getByParent,
|
||||
|
||||
@@ -9,6 +9,34 @@ const ChannelMaxNumber = 16
|
||||
|
||||
// const getTimeInDateTime = /(\d{4}),(\d{1,2}),(\d{1,2}),(\d{1,2}),(\d{1,2}),(\d{1,2})/
|
||||
|
||||
const hasCycleMode = (mode) => {
|
||||
if (mode === 1 || mode === 7) {
|
||||
return true
|
||||
}
|
||||
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 transMac = (rawAddr) => {
|
||||
let _address = ''
|
||||
rawAddr.forEach(addr => {
|
||||
@@ -84,6 +112,8 @@ const dateToStr = (time) => {
|
||||
|
||||
export default
|
||||
{
|
||||
hasCycleMode,
|
||||
getDefaultChartTypeByMode,
|
||||
transMac,
|
||||
transFileSize,
|
||||
transTime,
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import newDataZoom from '@/factories/chart/dataZoomFactory'
|
||||
import newChart, { newChartMode } from '@/factories/chart/chartFactory'
|
||||
import newChart from '@/factories/chart/chartFactory'
|
||||
import newTooltip from '@/factories/chart/tooltipFactory'
|
||||
// import newInterval from '@/factories/chart/intervalFactory'
|
||||
import newSeries from '@/factories/chart/seriesFactory'
|
||||
import { dataStreamBuffer } from './DataStreamBuffer'
|
||||
import { taskInfo } from './TaskInfo'
|
||||
import global_ from '@/data/global/global'
|
||||
|
||||
function getIndexArrayForBalenceSampleRate (indexArray, dis, l) {
|
||||
if (indexArray.length >= 3 || dis <= 0) {
|
||||
@@ -32,7 +33,6 @@ function makeXAxis (gridIndex, type, channel) {
|
||||
axisTick: { show: false },
|
||||
axisLabel: {
|
||||
show: true,
|
||||
// interval: 2,
|
||||
showMinLabel: false,
|
||||
showMaxLabel: false,
|
||||
color: '#aaa',
|
||||
@@ -45,11 +45,12 @@ function makeXAxis (gridIndex, type, channel) {
|
||||
// lineStyle: { color: '#eee' },
|
||||
// },
|
||||
// splitNumber: 20,
|
||||
interval: 'auto',
|
||||
interval: null,
|
||||
scale: true,
|
||||
min: 'dataMin',
|
||||
max: 'dataMax',
|
||||
channel: channel,
|
||||
seriesIndex: [],
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,35 +58,35 @@ function makeXAxis (gridIndex, type, channel) {
|
||||
function makeYAxis (gridIndex, type, channel) {
|
||||
return {
|
||||
type: type,
|
||||
// name: 'none',
|
||||
// nameLocation: 'center',
|
||||
// nameTextStyle: {
|
||||
// // align: 'left',
|
||||
// // verticalAlign: 'bottom',
|
||||
// },
|
||||
// // name: 'none',
|
||||
// // nameLocation: 'center',
|
||||
// // nameTextStyle: {
|
||||
// // // align: 'left',
|
||||
// // // verticalAlign: 'bottom',
|
||||
// // },
|
||||
gridIndex: gridIndex,
|
||||
axisTick: { show: false },
|
||||
axisLine: { show: false }, // color: '#ccc' } },
|
||||
axisLabel: {
|
||||
show: true,
|
||||
interval: 0,
|
||||
color: '#aaa',
|
||||
showMinLabel: false,
|
||||
showMaxLabel: false,
|
||||
},
|
||||
splitLine: { show: true, lineStyle: { color: '#aaa' } },
|
||||
// minorSplitLine: {
|
||||
// show: true,
|
||||
// lineStyle: { color: '#eee' },
|
||||
// },
|
||||
// // minorSplitLine: {
|
||||
// // show: true,
|
||||
// // lineStyle: { color: '#eee' },
|
||||
// // },
|
||||
animation: false,
|
||||
scale: true,
|
||||
min: 'dataMin',
|
||||
max: 'dataMax',
|
||||
// splitNumber: 3,
|
||||
splitNumber: 3,
|
||||
// minInterval: 1,
|
||||
interval: 'auto',
|
||||
interval: null,
|
||||
channel: channel,
|
||||
seriesIndex: [],
|
||||
}
|
||||
}
|
||||
|
||||
@@ -683,7 +684,7 @@ export const chartData = {
|
||||
|
||||
const _chartRegisterDevice = (chartID, device) => {
|
||||
if (taskInfo.getDeviceInfo(device.id).info.library_name.indexOf('Elite') >= 0) {
|
||||
const setting = newChartMode(taskInfo.getDeviceInfo(device.id).parameterSet.MODE)
|
||||
const setting = global_.getDefaultChartTypeByMode(taskInfo.getDeviceInfo(device.id).parameterSet.MODE)
|
||||
console.log(setting)
|
||||
const xType = setting[0]
|
||||
const xValue = setting[1]
|
||||
@@ -694,26 +695,26 @@ export const chartData = {
|
||||
_chartData[chartID].chartMode = taskInfo.getDeviceInfo(device.id).parameterSet.MODE
|
||||
switch (xValue) {
|
||||
case 1:
|
||||
_chartData[chartID].chartXUnit = 'nA'
|
||||
_chartData[chartID].chartXUnit = 'uA' // nA * 1000
|
||||
break
|
||||
case 2:
|
||||
_chartData[chartID].chartXUnit = 'uV'
|
||||
_chartData[chartID].chartXUnit = 'mV' // uV * 1000
|
||||
break
|
||||
case 3:
|
||||
_chartData[chartID].chartXUnit = 'mΩ'
|
||||
_chartData[chartID].chartXUnit = 'Ω' // mOhm * 1000
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
switch (yValue) {
|
||||
case 1:
|
||||
_chartData[chartID].chartYUnit = 'nA'
|
||||
_chartData[chartID].chartYUnit = 'uA'
|
||||
break
|
||||
case 2:
|
||||
_chartData[chartID].chartYUnit = 'uV'
|
||||
_chartData[chartID].chartYUnit = 'mV'
|
||||
break
|
||||
case 3:
|
||||
_chartData[chartID].chartYUnit = 'mΩ'
|
||||
_chartData[chartID].chartYUnit = 'Ω'
|
||||
break
|
||||
default:
|
||||
break
|
||||
@@ -776,6 +777,8 @@ export const chartData = {
|
||||
// TODO remove old buffer register
|
||||
if (_chartID != null) {
|
||||
// update only one
|
||||
console.log(_chartID, _chartData)
|
||||
|
||||
chartData.reset(_chartID, _chartData[_chartID].mappingID, _chartData[_chartID].cardName)
|
||||
_chartData[_chartID].mappingID = parseInt(item.id)
|
||||
switch (_type) {
|
||||
@@ -935,8 +938,12 @@ const chartRegister = (chartID, gridIndex, deviceNameX, deviceIDX, channelX, dev
|
||||
|
||||
// register series
|
||||
const _series = newSeries('line', legendName, _xAxisIndex, _yAxisIndex, xAxisSource, yAxisSource, formula, formulaSource)
|
||||
const _seriesIndex = _chartData[chartID].series.length
|
||||
_chartData[chartID].series.push(_series)
|
||||
|
||||
_chartData[chartID].xAxis[_xAxisIndex].seriesIndex.push(_seriesIndex)
|
||||
_chartData[chartID].yAxis[_yAxisIndex].seriesIndex.push(_seriesIndex)
|
||||
|
||||
// set xAxis format
|
||||
if (sourceList[0].name === 'Time') {
|
||||
_chartData[chartID].xAxis[_xAxisIndex].axisLabel.formatter = function (val) {
|
||||
@@ -961,22 +968,27 @@ 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) {
|
||||
case 1:
|
||||
_chartData[chartID].xAxis[_xAxisIndex].axisLabel.formatter = function (val) {
|
||||
return val + 'nA'
|
||||
return parseFloat(val / 1000).toFixed(2) + 'uA'
|
||||
}
|
||||
_chartData[chartID].chartXUnit = 'uA' // nA * 1000
|
||||
break
|
||||
case 2:
|
||||
_chartData[chartID].xAxis[_xAxisIndex].axisLabel.formatter = function (val) {
|
||||
return val + 'uV'
|
||||
return parseFloat(val / 1000).toFixed(2) + 'mV'
|
||||
}
|
||||
_chartData[chartID].chartXUnit = 'mV' // uV * 1000
|
||||
break
|
||||
case 3:
|
||||
_chartData[chartID].xAxis[_xAxisIndex].axisLabel.formatter = function (val) {
|
||||
return val + 'mΩ'
|
||||
return parseFloat(val / 1000).toFixed(2) + 'Ω'
|
||||
}
|
||||
_chartData[chartID].chartXUnit = 'Ω' // mOhm * 1000
|
||||
break
|
||||
default:
|
||||
break
|
||||
@@ -1005,28 +1017,42 @@ const chartRegister = (chartID, gridIndex, deviceNameX, deviceIDX, channelX, dev
|
||||
}
|
||||
|
||||
if (parseInt(sourceList[1].channel) >= 257 && parseInt(sourceList[1].channel) <= 260) {
|
||||
_chartData[chartID].yAxis[_yAxisIndex].min = -scaleRange
|
||||
_chartData[chartID].yAxis[_yAxisIndex].max = scaleRange
|
||||
}
|
||||
_chartData[chartID].yAxis[_yAxisIndex].axisLabel.formatter = function (val) {
|
||||
return val + 'uV'
|
||||
if (parseInt(sourceList[1].channel) === 260) {
|
||||
_chartData[chartID].yAxis[_yAxisIndex].min = 0
|
||||
_chartData[chartID].yAxis[_yAxisIndex].max = Math.ceil(Math.sqrt(Math.pow(scaleRange, 2) * 3))
|
||||
} else {
|
||||
_chartData[chartID].yAxis[_yAxisIndex].min = -scaleRange
|
||||
_chartData[chartID].yAxis[_yAxisIndex].max = scaleRange
|
||||
}
|
||||
_chartData[chartID].yAxis[_yAxisIndex].axisLabel.formatter = function (val) {
|
||||
return parseFloat(val / 100) + 'g'
|
||||
}
|
||||
} else {
|
||||
_chartData[chartID].yAxis[_yAxisIndex].axisLabel.formatter = function (val) {
|
||||
return parseFloat(val).toFixed(2) + 'uV'
|
||||
}
|
||||
}
|
||||
_chartData[chartID].chartYUnit = 'uV' // nA * 1000
|
||||
} else if (sourceList[1].name === 'Elite') {
|
||||
switch (sourceList[1].channel) {
|
||||
case 1:
|
||||
_chartData[chartID].yAxis[_yAxisIndex].axisLabel.formatter = function (val) {
|
||||
return val + 'nA'
|
||||
return parseFloat(val / 1000).toFixed(2) + 'uA'
|
||||
}
|
||||
_chartData[chartID].chartYUnit = 'uA' // nA * 1000
|
||||
console.log(_chartData[chartID])
|
||||
break
|
||||
case 2:
|
||||
_chartData[chartID].yAxis[_yAxisIndex].axisLabel.formatter = function (val) {
|
||||
return val + 'uV'
|
||||
return parseFloat(val / 1000).toFixed(2) + 'mV'
|
||||
}
|
||||
_chartData[chartID].chartYUnit = 'mV' // uV * 1000
|
||||
break
|
||||
case 3:
|
||||
_chartData[chartID].yAxis[_yAxisIndex].axisLabel.formatter = function (val) {
|
||||
return val + 'mΩ'
|
||||
return parseFloat(val / 1000).toFixed(2) + 'Ω'
|
||||
}
|
||||
_chartData[chartID].chartYUnit = 'Ω' // mOhm * 1000
|
||||
break
|
||||
default:
|
||||
break
|
||||
@@ -1086,8 +1112,10 @@ const chartRegister = (chartID, gridIndex, deviceNameX, deviceIDX, channelX, dev
|
||||
xAxis: _axisList[0],
|
||||
yAxis: _axisList[1],
|
||||
}
|
||||
|
||||
_chartData[chartID].grid[gridIndex].series.push(_gridSeries)
|
||||
if (_chartData[chartID].gridSource[gridIndex] == null) {
|
||||
_chartData[chartID].gridSource[gridIndex] = []
|
||||
}
|
||||
_chartData[chartID].gridSource[gridIndex].push(_gridSeries)
|
||||
|
||||
// console.log(_chartData[chartID])
|
||||
return _chartData[chartID]
|
||||
|
||||
+26
-25
@@ -6,7 +6,7 @@ const eliteImgUrl = require('@/assets/img/elite_img.png')
|
||||
const neuliveImgUrl = require('@/assets/img/neulive_img.png')
|
||||
// import { chartData } from './ChartsManagement'
|
||||
|
||||
const _taskInfo = newTask()
|
||||
let _taskInfo = newTask()
|
||||
// show the devices which mac is included in task
|
||||
const _deviceList = []
|
||||
// show the devices which mac is included in task and do not show Time
|
||||
@@ -107,17 +107,18 @@ export const taskInfo = {
|
||||
},
|
||||
|
||||
destroyed: () => {
|
||||
_taskInfo.controllerID = ''
|
||||
_taskInfo.deviceAddrList.length = 0
|
||||
_taskInfo.taskDeviceID.length = 0
|
||||
_taskInfo.chartNumber = 0
|
||||
deviceListRegister.length = 0
|
||||
for (const device in _taskInfo.deviceList) {
|
||||
_taskInfo.deviceList[device].info.status = ''
|
||||
_taskInfo.deviceList[device].info.isSync = false
|
||||
_taskInfo.deviceList[device].info.isStimulate = false
|
||||
}
|
||||
_taskInfo.formulaList.length = 0
|
||||
_taskInfo = newTask()
|
||||
// _taskInfo.controllerID = ''
|
||||
// _taskInfo.deviceAddrList.length = 0
|
||||
// _taskInfo.taskDeviceID.length = 0
|
||||
// _taskInfo.chartNumber = 0
|
||||
// deviceListRegister.length = 0
|
||||
// for (const device in _taskInfo.deviceList) {
|
||||
// _taskInfo.deviceList[device].info.status = ''
|
||||
// _taskInfo.deviceList[device].info.isSync = false
|
||||
// _taskInfo.deviceList[device].info.isStimulate = false
|
||||
// }
|
||||
// _taskInfo.formulaList.length = 0
|
||||
},
|
||||
|
||||
deviceInfo: async (mes) => {
|
||||
@@ -213,22 +214,22 @@ export const taskInfo = {
|
||||
|
||||
deviceDisconnected: async (deviceID) => {
|
||||
const update = async () => {
|
||||
taskInfo.getTaskInfo().deviceAddrList.splice(_taskInfo.taskDeviceID.indexOf(parseInt(deviceID)), 1)
|
||||
deviceListRegister.forEach(device => {
|
||||
if (device.id === _taskInfo.taskDeviceID.indexOf(parseInt(deviceID))) {
|
||||
deviceListRegister.splice(deviceListRegister.indexOf(device), 1)
|
||||
}
|
||||
})
|
||||
deviceListRegister.forEach(device => {
|
||||
if (device.id > _taskInfo.taskDeviceID.indexOf(parseInt(deviceID))) {
|
||||
device.id--
|
||||
}
|
||||
})
|
||||
_taskInfo.taskDeviceID.splice(_taskInfo.taskDeviceID.indexOf(parseInt(deviceID)), 1)
|
||||
// taskInfo.getTaskInfo().deviceAddrList.splice(_taskInfo.taskDeviceID.indexOf(parseInt(deviceID)), 1)
|
||||
// deviceListRegister.forEach(device => {
|
||||
// if (device.id === _taskInfo.taskDeviceID.indexOf(parseInt(deviceID))) {
|
||||
// deviceListRegister.splice(deviceListRegister.indexOf(device), 1)
|
||||
// }
|
||||
// })
|
||||
// deviceListRegister.forEach(device => {
|
||||
// if (device.id > _taskInfo.taskDeviceID.indexOf(parseInt(deviceID))) {
|
||||
// device.id--
|
||||
// }
|
||||
// })
|
||||
// _taskInfo.taskDeviceID.splice(_taskInfo.taskDeviceID.indexOf(parseInt(deviceID)), 1)
|
||||
_taskInfo.deviceList[parseInt(deviceID)].info.status = 'disconnected'
|
||||
}
|
||||
await update()
|
||||
await updateAllList()
|
||||
// await updateAllList()
|
||||
},
|
||||
|
||||
controllerShutdown: async () => {
|
||||
|
||||
@@ -2,7 +2,7 @@ function newChart (chartID) {
|
||||
return {
|
||||
chartID: parseInt(chartID),
|
||||
chartType: 'detail',
|
||||
chartDevice: 'neulive',
|
||||
chartDevice: 'elite', // elite or neulive
|
||||
chartMode: 0,
|
||||
chartXUnit: '',
|
||||
chartYUnit: '',
|
||||
@@ -25,6 +25,7 @@ function newChart (chartID) {
|
||||
snap: true,
|
||||
},
|
||||
grid: [],
|
||||
gridSource: [],
|
||||
xAxis: [],
|
||||
yAxis: [],
|
||||
dataZoom: null,
|
||||
@@ -32,25 +33,4 @@ function newChart (chartID) {
|
||||
}
|
||||
}
|
||||
|
||||
function newChartMode (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]
|
||||
return settings[mode]
|
||||
}
|
||||
|
||||
export default newChart
|
||||
export { newChartMode }
|
||||
|
||||
@@ -6,10 +6,11 @@ function newSeries (type, legendName, xAxisIndex, yAxisIndex, xAxisSource, yAxis
|
||||
showSymbol: false,
|
||||
showAllSymbol: false,
|
||||
symbolSize: 2,
|
||||
// [modified 2021/08/10] sampling method managed by vuex
|
||||
// sampling: 'average',
|
||||
sampling: function (frame) {
|
||||
return frame[0]
|
||||
},
|
||||
// sampling: function (frame) {
|
||||
// return frame[0]
|
||||
// },
|
||||
// clip the overflow on the coordinate system
|
||||
// clip: true,
|
||||
// ignore mouse events
|
||||
|
||||
@@ -54,22 +54,32 @@ function newTooltip (chartID) {
|
||||
if (param.seriesName === 'Time') {
|
||||
value = param.value[1]
|
||||
} else if (param.seriesName.split('_')[1] === 'T' && param.seriesName.split('_')[0] !== 'T') {
|
||||
if (param.seriesName.split('_')[0][param.seriesName.split('_')[0].length - 1] === 'V') {
|
||||
const physicalQuantity = param.seriesName.split('_')[0][param.seriesName.split('_')[0].length - 1]
|
||||
if (physicalQuantity === 'V') {
|
||||
value = parseFloat(param.value[0]).toFixed(3) + ' μV'
|
||||
} else if (param.seriesName.split('_')[0][param.seriesName.split('_')[0].length - 1] === 'I') {
|
||||
} else if (physicalQuantity === 'I') {
|
||||
value = parseFloat(param.value[0]).toFixed(3) + ' nA'
|
||||
} else if (param.seriesName.split('_')[0][param.seriesName.split('_')[0].length - 1] === 'R') {
|
||||
} else if (physicalQuantity === 'R') {
|
||||
value = parseFloat(param.value[0]).toFixed(3) + ' mΩ'
|
||||
} else if (physicalQuantity === 'X' || physicalQuantity === 'Y' || physicalQuantity === 'Z' || physicalQuantity === 'M') {
|
||||
value = (parseFloat(param.value[0]) / 100).toFixed(3) + ' (g)'
|
||||
} else if (!isNaN(physicalQuantity)) {
|
||||
value = (parseFloat(param.value[0]) / 1000).toFixed(3) + ' (mV)'
|
||||
} else {
|
||||
value = parseFloat(param.value[0]).toFixed(3)
|
||||
}
|
||||
} else if (param.seriesName.split('_')[1] !== 'T' && param.seriesName.split('_')[0] === 'T') {
|
||||
if (param.seriesName.split('_')[1][param.seriesName.split('_')[1].length - 1] === 'V') {
|
||||
const physicalQuantity = param.seriesName.split('_')[1][param.seriesName.split('_')[1].length - 1]
|
||||
if (physicalQuantity === 'V') {
|
||||
value = parseFloat(param.value[1]).toFixed(3) + ' μV'
|
||||
} else if (param.seriesName.split('_')[1][param.seriesName.split('_')[1].length - 1] === 'I') {
|
||||
} else if (physicalQuantity === 'I') {
|
||||
value = parseFloat(param.value[1]).toFixed(3) + ' nA'
|
||||
} else if (param.seriesName.split('_')[1][param.seriesName.split('_')[1].length - 1] === 'R') {
|
||||
} else if (physicalQuantity === 'R') {
|
||||
value = parseFloat(param.value[1]).toFixed(3) + ' mΩ'
|
||||
} else if (physicalQuantity === 'X' || physicalQuantity === 'Y' || physicalQuantity === 'Z' || physicalQuantity === 'M') {
|
||||
value = (parseFloat(param.value[1]) / 100).toFixed(3) + ' (g)'
|
||||
} else if (!isNaN(physicalQuantity)) {
|
||||
value = (parseFloat(param.value[1]) / 1000).toFixed(3) + ' (mV)'
|
||||
} else {
|
||||
value = parseFloat(param.value[1]).toFixed(3)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
function newChannel () {
|
||||
return {
|
||||
sampleRate: -1,
|
||||
timeInterval: -1,
|
||||
prevTime: -1,
|
||||
prevData: -1,
|
||||
downloadDataBuffer: [],
|
||||
downloadIDList: [],
|
||||
}
|
||||
}
|
||||
|
||||
export default newChannel
|
||||
@@ -1,11 +1,15 @@
|
||||
function newDownload () {
|
||||
return {
|
||||
_downloadIDList: [],
|
||||
_downloadBuffer: [],
|
||||
downloadIDList: {},
|
||||
downloadBuffer: {},
|
||||
progress: 0,
|
||||
status: '',
|
||||
device: 'Neulive or Elite',
|
||||
format: 'csv or csv-edf or excel',
|
||||
filename: '',
|
||||
size: 0,
|
||||
downloadStream: null,
|
||||
meta: {},
|
||||
channel: [],
|
||||
channelInfo: {},
|
||||
maxRows: 0,
|
||||
maxColumns: 0,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
function newDownloadStream () {
|
||||
return {
|
||||
fileStream: null,
|
||||
writer: null,
|
||||
}
|
||||
}
|
||||
|
||||
export default newDownloadStream
|
||||
+4
-42
@@ -75,9 +75,9 @@ export default new Router({
|
||||
component: EmptyParentComponent,
|
||||
children: [
|
||||
{
|
||||
name: 'neulive-csv-download',
|
||||
path: 'neulive/csv/:metaList?/:recover?',
|
||||
component: () => import('../components/download/neulive/csv/NeuliveDownloadCsv.vue'),
|
||||
name: 'download',
|
||||
path: ':format/:metaList',
|
||||
component: () => import('../components/download/Download.vue'),
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -92,11 +92,6 @@ export default new Router({
|
||||
component: () => import('../components/dashboard/Dashboard.vue'),
|
||||
default: true,
|
||||
},
|
||||
{
|
||||
name: 'about',
|
||||
path: 'about',
|
||||
component: () => import('../components/about/aboutContent.vue'),
|
||||
},
|
||||
{
|
||||
name: 'devices',
|
||||
path: 'devices',
|
||||
@@ -117,11 +112,6 @@ export default new Router({
|
||||
path: 'task-content/:taskID?',
|
||||
component: () => import('../components/task/content/TaskContent.vue'),
|
||||
},
|
||||
{
|
||||
name: 'project-content',
|
||||
path: 'project-content',
|
||||
component: () => import('../components/project/projectContent.vue'),
|
||||
},
|
||||
{
|
||||
name: 'file',
|
||||
path: 'file',
|
||||
@@ -130,38 +120,10 @@ export default new Router({
|
||||
// keepAlive: true,
|
||||
// },
|
||||
},
|
||||
// {
|
||||
// name: 'download',
|
||||
// path: 'download',
|
||||
// component: () => import('../components/download/Download.vue'),
|
||||
// // meta: {
|
||||
// // keepAlive: true,
|
||||
// // },
|
||||
// },
|
||||
{
|
||||
name: 'neulive-csv-download',
|
||||
path: 'download/neulive/csv/:metaList?/:recover?',
|
||||
component: () => import('../components/download/neulive/csv/NeuliveDownloadCsv.vue'),
|
||||
},
|
||||
{
|
||||
name: 'neulive-excel-download',
|
||||
path: 'download/neulive/excel/:metaList?',
|
||||
component: () => import('../components/download/neulive/excel/NeuliveDownloadExcel.vue'),
|
||||
},
|
||||
{
|
||||
name: 'elite-csv-download',
|
||||
path: 'download/elite/csv/:metaList?/:recover?',
|
||||
component: () => import('../components/download/elite/csv/EliteDownloadCsv.vue'),
|
||||
},
|
||||
{
|
||||
name: 'elite-excel-download',
|
||||
path: 'download/elite/excel/:metaList?',
|
||||
component: () => import('../components/download/elite/excel/EliteDownloadExcel.vue'),
|
||||
},
|
||||
{
|
||||
name: 'settings',
|
||||
path: 'settings',
|
||||
component: () => import('../components/about/aboutContent.vue'),
|
||||
component: () => import('../components/setting/settingContent.vue'),
|
||||
// meta: {
|
||||
// keepAlive: true,
|
||||
// },
|
||||
|
||||
+10
-16
@@ -2,19 +2,16 @@ import Vue from 'vue'
|
||||
import Vuex from 'vuex'
|
||||
import VuexI18n from 'vuex-i18n' // load vuex i18n module
|
||||
// import app from './modules/app'
|
||||
import state from './state'
|
||||
import setting from './modules/setting'
|
||||
import taskContent from './modules/task/content'
|
||||
import replay from './modules/analysis/replay'
|
||||
import projectContent from './modules/project/content'
|
||||
import neuliveCsv from './modules/file/neulive/csv'
|
||||
import neuliveExcel from './modules/file/neulive/excel'
|
||||
import eliteCsv from './modules/file/elite/csv'
|
||||
import eliteExcel from './modules/file/elite/excel'
|
||||
// import eliteFile from './modules/file/elite'
|
||||
// import file from './modules/file'
|
||||
import about from './modules/about'
|
||||
|
||||
import state from './state'
|
||||
import mutations from './mutations'
|
||||
|
||||
import replay from './modules/analysis/replay'
|
||||
import file from './modules/file'
|
||||
import download from './modules/download'
|
||||
|
||||
import * as getters from './getters'
|
||||
|
||||
Vue.use(Vuex)
|
||||
@@ -25,12 +22,9 @@ const store = new Vuex.Store({
|
||||
modules: {
|
||||
taskContent,
|
||||
replay,
|
||||
neuliveCsv,
|
||||
neuliveExcel,
|
||||
eliteCsv,
|
||||
eliteExcel,
|
||||
projectContent,
|
||||
about,
|
||||
setting,
|
||||
download,
|
||||
file,
|
||||
},
|
||||
state: state,
|
||||
mutations: mutations,
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
import types from '@/store/modules/about/types'
|
||||
|
||||
const typePath = types.device
|
||||
const deviceActs = {
|
||||
|
||||
/**
|
||||
* init devices list
|
||||
*
|
||||
* @param {object} api
|
||||
*/
|
||||
[typePath.init]: async ({ state, getters, commit, dispatch }, payload) => {
|
||||
const devices = await payload.api.device.getAll()
|
||||
commit(typePath.set, { deviceList: devices.data })
|
||||
},
|
||||
|
||||
/**
|
||||
* reorder devices list
|
||||
*
|
||||
* @param {object} api
|
||||
* @param {object} deviceList
|
||||
*/
|
||||
[typePath.reorder]: async ({ state, getters, commit, dispatch }, payload) => {
|
||||
if (payload.deviceList.length > 0) {
|
||||
// update connect_priority according to id
|
||||
payload.deviceList.map((v, idx) => {
|
||||
v.connect_priority = idx
|
||||
})
|
||||
// update database device's info
|
||||
for (const device of payload.deviceList) {
|
||||
dispatch(typePath.updateDatabaseByID, { id: device.id, request: { connect_priority: device.connect_priority }, api: payload.api })
|
||||
}
|
||||
commit(typePath.set, { deviceList: payload.deviceList })
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* update database device table data by ID with request
|
||||
*
|
||||
* @param {number} id
|
||||
* @param {object} request
|
||||
* @param {object} api
|
||||
*/
|
||||
[typePath.updateDatabaseByID]: async ({ state, getters, commit, dispatch }, payload) => {
|
||||
await payload.api.device.updateByID(payload.id, payload.request)
|
||||
},
|
||||
|
||||
/**
|
||||
* delete device
|
||||
*
|
||||
* @param {number} id
|
||||
* @param {number} index
|
||||
* @param {Array} deviceList
|
||||
* @param {object} api
|
||||
*/
|
||||
[typePath.remove]: async ({ state, getters, commit, dispatch }, payload) => {
|
||||
if (payload.deviceList.length > 0) {
|
||||
payload.deviceList.splice(payload.index, 1)
|
||||
dispatch(typePath.reorder, { deviceList: payload.deviceList, api: payload.api })
|
||||
|
||||
await dispatch(typePath.updateDatabaseByID, { id: payload.id, request: { deleted: true }, api: payload.api })
|
||||
await payload.api.device.del(payload.id)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
export default deviceActs
|
||||
@@ -19,6 +19,43 @@ const recGets = {
|
||||
[typePath.getAll]: (state) => {
|
||||
return state.recInfo
|
||||
},
|
||||
|
||||
/**
|
||||
* get cycle data mapping
|
||||
* @param {string} : meta ID
|
||||
* @param {int} : cycle channel index
|
||||
* @param {object} : cycleDataList, list value: object
|
||||
* @return {object} : cycle mapping
|
||||
*/
|
||||
[typePath.getCycleDict]: (state) => (cycleDataList) => {
|
||||
// get cycle data
|
||||
// const cycleDataList = state.recInfo[metaID][cycleDataID][state.currentScale]
|
||||
const cycleDataListNum = cycleDataList.length
|
||||
var cycleDict = {}
|
||||
var cycleStartTime = 0
|
||||
var cycleEndTime = 0
|
||||
var currentCycleIndex = 0
|
||||
for (let i = 0; i < cycleDataListNum; i++) {
|
||||
const cycleDataArray = cycleDataList[i].data
|
||||
for (let index = 0; index < cycleDataArray.length; index++) {
|
||||
const value = cycleDataArray[index]
|
||||
const time = parseInt(value[0])
|
||||
const cycleIndex = parseInt(value[1])
|
||||
if (cycleIndex === currentCycleIndex) {
|
||||
if (currentCycleIndex in cycleDict) {
|
||||
cycleEndTime = time
|
||||
cycleDict[cycleIndex][1] = cycleEndTime
|
||||
} else {
|
||||
cycleDict[cycleIndex] = [cycleStartTime, cycleEndTime]
|
||||
}
|
||||
} else {
|
||||
cycleStartTime = time
|
||||
currentCycleIndex++
|
||||
}
|
||||
}
|
||||
}
|
||||
return cycleDict
|
||||
},
|
||||
}
|
||||
|
||||
export default recGets
|
||||
|
||||
@@ -99,8 +99,8 @@ const chartMutations = {
|
||||
label += millisecond + ' ms '
|
||||
}
|
||||
} else { // not time, e.g. I, V, R
|
||||
const num = val / unitScale
|
||||
label = num.toExponential(3) + unit
|
||||
const num = String(val / unitScale)
|
||||
label = num + unit
|
||||
}
|
||||
return label
|
||||
}
|
||||
@@ -289,6 +289,47 @@ const chartMutations = {
|
||||
return chartData
|
||||
},
|
||||
|
||||
/**
|
||||
* update axis 間距刻度數量
|
||||
*
|
||||
* @param {int} chartID
|
||||
* @param {string} axis ('x' or 'y')
|
||||
*/
|
||||
[typePath.updateAxisSplitNumber]: (state, payload) => {
|
||||
if (payload.axis === 'x') {
|
||||
const axis = state.chartData[payload.chartID].xAxis
|
||||
const len = axis.length
|
||||
for (let i = 0; i < len; i++) {
|
||||
axis[i].splitNumber = 5
|
||||
}
|
||||
} else if (payload.axis === 'y') {
|
||||
const axis = state.chartData[payload.chartID].yAxis
|
||||
const len = axis.length
|
||||
let splitNum
|
||||
if (len === 1) {
|
||||
splitNum = 5
|
||||
} else if (len > 1 && len <= 4) {
|
||||
splitNum = 3
|
||||
} else if (len > 4) {
|
||||
splitNum = 1
|
||||
}
|
||||
for (let i = 0; i < len; i++) {
|
||||
axis[i].splitNumber = splitNum
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* update chart sampling method
|
||||
*
|
||||
* @param {int} chartID
|
||||
* @param {int} seriesIndex
|
||||
* @param {object} method
|
||||
*/
|
||||
[typePath.updateChartSampling]: (state, payload) => {
|
||||
state.chartData[payload.chartID].series[payload.seriesIndex].sampling = payload.method
|
||||
},
|
||||
|
||||
}
|
||||
|
||||
export default chartMutations
|
||||
|
||||
@@ -20,12 +20,14 @@ function newState () {
|
||||
startTimeCurrent: 0,
|
||||
endTimeCurrent: 0,
|
||||
currentScale: '0',
|
||||
sampleMethod: 'mean',
|
||||
axisXLabelScale: {}, // Linear or Log
|
||||
axisYLabelScale: {}, // Linear or Log
|
||||
axisXDataType: {}, // time, current, voltage or resistance, see ChangeAxis.vue
|
||||
axisYDataType: {},
|
||||
valueFormatX: {},
|
||||
valueFormatY: {},
|
||||
showCyclePanel: false,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,8 @@ const types = {
|
||||
updateAxisEventHandler: 'updateAxisEventHandlerChart',
|
||||
updateAxisValMinMax: 'updateAxisValMinMaxChart',
|
||||
updateRegistered: 'updateRegisteredChart',
|
||||
updateAxisSplitNumber: 'updateAxisSplitNumberChart',
|
||||
updateChartSampling: 'updateChartSamplingChart',
|
||||
|
||||
resetChartDataAxisLabel: 'resetChartDataAxisLabelChart',
|
||||
},
|
||||
@@ -59,6 +61,7 @@ const types = {
|
||||
updateDisplaySetting: 'updateDisplaySettingRec',
|
||||
|
||||
getAll: 'getAllRec',
|
||||
getCycleDict: 'getCycleDictRec',
|
||||
},
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
import types from '@/store/modules/download/types'
|
||||
import streamSaver from 'streamsaver'
|
||||
import newDownloadStream from '@/factories/file/downloadStreamFactory'
|
||||
|
||||
const typePath = types.downloadStream
|
||||
|
||||
const encode = TextEncoder.prototype.encode.bind(new TextEncoder())
|
||||
|
||||
const downloadStreamActs = {
|
||||
|
||||
[typePath.setDownloadStream]: function ({ state, getters, commit, dispatch }, payload) {
|
||||
const downloadInfo = state.downloadInfo
|
||||
if (downloadInfo.downloadStream === null) {
|
||||
downloadInfo.downloadStream = newDownloadStream()
|
||||
if (downloadInfo.downloadStream.fileStream === null) {
|
||||
downloadInfo.downloadStream.fileStream = streamSaver.createWriteStream(downloadInfo.filename + '.csv', {
|
||||
size: downloadInfo.size,
|
||||
})
|
||||
downloadInfo.downloadStream.writer = downloadInfo.downloadStream.fileStream.getWriter()
|
||||
window.isSecureContext && window.addEventListener('beforeunload', evt => {
|
||||
downloadInfo.downloadStream.writer.close()
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
[typePath.writeData]: function ({ state, getters, commit }, payload) {
|
||||
const data = encode(payload.data)
|
||||
data && state.downloadInfo.downloadStream.writer.write(data)
|
||||
},
|
||||
|
||||
[typePath.writerClose]: function ({ state, getters, commit }, payload) {
|
||||
state.downloadInfo.downloadStream.writer.close()
|
||||
},
|
||||
}
|
||||
|
||||
export default downloadStreamActs
|
||||
@@ -0,0 +1,242 @@
|
||||
import golbalMethods from '@/data/global/global'
|
||||
import types from '@/store/modules/download/types'
|
||||
|
||||
const typePath = types.export
|
||||
const typePathDownload = types.download
|
||||
const typePathDownloadStream = types.downloadStream
|
||||
|
||||
const NeuliveParameterOrder = ['RECORDING_CH', 'AXIS_CH', 'AMP_GAIN', 'ADC_CLOCK']
|
||||
const NeuliveAmpGain = [100, 400, 800]
|
||||
|
||||
const exportActs = {
|
||||
[typePath.setHeader]: function ({ state, getters, commit, dispatch }, payload) {
|
||||
const meta = state.metaInfo
|
||||
const device = state.downloadInfo.device
|
||||
const deviceHeader = ['Device', meta.device.device_name, golbalMethods.transMac(meta.device.device_address)]
|
||||
const libraryHeader = ['Libaray', meta.device.library_name, meta.device.library_version]
|
||||
const parameter = []
|
||||
|
||||
if (device[0] === 'Neulive') {
|
||||
NeuliveParameterOrder.forEach(p => {
|
||||
const value = meta.parameter_set[p]
|
||||
if (p === 'RECORDING_CH') {
|
||||
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) + '"'
|
||||
parameter.push(['Record channels', result])
|
||||
} else if (p === 'AXIS_CH') {
|
||||
let result = '"'
|
||||
const channelList = value.toString(2).split('').reverse()
|
||||
channelList.forEach((_value, _index) => {
|
||||
if (_value === '1') {
|
||||
if (_index === 0) {
|
||||
result = result + 'x,'
|
||||
} else if (_index === 1) {
|
||||
result = result + 'y,'
|
||||
} else if (_index === 2) {
|
||||
result = result + 'z,'
|
||||
} else if (_index === 3) {
|
||||
result = result + 'm,'
|
||||
}
|
||||
}
|
||||
})
|
||||
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') {
|
||||
const recordChannel = JSON.parse(meta.channels).filter(ch => parseInt(ch) < 256)
|
||||
parameter.push(['Sample Rate', parseInt(8e5 / (value * recordChannel.length))])
|
||||
}
|
||||
})
|
||||
} else if (device[0] === 'Elite') {
|
||||
const sortedParameterSet = {}
|
||||
Object.keys(meta.parameter_set).sort().forEach(key => {
|
||||
sortedParameterSet[key] = meta.parameter_set[key]
|
||||
})
|
||||
for (const p in sortedParameterSet) {
|
||||
parameter.push([p, meta.parameter_set[p]])
|
||||
}
|
||||
}
|
||||
const headersArray = [deviceHeader, libraryHeader, ...parameter]
|
||||
let headersString = ''
|
||||
headersArray.forEach(header => {
|
||||
headersString += header.join(',') + '\r\n'
|
||||
})
|
||||
console.log(headersString)
|
||||
dispatch(typePathDownloadStream.writeData, { data: headersString })
|
||||
},
|
||||
|
||||
[typePath.setTitle]: function ({ state, getters, commit, dispatch }, payload) {
|
||||
const downloadInfo = state.downloadInfo
|
||||
let channelString = ''
|
||||
let titleString = ''
|
||||
let cycle = -1
|
||||
|
||||
for (const channel in downloadInfo.channelInfo) {
|
||||
cycle = Math.max(cycle, downloadInfo.channelInfo[channel].downloadIDList.length)
|
||||
}
|
||||
|
||||
if (downloadInfo.format === 'csv-edf') {
|
||||
channelString += 'Time,'
|
||||
}
|
||||
|
||||
while (cycle > 0) {
|
||||
for (const channel of downloadInfo.channel) {
|
||||
if (downloadInfo.device[0] === 'Neulive') {
|
||||
if (downloadInfo.format === 'csv-edf') {
|
||||
switch (channel) {
|
||||
case 256:
|
||||
channelString += 'x,'
|
||||
break
|
||||
case 257:
|
||||
channelString += 'y,'
|
||||
break
|
||||
case 258:
|
||||
channelString += 'z,'
|
||||
break
|
||||
case 259:
|
||||
channelString += 'm,'
|
||||
break
|
||||
default:
|
||||
channelString += `${parseInt(channel) + 1},`
|
||||
break
|
||||
}
|
||||
} else {
|
||||
switch (channel) {
|
||||
case 256:
|
||||
channelString += 'channel,x,'
|
||||
titleString += 'Time[us],value[g],'
|
||||
break
|
||||
case 257:
|
||||
channelString += 'channel,y,'
|
||||
titleString += 'Time[us],value[g],'
|
||||
break
|
||||
case 258:
|
||||
channelString += 'channel,z,'
|
||||
titleString += 'Time[us],value[g],'
|
||||
break
|
||||
case 259:
|
||||
channelString += 'channel,m,'
|
||||
titleString += 'Time[us],value[g],'
|
||||
break
|
||||
default:
|
||||
channelString += `channel,${parseInt(channel) + 1},`
|
||||
titleString += 'Time[us],value[uV],'
|
||||
break
|
||||
}
|
||||
}
|
||||
} else if (downloadInfo.device[0] === 'Elite') {
|
||||
let unitTitle = ''
|
||||
switch (channel) {
|
||||
case 0:
|
||||
unitTitle = 'Current[nA]'
|
||||
break
|
||||
case 1:
|
||||
unitTitle = 'Voltage[uV]'
|
||||
break
|
||||
case 2:
|
||||
unitTitle = 'Resister[mohm]'
|
||||
break
|
||||
case 3:
|
||||
unitTitle = 'Cycle[round]'
|
||||
break
|
||||
default:
|
||||
unitTitle = ''
|
||||
break
|
||||
}
|
||||
// channelString += `channel ${_ch + 1},,`
|
||||
titleString += 'Time[us],' + unitTitle + ','
|
||||
}
|
||||
}
|
||||
cycle -= 1
|
||||
}
|
||||
|
||||
if (downloadInfo.device[0] === 'Neulive') {
|
||||
channelString = channelString.slice(0, -1) + '\r\n'
|
||||
titleString = titleString.slice(0, -1) + '\r\n'
|
||||
if (downloadInfo.format === 'csv-edf') {
|
||||
dispatch(typePathDownloadStream.writeData, { data: channelString })
|
||||
} else {
|
||||
dispatch(typePathDownloadStream.writeData, { data: channelString + titleString })
|
||||
}
|
||||
} else if (downloadInfo.device[0] === 'Elite') {
|
||||
titleString = titleString.slice(0, -1) + '\r\n'
|
||||
dispatch(typePathDownloadStream.writeData, { data: titleString })
|
||||
}
|
||||
console.log(channelString, titleString)
|
||||
},
|
||||
[typePath.setData]: function ({ state, getters, commit, dispatch }, payload) {
|
||||
const downloadInfo = state.downloadInfo
|
||||
const channels = state.downloadInfo.channel
|
||||
let dataLength = null
|
||||
for (const channel of channels) {
|
||||
for (const data of downloadInfo.channelInfo[channel].downloadDataBuffer) {
|
||||
if (dataLength === null) {
|
||||
dataLength = data.length
|
||||
}
|
||||
if (!payload.last) {
|
||||
dataLength = Math.min(dataLength, data.length)
|
||||
}
|
||||
if (payload.last) {
|
||||
dataLength = Math.max(dataLength, data.length)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let dataString = ''
|
||||
|
||||
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) {
|
||||
if (dataBuffer[index][row] === undefined) {
|
||||
if (downloadInfo.format === 'csv-edf' && payload.last) {
|
||||
dataBuffer[index][row] = []
|
||||
if (chIndex === 0) {
|
||||
dataBuffer[index][row].push(((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])
|
||||
} else {
|
||||
rowData.push(...['', ''])
|
||||
}
|
||||
} else {
|
||||
if (downloadInfo.format === 'csv-edf') {
|
||||
if (chIndex === 0) {
|
||||
dataBuffer[index][row][0] = (dataBuffer[index][row][0] / 1e6).toFixed(6)
|
||||
rowData.push(...dataBuffer[index][row])
|
||||
} else {
|
||||
rowData.push(dataBuffer[index][row][1])
|
||||
}
|
||||
} else {
|
||||
rowData.push(...dataBuffer[index][row])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
dataString = dataString + rowData.join(',') + '\r\n'
|
||||
rowData.length = 0
|
||||
}
|
||||
|
||||
dispatch(typePathDownloadStream.writeData, { data: dataString }).then(response => {
|
||||
// for (const channel of state.downloadInfo.channel) {
|
||||
// for (const data of state.downloadInfo.channelInfo[channel].downloadDataBuffer) {
|
||||
// data.splice(0, dataLength)
|
||||
// }
|
||||
// }
|
||||
commit(typePathDownload.delDownloadBuffer, { dataLength: dataLength })
|
||||
})
|
||||
},
|
||||
}
|
||||
|
||||
export default exportActs
|
||||
@@ -0,0 +1,9 @@
|
||||
import rawAct from './rawAct'
|
||||
import exportAct from './exportAct'
|
||||
import downloadStreamAct from './downloadStreamAct'
|
||||
|
||||
export default {
|
||||
...rawAct,
|
||||
...exportAct,
|
||||
...downloadStreamAct,
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
import types from '@/store/modules/download/types'
|
||||
|
||||
const typePath = types.raw
|
||||
|
||||
const rawActs = {
|
||||
/**
|
||||
* get raw data by single ID from database
|
||||
*
|
||||
* @param {Number} channel
|
||||
* @param {Array} rawDataIDList
|
||||
* @param {Number} time_duration
|
||||
* @param {objuct} api
|
||||
* @return {object} : raw data
|
||||
*/
|
||||
[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)
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* get raw data by multi ID from database
|
||||
*
|
||||
* @param {Number} channel
|
||||
* @param {Array} rawDataIDList
|
||||
* @param {Number} time_duration
|
||||
* @param {objuct} api
|
||||
* @return {object} : raw data
|
||||
*/
|
||||
[typePath.rawDataByIDs]: async ({ state, getters, commit, dispatch }, payload) => {
|
||||
const { channel, rawDataIDList, api } = payload
|
||||
const rawDataRes = await api.raw.getAttrByIDs(channel, rawDataIDList, 'id-channel-size-serial_number-start_time-end_time-data')
|
||||
if (rawDataRes.data !== null) {
|
||||
dispatch(typePath.parseRawData, { rawData: rawDataRes, channel: channel }).then(response => {
|
||||
}).catch(e => {
|
||||
console.log(e)
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
[typePath.parseRawData]: function ({ state, getters, commit, dispatch }, payload) {
|
||||
const { channel, rawData } = payload
|
||||
const dataArray = []
|
||||
for (const raw of rawData.data) {
|
||||
if (raw.data !== null && raw.data.length > 0) {
|
||||
const encodedData = raw.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] }).then(response => {
|
||||
dataArray.push(...response)
|
||||
}).catch(e => {
|
||||
console.log(e)
|
||||
})
|
||||
} 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)
|
||||
})
|
||||
} else {
|
||||
dispatch(typePath.parseData, { channel: channel, rawData: unzipDatas[i] }).then(response => {
|
||||
dataArray.push(...response)
|
||||
}).catch(e => {
|
||||
console.log(e)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
encodedData.length = 0
|
||||
unzipDatas.length = 0
|
||||
}
|
||||
}
|
||||
delete payload.rawData
|
||||
return dataArray
|
||||
},
|
||||
|
||||
[typePath.parseData]: function ({ state, getters, commit }, payload) {
|
||||
const { channel, rawData } = payload
|
||||
const meta = state.metaInfo
|
||||
const dataArray = []
|
||||
|
||||
for (let i = 0; i <= rawData.length - 1; i += 2) {
|
||||
if (rawData[i].length !== 0) {
|
||||
const time = parseInt(rawData[i])
|
||||
const data = (channel >= 256 && channel <= 259) ? (rawData[i + 1] / 100).toFixed(3) : rawData[i + 1]
|
||||
|
||||
if (time <= parseInt(meta.time_duration)) {
|
||||
const tmpData = [time, data]
|
||||
dataArray.push(tmpData)
|
||||
}
|
||||
}
|
||||
}
|
||||
delete payload.rawData
|
||||
return dataArray
|
||||
},
|
||||
|
||||
[typePath.parseFixedData]: function ({ state, getters, commit }, payload) {
|
||||
const { channel, rawData } = 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) {
|
||||
const time = Math.floor(parseInt(rawData[i]) / timeInterval) * timeInterval
|
||||
const data = (channel >= 256 && channel <= 259) ? (rawData[i + 1] / 100).toFixed(3) : rawData[i + 1]
|
||||
|
||||
let timeDiff = time - downloadInfo.channelInfo[channel].prevTime
|
||||
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)
|
||||
let timeCorrection = 0
|
||||
let dataIndex = 1
|
||||
|
||||
while (timeDiff > 0) {
|
||||
timeCorrection += timeInterval
|
||||
timeDiff -= timeInterval
|
||||
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])
|
||||
dataIndex = dataIndex + 1
|
||||
}
|
||||
}
|
||||
}
|
||||
if (time <= parseInt(meta.time_duration) && time !== downloadInfo.channelInfo[channel].prevTime) {
|
||||
dataArray.push([time, data])
|
||||
}
|
||||
downloadInfo.channelInfo[channel].prevTime = time
|
||||
downloadInfo.channelInfo[channel].prevData = data
|
||||
}
|
||||
}
|
||||
delete payload.rawData
|
||||
return dataArray
|
||||
},
|
||||
}
|
||||
|
||||
export default rawActs
|
||||
@@ -0,0 +1,5 @@
|
||||
import { getField } from 'vuex-map-fields'
|
||||
|
||||
export default {
|
||||
getField,
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
import types from '@/store/modules/download/types'
|
||||
|
||||
const typePath = types.download
|
||||
|
||||
function chunkArray (rawDataIDArray, chunkSize) {
|
||||
const arrayLength = rawDataIDArray.length
|
||||
const results = []
|
||||
for (let index = 0; index < arrayLength; index += chunkSize) {
|
||||
results.push(rawDataIDArray.slice(index, index + chunkSize))
|
||||
}
|
||||
return results
|
||||
}
|
||||
|
||||
const downloadMutations = {
|
||||
/**
|
||||
* set sample rate
|
||||
*
|
||||
*/
|
||||
[typePath.setSampleRate]: function (state, payload) {
|
||||
const meta = state.metaInfo
|
||||
const device = state.downloadInfo.device
|
||||
const channel = payload.channel
|
||||
const timeRatio = 1e6
|
||||
|
||||
let sampleRate = null
|
||||
let sampleRateDivideNum = 1
|
||||
|
||||
if (device[0] === 'Neulive') {
|
||||
if (channel < 256) {
|
||||
sampleRate = parseInt(800000 / parseInt(meta.configuration.ADC_CLOCK))
|
||||
sampleRateDivideNum = state.downloadInfo.channel.length
|
||||
} else if (channel >= 256 && channel <= 259) {
|
||||
sampleRate = parseInt(800000 / parseInt(meta.configuration.ADC_CLOCK) / 78)
|
||||
}
|
||||
} else if (device[0] === 'Elite') {
|
||||
if (device[1] === 'ZM15') {
|
||||
if (parseInt(meta.configuration.MODE) === 0 || parseInt(meta.configuration.MODE) === 1) {
|
||||
if (parseInt(meta.configuration.STEP_TIME) === 0) {
|
||||
sampleRate = 2
|
||||
} else if (parseInt(meta.configuration.STEP_TIME) === 1) {
|
||||
sampleRate = 1
|
||||
} else if (parseInt(meta.configuration.STEP_TIME) === 2) {
|
||||
sampleRate = 0.5
|
||||
}
|
||||
} else {
|
||||
sampleRate = parseInt(meta.configuration.SAMPLE_RATE) / 10
|
||||
}
|
||||
} else if (device[1] === 'EIS') {
|
||||
if (parseInt(meta.configuration.MODE) === 0) {
|
||||
sampleRate = 1
|
||||
} else {
|
||||
sampleRate = parseInt(meta.configuration.SAMPLE_RATE) / 10
|
||||
}
|
||||
} else {
|
||||
sampleRate = parseInt(meta.configuration.SAMPLE_RATE) / 10
|
||||
}
|
||||
}
|
||||
if (sampleRate !== null) {
|
||||
state.downloadInfo.channelInfo[channel].sampleRate = sampleRate
|
||||
state.downloadInfo.channelInfo[channel].timeInterval = parseInt((1 / (sampleRate / sampleRateDivideNum)) * timeRatio)
|
||||
}
|
||||
},
|
||||
/**
|
||||
* set download id list
|
||||
*
|
||||
*/
|
||||
[typePath.setdownloadIdList]: function (state, payload) {
|
||||
const channel = payload.channel
|
||||
const meta = state.metaInfo
|
||||
const downloadInfo = state.downloadInfo
|
||||
|
||||
if (downloadInfo.format === 'csv' || downloadInfo.format === 'csv-edf') {
|
||||
downloadInfo.channelInfo[channel].downloadIDList.push(JSON.parse(JSON.stringify(meta.raw_data[channel])))
|
||||
downloadInfo.maxColumns = 1
|
||||
downloadInfo.maxRows = downloadInfo.channelInfo[channel].downloadIDList[0].length
|
||||
} else if (downloadInfo.format === 'excel') {
|
||||
// get sample rate
|
||||
const sampleRate = downloadInfo.channelInfo[channel].sampleRate
|
||||
// estimate total sample nums
|
||||
const sampleNums = parseInt((parseInt(meta.time_duration) * sampleRate) / 1e6)
|
||||
const idNums = meta.raw_data[channel].length
|
||||
|
||||
// estimate per raw_data contains x of samples
|
||||
const samplePerRawData = parseInt(sampleNums / idNums)
|
||||
|
||||
// estimate 5e5 rows need how many ID
|
||||
const rawDataPerColumnTemp = parseInt((5e5 / parseInt(samplePerRawData)) + 1)
|
||||
const rawDataPerColumn = (rawDataPerColumnTemp > idNums) ? idNums : rawDataPerColumnTemp
|
||||
|
||||
const rawDataIDDoubleArray = chunkArray(meta.raw_data[channel], rawDataPerColumn)
|
||||
downloadInfo.maxColumns = rawDataIDDoubleArray.length
|
||||
for (const rawDataArray of rawDataIDDoubleArray) {
|
||||
downloadInfo.maxRows = Math.max(downloadInfo.maxRows, rawDataArray.length)
|
||||
downloadInfo.channelInfo[channel].downloadIDList.push(rawDataArray)
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
[typePath.delDownloadBuffer]: function (state, payload) {
|
||||
for (const channel of state.downloadInfo.channel) {
|
||||
for (const data of state.downloadInfo.channelInfo[channel].downloadDataBuffer) {
|
||||
data.splice(0, payload.dataLength)
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
export default downloadMutations
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
import downloadMut from './downloadMut'
|
||||
import exportMut from './exportMut'
|
||||
import { updateField } from 'vuex-map-fields'
|
||||
|
||||
export default {
|
||||
...downloadMut,
|
||||
...exportMut,
|
||||
updateField,
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
function newState () {
|
||||
return {
|
||||
metaList: [],
|
||||
metaInfo: {},
|
||||
downloadInfo: {},
|
||||
}
|
||||
}
|
||||
|
||||
export default newState
|
||||
@@ -0,0 +1,26 @@
|
||||
|
||||
const types = {
|
||||
download: {
|
||||
setSampleRate: 'setSampleRateDownload',
|
||||
setdownloadIdList: 'setdownloadIdListDownload',
|
||||
delDownloadBuffer: 'delDownloadBufferDownload',
|
||||
},
|
||||
export: {
|
||||
setHeader: 'setHeaderExport',
|
||||
setTitle: 'setTitleExport',
|
||||
setData: 'setDataExport',
|
||||
},
|
||||
raw: {
|
||||
rawDataByID: 'rawDataByIDRaw',
|
||||
parseRawData: 'parseRawDataRaw',
|
||||
parseData: 'parseDataRaw',
|
||||
parseFixedData: 'parseFixedDataRaw',
|
||||
},
|
||||
downloadStream: {
|
||||
setDownloadStream: 'setDownloadStream',
|
||||
writeData: 'writeDataDownloadStream',
|
||||
writerClose: 'writerCloseDownloadStream',
|
||||
},
|
||||
}
|
||||
|
||||
export default types
|
||||
@@ -0,0 +1,6 @@
|
||||
|
||||
import tableAct from './tableAct'
|
||||
|
||||
export default {
|
||||
...tableAct,
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import types from '@/store/modules/file/types'
|
||||
|
||||
const typePath = types.table
|
||||
|
||||
const tableActs = {
|
||||
/**
|
||||
* init meta
|
||||
*
|
||||
* @param {Array} metaIDList
|
||||
* @param {objuct} api
|
||||
* @return {object} : meta list info
|
||||
*/
|
||||
[typePath.init]: async ({ state, getters, commit }, payload) => {
|
||||
},
|
||||
}
|
||||
|
||||
export default tableActs
|
||||
@@ -1,145 +0,0 @@
|
||||
import newDownload from '@/factories/file/downloadFactory'
|
||||
import types from '@/store/modules/file/elite/csv/types'
|
||||
|
||||
const typePath = types.download
|
||||
|
||||
// function getExcleNeedColumns (downloadInfo, excelFormat) {
|
||||
// let maxIDNums = 1
|
||||
// const meta = downloadInfo.meta
|
||||
// const sampleRate = 800000 / meta.configuration.ADC_CLOCK
|
||||
// const sampleNums = parseInt((parseInt(meta.time_duration) * sampleRate) / 1e6)
|
||||
|
||||
// for (const channelID in meta.raw_data) {
|
||||
// maxIDNums = (meta.raw_data[channelID].length > maxIDNums) ? meta.raw_data[channelID].length : maxIDNums
|
||||
// }
|
||||
|
||||
// const RowPerID = parseInt(sampleNums / maxIDNums)
|
||||
// const IDPerColumn = (excelFormat) ? RowPerID / (parseInt(RowPerID / 5e5) + 1) : RowPerID
|
||||
|
||||
// for (const channelID in meta.raw_data) {
|
||||
// downloadInfo.downloadIDList[channelID] = chunkArray(meta.raw_data[channelID], IDPerColumn)
|
||||
// }
|
||||
// }
|
||||
|
||||
// function chunkArray (rawDataIDArray, chunkSize) {
|
||||
// const arrayLength = rawDataIDArray.length
|
||||
// const results = []
|
||||
// for (let index = 0; index < arrayLength; index += chunkSize) {
|
||||
// results.push(rawDataIDArray.slice(index, index + chunkSize))
|
||||
// }
|
||||
// return results
|
||||
// }
|
||||
|
||||
const downloadActs = {
|
||||
/**
|
||||
* init downloadList info
|
||||
*
|
||||
* @param {Array} metaIDList
|
||||
* @param {objuct} api
|
||||
* @return {object} : download list
|
||||
*/
|
||||
[typePath.init]: async ({ state, getters, commit }, payload) => {
|
||||
const promises = payload.metaIDList.map(async id => {
|
||||
const metaRes = await payload.api.meta.getByID(String(id))
|
||||
const downloadInfo = Object.assign(newDownload(), metaRes.data[0])
|
||||
for (const channel of JSON.parse(downloadInfo.channels)) {
|
||||
downloadInfo.downloadBuffer[channel] = []
|
||||
}
|
||||
// downloadInfo.downloadIDList = JSON.parse(JSON.stringify(downloadInfo.raw_data))
|
||||
// getExcleNeedColumns(downloadInfo, true)
|
||||
return downloadInfo
|
||||
})
|
||||
const list = await Promise.all(promises)
|
||||
commit(typePath.set, { list: list })
|
||||
return list
|
||||
},
|
||||
|
||||
// [typePath.start]: async ({ state, getters, commit }, payload) => {
|
||||
// },
|
||||
|
||||
/**
|
||||
* get raw data by multi ID from database
|
||||
*
|
||||
* @param {Number} channel
|
||||
* @param {Array} rawDataIDList
|
||||
* @param {Number} time_duration
|
||||
* @param {objuct} api
|
||||
* @return {object} : raw data
|
||||
*/
|
||||
[typePath.rawDataByIDs]: async ({ state, getters, commit, dispatch }, payload) => {
|
||||
const { channel, rawDataIDList, api } = payload
|
||||
const rawDataRes = await api.raw.getAttrByIDs(channel, rawDataIDList, 'id-channel-size-serial_number-start_time-end_time-data')
|
||||
dispatch(typePath.parseRawData, { rawData: rawDataRes, channel: channel })
|
||||
},
|
||||
|
||||
[typePath.parseRawData]: function ({ state, getters, commit, dispatch }, payload) {
|
||||
const { channel, rawData } = payload
|
||||
for (const raw of rawData.data) {
|
||||
if (raw.data !== null && raw.data.length > 0) {
|
||||
const encodedData = raw.data.split('"***"')
|
||||
// console.log(encodedData)
|
||||
const unzipDatas = encodedData.map(ctx => {
|
||||
return ctx.split(' ')
|
||||
})
|
||||
// console.log(unzipDatas)
|
||||
|
||||
for (let i = 0; i <= unzipDatas.length - 1; i++) {
|
||||
if (unzipDatas[i].length > 0) {
|
||||
dispatch(typePath.parseEachData, { rawData: unzipDatas[i], channel: channel })
|
||||
}
|
||||
}
|
||||
encodedData.length = 0
|
||||
// unzipDatas.length = 0
|
||||
}
|
||||
}
|
||||
delete payload.rawData
|
||||
},
|
||||
|
||||
[typePath.parseEachData]: function ({ state, getters, commit }, payload) {
|
||||
const { channel, rawData } = payload
|
||||
|
||||
const meta = state.downloadingFile
|
||||
const sampleRate = 800000 / meta.configuration.ADC_CLOCK
|
||||
const averageSampleRate = sampleRate / JSON.parse(meta.channels).length
|
||||
const timeInterval = parseInt((1 / averageSampleRate) * 1e6)
|
||||
let prevTime = -1
|
||||
let prevData = 0
|
||||
|
||||
for (let i = 0; i <= rawData.length - 1; i += 2) {
|
||||
if (rawData[i].length !== 0) {
|
||||
const time = parseInt(rawData[i])
|
||||
const data = rawData[i + 1]
|
||||
if (state.downloadingFile.recoverData) {
|
||||
let timeDiff = time - prevTime
|
||||
const timeDiffOrigin = timeDiff
|
||||
if (timeDiff >= 1.8 * timeInterval && prevTime !== -1) {
|
||||
console.log('data-recover', timeDiff)
|
||||
let timeCorrection = 0
|
||||
let dataIndex = 1
|
||||
|
||||
while (timeDiff > 0) {
|
||||
timeCorrection += timeInterval
|
||||
timeDiff -= timeInterval
|
||||
if (timeDiff > 0) {
|
||||
const _time = parseInt(prevTime) + parseInt(timeCorrection)
|
||||
const _data = parseInt(prevData) + (timeCorrection / timeDiffOrigin) * (parseInt(data) - parseInt(prevData))
|
||||
const tmpData = [_time, _data]
|
||||
state.downloadingFile.downloadBuffer[channel].push(tmpData)
|
||||
dataIndex = dataIndex + 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (time <= parseInt(meta.time_duration)) {
|
||||
const tmpData = [time, data]
|
||||
state.downloadingFile.downloadBuffer[channel].push(tmpData)
|
||||
}
|
||||
prevTime = time
|
||||
prevData = data
|
||||
}
|
||||
}
|
||||
delete payload.rawData
|
||||
},
|
||||
}
|
||||
|
||||
export default downloadActs
|
||||
@@ -1,191 +0,0 @@
|
||||
import streamSaver from 'streamsaver'
|
||||
import types from '@/store/modules/file/elite/csv/types'
|
||||
import golbalMethods from '@/data/global/global'
|
||||
|
||||
const typePath = types.export
|
||||
const typePathDownload = types.download
|
||||
|
||||
const NeuliveParameterOrder = ['RECORDING_CH', 'AMP_GAIN', 'ADC_CLOCK']
|
||||
const NeuliveAmpGain = [100, 400, 800]
|
||||
|
||||
let fileStream, writer
|
||||
const encode = TextEncoder.prototype.encode.bind(new TextEncoder())
|
||||
|
||||
function intoFileStream (data, filename, size, close) {
|
||||
if (!fileStream) {
|
||||
if (filename !== undefined) {
|
||||
fileStream = streamSaver.createWriteStream(filename + '.csv', {
|
||||
size: size,
|
||||
})
|
||||
writer = fileStream.getWriter()
|
||||
}
|
||||
}
|
||||
|
||||
data = encode(data)
|
||||
data && writer.write(data)
|
||||
}
|
||||
|
||||
function closeWriter () {
|
||||
writer.close()
|
||||
}
|
||||
|
||||
const exportActs = {
|
||||
/**
|
||||
* init meta
|
||||
*
|
||||
* @param {Array} metaIDList
|
||||
* @param {objuct} api
|
||||
* @return {object} : meta list info
|
||||
*/
|
||||
[typePath.init]: async ({ state, getters, commit }, payload) => {
|
||||
const promises = payload.metaIDList.map(async id => {
|
||||
const metaRes = await payload.api.meta.getByID(id)
|
||||
return metaRes.data[0]
|
||||
})
|
||||
const list = await Promise.all(promises)
|
||||
commit(typePath.set, { list: list })
|
||||
},
|
||||
|
||||
// createHeadersString: function (headers, channel) {
|
||||
[typePath.createHeadersString]: function ({ state, getters, commit, dispatch }, payload) {
|
||||
const headers = state.downloadingFile
|
||||
const device = ['Device', headers.device.device_name, golbalMethods.transMac(headers.device.device_address)]
|
||||
const library = ['Libaray', headers.device.library_name, headers.device.library_version]
|
||||
const parameter = []
|
||||
if (headers.device.library_name.indexOf('Neulive') >= 0) {
|
||||
NeuliveParameterOrder.forEach(p => {
|
||||
const value = headers.parameter_set[p]
|
||||
if (p === 'RECORDING_CH') {
|
||||
let result = '"'
|
||||
const channelList = value.toString(2).split('').reverse()
|
||||
channelList.forEach((_value, _index) => {
|
||||
if (_value === '1') {
|
||||
result = result + `${_index + 1},`
|
||||
}
|
||||
})
|
||||
result = result.slice(0, -1) + '"'
|
||||
parameter.push(['Record channels', result])
|
||||
} else if (p === 'AMP_GAIN') {
|
||||
parameter.push(['Amp gain', NeuliveAmpGain[value]])
|
||||
} else if (p === 'ADC_CLOCK') {
|
||||
parameter.push(['Sample Rate', parseInt(8e5 / (value * JSON.parse(headers.channels).length))])
|
||||
}
|
||||
})
|
||||
} else if (headers.device.library_name.indexOf('Elite') >= 0) {
|
||||
const sortedParameterSet = {}
|
||||
Object.keys(headers.parameter_set).sort().forEach(key => {
|
||||
sortedParameterSet[key] = headers.parameter_set[key]
|
||||
})
|
||||
for (const p in sortedParameterSet) {
|
||||
parameter.push([p, headers.parameter_set[p]])
|
||||
}
|
||||
}
|
||||
const headersArray = [device, library, ...parameter]
|
||||
let headersString = ''
|
||||
headersArray.forEach(header => {
|
||||
headersString += header.join(',') + '\r\n'
|
||||
})
|
||||
dispatch(typePath.writeDataToFileStream, { data: headersString })
|
||||
},
|
||||
// createTitlesString: function (headers, cycle, channel) {
|
||||
[typePath.createTitlesString]: function ({ state, getters, commit, dispatch }, payload) {
|
||||
let channelString = ''
|
||||
let titleString = ''
|
||||
|
||||
for (const _ch of JSON.parse(state.downloadingFile.channels)) {
|
||||
if (state.downloadingFile.device.library_name.indexOf('Neulive') >= 0) {
|
||||
switch (_ch) {
|
||||
case 256:
|
||||
channelString += 'channel,X,'
|
||||
break
|
||||
case 257:
|
||||
channelString += 'channel,Y,'
|
||||
break
|
||||
case 258:
|
||||
channelString += 'channel,Z,'
|
||||
break
|
||||
case 259:
|
||||
channelString += 'channel,M,'
|
||||
break
|
||||
default:
|
||||
channelString += `channel,${parseInt(_ch) + 1},`
|
||||
break
|
||||
}
|
||||
titleString += 'Time[us],value[uV],'
|
||||
} else if (state.downloadingFile.device.library_name.indexOf('Elite') >= 0) {
|
||||
const _time = 'Time[us]'
|
||||
let _title = ''
|
||||
switch (_ch) {
|
||||
case 0:
|
||||
_title = 'Current[nA]'
|
||||
break
|
||||
case 1:
|
||||
_title = 'Voltage[uV]'
|
||||
break
|
||||
case 2:
|
||||
_title = 'Resister[mohm]'
|
||||
break
|
||||
default:
|
||||
_title = ''
|
||||
break
|
||||
}
|
||||
// channelString += `channel ${_ch + 1},,`
|
||||
titleString += _time + ',' + _title + ','
|
||||
}
|
||||
}
|
||||
|
||||
if (state.downloadingFile.device.library_name.indexOf('Neulive') >= 0) {
|
||||
channelString = channelString.slice(0, -1) + '\r\n'
|
||||
titleString = titleString.slice(0, -1) + '\r\n'
|
||||
dispatch(typePath.writeDataToFileStream, { data: channelString + titleString })
|
||||
} else if (state.downloadingFile.device.library_name.indexOf('Elite') >= 0) {
|
||||
titleString = titleString.slice(0, -1) + '\r\n'
|
||||
dispatch(typePath.writeDataToFileStream, { data: titleString })
|
||||
}
|
||||
},
|
||||
|
||||
[typePath.createDataString]: function ({ state, getters, commit, dispatch }, payload) {
|
||||
const data = state.downloadingFile.downloadBuffer
|
||||
let dataLength
|
||||
|
||||
for (const channel in data) {
|
||||
if (dataLength === undefined) {
|
||||
dataLength = data[channel].length
|
||||
}
|
||||
if (data[channel].length < dataLength) {
|
||||
dataLength = data[channel].length
|
||||
}
|
||||
}
|
||||
|
||||
let dataString = ''
|
||||
|
||||
for (let idx = 0; idx < dataLength; idx++) {
|
||||
const rowData = []
|
||||
for (const channel in data) {
|
||||
if (data[channel][idx] === undefined) {
|
||||
rowData.push(...['', ''])
|
||||
} else {
|
||||
rowData.push(...data[channel][idx])
|
||||
}
|
||||
}
|
||||
dataString = dataString + rowData.join(',') + '\r\n'
|
||||
rowData.length = 0
|
||||
}
|
||||
|
||||
dispatch(typePath.writeDataToFileStream, { data: dataString })
|
||||
commit(typePathDownload.removeDownloadBuffer, { dataLength: dataLength })
|
||||
dataString = ''
|
||||
// return dataString
|
||||
},
|
||||
|
||||
[typePath.writeDataToFileStream]: function ({ state, getters, commit }, payload) {
|
||||
intoFileStream(payload.data, state.downloadingFile.name, state.downloadingFile.size)
|
||||
payload.data = null
|
||||
},
|
||||
|
||||
[typePath.closeFileStream]: function ({ state, getters, commit }, payload) {
|
||||
closeWriter()
|
||||
},
|
||||
}
|
||||
|
||||
export default exportActs
|
||||
@@ -1,7 +0,0 @@
|
||||
import downloadAct from './downloadAct'
|
||||
import exportAct from './exportAct'
|
||||
|
||||
export default {
|
||||
...downloadAct,
|
||||
...exportAct,
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
import types from '@/store/modules/file/elite/csv/types'
|
||||
|
||||
const typePath = types.download
|
||||
|
||||
const downloadGets = {
|
||||
/**
|
||||
* get download info by list index
|
||||
*
|
||||
* @param {int} index
|
||||
* @return {object} : download info
|
||||
*/
|
||||
[typePath.getByIndex]: (state) => (index) => {
|
||||
if (index == null || state.downloadList[index] == null) {
|
||||
return null
|
||||
}
|
||||
return state.downloadList[index]
|
||||
},
|
||||
|
||||
/**
|
||||
* get download by id
|
||||
*
|
||||
* @param {int} id
|
||||
* @return {object} : download info
|
||||
*/
|
||||
[typePath.getByID]: (state) => (id) => {
|
||||
state.downloadList.forEach(meta => {
|
||||
if (meta.id === id) {
|
||||
return meta
|
||||
}
|
||||
})
|
||||
return null
|
||||
},
|
||||
|
||||
/**
|
||||
* get downloading info
|
||||
*
|
||||
* @return {object} : download info
|
||||
*/
|
||||
[typePath.getDownloading]: (state) => {
|
||||
return state.downloadingFile
|
||||
},
|
||||
|
||||
/**
|
||||
* get all download info
|
||||
*
|
||||
* @return {Array} : meta list
|
||||
*/
|
||||
[typePath.getAll]: (state) => {
|
||||
return state.downloadList
|
||||
},
|
||||
|
||||
/**
|
||||
* get raw data ID remaining length
|
||||
*
|
||||
* @return {Array} : meta list
|
||||
*/
|
||||
[typePath.getRemainIDLength]: (state) => (index) => {
|
||||
let IDListLength = 0
|
||||
const downloadIDList = state.downloadList[index].raw_data
|
||||
|
||||
for (const channel in downloadIDList) {
|
||||
if (downloadIDList[channel].length > IDListLength) {
|
||||
IDListLength = downloadIDList[channel].length
|
||||
}
|
||||
}
|
||||
return IDListLength
|
||||
},
|
||||
}
|
||||
|
||||
export default downloadGets
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user