-
Notifications
You must be signed in to change notification settings - Fork 2
/
_device.tsx
123 lines (114 loc) · 3.4 KB
/
_device.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import React, { useState, useEffect } from 'react';
import dynamic from 'next/dynamic'
/* Wrap DevicePlot with a dynamic import to disable server-side rendering.
* Prevents `self is undefined` errors caused by Giraffe when rendered
* with Node.
*/
const DynamicDevicePlotWithNoSSR = dynamic(
() => import('./_devicePlot').then(mod => mod.DevicePlot),
{ ssr: false }
)
export function Device({deviceId}: {deviceId: string | string[]}) {
const [error, setError] = useState<string | null>(null)
const [isLoading, setIsLoading] = useState(false)
const [device, setDevice] = useState<any[] | null>(null)
const [data, setData] = useState<string[] | []>([])
deviceId = Array.isArray(deviceId) ? deviceId[0] : deviceId
useEffect(() => {
deviceId && getDevice()
}, [deviceId])
useEffect(() => {
getFieldData()
}, [deviceId])
function getFieldData() {
if(!device) {
return
}
setError(null)
setIsLoading(true)
const results: string[] = []
const fields = ['Humidity', 'Pressure', 'Temperature']
fields.forEach(field => {
getMeasurements(field)
.then(res => {
if(res.ok) {
return res.text()
} else {
setError(`${field} error: ${res.statusText}`)
return ''
}
})
.then(text => {
results.push(text)
console.log(results)
setData(results)
setIsLoading(false)
})
})
}
const getDevice = () => {
setIsLoading(true)
fetch(`/api/devices/${deviceId}`)
.then((res) => res.json())
.then((data) => {
if(Array.isArray(data)) {
setDevice(data)
}
if(data.error) {
setError(data.error)
}
setIsLoading(false)
})
}
const getMeasurements = (field: string) => {
const query =
`from(bucket: "${process.env.NEXT_PUBLIC_INFLUX_BUCKET}")
|> range(start: -60d)
|> filter(fn: (r) => r._measurement == "environment" and r.device == "${deviceId}" )
|> filter(fn: (r) => r._field == "${field}" )
|> aggregateWindow(every: 1h, fn: mean, createEmpty: false)
|> yield(name: "mean")
`
return (
fetch(`/api/devices/${deviceId}/measurements`,
{ method: 'POST',
headers: { 'Accept': 'application/csv', 'Content-Type': 'application/json'},
body: JSON.stringify({ query })
})
)
}
function writeSimulatedData() {
fetch('/api/devices/generate', {
method: 'POST',
body: JSON.stringify({ deviceIds: [deviceId] }),
headers: { "Content-Type": "application/json" }
})
.then((res) => {
if(!res.ok) {
setError(`Writing data: ${res.statusText}`)
}
getFieldData()
})
}
return (
<div>
<div className="alert">
{ isLoading && <span>Loading...</span> }
{ error &&
<span className="alert-danger">{ error }</span>
}
</div>
<h5>Device</h5>
{device && <h4>{deviceId}</h4>}
{device &&
<p><button onClick={ writeSimulatedData }>Generate data for this device</button></p>
}
{data.map((csv, i) =>
<div className='card-body'>
<div key={`${i}-line`}><DynamicDevicePlotWithNoSSR csv={csv} plot='line' /></div>
<div key={`${i}-table`}><DynamicDevicePlotWithNoSSR csv={csv} plot='table' title='' /></div>
</div>
)}
</div>
)
}