2018-11-03 20:21:33 +00:00
|
|
|
//
|
|
|
|
// Adafruit invests time and resources providing this open source code.
|
|
|
|
// Please support Adafruit and open source hardware by purchasing
|
|
|
|
// products from Adafruit!
|
|
|
|
//
|
|
|
|
// Copyright (c) 2015-2016 Adafruit Industries
|
|
|
|
// Authors: Tony DiCola, Todd Treece, Adam Bachman
|
|
|
|
// Licensed under the MIT license.
|
|
|
|
//
|
|
|
|
// All text above must be included in any redistribution.
|
|
|
|
//
|
|
|
|
#include "AdafruitIO_Feed.h"
|
|
|
|
#include "AdafruitIO.h"
|
|
|
|
|
|
|
|
AdafruitIO_Feed::AdafruitIO_Feed(AdafruitIO *io, const char *n):AdafruitIO_MQTT()
|
|
|
|
{
|
|
|
|
_io = io;
|
|
|
|
name = n;
|
2018-11-13 14:50:48 +00:00
|
|
|
owner = _io->_username;
|
|
|
|
|
|
|
|
_init();
|
|
|
|
}
|
|
|
|
|
|
|
|
AdafruitIO_Feed::AdafruitIO_Feed(AdafruitIO *io, const char *n, const char *un):AdafruitIO_MQTT()
|
|
|
|
{
|
|
|
|
_io = io;
|
|
|
|
name = n;
|
|
|
|
owner = un;
|
2018-11-03 20:21:33 +00:00
|
|
|
|
|
|
|
_init();
|
|
|
|
}
|
|
|
|
|
|
|
|
AdafruitIO_Feed::~AdafruitIO_Feed()
|
|
|
|
{
|
|
|
|
if(_sub)
|
|
|
|
delete _sub;
|
|
|
|
|
|
|
|
if(_pub)
|
|
|
|
delete _pub;
|
|
|
|
|
|
|
|
if(_get_pub)
|
2018-11-13 14:50:48 +00:00
|
|
|
delete _get_pub;
|
2018-11-03 20:21:33 +00:00
|
|
|
|
|
|
|
if(data)
|
|
|
|
delete data;
|
|
|
|
|
|
|
|
if(_topic)
|
|
|
|
free(_topic);
|
|
|
|
|
|
|
|
if (_get_topic)
|
|
|
|
free(_get_topic);
|
|
|
|
|
|
|
|
if(_feed_url)
|
|
|
|
free(_feed_url);
|
|
|
|
|
|
|
|
if(_create_url)
|
|
|
|
free(_create_url);
|
|
|
|
}
|
|
|
|
|
|
|
|
void AdafruitIO_Feed::onMessage(AdafruitIODataCallbackType cb)
|
|
|
|
{
|
|
|
|
_dataCallback = cb;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool AdafruitIO_Feed::save(char *value, double lat, double lon, double ele)
|
|
|
|
{
|
|
|
|
data->setValue(value, lat, lon, ele);
|
|
|
|
return _pub->publish(data->toCSV());
|
|
|
|
}
|
|
|
|
|
|
|
|
bool AdafruitIO_Feed::save(bool value, double lat, double lon, double ele)
|
|
|
|
{
|
|
|
|
data->setValue(value, lat, lon, ele);
|
|
|
|
return _pub->publish(data->toCSV());
|
|
|
|
}
|
|
|
|
|
|
|
|
bool AdafruitIO_Feed::save(String value, double lat, double lon, double ele)
|
|
|
|
{
|
|
|
|
data->setValue(value, lat, lon, ele);
|
|
|
|
return _pub->publish(data->toCSV());
|
|
|
|
}
|
|
|
|
|
|
|
|
bool AdafruitIO_Feed::save(int value, double lat, double lon, double ele)
|
|
|
|
{
|
|
|
|
data->setValue(value, lat, lon, ele);
|
|
|
|
return _pub->publish(data->toCSV());
|
|
|
|
}
|
|
|
|
|
|
|
|
bool AdafruitIO_Feed::save(unsigned int value, double lat, double lon, double ele)
|
|
|
|
{
|
|
|
|
data->setValue(value, lat, lon, ele);
|
|
|
|
return _pub->publish(data->toCSV());
|
|
|
|
}
|
|
|
|
|
|
|
|
bool AdafruitIO_Feed::save(long value, double lat, double lon, double ele)
|
|
|
|
{
|
|
|
|
data->setValue(value, lat, lon, ele);
|
|
|
|
return _pub->publish(data->toCSV());
|
|
|
|
}
|
|
|
|
|
|
|
|
bool AdafruitIO_Feed::save(unsigned long value, double lat, double lon, double ele)
|
|
|
|
{
|
|
|
|
data->setValue(value, lat, lon, ele);
|
|
|
|
return _pub->publish(data->toCSV());
|
|
|
|
}
|
|
|
|
|
|
|
|
bool AdafruitIO_Feed::save(float value, double lat, double lon, double ele, int precision)
|
|
|
|
{
|
|
|
|
data->setValue(value, lat, lon, ele, precision);
|
|
|
|
return _pub->publish(data->toCSV());
|
|
|
|
}
|
|
|
|
|
|
|
|
bool AdafruitIO_Feed::save(double value, double lat, double lon, double ele, int precision)
|
|
|
|
{
|
|
|
|
data->setValue(value, lat, lon, ele, precision);
|
|
|
|
return _pub->publish(data->toCSV());
|
|
|
|
}
|
|
|
|
|
|
|
|
bool AdafruitIO_Feed::get()
|
|
|
|
{
|
|
|
|
return _get_pub->publish("\0");
|
|
|
|
}
|
|
|
|
|
|
|
|
bool AdafruitIO_Feed::exists()
|
|
|
|
{
|
|
|
|
_io->_http->beginRequest();
|
|
|
|
_io->_http->get(_feed_url);
|
|
|
|
_io->_http->sendHeader("X-AIO-Key", _io->_key);
|
|
|
|
_io->_http->endRequest();
|
|
|
|
|
|
|
|
int status = _io->_http->responseStatusCode();
|
|
|
|
_io->_http->responseBody(); // needs to be read even if not used
|
|
|
|
|
|
|
|
return status == 200;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool AdafruitIO_Feed::create()
|
|
|
|
{
|
|
|
|
String body = "name=";
|
|
|
|
body += name;
|
|
|
|
|
|
|
|
_io->_http->beginRequest();
|
|
|
|
_io->_http->post(_create_url);
|
|
|
|
|
|
|
|
_io->_http->sendHeader("Content-Type", "application/x-www-form-urlencoded");
|
|
|
|
_io->_http->sendHeader("Content-Length", body.length());
|
|
|
|
_io->_http->sendHeader("X-AIO-Key", _io->_key);
|
|
|
|
|
|
|
|
// the following call to endRequest
|
|
|
|
// should be replaced by beginBody once the
|
|
|
|
// Arduino HTTP Client Library is updated
|
|
|
|
// _io->_http->beginBody();
|
|
|
|
_io->_http->endRequest();
|
|
|
|
|
|
|
|
_io->_http->print(body);
|
|
|
|
_io->_http->endRequest();
|
|
|
|
|
|
|
|
int status = _io->_http->responseStatusCode();
|
|
|
|
_io->_http->responseBody(); // needs to be read even if not used
|
|
|
|
|
|
|
|
return status == 201;
|
|
|
|
}
|
|
|
|
|
|
|
|
AdafruitIO_Data* AdafruitIO_Feed::lastValue()
|
|
|
|
{
|
|
|
|
// 15 extra for api path, 12 for /data/retain, 1 for null
|
|
|
|
String url = "/api/v2/";
|
2018-11-13 14:50:48 +00:00
|
|
|
url += owner;
|
2018-11-03 20:21:33 +00:00
|
|
|
url += "/feeds/";
|
|
|
|
url += name;
|
|
|
|
url += "/data/retain";
|
|
|
|
|
|
|
|
AIO_DEBUG_PRINT("lastValue get ");
|
|
|
|
AIO_DEBUG_PRINTLN(url);
|
|
|
|
|
|
|
|
_io->_http->beginRequest();
|
|
|
|
_io->_http->get(url.c_str());
|
|
|
|
_io->_http->sendHeader("X-AIO-Key", _io->_key);
|
|
|
|
_io->_http->endRequest();
|
|
|
|
|
|
|
|
int status = _io->_http->responseStatusCode();
|
|
|
|
String body = _io->_http->responseBody();
|
|
|
|
|
|
|
|
if (status >= 200 && status <= 299) {
|
|
|
|
|
|
|
|
if (body.length() > 0) {
|
|
|
|
return new AdafruitIO_Data(this, body.c_str());
|
|
|
|
}
|
|
|
|
|
2018-11-13 14:50:48 +00:00
|
|
|
return NULL;
|
|
|
|
|
2018-11-03 20:21:33 +00:00
|
|
|
} else {
|
|
|
|
|
|
|
|
AIO_ERROR_PRINT("error retrieving lastValue, status: ");
|
|
|
|
AIO_ERROR_PRINTLN(status);
|
|
|
|
AIO_ERROR_PRINT("response body: ");
|
|
|
|
AIO_ERROR_PRINTLN(_io->_http->responseBody());
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void AdafruitIO_Feed::setLocation(double lat, double lon, double ele)
|
|
|
|
{
|
|
|
|
data->setLocation(lat, lon, ele);
|
|
|
|
}
|
|
|
|
|
|
|
|
void AdafruitIO_Feed::subCallback(char *val, uint16_t len)
|
|
|
|
{
|
|
|
|
data->setCSV(val);
|
|
|
|
|
|
|
|
// call callback with data
|
|
|
|
if(_dataCallback)
|
|
|
|
_dataCallback(data);
|
|
|
|
}
|
|
|
|
|
|
|
|
void AdafruitIO_Feed::_init()
|
|
|
|
{
|
2018-11-13 14:50:48 +00:00
|
|
|
_sub = 0;
|
|
|
|
_pub = 0;
|
|
|
|
_get_pub = 0;
|
|
|
|
_dataCallback = 0;
|
2018-11-03 20:21:33 +00:00
|
|
|
|
|
|
|
// dynamically allocate memory for mqtt topic and REST URLs
|
2018-11-13 14:50:48 +00:00
|
|
|
_topic = (char *) malloc(sizeof(char) * (strlen(owner) + strlen(name) + 8)); // 8 extra chars for /f/, /csv & null termination
|
|
|
|
_get_topic = (char *) malloc(sizeof(char) * (strlen(owner) + strlen(name) + 12)); // 12 extra chars for /f/, /csv/get & null termination
|
|
|
|
_feed_url = (char *) malloc(sizeof(char) * (strlen(owner) + strlen(name) + 16)); // 16 extra for api path & null term
|
|
|
|
_create_url = (char *) malloc(sizeof(char) * (strlen(owner) + 15)); // 15 extra for api path & null term
|
2018-11-03 20:21:33 +00:00
|
|
|
|
|
|
|
// init feed data
|
|
|
|
data = new AdafruitIO_Data(this);
|
|
|
|
|
|
|
|
if(_topic && _create_url && _feed_url) {
|
|
|
|
|
|
|
|
// build topic string
|
2018-11-13 14:50:48 +00:00
|
|
|
strcpy(_topic, owner);
|
2018-11-03 20:21:33 +00:00
|
|
|
strcat(_topic, "/f/");
|
|
|
|
strcat(_topic, name);
|
|
|
|
strcat(_topic, "/csv");
|
|
|
|
|
|
|
|
// build feed url string
|
|
|
|
strcpy(_feed_url, "/api/v2/");
|
2018-11-13 14:50:48 +00:00
|
|
|
strcat(_feed_url, owner);
|
2018-11-03 20:21:33 +00:00
|
|
|
strcat(_feed_url, "/feeds/");
|
|
|
|
strcat(_feed_url, name);
|
|
|
|
|
|
|
|
// build create url string
|
|
|
|
strcpy(_create_url, "/api/v2/");
|
2018-11-13 14:50:48 +00:00
|
|
|
strcat(_create_url, owner);
|
2018-11-03 20:21:33 +00:00
|
|
|
strcat(_create_url, "/feeds");
|
|
|
|
|
|
|
|
// build /get topic string
|
2018-11-13 14:50:48 +00:00
|
|
|
strcpy(_get_topic, owner);
|
2018-11-03 20:21:33 +00:00
|
|
|
strcat(_get_topic, "/f/");
|
|
|
|
strcat(_get_topic, name);
|
|
|
|
strcat(_get_topic, "/csv/get");
|
|
|
|
|
|
|
|
// setup subscription
|
|
|
|
_sub = new Adafruit_MQTT_Subscribe(_io->_mqtt, _topic);
|
|
|
|
_pub = new Adafruit_MQTT_Publish(_io->_mqtt, _topic);
|
|
|
|
_get_pub = new Adafruit_MQTT_Publish(_io->_mqtt, _get_topic);
|
|
|
|
_io->_mqtt->subscribe(_sub);
|
|
|
|
|
|
|
|
_sub->setCallback(this, &AdafruitIO_MQTT::subCallback);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
// malloc failed
|
|
|
|
_topic = 0;
|
2018-11-13 14:50:48 +00:00
|
|
|
_get_topic = 0;
|
2018-11-03 20:21:33 +00:00
|
|
|
_create_url = 0;
|
|
|
|
_feed_url = 0;
|
|
|
|
_sub = 0;
|
|
|
|
_pub = 0;
|
|
|
|
_get_pub = 0;
|
|
|
|
data = 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|