d4f901d0b50f3502c51d1520d5cd553a03c08bd5
[apps/native/blind-motor.git] / src / lux_blind_sensor.c
1 /*
2  * Copyright (c) 2018 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 <service_app.h>
18 #include <stdio.h>
19 #include "st_things.h"
20 #include "log.h"
21 #include <Ecore.h>
22
23 #define _DEBUG_PRINT_
24 #ifdef _DEBUG_PRINT_
25 #include <sys/time.h>
26 #endif
27
28 #define SENSOR_EVENT_INTERVAL   (0.250f)        // sensor event timer : 250ms interval
29 #define JSON_PATH "device_def.json"
30 #define MUTEX_LOCK              pthread_mutex_lock(&mutex)
31 #define MUTEX_UNLOCK    pthread_mutex_unlock(&mutex)
32
33 Ecore_Timer *sensor_event_timer = NULL;
34 pthread_mutex_t  mutex = PTHREAD_MUTEX_INITIALIZER;
35
36 static const char *RES_CAPABILITY_ILLUMINANCEMEASUREMENT_MAIN_0 = "/capability/illuminanceMeasurement/main/0";
37 static const char *RES_CAPABILITY_DOORCONTROL_MAIN_0 = "/capability/doorControl/main/0";
38 static const char *RES_CAPABILITY_SWITCH_MAIN_0 = "/capability/switch/main/0";
39 static int g_lux_value = 0;
40 static bool g_switch_status = false;
41 static bool g_auto_operation_status = false;
42
43 /* resource handler */
44 extern int resource_open_i2c_handle(void);
45 extern int resource_close_i2c_handle(void);
46 extern int resource_read_illuminance_sensor(uint16_t *out_value);
47
48 /* get and set request handlers */
49 extern bool handle_get_request_on_resource_capability_illuminancemeasurement(st_things_get_request_message_s* req_msg, st_things_representation_s* resp_rep);
50 extern bool handle_get_request_on_resource_capability_switch(st_things_get_request_message_s* req_msg, st_things_representation_s* resp_rep);
51 extern bool handle_set_request_on_resource_capability_switch(st_things_set_request_message_s* req_msg, st_things_representation_s* resp_rep);
52 extern bool handle_get_request_on_resource_capability_doorcontrol(st_things_get_request_message_s* req_msg, st_things_representation_s* resp_rep);
53 extern bool handle_set_request_on_resource_capability_doorcontrol(st_things_set_request_message_s* req_msg, st_things_representation_s* resp_rep);
54
55 bool get_switch_status(void)
56 {
57         bool status = false;
58
59         MUTEX_LOCK;
60         status = g_switch_status;
61         MUTEX_UNLOCK;
62
63         return status;
64 }
65
66 void set_switch_status(bool status)
67 {
68         MUTEX_LOCK;
69         g_switch_status = status;
70         MUTEX_UNLOCK;
71
72 }
73
74 bool get_auto_operation_status(void)
75 {
76         bool status = false;
77
78         MUTEX_LOCK;
79         status = g_auto_operation_status;
80         MUTEX_UNLOCK;
81
82         return status;
83 }
84
85 void set_auto_operation_status(bool status)
86 {
87         MUTEX_LOCK;
88         g_auto_operation_status = status;
89         MUTEX_UNLOCK;
90
91 }
92
93 uint16_t get_sensor_value(void)
94 {
95         uint16_t value = 0;
96
97         MUTEX_LOCK;
98         value = g_lux_value;
99         MUTEX_UNLOCK;
100
101         return value;
102 }
103
104 static void set_sensor_value(uint16_t value)
105 {
106         MUTEX_LOCK;
107         g_lux_value = value;
108         MUTEX_UNLOCK;
109 }
110
111 static Eina_Bool _sensor_interval_event_cb(void *data)
112 {
113         uint16_t sensor_value;
114         int ret = 0;
115         bool switch_status = false;
116
117         // read sensor value in lux
118         ret = resource_read_illuminance_sensor(&sensor_value);
119         if (ret != 0) {
120                 ERR("Got invalid sensor value");
121                 // cancle periodic event timer operation
122                 return ECORE_CALLBACK_CANCEL;
123         } else {
124                 // save sensor value to global variable
125                 set_sensor_value(sensor_value);
126
127                 #ifdef _DEBUG_PRINT_
128                 struct timeval __tv;
129                 gettimeofday(&__tv, NULL);
130                 INFO("[%d.%06d] Lux=[%d]Lux", __tv.tv_sec, __tv.tv_usec, sensor_value);
131                 #endif
132
133                 // send notification when switch is on state.
134                 switch_status = get_switch_status();
135                 if (switch_status) {
136                         // send notification to cloud server
137                         st_things_notify_observers(RES_CAPABILITY_ILLUMINANCEMEASUREMENT_MAIN_0);
138                 }
139         }
140         // reset event timer periodic
141         return ECORE_CALLBACK_RENEW;
142 }
143
144 /* handle : for getting request on resources */
145 bool handle_get_request(st_things_get_request_message_s* req_msg, st_things_representation_s* resp_rep)
146 {
147         //DBG("resource_uri [%s]", req_msg->resource_uri);
148
149         if (0 == strcmp(req_msg->resource_uri, RES_CAPABILITY_SWITCH_MAIN_0)) {
150                 return handle_get_request_on_resource_capability_switch(req_msg, resp_rep);
151         }
152         if (0 == strcmp(req_msg->resource_uri, RES_CAPABILITY_ILLUMINANCEMEASUREMENT_MAIN_0)) {
153                 return handle_get_request_on_resource_capability_illuminancemeasurement(req_msg, resp_rep);
154         }
155         if (0 == strcmp(req_msg->resource_uri, RES_CAPABILITY_DOORCONTROL_MAIN_0)) {
156                 return handle_get_request_on_resource_capability_doorcontrol(req_msg, resp_rep);
157         }
158
159         ERR("not supported uri");
160         return false;
161 }
162
163 /* handle : for setting request on resources */
164 bool handle_set_request(st_things_set_request_message_s* req_msg, st_things_representation_s* resp_rep)
165 {
166         //DBG("resource_uri [%s]", req_msg->resource_uri);
167
168         if (0 == strcmp(req_msg->resource_uri, RES_CAPABILITY_SWITCH_MAIN_0)) {
169                 return handle_set_request_on_resource_capability_switch(req_msg, resp_rep);
170         }
171         if (0 == strcmp(req_msg->resource_uri, RES_CAPABILITY_DOORCONTROL_MAIN_0)) {
172                 return handle_set_request_on_resource_capability_doorcontrol(req_msg, resp_rep);
173         }
174
175         ERR("not supported uri");
176         return false;
177 }
178
179 /* callback functions */
180 bool handle_reset_request(void)
181 {
182         DBG("Received a request for RESET.");
183         return true;
184 }
185
186 void handle_reset_result(bool result)
187 {
188         DBG("Reset %s.\n", result ? "succeeded" : "failed");
189 }
190
191 bool handle_ownership_transfer_request(void)
192 {
193         DBG("Received a request for Ownership-transfer.");
194         return true;
195 }
196
197 void handle_things_status_change(st_things_status_e things_status)
198 {
199         DBG("Things status is changed: %d\n", things_status);
200 }
201
202 bool init_user()
203 {
204         // initialize mutex
205         pthread_mutex_init(&mutex, NULL);
206
207         // create timer event function
208         sensor_event_timer = ecore_timer_add(SENSOR_EVENT_INTERVAL, _sensor_interval_event_cb, NULL);
209         if (!sensor_event_timer) {
210                 ERR("Failed to add sensor_event_timer");
211                 return false;
212         }
213
214         return true;
215 }
216
217 /* initialize */
218 void init_thing()
219 {
220         FN_CALL;
221         static bool binitialized = false;
222         if (binitialized) {
223                 DBG("Already initialized!!");
224                 return;
225         }
226
227         bool easysetup_complete = false;
228
229         char app_json_path[128] = {0,};
230         char *app_res_path = NULL;
231         char *app_data_path = NULL;
232
233         app_res_path = app_get_resource_path();
234         if (!app_res_path) {
235                 ERR("app_res_path is NULL!!");
236                 return;
237         }
238
239         app_data_path = app_get_data_path();
240         if (!app_data_path) {
241                 ERR("app_data_path is NULL!!");
242                 free(app_res_path);
243                 return;
244         }
245
246         snprintf(app_json_path, sizeof(app_json_path), "%s/%s", app_res_path, JSON_PATH);
247
248         if (0 != st_things_set_configuration_prefix_path((const char *)app_res_path, (const char *)app_data_path)) {
249                 ERR("st_things_set_configuration_prefix_path() failed!!");
250                 free(app_res_path);
251                 free(app_data_path);
252                 return;
253         }
254
255         free(app_res_path);
256         free(app_data_path);
257
258         if (0 != st_things_initialize(app_json_path, &easysetup_complete)) {
259                 ERR("st_things_initialize() failed!!");
260                 return;
261         }
262
263         binitialized = true;
264         init_user();
265
266         DBG("easysetup_complete:[%d] ", easysetup_complete);
267
268         st_things_register_request_cb(handle_get_request, handle_set_request);
269         st_things_register_reset_cb(handle_reset_request, handle_reset_result);
270         st_things_register_user_confirm_cb(handle_ownership_transfer_request);
271         st_things_register_things_status_change_cb(handle_things_status_change);
272
273         st_things_start();
274
275         FN_END;
276 }
277
278 static bool service_app_create(void *user_data)
279 {
280         INFO("open I2C handle");
281         resource_open_i2c_handle();
282         return true;
283 }
284
285 static void service_app_terminate(void *user_data)
286 {
287         // clear timer event
288         if (sensor_event_timer) {
289                 ecore_timer_del(sensor_event_timer);
290                 sensor_event_timer = NULL;
291         }
292
293         INFO("close I2C handle");
294         resource_close_i2c_handle();
295
296         int status = pthread_mutex_destroy(&mutex);
297         INFO("mutex destroy status = %d", status);
298 }
299
300 static void service_app_control(app_control_h app_control, void *user_data)
301 {
302         if (app_control == NULL) {
303                 ERR("app_control is NULL");
304                 return;
305         }
306
307         init_thing();
308 }
309
310 int main(int argc, char *argv[])
311 {
312         FN_CALL;
313
314         service_app_lifecycle_callback_s event_callback;
315
316         event_callback.create = service_app_create;
317         event_callback.terminate = service_app_terminate;
318         event_callback.app_control = service_app_control;
319
320         return service_app_main(argc, argv, &event_callback, NULL);
321 }