Websocket sources working
This commit is contained in:
parent
c2226f73e0
commit
562348b5ea
28 changed files with 32411 additions and 6 deletions
89
src/lib/block_notify.cpp
Normal file
89
src/lib/block_notify.cpp
Normal file
|
@ -0,0 +1,89 @@
|
|||
#include "block_notify.hpp"
|
||||
|
||||
const char *wsServer = "wss://mempool.space/api/v1/ws";
|
||||
// WebsocketsClient client;
|
||||
esp_websocket_client_handle_t client;
|
||||
unsigned long int currentBlockHeight;
|
||||
|
||||
void setupBlockNotify()
|
||||
{
|
||||
// Get current block height through regular API
|
||||
HTTPClient *http = new HTTPClient();
|
||||
http->begin("https://mempool.space/api/blocks/tip/height");
|
||||
int httpCode = http->GET();
|
||||
|
||||
if (httpCode > 0 && httpCode == HTTP_CODE_OK)
|
||||
{
|
||||
String blockHeightStr = http->getString();
|
||||
currentBlockHeight = blockHeightStr.toInt();
|
||||
}
|
||||
|
||||
esp_websocket_client_config_t config = {
|
||||
.uri = "wss://mempool.space/api/v1/ws",
|
||||
};
|
||||
|
||||
client = esp_websocket_client_init(&config);
|
||||
esp_websocket_register_events(client, WEBSOCKET_EVENT_ANY, onWebsocketEvent, client);
|
||||
esp_websocket_client_start(client);
|
||||
}
|
||||
|
||||
void onWebsocketEvent(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data)
|
||||
{
|
||||
esp_websocket_event_data_t *data = (esp_websocket_event_data_t *)event_data;
|
||||
String init;
|
||||
String sub;
|
||||
switch (event_id)
|
||||
{
|
||||
case WEBSOCKET_EVENT_CONNECTED:
|
||||
Serial.println("Connected to Mempool.space WebSocket");
|
||||
// init = "{\"action\": \"init\"}";
|
||||
// if(esp_websocket_client_send_text(client, init.c_str(), init.length(), portMAX_DELAY) == -1) {
|
||||
// Serial.println("Error init");
|
||||
// }
|
||||
sub = "{\"action\": \"want\", \"data\":[\"blocks\"]}";
|
||||
if (esp_websocket_client_send_text(client, sub.c_str(), sub.length(), portMAX_DELAY) == -1)
|
||||
{
|
||||
Serial.println("Error want");
|
||||
}
|
||||
|
||||
break;
|
||||
case WEBSOCKET_EVENT_DATA:
|
||||
onWebsocketMessage(data);
|
||||
// Handle the received WebSocket message (block notifications) here
|
||||
break;
|
||||
case WEBSOCKET_EVENT_ERROR:
|
||||
Serial.println("Connnection error");
|
||||
break;
|
||||
case WEBSOCKET_EVENT_DISCONNECTED:
|
||||
Serial.println("Connnection Closed");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void onWebsocketMessage(esp_websocket_event_data_t *event_data)
|
||||
{
|
||||
DynamicJsonDocument doc(event_data->data_len);
|
||||
|
||||
deserializeJson(doc, (char *)event_data->data_ptr);
|
||||
// serializeJsonPretty(doc, Serial);
|
||||
|
||||
if (doc.containsKey("block"))
|
||||
{
|
||||
JsonObject block = doc["block"];
|
||||
|
||||
currentBlockHeight = block["height"].as<long>();
|
||||
Serial.print("New block found: ");
|
||||
Serial.println(block["height"].as<long>());
|
||||
|
||||
if (blockUpdateTaskHandle != nullptr)
|
||||
xTaskNotifyGive(blockUpdateTaskHandle);
|
||||
}
|
||||
|
||||
doc.clear();
|
||||
}
|
||||
|
||||
|
||||
unsigned long getBlockHeight()
|
||||
{
|
||||
return currentBlockHeight;
|
||||
}
|
18
src/lib/block_notify.hpp
Normal file
18
src/lib/block_notify.hpp
Normal file
|
@ -0,0 +1,18 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <Arduino.h>
|
||||
#include <HTTPClient.h>
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
#include "esp_websocket_client.h"
|
||||
#include "screen_handler.hpp"
|
||||
|
||||
//using namespace websockets;
|
||||
|
||||
void setupBlockNotify();
|
||||
|
||||
void onWebsocketEvent(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data);
|
||||
void onWebsocketMessage(esp_websocket_event_data_t* event_data);
|
||||
|
||||
unsigned long getBlockHeight();
|
23
src/lib/config.hpp
Normal file
23
src/lib/config.hpp
Normal file
|
@ -0,0 +1,23 @@
|
|||
#pragma once;
|
||||
#include <WiFiClientSecure.h>
|
||||
#include <Preferences.h>
|
||||
#include <Adafruit_MCP23X17.h>
|
||||
|
||||
#include "shared.hpp"
|
||||
#include <esp_system.h>
|
||||
#include <esp_netif.h>
|
||||
#include <esp_sntp.h>
|
||||
#include "epd.hpp"
|
||||
|
||||
#include "lib/screen_handler.hpp"
|
||||
#include "lib/webserver.hpp"
|
||||
#include "lib/block_notify.hpp"
|
||||
#include "lib/price_notify.hpp"
|
||||
|
||||
|
||||
void setup();
|
||||
void setupTime();
|
||||
void setupPreferences();
|
||||
void setupWifi();
|
||||
void setupWebsocketClients();
|
||||
void setupHardware();
|
267
src/lib/epd.cpp
Normal file
267
src/lib/epd.cpp
Normal file
|
@ -0,0 +1,267 @@
|
|||
#include "epd.hpp"
|
||||
|
||||
Native_Pin EPD_CS[NUM_SCREENS] = {
|
||||
Native_Pin(2),
|
||||
Native_Pin(4),
|
||||
Native_Pin(6),
|
||||
Native_Pin(10),
|
||||
Native_Pin(33),
|
||||
Native_Pin(21),
|
||||
Native_Pin(17),
|
||||
#if NUM_SCREENS == 9
|
||||
// MCP23X17_Pin(mcp2, 7),
|
||||
Native_Pin(-1),
|
||||
Native_Pin(-1),
|
||||
#endif
|
||||
};
|
||||
Native_Pin EPD_BUSY[NUM_SCREENS] = {
|
||||
Native_Pin(3),
|
||||
Native_Pin(5),
|
||||
Native_Pin(7),
|
||||
Native_Pin(9),
|
||||
Native_Pin(37),
|
||||
Native_Pin(18),
|
||||
Native_Pin(16),
|
||||
};
|
||||
MCP23X17_Pin EPD_RESET_MPD[NUM_SCREENS] = {
|
||||
MCP23X17_Pin(mcp, 8),
|
||||
MCP23X17_Pin(mcp, 9),
|
||||
MCP23X17_Pin(mcp, 10),
|
||||
MCP23X17_Pin(mcp, 11),
|
||||
MCP23X17_Pin(mcp, 12),
|
||||
MCP23X17_Pin(mcp, 13),
|
||||
MCP23X17_Pin(mcp, 14),
|
||||
};
|
||||
|
||||
Native_Pin EPD_DC = Native_Pin(14);
|
||||
|
||||
GxEPD2_BW<GxEPD2_213_B74, GxEPD2_213_B74::HEIGHT> displays[NUM_SCREENS] = {
|
||||
GxEPD2_213_B74(&EPD_CS[0], &EPD_DC, &EPD_RESET_MPD[0], &EPD_BUSY[0]),
|
||||
GxEPD2_213_B74(&EPD_CS[1], &EPD_DC, &EPD_RESET_MPD[1], &EPD_BUSY[1]),
|
||||
GxEPD2_213_B74(&EPD_CS[2], &EPD_DC, &EPD_RESET_MPD[2], &EPD_BUSY[2]),
|
||||
GxEPD2_213_B74(&EPD_CS[3], &EPD_DC, &EPD_RESET_MPD[3], &EPD_BUSY[3]),
|
||||
GxEPD2_213_B74(&EPD_CS[4], &EPD_DC, &EPD_RESET_MPD[4], &EPD_BUSY[4]),
|
||||
GxEPD2_213_B74(&EPD_CS[5], &EPD_DC, &EPD_RESET_MPD[5], &EPD_BUSY[5]),
|
||||
GxEPD2_213_B74(&EPD_CS[6], &EPD_DC, &EPD_RESET_MPD[6], &EPD_BUSY[6]),
|
||||
#if NUM_SCREENS == 9
|
||||
GxEPD2_213_B74(&EPD8_CS, &EPD_DC, &EPD_RESET_MPD[7], &EPD8_BUSY),
|
||||
GxEPD2_213_B74(&EPD9_CS, &EPD_DC, &EPD_RESET_MPD[8], &EPD9_BUSY),
|
||||
#endif
|
||||
};
|
||||
|
||||
std::array<String, NUM_SCREENS> currentEpdContent;
|
||||
std::array<String, NUM_SCREENS> epdContent;
|
||||
uint32_t lastFullRefresh[NUM_SCREENS];
|
||||
TaskHandle_t tasks[NUM_SCREENS];
|
||||
SemaphoreHandle_t epdUpdateSemaphore[NUM_SCREENS];
|
||||
|
||||
int fgColor = GxEPD_WHITE;
|
||||
int bgColor = GxEPD_BLACK;
|
||||
|
||||
#define FONT_SMALL Antonio_SemiBold20pt7b
|
||||
#define FONT_BIG Antonio_SemiBold90pt7b
|
||||
|
||||
void setupDisplays()
|
||||
{
|
||||
for (uint i = 0; i < NUM_SCREENS; i++)
|
||||
{
|
||||
displays[i].init();
|
||||
}
|
||||
|
||||
for (uint i = 0; i < NUM_SCREENS; i++)
|
||||
{
|
||||
epdUpdateSemaphore[i] = xSemaphoreCreateBinary();
|
||||
xSemaphoreGive(epdUpdateSemaphore[i]);
|
||||
|
||||
int *taskParam = new int;
|
||||
*taskParam = i;
|
||||
|
||||
xTaskCreate(updateDisplay, "EpdUpd" + char(i), 4096, taskParam, 1, &tasks[i]); // create task
|
||||
}
|
||||
|
||||
epdContent = {"B",
|
||||
"T",
|
||||
"C",
|
||||
"L",
|
||||
"O",
|
||||
"C",
|
||||
"K"};
|
||||
for (uint i = 0; i < NUM_SCREENS; i++)
|
||||
{
|
||||
xTaskNotifyGive(tasks[i]);
|
||||
}
|
||||
|
||||
xTaskCreate(taskEpd, "epd_task", 2048, NULL, 1, NULL);
|
||||
}
|
||||
|
||||
void taskEpd(void *pvParameters)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
bool updatedThisCycle = false;
|
||||
|
||||
for (uint i = 0; i < NUM_SCREENS; i++)
|
||||
{
|
||||
if (epdContent[i].compareTo(currentEpdContent[i]) != 0)
|
||||
{
|
||||
if (!updatedThisCycle)
|
||||
{
|
||||
updatedThisCycle = true;
|
||||
}
|
||||
|
||||
if (xSemaphoreTake(epdUpdateSemaphore[i], pdMS_TO_TICKS(5000)) == pdTRUE)
|
||||
{
|
||||
xTaskNotifyGive(tasks[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println("Couldnt get screen" + String(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef WITH_RGB_LED
|
||||
if (updatedThisCycle && preferences.getBool("ledFlashOnUpd", false))
|
||||
{
|
||||
xTaskNotifyGive(ledHandlerTaskHandle);
|
||||
}
|
||||
#endif
|
||||
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
}
|
||||
}
|
||||
|
||||
void setEpdContent(std::array<String, NUM_SCREENS> newEpdContent)
|
||||
{
|
||||
epdContent = newEpdContent;
|
||||
}
|
||||
|
||||
extern "C" void updateDisplay(void *pvParameters) noexcept
|
||||
{
|
||||
const int epdIndex = *(int *)pvParameters;
|
||||
delete (int *)pvParameters;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
// Wait for the task notification
|
||||
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
|
||||
|
||||
if (epdContent[epdIndex].compareTo(currentEpdContent[epdIndex]) != 0)
|
||||
{
|
||||
displays[epdIndex].init(0, false); // Little longer reset duration because of MCP
|
||||
|
||||
bool updatePartial = true;
|
||||
|
||||
// Full Refresh every half hour
|
||||
if (!lastFullRefresh[epdIndex] || (millis() - lastFullRefresh[epdIndex]) > (preferences.getUInt("fullRefreshMin", 30) * 60 * 1000))
|
||||
{
|
||||
updatePartial = false;
|
||||
lastFullRefresh[epdIndex] = millis();
|
||||
}
|
||||
if (strstr(epdContent[epdIndex].c_str(), "/") != NULL)
|
||||
{
|
||||
String top = epdContent[epdIndex].substring(0, epdContent[epdIndex].indexOf("/"));
|
||||
String bottom = epdContent[epdIndex].substring(epdContent[epdIndex].indexOf("/") + 1);
|
||||
splitText(epdIndex, top, bottom, updatePartial);
|
||||
}
|
||||
else
|
||||
{
|
||||
showDigit(epdIndex, epdContent[epdIndex].c_str()[0], updatePartial, &FONT_BIG);
|
||||
}
|
||||
|
||||
#ifdef USE_UNIVERSAL_PIN
|
||||
char tries = 0;
|
||||
while (tries < 3)
|
||||
{
|
||||
if (displays[epdIndex].displayWithReturn(updatePartial))
|
||||
{
|
||||
displays[epdIndex].hibernate();
|
||||
currentEpdContent[epdIndex] = epdContent[epdIndex];
|
||||
break;
|
||||
}
|
||||
|
||||
delay(100);
|
||||
tries++;
|
||||
}
|
||||
#else
|
||||
displays[epdIndex].display(updatePartial);
|
||||
displays[epdIndex].hibernate();
|
||||
currentEpdContent[epdIndex] = epdContent[epdIndex];
|
||||
#endif
|
||||
}
|
||||
xSemaphoreGive(epdUpdateSemaphore[epdIndex]);
|
||||
}
|
||||
}
|
||||
|
||||
void splitText(const uint dispNum, String top, String bottom, bool partial)
|
||||
{
|
||||
displays[dispNum].setRotation(2);
|
||||
displays[dispNum].setFont(&FONT_SMALL);
|
||||
displays[dispNum].setTextColor(getFgColor());
|
||||
|
||||
// Top text
|
||||
int16_t ttbx, ttby;
|
||||
uint16_t ttbw, ttbh;
|
||||
displays[dispNum].getTextBounds(top, 0, 0, &ttbx, &ttby, &ttbw, &ttbh);
|
||||
uint16_t tx = ((displays[dispNum].width() - ttbw) / 2) - ttbx;
|
||||
uint16_t ty = ((displays[dispNum].height() - ttbh) / 2) - ttby - ttbh / 2 - 12;
|
||||
|
||||
// Bottom text
|
||||
int16_t tbbx, tbby;
|
||||
uint16_t tbbw, tbbh;
|
||||
displays[dispNum].getTextBounds(bottom, 0, 0, &tbbx, &tbby, &tbbw, &tbbh);
|
||||
uint16_t bx = ((displays[dispNum].width() - tbbw) / 2) - tbbx;
|
||||
uint16_t by = ((displays[dispNum].height() - tbbh) / 2) - tbby + tbbh / 2 + 12;
|
||||
|
||||
// Make separator as wide as the shortest text.
|
||||
uint16_t lineWidth, lineX;
|
||||
if (tbbw < ttbh)
|
||||
lineWidth = tbbw;
|
||||
else
|
||||
lineWidth = ttbw;
|
||||
lineX = round((displays[dispNum].width() - lineWidth) / 2);
|
||||
|
||||
displays[dispNum].fillScreen(getBgColor());
|
||||
displays[dispNum].setCursor(tx, ty);
|
||||
displays[dispNum].print(top);
|
||||
displays[dispNum].fillRoundRect(lineX, displays[dispNum].height() / 2 - 3, lineWidth, 6, 3, getFgColor());
|
||||
displays[dispNum].setCursor(bx, by);
|
||||
displays[dispNum].print(bottom);
|
||||
}
|
||||
|
||||
void showDigit(const uint dispNum, char chr, bool partial, const GFXfont *font)
|
||||
{
|
||||
String str(chr);
|
||||
displays[dispNum].setRotation(2);
|
||||
displays[dispNum].setFont(font);
|
||||
displays[dispNum].setTextColor(getFgColor());
|
||||
int16_t tbx, tby;
|
||||
uint16_t tbw, tbh;
|
||||
displays[dispNum].getTextBounds(str, 0, 0, &tbx, &tby, &tbw, &tbh);
|
||||
// center the bounding box by transposition of the origin:
|
||||
uint16_t x = ((displays[dispNum].width() - tbw) / 2) - tbx;
|
||||
uint16_t y = ((displays[dispNum].height() - tbh) / 2) - tby;
|
||||
displays[dispNum].fillScreen(getBgColor());
|
||||
displays[dispNum].setCursor(x, y);
|
||||
displays[dispNum].print(str);
|
||||
}
|
||||
|
||||
int getBgColor()
|
||||
{
|
||||
return bgColor;
|
||||
}
|
||||
|
||||
int getFgColor()
|
||||
{
|
||||
return fgColor;
|
||||
}
|
||||
|
||||
void setBgColor(int color)
|
||||
{
|
||||
bgColor = color;
|
||||
}
|
||||
|
||||
void setFgColor(int color)
|
||||
{
|
||||
fgColor = color;
|
||||
}
|
22
src/lib/epd.hpp
Normal file
22
src/lib/epd.hpp
Normal file
|
@ -0,0 +1,22 @@
|
|||
#pragma once
|
||||
|
||||
#include <GxEPD2_BW.h>
|
||||
#include <native_pin.hpp>
|
||||
#include <mcp23x17_pin.hpp>
|
||||
#include "shared.hpp"
|
||||
#include "config.hpp"
|
||||
#include "fonts/fonts.hpp"
|
||||
|
||||
void setupDisplays();
|
||||
void taskEpd(void *pvParameters);
|
||||
|
||||
void splitText(const uint dispNum, String top, String bottom, bool partial);
|
||||
void showDigit(const uint dispNum, char chr, bool partial, const GFXfont *font);
|
||||
extern "C" void updateDisplay(void *pvParameters) noexcept;
|
||||
|
||||
int getBgColor();
|
||||
int getFgColor();
|
||||
void setBgColor(int color);
|
||||
void setFgColor(int color);
|
||||
|
||||
void setEpdContent(std::array<String, NUM_SCREENS> newEpdContent);
|
64
src/lib/price_notify.cpp
Normal file
64
src/lib/price_notify.cpp
Normal file
|
@ -0,0 +1,64 @@
|
|||
#include "price_notify.hpp"
|
||||
|
||||
const char *wsServerPrice = "wss://ws.coincap.io/prices?assets=bitcoin";
|
||||
// WebsocketsClient client;
|
||||
esp_websocket_client_handle_t clientPrice;
|
||||
unsigned long int currentPrice;
|
||||
|
||||
void setupPriceNotify()
|
||||
{
|
||||
esp_websocket_client_config_t config = {
|
||||
.uri = wsServerPrice,
|
||||
};
|
||||
|
||||
clientPrice = esp_websocket_client_init(&config);
|
||||
esp_websocket_register_events(clientPrice, WEBSOCKET_EVENT_ANY, onWebsocketPriceEvent, clientPrice);
|
||||
esp_websocket_client_start(clientPrice);
|
||||
}
|
||||
|
||||
void onWebsocketPriceEvent(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data)
|
||||
{
|
||||
esp_websocket_event_data_t *data = (esp_websocket_event_data_t *)event_data;
|
||||
String init;
|
||||
String sub;
|
||||
switch (event_id)
|
||||
{
|
||||
case WEBSOCKET_EVENT_CONNECTED:
|
||||
Serial.println("Connected to CoinCap.io WebSocket");
|
||||
break;
|
||||
case WEBSOCKET_EVENT_DATA:
|
||||
onWebsocketPriceMessage(data);
|
||||
break;
|
||||
case WEBSOCKET_EVENT_ERROR:
|
||||
Serial.println("Connnection error");
|
||||
break;
|
||||
case WEBSOCKET_EVENT_DISCONNECTED:
|
||||
Serial.println("Connnection Closed");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void onWebsocketPriceMessage(esp_websocket_event_data_t* event_data)
|
||||
{
|
||||
DynamicJsonDocument doc(event_data->data_len);
|
||||
|
||||
deserializeJson(doc, (char *)event_data->data_ptr);
|
||||
|
||||
if (doc.containsKey("bitcoin")) {
|
||||
if (currentPrice != doc["bitcoin"].as<long>()) {
|
||||
Serial.printf("New price %lu\r\n", currentPrice);
|
||||
|
||||
const unsigned long oldPrice = currentPrice;
|
||||
currentPrice = doc["bitcoin"].as<long>();
|
||||
|
||||
// if (abs((int)(oldPrice-currentPrice)) > round(0.0015*oldPrice)) {
|
||||
if (priceUpdateTaskHandle != nullptr)
|
||||
xTaskNotifyGive(priceUpdateTaskHandle);
|
||||
//}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsigned long getPrice() {
|
||||
return currentPrice;
|
||||
}
|
17
src/lib/price_notify.hpp
Normal file
17
src/lib/price_notify.hpp
Normal file
|
@ -0,0 +1,17 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <Arduino.h>
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
#include "esp_websocket_client.h"
|
||||
#include "screen_handler.hpp"
|
||||
|
||||
//using namespace websockets;
|
||||
|
||||
void setupPriceNotify();
|
||||
|
||||
void onWebsocketPriceEvent(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data);
|
||||
void onWebsocketPriceMessage(esp_websocket_event_data_t* event_data);
|
||||
|
||||
unsigned long getPrice();
|
72
src/lib/screen_handler.cpp
Normal file
72
src/lib/screen_handler.cpp
Normal file
|
@ -0,0 +1,72 @@
|
|||
#include "screen_handler.hpp"
|
||||
|
||||
TaskHandle_t priceUpdateTaskHandle;
|
||||
TaskHandle_t blockUpdateTaskHandle;
|
||||
|
||||
std::array<String, NUM_SCREENS> taskEpdContent = {"", "", "", "", "", "", ""};
|
||||
std::string priceString;
|
||||
|
||||
void taskPriceUpdate(void *pvParameters)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
|
||||
|
||||
unsigned long price = getPrice();
|
||||
uint firstIndex = 0;
|
||||
if (false) {
|
||||
priceString = ("$" + String(price)).c_str();
|
||||
|
||||
if (priceString.length() < (NUM_SCREENS)) {
|
||||
priceString.insert(priceString.begin(), NUM_SCREENS - priceString.length(), ' ');
|
||||
taskEpdContent[0] = "BTC/USD";
|
||||
firstIndex = 1;
|
||||
}
|
||||
} else {
|
||||
priceString = String(int(round(1 / float(price) * 10e7))).c_str();
|
||||
|
||||
if (priceString.length() < (NUM_SCREENS)) {
|
||||
priceString.insert(priceString.begin(), NUM_SCREENS - priceString.length(), ' ');
|
||||
taskEpdContent[0] = "MSCW/TIME";
|
||||
firstIndex = 1;
|
||||
}
|
||||
}
|
||||
|
||||
for (uint i = firstIndex; i < NUM_SCREENS; i++)
|
||||
{
|
||||
taskEpdContent[i] = priceString[i];
|
||||
}
|
||||
|
||||
setEpdContent(taskEpdContent);
|
||||
}
|
||||
}
|
||||
|
||||
void taskBlockUpdate(void *pvParameters)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
|
||||
|
||||
std::string blockNrString = String(getBlockHeight()).c_str();
|
||||
uint firstIndex = 0;
|
||||
if (blockNrString.length() < NUM_SCREENS) {
|
||||
blockNrString.insert(blockNrString.begin(), NUM_SCREENS - blockNrString.length(), ' ');
|
||||
taskEpdContent[0] = "BLOCK/HEIGHT";
|
||||
firstIndex = 1;
|
||||
}
|
||||
|
||||
for (uint i = firstIndex; i < NUM_SCREENS; i++)
|
||||
{
|
||||
taskEpdContent[i] = blockNrString[i];
|
||||
}
|
||||
|
||||
setEpdContent(taskEpdContent);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void setupTasks()
|
||||
{
|
||||
xTaskCreate(taskPriceUpdate, "updatePrice", 1024, NULL, 1, &priceUpdateTaskHandle);
|
||||
xTaskCreate(taskBlockUpdate, "updateBlock", 1024, NULL, 1, &blockUpdateTaskHandle);
|
||||
}
|
16
src/lib/screen_handler.hpp
Normal file
16
src/lib/screen_handler.hpp
Normal file
|
@ -0,0 +1,16 @@
|
|||
#pragma once
|
||||
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <freertos/task.h>
|
||||
|
||||
#include "lib/block_notify.hpp"
|
||||
#include "lib/price_notify.hpp"
|
||||
#include "lib/epd.hpp"
|
||||
|
||||
extern TaskHandle_t priceUpdateTaskHandle;
|
||||
extern TaskHandle_t blockUpdateTaskHandle;
|
||||
|
||||
void taskPriceUpdate(void *pvParameters);
|
||||
void taskBlockUpdate(void *pvParameters);
|
||||
|
||||
void setupTasks();
|
7
src/lib/shared.hpp
Normal file
7
src/lib/shared.hpp
Normal file
|
@ -0,0 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <Adafruit_MCP23X17.h>
|
||||
#include <Preferences.h>
|
||||
|
||||
extern Adafruit_MCP23X17 mcp;
|
||||
extern Preferences preferences;
|
43
src/lib/webserver.cpp
Normal file
43
src/lib/webserver.cpp
Normal file
|
@ -0,0 +1,43 @@
|
|||
#include "webserver.hpp"
|
||||
|
||||
AsyncWebServer server(80);
|
||||
|
||||
void setupWebserver()
|
||||
{
|
||||
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||
request->send(200, "text/plain", "Hello, world");
|
||||
});
|
||||
|
||||
server.on("/status", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||
AsyncResponseStream *response = request->beginResponseStream("application/json");
|
||||
StaticJsonDocument<128> root;
|
||||
|
||||
root["currentPrice"] = getPrice();
|
||||
root["currentBlockHeight"] = getBlockHeight();
|
||||
root["espFreeHeap"] = ESP.getFreeHeap();
|
||||
root["espHeapSize"] = ESP.getHeapSize();
|
||||
root["espFreePsram"] = ESP.getFreePsram();
|
||||
root["espPsramSize"] = ESP.getPsramSize();
|
||||
|
||||
serializeJson(root, *response);
|
||||
|
||||
|
||||
request->send(response);
|
||||
});
|
||||
|
||||
server.onNotFound(onNotFound);
|
||||
|
||||
server.begin();
|
||||
}
|
||||
|
||||
void onNotFound(AsyncWebServerRequest *request)
|
||||
{
|
||||
if (request->method() == HTTP_OPTIONS)
|
||||
{
|
||||
request->send(200);
|
||||
}
|
||||
else
|
||||
{
|
||||
request->send(404);
|
||||
}
|
||||
};
|
10
src/lib/webserver.hpp
Normal file
10
src/lib/webserver.hpp
Normal file
|
@ -0,0 +1,10 @@
|
|||
#pragma once
|
||||
|
||||
#include "ESPAsyncWebServer.h"
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
#include "lib/block_notify.hpp"
|
||||
#include "lib/price_notify.hpp"
|
||||
|
||||
void setupWebserver();
|
||||
void onNotFound(AsyncWebServerRequest *request);
|
Loading…
Add table
Add a link
Reference in a new issue