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_POWER "/capability/switch/main/0"
40 #define SENSOR_KEY_POWER "power"
41 #define SENSOR_POWER_INITIALIZING "off"
43 #define I2C_BUS_NUMBER (1)
46 #define SENSOR_GATHER_INTERVAL (1.0f)
51 typedef struct app_data_s {
52 Ecore_Timer *getter_illuminance;
53 sensor_data *illuminance_data;
54 sensor_data *power_data;
57 static app_data *g_ad = NULL;
59 #define ILLUMINATION_CRITERIA 1000
61 // HS-53 Servo Motor Duty Cycle : 0.54ms ~ 2.1ms
62 // Spec Duty Cycle : 0.553ms ~ 2.227ms(https://www.servocity.com/hitec-hs-53-servo)
63 #define SERVO_MOTOR_DUTY_CYCLE_COUNTER_CLOCKWISE 1.0
64 #define SERVO_MOTOR_DUTY_CYCLE_CLOCKWISE 2.0
67 #define BLIND_DOWN "off"
69 static inline int __get_illuminance(void *data, unsigned int *illuminance_value)
75 retv_if(!ad->illuminance_data, -1);
78 ret = resource_read_illuminance_sensor(1, illuminance_value);
79 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));
119 static Eina_Bool __illuminance_to_servo_motor(void *data)
122 unsigned int illuminance_value = 0;
127 _E("failed to get app_data");
131 if (!ad->illuminance_data) {
132 _E("failed to get illuminance_data");
136 ret = __get_illuminance(ad, &illuminance_value);
137 retv_if(ret != 0, ECORE_CALLBACK_RENEW);
139 #if 1 // # Senario : Illuminance sensor
142 if (illuminance_value < ILLUMINATION_CRITERIA) {
148 ret = __set_servo_motor(ad, on);
149 retv_if(ret != 0, ECORE_CALLBACK_RENEW);
152 return ECORE_CALLBACK_RENEW;
155 void gathering_stop(void *data)
161 if (ad->getter_illuminance)
162 ecore_timer_del(ad->getter_illuminance);
165 void gathering_start(void *data)
173 ad->getter_illuminance = ecore_timer_add(SENSOR_GATHER_INTERVAL, __illuminance_to_servo_motor, ad);
174 if (!ad->getter_illuminance)
175 _E("Failed to add getter_illuminance");
179 static bool handle_reset_request(void)
181 _D("Received a request for RESET.");
185 static void handle_reset_result(bool result)
187 _D("Reset %s.\n", result ? "succeeded" : "failed");
190 static bool handle_ownership_transfer_request(void)
192 _D("Received a request for Ownership-transfer.");
196 static void handle_things_status_change(st_things_status_e things_status)
198 _D("Things status is changed: %d", things_status);
200 if (things_status == ST_THINGS_STATUS_REGISTERED_TO_CLOUD) {
201 ecore_main_loop_thread_safe_call_async(gathering_start, g_ad);
205 static bool handle_get_request(st_things_get_request_message_s* req_msg, st_things_representation_s* resp_rep)
207 _D("resource_uri [%s]", req_msg->resource_uri);
208 retv_if(!g_ad, false);
210 if (0 == strcmp(req_msg->resource_uri, SENSOR_URI_ILLUMINANCE)) {
211 if (req_msg->has_property_key(req_msg, SENSOR_KEY_ILLUMINANCE)) {
212 unsigned int value = 0;
213 sensor_data_get_uint(g_ad->illuminance_data, &value);
214 resp_rep->set_int_value(resp_rep, SENSOR_KEY_ILLUMINANCE, value);
217 } else if (0 == strcmp(req_msg->resource_uri, SENSOR_URI_POWER)) {
218 if (req_msg->has_property_key(req_msg, SENSOR_KEY_POWER)) {
219 const char *str = NULL;
220 sensor_data_get_string(g_ad->power_data, &str);
222 str = SENSOR_POWER_INITIALIZING;
224 resp_rep->set_str_value(resp_rep, SENSOR_KEY_POWER, str);
225 _D("Power : %s", str);
229 _E("not supported uri");
233 static bool handle_set_request(st_things_set_request_message_s* req_msg, st_things_representation_s* resp_rep)
235 _D("resource_uri [%s]", req_msg->resource_uri);
236 retv_if(!g_ad, false);
238 if (0 == strcmp(req_msg->resource_uri, SENSOR_URI_POWER)) {
242 if (req_msg->rep->get_str_value(req_msg->rep, SENSOR_KEY_POWER, &str)) {
243 retv_if(!str, false);
244 _D("set [%s:%s] == %s", SENSOR_URI_POWER, SENSOR_KEY_POWER, str);
246 sensor_data_set_string(g_ad->power_data, str, strlen(str));
247 resp_rep->set_str_value(resp_rep, SENSOR_KEY_POWER, str);
249 if (0 == strcmp(str, "on")) {
250 ret = __set_servo_motor(g_ad, 1);
252 ret = __set_servo_motor(g_ad, 0);
255 retv_if(ret != 0, false);
257 _E("cannot get a string value");
265 static int __st_things_init(void)
267 bool easysetup_complete = false;
268 char app_json_path[128] = {'\0', };
269 char *app_res_path = NULL;
270 char *app_data_path = NULL;
272 app_res_path = app_get_resource_path();
274 _E("app_res_path is NULL!!");
278 app_data_path = app_get_data_path();
279 if (!app_data_path) {
280 _E("app_data_path is NULL!!");
285 snprintf(app_json_path, sizeof(app_json_path), "%s%s", app_res_path, JSON_PATH);
287 if (0 != st_things_set_configuration_prefix_path(app_res_path, app_data_path)) {
288 _E("st_things_set_configuration_prefix_path() failed!!");
297 if (0 != st_things_initialize(app_json_path, &easysetup_complete)) {
298 _E("st_things_initialize() failed!!");
302 _D("easysetup_complete:[%d] ", easysetup_complete);
304 st_things_register_request_cb(handle_get_request, handle_set_request);
305 st_things_register_reset_cb(handle_reset_request, handle_reset_result);
306 st_things_register_user_confirm_cb(handle_ownership_transfer_request);
307 st_things_register_things_status_change_cb(handle_things_status_change);
312 static int __st_things_deinit(void)
314 st_things_deinitialize();
318 static int __st_things_start(void)
324 static int __st_things_stop(void)
329 #endif /* USE_ST_SDK */
331 static bool service_app_create(void *user_data)
333 app_data *ad = (app_data *)user_data;
335 ad->illuminance_data = sensor_data_new(SENSOR_DATA_TYPE_UINT);
336 if (!ad->illuminance_data)
339 ad->power_data = sensor_data_new(SENSOR_DATA_TYPE_STR);
342 sensor_data_set_string(g_ad->power_data, SENSOR_POWER_INITIALIZING, strlen(SENSOR_POWER_INITIALIZING));
345 if (__st_things_init())
352 static void service_app_control(app_control_h app_control, void *user_data)
357 gathering_start(user_data);
361 static void service_app_terminate(void *user_data)
363 app_data *ad = (app_data *)user_data;
365 resource_close_illuminance_sensor();
366 resource_close_servo_motor();
370 __st_things_deinit();
375 sensor_data_free(ad->illuminance_data);
379 int main(int argc, char *argv[])
382 service_app_lifecycle_callback_s event_callback;
384 ad = calloc(1, sizeof(app_data));
389 event_callback.create = service_app_create;
390 event_callback.terminate = service_app_terminate;
391 event_callback.app_control = service_app_control;
393 return service_app_main(argc, argv, &event_callback, ad);