2 * Copyright (c) 2018 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 #include <peripheral_io.h>
19 #include <app_common.h>
20 #include "resource/resource_servo_motor.h"
22 #include "smartthings_resource.h"
24 static const char *PROP_DOORSTATE = "doorState";
25 static const char *RES_CAPABILITY_DOORCONTROL_MAIN_0 = "/capability/doorControl/main/0";
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
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";
37 static char g_door_state[VALUE_STR_LEN_MAX] = "closed";
39 char *door_state_file_name="door_state";
41 extern smartthings_resource_h st_handle;
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);
48 bool get_door_state(char *door_state)
51 char file_name_path[MAX_PATH_LEN];
52 char *app_data_path = NULL;
54 app_data_path = app_get_data_path();
55 sprintf(file_name_path, "%s%s", app_data_path, door_state_file_name);
57 if((fd = fopen(file_name_path, "r")) == NULL) {
58 _E("ERROR: can't fopen file: %s", file_name_path);
62 if (fgets(door_state, 8, fd) == NULL) {
63 _E("fgets read string error");
68 _I("door_state : %s", door_state);
76 bool set_door_state(const char *door_state)
80 char file_name_path[MAX_PATH_LEN];
81 char *app_data_path = NULL;
84 app_data_path = app_get_data_path();
85 sprintf(file_name_path, "%s%s", app_data_path, door_state_file_name);
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);
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);
104 strncpy(g_door_state, door_state, VALUE_STR_LEN_MAX);
109 void set_auto_motor_driving(uint16_t sensor_value)
111 bool auto_status = get_auto_operation_status();
113 if (auto_status == false)
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));
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));
131 _E("invalid sensor_value [%d]", sensor_value);
135 // notify door state to cloud
136 int error = SMARTTHINGS_RESOURCE_ERROR_NONE;
137 smartthings_payload_h resp_payload = NULL;
140 _E("st_handle is NULL");
143 _D("g_door_state: %s", g_door_state);
145 error = smartthings_payload_create(&resp_payload);
146 if (error != SMARTTHINGS_RESOURCE_ERROR_NONE || !resp_payload) {
147 _E("smartthings_payload_create() failed, [%d]", error);
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);
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);
162 if (smartthings_payload_destroy(resp_payload))
163 _E("smartthings_payload_destroy() failed");
168 bool handle_get_request_on_resource_capability_doorcontrol_main_0(smartthings_payload_h resp_payload, void *user_data)
170 int error = SMARTTHINGS_RESOURCE_ERROR_NONE;
172 _D("Received a GET request for Sensor");
174 if (get_door_state(g_door_state) != true) {
175 set_door_state(VALUE_DOOR_STATE_CLOSED);
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);
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);
198 bool handle_set_request_on_resource_capability_doorcontrol_main_0(smartthings_payload_h payload, smartthings_payload_h resp_payload, void *user_data)
200 int error = SMARTTHINGS_RESOURCE_ERROR_NONE;
201 door_state_e state = DOOR_STATE_UNKNOWN;
202 char *str_value = NULL;
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);
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);
220 _D("Received a SET request for Sensor : [%s]", str_value);
222 if (0 != strncmp(str_value, g_door_state, strlen(g_door_state))) {
223 strncpy(g_door_state, str_value, VALUE_STR_LEN_MAX);
226 set_door_state(g_door_state);
228 if (0 == strncmp(g_door_state, VALUE_DOOR_STATE_OPENED, strlen(VALUE_DOOR_STATE_OPENED))) {
230 set_auto_operation_status(false);
231 state = DOOR_STATE_OPENED;
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;
239 state = DOOR_STATE_OPENING;
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;
248 state = DOOR_STATE_CLOSING;
251 else if (0 == strncmp(g_door_state, VALUE_DOOR_STATE_CLOSED, strlen(VALUE_DOOR_STATE_CLOSED))) {
253 set_auto_operation_status(false);
254 state = DOOR_STATE_CLOSE;
257 _E("Door state Unknown");
258 state = DOOR_STATE_UNKNOWN;
261 if (state != DOOR_STATE_UNKNOWN) {
262 if (resource_motor_driving(state) != PERIPHERAL_ERROR_NONE)
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);