INFOBoard/lib/utils/utils.cpp

215 lines
5.7 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#ifndef __UTILS__
#include <utils.h>
#endif
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClientSecureBearSSL.h>
#include <ArduinoJson.h>
#include <TimeLib.h>
#include <WiFiUdp.h>
// 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)
};
BoardInfo Board = {
"0.0.1",
WiFi.localIP()
};
// 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);
}
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;
}
long view = 0;
long likes = 0;
long follower = 0;
long dayView = 0;
long weekView = 0;
long monthView = 0;
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;
static String webViewerUrl = "https://api.foolishfox.cn/data/board.json";
static const char UserAgent[] PROGMEM = "UserAgent";
static const char Cookie[] PROGMEM = "Cookie";
static WiFiClient client;
std::unique_ptr<BearSSL::WiFiClientSecure>clientSecure(new BearSSL::WiFiClientSecure);
StaticJsonDocument<256> jsonBuffer;
static void getFollower() {
HTTPClient http;
http.begin(client, followerUrl);
int resCode = http.GET();
if( resCode == 200 ) {
String resBuffer = http.getString();
DeserializationError error = deserializeJson(jsonBuffer, resBuffer);
if( error ) {
Serial.print(F("deserializeJson(Follower) failed: "));
Serial.println(error.f_str());
return;
}
follower = jsonBuffer["data"]["follower"];
} else {
Serial.printf("[HTTP] GET Follower failed, error: %d\n", resCode);
}
http.end();
}
static void getViewAndLikes() {
HTTPClient http;
http.begin(client, viewAndLikesUrl);
http.addHeader("Host", "api.bilibili.com");
http.addHeader("User-Agent", UserAgent);
http.addHeader("Cookie", Cookie);
int resCode = http.GET();
if( resCode == 200 ) {
String resBuffer = http.getString();
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 {
Serial.printf("[HTTP] GET View & Likes failed, error: %d\n", resCode);
}
http.end();
}
static void getWebView() {
HTTPClient https;
clientSecure->setInsecure();
https.begin(*clientSecure, webViewerUrl);
int resCode = https.GET();
if( resCode == 200 ) {
String resBuffer = https.getString();
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 {
Serial.printf("[HTTP] GET Web View failed, error: %d\n", resCode);
}
https.end();
}
void getData() {
getFollower();
getViewAndLikes();
getWebView();
}