Skip to content

Instantly share code, notes, and snippets.

@parasquid
Created November 13, 2020 08:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save parasquid/098a098c500d763fc112b4fc56a7932f to your computer and use it in GitHub Desktop.
Save parasquid/098a098c500d763fc112b4fc56a7932f to your computer and use it in GitHub Desktop.
airquality.html
<!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/moment@2.24.0/min/moment.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js@2.8.0"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-streaming@1.8.0"></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