Browse Source

Non SSL version of Thingspeak module

i18n
Xose Pérez 7 years ago
parent
commit
9d6a5727a5
8 changed files with 144 additions and 25 deletions
  1. +1
    -0
      code/espurna/config/arduino.h
  2. +17
    -3
      code/espurna/config/general.h
  3. +1
    -1
      code/espurna/config/sensors.h
  4. +6
    -0
      code/espurna/espurna.ino
  5. +5
    -0
      code/espurna/relay.ino
  6. +8
    -0
      code/espurna/sensor.ino
  7. +104
    -21
      code/espurna/thinkspeak.ino
  8. +2
    -0
      code/html/custom.js

+ 1
- 0
code/espurna/config/arduino.h View File

@ -83,6 +83,7 @@
//#define SSDP_SUPPORT 1
//#define TELNET_SUPPORT 0
//#define TERMINAL_SUPPORT 0
//#define THINGSPEAK_SUPPORT 0
//#define WEB_SUPPORT 0
//--------------------------------------------------------------------------------


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

@ -306,7 +306,7 @@ PROGMEM const char* const custom_reset_string[] = {
#endif
// This is not working at the moment!!
// Requires ASYNC_TCP_SSL_ENABLED to 1 and ESP8266 Arduino Core staging version.
// Requires ASYNC_TCP_SSL_ENABLED to 1 and ESP8266 Arduino Core 2.4.0
#define WEB_SSL_ENABLED 0 // Use HTTPS web interface
#define WEB_MODE_NORMAL 0
@ -405,7 +405,7 @@ PROGMEM const char* const custom_reset_string[] = {
// MQTT OVER SSL
// Using MQTT over SSL works pretty well but generates problems with the web interface.
// It could be a good idea to use it in conjuntion with WEB_SUPPORT=0.
// Requires ASYNC_TCP_SSL_ENABLED to 1 and ESP8266 Arduino Core staging version.
// Requires ASYNC_TCP_SSL_ENABLED to 1 and ESP8266 Arduino Core 2.4.0.
//
// You can use it with MQTT_USE_ASYNC=1 (AsyncMqttClient library)
// but you might experience hiccups on the web interface, so my recommendation is:
@ -621,9 +621,23 @@ PROGMEM const char* const custom_reset_string[] = {
#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_HOST "api.thingspeak.com"
#if THINGSPEAK_USE_SSL
#define THINGSPEAK_PORT 443
#else
#define THINGSPEAK_PORT 80
#endif
#define THINGSPEAK_URL "/update"
#define THINGSPEAK_APIKEY "" // Default API KEY
#ifndef ASYNC_TCP_SSL_ENABLED
#if THINGSPEAK_USE_SSL && THINGSPEAK_USE_ASYNC
#undef THINGSPEAK_SUPPORT // Thingspeak in ASYNC mode requires ASYNC_TCP_SSL_ENABLED
#endif
#endif
// -----------------------------------------------------------------------------
// NTP


+ 1
- 1
code/espurna/config/sensors.h View File

@ -396,7 +396,7 @@
//------------------------------------------------------------------------------
#ifndef SI7021_SUPPORT
#define SI7021_SUPPORT 0
#define SI7021_SUPPORT 1
#endif
#ifndef SI7021_ADDRESS


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

@ -189,6 +189,9 @@ void welcome() {
#if TERMINAL_SUPPORT
DEBUG_MSG_P(PSTR(" TERMINAL"));
#endif
#if THINGSPEAK_SUPPORT
DEBUG_MSG_P(PSTR(" THINGSPEAK"));
#endif
#if WEB_SUPPORT
DEBUG_MSG_P(PSTR(" WEB"));
#endif
@ -357,6 +360,9 @@ void setup() {
#if INFLUXDB_SUPPORT
idbSetup();
#endif
#if THINGSPEAK_SUPPORT
tspkSetup();
#endif
#if RF_SUPPORT
rfSetup();
#endif


+ 5
- 0
code/espurna/relay.ino View File

@ -747,6 +747,11 @@ void relayLoop(void) {
relayInfluxDB(id);
#endif
#if THINGSPEAK_SUPPORT
tspkEnqueueRelay(id, status);
tspkFlush();
#endif
// Flag relay-based LEDs to update status
ledUpdate(true);


+ 8
- 0
code/espurna/sensor.ino View File

@ -649,6 +649,10 @@ void sensorLoop() {
}
#endif // INFLUXDB_SUPPORT
#if THINGSPEAK_SUPPORT
tspkEnqueueMeasurement(i, buffer);
#endif
#if DOMOTICZ_SUPPORT
{
char key[15];
@ -685,6 +689,10 @@ void sensorLoop() {
wsSend(_sensorWebSocketSendData);
#endif
#if THINGSPEAK_SUPPORT
if (report_count == 0) tspkFlush();
#endif
}
}


+ 104
- 21
code/espurna/thinkspeak.ino View File

@ -8,18 +8,37 @@ Copyright (C) 2018 by Xose Pérez <xose dot perez at gmail dot com>
#if THINGSPEAK_SUPPORT
#include <ESP8266WiFi.h>
#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
WiFiClientSecure _tspk_client;
#else
WiFiClient _tspk_client;
#endif
#endif
bool _tspk_enabled = false;
WiFiClientSecure _tspk_client;
char * _tspk_queue[0];
char * _tspk_queue[8] = {NULL};
// -----------------------------------------------------------------------------
void _tspkWebSocketOnSend(JsonObject& root) {
root["tspkVisible"] = 1;
root["tspkEnabled"] = getSetting("idbEnabled", THINGSPEAK_ENABLED).toInt() == 1;
root["tspkEnabled"] = getSetting("tspkEnabled", THINGSPEAK_ENABLED).toInt() == 1;
JsonArray& relays = root.createNestedArray("tspkRelays");
for (byte i=0; i<relayCount(); i++) {
@ -47,49 +66,112 @@ void _tspkConfigure() {
}
}
#if THINGSPEAK_USE_ASYNC
bool _tspkPost(String data) {
_tspk_client.onError([](void * arg, AsyncClient * client, int error) {
DEBUG_MSG("[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());
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);
}, NULL);
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()
);
client->write(buffer);
}, NULL);
#if ASYNC_TCP_SSL_ENABLED
if (!_tspk_client.connect(THINGSPEAK_HOST, THINGSPEAK_PORT, THINGSPEAK_USE_SSL)) {
#else
if (!_tspk_client.connect(THINGSPEAK_HOST, THINGSPEAK_PORT)) {
#endif
DEBUG_MSG("[THINGSPEAK] Connection failed\n");
}
}
#else
bool _tspkPost(String data) {
if (_tspk_client.connect(THINGSPEAK_HOST, 443)) {
if (_tspk_client.connect(THINGSPEAK_HOST, THINGSPEAK_PORT)) {
DEBUG_MSG("[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("User-Agent: ESPurna");
_tspk_client.println("Connection: close");
_tspk_client.println("Content-Type: application/x-www-form-urlencoded;");
_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();
delay(10);
String response = _tspk_client.readString();
int bodypos = response.indexOf("\r\n\r\n") + 4;
Serial.println(response.substring(bodypos));
return true;
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);
_tspk_client.stop();
return (code > 0);
}
DEBUG_MSG("[THINGSPEAK] Connection failed\n");
return false;
}
#endif
bool _tspkEnqueue(unsigned char index, char * payload) {
DEBUG_MSG("[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);
}
// -----------------------------------------------------------------------------
bool tspkSendRelay(unsigned char index, unsigned char status, bool enqueue) {
bool tspkEnqueueRelay(unsigned char index, unsigned char status) {
if (!_tspk_enabled) return true;
unsigned char id = getSetting("tspkRelay", index, 0).toInt();
if (id > 0) {
--id;
char payload[3];
itoa(status ? 1 : 0, payload, 10);
if (_tspk_queue[id]) free(_tspk_queue[id]);
_tspk_queue[id] = strdup(payload);
if (!enqueue) tspkFlush();
_tspkEnqueue(id, payload);
}
}
bool tspkSendMeasurement(unsigned char index, char * payload, bool enqueue) {
bool tspkEnqueueMeasurement(unsigned char index, char * payload) {
if (!_tspk_enabled) return true;
unsigned char id = getSetting("tspkMagnitude", index, 0).toInt();
if (id > 0) {
--id;
if (_tspk_queue[id]) free(_tspk_queue[id]);
_tspk_queue[id] = strdup(payload);
if (!enqueue) tspkFlush();
_tspkEnqueue(id, payload);
}
}
@ -102,10 +184,11 @@ bool tspkFlush() {
// Walk the fields
for (unsigned char id=0; id<8; id++) {
if (_tspk_queue[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;
}
}


+ 2
- 0
code/html/custom.js View File

@ -684,6 +684,8 @@ function rfbSend() {
function processData(data) {
console.log(data);
// title
if ("app_name" in data) {
var title = data.app_name;


Loading…
Cancel
Save