2 * Copyright (c) 2018 Samsung Electronics Co., Ltd.
4 * Contact: Jin Yoon <jinny.yoon@samsung.com>
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an AS IS BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
20 #include <service_app.h>
28 #include "st_things.h"
30 #include "sensor-data.h"
33 #define JSON_PATH "device_def.json"
35 #define SENSOR_URI_ILLUMINANCE "/capability/illuminanceMeasurement/main/0"
36 #define SENSOR_KEY_ILLUMINANCE "illuminance"
37 #define SENSOR_KEY_RANGE "range"
39 #define SENSOR_URI_DOOR "/capability/doorControl/main/0"
40 #define SENSOR_KEY_DOOR "doorState"
41 #define SENSOR_POWER_INITIALIZING BLIND_DOWN
43 #define I2C_BUS_NUMBER (1)
44 #define SENSOR_GATHER_INTERVAL (5.0f)
49 typedef struct app_data_s {
50 Ecore_Timer *getter_illuminance;
51 sensor_data *illuminance_data;
52 sensor_data *power_data;
55 static app_data *g_ad = NULL;
57 #define ILLUMINATION_CRITERIA 1000
59 // HS-53 Servo Motor Duty Cycle : 0.54ms ~ 2.1ms
60 // Spec Duty Cycle : 0.553ms ~ 2.227ms(https://www.servocity.com/hitec-hs-53-servo)
61 #define SERVO_MOTOR_DUTY_CYCLE_COUNTER_CLOCKWISE 1.0
62 #define SERVO_MOTOR_DUTY_CYCLE_CLOCKWISE 2.0
64 #define BLIND_UP "opening"
65 #define BLIND_DOWN "closing"
67 static inline int __get_illuminance(void *data, unsigned int *illuminance_value)
73 retv_if(!ad->illuminance_data, -1);
77 ret = resource_read_illuminance_sensor(/*** BUS ***/, illuminance_value);
78 retv_if(ret != 0, -1);
81 sensor_data_set_uint(ad->illuminance_data, *illuminance_value);
82 _D("Illuminance value : %u", *illuminance_value);
85 st_things_notify_observers(SENSOR_URI_ILLUMINANCE);
91 static int __set_servo_motor(void *data, int on)
93 double duty_cycle = 0;
95 const char *power_value = NULL;
99 retv_if(!ad->illuminance_data, -1);
102 duty_cycle = SERVO_MOTOR_DUTY_CYCLE_CLOCKWISE;
103 power_value = BLIND_UP;
105 duty_cycle = SERVO_MOTOR_DUTY_CYCLE_COUNTER_CLOCKWISE;
106 power_value = BLIND_DOWN;
110 ret = resource_set_servo_motor_value(/*** DUTY CYCLE ***/);
111 retv_if(ret != 0, -1);
114 sensor_data_set_string(ad->power_data, power_value, strlen(power_value));
115 st_things_notify_observers(SENSOR_URI_DOOR);
120 static Eina_Bool __illuminance_to_servo_motor(void *data)
123 unsigned int illuminance_value = 0;
128 _E("failed to get app_data");
132 if (!ad->illuminance_data) {
133 _E("failed to get illuminance_data");
137 ret = __get_illuminance(ad, &illuminance_value);
138 retv_if(ret != 0, ECORE_CALLBACK_RENEW);
140 #if 0 // # Senario : Illuminance sensor
143 if (illuminance_value < ILLUMINATION_CRITERIA) {
149 ret = __set_servo_motor(ad, on);
150 retv_if(ret != 0, ECORE_CALLBACK_RENEW);
153 return ECORE_CALLBACK_RENEW;
156 void gathering_stop(void *data)
162 if (ad->getter_illuminance)
163 ecore_timer_del(ad->getter_illuminance);
166 void gathering_start(void *data)
174 ad->getter_illuminance = ecore_timer_add(SENSOR_GATHER_INTERVAL, __illuminance_to_servo_motor, ad);
175 if (!ad->getter_illuminance)
176 _E("Failed to add getter_illuminance");
180 static bool handle_reset_request(void)
182 _D("Received a request for RESET.");
186 static void handle_reset_result(bool result)
188 _D("Reset %s.\n", result ? "succeeded" : "failed");
191 static bool handle_ownership_transfer_request(void)
193 _D("Received a request for Ownership-transfer.");
197 static void handle_things_status_change(st_things_status_e things_status)
199 _D("Things status is changed: %d", things_status);
201 if (things_status == ST_THINGS_STATUS_REGISTERED_TO_CLOUD) {
202 ecore_main_loop_thread_safe_call_async(gathering_start, g_ad);
206 static bool handle_get_request(st_things_get_request_message_s* req_msg, st_things_representation_s* resp_rep)
208 _D("resource_uri [%s]", req_msg->resource_uri);
209 retv_if(!g_ad, false);
212 if (0 == strcmp(req_msg->resource_uri, /*** URI ILLUMINANCE ***/)) {
213 if (req_msg->has_property_key(req_msg, SENSOR_KEY_ILLUMINANCE)) {
214 unsigned int value = 0;
215 sensor_data_get_uint(g_ad->illuminance_data, &value);
216 resp_rep->set_int_value(resp_rep, SENSOR_KEY_ILLUMINANCE, value);
220 } else if (0 == strcmp(req_msg->resource_uri, /*** URI_DOOR ***/)) {
221 if (req_msg->has_property_key(req_msg, SENSOR_KEY_DOOR)) {
222 const char *str = NULL;
223 sensor_data_get_string(g_ad->power_data, &str);
225 str = SENSOR_POWER_INITIALIZING;
227 resp_rep->set_str_value(resp_rep, SENSOR_KEY_DOOR, str);
228 _D("Power : %s", str);
232 _E("not supported uri");
236 static bool handle_set_request(st_things_set_request_message_s* req_msg, st_things_representation_s* resp_rep)
238 _D("resource_uri [%s]", req_msg->resource_uri);
239 retv_if(!g_ad, false);
242 if (0 == strcmp(req_msg->resource_uri, /*** URI DOOR ***/)) {
246 if (req_msg->rep->get_str_value(req_msg->rep, SENSOR_KEY_DOOR, &str)) {
247 retv_if(!str, false);
248 _D("set [%s:%s] == %s", SENSOR_URI_DOOR, SENSOR_KEY_DOOR, str);
250 sensor_data_set_string(g_ad->power_data, str, strlen(str));
251 resp_rep->set_str_value(resp_rep, SENSOR_KEY_DOOR, str);
253 if (0 == strcmp(str, "opening")) {
254 ret = __set_servo_motor(g_ad, 1);
256 ret = __set_servo_motor(g_ad, 0);
259 retv_if(ret != 0, false);
261 _E("cannot get a string value");
269 static int __st_things_init(void)
271 bool easysetup_complete = false;
272 char app_json_path[128] = {'\0', };
273 char *app_res_path = NULL;
274 char *app_data_path = NULL;
276 app_res_path = app_get_resource_path();
278 _E("app_res_path is NULL!!");
282 app_data_path = app_get_data_path();
283 if (!app_data_path) {
284 _E("app_data_path is NULL!!");
289 snprintf(app_json_path, sizeof(app_json_path), "%s%s", app_res_path, JSON_PATH);
291 if (0 != st_things_set_configuration_prefix_path(app_res_path, app_data_path)) {
292 _E("st_things_set_configuration_prefix_path() failed!!");
301 if (0 != st_things_initialize(app_json_path, &easysetup_complete)) {
302 _E("st_things_initialize() failed!!");
306 _D("easysetup_complete:[%d] ", easysetup_complete);
308 st_things_register_request_cb(handle_get_request, handle_set_request);
309 st_things_register_reset_cb(handle_reset_request, handle_reset_result);
310 st_things_register_user_confirm_cb(handle_ownership_transfer_request);
311 st_things_register_things_status_change_cb(handle_things_status_change);
316 static int __st_things_deinit(void)
318 st_things_deinitialize();
322 static int __st_things_start(void)
328 static int __st_things_stop(void)
333 #endif /* USE_ST_SDK */
335 static bool service_app_create(void *user_data)
337 app_data *ad = (app_data *)user_data;
339 ad->illuminance_data = sensor_data_new(SENSOR_DATA_TYPE_UINT);
340 if (!ad->illuminance_data)
343 ad->power_data = sensor_data_new(SENSOR_DATA_TYPE_STR);
346 sensor_data_set_string(g_ad->power_data, SENSOR_POWER_INITIALIZING, strlen(SENSOR_POWER_INITIALIZING));
349 if (__st_things_init())
356 static void service_app_control(app_control_h app_control, void *user_data)
361 gathering_start(user_data);
365 static void service_app_terminate(void *user_data)
367 app_data *ad = (app_data *)user_data;
369 resource_close_illuminance_sensor();
370 resource_close_servo_motor();
374 __st_things_deinit();
379 sensor_data_free(ad->illuminance_data);
383 int main(int argc, char *argv[])
386 service_app_lifecycle_callback_s event_callback;
388 ad = calloc(1, sizeof(app_data));
393 event_callback.create = service_app_create;
394 event_callback.terminate = service_app_terminate;
395 event_callback.app_control = service_app_control;
397 return service_app_main(argc, argv, &event_callback, ad);