- Adds notification indicators
- Adds the possibility to modify the [color correction](https://blueforcer.github.io/awtrix-light/#/dev) 
- Adds the possibility to turn the Matrix on and off via MQTT or HTTP
This commit is contained in:
Stephan Mühl
2023-04-10 18:32:23 +02:00
committed by GitHub
15 changed files with 433 additions and 52 deletions

View File

@@ -1,25 +1,41 @@
# MQTT / HTTP API
## Status
In MQTT awtrix send its stats every 10s to `[PREFIX]/stats`
With HTTP, make GET request to `http://[IP]/api/stats`
## Update
Awtrix searches for an update every 1 Hour. If a new one is found it will be published to HA and in the stats.
You can start the update with update button in HA or:
## Turn display on or off
| Topic | URL | Payload/Body | HTTP Header | HTTP method |
| --- | --- | --- | --- | --- |
| `[PREFIX]/doupdate` |`http://[IP]/api/doupdate` | JSON | empty payload/body | POST |
| Topic | URL | Payload/Body | HTTP method |
| --- | --- | --- | --- |
| `[PREFIX]/power` | `http://[IP]/api/power` | `{"state":value}` | POST |
Valid values are:
- `0` => off
- `1` => on
## Colored indicators
A colored indicator is like a small notification sign wich will be shown on the upper right or lower right corner.
| Topic | URL | Payload/Body | HTTP method |
| --- | --- | --- | --- |
| `[PREFIX]/indicator1` | `http://[IP]/api/indicator1` | `{"color":[255,0,0]}` | POST |
| `[PREFIX]/indicator2` | `http://[IP]/api/indicator2` | `{"color":[0,255,0]}` | POST |
Instead of a RGB array you can also sent HEX color strings like `{"color":"#32a852"}`
Send the color black `{"color":[0,0,0]}` or `{"color":"0"}` to hide the indicators.
Optionally you can make the indicator blinking by adding the key `"blink":true/false`.
## Custom Apps and Notifications
With AWTRIX Light, you can create custom apps or notifications to display your own text and icons.
With MQTT simply send a JSON object to the topic `[PREFIX]/custom/[page]` where [page] is a the name of your page (without spaces).
With the [HTTP API](api?id=add-custom-app) you have to set the appname in the request header (`name = Appname`)
With MQTT simply send a JSON object to the topic `[PREFIX]/custom/[app]` where [app] is a the name of your app (without spaces).
With the HTTP API you have to set the appname in the request header (`name = [appname]`)
You can also send a one-time notification with the same JSON format. Simply send your JSON object to `[PREFIX]/notify` or `http://[IP]/api/notify`.
| Topic | URL | Payload/Body | Query parameters | HTTP method |
| --- | --- | --- | --- | --- |
@@ -43,14 +59,14 @@ The JSON object has the following properties:
| `sound` | string | The filename of your RTTTL ringtone file (without extension). | |
| `pushIcon` | number | 0 = Icon doesn't move. 1 = Icon moves with text and will not appear again. 2 = Icon moves with text but appears again when the text starts to scroll again. | 0 |
| `bar` | array of integers | draws a bargraph. Without icon maximum 16 values, with icon 11 values | |
| `textCase` | integer | Changes teh Uppercase setting. 0=global setting, 1=forces uppercase; 2=shows what is sent. | 0 |
| `textCase` | integer | Changes the Uppercase setting. 0=global setting, 1=forces uppercase; 2=shows as it sent. | 0 |
All keys are optional, so you can send just the properties you want to use.
To update a custom page, simply send a modified JSON object to the same topic. The display will be updated immediately.
You can also send a one-time notification with the same JSON format. Simply send your JSON object to "awtrixlight/notify".
### Example
@@ -222,7 +238,7 @@ The JSON object has the following properties:
Each value is optional, so you can set a timer for just minutes, or any combination of hours, minutes, and seconds. If you only want to start a timer in some minutes, just send the minutes.
## Example
#### Example
Here's an example JSON object to start a timer for 1 hour, 30 minutes, and 10 seconds, with the sound "friends":
@@ -235,3 +251,10 @@ Here's an example JSON object to start a timer for 1 hour, 30 minutes, and 10 se
}
```
## Update
Awtrix searches for an update every 1 Hour. If a new one is found it will be published to HA and in the stats.
You can start the update with update button in HA or:
| Topic | URL | Payload/Body | HTTP Header | HTTP method |
| --- | --- | --- | --- | --- |
| `[PREFIX]/doupdate` |`http://[IP]/api/doupdate` | JSON | empty payload/body | POST |

View File

@@ -12,5 +12,6 @@ The JSON object has the following properties:
| Key | Type | Description | Default |
| --- | ---- | ----------- | ------- |
| `bootsound` | string | Uses a custom melodie while booting | |
| `uppercase` | boolean | Print every character in uppercase | true |
| `temp_dec_places` | int | Number of decimal places for temperature measurements | 0 |
| `uppercase` | boolean | Print every character in uppercase | `true` |
| `temp_dec_places` | int | Number of decimal places for temperature measurements | `0` |
| `color_correction` | array of int | Sets the colorcorrection of the matrix | `[255,255,255]` |

View File

@@ -30,8 +30,8 @@
#include "MatrixDisplayUi.h"
#include "Fonts/AwtrixFont.h"
GifPlayer gif1;
GifPlayer gif2;
GifPlayer gif1;
GifPlayer gif2;
MatrixDisplayUi::MatrixDisplayUi(FastLED_NeoMatrix *matrix)
{
@@ -223,12 +223,44 @@ void MatrixDisplayUi::tick()
}
this->matrix->clear();
if (this->AppCount > 0)
this->drawApp();
this->drawOverlays();
this->drawIndicators();
this->matrix->show();
}
void MatrixDisplayUi::drawIndicators()
{
if (indicator1State && !indicator1Blink)
{
matrix->drawPixel(31, 0, indicator1Color);
matrix->drawPixel(30, 0, indicator1Color);
matrix->drawPixel(31, 1, indicator1Color);
}
if (indicator2State && !indicator2Blink)
{
matrix->drawPixel(31, 7, indicator2Color);
matrix->drawPixel(31, 6, indicator2Color);
matrix->drawPixel(30, 7, indicator2Color);
}
if (indicator1State && indicator1Blink && (millis() % 1000) < 500)
{
matrix->drawPixel(31, 0, indicator1Color);
matrix->drawPixel(30, 0, indicator1Color);
matrix->drawPixel(31, 1, indicator1Color);
}
if (indicator2State && indicator2Blink && (millis() % 1000) < 500)
{
matrix->drawPixel(31, 7, indicator2Color);
matrix->drawPixel(31, 6, indicator2Color);
matrix->drawPixel(30, 7, indicator2Color);
}
}
void MatrixDisplayUi::drawApp()
{
switch (this->state.appState)
@@ -293,3 +325,33 @@ uint8_t MatrixDisplayUi::getnextAppNumber()
return this->nextAppNumber;
return (this->state.currentApp + this->AppCount + this->state.appTransitionDirection) % this->AppCount;
}
void MatrixDisplayUi::setIndicator1Color(uint16_t color)
{
this->indicator1Color = color;
}
void MatrixDisplayUi::setIndicator1State(bool state)
{
this->indicator1State = state;
}
void MatrixDisplayUi::setIndicator2Color(uint16_t color)
{
this->indicator2Color = color;
}
void MatrixDisplayUi::setIndicator2State(bool state)
{
this->indicator2State = state;
}
void MatrixDisplayUi::setIndicator1Blink(bool blink)
{
this->indicator1Blink = blink;
}
void MatrixDisplayUi::setIndicator2Blink(bool blink)
{
this->indicator2Blink = blink;
}

View File

