Sensor-based, context-aware apps do things like adjust screen brightness according to ambient light sensor readings and control a cooling fan's speed based on temperature. Writing software to interact with several devices, each with a different API, can be a nightmare. Sensor API's common API and vendor-specific extensions let developers leave compatibility worries to sensor vendors.
The COM-based Sensor API works with drivers via extensions to a sensor class and consists of three main interfaces:
• ISensorManager provides methods for identifying and retrieving available sensors, requesting permissions, and controlling what happens when the user connects a sensor to a computer.
• ISensor lets sensors get and set properties, obtain reports, and control sensor-related events.
• ISensorDataReport reports sensor data and provides time stamps.
ISensorManager classifies sensors by category (GetSensorByCategory) based on what's being sensed, like location, motion, and environmentals and by type (GetSensorByType)--like voltage, GPS, and accelerometer--based on how the corresponding category is sensed.
The Windows API Code Pack for Microsoft's .NET Framework has wrapper classes to handle unmanaged Sensor APIs. It replicates the main interfaces with three classes of wrapping properties and events: SensorManager; Sensor, an abstract base class; and SensorDataReport, also an abstract base class.
The API Code Pack also provides a subclass of sensor for each of the following types: AmbientLightSensor, BooleanSwitchArray, Accelerometer3D, and UnknownSensor. Each sensor subclass uses the corresponding subclass of SensorDataReport.
A common application of the Sensor API involves measuring and possibly changing lighting conditions. Such ambient light-sensing applications include ones that automatically adjust the brightness of a computer screen or illuminate a keyboard. To build a light-sensing program like this in C#, start by adding the Microsoft.WindowsAPICodePack.Sensors assembly as a reference to an existing project and include "using Microsoft.WindowsAPICodePack.Sensors." This lets you access the classes and types that the Sensor API wrapper provides.
An option is to include the Windows API Code Pack Library Sensors project instead of adding a reference to the assembly. You can use the SensorManager class to get a list of all the ambient light sensors. In this case, the type ID is a mix of category and type:
lightSensorList = SensorManager.
SensorList is a list of Microsoft.WindowsAPICodePack.Sensors.Sensor; lightSensorList holds a list of the available ambient light sensors. If there are no in- stances of the required type of sensor, GetSensorsByTypeId returns a null value.
Once you get the list of sensors of a specific type, request permission to use them. The API wrapper class maps each sensor type to the sensor type GUID expected by the underlying COM API. The RequestPermission method receives three parameters:
• The parent window handle; in this case, IntPtr.Zero.
• A bool value indicating whether the dialog that appears should be modal (synchronous call).
• SensorList of Sensor with all the sensors needed to request permission to access. Because this parameter is a SensorList of Sensor and lightSensorList is a SensorList of AmbientLightSensor, it's necessary to add the elements of this list to a new SensorList of Sensor.
Check whether the SensorList is null before creating the new list and calling the RequestPermission method. To keep things simple, I don't include code to catch exceptions.
lightSensor = lightSensorList;
First, I create OnDataReportChanged, a DataReportChangeHandler method. This method receives the AmbientLightSensor instance and can react according to the changes in the value read (see sample code, p. 40). The sensor's GUID can be obtained in lightSensor.SensorId.Value. Since the event handler can be attached to many sensors, it's necessary to add code to check which sensor is bringing new data. In this case, I'm assuming there are several ambient light sensors. The sender must be typecast to AmbientLightSensor because the definition for the event handler uses the generic Sensor class. CurrentLuminousIntensity.Intensity offers the light intensity value. You can fire the necessary actions according to the new value that's been read.
Now add code to force the sensor to generate a new data report by subscribing to the sensor's DataReportChanged event:
This code calls the TryUpdateData method to generate the new data report, so there's an initial value. Then, the DataReportChanged event fires periodically (or once the measured value changes beyond a certain threshold).
With a common API, the Windows 7 Sensor API provides a simple way to create context-aware applications without the need to learn multiple proprietary APIs.
Gastón Hillar is an IT consultant.