Moin,
habe schon hier im Forum geschaut und auch ein 2 Jahre alten post gefunden, der mir leider nicht weitergeholfen hat - die Basis des Codes habe ich auch benutzt.
So nun zum Problem. Habe eine Bekannte die anfängt zu camen (camgirl) und gerne einen "Abo Counter" haben möchte. Sowas kennt man ja schon von yt und co.
Der erste Teil wäre nun das parsen, wo ich ja nicht weiterkomme ,danach müsste ich noch die Werte an die Led Segmente ausgeben.
Also mal im quelltext ihres Profils geschaut und sah ihre follower, User Agent verbietet mir aber das parsen.
Habe dann ihre Zugangsdaten bekommen und fand das ich mir ein Token generieren konnte, was ich auch gemacht habe.
Hier ist auch das Problem habe noch nie mit einer api/json gearbeitet.
Die meisten Beispiele sind in json v5, also kurz ArduinoJson gedowngradet.
So ist der aufbau der json:
{
"username": "abc",
"time_online": -1,
"tips_in_last_hour": null,
"num_followers": 1, <- das will ich haben
"token_balance": 0, <- das will ich haben
"satisfaction_score": 100,
"num_tokened_viewers": 0,
"votes_down": 0,
"votes_up": 1,
"last_broadcast": "2000-01-01T01:11:111.111111",
"num_registered_viewers": 0,
"num_viewers": 0
}
Mein jetziger Code:
#include <ESP8266HTTPClient.h>
#include <ArduinoJson.h>
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <WiFiUdp.h>
WiFiClient client;
const char WiFiSSID[] = "wlanssid"; //### your Router SSID
const char WiFiPSK[] = "wlanpw"; //### your Router Password
const char* server = "chaturbate.com"; // server's address
const char* resource = "/statsapi/?username=abc123&token=langertoken"; // http resource "Kanalinfo"
const unsigned long BAUD_RATE = 115200; // serial connection speed
const unsigned long HTTP_TIMEOUT = 10000; // max respone time from server
const size_t MAX_CONTENT_SIZE = 512; // max size of the HTTP response
bool isConnected(long timeOutSec) {
timeOutSec = timeOutSec * 1000; int z = 0;
while (WiFi.status() != WL_CONNECTED) {
delay(200);
Serial.print(".");
if (z == timeOutSec / 200) { return false; }
z++; } return true;}
// The type of data that we want to extract from the page
struct UserData {
char num_followers[32];
char token_balance[32];
};
// ARDUINO entry point #1: runs once when you press reset or power the board
void setup() {
initSerial();
WiFi.mode(WIFI_STA);
WiFi.begin(WiFiSSID, WiFiPSK);
if (isConnected(30)) {
Serial.println(F("WLAN läuft")); }}
// ARDUINO entry point #2: runs over and over again forever
void loop() {
if (connect(server)) {
if (sendRequest(server, resource) && skipResponseHeaders()) {
UserData userData;
if (readReponseContent(&userData)) {
printUserData(&userData);
}
}
}
disconnect();
wait();
}
// Initialize Serial port
void initSerial() {
Serial.begin(BAUD_RATE);
while (!Serial) {
; // wait for serial port to initialize
}
Serial.println("Serial ready");
}
// Open connection to the HTTP server
bool connect(const char* hostName) {
Serial.print("Connect to ");
Serial.println(hostName);
bool ok = client.connect(hostName, 80);
Serial.println(ok ? "Connected" : "Connection Failed!");
return ok;
}
// Send the HTTP GET request to the server
bool sendRequest(const char* host, const char* resource) {
Serial.print("GET ");
Serial.println(resource);
client.print("GET ");
client.print(resource);
client.println(" HTTP/1.0");
client.print("Host: ");
client.println(host);
client.println("Connection: close");
client.println();
return true;
}
// Skip HTTP headers so that we are at the beginning of the response's body
bool skipResponseHeaders() {
// HTTP headers end with an empty line
char endOfHeaders[] = "\r\n\r\n";
client.setTimeout(HTTP_TIMEOUT);
bool ok = client.find(endOfHeaders);
if (!ok) {
Serial.println("No response or invalid response!");
}
return ok;
}
// Parse the JSON from the input string and extract the interesting values
// Here is the JSON we need to parse
//{
// "username": "abc",
// "time_online": -1,
// "tips_in_last_hour": null,
// "num_followers": 1,
// "token_balance": 0,
// "satisfaction_score": 100,
// "num_tokened_viewers": 0,
// "votes_down": 0,
// "votes_up": 1,
// "last_broadcast": "2000-01-01T01:11:118.111111",
// "num_registered_viewers": 0,
// "num_viewers": 0
// }
bool readReponseContent(struct UserData* userData) {
// Compute optimal size of the JSON buffer according to what we need to parse.
// See https://bblanchon.github.io/ArduinoJson/assistant/
const size_t BUFFER_SIZE =
JSON_OBJECT_SIZE(1) // the root object has 2 elements
+ JSON_OBJECT_SIZE(5) // the "entity" object has 5 elements
+ MAX_CONTENT_SIZE; // additional space for strings
// Allocate a temporary memory pool
DynamicJsonBuffer jsonBuffer(BUFFER_SIZE);
JsonObject& root = jsonBuffer.parseObject(client);
if (!root.success()) {
Serial.println("JSON parsing failed!");
return false;
}
// Here were copy the strings we're interested in
strcpy(userData->num_followers, root["num_followers"]);
strcpy(userData->token_balance, root["token_balance"]);
// It's not mandatory to make a copy, you could just use the pointers
// Since, they are pointing inside the "content" buffer, so you need to make
// sure it's still in memory when you read the string
return true;
}
// Print the data extracted from the JSON
void printUserData(const struct UserData* userData) {
Serial.print("Deine Follower:");
Serial.println(userData->num_followers);
Serial.print("Deine Token:");
Serial.println(userData->token_balance);
}
// Close the connection with the HTTP server
void disconnect() {
Serial.println("Disconnect");
client.stop();
}
// Pause for a 10 minute
void wait() {
Serial.println("Wait 600 seconds");
delay(600000);
}
Sehe gerade das ich #include <WiFiUdp.h> nicht brauche. Mein weiterer Gedanke war, dass das Programm vielleicht mit http die Anfrage macht. Aber in der url ist https, könnte hier ein Fehler sein?
Im Monitor bekomme ich
connect to chaturbate.com
connected
GET /statsapi/?username=abc123&token=langertoken
JSON parsing failed!
Disconnect
Habe mir auch schon überlegt den ganzen Code neu zumachen und gleich ArduinoJson v6 zu benutzten, sollte ich das lieber machen oder ist im obigem Code nur ein kleiner Fehler den ich übersehe?