Created
November 13, 2020 08:51
-
-
Save parasquid/098a098c500d763fc112b4fc56a7932f to your computer and use it in GitHub Desktop.
airquality.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<head> | |
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"> | |
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> | |
<meta name="HandheldFriendly" content="true"> | |
<style> | |
button { font-size: xx-large; } | |
</style> | |
<script src="https://cdn.jsdelivr.net/npm/[email protected]/min/moment.min.js"></script> | |
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script> | |
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script> | |
<script> | |
const ECO2 = 'd7e50001-0109-4306-956f-2f725ba7a85d'; | |
const TVOC = 'd7e50002-0109-4306-956f-2f725ba7a85d'; | |
const PM25 = 'd7e50003-0109-4306-956f-2f725ba7a85d'; | |
const PM10 = 'd7e50004-0109-4306-956f-2f725ba7a85d'; | |
const characteristics = { | |
temperature: 'temperature', | |
humidity: 'humidity', | |
eCO2: ECO2, | |
TVOC: TVOC, | |
'pm2.5': PM25, | |
'pm10': PM10, | |
} | |
const chartColors = { | |
temperature: 'rgb(255, 99, 132)', | |
humidity: 'rgb(255, 159, 64)', | |
eCO2: 'rgb(255, 205, 86)', | |
TVOC: 'rgb(75, 192, 192)', | |
'pm2.5': 'rgb(54, 162, 235)', | |
'pm10': 'rgb(153, 102, 255)', | |
t: 'rgb(201, 203, 207)' | |
}; | |
const chartConfig = { | |
type: 'line', | |
data: { | |
datasets: [] | |
}, | |
options: { | |
scales: { | |
xAxes: [{ | |
type: 'realtime', | |
realtime: { | |
duration: 50000, | |
delay: 500, | |
} | |
}], | |
yAxes: [{ | |
id: 'A', | |
type: 'linear', | |
position: 'left', | |
}, { | |
id: 'B', | |
type: 'linear', | |
position: 'right', | |
ticks: { | |
min: 400 | |
}, | |
}], | |
}, | |
tooltips: { | |
mode: 'nearest', | |
intersect: false | |
}, | |
hover: { | |
mode: 'nearest', | |
intersect: false | |
}, | |
plugins: { | |
streaming: { | |
frameRate: 60 | |
} | |
} | |
} | |
}; | |
Object.keys(characteristics).forEach(label => { | |
let yAxisID = 'A'; | |
console.log(chartColors[1]) | |
if(label === 'eCO2') yAxisID = 'B' | |
chartConfig.data.datasets.push({ | |
label, | |
yAxisID, | |
borderColor: chartColors[label], | |
fill: false, | |
data: [], | |
}); | |
}) | |
let device = null; | |
let characteristic = null; | |
let ctx = null; | |
let chart = null; | |
</script> | |
</head> | |
<body> | |
<div style="width:auto; margin:auto;"> | |
<center> | |
<button onclick="connectAndSubscribe(this)" id="connectButton"> | |
Connect to device | |
</button> | |
<button onclick="disconnect(this)" disabled id="disconnectButton"> | |
Disconnect from device | |
</button> | |
</center> | |
<canvas id="myChart" style="display: block; width: auto; height: 480px;" width="auto" height="480"></canvas> | |
</div> | |
<script> | |
ctx = document.getElementById('myChart').getContext('2d'); | |
chart = new Chart(ctx, chartConfig); | |
const connectButton = document.getElementById('connectButton'); | |
const disconnectButton = document.getElementById('disconnectButton'); | |
const connectAndSubscribe = async(e) => { | |
try { | |
const services = []; | |
const filters = [{services}] | |
services.push('environmental_sensing'); | |
// summon pairing ui | |
device = await navigator.bluetooth.requestDevice({filters}); | |
// setup callback so we can clean up on disconnection | |
device.addEventListener('gattserverdisconnected', onDisconnected); | |
// connect to the lightbulb | |
const server = await device.gatt.connect(); | |
const service = await server.getPrimaryService('environmental_sensing'); | |
Object.keys(characteristics).forEach((name) => { | |
service.getCharacteristic(characteristics[name]) | |
.then(c => c.startNotifications()) | |
.then(c => c.addEventListener( | |
'characteristicvaluechanged', | |
handleCharacteristicValueChanged(name) | |
) | |
); | |
}); | |
connectButton.disabled = true; | |
disconnectButton.disabled = false; | |
} catch(err) { | |
console.error({err}); | |
} | |
}; | |
const onDisconnected = (event) => { | |
device = null; | |
characteristic = null; | |
connectButton.disabled = false; | |
disconnectButton.disabled = true; | |
console.log("disconnected!"); | |
}; | |
const handleCharacteristicValueChanged = (name) => (event) => { | |
let value = event.target.value.getUint16(0, true); // little endian | |
if (name === 'temperature' || name === 'humidity') value = value / 100; | |
chart.data.datasets.find((d) => d.label === name).data.push({ | |
x: Date.now(), | |
y: value, | |
}) | |
chart.update({ preservation: true }); | |
}; | |
const disconnect = async(e) => { | |
if (device && device.gatt.connected) device.gatt.disconnect(); | |
}; | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment