add beaconScanner
This commit is contained in:
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@@ -47,6 +47,7 @@
|
||||
"stdexcept": "cpp",
|
||||
"streambuf": "cpp",
|
||||
"cinttypes": "cpp",
|
||||
"typeinfo": "cpp"
|
||||
"typeinfo": "cpp",
|
||||
"tjpgd.h": "c"
|
||||
}
|
||||
}
|
||||
@@ -220,7 +220,7 @@ void MatrixDisplayUi::tick()
|
||||
if (this->AppCount > 0)
|
||||
this->drawApp();
|
||||
this->drawOverlays();
|
||||
this->matrix->show();
|
||||
//this->matrix->show();
|
||||
}
|
||||
|
||||
void MatrixDisplayUi::drawApp()
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
#define HADEVICE_INIT \
|
||||
_ownsUniqueId(false), \
|
||||
_serializer(new HASerializer(nullptr, 5)), \
|
||||
_serializer(new HASerializer(nullptr, 6)), \
|
||||
_availabilityTopic(nullptr), \
|
||||
_sharedAvailability(false), \
|
||||
_available(true) // device will be available by default
|
||||
@@ -68,6 +68,11 @@ void HADevice::setModel(const char* model)
|
||||
_serializer->set(AHATOFSTR(HADeviceModelProperty), model);
|
||||
}
|
||||
|
||||
void HADevice::setURL(const char* url)
|
||||
{
|
||||
_serializer->set(AHATOFSTR(HAIPProperty), url);
|
||||
}
|
||||
|
||||
void HADevice::setName(const char* name)
|
||||
{
|
||||
_serializer->set(AHATOFSTR(HANameProperty), name);
|
||||
|
||||
@@ -45,33 +45,43 @@ public:
|
||||
* Returns pointer to the unique ID. It can be nullptr if the device has no ID assigned.
|
||||
*/
|
||||
inline const char *getUniqueId() const
|
||||
{ return _uniqueId; }
|
||||
{
|
||||
return _uniqueId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the instance of the HASerializer used by the device.
|
||||
* This method is used by all entities to serialize device's representation.
|
||||
*/
|
||||
inline const HASerializer *getSerializer() const
|
||||
{ return _serializer; }
|
||||
{
|
||||
return _serializer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the shared availability is enabled for the device.
|
||||
*/
|
||||
inline bool isSharedAvailabilityEnabled() const
|
||||
{ return _sharedAvailability; }
|
||||
{
|
||||
return _sharedAvailability;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns availability topic generated by the HADevice::enableSharedAvailability method.
|
||||
* It can be nullptr if the shared availability is not enabled.
|
||||
*/
|
||||
inline const char *getAvailabilityTopic() const
|
||||
{ return _availabilityTopic; }
|
||||
{
|
||||
return _availabilityTopic;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns online/offline state of the device.
|
||||
*/
|
||||
inline bool isAvailable() const
|
||||
{ return _available; }
|
||||
{
|
||||
return _available;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets unique ID of the device based on the given byte array.
|
||||
@@ -97,6 +107,7 @@ public:
|
||||
*/
|
||||
void setModel(const char *model);
|
||||
|
||||
void setURL(const char *url);
|
||||
/**
|
||||
* Sets the "name" property that's going to be displayed in the Home Assistant.
|
||||
*
|
||||
|
||||
@@ -37,6 +37,7 @@ const char HADeviceManufacturerProperty[] PROGMEM = {"mf"};
|
||||
const char HADeviceModelProperty[] PROGMEM = {"mdl"};
|
||||
const char HADeviceSoftwareVersionProperty[] PROGMEM = {"sw"};
|
||||
const char HANameProperty[] PROGMEM = {"name"};
|
||||
const char HAIPProperty[] PROGMEM = {"cu"};
|
||||
const char HAUniqueIdProperty[] PROGMEM = {"uniq_id"};
|
||||
const char HADeviceProperty[] PROGMEM = {"dev"};
|
||||
const char HADeviceClassProperty[] PROGMEM = {"dev_cla"};
|
||||
|
||||
@@ -35,6 +35,7 @@ extern const char HASerializerUnderscore[];
|
||||
extern const char HADeviceIdentifiersProperty[];
|
||||
extern const char HADeviceManufacturerProperty[];
|
||||
extern const char HADeviceModelProperty[];
|
||||
extern const char HAIPProperty[];
|
||||
extern const char HADeviceSoftwareVersionProperty[];
|
||||
extern const char HANameProperty[];
|
||||
extern const char HAUniqueIdProperty[];
|
||||
|
||||
@@ -199,7 +199,6 @@
|
||||
}
|
||||
|
||||
#preview img {
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
image-rendering: pixelated;
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ board = esp32dev
|
||||
board_build.partitions = awtrix_partition.csv
|
||||
upload_speed = 921600
|
||||
framework = arduino
|
||||
monitor_speed = 115200
|
||||
build_flags = -DULANZI -D MQTT_MAX_PACKET_SIZE=1024
|
||||
lib_deps =
|
||||
adafruit/Adafruit SHT31 Library@^2.2.0
|
||||
@@ -23,12 +24,14 @@ lib_deps =
|
||||
marcmerlin/FastLED NeoMatrix@^1.2
|
||||
knolleary/PubSubClient@^2.8
|
||||
plerup/EspSoftwareSerial@^8.0.1
|
||||
h2zero/NimBLE-Arduino@^1.4.1
|
||||
|
||||
[env:awtrix_upgrade]
|
||||
platform = https://github.com/platformio/platform-espressif32.git
|
||||
board = wemos_d1_mini32
|
||||
board_build.partitions = awtrix_partition.csv
|
||||
upload_speed = 921600
|
||||
monitor_speed = 115200
|
||||
framework = arduino
|
||||
build_flags = -DAWTRIX_UPGRADE -D MQTT_MAX_PACKET_SIZE=1024
|
||||
lib_deps =
|
||||
@@ -39,3 +42,4 @@ lib_deps =
|
||||
marcmerlin/FastLED NeoMatrix@^1.2
|
||||
knolleary/PubSubClient@^2.8
|
||||
plerup/EspSoftwareSerial@^8.0.1
|
||||
h2zero/NimBLE-Arduino@^1.4.1
|
||||
|
||||
289
src/BeaconScanner.cpp
Normal file
289
src/BeaconScanner.cpp
Normal file
@@ -0,0 +1,289 @@
|
||||
#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("laodSettings");
|
||||
File file = LittleFS.open("/beacons.json", "r");
|
||||
if (!file)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
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();
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
18
src/BeaconScanner.h
Normal file
18
src/BeaconScanner.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#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
|
||||
@@ -26,9 +26,9 @@ Ticker TimerTicker;
|
||||
|
||||
#define MATRIX_WIDTH 32
|
||||
#define MATRIX_HEIGHT 8
|
||||
|
||||
fs::File gifFile;
|
||||
GifPlayer gif;
|
||||
|
||||
bool showGif;
|
||||
CRGB leds[MATRIX_WIDTH * MATRIX_HEIGHT];
|
||||
FastLED_NeoMatrix matrix(leds, 32, 8, NEO_MATRIX_TOP + NEO_MATRIX_LEFT + NEO_MATRIX_ROWS + NEO_MATRIX_ZIGZAG);
|
||||
|
||||
@@ -90,10 +90,11 @@ bool DisplayManager_::setAutoTransition(bool active)
|
||||
}
|
||||
}
|
||||
|
||||
void DisplayManager_::drawGIF(uint16_t x, uint16_t y, fs::File gifFile)
|
||||
void DisplayManager_::drawGIF(uint16_t x, uint16_t y, fs::File gFile)
|
||||
{
|
||||
gif.setFile(gifFile);
|
||||
gif.drawFrame(x, y);
|
||||
gif.setFile(gFile);
|
||||
if (!showGif)
|
||||
showGif = true;
|
||||
}
|
||||
|
||||
void DisplayManager_::drawJPG(uint16_t x, uint16_t y, fs::File jpgFile)
|
||||
@@ -129,6 +130,7 @@ void DisplayManager_::clearMatrix()
|
||||
|
||||
bool jpg_output(int16_t x, int16_t y, uint16_t w, uint16_t h, uint16_t *bitmap)
|
||||
{
|
||||
|
||||
uint16_t bitmapIndex = 0;
|
||||
|
||||
for (uint16_t row = 0; row < h; row++)
|
||||
@@ -244,6 +246,7 @@ void removeCustomApp(const String &name)
|
||||
|
||||
void DisplayManager_::generateCustomPage(String name, const char *json)
|
||||
{
|
||||
|
||||
if (strcmp(json, "") == 0 && customApps.count(name))
|
||||
{
|
||||
Serial.println("delete");
|
||||
@@ -252,6 +255,8 @@ void DisplayManager_::generateCustomPage(String name, const char *json)
|
||||
return;
|
||||
}
|
||||
|
||||
Serial.printf("Appname %s", name);
|
||||
|
||||
DynamicJsonDocument doc(1024);
|
||||
DeserializationError error = deserializeJson(doc, json);
|
||||
if (error)
|
||||
@@ -516,6 +521,7 @@ void DisplayManager_::setup()
|
||||
{
|
||||
|
||||
TJpgDec.setCallback(jpg_output);
|
||||
TJpgDec.setJpgScale(1);
|
||||
FastLED.addLeds<NEOPIXEL, MATRIX_PIN>(leds, MATRIX_WIDTH * MATRIX_HEIGHT);
|
||||
gif.setMatrix(&matrix);
|
||||
ui.setAppAnimation(SLIDE_DOWN);
|
||||
@@ -524,6 +530,10 @@ void DisplayManager_::setup()
|
||||
ui.init();
|
||||
}
|
||||
|
||||
void ShowGif()
|
||||
{
|
||||
}
|
||||
|
||||
void DisplayManager_::tick()
|
||||
{
|
||||
if (AP_MODE)
|
||||
@@ -532,9 +542,11 @@ void DisplayManager_::tick()
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
if (ui.getUiState()->appState == IN_TRANSITION && !appIsSwitching)
|
||||
{
|
||||
appIsSwitching = true;
|
||||
showGif = false;
|
||||
}
|
||||
else if (ui.getUiState()->appState == FIXED && appIsSwitching)
|
||||
{
|
||||
@@ -542,7 +554,11 @@ void DisplayManager_::tick()
|
||||
MQTTManager.setCurrentApp(CURRENT_APP);
|
||||
setAppTime(TIME_PER_APP);
|
||||
}
|
||||
ui.update();
|
||||
int remainingTimeBudget = ui.update();
|
||||
|
||||
if (showGif)
|
||||
gif.drawFrame(0, 0);
|
||||
matrix.show();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -896,6 +912,7 @@ String DisplayManager_::getStat()
|
||||
snprintf(buffer, 5, "%.0f", CURRENT_LUX);
|
||||
doc[LuxKey] = buffer;
|
||||
doc[LDRRawKey] = LDR_RAW;
|
||||
doc["ram"] = ESP.getFreeHeap();
|
||||
doc[BrightnessKey] = BRIGHTNESS;
|
||||
snprintf(buffer, 5, "%.0f", CURRENT_TEMP);
|
||||
doc[TempKey] = buffer;
|
||||
|
||||
@@ -10,12 +10,14 @@ public:
|
||||
#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[8 * 8];
|
||||
int lastFrame[WIDTH * HEIGHT];
|
||||
bool lastFrameDrawn = false;
|
||||
unsigned long nextFrameTime = 0;
|
||||
#define GIFHDRTAGNORM "GIF87a"
|
||||
@@ -30,6 +32,7 @@ private:
|
||||
#define DISPOSAL_LEAVE 1
|
||||
#define DISPOSAL_BACKGROUND 2
|
||||
#define DISPOSAL_RESTORE 3
|
||||
|
||||
typedef struct
|
||||
{
|
||||
byte Red;
|
||||
@@ -67,8 +70,8 @@ public:
|
||||
byte lzwImageData[1280];
|
||||
char tempBuffer[260];
|
||||
File file;
|
||||
byte imageData[8 * 8];
|
||||
byte imageDataBU[8 * 8];
|
||||
byte imageData[WIDTH * HEIGHT];
|
||||
byte imageDataBU[WIDTH * HEIGHT];
|
||||
|
||||
void backUpStream(int n)
|
||||
{
|
||||
@@ -99,7 +102,7 @@ public:
|
||||
int yOffset;
|
||||
for (int yy = y; yy < height + y; yy++)
|
||||
{
|
||||
yOffset = yy * 8;
|
||||
yOffset = yy * WIDTH;
|
||||
for (int xx = x; xx < width + x; xx++)
|
||||
{
|
||||
imageData[yOffset + xx] = colorIndex;
|
||||
@@ -119,7 +122,7 @@ public:
|
||||
|
||||
for (int yy = y; yy < height + y; yy++)
|
||||
{
|
||||
yOffset = yy * 8;
|
||||
yOffset = yy * WIDTH;
|
||||
for (int xx = x; xx < width + x; xx++)
|
||||
{
|
||||
offset = yOffset + xx;
|
||||
@@ -229,8 +232,8 @@ public:
|
||||
|
||||
rectX = 0;
|
||||
rectY = 0;
|
||||
rectWidth = 8;
|
||||
rectHeight = 8;
|
||||
rectWidth = WIDTH;
|
||||
rectHeight = HEIGHT;
|
||||
}
|
||||
|
||||
if ((prevDisposalMethod != DISPOSAL_NONE) && (prevDisposalMethod != DISPOSAL_LEAVE))
|
||||
@@ -450,7 +453,7 @@ public:
|
||||
int yOffset, pixel;
|
||||
for (int y = tbiImageY; y < tbiHeight + tbiImageY; y++)
|
||||
{
|
||||
yOffset = y * 8;
|
||||
yOffset = y * WIDTH;
|
||||
for (int x = tbiImageX; x < tbiWidth + tbiImageX; x++)
|
||||
{
|
||||
pixel = lastFrame[yOffset + x];
|
||||
@@ -474,26 +477,26 @@ public:
|
||||
{
|
||||
for (int line = tbiImageY + 0; line < tbiHeight + tbiImageY; line += 8)
|
||||
{
|
||||
lzw_decode(imageData + (line * 8) + tbiImageX, tbiWidth);
|
||||
lzw_decode(imageData + (line * WIDTH) + tbiImageX, tbiWidth);
|
||||
}
|
||||
for (int line = tbiImageY + 4; line < tbiHeight + tbiImageY; line += 8)
|
||||
{
|
||||
lzw_decode(imageData + (line * 8) + tbiImageX, tbiWidth);
|
||||
lzw_decode(imageData + (line * WIDTH) + tbiImageX, tbiWidth);
|
||||
}
|
||||
for (int line = tbiImageY + 2; line < tbiHeight + tbiImageY; line += 4)
|
||||
{
|
||||
lzw_decode(imageData + (line * 8) + tbiImageX, tbiWidth);
|
||||
lzw_decode(imageData + (line * WIDTH) + tbiImageX, tbiWidth);
|
||||
}
|
||||
for (int line = tbiImageY + 1; line < tbiHeight + tbiImageY; line += 2)
|
||||
{
|
||||
lzw_decode(imageData + (line * 8) + tbiImageX, tbiWidth);
|
||||
lzw_decode(imageData + (line * WIDTH) + tbiImageX, tbiWidth);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int line = tbiImageY; line < tbiHeight + tbiImageY; line++)
|
||||
{
|
||||
lzw_decode(imageData + (line * 8) + tbiImageX, tbiWidth);
|
||||
lzw_decode(imageData + (line * WIDTH) + tbiImageX, tbiWidth);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -510,7 +513,7 @@ public:
|
||||
int yOffset, pixel;
|
||||
for (int y = tbiImageY; y < tbiHeight + tbiImageY; y++)
|
||||
{
|
||||
yOffset = y * 8;
|
||||
yOffset = y * WIDTH;
|
||||
for (int x = tbiImageX; x < tbiWidth + tbiImageX; x++)
|
||||
{
|
||||
pixel = imageData[yOffset + x];
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
WiFiClient espClient;
|
||||
uint8_t lastBrightness;
|
||||
HADevice device;
|
||||
HAMqtt mqtt(espClient, device, 19);
|
||||
HAMqtt mqtt(espClient, device, 21);
|
||||
|
||||
unsigned long reconnectTimer = 0;
|
||||
const unsigned long reconnectInterval = 30000; // 30 Sekunden
|
||||
@@ -262,6 +262,9 @@ void MQTTManager_::setup()
|
||||
device.setSoftwareVersion(VERSION);
|
||||
device.setManufacturer(HAmanufacturer);
|
||||
device.setModel(HAmodel);
|
||||
char url[50];
|
||||
snprintf(url, sizeof(url), "http://%s", WiFi.localIP().toString().c_str());
|
||||
device.setURL("http://192.168.178.102");
|
||||
device.setAvailability(true);
|
||||
device.enableSharedAvailability();
|
||||
device.enableLastWill();
|
||||
|
||||
@@ -268,7 +268,7 @@ void PeripheryManager_::tick()
|
||||
CURRENT_TEMP = bme280.readTemperature();
|
||||
CURRENT_HUM = bme280.readHumidity();
|
||||
#endif
|
||||
checkAlarms();
|
||||
//checkAlarms();
|
||||
MQTTManager.sendStats();
|
||||
}
|
||||
|
||||
|
||||
@@ -36,6 +36,8 @@
|
||||
#include "MQTTManager.h"
|
||||
#include "ServerManager.h"
|
||||
#include "Globals.h"
|
||||
#include "UpdateManager.h"
|
||||
#include "BeaconScanner.h"
|
||||
|
||||
TaskHandle_t taskHandle;
|
||||
volatile bool StopTask = false;
|
||||
@@ -58,8 +60,8 @@ void BootAnimation(void *parameter)
|
||||
void setup()
|
||||
{
|
||||
PeripheryManager.setup();
|
||||
delay(500);
|
||||
Serial.begin(9600);
|
||||
delay(1000);
|
||||
Serial.begin(115200);
|
||||
loadSettings();
|
||||
ServerManager.loadSettings();
|
||||
DisplayManager.setup();
|
||||
@@ -80,6 +82,7 @@ void setup()
|
||||
DisplayManager.HSVtext(x, 6, ("AWTRIX " + ServerManager.myIP.toString()).c_str(), true);
|
||||
x -= 0.18;
|
||||
}
|
||||
BeaconScanner.setup();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user