tizen 5.0 migration
[apps/native/blind-motor.git] / src / capability / capability_doorcontrol.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 "log.h"
18 #include <peripheral_io.h>
19 #include <app_common.h>
20 #include "resource/resource_servo_motor.h"
21
22 #include "smartthings_resource.h"
23
24 static const char *PROP_DOORSTATE = "doorState";
25 static const char *RES_CAPABILITY_DOORCONTROL_MAIN_0 = "/capability/doorControl/main/0";
26
27 #define VALUE_STR_LEN_MAX 32
28 #define AUTO_CLOSE_LUX_VALUE    40
29 #define AUTO_OPEN_LUX_VALUE             500
30 #define MAX_PATH_LEN    1024
31
32 static const char *VALUE_DOOR_STATE_OPENED = "opened";
33 static const char *VALUE_DOOR_STATE_OPENING = "opening";
34 static const char *VALUE_DOOR_STATE_CLOSING = "closing";
35 static const char *VALUE_DOOR_STATE_CLOSED = "closed";
36
37 static char g_door_state[VALUE_STR_LEN_MAX] = "closed";
38
39 char *door_state_file_name="door_state";
40
41 extern smartthings_resource_h st_handle;
42
43 //#define _USE_PLUGIN_APP_
44 extern bool get_auto_operation_status(void);
45 extern void set_auto_operation_status(bool status);
46 extern peripheral_error_e resource_motor_driving(door_state_e mode);
47
48 bool get_door_state(char *door_state)
49 {
50         FILE * fd;
51         char file_name_path[MAX_PATH_LEN];
52         char *app_data_path = NULL;
53
54         app_data_path = app_get_data_path();
55         sprintf(file_name_path, "%s%s", app_data_path, door_state_file_name);
56
57         if((fd = fopen(file_name_path, "r")) == NULL) {
58                 _E("ERROR: can't fopen file: %s", file_name_path);
59                 free(app_data_path);
60                 return false;
61         }
62         if (fgets(door_state, 8, fd) == NULL) {
63                 _E("fgets read string error");
64                 free(app_data_path);
65                 fclose(fd);
66                 return false;
67         }
68         _I("door_state : %s", door_state);
69
70         fclose(fd);
71         free(app_data_path);
72
73         return true;
74 }
75
76 bool set_door_state(const char *door_state)
77 {
78         FILE *fp;
79         char buffer[16];
80         char file_name_path[MAX_PATH_LEN];
81         char *app_data_path = NULL;
82         int num;
83
84         app_data_path = app_get_data_path();
85         sprintf(file_name_path, "%s%s", app_data_path, door_state_file_name);
86
87         if((fp = fopen(file_name_path, "w+")) == NULL) {
88                 _E("ERROR: can't fopen file: %s", file_name_path);
89                 strncpy(g_door_state, door_state, VALUE_STR_LEN_MAX);
90                 free(app_data_path);
91                 return false;
92         }
93         memset(buffer, 0, sizeof(buffer));
94         sprintf(buffer, "%s", door_state);
95         if ((num = fputs(buffer, fp)) == EOF) {
96                 _E("ERROR: fputs failed");
97                 strncpy(g_door_state, door_state, VALUE_STR_LEN_MAX);
98                 free(app_data_path);
99                 fclose(fp);
100                 return false;
101         }
102         fclose(fp);
103
104         strncpy(g_door_state, door_state, VALUE_STR_LEN_MAX);
105         free(app_data_path);
106         return true;
107 }
108
109 void set_auto_motor_driving(uint16_t sensor_value)
110 {
111         bool auto_status = get_auto_operation_status();
112
113         if (auto_status == false)
114                 return;
115
116         if (sensor_value <= AUTO_CLOSE_LUX_VALUE) {
117                 if (0 != strncmp(g_door_state, VALUE_DOOR_STATE_CLOSING, strlen(VALUE_DOOR_STATE_CLOSING))) {
118                         resource_motor_driving(DOOR_STATE_CLOSING);
119                         set_door_state(VALUE_DOOR_STATE_CLOSING);
120                         strncpy(g_door_state, VALUE_DOOR_STATE_CLOSING, strlen(VALUE_DOOR_STATE_CLOSING));
121                 }
122         }
123         else if (sensor_value > AUTO_OPEN_LUX_VALUE) {
124                 if (0 != strncmp(g_door_state, VALUE_DOOR_STATE_OPENING, strlen(VALUE_DOOR_STATE_OPENING))) {
125                         resource_motor_driving(DOOR_STATE_OPENING);
126                         set_door_state(VALUE_DOOR_STATE_OPENING);
127                         strncpy(g_door_state, VALUE_DOOR_STATE_OPENING, strlen(VALUE_DOOR_STATE_OPENING));
128                 }
129         }
130         else {
131                 _E("invalid sensor_value [%d]", sensor_value);
132                 return;
133         }
134
135         // notify door state to cloud
136         int error = SMARTTHINGS_RESOURCE_ERROR_NONE;
137         smartthings_payload_h resp_payload = NULL;
138
139         if (!st_handle) {
140                 _E("st_handle is NULL");
141                 return;
142         }
143         _D("g_door_state: %s", g_door_state);
144
145         error = smartthings_payload_create(&resp_payload);
146         if (error != SMARTTHINGS_RESOURCE_ERROR_NONE || !resp_payload) {
147                 _E("smartthings_payload_create() failed, [%d]", error);
148                 return;
149         }
150
151         error = smartthings_payload_set_string(resp_payload, PROP_DOORSTATE, g_door_state);
152         if (error != SMARTTHINGS_RESOURCE_ERROR_NONE) {
153                 _E("smartthings_payload_set_int() failed, [%d]", error);
154         }
155
156         error = smartthings_resource_notify(st_handle, RES_CAPABILITY_DOORCONTROL_MAIN_0, resp_payload);
157         if (error != SMARTTHINGS_RESOURCE_ERROR_NONE) {
158                 _E("smartthings_resource_notify() failed, [%d]", error);
159                 return;
160         }
161
162         if (smartthings_payload_destroy(resp_payload))
163                 _E("smartthings_payload_destroy() failed");
164
165 }
166
167
168 bool handle_get_request_on_resource_capability_doorcontrol_main_0(smartthings_payload_h resp_payload, void *user_data)
169 {
170         int error = SMARTTHINGS_RESOURCE_ERROR_NONE;
171
172         _D("Received a GET request for Sensor");
173
174         if (get_door_state(g_door_state) != true) {
175                 set_door_state(VALUE_DOOR_STATE_CLOSED);
176         }
177
178         /* check door state */
179         if ((0 == strncmp(g_door_state, VALUE_DOOR_STATE_OPENED, strlen(VALUE_DOOR_STATE_OPENED))) ||
180                 (0 == strncmp(g_door_state, VALUE_DOOR_STATE_CLOSED, strlen(VALUE_DOOR_STATE_CLOSED)))) {
181                 _I("g_door_state(%s) : Auto Operation OFF!!", g_door_state);
182                 set_auto_operation_status(false);
183         } else if ((0 == strncmp(g_door_state, VALUE_DOOR_STATE_OPENING, strlen(VALUE_DOOR_STATE_OPENING))) ||
184                                 (0 == strncmp(g_door_state, VALUE_DOOR_STATE_CLOSING, strlen(VALUE_DOOR_STATE_CLOSING)))) {
185                 _I("g_door_state(%s) : Auto Operation ON!!", g_door_state);
186                 set_auto_operation_status(true);
187         }
188
189         error = smartthings_payload_set_string(resp_payload, PROP_DOORSTATE, g_door_state);
190         if (error != SMARTTHINGS_RESOURCE_ERROR_NONE) {
191                 _E("smartthings_payload_set_string() failed, [%d]", error);
192                 return false;
193         }
194
195         return true;
196 }
197
198 bool handle_set_request_on_resource_capability_doorcontrol_main_0(smartthings_payload_h payload, smartthings_payload_h resp_payload, void *user_data)
199 {
200         int error = SMARTTHINGS_RESOURCE_ERROR_NONE;
201         door_state_e state = DOOR_STATE_UNKNOWN;
202         char *str_value = NULL;
203
204         error = smartthings_payload_get_string(payload, PROP_DOORSTATE, &str_value);
205         if (error != SMARTTHINGS_RESOURCE_ERROR_NONE) {
206                 _E("smartthings_payload_get_string() failed, [%d]", error);
207                 return false;
208         }
209
210         /* check validation */
211         if ((0 != strncmp(str_value, VALUE_DOOR_STATE_OPENED, strlen(VALUE_DOOR_STATE_OPENED)))
212                 && (0 != strncmp(str_value, VALUE_DOOR_STATE_OPENING, strlen(VALUE_DOOR_STATE_OPENING)))
213                 && (0 != strncmp(str_value, VALUE_DOOR_STATE_CLOSING, strlen(VALUE_DOOR_STATE_CLOSING)))
214                 && (0 != strncmp(str_value, VALUE_DOOR_STATE_CLOSED, strlen(VALUE_DOOR_STATE_CLOSED)))) {
215                 _E("Not supported value!! str_value : %s", str_value);
216                 free(str_value);
217                 return false;
218         }
219
220         _D("Received a SET request for Sensor : [%s]", str_value);
221
222         if (0 != strncmp(str_value, g_door_state, strlen(g_door_state))) {
223                 strncpy(g_door_state, str_value, VALUE_STR_LEN_MAX);
224                 free(str_value);
225
226                 set_door_state(g_door_state);
227
228                 if (0 == strncmp(g_door_state, VALUE_DOOR_STATE_OPENED, strlen(VALUE_DOOR_STATE_OPENED))) {
229                         _I("Door Opened");
230                         set_auto_operation_status(false);
231                         state = DOOR_STATE_OPENED;
232                 }
233                 else if (0 == strncmp(g_door_state, VALUE_DOOR_STATE_OPENING, strlen(VALUE_DOOR_STATE_OPENING))) {
234                         _I("Door Opening - AUTO");
235                         set_auto_operation_status(true);
236 #ifdef _USE_PLUGIN_APP_
237                         state = DOOR_STATE_UNKNOWN;
238 #else
239                         state = DOOR_STATE_OPENING;
240 #endif
241                 }
242                 else if (0 == strncmp(g_door_state, VALUE_DOOR_STATE_CLOSING, strlen(VALUE_DOOR_STATE_CLOSING))) {
243                         _I("Door Closing - AUTO");
244                         set_auto_operation_status(true);
245 #ifdef _USE_PLUGIN_APP_
246                         state = DOOR_STATE_UNKNOWN;
247 #else
248                         state = DOOR_STATE_CLOSING;
249 #endif
250                 }
251                 else if (0 == strncmp(g_door_state, VALUE_DOOR_STATE_CLOSED, strlen(VALUE_DOOR_STATE_CLOSED))) {
252                         _I("Door Closed");
253                         set_auto_operation_status(false);
254                         state = DOOR_STATE_CLOSE;
255                 }
256                 else {
257                         _E("Door state Unknown");
258                         state = DOOR_STATE_UNKNOWN;
259                 }
260
261                 if (state != DOOR_STATE_UNKNOWN) {
262                         if (resource_motor_driving(state) != PERIPHERAL_ERROR_NONE)
263                                 return false;
264                 }
265         }
266
267         error = smartthings_payload_set_string(resp_payload, PROP_DOORSTATE, g_door_state);
268         if (error != SMARTTHINGS_RESOURCE_ERROR_NONE) {
269                 _E("smartthings_payload_set_string() failed, [%d]", error);
270                 return false;
271         }
272
273         return true;
274 }