rename modules
[apps/native/st-things-co2-meter.git] / src / co2.c
1 /*
2  * Copyright (c) 2017 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Flora License, Version 1.1 (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://floralicense.org/license/
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 <co2-sensor.h>
18 #include <tizen.h>
19 #include <service_app.h>
20 #include <stdio.h>
21 #include <string.h>
22 #include <stdlib.h>
23 #include <pthread.h>
24 #include <Ecore.h>
25
26 #include "st_things.h"
27 #include "log.h"
28 #include "sensor-data.h"
29 #include "co2-sensor.h"
30
31 //#define TEST_RANDOM_VAL_GEN
32
33 #ifdef TEST_RANDOM_VAL_GEN
34 #include <time.h>
35 #include <stdlib.h>
36 #define RAND_VAL_MIN 0
37 #define RAND_VAL_MAX_CO2 1023
38 #endif /* TEST_RANDOM_VAL_GEN */
39
40 #define JSON_PATH "device_def.json"
41 #define SENSOR_URI_CO2 "/capability/airQualitySensor/main/0"
42 #define SENSOR_KEY_CO2 "airQuality"
43 #define SENSOR_KEY_RANGE "range"
44
45 #define SENSOR_CH_CO2 (0)
46 #define SENSOR_THRESHOLD_CO2 (650)
47
48 #define SENSOR_GATHER_INTERVAL (0.05f)
49 #define SENSOR_GATHER_COUNT (5)
50
51 //#define USE_ST_SDK
52
53 typedef struct app_data_s {
54         Ecore_Timer *getter_co2;
55         sensor_data *co2_data;
56 } app_data;
57
58 static app_data *g_ad = NULL;
59
60 #ifdef TEST_RANDOM_VAL_GEN
61 static int rand_read_co2_sensor(unsigned int *out_value)
62 {
63         unsigned int val = 0;
64
65         val = RAND_VAL_MIN + rand() / (RAND_MAX / (RAND_VAL_MAX_CO2 - RAND_VAL_MIN + 1) + 1);
66         *out_value = val;
67
68         return 0;
69 }
70 #endif
71
72 static int read_co2_sensor(unsigned int *out_value)
73 {
74         int ret = 0;
75         retv_if(!out_value, -1);
76
77 #ifdef TEST_RANDOM_VAL_GEN
78         ret = rand_read_co2_sensor(out_value);
79 #else /* TEST_RANDOM_VAL_GEN */
80         ret = co2_sensor_read(SENSOR_CH_CO2, out_value);
81 #endif /* TEST_RANDOM_VAL_GEN */
82
83         return ret;
84 }
85
86 static Eina_Bool __get_co2(void *data)
87 {
88         int ret = 0;
89         unsigned int value = 0;
90         static unsigned int sum = 0;
91         static unsigned int count = 0;
92
93         app_data *ad = data;
94
95         if (!ad) {
96                 _E("failed to get app_data");
97                 service_app_exit();
98         }
99
100         if (!ad->co2_data) {
101                 _E("failed to get co2_data");
102                 service_app_exit();
103         }
104
105         ret = read_co2_sensor(&value);
106         retv_if(ret != 0, ECORE_CALLBACK_RENEW);
107
108         count++;
109         sum += value;
110
111         if (count == SENSOR_GATHER_COUNT) {
112                 unsigned int avg = 0;
113                 avg = sum/SENSOR_GATHER_COUNT;
114
115                 _D("co2 avg value - %u", avg);
116
117                 sensor_data_set_uint(ad->co2_data, avg);
118
119                 if (avg <= SENSOR_THRESHOLD_CO2) {
120         #ifdef USE_ST_SDK
121                         st_things_notify_observers(SENSOR_URI_CO2);
122         #endif
123                 }
124
125                 count = 0;
126                 sum = 0;
127         }
128
129         return ECORE_CALLBACK_RENEW;
130 }
131
132 void gathering_start(void *data)
133 {
134         app_data *ad = data;
135         ret_if(!ad);
136
137         if (ad->getter_co2)
138                 ecore_timer_del(ad->getter_co2);
139
140         ad->getter_co2 = ecore_timer_add(SENSOR_GATHER_INTERVAL, __get_co2, ad);
141         if (!ad->getter_co2)
142                 _E("Failed to add getter_co2");
143
144         return;
145 }
146
147 #ifdef USE_ST_SDK
148 static bool handle_reset_request(void)
149 {
150         _D("Received a request for RESET.");
151         return false;
152 }
153
154 static void handle_reset_result(bool result)
155 {
156         _D("Reset %s.\n", result ? "succeeded" : "failed");
157 }
158
159 static bool handle_ownership_transfer_request(void)
160 {
161         _D("Received a request for Ownership-transfer.");
162         return true;
163 }
164
165 static void handle_things_status_change(st_things_status_e things_status)
166 {
167         _D("Things status is changed: %d\n", things_status);
168
169         if (things_status == ST_THINGS_STATUS_REGISTERED_TO_CLOUD)
170                 ecore_main_loop_thread_safe_call_async(gathering_start, g_ad);
171 }
172
173 static bool handle_get_request(st_things_get_request_message_s* req_msg, st_things_representation_s* resp_rep)
174 {
175         _D("resource_uri [%s]", req_msg->resource_uri);
176         retv_if(!g_ad, false);
177
178         if (0 == strcmp(req_msg->resource_uri, SENSOR_URI_CO2)) {
179                 if (req_msg->has_property_key(req_msg, SENSOR_KEY_CO2)) {
180                         unsigned int value = 0;
181                         sensor_data_get_uint(g_ad->co2_data, &value);
182                         resp_rep->set_int_value(resp_rep, SENSOR_KEY_CO2, value);
183                 }
184                 if (req_msg->has_property_key(req_msg, SENSOR_KEY_RANGE)) {
185                         const double range[2] = { 0.0, 1024.0 };
186                         resp_rep->set_double_array_value(resp_rep, SENSOR_KEY_RANGE, range, 2);
187                 }
188                 return true;
189         }
190         _E("not supported uri");
191         return false;
192 }
193
194 static bool handle_set_request(st_things_set_request_message_s* req_msg, st_things_representation_s* resp_rep)
195 {
196         _D("resource_uri [%s]", req_msg->resource_uri);
197     return false;
198 }
199
200 static int __things_init(void)
201 {
202         bool easysetup_complete = false;
203         char app_json_path[128] = {'\0', };
204         char *app_res_path = NULL;
205         char *app_data_path = NULL;
206
207         app_res_path = app_get_resource_path();
208         if (!app_res_path) {
209                 _E("app_res_path is NULL!!");
210                 return -1;
211         }
212
213         app_data_path = app_get_data_path();
214         if (!app_data_path) {
215                 _E("app_data_path is NULL!!");
216                 free(app_res_path);
217                 return -1;
218         }
219
220         snprintf(app_json_path, sizeof(app_json_path), "%s%s", app_res_path, JSON_PATH);
221
222         if (0 != st_things_set_configuration_prefix_path(app_res_path, app_data_path)) {
223                 _E("st_things_set_configuration_prefix_path() failed!!");
224                 free(app_res_path);
225                 free(app_data_path);
226                 return -1;
227         }
228
229         free(app_res_path);
230         free(app_data_path);
231
232         if (0 != st_things_initialize(app_json_path, &easysetup_complete)) {
233                 _E("st_things_initialize() failed!!");
234                 return -1;
235         }
236
237         _D("easysetup_complete:[%d] ", easysetup_complete);
238
239         st_things_register_request_cb(handle_get_request, handle_set_request);
240         st_things_register_reset_cb(handle_reset_request, handle_reset_result);
241         st_things_register_user_confirm_cb(handle_ownership_transfer_request);
242         st_things_register_things_status_change_cb(handle_things_status_change);
243
244         return 0;
245 }
246
247 static int __things_deinit(void)
248 {
249         st_things_deinitialize();
250         return 0;
251 }
252
253 static int __things_start(void)
254 {
255         st_things_start();
256         return 0;
257 }
258
259 static int __things_stop(void)
260 {
261         st_things_stop();
262         return 0;
263 }
264 #endif /* USE_ST_SDK */
265
266 static bool service_app_create(void *user_data)
267 {
268         app_data *ad = (app_data *)user_data;
269
270         ad->co2_data = sensor_data_new(SENSOR_DATA_TYPE_UINT);
271         if (!ad->co2_data)
272                 return false;
273
274 #ifdef USE_ST_SDK
275         if (__things_init())
276                 return false;
277 #endif
278
279         return true;
280 }
281
282 static void service_app_control(app_control_h app_control, void *user_data)
283 {
284 #ifdef USE_ST_SDK
285         __things_start();
286 #else
287         gathering_start(user_data);
288 #endif
289 }
290
291 static void service_app_terminate(void *user_data)
292 {
293         app_data *ad = (app_data *)user_data;
294
295         if (ad->getter_co2)
296                 ecore_timer_del(ad->getter_co2);
297
298 #ifdef USE_ST_SDK
299         __things_stop();
300         __things_deinit();
301 #endif
302
303         sensor_data_free(ad->co2_data);
304         co2_sensor_close();
305         free(ad);
306
307         FN_END;
308 }
309
310 int main(int argc, char *argv[])
311 {
312         app_data *ad = NULL;
313         service_app_lifecycle_callback_s event_callback;
314
315         ad = calloc(1, sizeof(app_data));
316         retv_if(!ad, -1);
317
318         g_ad = ad;
319
320         event_callback.create = service_app_create;
321         event_callback.terminate = service_app_terminate;
322         event_callback.app_control = service_app_control;
323
324         return service_app_main(argc, argv, &event_callback, ad);
325 }