update gitignore
[apps/native/st-things-co2-meter.git] / src / co2.c
1 /* ****************************************************************
2  *
3  * Copyright 2017 Samsung Electronics All Rights Reserved.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  ******************************************************************/
18
19 #include <tizen.h>
20 #include <service_app.h>
21 #include <string.h>
22 #include <stdlib.h>
23 #include <Ecore.h>
24
25 #include "st_things.h"
26 #include "log.h"
27 #include "sensor-data.h"
28 #include "co2-sensor.h"
29
30 #define JSON_NAME "device_def.json"
31 #define SENSOR_URI_CO2 "/capability/airQualitySensor/main/0"
32 #define SENSOR_KEY_CO2 "airQuality"
33 #define SENSOR_KEY_RANGE "range"
34
35 #define SENSOR_CH_CO2 (0)
36 #define SENSOR_GATHER_INTERVAL (0.05f)
37 #define SENSOR_GATHER_COUNT (60)
38
39 //#define USE_ST_SDK
40
41 typedef struct app_data_s {
42         Ecore_Timer *getter_co2;
43         sensor_data *co2_data;
44 } app_data;
45
46 static app_data *g_ad = NULL;
47
48 static Eina_Bool __get_co2(void *data)
49 {
50         int ret = 0;
51         unsigned int value = 0;
52         static unsigned int sum = 0;
53         static unsigned int count = 0;
54
55         app_data *ad = data;
56
57         if (!ad) {
58                 _E("failed to get app_data");
59                 service_app_exit();
60                 return ECORE_CALLBACK_CANCEL;
61         }
62
63         if (!ad->co2_data) {
64                 _E("failed to get co2_data");
65                 service_app_exit();
66                 ad->getter_co2 = NULL;
67                 return ECORE_CALLBACK_CANCEL;
68         }
69
70         ret = co2_sensor_read(SENSOR_CH_CO2, &value);
71         retv_if(ret != 0, ECORE_CALLBACK_RENEW);
72
73         count++;
74         sum += value;
75
76         if (count == SENSOR_GATHER_COUNT) {
77                 unsigned int avg = 0;
78                 avg = sum/SENSOR_GATHER_COUNT;
79
80                 _D("co2 avg - [%u], [%u ppm]", avg, co2_sensor_value_to_ppm(avg));
81
82                 sensor_data_set_uint(ad->co2_data, avg);
83
84 #ifdef USE_ST_SDK
85                 st_things_notify_observers(SENSOR_URI_CO2);
86 #endif
87                 count = 0;
88                 sum = 0;
89         }
90
91         return ECORE_CALLBACK_RENEW;
92 }
93
94 static void gathering_stop(void *data)
95 {
96         app_data *ad = data;
97         ret_if(!ad);
98
99         if (ad->getter_co2) {
100                 ecore_timer_del(ad->getter_co2);
101                 ad->getter_co2 = NULL;
102         }
103 }
104
105 static void gathering_start(void *data)
106 {
107         app_data *ad = data;
108         ret_if(!ad);
109
110         ad->getter_co2 = ecore_timer_add(SENSOR_GATHER_INTERVAL, __get_co2, ad);
111         if (!ad->getter_co2)
112                 _E("Failed to add getter_co2");
113 }
114
115 #ifdef USE_ST_SDK
116 static bool handle_reset_request(void)
117 {
118         _D("Received a request for RESET.");
119         return false;
120 }
121
122 static void handle_reset_result(bool result)
123 {
124         _D("Reset %s.\n", result ? "succeeded" : "failed");
125 }
126
127 static bool handle_ownership_transfer_request(void)
128 {
129         _D("Received a request for Ownership-transfer.");
130         return true;
131 }
132
133 static void handle_things_status_change(st_things_status_e things_status)
134 {
135         _D("Things status is changed: %d\n", things_status);
136
137         if (things_status == ST_THINGS_STATUS_REGISTERED_TO_CLOUD)
138                 ecore_main_loop_thread_safe_call_async(gathering_start, g_ad);
139         else
140                 ecore_main_loop_thread_safe_call_async(gathering_stop, g_ad);
141 }
142
143 static bool handle_get_request(st_things_get_request_message_s* req_msg, st_things_representation_s* resp_rep)
144 {
145         _D("resource_uri [%s]", req_msg->resource_uri);
146         retv_if(!g_ad, false);
147
148         if (0 == strcmp(req_msg->resource_uri, SENSOR_URI_CO2)) {
149                 _D("query : %s, property: %s", req_msg->query, req_msg->property_key);
150
151                 if (req_msg->has_property_key(req_msg, SENSOR_KEY_CO2)) {
152                         unsigned int value = 0;
153                         sensor_data_get_uint(g_ad->co2_data, &value);
154                         resp_rep->set_int_value(resp_rep, SENSOR_KEY_CO2, value);
155                 }
156                 if (req_msg->has_property_key(req_msg, SENSOR_KEY_RANGE)) {
157                         const double range[2] = { 0.0, 1024.0 };
158                         resp_rep->set_double_array_value(resp_rep, SENSOR_KEY_RANGE, range, 2);
159                 }
160                 return true;
161         }
162         _E("not supported uri");
163         return false;
164 }
165
166 static bool handle_set_request(st_things_set_request_message_s* req_msg, st_things_representation_s* resp_rep)
167 {
168         _D("resource_uri [%s]", req_msg->resource_uri);
169         return false;
170 }
171
172 static int __things_init(void)
173 {
174         bool easysetup_complete = false;
175         char app_json_path[128] = {'\0', };
176         char *app_res_path = NULL;
177         char *app_data_path = NULL;
178
179         app_res_path = app_get_resource_path();
180         if (!app_res_path) {
181                 _E("app_res_path is NULL!!");
182                 return -1;
183         }
184
185         app_data_path = app_get_data_path();
186         if (!app_data_path) {
187                 _E("app_data_path is NULL!!");
188                 free(app_res_path);
189                 return -1;
190         }
191
192         if (0 != st_things_set_configuration_prefix_path(app_res_path, app_data_path)) {
193                 _E("st_things_set_configuration_prefix_path() failed!!");
194                 free(app_res_path);
195                 free(app_data_path);
196                 return -1;
197         }
198         free(app_data_path);
199
200         snprintf(app_json_path, sizeof(app_json_path), "%s%s", app_res_path, JSON_NAME);
201         free(app_res_path);
202
203         if (0 != st_things_initialize(app_json_path, &easysetup_complete)) {
204                 _E("st_things_initialize() failed!!");
205                 return -1;
206         }
207
208         _D("easysetup_complete:[%d] ", easysetup_complete);
209
210         st_things_register_request_cb(handle_get_request, handle_set_request);
211         st_things_register_reset_cb(handle_reset_request, handle_reset_result);
212         st_things_register_user_confirm_cb(handle_ownership_transfer_request);
213         st_things_register_things_status_change_cb(handle_things_status_change);
214
215         return 0;
216 }
217
218 static int __things_deinit(void)
219 {
220         st_things_deinitialize();
221         return 0;
222 }
223
224 static int __things_start(void)
225 {
226         st_things_start();
227         return 0;
228 }
229
230 static int __things_stop(void)
231 {
232         st_things_stop();
233         return 0;
234 }
235 #endif /* USE_ST_SDK */
236
237 static bool service_app_create(void *user_data)
238 {
239         app_data *ad = (app_data *)user_data;
240
241         ad->co2_data = sensor_data_new(SENSOR_DATA_TYPE_UINT);
242         if (!ad->co2_data)
243                 return false;
244
245 #ifdef USE_ST_SDK
246         if (__things_init())
247                 return false;
248 #endif
249
250         return true;
251 }
252
253 static void service_app_control(app_control_h app_control, void *user_data)
254 {
255 #ifdef USE_ST_SDK
256         __things_stop();
257         __things_start();
258 #else
259         gathering_stop(user_data);
260         gathering_start(user_data);
261 #endif
262 }
263
264 static void service_app_terminate(void *user_data)
265 {
266         app_data *ad = (app_data *)user_data;
267
268         if (!ad)
269                 return;
270
271 #ifdef USE_ST_SDK
272         __things_stop();
273         __things_deinit();
274 #endif
275
276         sensor_data_free(ad->co2_data);
277         co2_sensor_close();
278         free(ad);
279
280         FN_END;
281 }
282
283 int main(int argc, char *argv[])
284 {
285         app_data *ad = NULL;
286         service_app_lifecycle_callback_s event_callback;
287
288         ad = calloc(1, sizeof(app_data));
289         retv_if(!ad, -1);
290
291         g_ad = ad;
292
293         event_callback.create = service_app_create;
294         event_callback.terminate = service_app_terminate;
295         event_callback.app_control = service_app_control;
296
297         return service_app_main(argc, argv, &event_callback, ad);
298 }
299