mirror of
https://github.com/GoogleChrome/chrome-extensions-samples.git
synced 2026-03-27 13:29:34 +07:00
Show dialog on the chart when device is disconnected
This commit is contained in:
@@ -5,3 +5,7 @@ Team: chengweih001, scheib, alvinjiooo.
|
||||
Design Doc: [go/fugu-exploration-sprint-2023-CO2-meter-extension](https://docs.google.com/document/d/1GX98Vfve1EvQ5BUajh4XE63-3PakTfxnZf_kKnl3U8o/edit?resourcekey=0-g2tQqNx2aKTYQRfXKHo9cA#) (Google internal only, this link can be removed when PR)
|
||||
|
||||
[TODO add the reason of this project and how this sample can help developers]
|
||||
|
||||
|
||||
## Known Issue
|
||||
* The extension couldn't detect device status properly when the device permission is revoked.
|
||||
@@ -18,7 +18,8 @@ import icon from "./modules/icon.js";
|
||||
import storage from "./modules/storage.js";
|
||||
import CO2Meter from "./modules/co2_meter.js";
|
||||
import {
|
||||
CO2_READING_KEY, TEMPERATURE_READING_KEY, NEW_READING_SAVED_MESSAGE
|
||||
CO2_READING_KEY, TEMPERATURE_READING_KEY, NEW_READING_SAVED_MESSAGE,
|
||||
PERMISSION_GRANTED_MESSAGE, CO2_METER_UNAVAILABLE
|
||||
} from "./modules/constant.js";
|
||||
|
||||
var clients = new Set();
|
||||
@@ -26,15 +27,24 @@ var clients = new Set();
|
||||
async function co2MeterConnected() {
|
||||
icon.setConnected();
|
||||
await CO2Meter.init();
|
||||
createAlarm();
|
||||
if (CO2Meter.getDeviceStatus()) {
|
||||
createAlarm();
|
||||
}
|
||||
};
|
||||
|
||||
function co2MeterDisconnected() {
|
||||
broadcastMessage(CO2_METER_UNAVAILABLE);
|
||||
icon.setDisconnected();
|
||||
clearAlarm();
|
||||
}
|
||||
|
||||
function clearAlarm() {
|
||||
console.log('Clear Alarm');
|
||||
chrome.alarms.clearAll();
|
||||
}
|
||||
|
||||
async function createAlarm() {
|
||||
console.log('Start Alarm');
|
||||
chrome.alarms.create("getReadingAlarm", {
|
||||
delayInMinutes: 0,
|
||||
periodInMinutes: await storage.getIntervalInSeconds() / 60
|
||||
@@ -43,28 +53,39 @@ async function createAlarm() {
|
||||
|
||||
async function onAlarmGetReading(alarm) {
|
||||
if (!CO2Meter.getDeviceStatus()) {
|
||||
chrome.alarms.clearAll();
|
||||
icon.setDisconnected();
|
||||
co2MeterDisconnected();
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
console.log('To read CO2');
|
||||
var reading = await CO2Meter.getCO2Reading();
|
||||
storage.setCO2Value(reading[CO2_READING_KEY]);
|
||||
storage.setTempValue(reading[TEMPERATURE_READING_KEY]);
|
||||
await broadcastNewReading();
|
||||
await broadcastMessage(NEW_READING_SAVED_MESSAGE);
|
||||
} catch (e) {
|
||||
console.log('Exception when reading CO2!', e);
|
||||
}
|
||||
}
|
||||
|
||||
async function broadcastNewReading() {
|
||||
async function broadcastMessage(message) {
|
||||
for (const client of clients.values()) {
|
||||
client.postMessage(NEW_READING_SAVED_MESSAGE);
|
||||
client.postMessage(message);
|
||||
}
|
||||
}
|
||||
|
||||
function onPermissionGranted() {
|
||||
co2MeterConnected();
|
||||
}
|
||||
|
||||
async function initilize() {
|
||||
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
||||
if (message === PERMISSION_GRANTED_MESSAGE) {
|
||||
onPermissionGranted();
|
||||
broadcastMessage(PERMISSION_GRANTED_MESSAGE);
|
||||
}
|
||||
});
|
||||
|
||||
chrome.runtime.onConnect.addListener(function (port) {
|
||||
console.log(`${port.name} connected`);
|
||||
port.onDisconnect.addListener(function (port) {
|
||||
|
||||
@@ -8,4 +8,9 @@
|
||||
<canvas id="chart"></canvas>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
</html>
|
||||
|
||||
<dialog id="device-disconnected">
|
||||
<p>Device is not detected, please make sure the CO2 meter is connected and the permission is granted!</p>
|
||||
<p>Permission can be granted in the settings page.</p>
|
||||
</dialog>
|
||||
@@ -1,7 +1,8 @@
|
||||
import storage from "./modules/storage.js";
|
||||
import { NEW_READING_SAVED_MESSAGE } from "./modules/constant.js";
|
||||
import { NEW_READING_SAVED_MESSAGE, PERMISSION_GRANTED_MESSAGE, CO2_METER_UNAVAILABLE } from "./modules/constant.js";
|
||||
import CO2Meter from "./modules/co2_meter.js";
|
||||
|
||||
let lastChartUpdateTimeMs =
|
||||
let lastChartUpdateTimeMs =
|
||||
new Date(new Date().getTime() - 7 * 24 * 60 * 60 * 1000).getTime(); // Initialize to one week ago.
|
||||
|
||||
let chart = null;
|
||||
@@ -54,14 +55,39 @@ window.onload = async e => {
|
||||
|
||||
chart = new Chart(document.getElementById('chart'), chartConfig);
|
||||
await updateChart();
|
||||
|
||||
|
||||
// Update when document becomes visible.
|
||||
document.onvisibilitychange = updateChart;
|
||||
|
||||
// Register for messages to update chart upon new data readings.
|
||||
chrome.runtime.connect().onMessage.addListener((msg) => {
|
||||
if (msg === NEW_READING_SAVED_MESSAGE) { updateChart() }
|
||||
if (msg === NEW_READING_SAVED_MESSAGE) { updateChart(); }
|
||||
else if (msg === PERMISSION_GRANTED_MESSAGE) { updateCO2MeterStatus(true); }
|
||||
else if (msg === CO2_METER_UNAVAILABLE) { updateCO2MeterStatus(false); }
|
||||
});
|
||||
|
||||
await CO2Meter.init();
|
||||
updateCO2MeterStatus(CO2Meter.getDeviceStatus());
|
||||
CO2Meter.registerCallback(CO2MeterConnected, CO2MeterDisconnected);
|
||||
}
|
||||
|
||||
function updateCO2MeterStatus(connected) {
|
||||
let dialog = document.getElementById('device-disconnected');
|
||||
if (connected) {
|
||||
dialog.close();
|
||||
} else {
|
||||
if (!dialog.open) {
|
||||
dialog.showModal();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function CO2MeterConnected() {
|
||||
updateCO2MeterStatus(true);
|
||||
}
|
||||
|
||||
function CO2MeterDisconnected() {
|
||||
updateCO2MeterStatus(false);
|
||||
}
|
||||
|
||||
async function updateChart() {
|
||||
|
||||
@@ -16,7 +16,8 @@ Or it returns false instead.
|
||||
|
||||
import icon from "./icon.js";
|
||||
import {
|
||||
CO2_READING_KEY, TEMPERATURE_READING_KEY
|
||||
CO2_READING_KEY, TEMPERATURE_READING_KEY,
|
||||
PERMISSION_GRANTED_MESSAGE
|
||||
} from "./constant.js";
|
||||
|
||||
const key = new Uint8Array([0xc4, 0xc6, 0xc0, 0x92, 0x40, 0x23, 0xdc, 0x96]);
|
||||
@@ -89,9 +90,9 @@ class CO2Meter {
|
||||
requestPermission() {
|
||||
// The extension currently only support this model:
|
||||
// https://www.co2meter.com/products/co2mini-co2-indoor-air-quality-monitor
|
||||
navigator.hid.requestDevice({ filters: [{ vendorId: 1241, productId: 41042 }] }).then((device) => {
|
||||
navigator.hid.requestDevice({ filters: [{ vendorId: 1241, productId: 41042 }] }).then((device) => {
|
||||
console.log('CO2 meter permission granted!', device[0]);
|
||||
icon.setConnected();
|
||||
chrome.runtime.sendMessage(PERMISSION_GRANTED_MESSAGE);
|
||||
})
|
||||
}
|
||||
|
||||
@@ -105,7 +106,9 @@ class CO2Meter {
|
||||
}
|
||||
|
||||
disconnectHandler() {
|
||||
this.device.close();
|
||||
if (this.device) {
|
||||
this.device.close();
|
||||
}
|
||||
this.device = null;
|
||||
this.reading = null;
|
||||
if (this.disconnectClientCB &&
|
||||
@@ -155,7 +158,8 @@ class CO2Meter {
|
||||
this.device.addEventListener('inputreport', onInputReport);
|
||||
await this.device.open();
|
||||
await this.device.sendFeatureReport(0, key);
|
||||
} catch {
|
||||
} catch (e) {
|
||||
console.log('CO2 reading exception:', e);
|
||||
this.device.removeEventListener('inputreport', onInputReport);
|
||||
await this.device.close();
|
||||
reject('Fail to open CO2 meter for reading');
|
||||
|
||||
@@ -15,4 +15,6 @@
|
||||
export const CO2_READING_KEY = 'CO2';
|
||||
export const TEMPERATURE_READING_KEY = 'Temperature';
|
||||
|
||||
export const NEW_READING_SAVED_MESSAGE = 'new reading saved';
|
||||
export const NEW_READING_SAVED_MESSAGE = 'new reading saved';
|
||||
export const PERMISSION_GRANTED_MESSAGE = 'permission granted';
|
||||
export const CO2_METER_UNAVAILABLE = 'co2 meter unavailable';
|
||||
Reference in New Issue
Block a user