This describes a generic framework for discovering and using sensors and devices. There are three primary components: a new SensorSource
interface, extensions to the Generic Sensor API to support it, and a new SensorRegistry
interface for discovering sensors.
Naming things is considered one of the hardest problems in computer science, and that was true of designing this preliminary spec. I had to decide on a name for the API, whether or not to use Sensor to mean any device and not just a sensor, whether to create a separate Device interface and use a term that unifies Sensor and Device, and if so, what its name should be.
I eventually decided to use Sensor
as this document describes extensions and additions to the existing Generic Sensor API. I forsee names being changed or new interfaces being designed (such as Device
to encapsulate both sensor devices and actuator devices).
Next, I had to decide on a term for the interface between a Sensor and a Sensor Discovery API. Some potential candidates were: SensorDriver
, SensorSource
, SensorManager
, and SensorController
. I choose the name SensorSource
because it most accurately conveys the purpose, but consideration should be given to other names as well.
For this to work, the Generic Sensor API should be extended so that it and every interface that extends it should support an optional source
parameter in the constructor parameter. This will allow existing global sensor classes such as Accelerometer
to continue functioning while also being compatible with the new Sensor Discovery features.
How a class utilizes the source
parameter is class-specific. For example, Accelerometer
may only use SensorSource
instances created by the browser and may throw an exception when created by the user.
interface SensorOptions {
frequency?: number | undefined;
source?: SensorSource | undefined;
}
declare class Sensor extends EventTarget {
constructor(options?: SensorOptions);
}
A SensorSource
is similar to a driver, acting as an interface between a program and hardware. Unlike real operating system drivers, however, SensorSource
can be entirely userspace, acting as a bridge to a real-word sensor that sits behind multiple drivers (i.e. a sensor attached to a hub connected to the host with Bluetooth).
While SensorSource
instances can be created manually, they are intended to be created inside a SensorRegistry
, which provides SensorSource
instances to pass to the constructor of a Sensor
class.
SensorSource
inherits from EventTarget
to provide an important feature of computer drivers: interrupts. The intention is to signal a SensorSource
to handle an event asynchronously. This may be replaced by having an AbortSignal
member instead.
interface SensorSource extends EventTarget {
input: ReadableStream;
output: WritableStream;
meta: Record<string, string | number | boolean | Uint8Array>;
}
A SensorRegistry
handles the discovery of available sensors and creating SensorSource
instances to interact with them.
SensorRegistry
can best be thought of as a bus, acting as a physical or virtual link between a host and a device it wants to interact with.
TODO: Still working on SensorRegistry
!!!
type SensorClass = "Accelerometer" | "Gyroscope" | "Battery" | DOMString;
interface SensorRegistry {
readonly sensors: Map<SensorClass, SensorSource[]>;
}