diff --git a/README.md b/README.md
index 97a9970..056df94 100644
--- a/README.md
+++ b/README.md
@@ -16,11 +16,12 @@

[](https://github.com/Blueforcer/awtrix-light/actions/workflows/main.yml)
+
+
+
+
-
-
-
-AWTRIX Light is an open‑source custom firmware for the [Ulanzi Smart Pixel clock TC001](https://www.ulanzi.com/products/ulanzi-pixel-smart-clock-2882)
+AWTRIX Light is a open‑source custom firmware for the [Ulanzi Smart Pixel clock TC001](https://www.ulanzi.com/products/ulanzi-pixel-smart-clock-2882)
AWL meant to be a companion for your smarthome like HomeAssistant, IOBroker, NodeRed and so on.
Even if you don't have a Smarthome system, but would like to experiment with NodeRed or N8N, you are still welcome to join us.
@@ -40,7 +41,9 @@ Join the thousands of satisfied awtrix users who have already chosen Awtrix 2 an
- Onscreen menu where you can change your settings directly on the device
- Pre-installed Apps like time, date, temperature, humidity and battery
- Add customapps without recompiling straight from your Smarthome.
-- Noitification support
+- Notification support
+- Animated icons
+- Custom icons without recompiling
- Easy to use icon system
- Powerful MQTT commands
- HTTP API
diff --git a/docs/api.md b/docs/api.md
index 24ef510..daefb3f 100644
--- a/docs/api.md
+++ b/docs/api.md
@@ -43,7 +43,7 @@ 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 what is sent. | 0 |
All keys are optional, so you can send just the properties you want to use.
@@ -222,7 +222,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 +235,11 @@ Here's an example JSON object to start a timer for 1 hour, 30 minutes, and 10 se
}
```
+## Turn display on or off
+| Topic | URL | Payload/Body | HTTP method |
+| --- | --- | --- | --- |
+| `[PREFIX]/onstate` | `http://[IP]/api/onstate` | `{"state":value}` | POST |
+
+Valid values are:
+- `0` => off
+- `1` => on
diff --git a/docs/flasher.md b/docs/flasher.md
index 0338bec..2e92874 100644
--- a/docs/flasher.md
+++ b/docs/flasher.md
@@ -2,6 +2,6 @@
# Online flasher
Available in Google Chrome and Microsoft Edge browsers.
-If you falsh your Ulanzi Clock the first time you need to check "erase".
+If you flash your Ulanzi Clock the first time you need to check "erase".
[filename](flasher/index.html ':include :type=iframe')
diff --git a/docs/flasher/firmware/firmware.bin b/docs/flasher/firmware/firmware.bin
index 7f6fe56..5d935fa 100644
Binary files a/docs/flasher/firmware/firmware.bin and b/docs/flasher/firmware/firmware.bin differ
diff --git a/docs/flasher/firmware/manifest.json b/docs/flasher/firmware/manifest.json
index 257a148..6f2cd1d 100644
--- a/docs/flasher/firmware/manifest.json
+++ b/docs/flasher/firmware/manifest.json
@@ -1,6 +1,6 @@
{
"name": "AWTRIX Light",
- "version": "0.47",
+ "version": "0.48",
"home_assistant_domain": "AwtrixLight",
"funding_url": "https://blueforcer.de",
"new_install_prompt_erase": true,
diff --git a/docs/flasher/index.html b/docs/flasher/index.html
index d479fe2..99d5e41 100644
--- a/docs/flasher/index.html
+++ b/docs/flasher/index.html
@@ -75,7 +75,7 @@
}
}
-
+
diff --git a/src/DisplayManager.cpp b/src/DisplayManager.cpp
index 834f7ed..7178137 100644
--- a/src/DisplayManager.cpp
+++ b/src/DisplayManager.cpp
@@ -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;
@@ -421,7 +423,7 @@ void DisplayManager_::generateNotification(const char *json)
else
{
notify.barSize = 0;
- }
+ }
if (doc.containsKey("color"))
{
@@ -473,7 +475,7 @@ void DisplayManager_::generateNotification(const char *json)
}
else
{
- fs::File nullPointer;
+ fs::File nullPointer;
notify.icon = nullPointer;
}
}
@@ -802,10 +804,12 @@ std::pair 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);
}
@@ -944,6 +948,32 @@ String DisplayManager_::getAppsAsJson()
return json;
}
+
+void DisplayManager_::onStateParse(const char *json)
+{
+ DynamicJsonDocument doc(512);
+ DeserializationError error = deserializeJson(doc, json);
+ if (error)
+ return;
+ bool state = doc["state"].as();
+ onState(state);
+}
+
+void DisplayManager_::onState(bool state)
+{
+ if (state)
+ {
+ MATRIX_OFF = false;
+ setBrightness(lastBrightness);
+ }
+ else
+ {
+ MATRIX_OFF = true;
+ lastBrightness = BRIGHTNESS;
+ setBrightness(0);
+ }
+}
+
void DisplayManager_::setIndicator1(bool state, uint16_t color)
{
ui->setIndicator1(state, color);
@@ -953,3 +983,4 @@ void DisplayManager_::setIndicator2(bool state, uint16_t color)
{
ui->setIndicator2(state, color);
}
+
diff --git a/src/DisplayManager.h b/src/DisplayManager.h
index 44caeeb..811751f 100644
--- a/src/DisplayManager.h
+++ b/src/DisplayManager.h
@@ -66,8 +66,13 @@ public:
void setAppTime(uint16_t duration);
String getAppsAsJson();
String getStat();
+
+ void onState(bool state);
+ void onStateParse(const char *json);
+
void setIndicator1(bool state, uint16_t color);
void setIndicator2(bool state, uint16_t color);
+
};
extern DisplayManager_ &DisplayManager;
diff --git a/src/MQTTManager.cpp b/src/MQTTManager.cpp
index 281dd17..78c7de7 100644
--- a/src/MQTTManager.cpp
+++ b/src/MQTTManager.cpp
@@ -10,7 +10,6 @@
#include "UpdateManager.h"
WiFiClient espClient;
-uint8_t lastBrightness;
HADevice device;
HAMqtt mqtt(espClient, device, 25);
@@ -123,17 +122,7 @@ void onStateCommand(bool state, HALight *sender)
{
if (sender == Matrix)
{
- if (state)
- {
- MATRIX_OFF = false;
- DisplayManager.setBrightness(lastBrightness);
- }
- else
- {
- MATRIX_OFF = true;
- lastBrightness = BRIGHTNESS;
- DisplayManager.setBrightness(0);
- }
+ DisplayManager.onState(state);
}
else if (sender == Indikator1)
{
@@ -143,7 +132,6 @@ void onStateCommand(bool state, HALight *sender)
{
DisplayManager.setIndicator2(state, 0);
}
-
sender->setState(state);
}
@@ -153,7 +141,6 @@ void onBrightnessCommand(uint8_t brightness, HALight *sender)
if (AUTO_BRIGHTNESS)
return;
BRIGHTNESS = brightness;
- lastBrightness = brightness;
saveSettings();
DisplayManager.setBrightness(brightness);
}
@@ -232,7 +219,13 @@ void onMqttMessage(const char *topic, const uint8_t *payload, uint16_t length)
delete[] payloadCopy;
return;
}
-
+ if (strTopic.equals(MQTT_PREFIX + "/onstate"))
+ {
+ DisplayManager.onStateParse(payloadCopy);
+ Serial.println(payloadCopy);
+ delete[] payloadCopy;
+ return;
+ }
else if (strTopic.startsWith(MQTT_PREFIX + "/custom"))
{
String topic_str = topic;
@@ -263,7 +256,8 @@ void onMqttConnected()
"/nextapp",
"/doupdate",
"/nextapp",
- "/apps"};
+ "/apps",
+ "/onstate"};
for (const char *topic : topics)
{
String fullTopic = prefix + topic;
@@ -297,7 +291,6 @@ char batID[40];
void MQTTManager_::setup()
{
-
if (HA_DISCOVERY)
{
Serial.println(F("Starting Homeassistant discorvery"));
@@ -406,8 +399,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);
diff --git a/src/PeripheryManager.cpp b/src/PeripheryManager.cpp
index 7e397b3..7153e8b 100644
--- a/src/PeripheryManager.cpp
+++ b/src/PeripheryManager.cpp
@@ -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();
}
diff --git a/src/ServerManager.cpp b/src/ServerManager.cpp
index 2e4db3e..fa72d37 100644
--- a/src/ServerManager.cpp
+++ b/src/ServerManager.cpp
@@ -102,6 +102,8 @@ void ServerManager_::setup()
mws.addHandler("/api/doupdate", HTTP_POST, []()
{ if (UPDATE_AVAILABLE)
UpdateManager.updateFirmware(); mws.webserver->send(200,"OK"); });
+ mws.addHandler("/api/onstate", HTTP_POST, []()
+ { DisplayManager.onStateParse(mws.webserver->arg("plain").c_str()); mws.webserver->send(200,"OK"); });
Serial.println("Webserver loaded");
}
mws.addHandler("/version", HTTP_GET, versionHandler);
diff --git a/version b/version
index 4f009b9..8ae5e61 100644
--- a/version
+++ b/version
@@ -1 +1 @@
-0.47
+0.48