2024-09-05 12:00:15 +00:00
|
|
|
#include "v2_notify.hpp"
|
|
|
|
|
2024-09-18 00:00:10 +00:00
|
|
|
using namespace V2Notify;
|
2024-09-05 12:00:15 +00:00
|
|
|
|
2024-09-18 00:00:10 +00:00
|
|
|
namespace V2Notify
|
2024-09-05 12:00:15 +00:00
|
|
|
{
|
2024-09-18 00:00:10 +00:00
|
|
|
WebSocketsClient webSocket;
|
|
|
|
|
|
|
|
TaskHandle_t v2NotifyTaskHandle;
|
|
|
|
|
|
|
|
void setupV2Notify()
|
|
|
|
{
|
|
|
|
String hostname = "ws.btclock.dev";
|
|
|
|
if (preferences.getBool("stagingSource", DEFAULT_STAGING_SOURCE))
|
|
|
|
{
|
|
|
|
Serial.println(F("Connecting to V2 staging source"));
|
|
|
|
hostname = "ws-staging.btclock.dev";
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Serial.println(F("Connecting to V2 source"));
|
|
|
|
}
|
|
|
|
|
|
|
|
webSocket.beginSSL(hostname, 443, "/api/v2/ws");
|
|
|
|
webSocket.onEvent(V2Notify::onWebsocketV2Event);
|
|
|
|
webSocket.setReconnectInterval(5000);
|
|
|
|
webSocket.enableHeartbeat(15000, 3000, 2);
|
|
|
|
|
|
|
|
V2Notify::setupV2NotifyTask();
|
2024-09-11 01:23:41 +00:00
|
|
|
}
|
2024-09-05 12:00:15 +00:00
|
|
|
|
2024-09-18 00:00:10 +00:00
|
|
|
void onWebsocketV2Event(WStype_t type, uint8_t *payload, size_t length)
|
|
|
|
{
|
|
|
|
switch (type)
|
2024-09-05 12:00:15 +00:00
|
|
|
{
|
2024-09-18 00:00:10 +00:00
|
|
|
case WStype_DISCONNECTED:
|
|
|
|
Serial.printf("[WSc] Disconnected!\n");
|
|
|
|
break;
|
|
|
|
case WStype_CONNECTED:
|
|
|
|
{
|
|
|
|
Serial.printf("[WSc] Connected to url: %s\n", payload);
|
2024-09-05 12:00:15 +00:00
|
|
|
|
|
|
|
JsonDocument response;
|
|
|
|
|
|
|
|
response["type"] = "subscribe";
|
|
|
|
response["eventType"] = "blockfee";
|
|
|
|
size_t responseLength = measureMsgPack(response);
|
2024-09-18 00:00:10 +00:00
|
|
|
uint8_t *buffer = new uint8_t[responseLength];
|
2024-09-05 12:00:15 +00:00
|
|
|
serializeMsgPack(response, buffer, responseLength);
|
|
|
|
webSocket.sendBIN(buffer, responseLength);
|
|
|
|
delete[] buffer;
|
|
|
|
|
|
|
|
buffer = new uint8_t[responseLength];
|
|
|
|
|
|
|
|
response["type"] = "subscribe";
|
|
|
|
response["eventType"] = "blockheight";
|
|
|
|
responseLength = measureMsgPack(response);
|
|
|
|
buffer = new uint8_t[responseLength];
|
|
|
|
serializeMsgPack(response, buffer, responseLength);
|
|
|
|
webSocket.sendBIN(buffer, responseLength);
|
|
|
|
|
|
|
|
delete[] buffer;
|
|
|
|
|
|
|
|
buffer = new uint8_t[responseLength];
|
|
|
|
|
|
|
|
response["type"] = "subscribe";
|
|
|
|
response["eventType"] = "price";
|
|
|
|
|
|
|
|
JsonArray currenciesArray = response["currencies"].to<JsonArray>();
|
|
|
|
|
|
|
|
for (const auto &str : getActiveCurrencies())
|
|
|
|
{
|
|
|
|
currenciesArray.add(str);
|
|
|
|
}
|
2024-09-18 00:00:10 +00:00
|
|
|
|
|
|
|
// response["currencies"] = currenciesArray;
|
2024-09-05 12:00:15 +00:00
|
|
|
responseLength = measureMsgPack(response);
|
|
|
|
buffer = new uint8_t[responseLength];
|
|
|
|
serializeMsgPack(response, buffer, responseLength);
|
|
|
|
webSocket.sendBIN(buffer, responseLength);
|
2024-09-18 00:00:10 +00:00
|
|
|
break;
|
2024-09-05 12:00:15 +00:00
|
|
|
}
|
2024-09-18 00:00:10 +00:00
|
|
|
case WStype_TEXT:
|
|
|
|
Serial.printf("[WSc] get text: %s\n", payload);
|
2024-09-05 12:00:15 +00:00
|
|
|
|
2024-09-18 00:00:10 +00:00
|
|
|
// send message to server
|
|
|
|
// webSocket.sendTXT("message here");
|
|
|
|
break;
|
|
|
|
case WStype_BIN:
|
2024-09-05 12:00:15 +00:00
|
|
|
{
|
|
|
|
JsonDocument doc;
|
|
|
|
DeserializationError error = deserializeMsgPack(doc, payload, length);
|
|
|
|
|
2024-09-18 00:00:10 +00:00
|
|
|
V2Notify::handleV2Message(doc);
|
|
|
|
break;
|
2024-09-05 12:00:15 +00:00
|
|
|
}
|
2024-09-18 00:00:10 +00:00
|
|
|
case WStype_ERROR:
|
|
|
|
case WStype_FRAGMENT_TEXT_START:
|
|
|
|
case WStype_FRAGMENT_BIN_START:
|
|
|
|
case WStype_FRAGMENT:
|
2024-09-05 12:00:15 +00:00
|
|
|
case WStype_PING:
|
|
|
|
case WStype_PONG:
|
2024-09-18 00:00:10 +00:00
|
|
|
case WStype_FRAGMENT_FIN:
|
|
|
|
break;
|
|
|
|
}
|
2024-09-05 12:00:15 +00:00
|
|
|
}
|
|
|
|
|
2024-09-18 00:00:10 +00:00
|
|
|
void handleV2Message(JsonDocument doc)
|
|
|
|
{
|
|
|
|
if (doc.containsKey("blockheight"))
|
|
|
|
{
|
|
|
|
uint newBlockHeight = doc["blockheight"].as<uint>();
|
2024-09-05 12:00:15 +00:00
|
|
|
|
2024-09-18 00:00:10 +00:00
|
|
|
if (newBlockHeight == getBlockHeight())
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2024-09-05 12:00:15 +00:00
|
|
|
|
2024-09-18 00:00:10 +00:00
|
|
|
processNewBlock(newBlockHeight);
|
|
|
|
}
|
|
|
|
else if (doc.containsKey("blockfee"))
|
|
|
|
{
|
|
|
|
uint medianFee = doc["blockfee"].as<uint>();
|
2024-09-05 12:00:15 +00:00
|
|
|
|
2024-09-18 00:00:10 +00:00
|
|
|
processNewBlockFee(medianFee);
|
|
|
|
}
|
|
|
|
else if (doc.containsKey("price"))
|
|
|
|
{
|
2024-09-05 12:00:15 +00:00
|
|
|
|
2024-09-18 00:00:10 +00:00
|
|
|
// Iterate through the key-value pairs of the "price" object
|
|
|
|
for (JsonPair kv : doc["price"].as<JsonObject>())
|
|
|
|
{
|
|
|
|
const char *currency = kv.key().c_str();
|
|
|
|
uint newPrice = kv.value().as<uint>();
|
|
|
|
|
|
|
|
processNewPrice(newPrice, getCurrencyChar(currency));
|
|
|
|
}
|
|
|
|
}
|
2024-09-05 12:00:15 +00:00
|
|
|
}
|
|
|
|
|
2024-09-18 00:00:10 +00:00
|
|
|
void taskV2Notify(void *pvParameters)
|
|
|
|
{
|
|
|
|
for (;;)
|
|
|
|
{
|
|
|
|
webSocket.loop();
|
|
|
|
vTaskDelay(10 / portTICK_PERIOD_MS);
|
|
|
|
}
|
|
|
|
}
|
2024-09-05 12:00:15 +00:00
|
|
|
|
2024-09-18 00:00:10 +00:00
|
|
|
void setupV2NotifyTask()
|
|
|
|
{
|
|
|
|
xTaskCreate(V2Notify::taskV2Notify, "v2Notify", (6 * 1024), NULL, tskIDLE_PRIORITY,
|
|
|
|
&V2Notify::v2NotifyTaskHandle);
|
|
|
|
}
|
2024-09-05 12:00:15 +00:00
|
|
|
|
2024-09-18 00:00:10 +00:00
|
|
|
bool isV2NotifyConnected()
|
|
|
|
{
|
|
|
|
return webSocket.isConnected();
|
|
|
|
}
|
|
|
|
}
|