LED YouTube Live Subscriber Counter

Hallo zusammen,

Ich versuche gerade den LED YouTube Live Subscriber Counter zu installieren. So weit so gut. Die Aufgabe ist die YouTube-Abo-Zahlen abzurufen und auf einer LED auszugeben. Genau Info findet ihr hier: http://ibuynewstuff.com/led-youtube-live-subscriber-counter-red-play-button/

Leider bekomme ich folgende Meldung:

Connecting to home_Neu2,4 <- mein W-Lan
.............
WiFi connected
IP address: 
192.168.2.174
Subscribe :)
connecting to www.googleapis.com
connection failed

Wenn ich den Link aufrufe geht es aber bestens:
https://www.googleapis.com/youtube/v3/channels?part=statistics&id=meine_ID_&key=mein-key_&fields=items/statistics/subscriberCount

Meine ID und Key habe ich entfernt :frowning:

Ausgabe:

{
 "items": [
  {
   "statistics": {
    "subscriberCount": "2570"
   }
  }
 ]
}

Ich komme einfach nicht weiter. Anbei der Code:

Der Code ist im Anhang. Sind zu viel Zeilen.

Ich habe zur Sicherheit noch den Fingerprint hinzu gefügt was leider auch nicht geholfen hat.
Es wird keine Verbindung zum www.googleapis.com hergestellt.

Über eine Hilfe würde ich mich freuen. :slight_smile:

MFG Jörg

youtube.txt (21.4 KB)

Hi

Breche Deinen Sketch soweit zusammen, daß Du nur noch die Abfrage hast, Die Dich derzeit ärgert.
So hast Du einen Sketch, Der nicht so lang ist, kompiliert und von Jedem, Der ebenfalls einen 'was überhaupt' Sein Eigen nennt und ebenfalls bei YouTube auf diesen, Seinen, Zähler zugreifen kann, ausprobiert werden kann.

Zugangsdaten kann man in einem separatem Tab auslagern und Diesen, wie jede andere .h Datei, includieren.
So hast Du im Aufruf nur Platzhalter und musst nicht bei jedem Post drauf achten, daß Du wirklich alle privaten Informationen ge-x-t hast.

Selber habe ich noch keinen Arduino 'online', scheide daher wohl für produktive Hilfe aus - 'blöde' Ideen habe ich aber durchaus genug, Die ich Dir unterbreiten könnte.

MfG

PS: Du kannst Deinen aktuellen Sketch per 'Archivieren' als ZIP-File auf Platte speichern lassen - so versaust Du Dir nicht den jetzigen Stand.

Danke für den Tipp aber der Code ist frei zugänglich, nicht von mir und darf von jedem genutzt werden.

Ich habe einen weiteren für alle verfügbaren Code gefunden. Das passende Video findet sich hier.

Das ist eine schlankere Ausführung und benötigt auch nicht die Google API:

/*
  Code for the video:
  https://youtu.be/mn9L85bhyjI
  (c)2016 Pawel A. Hernik
 
  ESP-01 pinout:

  GPIO 2 - DataIn
  GPIO 1 - LOAD/CS
  GPIO 0 - CLK

  ------------------------
  NodeMCU 1.0 pinout:

  D8 - DataIn
  D7 - LOAD/CS
  D6 - CLK
*/


#include "Arduino.h"
#include <ESP8266WiFi.h>

WiFiClient client;

#define NUM_MAX 4
#define ROTATE 90

// for ESP-01 module
//#define DIN_PIN 2 // D4
//#define CS_PIN  3 // D9/RX
//#define CLK_PIN 0 // D3

// for NodeMCU 1.0
#define DIN_PIN 15  // D8
#define CS_PIN  13  // D7
#define CLK_PIN 12  // D6

#include "max7219.h"
#include "fonts.h"

// =======================================================================
// Your config below!
// =======================================================================
const char* ssid = "home_Neu2,4";
const char* password = "mein_passwort";
const char* YTchannel = "UCQS1ZB3BVSrBo3tCs7PyfxQ";   // YT user id
// =======================================================================