@@ -77,7 +77,6 @@ class MatrixDisplayUi
private:
FastLED_NeoMatrix *matrix;
// Values for the Apps
AnimationDirection appAnimationDirection = SLIDE_DOWN;
int8_t lastTransitionDirection = 1;
@@ -102,6 +101,14 @@ private:
// Bookeeping for update
uint8_t updateInterval = 33;
uint16_t indicator1Color = 63488;
uint16_t indicator2Color = 31;
bool indicator1State = false;
bool indicator2State = false;
bool indicator1Blink = false;
bool indicator2Blink = false;
uint8_t getnextAppNumber();
void drawApp();
void drawOverlays();
@@ -148,6 +155,15 @@ public:
*/
void setTimePerTransition(uint16_t time);
void setIndicator1Color(uint16_t color);
void setIndicator1State(bool state);
void setIndicator2Color(uint16_t color);
void setIndicator2State(bool state);
void setIndicator1Blink(bool Blink);
void setIndicator2Blink(bool Blink);
void drawIndicators();
// Customize indicator position and style
// App settings

View File

@@ -17,6 +17,15 @@ const char HAmodel[] PROGMEM = {"AWTRIX Light"};
const char HAmatID[] PROGMEM = {"%s_mat"};
const char HAmatIcon[] PROGMEM = {"mdi:lightbulb"};
const char HAmatName[] PROGMEM = {"Matrix"};
const char HAi1ID[] PROGMEM = {"%s_ind1"};
const char HAi1Icon[] PROGMEM = {"mdi:arrow-top-right-thick"};
const char HAi1Name[] PROGMEM = {"Indicator 1"};
const char HAi2ID[] PROGMEM = {"%s_ind2"};
const char HAi2Icon[] PROGMEM = {"mdi:arrow-bottom-right-thick"};
const char HAi2Name[] PROGMEM = {"Indicator 2"};
const char HAbriID[] PROGMEM = {"%s_bri"};
const char HAbriIcon[] PROGMEM = {"mdi:brightness-auto"};
const char HAbriName[] PROGMEM = {"Brightness mode"};
@@ -74,12 +83,10 @@ const char HAupdateName[] PROGMEM = {"Update"};
const char HAupdateClass[] PROGMEM = {"update"};
const char HAupdateIcon[] PROGMEM = {"mdi:update"};
const char HAdoUpID[] PROGMEM = {"%s_doupd"};
const char HAdoUpName[] PROGMEM = {"Start Update"};
const char HAdoUpIcon[] PROGMEM = {"mdi:update"};
const char HAsigID[] PROGMEM = {"%s_sig"};
const char HAsigIcon[] PROGMEM = {"mdi:sun-wireless"};
const char HAsigName[] PROGMEM = {"WiFi strength"};

View File

@@ -17,6 +17,15 @@ extern const char HAmodel[];
extern const char HAmatID[];
extern const char HAmatIcon[];
extern const char HAmatName[];
extern const char HAi1ID[];
extern const char HAi1Icon[];
extern const char HAi1Name[];
extern const char HAi2ID[];
extern const char HAi2Icon[];
extern const char HAi2Name[];
extern const char HAbriID[];
extern const char HAbriIcon[];
extern const char HAbriName[];

View File

