Tag 19: ThingSpeak
In den letzten Tagen der Adventszeit beschäftigen wir uns mit einem ganz neuen Thema, nämlich der Internetseite ThingSpeak. Diese Seite wurde speziell für das Thema Internet of Things entwickelt und hält verschiedene praktische Funktionen für Sie bereit.
Bevor Sie also wie sonst üblich, den Aufbau und das Programm angehen, müssen Sie sich zunächst einen Account auf der Seite
erstellen. Loggen Sie sich dann mit Ihren Nutzerdaten unter dem Punkt Sign In ein. Sie sehen eine Seite, die Ihre Channels zeigt. Da Sie noch keine Kanäle haben, wird diese Seite ziemlich leer aussehen. Klicken Sie auf New Channel und vergeben einen Namen, z.B. Light, denn Sie werden in diesem Projekt die Helligkeit messen. Unter dem Punkt Field1 können Sie nun noch einen Namen für das Feld vergeben, evtl. Brightness. Alle anderen Felder können vorerst leer bleiben.
Klicken Sie auf Save Channel, um die Einstellungen zu speichern. Sie werden zu der Seite Ihres Channels weitergeleitet, auf der aber nur ein leeres Diagramm zu sehen ist. Klicken Sie in dem darüber liegenden Reiter auf API-Keys. Die Zahlen und Buchstabenfolge die Sie unter dem Punkt Write API Key finden, werden Sie gleich benötigen.
Hinter dem heutigen Türchen finden Sie erneut ein Kabel. Sie können nun auch dreibeinige Bauteile, wie das IR-Empfangsmodul, abseits des Steckboards platzieren. Der Aufbau des heutigen Versuchs ist mit dem Versuchsaufbau des 15. Tages identisch. Ein Spannungsteiler mit 10-kΩ-Widerstand und Fototransistor ermöglicht das Messen der aktuellen Helligkeit.
Das Programm: Day19_ThinkSpeak1
Das heutige Programm misst nun, ähnlich dem Programm des 15. Tages, die Helligkeit. Doch anders als im vergangenen Versuch werden die Daten direkt an die ThingSpeak Seite gesendet. Diese Seite speichert die Daten nicht nur, sondern stellt sie auch übersichtlich in einem Diagramm dar. Eine sehr praktische Funktion für eine Messstation mit Langzeitüberwachung.
Damit das Programm an die Webseite senden kann, müssen Sie außer Ihren WLAN-Daten zunächst den oben erwähnten API-Key in das Programm unter den Punkt ThingSpeakKEY eintragen. Nach dem Upload empfiehlt es sich, den Serial Monitor zu öffnen. In der Regel sollte eine Update Send Meldung die erfolgreiche Übertragung begleiten. Auf der ThingSpeak Seite können Sie nun wieder auf den Reiter Private View ihres Kanals klicken. Dort sehen Sie das Diagramm Ihres Channels welches alle 10 Sekunden neue Daten empfängt.
Hello All, sorry to bother, does anyone have an example of adding a Authorization Bearer to the HTTP Header of an AT command?
in curl it would be something like curl -k -X POST -H „Authorization: Bearer “ -d „“ https://
would this be possible using the pretzel board?
Thank you in Advance,
funktioniert ja prima, aber ich möchte drei werte verschicken, wie muss dann der string für thinkspeak aufgebaut sein?
Hi,
ich übernehme jetzt mal keine Garantie aber ich meine, dass du in der Funktion sendThingPost die msg-Variable so anpassen musst, dass das Ergebniss etwas so aussieht:
field1=(Field 1 Data)&field2=(Field 2 Data)&field3=(Field 3 Data)
also (Field X Data) muss dann durch den Messwert ersetzt werden.
jawohl, so geht’s! thx
Kannst du den Code mal schicken?
Hallo,
ich bin spät dran aber, hatte leider im Dezember nicht so viel Zeit. Ich bekomme es irgendwie nicht hin 2 Werte an ThingSpeak zu übermitteln. Ich habe den Code wie folgt abgeändert:
void loop() {
int chk = DHT11.read(DHT11PIN);
if (sendThingPost(ThingSpeakKEY, DHT11.temperature, DHT11.humidity)) debug(„Update Send“);
Serial.println (String url, String key, String msg, String msg2);
delay(15000);
}
//—————————————–ThingsSpeak Functions————————————
boolean sendThingPost(String key, float value1, float value2)
{
boolean succes = true;
String Host = „api.thingspeak.com“;
String msg = „field1=“ + String(value1);
String msg2 = „&field2=“ + String(value2);
succes &= sendCom(„AT+CIPSTART=\“TCP\“,\““ + Host + „\“,80″, „OK“);
String postRequest = createThingPost(„/update“, key, msg, msg2);
if (sendCom(„AT+CIPSEND=“ + String(postRequest.length()), „>“))
{
esp8266.print(postRequest);
esp8266.find(„SEND OK“);
if (!esp8266.find(„CLOSED“)) succes &= sendCom(„AT+CIPCLOSE“, „OK“);
}
else
{
succes = false;
}
return succes;
}
String createThingPost(String url, String key, String msg, String msg2)
{
String xBuffer;
for (int i = 0; i <= sizeof(thingPost); i++)
{
char myChar = pgm_read_byte_near(thingPost + i);
xBuffer += myChar;
}
String append = "api_key=" + key + "&" + msg;
xBuffer.replace("*URL*", url);
xBuffer.replace("*LEN*", String( append.length()));
xBuffer.replace("*APPEND*", append);
return xBuffer;
}
String createThingGet(String url, String key)
{
String xBuffer;
for (int i = 0; i <= sizeof(thingPost); i++)
{
char myChar = pgm_read_byte_near(thingPost + i);
xBuffer += myChar;
}
String append = "api_key=" + key;
xBuffer.replace("POST", "GET");
xBuffer.replace("*URL*", url);
xBuffer.replace("*LEN*", String( append.length()));
xBuffer.replace("*APPEND*", append);
return xBuffer;
}
String createThingGet(String url, String key, String msg, String msg2)
{
String xBuffer;
for (int i = 0; i <= sizeof(thingPost); i++)
{
char myChar = pgm_read_byte_near(thingPost + i);
xBuffer += myChar;
}
String append = "api_key=" + key + "&" + msg + msg2;
xBuffer.replace("POST", "GET");
xBuffer.replace("*URL*", url);
xBuffer.replace("*LEN*", String( append.length()));
xBuffer.replace("*APPEND*", append);
return xBuffer;
}
Wäre schön wenn mir jemand helfen könnte meinen Fehler zu finden. oder einen Tipp zur lösung geben könnte.
Mit freundlichem Gruß
Ronald
Hi, bin ich zu spät?
Bin kein Pro aber dass du 2 msg strings generierst und zu übergeben suchst sieht schräg aus.
Dein Code
String msg = „field1=“ + String(value1);
String msg2 = „&field2=“ + String(value2);
succes &= sendCom(„AT+CIPSTART=\“TCP\“,\““ + Host + „\“,80″, „OK“);
String postRequest = createThingPost(„/update“, key, msg, msg2);
Mein Code funkst soweit, ich verlängere nur den String msg, keine neue Message:
String msg = „field1=“ + String(value1) +“&field2=“ + String(value2);
Hoffe es hilft!
Also ich wollte 4 Werte versenden und habe mir den entsprechenden String zusammengebaut. Seltsamerweise wurde dann aber gar nichts mehr übertragen. Sobald ich einen Wert rausgenommen habe, ging es wieder. Dabei war es egal, welchen Wert ich entfernte.
Nach vielen herumprobieren habe ich den Fehler soweit lokalisiert, das der String einfach zu lang ist und dann gar nichts mehr gesendet wird.
Ich habe mir jetzt damit geholfen, die Übertragung aufzusplitten und in 15s Abständen zu senden und anschliessend das delay wieder auf den normalen Messabstand zu erhöhen.
Hat schon mal jemand versucht, die Daten an eine eigene Website zu schicken?
Wäre schön, wenn man die Messwerte selber in einer Datenbank sammeln könnte.
Würde ich mir im Quelltext ja gerne selber erarbeiten, leider ist dieser – wie alle – nicht Dokumentiert.
Diese „friss oder stirb“ Methode ist einfach zum K++++
Diesen Beitrag finde ich auch nicht gerade appetitlich!
In den diversen Tagen wurden beide Seiten, senden und empfangen von Daten, gezeigt (und geübt).
Hallo Thorsten,
ich habe auch bereits daran gedacht, die Daten in einer eigenen Datenbank abzulegen. Jedoch habe ich bisher nicht die Zeit dazu gefunden eine API zu programmieren, die Daten entgegen nehmen und in der DB ablegen kann. Den Code anzupassen ist glaube das kleinere Übel, wenn die Gegenseite steht. (Natürlich unter der Voraussetzung man hat die Arduinosprache verstanden…)
Hallo Nikdro,
du könntest dir eine Menge Arbeit sparen wenn du einfach die API von thingspeak nimmst. Man greift dann zwar immer noch auf externe quellen zurück aber man hat eben schon mal eine sehr gute Basis und muss nicht alles selber programmieren. Das Programm für den Arduino zu ändern sollte ja nicht allzu schwer sein da muss man sich halt mal ein bisschen einlesen um das komplett zu verstehen. Sen Server kann man dann auch prima auf einem der vielen Einplatinencomputern (RasPi usw) laufen lassen.
Sendet leider nur 1-3 mal den Wert und bricht dann ab mit:
OK
Update Send
ESP SEND ERROR: AT+CIPCLOSE
ESP SEND ERROR: AT+CIPSTART=“TCP“,“api.thingspeak.com“,80
ESP SEND ERROR: AT+CIPSEND=169
Hi,
bei mir kam die Fehlermeldung nach 2 mal senden, danach sendet das NanoESP einfach weiter und es funktioniert.
Allerdings habe ich eine Fehlermeldung mit 170
Habe inzwischen nach vielen Versuchen möglicherweise den Grund für die Probleme gefunden. Mein AccessPoint für WLAN ist über das Stromnetz mit Powerlan-Adaptern an den Router angeschlossen. Vielleicht gibt es hier irgendwelche Übertragungsverluste/Anschlussprobleme. Wenn ich direkt am Router-WLAN ankopple funktioniert alles reibungslos.
Hat jemand versucht die sendeinterval von 10sek zu verändern?
Bin nicht der Profi aber aus meiner sind es 15sek und nicht 10
Im Code steht
void loop() {
if (sendThingPost(ThingSpeakKEY, analogRead(SENSOR))) debug(„Update Send“);
delay(15000);
Das Delay steht für 15000 ms warten also 15 sek
Versuche mal hier die Zeit zu ändern
Aber ich gebe dir keine Garantie, dass das stimmt ;)
Danke
Ich sag mal als Hilfe: Abtastung
Sorry, sollte als Antwort in einem Beitrag erscheinen
Kann mir jemand die Codes von einem Medion Life P24008 (MD 28000)
Hat schon Jemand versucht die Daten an FHEM zu schicken da dort ja auch ein TCP Server läuft?
Wäre ja echt spannend die Arduino-Sensorwelt anzubinden.
Ich habe FHEM mit dem NanoESP gerade mal ausprobiert. Funktioniert ganz gut, die Daten werden in ein Log geschrieben und als Diagramm dargestellt. In der fhem.cfg habe ich sowas hier:
define Light dummy
define Log.Light FileLog light.log Light:L:.*
define SVG_Log.Light_1 SVG Log.Light:SVG_Log.Light_1:CURRENT
(Der SVG Plot ist über das Webinterface angelegt, dabei wird dann offenbar auch eine passende gnuplot config erzeugt)
Das Programm auf dem NanoESP ist entsprechend geändert, damit es einen GET-Request mit dieser URL sendet:
String url = „/fhem?cmd=setreading%20Light%20state%20L:%20“ + String(value);
Zusätzliche HTTP-Header oder den POST-Body, der im Original-Programm gesendet wird, braucht man nicht.
Hallo Ralf,
könntest Du mal den Sketch posten… ich kämpfe schon den ganzen Tag mit genau diesem Problem ;-((((
Die wichtigsten Änderungen gegenüber dem Original-Applet sind diese hier:
#define FhemHost „[Your Host]“
const byte fhemGet[] PROGMEM = {
‚G‘, ‚E‘, ‚T‘, ‚ ‚, ‚*‘, ‚U‘, ‚R‘, ‚L‘, ‚*‘, ‚ ‚, ‚H‘, ‚T‘, ‚T‘, ‚P‘, ‚/‘, ‚1‘, ‚.‘, ‚1‘, 10, 10
};
void loop() {
if (sendFhemGet(analogRead(SENSOR))) debug(„Update Send“);
delay(15000);
}
boolean sendFhemGet(int value)
{
boolean succes = true;
String Host = FhemHost;
String url = „/fhem?cmd=setreading%20Light%20state%20L:%20“ + String(value);
succes &= sendCom(„AT+CIPSTART=\“TCP\“,\““ + Host + „\“,8083″, „OK“);
String getRequest = createFhemGet(url);
if (sendCom(„AT+CIPSEND=“ + String(getRequest.length()), „>“))
{
esp8266.print(getRequest);
esp8266.find(„SEND OK“);
if (!esp8266.find(„CLOSED“)) succes &= sendCom(„AT+CIPCLOSE“, „OK“);
}
else
{
succes = false;
}
return succes;
}
String createFhemGet(String url)
{
String xBuffer;
for (int i = 0; i <= sizeof(fhemGet); i++)
{
char myChar = pgm_read_byte_near(fhemGet + i);
xBuffer += myChar;
}
xBuffer.replace("*URL*", url);
return xBuffer;
}
Gruß,
Ralf
funktioniert! Danke.
Hast Du eine Idee wie ich auch noch die Authentifizierung von FHEM dazu bekomme?
Zum Thema Authentifizierung mit FHEM, ich nehme an da steht in etwa sowas in der fhem.cfg:
attr WEB basicAuth ZmhlbXVzZXI6c2VjcmV0
Um dagegen zu authentifizieren, benötigt man im HTTP-Request einen zusätzlichen Header:
Authorization: Basic ZmhlbXVzZXI6c2VjcmV0
Im Applet würde sich dies hier ändern:
const byte fhemGet[] PROGMEM = {
‚G‘, ‚E‘, ‚T‘, ‚ ‚, ‚*‘, ‚U‘, ‚R‘, ‚L‘, ‚*‘, ‚ ‚, ‚H‘, ‚T‘, ‚T‘, ‚P‘, ‚/‘, ‚1‘, ‚.‘, ‚1‘, 10,
‚A‘, ‚u‘, ‚t‘, ‚h‘, ‚o‘, ‚r‘, ‚i‘, ‚z‘, ‚a‘, ‚t‘, ‚i‘, ‚o‘, ’n‘, ‚:‘, ‚ ‚, ‚B‘, ‚a‘, ’s‘, ‚i‘, ‚c‘, ‚ ‚,
‚Z‘, ‚m‘, ‚h‘, ‚l‘, ‚b‘, ‚X‘, ‚V‘, ‚z‘, ‚Z‘, ‚X‘, ‚I‘, ‚6‘, ‚c‘, ‚2‘, ‚V‘, ‚j‘, ‚c‘, ‚m‘, ‚V‘, ‚0‘,
10, 10
};
Bitte beachten, dass der base64-String im Authorization-Header abhängig von Username und Passwort ist, siehe FHEM-Doku zu basicAuth. Ich hab die Änderung oben jetzt nicht gegen FHEM getestet, aber von der Theorie her müsste das funktionieren ;-)
Interessant zu sehen ist, dass die Helligkeit einer LED-Lampe zwischen zwei Werten (in meinem Fall im Diagramm so zwischen 380 und 670) schwankt, wenn der Sensor in der Nähe derselben Lichtquelle unbewegt bleibt.
Bei Halogenlampen ist die Helligkeit dagegen fast konstant.
Das läßt sich auch technisch erklären, kommst Du selbst drauf?
Ich sag mal als Hilfe: Abtastung
Schon klar, wenn ich eine batteriebetriebene LED-Lampe nehm, dann schwankt da nix mehr.
Und bei ner LED-Lampe in Glühbirnenform kann man ja keinen grossen Aufwand für die Gleichrichtung treiben.
Doch bei recht teuren Steh- und Deckenlampen, die extra als LED-Lampe gebaut wurden (also keine LED als Glühlampenersatz) hätte ich dann schon ne perfekt geglättete Gleichspannung erwartet… ;-)
Leider sind auch die meisten teureren Trafos/Umformer nicht so genau ;-)