Browse Source

Non SSL version of Thingspeak module

i18n
Xose Pérez 6 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 SSDP_SUPPORT 1
//#define TELNET_SUPPORT 0 //#define TELNET_SUPPORT 0
//#define TERMINAL_SUPPORT 0 //#define TERMINAL_SUPPORT 0
//#define THINGSPEAK_SUPPORT 0
//#define WEB_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 #endif
// This is not working at the moment!! // 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_SSL_ENABLED 0 // Use HTTPS web interface
#define WEB_MODE_NORMAL 0 #define WEB_MODE_NORMAL 0
@ -405,7 +405,7 @@ PROGMEM const char* const custom_reset_string[] = {
// MQTT OVER SSL // MQTT OVER SSL
// Using MQTT over SSL works pretty well but generates problems with the web interface. // 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. // 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) // You can use it with MQTT_USE_ASYNC=1 (AsyncMqttClient library)
// but you might experience hiccups on the web interface, so my recommendation is: // 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 #endif
#define THINGSPEAK_ENABLED 0 // Thingspeak disabled by default #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" #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_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 // NTP


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

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


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

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


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

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


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

@ -649,6 +649,10 @@ void sensorLoop() {
} }
#endif // INFLUXDB_SUPPORT #endif // INFLUXDB_SUPPORT
#if THINGSPEAK_SUPPORT
tspkEnqueueMeasurement(i, buffer);
#endif
#if DOMOTICZ_SUPPORT #if DOMOTICZ_SUPPORT
{ {
char key[15]; char key[15];
@ -685,6 +689,10 @@ void sensorLoop() {
wsSend(_sensorWebSocketSendData); wsSend(_sensorWebSocketSendData);
#endif #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 #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; bool _tspk_enabled = false;
WiFiClientSecure _tspk_client;
char * _tspk_queue[0];
char * _tspk_queue[8] = {NULL};
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void _tspkWebSocketOnSend(JsonObject& root) { void _tspkWebSocketOnSend(JsonObject& root) {
root["tspkVisible"] = 1; root["tspkVisible"] = 1;
root["tspkEnabled"] = getSetting("idbEnabled", THINGSPEAK_ENABLED).toInt() == 1;
root["tspkEnabled"] = getSetting("tspkEnabled", THINGSPEAK_ENABLED).toInt() == 1;
JsonArray& relays = root.createNestedArray("tspkRelays"); JsonArray& relays = root.createNestedArray("tspkRelays");
for (byte i=0; i<relayCount(); i++) { 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) { 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("POST " + String(THINGSPEAK_URL) + " HTTP/1.1");
_tspk_client.println("Host: " + String(THINGSPEAK_HOST)); _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("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.print("Content-Length: ");
_tspk_client.println(data.length()); _tspk_client.println(data.length());
_tspk_client.println(); _tspk_client.println();
_tspk_client.println(data); _tspk_client.println(data);
_tspk_client.println();
delay(10); delay(10);
String response = _tspk_client.readString(); 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; 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; if (!_tspk_enabled) return true;
unsigned char id = getSetting("tspkRelay", index, 0).toInt(); unsigned char id = getSetting("tspkRelay", index, 0).toInt();
if (id > 0) { if (id > 0) {
--id;
char payload[3]; char payload[3];
itoa(status ? 1 : 0, payload, 10); 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; if (!_tspk_enabled) return true;
unsigned char id = getSetting("tspkMagnitude", index, 0).toInt(); unsigned char id = getSetting("tspkMagnitude", index, 0).toInt();
if (id > 0) { 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 // Walk the fields
for (unsigned char id=0; id<8; id++) { for (unsigned char id=0; id<8; id++) {
if (_tspk_queue[id]) {
if (_tspk_queue[id] != NULL) {
if (data.length() > 0) data = data + String("&"); if (data.length() > 0) data = data + String("&");
data = data + String("field") + String(id+1) + String("=") + String(_tspk_queue[id]); data = data + String("field") + String(id+1) + String("=") + String(_tspk_queue[id]);
free(_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) { function processData(data) {
console.log(data);
// title // title
if ("app_name" in data) { if ("app_name" in data) {
var title = data.app_name; var title = data.app_name;


Loading…
Cancel
Save