-Add update sensor to HA. AWL search for an update every hour.
- Fixes  duration in custom apps
This commit is contained in:
Stephan Mühl
2023-04-02 00:56:24 +02:00
parent 3c27f09287
commit b08e38f06c
12 changed files with 299 additions and 132 deletions

View File

@@ -69,6 +69,17 @@ const char HAtransID[] PROGMEM = {"%s_tra"};
const char HAtransName[] PROGMEM = {"Transition"};
const char HAtransIcon[] PROGMEM = {"mdi:swap-vertical"};
const char HAupdateID[] PROGMEM = {"%s_upd"};
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"};
@@ -104,3 +115,4 @@ const char TempKey[] PROGMEM = {"temp"};
const char HumKey[] PROGMEM = {"hum"};
const char UpTimeKey[] PROGMEM = {"uptime"};
const char SignalStrengthKey[] PROGMEM = {"wifi_signal"};
const char UpdateKey[] PROGMEM = {"up_available"};

View File

@@ -77,10 +77,19 @@ extern const char HAupID[];
extern const char HAupName[];
extern const char HAupClass[];
extern const char HAdoUpID[];
extern const char HAdoUpName[];
extern const char HAdoUpIcon[];
extern const char HAtransID[];
extern const char HAtransName[];
extern const char HAtransIcon[];
extern const char HAupdateID[];
extern const char HAupdateName[];
extern const char HAupdateClass[];
extern const char HAupdateIcon[];
extern const char HAbtnLID[];
extern const char HAbtnLName[];
@@ -106,5 +115,5 @@ extern const char TempKey[];
extern const char HumKey[];
extern const char UpTimeKey[];
extern const char SignalStrengthKey[];
extern const char UpdateKey[];
#endif

View File