@@ -37,6 +37,8 @@ CRGB leds[MATRIX_WIDTH * MATRIX_HEIGHT];
FastLED_NeoMatrix *matrix = new FastLED_NeoMatrix(leds, 8, 8, 4, 1, NEO_MATRIX_TOP + NEO_MATRIX_LEFT + NEO_MATRIX_ROWS + NEO_MATRIX_PROGRESSIVE);
MatrixDisplayUi *ui = new MatrixDisplayUi(matrix);
uint8_t lastBrightness;
DisplayManager_ &DisplayManager_::getInstance()
{
static DisplayManager_ instance;
@@ -54,6 +56,11 @@ void DisplayManager_::setBrightness(uint8_t bri)
else
{
matrix->setBrightness(bri);
if (GAMMA > 0)
{
Serial.println(GAMMA);
napplyGamma_video(&leds[256], 256, GAMMA);
}
}
}
@@ -140,6 +147,7 @@ bool jpg_output(int16_t x, int16_t y, uint16_t w, uint16_t h, uint16_t *bitmap)
void DisplayManager_::printText(int16_t x, int16_t y, const char *text, bool centered, byte textCase)
{
if (centered)
{
uint16_t textWidth = getTextWidth(text, textCase);
@@ -533,9 +541,12 @@ void DisplayManager_::setup()
TJpgDec.setCallback(jpg_output);
TJpgDec.setJpgScale(1);
FastLED.addLeds<NEOPIXEL, MATRIX_PIN>(leds, MATRIX_WIDTH * MATRIX_HEIGHT).setTemperature(OvercastSky);
FastLED.addLeds<NEOPIXEL, MATRIX_PIN>(leds, MATRIX_WIDTH * MATRIX_HEIGHT);
setMatrixLayout(MATRIX_LAYOUT);
if (COLOR_CORRECTION)
{
FastLED.setCorrection(COLOR_CORRECTION);
}
gif.setMatrix(matrix);
ui->setAppAnimation(SLIDE_DOWN);
ui->setTimePerApp(TIME_PER_APP);
@@ -555,6 +566,7 @@ void DisplayManager_::tick()
else
{
ui->update();
if (ui->getUiState()->appState == IN_TRANSITION && !appIsSwitching)
@@ -800,10 +812,12 @@ std::pair<String, AppCallback> getNativeAppByName(const String &appName)
{
return std::make_pair("hum", HumApp);
}
#ifdef ULANZI
else if (appName == "bat")
{
return std::make_pair("bat", BatApp);
}
#endif
return std::make_pair("", nullptr);
}
@@ -941,3 +955,145 @@ String DisplayManager_::getAppsAsJson()
serializeJson(appsObject, json);
return json;
}
void DisplayManager_::powerStateParse(const char *json)
{
DynamicJsonDocument doc(128);
DeserializationError error = deserializeJson(doc, json);
if (error)
return;
if (doc.containsKey("state"))
{
bool state = doc["state"].as<bool>();
setPower(state);
}
}
void DisplayManager_::setPower(bool state)
{
if (state)
{
MATRIX_OFF = false;
setBrightness(lastBrightness);
}
else
{
MATRIX_OFF = true;
lastBrightness = BRIGHTNESS;
setBrightness(0);
}
}
void DisplayManager_::setIndicator1Color(uint16_t color)
{
ui->setIndicator1Color(color);
}
void DisplayManager_::setIndicator1State(bool state)
{
ui->setIndicator1State(state);
}
void DisplayManager_::setIndicator2Color(uint16_t color)
{
ui->setIndicator2Color(color);
}
void DisplayManager_::setIndicator2State(bool state)
{
ui->setIndicator2State(state);
}
void DisplayManager_::indicatorParser(uint8_t indicator, const char *json)
{
DynamicJsonDocument doc(128);
DeserializationError error = deserializeJson(doc, json);
if (error)
return;
if (doc.containsKey("color"))
{
auto color = doc["color"];
if (color.is<String>())
{
uint16_t col = hexToRgb565(color.as<String>());
if (col > 0)
{
if (indicator == 1)
{
ui->setIndicator1State(true);
ui->setIndicator1Color(col);
}
else
{
ui->setIndicator2State(true);
ui->setIndicator2Color(col);
}
}
else
{
if (indicator == 1)
{
ui->setIndicator1State(false);
}
else
{
ui->setIndicator2State(false);
}
}
}
else if (color.is<JsonArray>() && color.size() == 3)
{
uint8_t r = color[0];
uint8_t g = color[1];
uint8_t b = color[2];
if (r == 0 && g == 0 && b == 0)
{
if (indicator == 1)
{
ui->setIndicator1State(false);
}
else
{
ui->setIndicator2State(false);
}
}
else
{
if (indicator == 1)
{
ui->setIndicator1State(true);
ui->setIndicator1Color((r << 11) | (g << 5) | b);
}
else
{
ui->setIndicator2State(true);
ui->setIndicator2Color((r << 11) | (g << 5) | b);
}
}
}
}
if (doc.containsKey("blink"))
{
if (indicator == 1)
{
ui->setIndicator1Blink(doc["blink"].as<bool>());
}
else
{
ui->setIndicator2Blink(doc["blink"].as<bool>());
}
}
else
{
if (indicator == 1)
{
ui->setIndicator1Blink(false);
}
else
{
ui->setIndicator2Blink(false);
}
}
}

View File

@@ -51,11 +51,10 @@ public:
void MatrixState(bool);
void generateNotification(const char *json);
void generateCustomPage(const String &name, const char *json);
void printText(int16_t x, int16_t y, const char *text, bool centered, byte textCase);
void printText(int16_t x, int16_t y, const char *text, bool centered, byte textCase);
bool setAutoTransition(bool active);
void switchToApp(const char *json);
void setNewSettings(const char *json);
void drawGIF(uint16_t x, uint16_t y, fs::File gifFile);
void drawJPG(uint16_t x, uint16_t y, fs::File jpgFile);
void drawProgressBar(int cur, int total);
void drawMenuIndicator(int cur, int total, uint16_t color);
@@ -66,6 +65,13 @@ public:
void setAppTime(uint16_t duration);
String getAppsAsJson();
String getStat();
void setPower(bool state);
void powerStateParse(const char *json);
void setIndicator1Color(uint16_t color);
void setIndicator1State(bool state);
void setIndicator2Color(uint16_t color);
void setIndicator2State(bool state);
void indicatorParser(uint8_t indicator, const char *json);
};
extern DisplayManager_ &DisplayManager;

