In order to learn about sensor development, I decided to do a take on the Sensor Diagnostic Tool application. My application called Sensor Starter is a WPF application that leverages the Sensor Wrapper Library to program to the Sensor API. The User Interface displays the enumerated sensors in a tree control, displays sensor properties and sensor data in a set of grid controls and displays graphical output for each activated sensor on the JM Badge:

clip_image002

Enumerating Sensors

The code to enumerate the sensors is quite simple. The library provides a SensorManager that has a static method called GetAllSensors() that returns an array of Sensor objects:

Sensor[] sensors = SensorManager.GetAllSensors();

Each sensor object is then wrapped in a SensorModel, a class that provides additional sensor processing. The SensorModel is inserted into a Dictionary (m_sensors) indexed by the Sensor ID which is a GUID. Finally the Sensor information is added to the TreeView for display to the user:

 

for (int i = 0; i < sensors.Length; i++)

{

Sensor s = sensors[i];

m_sensors[s.SensorID] = new SensorModel(s);

TreeViewItem nodeSensor = new TreeViewItem();

nodeSensor.Header = m_sensors[s.SensorID].Sensor.FriendlyName;

nodeSensor.Tag = (object)m_sensors[s.SensorID].Sensor.SensorID;

((TreeViewItem)SensorTreeView.Items[0]).Items.Add(nodeSensor);

}

clip_image003

Hooking into Sensor Events

If the user clicks on one of the Sensors in the list, the DataUpdated Event is hooked into and the application starts to receive a real-time feed from the sensor on a background thread:

 

// hook up the data update event handler

private void SensorTreeView_SelectedItemChanged( object sender, RoutedPropertyChangedEventArgs<object> e)

{

// selected item in the tree

TreeViewItem t = (TreeViewItem) SensorTreeView.SelectedItem;

// index into the dictionay of sensors

Guid sensorID = (Guid) t.Tag;

//set event handlers for the selected sensor

m_sensors[sensorID].Sensor.DataUpdated += new

SensorDataUpdatedEventHandler(DataUpdatedHandler);

}

 

// this method will queue up the data update request

// asynchronously using the WPF Dispatcher object

public void DataUpdatedHandler(Sensor sensor, SensorDataReport newData)

{

ThreadStart start = delegate()

{

    // use the dispatcher to update UI elements with new data figures

    DispatcherOperation op = Dispatcher.BeginInvoke(

    DispatcherPriority.Normal,

    new Action<Sensor>(UpdateData), sensor);

};

// Create the thread and kick it started!

new Thread(start).Start();

}

Handling Sensor Data and Properties

The UpdateData() method is where all the magic happens. The sensor provides a data report and a property report. This data and properties are translated into DataTables by the SensorModel so that the WPF application can deal with it more easily, binding it to data grids and updating graphical elements on the screen:

// raw data coming back from the sensor

SensorDataReport sensorDataReport;

// raw data mapped to fields

IDictionary<PropertyKey, object> sensorData;

// sensor properties coming back from the sensor

IDictionary<PropertyKey, object> sensorProperties;

sensorDataReport = s.GetDataReport();

sensorData = sensorDataReport.GetDataFields();

sensorProperties = s.GetAllProperties();

//grab the model for the sensor of interest

SensorModel sm = m_sensors[s.SensorID];

// translate the data and properties to DataTable based name, value

// pairs for binding to the grids

DataTable d = sm.XLate(sensorData);

DataTable p = sm.XLate(sensorProperties);

clip_image007

The Location API

The Location API is built on top of the Sensor API and provides two sources of data:

  • Civic Address Location
  • Longitude, Latitude Location (GPS Device)

The Civic Address Location is the Default Location that the user has entered into the Control Panel à Hardware and Sound à Location and Other Sensors à Default Location screen.

clip_image009

This information is something that users may not want to share with other user accounts and applications so there is a security setting screen on the Control Panel à Hardware and Sound à Location and Sensors à User Settings screen:

clip_image011

If the application has permission, the Civic Address information can be retrieved by requesting a Civic Address Location Report:

 

CivicAddressDialog d = new CivicAddressDialog(SensorModel.GetCivicAddressReport());

 

In the Sensor Starter Application, I take this report and display the results in a dialog:

public CivicAddressDialog(CivicAddressLocationReport report)

{

InitializeComponent();

m_report = report;

AddrLine1.Text = m_report.AddressLine1;

AddrLine2.Text = m_report.AddressLine2;

City.Text = m_report.City;

StateProvince.Text = m_report.StateOrProvince;

CountryRegion.Text = m_report.CountryOrRegion;

PostalCode.Text = m_report.PostalCode;

Timestamp.Text = m_report.Timestamp.ToLocalTime().ToString();

DetailLevel.Text = m_report.DetailLevel.ToString();

}

clip_image013

Here is a link to the sample application code:

Back