liblightify++.hpp
Go to the documentation of this file.
/*
liblightify -- library to control OSRAM's LIGHTIFY
Copyright (c) 2015, Tobias Frost <tobi@coldtobi.de>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the author nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SRC_LIBLIGHTIFY___LIGHTIFY___HPP_
#define SRC_LIBLIGHTIFY___LIGHTIFY___HPP_
#include <liblightify/liblightify.h>
#include <string.h>
#include <netdb.h>
#include <unistd.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#undef LIGHTIFY_ALLOW_THROW
#ifdef LIGHTIFY_ALLOW_THROW
#include <stdexcept>
#endif
class Lightify_Node {
friend class Lightify;
protected:
Lightify_Node(struct lightify_ctx *ctx,
struct lightify_node *node) {
_ctx = ctx;
_node = node;
}
public:
// NOTE: Getters of node information will generally access cached data.
// An update from the actual node data has to be explicitly requested.
// An exception is the Name: It can only be queried with a scan.
const char *GetName(void) const {
return lightify_node_get_name(_node);
}
unsigned long long GetMAC(void) const {
return lightify_node_get_nodeadr(_node);
}
unsigned int GetZoneAdr(void) const{
return lightify_node_get_zoneadr(_node);
}
unsigned int GetGroup(void) const{
return lightify_node_get_grpadr(_node);
}
lightify_node_type GetLampType(void)const {
return lightify_node_get_lamptype(_node);
}
int GetRed(void) const {
return lightify_node_get_red(_node);
}
int GetBlue(void) const {
return lightify_node_get_blue(_node);
}
int GetGreen(void) const {
return lightify_node_get_green(_node);
}
int GetWhite(void) const {
return lightify_node_get_white(_node);
}
int GetCCT(void) const {
return lightify_node_get_cct(_node);
}
int GetBrightness(void) const {
return lightify_node_get_brightness(_node);
}
int IsOn(void) const {
return lightify_node_is_on(_node);
}
int GetOnlineState(void) const {
return lightify_node_get_onlinestate(_node);
}
int IsStale(void) const {
return lightify_node_is_stale(_node);
}
/* The setter functions actually talk with the nodes.
* After setting the values are *not* verified from the hardware,
* only the cache will be updated.
*
* */
int TurnOnOff(bool onoff) {
return lightify_node_request_onoff(_ctx, _node, onoff);
}
int SetCCT(int cct, int time) {
return lightify_node_request_cct(_ctx, _node, cct, time);
}
int SetRGBW(int red, int green, int blue, int white, int time) {
return lightify_node_request_rgbw(_ctx,_node, red, green, blue, white, time);
}
int SetBrightness(int level, int time) {
return lightify_node_request_brightness(_ctx, _node, level, time);
}
int UpdateNodeInfo(void) {
return lightify_node_request_update(_ctx, _node);
}
private:
Lightify_Node(const Lightify_Node &other) {
// No copies!
}
private:
struct lightify_node *_node;
struct lightify_ctx *_ctx;
};
class Lightify_Group {
friend class Lightify;
protected:
Lightify_Group(struct lightify_ctx *ctx,
struct lightify_group *group) {
_ctx = ctx;
_group = group;
}
public:
int GetId() {
return lightify_group_get_id(_group);
}
const char *GetName() {
return lightify_group_get_name(_group);
}
int TurnOnOff(bool onoff) {
return lightify_group_request_onoff(_ctx, _group, onoff);
}
int SetCCT(int cct, int time) {
return lightify_group_request_cct(_ctx, _group, cct, time);
}
int SetRGBW(int red, int green, int blue, int white, int time) {
return lightify_group_request_rgbw(_ctx,_group, red, green, blue, white, time);
}
int SetBrightness(int level, int time) {
return lightify_group_request_brightness(_ctx, _group, level, time);
}
private:
Lightify_Group(const Lightify_Group &) {
// No copies!
// Just to avoid warnings..
_ctx = NULL; _group = NULL;
}
private:
struct lightify_group *_group;
struct lightify_ctx *_ctx;
};
class Lightify {
public:
Lightify(const char *host, unsigned int port=4000) {
_host = 0;
if (host) {
_host = strdup(host);
}
_port = port;
_sockfd = -1;
_ctx = NULL;
_nodesmap = NULL;
_groupsmap = NULL;
_no_nodes = 0;
_no_groups = 0;
int err = lightify_new(&_ctx, NULL);
#ifdef LIGHTIFY_ALLOW_THROW
if (err < 0 || !_ctx) {
throw std::bad_alloc;
}
#endif
}
virtual ~Lightify() {
if (_ctx) lightify_free(_ctx);
if (_host) free(_host);
if (_sockfd != -1) close(_sockfd);
_free_nodemap();
_free_groupmap();
}
int Open(void) {
if (_sockfd > 0) {
int e = Close();
if (e < 0) return e;
}
int err;
struct sockaddr_in serv_addr;
struct hostent *server;
_sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (_sockfd < 0) {
err = _sockfd;
_sockfd = -1;
return err;
}
// FIXME gethostbyname is depreciated.
server = gethostbyname(_host);
if (server == NULL) {
// no such host
err = h_errno;
if (err >= 0) err = -EHOSTUNREACH;
goto err_out;
}
memset((char *) &serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
memcpy((char *) &serv_addr.sin_addr.s_addr, (char *) server->h_addr,
server->h_length);
serv_addr.sin_port = htons(_port);
/* Now connect to the server */
err = connect(_sockfd, (struct sockaddr*) &serv_addr, sizeof(serv_addr));
if (err < 0) {
err = -errno;
goto err_out;
}
err = lightify_skt_setfd(_ctx, _sockfd);
if (err < 0) {
goto err_out;
}
return 0;
err_out:
if (_sockfd > 0) Close();
return err;
}
int Close(void) {
int i = 20;
if (_sockfd == -1) return -EBADF;
lightify_skt_setfd(_ctx, -1);
int local_socketfd = _sockfd;
_sockfd = -1;
/* Retry interrupted system calls, but with capped iteration count.*/
while (--i && 0 != close(local_socketfd)) {
if (errno != EINTR) return errno;
}
if (!i) return -EINTR;
return 0;
}
int ScanNodes(void) {
int err;
if (_sockfd == -1) return -EBADF;
_free_nodemap();
err = lightify_node_request_scan(_ctx);
if (err < 0) return err;
struct lean_nodemap *last_inserted = NULL;
struct lightify_node *node = NULL;
while(node = lightify_node_get_next(_ctx,node)) {
struct lean_nodemap *nm = new lean_nodemap();
if (!nm) return -ENOMEM;
nm->next = 0;
nm->node = new Lightify_Node(_ctx,node);
if (!nm->node) {
delete nm;
return -ENOMEM;
}
if (!last_inserted) {
_nodesmap = nm;
} else {
last_inserted->next = nm;
}
last_inserted = nm;
_no_nodes ++;
}
return _no_nodes;
}
int ScanGroups(void) {
int err;
if (_sockfd == -1) return -EBADF;
_free_groupmap();
err = lightify_group_request_scan(_ctx);
if (err < 0) return err;
struct lean_groupmap *last_inserted = NULL;
struct lightify_group *group = NULL;
while ( (group = lightify_group_get_next(_ctx, group))) {
struct lean_groupmap *gm = new lean_groupmap();
if (!gm) return -ENOMEM;
gm->next = NULL;
gm-> group = new Lightify_Group(_ctx, group);
if (!gm->group) {
delete gm;
return -ENOMEM;
}
if (!last_inserted) {
_groupsmap = gm;
} else {
last_inserted->next = gm;
}
last_inserted = gm;
_no_groups++;
}
return _no_groups;
}
struct lightify_ctx *GetCtx(void) {
return _ctx;
}
int TurnAllOnOff(bool onoff)
{
return lightify_node_request_onoff(_ctx,NULL,onoff);
}
Lightify_Node *GetNode(long long mac) {
struct lean_nodemap *nm = _nodesmap;
while(nm) {
if (nm->node->GetMAC() == mac) return nm->node;
nm = nm->next;
}
return NULL;
}
Lightify_Node* GetNodeAtPosX(int x) const {
if (x >= _no_nodes) return NULL;
struct lean_nodemap *nm = _nodesmap;
while(nm && x--) nm = nm->next;
return (nm ? nm->node : NULL);
}
Lightify_Group* GetGroupAtPosX(int pos) const {
if (pos >= _no_groups) return NULL;
struct lean_groupmap *gm = _groupsmap;
while(pos--) gm = gm->next;
return gm->group;
}
const struct lightify_ctx *GetLightifyContext(void) const {
return _ctx;
}
int IsOpen(void) const
{
return (_sockfd > 0);
}
int SetHostname(const char *host, unsigned int port=4000) {
if (!host) return -EINVAL;
if (port > 0xFFFFUL) return -EINVAL;
if (_host) free(_host);
_host = strdup(host);
if (!_host) return -ENOMEM;
return 0;
}
int GetNodesCount(void) {
return _no_nodes;
}
int GetGroupsCount(void) {
return _no_groups;
}
private:
void _free_nodemap(void) {
struct lean_nodemap *nmtmp, *nm = _nodesmap;
while (nm) {
nmtmp = nm->next;
delete nm->node;
delete nm;
nm = nmtmp;
}
_nodesmap = NULL;
_no_nodes = 0;
}
void _free_groupmap(void) {
struct lean_groupmap *gmtmp, *gm = _groupsmap;
while (gm) {
gmtmp = gm->next;
delete gm->group;
delete gm;
gm = gmtmp;
}
_groupsmap = NULL;
_no_groups = 0;
}
struct lightify_ctx *_ctx;
char *_host;
unsigned int _port;
int _sockfd;
// this is to avoid avoid STL...
struct lean_nodemap {
struct lean_nodemap *next;
Lightify_Node *node;
};
struct lean_groupmap {
struct lean_groupmap *next;
Lightify_Group *group;
};
struct lean_nodemap *_nodesmap;
struct lean_groupmap *_groupsmap;
int _no_nodes;
int _no_groups;
};
#endif /* SRC_LIBLIGHTIFY___LIGHTIFY___HPP_ */
Lightify_Node::GetBlue
int GetBlue(void) const
Definition: liblightify++.hpp:105
err
#define err(ctx, arg...)
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::UpdateNodeInfo
int UpdateNodeInfo(void)
Definition: liblightify++.hpp:205
lightify_skt_setfd
int lightify_skt_setfd(struct lightify_ctx *ctx, int socket)
Definition: socket.c:204
lightify_free
LIGHTIFY_EXPORT int lightify_free(struct lightify_ctx *ctx)
Definition: context.c:494
lightify_node_request_scan
LIGHTIFY_EXPORT int lightify_node_request_scan(struct lightify_ctx *ctx)
Definition: context.c:505
lightify_node_get_name
const char * lightify_node_get_name(struct lightify_node *node)
Definition: node.c:164
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::GetBrightness
int GetBrightness(void) const
Definition: liblightify++.hpp:125
Lightify::GetGroupAtPosX
Lightify_Group * GetGroupAtPosX(int pos) const
Definition: liblightify++.hpp:520
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_Node::GetGreen
int GetGreen(void) const
Definition: liblightify++.hpp:110
Lightify_Node::IsStale
int IsStale(void) const
Definition: liblightify++.hpp:142
lightify_group_request_scan
LIGHTIFY_EXPORT int lightify_group_request_scan(struct lightify_ctx *ctx)
Definition: context.c:1082
Lightify::GetNode
Lightify_Node * GetNode(long long mac)
Definition: liblightify++.hpp:494
Lightify::GetGroupsCount
int GetGroupsCount(void)
Definition: liblightify++.hpp:567
Lightify_Group::Lightify_Group
Lightify_Group(struct lightify_ctx *ctx, struct lightify_group *group)
Definition: liblightify++.hpp:223
Lightify
Definition: liblightify++.hpp:304
lightify_node_get_nodeadr
uint64_t lightify_node_get_nodeadr(struct lightify_node *node)
Definition: node.c:175
Lightify_Group::SetCCT
int SetCCT(int cct, int time)
Definition: liblightify++.hpp:250
lightify_node_is_stale
int lightify_node_is_stale(struct lightify_node *node)
Definition: node.c:302
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::GetCCT
int GetCCT(void) const
Definition: liblightify++.hpp:120
Lightify::Open
int Open(void)
Definition: liblightify++.hpp:339
lightify_ctx
Definition: context.h:68
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_is_on
int lightify_node_is_on(struct lightify_node *node)
Definition: node.c:286
lightify_group_get_id
LIGHTIFY_EXPORT int lightify_group_get_id(struct lightify_group *grp)
Definition: groups.c:128
_ctx
struct lightify_ctx * _ctx
Definition: test-lightify.c:40
Lightify::GetNodesCount
int GetNodesCount(void)
Definition: liblightify++.hpp:563
Lightify::ScanNodes
int ScanNodes(void)
Definition: liblightify++.hpp:410
Lightify_Node::Lightify_Node
Lightify_Node(struct lightify_ctx *ctx, struct lightify_node *node)
Definition: liblightify++.hpp:63
Lightify::Close
int Close(void)
Definition: liblightify++.hpp:394
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::IsOpen
int IsOpen(void) const
Definition: liblightify++.hpp:538
lightify_group
Definition: groups.c:46
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::Lightify
Lightify(const char *host, unsigned int port=4000)
Definition: liblightify++.hpp:308
lightify_node_get_grpadr
uint16_t lightify_node_get_grpadr(struct lightify_node *node)
Definition: node.c:197
port
int port
Definition: lightify-util.c:97
Lightify_Node::GetOnlineState
int GetOnlineState(void) const
Definition: liblightify++.hpp:135
Lightify_Group::TurnOnOff
int TurnOnOff(bool onoff)
Definition: liblightify++.hpp:239
Lightify::ScanGroups
int ScanGroups(void)
Definition: liblightify++.hpp:448
lightify_node_get_red
int lightify_node_get_red(struct lightify_node *node)
Definition: node.c:219
Lightify_Node::GetZoneAdr
unsigned int GetZoneAdr(void) const
Definition: liblightify++.hpp:85
Lightify_Node::GetLampType
lightify_node_type GetLampType(void) const
Definition: liblightify++.hpp:95
Lightify_Node::SetBrightness
int SetBrightness(int level, int time)
Definition: liblightify++.hpp:193
Lightify::GetCtx
struct lightify_ctx * GetCtx(void)
Definition: liblightify++.hpp:483
lightify_node_get_cct
int lightify_node_get_cct(struct lightify_node *node)
Definition: node.c:263
liblightify.h
Lightify::GetNodeAtPosX
Lightify_Node * GetNodeAtPosX(int x) const
Definition: liblightify++.hpp:508
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_node_get_white
int lightify_node_get_white(struct lightify_node *node)
Definition: node.c:252
Lightify_Group::GetId
int GetId()
Definition: liblightify++.hpp:230
lightify_node_type
lightify_node_type
Definition: liblightify.h:105
Lightify_Node::SetCCT
int SetCCT(int cct, int time)
Definition: liblightify++.hpp:164
Lightify_Node::GetMAC
unsigned long long GetMAC(void) const
Definition: liblightify++.hpp:80
Lightify_Node::IsOn
int IsOn(void) const
Definition: liblightify++.hpp:130
Lightify_Node::GetWhite
int GetWhite(void) const
Definition: liblightify++.hpp:115
Lightify_Group::SetRGBW
int SetRGBW(int red, int green, int blue, int white, int time)
Definition: liblightify++.hpp:268
Lightify_Node
Enable the use of exception within this wrapper.
Definition: liblightify++.hpp:60
lightify_new
LIGHTIFY_EXPORT int lightify_new(struct lightify_ctx **ctx, void *reserved)
Definition: context.c:445
lightify_node
Definition: node.c:43
Lightify_Node::TurnOnOff
int TurnOnOff(bool onoff)
Definition: liblightify++.hpp:153
Lightify_Node::GetGroup
unsigned int GetGroup(void) const
Definition: liblightify++.hpp:90
lightify_node_get_lamptype
enum lightify_node_type lightify_node_get_lamptype(struct lightify_node *node)
Definition: node.c:208
Lightify_Node::GetRed
int GetRed(void) const
Definition: liblightify++.hpp:100
lightify_node_get_onlinestate
int lightify_node_get_onlinestate(struct lightify_node *node)
Definition: node.c:297
Lightify::GetLightifyContext
const struct lightify_ctx * GetLightifyContext(void) const
Definition: liblightify++.hpp:529
lightify_node_request_update
LIGHTIFY_EXPORT int lightify_node_request_update(struct lightify_ctx *ctx, struct lightify_node *node)
Definition: context.c:987
Lightify_Group
Definition: liblightify++.hpp:220
Lightify::SetHostname
int SetHostname(const char *host, unsigned int port=4000)
Definition: liblightify++.hpp:552
lightify_node_get_green
int lightify_node_get_green(struct lightify_node *node)
Definition: node.c:241
Lightify::TurnAllOnOff
int TurnAllOnOff(bool onoff)
Definition: liblightify++.hpp:488
Lightify_Group::GetName
const char * GetName()
Definition: liblightify++.hpp:234
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
Lightify_Node::SetRGBW
int SetRGBW(int red, int green, int blue, int white, int time)
Definition: liblightify++.hpp:182
Lightify::~Lightify
virtual ~Lightify()
Definition: liblightify++.hpp:329
lightify_group_get_name
LIGHTIFY_EXPORT const char * lightify_group_get_name(struct lightify_group *grp)
Definition: groups.c:117
Lightify_Group::SetBrightness
int SetBrightness(int level, int time)
Definition: liblightify++.hpp:279
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_node_get_zoneadr
uint16_t lightify_node_get_zoneadr(struct lightify_node *node)
Definition: node.c:186
Lightify_Node::GetName
const char * GetName(void) const
Definition: liblightify++.hpp:75