View File

@@ -8,6 +8,38 @@
std::map<char, uint16_t> CharMap = {
{32, 2}, {33, 2}, {34, 4}, {35, 4}, {36, 4}, {37, 4}, {38, 4}, {39, 2}, {40, 3}, {41, 3}, {42, 4}, {43, 4}, {44, 3}, {45, 4}, {46, 2}, {47, 4}, {48, 4}, {49, 4}, {50, 4}, {51, 4}, {52, 4}, {53, 4}, {54, 4}, {55, 4}, {56, 4}, {57, 4}, {58, 2}, {59, 3}, {60, 4}, {61, 4}, {62, 4}, {63, 4}, {64, 4}, {65, 4}, {66, 4}, {67, 4}, {68, 4}, {69, 4}, {70, 4}, {71, 4}, {72, 4}, {73, 2}, {74, 4}, {75, 4}, {76, 4}, {77, 6}, {78, 5}, {79, 4}, {80, 4}, {81, 5}, {82, 4}, {83, 4}, {84, 4}, {85, 4}, {86, 4}, {87, 6}, {88, 4}, {89, 4}, {90, 4}, {91, 4}, {92, 4}, {93, 4}, {94, 4}, {95, 4}, {96, 3}, {97, 4}, {98, 4}, {99, 4}, {100, 4}, {101, 4}, {102, 4}, {103, 4}, {104, 4}, {105, 2}, {106, 4}, {107, 4}, {108, 4}, {109, 4}, {110, 4}, {111, 4}, {112, 4}, {113, 4}, {114, 4}, {115, 4}, {116, 4}, {117, 4}, {118, 4}, {119, 4}, {120, 4}, {121, 4}, {122, 4}, {123, 4}, {124, 2}, {125, 4}, {126, 4}, {161, 2}, {162, 4}, {163, 4}, {164, 4}, {165, 4}, {166, 2}, {167, 4}, {168, 4}, {169, 4}, {170, 4}, {171, 3}, {172, 4}, {173, 3}, {174, 4}, {175, 4}, {176, 4}, {177, 4}, {178, 4}, {179, 4}, {180, 3}, {181, 4}, {182, 4}, {183, 4}, {184, 4}, {185, 2}, {186, 4}, {187, 3}, {188, 4}, {189, 4}, {190, 4}, {191, 4}, {192, 4}, {193, 4}, {194, 4}, {195, 4}, {196, 4}, {197, 4}, {198, 4}, {199, 4}, {200, 4}, {201, 4}, {202, 4}, {203, 4}, {204, 4}, {205, 4}, {206, 4}, {207, 4}, {208, 4}, {209, 4}, {210, 4}, {211, 4}, {212, 4}, {213, 4}, {214, 4}, {215, 4}, {216, 4}, {217, 4}, {218, 4}, {219, 4}, {220, 4}, {221, 4}, {222, 4}, {223, 4}, {224, 4}, {225, 4}, {226, 4}, {227, 4}, {228, 4}, {229, 4}, {230, 4}, {231, 4}, {232, 4}, {233, 4}, {234, 4}, {235, 4}, {236, 3}, {237, 3}, {238, 4}, {239, 4}, {240, 4}, {241, 4}, {242, 4}, {243, 4}, {244, 4}, {245, 4}, {246, 4}, {247, 4}, {248, 4}, {249, 4}, {250, 4}, {251, 4}, {252, 4}, {253, 4}, {254, 4}, {255, 4}, {285, 2}, {338, 4}, {339, 4}, {352, 4}, {353, 4}, {376, 4}, {381, 4}, {382, 4}, {3748, 2}, {5024, 2}, {8226, 2}, {8230, 4}, {8364, 4}, {65533, 4}};
//---------------------------------------------------------------
// This is the gamma lookup for mapping 255 brightness levels
// The lookup table would be similar but have slightly shifted
// numbers for different gammas (gamma 2.0, 2.2, 2.5, etc.)
const uint8_t PROGMEM gamma8[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2,
2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5,
5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10,
10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 16, 16,
17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 24, 24, 25,
25, 26, 27, 27, 28, 29, 29, 30, 31, 32, 32, 33, 34, 35, 35, 36,
37, 38, 39, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 50,
51, 52, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 66, 67, 68,
69, 70, 72, 73, 74, 75, 77, 78, 79, 81, 82, 83, 85, 86, 87, 89,
90, 92, 93, 95, 96, 98, 99,101,102,104,105,107,109,110,112,114,
115,117,119,120,122,124,126,127,129,131,133,135,137,138,140,142,
144,146,148,150,152,154,156,158,160,162,164,167,169,171,173,175,
177,180,182,184,186,189,191,193,196,198,200,203,205,208,210,213,
215,218,220,223,225,228,231,233,236,239,241,244,247,249,252,255 };
CRGB applyGammaCorrection(const CRGB& color) {
CRGB correctedColor;
correctedColor.r = pgm_read_byte(&gamma8[color.r]);
correctedColor.g = pgm_read_byte(&gamma8[color.g]);
correctedColor.b = pgm_read_byte(&gamma8[color.b]);
return correctedColor;
}
uint32_t hsvToRgb(uint8_t h, uint8_t s, uint8_t v)
{
CHSV hsv(h, s, v);

View File

@@ -2,6 +2,7 @@
#include "Preferences.h"
#include <WiFi.h>
#include <ArduinoJson.h>
#include <LittleFS.h>
Preferences Settings;
@@ -66,6 +67,22 @@ void loadDevSettings()
TEMP_DECIMAL_PLACES = doc["temp_dec_places"].as<int>();
}
if (doc.containsKey("gamma"))
{
GAMMA = doc["gamma"].as<float>();
}
if (doc.containsKey("color_correction"))
{
auto correction = doc["color_correction"];
if (correction.is<JsonArray>() && correction.size() == 3)
{
uint8_t r = correction[0];
uint8_t g = correction[1];
uint8_t b = correction[2];
COLOR_CORRECTION.setRGB(r, g, b);
}
}
file.close();
}
}
@@ -139,7 +156,7 @@ IPAddress gateway;
IPAddress subnet;
IPAddress primaryDNS;
IPAddress secondaryDNS;
const char *VERSION = "0.48";
const char *VERSION = "0.49";
String MQTT_HOST = "";
uint16_t MQTT_PORT = 1883;
String MQTT_USER;
@@ -211,3 +228,5 @@ uint8_t VOLUME;
int MATRIX_LAYOUT;
bool UPDATE_AVAILABLE = false;
long RECEIVED_MESSAGES;
CRGB COLOR_CORRECTION;
float GAMMA = 0;