@@ -293,7 +293,7 @@ void DisplayManager_::generateCustomPage(String name, const char *json)
customApp.barSize = 0;
}
customApp.duration = doc.containsKey("duration") ? doc["duration"].as<int>() * 1000 : -1;
customApp.duration = doc.containsKey("duration") ? doc["duration"].as<int>() * 1000 : 0;
int pos = doc.containsKey("pos") ? doc["pos"].as<uint8_t>() : -1;
customApp.rainbow = doc.containsKey("rainbow") ? doc["rainbow"] : false;
customApp.pushIcon = doc.containsKey("pushIcon") ? doc["pushIcon"] : 0;
@@ -514,7 +514,7 @@ void DisplayManager_::loadNativeApps()
void DisplayManager_::setup()
{
TJpgDec.setCallback(jpg_output);
FastLED.addLeds<NEOPIXEL, MATRIX_PIN>(leds, MATRIX_WIDTH * MATRIX_HEIGHT);
gif.setMatrix(&matrix);
@@ -891,8 +891,10 @@ String DisplayManager_::getStat()
{
StaticJsonDocument<200> doc;
char buffer[5];
#ifdef ULANZI
doc[BatKey] = BATTERY_PERCENT;
doc[BatRawKey] = BATTERY_RAW;
#endif
snprintf(buffer, 5, "%.0f", CURRENT_LUX);
doc[LuxKey] = buffer;
doc[LDRRawKey] = LDR_RAW;
@@ -903,6 +905,7 @@ String DisplayManager_::getStat()
doc[HumKey] = buffer;
doc[UpTimeKey] = PeripheryManager.readUptime();
doc[SignalStrengthKey] = WiFi.RSSI();
doc[UpdateKey] = UPDATE_AVAILABLE;
String jsonString;
serializeJson(doc, jsonString);
return jsonString;

View File

@@ -121,7 +121,7 @@ IPAddress gateway;
IPAddress subnet;
IPAddress primaryDNS;
IPAddress secondaryDNS;
const char *VERSION = "0.46";
const char *VERSION = "0.47";
String MQTT_HOST = "";
uint16_t MQTT_PORT = 1883;
String MQTT_USER;
@@ -187,4 +187,5 @@ bool SOUND_ACTIVE;
String BOOT_SOUND = "";
uint8_t VOLUME;
uint8_t VOLUME_PERCENT;
int MATRIX_LAYOUT;
int MATRIX_LAYOUT;
bool UPDATE_AVAILABLE = false;

View File

@@ -71,6 +71,7 @@ extern String BOOT_SOUND;
extern uint8_t VOLUME;
extern uint8_t VOLUME_PERCENT;
extern int MATRIX_LAYOUT;
extern bool UPDATE_AVAILABLE;
void loadSettings();
void saveSettings();
#endif // Globals_H

View File

@@ -7,6 +7,7 @@
#include <ArduinoJson.h>
#include "Dictionary.h"
#include "PeripheryManager.h"
#include "Updater.h"
WiFiClient espClient;
uint8_t lastBrightness;
@@ -36,6 +37,8 @@ HASensor *ram = nullptr;
HABinarySensor *btnleft = nullptr;
HABinarySensor *btnmid = nullptr;
HABinarySensor *btnright = nullptr;
HABinarySensor *update = nullptr;
HAButton *doUpdate = nullptr;
// The getter for the instantiated singleton instance
MQTTManager_ &MQTTManager_::getInstance()
@@ -61,6 +64,11 @@ void onButtonCommand(HAButton *sender)
{
DisplayManager.previousApp();
}
else if (sender == doUpdate)
{
if (UPDATE_AVAILABLE)
Updater.updateFirmware();
}
}
void onSwitchCommand(bool state, HASwitch *sender)
@@ -183,6 +191,12 @@ void onMqttMessage(const char *topic, const uint8_t *payload, uint16_t length)
DisplayManager.previousApp();
return;
}
if (strTopic == MQTT_PREFIX + "/doupdate")
{
if (UPDATE_AVAILABLE)
Updater.updateFirmware();
return;
}
else if (strTopic.startsWith(MQTT_PREFIX + "/custom"))
{
@@ -212,6 +226,7 @@ void onMqttConnected()
"/settings",
"/previousapp",
"/nextapp",
"/doupdate",
"/nextapp",
"/apps"};
for (const char *topic : topics)
@@ -222,7 +237,6 @@ void onMqttConnected()
Serial.println(F("MQTT Connected"));
}
void connect()
{
mqtt.onMessage(onMqttMessage);
@@ -241,7 +255,7 @@ void connect()
}
char matID[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];
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];
#endif
@@ -299,6 +313,12 @@ void MQTTManager_::setup()
dismiss->setIcon(HAbtnaIcon);
dismiss->setName(HAbtnaName);
sprintf(doUpdateID, HAdoUpID, macStr);
doUpdate = new HAButton(doUpdateID);
doUpdate->setIcon(HAdoUpIcon);
doUpdate->setName(HAdoUpName);
doUpdate->onCommand(onButtonCommand);
sprintf(transID, HAtransID, macStr);
transition = new HASwitch(transID);
transition->setIcon(HAtransIcon);
@@ -373,6 +393,12 @@ void MQTTManager_::setup()
btnleft = new HABinarySensor(btnLID);
btnleft->setName(HAbtnLName);
sprintf(updateID, HAupdateID, macStr);
update = new HABinarySensor(updateID);
update->setIcon(HAupdateIcon);
update->setName(HAupdateName);
update->setDeviceClass(HAupdateClass);
sprintf(btnMID, HAbtnMID, macStr);
btnmid = new HABinarySensor(btnMID);
btnmid->setName(HAbtnMName);
@@ -456,6 +482,8 @@ void MQTTManager_::sendStats()
uptime->setValue(PeripheryManager.readUptime());
version->setValue(VERSION);
transition->setState(AUTO_TRANSITION, false);
update->setState(UPDATE_AVAILABLE, false);
}
else
{

View File

@@ -6,6 +6,7 @@
#include <PeripheryManager.h>
#include <updater.h>
#include <icons.h>
#include <Updater.h>
String menuText;
int menuSelection;
@@ -377,9 +378,9 @@ void MenuManager_::selectButton()
#endif
case 13:
if (FirmwareVersionCheck())
if (Updater.checkUpdate(true))
{
updateFirmware();
Updater.updateFirmware();
}
break;
default:

View File

@@ -9,6 +9,7 @@
#include <LittleFS.h>
#include <WiFi.h>
#include "DisplayManager.h"
#include "Updater.h"
WebServer server(80);
FSWebServer mws(LittleFS, server);
@@ -37,7 +38,6 @@ void saveHandler()
webRequest->send(200);
}
void ServerManager_::setup()
{
if (!local_IP.fromString(NET_IP) || !gateway.fromString(NET_GW) || !subnet.fromString(NET_SN) || !primaryDNS.fromString(NET_PDNS) || !secondaryDNS.fromString(NET_SDNS))
@@ -53,7 +53,7 @@ void ServerManager_::setup()
if (isConnected)
{
mws.addOptionBox("Network");
mws.addOption("Static IP", NET_STATIC);
mws.addOption("Local IP", NET_IP);
@@ -97,6 +97,9 @@ 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/doupdate", HTTP_POST, []()
{ if (UPDATE_AVAILABLE)
Updater.updateFirmware(); mws.webserver->send(200,"OK"); });
Serial.println("Webserver loaded");
}
mws.addHandler("/version", HTTP_GET, versionHandler);

