Skip to content

Commit 41d9d76

Browse files
committed
add group class
1 parent b72b376 commit 41d9d76

File tree

2 files changed

+436
-0
lines changed

2 files changed

+436
-0
lines changed

src/AdafruitIO_Group.cpp

Lines changed: 359 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,359 @@
1+
//
2+
// Adafruit invests time and resources providing this open source code.
3+
// Please support Adafruit and open source hardware by purchasing
4+
// products from Adafruit!
5+
//
6+
// Copyright (c) 2015-2016 Adafruit Industries
7+
// Author: Todd Treece
8+
// Licensed under the MIT license.
9+
//
10+
// All text above must be included in any redistribution.
11+
//
12+
#include "AdafruitIO_Group.h"
13+
#include "AdafruitIO.h"
14+
15+
AdafruitIO_Group::AdafruitIO_Group(AdafruitIO *io, const char *n):AdafruitIO_MQTT()
16+
{
17+
_io = io;
18+
name = n;
19+
20+
_init();
21+
}
22+
23+
AdafruitIO_Group::~AdafruitIO_Group()
24+
{
25+
if(_sub)
26+
delete _sub;
27+
28+
if(_pub)
29+
delete _pub;
30+
31+
if(data)
32+
delete data;
33+
34+
if(_topic)
35+
free(_topic);
36+
37+
if(_group_url)
38+
free(_group_url);
39+
40+
if(_create_url)
41+
free(_create_url);
42+
}
43+
44+
void AdafruitIO_Group::set(const char *feed, char *value)
45+
{
46+
AdafruitIO_Data *f = getFeed(feed);
47+
f->setValue(value);
48+
}
49+
50+
void AdafruitIO_Group::set(const char *feed, bool value)
51+
{
52+
AdafruitIO_Data *f = getFeed(feed);
53+
f->setValue(value);
54+
}
55+
56+
void AdafruitIO_Group::set(const char *feed, String value)
57+
{
58+
AdafruitIO_Data *f = getFeed(feed);
59+
f->setValue(value);
60+
}
61+
62+
void AdafruitIO_Group::set(const char *feed, int value)
63+
{
64+
AdafruitIO_Data *f = getFeed(feed);
65+
f->setValue(value);
66+
}
67+
68+
void AdafruitIO_Group::set(const char *feed, unsigned int value)
69+
{
70+
AdafruitIO_Data *f = getFeed(feed);
71+
f->setValue(value);
72+
}
73+
74+
void AdafruitIO_Group::set(const char *feed, long value)
75+
{
76+
AdafruitIO_Data *f = getFeed(feed);
77+
f->setValue(value);
78+
}
79+
80+
void AdafruitIO_Group::set(const char *feed, unsigned long value)
81+
{
82+
AdafruitIO_Data *f = getFeed(feed);
83+
f->setValue(value);
84+
}
85+
86+
void AdafruitIO_Group::set(const char *feed, float value)
87+
{
88+
AdafruitIO_Data *f = getFeed(feed);
89+
f->setValue(value);
90+
}
91+
92+
void AdafruitIO_Group::set(const char *feed, double value)
93+
{
94+
AdafruitIO_Data *f = getFeed(feed);
95+
f->setValue(value);
96+
}
97+
98+
bool AdafruitIO_Group::save()
99+
{
100+
101+
if(data == NULL)
102+
return false;
103+
104+
char csv[150];
105+
AdafruitIO_Data *cur_data = data;
106+
107+
strcpy(csv, "");
108+
109+
while(cur_data != NULL) {
110+
111+
strcat(csv, cur_data->feedName());
112+
strcat(csv, ",");
113+
strcat(csv, cur_data->toChar());
114+
strcat(csv, "\n");
115+
116+
cur_data = cur_data->next_data;
117+
118+
}
119+
120+
return _pub->publish(csv);
121+
122+
}
123+
124+
AdafruitIO_Data* AdafruitIO_Group::getFeed(const char *feed)
125+
{
126+
uint8_t i;
127+
128+
if(data == NULL) {
129+
data = new AdafruitIO_Data(feed);
130+
return data;
131+
}
132+
133+
AdafruitIO_Data *cur_data = data;
134+
135+
while(cur_data != NULL) {
136+
137+
if(strcmp(cur_data->feedName(), feed) == 0) {
138+
return cur_data;
139+
}
140+
141+
if(! cur_data->next_data) {
142+
cur_data->next_data = new AdafruitIO_Data(feed);
143+
return cur_data->next_data;
144+
}
145+
146+
cur_data = cur_data->next_data;
147+
148+
}
149+
150+
}
151+
152+
void AdafruitIO_Group::onMessage(AdafruitIODataCallbackType cb)
153+
{
154+
uint8_t i;
155+
156+
if(_groupCallback == NULL) {
157+
_groupCallback = new AdafruitIOGroupCallback(cb);
158+
return;
159+
}
160+
161+
AdafruitIOGroupCallback *cur_cb = _groupCallback;
162+
163+
while(cur_cb != NULL) {
164+
165+
if(! cur_cb->next_cb) {
166+
cur_cb->next_cb = new AdafruitIOGroupCallback(cb);
167+
return;
168+
}
169+
170+
cur_cb = cur_cb->next_cb;
171+
172+
}
173+
174+
}
175+
176+
void AdafruitIO_Group::onMessage(const char *feed, AdafruitIODataCallbackType cb)
177+
{
178+
uint8_t i;
179+
180+
if(_groupCallback == NULL) {
181+
_groupCallback = new AdafruitIOGroupCallback(feed, cb);
182+
return;
183+
}
184+
185+
AdafruitIOGroupCallback *cur_cb = _groupCallback;
186+
187+
while(cur_cb != NULL) {
188+
189+
if(strcmp(cur_cb->feed, feed) == 0) {
190+
return;
191+
}
192+
193+
if(! cur_cb->next_cb) {
194+
cur_cb->next_cb = new AdafruitIOGroupCallback(feed, cb);
195+
return;
196+
}
197+
198+
cur_cb = cur_cb->next_cb;
199+
200+
}
201+
202+
}
203+
204+
void AdafruitIO_Group::call(AdafruitIO_Data *d)
205+
{
206+
uint8_t i;
207+
208+
if(_groupCallback == NULL) {
209+
return;
210+
}
211+
212+
AdafruitIOGroupCallback *cur_cb = _groupCallback;
213+
214+
while(cur_cb) {
215+
216+
if(strcmp(cur_cb->feed, d->feedName()) == 0 || cur_cb->feed == NULL) {
217+
cur_cb->dataCallback(d);
218+
}
219+
220+
cur_cb = cur_cb->next_cb;
221+
222+
}
223+
224+
}
225+
226+
void AdafruitIO_Group::subCallback(char *val, uint16_t len)
227+
{
228+
229+
char *line;
230+
char *name;
231+
char *value;
232+
233+
if(_groupCallback == NULL)
234+
return;
235+
236+
while((line = strtok_r(val, "\n", &val)) != NULL) {
237+
238+
name = strtok_r(line, ",", &line);
239+
240+
// couldn't grab name from line, move on
241+
if(! name)
242+
continue;
243+
244+
// don't handle location for now
245+
if(strcmp(name, "location") == 0)
246+
continue;
247+
248+
value = strtok_r(line, ",", &line);
249+
250+
// no value? move on
251+
if(! value)
252+
continue;
253+
254+
AdafruitIO_Data *feed = getFeed(name);
255+
256+
// we couldn't get the data, move on
257+
if(! feed)
258+
continue;
259+
260+
feed->setValue(value);
261+
call(feed);
262+
263+
}
264+
265+
}
266+
267+
void AdafruitIO_Group::setLocation(double lat, double lon, double ele)
268+
{
269+
uint8_t i;
270+
271+
if(data == NULL) {
272+
return;
273+
}
274+
275+
AdafruitIO_Data *cur_data = data;
276+
277+
while(cur_data) {
278+
cur_data->setLocation(lat, lon, ele);
279+
cur_data = cur_data->next_data;
280+
}
281+
282+
}
283+
284+
bool AdafruitIO_Group::exists()
285+
{
286+
_io->_http->startRequest(_group_url, HTTP_METHOD_GET);
287+
_io->_http->sendHeader("X-AIO-Key", _io->_key);
288+
_io->_http->endRequest();
289+
int status = _io->_http->responseStatusCode();
290+
_io->_http->responseBody(); // needs to be read even if not used
291+
return status == 200;
292+
}
293+
294+
bool AdafruitIO_Group::create()
295+
{
296+
String body = "name=";
297+
body += name;
298+
299+
_io->_http->startRequest(_create_url, HTTP_METHOD_POST);
300+
_io->_http->sendHeader(HTTP_HEADER_CONTENT_TYPE, "application/x-www-form-urlencoded");
301+
_io->_http->sendHeader(HTTP_HEADER_CONTENT_LENGTH, body.length());
302+
_io->_http->sendHeader("X-AIO-Key", _io->_key);
303+
_io->_http->endRequest();
304+
_io->_http->write((const byte*)body.c_str(), body.length());
305+
306+
int status = _io->_http->responseStatusCode();
307+
_io->_http->responseBody(); // needs to be read even if not used
308+
return status == 201;
309+
}
310+
311+
312+
void AdafruitIO_Group::_init()
313+
{
314+
315+
// dynamically allocate memory for mqtt topic and REST URLs
316+
_topic = (char *) malloc(sizeof(char) * (strlen(_io->_username) + strlen(name) + 8)); // 8 extra chars for /g/, /csv & null termination
317+
_group_url = (char *) malloc(sizeof(char) * (strlen(_io->_username) + strlen(name) + 16)); // 16 extra for api path & null term
318+
_create_url = (char *) malloc(sizeof(char) * (strlen(_io->_username) + 15)); // 15 extra for api path & null term
319+
320+
data = 0;
321+
322+
if(_topic && _create_url && _group_url) {
323+
324+
// build topic string
325+
strcpy(_topic, _io->_username);
326+
strcat(_topic, "/g/");
327+
strcat(_topic, name);
328+
strcat(_topic, "/csv");
329+
330+
// build feed url string
331+
strcpy(_group_url, "/api/v2/");
332+
strcat(_group_url, _io->_username);
333+
strcat(_group_url, "/groups/");
334+
strcat(_group_url, name);
335+
336+
// build create url string
337+
strcpy(_create_url, "/api/v2/");
338+
strcat(_create_url, _io->_username);
339+
strcat(_create_url, "/groups");
340+
341+
// setup subscription
342+
_sub = new Adafruit_MQTT_Subscribe(_io->_mqtt, _topic);
343+
_pub = new Adafruit_MQTT_Publish(_io->_mqtt, _topic);
344+
_io->_mqtt->subscribe(_sub);
345+
346+
_sub->setCallback(this, &AdafruitIO_MQTT::subCallback);
347+
348+
} else {
349+
350+
// malloc failed
351+
_topic = 0;
352+
_create_url = 0;
353+
_group_url = 0;
354+
_sub = 0;
355+
_pub = 0;
356+
357+
}
358+
359+
}

0 commit comments

Comments
 (0)