Sensor Scol plugin
Multi platform sensors for handled devices
SWSensor.cpp
1#ifdef _WIN32
2
3#include <windows.h>
4#include <initguid.h>
5#include <propkeydef.h>
6#include "Sensors.h"
7#include "Sensorsapi.h"
8
9#include <chrono>
10#include "SSensor.h"
11#include "SWSensor.h"
12
13 /* * * * * * * * * * * * * SENSOR * * * * * * * * * * * * */
14
15SSensorManager* SWSensorManager::mSingletonInstance;
16
17SWSensor::SWSensor() : SSensor()
18{
19 mISensor = NULL;
20}
21
22SWSensor::SWSensor(SSensorType type) : SSensor(type)
23{
24 mISensor = NULL;
25}
26
27SWSensor::~SWSensor()
28{
29 SAFE_RELEASE(mISensor);
30}
31
32SSensorData SWSensor::GetData()
33{
34 SSensorData sensorData;
35 memset(&sensorData, 0, sizeof(sensorData));
36
37 if (mEnabled && mISensor)
38 {
39 SENSOR_TYPE_ID iSensorType;
40 mISensor->GetType(&iSensorType);
41 if (IsEqualGUID(iSensorType, SENSOR_TYPE_ACCELEROMETER_3D))
42 {
43 // GET DATA
44 ISensorDataReport* sensorReport(NULL);
45 HRESULT hr = S_OK;
46 hr = mISensor->GetData(&sensorReport);
47 if (!SUCCEEDED(hr))
48 {
49 // TODO: ERROR! NO DATA AVAILABLE
50 }
51 PROPVARIANT x, y, z, tm;
52 hr = sensorReport->GetSensorValue(SENSOR_DATA_TYPE_TIMESTAMP, &tm);
53 hr = hr && sensorReport->GetSensorValue(SENSOR_DATA_TYPE_ACCELERATION_X_G, &x);
54 hr = hr && sensorReport->GetSensorValue(SENSOR_DATA_TYPE_ACCELERATION_Y_G, &y);
55 hr = hr && sensorReport->GetSensorValue(SENSOR_DATA_TYPE_ACCELERATION_Z_G, &z);
56 if (!SUCCEEDED(hr))
57 {
58 // TODO: ERROR! NO DATA AVAILABLE
59 }
60
61 sensorData.delta = GetElapsedTime(std::chrono::duration<int64_t, std::nano>(std::chrono::system_clock::now().time_since_epoch()).count()); //tm.filetime
62 sensorData.vec3 = Vector3d(x.dblVal, y.dblVal, z.dblVal);
63 CallSensorCb(sensorData);
64 }
65 else if (IsEqualGUID(iSensorType, SENSOR_TYPE_COMPASS_3D))
66 {
67 // GET DATA
68 ISensorDataReport* sensorReport(NULL);
69 HRESULT hr = S_OK;
70 hr = mISensor->GetData(&sensorReport);
71 if (!SUCCEEDED(hr))
72 {
73 // TODO: ERROR! NO DATA AVAILABLE
74 }
75 PROPVARIANT x, y, z, tm;
76 hr = sensorReport->GetSensorValue(SENSOR_DATA_TYPE_TIMESTAMP, &tm);
77 hr = hr && sensorReport->GetSensorValue(SENSOR_DATA_TYPE_MAGNETIC_HEADING_X_DEGREES, &x);
78 hr = hr && sensorReport->GetSensorValue(SENSOR_DATA_TYPE_MAGNETIC_HEADING_Y_DEGREES, &y);
79 hr = hr && sensorReport->GetSensorValue(SENSOR_DATA_TYPE_MAGNETIC_HEADING_Z_DEGREES, &z);
80 if (!SUCCEEDED(hr))
81 {
82 // TODO: ERROR! NO DATA AVAILABLE
83 }
84
85 sensorData.delta = GetElapsedTime(std::chrono::duration<int64_t, std::nano>(std::chrono::system_clock::now().time_since_epoch()).count()); //tm.filetime
86 sensorData.vec3 = Vector3d(x.dblVal, y.dblVal, z.dblVal);
87 CallSensorCb(sensorData);
88 }
89 else if (IsEqualGUID(iSensorType, SENSOR_TYPE_GYROMETER_3D))
90 {
91 // GET DATA
92 ISensorDataReport* sensorReport(NULL);
93 HRESULT hr = S_OK;
94 hr = mISensor->GetData(&sensorReport);
95 if (!SUCCEEDED(hr))
96 {
97 // TODO: ERROR! NO DATA AVAILABLE
98 }
99 PROPVARIANT x, y, z, tm;
100 hr = sensorReport->GetSensorValue(SENSOR_DATA_TYPE_TIMESTAMP, &tm);
101 hr = hr && sensorReport->GetSensorValue(SENSOR_DATA_TYPE_ANGULAR_ACCELERATION_X_DEGREES_PER_SECOND_SQUARED, &x);
102 hr = hr && sensorReport->GetSensorValue(SENSOR_DATA_TYPE_ANGULAR_ACCELERATION_Y_DEGREES_PER_SECOND_SQUARED, &y);
103 hr = hr && sensorReport->GetSensorValue(SENSOR_DATA_TYPE_ANGULAR_ACCELERATION_Z_DEGREES_PER_SECOND_SQUARED, &z);
104 if (!SUCCEEDED(hr))
105 {
106 // TODO: ERROR! NO DATA AVAILABLE
107 }
108
109 sensorData.delta = GetElapsedTime(std::chrono::duration<int64_t, std::nano>(std::chrono::system_clock::now().time_since_epoch()).count()); //tm.filetime
110 sensorData.vec3 = Vector3d(x.dblVal, y.dblVal, z.dblVal);
111 CallSensorCb(sensorData);
112 }
113 else if (IsEqualGUID(iSensorType, SENSOR_TYPE_AMBIENT_LIGHT))
114 {
115 // GET DATA
116 ISensorDataReport* sensorReport(NULL);
117 HRESULT hr = S_OK;
118 hr = mISensor->GetData(&sensorReport);
119 if (!SUCCEEDED(hr))
120 {
121 // TODO: ERROR! NO DATA AVAILABLE
122 }
123 PROPVARIANT l, tm;
124 hr = sensorReport->GetSensorValue(SENSOR_DATA_TYPE_TIMESTAMP, &tm);
125 hr = hr && sensorReport->GetSensorValue(SENSOR_DATA_TYPE_LIGHT_LEVEL_LUX, &l);
126 if (!SUCCEEDED(hr))
127 {
128 // TODO: ERROR! NO DATA AVAILABLE
129 }
130
131 sensorData.delta = GetElapsedTime(std::chrono::duration<int64_t, std::nano>(std::chrono::system_clock::now().time_since_epoch()).count()); //tm.filetime
132 sensorData.fval = (float) l.dblVal;
133 CallSensorCb(sensorData);
134 }
135
136 // >>>>> ADD HERE NEW SENSOR TYPES TO BE SUPPORTED <<<<<
137
138 else
139 {
140 // TODO ERROR: INVALID SENSOR TYPE
141 }
142 }
143
144 return sensorData;
145}
146
147void SWSensor::SetISensor(ISensor* isensor)
148{
149 mISensor = isensor;
150}
151
152ISensor* SWSensor::GetISensor()
153{
154 return mISensor;
155}
156
157 /* * * * * * * * * * * * * SENSOR MANAGER * * * * * * * * * * * * */
158
159SWSensorManager::SWSensorManager() : SSensorManager()
160{
161 CoInitialize(NULL);
162
163 // ISensorManager creation
164 HRESULT hr = CoCreateInstance(CLSID_SensorManager,
165 NULL, CLSCTX_INPROC_SERVER, // is agregate? | context in which launch the code
166 IID_ISensorManager, (void**)&mISensorManager);
167 if (hr == S_OK)
168 {
169 // Making list of available ISensors
170 ISensorCollection * sensorList;
171 hr = mISensorManager->GetSensorsByCategory(SENSOR_CATEGORY_ALL, &sensorList);
172 if (hr == S_OK)
173 {
174 ULONG sensorCount(0);
175 sensorList->GetCount(&sensorCount);
176 MMechostr(MSKDEBUG, "SWSensorManager() : %d sensors has been found", sensorCount);
177
178 // Setting sensor list for scol
179 for (unsigned int i = 0; i < sensorCount; i++)
180 {
181 ISensor* wsensor;
182 hr = sensorList->GetAt(i, &wsensor);
183 if (hr == S_OK)
184 {
185 SENSOR_TYPE_ID iSensorType;
186 wsensor->GetType(&iSensorType);
187
188 if (IsEqualGUID(iSensorType, SENSOR_TYPE_ACCELEROMETER_3D))
189 {
190 MMechostr(MSKDEBUG, "SWSensorManager() : an accelerometer has been found (%d)", i);
191 SWSensor* sensor = new SWSensor(SSENSOR_TYPE_ACCELEROMETER);
192 sensor->SetISensor(wsensor);
193 mSensorList.insert(sensor);
194 SetSensorDelay(sensor, 10); // 100Hz in ms
195 }
196 else if (IsEqualGUID(iSensorType, SENSOR_TYPE_COMPASS_3D))
197 {
198 MMechostr(MSKDEBUG, "SWSensorManager() : an magnetometer has been found (%d)", i);
199 SWSensor* sensor = new SWSensor(SSENSOR_TYPE_MAGNETIC_FIELD);
200 sensor->SetISensor(wsensor);
201 mSensorList.insert(sensor);
202 SetSensorDelay(sensor, 10); // 100Hz in ms
203 }
204 else if (IsEqualGUID(iSensorType, SENSOR_TYPE_GYROMETER_3D))
205 {
206 MMechostr(MSKDEBUG, "SWSensorManager() : an gyrometer has been found (%d)", i);
207 SWSensor* sensor = new SWSensor(SSENSOR_TYPE_GYROSCOPE);
208 sensor->SetISensor(wsensor);
209 mSensorList.insert(sensor);
210 SetSensorDelay(sensor, 10); // 100Hz in ms
211 }
212 else if (IsEqualGUID(iSensorType, SENSOR_TYPE_AMBIENT_LIGHT))
213 {
214 MMechostr(MSKDEBUG, "SWSensorManager() : a light sensor has been found (%d)", i);
215 SWSensor* sensor = new SWSensor(SSENSOR_TYPE_LIGHT);
216 sensor->SetISensor(wsensor);
217 mSensorList.insert(sensor);
218 SetSensorDelay(sensor, 10); // 100Hz in ms
219 }
220
221 // >>>>> ADD HERE NEW SENSOR TYPES TO BE SUPPORTED <<<<<
222
223 else
224 {
225 // TODO ERROR: INVALID SENSOR TYPE
226 MMechostr(MSKDEBUG, "SSensorManager() : an unknown sensor has been found (%d)", i);
227 }
228 }
229 else
230 {
231 // TODO: ERROR ON ISENSOR ACCESS
232 }
233 }
234 SAFE_RELEASE(sensorList);
235 }
236 else
237 {
238 // TODO: ERROR ON SENSOR LIST
239 }
240 }
241 else
242 {
243 // TODO: ERROR ON ISENSOR MANAGER
244 }
245}
246
247SWSensorManager::~SWSensorManager()
248{
249 CoUninitialize();
250
251 for (std::set<SSensor*>::iterator it = mSensorList.begin(); it != mSensorList.end(); ++it)
252 {
253 SWSensor* sensor = (SWSensor*) (*it);
254 SAFE_DELETE(sensor);
255 }
256
257 mSingletonInstance = NULL;
258}
259
260int SWSensorManager::SetSensorDelay(SSensor* sensor, unsigned long millisecondsDelay)
261{
262 if (sensor)
263 {
264 ISensor* wsensor = ((SWSensor*)sensor)->GetISensor();
265
266 IPortableDeviceValues* propsToSet = NULL;
267 IPortableDeviceValues* propsReturn = NULL;
268
269 HRESULT hr = CoCreateInstance(__uuidof(PortableDeviceValues), NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&propsToSet));
270 if (SUCCEEDED(hr))
271 {
272 // Set new delay to set
273 hr = propsToSet->SetUnsignedIntegerValue(SENSOR_PROPERTY_CURRENT_REPORT_INTERVAL, millisecondsDelay);
274 if (SUCCEEDED(hr))
275 {
276 // Apply modification on sensor
277 hr = wsensor->SetProperties(propsToSet, &propsReturn);
278 if (hr == S_FALSE)
279 {
280 HRESULT hrError = S_OK;
281 hr = propsReturn->GetErrorValue(SENSOR_PROPERTY_CURRENT_REPORT_INTERVAL, &hrError);
282 if (SUCCEEDED(hr))
283 {
284 wprintf_s(L"\nSetting current report interval failed with error 0x%X\n", hrError);
285 hr = hrError;
286 }
287 }
288 else if (hr == E_ACCESSDENIED)
289 {
290 // No permission. Take appropriate action.
291 }
292 }
293 }
294
295 SAFE_RELEASE(propsToSet);
296 SAFE_RELEASE(propsReturn);
297
298 return hr;
299 }
300 else
301 {
302 // TODO: ERROR INVALID SENSOR
303 return -1;
304 }
305}
306
307int SWSensorManager::SetSensorEnable(SSensorType sensorType, bool state)
308{
309 if (IsAvailable(sensorType))
310 return 0;
311 else
312 // ERROR: THE SENSOR IS NOT AVAILABLE
313 return -1;
314}
315
316void SWSensorManager::Vibrate(long millis)
317{
318
319}
320
321void SWSensorManager::StartVibration()
322{
323
324}
325
326void SWSensorManager::StopVibration()
327{
328
329}
330
331void SWSensorManager::VibratePattern(std::vector<int> pattern, bool loop)
332{
333
334}
335
336void SWSensorManager::StartLocationService()
337{
338
339}
340
341void SWSensorManager::StopLocationService()
342{
343
344}
345
346bool SWSensorManager::GetLocation(float &longitude, float &latitude, float &altitude)
347{
348 return false;
349}
350
351#endif