View File

@@ -1,6 +1,7 @@
#ifndef GLOBALS_H
#define GLOBALS_H
#include <Arduino.h>
#include <FastLED.h>
extern const char *uniqueID;
extern const char *VERSION;
@@ -76,6 +77,8 @@ extern uint8_t VOLUME;
extern int MATRIX_LAYOUT;
extern bool UPDATE_AVAILABLE;
extern long RECEIVED_MESSAGES;
extern CRGB COLOR_CORRECTION;
extern float GAMMA;
void loadSettings();
void saveSettings();
#endif // Globals_H

View File

@@ -10,14 +10,15 @@
#include "UpdateManager.h"
WiFiClient espClient;
uint8_t lastBrightness;
HADevice device;
HAMqtt mqtt(espClient, device, 22);
HAMqtt mqtt(espClient, device, 25);
unsigned long reconnectTimer = 0;
const unsigned long reconnectInterval = 30000; // 30 Sekunden
HALight *Matrix = nullptr;
HALight *Indikator1 = nullptr;
HALight *Indikator2 = nullptr;
HASelect *BriMode = nullptr;
HAButton *dismiss = nullptr;
HAButton *nextApp = nullptr;
@@ -101,25 +102,36 @@ void onSelectCommand(int8_t index, HASelect *sender)
void onRGBColorCommand(HALight::RGBColor color, HALight *sender)
{
TEXTCOLOR_565 = ((color.red & 0x1F) << 11) | ((color.green & 0x3F) << 5) | (color.blue & 0x1F);
saveSettings();
if (sender == Matrix)
{
TEXTCOLOR_565 = ((color.red & 0x1F) << 11) | ((color.green & 0x3F) << 5) | (color.blue & 0x1F);
saveSettings();
}
else if (sender == Indikator1)
{
DisplayManager.setIndicator1Color(((color.red & 0x1F) << 11) | ((color.green & 0x3F) << 5) | (color.blue & 0x1F));
}
else if (sender == Indikator2)
{
DisplayManager.setIndicator2Color(((color.red & 0x1F) << 11) | ((color.green & 0x3F) << 5) | (color.blue & 0x1F));
}
sender->setRGBColor(color); // report color back to the Home Assistant
}
void onStateCommand(bool state, HALight *sender)
{
if (state)
if (sender == Matrix)
{
MATRIX_OFF = false;
DisplayManager.setBrightness(lastBrightness);
DisplayManager.setPower(state);
}
else
else if (sender == Indikator1)
{
MATRIX_OFF = true;
lastBrightness = BRIGHTNESS;
DisplayManager.setBrightness(0);
DisplayManager.setIndicator1State(state);
}
else if (sender == Indikator2)
{
DisplayManager.setIndicator2State(state);
}
sender->setState(state);
}
@@ -129,7 +141,6 @@ void onBrightnessCommand(uint8_t brightness, HALight *sender)
if (AUTO_BRIGHTNESS)
return;
BRIGHTNESS = brightness;
lastBrightness = brightness;
saveSettings();
DisplayManager.setBrightness(brightness);
}
@@ -208,7 +219,24 @@ void onMqttMessage(const char *topic, const uint8_t *payload, uint16_t length)
delete[] payloadCopy;
return;
}
if (strTopic.equals(MQTT_PREFIX + "/power"))
{
DisplayManager.powerStateParse(payloadCopy);
delete[] payloadCopy;
return;
}
if (strTopic.equals(MQTT_PREFIX + "/indicator1"))
{
DisplayManager.indicatorParser(1, payloadCopy);
delete[] payloadCopy;
return;
}
if (strTopic.equals(MQTT_PREFIX + "/indicator2"))
{
DisplayManager.indicatorParser(2, payloadCopy);
delete[] payloadCopy;
return;
}
else if (strTopic.startsWith(MQTT_PREFIX + "/custom"))
{
String topic_str = topic;
@@ -239,7 +267,10 @@ void onMqttConnected()
"/nextapp",
"/doupdate",
"/nextapp",
"/apps"};
"/apps",
"/power",
"/indicator1",
"/indicator2"};
for (const char *topic : topics)
{
String fullTopic = prefix + topic;
@@ -265,7 +296,7 @@ void connect()
}
}
char matID[40], briID[40];
char matID[40], ind1ID[40], ind2ID[40], briID[40];
char btnAID[40], btnBID[40], btnCID[40], appID[40], tempID[40], humID[40], luxID[40], verID[40], ramID[40], upID[40], sigID[40], btnLID[40], btnMID[40], btnRID[40], transID[40], updateID[40], doUpdateID[40];
#ifdef ULANZI
char batID[40];
@@ -273,7 +304,6 @@ char batID[40];
void MQTTManager_::setup()
{
if (HA_DISCOVERY)
{
Serial.println(F("Starting Homeassistant discorvery"));
@@ -304,6 +334,20 @@ void MQTTManager_::setup()
Matrix->setCurrentState(true);
Matrix->setBRIGHTNESS(BRIGHTNESS);
sprintf(ind1ID, HAi1ID, macStr);
Indikator1 = new HALight(ind1ID, HALight::RGBFeature);
Indikator1->setIcon(HAi1Icon);
Indikator1->setName(HAi1Name);
Indikator1->onStateCommand(onStateCommand);
Indikator1->onRGBColorCommand(onRGBColorCommand);
sprintf(ind2ID, HAi2ID, macStr);
Indikator2 = new HALight(ind2ID, HALight::RGBFeature);
Indikator2->setIcon(HAi2Icon);
Indikator2->setName(HAi2Name);
Indikator2->onStateCommand(onStateCommand);
Indikator2->onRGBColorCommand(onRGBColorCommand);
HALight::RGBColor color;
color.red = (TEXTCOLOR_565 >> 11) << 3;
color.green = ((TEXTCOLOR_565 >> 5) & 0x3F) << 2;
@@ -368,8 +412,8 @@ void MQTTManager_::setup()
humidity->setName(HAhumName);
humidity->setDeviceClass(HAhumClass);
humidity->setUnitOfMeasurement(HAhumUnit);
#ifdef ULANZI
#ifdef ULANZI
sprintf(batID, HAbatID, macStr);
battery = new HASensor(batID);
battery->setIcon(HAbatIcon);

View File

@@ -96,7 +96,6 @@ void left_button_pressed()
#ifndef ULANZI
PeripheryManager.playFromFile(DFMINI_MP3_CLICK);
#endif
DisplayManager.leftButton();
MenuManager.leftButton();
}
@@ -106,7 +105,6 @@ void right_button_pressed()
#ifndef ULANZI
PeripheryManager.playFromFile(DFMINI_MP3_CLICK);
#endif
DisplayManager.rightButton();
MenuManager.rightButton();
}

