NerdNos-Firmware/src/monitor.cpp
2023-09-09 13:47:13 +03:00

294 lines
8.8 KiB
C++

#include <Arduino.h>
#include <WiFi.h>
#include "mbedtls/md.h"
#include "HTTPClient.h"
#include <NTPClient.h>
#include <WiFiUdp.h>
#include "mining.h"
#include "utils.h"
#include "monitor.h"
extern char poolString[80];
extern uint32_t templates;
extern uint32_t hashes;
extern uint32_t Mhashes;
extern uint32_t totalKHashes;
extern uint32_t elapsedKHs;
extern uint64_t upTime;
extern uint32_t shares; // increase if blockhash has 32 bits of zeroes
extern uint32_t valids; // increased if blockhash <= targethalfshares
extern double best_diff; // track best diff
extern monitor_data mMonitor;
extern int GMTzone; //Gotten from saved config
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "europe.pool.ntp.org", 3600, 60000);
unsigned int bitcoin_price=0;
String current_block = "793261";
global_data gData;
void setup_monitor(void){
/******** TIME ZONE SETTING *****/
timeClient.begin();
// Adjust offset depending on your zone
// GMT +2 in seconds (zona horaria de Europa Central)
timeClient.setTimeOffset(3600 * GMTzone);
Serial.println("TimeClient setup done");
}
unsigned long mGlobalUpdate =0;
void updateGlobalData(void){
if((mGlobalUpdate == 0) || (millis() - mGlobalUpdate > UPDATE_Global_min * 60 * 1000)){
if (WiFi.status() != WL_CONNECTED) return;
//Make first API call to get global hash and current difficulty
HTTPClient http;
http.begin(getGlobalHash);
int httpCode = http.GET();
if (httpCode == HTTP_CODE_OK) {
String payload = http.getString();
DynamicJsonDocument doc(1024);
deserializeJson(doc, payload);
String temp = "";
if (doc.containsKey("currentHashrate")) temp = String(doc["currentHashrate"].as<float>());
if(temp.length()>18 + 3) //Exahashes more than 18 digits + 3 digits decimals
gData.globalHash = temp.substring(0,temp.length()-18 - 3);
if (doc.containsKey("currentDifficulty")) temp = String(doc["currentDifficulty"].as<float>());
if(temp.length()>10 + 3){ //Terahash more than 10 digits + 3 digit decimals
temp = temp.substring(0,temp.length()-10 - 3);
gData.difficulty = temp.substring(0,temp.length()-2) + "." + temp.substring(temp.length()-2,temp.length()) + "T";
}
doc.clear();
mGlobalUpdate = millis();
}
http.end();
//Make third API call to get fees
http.begin(getFees);
httpCode = http.GET();
if (httpCode == HTTP_CODE_OK) {
String payload = http.getString();
DynamicJsonDocument doc(1024);
deserializeJson(doc, payload);
String temp = "";
if (doc.containsKey("halfHourFee")) gData.halfHourFee = doc["halfHourFee"].as<int>();
doc.clear();
mGlobalUpdate = millis();
}
http.end();
}
}
unsigned long mHeightUpdate = 0;
String getBlockHeight(void){
if((mHeightUpdate == 0) || (millis() - mHeightUpdate > UPDATE_Height_min * 60 * 1000)){
if (WiFi.status() != WL_CONNECTED) return current_block;
HTTPClient http;
http.begin(getHeightAPI);
int httpCode = http.GET();
if (httpCode == HTTP_CODE_OK) {
String payload = http.getString();
payload.trim();
current_block = payload;
mHeightUpdate = millis();
}
http.end();
}
return current_block;
}
unsigned long mBTCUpdate = 0;
String getBTCprice(void){
if((mBTCUpdate == 0) || (millis() - mBTCUpdate > UPDATE_BTC_min * 60 * 1000)){
if (WiFi.status() != WL_CONNECTED) return (String(bitcoin_price) + "$");
HTTPClient http;
http.begin(getBTCAPI);
int httpCode = http.GET();
if (httpCode == HTTP_CODE_OK) {
String payload = http.getString();
DynamicJsonDocument doc(1024);
deserializeJson(doc, payload);
if (doc.containsKey("bitcoin")) bitcoin_price = doc["bitcoin"]["usd"];
doc.clear();
mBTCUpdate = millis();
}
http.end();
}
return (String(bitcoin_price) + "$");
}
unsigned long mTriggerUpdate = 0;
unsigned long initialMillis = millis();
unsigned long initialTime = 0;
void getTime(unsigned long* currentHours, unsigned long* currentMinutes, unsigned long* currentSeconds){
//Check if need an NTP call to check current time
if((mTriggerUpdate == 0) || (millis() - mTriggerUpdate > UPDATE_PERIOD_h * 60 * 60 * 1000)){ //60 sec. * 60 min * 1000ms
if(WiFi.status() == WL_CONNECTED) {
timeClient.update(); //NTP call to get current time
mTriggerUpdate = millis();
initialTime = timeClient.getEpochTime(); // Guarda la hora inicial (en segundos desde 1970)
Serial.print("TimeClient NTPupdateTime ");
}
}
unsigned long elapsedTime = (millis() - mTriggerUpdate) / 1000; // Tiempo transcurrido en segundos
unsigned long currentTime = initialTime + elapsedTime; // La hora actual
// convierte la hora actual en horas, minutos y segundos
*currentHours = currentTime % 86400 / 3600;
*currentMinutes = currentTime % 3600 / 60;
*currentSeconds = currentTime % 60;
}
String getTime(void){
//Check if need an NTP call to check current time
if((mTriggerUpdate == 0) || (millis() - mTriggerUpdate > UPDATE_PERIOD_h * 60 * 60 * 1000)){ //60 sec. * 60 min * 1000ms
if(WiFi.status() == WL_CONNECTED) {
if(timeClient.update()) mTriggerUpdate = millis();
initialTime = timeClient.getEpochTime(); // Guarda la hora inicial (en segundos desde 1970)
Serial.print("TimeClient NTPupdateTime ");
}
}
unsigned long elapsedTime = (millis() - mTriggerUpdate) / 1000; // Tiempo transcurrido en segundos
unsigned long currentTime = initialTime + elapsedTime; // La hora actual
// convierte la hora actual en horas, minutos y segundos
unsigned long currentHours = currentTime % 86400 / 3600;
unsigned long currentMinutes = currentTime % 3600 / 60;
unsigned long currentSeconds = currentTime % 60;
char LocalHour[10];
sprintf(LocalHour, "%02d:%02d", currentHours, currentMinutes);
String mystring(LocalHour);
return LocalHour;
}
String getCurrentHashRate(unsigned long mElapsed)
{
return String((1.0 * (elapsedKHs * 1000)) / mElapsed, 2);
}
mining_data getMiningData(unsigned long mElapsed)
{
mining_data data;
char best_diff_string[16] = {0};
suffix_string(best_diff, best_diff_string, 16, 0);
char timeMining[15] = {0};
uint64_t secElapsed = upTime + (esp_timer_get_time() / 1000000);
int days = secElapsed / 86400;
int hours = (secElapsed - (days * 86400)) / 3600; // Number of seconds in an hour
int mins = (secElapsed - (days * 86400) - (hours * 3600)) / 60; // Remove the number of hours and calculate the minutes.
int secs = secElapsed - (days * 86400) - (hours * 3600) - (mins * 60);
sprintf(timeMining, "%01d %02d:%02d:%02d", days, hours, mins, secs);
data.completedShares = shares;
data.totalMHashes = Mhashes;
data.totalKHashes = totalKHashes;
data.currentHashRate = getCurrentHashRate(mElapsed);
data.templates = templates;
data.bestDiff = best_diff_string;
data.timeMining = timeMining;
data.valids = valids;
data.temp = String(temperatureRead(), 0);
data.currentTime = getTime();
return data;
}
clock_data getClockData(unsigned long mElapsed)
{
clock_data data;
data.completedShares = shares;
data.totalKHashes = totalKHashes;
data.currentHashRate = getCurrentHashRate(mElapsed);
data.btcPrice = getBTCprice();
data.blockHeight = getBlockHeight();
data.currentTime = getTime();
return data;
}
clock_data_t getClockData_t(unsigned long mElapsed)
{
clock_data_t data;
data.valids = valids;
data.currentHashRate = getCurrentHashRate(mElapsed);
getTime(&data.currentHours, &data.currentMinutes, &data.currentSeconds);
return data;
}
coin_data getCoinData(unsigned long mElapsed)
{
coin_data data;
updateGlobalData(); // Update gData vars asking mempool APIs
data.completedShares = shares;
data.totalKHashes = totalKHashes;
data.currentHashRate = getCurrentHashRate(mElapsed);
data.btcPrice = getBTCprice();
data.currentTime = getTime();
data.halfHourFee = String(gData.halfHourFee) + " sat/vB";
data.netwrokDifficulty = gData.difficulty;
data.globalHashRate = gData.globalHash;
data.blockHeight = getBlockHeight();
unsigned long currentBlock = data.blockHeight.toInt();
unsigned long remainingBlocks = (((currentBlock / HALVING_BLOCKS) + 1) * HALVING_BLOCKS) - currentBlock;
data.progressPercent = (HALVING_BLOCKS - remainingBlocks) * 100 / HALVING_BLOCKS;
data.remainingBlocks = String(remainingBlocks) + " BLOCKS";
return data;
}