void setup() 
{
  Serial.begin(115200);
  initMAX7219();
  sendCmdAll(CMD_SHUTDOWN,1);
  sendCmdAll(CMD_INTENSITY,0);
  Serial.print("Connecting WiFi ");
  WiFi.begin(ssid, password);
  printStringWithShift(" WiFi ...",15);
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print("."); delay(500);
  }
  Serial.println("");
  Serial.print("Connected: "); Serial.println(WiFi.localIP());
}
// =======================================================================

void loop()
{
  Serial.println("Getting data ...");
  printStringWithShift("  ... YT ...",15);
  int subs, views, cnt = 0;
  String yt1,yt2;
  while(1) {
    if(!cnt--) {
      cnt = 50;  // data is refreshed every 50 loops
      if(getYTSubs(YTchannel,&subs,&views)==0) {
        yt1 = "     SUBSCRIBERS:      "+String(subs)+" ";
        yt2 = "      VIEWS:   "+String(views);
      } else {
        yt1 = "   YouTube";
        yt2 = "   Error!";
      }
    }
    printStringWithShift(yt1.c_str(),20);
    delay(3000);
    printStringWithShift(yt2.c_str(),20);
    delay(3000);
  }
}
// =======================================================================

int showChar(char ch, const uint8_t *data)
{
  int len = pgm_read_byte(data);
  int i,w = pgm_read_byte(data + 1 + ch * len);
  for (i = 0; i < w; i++)
    scr[NUM_MAX*8 + i] = pgm_read_byte(data + 1 + ch * len + 1 + i);
  scr[NUM_MAX*8 + i] = 0;
  return w;
}

// =======================================================================
int dualChar = 0;

unsigned char convertPolish(unsigned char _c)
{
  unsigned char c = _c;
  if(c==196 || c==197 || c==195) {
    dualChar = c;
    return 0;
  }
  if(dualChar) {
    switch(_c) {
      case 133: c = 1+'~'; break; // 'ą'
      case 135: c = 2+'~'; break; // 'ć'
      case 153: c = 3+'~'; break; // 'ę'
      case 130: c = 4+'~'; break; // 'ł'
      case 132: c = dualChar==197 ? 5+'~' : 10+'~'; break; // 'ń' and 'Ą'
      case 179: c = 6+'~'; break; // 'ó'
      case 155: c = 7+'~'; break; // 'ś'
      case 186: c = 8+'~'; break; // 'ź'
      case 188: c = 9+'~'; break; // 'ż'
      //case 132: c = 10+'~'; break; // 'Ą'
      case 134: c = 11+'~'; break; // 'Ć'
      case 152: c = 12+'~'; break; // 'Ę'
      case 129: c = 13+'~'; break; // 'Ł'
      case 131: c = 14+'~'; break; // 'Ń'
      case 147: c = 15+'~'; break; // 'Ó'
      case 154: c = 16+'~'; break; // 'Ś'
      case 185: c = 17+'~'; break; // 'Ź'
      case 187: c = 18+'~'; break; // 'Ż'
      default:  break;
    }
    dualChar = 0;
    return c;
  }    
  switch(_c) {
    case 185: c = 1+'~'; break;
    case 230: c = 2+'~'; break;
    case 234: c = 3+'~'; break;
    case 179: c = 4+'~'; break;
    case 241: c = 5+'~'; break;
    case 243: c = 6+'~'; break;
    case 156: c = 7+'~'; break;
    case 159: c = 8+'~'; break;
    case 191: c = 9+'~'; break;
    case 165: c = 10+'~'; break;
    case 198: c = 11+'~'; break;
    case 202: c = 12+'~'; break;
    case 163: c = 13+'~'; break;
    case 209: c = 14+'~'; break;
    case 211: c = 15+'~'; break;
    case 140: c = 16+'~'; break;
    case 143: c = 17+'~'; break;
    case 175: c = 18+'~'; break;
    default:  break;
  }
  return c;
}

// =======================================================================

