update
This commit is contained in:
111
src/Apps.h
111
src/Apps.h
@@ -107,7 +107,7 @@ int findAppIndexByName(const String &name)
|
||||
return -1;
|
||||
}
|
||||
|
||||
void TimeApp(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame)
|
||||
void TimeApp(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame, GifPlayer *gifPlayer)
|
||||
{
|
||||
if (notify.flag)
|
||||
return;
|
||||
@@ -155,7 +155,7 @@ void TimeApp(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x,
|
||||
}
|
||||
}
|
||||
|
||||
void DateApp(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame)
|
||||
void DateApp(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame, GifPlayer *gifPlayer)
|
||||
{
|
||||
if (notify.flag)
|
||||
return;
|
||||
@@ -183,7 +183,7 @@ void DateApp(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x,
|
||||
}
|
||||
}
|
||||
|
||||
void TempApp(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame)
|
||||
void TempApp(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame, GifPlayer *gifPlayer)
|
||||
{
|
||||
if (notify.flag)
|
||||
return;
|
||||
@@ -209,7 +209,7 @@ void TempApp(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x,
|
||||
}
|
||||
}
|
||||
|
||||
void HumApp(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame)
|
||||
void HumApp(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame, GifPlayer *gifPlayer)
|
||||
{
|
||||
if (notify.flag)
|
||||
return;
|
||||
@@ -222,10 +222,8 @@ void HumApp(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, i
|
||||
matrix->print("%");
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef ULANZI
|
||||
void BatApp(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame)
|
||||
void BatApp(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame, GifPlayer *gifPlayer)
|
||||
{
|
||||
if (notify.flag)
|
||||
return;
|
||||
@@ -238,7 +236,7 @@ void BatApp(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, i
|
||||
}
|
||||
#endif
|
||||
|
||||
void MenuApp(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state)
|
||||
void MenuApp(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, GifPlayer *gifPlayer)
|
||||
{
|
||||
if (!MenuManager.inMenu)
|
||||
return;
|
||||
@@ -246,7 +244,7 @@ void MenuApp(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state)
|
||||
DisplayManager.printText(0, 6, utf8ascii(MenuManager.menutext()).c_str(), true, true);
|
||||
}
|
||||
|
||||
void AlarmApp(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state)
|
||||
void AlarmApp(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, GifPlayer *gifPlayer)
|
||||
{
|
||||
if (ALARM_ACTIVE)
|
||||
{
|
||||
@@ -271,7 +269,7 @@ void AlarmApp(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state)
|
||||
}
|
||||
}
|
||||
|
||||
void TimerApp(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state)
|
||||
void TimerApp(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, GifPlayer *gifPlayer)
|
||||
{
|
||||
if (TIMER_ACTIVE)
|
||||
{
|
||||
@@ -297,7 +295,7 @@ void TimerApp(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state)
|
||||
}
|
||||
}
|
||||
|
||||
void ShowCustomApp(String name, FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame)
|
||||
void ShowCustomApp(String name, FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame, GifPlayer *gifPlayer)
|
||||
{
|
||||
// Abort if notify.flag is set
|
||||
if (notify.flag)
|
||||
@@ -457,10 +455,8 @@ void ShowCustomApp(String name, FastLED_NeoMatrix *matrix, MatrixDisplayUiState
|
||||
// Display animated GIF if enabled and App is fixed, since we have only one gifplayer instance, it looks weird when 2 apps want to draw a different gif
|
||||
if (ca->isGif)
|
||||
{
|
||||
if (state->appState == FIXED)
|
||||
{
|
||||
DisplayManager.drawGIF(x + ca->iconPosition, y, ca->icon);
|
||||
}
|
||||
|
||||
gifPlayer->playGif(x + ca->iconPosition, y, &ca->icon);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -478,7 +474,7 @@ void ShowCustomApp(String name, FastLED_NeoMatrix *matrix, MatrixDisplayUiState
|
||||
DisplayManager.getInstance().resetTextColor();
|
||||
}
|
||||
|
||||
void NotifyApp(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state)
|
||||
void NotifyApp(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, GifPlayer *gifPlayer)
|
||||
{
|
||||
// Check if notification flag is set
|
||||
if (!notify.flag)
|
||||
@@ -634,7 +630,8 @@ void NotifyApp(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state)
|
||||
if (notify.isGif)
|
||||
{
|
||||
// Display GIF if present
|
||||
DisplayManager.drawGIF(notify.iconPosition, 0, notify.icon);
|
||||
|
||||
gifPlayer->playGif(notify.iconPosition, 0, ¬ify.icon);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -655,124 +652,124 @@ void NotifyApp(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state)
|
||||
|
||||
// Unattractive to have a function for every customapp wich does the same, but currently still no other option found TODO
|
||||
|
||||
void CApp1(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame)
|
||||
void CApp1(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame, GifPlayer *gifPlayer)
|
||||
{
|
||||
String name = getAppNameByFunction(CApp1);
|
||||
ShowCustomApp(name, matrix, state, x, y, firstFrame, lastFrame);
|
||||
ShowCustomApp(name, matrix, state, x, y, firstFrame, lastFrame, gifPlayer);
|
||||
}
|
||||
|
||||
void CApp2(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame)
|
||||
void CApp2(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame, GifPlayer *gifPlayer)
|
||||
{
|
||||
String name = getAppNameByFunction(CApp2);
|
||||
ShowCustomApp(name, matrix, state, x, y, firstFrame, lastFrame);
|
||||
ShowCustomApp(name, matrix, state, x, y, firstFrame, lastFrame, gifPlayer);
|
||||
}
|
||||
|
||||
void CApp3(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame)
|
||||
void CApp3(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame, GifPlayer *gifPlayer)
|
||||
{
|
||||
String name = getAppNameByFunction(CApp3);
|
||||
ShowCustomApp(name, matrix, state, x, y, firstFrame, lastFrame);
|
||||
ShowCustomApp(name, matrix, state, x, y, firstFrame, lastFrame, gifPlayer);
|
||||
}
|
||||
|
||||
void CApp4(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame)
|
||||
void CApp4(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame, GifPlayer *gifPlayer)
|
||||
{
|
||||
String name = getAppNameByFunction(CApp4);
|
||||
ShowCustomApp(name, matrix, state, x, y, firstFrame, lastFrame);
|
||||
ShowCustomApp(name, matrix, state, x, y, firstFrame, lastFrame, gifPlayer);
|
||||
}
|
||||
|
||||
void CApp5(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame)
|
||||
void CApp5(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame, GifPlayer *gifPlayer)
|
||||
{
|
||||
String name = getAppNameByFunction(CApp5);
|
||||
ShowCustomApp(name, matrix, state, x, y, firstFrame, lastFrame);
|
||||
ShowCustomApp(name, matrix, state, x, y, firstFrame, lastFrame, gifPlayer);
|
||||
}
|
||||
|
||||
void CApp6(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame)
|
||||
void CApp6(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame, GifPlayer *gifPlayer)
|
||||
{
|
||||
String name = getAppNameByFunction(CApp6);
|
||||
ShowCustomApp(name, matrix, state, x, y, firstFrame, lastFrame);
|
||||
ShowCustomApp(name, matrix, state, x, y, firstFrame, lastFrame, gifPlayer);
|
||||
}
|
||||
|
||||
void CApp7(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame)
|
||||
void CApp7(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame, GifPlayer *gifPlayer)
|
||||
{
|
||||
String name = getAppNameByFunction(CApp7);
|
||||
ShowCustomApp(name, matrix, state, x, y, firstFrame, lastFrame);
|
||||
ShowCustomApp(name, matrix, state, x, y, firstFrame, lastFrame, gifPlayer);
|
||||
}
|
||||
|
||||
void CApp8(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame)
|
||||
void CApp8(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame, GifPlayer *gifPlayer)
|
||||
{
|
||||
String name = getAppNameByFunction(CApp8);
|
||||
ShowCustomApp(name, matrix, state, x, y, firstFrame, lastFrame);
|
||||
ShowCustomApp(name, matrix, state, x, y, firstFrame, lastFrame, gifPlayer);
|
||||
}
|
||||
|
||||
void CApp9(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame)
|
||||
void CApp9(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame, GifPlayer *gifPlayer)
|
||||
{
|
||||
String name = getAppNameByFunction(CApp9);
|
||||
ShowCustomApp(name, matrix, state, x, y, firstFrame, lastFrame);
|
||||
ShowCustomApp(name, matrix, state, x, y, firstFrame, lastFrame, gifPlayer);
|
||||
}
|
||||
|
||||
void CApp10(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame)
|
||||
void CApp10(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame, GifPlayer *gifPlayer)
|
||||
{
|
||||
String name = getAppNameByFunction(CApp10);
|
||||
ShowCustomApp(name, matrix, state, x, y, firstFrame, lastFrame);
|
||||
ShowCustomApp(name, matrix, state, x, y, firstFrame, lastFrame, gifPlayer);
|
||||
}
|
||||
|
||||
void CApp11(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame)
|
||||
void CApp11(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame, GifPlayer *gifPlayer)
|
||||
{
|
||||
String name = getAppNameByFunction(CApp11);
|
||||
ShowCustomApp(name, matrix, state, x, y, firstFrame, lastFrame);
|
||||
ShowCustomApp(name, matrix, state, x, y, firstFrame, lastFrame, gifPlayer);
|
||||
}
|
||||
|
||||
void CApp12(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame)
|
||||
void CApp12(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame, GifPlayer *gifPlayer)
|
||||
{
|
||||
String name = getAppNameByFunction(CApp12);
|
||||
ShowCustomApp(name, matrix, state, x, y, firstFrame, lastFrame);
|
||||
ShowCustomApp(name, matrix, state, x, y, firstFrame, lastFrame, gifPlayer);
|
||||
}
|
||||
|
||||
void CApp13(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame)
|
||||
void CApp13(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame, GifPlayer *gifPlayer)
|
||||
{
|
||||
String name = getAppNameByFunction(CApp13);
|
||||
ShowCustomApp(name, matrix, state, x, y, firstFrame, lastFrame);
|
||||
ShowCustomApp(name, matrix, state, x, y, firstFrame, lastFrame, gifPlayer);
|
||||
}
|
||||
|
||||
void CApp14(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame)
|
||||
void CApp14(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame, GifPlayer *gifPlayer)
|
||||
{
|
||||
String name = getAppNameByFunction(CApp14);
|
||||
ShowCustomApp(name, matrix, state, x, y, firstFrame, lastFrame);
|
||||
ShowCustomApp(name, matrix, state, x, y, firstFrame, lastFrame, gifPlayer);
|
||||
}
|
||||
|
||||
void CApp15(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame)
|
||||
void CApp15(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame, GifPlayer *gifPlayer)
|
||||
{
|
||||
String name = getAppNameByFunction(CApp15);
|
||||
ShowCustomApp(name, matrix, state, x, y, firstFrame, lastFrame);
|
||||
ShowCustomApp(name, matrix, state, x, y, firstFrame, lastFrame, gifPlayer);
|
||||
}
|
||||
|
||||
void CApp16(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame)
|
||||
void CApp16(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame, GifPlayer *gifPlayer)
|
||||
{
|
||||
String name = getAppNameByFunction(CApp16);
|
||||
ShowCustomApp(name, matrix, state, x, y, firstFrame, lastFrame);
|
||||
ShowCustomApp(name, matrix, state, x, y, firstFrame, lastFrame, gifPlayer);
|
||||
}
|
||||
|
||||
void CApp17(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame)
|
||||
void CApp17(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame, GifPlayer *gifPlayer)
|
||||
{
|
||||
String name = getAppNameByFunction(CApp17);
|
||||
ShowCustomApp(name, matrix, state, x, y, firstFrame, lastFrame);
|
||||
ShowCustomApp(name, matrix, state, x, y, firstFrame, lastFrame, gifPlayer);
|
||||
}
|
||||
|
||||
void CApp18(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame)
|
||||
void CApp18(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame, GifPlayer *gifPlayer)
|
||||
{
|
||||
String name = getAppNameByFunction(CApp18);
|
||||
ShowCustomApp(name, matrix, state, x, y, firstFrame, lastFrame);
|
||||
ShowCustomApp(name, matrix, state, x, y, firstFrame, lastFrame, gifPlayer);
|
||||
}
|
||||
|
||||
void CApp19(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame)
|
||||
void CApp19(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame, GifPlayer *gifPlayer)
|
||||
{
|
||||
String name = getAppNameByFunction(CApp19);
|
||||
ShowCustomApp(name, matrix, state, x, y, firstFrame, lastFrame);
|
||||
ShowCustomApp(name, matrix, state, x, y, firstFrame, lastFrame, gifPlayer);
|
||||
}
|
||||
|
||||
void CApp20(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame)
|
||||
void CApp20(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame, GifPlayer *gifPlayer)
|
||||
{
|
||||
String name = getAppNameByFunction(CApp20);
|
||||
ShowCustomApp(name, matrix, state, x, y, firstFrame, lastFrame);
|
||||
ShowCustomApp(name, matrix, state, x, y, firstFrame, lastFrame, gifPlayer);
|
||||
}
|
||||
|
||||
const uint16_t *getWeatherIcon(int code)
|
||||
|
||||
@@ -1,292 +0,0 @@
|
||||
#include <BeaconScanner.h>
|
||||
#include <NimBLEDevice.h>
|
||||
#include <Ticker.h>
|
||||
#include "MQTTManager.h"
|
||||
#include <ArduinoJson.h>
|
||||
#include <LittleFS.h>
|
||||
#include <DisplayManager.h>
|
||||
|
||||
float triggerDistance = 0.6;
|
||||
String room = "Büro";
|
||||
std::vector<String> allowedIds;
|
||||
|
||||
Ticker scanTicker;
|
||||
// The getter for the instantiated singleton instance
|
||||
BeaconScanner_ &BeaconScanner_::getInstance()
|
||||
{
|
||||
static BeaconScanner_ instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
// Initialize the global shared instance
|
||||
BeaconScanner_ &BeaconScanner = BeaconScanner.getInstance();
|
||||
|
||||
static const int scanTime = 5; // In Sekunden
|
||||
NimBLEScan *pBLEScan;
|
||||
|
||||
uint32_t fnv1a_32(const String &input)
|
||||
{
|
||||
const uint32_t FNV_PRIME = 0x01000193;
|
||||
const uint32_t FNV_OFFSET_BASIS = 0x811C9DC5;
|
||||
|
||||
uint32_t hash = FNV_OFFSET_BASIS;
|
||||
|
||||
for (unsigned int i = 0; i < input.length(); ++i)
|
||||
{
|
||||
hash ^= static_cast<uint8_t>(input[i]);
|
||||
hash *= FNV_PRIME;
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
String getManufacturerName(uint16_t manufacturerID)
|
||||
{
|
||||
switch (manufacturerID)
|
||||
{
|
||||
case 0x004C: // Apple, Inc.
|
||||
return "Apple";
|
||||
case 0x0118: // Google, Inc.
|
||||
return "Google";
|
||||
case 0x000F: // Microsoft Corporation
|
||||
return "Microsoft";
|
||||
case 0x0030: // Ericsson Technology Licensing
|
||||
return "Ericsson";
|
||||
case 0x0039: // Intel Corp.
|
||||
return "Intel";
|
||||
case 0x0059: // Samsung Electronics Co., Ltd.
|
||||
return "Samsung";
|
||||
case 0x000D: // Nokia Corporation
|
||||
return "Nokia";
|
||||
case 0x0100: // Broadcom Corporation
|
||||
return "Broadcom";
|
||||
case 0x0034: // Texas Instruments Inc.
|
||||
return "Texas Instruments";
|
||||
case 0x0075: // Sony Ericsson Mobile Communications AB
|
||||
return "Sony Ericsson";
|
||||
case 0x0089: // Panasonic Corporation
|
||||
return "Panasonic";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
bool isIdAllowed(const char *id)
|
||||
{
|
||||
if (allowedIds.size() == 0)
|
||||
return true;
|
||||
for (const String &allowedId : allowedIds)
|
||||
{
|
||||
if (strcmp(id, allowedId.c_str()) == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Serial.println("Not allowed");
|
||||
return false;
|
||||
}
|
||||
|
||||
double calculateDistance(int rssi, int8_t txPower)
|
||||
{
|
||||
if (rssi == 0)
|
||||
{
|
||||
return -1.0;
|
||||
}
|
||||
|
||||
double pathLoss = txPower - rssi;
|
||||
// Path Loss Exponent (n) ist eine Umgebungsspezifische Konstante und liegt normalerweise zwischen 2 und 4.
|
||||
// 2 entspricht Freiraum, während 4 dichtere Umgebungen repräsentiert.
|
||||
double pathLossExponent = 3.0;
|
||||
|
||||
return pow(10, pathLoss / (10 * pathLossExponent));
|
||||
}
|
||||
|
||||
String toHexString(const std::string &input)
|
||||
{
|
||||
String hexString = "";
|
||||
for (unsigned char c : input)
|
||||
{
|
||||
char hexChar[3];
|
||||
snprintf(hexChar, sizeof(hexChar), "%02X", c);
|
||||
hexString += hexChar;
|
||||
}
|
||||
return hexString;
|
||||
}
|
||||
|
||||
bool isIBeacon(NimBLEAdvertisedDevice *advertisedDevice, uint16_t *major, uint16_t *minor, int8_t *txPower, String *uuid, String *manufacturerName)
|
||||
{
|
||||
std::string payload = advertisedDevice->getManufacturerData();
|
||||
|
||||
if (payload.size() == 25 && static_cast<uint8_t>(payload[0]) == 0x4C && static_cast<uint8_t>(payload[1]) == 0x00 && static_cast<uint8_t>(payload[2]) == 0x02 && static_cast<uint8_t>(payload[3]) == 0x15)
|
||||
{
|
||||
uint16_t manufacturerID = (static_cast<uint8_t>(payload[0]) << 8) | static_cast<uint8_t>(payload[1]);
|
||||
*uuid = toHexString(payload.substr(4, 16));
|
||||
*major = (static_cast<uint8_t>(payload[20]) << 8) | static_cast<uint8_t>(payload[21]);
|
||||
*minor = (static_cast<uint8_t>(payload[22]) << 8) | static_cast<uint8_t>(payload[23]);
|
||||
*txPower = static_cast<int8_t>(payload[24]);
|
||||
*manufacturerName = getManufacturerName(manufacturerID);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isEddystoneUID(NimBLEAdvertisedDevice *advertisedDevice, String *namespaceID, String *instanceID)
|
||||
{
|
||||
std::string serviceData = advertisedDevice->getServiceData();
|
||||
if (serviceData.size() >= 20 && static_cast<uint8_t>(serviceData[0]) == 0xAA && static_cast<uint8_t>(serviceData[1]) == 0xFE && static_cast<uint8_t>(serviceData[2]) == 0x00)
|
||||
{
|
||||
*namespaceID = toHexString(serviceData.substr(4, 10));
|
||||
*instanceID = toHexString(serviceData.substr(14, 6));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
class MyAdvertisedDeviceCallbacks : public NimBLEAdvertisedDeviceCallbacks
|
||||
{
|
||||
void onResult(NimBLEAdvertisedDevice *advertisedDevice)
|
||||
{
|
||||
StaticJsonDocument<512> doc;
|
||||
uint16_t major;
|
||||
uint16_t minor;
|
||||
int8_t txPower;
|
||||
String uuid;
|
||||
String manufacturer;
|
||||
|
||||
uint32_t hashedUUID = fnv1a_32(uuid);
|
||||
char compressedUUID[9];
|
||||
snprintf(compressedUUID, sizeof(compressedUUID), "%08X", hashedUUID);
|
||||
|
||||
int rssi = advertisedDevice->getRSSI();
|
||||
doc["id"] = compressedUUID;
|
||||
doc["rssi"] = rssi;
|
||||
String topic;
|
||||
bool sendToMQTT = false;
|
||||
topic = String("rooms/") + room;
|
||||
if (isIBeacon(advertisedDevice, &major, &minor, &txPower, &uuid, &manufacturer))
|
||||
{
|
||||
double BeaconDistance = calculateDistance(rssi, txPower);
|
||||
|
||||
doc["txPower"] = txPower;
|
||||
doc["distance"] = BeaconDistance;
|
||||
|
||||
if (advertisedDevice->haveName())
|
||||
{
|
||||
String nameBLE = String(advertisedDevice->getName().c_str());
|
||||
doc["name"] = nameBLE;
|
||||
}
|
||||
Serial.print("iBeacon UUID: ");
|
||||
Serial.print(compressedUUID);
|
||||
Serial.print(" Distance: ");
|
||||
Serial.print(BeaconDistance);
|
||||
Serial.print(" Manufacturer: ");
|
||||
Serial.print(manufacturer);
|
||||
Serial.print(" TxPower: ");
|
||||
Serial.println(txPower);
|
||||
|
||||
if (BeaconDistance < 0.2)
|
||||
{
|
||||
char jsonString[100];
|
||||
memset(jsonString, 0, sizeof(jsonString));
|
||||
std::snprintf(jsonString, sizeof(jsonString), "{\"text\":\"%s\",\"duration\":\"%d\",\"color\":%s\"}", compressedUUID, 4,"#00ff00");
|
||||
DisplayManager.generateNotification(jsonString);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((BeaconDistance <= triggerDistance) && isIdAllowed(compressedUUID))
|
||||
{
|
||||
char JSONmessageBuffer[512];
|
||||
serializeJson(doc, JSONmessageBuffer);
|
||||
MQTTManager.publish(topic.c_str(), JSONmessageBuffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void BeaconScanner_::startScan()
|
||||
{
|
||||
Serial.println(F("---------------"));
|
||||
Serial.println(F("Scan BLE"));
|
||||
Serial.println(F("---------------"));
|
||||
pBLEScan->start(scanTime, [](NimBLEScanResults results)
|
||||
{ scanTicker.once(scanTime, []()
|
||||
{ BeaconScanner.startScan(); }); });
|
||||
}
|
||||
|
||||
void printAllowedIds()
|
||||
{
|
||||
Serial.println("Allowed IDs:");
|
||||
for (const String &allowedId : allowedIds)
|
||||
{
|
||||
Serial.println(allowedId);
|
||||
}
|
||||
}
|
||||
|
||||
bool loadBeaconSettings()
|
||||
{
|
||||
Serial.println("loadSettings");
|
||||
if (LittleFS.exists("/beacons.json"))
|
||||
{
|
||||
File file = LittleFS.open("/beacons.json", "r");
|
||||
DynamicJsonDocument doc(128);
|
||||
DeserializationError error = deserializeJson(doc, file);
|
||||
if (error)
|
||||
{
|
||||
Serial.println(F("Failed to read beacon settings"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (doc.containsKey("room"))
|
||||
{
|
||||
room = doc["room"].as<String>();
|
||||
Serial.println(room);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (doc.containsKey("trigger_distance"))
|
||||
{
|
||||
triggerDistance = doc["trigger_distance"].as<float>();
|
||||
Serial.println(triggerDistance);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (doc.containsKey("allowed_ids"))
|
||||
{
|
||||
JsonArray allowedIdsJsonArray = doc["allowed_ids"];
|
||||
for (const char *id : allowedIdsJsonArray)
|
||||
{
|
||||
allowedIds.push_back(String(id));
|
||||
}
|
||||
printAllowedIds();
|
||||
}
|
||||
|
||||
return true;
|
||||
file.close();
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void BeaconScanner_::setup()
|
||||
{
|
||||
if (!loadBeaconSettings())
|
||||
return;
|
||||
NimBLEDevice::init("");
|
||||
NimBLEDevice::setPower(ESP_PWR_LVL_P9);
|
||||
pBLEScan = NimBLEDevice::getScan();
|
||||
pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
|
||||
pBLEScan->setInterval(100);
|
||||
pBLEScan->setWindow(99);
|
||||
pBLEScan->setActiveScan(true);
|
||||
pBLEScan->setMaxResults(0);
|
||||
startScan();
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
#ifndef BeaconScanner_h
|
||||
#define BeaconScanner_h
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
class BeaconScanner_
|
||||
{
|
||||
private:
|
||||
BeaconScanner_() = default;
|
||||
|
||||
public:
|
||||
static BeaconScanner_ &getInstance();
|
||||
void setup();
|
||||
void startScan();
|
||||
};
|
||||
|
||||
extern BeaconScanner_ &BeaconScanner;
|
||||
#endif
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "Apps.h"
|
||||
#include "Dictionary.h"
|
||||
#include <set>
|
||||
#include "GifPlayer.h"
|
||||
|
||||
Ticker AlarmTicker;
|
||||
Ticker TimerTicker;
|
||||
@@ -93,12 +94,6 @@ bool DisplayManager_::setAutoTransition(bool active)
|
||||
showGif = false;
|
||||
}
|
||||
|
||||
void DisplayManager_::drawGIF(uint16_t x, uint16_t y, fs::File gFile)
|
||||
{
|
||||
gif.setFile(gFile);
|
||||
gif.drawFrame(x, y);
|
||||
}
|
||||
|
||||
void DisplayManager_::drawJPG(uint16_t x, uint16_t y, fs::File jpgFile)
|
||||
{
|
||||
TJpgDec.drawFsJpg(x, y, jpgFile);
|
||||
@@ -211,7 +206,7 @@ void pushCustomApp(String name, int position)
|
||||
if (customApps.count(name) == 0)
|
||||
{
|
||||
++customPagesCount;
|
||||
void (*customApps[20])(FastLED_NeoMatrix *, MatrixDisplayUiState *, int16_t, int16_t, bool, bool) = {CApp1, CApp2, CApp3, CApp4, CApp5, CApp6, CApp7, CApp8, CApp9, CApp10, CApp11, CApp12, CApp13, CApp14, CApp15, CApp16, CApp17, CApp18, CApp19, CApp20};
|
||||
void (*customApps[20])(FastLED_NeoMatrix *, MatrixDisplayUiState *, int16_t, int16_t, bool, bool, GifPlayer *) = {CApp1, CApp2, CApp3, CApp4, CApp5, CApp6, CApp7, CApp8, CApp9, CApp10, CApp11, CApp12, CApp13, CApp14, CApp15, CApp16, CApp17, CApp18, CApp19, CApp20};
|
||||
|
||||
if (position < 0) // Insert at the end of the vector
|
||||
{
|
||||
@@ -307,7 +302,7 @@ void DisplayManager_::generateCustomPage(const String &name, const char *json)
|
||||
customApp.pushIcon = doc.containsKey("pushIcon") ? doc["pushIcon"] : 0;
|
||||
customApp.textCase = doc.containsKey("textCase") ? doc["textCase"] : 0;
|
||||
customApp.name = name;
|
||||
customApp.text = utf8ascii(doc["text"].as<String>());
|
||||
customApp.text = doc.containsKey("text") ? utf8ascii(doc["text"].as<String>()) : "";
|
||||
|
||||
if (doc.containsKey("color"))
|
||||
{
|
||||
@@ -386,7 +381,7 @@ void DisplayManager_::generateNotification(const char *json)
|
||||
deserializeJson(doc, json);
|
||||
|
||||
notify.duration = doc.containsKey("duration") ? doc["duration"].as<int>() * 1000 : TIME_PER_APP;
|
||||
notify.text = utf8ascii(doc["text"].as<String>());
|
||||
notify.text = doc.containsKey("text") ? utf8ascii(doc["text"].as<String>()) : "";
|
||||
notify.repeat = doc.containsKey("repeat") ? doc["repeat"].as<uint16_t>() : -1;
|
||||
notify.rainbow = doc.containsKey("rainbow") ? doc["rainbow"].as<bool>() : false;
|
||||
notify.hold = doc.containsKey("hold") ? doc["hold"].as<bool>() : false;
|
||||
@@ -551,10 +546,6 @@ void DisplayManager_::setup()
|
||||
ui->init();
|
||||
}
|
||||
|
||||
void ShowGif()
|
||||
{
|
||||
}
|
||||
|
||||
void DisplayManager_::tick()
|
||||
{
|
||||
if (AP_MODE)
|
||||
@@ -577,9 +568,6 @@ void DisplayManager_::tick()
|
||||
MQTTManager.setCurrentApp(CURRENT_APP);
|
||||
setAppTime(TIME_PER_APP);
|
||||
}
|
||||
// if (showGif && !MenuManager.inMenu)
|
||||
//
|
||||
// matrix->show();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
657
src/GifPlayer.h
657
src/GifPlayer.h
@@ -1,657 +0,0 @@
|
||||
#ifndef GifPlayer_H
|
||||
#define GifPlayer_H
|
||||
|
||||
class GifPlayer
|
||||
{
|
||||
public:
|
||||
#define ERROR_NONE 0
|
||||
#define ERROR_FILEOPEN 1
|
||||
#define ERROR_FILENOTGIF 2
|
||||
#define ERROR_BADGIFFORMAT 3
|
||||
#define ERROR_UNKNOWNCONTROLEXT 4
|
||||
#define ERROR_FINISHED 5
|
||||
#define WIDTH 32
|
||||
#define HEIGHT 8
|
||||
private:
|
||||
bool needNewFrame;
|
||||
long lastFrameTime;
|
||||
bool firstFrameDone;
|
||||
int newframeDelay;
|
||||
int lastFrame[WIDTH * HEIGHT];
|
||||
bool lastFrameDrawn = false;
|
||||
unsigned long nextFrameTime = 0;
|
||||
#define GIFHDRTAGNORM "GIF87a"
|
||||
#define GIFHDRTAGNORM1 "GIF89a"
|
||||
#define GIFHDRSIZE 6
|
||||
FastLED_NeoMatrix *mtx;
|
||||
#define COLORTBLFLAG 0x80
|
||||
#define INTERLACEFLAG 0x40
|
||||
#define TRANSPARENTFLAG 0x01
|
||||
#define NO_TRANSPARENT_INDEX -1
|
||||
#define DISPOSAL_NONE 0
|
||||
#define DISPOSAL_LEAVE 1
|
||||
#define DISPOSAL_BACKGROUND 2
|
||||
#define DISPOSAL_RESTORE 3
|
||||
|
||||
typedef struct
|
||||
{
|
||||
byte Red;
|
||||
byte Green;
|
||||
byte Blue;
|
||||
} _RGB;
|
||||
int lsdWidth;
|
||||
int lsdHeight;
|
||||
int lsdPackedField;
|
||||
int lsdAspectRatio;
|
||||
int lsdBackgroundIndex;
|
||||
int offsetX;
|
||||
int offsetY;
|
||||
int tbiImageX;
|
||||
int tbiImageY;
|
||||
int tbiWidth;
|
||||
int tbiHeight;
|
||||
int tbiPackedBits;
|
||||
boolean tbiInterlaced;
|
||||
|
||||
public:
|
||||
int frameDelay;
|
||||
int transparentColorIndex;
|
||||
int prevBackgroundIndex;
|
||||
int prevDisposalMethod;
|
||||
int disposalMethod;
|
||||
int lzwCodeSize;
|
||||
boolean keyFrame;
|
||||
int rectX;
|
||||
int rectY;
|
||||
int rectWidth;
|
||||
int rectHeight;
|
||||
int colorCount;
|
||||
_RGB gifPalette[256];
|
||||
byte lzwImageData[1280];
|
||||
char tempBuffer[260];
|
||||
File file;
|
||||
byte imageData[WIDTH * HEIGHT];
|
||||
byte imageDataBU[WIDTH * HEIGHT];
|
||||
|
||||
void backUpStream(int n)
|
||||
{
|
||||
file.seek(file.position() - n, SeekSet);
|
||||
}
|
||||
|
||||
int readByte()
|
||||
{
|
||||
int b = file.read();
|
||||
return b;
|
||||
}
|
||||
|
||||
int readWord()
|
||||
{
|
||||
int b0 = readByte();
|
||||
int b1 = readByte();
|
||||
return (b1 << 8) | b0;
|
||||
}
|
||||
|
||||
int readIntoBuffer(void *buffer, int numberOfBytes)
|
||||
{
|
||||
int result = file.read((uint8_t *)buffer, numberOfBytes);
|
||||
return result;
|
||||
}
|
||||
|
||||
void fillImageDataRect(byte colorIndex, int x, int y, int width, int height)
|
||||
{
|
||||
int yOffset;
|
||||
for (int yy = y; yy < height + y; yy++)
|
||||
{
|
||||
yOffset = yy * WIDTH;
|
||||
for (int xx = x; xx < width + x; xx++)
|
||||
{
|
||||
imageData[yOffset + xx] = colorIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void fillImageData(byte colorIndex)
|
||||
{
|
||||
memset(imageData, colorIndex, sizeof(imageData));
|
||||
}
|
||||
|
||||
void copyImageDataRect(byte *src, byte *dst, int x, int y, int width, int height)
|
||||
{
|
||||
|
||||
int yOffset, offset;
|
||||
|
||||
for (int yy = y; yy < height + y; yy++)
|
||||
{
|
||||
yOffset = yy * WIDTH;
|
||||
for (int xx = x; xx < width + x; xx++)
|
||||
{
|
||||
offset = yOffset + xx;
|
||||
dst[offset] = src[offset];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void parsePlainTextExtension()
|
||||
{
|
||||
byte len = readByte();
|
||||
readIntoBuffer(tempBuffer, len);
|
||||
len = readByte();
|
||||
while (len != 0)
|
||||
{
|
||||
readIntoBuffer(tempBuffer, len);
|
||||
len = readByte();
|
||||
}
|
||||
}
|
||||
|
||||
void parseGraphicControlExtension()
|
||||
{
|
||||
readByte();
|
||||
int packedBits = readByte();
|
||||
frameDelay = readWord();
|
||||
transparentColorIndex = readByte();
|
||||
|
||||
if ((packedBits & TRANSPARENTFLAG) == 0)
|
||||
{
|
||||
// Indicate no transparent index
|
||||
transparentColorIndex = NO_TRANSPARENT_INDEX;
|
||||
}
|
||||
disposalMethod = (packedBits >> 2) & 7;
|
||||
if (disposalMethod > 3)
|
||||
{
|
||||
disposalMethod = 0;
|
||||
}
|
||||
|
||||
readByte(); // Toss block end
|
||||
}
|
||||
|
||||
void parseApplicationExtension()
|
||||
{
|
||||
memset(tempBuffer, 0, sizeof(tempBuffer));
|
||||
byte len = readByte();
|
||||
readIntoBuffer(tempBuffer, len);
|
||||
len = readByte();
|
||||
while (len != 0)
|
||||
{
|
||||
readIntoBuffer(tempBuffer, len);
|
||||
len = readByte();
|
||||
}
|
||||
}
|
||||
|
||||
void parseCommentExtension()
|
||||
{
|
||||
byte len = readByte();
|
||||
while (len != 0)
|
||||
{
|
||||
memset(tempBuffer, 0, sizeof(tempBuffer));
|
||||
readIntoBuffer(tempBuffer, len);
|
||||
len = readByte();
|
||||
}
|
||||
}
|
||||
|
||||
int parseGIFFileTerminator()
|
||||
{
|
||||
byte b = readByte();
|
||||
if (b != 0x3B)
|
||||
{
|
||||
return ERROR_BADGIFFORMAT;
|
||||
}
|
||||
else
|
||||
{
|
||||
return ERROR_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned long parseTableBasedImage()
|
||||
{
|
||||
tbiImageX = readWord();
|
||||
tbiImageY = readWord();
|
||||
tbiWidth = readWord();
|
||||
tbiHeight = readWord();
|
||||
tbiPackedBits = readByte();
|
||||
tbiInterlaced = ((tbiPackedBits & INTERLACEFLAG) != 0);
|
||||
boolean localColorTable = ((tbiPackedBits & COLORTBLFLAG) != 0);
|
||||
if (localColorTable)
|
||||
{
|
||||
int colorBits = ((tbiPackedBits & 7) + 1);
|
||||
colorCount = 1 << colorBits;
|
||||
int colorTableBytes = sizeof(_RGB) * colorCount;
|
||||
readIntoBuffer(gifPalette, colorTableBytes);
|
||||
}
|
||||
|
||||
if (keyFrame)
|
||||
{
|
||||
if (transparentColorIndex == NO_TRANSPARENT_INDEX)
|
||||
{
|
||||
fillImageData(lsdBackgroundIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
fillImageData(transparentColorIndex);
|
||||
}
|
||||
keyFrame = false;
|
||||
|
||||
rectX = 0;
|
||||
rectY = 0;
|
||||
rectWidth = WIDTH;
|
||||
rectHeight = HEIGHT;
|
||||
}
|
||||
|
||||
if ((prevDisposalMethod != DISPOSAL_NONE) && (prevDisposalMethod != DISPOSAL_LEAVE))
|
||||
{
|
||||
// mtx->clear();
|
||||
}
|
||||
|
||||
if (prevDisposalMethod == DISPOSAL_BACKGROUND)
|
||||
{
|
||||
fillImageDataRect(prevBackgroundIndex, rectX, rectY, rectWidth, rectHeight);
|
||||
}
|
||||
else if (prevDisposalMethod == DISPOSAL_RESTORE)
|
||||
{
|
||||
copyImageDataRect(imageDataBU, imageData, rectX, rectY, rectWidth, rectHeight);
|
||||
}
|
||||
prevDisposalMethod = disposalMethod;
|
||||
if (disposalMethod != DISPOSAL_NONE)
|
||||
{
|
||||
rectX = tbiImageX;
|
||||
rectY = tbiImageY;
|
||||
rectWidth = tbiWidth;
|
||||
rectHeight = tbiHeight;
|
||||
if (disposalMethod == DISPOSAL_BACKGROUND)
|
||||
{
|
||||
if (transparentColorIndex != NO_TRANSPARENT_INDEX)
|
||||
{
|
||||
prevBackgroundIndex = transparentColorIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
prevBackgroundIndex = lsdBackgroundIndex;
|
||||
}
|
||||
}
|
||||
else if (disposalMethod == DISPOSAL_RESTORE)
|
||||
{
|
||||
copyImageDataRect(imageData, imageDataBU, rectX, rectY, rectWidth, rectHeight);
|
||||
}
|
||||
}
|
||||
lzwCodeSize = readByte();
|
||||
int offset = 0;
|
||||
int dataBlockSize = readByte();
|
||||
while (dataBlockSize != 0)
|
||||
{
|
||||
backUpStream(1);
|
||||
dataBlockSize++;
|
||||
if (offset + dataBlockSize <= (int)sizeof(lzwImageData))
|
||||
{
|
||||
readIntoBuffer(lzwImageData + offset, dataBlockSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < dataBlockSize; i++)
|
||||
file.read();
|
||||
}
|
||||
|
||||
offset += dataBlockSize;
|
||||
dataBlockSize = readByte();
|
||||
}
|
||||
lzw_decode_init(lzwCodeSize, lzwImageData);
|
||||
decompressAndDisplayFrame();
|
||||
transparentColorIndex = NO_TRANSPARENT_INDEX;
|
||||
disposalMethod = DISPOSAL_NONE;
|
||||
if (frameDelay < 1)
|
||||
{
|
||||
frameDelay = 1;
|
||||
}
|
||||
newframeDelay = frameDelay * 10;
|
||||
return frameDelay * 10;
|
||||
}
|
||||
|
||||
#define LZW_MAXBITS 10
|
||||
#define LZW_SIZTABLE (1 << LZW_MAXBITS)
|
||||
unsigned int mask[17] = {
|
||||
0x0000, 0x0001, 0x0003, 0x0007,
|
||||
0x000F, 0x001F, 0x003F, 0x007F,
|
||||
0x00FF, 0x01FF, 0x03FF, 0x07FF,
|
||||
0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF,
|
||||
0xFFFF};
|
||||
|
||||
byte *pbuf;
|
||||
int bbits;
|
||||
int bbuf;
|
||||
int cursize; // The current code size
|
||||
int curmask;
|
||||
int codesize;
|
||||
int clear_code;
|
||||
int end_code;
|
||||
int newcodes; // First available code
|
||||
int top_slot; // Highest code for current size
|
||||
int extra_slot;
|
||||
int slot; // Last read code
|
||||
int fc, oc;
|
||||
int bs; // Current buffer size for GIF
|
||||
byte *sp;
|
||||
byte stack[LZW_SIZTABLE];
|
||||
byte suffix[LZW_SIZTABLE];
|
||||
unsigned int prefix[LZW_SIZTABLE];
|
||||
|
||||
void lzw_decode_init(int csize, byte *buf)
|
||||
{
|
||||
pbuf = buf;
|
||||
bbuf = 0;
|
||||
bbits = 0;
|
||||
bs = 0;
|
||||
codesize = csize;
|
||||
cursize = codesize + 1;
|
||||
curmask = mask[cursize];
|
||||
top_slot = 1 << cursize;
|
||||
clear_code = 1 << codesize;
|
||||
end_code = clear_code + 1;
|
||||
slot = newcodes = clear_code + 2;
|
||||
oc = fc = -1;
|
||||
sp = stack;
|
||||
}
|
||||
|
||||
int lzw_get_code()
|
||||
{
|
||||
while (bbits < cursize)
|
||||
{
|
||||
if (!bs)
|
||||
{
|
||||
bs = *pbuf++;
|
||||
}
|
||||
bbuf |= (*pbuf++) << bbits;
|
||||
bbits += 8;
|
||||
bs--;
|
||||
}
|
||||
int c = bbuf;
|
||||
bbuf >>= cursize;
|
||||
bbits -= cursize;
|
||||
return c & curmask;
|
||||
}
|
||||
|
||||
int lzw_decode(byte *buf, int len)
|
||||
{
|
||||
int l, c, code;
|
||||
|
||||
if (end_code < 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
l = len;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
while (sp > stack)
|
||||
{
|
||||
*buf++ = *(--sp);
|
||||
if ((--l) == 0)
|
||||
{
|
||||
goto the_end;
|
||||
}
|
||||
}
|
||||
c = lzw_get_code();
|
||||
if (c == end_code)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if (c == clear_code)
|
||||
{
|
||||
cursize = codesize + 1;
|
||||
curmask = mask[cursize];
|
||||
slot = newcodes;
|
||||
top_slot = 1 << cursize;
|
||||
fc = oc = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
code = c;
|
||||
if ((code == slot) && (fc >= 0))
|
||||
{
|
||||
*sp++ = fc;
|
||||
code = oc;
|
||||
}
|
||||
else if (code >= slot)
|
||||
{
|
||||
break;
|
||||
}
|
||||
while (code >= newcodes)
|
||||
{
|
||||
*sp++ = suffix[code];
|
||||
code = prefix[code];
|
||||
}
|
||||
*sp++ = code;
|
||||
if ((slot < top_slot) && (oc >= 0))
|
||||
{
|
||||
suffix[slot] = code;
|
||||
prefix[slot++] = oc;
|
||||
}
|
||||
fc = code;
|
||||
oc = c;
|
||||
if (slot >= top_slot)
|
||||
{
|
||||
if (cursize < LZW_MAXBITS)
|
||||
{
|
||||
top_slot <<= 1;
|
||||
curmask = mask[++cursize];
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
end_code = -1;
|
||||
the_end:
|
||||
return len - l;
|
||||
}
|
||||
|
||||
void redrawLastFrame()
|
||||
{
|
||||
if (needNewFrame)
|
||||
return;
|
||||
CRGB color;
|
||||
int yOffset, pixel;
|
||||
for (int y = tbiImageY; y < tbiHeight + tbiImageY; y++)
|
||||
{
|
||||
yOffset = y * WIDTH;
|
||||
for (int x = tbiImageX; x < tbiWidth + tbiImageX; x++)
|
||||
{
|
||||
pixel = lastFrame[yOffset + x];
|
||||
if (pixel == -99)
|
||||
{
|
||||
mtx->drawPixel(x + offsetX, y + offsetY, mtx->Color(0, 0, 0));
|
||||
continue;
|
||||
}
|
||||
color.red = gifPalette[pixel].Red;
|
||||
color.green = gifPalette[pixel].Green;
|
||||
color.blue = gifPalette[pixel].Blue;
|
||||
mtx->drawPixel(x + offsetX, y + offsetY, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void decompressAndDisplayFrame()
|
||||
{
|
||||
CRGB color;
|
||||
if (tbiInterlaced)
|
||||
{
|
||||
for (int line = tbiImageY + 0; line < tbiHeight + tbiImageY; line += 8)
|
||||
{
|
||||
lzw_decode(imageData + (line * WIDTH) + tbiImageX, tbiWidth);
|
||||
}
|
||||
for (int line = tbiImageY + 4; line < tbiHeight + tbiImageY; line += 8)
|
||||
{
|
||||
lzw_decode(imageData + (line * WIDTH) + tbiImageX, tbiWidth);
|
||||
}
|
||||
for (int line = tbiImageY + 2; line < tbiHeight + tbiImageY; line += 4)
|
||||
{
|
||||
lzw_decode(imageData + (line * WIDTH) + tbiImageX, tbiWidth);
|
||||
}
|
||||
for (int line = tbiImageY + 1; line < tbiHeight + tbiImageY; line += 2)
|
||||
{
|
||||
lzw_decode(imageData + (line * WIDTH) + tbiImageX, tbiWidth);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int line = tbiImageY; line < tbiHeight + tbiImageY; line++)
|
||||
{
|
||||
lzw_decode(imageData + (line * WIDTH) + tbiImageX, tbiWidth);
|
||||
}
|
||||
}
|
||||
|
||||
// Ersetze alle transparenten Pixel durch schwarze Pixel
|
||||
for (int i = 0; i < tbiWidth * tbiHeight; i++)
|
||||
{
|
||||
if (imageData[i] == transparentColorIndex)
|
||||
{
|
||||
imageData[i] = -99; // Indexwert für Schwarz
|
||||
}
|
||||
}
|
||||
|
||||
int pixel, yOffset;
|
||||
for (int y = tbiImageY; y < tbiHeight + tbiImageY; y++)
|
||||
{
|
||||
yOffset = y * WIDTH;
|
||||
for (int x = tbiImageX; x < tbiWidth + tbiImageX; x++)
|
||||
{
|
||||
pixel = imageData[yOffset + x];
|
||||
if (pixel == transparentColorIndex) // Check if the pixel index is the transparent index
|
||||
{
|
||||
mtx->drawPixel(x + offsetX, y + offsetY, mtx->Color(0, 0, 0)); // Draw a black pixel
|
||||
lastFrame[yOffset + x] = -99; // Save it as a special value
|
||||
}
|
||||
else
|
||||
{
|
||||
color.red = gifPalette[pixel].Red;
|
||||
color.green = gifPalette[pixel].Green;
|
||||
color.blue = gifPalette[pixel].Blue;
|
||||
mtx->drawPixel(x + offsetX, y + offsetY, color);
|
||||
lastFrame[yOffset + x] = pixel;
|
||||
}
|
||||
}
|
||||
}
|
||||
needNewFrame = false;
|
||||
lastFrameTime = millis();
|
||||
}
|
||||
|
||||
public:
|
||||
void setMatrix(FastLED_NeoMatrix *matrix)
|
||||
{
|
||||
mtx = matrix;
|
||||
}
|
||||
void setFile(File imageFile)
|
||||
{
|
||||
if (imageFile.name() == file.name())
|
||||
return;
|
||||
|
||||
needNewFrame = true;
|
||||
file = imageFile;
|
||||
memset(lastFrame, 0, sizeof(lastFrame));
|
||||
memset(gifPalette, 0, sizeof(gifPalette));
|
||||
memset(lzwImageData, 0, sizeof(lzwImageData));
|
||||
memset(imageData, 0, sizeof(imageData));
|
||||
memset(imageDataBU, 0, sizeof(imageDataBU));
|
||||
memset(stack, 0, sizeof(stack));
|
||||
memset(suffix, 0, sizeof(suffix));
|
||||
memset(prefix, 0, sizeof(prefix));
|
||||
parseGifHeader();
|
||||
parseLogicalScreenDescriptor();
|
||||
parseGlobalColorTable();
|
||||
drawFrame(offsetX, offsetY);
|
||||
}
|
||||
|
||||
boolean parseGifHeader()
|
||||
{
|
||||
char buffer[10];
|
||||
readIntoBuffer(buffer, GIFHDRSIZE);
|
||||
if ((strncmp(buffer, GIFHDRTAGNORM, GIFHDRSIZE) != 0) &&
|
||||
(strncmp(buffer, GIFHDRTAGNORM1, GIFHDRSIZE) != 0))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void parseLogicalScreenDescriptor()
|
||||
{
|
||||
lsdWidth = readWord();
|
||||
lsdHeight = readWord();
|
||||
lsdPackedField = readByte();
|
||||
lsdBackgroundIndex = readByte();
|
||||
lsdAspectRatio = readByte();
|
||||
}
|
||||
|
||||
void parseGlobalColorTable()
|
||||
{
|
||||
if (lsdPackedField & COLORTBLFLAG)
|
||||
{
|
||||
colorCount = 1 << ((lsdPackedField & 7) + 1);
|
||||
int colorTableBytes = sizeof(_RGB) * colorCount;
|
||||
readIntoBuffer(gifPalette, colorTableBytes);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned long drawFrame(int x, int y)
|
||||
{
|
||||
offsetX = x;
|
||||
offsetY = y;
|
||||
if (!file)
|
||||
return 0;
|
||||
|
||||
if (millis() - lastFrameTime < newframeDelay)
|
||||
{
|
||||
redrawLastFrame();
|
||||
return 0;
|
||||
}
|
||||
|
||||
lastFrameDrawn = false;
|
||||
|
||||
boolean done = false;
|
||||
while (!done)
|
||||
{
|
||||
byte b = readByte();
|
||||
if (b == 0x2c)
|
||||
{
|
||||
parseTableBasedImage();
|
||||
return 0;
|
||||
}
|
||||
else if (b == 0x21)
|
||||
{
|
||||
b = readByte();
|
||||
switch (b)
|
||||
{
|
||||
case 0x01:
|
||||
parsePlainTextExtension();
|
||||
break;
|
||||
case 0xf9:
|
||||
parseGraphicControlExtension();
|
||||
break;
|
||||
case 0xfe:
|
||||
parseCommentExtension();
|
||||
break;
|
||||
case 0xff:
|
||||
parseApplicationExtension();
|
||||
break;
|
||||
default:
|
||||
return ERROR_UNKNOWNCONTROLEXT;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
done = true;
|
||||
file.seek(0);
|
||||
parseGifHeader();
|
||||
parseLogicalScreenDescriptor();
|
||||
parseGlobalColorTable();
|
||||
drawFrame(offsetX, offsetY);
|
||||
return ERROR_FINISHED;
|
||||
}
|
||||
}
|
||||
return ERROR_NONE;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
@@ -37,7 +37,6 @@
|
||||
#include "ServerManager.h"
|
||||
#include "Globals.h"
|
||||
#include "UpdateManager.h"
|
||||
#include "BeaconScanner.h"
|
||||
|
||||
TaskHandle_t taskHandle;
|
||||
volatile bool StopTask = false;
|
||||
@@ -85,7 +84,7 @@ void setup()
|
||||
DisplayManager.HSVtext(x, 6, ("AWTRIX " + ServerManager.myIP.toString()).c_str(), true, 0);
|
||||
x -= 0.18;
|
||||
}
|
||||
BeaconScanner.setup();
|
||||
// BeaconScanner.setup();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -94,6 +93,7 @@ void setup()
|
||||
}
|
||||
|
||||
delay(200);
|
||||
DisplayManager.setBrightness(BRIGHTNESS);
|
||||
DisplayManager.clearMatrix();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user