286 lines
6.8 KiB
JavaScript
286 lines
6.8 KiB
JavaScript
var chart = null
|
|
var chart2 = null
|
|
function initCharts() {
|
|
chart = c3.generate({
|
|
bindto: '#humidity-temp',
|
|
data: {
|
|
x: 'time',
|
|
columns: [
|
|
['time', 1, 2, 3, 4],
|
|
['temp', 24, 24.5, 24.3, 24.6],
|
|
['humidity', 83.1, 99.5, 74.3, 84.6],
|
|
],
|
|
axes: {
|
|
temp: 'y',
|
|
humidity: 'y2'
|
|
}
|
|
},
|
|
axis: {
|
|
x: {
|
|
tick: {
|
|
format: (x) => new Date(x).toISOString()
|
|
}
|
|
},
|
|
y2: {
|
|
show: true
|
|
}
|
|
},
|
|
zoom: {
|
|
enabled: true
|
|
}
|
|
})
|
|
chart2 = c3.generate({
|
|
bindto: '#volts',
|
|
data: {
|
|
x: 'time',
|
|
columns: [
|
|
['time', 1, 2, 3, 4],
|
|
['voltage', 24, 24.5, 24.3, 24.6],
|
|
['voltage2', 24, 24.5, 24.3, 24.6],
|
|
],
|
|
axes: {
|
|
voltage: 'y',
|
|
voltage2: 'y',
|
|
}
|
|
},
|
|
axis: {
|
|
x: {
|
|
tick: {
|
|
format: (x) => new Date(x).toISOString()
|
|
}
|
|
},
|
|
},
|
|
zoom: {
|
|
enabled: true
|
|
}
|
|
})
|
|
}
|
|
|
|
var max_interval_millis = 5*60*1000
|
|
var decimation_rate = 1
|
|
|
|
var cur_time_millis = 0
|
|
var time = []
|
|
var temp = []
|
|
var humd = []
|
|
var volts = []
|
|
var volts2 = []
|
|
|
|
function status(msg) {
|
|
document.getElementById('status').textContent = msg
|
|
}
|
|
|
|
var autoupdate = true
|
|
var chart_updater = null
|
|
|
|
async function updateCharts() {
|
|
status("loading data...")
|
|
const latest = await fetch("/api/latest")
|
|
const last_time_millis = await latest.json()
|
|
if (last_time_millis > cur_time_millis) {
|
|
// we need to collect more data to catch up
|
|
// time is in milliseconds so we divide by 1000
|
|
var diff = (last_time_millis - cur_time_millis) / 1000
|
|
// worst case load only the last two weeks of data
|
|
diff = Math.min(diff, max_interval_millis/1000)
|
|
var path = "/api/last/weeks/"
|
|
var offset = diff
|
|
if (diff < 60) {
|
|
path = "/api/last/seconds/"
|
|
offset = Math.ceil(diff)
|
|
} else if (diff < 60*60) {
|
|
path = "/api/last/minutes/"
|
|
offset = Math.ceil(diff/60)
|
|
} else if (diff < 24*60*60) {
|
|
path = "/api/last/hours/"
|
|
offset = Math.ceil(diff/(60*60))
|
|
} else if (diff < 7*24*60*60) {
|
|
path = "/api/last/days/"
|
|
offset = Math.ceil(diff/(24*60*60))
|
|
} else {
|
|
path = "/api/last/weeks/"
|
|
offset = Math.ceil(diff/(7*24*60*60))
|
|
}
|
|
const new_data = await fetch(path + offset)
|
|
const new_data_json = await new_data.json()
|
|
// copy the data into the arrays
|
|
new_data_json.sort((a, b) => a.t - b.t)
|
|
new_data_json.forEach((v) => {
|
|
var last_time = time[time.length-1]
|
|
if (time.length == 0) {
|
|
last_time = 0
|
|
}
|
|
if (v.t > last_time) {
|
|
time.push(v.t)
|
|
temp.push(v.temp)
|
|
humd.push(v.hum)
|
|
volts.push(v.hv)
|
|
volts2.push(v.hv2)
|
|
}
|
|
})
|
|
// truncate all the lists as necessary
|
|
// using the time array to determine the splicing points
|
|
cur_time_millis = time[time.length - 1]
|
|
const min_time = cur_time_millis - max_interval_millis
|
|
|
|
var slice_idx = 0
|
|
for (var i = 0; i < time.length; i++) {
|
|
if (time[i] >= min_time) {
|
|
slice_idx = i
|
|
break
|
|
}
|
|
}
|
|
//console.log("slice idx ", slice_idx)
|
|
|
|
temp = temp.slice(slice_idx)
|
|
humd = humd.slice(slice_idx)
|
|
volts = volts.slice(slice_idx)
|
|
volts2 = volts2.slice(slice_idx)
|
|
time = time.slice(slice_idx)
|
|
|
|
const temp_d = temp.filter((_, idx) => (idx % decimation_rate) == 0)
|
|
const humd_d = humd.filter((_, idx) => (idx % decimation_rate) == 0)
|
|
const volts_d = volts.filter((_, idx) => (idx % decimation_rate) == 0)
|
|
const volts2_d = volts2.filter((_, idx) => (idx % decimation_rate) == 0)
|
|
const time_d = time.filter((_, idx) => (idx % decimation_rate) == 0)
|
|
|
|
chart.load({
|
|
columns: [
|
|
["time"].concat(time_d),
|
|
["temp"].concat(temp_d),
|
|
["humidity"].concat(humd_d),
|
|
]
|
|
})
|
|
chart2.load({
|
|
columns: [
|
|
["time"].concat(time_d),
|
|
["voltage"].concat(volts_d),
|
|
["voltage2"].concat(volts2_d),
|
|
]
|
|
})
|
|
status("charts updated")
|
|
}
|
|
|
|
if (autoupdate) {
|
|
chartupdater()
|
|
}
|
|
}
|
|
|
|
const sleep = (ms) => new Promise(r => setTimeout(r, ms))
|
|
var chart_update_millis = 2000
|
|
|
|
async function chartupdater() {
|
|
if (chart_updater) return
|
|
chart_updater = true
|
|
|
|
try {
|
|
while (autoupdate) {
|
|
await sleep(chart_update_millis)
|
|
// wait at least two seconds to avoid wasting a lot of bandwidth
|
|
const resp = await fetch("/api/update")
|
|
updateCharts()
|
|
}
|
|
} finally {
|
|
chart_updater = false
|
|
}
|
|
}
|
|
|
|
var status_updater = false
|
|
async function updateStatus() {
|
|
const status_resp = await fetch("/api/status")
|
|
const status = await status_resp.json()
|
|
//console.log(status)
|
|
const humidifier_state = (status.humidifier ? "on" : "off")
|
|
const manual_mode_state = (status.manual_mode ? "on" : "off")
|
|
//console.log(humidifier_state)
|
|
document.getElementById("device-status").textContent = "connected: " +
|
|
status.connected + ", manual mode: " + manual_mode_state + ", humidifier: "
|
|
+ humidifier_state
|
|
|
|
if (autoupdate) {
|
|
waitThenUpdateStatus()
|
|
}
|
|
}
|
|
|
|
async function waitThenUpdateStatus() {
|
|
if (status_updater) return
|
|
status_updater = true
|
|
try {
|
|
while (autoupdate) {
|
|
await fetch("/api/status_update")
|
|
updateStatus()
|
|
}
|
|
} finally {
|
|
status_updater = false
|
|
}
|
|
}
|
|
|
|
async function testAdminMode() {
|
|
const msg = JSON.stringify({
|
|
auth: "password",
|
|
data: {
|
|
set_params: {
|
|
name: "target_lower",
|
|
value: 0.87
|
|
}
|
|
}
|
|
})
|
|
await fetch("/api/admin", {
|
|
method: "POST",
|
|
body: msg
|
|
})
|
|
}
|
|
|
|
window.onload = () => {
|
|
initCharts()
|
|
updateCharts()
|
|
updateStatus()
|
|
|
|
document.getElementById('update').addEventListener('click', (e) => {
|
|
updateCharts()
|
|
updateStatus()
|
|
})
|
|
document.getElementById('autoupdate').addEventListener('click', (e) => {
|
|
autoupdate = document.getElementById('autoupdate').checked
|
|
})
|
|
document.getElementsByName('decim').forEach((elem) => {
|
|
elem.addEventListener('click', (e) => {
|
|
if (elem.checked) {
|
|
decimation_rate = parseInt(elem.value)
|
|
}
|
|
})
|
|
})
|
|
document.getElementsByName('update').forEach((elem) => {
|
|
elem.addEventListener('click', (e) => {
|
|
if (elem.checked) {
|
|
chart_update_millis = parseInt(elem.value)
|
|
}
|
|
})
|
|
})
|
|
|
|
document.getElementsByName('duration').forEach((elem) => {
|
|
elem.addEventListener('click', (e) => {
|
|
const old_millis = max_interval_millis
|
|
if (elem.checked) {
|
|
max_interval_millis = parseInt(elem.value)*1000*60
|
|
if (max_interval_millis != old_millis) {
|
|
// reset the chart data to force a reload on the next update
|
|
cur_time_millis = 0
|
|
time = []
|
|
temp = []
|
|
humd = []
|
|
volts = []
|
|
volts2 = []
|
|
}
|
|
}
|
|
})
|
|
})
|
|
|
|
/*
|
|
document.getElementById('test-admin').addEventListener('click', (e) => {
|
|
testAdminMode()
|
|
})
|
|
*/
|
|
}
|
|
|