void printCharWithShift(unsigned char c, int shiftDelay) {
  c = convertPolish(c);
  if (c < ' ' || c > MAX_CHAR) return;
  c -= 32;
  int w = showChar(c, font);
  for (int i=0; i<w+1; i++) {
    delay(shiftDelay);
    scrollLeft();
    refreshAll();
  }
}

// =======================================================================

void printStringWithShift(const char* s, int shiftDelay){
  while (*s) {
    printCharWithShift(*s++, shiftDelay);
  }
}

// =======================================================================
unsigned int convToInt(const char *txt)
{
  unsigned int val = 0;
  for(int i=0; i<strlen(txt); i++)
    if(isdigit(txt[i])) val=val*10+(txt[i]&0xf);
  return val;
}
// =======================================================================

const char* ytHost = "www.youtube.com";
int getYTSubs(const char *channelId, int *pSubs, int *pViews)
{
  if(!pSubs || !pViews) return -2;
  WiFiClientSecure client;
  Serial.print("connecting to "); Serial.println(ytHost);
  if (!client.connect(ytHost, 443)) {
    Serial.println("connection failed");
    return -1;
  }
  client.print(String("GET /channel/") + String(channelId) +"/about HTTP/1.1\r\n" + "Host: " + ytHost + "\r\nConnection: close\r\n\r\n");
  int repeatCounter = 10;
  while (!client.available() && repeatCounter--) {
    Serial.println("y."); delay(500);
  }
  int idxS, idxE, statsFound = 0;
  *pSubs = *pViews = 0;
  while (client.connected() && client.available()) {
    String line = client.readStringUntil('\n');
    if(statsFound == 0) {
      statsFound = (line.indexOf("about-stats")>0);
    } else {
      idxS = line.indexOf("<b>");
      idxE = line.indexOf("</b>");
      String val = line.substring(idxS + 3, idxE);
      if(!*pSubs)
        *pSubs = convToInt(val.c_str());
      else {
        *pViews = convToInt(val.c_str());
        break;
      }
    }
  }
  client.stop();
  return 0;
}

Leider bekomme ich hier die gleiche Meldung. Aus der ich jetzt folge das mein Router eventuell die Anfragen blockieren könnte. Kann das sein? Die Anfrage wird ja auch nicht blockiert wenn ich die mit dem Browser aufrufe?

Meldung:

Connecting WiFi .........
Connected: 192.168.2.174
Getting data ...
connecting to www.youtube.com
connection failed

Einer eine Idee?

Brauchst Du vieleicht einen Account oder Registrierung bei Youtube?
Grüße Uwe

Hi

Wird dort 'www.youtube.de/...' aufgerufen, fehlt Da vll. nur das http:// davor?

MfG

uwefed:
Brauchst Du vieleicht einen Account oder Registrierung bei Youtube?
Grüße Uwe

Bei dem ersten Code braucht man den (habe ich auch) bei dem zweiten nicht.

und wie schon Beschrieben ruft man die Seite über den Browser auf geht es.

Danke

Hi

Im Browser kann ich auch auf das www. verzichten - nicht Alles, was Du machst, wird auch genau so von der Technik weiter gegeben - überall wird dem 'dummen User' unter die Arme gegriffen, daß Der nicht überall Alles selber machen muß.
Nennt man Komfort, dabei verliert man aber auch die Kontrolle darüber, was wirklich abläuft.

Du darfst weiter davon ausgehen, daß wir Deine Beiträge durchaus mit Interesse lesen und uns so Kleinigkeiten wie 'Das und Das klappt' nicht entgehen.

MfG

Ein Auszug aus dem ibuynewstuff Link

While it’s cool to see your live subscriber count on this nice 80×8 LED display,
... It should run from the voltage supplied by the pins of the ESP8266 because it doesn’t use too many LEDS,
but you can always attach the 5V DC power supply to the back screws of the board if you need more juice (I recommend this).
It will make the display of the LED YouTube Live Subscriber Counter brighter and run to ideal power conditions.

Das nenne ich mal optimistisch :wink:

