2022-01-09 16:53:22 +08:00
|
|
|
|
#ifndef __UTILS__
|
2022-01-08 18:32:31 +08:00
|
|
|
|
#include <utils.h>
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#include <Arduino.h>
|
|
|
|
|
|
|
|
|
|
#include <ESP8266WiFi.h>
|
|
|
|
|
#include <ESP8266HTTPClient.h>
|
2022-01-10 03:15:46 +08:00
|
|
|
|
#include <WiFiClientSecureBearSSL.h>
|
2022-01-08 18:32:31 +08:00
|
|
|
|
|
|
|
|
|
#include <ArduinoJson.h>
|
|
|
|
|
|
2022-01-09 01:19:45 +08:00
|
|
|
|
#include <TimeLib.h>
|
|
|
|
|
#include <WiFiUdp.h>
|
|
|
|
|
|
2022-01-09 16:53:22 +08:00
|
|
|
|
// Global Config
|
|
|
|
|
IPConfig APStatic = {
|
|
|
|
|
IPAddress(10, 1, 1, 1),
|
|
|
|
|
IPAddress(10, 0, 1, 1),
|
|
|
|
|
IPAddress(255, 255, 255, 0)
|
|
|
|
|
};
|
|
|
|
|
IPConfig STAStatic = {
|
|
|
|
|
IPAddress(192, 168, 43, 141),
|
|
|
|
|
IPAddress(192,168,0,1),
|
|
|
|
|
IPAddress(255, 255, 255, 0)
|
|
|
|
|
};
|
2022-01-09 17:42:48 +08:00
|
|
|
|
BoardInfo Board = {
|
2022-01-10 20:27:23 +08:00
|
|
|
|
"0.1.0",
|
2022-01-09 17:42:48 +08:00
|
|
|
|
WiFi.localIP()
|
|
|
|
|
};
|
2022-01-09 16:53:22 +08:00
|
|
|
|
|
2022-01-09 01:19:45 +08:00
|
|
|
|
// https://github.com/PaulStoffregen/Time/blob/master/examples/TimeNTP_ESP8266WiFi/TimeNTP_ESP8266WiFi.ino
|
|
|
|
|
static const int timeZone = 8;
|
|
|
|
|
static const int NTP_PACKET_SIZE = 48;
|
|
|
|
|
static byte packetBuffer[NTP_PACKET_SIZE];
|
|
|
|
|
static IPAddress ntpServerIP(203, 107, 6, 88);
|
|
|
|
|
// static const char ntpServerName[] = "ntp.aliyun.com";
|
|
|
|
|
|
|
|
|
|
static bool isNTPConnected = false;
|
|
|
|
|
static WiFiUDP ntpUDP;
|
|
|
|
|
static unsigned int localPort = 2390;
|
|
|
|
|
|
|
|
|
|
static void sendNTPpacket(IPAddress& address)
|
|
|
|
|
{
|
|
|
|
|
memset(packetBuffer, 0, NTP_PACKET_SIZE);
|
|
|
|
|
packetBuffer[0] = 0b11100011; // LI, Version, Mode
|
|
|
|
|
packetBuffer[1] = 0; // Stratum, or type of clock
|
|
|
|
|
packetBuffer[2] = 6; // Polling Interval
|
|
|
|
|
packetBuffer[3] = 0xEC; // Peer Clock Precision
|
|
|
|
|
// 8 bytes of zero for Root Delay & Root Dispersion
|
|
|
|
|
packetBuffer[12] = 49;
|
|
|
|
|
packetBuffer[13] = 0x4E;
|
|
|
|
|
packetBuffer[14] = 49;
|
|
|
|
|
packetBuffer[15] = 52;
|
|
|
|
|
ntpUDP.beginPacket(address, 123);
|
|
|
|
|
ntpUDP.write(packetBuffer, NTP_PACKET_SIZE);
|
|
|
|
|
ntpUDP.endPacket();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static time_t getNtpTime() {
|
|
|
|
|
byte tmp[1];
|
|
|
|
|
while( ntpUDP.parsePacket() > 0 ) ntpUDP.read(tmp, 1);
|
|
|
|
|
|
|
|
|
|
sendNTPpacket(ntpServerIP);
|
|
|
|
|
|
|
|
|
|
uint32_t beginWait = millis();
|
|
|
|
|
while( millis() - beginWait < 1500 )
|
|
|
|
|
{
|
|
|
|
|
int size = ntpUDP.parsePacket();
|
|
|
|
|
if( size >= NTP_PACKET_SIZE )
|
|
|
|
|
{
|
|
|
|
|
isNTPConnected = true;
|
|
|
|
|
ntpUDP.read(packetBuffer, NTP_PACKET_SIZE);
|
|
|
|
|
|
|
|
|
|
// 将从位置40开始的四个字节转换为长整型,只取前32位整数部分
|
|
|
|
|
unsigned long secsSince1900;
|
|
|
|
|
secsSince1900 = (unsigned long)packetBuffer[40] << 24;
|
|
|
|
|
secsSince1900 |= (unsigned long)packetBuffer[41] << 16;
|
|
|
|
|
secsSince1900 |= (unsigned long)packetBuffer[42] << 8;
|
|
|
|
|
secsSince1900 |= (unsigned long)packetBuffer[43];
|
|
|
|
|
|
|
|
|
|
return secsSince1900 - 2208988800UL + timeZone * SECS_PER_HOUR;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
isNTPConnected = false;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void initNtp() {
|
|
|
|
|
ntpUDP.begin(localPort);
|
|
|
|
|
setSyncProvider(getNtpTime);
|
|
|
|
|
setSyncInterval(300);
|
|
|
|
|
}
|
2022-01-08 18:32:31 +08:00
|
|
|
|
|
2022-01-09 01:19:45 +08:00
|
|
|
|
static String formatDigits(int digits)
|
|
|
|
|
{
|
|
|
|
|
if( digits < 10 )
|
|
|
|
|
return "0" + (String)digits;
|
|
|
|
|
return (String)digits;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
String ntpTime() {
|
|
|
|
|
String timeString("");
|
|
|
|
|
timeString = (String)year() + '-'
|
|
|
|
|
+ formatDigits(month()) + '-'
|
|
|
|
|
+ formatDigits(day()) + ' '
|
|
|
|
|
+ formatDigits(hour()) + ':'
|
|
|
|
|
+ formatDigits(minute()) + ':'
|
|
|
|
|
+ formatDigits(second());
|
|
|
|
|
return timeString;
|
|
|
|
|
}
|
2022-01-08 18:32:31 +08:00
|
|
|
|
|
|
|
|
|
|
2022-01-09 01:19:45 +08:00
|
|
|
|
long view = 0;
|
|
|
|
|
long likes = 0;
|
2022-01-09 17:42:48 +08:00
|
|
|
|
long follower = 0;
|
2022-01-09 01:19:45 +08:00
|
|
|
|
long dayView = 0;
|
|
|
|
|
long weekView = 0;
|
|
|
|
|
long monthView = 0;
|
|
|
|
|
|
2022-01-10 03:15:46 +08:00
|
|
|
|
static String UID = "450115492";
|
|
|
|
|
static String followerUrl = "http://api.bilibili.com/x/relation/stat?vmid=" + UID;
|
|
|
|
|
static String viewAndLikesUrl = "http://api.bilibili.com/x/space/upstat?mid=" + UID;
|
2022-01-09 17:42:48 +08:00
|
|
|
|
static String webViewerUrl = "https://api.foolishfox.cn/data/board.json";
|
|
|
|
|
|
2022-01-10 20:26:01 +08:00
|
|
|
|
const char UserAgent[] PROGMEM = "UserAgent";
|
|
|
|
|
const char Cookie[] PROGMEM = "Cookie";
|
2022-01-09 01:19:45 +08:00
|
|
|
|
|
2022-01-10 03:15:46 +08:00
|
|
|
|
static WiFiClient client;
|
|
|
|
|
std::unique_ptr<BearSSL::WiFiClientSecure>clientSecure(new BearSSL::WiFiClientSecure);
|
|
|
|
|
StaticJsonDocument<256> jsonBuffer;
|
2022-01-09 01:19:45 +08:00
|
|
|
|
|
2022-01-10 03:15:46 +08:00
|
|
|
|
static void getFollower() {
|
|
|
|
|
HTTPClient http;
|
|
|
|
|
http.begin(client, followerUrl);
|
|
|
|
|
|
|
|
|
|
int resCode = http.GET();
|
2022-01-10 20:26:01 +08:00
|
|
|
|
|
2022-01-09 01:19:45 +08:00
|
|
|
|
if( resCode == 200 ) {
|
2022-01-10 03:15:46 +08:00
|
|
|
|
String resBuffer = http.getString();
|
2022-01-10 20:26:01 +08:00
|
|
|
|
Serial.println(resBuffer);
|
2022-01-09 01:19:45 +08:00
|
|
|
|
DeserializationError error = deserializeJson(jsonBuffer, resBuffer);
|
2022-01-08 18:32:31 +08:00
|
|
|
|
|
|
|
|
|
if( error ) {
|
2022-01-09 01:19:45 +08:00
|
|
|
|
Serial.print(F("deserializeJson(Follower) failed: "));
|
2022-01-08 18:32:31 +08:00
|
|
|
|
Serial.println(error.f_str());
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
follower = jsonBuffer["data"]["follower"];
|
|
|
|
|
} else {
|
2022-01-10 20:26:01 +08:00
|
|
|
|
Serial.printf_P(PSTR("[HTTP] GET Follower failed, error: %d\n"), resCode);
|
2022-01-08 18:32:31 +08:00
|
|
|
|
}
|
|
|
|
|
|
2022-01-10 03:15:46 +08:00
|
|
|
|
http.end();
|
2022-01-08 18:32:31 +08:00
|
|
|
|
}
|
|
|
|
|
|
2022-01-10 03:15:46 +08:00
|
|
|
|
static void getViewAndLikes() {
|
|
|
|
|
HTTPClient http;
|
|
|
|
|
http.begin(client, viewAndLikesUrl);
|
|
|
|
|
|
|
|
|
|
http.addHeader("Host", "api.bilibili.com");
|
|
|
|
|
http.addHeader("User-Agent", UserAgent);
|
|
|
|
|
http.addHeader("Cookie", Cookie);
|
2022-01-09 01:19:45 +08:00
|
|
|
|
|
2022-01-10 03:15:46 +08:00
|
|
|
|
int resCode = http.GET();
|
2022-01-09 01:19:45 +08:00
|
|
|
|
if( resCode == 200 ) {
|
2022-01-10 03:15:46 +08:00
|
|
|
|
String resBuffer = http.getString();
|
2022-01-10 20:26:01 +08:00
|
|
|
|
Serial.println(resBuffer);
|
2022-01-09 01:19:45 +08:00
|
|
|
|
DeserializationError error = deserializeJson(jsonBuffer, resBuffer);
|
|
|
|
|
|
|
|
|
|
if( error ) {
|
|
|
|
|
Serial.print(F("deserializeJson(View & Likes) failed: "));
|
|
|
|
|
Serial.println(error.f_str());
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
likes = jsonBuffer["data"]["likes"];
|
|
|
|
|
view = jsonBuffer["data"]["archive"]["view"];
|
|
|
|
|
} else {
|
2022-01-10 20:26:01 +08:00
|
|
|
|
Serial.printf_P(PSTR("[HTTP] GET View & Likes failed, error: %d\n"), resCode);
|
2022-01-09 01:19:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
2022-01-10 03:15:46 +08:00
|
|
|
|
http.end();
|
2022-01-09 01:19:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
2022-01-10 03:15:46 +08:00
|
|
|
|
static void getWebView() {
|
|
|
|
|
HTTPClient https;
|
|
|
|
|
clientSecure->setInsecure();
|
|
|
|
|
https.begin(*clientSecure, webViewerUrl);
|
2022-01-09 01:19:45 +08:00
|
|
|
|
|
2022-01-10 03:15:46 +08:00
|
|
|
|
int resCode = https.GET();
|
2022-01-09 01:19:45 +08:00
|
|
|
|
if( resCode == 200 ) {
|
2022-01-10 03:15:46 +08:00
|
|
|
|
String resBuffer = https.getString();
|
2022-01-10 20:26:01 +08:00
|
|
|
|
Serial.println(resBuffer);
|
2022-01-09 01:19:45 +08:00
|
|
|
|
DeserializationError error = deserializeJson(jsonBuffer, resBuffer);
|
|
|
|
|
|
|
|
|
|
if( error ) {
|
|
|
|
|
Serial.print(F("deserializeJson(Web View) failed: "));
|
|
|
|
|
Serial.println(error.f_str());
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dayView = jsonBuffer["day"];
|
|
|
|
|
weekView = jsonBuffer["week"];
|
|
|
|
|
monthView = jsonBuffer["month"];
|
|
|
|
|
} else {
|
2022-01-10 20:26:01 +08:00
|
|
|
|
Serial.printf_P(PSTR("[HTTP] GET Web View failed, error: %d\n"), resCode);
|
2022-01-09 01:19:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
2022-01-10 03:15:46 +08:00
|
|
|
|
https.end();
|
2022-01-09 01:19:45 +08:00
|
|
|
|
}
|
2022-01-08 18:32:31 +08:00
|
|
|
|
|
2022-01-09 17:42:48 +08:00
|
|
|
|
void getData() {
|
2022-01-09 01:19:45 +08:00
|
|
|
|
getFollower();
|
|
|
|
|
getViewAndLikes();
|
2022-01-10 03:15:46 +08:00
|
|
|
|
getWebView();
|
2022-01-08 18:32:31 +08:00
|
|
|
|
}
|