liblightify
liblightify++.hpp
Go to the documentation of this file.
1 /*
2  liblightify -- library to control OSRAM's LIGHTIFY
3 
4  Copyright (c) 2015, Tobias Frost <tobi@coldtobi.de>
5  All rights reserved.
6 
7  Redistribution and use in source and binary forms, with or without
8  modification, are permitted provided that the following conditions are met:
9 
10  * Redistributions of source code must retain the above copyright
11  notice, this list of conditions and the following disclaimer.
12 
13  * Redistributions in binary form must reproduce the above copyright
14  notice, this list of conditions and the following disclaimer in the
15  documentation and/or other materials provided with the distribution.
16 
17  * Neither the name of the author nor the
18  names of its contributors may be used to endorse or promote products
19  derived from this software without specific prior written permission.
20 
21  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
22  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24  DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
25  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
28  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 
40 #ifndef SRC_LIBLIGHTIFY___LIGHTIFY___HPP_
41 #define SRC_LIBLIGHTIFY___LIGHTIFY___HPP_
42 
43 
45 #include <string.h>
46 
47 #include <netdb.h>
48 #include <unistd.h>
49 #include <errno.h>
50 #include <sys/socket.h>
51 #include <netinet/in.h>
52 #include <netinet/ip.h>
53 
55 #undef LIGHTIFY_ALLOW_THROW
56 #ifdef LIGHTIFY_ALLOW_THROW
57 #include <stdexcept>
58 #endif
59 
61  friend class Lightify;
62 protected:
64  struct lightify_node *node) {
65  _ctx = ctx;
66  _node = node;
67  }
68 
69 public:
70  // NOTE: Getters of node information will generally access cached data.
71  // An update from the actual node data has to be explicitly requested.
72  // An exception is the Name: It can only be queried with a scan.
73 
75  const char *GetName(void) const {
76  return lightify_node_get_name(_node);
77  }
78 
80  unsigned long long GetMAC(void) const {
81  return lightify_node_get_nodeadr(_node);
82  }
83 
85  unsigned int GetZoneAdr(void) const{
86  return lightify_node_get_zoneadr(_node);
87  }
88 
90  unsigned int GetGroup(void) const{
91  return lightify_node_get_grpadr(_node);
92  }
93 
96  return lightify_node_get_lamptype(_node);
97  }
98 
100  int GetRed(void) const {
101  return lightify_node_get_red(_node);
102  }
103 
105  int GetBlue(void) const {
106  return lightify_node_get_blue(_node);
107  }
108 
110  int GetGreen(void) const {
111  return lightify_node_get_green(_node);
112  }
113 
115  int GetWhite(void) const {
116  return lightify_node_get_white(_node);
117  }
118 
120  int GetCCT(void) const {
121  return lightify_node_get_cct(_node);
122  }
123 
125  int GetBrightness(void) const {
126  return lightify_node_get_brightness(_node);
127  }
128 
130  int IsOn(void) const {
131  return lightify_node_is_on(_node);
132  }
133 
135  int GetOnlineState(void) const {
136  return lightify_node_get_onlinestate(_node);
137  }
138 
142  int IsStale(void) const {
143  return lightify_node_is_stale(_node);
144  }
145 
146  /* The setter functions actually talk with the nodes.
147  * After setting the values are *not* verified from the hardware,
148  * only the cache will be updated.
149  *
150  * */
151 
153  int TurnOnOff(bool onoff) {
154  return lightify_node_request_onoff(_ctx, _node, onoff);
155  }
156 
164  int SetCCT(int cct, int time) {
165  return lightify_node_request_cct(_ctx, _node, cct, time);
166  }
167 
182  int SetRGBW(int red, int green, int blue, int white, int time) {
183  return lightify_node_request_rgbw(_ctx,_node, red, green, blue, white, time);
184  }
185 
193  int SetBrightness(int level, int time) {
194  return lightify_node_request_brightness(_ctx, _node, level, time);
195  }
196 
205  int UpdateNodeInfo(void) {
206  return lightify_node_request_update(_ctx, _node);
207  }
208 
209 
210 private:
211  Lightify_Node(const Lightify_Node &other) {
212  // No copies!
213  }
214 
215 private:
216  struct lightify_node *_node;
217  struct lightify_ctx *_ctx;
218 };
219 
221  friend class Lightify;
222 protected:
224  struct lightify_group *group) {
225  _ctx = ctx;
226  _group = group;
227  }
228 
229 public:
230  int GetId() {
231  return lightify_group_get_id(_group);
232  }
233 
234  const char *GetName() {
235  return lightify_group_get_name(_group);
236  }
237 
239  int TurnOnOff(bool onoff) {
240  return lightify_group_request_onoff(_ctx, _group, onoff);
241  }
242 
250  int SetCCT(int cct, int time) {
251  return lightify_group_request_cct(_ctx, _group, cct, time);
252  }
253 
268  int SetRGBW(int red, int green, int blue, int white, int time) {
269  return lightify_group_request_rgbw(_ctx,_group, red, green, blue, white, time);
270  }
271 
279  int SetBrightness(int level, int time) {
280  return lightify_group_request_brightness(_ctx, _group, level, time);
281  }
282 
283 
284 private:
285  Lightify_Group(const Lightify_Group &) {
286  // No copies!
287  // Just to avoid warnings..
288  _ctx = NULL; _group = NULL;
289  }
290 
291 
292 
293 private:
294  struct lightify_group *_group;
295  struct lightify_ctx *_ctx;
296 };
297 
304 class Lightify {
305 public:
308  Lightify(const char *host, unsigned int port=4000) {
309  _host = 0;
310  if (host) {
311  _host = strdup(host);
312  }
313  _port = port;
314  _sockfd = -1;
315  _ctx = NULL;
316  _nodesmap = NULL;
317  _groupsmap = NULL;
318  _no_nodes = 0;
319  _no_groups = 0;
320 
321  int err = lightify_new(&_ctx, NULL);
322 #ifdef LIGHTIFY_ALLOW_THROW
323  if (err < 0 || !_ctx) {
324  throw std::bad_alloc;
325  }
326 #endif
327  }
328 
329  virtual ~Lightify() {
330  if (_ctx) lightify_free(_ctx);
331  if (_host) free(_host);
332  if (_sockfd != -1) close(_sockfd);
333  _free_nodemap();
334  _free_groupmap();
335  }
336 
339  int Open(void) {
340 
341  if (_sockfd > 0) {
342  int e = Close();
343  if (e < 0) return e;
344  }
345 
346  int err;
347  struct sockaddr_in serv_addr;
348  struct hostent *server;
349 
350  _sockfd = socket(AF_INET, SOCK_STREAM, 0);
351 
352  if (_sockfd < 0) {
353  err = _sockfd;
354  _sockfd = -1;
355  return err;
356  }
357 
358  // FIXME gethostbyname is depreciated.
359  server = gethostbyname(_host);
360  if (server == NULL) {
361  // no such host
362  err = h_errno;
363  if (err >= 0) err = -EHOSTUNREACH;
364  goto err_out;
365  }
366 
367  memset((char *) &serv_addr, 0, sizeof(serv_addr));
368  serv_addr.sin_family = AF_INET;
369  memcpy((char *) &serv_addr.sin_addr.s_addr, (char *) server->h_addr,
370  server->h_length);
371  serv_addr.sin_port = htons(_port);
372 
373  /* Now connect to the server */
374  err = connect(_sockfd, (struct sockaddr*) &serv_addr, sizeof(serv_addr));
375  if (err < 0) {
376  err = -errno;
377  goto err_out;
378  }
379 
380  err = lightify_skt_setfd(_ctx, _sockfd);
381  if (err < 0) {
382  goto err_out;
383  }
384 
385  return 0;
386 
387 err_out:
388  if (_sockfd > 0) Close();
389  return err;
390 
391  }
392 
394  int Close(void) {
395  int i = 20;
396  if (_sockfd == -1) return -EBADF;
398  int local_socketfd = _sockfd;
399  _sockfd = -1;
400  /* Retry interrupted system calls, but with capped iteration count.*/
401  while (--i && 0 != close(local_socketfd)) {
402  if (errno != EINTR) return errno;
403  }
404  if (!i) return -EINTR;
405  return 0;
406  }
407 
410  int ScanNodes(void) {
411 
412  int err;
413  if (_sockfd == -1) return -EBADF;
414  _free_nodemap();
416  if (err < 0) return err;
417 
418  struct lean_nodemap *last_inserted = NULL;
419  struct lightify_node *node = NULL;
420  while(node = lightify_node_get_next(_ctx,node)) {
421  struct lean_nodemap *nm = new lean_nodemap();
422  if (!nm) return -ENOMEM;
423  nm->next = 0;
424  nm->node = new Lightify_Node(_ctx,node);
425  if (!nm->node) {
426  delete nm;
427  return -ENOMEM;
428  }
429 
430  if (!last_inserted) {
431  _nodesmap = nm;
432  } else {
433  last_inserted->next = nm;
434  }
435  last_inserted = nm;
436  _no_nodes ++;
437  }
438  return _no_nodes;
439 
440  }
441 
448  int ScanGroups(void) {
449  int err;
450  if (_sockfd == -1) return -EBADF;
451  _free_groupmap();
453  if (err < 0) return err;
454 
455  struct lean_groupmap *last_inserted = NULL;
456  struct lightify_group *group = NULL;
457  while ( (group = lightify_group_get_next(_ctx, group))) {
458  struct lean_groupmap *gm = new lean_groupmap();
459  if (!gm) return -ENOMEM;
460  gm->next = NULL;
461  gm-> group = new Lightify_Group(_ctx, group);
462  if (!gm->group) {
463  delete gm;
464  return -ENOMEM;
465  }
466 
467  if (!last_inserted) {
468  _groupsmap = gm;
469  } else {
470  last_inserted->next = gm;
471  }
472  last_inserted = gm;
473  _no_groups++;
474  }
475  return _no_groups;
476  }
477 
483  struct lightify_ctx *GetCtx(void) {
484  return _ctx;
485  }
486 
488  int TurnAllOnOff(bool onoff)
489  {
490  return lightify_node_request_onoff(_ctx,NULL,onoff);
491  }
492 
494  Lightify_Node *GetNode(long long mac) {
495  struct lean_nodemap *nm = _nodesmap;
496  while(nm) {
497  if (nm->node->GetMAC() == mac) return nm->node;
498  nm = nm->next;
499  }
500  return NULL;
501  }
502 
508  Lightify_Node* GetNodeAtPosX(int x) const {
509  if (x >= _no_nodes) return NULL;
510  struct lean_nodemap *nm = _nodesmap;
511  while(nm && x--) nm = nm->next;
512  return (nm ? nm->node : NULL);
513  }
514 
520  Lightify_Group* GetGroupAtPosX(int pos) const {
521  if (pos >= _no_groups) return NULL;
522  struct lean_groupmap *gm = _groupsmap;
523  while(pos--) gm = gm->next;
524  return gm->group;
525  }
526 
529  const struct lightify_ctx *GetLightifyContext(void) const {
530  return _ctx;
531  }
532 
538  int IsOpen(void) const
539  {
540  return (_sockfd > 0);
541  }
542 
552  int SetHostname(const char *host, unsigned int port=4000) {
553  if (!host) return -EINVAL;
554  if (port > 0xFFFFUL) return -EINVAL;
555 
556  if (_host) free(_host);
557  _host = strdup(host);
558  if (!_host) return -ENOMEM;
559  return 0;
560  }
561 
562 
563  int GetNodesCount(void) {
564  return _no_nodes;
565  }
566 
567  int GetGroupsCount(void) {
568  return _no_groups;
569  }
570 
571 
572 private:
573  void _free_nodemap(void) {
574  struct lean_nodemap *nmtmp, *nm = _nodesmap;
575  while (nm) {
576  nmtmp = nm->next;
577  delete nm->node;
578  delete nm;
579  nm = nmtmp;
580  }
581  _nodesmap = NULL;
582  _no_nodes = 0;
583  }
584 
585  void _free_groupmap(void) {
586  struct lean_groupmap *gmtmp, *gm = _groupsmap;
587  while (gm) {
588  gmtmp = gm->next;
589  delete gm->group;
590  delete gm;
591  gm = gmtmp;
592  }
593  _groupsmap = NULL;
594  _no_groups = 0;
595  }
596 
597  struct lightify_ctx *_ctx;
598  char *_host;
599  unsigned int _port;
600  int _sockfd;
601 
602  // this is to avoid avoid STL...
603  struct lean_nodemap {
604  struct lean_nodemap *next;
605  Lightify_Node *node;
606  };
607 
608  struct lean_groupmap {
609  struct lean_groupmap *next;
610  Lightify_Group *group;
611  };
612 
613  struct lean_nodemap *_nodesmap;
614  struct lean_groupmap *_groupsmap;
615 
616  int _no_nodes;
617  int _no_groups;
618 };
619 
620 
621 #endif /* SRC_LIBLIGHTIFY___LIGHTIFY___HPP_ */
Lightify_Node::GetName
const char * GetName(void) const
Definition: liblightify++.hpp:75
lightify_free
LIGHTIFY_EXPORT int lightify_free(struct lightify_ctx *ctx)
Definition: context.c:494
Lightify_Node::GetBlue
int GetBlue(void) const
Definition: liblightify++.hpp:105
lightify_node_get_lamptype
enum lightify_node_type lightify_node_get_lamptype(struct lightify_node *node)
Definition: node.c:208
lightify_node_request_onoff
LIGHTIFY_EXPORT int lightify_node_request_onoff(struct lightify_ctx *ctx, struct lightify_node *node, int onoff)
Definition: context.c:922
lightify_node_get_brightness
int lightify_node_get_brightness(struct lightify_node *node)
Definition: node.c:274
Lightify::Open
int Open(void)
Definition: liblightify++.hpp:339
err
#define err(ctx, arg...)
Lightify_Group::Lightify_Group
Lightify_Group(struct lightify_ctx *ctx, struct lightify_group *group)
Definition: liblightify++.hpp:223
Lightify::SetHostname
int SetHostname(const char *host, unsigned int port=4000)
Definition: liblightify++.hpp:552
Lightify_Node::SetRGBW
int SetRGBW(int red, int green, int blue, int white, int time)
Definition: liblightify++.hpp:182
Lightify_Node::GetRed
int GetRed(void) const
Definition: liblightify++.hpp:100
lightify_skt_setfd
int lightify_skt_setfd(struct lightify_ctx *ctx, int socket)
Definition: socket.c:204
Lightify_Node::GetLampType
lightify_node_type GetLampType(void) const
Definition: liblightify++.hpp:95
Lightify_Group
Definition: liblightify++.hpp:220
Lightify::Close
int Close(void)
Definition: liblightify++.hpp:394
Lightify::IsOpen
int IsOpen(void) const
Definition: liblightify++.hpp:538
lightify_group_request_brightness
LIGHTIFY_EXPORT int lightify_group_request_brightness(struct lightify_ctx *ctx, struct lightify_group *group, unsigned int level, unsigned int fadetime)
Definition: context.c:1223
lightify_node_request_scan
LIGHTIFY_EXPORT int lightify_node_request_scan(struct lightify_ctx *ctx)
Definition: context.c:505
lightify_group_request_scan
LIGHTIFY_EXPORT int lightify_group_request_scan(struct lightify_ctx *ctx)
Definition: context.c:1082
lightify_node_get_name
const char * lightify_node_get_name(struct lightify_node *node)
Definition: node.c:164
lightify_node_is_on
int lightify_node_is_on(struct lightify_node *node)
Definition: node.c:286
lightify_group
Definition: groups.c:46
Lightify::TurnAllOnOff
int TurnAllOnOff(bool onoff)
Definition: liblightify++.hpp:488
Lightify_Node::Lightify_Node
Lightify_Node(struct lightify_ctx *ctx, struct lightify_node *node)
Definition: liblightify++.hpp:63
port
int port
Definition: lightify-util.c:97
Lightify::GetNodeAtPosX
Lightify_Node * GetNodeAtPosX(int x) const
Definition: liblightify++.hpp:508
Lightify::Lightify
Lightify(const char *host, unsigned int port=4000)
Definition: liblightify++.hpp:308
lightify_node_get_nodeadr
uint64_t lightify_node_get_nodeadr(struct lightify_node *node)
Definition: node.c:175
lightify_node_get_grpadr
uint16_t lightify_node_get_grpadr(struct lightify_node *node)
Definition: node.c:197
Lightify_Node::GetGreen
int GetGreen(void) const
Definition: liblightify++.hpp:110
Lightify_Node::GetMAC
unsigned long long GetMAC(void) const
Definition: liblightify++.hpp:80
lightify_node_get_red
int lightify_node_get_red(struct lightify_node *node)
Definition: node.c:219
_ctx
struct lightify_ctx * _ctx
Definition: test-lightify.c:40
Lightify
Definition: liblightify++.hpp:304
Lightify::ScanGroups
int ScanGroups(void)
Definition: liblightify++.hpp:448
Lightify_Node::SetBrightness
int SetBrightness(int level, int time)
Definition: liblightify++.hpp:193
Lightify_Node
Enable the use of exception within this wrapper.
Definition: liblightify++.hpp:60
Lightify_Group::SetCCT
int SetCCT(int cct, int time)
Definition: liblightify++.hpp:250
Lightify_Node::IsOn
int IsOn(void) const
Definition: liblightify++.hpp:130
Lightify_Group::TurnOnOff
int TurnOnOff(bool onoff)
Definition: liblightify++.hpp:239
liblightify.h
Lightify::GetGroupAtPosX
Lightify_Group * GetGroupAtPosX(int pos) const
Definition: liblightify++.hpp:520
lightify_node_request_brightness
LIGHTIFY_EXPORT int lightify_node_request_brightness(struct lightify_ctx *ctx, struct lightify_node *node, unsigned int level, unsigned int fadetime)
Definition: context.c:975
Lightify::GetNode
Lightify_Node * GetNode(long long mac)
Definition: liblightify++.hpp:494
Lightify_Node::GetGroup
unsigned int GetGroup(void) const
Definition: liblightify++.hpp:90
lightify_node_get_green
int lightify_node_get_green(struct lightify_node *node)
Definition: node.c:241
Lightify_Node::GetOnlineState
int GetOnlineState(void) const
Definition: liblightify++.hpp:135
lightify_node_type
lightify_node_type
Definition: liblightify.h:105
Lightify_Node::IsStale
int IsStale(void) const
Definition: liblightify++.hpp:142
Lightify_Node::GetCCT
int GetCCT(void) const
Definition: liblightify++.hpp:120
lightify_node
Definition: node.c:43
Lightify::GetLightifyContext
const struct lightify_ctx * GetLightifyContext(void) const
Definition: liblightify++.hpp:529
lightify_ctx
Definition: context.h:68
lightify_node_get_zoneadr
uint16_t lightify_node_get_zoneadr(struct lightify_node *node)
Definition: node.c:186
lightify_new
LIGHTIFY_EXPORT int lightify_new(struct lightify_ctx **ctx, void *reserved)
Definition: context.c:445
lightify_node_get_cct
int lightify_node_get_cct(struct lightify_node *node)
Definition: node.c:263
Lightify_Node::GetBrightness
int GetBrightness(void) const
Definition: liblightify++.hpp:125
lightify_node_get_next
LIGHTIFY_EXPORT struct lightify_node * lightify_node_get_next(struct lightify_ctx *ctx, struct lightify_node *node)
Definition: context.c:402
Lightify_Group::GetId
int GetId()
Definition: liblightify++.hpp:230
lightify_group_request_cct
LIGHTIFY_EXPORT int lightify_group_request_cct(struct lightify_ctx *ctx, struct lightify_group *group, unsigned int cct, unsigned int fadetime)
Definition: context.c:1192
lightify_node_get_white
int lightify_node_get_white(struct lightify_node *node)
Definition: node.c:252
lightify_group_request_rgbw
LIGHTIFY_EXPORT int lightify_group_request_rgbw(struct lightify_ctx *ctx, struct lightify_group *group, unsigned int r, unsigned int g, unsigned int b, unsigned int w, unsigned int fadetime)
Definition: context.c:1205
lightify_group_get_id
LIGHTIFY_EXPORT int lightify_group_get_id(struct lightify_group *grp)
Definition: groups.c:128
Lightify_Node::UpdateNodeInfo
int UpdateNodeInfo(void)
Definition: liblightify++.hpp:205
Lightify::GetNodesCount
int GetNodesCount(void)
Definition: liblightify++.hpp:563
lightify_group_request_onoff
LIGHTIFY_EXPORT int lightify_group_request_onoff(struct lightify_ctx *ctx, struct lightify_group *group, int onoff)
Definition: context.c:1178
Lightify_Node::SetCCT
int SetCCT(int cct, int time)
Definition: liblightify++.hpp:164
Lightify::ScanNodes
int ScanNodes(void)
Definition: liblightify++.hpp:410
Lightify::GetCtx
struct lightify_ctx * GetCtx(void)
Definition: liblightify++.hpp:483
Lightify_Node::GetZoneAdr
unsigned int GetZoneAdr(void) const
Definition: liblightify++.hpp:85
lightify_group_get_next
LIGHTIFY_EXPORT struct lightify_group * lightify_group_get_next(struct lightify_ctx *ctx, struct lightify_group *current)
Definition: groups.c:134
Lightify_Node::GetWhite
int GetWhite(void) const
Definition: liblightify++.hpp:115
lightify_node_get_onlinestate
int lightify_node_get_onlinestate(struct lightify_node *node)
Definition: node.c:297
Lightify::~Lightify
virtual ~Lightify()
Definition: liblightify++.hpp:329
Lightify_Group::SetRGBW
int SetRGBW(int red, int green, int blue, int white, int time)
Definition: liblightify++.hpp:268
Lightify_Group::GetName
const char * GetName()
Definition: liblightify++.hpp:234
Lightify::GetGroupsCount
int GetGroupsCount(void)
Definition: liblightify++.hpp:567
lightify_node_request_update
LIGHTIFY_EXPORT int lightify_node_request_update(struct lightify_ctx *ctx, struct lightify_node *node)
Definition: context.c:987
lightify_node_request_rgbw
LIGHTIFY_EXPORT int lightify_node_request_rgbw(struct lightify_ctx *ctx, struct lightify_node *node, unsigned int r, unsigned int g, unsigned int b, unsigned int w, unsigned int fadetime)
Definition: context.c:959
Lightify_Node::TurnOnOff
int TurnOnOff(bool onoff)
Definition: liblightify++.hpp:153
lightify_group_get_name
const LIGHTIFY_EXPORT char * lightify_group_get_name(struct lightify_group *grp)
Definition: groups.c:117
lightify_node_is_stale
int lightify_node_is_stale(struct lightify_node *node)
Definition: node.c:302
Lightify_Group::SetBrightness
int SetBrightness(int level, int time)
Definition: liblightify++.hpp:279
lightify_node_request_cct
LIGHTIFY_EXPORT int lightify_node_request_cct(struct lightify_ctx *ctx, struct lightify_node *node, unsigned int cct, unsigned int fadetime)
Definition: context.c:947
lightify_node_get_blue
int lightify_node_get_blue(struct lightify_node *node)
Definition: node.c:230