152
src/Updater.cpp Normal file
View File

@@ -0,0 +1,152 @@
#include <updater.h>
#include <WiFi.h>
#include <HTTPClient.h>
#include <HTTPUpdate.h>
#include <WiFiClientSecure.h>
#include "cert.h"
#include "DisplayManager.h"
#include <Ticker.h>
#include "Globals.h"
#define URL_fw_Version "https://raw.githubusercontent.com/Blueforcer/awtrix-light/main/version"
#define URL_fw_Bin "https://raw.githubusercontent.com/Blueforcer/awtrix-light/main/docs/flasher/firmware/firmware.bin"
Ticker UpdateTicker;
// The getter for the instantiated singleton instance
Updater_ &Updater_::getInstance()
{
static Updater_ instance;
return instance;
}
// Initialize the global shared instance
Updater_ &Updater = Updater.getInstance();
void update_started()
{
}
void update_finished()
{
}
void update_progress(int cur, int total)
{
DisplayManager.drawProgressBar(cur, total);
}
void update_error(int err)
{
DisplayManager.clear();
DisplayManager.printText(0, 6, "FAIL", true, true);
DisplayManager.show();
}
void Updater_::updateFirmware()
{
WiFiClientSecure client;
client.setCACert(rootCACertificate);
httpUpdate.onStart(update_started);
httpUpdate.onEnd(update_finished);
httpUpdate.onProgress(update_progress);
httpUpdate.onError(update_error);
t_httpUpdate_return ret = httpUpdate.update(client, URL_fw_Bin);
switch (ret)
{
case HTTP_UPDATE_FAILED:
Serial.printf("HTTP_UPDATE_FAILD Error (%d): %s\n", httpUpdate.getLastError(), httpUpdate.getLastErrorString().c_str());
break;
case HTTP_UPDATE_NO_UPDATES:
Serial.println("HTTP_UPDATE_NO_UPDATES");
break;
case HTTP_UPDATE_OK:
Serial.println("HTTP_UPDATE_OK");
break;
}
}
bool Updater_::checkUpdate(bool withScreen)
{
if (withScreen)
{
DisplayManager.clear();
DisplayManager.printText(0, 6, "CHECK", true, true);
DisplayManager.show();
}
String payload;
int httpCode;
String fwurl = "";
fwurl += URL_fw_Version;
fwurl += "?";
fwurl += String(rand());
Serial.println(fwurl);
WiFiClientSecure *client = new WiFiClientSecure;
if (client)
{
client->setCACert(rootCACertificate);
HTTPClient https;
if (https.begin(*client, fwurl))
{ // HTTPS
Serial.print("[HTTPS] GET...\n");
// start connection and send HTTP header
delay(100);
httpCode = https.GET();
delay(100);
if (httpCode == HTTP_CODE_OK) // if version received
{
payload = https.getString(); // save received version
}
else
{
Serial.print("error in downloading version file:");
Serial.println(httpCode);
}
https.end();
}
delete client;
}
if (httpCode == HTTP_CODE_OK) // if version received
{
payload.trim();
if (payload.equals(VERSION))
{
UPDATE_AVAILABLE = false;
Serial.printf("\nDevice already on latest firmware version: %s\n", VERSION);
if (withScreen)
{
DisplayManager.clear();
DisplayManager.printText(0, 6, "NO UP :(", true, true);
DisplayManager.show();
delay(1000);
}
return 0;
}
else
{
UPDATE_AVAILABLE = true;
return 1;
}
}
UPDATE_AVAILABLE = false;
return 0;
}
void checkUpdateNoReturn()
{
Serial.println("Check Update");
Updater.getInstance().checkUpdate(false);
}
void Updater_::setup()
{
UpdateTicker.attach(3600, checkUpdateNoReturn);
}

View File

