Object.defineProperty(obj, n, {value: v, writable: false});
}
+var ACCUMULATIVE_PEDOMETER_DATA = 'ACCUMULATIVE_PEDOMETER_DATA';
+
var HumanActivityType = {
PEDOMETER: 'PEDOMETER',
WRIST_UP: 'WRIST_UP',
function convertActivityData(type, data) {
switch (type) {
case HumanActivityType.PEDOMETER:
- // TODO(r.galka) Not Supported in current implementation
- return undefined;
+ return new HumanActivityPedometerData(data);
+ case ACCUMULATIVE_PEDOMETER_DATA:
+ return new HumanActivityAccumulativePedometerData(data);
case HumanActivityType.WRIST_UP:
return null;
case HumanActivityType.HRM:
native_.removeListener(listenerId);
}
+// Pedometer listener and accumulative pedometer listener are handled by a single
+// callback. Native side sends both objects, JS side needs to pass the data to
+// appropriate listeners.
+var pedometerListener = null;
+var accumulativePedometerListener = null;
+
+function pedometerCallback(result) {
+ if (pedometerListener) {
+ pedometerListener(convertActivityData(HumanActivityType.PEDOMETER, result));
+ }
+
+ if (accumulativePedometerListener) {
+ accumulativePedometerListener(convertActivityData(ACCUMULATIVE_PEDOMETER_DATA, result));
+ }
+}
+
HumanActivityMonitorManager.prototype.start = function(type, changedCallback) {
var args = validator_.validateArgs(arguments, [
{name: 'type', type: types_.ENUM, values: Object.keys(HumanActivityType)},
break;
}
+ var listener = HumanActivityType.PEDOMETER === args.type ? pedometerCallback : function(result) {
+ native_.callIfPossible(args.changedCallback, convertActivityData(args.type, result));
+ };
+
console.log("callbackInterval = " + callbackInterval + ", sampleInterval = " + sampleInterval);
startListener(listenerId,
- function(result) {
- native_.callIfPossible(args.changedCallback, convertActivityData(args.type, result));
- },
+ listener,
'HumanActivityMonitorManager_start',
{ type: args.type,
listenerId: listenerId,
sampleInterval: sampleInterval
}
);
+
+ if (HumanActivityType.PEDOMETER === args.type) {
+ pedometerListener = args.changedCallback;
+ }
};
HumanActivityMonitorManager.prototype.stop = function(type) {
stopListener('HumanActivityMonitor_' + args.type,
'HumanActivityMonitorManager_stop',
{ type: args.type });
-};
-var accumulativePedometerListenerId = 'HumanActivityMonitor_AccumulativePedometerListener';
+ if (HumanActivityType.PEDOMETER === args.type) {
+ pedometerListener = null;
+ }
+};
-HumanActivityMonitorManager.prototype.setAccumulativePedometerListener = function(changeCallback) {
+HumanActivityMonitorManager.prototype.setAccumulativePedometerListener = function() {
var args = validator_.validateArgs(arguments, [
{name: 'changeCallback', type: types_.FUNCTION}
]);
- var listenerId = accumulativePedometerListenerId;
+ var oldPedometerListener = pedometerListener;
- startListener(listenerId,
- function(result) {
- args.changeCallback(convertActivityData(HumanActivityType.PEDOMETER, result));
- },
- 'HumanActivityMonitorManager_setAccumulativePedometerListener',
- { listenerId: listenerId });
+ // calling start() will overwrite pedometerListener, needs to be restored afterwards
+ this.start(HumanActivityType.PEDOMETER, args.changeCallback);
+
+ accumulativePedometerListener = args.changeCallback;
+ pedometerListener = oldPedometerListener;
};
HumanActivityMonitorManager.prototype.unsetAccumulativePedometerListener = function() {
- stopListener(accumulativePedometerListenerId,
- 'HumanActivityMonitorManager_unsetAccumulativePedometerListener',
- {});
+ var oldPedometerListener = pedometerListener;
+
+ // calling stop() will overwrite pedometerListener, needs to be restored afterwards
+ this.stop(HumanActivityType.PEDOMETER);
+
+ accumulativePedometerListener = null;
+ pedometerListener = oldPedometerListener;
};
activityRecognitionListener.removeListener(args.watchId);
};
-function StepDifference() {
- SetReadOnlyProperty(this, 'stepCountDifference', null);
- SetReadOnlyProperty(this, 'timestamp', null);
+function StepDifference(data) {
+ SetReadOnlyProperty(this, 'stepCountDifference', data.stepCountDifference);
+ SetReadOnlyProperty(this, 'timestamp', data.timestamp);
}
}
-function HumanActivityPedometerData() {
- SetReadOnlyProperty(this, 'stepStatus', null);
- SetReadOnlyProperty(this, 'speed', null);
- SetReadOnlyProperty(this, 'walkingFrequency', null);
- SetReadOnlyProperty(this, 'cumulativeDistance', null);
- SetReadOnlyProperty(this, 'cumulativeCalorie', null);
- SetReadOnlyProperty(this, 'cumulativeTotalStepCount', null);
- SetReadOnlyProperty(this, 'cumulativeWalkStepCount', null);
- SetReadOnlyProperty(this, 'cumulativeRunStepCount', null);
- SetReadOnlyProperty(this, 'stepCountDifferences', null);
+function HumanActivityPedometerData(data) {
+ SetReadOnlyProperty(this, 'stepStatus', data.stepStatus);
+ SetReadOnlyProperty(this, 'speed', data.speed);
+ SetReadOnlyProperty(this, 'walkingFrequency', data.walkingFrequency);
+ SetReadOnlyProperty(this, 'cumulativeDistance', data.cumulativeDistance);
+ SetReadOnlyProperty(this, 'cumulativeCalorie', data.cumulativeCalorie);
+ SetReadOnlyProperty(this, 'cumulativeTotalStepCount', data.cumulativeTotalStepCount);
+ SetReadOnlyProperty(this, 'cumulativeWalkStepCount', data.cumulativeWalkStepCount);
+ SetReadOnlyProperty(this, 'cumulativeRunStepCount', data.cumulativeRunStepCount);
+
+ var steps = [];
+ for (var i = 0; i < data.stepCountDifferences.length; ++i) {
+ steps.push(new StepDifference(data.stepCountDifferences[i]));
+ }
+ SetReadOnlyProperty(this, 'stepCountDifferences', steps);
}
HumanActivityPedometerData.prototype = new HumanActivityData();
HumanActivityPedometerData.prototype.constructor = HumanActivityPedometerData;
-function HumanActivityAccumulativePedometerData() {
- SetReadOnlyProperty(this, 'stepStatus', null);
- SetReadOnlyProperty(this, 'speed', null);
- SetReadOnlyProperty(this, 'walkingFrequency', null);
- SetReadOnlyProperty(this, 'accumulativeDistance', null);
- SetReadOnlyProperty(this, 'accumulativeCalorie', null);
- SetReadOnlyProperty(this, 'accumulativeTotalStepCount', null);
- SetReadOnlyProperty(this, 'accumulativeWalkStepCount', null);
- SetReadOnlyProperty(this, 'accumulativeRunStepCount', null);
- SetReadOnlyProperty(this, 'stepCountDifferences', null);
+function HumanActivityAccumulativePedometerData(data) {
+ SetReadOnlyProperty(this, 'stepStatus', data.stepStatus);
+ SetReadOnlyProperty(this, 'speed', data.speed);
+ SetReadOnlyProperty(this, 'walkingFrequency', data.walkingFrequency);
+ SetReadOnlyProperty(this, 'accumulativeDistance', data.accumulativeDistance);
+ SetReadOnlyProperty(this, 'accumulativeCalorie', data.accumulativeCalorie);
+ SetReadOnlyProperty(this, 'accumulativeTotalStepCount', data.accumulativeTotalStepCount);
+ SetReadOnlyProperty(this, 'accumulativeWalkStepCount', data.accumulativeWalkStepCount);
+ SetReadOnlyProperty(this, 'accumulativeRunStepCount', data.accumulativeRunStepCount);
+
+ var steps = [];
+ for (var i = 0; i < data.stepCountDifferences.length; ++i) {
+ steps.push(new StepDifference(data.stepCountDifferences[i]));
+ }
+ SetReadOnlyProperty(this, 'stepCountDifferences', steps);
}
HumanActivityAccumulativePedometerData.prototype = new HumanActivityData();
#include <gesture_recognition.h>
#include <location_batch.h>
#include <sensor.h>
+#include <sensor_internal.h>
#include "common/logger.h"
#include "common/optional.h"
const std::string kStatus = "status";
const std::string kTimestamp = "timestamp";
+const std::string kStepStatus = "stepStatus";
+const std::string kSpeed = "speed";
+const std::string kWalkingFrequency = "walkingFrequency";
+const std::string kCumulativeDistance = "cumulativeDistance";
+const std::string kCumulativeCalorie = "cumulativeCalorie";
+const std::string kCumulativeTotalStepCount = "cumulativeTotalStepCount";
+const std::string kCumulativeWalkStepCount = "cumulativeWalkStepCount";
+const std::string kCumulativeRunStepCount = "cumulativeRunStepCount";
+const std::string kStepCountDifferences = "stepCountDifferences";
+const std::string kStepCountDifference = "stepCountDifference";
+
+const std::string kAccumulativeDistance = "accumulativeDistance";
+const std::string kAccumulativeCalorie = "accumulativeCalorie";
+const std::string kAccumulativeTotalStepCount = "accumulativeTotalStepCount";
+const std::string kAccumulativeWalkStepCount = "accumulativeWalkStepCount";
+const std::string kAccumulativeRunStepCount = "accumulativeRunStepCount";
+
+// helper structure, allows easier access to data values
+struct PedometerDataWrapper : public sensor_pedometer_data_t {
+ inline float steps() const {
+ return values[0];
+ }
+
+ inline float walk_steps() const {
+ return values[1];
+ }
+
+ inline float run_steps() const {
+ return values[2];
+ }
+
+ inline float distance() const {
+ return values[3];
+ }
+
+ inline float calories() const {
+ return values[4];
+ }
+
+ inline float speed() const {
+ return values[5];
+ }
+
+ inline float frequency() const {
+ return values[6];
+ }
+
+ inline sensor_pedometer_state_e state() const {
+ return static_cast<sensor_pedometer_state_e>(values[7]);
+ }
+};
+
+void InsertStepDifference(float step_difference, float timestamp, picojson::array* out) {
+ ScopeLogger();
+
+ picojson::object d;
+
+ d.insert(std::make_pair(kStepCountDifference, picojson::value(step_difference)));
+ d.insert(std::make_pair(kTimestamp, picojson::value(timestamp)));
+
+ out->push_back(picojson::value{d});
+}
+
+std::string FromSensorPedometerState(sensor_pedometer_state_e e) {
+ switch (e) {
+ case SENSOR_PEDOMETER_STATE_STOP:
+ return "NOT_MOVING";
+
+ case SENSOR_PEDOMETER_STATE_WALK:
+ return "WALKING";
+
+ case SENSOR_PEDOMETER_STATE_RUN:
+ return "RUNNING";
+
+ default:
+ return "UNKNOWN";
+ }
+}
+
} // namespace
const std::string kActivityTypeGps = "GPS";
: activity_recognition_(std::make_shared<ActivityRecognition>()) {
ScopeLogger();
+ auto convert_pedometer = [](sensor_event_s* event, picojson::object* data) -> PlatformResult {
+ ScopeLogger("convert_pedometer");
+
+ const auto pedometer_data = (PedometerDataWrapper*)event;
+
+ static const auto initial_pedometer_data = *pedometer_data; // will be initialized only once
+ static float steps_so_far = 0.0;
+
+ const auto state = pedometer_data->state();
+
+ if (SENSOR_PEDOMETER_STATE_UNKNOWN == state) {
+ return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Unknown sensor step state");
+ }
+
+ data->insert(std::make_pair(kStepStatus, picojson::value(FromSensorPedometerState(state))));
+ data->insert(std::make_pair(kSpeed, picojson::value(pedometer_data->speed())));
+ data->insert(std::make_pair(kWalkingFrequency, picojson::value(pedometer_data->frequency())));
+
+ data->insert(std::make_pair(kCumulativeDistance, picojson::value(pedometer_data->distance() - initial_pedometer_data.distance())));
+ data->insert(std::make_pair(kCumulativeCalorie, picojson::value(pedometer_data->calories() - initial_pedometer_data.calories())));
+ data->insert(std::make_pair(kCumulativeTotalStepCount, picojson::value(pedometer_data->steps() - initial_pedometer_data.steps())));
+ data->insert(std::make_pair(kCumulativeWalkStepCount, picojson::value(pedometer_data->walk_steps() - initial_pedometer_data.walk_steps())));
+ data->insert(std::make_pair(kCumulativeRunStepCount, picojson::value(pedometer_data->run_steps() - initial_pedometer_data.run_steps())));
+
+ data->insert(std::make_pair(kAccumulativeDistance, picojson::value(pedometer_data->distance())));
+ data->insert(std::make_pair(kAccumulativeCalorie, picojson::value(pedometer_data->calories())));
+ data->insert(std::make_pair(kAccumulativeTotalStepCount, picojson::value(pedometer_data->steps())));
+ data->insert(std::make_pair(kAccumulativeWalkStepCount, picojson::value(pedometer_data->walk_steps())));
+ data->insert(std::make_pair(kAccumulativeRunStepCount, picojson::value(pedometer_data->run_steps())));
+
+ auto& diffs = data->insert(std::make_pair(kStepCountDifferences, picojson::value{picojson::array{}})).first->second.get<picojson::array>();
+
+ if (pedometer_data->diffs_count > 0) {
+ for (int i = 0; i < pedometer_data->diffs_count; ++i) {
+ InsertStepDifference(pedometer_data->diffs[i].steps, pedometer_data->diffs[i].timestamp, &diffs);
+ }
+ } else {
+ InsertStepDifference(steps_so_far > 0.0 ? pedometer_data->steps() - steps_so_far : 0.0, pedometer_data->timestamp, &diffs);
+ }
+
+ steps_so_far = pedometer_data->steps();
+
+ return PlatformResult(ErrorCode::NO_ERROR);
+ };
+
auto convert_hrm = [](sensor_event_s* event, picojson::object* data) -> PlatformResult {
ScopeLogger("convert_hrm");
return PlatformResult(ErrorCode::NO_ERROR);
};
- monitors_.insert(std::make_pair(kActivityTypePedometer, std::make_shared<Monitor>(kActivityTypePedometer))); // not supported
+ monitors_.insert(std::make_pair(kActivityTypePedometer, std::make_shared<Monitor::SensorMonitor>(kActivityTypePedometer, SENSOR_HUMAN_PEDOMETER, convert_pedometer)));
monitors_.insert(std::make_pair(kActivityTypeWristUp, std::make_shared<Monitor::GestureMonitor>(kActivityTypeWristUp)));
monitors_.insert(std::make_pair(kActivityTypeHrm, std::make_shared<Monitor::SensorMonitor>(kActivityTypeHrm, SENSOR_HRM, convert_hrm)));
monitors_.insert(std::make_pair(kActivityTypeGps, std::make_shared<Monitor::GpsMonitor>(kActivityTypeGps)));