Browse Source

Check ThingSpeak update frequency limit (15s)

i18n
Xose Pérez 6 years ago
parent
commit
c4bdb03024
3 changed files with 76 additions and 62 deletions
  1. +5
    -3
      code/espurna/config/general.h
  2. +3
    -0
      code/espurna/espurna.ino
  3. +68
    -59
      code/espurna/thinkspeak.ino

+ 5
- 3
code/espurna/config/general.h View File

@ -617,14 +617,15 @@ PROGMEM const char* const custom_reset_string[] = {
// -----------------------------------------------------------------------------
#ifndef THINGSPEAK_SUPPORT
#define THINGSPEAK_SUPPORT 1 // Enable Thingspeak support by default (???Kb)
#define THINGSPEAK_SUPPORT 0 // Enable Thingspeak support by default (???Kb)
#endif
#define THINGSPEAK_ENABLED 0 // Thingspeak disabled by default
#define THINGSPEAK_USE_SSL 0 // Use secure connection
#define THINGSPEAK_USE_ASYNC 0 // Use AsyncClient instead of WiFiClientSecure
#define THINGSPEAK_APIKEY "" // Default API KEY
#define THINGSPEAK_USE_ASYNC 1 // Use AsyncClient instead of WiFiClientSecure
#define THINGSPEAK_USE_SSL 0 // Use secure connection
#define THINGSPEAK_HOST "api.thingspeak.com"
#if THINGSPEAK_USE_SSL
#define THINGSPEAK_PORT 443
@ -632,6 +633,7 @@ PROGMEM const char* const custom_reset_string[] = {
#define THINGSPEAK_PORT 80
#endif
#define THINGSPEAK_URL "/update"
#define THINGSPEAK_MIN_INTERVAL 15000 // Minimum interval between POSTs (in millis)
#ifndef ASYNC_TCP_SSL_ENABLED
#if THINGSPEAK_USE_SSL && THINGSPEAK_USE_ASYNC


+ 3
- 0
code/espurna/espurna.ino View File

@ -433,6 +433,9 @@ void loop() {
#if SENSOR_SUPPORT
sensorLoop();
#endif
#if THINGSPEAK_SUPPORT
tspkLoop();
#endif
// Power saving delay
delay(_loopDelay);


+ 68
- 59
code/espurna/thinkspeak.ino View File

@ -11,16 +11,6 @@ Copyright (C) 2018 by Xose Pérez <xose dot perez at gmail dot com>
#if THINGSPEAK_USE_ASYNC
#include <ESPAsyncTCP.h>
AsyncClient _tspk_client;
const char THINGSPEAK_REQUEST_TEMPLATE[] PROGMEM =
"POST %s HTTP/1.1\r\n"
"Host: %s\r\n"
"User-Agent: ESPurna\r\n"
"Connection: close\r\n"
"Content-Type: application/x-www-form-urlencoded\r\n"
"Content-Length: %d\r\n\r\n"
"%s\r\n";
#else
#include <ESP8266WiFi.h>
#if THINGSPEAK_USE_SSL
@ -30,9 +20,21 @@ Copyright (C) 2018 by Xose Pérez <xose dot perez at gmail dot com>
#endif
#endif
const char THINGSPEAK_REQUEST_TEMPLATE[] PROGMEM =
"POST %s HTTP/1.1\r\n"
"Host: %s\r\n"
"User-Agent: ESPurna\r\n"
"Connection: close\r\n"
"Content-Type: application/x-www-form-urlencoded\r\n"
"Content-Length: %d\r\n\r\n"
"%s\r\n";
bool _tspk_enabled = false;
char * _tspk_queue[8] = {NULL};
bool _tspk_flush = false;
unsigned long _tspk_last_flush = 0;
// -----------------------------------------------------------------------------
void _tspkWebSocketOnSend(JsonObject& root) {
@ -68,24 +70,23 @@ void _tspkConfigure() {
#if THINGSPEAK_USE_ASYNC
bool _tspkPost(String data) {
void _tspkPost(String data) {
_tspk_client.onError([](void * arg, AsyncClient * client, int error) {
DEBUG_MSG("[THINGSPEAK] Connection error (%d)\n", error);
_P(PSTR("[THINGSPEAK] Connection error (%d)\n", error);
_tspk_client = NULL;
}, NULL);
_tspk_client.onConnect([data](void * arg, AsyncClient * client) {
DEBUG_MSG("[THINGSPEAK] POST %s\n", data.c_str());
DEBUG_MSG_P(PSTR("[THINGSPEAK] POST %s\n"), data.c_str());
client->onData([](void * arg, AsyncClient * c, void * response, size_t len) {
char * b = (char *) response;
b[len] = 0;
Serial.println(b);
char * p = strstr((char *)response, "\r\n\r\n");
unsigned int code = (p != NULL) ? atoi(&p[4]) : 0;
DEBUG_MSG("[THINGSPEAK] Response value: %d\n", code);
DEBUG_MSG_P(PSTR("[THINGSPEAK] Response value: %d\n"), code);
}, NULL);
char buffer[strlen_P(THINGSPEAK_REQUEST_TEMPLATE) + strlen(THINGSPEAK_URL) + strlen(THINGSPEAK_HOST) + data.length()];
@ -106,55 +107,75 @@ bool _tspkPost(String data) {
#else
if (!_tspk_client.connect(THINGSPEAK_HOST, THINGSPEAK_PORT)) {
#endif
DEBUG_MSG("[THINGSPEAK] Connection failed\n");
DEBUG_MSG_P(PSTR("[THINGSPEAK] Connection failed\n"));
}
}
#else
#else // not THINGSPEAK_USE_ASYNC
bool _tspkPost(String data) {
void _tspkPost(String data) {
if (_tspk_client.connect(THINGSPEAK_HOST, THINGSPEAK_PORT)) {
DEBUG_MSG("[THINGSPEAK] POST %s\n", data.c_str());
DEBUG_MSG_P(PSTR("[THINGSPEAK] POST %s\n"), data.c_str());
_tspk_client.println("POST " + String(THINGSPEAK_URL) + " HTTP/1.1");
_tspk_client.println("Host: " + String(THINGSPEAK_HOST));
_tspk_client.println("User-Agent: ESPurna");
_tspk_client.println("Connection: close");
_tspk_client.println("Content-Type: application/x-www-form-urlencoded");
_tspk_client.print("Content-Length: ");
_tspk_client.println(data.length());
_tspk_client.println();
_tspk_client.println(data);
_tspk_client.println();
char buffer[strlen_P(THINGSPEAK_REQUEST_TEMPLATE) + strlen(THINGSPEAK_URL) + strlen(THINGSPEAK_HOST) + data.length()];
snprintf_P(buffer, sizeof(buffer),
THINGSPEAK_REQUEST_TEMPLATE,
THINGSPEAK_URL,
THINGSPEAK_HOST,
data.length(),
data.c_str()
);
_tspk_client.print(buffer);
delay(10);
nice_delay(100);
String response = _tspk_client.readString();
int pos = response.indexOf("\r\n\r\n");
unsigned int code = (pos > 0) ? response.substring(pos + 4).toInt() : 0;
DEBUG_MSG("[THINGSPEAK] Response value: %d\n", code);
DEBUG_MSG_P(PSTR("[THINGSPEAK] Response value: %d\n"), code);
_tspk_client.stop();
return (code > 0);
return;
}
DEBUG_MSG("[THINGSPEAK] Connection failed\n");
return false;
DEBUG_MSG_P(PSTR("[THINGSPEAK] Connection failed\n"));
}
#endif
#endif // THINGSPEAK_USE_ASYNC
bool _tspkEnqueue(unsigned char index, char * payload) {
DEBUG_MSG("[THINGSPEAK] Enqueuing field #%d with value %s\n", index, payload);
DEBUG_MSG_P(PSTR("[THINGSPEAK] Enqueuing field #%d with value %s\n"), index, payload);
--index;
if (_tspk_queue[index] != NULL) free(_tspk_queue[index]);
_tspk_queue[index] = strdup(payload);
}
void _tspkFlush() {
String data;
// Walk the fields
for (unsigned char id=0; id<8; id++) {
if (_tspk_queue[id] != NULL) {
if (data.length() > 0) data = data + String("&");
data = data + String("field") + String(id+1) + String("=") + String(_tspk_queue[id]);
free(_tspk_queue[id]);
_tspk_queue[id] = NULL;
}
}
// POST data if any
if (data.length() > 0) {
data = data + String("&api_key=") + getSetting("tspkKey");
_tspkPost(data);
_tspk_last_flush = millis();
}
}
// -----------------------------------------------------------------------------
bool tspkEnqueueRelay(unsigned char index, unsigned char status) {
@ -175,29 +196,8 @@ bool tspkEnqueueMeasurement(unsigned char index, char * payload) {
}
}
bool tspkFlush() {
if (!_tspk_enabled) return true;
if (!wifiConnected() || (WiFi.getMode() != WIFI_STA)) return true;
String data;
// Walk the fields
for (unsigned char id=0; id<8; id++) {
if (_tspk_queue[id] != NULL) {
if (data.length() > 0) data = data + String("&");
data = data + String("field") + String(id+1) + String("=") + String(_tspk_queue[id]);
free(_tspk_queue[id]);
_tspk_queue[id] = NULL;
}
}
// POST data if any
if (data.length() > 0) {
data = data + String("&api_key=") + getSetting("tspkKey");
_tspkPost(data);
}
void tspkFlush() {
_tspk_flush = true;
}
bool tspkEnabled() {
@ -212,4 +212,13 @@ void tspkSetup() {
#endif
}
void tspkLoop() {
if (!_tspk_enabled) return;
if (!wifiConnected() || (WiFi.getMode() != WIFI_STA)) return;
if (_tspk_flush && (millis() - _tspk_last_flush > THINGSPEAK_MIN_INTERVAL)) {
_tspkFlush();
_tspk_flush = false;
}
}
#endif

Loading…
Cancel
Save