Obwohl auch schon so anscheinend die Spannung einbricht.

Hoffentlich versteht der Author mehr von Soft- als von Hardware.

Whandall:
Ein Auszug aus dem ibuynewstuff Link

Das nenne ich mal optimistisch :wink:

Obwohl auch schon so anscheinend die Spannung einbricht.

Hoffentlich versteht der Author mehr von Soft- als von Hardware.

Leine Sorge ich schließe ein zusätzliche Netzteil an :slight_smile:

Na hoffentlich :wink:

Die ESPs sind sowieso ziemlich empfindlich was die Stromversorgung angeht finde ich,
da is es keine gute Idee einer NodeMCU 640 LEDs an 5V zu legen, auch nicht gemultiplext.

Die Funktion printStringWithShift setzt "connection failed", wenn if (!client.connect(ytHost, 443)) false ist:

const char* ytHost = "www.youtube.com";
int getYTSubs(const char *channelId, int *pSubs, int *pViews)
{
  if(!pSubs || !pViews) return -2;
  WiFiClientSecure client;
  Serial.print("connecting to "); Serial.println(ytHost);
  if (!client.connect(ytHost, 443)) {
    Serial.println("connection failed");
    return -1;
  }

443 wird mit Sicherheit der Port sein und 443 benötigt bestimmt https://, vermutlich läuft hier die automatische Weiterleitung von http zu https nicht.

Ändere mal
const char* ytHost = "www.youtube.com";

in
const char* ytHost = "https://www.youtube.com";
und teste es erneut.

Habe ich auch gedacht leider bleibt es bei "connection failed"..... :confused:

WiFi connected
IP address: 
192.168.178.44
Subscribe :)
connecting to https://www.youtube.com
connection failed

Für https (Port 443) brauchst Du auch einen Client, der das kann.
Schaue Dir mal den WiFiClientSecure an.

Gruß Tommy

Ich würde mal das https:// aus dem yHost wieder rausmachen.

Und dann am client mal getLastSSLError(...) aufrufen um zu sehen warum das connect(...) schiefgeht.

Tommy56:
Für https (Port 443) brauchst Du auch einen Client, der das kann.
Schaue Dir mal den WiFiClientSecure an.

Gruß Tommy

Danke für deine Hilfe. Ich habe die WiFiClientSecure Bibliothek eingebunden. Muss ich den was besonders beachten?

mfg

Das kommt darauf an, welche Version der ESP8266-Libs Du verwendest.

Bei 2.3.x kannst Du erst mal die Fingerprint-Prüfung weg lassen, bei >= 2.4.x solltest Du für die ersten Tests client.setInsecure() benutzen.

In wieweit das dann für den produktiven Einsatz genügt, musst Du selbst entscheiden.

Gruß Tommy

Rintin:
Ich würde mal das https:// aus dem yHost wieder rausmachen.

Und dann am client mal getLastSSLError(...) aufrufen um zu sehen warum das connect(...) schiefgeht.

Da ich nicht weiter gekommen bin habe ich ein länger Pause gemacht :slight_smile:

Deswegen erst heute meine erneute Frage. Wie binde ich den getLastSSLError genau ein. Ich habe verschiedene Varianten getestet (kann leider nicht Programmieren) komme aber zu keinem Ergebnis. Würdest du mir mit einem Beispielcode helfen?

mfg

Tommy56:
Das kommt darauf an, welche Version der ESP8266-Libs Du verwendest.

Bei 2.3.x kannst Du erst mal die Fingerprint-Prüfung weg lassen, bei >= 2.4.x solltest Du für die ersten Tests client.setInsecure() benutzen.

In wieweit das dann für den produktiven Einsatz genügt, musst Du selbst entscheiden.

Gruß Tommy

Hallo Tommy,

hast du hier einen Beispielcode für mich. Leider verstehe ich da nur Bahnhof.. :slight_smile:

MFG Jörg

Nutze die Beispiele aus den Libs. z.B. HTTPSRequest

Die hast Du auch auf Deinem PC.

Gruß Tommy