Files
Jack Hsieh e7c398bf93 CO2 meter extension - a sample for using WebHID on extension service worker. (#921)
* Initial README.md file

* fix design doc link

* Update README.md adding scheib

* Update README.md

* test

* update README.md with alvinjiooo

* add a ascii fish in README.md

* Update README.md

* skeloton extension

* Add original co2meter.html

* add buttons to settings page

* Initial storage module stub.

* Add storage module reference from settings page.

* Fix settings JS to be module compatible.

* Add stubs for settings storage writing

* Call saveCO2Value() from onInputReport in co2meter.html

* background page to read CO2 periodically based on the stored interval

* verion 1.0 /module/co2_meter.js

* Refactor settings.html and hook up CO2 driver

* update v2 of /module/co2_meter.js which access all methods from CO2Meter class

* Fix co2_meter import in background.js

* background page to show CO2 meter disconnected icon

* v2.1 update /module/co2_meter.js add support for virtual meter and connection listener also rquestPermission

* v2.1 update /module/co2_meter.js

* Import idb-keyval indexedDB library into storage.js, with trivial usage.

* background page handle disconnect connect device

* update v2.2 /module/co2_meter.js make  non-static and add guarding flag for exccessive reading

* update v2.3 /module/co2_meter.js await device to close before open device in

* update v2.4 /module/co2_meter.js change to return reject promise instead of Error in

* Add third-party/idb-keyval, use to set/get interval.

* Simplify settings and storage.

* handle background page device disconnect/connect

* Rename *_script.js files to only *.js.

* Add temp reading

* Add chart to popup.html with chartjs etc.

* Update extension tool tip to show connected/disconnected status.

* use indexedDB to store CO2 reading

* Renaming items in background.js

Name methods more clearly for what they are doing.
Collapse some code when possible to be inline.

* add  in Storage

* add support for storing temperature and query temperature in range

* background page boardcasting reading updated

* Refactor chart out of popup into chart.html for iframing

* Continued: chart out of popup into chart.html for iframing

* Use message channel for message broadcasting and move common constant to constant.js

* Work in progress for data into chart.

* Use set for clients in background page

* Add promise to storage constructor.

* Change IDB version number due to schema change

* Populate chart data.

* check store name before creating when version changed

* increase popup window and iframe size

* Update chart upon new data.

* Add calibration period and refactor inputReport

* Use flexbox to layout pages.

* move internal and temperature unit into setting store

* move dbInitialized into transaction oncomplete event

* remove reading out interval and temp unit log

* Remove co2meter.html

* Add .map files for third party code to remove devtools warnings.

* Display chart in Fahrenheit

* remove idb-keyvalue

* prettier storage.js and add comments to public methods

* Chart style: time axis respects time of data, no data points

* Show dialog on the chart when device is disconnected

* Add Example Data Button

* Close dialog button

* Implement toggling between Celsius / Fahrenheit

* polish co2_meter.js and remove virtual device and change default interval to 30 sec

* Change small icon to CO2 text

* change reading interval default to 30 secs which helps the chart update faster for fresh load case

* Fix lint error

* Clean up console.log

* Add chrome.alarm example

* remove keep alive for reading alarm

* refactor to keep connection open

* add README.md

* strip down

* addressed comments

* add link to README.md

---------

Co-authored-by: Vincent Scheib <scheib@users.noreply.github.com>
Co-authored-by: Alvin Ji <111466895+alvinjiooo@users.noreply.github.com>
Co-authored-by: Alvin Ji <alvinji@chromium.org>
Co-authored-by: Alpaca Jam <alvinji@google.com>
2023-06-16 20:56:03 +02:00

117 lines
3.0 KiB
JavaScript

// Copyright 2023 Google LLC
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// https://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
'use strict';
import icon from './modules/icon.js';
import CO2Meter from './modules/co2_meter.js';
import {
PERMISSION_GRANTED_MESSAGE,
CO2_METER_UNAVAILABLE,
CO2_METER_AVAILABLE,
NO_CO2_METER_FOR_READING,
NEW_CO2_READING,
NEW_TEMP_READING,
READING_UNKNOWN
} from './modules/constant.js';
let clients = new Set();
let last_co2_reading = READING_UNKNOWN;
let last_temp_reading = READING_UNKNOWN;
async function co2MeterConnected() {
broadcastMessage(CO2_METER_AVAILABLE);
icon.setConnected();
startCO2Reading();
}
async function co2MeterDisconnected() {
CO2Meter.stopReading();
broadcastMessage(CO2_METER_UNAVAILABLE);
icon.setDisconnected();
last_co2_reading = READING_UNKNOWN;
last_temp_reading = READING_UNKNOWN;
await broadcastMessage(NEW_CO2_READING, last_co2_reading);
await broadcastMessage(NEW_TEMP_READING, last_temp_reading);
}
async function broadcastMessage(type, data) {
for (const client of clients.values()) {
client.postMessage({
type: type,
data: data
});
}
}
function onPermissionGranted() {
co2MeterConnected();
}
async function startCO2Reading() {
try {
await CO2Meter.startReading();
} catch (e) {
console.log('Exception when startCO2Reading:', e);
if (e === NO_CO2_METER_FOR_READING) {
co2MeterDisconnected();
}
}
}
async function OnCO2Reading(co2_reading) {
last_co2_reading = co2_reading;
await broadcastMessage(NEW_CO2_READING, co2_reading);
}
async function OnTempReading(temp_reading) {
last_temp_reading = temp_reading;
await broadcastMessage(NEW_TEMP_READING, temp_reading);
}
async function initialize() {
chrome.runtime.onMessage.addListener((message) => {
if (message === PERMISSION_GRANTED_MESSAGE) {
onPermissionGranted();
broadcastMessage(CO2_METER_AVAILABLE);
}
});
chrome.runtime.onConnect.addListener(async function (port) {
port.onDisconnect.addListener(function (port) {
clients.delete(port);
});
clients.add(port);
await broadcastMessage(NEW_CO2_READING, last_co2_reading);
await broadcastMessage(NEW_TEMP_READING, last_temp_reading);
});
await CO2Meter.init(
co2MeterConnected,
co2MeterDisconnected,
OnCO2Reading,
OnTempReading
);
startCO2Reading();
}
if (navigator.hid) {
initialize();
} else {
console.error(
'WebHID is not available! Use chrome://flags#enable-web-hid-on-extension-service-worker'
);
}