sensor: reorganize the folder structure
[platform/core/context/context-provider.git] / src / sensor / pedometer / PedometerLogger.cpp
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <sqlite3.h>
18 #include <SensorRecorderTypes.h>
19 #include "../TypesInternal.h"
20 #include "../ClientInfo.h"
21 #include "PedometerLogger.h"
22
23 using namespace ctx;
24
25 PedometerLogger::PedometerLogger() :
26         __firstEvent(true)
27 {
28         setSensor(HUMAN_PEDOMETER_SENSOR);
29         setPowerSave(false);
30
31         /* Create the log table */
32         executeQuery(
33                         "CREATE TABLE IF NOT EXISTS " PEDOMETER_RECORD " (" \
34                                 KEY_START_TIME " INTEGER NOT NULL, " \
35                                 KEY_END_TIME " INTEGER NOT NULL PRIMARY KEY, " \
36                                 KEY_WALK_STEPS " INTEGER NOT NULL, " \
37                                 KEY_RUN_STEPS " INTEGER NOT NULL, " \
38                                 KEY_DISTANCE " REAL NOT NULL, " \
39                                 KEY_CALORIES " REAL NOT NULL" \
40                         ")");
41
42         ClientInfo clientInfo;
43         if (clientInfo.exist(SUBJ_SENSOR_PEDOMETER))
44                 start();
45 }
46
47 PedometerLogger::~PedometerLogger()
48 {
49 }
50
51 bool PedometerLogger::start()
52 {
53         if (SensorProxy::isRunning())
54                 return true;
55
56         _I(GREEN("Start to record"));
57
58         if (SensorProxy::start()) {
59                 flush();
60                 return true;
61         }
62
63         return false;
64 }
65
66 void PedometerLogger::stop()
67 {
68         _I(GREEN("Stop recording"));
69
70         SensorProxy::stop();
71         __firstEvent = true;
72 }
73
74 void PedometerLogger::onEvent(sensor_data_t *eventData)
75 {
76         sensor_pedometer_data_t *pedometerData = reinterpret_cast<sensor_pedometer_data_t*>(eventData);
77         uint64_t timestamp = getTime();
78
79         if (__firstEvent) {
80                 _D("Baseline event");
81                 __firstEvent = false;
82         } else if (pedometerData->diffs_count == 0) {
83                 _D("Single event");
84                 __recordSingle(pedometerData, timestamp);
85         } else {
86                 _D("Batch event");
87                 __recordBatch(pedometerData, timestamp);
88         }
89
90         __baseline.timestamp = timestamp;
91         __baseline.walkSteps = eventData->values[1];
92         __baseline.runSteps  = eventData->values[2];
93         __baseline.distance  = eventData->values[3];
94         __baseline.calories  = eventData->values[4];
95
96         _D("Baseline: %u, %u, %.3f, %.3f",
97                         __baseline.walkSteps, __baseline.runSteps, __baseline.distance, __baseline.calories);
98
99         removeExpired(SUBJ_SENSOR_PEDOMETER, PEDOMETER_RECORD, KEY_END_TIME);
100 }
101
102 void PedometerLogger::__recordSingle(sensor_pedometer_data_t *eventData, uint64_t timestamp)
103 {
104         DataRecord record;
105         record.walkSteps = static_cast<unsigned int>(eventData->values[1]) - __baseline.walkSteps;
106         record.runSteps  = static_cast<unsigned int>(eventData->values[2]) - __baseline.runSteps;
107         record.distance  = eventData->values[3] - __baseline.distance;
108         record.calories  = eventData->values[4] - __baseline.calories;
109
110         IF_FAIL_VOID_TAG(record.walkSteps + record.runSteps > 0, _D, "Skipping zero-count event");
111
112         char *query = sqlite3_mprintf(
113                         "INSERT INTO " PEDOMETER_RECORD "(" \
114                                 KEY_START_TIME ", " \
115                                 KEY_END_TIME ", " \
116                                 KEY_WALK_STEPS ", " \
117                                 KEY_RUN_STEPS ", " \
118                                 KEY_DISTANCE ", " \
119                                 KEY_CALORIES ") " \
120                                 "VALUES (%llu, %llu, %u, %u, %.3f, %.3f)",
121                         __baseline.timestamp, timestamp, record.walkSteps, record.runSteps, record.distance, record.calories);
122         executeQuery(query);
123         sqlite3_free(query);
124 }
125
126 void PedometerLogger::__recordBatch(sensor_pedometer_data_t *eventData, uint64_t timestamp)
127 {
128         std::string query("INSERT INTO " PEDOMETER_RECORD "(" \
129                                 KEY_START_TIME ", " \
130                                 KEY_END_TIME ", " \
131                                 KEY_WALK_STEPS ", " \
132                                 KEY_RUN_STEPS ", " \
133                                 KEY_DISTANCE ", " \
134                                 KEY_CALORIES ") VALUES ");
135         char buffer[256];
136
137         for (int i = 0; i < eventData->diffs_count; ++i) {
138                 if (eventData->diffs[i].walk_steps + eventData->diffs[i].run_steps == 0) {
139                         _D("Skipping zero-count event");
140                         continue;
141                 }
142
143                 /* TODO: check the timestamps.. they look strange.. */
144                 g_snprintf(buffer, sizeof(buffer), "(%llu, %llu, %d, %d, %.3f, %.3f),",
145                                 i == 0 ? __baseline.timestamp : SEC_TO_MS(static_cast<uint64_t>(eventData->diffs[i-1].timestamp)),
146                                 SEC_TO_MS(static_cast<uint64_t>(eventData->diffs[i].timestamp)),
147                                 eventData->diffs[i].walk_steps,
148                                 eventData->diffs[i].run_steps,
149                                 eventData->diffs[i].distance,
150                                 eventData->diffs[i].calories);
151                 query += buffer;
152         }
153
154         query.resize(query.size() - 1);
155         IF_FAIL_VOID_TAG(query.at(query.size() - 1) == ')', _D, "No records");
156
157         executeQuery(query.c_str());
158 }