06351ec96d3d35a27d65273915f8a75ecd2aa3ca
[platform/core/connectivity/zigbee-manager.git] / zigbee-daemon / zigbee-interface / src / zigbee_service_dbus_interface_zcl_thermostat.c
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd. All rights reserved.
3  *
4  * Contact: Suresh Kumar N (suresh.n@samsung.com)
5  *
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
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
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.
17  */
18
19 #include "zigbee_service_interface_common.h"
20
21 #include <zblib_driver_zcl_thermostat.h>
22
23 /* LCOV_EXCL_START */
24 static void *_service_interface_ref_zigbee_zcl_thermostat(
25         ZigBeeServiceInterface *service_interface)
26 {
27         ZigbeeObjectSkeleton *zigbee_object = NULL;
28         ZigbeeCustomData_t *custom_data = NULL;
29         ZigbeeZcl_thermostat *thermo_object = NULL;
30
31         custom_data = (ZigbeeCustomData_t *)zblib_service_interface_ref_user_data(service_interface);
32         if (NULL == custom_data) {
33                 Z_LOGE("D-BUS service interface custom_data is NULL!");
34                 return NULL;
35         }
36
37         /* Get zigbee object */
38         zigbee_object = g_hash_table_lookup(custom_data->objects, ZIGBEE_SERVICE_PATH);
39         if (NULL == zigbee_object) {
40                 Z_LOGW("Cannot find ZigBee D-BUS interface object!", zigbee_object);
41                 return NULL;
42         }
43
44         thermo_object = zigbee_object_get_zcl_thermostat(ZIGBEE_OBJECT(zigbee_object));
45         return thermo_object;
46 }
47
48 static void on_thermostat_get_local_temp_resp(ZigBeeServiceInterface *service_interface,
49         guint request_id, gpointer resp_data, guint resp_data_len, gpointer resp_cb_data)
50 {
51         ZigbeeServiceInterfaceRespCbData_t *cb_data =
52                 (ZigbeeServiceInterfaceRespCbData_t *)resp_cb_data;
53
54         ZigbeeZcl_thermostat *thermo_object = NULL;
55         GDBusMethodInvocation *invocation = NULL;
56
57         ZigbeeGeneralResp_t *payload = (ZigbeeGeneralResp_t *)resp_data;
58
59         NOT_USED(service_interface);
60         NOT_USED(request_id);
61
62         if (NULL == resp_data || 0 == resp_data_len) {
63                 Z_LOGE("resp_data=%p or resp_data_len=%d is null", resp_data, resp_data_len);
64                 g_free(cb_data);
65                 return;
66         }
67
68         thermo_object = zigbee_service_dbus_interface_ref_interface_object(cb_data);
69         zblib_check_null_free_and_ret("thermo_object", thermo_object, cb_data);
70
71         invocation = zigbee_service_dbus_interface_ref_invocation(cb_data);
72         zblib_check_null_free_and_ret("invocation", invocation, cb_data);
73
74         zigbee_zcl_thermostat_complete_get_local_temp(thermo_object, invocation,
75                 payload->result);
76
77         g_free(cb_data);
78 }
79
80 static gboolean on_thermostat_get_local_temp(ZigbeeZcl_thermostat *thermostat_object,
81         GDBusMethodInvocation *invocation,
82         GVariant *eui64,
83         gchar endpoint,
84         gpointer user_data)
85 {
86         ZigBeeServiceInterface *service_interface = (ZigBeeServiceInterface *)user_data;
87         ZigbeeZclThermostatGetLocalTemp_t req;
88         ZigbeeServiceInterfaceRespCbData_t *resp_cb_data = NULL;
89
90         GVariantIter *iter = NULL;
91         guint i = 0;
92
93         gboolean ret;
94
95         memset(&req, 0x0, sizeof(ZigbeeZclThermostatGetLocalTemp_t));
96
97         /* Update request structure */
98         g_variant_get(eui64, "a(y)", &iter);
99         while (g_variant_iter_loop(iter, "(y)", &(req.eui64[i]))) {
100                 i++;
101                 if (i >= ZIGBEE_EUI64_SIZE)
102                         break;
103         }
104         req.endpoint = endpoint;
105
106         /* Allocate response callback data */
107         resp_cb_data =
108                 zigbee_service_dbus_interface_create_resp_cb_data(thermostat_object,
109                         invocation, NULL, 0);
110         if (NULL == resp_cb_data) {
111                 Z_LOGE("zigbee_service_dbus_interface_create_resp_cb_data failed!");
112
113                 /* Send failure response */
114                 ZIGBEE_DBUS_FAIL_RESPONSE(invocation, ZIGBEE_DBUS_DEFAULT_REQ_FAILED_MSG);
115
116                 return TRUE;
117         }
118
119         /* Dispatch request */
120         ret = zigbee_service_dbus_interface_dispatch_request(service_interface,
121                 ZBLIB_DRIVER_TYPE_ZCL_THERMOSTAT,
122                 ZBLIB_ZCL_THERMOSTAT_OPS_GET_LOCAL_TEMP,
123                 &req, sizeof(req),
124                 on_thermostat_get_local_temp_resp, resp_cb_data);
125         if (FALSE == ret) {
126                 Z_LOGE("zigbee_service_dbus_interface_dispatch_request failed!");
127
128                 /* Free response callback data */
129                 zigbee_service_dbus_interface_destroy_resp_cb_data(resp_cb_data);
130
131                 /* Send failure response */
132                 ZIGBEE_DBUS_FAIL_RESPONSE(invocation, ZIGBEE_DBUS_DEFAULT_REQ_FAILED_MSG);
133
134                 return TRUE;
135         }
136
137         return TRUE;
138 }
139
140 static void on_thermostat_get_weekly_schedule_resp(ZigBeeServiceInterface *service_interface,
141         guint request_id, gpointer resp_data, guint resp_data_len, gpointer resp_cb_data)
142 {
143         ZigbeeServiceInterfaceRespCbData_t *cb_data =
144                 (ZigbeeServiceInterfaceRespCbData_t *)resp_cb_data;
145
146         ZigbeeZcl_thermostat *thermo_object = NULL;
147         GDBusMethodInvocation *invocation = NULL;
148
149         ZigbeeGeneralResp_t *payload = (ZigbeeGeneralResp_t *)resp_data;
150
151         NOT_USED(service_interface);
152         NOT_USED(request_id);
153
154         if (NULL == resp_data || 0 == resp_data_len) {
155                 Z_LOGE("resp_data=%p or resp_data_len=%d is null", resp_data, resp_data_len);
156                 g_free(cb_data);
157                 return;
158         }
159
160         thermo_object = zigbee_service_dbus_interface_ref_interface_object(cb_data);
161         zblib_check_null_free_and_ret("thermo_object", thermo_object, cb_data);
162
163         invocation = zigbee_service_dbus_interface_ref_invocation(cb_data);
164         zblib_check_null_free_and_ret("invocation", invocation, cb_data);
165
166         zigbee_zcl_thermostat_complete_get_weekly_schedule(thermo_object, invocation,
167                 payload->result);
168
169         g_free(cb_data);
170 }
171
172 static gboolean on_thermostat_get_weekly_schedule(ZigbeeZcl_thermostat *thermostat_object,
173         GDBusMethodInvocation *invocation,
174         GVariant *eui64,
175         gchar endpoint,
176         gchar no_of_days,
177         gchar mode,
178         gpointer user_data)
179 {
180         ZigBeeServiceInterface *service_interface = (ZigBeeServiceInterface *)user_data;
181         ZigbeeZclThermostatGetWeeklySchedule_t req;
182         ZigbeeServiceInterfaceRespCbData_t *resp_cb_data = NULL;
183
184         GVariantIter *iter = NULL;
185         guint i = 0;
186
187         gboolean ret;
188
189         memset(&req, 0x0, sizeof(ZigbeeZclThermostatGetWeeklySchedule_t));
190
191         /* Update request structure */
192         g_variant_get(eui64, "a(y)", &iter);
193         while (g_variant_iter_loop(iter, "(y)", &(req.eui64[i]))) {
194                 i++;
195                 if (i >= ZIGBEE_EUI64_SIZE)
196                         break;
197         }
198         req.endpoint = endpoint;
199         req.num_of_days = no_of_days;
200         req.mode = mode;
201
202         /* Allocate response callback data */
203         resp_cb_data =
204                 zigbee_service_dbus_interface_create_resp_cb_data(thermostat_object,
205                         invocation, NULL, 0);
206         if (NULL == resp_cb_data) {
207                 Z_LOGE("zigbee_service_dbus_interface_create_resp_cb_data failed!");
208
209                 /* Send failure response */
210                 ZIGBEE_DBUS_FAIL_RESPONSE(invocation, ZIGBEE_DBUS_DEFAULT_REQ_FAILED_MSG);
211
212                 return TRUE;
213         }
214
215         /* Dispatch request */
216         ret = zigbee_service_dbus_interface_dispatch_request(service_interface,
217                 ZBLIB_DRIVER_TYPE_ZCL_THERMOSTAT,
218                 ZBLIB_ZCL_THERMOSTAT_OPS_GET_WEEKLY_SCHEDULE,
219                 &req, sizeof(req),
220                 on_thermostat_get_weekly_schedule_resp, resp_cb_data);
221         if (FALSE == ret) {
222                 Z_LOGE("zigbee_service_dbus_interface_dispatch_request failed!");
223
224                 /* Free response callback data */
225                 zigbee_service_dbus_interface_destroy_resp_cb_data(resp_cb_data);
226
227                 /* Send failure response */
228                 ZIGBEE_DBUS_FAIL_RESPONSE(invocation, ZIGBEE_DBUS_DEFAULT_REQ_FAILED_MSG);
229
230                 return TRUE;
231         }
232
233         return TRUE;
234 }
235
236 static void on_thermostat_set_weekly_schedule_resp(ZigBeeServiceInterface *service_interface,
237         guint request_id, gpointer resp_data, guint resp_data_len, gpointer resp_cb_data)
238 {
239         ZigbeeServiceInterfaceRespCbData_t *cb_data =
240                 (ZigbeeServiceInterfaceRespCbData_t *)resp_cb_data;
241
242         ZigbeeZcl_thermostat *thermo_object = NULL;
243         GDBusMethodInvocation *invocation = NULL;
244
245         ZigbeeGeneralResp_t *payload = (ZigbeeGeneralResp_t *)resp_data;
246
247         NOT_USED(service_interface);
248         NOT_USED(request_id);
249
250         if (NULL == resp_data || 0 == resp_data_len) {
251                 Z_LOGE("resp_data=%p or resp_data_len=%d is null", resp_data, resp_data_len);
252                 g_free(cb_data);
253                 return;
254         }
255
256         thermo_object = zigbee_service_dbus_interface_ref_interface_object(cb_data);
257         zblib_check_null_free_and_ret("thermo_object", thermo_object, cb_data);
258
259         invocation = zigbee_service_dbus_interface_ref_invocation(cb_data);
260         zblib_check_null_free_and_ret("invocation", invocation, cb_data);
261
262         zigbee_zcl_thermostat_complete_set_weekly_schedule(thermo_object, invocation,
263                 payload->result);
264
265         g_free(cb_data);
266 }
267
268 static gboolean on_thermostat_set_weekly_schedule(ZigbeeZcl_thermostat *thermostat_object,
269         GDBusMethodInvocation *invocation,
270         GVariant *eui64,
271         gchar endpoint,
272         gchar no_of_transitions,
273         gchar no_of_days,
274         gchar mode,
275         GVariant *payload,
276         gchar payload_len,
277         gpointer user_data)
278 {
279         ZigBeeServiceInterface *service_interface = (ZigBeeServiceInterface *)user_data;
280         ZigbeeZclThermostatSetWeeklySchedule_t req;
281         ZigbeeServiceInterfaceRespCbData_t *resp_cb_data = NULL;
282
283         GVariantIter *iter = NULL;
284         guint i = 0;
285
286         gboolean ret;
287
288         memset(&req, 0x0, sizeof(ZigbeeZclThermostatSetWeeklySchedule_t));
289
290         /* Update request structure */
291         g_variant_get(eui64, "a(y)", &iter);
292         while (g_variant_iter_loop(iter, "(y)", &(req.eui64[i]))) {
293                 i++;
294                 if (i >= ZIGBEE_EUI64_SIZE)
295                         break;
296         }
297         req.endpoint = endpoint;
298         req.no_of_transitions = no_of_transitions;
299         req.num_of_days = no_of_days;
300         req.mode = mode;
301
302         i = 0;
303         g_variant_get(payload, "a(y)", &iter);
304         while (g_variant_iter_loop(iter, "(y)", &(req.payload[i]))) {
305                 i++;
306                 if (i >= (guint)payload_len)
307                         break;
308         }
309         req.payload_len = payload_len;
310
311         /* Allocate response callback data */
312         resp_cb_data =
313                 zigbee_service_dbus_interface_create_resp_cb_data(thermostat_object,
314                         invocation, NULL, 0);
315         if (NULL == resp_cb_data) {
316                 Z_LOGE("zigbee_service_dbus_interface_create_resp_cb_data failed!");
317
318                 /* Send failure response */
319                 ZIGBEE_DBUS_FAIL_RESPONSE(invocation, ZIGBEE_DBUS_DEFAULT_REQ_FAILED_MSG);
320
321                 return TRUE;
322         }
323
324         /* Dispatch request */
325         ret = zigbee_service_dbus_interface_dispatch_request(service_interface,
326                 ZBLIB_DRIVER_TYPE_ZCL_THERMOSTAT,
327                 ZBLIB_ZCL_THERMOSTAT_OPS_SET_WEEKLY_SCHEDULE,
328                 &req, sizeof(req),
329                 on_thermostat_set_weekly_schedule_resp, resp_cb_data);
330         if (FALSE == ret) {
331                 Z_LOGE("zigbee_service_dbus_interface_dispatch_request failed!");
332
333                 /* Free response callback data */
334                 zigbee_service_dbus_interface_destroy_resp_cb_data(resp_cb_data);
335
336                 /* Send failure response */
337                 ZIGBEE_DBUS_FAIL_RESPONSE(invocation, ZIGBEE_DBUS_DEFAULT_REQ_FAILED_MSG);
338
339                 return TRUE;
340         }
341
342         return TRUE;
343 }
344
345 static void on_thermostat_clear_weekly_schedule_resp(ZigBeeServiceInterface *service_interface,
346         guint request_id, gpointer resp_data, guint resp_data_len, gpointer resp_cb_data)
347 {
348         ZigbeeServiceInterfaceRespCbData_t *cb_data =
349                 (ZigbeeServiceInterfaceRespCbData_t *)resp_cb_data;
350
351         ZigbeeZcl_thermostat *thermo_object = NULL;
352         GDBusMethodInvocation *invocation = NULL;
353
354         ZigbeeGeneralResp_t *payload = (ZigbeeGeneralResp_t *)resp_data;
355
356         NOT_USED(service_interface);
357         NOT_USED(request_id);
358
359         if (NULL == resp_data || 0 == resp_data_len) {
360                 Z_LOGE("resp_data=%p or resp_data_len=%d is null", resp_data, resp_data_len);
361                 g_free(cb_data);
362                 return;
363         }
364
365         thermo_object = zigbee_service_dbus_interface_ref_interface_object(cb_data);
366         zblib_check_null_free_and_ret("thermo_object", thermo_object, cb_data);
367
368         invocation = zigbee_service_dbus_interface_ref_invocation(cb_data);
369         zblib_check_null_free_and_ret("invocation", invocation, cb_data);
370
371         zigbee_zcl_thermostat_complete_clear_weekly_schedule(thermo_object, invocation,
372                 payload->result);
373
374         g_free(cb_data);
375 }
376
377 static gboolean on_thermostat_clear_weekly_schedule(ZigbeeZcl_thermostat *thermostat_object,
378         GDBusMethodInvocation *invocation,
379         GVariant *eui64,
380         gchar endpoint,
381         gpointer user_data)
382 {
383         ZigBeeServiceInterface *service_interface = (ZigBeeServiceInterface *)user_data;
384         ZigbeeZclThermostatClearWeeklySchedule_t req;
385         ZigbeeServiceInterfaceRespCbData_t *resp_cb_data = NULL;
386
387         GVariantIter *iter = NULL;
388         guint i = 0;
389
390         gboolean ret;
391
392         memset(&req, 0x0, sizeof(ZigbeeZclThermostatClearWeeklySchedule_t));
393
394         /* Update request structure */
395         g_variant_get(eui64, "a(y)", &iter);
396         while (g_variant_iter_loop(iter, "(y)", &(req.eui64[i]))) {
397                 i++;
398                 if (i >= ZIGBEE_EUI64_SIZE)
399                         break;
400         }
401         req.endpoint = endpoint;
402
403         /* Allocate response callback data */
404         resp_cb_data =
405                 zigbee_service_dbus_interface_create_resp_cb_data(thermostat_object,
406                         invocation, NULL, 0);
407         if (NULL == resp_cb_data) {
408                 Z_LOGE("zigbee_service_dbus_interface_create_resp_cb_data failed!");
409
410                 /* Send failure response */
411                 ZIGBEE_DBUS_FAIL_RESPONSE(invocation, ZIGBEE_DBUS_DEFAULT_REQ_FAILED_MSG);
412
413                 return TRUE;
414         }
415
416         /* Dispatch request */
417         ret = zigbee_service_dbus_interface_dispatch_request(service_interface,
418                 ZBLIB_DRIVER_TYPE_ZCL_THERMOSTAT,
419                 ZBLIB_ZCL_THERMOSTAT_OPS_CLEAR_WEEKLY_SCHEDULE,
420                 &req, sizeof(req),
421                 on_thermostat_clear_weekly_schedule_resp, resp_cb_data);
422         if (FALSE == ret) {
423                 Z_LOGE("zigbee_service_dbus_interface_dispatch_request failed!");
424
425                 /* Free response callback data */
426                 zigbee_service_dbus_interface_destroy_resp_cb_data(resp_cb_data);
427
428                 /* Send failure response */
429                 ZIGBEE_DBUS_FAIL_RESPONSE(invocation, ZIGBEE_DBUS_DEFAULT_REQ_FAILED_MSG);
430
431                 return TRUE;
432         }
433
434         return TRUE;
435 }
436
437 static void on_thermostat_setpoint_raise_lower_resp(ZigBeeServiceInterface *service_interface,
438         guint request_id, gpointer resp_data, guint resp_data_len, gpointer resp_cb_data)
439 {
440         ZigbeeServiceInterfaceRespCbData_t *cb_data =
441                 (ZigbeeServiceInterfaceRespCbData_t *)resp_cb_data;
442
443         ZigbeeZcl_thermostat *thermo_object = NULL;
444         GDBusMethodInvocation *invocation = NULL;
445
446         ZigbeeGeneralResp_t *payload = (ZigbeeGeneralResp_t *)resp_data;
447
448         NOT_USED(service_interface);
449         NOT_USED(request_id);
450
451         if (NULL == resp_data || 0 == resp_data_len) {
452                 Z_LOGE("resp_data=%p or resp_data_len=%d is null", resp_data, resp_data_len);
453                 g_free(cb_data);
454                 return;
455         }
456
457         thermo_object = zigbee_service_dbus_interface_ref_interface_object(cb_data);
458         zblib_check_null_free_and_ret("thermo_object", thermo_object, cb_data);
459
460         invocation = zigbee_service_dbus_interface_ref_invocation(cb_data);
461         zblib_check_null_free_and_ret("invocation", invocation, cb_data);
462
463         zigbee_zcl_thermostat_complete_setpoint_raise_lower(thermo_object, invocation,
464                 payload->result);
465
466         g_free(cb_data);
467 }
468
469 static gboolean on_thermostat_setpoint_raise_lower(ZigbeeZcl_thermostat *thermostat_object,
470         GDBusMethodInvocation *invocation,
471         gshort node_id,
472         gchar endpoint,
473         gchar mode,
474         gchar amount,
475         gpointer user_data)
476 {
477         ZigBeeServiceInterface *service_interface = (ZigBeeServiceInterface *)user_data;
478         ZigbeeZclThermostatSetpointRaiseLower_t req;
479         ZigbeeServiceInterfaceRespCbData_t *resp_cb_data = NULL;
480
481         gboolean ret;
482
483         memset(&req, 0x0, sizeof(ZigbeeZclThermostatSetpointRaiseLower_t));
484
485         /* Update request structure */
486         req.node_id = node_id;
487         req.endpoint = endpoint;
488         req.mode = mode;
489         req.amount = amount;
490
491         /* Allocate response callback data */
492         resp_cb_data =
493                 zigbee_service_dbus_interface_create_resp_cb_data(thermostat_object,
494                         invocation, NULL, 0);
495         if (NULL == resp_cb_data) {
496                 Z_LOGE("zigbee_service_dbus_interface_create_resp_cb_data failed!");
497
498                 /* Send failure response */
499                 ZIGBEE_DBUS_FAIL_RESPONSE(invocation, ZIGBEE_DBUS_DEFAULT_REQ_FAILED_MSG);
500
501                 return TRUE;
502         }
503
504         /* Dispatch request */
505         ret = zigbee_service_dbus_interface_dispatch_request(service_interface,
506                 ZBLIB_DRIVER_TYPE_ZCL_THERMOSTAT,
507                 ZBLIB_ZCL_THERMOSTAT_OPS_SETPOINT_RAISE_LOWER,
508                 &req, sizeof(req),
509                 on_thermostat_setpoint_raise_lower_resp, resp_cb_data);
510         if (FALSE == ret) {
511                 Z_LOGE("zigbee_service_dbus_interface_dispatch_request failed!");
512
513                 /* Free response callback data */
514                 zigbee_service_dbus_interface_destroy_resp_cb_data(resp_cb_data);
515
516                 /* Send failure response */
517                 ZIGBEE_DBUS_FAIL_RESPONSE(invocation, ZIGBEE_DBUS_DEFAULT_REQ_FAILED_MSG);
518
519                 return TRUE;
520         }
521
522         return TRUE;
523 }
524
525 void zigbee_service_dbus_interface_zcl_thermostat_notification(ZigBeeServiceInterface *service_interface,
526         guint noti_id, gpointer noti_data, guint noti_data_len, gpointer noti_cb_data)
527 {
528         ZigbeeZcl_thermostat *thermo_object;
529
530         zblib_check_null_ret("service_interface", service_interface);
531
532         if (NULL == noti_data || 0 == noti_data_len) {
533                 Z_LOGE("noti_data=%p or noti_data_len=%d is null", noti_data, noti_data_len);
534                 return;
535         }
536
537         thermo_object = _service_interface_ref_zigbee_zcl_thermostat(service_interface);
538         zblib_check_null_ret("thermo_object", thermo_object);
539
540         NOT_USED(noti_cb_data);
541
542         switch (noti_id) {
543         default:
544                 Z_LOGE("Unexpected notification [%x]", noti_id);
545         break;
546         }
547
548         /* ZigbeeZcl_thermostat should be dereferenced */
549         g_object_unref(thermo_object);
550
551 }
552 /* LCOV_EXCL_STOP */
553
554 gboolean zigbee_service_dbus_interface_zcl_thermostat_init(ZigBeeServiceInterface *service_interface,
555         ZigbeeObjectSkeleton *zigbee_object)
556 {
557         ZigbeeZcl_thermostat *thermostat_object;
558
559         if (NULL == service_interface) {
560                 /* LCOV_EXCL_START */
561                 Z_LOGE("service_interface is NULL");
562                 return FALSE;
563                 /* LCOV_EXCL_STOP */
564         }
565
566         thermostat_object = zigbee_zcl_thermostat_skeleton_new();
567         zigbee_object_skeleton_set_zcl_thermostat(zigbee_object, thermostat_object);
568         g_object_unref(thermostat_object);
569
570         Z_LOGI("thermostat_object: [%p]", thermostat_object);
571
572         /*
573          * Register signal handlers for 'thermostat' interface
574          */
575         g_signal_connect(thermostat_object,
576                 "handle-get-local-temp",
577                 G_CALLBACK(on_thermostat_get_local_temp), service_interface);
578
579         g_signal_connect(thermostat_object,
580                 "handle-get-weekly-schedule",
581                 G_CALLBACK(on_thermostat_get_weekly_schedule), service_interface);
582
583         g_signal_connect(thermostat_object,
584                 "handle-set-weekly-schedule",
585                 G_CALLBACK(on_thermostat_set_weekly_schedule), service_interface);
586
587         g_signal_connect(thermostat_object,
588                 "handle-clear-weekly-schedule",
589                 G_CALLBACK(on_thermostat_clear_weekly_schedule), service_interface);
590
591         g_signal_connect(thermostat_object,
592                 "handle-setpoint-raise-lower",
593                 G_CALLBACK(on_thermostat_setpoint_raise_lower), service_interface);
594
595         return TRUE;
596 }