@@ -36,6 +36,7 @@
#include "MQTTManager.h"
#include "ServerManager.h"
#include "Globals.h"
#include "Updater.h"
TaskHandle_t taskHandle;
volatile bool StopTask = false;
@@ -58,7 +59,7 @@ void BootAnimation(void *parameter)
void setup()
{
PeripheryManager.setup();
delay(500);
delay(1000);
Serial.begin(9600);
loadSettings();
ServerManager.loadSettings();
@@ -73,6 +74,8 @@ void setup()
{
MQTTManager.setup();
DisplayManager.loadNativeApps();
Updater.setup();
Updater.checkUpdate(false);
StopTask = true;
float x = 4;
while (x >= -85)
@@ -80,6 +83,7 @@ void setup()
DisplayManager.HSVtext(x, 6, ("AWTRIX " + ServerManager.myIP.toString()).c_str(), true);
x -= 0.18;
}
}
else
{
@@ -98,7 +102,6 @@ void loop()
PeripheryManager.tick();
if (ServerManager.isConnected)
{
MQTTManager.tick();
}
}

View File

@@ -1,122 +1,29 @@
#include <WiFi.h>
#include <HTTPClient.h>
#include <HTTPUpdate.h>
#include <WiFiClientSecure.h>
#include "cert.h"
#include "DisplayManager.h"
#ifndef UPDATER_h
#define UPDATER_h
#define URL_fw_Version "https://raw.githubusercontent.com/Blueforcer/awtrix-light/main/version"
#define URL_fw_Bin "https://raw.githubusercontent.com/Blueforcer/awtrix-light/main/docs/flasher/firmware/firmware.bin"
#include <Arduino.h>
#include <EasyButton.h>
#ifdef ULANZI
#include "Adafruit_SHT31.h"
#else
#include "Adafruit_BME280.h"
#include "SoftwareSerial.h"
#include <DFMiniMp3.h>
#endif
void update_started()
class Updater_
{
}
void update_finished()
{
}
void update_progress(int cur, int total)
{
DisplayManager.drawProgressBar(cur, total);
}
void update_error(int err)
{
DisplayManager.clear();
DisplayManager.printText(0, 6, "FAIL", true, true);
DisplayManager.show();
}
void updateFirmware()
{
WiFiClientSecure client;
client.setCACert(rootCACertificate);
httpUpdate.onStart(update_started);
httpUpdate.onEnd(update_finished);
httpUpdate.onProgress(update_progress);
httpUpdate.onError(update_error);
t_httpUpdate_return ret = httpUpdate.update(client, URL_fw_Bin);
switch (ret)
{
case HTTP_UPDATE_FAILED:
Serial.printf("HTTP_UPDATE_FAILD Error (%d): %s\n", httpUpdate.getLastError(), httpUpdate.getLastErrorString().c_str());
break;
case HTTP_UPDATE_NO_UPDATES:
Serial.println("HTTP_UPDATE_NO_UPDATES");
break;
case HTTP_UPDATE_OK:
Serial.println("HTTP_UPDATE_OK");
break;
}
}
private:
Updater_() = default;
bool FirmwareVersionCheck()
{
DisplayManager.clear();
DisplayManager.printText(0, 6, "CHECK", true, true);
DisplayManager.show();
String payload;
int httpCode;
String fwurl = "";
fwurl += URL_fw_Version;
fwurl += "?";
fwurl += String(rand());
Serial.println(fwurl);
WiFiClientSecure *client = new WiFiClientSecure;
public:
static Updater_ &getInstance();
void setup();
bool checkUpdate(bool);
void updateFirmware();
};
if (client)
{
client->setCACert(rootCACertificate);
HTTPClient https;
if (https.begin(*client, fwurl))
{ // HTTPS
Serial.print("[HTTPS] GET...\n");
// start connection and send HTTP header
delay(100);
httpCode = https.GET();
delay(100);
if (httpCode == HTTP_CODE_OK) // if version received
{
payload = https.getString(); // save received version
}
else
{
Serial.print("error in downloading version file:");
Serial.println(httpCode);
}
https.end();
}
delete client;
}
if (httpCode == HTTP_CODE_OK) // if version received
{
payload.trim();
if (payload.equals(VERSION))
{
Serial.printf("\nDevice already on latest firmware version:%s\n", VERSION);
DisplayManager.clear();
DisplayManager.printText(0, 6, "NO UP :(", true, true);
DisplayManager.show();
delay(1000);
return 0;
}
else
{
Serial.println(payload);
Serial.println("New firmware detected");
DisplayManager.printText(0, 6, payload.c_str(), true, true);
return 1;
}
}
return 0;
}
extern Updater_ &Updater;
#endif