shrooms-server/dev/dev.htm

251 lines
5.9 KiB
HTML

<!doctype html>
<html>
<head>
<!-- Load c3.css -->
<link href="/c3.css" rel="stylesheet" type=text/css>
<!-- Load d3.js and c3.js -->
<script src="/d3.v5.min.js" charset="utf-8"></script>
<script src="/c3.min.js"></script>
<script>
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],
],
axes: {
voltage: '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 = []
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)
}
})
// 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)
time = time.slice(slice_idx)
chart.load({
columns: [
["time"].concat(time),
["temp"].concat(temp),
["humidity"].concat(humd),
]
})
chart2.load({
columns: [
["time"].concat(time),
["voltage"].concat(volts),
]
})
status("charts updated")
}
if (autoupdate) {
chart_updater = chartupdater()
} else {
chart_updater = null
}
}
const sleep = (ms) => new Promise(r => setTimeout(r, ms))
var chart_update_millis = 2000
async function chartupdater() {
if (chart_updater != null) return
await sleep(chart_update_millis)
// wait at least two seconds to avoid wasting a lot of bandwidth
const resp = await fetch("/api/update")
chart_updater = null
updateCharts()
}
var status_updater = null
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")
//console.log(humidifier_state)
document.getElementById("device-status").textContent = "connected: " + status.connected + ", humidifier: " + humidifier_state
if (autoupdate) {
status_updater = waitThenUpdateStatus()
} else {
status_updater = null
}
}
async function waitThenUpdateStatus() {
if (status_updater != null) return
await fetch("/api/status_update")
status_updater = null
updateStatus()
}
async function testAdminMode() {
const msg = JSON.stringify({
auth: "password",
data: {
manual_mode: true
}
})
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.getElementById('test-admin').addEventListener('click', (e) => {
testAdminMode()
})
}
</script>
</head>
<body>
<div id="device-status"></div>
<div id="humidity-temp"></div>
<div id="volts"></div>
<div>
<form>
<input type=checkbox id=autoupdate checked>Autoupdate</input>
<input type=button id=update value="Update"></input>
<input type=button id=test-admin value="Test admin mode"></input>
<!-- TODO add decimation and window size options -->
<span id=status></span>
</form>
</div>
</body>
</html>