WebUI: Add German translation, switch to own price source
This commit is contained in:
parent
a2fa0a12a8
commit
efaab00fb4
6 changed files with 117 additions and 48 deletions
2
data
2
data
|
@ -1 +1 @@
|
|||
Subproject commit dcdf98964a42ccd83b2d2501bbed46a640bbc300
|
||||
Subproject commit e47fc066b0608132c44a35f7041be80b263adcff
|
|
@ -41,7 +41,8 @@ void setup()
|
|||
if (mcp1.digitalRead(0) == LOW)
|
||||
{
|
||||
// Then loop forever to prevent anything else from writing to the screen
|
||||
while (true) {
|
||||
while (true)
|
||||
{
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
|
@ -84,7 +85,7 @@ void tryImprovSetup()
|
|||
}
|
||||
}
|
||||
|
||||
// if (!preferences.getBool("wifiConfigured", false))
|
||||
// if (!preferences.getBool("wifiConfigured", false))
|
||||
{
|
||||
|
||||
queueLedEffect(LED_EFFECT_WIFI_WAIT_FOR_CONFIG);
|
||||
|
@ -130,13 +131,23 @@ void tryImprovSetup()
|
|||
const String explainText = "*SSID: *\r\n" +
|
||||
wifiManager->getConfigPortalSSID() +
|
||||
"\r\n\r\n*Password:*\r\n" + softAP_password;
|
||||
// Set the UNIX timestamp
|
||||
time_t timestamp = LAST_BUILD_TIME; // Example timestamp: March 7, 2021 00:00:00 UTC
|
||||
|
||||
// Convert the timestamp to a struct tm in UTC
|
||||
struct tm *timeinfo = gmtime(×tamp);
|
||||
|
||||
// Format the date
|
||||
char formattedDate[20];
|
||||
strftime(formattedDate, sizeof(formattedDate), "%y-%m-%d\r\n%H:%M:%S", timeinfo);
|
||||
|
||||
std::array<String, NUM_SCREENS> epdContent = {
|
||||
"Welcome!",
|
||||
"Bienvenidos!",
|
||||
"To setup\r\nscan QR or\r\nconnect\r\nmanually",
|
||||
"Para\r\nconfigurar\r\nescanear QR\r\no conectar\r\nmanualmente",
|
||||
explainText,
|
||||
"*Hostname*:\r\n" + getMyHostname(),
|
||||
"*Hostname*:\r\n" + getMyHostname() + "\r\n\r\n" + "*FW build date:*\r\n" + formattedDate,
|
||||
qrText};
|
||||
setEpdContent(epdContent); });
|
||||
|
||||
|
@ -311,6 +322,17 @@ void setupHardware()
|
|||
Serial.println(F("Error loading WebUI"));
|
||||
}
|
||||
|
||||
// if (!LittleFS.exists("/qr.txt"))
|
||||
// {
|
||||
// File f = LittleFS.open("/qr.txt", "w");
|
||||
|
||||
// if(f) {
|
||||
|
||||
// } else {
|
||||
// Serial.println(F("Can't write QR to FS"));
|
||||
// }
|
||||
// }
|
||||
|
||||
setupLeds();
|
||||
|
||||
WiFi.setHostname(getMyHostname().c_str());
|
||||
|
@ -665,17 +687,27 @@ String getMyHostname()
|
|||
return hostname;
|
||||
}
|
||||
|
||||
uint getLastTimeSync() {
|
||||
uint getLastTimeSync()
|
||||
{
|
||||
return lastTimeSync;
|
||||
}
|
||||
|
||||
#ifdef HAS_FRONTLIGHT
|
||||
void setupFrontlight() {
|
||||
flArray.begin();
|
||||
void setupFrontlight()
|
||||
{
|
||||
if (!flArray.begin(PCA9685_MODE1_AUTOINCR, PCA9685_MODE2_INVERT))
|
||||
{
|
||||
Serial.println(F("FL driver error"));
|
||||
return;
|
||||
}
|
||||
Serial.println(F("FL driver active"));
|
||||
flArray.setFrequency(1000);
|
||||
flArray.setOutputEnablePin(PCA_OE_PIN);
|
||||
|
||||
if (!preferences.isKey("flMaxBrightness")) {
|
||||
flArray.setOutputEnable(true);
|
||||
delay(1000);
|
||||
flArray.setOutputEnable(false);
|
||||
if (!preferences.isKey("flMaxBrightness"))
|
||||
{
|
||||
preferences.putUInt("flMaxBrightness", 4095);
|
||||
}
|
||||
// Initialize all LEDs to off
|
||||
|
|
|
@ -339,7 +339,7 @@ void frontlightFadeInAll() {
|
|||
for (int ledPin = 0; ledPin < NUM_SCREENS; ledPin++) {
|
||||
flArray.setPWM(ledPin, 0, dutyCycle);
|
||||
}
|
||||
delay(flDelayTime);
|
||||
vTaskDelay(pdMS_TO_TICKS(flDelayTime));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -348,21 +348,21 @@ void frontlightFadeOutAll() {
|
|||
for (int ledPin = 0; ledPin < NUM_SCREENS; ledPin++) {
|
||||
flArray.setPWM(ledPin, 0, dutyCycle);
|
||||
}
|
||||
delay(flDelayTime);
|
||||
vTaskDelay(pdMS_TO_TICKS(flDelayTime));
|
||||
}
|
||||
}
|
||||
|
||||
void frontlightFadeIn(uint num) {
|
||||
for (int dutyCycle = 0; dutyCycle <= preferences.getUInt("flMaxBrightness"); dutyCycle += 5) {
|
||||
flArray.setPWM(num, 0, dutyCycle);
|
||||
delay(flDelayTime);
|
||||
vTaskDelay(pdMS_TO_TICKS(flDelayTime));
|
||||
}
|
||||
}
|
||||
|
||||
void frontlightFadeOut(uint num) {
|
||||
for (int dutyCycle = preferences.getUInt("flMaxBrightness"); dutyCycle >= 0; dutyCycle -= 5) {
|
||||
flArray.setPWM(num, 0, dutyCycle);
|
||||
delay(flDelayTime);
|
||||
vTaskDelay(pdMS_TO_TICKS(flDelayTime));
|
||||
}
|
||||
}
|
||||
#endif
|
|
@ -1,5 +1,6 @@
|
|||
#include "price_notify.hpp"
|
||||
|
||||
const char *wsOwnServerPrice = "wss://ws.btclock.store/ws?assets=bitcoin";
|
||||
const char *wsServerPrice = "wss://ws.coincap.io/prices?assets=bitcoin";
|
||||
|
||||
// const char* coinCapWsCert = R"(-----BEGIN CERTIFICATE-----
|
||||
|
@ -35,17 +36,25 @@ const char *wsServerPrice = "wss://ws.coincap.io/prices?assets=bitcoin";
|
|||
|
||||
// WebsocketsClient client;
|
||||
esp_websocket_client_handle_t clientPrice = NULL;
|
||||
uint currentPrice = 30000;
|
||||
esp_websocket_client_config_t config;
|
||||
uint currentPrice = 50000;
|
||||
unsigned long int lastPriceUpdate;
|
||||
bool priceNotifyInit = false;
|
||||
|
||||
void setupPriceNotify() {
|
||||
void setupPriceNotify()
|
||||
{
|
||||
// currentPrice = preferences.get("lastPrice", 30000);
|
||||
|
||||
esp_websocket_client_config_t config = {.uri = wsServerPrice,
|
||||
// .task_stack = (7*1024),
|
||||
// .cert_pem = coinCapWsCert,
|
||||
.user_agent = USER_AGENT};
|
||||
if (preferences.getBool("ownPriceSource", true))
|
||||
{
|
||||
config = {.uri = wsOwnServerPrice,
|
||||
.user_agent = USER_AGENT};
|
||||
}
|
||||
else
|
||||
{
|
||||
config = {.uri = wsServerPrice,
|
||||
.user_agent = USER_AGENT};
|
||||
}
|
||||
|
||||
clientPrice = esp_websocket_client_init(&config);
|
||||
esp_websocket_register_events(clientPrice, WEBSOCKET_EVENT_ANY,
|
||||
|
@ -54,40 +63,46 @@ void setupPriceNotify() {
|
|||
}
|
||||
|
||||
void onWebsocketPriceEvent(void *handler_args, esp_event_base_t base,
|
||||
int32_t event_id, void *event_data) {
|
||||
int32_t event_id, void *event_data)
|
||||
{
|
||||
esp_websocket_event_data_t *data = (esp_websocket_event_data_t *)event_data;
|
||||
|
||||
switch (event_id) {
|
||||
case WEBSOCKET_EVENT_CONNECTED:
|
||||
Serial.println(F("Connected to CoinCap.io WebSocket"));
|
||||
priceNotifyInit = true;
|
||||
switch (event_id)
|
||||
{
|
||||
case WEBSOCKET_EVENT_CONNECTED:
|
||||
Serial.println("Connected to " + String(config.uri) + " WebSocket");
|
||||
priceNotifyInit = true;
|
||||
|
||||
break;
|
||||
case WEBSOCKET_EVENT_DATA:
|
||||
onWebsocketPriceMessage(data);
|
||||
break;
|
||||
case WEBSOCKET_EVENT_ERROR:
|
||||
Serial.println(F("Price WS Connnection error"));
|
||||
break;
|
||||
case WEBSOCKET_EVENT_DISCONNECTED:
|
||||
Serial.println(F("Price WS Connnection Closed"));
|
||||
break;
|
||||
break;
|
||||
case WEBSOCKET_EVENT_DATA:
|
||||
onWebsocketPriceMessage(data);
|
||||
break;
|
||||
case WEBSOCKET_EVENT_ERROR:
|
||||
Serial.println(F("Price WS Connnection error"));
|
||||
break;
|
||||
case WEBSOCKET_EVENT_DISCONNECTED:
|
||||
Serial.println(F("Price WS Connnection Closed"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void onWebsocketPriceMessage(esp_websocket_event_data_t *event_data) {
|
||||
void onWebsocketPriceMessage(esp_websocket_event_data_t *event_data)
|
||||
{
|
||||
JsonDocument doc;
|
||||
|
||||
deserializeJson(doc, (char *)event_data->data_ptr);
|
||||
|
||||
if (doc.containsKey("bitcoin")) {
|
||||
if (currentPrice != doc["bitcoin"].as<long>()) {
|
||||
if (doc.containsKey("bitcoin"))
|
||||
{
|
||||
if (currentPrice != doc["bitcoin"].as<long>())
|
||||
{
|
||||
uint minSecPriceUpd = preferences.getUInt(
|
||||
"minSecPriceUpd", DEFAULT_SECONDS_BETWEEN_PRICE_UPDATE);
|
||||
uint currentTime = esp_timer_get_time() / 1000000;
|
||||
|
||||
if (lastPriceUpdate == 0 ||
|
||||
(currentTime - lastPriceUpdate) > minSecPriceUpd) {
|
||||
(currentTime - lastPriceUpdate) > minSecPriceUpd)
|
||||
{
|
||||
// const unsigned long oldPrice = currentPrice;
|
||||
currentPrice = doc["bitcoin"].as<uint>();
|
||||
preferences.putUInt("lastPrice", currentPrice);
|
||||
|
@ -95,7 +110,8 @@ void onWebsocketPriceMessage(esp_websocket_event_data_t *event_data) {
|
|||
// if (abs((int)(oldPrice-currentPrice)) > round(0.0015*oldPrice)) {
|
||||
if (workQueue != nullptr && (getCurrentScreen() == SCREEN_BTC_TICKER ||
|
||||
getCurrentScreen() == SCREEN_MSCW_TIME ||
|
||||
getCurrentScreen() == SCREEN_MARKET_CAP)) {
|
||||
getCurrentScreen() == SCREEN_MARKET_CAP))
|
||||
{
|
||||
WorkItem priceUpdate = {TASK_PRICE_UPDATE, 0};
|
||||
xQueueSend(workQueue, &priceUpdate, portMAX_DELAY);
|
||||
}
|
||||
|
@ -105,7 +121,8 @@ void onWebsocketPriceMessage(esp_websocket_event_data_t *event_data) {
|
|||
}
|
||||
}
|
||||
|
||||
uint getLastPriceUpdate() {
|
||||
uint getLastPriceUpdate()
|
||||
{
|
||||
return lastPriceUpdate;
|
||||
}
|
||||
|
||||
|
@ -113,17 +130,22 @@ uint getPrice() { return currentPrice; }
|
|||
|
||||
void setPrice(uint newPrice) { currentPrice = newPrice; }
|
||||
|
||||
bool isPriceNotifyConnected() {
|
||||
if (clientPrice == NULL) return false;
|
||||
bool isPriceNotifyConnected()
|
||||
{
|
||||
if (clientPrice == NULL)
|
||||
return false;
|
||||
return esp_websocket_client_is_connected(clientPrice);
|
||||
}
|
||||
|
||||
bool getPriceNotifyInit() {
|
||||
bool getPriceNotifyInit()
|
||||
{
|
||||
return priceNotifyInit;
|
||||
}
|
||||
|
||||
void stopPriceNotify() {
|
||||
if (clientPrice == NULL) return;
|
||||
void stopPriceNotify()
|
||||
{
|
||||
if (clientPrice == NULL)
|
||||
return;
|
||||
esp_websocket_client_close(clientPrice, pdMS_TO_TICKS(5000));
|
||||
esp_websocket_client_stop(clientPrice);
|
||||
esp_websocket_client_destroy(clientPrice);
|
||||
|
@ -131,9 +153,11 @@ void stopPriceNotify() {
|
|||
clientPrice = NULL;
|
||||
}
|
||||
|
||||
void restartPriceNotify() {
|
||||
void restartPriceNotify()
|
||||
{
|
||||
stopPriceNotify();
|
||||
if (clientPrice == NULL) {
|
||||
if (clientPrice == NULL)
|
||||
{
|
||||
setupPriceNotify();
|
||||
return;
|
||||
}
|
||||
|
|
10
src/lib/shared.cpp
Normal file
10
src/lib/shared.cpp
Normal file
|
@ -0,0 +1,10 @@
|
|||
#include "shared.hpp"
|
||||
|
||||
#ifdef TEST_SCREENS
|
||||
uint8_t input_buffer[3 * input_buffer_pixels]; // up to depth 24
|
||||
uint8_t output_row_mono_buffer[max_row_width / 8]; // buffer for at least one row of b/w bits
|
||||
uint8_t output_row_color_buffer[max_row_width / 8]; // buffer for at least one row of color bits
|
||||
uint8_t mono_palette_buffer[max_palette_pixels / 8]; // palette buffer for depth <= 8 b/w
|
||||
uint8_t color_palette_buffer[max_palette_pixels / 8]; // palette buffer for depth <= 8 c/w
|
||||
uint16_t rgb_palette_buffer[max_palette_pixels]; // palette buffer for depth <= 8 for buffered graphics, needed for 7-color display
|
||||
#endif
|
|
@ -329,7 +329,7 @@ void onApiSettingsPatch(AsyncWebServerRequest *request, JsonVariant &json) {
|
|||
String boolSettings[] = {"fetchEurPrice", "ledTestOnPower", "ledFlashOnUpd",
|
||||
"mdnsEnabled", "otaEnabled", "stealFocus",
|
||||
"mcapBigChar", "useSatsSymbol", "useBlkCountdown",
|
||||
"suffixPrice", "disableLeds"};
|
||||
"suffixPrice", "disableLeds", "ownPriceSource", "flAlwaysOn"};
|
||||
|
||||
for (String setting : boolSettings) {
|
||||
if (settings.containsKey(setting)) {
|
||||
|
@ -425,10 +425,13 @@ void onApiSettingsGet(AsyncWebServerRequest *request) {
|
|||
root["hostname"] = getMyHostname();
|
||||
root["ip"] = WiFi.localIP();
|
||||
root["txPower"] = WiFi.getTxPower();
|
||||
root["ownPriceSource"] = preferences.getBool("ownPriceSource", true);
|
||||
|
||||
#ifdef HAS_FRONTLIGHT
|
||||
root["hasFrontlight"] = true;
|
||||
root["flMaxBrightness"] = preferences.getUInt("flMaxBrightness", 4095);
|
||||
root["flAlwaysOn"] = preferences.getBool("flAlwaysOn", false);
|
||||
|
||||
#else
|
||||
root["hasFrontlight"] = false;
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue