Compare commits
71 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c4163f1ce5 | |||
| d1e7d02a3c | |||
| 81bb8e7b98 | |||
| b822215c04 | |||
| 74e6565c27 | |||
| 0b6b551921 | |||
| ace749b742 | |||
| 75cb542795 | |||
| 29325f2165 | |||
| 21ca818ab6 | |||
| 6d7f5d26ee | |||
| 68e4e6ffea | |||
| eeb08342f6 | |||
| 64988aa95a | |||
| e4816e9447 | |||
| b1c92721be | |||
| d27946ed88 | |||
| adc5686033 | |||
| 5f9c91e5e7 | |||
| e5ccd05903 | |||
| 358687c8dd | |||
| 283c3fbb57 | |||
| 8edfaf6224 | |||
| ed511992ea | |||
| 8ebae697b1 | |||
| 93a0888de5 | |||
| c0c23e77ee | |||
| 684a1fa44b | |||
| fb87eb90ca | |||
| 7b22866929 | |||
| aa5db953a8 | |||
| 4e1021acb9 | |||
| 3d763a3e36 | |||
| ad0f54775b | |||
| 251dcfb750 | |||
| 62b60d02e4 | |||
| 82587d7506 | |||
| 51d69d5a97 | |||
| 9319fa131b | |||
| 10cd8c2d1b | |||
| a93d784d16 | |||
| 54bccd0253 | |||
| f49750a70a | |||
| fc29545948 | |||
| 000722d2d1 | |||
| 9e9dd22bdf | |||
| a6ec77c523 | |||
| 1f1795eb6c | |||
| 373fbafd6c | |||
| e1200a47a1 | |||
| 667469dd50 | |||
| 83816f16d4 | |||
| 92fdfefa30 | |||
| d7bfc9d7c2 | |||
| a0e74c61ee | |||
| 293db99a2e | |||
| 6e05fda2e3 | |||
| 1826a8618b | |||
| 97a3176bd9 | |||
| 2cd467b431 | |||
| 1574883381 | |||
| 78f29fe34c | |||
| 6882cd320f | |||
| b74bbe083d | |||
| cef86f27c2 | |||
| 3b2114b95f | |||
| 3164add2c0 | |||
| 9b5d237928 | |||
| 54be774fe8 | |||
| 52a4dac990 | |||
| 9a3d9689fd |
@@ -23,6 +23,26 @@ createuser biopro -P --interactive
|
||||
|
||||
### Run apiServer on device
|
||||
|
||||
##### Install node.js
|
||||
```
|
||||
sudo apt-get upgrade
|
||||
sudo apt-get update
|
||||
```
|
||||
|
||||
```
|
||||
### setup_14.x can change to your version
|
||||
curl -sL https://deb.nodesource.com/setup_14.x | sudo -E bash -
|
||||
### install node and npm
|
||||
sudo apt-get install -y nodejs
|
||||
```
|
||||
|
||||
##### (optional) if the installation of node.js fail
|
||||
```
|
||||
sudo apt update
|
||||
curl -sL https://deb.nodesource.com/setup_14.x | sudo -E bash -
|
||||
sudo apt-get install -y nodejs
|
||||
```
|
||||
|
||||
##### Clone project
|
||||
```
|
||||
git clone https://gitlab.com/bioproscientific/bioproapiserver.git
|
||||
@@ -35,12 +55,9 @@ vim config.js
|
||||
```
|
||||
change the code following as:
|
||||
```
|
||||
/*
|
||||
change apiserver port to postgres port, 54321 --> 5432 (default)
|
||||
*/
|
||||
export const pgDB = {
|
||||
host: '127.0.0.1', // 服务器地址
|
||||
port: 54321, // 数据库端口号 -----------------> 5432
|
||||
port: 5432, // 数据库端口号
|
||||
username: 'biopro', // 数据库用户名
|
||||
password: 'BioProControlBox', // 数据库密码
|
||||
database: 'postgres' // 数据库名称
|
||||
@@ -60,7 +77,8 @@ sudo vim /etc/rc.local
|
||||
```
|
||||
add the code following as:
|
||||
```
|
||||
nohup node /home/pi/bioproapiserver/dist/app.js > /home/pi/.api_server.out &
|
||||
now=$(date +"%F_%T")
|
||||
sudo -H -u pi nohup node /home/pi/bioproapiserver/dist/app.js > /home/pi/.api_server_$now.out &
|
||||
```
|
||||
|
||||
### Localhost develop
|
||||
@@ -79,4 +97,4 @@ npm run start
|
||||
```
|
||||
|
||||
##### References
|
||||
>https://opensource.com/article/17/10/set-postgres-database-your-raspberry-pi
|
||||
>https://opensource.com/article/17/10/set-postgres-database-your-raspberry-pi
|
||||
|
||||
Generated
+13
@@ -2448,6 +2448,14 @@
|
||||
"integrity": "sha512-zg7Hz2k5lI8kb7U32998pRRFin7zJlkfezGJjUc2heaD4Pw2wObakCDVzkKztTm/Ln7eiVvYsjqak0Ed4LkMDA==",
|
||||
"dev": true
|
||||
},
|
||||
"axios": {
|
||||
"version": "0.24.0",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-0.24.0.tgz",
|
||||
"integrity": "sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==",
|
||||
"requires": {
|
||||
"follow-redirects": "^1.14.4"
|
||||
}
|
||||
},
|
||||
"babel-core": {
|
||||
"version": "7.0.0-bridge.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-core/-/babel-core-7.0.0-bridge.0.tgz",
|
||||
@@ -4860,6 +4868,11 @@
|
||||
"readable-stream": "^2.3.6"
|
||||
}
|
||||
},
|
||||
"follow-redirects": {
|
||||
"version": "1.14.5",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.5.tgz",
|
||||
"integrity": "sha512-wtphSXy7d4/OR+MvIFbCVBDzZ5520qV8XfPklSN5QtxuMUJZ+b0Wnst1e1lCDocfzuCkHqj8k0FpZqO+UIaKNA=="
|
||||
},
|
||||
"for-in": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
|
||||
|
||||
+2
-1
@@ -7,13 +7,14 @@
|
||||
"scripts": {
|
||||
"start": "gulp nodemon",
|
||||
"dev": "gulp",
|
||||
"build": "babel src -d dist --copy-files",
|
||||
"build": "babel src -d dist",
|
||||
"production": "node dist/app.js",
|
||||
"test": "jest",
|
||||
"link": "eslint .",
|
||||
"link:fix": "eslint --fix ."
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "^0.24.0",
|
||||
"jsonwebtoken": "^8.5.1",
|
||||
"koa": "^2.11.0",
|
||||
"koa-body": "^4.1.1",
|
||||
|
||||
+26
-26
@@ -1,39 +1,39 @@
|
||||
import path from 'path'
|
||||
|
||||
// 系统配置
|
||||
// system config
|
||||
export const System = {
|
||||
API_server_type: 'http://', // API服务器协议类型,包含"http://"或"https://"
|
||||
API_server_host: 'localhost', // API服务器暴露的域名地址,请勿添加"http://"
|
||||
API_server_port: '3000', // API服务器监听的端口号
|
||||
HTTP_server_type: 'http://', // HTTP服务器协议类型,包含"http://"或"https://"
|
||||
HTTP_server_host: 'www.XXX.com', // HTTP服务器地址,请勿添加"http://" (即前端调用使用的服务器地址,如果是APP请设置为 * )
|
||||
HTTP_server_port: '65534', // HTTP服务器端口号
|
||||
System_country: 'zh-cn', // 所在国家的国家代码
|
||||
System_plugin_path: path.join(__dirname, './plugins'), // 插件路径
|
||||
Session_Key: 'RESTfulAPI', // 生产环境务必随机设置一个值
|
||||
db_type: 'mysql' // 数据库类型
|
||||
API_server_type: 'http://',
|
||||
API_server_host: 'localhost',
|
||||
API_server_port: '3000',
|
||||
HTTP_server_type: 'http://',
|
||||
HTTP_server_host: 'www.XXX.com', // HTTP server address(as client browser location,* if its app )
|
||||
HTTP_server_port: '65534',
|
||||
System_country: 'zh-cn',
|
||||
System_plugin_path: path.join(__dirname, './plugins'),
|
||||
Session_Key: 'RESTfulAPI',
|
||||
db_type: 'mysql'
|
||||
}
|
||||
|
||||
export const DB = {
|
||||
host: 'localhost', // 服务器地址
|
||||
port: 3306, // 数据库端口号
|
||||
username: 'admin', // 数据库用户名
|
||||
password: 'admin888', // 数据库密码
|
||||
database: 'development', // 数据库名称
|
||||
prefix: 'api_' // 默认"api_"
|
||||
host: 'localhost',
|
||||
port: 3306,
|
||||
username: 'admin',
|
||||
password: 'admin888',
|
||||
database: 'development',
|
||||
prefix: 'api_'
|
||||
}
|
||||
|
||||
export const pgDB = {
|
||||
host: '127.0.0.1', // 服务器地址
|
||||
port: 54321, // 数据库端口号
|
||||
username: 'biopro', // 数据库用户名
|
||||
password: 'BioProControlBox', // 数据库密码
|
||||
database: 'postgres' // 数据库名称
|
||||
host: '127.0.0.1',
|
||||
port: 5432,
|
||||
username: 'biopro',
|
||||
password: 'BioProControlBox',
|
||||
database: 'postgres'
|
||||
}
|
||||
|
||||
export const SendEmail = {
|
||||
service: 'smtp.abcd.com', // SMTP服务提供商域名
|
||||
username: 'postmaster%40abcd.com', // 用户名/用户邮箱
|
||||
password: 'password', // 邮箱密码
|
||||
sender_address: '"XX平台 👥" <postmaster@abcd.com>'
|
||||
service: 'smtp.abcd.com',
|
||||
username: 'postmaster%40abcd.com',
|
||||
password: 'password',
|
||||
sender_address: '<postmaster@abcd.com>'
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
from scipy import signal
|
||||
import sys
|
||||
|
||||
# argv = _type, order, fs, f0, f1, f2
|
||||
if len(sys.argv) < 7:
|
||||
_type = 'highpass' # 'highpass', 'lowpass', 'bandstop', 'bandpass'
|
||||
order = 20
|
||||
fs = 1000
|
||||
f0 = 48
|
||||
f1 = 52
|
||||
f2 = 25
|
||||
# exit()
|
||||
else:
|
||||
_type = sys.argv[1] # 'highpass', 'lowpass', 'bandstop', 'bandpass'
|
||||
order = int(sys.argv[2])
|
||||
fs = float(sys.argv[3])
|
||||
f0 = float(sys.argv[4])
|
||||
f1 = float(sys.argv[5])
|
||||
f2 = float(sys.argv[6])
|
||||
|
||||
# fs = 1000
|
||||
|
||||
if _type in ['bandstop', 'bandpass']:
|
||||
sos = signal.butter(order, [f0/fs*2,f1/fs*2], _type, output='sos')
|
||||
elif _type in ['highpass', 'lowpass']:
|
||||
sos = signal.butter(order, f2/fs*2, _type, output='sos')
|
||||
else:
|
||||
b, a = signal.iirnotch(f2, order, fs)
|
||||
sos = signal.tf2sos(b, a)
|
||||
|
||||
ret = ''
|
||||
for s_list in sos:
|
||||
for s in s_list:
|
||||
ret += str(s) + ','
|
||||
ret = ret[:-1]
|
||||
ret += '/'
|
||||
|
||||
print(ret[:-2], end='')
|
||||
@@ -1,57 +1,116 @@
|
||||
import RecordingDataMeta from '../../models/file/recording_data_meta'
|
||||
import childProcess from 'child_process'
|
||||
import path from 'path'
|
||||
import { homedir } from 'os'
|
||||
|
||||
const recordingDataMeta = new RecordingDataMeta()
|
||||
|
||||
export const spikeDetect = async (ctx, next) => {
|
||||
const request = ctx.request.body
|
||||
ctx.req.setTimeout(0)
|
||||
|
||||
const id = request.id
|
||||
const controllerId = request.controller_id
|
||||
const metaId = request.meta_id
|
||||
const channel = request.channel
|
||||
const cutOffFreq = request.cut_off_freq
|
||||
const filterOrder = request.filter_order
|
||||
const threshold = request.threshold
|
||||
const waveForm = request.waveForm
|
||||
const retDataType = request.ret_data_type
|
||||
// console.log(id, channel, cutOffFreq, threshold, waveForm)
|
||||
const dataType = request.data_type
|
||||
|
||||
const result = await recordingDataMeta.getByID(metaId)
|
||||
|
||||
const result = await recordingDataMeta.getByID(id)
|
||||
const channels = JSON.parse(result[0].channels)
|
||||
const sampleRate = 8e5 / result[0].parameter_set.ADC_CLOCK / channels.length
|
||||
const timeDuration = result[0].time_duration / 1e6
|
||||
// console.log(sampleRate, timeDuration)
|
||||
const rawData = JSON.stringify(result[0].raw_data[channel])
|
||||
|
||||
const process = childProcess.spawnSync('python3', [
|
||||
path.join(__dirname, '/spikeDetect.py'),
|
||||
'meta_id=' + id,
|
||||
'channel=' + channel,
|
||||
'cut_off_freq=' + cutOffFreq,
|
||||
'threshold=' + threshold,
|
||||
'waveform=' + waveForm,
|
||||
'sample_rate=' + sampleRate,
|
||||
'time_duration=' + timeDuration,
|
||||
'ret_data_type=' + retDataType
|
||||
], { maxBuffer: 2 * 1024 * 1024 * 1024 })
|
||||
function getPromise () {
|
||||
return new Promise((resolve, reject) => {
|
||||
const subprocess = childProcess.spawn('python3', [
|
||||
path.join(homedir(), 'bioproanalysis', 'spike_detect', 'main.py'),
|
||||
'controller_id=' + controllerId,
|
||||
'meta_id=' + metaId,
|
||||
'channel=' + channel,
|
||||
'cut_off_freq=' + cutOffFreq,
|
||||
'filter_order=' + filterOrder,
|
||||
'threshold=' + threshold,
|
||||
'waveform=' + waveForm,
|
||||
'sample_rate=' + sampleRate,
|
||||
'time_duration=' + timeDuration,
|
||||
'data_type=' + dataType,
|
||||
'raw_data=' + rawData
|
||||
])
|
||||
|
||||
// console.log('out', process.stdout.toString())
|
||||
console.log('err', process.stderr.toString())
|
||||
let totalString = ''
|
||||
|
||||
ctx.body = process.stdout.toString()
|
||||
subprocess.stdout.on('data', async (data) => {
|
||||
const dataString = data.toString()
|
||||
totalString += dataString
|
||||
})
|
||||
|
||||
// const process = child_process.execSync('python3 /Users/lubokai/Desktop/bioproapiserver/src/controllers/analysis/test.py 1089 0')
|
||||
// console.log(process)
|
||||
// process.stdout.on('data', (data) => {
|
||||
// _data += data.toString()
|
||||
// })
|
||||
subprocess.stderr.on('data', (error) => {
|
||||
reject(error)
|
||||
console.error(`Error ${error}`)
|
||||
})
|
||||
|
||||
// process.stderr.on('data', (data) => {
|
||||
// console.error(data.toString())
|
||||
// })
|
||||
subprocess.on('close', (code) => {
|
||||
resolve(totalString)
|
||||
console.log(`spike detect analysis process exited with code ${code}`)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// process.on('exit', (code) => {
|
||||
// console.log(_data)
|
||||
// console.log(`Child exited with code ${code}`)
|
||||
// })
|
||||
const ret = await getPromise()
|
||||
ctx.body = ret
|
||||
|
||||
next()
|
||||
}
|
||||
|
||||
export const IIRFliter = async (ctx, next) => {
|
||||
const request = ctx.request.body
|
||||
ctx.req.setTimeout(0)
|
||||
|
||||
const type = request.type
|
||||
const order = request.order
|
||||
const fs = request.fs
|
||||
const f0 = request.f0
|
||||
const f1 = request.f1
|
||||
const f2 = request.f2
|
||||
|
||||
function getPromise () {
|
||||
return new Promise((resolve, reject) => {
|
||||
const subprocess = childProcess.spawn('python3', [
|
||||
path.join(homedir(), 'bioproanalysis', 'filter', 'IIRFilter.py'),
|
||||
type,
|
||||
order,
|
||||
fs,
|
||||
f0,
|
||||
f1,
|
||||
f2
|
||||
])
|
||||
|
||||
let totalString = ''
|
||||
|
||||
subprocess.stdout.on('data', async (data) => {
|
||||
const dataString = data.toString()
|
||||
totalString += dataString
|
||||
})
|
||||
|
||||
subprocess.stderr.on('data', (error) => {
|
||||
reject(error)
|
||||
console.error(`Error ${error}`)
|
||||
})
|
||||
|
||||
subprocess.on('close', (code) => {
|
||||
resolve(totalString)
|
||||
console.log(`iir filter analysis process exited with code ${code}`)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const ret = await getPromise()
|
||||
ctx.body = ret
|
||||
|
||||
next()
|
||||
}
|
||||
|
||||
@@ -1,110 +0,0 @@
|
||||
import sys
|
||||
import ast
|
||||
import psycopg2
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
|
||||
from math import ceil, floor
|
||||
from json import loads, dumps
|
||||
from scipy.fft import fft, fftfreq, rfft, rfftfreq, irfft, ifft
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
params = {}
|
||||
for input in sys.argv[1:]: #Now we're going to iterate over argv[1:] (argv[0] is the program name)
|
||||
param = input.split("=") #Get what's left of the '='
|
||||
params[param[0]] = param[1]
|
||||
|
||||
meta_id = params['meta_id']
|
||||
channel = params['channel']
|
||||
cut_off_freq = int(params['cut_off_freq'])
|
||||
threshold = ast.literal_eval('[' + params['threshold'] + ']')
|
||||
waveform = ast.literal_eval('[' + params['waveform'] + ']')
|
||||
SAMPLE_RATE = int(params['sample_rate'])
|
||||
DURATION = ceil(float(params['time_duration']))
|
||||
DELTA_TIME = 1e6 / SAMPLE_RATE
|
||||
N = SAMPLE_RATE * DURATION
|
||||
ret_data_type = params['ret_data_type']
|
||||
|
||||
# print(meta_id, channel, cut_off_freq, threshold, waveForm, SAMPLE_RATE, DURATION, N)
|
||||
|
||||
conn = psycopg2.connect(database="postgres", user="biopro", password="BioProControlBox", host="127.0.0.1", port="5432")
|
||||
cur = conn.cursor()
|
||||
sql_str = 'SELECT data FROM "public"."' + str(channel) + '_recording_data_raws" WHERE parent = ' + meta_id + 'ORDER BY id ASC'
|
||||
cur.execute(sql_str)
|
||||
ret = None
|
||||
try:
|
||||
ret = cur.fetchall()
|
||||
except BaseException as e:
|
||||
print(e)
|
||||
exit
|
||||
finally:
|
||||
time = np.array([], dtype=int)
|
||||
data = np.array([])
|
||||
|
||||
for sub_data in ret:
|
||||
for split_data in sub_data[0].split('"***"')[:-1]:
|
||||
value = np.array(split_data.split(' '))
|
||||
time = np.append(time, value[::2].astype(np.int))
|
||||
data = np.append(data, value[1::2].astype(np.int))
|
||||
|
||||
# print(len(time), len(data))
|
||||
|
||||
xf = rfftfreq(N, 1 / SAMPLE_RATE)
|
||||
points_per_freq = len(xf) / (SAMPLE_RATE / 2)
|
||||
target_idx = int(points_per_freq * cut_off_freq)
|
||||
|
||||
# print(xf[target_idx])
|
||||
|
||||
yf = rfft(data)
|
||||
yf[:target_idx] = 0
|
||||
new_sig = np.round(irfft(yf, len(data)),3)
|
||||
|
||||
# print(time[-1])
|
||||
# print(len(datas))
|
||||
# print(len(yf),yf)
|
||||
|
||||
if threshold[0] == 'below':
|
||||
th = new_sig < threshold[1]
|
||||
elif threshold[0] == 'over':
|
||||
th = new_sig > threshold[1]
|
||||
elif threshold[0] == 'auto':
|
||||
th = new_sig
|
||||
|
||||
threshold_edges = np.convolve([1, -1], th, mode='same')
|
||||
thresholded_edge_indices = np.where(threshold_edges==1)[0]
|
||||
|
||||
filter_array = []
|
||||
for idx, point in enumerate(thresholded_edge_indices):
|
||||
if idx > 0:
|
||||
if time[thresholded_edge_indices[idx]] - int(waveform[2]) >= time[thresholded_edge_indices[idx-1]]:
|
||||
filter_array.append(True)
|
||||
elif time[thresholded_edge_indices[idx]] - int(waveform[1]) >= time[thresholded_edge_indices[idx-1]]:
|
||||
filter_array.append(True)
|
||||
else:
|
||||
filter_array.append(False)
|
||||
else:
|
||||
if time[thresholded_edge_indices[idx]] - int(waveform[1]) < 0:
|
||||
filter_array.append(False)
|
||||
else:
|
||||
filter_array.append(True)
|
||||
|
||||
timemark_list = thresholded_edge_indices[filter_array]
|
||||
|
||||
if ret_data_type == 'all':
|
||||
print(' '.join(str(x) for x in time))
|
||||
print(' '.join(str(x) for x in new_sig))
|
||||
print(' '.join(str(x) for x in timemark_list))
|
||||
elif ret_data_type == 'partial':
|
||||
return_sub_signal_lists = {}
|
||||
for timemark in timemark_list:
|
||||
start_index = timemark - floor(int(waveform[1] / DELTA_TIME))
|
||||
end_index = timemark + ceil(int(waveform[2] / DELTA_TIME))
|
||||
|
||||
subSignal = new_sig[start_index: end_index + 2]
|
||||
return_sub_signal_lists[str(timemark)] = ' '.join(str(x) for x in subSignal)
|
||||
print(dumps(return_sub_signal_lists))
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
exit
|
||||
+118
-11
@@ -1,17 +1,19 @@
|
||||
import jwt from 'jsonwebtoken'
|
||||
import fs from 'fs'
|
||||
import path from 'path'
|
||||
import childProcess from 'child_process'
|
||||
import { readFile, writeFile } from 'fs/promises'
|
||||
import { homedir } from 'os'
|
||||
const axios = require('axios')
|
||||
const crypto = require('crypto')
|
||||
|
||||
const publicKey = fs.readFileSync(path.join(__dirname, '../../publicKey.pub'))
|
||||
|
||||
// 用户登录的时候返回token
|
||||
// let token = jwt.sign({
|
||||
// userInfo: userInfo // 你要保存到token的数据
|
||||
// }, publicKey, { expiresIn: '7d' })
|
||||
const licenseUrl = 'http://52.194.17.114:3000'
|
||||
const apiFuncName = 'apiServer'
|
||||
|
||||
export const getCookie = (ctx, next) => {
|
||||
const token = jwt.sign({
|
||||
userInfo: 'tommy' // 你要保存到token的数据
|
||||
userInfo: 'tommy'
|
||||
}, publicKey, { expiresIn: '7d' })
|
||||
|
||||
ctx.body = token
|
||||
@@ -22,9 +24,6 @@ export const getCookie = (ctx, next) => {
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查授权是否合法
|
||||
*/
|
||||
export const CheckAuth = (ctx, next) => {
|
||||
const token = ctx.request.header.authorization
|
||||
try {
|
||||
@@ -38,7 +37,7 @@ export const CheckAuth = (ctx, next) => {
|
||||
return {
|
||||
status: 403,
|
||||
result: {
|
||||
errInfo: '没有授权'
|
||||
errInfo: 'no auth'
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -46,7 +45,7 @@ export const CheckAuth = (ctx, next) => {
|
||||
return {
|
||||
status: 503,
|
||||
result: {
|
||||
errInfo: '解密错误'
|
||||
errInfo: 'decode fail'
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -60,3 +59,111 @@ export const Post = (ctx, next) => {
|
||||
return CheckAuth(ctx).then(result => { ctx.body = result; next() })
|
||||
}
|
||||
}
|
||||
|
||||
export const updateLicense = async (ctx, next) => {
|
||||
function wgetEXEC (url, name) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const subprocess = childProcess.exec('wget ' + url + name + ' -O ' + homedir + '/checkToken')
|
||||
subprocess.stdout.on('data', async (data) => {
|
||||
})
|
||||
// subprocess.stderr.on('data', (error) => {
|
||||
// // reject(error)
|
||||
// console.error(`Error ${error}`)
|
||||
// })
|
||||
subprocess.on('close', (code) => {
|
||||
resolve(true)
|
||||
console.log(`wgetEXE process exited with code ${code}`)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function chmodEXEC () {
|
||||
return new Promise((resolve, reject) => {
|
||||
const subprocess = childProcess.exec('chmod 777 ' + homedir + '/checkToken')
|
||||
subprocess.stdout.on('data', async (data) => {
|
||||
})
|
||||
// subprocess.stderr.on('data', (error) => {
|
||||
// // reject(error)
|
||||
// console.error(`Error ${error}`)
|
||||
// })
|
||||
subprocess.on('close', (code) => {
|
||||
resolve(true)
|
||||
console.log(`wgetEXE process exited with code ${code}`)
|
||||
return true
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const mac = await readFile('/sys/class/net/eth0/address')
|
||||
const ret = await axios.post(licenseUrl + '/api/controller/token', {
|
||||
mac_controller: mac.toString().substr(0, 17)
|
||||
})
|
||||
switch (ret.status) {
|
||||
case 200:
|
||||
await writeFile(homedir + '/token.txt', ret.data.token)
|
||||
await writeFile(homedir + '/cute.txt', ret.data.cute)
|
||||
await wgetEXEC(licenseUrl + '/assets/exec/', ret.data.name)
|
||||
await chmodEXEC()
|
||||
ctx.status = 200
|
||||
break
|
||||
case 201:
|
||||
await writeFile(homedir + '/token.txt', ret.data.token)
|
||||
await writeFile(homedir + '/cute.txt', ret.data.cute)
|
||||
await wgetEXEC(licenseUrl + '/assets/exec/', ret.data.name)
|
||||
await chmodEXEC()
|
||||
ctx.status = 200
|
||||
break
|
||||
case 202:
|
||||
await writeFile(homedir + '/token.txt', ret.data.token)
|
||||
await writeFile(homedir + '/cute.txt', ret.data.cute)
|
||||
await wgetEXEC(licenseUrl + '/assets/exec/', ret.data.name)
|
||||
await chmodEXEC()
|
||||
ctx.status = 202
|
||||
break
|
||||
case 203:
|
||||
ctx.status = 203
|
||||
break
|
||||
default:
|
||||
ctx.status = 305
|
||||
break
|
||||
}
|
||||
|
||||
console.log(ret.status, ret.data)
|
||||
// 200 success; 201 doesnt need to update; 202 no license; 203 info fail
|
||||
|
||||
ctx.body = ''
|
||||
next()
|
||||
}
|
||||
|
||||
export const checkLicense = async (ctx, next) => {
|
||||
const mac = await readFile('/sys/class/net/eth0/address')
|
||||
ctx.body = await runCheckToken(mac.toString().substr(0, 17))
|
||||
next()
|
||||
}
|
||||
|
||||
export const runCheckToken = async (mac) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const tokenPath = homedir + '/token.txt'
|
||||
const cutePath = homedir + '/cute.txt'
|
||||
const subprocess = childProcess.exec(homedir + '/./checkToken ' + apiFuncName + ' ' + tokenPath + ' ' + cutePath)
|
||||
let _data = ''
|
||||
subprocess.stdout.on('data', async (data) => {
|
||||
_data += data
|
||||
})
|
||||
subprocess.on('close', (code) => {
|
||||
const pass = crypto.createHmac('sha256', mac).update(apiFuncName + 'pass').digest('hex')
|
||||
const outdated = crypto.createHmac('sha256', mac).update(apiFuncName + 'outdated').digest('hex')
|
||||
switch (_data) {
|
||||
case pass:
|
||||
resolve('pass')
|
||||
break
|
||||
case outdated:
|
||||
resolve('outdated')
|
||||
break
|
||||
default:
|
||||
resolve('fail')
|
||||
break
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
@@ -80,6 +80,15 @@ export const getDataByID = async (ctx, next) => {
|
||||
next()
|
||||
}
|
||||
|
||||
export const getSdDataByID = async (ctx, next) => {
|
||||
const index = ctx.params.channel
|
||||
const id = ctx.params.id
|
||||
const result = await recordingDataRaw.getSdDataByID(id, index)
|
||||
ctx.body = result
|
||||
|
||||
next()
|
||||
}
|
||||
|
||||
export const getByParent = async (ctx, next) => {
|
||||
const index = ctx.params.channel
|
||||
const parent = ctx.params.parent
|
||||
|
||||
@@ -0,0 +1,195 @@
|
||||
import RecordingDataMeta from '../../../models/file/recording_data_meta'
|
||||
import Controller from '../../../models/product/controller'
|
||||
import childProcess from 'child_process'
|
||||
import path from 'path'
|
||||
import { homedir } from 'os'
|
||||
|
||||
const recordingDataMeta = new RecordingDataMeta()
|
||||
const controller = new Controller()
|
||||
|
||||
const sdPath = [homedir(), 'bioproanalysis', 'sdcard']
|
||||
const sdGetPath = [...sdPath, 'neuLiveSD_C', 'sd_list']
|
||||
const sdDeletePath = [...sdPath, 'neuLiveSD_C', 'sd_remove']
|
||||
const sdUploadPath = [...sdPath, 'sd_download.py']
|
||||
|
||||
const getParameter = async (metaID, parameterName) => {
|
||||
const ret = await recordingDataMeta.getByID(metaID)
|
||||
return ret[0].parameter_set[parameterName]
|
||||
}
|
||||
|
||||
const getPath = async (uuid) => {
|
||||
return getPathByUuid(uuid, getUuidPathArray(await getUuidPathStringPromise()))
|
||||
}
|
||||
|
||||
const getPathByUuid = (uuid, uuidPathArray) => {
|
||||
for (const uuidPath of uuidPathArray) {
|
||||
if (uuidPath[0] === uuid) {
|
||||
return uuidPath[1]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// [uuid1, uuid2, uuid3...]
|
||||
const getUuidList = (uuidPathString) => {
|
||||
return uuidPathString.split('\n').map(val => val.split(' ')[0])
|
||||
}
|
||||
|
||||
// [[uuid1, path1], [uuid2, path2], [uuid3, path3]...]
|
||||
const getUuidPathArray = (uuidPathString) => {
|
||||
return uuidPathString.split('\n').map(val => val.split(' '))
|
||||
}
|
||||
|
||||
// 'uuid1 path1\n uuid2 path2\n uuid3 path3\n....'
|
||||
const getUuidPathStringPromise = async () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const subprocess = childProcess.spawn(path.join(...sdGetPath))
|
||||
|
||||
let dataString = ''
|
||||
subprocess.stdout.on('data', async (data) => {
|
||||
dataString += data.toString()
|
||||
})
|
||||
|
||||
subprocess.stderr.on('data', (error) => {
|
||||
console.error(`Error ${error}`)
|
||||
reject(error)
|
||||
})
|
||||
|
||||
subprocess.on('close', (code) => {
|
||||
console.log(`sdcard get process exited with code ${code}`)
|
||||
resolve(dataString)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function uploadPromise (uuidPath, uuid, ampGain) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const subprocess = childProcess.spawn('python3', [
|
||||
path.join(...sdUploadPath),
|
||||
uuidPath,
|
||||
uuid,
|
||||
ampGain
|
||||
])
|
||||
|
||||
let dataString = ''
|
||||
|
||||
subprocess.stdout.on('data', async (data) => {
|
||||
dataString += data.toString()
|
||||
console.log('upload', dataString)
|
||||
})
|
||||
|
||||
subprocess.stderr.on('data', (error) => {
|
||||
reject(error)
|
||||
console.error(`Error ${error}`)
|
||||
})
|
||||
|
||||
subprocess.on('close', (code) => {
|
||||
console.log(`sd card upload process exited with code ${code}`)
|
||||
resolve(dataString)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function deletePromise (uuidPath) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const subprocess = childProcess.spawn(
|
||||
path.join(...sdDeletePath),
|
||||
[uuidPath, 120]
|
||||
)
|
||||
let dataString = ''
|
||||
subprocess.stdout.on('data', async (data) => {
|
||||
dataString += data.toString()
|
||||
})
|
||||
|
||||
subprocess.stderr.on('data', (error) => {
|
||||
console.error(`Error ${error}`)
|
||||
reject(error)
|
||||
})
|
||||
|
||||
subprocess.on('close', (code) => {
|
||||
console.log(`grep process exited with code ${code}`)
|
||||
resolve(dataString)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export const exist = async (ctx, next) => {
|
||||
const request = ctx.request.body
|
||||
// const controllerID = request.controllerID
|
||||
const uuid = request.uuid
|
||||
const path = await getPath(uuid)
|
||||
let result
|
||||
(path !== undefined) ? result = true : result = false
|
||||
|
||||
ctx.body = result
|
||||
|
||||
next()
|
||||
}
|
||||
|
||||
export const uploadThenDelete = async (ctx, next) => {
|
||||
const request = ctx.request.body
|
||||
const controllerID = request.controllerID
|
||||
const metaID = request.metaID
|
||||
const uuid = request.uuid
|
||||
const uuidPath = await getPath(uuid)
|
||||
const ampGain = await getParameter(metaID, 'AMP_GAIN')
|
||||
|
||||
// timeout defualt 120s to no-limit
|
||||
ctx.req.setTimeout(0)
|
||||
|
||||
// controller column sd_uploading update
|
||||
await controller.update({
|
||||
sd_uploading: true
|
||||
}, controllerID)
|
||||
|
||||
const uploadResult = await uploadPromise(uuidPath, uuid, ampGain)
|
||||
|
||||
if (uploadResult === 'true') {
|
||||
// meta sd_card_uploaded true
|
||||
await recordingDataMeta.update({
|
||||
sd_data_uploaded: true
|
||||
}, metaID)
|
||||
await deletePromise(uuidPath)
|
||||
}
|
||||
|
||||
// controller column sd_uploading close
|
||||
await controller.update({
|
||||
sd_uploading: false
|
||||
}, controllerID)
|
||||
|
||||
ctx.body = uploadResult
|
||||
next()
|
||||
}
|
||||
|
||||
export const getFileList = async (ctx, next) => {
|
||||
const result = await getUuidPathStringPromise()
|
||||
const uuidList = getUuidList(result)
|
||||
|
||||
ctx.body = uuidList
|
||||
next()
|
||||
}
|
||||
|
||||
// export const deleted = async (ctx, next) => {
|
||||
// const request = ctx.request.body
|
||||
// const controllerID = request.controllerID
|
||||
// const uuid = request.uuid
|
||||
// const uuidPath = await getPath(uuid)
|
||||
|
||||
// // timeout defualt 120s to no-limit
|
||||
// ctx.req.setTimeout(0)
|
||||
|
||||
// // controller column sd_uploading update
|
||||
// await controller.update({
|
||||
// sd_uploading: true
|
||||
// }, controllerID)
|
||||
|
||||
// const result = await deletePromise(uuidPath)
|
||||
|
||||
// // controller column sd_uploading close
|
||||
// await controller.update({
|
||||
// sd_uploading: false
|
||||
// }, controllerID)
|
||||
|
||||
// ctx.body = result
|
||||
|
||||
// next()
|
||||
// }
|
||||
@@ -0,0 +1,25 @@
|
||||
import SDRawNeulive from '../../models/file/sd_raw_neulive'
|
||||
import * as auth from '../auth'
|
||||
|
||||
const sd_raw_Neulive = new SDRawNeulive()
|
||||
|
||||
export const create = async (ctx, next) => {
|
||||
const data = ctx.request.body
|
||||
const result = await sd_raw_Neulive.create(data)
|
||||
ctx.body = result
|
||||
next()
|
||||
}
|
||||
|
||||
export const getByParentUUID = async (ctx, next) => {
|
||||
const parent_uuid = ctx.params.parent_uuid
|
||||
const result = await sd_raw_Neulive.getByParentUUID(parent_uuid)
|
||||
ctx.body = result
|
||||
next()
|
||||
}
|
||||
|
||||
export const deleteByParentUUID = async (ctx, next) => {
|
||||
const parent_uuid = ctx.params.parent_uuid
|
||||
const result = await sd_raw_Neulive.deleteByParentUUID(parent_uuid)
|
||||
ctx.body = result
|
||||
next()
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import * as recordingDataMeta from './file/recording_data_meta'
|
||||
import * as recordingDataRaw from './file/recording_data_raw'
|
||||
import * as recordingDataMini from './file/recording_data_mini'
|
||||
import * as analysis from './analysis'
|
||||
import * as sdCard from './file/sd_card'
|
||||
|
||||
export default {
|
||||
upload,
|
||||
@@ -21,5 +22,6 @@ export default {
|
||||
recordingDataMeta,
|
||||
recordingDataRaw,
|
||||
recordingDataMini,
|
||||
analysis
|
||||
analysis,
|
||||
sdCard
|
||||
}
|
||||
|
||||
@@ -19,15 +19,6 @@ export const update = async (ctx, next) => {
|
||||
next()
|
||||
}
|
||||
|
||||
export const updateByID = async (ctx, next) => {
|
||||
const data = ctx.request.body
|
||||
const id = ctx.params.id
|
||||
const result = await controller.updateByID(data, id)
|
||||
ctx.body = result
|
||||
|
||||
next()
|
||||
}
|
||||
|
||||
export const updateByAttr = async (ctx, next) => {
|
||||
const data = ctx.request.body
|
||||
const attr = ctx.params.attr
|
||||
@@ -45,6 +36,14 @@ export const clearDeleted = async (ctx, next) => {
|
||||
next()
|
||||
}
|
||||
|
||||
export const getByName = async (ctx, next) => {
|
||||
const name = ctx.params.name
|
||||
const result = await controller.getByName(name)
|
||||
ctx.body = result
|
||||
|
||||
next()
|
||||
}
|
||||
|
||||
export const getByMac = async (ctx, next) => {
|
||||
const mac = ctx.params.mac
|
||||
const result = await controller.getByMac(mac)
|
||||
@@ -53,6 +52,14 @@ export const getByMac = async (ctx, next) => {
|
||||
next()
|
||||
}
|
||||
|
||||
export const getByMqttId = async (ctx, next) => {
|
||||
const mqttId = ctx.params.mqtt_id
|
||||
const result = await controller.getByMqttId(mqttId)
|
||||
ctx.body = result
|
||||
|
||||
next()
|
||||
}
|
||||
|
||||
export const getByAttr = async (ctx, next) => {
|
||||
const attr = ctx.params.attr
|
||||
const value = ctx.params.value
|
||||
|
||||
@@ -11,17 +11,9 @@ export const create = async (ctx, next) => {
|
||||
}
|
||||
|
||||
export const update = async (ctx, next) => {
|
||||
const data = ctx.request.body
|
||||
const result = await device.update(data)
|
||||
ctx.body = result
|
||||
|
||||
next()
|
||||
}
|
||||
|
||||
export const updateByID = async (ctx, next) => {
|
||||
const data = ctx.request.body
|
||||
const id = ctx.params.id
|
||||
const result = await device.updateByID(data, id)
|
||||
const result = await device.update(data, id)
|
||||
ctx.body = result
|
||||
|
||||
next()
|
||||
|
||||
+4
-2
@@ -28,10 +28,10 @@ db.tasks = require('./schema/task.model')(sequelize, Sequelize)
|
||||
db.devices = require('./schema/device.model')(sequelize, Sequelize)
|
||||
db.collections = require('./schema/collection.model')(sequelize, Sequelize)
|
||||
db.recording_data_metas = require('./schema/recording_data_meta.model')(sequelize, Sequelize)
|
||||
for (let i = 0; i < 32; i++) {
|
||||
for (let i = 0; i < 64; i++) {
|
||||
db[i + '_recording_data_raws'] = require('./schema/recording_data_raw.model')(sequelize, Sequelize, i)
|
||||
}
|
||||
for (let i = 0; i < 32; i++) {
|
||||
for (let i = 0; i < 64; i++) {
|
||||
db[i + '_recording_data_minis'] = require('./schema/recording_data_mini.model')(sequelize, Sequelize, i)
|
||||
}
|
||||
for (let i = 256; i < 288; i++) {
|
||||
@@ -41,6 +41,8 @@ for (let i = 256; i < 288; i++) {
|
||||
db[i + '_recording_data_minis'] = require('./schema/recording_data_mini.model')(sequelize, Sequelize, i)
|
||||
}
|
||||
|
||||
db.sd_raw_neulive = require('./schema/sd_raw_neulive.model')(sequelize, Sequelize)
|
||||
|
||||
db.sequelize.sync()
|
||||
|
||||
sequelizeStream(db.sequelize, 1000)
|
||||
|
||||
@@ -104,6 +104,10 @@ module.exports = (sequelize, Sequelize) => {
|
||||
type: Sequelize.STRING,
|
||||
defaultValue: ''
|
||||
},
|
||||
sd_uploading: {
|
||||
type: Sequelize.BOOLEAN,
|
||||
defaultValue: false
|
||||
},
|
||||
deleted: {
|
||||
type: Sequelize.BOOLEAN,
|
||||
defaultValue: false
|
||||
|
||||
@@ -25,6 +25,10 @@ module.exports = (sequelize, Sequelize) => {
|
||||
type: Sequelize.STRING,
|
||||
defaultValue: '-1'
|
||||
},
|
||||
start_time_abs: {
|
||||
type: Sequelize.STRING,
|
||||
defaultValue: '0'
|
||||
},
|
||||
time_duration: {
|
||||
type: Sequelize.STRING,
|
||||
defaultValue: '0'
|
||||
@@ -73,6 +77,14 @@ module.exports = (sequelize, Sequelize) => {
|
||||
type: Sequelize.TEXT,
|
||||
defaultValue: ''
|
||||
},
|
||||
sd_data_record: {
|
||||
type: Sequelize.BOOLEAN,
|
||||
defaultValue: true
|
||||
},
|
||||
sd_data_uploaded: {
|
||||
type: Sequelize.BOOLEAN,
|
||||
defaultValue: false
|
||||
},
|
||||
deleted: {
|
||||
type: Sequelize.BOOLEAN,
|
||||
defaultValue: false
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
module.exports = (sequelize, Sequelize, i) => {
|
||||
const RecordingDataRaw = sequelize.define('bps_sd_raw_neulive', {
|
||||
channel: {
|
||||
type: Sequelize.INTEGER
|
||||
},
|
||||
parent_uuid: {
|
||||
type: Sequelize.STRING,
|
||||
},
|
||||
data: {
|
||||
type: Sequelize.TEXT,
|
||||
defaultValue: ''
|
||||
},
|
||||
start_time_sec: {
|
||||
type: Sequelize.INTEGER,
|
||||
defaultValue: 0
|
||||
},
|
||||
end_time_sec: {
|
||||
type: Sequelize.INTEGER,
|
||||
defaultValue: 0
|
||||
},
|
||||
start_time_micro: {
|
||||
type: Sequelize.INTEGER,
|
||||
defaultValue: 0
|
||||
},
|
||||
end_time_micro: {
|
||||
type: Sequelize.INTEGER,
|
||||
defaultValue: 0
|
||||
}
|
||||
},
|
||||
{
|
||||
freezeTableName: true,
|
||||
timestamps: false
|
||||
}
|
||||
)
|
||||
|
||||
return RecordingDataRaw
|
||||
}
|
||||
@@ -103,6 +103,22 @@ class RecordingDataRaw {
|
||||
return ret
|
||||
}
|
||||
|
||||
async getSdDataByID (id, index) {
|
||||
const ret = await db[index + '_recording_data_raws'].findAllWithStream(
|
||||
{
|
||||
batchSize: 1000,
|
||||
where: {
|
||||
id: id
|
||||
},
|
||||
attributes: [
|
||||
'sd_data'
|
||||
]
|
||||
}
|
||||
)
|
||||
return ret
|
||||
}
|
||||
|
||||
|
||||
async getByAttrID (id, attr, index) {
|
||||
const attrList = attr.split('-')
|
||||
const ret = await db[index + '_recording_data_raws'].findAll(
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
const db = require('../../db/database')
|
||||
|
||||
class SDRawNeulive {
|
||||
async create (req) {
|
||||
return db['sd_raw_neulive'].create(
|
||||
req
|
||||
)
|
||||
}
|
||||
|
||||
async getByParentUUID (parent_uuid) {
|
||||
const ret = await db['sd_raw_neulive'].findAllWithStream(
|
||||
{
|
||||
batchSize: 1000,
|
||||
where: {
|
||||
parent_uuid: parent_uuid
|
||||
},
|
||||
order: [
|
||||
['id', 'ASC']
|
||||
],
|
||||
attributes: [
|
||||
'data',
|
||||
'start_time',
|
||||
'end_time'
|
||||
]
|
||||
}
|
||||
)
|
||||
return ret
|
||||
}
|
||||
|
||||
async deleteByParentUUID (parent_uuid) {
|
||||
const ret = await db['sd_raw_neulive'].destroy(
|
||||
{
|
||||
where: {
|
||||
parent_uuid: parent_uuid
|
||||
}
|
||||
}
|
||||
)
|
||||
return ret
|
||||
}
|
||||
}
|
||||
|
||||
export default SDRawNeulive
|
||||
@@ -31,19 +31,6 @@ class ControllerModel {
|
||||
}
|
||||
}
|
||||
|
||||
async updateByID (req, id) {
|
||||
req.updated_at = db.Sequelize.literal('CURRENT_TIMESTAMP')
|
||||
const ret = await db.controllers.update(
|
||||
req,
|
||||
{
|
||||
where: {
|
||||
id: id
|
||||
}
|
||||
}
|
||||
)
|
||||
return ret
|
||||
}
|
||||
|
||||
async updateByAttr (req, attr, value) {
|
||||
const whereObj = {}
|
||||
const attrList = attr.split('-')
|
||||
@@ -105,6 +92,17 @@ class ControllerModel {
|
||||
return ret
|
||||
}
|
||||
|
||||
async getByMqttId (mqttId) {
|
||||
const ret = await db.controllers.findAll(
|
||||
{
|
||||
where: {
|
||||
mqtt_id: mqttId
|
||||
}
|
||||
}
|
||||
)
|
||||
return ret
|
||||
}
|
||||
|
||||
async getByAttr (attr, value) {
|
||||
const whereObj = {}
|
||||
const attrList = attr.split('-')
|
||||
|
||||
@@ -35,19 +35,6 @@ class DeviceModel {
|
||||
}
|
||||
}
|
||||
|
||||
async updateByID (req, id) {
|
||||
req.updated_at = db.Sequelize.literal('CURRENT_TIMESTAMP')
|
||||
const ret = await db.devices.update(
|
||||
req,
|
||||
{
|
||||
where: {
|
||||
id: id
|
||||
}
|
||||
}
|
||||
)
|
||||
return ret
|
||||
}
|
||||
|
||||
async updateByMac (req, mac) {
|
||||
req.updated_at = db.Sequelize.literal('CURRENT_TIMESTAMP')
|
||||
const ret = await db.devices.update(
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
import controllers from '../../controllers'
|
||||
|
||||
// '/api/analysis'
|
||||
|
||||
export default function (_prefix) {
|
||||
const prefix = _prefix + '/analysis'
|
||||
return [
|
||||
['POST', prefix + '/spike_detect', controllers.analysis.spikeDetect],
|
||||
['POST', prefix + '/iir_filter', controllers.analysis.IIRFliter]
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import controllers from '../../controllers'
|
||||
|
||||
// '/api/controller'
|
||||
|
||||
export default function (_prefix) {
|
||||
const prefix = _prefix + '/controller'
|
||||
return [
|
||||
['POST', prefix + '/create', controllers.controller.create],
|
||||
['POST', prefix + '/update/:id', controllers.controller.update],
|
||||
['POST', prefix + '/update_by_attr/:attr/:value', controllers.controller.updateByAttr],
|
||||
['GET', prefix + '/get_by_name/:name', controllers.controller.getByName],
|
||||
['GET', prefix + '/get_by_mqtt_id/:mqtt_id', controllers.controller.getByMqttId],
|
||||
['GET', prefix + '/get_by_mac/:mac', controllers.controller.getByMac],
|
||||
['GET', prefix + '/get_by_attr/:attr/:value', controllers.controller.getByAttr],
|
||||
['GET', prefix + '/get/all', controllers.controller.getAll]
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import controllers from '../../controllers'
|
||||
|
||||
// '/api/device'
|
||||
|
||||
export default function (_prefix) {
|
||||
const prefix = _prefix + '/device'
|
||||
return [
|
||||
['POST', prefix + '/create', controllers.device.create],
|
||||
['POST', prefix + '/update/:id', controllers.device.update],
|
||||
['POST', prefix + '/update_by_mac/:mac', controllers.device.updateByMac],
|
||||
['POST', prefix + '/update_by_attr/:attr/:value', controllers.device.updateByAttr],
|
||||
['GET', prefix + '/clear_deleted/:id', controllers.device.clearDeleted],
|
||||
['GET', prefix + '/get_by_mac/:mac', controllers.device.getByMac],
|
||||
['GET', prefix + '/get_by_attr/:attr/:value', controllers.device.getByAttr],
|
||||
['GET', prefix + '/get/all', controllers.device.getAll]
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
import controllers from '../../../controllers'
|
||||
|
||||
// '/api/file/collection'
|
||||
|
||||
export default function (_prefix) {
|
||||
const prefix = _prefix + '/collection'
|
||||
return [
|
||||
['POST', prefix + '/create', controllers.collection.create],
|
||||
['POST', prefix + '/update/:id', controllers.collection.update],
|
||||
['GET', prefix + '/clear_deleted/:controller_id', controllers.collection.clearDeleted],
|
||||
['GET', prefix + '/get_by_id/:id', controllers.collection.getByID],
|
||||
['GET', prefix + '/get_by_name/:name/:controller_id', controllers.collection.getByName],
|
||||
['GET', prefix + '/get_by_parent/:type/:parent', controllers.collection.getByParent],
|
||||
['GET', prefix + '/get_by_parent_name/:type/:parent/:name', controllers.collection.getByParentName],
|
||||
['GET', prefix + '/get/all/:controller_id', controllers.collection.getAll],
|
||||
['GET', prefix + '/get_by_name/:name', controllers.collection.getByName],
|
||||
['GET', prefix + '/get/all', controllers.collection.getAll],
|
||||
['GET', prefix + '/clear_deleted', controllers.collection.clearDeleted]
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import collection from './collection'
|
||||
import meta from './meta'
|
||||
import mini from './mini'
|
||||
import raw from './raw'
|
||||
import sdcard from './sdcard'
|
||||
|
||||
export default function (_prefix) {
|
||||
const prefix = _prefix + '/file'
|
||||
return [
|
||||
...collection(prefix),
|
||||
...meta(prefix),
|
||||
...mini(prefix),
|
||||
...raw(prefix),
|
||||
...sdcard(prefix)
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
import controllers from '../../../controllers'
|
||||
|
||||
// '/api/file/meta'
|
||||
|
||||
export default function (_prefix) {
|
||||
const prefix = _prefix + '/meta'
|
||||
return [
|
||||
['POST', prefix + '/create', controllers.recordingDataMeta.create],
|
||||
['POST', prefix + '/update/:id', controllers.recordingDataMeta.update],
|
||||
['GET', prefix + '/clear_deleted/', controllers.recordingDataMeta.clearDeleted],
|
||||
['GET', prefix + '/get_by_name/:name', controllers.recordingDataMeta.getByName],
|
||||
['GET', prefix + '/get_by_uuid/:uuid', controllers.recordingDataMeta.getByUUID],
|
||||
['GET', prefix + '/get_by_id/:id', controllers.recordingDataMeta.getByID],
|
||||
['GET', prefix + '/get_by_path/:path', controllers.recordingDataMeta.getByPath],
|
||||
['GET', prefix + '/get_by_parent/:type/:parent', controllers.recordingDataMeta.getByParent],
|
||||
['GET', prefix + '/get_count_by_parent/:type/:parent', controllers.recordingDataMeta.getCountByParent],
|
||||
['GET', prefix + '/get_by_parent_with_limit/:type/:parent/:limit/:offset/:order', controllers.recordingDataMeta.getByParentWithLimit],
|
||||
['GET', prefix + '/get_by_attr_parent_with_limit/:type/:parent/:limit/:offset/:order/:attr', controllers.recordingDataMeta.getByAttrsParentWithLimit],
|
||||
['GET', prefix + '/get_or_create_by_path/:path', controllers.recordingDataMeta.getOrCreateByPath],
|
||||
['GET', prefix + '/get/all', controllers.recordingDataMeta.getAll]
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import controllers from '../../../controllers'
|
||||
|
||||
// '/api/file/mini'
|
||||
|
||||
export default function (_prefix) {
|
||||
const prefix = _prefix + '/mini'
|
||||
return [
|
||||
['POST', prefix + '/create/:channel', controllers.recordingDataMini.create],
|
||||
['POST', prefix + '/update/:channel/:id', controllers.recordingDataMini.update],
|
||||
['GET', prefix + '/clear_deleted/:channel/:id', controllers.recordingDataMini.clearDeleted],
|
||||
['GET', prefix + '/get_by_id/:channel/:id', controllers.recordingDataMini.getByID],
|
||||
['GET', prefix + '/get_by_parent/:channel/:parent', controllers.recordingDataMini.getByParent],
|
||||
['GET', prefix + '/get_attr_by_id/:channel/:id/:attr', controllers.recordingDataMini.getAttrByID],
|
||||
['GET', prefix + '/get_attr_by_parent/:channel/:parent/:attr', controllers.recordingDataMini.getAttrByParent],
|
||||
['GET', prefix + '/random/get_by_id/:channel/:id', controllers.recordingDataMini.getRandomDataByID],
|
||||
['GET', prefix + '/mean/get_by_id/:channel/:id', controllers.recordingDataMini.getMeanDataByID]
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
import controllers from '../../../controllers'
|
||||
|
||||
// '/api/file/raw'
|
||||
|
||||
export default function (_prefix) {
|
||||
const prefix = _prefix + '/raw'
|
||||
return [
|
||||
['POST', prefix + '/create/:channel', controllers.recordingDataRaw.create],
|
||||
['POST', prefix + '/update/:channel/:id', controllers.recordingDataRaw.update],
|
||||
['POST', prefix + '/update_sd_data/:channel/:id', controllers.recordingDataRaw.updateSdData],
|
||||
['GET', prefix + '/clear_deleted/:channel/:id', controllers.recordingDataRaw.clearDeleted],
|
||||
['GET', prefix + '/get_by_id/:channel/:id', controllers.recordingDataRaw.getByID],
|
||||
['GET', prefix + '/get_by_ids/:channel/:id', controllers.recordingDataRaw.getByIDs],
|
||||
['GET', prefix + '/get_data_by_id/:channel/:id', controllers.recordingDataRaw.getDataByID],
|
||||
['GET', prefix + '/get_sd_data_by_id/:channel/:id', controllers.recordingDataRaw.getSdDataByID],
|
||||
['GET', prefix + '/get_by_parent/:channel/:parent', controllers.recordingDataRaw.getByParent],
|
||||
['GET', prefix + '/get_attr_by_id/:channel/:id/:attr', controllers.recordingDataRaw.getAttrByID],
|
||||
['GET', prefix + '/get_attr_by_ids/:channel/:id/:attr', controllers.recordingDataRaw.getAttrByIDs],
|
||||
['GET', prefix + '/get_attr_by_parent/:channel/:parent/:attr', controllers.recordingDataRaw.getAttrByParent]
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import controllers from '../../../controllers'
|
||||
|
||||
// '/api/file/sdcard'
|
||||
|
||||
export default function (_prefix) {
|
||||
const prefix = _prefix + '/sdcard'
|
||||
return [
|
||||
['GET', prefix + '/get', controllers.sdCard.getFileList],
|
||||
['POST', prefix + '/exist', controllers.sdCard.exist],
|
||||
['POST', prefix + '/upload', controllers.sdCard.uploadThenDelete],
|
||||
// ['POST', prefix + '/delete', controllers.sdCard.deleted]
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import file from './file'
|
||||
import project from './project'
|
||||
import device from './device'
|
||||
import controller from './controller'
|
||||
import analysis from './analysis'
|
||||
|
||||
export default function (_prefix) {
|
||||
const prefix = _prefix + '/api'
|
||||
|
||||
return [
|
||||
...file(prefix),
|
||||
...project(prefix),
|
||||
...device(prefix),
|
||||
...controller(prefix),
|
||||
...analysis(prefix)
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import task from './task'
|
||||
|
||||
export default function (_prefix) {
|
||||
const prefix = _prefix + '/project'
|
||||
return [
|
||||
...task(prefix)
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import controllers from '../../../controllers'
|
||||
|
||||
// '/api/task'
|
||||
|
||||
export default function (_prefix) {
|
||||
const prefix = _prefix + '/task'
|
||||
return [
|
||||
['POST', prefix + '/create', controllers.task.create],
|
||||
['POST', prefix + '/update/:id', controllers.task.update],
|
||||
['POST', prefix + '/update_by_attr/:attr/:value', controllers.task.updateByAttr],
|
||||
['GET', prefix + '/get_by_id/:id', controllers.task.getByID],
|
||||
['GET', prefix + '/get_by_attr/:attr/:value', controllers.task.getByAttr],
|
||||
['GET', prefix + '/get/all', controllers.task.getAll]
|
||||
]
|
||||
}
|
||||
+26
-103
@@ -1,112 +1,35 @@
|
||||
import KoaRouter from 'koa-router'
|
||||
import controllers from '../controllers'
|
||||
import api from './api'
|
||||
|
||||
const router = new KoaRouter()
|
||||
|
||||
export default router
|
||||
.get('/public/get', function (ctx, next) {
|
||||
ctx.body = '禁止访问!'
|
||||
})
|
||||
.all('/upload', controllers.upload)
|
||||
.get('/public/api/:name', controllers.api.Get)
|
||||
.post('/api/:name', controllers.api.Post)
|
||||
.put('/api/:name', controllers.api.Put)
|
||||
.del('/api/:name', controllers.api.Delete)
|
||||
.post('/auth/:action', controllers.auth.Post)
|
||||
router
|
||||
// .get('/public/get', function (ctx, next) {
|
||||
// ctx.body = 'no access'
|
||||
// })
|
||||
// .all('/upload', controllers.upload)
|
||||
// .get('/public/api/:name', controllers.api.Get)
|
||||
// .post('/api/:name', controllers.api.Post)
|
||||
// .put('/api/:name', controllers.api.Put)
|
||||
// .del('/api/:name', controllers.api.Delete)
|
||||
// .post('/auth/:action', controllers.auth.Post)
|
||||
// user
|
||||
.get('/public/auth/get_cookie', controllers.auth.getCookie)
|
||||
.get('/public/auth/update_license', controllers.auth.updateLicense)
|
||||
.get('/public/auth/check_license', controllers.auth.checkLicense)
|
||||
|
||||
// collection
|
||||
.post('/api/file/collection/create', controllers.collection.create)
|
||||
.post('/api/file/collection/update/:id', controllers.collection.update)
|
||||
.get('/api/file/collection/clear_deleted/:controller_id', controllers.collection.clearDeleted)
|
||||
.get('/api/file/collection/get_by_id/:id', controllers.collection.getByID)
|
||||
.get('/api/file/collection/get_by_name/:name/:controller_id', controllers.collection.getByName)
|
||||
.get('/api/file/collection/get_by_parent/:type/:parent', controllers.collection.getByParent)
|
||||
.get('/api/file/collection/get_by_parent_name/:type/:parent/:name', controllers.collection.getByParentName)
|
||||
.get('/api/file/collection/get/all/:controller_id', controllers.collection.getAll)
|
||||
for (const _route of api('')) {
|
||||
switch (_route[0]) {
|
||||
case 'GET':
|
||||
router.get(_route[1], _route[2])
|
||||
break
|
||||
case 'POST':
|
||||
router.post(_route[1], _route[2])
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
.get('/api/file/collection/get_by_name/:name', controllers.collection.getByName)
|
||||
.get('/api/file/collection/get/all', controllers.collection.getAll)
|
||||
.get('/api/file/collection/clear_deleted/', controllers.collection.clearDeleted)
|
||||
|
||||
// meta
|
||||
.post('/api/file/meta/create', controllers.recordingDataMeta.create)
|
||||
.post('/api/file/meta/update/:id', controllers.recordingDataMeta.update)
|
||||
.get('/api/file/meta/clear_deleted/', controllers.recordingDataMeta.clearDeleted)
|
||||
.get('/api/file/meta/get_by_name/:name', controllers.recordingDataMeta.getByName)
|
||||
.get('/api/file/meta/get_by_uuid/:uuid', controllers.recordingDataMeta.getByUUID)
|
||||
.get('/api/file/meta/get_by_id/:id', controllers.recordingDataMeta.getByID)
|
||||
.get('/api/file/meta/get_by_path/:path', controllers.recordingDataMeta.getByPath)
|
||||
.get('/api/file/meta/get_by_parent/:type/:parent', controllers.recordingDataMeta.getByParent)
|
||||
.get('/api/file/meta/get_count_by_parent/:type/:parent', controllers.recordingDataMeta.getCountByParent)
|
||||
.get('/api/file/meta/get_by_parent_with_limit/:type/:parent/:limit/:offset/:order', controllers.recordingDataMeta.getByParentWithLimit)
|
||||
.get('/api/file/meta/get_by_attr_parent_with_limit/:type/:parent/:limit/:offset/:order/:attr', controllers.recordingDataMeta.getByAttrsParentWithLimit)
|
||||
|
||||
.get('/api/file/meta/get_or_create_by_path/:path', controllers.recordingDataMeta.getOrCreateByPath)
|
||||
.get('/api/file/meta/get/all', controllers.recordingDataMeta.getAll)
|
||||
|
||||
// raw
|
||||
.post('/api/file/raw/create/:channel', controllers.recordingDataRaw.create)
|
||||
.post('/api/file/raw/update/:channel/:id', controllers.recordingDataRaw.update)
|
||||
.post('/api/file/raw/update_sd_data/:channel/:id', controllers.recordingDataRaw.updateSdData)
|
||||
.get('/api/file/raw/clear_deleted/:channel/:id', controllers.recordingDataRaw.clearDeleted)
|
||||
.get('/api/file/raw/get_by_id/:channel/:id', controllers.recordingDataRaw.getByID)
|
||||
.get('/api/file/raw/get_by_ids/:channel/:id', controllers.recordingDataRaw.getByIDs)
|
||||
.get('/api/file/raw/get_data_by_id/:channel/:id', controllers.recordingDataRaw.getDataByID)
|
||||
.get('/api/file/raw/get_by_parent/:channel/:parent', controllers.recordingDataRaw.getByParent)
|
||||
.get('/api/file/raw/get_attr_by_id/:channel/:id/:attr', controllers.recordingDataRaw.getAttrByID)
|
||||
.get('/api/file/raw/get_attr_by_ids/:channel/:id/:attr', controllers.recordingDataRaw.getAttrByIDs)
|
||||
.get('/api/file/raw/get_attr_by_parent/:channel/:parent/:attr', controllers.recordingDataRaw.getAttrByParent)
|
||||
|
||||
// mini
|
||||
.post('/api/file/mini/create/:channel', controllers.recordingDataMini.create)
|
||||
.post('/api/file/mini/update/:channel/:id', controllers.recordingDataMini.update)
|
||||
.get('/api/file/mini/clear_deleted/:channel/:id', controllers.recordingDataMini.clearDeleted)
|
||||
.get('/api/file/mini/get_by_id/:channel/:id', controllers.recordingDataMini.getByID)
|
||||
.get('/api/file/mini/get_by_parent/:channel/:parent', controllers.recordingDataMini.getByParent)
|
||||
.get('/api/file/mini/get_attr_by_id/:channel/:id/:attr', controllers.recordingDataMini.getAttrByID)
|
||||
.get('/api/file/mini/get_attr_by_parent/:channel/:parent/:attr', controllers.recordingDataMini.getAttrByParent)
|
||||
.get('/api/file/mini/random/get_by_id/:channel/:id', controllers.recordingDataMini.getRandomDataByID)
|
||||
.get('/api/file/mini/mean/get_by_id/:channel/:id', controllers.recordingDataMini.getMeanDataByID)
|
||||
|
||||
// device
|
||||
.post('/api/device/create', controllers.device.create)
|
||||
.post('/api/device/update/:id', controllers.device.update)
|
||||
.post('/api/device/update/all', controllers.device.update)
|
||||
.post('/api/device/update_by_id/:id', controllers.device.updateByID)
|
||||
.post('/api/device/update_by_mac/:mac', controllers.device.updateByMac)
|
||||
.post('/api/device/update_by_attr/:attr/:value', controllers.device.updateByAttr)
|
||||
.get('/api/device/clear_deleted/:id', controllers.device.clearDeleted)
|
||||
.get('/api/device/get_by_mac/:mac', controllers.device.getByMac)
|
||||
.get('/api/device/get_by_attr/:attr/:value', controllers.device.getByAttr)
|
||||
.get('/api/device/get/all', controllers.device.getAll)
|
||||
|
||||
.post('/api/device/update_by_id/:id', controllers.device.updateByID)
|
||||
.post('/api/device/update', controllers.device.update)
|
||||
|
||||
// controller
|
||||
.post('/api/controller/create', controllers.controller.create)
|
||||
.post('/api/controller/update/:id', controllers.controller.update)
|
||||
.post('/api/controller/update/all', controllers.controller.update)
|
||||
.post('/api/controller/update_by_attr/:attr/:value', controllers.controller.updateByAttr)
|
||||
.get('/api/controller/get_by_mac/:mac', controllers.controller.getByMac)
|
||||
.get('/api/controller/get_by_attr/:attr/:value', controllers.controller.getByAttr)
|
||||
.get('/api/controller/get/all', controllers.controller.getAll)
|
||||
|
||||
.post('/api/controller/update_by_id/:id', controllers.controller.updateByID)
|
||||
.post('/api/controller/update', controllers.controller.update)
|
||||
|
||||
// task
|
||||
.post('/api/task/create', controllers.task.create)
|
||||
.post('/api/task/update/:id', controllers.task.update)
|
||||
.post('/api/task/update_by_attr/:attr/:value', controllers.task.updateByAttr)
|
||||
.post('/api/task/update/all', controllers.task.update)
|
||||
.get('/api/task/get_by_id/:id', controllers.task.getByID)
|
||||
.get('/api/task/get_by_attr/:attr/:value', controllers.task.getByAttr)
|
||||
.get('/api/task/get/all', controllers.task.getAll)
|
||||
|
||||
.post('/api/task/update', controllers.task.update)
|
||||
.post('/api/task/update_by_id/:id', controllers.task.updateByID)
|
||||
// analyze
|
||||
.post('/api/analysis/spike_detect', controllers.analysis.spikeDetect)
|
||||
export default router
|
||||
|
||||
Reference in New Issue
Block a user