View File

@@ -99,9 +99,15 @@ void ServerManager_::setup()
{ DisplayManager.generateCustomPage(mws.webserver->arg("name"),mws.webserver->arg("plain").c_str()); mws.webserver->send(200,"OK"); });
mws.addHandler("/api/stats", HTTP_GET, []()
{ mws.webserver->sendContent(DisplayManager.getStat()); });
mws.addHandler("/api/indicator1", HTTP_POST, []()
{ DisplayManager.indicatorParser(1,mws.webserver->arg("plain").c_str()); mws.webserver->send(200,"OK"); });
mws.addHandler("/api/indicator2", HTTP_POST, []()
{ DisplayManager.indicatorParser(2,mws.webserver->arg("plain").c_str()); mws.webserver->send(200,"OK"); });
mws.addHandler("/api/doupdate", HTTP_POST, []()
{ if (UPDATE_AVAILABLE)
UpdateManager.updateFirmware(); mws.webserver->send(200,"OK"); });
mws.addHandler("/api/power", HTTP_POST, []()
{ DisplayManager.powerStateParse(mws.webserver->arg("plain").c_str()); mws.webserver->send(200,"OK"); });
Serial.println("Webserver loaded");
}
mws.addHandler("/version", HTTP_GET, versionHandler);

View File

@@ -94,7 +94,6 @@ void setup()
delay(200);
DisplayManager.setBrightness(BRIGHTNESS);
DisplayManager.clearMatrix();
}
void loop()