Merge pull request #36 from Elfish/main
Various changes to support AWTRIX 2 hardware
This commit is contained in:
13
docs/api.md
13
docs/api.md
@@ -9,16 +9,17 @@ With HTTP, make GET request to `http://[IP]/api/stats`
|
|||||||
## Update
|
## 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.
|
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:
|
You can start the update with update button in HA or:
|
||||||
| Topic | URL | Payload/Body | HTTP Header | HTTP method |
|
|
||||||
| --- | --- | --- |--- |--- |
|
| Topic | URL | Payload/Body | HTTP Header | HTTP method |
|
||||||
| `[PREFIX]/doupdate` |`http://[IP]/api/doupdate` | JSON | empty payload/body | POST |
|
| --- | --- | --- | --- | --- |
|
||||||
|
| `[PREFIX]/doupdate` |`http://[IP]/api/doupdate` | JSON | empty payload/body | POST |
|
||||||
|
|
||||||
## Add custom app
|
## Add custom app
|
||||||
create custom apps or notifications to display your own text and icons.
|
create custom apps or notifications to display your own text and icons.
|
||||||
Have a look at [this section](custom?id=custom-apps-and-notifications)
|
Have a look at [this section](custom?id=custom-apps-and-notifications)
|
||||||
|
|
||||||
| Topic | URL | Payload/Body | HTTP Header | HTTP method |
|
| Topic | URL | Payload/Body | Query parameters | HTTP method |
|
||||||
| --- | --- | --- |--- |--- |
|
| --- | --- | --- | --- | --- |
|
||||||
| `[PREFIX]/custom/[appname]` |`http://[IP]/api/custom` | JSON | name = [appname] | POST |
|
| `[PREFIX]/custom/[appname]` |`http://[IP]/api/custom` | JSON | name = [appname] | POST |
|
||||||
|
|
||||||
## Dismiss Notification
|
## Dismiss Notification
|
||||||
@@ -184,6 +185,6 @@ Here's an example JSON object to start a timer for 1 hour, 30 minutes, and 10 se
|
|||||||
"minutes": 30,
|
"minutes": 30,
|
||||||
"seconds": 10,
|
"seconds": 10,
|
||||||
"sound": "friends"
|
"sound": "friends"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ lib_deps =
|
|||||||
plerup/EspSoftwareSerial@^8.0.1
|
plerup/EspSoftwareSerial@^8.0.1
|
||||||
h2zero/NimBLE-Arduino@^1.4.1
|
h2zero/NimBLE-Arduino@^1.4.1
|
||||||
|
|
||||||
|
|
||||||
[env:awtrix_upgrade]
|
[env:awtrix_upgrade]
|
||||||
platform = https://github.com/platformio/platform-espressif32.git
|
platform = https://github.com/platformio/platform-espressif32.git
|
||||||
board = wemos_d1_mini32
|
board = wemos_d1_mini32
|
||||||
@@ -36,6 +37,7 @@ framework = arduino
|
|||||||
build_flags = -DAWTRIX_UPGRADE -D MQTT_MAX_PACKET_SIZE=1024
|
build_flags = -DAWTRIX_UPGRADE -D MQTT_MAX_PACKET_SIZE=1024
|
||||||
lib_deps =
|
lib_deps =
|
||||||
adafruit/Adafruit BME280 Library@^2.2.2
|
adafruit/Adafruit BME280 Library@^2.2.2
|
||||||
|
plerup/EspSoftwareSerial@^8.0.1
|
||||||
bblanchon/ArduinoJson@^6.20.0
|
bblanchon/ArduinoJson@^6.20.0
|
||||||
evert-arias/EasyButton@^2.0.1
|
evert-arias/EasyButton@^2.0.1
|
||||||
fastled/FastLED@^3.5.0
|
fastled/FastLED@^3.5.0
|
||||||
|
|||||||
12
src/Apps.h
12
src/Apps.h
@@ -251,7 +251,13 @@ void AlarmApp(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state)
|
|||||||
if (ALARM_SOUND != "")
|
if (ALARM_SOUND != "")
|
||||||
{
|
{
|
||||||
if (!PeripheryManager.isPlaying())
|
if (!PeripheryManager.isPlaying())
|
||||||
|
{
|
||||||
|
#ifdef ULANZI
|
||||||
PeripheryManager.playFromFile("/MELODIES/" + ALARM_SOUND + ".txt");
|
PeripheryManager.playFromFile("/MELODIES/" + ALARM_SOUND + ".txt");
|
||||||
|
#else
|
||||||
|
PeripheryManager.playFromFile(DFMINI_MP3_ALARM);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -271,7 +277,13 @@ void TimerApp(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state)
|
|||||||
if (TIMER_SOUND != "")
|
if (TIMER_SOUND != "")
|
||||||
{
|
{
|
||||||
if (!PeripheryManager.isPlaying())
|
if (!PeripheryManager.isPlaying())
|
||||||
|
{
|
||||||
|
#ifdef ULANZI
|
||||||
PeripheryManager.playFromFile("/MELODIES/" + TIMER_SOUND + ".txt");
|
PeripheryManager.playFromFile("/MELODIES/" + TIMER_SOUND + ".txt");
|
||||||
|
#else
|
||||||
|
PeripheryManager.playFromFile(DFMINI_MP3_TIMER);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -106,8 +106,10 @@ const char HAramClass[] PROGMEM = {"data_size"};
|
|||||||
const char HAramUnit[] PROGMEM = {"B"};
|
const char HAramUnit[] PROGMEM = {"B"};
|
||||||
|
|
||||||
// JSON properites
|
// JSON properites
|
||||||
|
#ifdef ULANZI
|
||||||
const char BatKey[] PROGMEM = {"bat"};
|
const char BatKey[] PROGMEM = {"bat"};
|
||||||
const char BatRawKey[] PROGMEM = {"bat_raw"};
|
const char BatRawKey[] PROGMEM = {"bat_raw"};
|
||||||
|
#endif
|
||||||
const char LuxKey[] PROGMEM = {"lux"};
|
const char LuxKey[] PROGMEM = {"lux"};
|
||||||
const char LDRRawKey[] PROGMEM = {"ldr_raw"};
|
const char LDRRawKey[] PROGMEM = {"ldr_raw"};
|
||||||
const char BrightnessKey[] PROGMEM = {"bri"};
|
const char BrightnessKey[] PROGMEM = {"bri"};
|
||||||
|
|||||||
@@ -106,8 +106,10 @@ extern const char HAramClass[];
|
|||||||
extern const char HAramUnit[];
|
extern const char HAramUnit[];
|
||||||
|
|
||||||
// JSON properites
|
// JSON properites
|
||||||
|
#ifdef ULANZI
|
||||||
extern const char BatKey[];
|
extern const char BatKey[];
|
||||||
extern const char BatRawKey[];
|
extern const char BatRawKey[];
|
||||||
|
#endif
|
||||||
extern const char LuxKey[];
|
extern const char LuxKey[];
|
||||||
extern const char LDRRawKey[];
|
extern const char LDRRawKey[];
|
||||||
extern const char BrightnessKey[];
|
extern const char BrightnessKey[];
|
||||||
|
|||||||
@@ -30,7 +30,12 @@ fs::File gifFile;
|
|||||||
GifPlayer gif;
|
GifPlayer gif;
|
||||||
bool showGif;
|
bool showGif;
|
||||||
CRGB leds[MATRIX_WIDTH * MATRIX_HEIGHT];
|
CRGB leds[MATRIX_WIDTH * MATRIX_HEIGHT];
|
||||||
|
// Awtrix Big / Ulanzi
|
||||||
FastLED_NeoMatrix matrix(leds, 32, 8, NEO_MATRIX_TOP + NEO_MATRIX_LEFT + NEO_MATRIX_ROWS + NEO_MATRIX_ZIGZAG);
|
FastLED_NeoMatrix matrix(leds, 32, 8, NEO_MATRIX_TOP + NEO_MATRIX_LEFT + NEO_MATRIX_ROWS + NEO_MATRIX_ZIGZAG);
|
||||||
|
// Awtrid Midi
|
||||||
|
//FastLED_NeoMatrix matrix(leds, 8, 8, 4, 1, NEO_MATRIX_TOP + NEO_MATRIX_LEFT + NEO_MATRIX_ROWS + NEO_MATRIX_PROGRESSIVE);
|
||||||
|
// Awtrix Mini?
|
||||||
|
//FastLED_NeoMatrix(leds, 32, 8, NEO_MATRIX_TOP + NEO_MATRIX_LEFT + NEO_MATRIX_COLUMNS + NEO_MATRIX_ZIGZAG);
|
||||||
|
|
||||||
MatrixDisplayUi ui(&matrix);
|
MatrixDisplayUi ui(&matrix);
|
||||||
|
|
||||||
@@ -271,7 +276,11 @@ void DisplayManager_::generateCustomPage(String name, const char *json)
|
|||||||
|
|
||||||
if (doc.containsKey("sound"))
|
if (doc.containsKey("sound"))
|
||||||
{
|
{
|
||||||
|
#ifdef ULANZI
|
||||||
customApp.sound = ("/" + doc["sound"].as<String>() + ".txt");
|
customApp.sound = ("/" + doc["sound"].as<String>() + ".txt");
|
||||||
|
#else
|
||||||
|
customApp.sound = doc["sound"].as<String>();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -390,7 +399,11 @@ void DisplayManager_::generateNotification(const char *json)
|
|||||||
|
|
||||||
if (doc.containsKey("sound"))
|
if (doc.containsKey("sound"))
|
||||||
{
|
{
|
||||||
|
#ifdef ULANZI
|
||||||
PeripheryManager.playFromFile("/MELODIES/" + doc["sound"].as<String>() + ".txt");
|
PeripheryManager.playFromFile("/MELODIES/" + doc["sound"].as<String>() + ".txt");
|
||||||
|
#else
|
||||||
|
PeripheryManager.playFromFile(doc["sound"].as<String>());
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (doc.containsKey("bar"))
|
if (doc.containsKey("bar"))
|
||||||
@@ -832,17 +845,13 @@ void DisplayManager_::updateAppVector(const char *json)
|
|||||||
callback = HumApp;
|
callback = HumApp;
|
||||||
SHOW_HUM = show;
|
SHOW_HUM = show;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ULANZI
|
#ifdef ULANZI
|
||||||
|
|
||||||
else if (name == "bat")
|
else if (name == "bat")
|
||||||
{
|
{
|
||||||
callback = BatApp;
|
callback = BatApp;
|
||||||
SHOW_BAT = show;
|
SHOW_BAT = show;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// If the app is not one of the built-in apps, check if it's already in the vector
|
// If the app is not one of the built-in apps, check if it's already in the vector
|
||||||
|
|||||||
@@ -19,7 +19,9 @@ void startLittleFS()
|
|||||||
{
|
{
|
||||||
if (LittleFS.begin())
|
if (LittleFS.begin())
|
||||||
{
|
{
|
||||||
|
#ifdef ULANZI
|
||||||
LittleFS.mkdir("/MELODIES");
|
LittleFS.mkdir("/MELODIES");
|
||||||
|
#endif
|
||||||
LittleFS.mkdir("/ICONS");
|
LittleFS.mkdir("/ICONS");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -32,31 +34,30 @@ void startLittleFS()
|
|||||||
|
|
||||||
void loadDevSettings()
|
void loadDevSettings()
|
||||||
{
|
{
|
||||||
Serial.println("laodSettings");
|
Serial.println("loadSettings");
|
||||||
File file = LittleFS.open("/dev.json", "r");
|
if (LittleFS.exists("/dev.json"))
|
||||||
if (!file)
|
|
||||||
{
|
{
|
||||||
return;
|
File file = LittleFS.open("/dev.json", "r");
|
||||||
}
|
DynamicJsonDocument doc(128);
|
||||||
DynamicJsonDocument doc(128);
|
DeserializationError error = deserializeJson(doc, file);
|
||||||
DeserializationError error = deserializeJson(doc, file);
|
if (error)
|
||||||
if (error)
|
{
|
||||||
{
|
Serial.println(F("Failed to read dev settings"));
|
||||||
Serial.println(F("Failed to read dev settings"));
|
return;
|
||||||
return;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (doc.containsKey("bootsound"))
|
if (doc.containsKey("bootsound"))
|
||||||
{
|
{
|
||||||
BOOT_SOUND = doc["bootsound"].as<String>();
|
BOOT_SOUND = doc["bootsound"].as<String>();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (doc.containsKey("bootsound"))
|
if (doc.containsKey("bootsound"))
|
||||||
{
|
{
|
||||||
UPPERCASE_LETTERS = doc["uppercase"].as<bool>();
|
UPPERCASE_LETTERS = doc["uppercase"].as<bool>();
|
||||||
}
|
}
|
||||||
|
|
||||||
file.close();
|
file.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void loadSettings()
|
void loadSettings()
|
||||||
@@ -83,6 +84,11 @@ void loadSettings()
|
|||||||
SHOW_BAT = Settings.getBool("BAT", true);
|
SHOW_BAT = Settings.getBool("BAT", true);
|
||||||
#endif
|
#endif
|
||||||
SOUND_ACTIVE = Settings.getBool("SOUND", true);
|
SOUND_ACTIVE = Settings.getBool("SOUND", true);
|
||||||
|
#ifndef ULANZI
|
||||||
|
//Settings.putUInt("VOL", VOLUME_PERCENT);
|
||||||
|
VOLUME_PERCENT = Settings.getUInt("VOL", 50);
|
||||||
|
VOLUME = map(VOLUME_PERCENT, 0, 100, 0, 30);
|
||||||
|
#endif
|
||||||
Settings.end();
|
Settings.end();
|
||||||
uniqueID = getID();
|
uniqueID = getID();
|
||||||
MQTT_PREFIX = String(uniqueID);
|
MQTT_PREFIX = String(uniqueID);
|
||||||
@@ -112,6 +118,9 @@ void saveSettings()
|
|||||||
Settings.putBool("BAT", SHOW_BAT);
|
Settings.putBool("BAT", SHOW_BAT);
|
||||||
#endif
|
#endif
|
||||||
Settings.putBool("SOUND", SOUND_ACTIVE);
|
Settings.putBool("SOUND", SOUND_ACTIVE);
|
||||||
|
#ifndef ULANZI
|
||||||
|
Settings.putUInt("VOL", VOLUME_PERCENT);
|
||||||
|
#endif
|
||||||
Settings.end();
|
Settings.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -185,7 +194,7 @@ bool ALARM_ACTIVE;
|
|||||||
uint16_t TEXTCOLOR_565 = 0xFFFF;
|
uint16_t TEXTCOLOR_565 = 0xFFFF;
|
||||||
bool SOUND_ACTIVE;
|
bool SOUND_ACTIVE;
|
||||||
String BOOT_SOUND = "";
|
String BOOT_SOUND = "";
|
||||||
uint8_t VOLUME;
|
|
||||||
uint8_t VOLUME_PERCENT;
|
uint8_t VOLUME_PERCENT;
|
||||||
|
uint8_t VOLUME;
|
||||||
int MATRIX_LAYOUT;
|
int MATRIX_LAYOUT;
|
||||||
bool UPDATE_AVAILABLE = false;
|
bool UPDATE_AVAILABLE = false;
|
||||||
@@ -68,8 +68,8 @@ extern bool START_ON_MONDAY;
|
|||||||
extern bool IS_CELSIUS;
|
extern bool IS_CELSIUS;
|
||||||
extern bool SOUND_ACTIVE;
|
extern bool SOUND_ACTIVE;
|
||||||
extern String BOOT_SOUND;
|
extern String BOOT_SOUND;
|
||||||
extern uint8_t VOLUME;
|
|
||||||
extern uint8_t VOLUME_PERCENT;
|
extern uint8_t VOLUME_PERCENT;
|
||||||
|
extern uint8_t VOLUME;
|
||||||
extern int MATRIX_LAYOUT;
|
extern int MATRIX_LAYOUT;
|
||||||
extern bool UPDATE_AVAILABLE;
|
extern bool UPDATE_AVAILABLE;
|
||||||
void loadSettings();
|
void loadSettings();
|
||||||
|
|||||||
@@ -360,16 +360,16 @@ void MQTTManager_::setup()
|
|||||||
humidity->setName(HAhumName);
|
humidity->setName(HAhumName);
|
||||||
humidity->setDeviceClass(HAhumClass);
|
humidity->setDeviceClass(HAhumClass);
|
||||||
humidity->setUnitOfMeasurement(HAhumUnit);
|
humidity->setUnitOfMeasurement(HAhumUnit);
|
||||||
|
|
||||||
#ifdef ULANZI
|
#ifdef ULANZI
|
||||||
|
|
||||||
sprintf(batID, HAbatID, macStr);
|
sprintf(batID, HAbatID, macStr);
|
||||||
battery = new HASensor(batID);
|
battery = new HASensor(batID);
|
||||||
battery->setIcon(HAbatIcon);
|
battery->setIcon(HAbatIcon);
|
||||||
battery->setName(HAbatName);
|
battery->setName(HAbatName);
|
||||||
battery->setDeviceClass(HAbatClass);
|
battery->setDeviceClass(HAbatClass);
|
||||||
battery->setUnitOfMeasurement(HAbatUnit);
|
battery->setUnitOfMeasurement(HAbatUnit);
|
||||||
#endif
|
|
||||||
|
|
||||||
|
#endif
|
||||||
sprintf(luxID, HAluxID, macStr);
|
sprintf(luxID, HAluxID, macStr);
|
||||||
illuminance = new HASensor(luxID);
|
illuminance = new HASensor(luxID);
|
||||||
illuminance->setIcon(HAluxIcon);
|
illuminance->setIcon(HAluxIcon);
|
||||||
@@ -458,8 +458,8 @@ void MQTTManager_::sendStats()
|
|||||||
#ifdef ULANZI
|
#ifdef ULANZI
|
||||||
snprintf(buffer, 5, "%d", BATTERY_PERCENT);
|
snprintf(buffer, 5, "%d", BATTERY_PERCENT);
|
||||||
battery->setValue(buffer);
|
battery->setValue(buffer);
|
||||||
#endif
|
|
||||||
|
|
||||||
|
#endif
|
||||||
snprintf(buffer, 5, "%.0f", CURRENT_TEMP);
|
snprintf(buffer, 5, "%.0f", CURRENT_TEMP);
|
||||||
temperature->setValue(buffer);
|
temperature->setValue(buffer);
|
||||||
|
|
||||||
|
|||||||
@@ -28,8 +28,12 @@ enum MenuState
|
|||||||
WeekdayMenu,
|
WeekdayMenu,
|
||||||
TempMenu,
|
TempMenu,
|
||||||
Appmenu,
|
Appmenu,
|
||||||
|
#ifdef ULANZI
|
||||||
|
SoundMenu
|
||||||
|
#else
|
||||||
SoundMenu,
|
SoundMenu,
|
||||||
VolumeMenu
|
VolumeMenu
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *menuItems[] PROGMEM = {
|
const char *menuItems[] PROGMEM = {
|
||||||
@@ -45,10 +49,17 @@ const char *menuItems[] PROGMEM = {
|
|||||||
"TEMP",
|
"TEMP",
|
||||||
"APPS",
|
"APPS",
|
||||||
"SOUND",
|
"SOUND",
|
||||||
|
#ifndef ULANZI
|
||||||
|
"VOLUME" ,
|
||||||
|
#endif
|
||||||
"UPDATE"};
|
"UPDATE"};
|
||||||
|
|
||||||
int8_t menuIndex = 0;
|
int8_t menuIndex = 0;
|
||||||
|
#ifdef ULANZI
|
||||||
uint8_t menuItemCount = 13;
|
uint8_t menuItemCount = 13;
|
||||||
|
#else
|
||||||
|
uint8_t menuItemCount = 14;
|
||||||
|
#endif
|
||||||
|
|
||||||
const char *timeFormat[] PROGMEM = {
|
const char *timeFormat[] PROGMEM = {
|
||||||
"%H:%M:%S",
|
"%H:%M:%S",
|
||||||
@@ -193,6 +204,10 @@ String MenuManager_::menutext()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
#ifndef ULANZI
|
||||||
|
case VolumeMenu:
|
||||||
|
return String(VOLUME_PERCENT) + "%";
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -250,10 +265,13 @@ void MenuManager_::rightButton()
|
|||||||
case TempMenu:
|
case TempMenu:
|
||||||
IS_CELSIUS = !IS_CELSIUS;
|
IS_CELSIUS = !IS_CELSIUS;
|
||||||
break;
|
break;
|
||||||
|
#ifndef ULANZI
|
||||||
case VolumeMenu:
|
case VolumeMenu:
|
||||||
VOLUME_PERCENT = (VOLUME_PERCENT % 100) + 1;
|
if ((VOLUME_PERCENT + 1) > 100)
|
||||||
VOLUME = map(VOLUME_PERCENT, 0, 100, 0, 30);
|
VOLUME_PERCENT = 0;
|
||||||
PeripheryManager.setVolume(VOLUME);
|
else
|
||||||
|
VOLUME_PERCENT++;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -314,10 +332,13 @@ void MenuManager_::leftButton()
|
|||||||
case SoundMenu:
|
case SoundMenu:
|
||||||
SOUND_ACTIVE = !SOUND_ACTIVE;
|
SOUND_ACTIVE = !SOUND_ACTIVE;
|
||||||
break;
|
break;
|
||||||
|
#ifndef ULANZI
|
||||||
case VolumeMenu:
|
case VolumeMenu:
|
||||||
VOLUME_PERCENT = (VOLUME_PERCENT % 100) + 1;
|
if ((VOLUME_PERCENT - 1) < 0)
|
||||||
VOLUME = map(VOLUME_PERCENT, 0, 100, 0, 30);
|
VOLUME_PERCENT = 100;
|
||||||
PeripheryManager.setVolume(VOLUME);
|
else
|
||||||
|
VOLUME_PERCENT--;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -372,11 +393,10 @@ void MenuManager_::selectButton()
|
|||||||
currentState = SoundMenu;
|
currentState = SoundMenu;
|
||||||
break;
|
break;
|
||||||
case 12:
|
case 12:
|
||||||
#ifdef AWTRIX_UPGRADE
|
#ifndef ULANZI
|
||||||
currentState = VolumeMenu;
|
currentState = VolumeMenu;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
case 13:
|
case 13:
|
||||||
if (UpdateManager.checkUpdate(true))
|
if (UpdateManager.checkUpdate(true))
|
||||||
{
|
{
|
||||||
@@ -454,12 +474,6 @@ void MenuManager_::selectButtonLong()
|
|||||||
DisplayManager.applyAllSettings();
|
DisplayManager.applyAllSettings();
|
||||||
saveSettings();
|
saveSettings();
|
||||||
break;
|
break;
|
||||||
case VolumeMenu:
|
|
||||||
#ifdef AWTRIX_UPGRADE
|
|
||||||
VOLUME = map(VOLUME_PERCENT, 0, 100, 0, 30);
|
|
||||||
saveSettings();
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
case TimeFormatMenu:
|
case TimeFormatMenu:
|
||||||
TIME_FORMAT = timeFormat[timeFormatIndex];
|
TIME_FORMAT = timeFormat[timeFormatIndex];
|
||||||
saveSettings();
|
saveSettings();
|
||||||
@@ -476,6 +490,13 @@ void MenuManager_::selectButtonLong()
|
|||||||
DisplayManager.loadNativeApps();
|
DisplayManager.loadNativeApps();
|
||||||
saveSettings();
|
saveSettings();
|
||||||
break;
|
break;
|
||||||
|
#ifndef ULANZI
|
||||||
|
case VolumeMenu:
|
||||||
|
VOLUME = map(VOLUME_PERCENT, 0, 100, 0, 30);
|
||||||
|
PeripheryManager.setVolume(VOLUME);
|
||||||
|
saveSettings();
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,13 @@
|
|||||||
#include <PeripheryManager.h>
|
#include <PeripheryManager.h>
|
||||||
|
#ifdef ULANZI
|
||||||
#include <melody_player.h>
|
#include <melody_player.h>
|
||||||
#include <melody_factory.h>
|
#include <melody_factory.h>
|
||||||
|
#include "Adafruit_SHT31.h"
|
||||||
|
#else
|
||||||
|
#include "Adafruit_BME280.h"
|
||||||
|
#include "SoftwareSerial.h"
|
||||||
|
#include <DFMiniMp3.h>
|
||||||
|
#endif
|
||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
#include "DisplayManager.h"
|
#include "DisplayManager.h"
|
||||||
#include "MQTTManager.h"
|
#include "MQTTManager.h"
|
||||||
@@ -17,32 +24,37 @@
|
|||||||
#define BUTTON_UP_PIN 26
|
#define BUTTON_UP_PIN 26
|
||||||
#define BUTTON_DOWN_PIN 14
|
#define BUTTON_DOWN_PIN 14
|
||||||
#define BUTTON_SELECT_PIN 27
|
#define BUTTON_SELECT_PIN 27
|
||||||
|
#define I2C_SCL_PIN 22
|
||||||
|
#define I2C_SDA_PIN 21
|
||||||
#else
|
#else
|
||||||
// Pinouts für das WEMOS_D1_MINI32-Environment
|
// Pinouts für das WEMOS_D1_MINI32-Environment
|
||||||
#define BUZZER_PIN -1
|
|
||||||
#define LDR_PIN A0
|
#define LDR_PIN A0
|
||||||
#define BUTTON_UP_PIN D0
|
#define BUTTON_UP_PIN D0
|
||||||
#define BUTTON_DOWN_PIN D4
|
#define BUTTON_DOWN_PIN D8
|
||||||
#define BUTTON_SELECT_PIN D8
|
#define BUTTON_SELECT_PIN D4
|
||||||
|
#define DFPLAYER_RX D7
|
||||||
|
#define DFPLAYER_TX D5
|
||||||
|
#define I2C_SCL_PIN D1
|
||||||
|
#define I2C_SDA_PIN D3
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef ULANZI
|
#ifdef ULANZI
|
||||||
Adafruit_SHT31 sht31;
|
Adafruit_SHT31 sht31;
|
||||||
#else
|
#else
|
||||||
|
|
||||||
class Mp3Notify
|
|
||||||
{
|
|
||||||
};
|
|
||||||
Adafruit_BME280 bme280;
|
Adafruit_BME280 bme280;
|
||||||
SoftwareSerial mySoftwareSerial(D7, D5); // RX, TX
|
TwoWire I2Cbme280 = TwoWire(0);
|
||||||
typedef DFMiniMp3<SoftwareSerial, Mp3Notify> DfMp3;
|
|
||||||
DfMp3 dfmp3(mySoftwareSerial);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
EasyButton button_left(BUTTON_UP_PIN);
|
EasyButton button_left(BUTTON_UP_PIN);
|
||||||
EasyButton button_right(BUTTON_DOWN_PIN);
|
EasyButton button_right(BUTTON_DOWN_PIN);
|
||||||
EasyButton button_select(BUTTON_SELECT_PIN);
|
EasyButton button_select(BUTTON_SELECT_PIN);
|
||||||
|
#ifdef ULANZI
|
||||||
MelodyPlayer player(BUZZER_PIN, LOW);
|
MelodyPlayer player(BUZZER_PIN, LOW);
|
||||||
|
#else
|
||||||
|
class Mp3Notify{};
|
||||||
|
SoftwareSerial mySoftwareSerial(DFPLAYER_RX, DFPLAYER_TX); // RX, TX
|
||||||
|
DFMiniMp3<SoftwareSerial, Mp3Notify> dfmp3(mySoftwareSerial);
|
||||||
|
#endif
|
||||||
|
|
||||||
#define USED_PHOTOCELL LightDependentResistor::GL5516
|
#define USED_PHOTOCELL LightDependentResistor::GL5516
|
||||||
|
|
||||||
@@ -67,11 +79,6 @@ float sampleSum = 0.0;
|
|||||||
float sampleAverage = 0.0;
|
float sampleAverage = 0.0;
|
||||||
float brightnessPercent = 0.0;
|
float brightnessPercent = 0.0;
|
||||||
|
|
||||||
#ifdef awrtrix_upgrade
|
|
||||||
class Mp3Notify;
|
|
||||||
SoftwareSerial mySoftwareSerial(D7, D5); // RX, TX
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// The getter for the instantiated singleton instance
|
// The getter for the instantiated singleton instance
|
||||||
PeripheryManager_ &PeripheryManager_::getInstance()
|
PeripheryManager_ &PeripheryManager_::getInstance()
|
||||||
{
|
{
|
||||||
@@ -84,6 +91,7 @@ PeripheryManager_ &PeripheryManager = PeripheryManager.getInstance();
|
|||||||
|
|
||||||
void left_button_pressed()
|
void left_button_pressed()
|
||||||
{
|
{
|
||||||
|
PeripheryManager.playFromFile(DFMINI_MP3_CLICK);
|
||||||
if (AP_MODE)
|
if (AP_MODE)
|
||||||
{
|
{
|
||||||
--MATRIX_LAYOUT;
|
--MATRIX_LAYOUT;
|
||||||
@@ -101,6 +109,7 @@ void left_button_pressed()
|
|||||||
|
|
||||||
void right_button_pressed()
|
void right_button_pressed()
|
||||||
{
|
{
|
||||||
|
PeripheryManager.playFromFile(DFMINI_MP3_CLICK);
|
||||||
if (AP_MODE)
|
if (AP_MODE)
|
||||||
{
|
{
|
||||||
++MATRIX_LAYOUT;
|
++MATRIX_LAYOUT;
|
||||||
@@ -118,18 +127,21 @@ void right_button_pressed()
|
|||||||
|
|
||||||
void select_button_pressed()
|
void select_button_pressed()
|
||||||
{
|
{
|
||||||
|
PeripheryManager.playFromFile(DFMINI_MP3_CLICK);
|
||||||
DisplayManager.selectButton();
|
DisplayManager.selectButton();
|
||||||
MenuManager.selectButton();
|
MenuManager.selectButton();
|
||||||
}
|
}
|
||||||
|
|
||||||
void select_button_pressed_long()
|
void select_button_pressed_long()
|
||||||
{
|
{
|
||||||
|
PeripheryManager.playFromFile(DFMINI_MP3_CLICK);
|
||||||
DisplayManager.selectButtonLong();
|
DisplayManager.selectButtonLong();
|
||||||
MenuManager.selectButtonLong();
|
MenuManager.selectButtonLong();
|
||||||
}
|
}
|
||||||
|
|
||||||
void select_button_tripple()
|
void select_button_tripple()
|
||||||
{
|
{
|
||||||
|
PeripheryManager.playFromFile(DFMINI_MP3_CLICK_ON);
|
||||||
if (MATRIX_OFF)
|
if (MATRIX_OFF)
|
||||||
{
|
{
|
||||||
DisplayManager.MatrixState(true);
|
DisplayManager.MatrixState(true);
|
||||||
@@ -147,13 +159,14 @@ void PeripheryManager_::playBootSound()
|
|||||||
if (BOOT_SOUND == "")
|
if (BOOT_SOUND == "")
|
||||||
{
|
{
|
||||||
#ifdef ULANZI
|
#ifdef ULANZI
|
||||||
|
// no standard sound
|
||||||
const int nNotes = 6;
|
const int nNotes = 6;
|
||||||
String notes[nNotes] = {"E5", "C5", "G4", "E4", "G4", "C5"};
|
String notes[nNotes] = {"E5", "C5", "G4", "E4", "G4", "C5"};
|
||||||
const int timeUnit = 150;
|
const int timeUnit = 150;
|
||||||
Melody melody = MelodyFactory.load("Bootsound", timeUnit, notes, nNotes);
|
Melody melody = MelodyFactory.load("Bootsound", timeUnit, notes, nNotes);
|
||||||
player.playAsync(melody);
|
player.playAsync(melody);
|
||||||
#else
|
#else
|
||||||
// no standardsound
|
playFromFile(DFMINI_MP3_BOOT);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -161,7 +174,7 @@ void PeripheryManager_::playBootSound()
|
|||||||
#ifdef ULANZI
|
#ifdef ULANZI
|
||||||
playFromFile("/MELODIES/" + BOOT_SOUND + ".txt");
|
playFromFile("/MELODIES/" + BOOT_SOUND + ".txt");
|
||||||
#else
|
#else
|
||||||
dfmp3.playMp3FolderTrack(BOOT_SOUND.toInt());
|
playFromFile(BOOT_SOUND);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -171,16 +184,20 @@ void PeripheryManager_::stopSound()
|
|||||||
#ifdef ULANZI
|
#ifdef ULANZI
|
||||||
player.stop();
|
player.stop();
|
||||||
#else
|
#else
|
||||||
dfmp3.stop();
|
dfmp3.stopAdvertisement();
|
||||||
|
delay(50);
|
||||||
|
dfmp3.stop();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef ULANZI
|
||||||
void PeripheryManager_::setVolume(uint8_t vol)
|
void PeripheryManager_::setVolume(uint8_t vol)
|
||||||
{
|
{
|
||||||
#ifdef AWTRIX_UPGRADE
|
uint8_t curVolume = dfmp3.getVolume(); // need to read volume in order to work. Donno why! :(
|
||||||
dfmp3.setVolume(vol);
|
dfmp3.setVolume(vol);
|
||||||
#endif
|
delay(50);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void PeripheryManager_::playFromFile(String file)
|
void PeripheryManager_::playFromFile(String file)
|
||||||
{
|
{
|
||||||
@@ -199,11 +216,14 @@ bool PeripheryManager_::isPlaying()
|
|||||||
#ifdef ULANZI
|
#ifdef ULANZI
|
||||||
return player.isPlaying();
|
return player.isPlaying();
|
||||||
#else
|
#else
|
||||||
return false;
|
if ((dfmp3.getStatus() & 0xff) == 0x01) // 0x01 = DfMp3_StatusState_Playing
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void fistStart()
|
void firstStart()
|
||||||
{
|
{
|
||||||
#ifdef ULANZI
|
#ifdef ULANZI
|
||||||
uint16_t ADCVALUE = analogRead(BATTERY_PIN);
|
uint16_t ADCVALUE = analogRead(BATTERY_PIN);
|
||||||
@@ -226,8 +246,14 @@ void PeripheryManager_::setup()
|
|||||||
{
|
{
|
||||||
startTime = millis();
|
startTime = millis();
|
||||||
pinMode(LDR_PIN, INPUT);
|
pinMode(LDR_PIN, INPUT);
|
||||||
|
#ifdef ULANZI
|
||||||
pinMode(BUZZER_PIN, OUTPUT);
|
pinMode(BUZZER_PIN, OUTPUT);
|
||||||
digitalWrite(BUZZER_PIN, LOW);
|
digitalWrite(BUZZER_PIN, LOW);
|
||||||
|
#else
|
||||||
|
dfmp3.begin();
|
||||||
|
delay(100);
|
||||||
|
setVolume(VOLUME);
|
||||||
|
#endif
|
||||||
button_left.begin();
|
button_left.begin();
|
||||||
button_right.begin();
|
button_right.begin();
|
||||||
button_select.begin();
|
button_select.begin();
|
||||||
@@ -236,20 +262,21 @@ void PeripheryManager_::setup()
|
|||||||
button_select.onPressed(select_button_pressed);
|
button_select.onPressed(select_button_pressed);
|
||||||
button_select.onPressedFor(1000, select_button_pressed_long);
|
button_select.onPressedFor(1000, select_button_pressed_long);
|
||||||
button_select.onSequence(2, 300, select_button_tripple);
|
button_select.onSequence(2, 300, select_button_tripple);
|
||||||
Wire.begin(21, 22);
|
|
||||||
#ifdef ULANZI
|
#ifdef ULANZI
|
||||||
|
Wire.begin(I2C_SDA_PIN, I2C_SCL_PIN);
|
||||||
sht31.begin(0x44);
|
sht31.begin(0x44);
|
||||||
#else
|
#else
|
||||||
bme280.begin();
|
I2Cbme280.begin(I2C_SDA_PIN, I2C_SCL_PIN);
|
||||||
|
bme280.begin(0x76, &I2Cbme280);
|
||||||
dfmp3.begin();
|
dfmp3.begin();
|
||||||
#endif
|
#endif
|
||||||
photocell.setPhotocellPositionOnGround(false);
|
photocell.setPhotocellPositionOnGround(false);
|
||||||
fistStart();
|
firstStart();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PeripheryManager_::tick()
|
void PeripheryManager_::tick()
|
||||||
{
|
{
|
||||||
|
|
||||||
MQTTManager.sendButton(0, button_left.read());
|
MQTTManager.sendButton(0, button_left.read());
|
||||||
MQTTManager.sendButton(1, button_select.read());
|
MQTTManager.sendButton(1, button_select.read());
|
||||||
MQTTManager.sendButton(2, button_right.read());
|
MQTTManager.sendButton(2, button_right.read());
|
||||||
@@ -302,63 +329,61 @@ time_t lastAlarmTime = 0;
|
|||||||
|
|
||||||
void PeripheryManager_::checkAlarms()
|
void PeripheryManager_::checkAlarms()
|
||||||
{
|
{
|
||||||
File file = LittleFS.open("/alarms.json", "r");
|
if (LittleFS.exists("/alarms.json"))
|
||||||
if (!file)
|
|
||||||
{
|
{
|
||||||
return;
|
File file = LittleFS.open("/alarms.json", "r");
|
||||||
}
|
DynamicJsonDocument doc(file.size() * 1.33);
|
||||||
|
DeserializationError error = deserializeJson(doc, file);
|
||||||
DynamicJsonDocument doc(file.size() * 1.33);
|
if (error)
|
||||||
DeserializationError error = deserializeJson(doc, file);
|
|
||||||
if (error)
|
|
||||||
{
|
|
||||||
Serial.println(F("Failed to read Alarm file"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
JsonArray alarms = doc["alarms"];
|
|
||||||
file.close();
|
|
||||||
|
|
||||||
time_t now1 = time(nullptr);
|
|
||||||
struct tm *timeInfo;
|
|
||||||
timeInfo = localtime(&now1);
|
|
||||||
int currentHour = timeInfo->tm_hour;
|
|
||||||
int currentMinute = timeInfo->tm_min;
|
|
||||||
int currentDay = timeInfo->tm_wday - 1;
|
|
||||||
|
|
||||||
for (JsonObject alarm : alarms)
|
|
||||||
{
|
|
||||||
int alarmHour = alarm["hour"];
|
|
||||||
int alarmMinute = alarm["minute"];
|
|
||||||
String alarmDays = alarm["days"];
|
|
||||||
|
|
||||||
if (currentHour == alarmHour && currentMinute == alarmMinute && alarmDays.indexOf(String(currentDay)) != -1)
|
|
||||||
{
|
{
|
||||||
if (difftime(now1, lastAlarmTime) < MIN_ALARM_INTERVAL)
|
Serial.println(F("Failed to read Alarm file"));
|
||||||
{
|
return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ALARM_ACTIVE = true;
|
|
||||||
lastAlarmTime = now1;
|
|
||||||
|
|
||||||
if (alarm.containsKey("sound"))
|
|
||||||
{
|
|
||||||
ALARM_SOUND = alarm["sound"].as<String>();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ALARM_SOUND = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (alarm.containsKey("snooze"))
|
|
||||||
{
|
|
||||||
SNOOZE_TIME = alarm["snooze"].as<uint8_t>();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SNOOZE_TIME = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
JsonArray alarms = doc["alarms"];
|
||||||
|
file.close();
|
||||||
|
|
||||||
|
time_t now1 = time(nullptr);
|
||||||
|
struct tm *timeInfo;
|
||||||
|
timeInfo = localtime(&now1);
|
||||||
|
int currentHour = timeInfo->tm_hour;
|
||||||
|
int currentMinute = timeInfo->tm_min;
|
||||||
|
int currentDay = timeInfo->tm_wday - 1;
|
||||||
|
|
||||||
|
for (JsonObject alarm : alarms)
|
||||||
|
{
|
||||||
|
int alarmHour = alarm["hour"];
|
||||||
|
int alarmMinute = alarm["minute"];
|
||||||
|
String alarmDays = alarm["days"];
|
||||||
|
|
||||||
|
if (currentHour == alarmHour && currentMinute == alarmMinute && alarmDays.indexOf(String(currentDay)) != -1)
|
||||||
|
{
|
||||||
|
if (difftime(now1, lastAlarmTime) < MIN_ALARM_INTERVAL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ALARM_ACTIVE = true;
|
||||||
|
lastAlarmTime = now1;
|
||||||
|
|
||||||
|
if (alarm.containsKey("sound"))
|
||||||
|
{
|
||||||
|
ALARM_SOUND = alarm["sound"].as<String>();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ALARM_SOUND = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (alarm.containsKey("snooze"))
|
||||||
|
{
|
||||||
|
SNOOZE_TIME = alarm["snooze"].as<uint8_t>();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SNOOZE_TIME = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,12 +3,13 @@
|
|||||||
|
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include <EasyButton.h>
|
#include <EasyButton.h>
|
||||||
#ifdef ULANZI
|
#ifndef ULANZI
|
||||||
#include "Adafruit_SHT31.h"
|
#define DFMINI_MP3_BOOT "1"
|
||||||
#else
|
#define DFMINI_MP3_ALARM "2"
|
||||||
#include "Adafruit_BME280.h"
|
#define DFMINI_MP3_TIMER "2"
|
||||||
#include "SoftwareSerial.h"
|
#define DFMINI_MP3_CLICK "5"
|
||||||
#include <DFMiniMp3.h>
|
#define DFMINI_MP3_CLICK_ON "3"
|
||||||
|
#define DFMINI_MP3_ENTER "4"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class PeripheryManager_
|
class PeripheryManager_
|
||||||
@@ -37,7 +38,9 @@ public:
|
|||||||
void playFromFile(String file);
|
void playFromFile(String file);
|
||||||
bool isPlaying();
|
bool isPlaying();
|
||||||
void stopSound();
|
void stopSound();
|
||||||
|
#ifndef ULANZI
|
||||||
void setVolume(uint8_t);
|
void setVolume(uint8_t);
|
||||||
|
#endif
|
||||||
const char *readUptime();
|
const char *readUptime();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -8,8 +8,13 @@
|
|||||||
#include <Ticker.h>
|
#include <Ticker.h>
|
||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
|
|
||||||
|
#ifdef ULANZI
|
||||||
#define URL_fw_Version "https://raw.githubusercontent.com/Blueforcer/awtrix-light/main/version"
|
#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"
|
#define URL_fw_Bin "https://raw.githubusercontent.com/Blueforcer/awtrix-light/main/docs/flasher/firmware/firmware.bin"
|
||||||
|
#else
|
||||||
|
#define URL_fw_Version "todo"
|
||||||
|
#define URL_fw_Bin "todo"
|
||||||
|
#endif
|
||||||
|
|
||||||
Ticker UpdateTicker;
|
Ticker UpdateTicker;
|
||||||
|
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ void BootAnimation(void *parameter)
|
|||||||
|
|
||||||
void setup()
|
void setup()
|
||||||
{
|
{
|
||||||
|
|
||||||
PeripheryManager.setup();
|
PeripheryManager.setup();
|
||||||
delay(1000);
|
delay(1000);
|
||||||
Serial.begin(115200);
|
Serial.begin(115200);
|
||||||
|
|||||||
Reference in New Issue
Block a user