Added Sync Time to LCD, Fixed UTC Timestamp issues
This commit is contained in:
@@ -47,120 +47,465 @@ struct MelodyInfo {
|
|||||||
const char* uid; // Unique identifier
|
const char* uid; // Unique identifier
|
||||||
const uint16_t* data; // Pointer to melody data in PROGMEM
|
const uint16_t* data; // Pointer to melody data in PROGMEM
|
||||||
uint16_t stepCount; // Number of steps
|
uint16_t stepCount; // Number of steps
|
||||||
uint16_t defaultSpeed; // Default speed in milliseconds per beat
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// ═════════════════════════════════════════════════════════════════════════════════
|
// ═════════════════════════════════════════════════════════════════════════════════
|
||||||
// EXAMPLE MELODIES - Add your melodies here!
|
// BuiltIn Melodies // More can be added here
|
||||||
// ═════════════════════════════════════════════════════════════════════════════════
|
// ═════════════════════════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
// Example: Simple Scale (C-D-E-F-G-A-B-C)
|
// 1 Bell Test Melody
|
||||||
const uint16_t PROGMEM melody_simple_scale[] = {
|
const uint16_t PROGMEM builtin_1bell_test[] = {
|
||||||
0x0001, 0x0002, 0x0004, 0x0008,
|
0x0001, 0x0000, 0x0001, 0x0000
|
||||||
0x0010, 0x0020, 0x0040, 0x0080
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Example: Happy Birthday (simplified)
|
// Doxology Traditional
|
||||||
const uint16_t PROGMEM melody_happy_birthday[] = {
|
const uint16_t PROGMEM builtin_doxology_traditional[] = {
|
||||||
0x0001, 0x0001, 0x0002, 0x0001,
|
0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0004, 0x0000, 0x0000,
|
||||||
0x0008, 0x0004, 0x0001, 0x0001,
|
0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0008, 0x0000, 0x0000,
|
||||||
0x0002, 0x0001, 0x0010, 0x0008,
|
0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002,
|
||||||
0x0001, 0x0001, 0x0080, 0x0008,
|
0x0001, 0x0002, 0x0001, 0x0004, 0x0001, 0x0008, 0x0000, 0x0000
|
||||||
0x0004, 0x0002, 0x0040, 0x0040,
|
|
||||||
0x0008, 0x0004, 0x0002
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Example: Jingle Bells (simplified)
|
// Doxology Alternative
|
||||||
const uint16_t PROGMEM melody_jingle_bells[] = {
|
const uint16_t PROGMEM builtin_doxology_alternative[] = {
|
||||||
0x0004, 0x0004, 0x0004, 0x0000,
|
0x0001, 0x0000, 0x0002, 0x0004, 0x0000, 0x0018, 0x0000, 0x0001,
|
||||||
0x0004, 0x0004, 0x0004, 0x0000,
|
0x0000, 0x0002, 0x0004, 0x0000, 0x0018, 0x0000, 0x0001, 0x0000,
|
||||||
0x0004, 0x0008, 0x0001, 0x0002,
|
0x0002, 0x0004, 0x0000, 0x0018, 0x0000, 0x0001, 0x0002, 0x0001,
|
||||||
0x0004, 0x0000, 0x0000, 0x0000,
|
0x0002, 0x0004, 0x0000, 0x0018, 0x0000
|
||||||
0x0008, 0x0008, 0x0008, 0x0008,
|
|
||||||
0x0008, 0x0004, 0x0004, 0x0004,
|
|
||||||
0x0002, 0x0002, 0x0004, 0x0002,
|
|
||||||
0x0008, 0x0000, 0x0000, 0x0000
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Example: Westminster Chimes
|
// Doxology Festive
|
||||||
const uint16_t PROGMEM melody_westminster_chimes[] = {
|
const uint16_t PROGMEM builtin_doxology_festive[] = {
|
||||||
0x0008, 0x0004, 0x0002, 0x0001,
|
0x0002, 0x0004, 0x0009, 0x0004, 0x0002, 0x0004, 0x0011, 0x0004,
|
||||||
0x0001, 0x0002, 0x0008, 0x0004,
|
0x0002, 0x0004, 0x0021, 0x0004, 0x0002, 0x0004, 0x0011, 0x0004
|
||||||
0x0008, 0x0001, 0x0002, 0x0004,
|
|
||||||
0x0002, 0x0008, 0x0004, 0x0001
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Example: Alarm Pattern
|
// Vesper Traditional
|
||||||
const uint16_t PROGMEM melody_alarm[] = {
|
const uint16_t PROGMEM builtin_vesper_traditional[] = {
|
||||||
0x0001, 0x0080, 0x0001, 0x0080,
|
0x0001, 0x0002, 0x0004, 0x0000, 0x0001, 0x0002, 0x0004, 0x0000,
|
||||||
0x0001, 0x0080, 0x0001, 0x0080,
|
0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0004, 0x0000
|
||||||
0x0000, 0x0000, 0x0001, 0x0080,
|
|
||||||
0x0001, 0x0080, 0x0001, 0x0080
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Example: Doorbell
|
// Vesper Alternative
|
||||||
const uint16_t PROGMEM melody_doorbell[] = {
|
const uint16_t PROGMEM builtin_vesper_alternative[] = {
|
||||||
0x0004, 0x0008, 0x0004, 0x0008
|
0x0001, 0x0002, 0x0000, 0x0000, 0x0001, 0x0002, 0x0000, 0x0000,
|
||||||
|
0x0001, 0x0004, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||||
|
0x0001, 0x0002, 0x0000, 0x0000, 0x0001, 0x0002, 0x0000, 0x0000,
|
||||||
|
0x0001, 0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||||
|
0x0001, 0x0002, 0x0000, 0x0000, 0x0001, 0x0002, 0x0000, 0x0000,
|
||||||
|
0x0001, 0x0002, 0x0000, 0x0000, 0x0001, 0x0002, 0x0000, 0x0000,
|
||||||
|
0x0001, 0x0002, 0x0000, 0x0000, 0x0001, 0x0004, 0x0000, 0x0000,
|
||||||
|
0x0001, 0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
|
||||||
};
|
};
|
||||||
|
|
||||||
// Example: Single Bell Test
|
// Catehetical
|
||||||
const uint16_t PROGMEM melody_single_bell[] = {
|
const uint16_t PROGMEM builtin_catehetical[] = {
|
||||||
0x0001
|
0x0001, 0x0002, 0x0004, 0x0008, 0x0010
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Orthros Traditional
|
||||||
|
const uint16_t PROGMEM builtin_orthros_traditional[] = {
|
||||||
|
0x0001, 0x0000, 0x0002, 0x0000, 0x0004, 0x0008, 0x0000, 0x0010,
|
||||||
|
0x0000, 0x0020, 0x0000, 0x0040, 0x0080, 0x0000
|
||||||
|
};
|
||||||
|
|
||||||
|
// Orthros Alternative
|
||||||
|
const uint16_t PROGMEM builtin_orthros_alternative[] = {
|
||||||
|
0x0001, 0x0000, 0x0002, 0x0001, 0x0000, 0x0002, 0x0000, 0x0001,
|
||||||
|
0x0000, 0x0001, 0x0002, 0x0001, 0x0000, 0x0004, 0x0000
|
||||||
|
};
|
||||||
|
|
||||||
|
// Mournfull Toll
|
||||||
|
const uint16_t PROGMEM builtin_mournfull_toll[] = {
|
||||||
|
0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001,
|
||||||
|
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0004, 0x0000,
|
||||||
|
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0004, 0x0000, 0x0000,
|
||||||
|
0x0000, 0x0000, 0x0000, 0x0000, 0x0002, 0x0000, 0x0000, 0x0000,
|
||||||
|
0x0000, 0x0000, 0x0000, 0x0002, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||||
|
0x0000, 0x0000, 0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||||
|
0x0000, 0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
|
||||||
|
};
|
||||||
|
|
||||||
|
// Mournfull Toll Alternative
|
||||||
|
const uint16_t PROGMEM builtin_mournfull_toll_alternative[] = {
|
||||||
|
0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001,
|
||||||
|
0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0004,
|
||||||
|
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0004, 0x0004,
|
||||||
|
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0002, 0x0000,
|
||||||
|
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0002, 0x0002, 0x0000,
|
||||||
|
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0008, 0x0000, 0x0000,
|
||||||
|
0x0000, 0x0000, 0x0000, 0x0000, 0x0008, 0x0008, 0x0000, 0x0000,
|
||||||
|
0x0000, 0x0000, 0x0000, 0x0000
|
||||||
|
};
|
||||||
|
|
||||||
|
// Mournfull Toll Meg Par
|
||||||
|
const uint16_t PROGMEM builtin_mournfull_toll_meg_par[] = {
|
||||||
|
0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001,
|
||||||
|
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0001,
|
||||||
|
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0004, 0x0000,
|
||||||
|
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0004, 0x0000, 0x0000,
|
||||||
|
0x0000, 0x0000, 0x0000, 0x0000, 0x0004, 0x0004, 0x0000, 0x0000,
|
||||||
|
0x0000, 0x0000, 0x0000, 0x0000, 0x0002, 0x0000, 0x0000, 0x0000,
|
||||||
|
0x0000, 0x0000, 0x0000, 0x0002, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||||
|
0x0000, 0x0000, 0x0002, 0x0002, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||||
|
0x0000, 0x0000, 0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||||
|
0x0000, 0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||||
|
0x0008, 0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
|
||||||
|
};
|
||||||
|
|
||||||
|
// Sematron
|
||||||
|
const uint16_t PROGMEM builtin_sematron[] = {
|
||||||
|
0x0001, 0x0001, 0x0001, 0x0002, 0x0001, 0x0001, 0x0001, 0x0008,
|
||||||
|
0x0001, 0x0001, 0x0001, 0x0002, 0x0001, 0x0004, 0x0001, 0x0008
|
||||||
|
};
|
||||||
|
|
||||||
|
// Sematron Alternative
|
||||||
|
const uint16_t PROGMEM builtin_sematron_alternative[] = {
|
||||||
|
0x0001, 0x0001, 0x0001, 0x0002, 0x0001, 0x0001, 0x0001, 0x0008,
|
||||||
|
0x0001, 0x0002, 0x0001, 0x0004, 0x0001, 0x0001, 0x0001, 0x0008
|
||||||
|
};
|
||||||
|
|
||||||
|
// Athonite 1 2 Voices
|
||||||
|
const uint16_t PROGMEM builtin_athonite_1_2_voices[] = {
|
||||||
|
0x0001, 0x0002, 0x0001, 0x0001, 0x0002, 0x0001, 0x0001, 0x0002,
|
||||||
|
0x0001, 0x0001, 0x0002, 0x0001, 0x0002
|
||||||
|
};
|
||||||
|
|
||||||
|
// Athonite 3 Voices
|
||||||
|
const uint16_t PROGMEM builtin_athonite_3_voices[] = {
|
||||||
|
0x0002, 0x0001, 0x0000, 0x0000, 0x0002, 0x0001, 0x0000, 0x0000,
|
||||||
|
0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0000, 0x0001,
|
||||||
|
0x0002, 0x0001, 0x0000, 0x0001, 0x0002, 0x0001, 0x0000, 0x0001,
|
||||||
|
0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0000, 0x0001,
|
||||||
|
0x0002, 0x0001, 0x0000, 0x0001, 0x0002, 0x0001, 0x0000, 0x0001,
|
||||||
|
0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0004, 0x0001,
|
||||||
|
0x0002, 0x0001, 0x0004, 0x0001, 0x0002, 0x0001, 0x0004, 0x0001,
|
||||||
|
0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0004, 0x0001,
|
||||||
|
0x0002, 0x0001, 0x0004, 0x0001, 0x0002, 0x0001, 0x0004, 0x0001,
|
||||||
|
0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0004
|
||||||
|
};
|
||||||
|
|
||||||
|
// Athonite 3 4 Voices
|
||||||
|
const uint16_t PROGMEM builtin_athonite_3_4_voices[] = {
|
||||||
|
0x0002, 0x0001, 0x0000, 0x0000, 0x0002, 0x0001, 0x0000, 0x0000,
|
||||||
|
0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0000, 0x0001,
|
||||||
|
0x0002, 0x0001, 0x0000, 0x0001, 0x0002, 0x0001, 0x0000, 0x0001,
|
||||||
|
0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0000, 0x0001,
|
||||||
|
0x0002, 0x0001, 0x0000, 0x0001, 0x0002, 0x0001, 0x0000, 0x0001,
|
||||||
|
0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0004, 0x0001,
|
||||||
|
0x0002, 0x0001, 0x0000, 0x0005, 0x0002, 0x0001, 0x0000, 0x0005,
|
||||||
|
0x0002, 0x0001, 0x0000, 0x0005, 0x0002, 0x0001, 0x0002, 0x0005,
|
||||||
|
0x0002, 0x0001, 0x0008, 0x0005, 0x0002, 0x0001, 0x0000, 0x0005,
|
||||||
|
0x0002, 0x0001, 0x0000, 0x0005, 0x0002, 0x0001, 0x0002, 0x0005,
|
||||||
|
0x0002, 0x0001, 0x0009, 0x0002, 0x0001, 0x0005, 0x0002, 0x0001,
|
||||||
|
0x000A, 0x0002, 0x0001, 0x0006, 0x0002, 0x0001, 0x0009, 0x0002,
|
||||||
|
0x0001, 0x0005, 0x0002, 0x0001, 0x000A, 0x0002, 0x0001, 0x0006,
|
||||||
|
0x0002, 0x0001, 0x0009
|
||||||
|
};
|
||||||
|
|
||||||
|
// Athonite 4 8 Voices
|
||||||
|
const uint16_t PROGMEM builtin_athonite_4_8_voices[] = {
|
||||||
|
0x0002, 0x0001, 0x0000, 0x0000, 0x0002, 0x0001, 0x0000, 0x0000,
|
||||||
|
0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0000, 0x0001,
|
||||||
|
0x0002, 0x0001, 0x0000, 0x0001, 0x0002, 0x0001, 0x0000, 0x0001,
|
||||||
|
0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0000, 0x0001,
|
||||||
|
0x0002, 0x0001, 0x0000, 0x0001, 0x0002, 0x0001, 0x0000, 0x0001,
|
||||||
|
0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0004, 0x0001,
|
||||||
|
0x0002, 0x0001, 0x0000, 0x0005, 0x0002, 0x0001, 0x0000, 0x0005,
|
||||||
|
0x0002, 0x0001, 0x0000, 0x0005, 0x0002, 0x0001, 0x0002, 0x0005,
|
||||||
|
0x0002, 0x0001, 0x0008, 0x0005, 0x0002, 0x0001, 0x0000, 0x0005,
|
||||||
|
0x0002, 0x0001, 0x0000, 0x0005, 0x0002, 0x0001, 0x0002, 0x0005,
|
||||||
|
0x0002, 0x0001, 0x0009, 0x0002, 0x0001, 0x0011, 0x0002, 0x0001,
|
||||||
|
0x0022, 0x0002, 0x0001, 0x0081, 0x0002, 0x0001, 0x000A, 0x0002,
|
||||||
|
0x0001, 0x0041, 0x0002, 0x0001, 0x0012, 0x0002, 0x0001, 0x0021,
|
||||||
|
0x0002, 0x0001, 0x0082, 0x0002, 0x0001, 0x0009, 0x0002, 0x0001,
|
||||||
|
0x0042, 0x0002, 0x0001, 0x0011, 0x0002, 0x0001, 0x0022, 0x0002,
|
||||||
|
0x0001, 0x0081, 0x0002, 0x0001, 0x000A, 0x0002, 0x0001, 0x0041,
|
||||||
|
0x0002, 0x0001, 0x0000, 0x0005, 0x0002, 0x0001, 0x0000, 0x0005,
|
||||||
|
0x0002, 0x0001, 0x0002, 0x0005, 0x0002, 0x0001, 0x0000, 0x0000,
|
||||||
|
0x0000
|
||||||
|
};
|
||||||
|
|
||||||
|
// Onebyone 2 3 Voices
|
||||||
|
const uint16_t PROGMEM builtin_onebyone_2_3_voices[] = {
|
||||||
|
0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000,
|
||||||
|
0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000,
|
||||||
|
0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002,
|
||||||
|
0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002,
|
||||||
|
0x0001, 0x0002, 0x0001, 0x0004, 0x0001, 0x0002, 0x0001, 0x0004,
|
||||||
|
0x0001, 0x0002, 0x0001, 0x0004, 0x0001, 0x0002, 0x0001, 0x0004,
|
||||||
|
0x0001, 0x0002, 0x0001, 0x0004, 0x0001, 0x0002, 0x0001, 0x0004,
|
||||||
|
0x0001, 0x0002, 0x0001, 0x0004, 0x0001, 0x0002, 0x0001, 0x0004,
|
||||||
|
0x0001, 0x0002, 0x0001, 0x0004, 0x0001, 0x0002, 0x0001, 0x0004,
|
||||||
|
0x0001, 0x0002, 0x0001, 0x0004, 0x0001, 0x0002, 0x0001, 0x0004,
|
||||||
|
0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002,
|
||||||
|
0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002
|
||||||
|
};
|
||||||
|
|
||||||
|
// Onebyone 4 8 Voices
|
||||||
|
const uint16_t PROGMEM builtin_onebyone_4_8_voices[] = {
|
||||||
|
0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000,
|
||||||
|
0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000,
|
||||||
|
0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002,
|
||||||
|
0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002,
|
||||||
|
0x0001, 0x0002, 0x0001, 0x0004, 0x0001, 0x0002, 0x0001, 0x0004,
|
||||||
|
0x0001, 0x0002, 0x0001, 0x0004, 0x0001, 0x0002, 0x0001, 0x0004,
|
||||||
|
0x0002, 0x0004, 0x0008, 0x0004, 0x0002, 0x0011, 0x0002, 0x0004,
|
||||||
|
0x0008, 0x0004, 0x0002, 0x0021, 0x0002, 0x0004, 0x0008, 0x0004,
|
||||||
|
0x0002, 0x0041, 0x0002, 0x0004, 0x0008, 0x0004, 0x0002, 0x0081,
|
||||||
|
0x0002, 0x0004, 0x0008, 0x0004, 0x0002, 0x0041, 0x0002, 0x0004,
|
||||||
|
0x0008, 0x0004, 0x0002, 0x0021, 0x0002, 0x0004, 0x0008, 0x0004,
|
||||||
|
0x0002, 0x0041, 0x0002, 0x0004, 0x0008, 0x0004, 0x0002, 0x0081,
|
||||||
|
0x0002, 0x0004, 0x0008, 0x0004, 0x0002, 0x0041, 0x0002, 0x0004,
|
||||||
|
0x0008, 0x0004, 0x0002, 0x0021, 0x0002, 0x0004, 0x0008, 0x0004,
|
||||||
|
0x0002, 0x0001, 0x0002, 0x0001, 0x0004, 0x0001, 0x0002, 0x0001,
|
||||||
|
0x0004, 0x0001, 0x0002, 0x0001, 0x0004, 0x0001, 0x0002, 0x0001,
|
||||||
|
0x0004, 0x0001, 0x0002, 0x0001, 0x0004, 0x0001, 0x0002, 0x0001,
|
||||||
|
0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001,
|
||||||
|
0x0002, 0x0001, 0x0000
|
||||||
|
};
|
||||||
|
|
||||||
|
// Festive 1Voice
|
||||||
|
const uint16_t PROGMEM builtin_festive_1voice[] = {
|
||||||
|
0x0001, 0x0001, 0x0001, 0x0000, 0x0001, 0x0001, 0x0001, 0x0001,
|
||||||
|
0x0000, 0x0001, 0x0000, 0x0001, 0x0001, 0x0001, 0x0000, 0x0001,
|
||||||
|
0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0000, 0x0001, 0x0000
|
||||||
|
};
|
||||||
|
|
||||||
|
// Festive 4Voices
|
||||||
|
const uint16_t PROGMEM builtin_festive_4voices[] = {
|
||||||
|
0x0001, 0x0002, 0x0004, 0x0009, 0x0002, 0x0001, 0x0004, 0x0009
|
||||||
|
};
|
||||||
|
|
||||||
|
// Festive 5Voices
|
||||||
|
const uint16_t PROGMEM builtin_festive_5voices[] = {
|
||||||
|
0x0001, 0x0002, 0x0004, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002,
|
||||||
|
0x0008, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0004, 0x0002,
|
||||||
|
0x0001, 0x0002, 0x0001, 0x0002, 0x0010, 0x0002, 0x0001, 0x0002
|
||||||
|
};
|
||||||
|
|
||||||
|
// Festive 5Voice Alternative
|
||||||
|
const uint16_t PROGMEM builtin_festive_5voice_alternative[] = {
|
||||||
|
0x0004, 0x0002, 0x0008, 0x0001, 0x0004, 0x0004, 0x0002, 0x0008,
|
||||||
|
0x0001, 0x0010, 0x0004, 0x0002, 0x0008, 0x0001, 0x0004, 0x0004,
|
||||||
|
0x0002, 0x0008, 0x0001, 0x0011, 0x0004, 0x0002, 0x0008, 0x0001,
|
||||||
|
0x0004, 0x0004, 0x0002, 0x0008, 0x0001, 0x0011, 0x0004, 0x0002,
|
||||||
|
0x0008, 0x0001, 0x0005, 0x0004, 0x0002, 0x0008, 0x0001, 0x0011,
|
||||||
|
0x0004, 0x0002, 0x0008, 0x0001, 0x0005, 0x0004, 0x0002, 0x0008,
|
||||||
|
0x0001, 0x0011, 0x0004, 0x0002, 0x0008, 0x0001, 0x0004, 0x0004,
|
||||||
|
0x0002, 0x0008, 0x0001, 0x0010, 0x0004, 0x0002, 0x0008, 0x0001,
|
||||||
|
0x0004, 0x0004, 0x0002, 0x0008, 0x0001, 0x0010
|
||||||
|
};
|
||||||
|
|
||||||
|
// Festive 6Voices
|
||||||
|
const uint16_t PROGMEM builtin_festive_6voices[] = {
|
||||||
|
0x0001, 0x0002, 0x0004, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002,
|
||||||
|
0x0008, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0004, 0x0002,
|
||||||
|
0x0001, 0x0002, 0x0001, 0x0002, 0x0010, 0x0002, 0x0001, 0x0002,
|
||||||
|
0x0001, 0x0002, 0x0009, 0x0002, 0x0001, 0x0002, 0x0011, 0x0002,
|
||||||
|
0x0001, 0x0002, 0x0005, 0x0002, 0x0001, 0x0002, 0x0021, 0x0002,
|
||||||
|
0x0001, 0x0002, 0x0009, 0x0002, 0x0001, 0x0002, 0x0011, 0x0002,
|
||||||
|
0x0001, 0x0002, 0x0005, 0x0002, 0x0001, 0x0002, 0x0021, 0x0002,
|
||||||
|
0x0001, 0x0002, 0x0009, 0x0002, 0x0001, 0x0002, 0x0011, 0x0002,
|
||||||
|
0x0001, 0x0002, 0x0005, 0x0002, 0x0001, 0x0002, 0x0021, 0x0002,
|
||||||
|
0x0001, 0x0002
|
||||||
|
};
|
||||||
|
|
||||||
|
// Festive 8Voices
|
||||||
|
const uint16_t PROGMEM builtin_festive_8voices[] = {
|
||||||
|
0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080
|
||||||
|
};
|
||||||
|
|
||||||
|
// Ormilia
|
||||||
|
const uint16_t PROGMEM builtin_ormilia[] = {
|
||||||
|
0x0002, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001,
|
||||||
|
0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001,
|
||||||
|
0x0002, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001,
|
||||||
|
0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001,
|
||||||
|
0x0002, 0x0001, 0x0000, 0x0001, 0x0002, 0x0001, 0x0000, 0x0001,
|
||||||
|
0x0002, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001,
|
||||||
|
0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001, 0x0002, 0x0001,
|
||||||
|
0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001,
|
||||||
|
0x0002, 0x0009, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001,
|
||||||
|
0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001,
|
||||||
|
0x0002, 0x0005, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001,
|
||||||
|
0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001,
|
||||||
|
0x0002, 0x0009, 0x0000, 0x0001, 0x0002, 0x0005, 0x0000, 0x0001,
|
||||||
|
0x0002, 0x0009, 0x0000, 0x0001, 0x0002, 0x0005, 0x0000, 0x0001,
|
||||||
|
0x0002, 0x0011, 0x0002, 0x0001, 0x0002, 0x0021, 0x0002, 0x0001,
|
||||||
|
0x0002, 0x0011, 0x0002, 0x0001, 0x0002, 0x0021, 0x0002, 0x0041,
|
||||||
|
0x0002, 0x0081, 0x0002, 0x0009, 0x0002, 0x0041, 0x0002, 0x0081,
|
||||||
|
0x0002, 0x0009, 0x0002, 0x0041, 0x0002, 0x0081, 0x0002, 0x0005,
|
||||||
|
0x0002, 0x0001, 0x0000
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// ═════════════════════════════════════════════════════════════════════════════════
|
// ═════════════════════════════════════════════════════════════════════════════════
|
||||||
// MELODY LIBRARY - Array of all built-in melodies
|
// MELODY LIBRARY - Array of all built-in melodies
|
||||||
// ═════════════════════════════════════════════════════════════════════════════════
|
// ═════════════════════════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
const MelodyInfo MELODY_LIBRARY[] = {
|
const MelodyInfo MELODY_LIBRARY[] = {
|
||||||
{
|
{
|
||||||
"Simple Scale",
|
"1 Bell Test",
|
||||||
"builtin_scale",
|
"builtin_1bell_test",
|
||||||
melody_simple_scale,
|
builtin_1bell_test,
|
||||||
sizeof(melody_simple_scale) / sizeof(uint16_t),
|
sizeof(builtin_1bell_test) / sizeof(uint16_t)
|
||||||
200 // 200ms per beat
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Happy Birthday",
|
"Doxology Traditional",
|
||||||
"builtin_happy_birthday",
|
"builtin_doxology_traditional",
|
||||||
melody_happy_birthday,
|
builtin_doxology_traditional,
|
||||||
sizeof(melody_happy_birthday) / sizeof(uint16_t),
|
sizeof(builtin_doxology_traditional) / sizeof(uint16_t)
|
||||||
250
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Jingle Bells",
|
"Doxology Alternative",
|
||||||
"builtin_jingle_bells",
|
"builtin_doxology_alternative",
|
||||||
melody_jingle_bells,
|
builtin_doxology_alternative,
|
||||||
sizeof(melody_jingle_bells) / sizeof(uint16_t),
|
sizeof(builtin_doxology_alternative) / sizeof(uint16_t)
|
||||||
180
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Westminster Chimes",
|
"Doxology Festive",
|
||||||
"builtin_westminster",
|
"builtin_doxology_festive",
|
||||||
melody_westminster_chimes,
|
builtin_doxology_festive,
|
||||||
sizeof(melody_westminster_chimes) / sizeof(uint16_t),
|
sizeof(builtin_doxology_festive) / sizeof(uint16_t)
|
||||||
400
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Alarm",
|
"Vesper Traditional",
|
||||||
"builtin_alarm",
|
"builtin_vesper_traditional",
|
||||||
melody_alarm,
|
builtin_vesper_traditional,
|
||||||
sizeof(melody_alarm) / sizeof(uint16_t),
|
sizeof(builtin_vesper_traditional) / sizeof(uint16_t)
|
||||||
150
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Doorbell",
|
"Vesper Alternative",
|
||||||
"builtin_doorbell",
|
"builtin_vesper_alternative",
|
||||||
melody_doorbell,
|
builtin_vesper_alternative,
|
||||||
sizeof(melody_doorbell) / sizeof(uint16_t),
|
sizeof(builtin_vesper_alternative) / sizeof(uint16_t)
|
||||||
300
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Single Bell Test",
|
"Catehetical",
|
||||||
"builtin_single_bell",
|
"builtin_catehetical",
|
||||||
melody_single_bell,
|
builtin_catehetical,
|
||||||
sizeof(melody_single_bell) / sizeof(uint16_t),
|
sizeof(builtin_catehetical) / sizeof(uint16_t)
|
||||||
100
|
},
|
||||||
|
{
|
||||||
|
"Orthros Traditional",
|
||||||
|
"builtin_orthros_traditional",
|
||||||
|
builtin_orthros_traditional,
|
||||||
|
sizeof(builtin_orthros_traditional) / sizeof(uint16_t)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Orthros Alternative",
|
||||||
|
"builtin_orthros_alternative",
|
||||||
|
builtin_orthros_alternative,
|
||||||
|
sizeof(builtin_orthros_alternative) / sizeof(uint16_t)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Mournfull Toll",
|
||||||
|
"builtin_mournfull_toll",
|
||||||
|
builtin_mournfull_toll,
|
||||||
|
sizeof(builtin_mournfull_toll) / sizeof(uint16_t)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Mournfull Toll Alternative",
|
||||||
|
"builtin_mournfull_toll_alternative",
|
||||||
|
builtin_mournfull_toll_alternative,
|
||||||
|
sizeof(builtin_mournfull_toll_alternative) / sizeof(uint16_t)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Mournfull Toll Meg Par",
|
||||||
|
"builtin_mournfull_toll_meg_par",
|
||||||
|
builtin_mournfull_toll_meg_par,
|
||||||
|
sizeof(builtin_mournfull_toll_meg_par) / sizeof(uint16_t)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Sematron",
|
||||||
|
"builtin_sematron",
|
||||||
|
builtin_sematron,
|
||||||
|
sizeof(builtin_sematron) / sizeof(uint16_t)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Sematron Alternative",
|
||||||
|
"builtin_sematron_alternative",
|
||||||
|
builtin_sematron_alternative,
|
||||||
|
sizeof(builtin_sematron_alternative) / sizeof(uint16_t)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Athonite 1 2 Voices",
|
||||||
|
"builtin_athonite_1_2_voices",
|
||||||
|
builtin_athonite_1_2_voices,
|
||||||
|
sizeof(builtin_athonite_1_2_voices) / sizeof(uint16_t)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Athonite 3 Voices",
|
||||||
|
"builtin_athonite_3_voices",
|
||||||
|
builtin_athonite_3_voices,
|
||||||
|
sizeof(builtin_athonite_3_voices) / sizeof(uint16_t)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Athonite 3 4 Voices",
|
||||||
|
"builtin_athonite_3_4_voices",
|
||||||
|
builtin_athonite_3_4_voices,
|
||||||
|
sizeof(builtin_athonite_3_4_voices) / sizeof(uint16_t)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Athonite 4 8 Voices",
|
||||||
|
"builtin_athonite_4_8_voices",
|
||||||
|
builtin_athonite_4_8_voices,
|
||||||
|
sizeof(builtin_athonite_4_8_voices) / sizeof(uint16_t)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Onebyone 2 3 Voices",
|
||||||
|
"builtin_onebyone_2_3_voices",
|
||||||
|
builtin_onebyone_2_3_voices,
|
||||||
|
sizeof(builtin_onebyone_2_3_voices) / sizeof(uint16_t)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Onebyone 4 8 Voices",
|
||||||
|
"builtin_onebyone_4_8_voices",
|
||||||
|
builtin_onebyone_4_8_voices,
|
||||||
|
sizeof(builtin_onebyone_4_8_voices) / sizeof(uint16_t)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Festive 1Voice",
|
||||||
|
"builtin_festive_1voice",
|
||||||
|
builtin_festive_1voice,
|
||||||
|
sizeof(builtin_festive_1voice) / sizeof(uint16_t)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Festive 4Voices",
|
||||||
|
"builtin_festive_4voices",
|
||||||
|
builtin_festive_4voices,
|
||||||
|
sizeof(builtin_festive_4voices) / sizeof(uint16_t)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Festive 5Voices",
|
||||||
|
"builtin_festive_5voices",
|
||||||
|
builtin_festive_5voices,
|
||||||
|
sizeof(builtin_festive_5voices) / sizeof(uint16_t)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Festive 5Voice Alternative",
|
||||||
|
"builtin_festive_5voice_alternative",
|
||||||
|
builtin_festive_5voice_alternative,
|
||||||
|
sizeof(builtin_festive_5voice_alternative) / sizeof(uint16_t)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Festive 6Voices",
|
||||||
|
"builtin_festive_6voices",
|
||||||
|
builtin_festive_6voices,
|
||||||
|
sizeof(builtin_festive_6voices) / sizeof(uint16_t)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Festive 8Voices",
|
||||||
|
"builtin_festive_8voices",
|
||||||
|
builtin_festive_8voices,
|
||||||
|
sizeof(builtin_festive_8voices) / sizeof(uint16_t)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Ormilia",
|
||||||
|
"builtin_ormilia",
|
||||||
|
builtin_ormilia,
|
||||||
|
sizeof(builtin_ormilia) / sizeof(uint16_t)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -225,29 +570,10 @@ inline String getBuiltInMelodiesJSON() {
|
|||||||
json += "{";
|
json += "{";
|
||||||
json += "\"name\":\"" + String(MELODY_LIBRARY[i].name) + "\",";
|
json += "\"name\":\"" + String(MELODY_LIBRARY[i].name) + "\",";
|
||||||
json += "\"uid\":\"" + String(MELODY_LIBRARY[i].uid) + "\",";
|
json += "\"uid\":\"" + String(MELODY_LIBRARY[i].uid) + "\",";
|
||||||
json += "\"steps\":" + String(MELODY_LIBRARY[i].stepCount) + ",";
|
|
||||||
json += "\"speed\":" + String(MELODY_LIBRARY[i].defaultSpeed);
|
|
||||||
json += "}";
|
json += "}";
|
||||||
}
|
}
|
||||||
json += "]";
|
json += "]";
|
||||||
return json;
|
return json;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace BuiltInMelodies
|
}
|
||||||
|
|
||||||
// ═══════════════════════════════════════════════════════════════════════════════════
|
|
||||||
// USAGE EXAMPLE:
|
|
||||||
// ═══════════════════════════════════════════════════════════════════════════════════
|
|
||||||
/*
|
|
||||||
// Check if melody is built-in
|
|
||||||
if (BuiltInMelodies::isBuiltInMelody(uid)) {
|
|
||||||
// Load it from firmware
|
|
||||||
std::vector<uint16_t> melodyData;
|
|
||||||
if (BuiltInMelodies::loadBuiltInMelody(uid, melodyData)) {
|
|
||||||
// Use melodyData...
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Load from SD card as usual
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
// ═══════════════════════════════════════════════════════════════════════════════════
|
|
||||||
@@ -283,6 +283,8 @@ void CommandHandler::handleSystemInfoCommand(JsonVariant contents, const Message
|
|||||||
handleNetworkInfoCommand(context);
|
handleNetworkInfoCommand(context);
|
||||||
} else if (action == "get_full_settings") {
|
} else if (action == "get_full_settings") {
|
||||||
handleGetFullSettingsCommand(context);
|
handleGetFullSettingsCommand(context);
|
||||||
|
} else if (action == "sync_time_to_lcd") {
|
||||||
|
handleSyncTimeToLcdCommand(context);
|
||||||
} else {
|
} else {
|
||||||
LOG_WARNING("Unknown system info action: %s", action.c_str());
|
LOG_WARNING("Unknown system info action: %s", action.c_str());
|
||||||
sendErrorResponse("system_info", "Unknown action: " + action, context);
|
sendErrorResponse("system_info", "Unknown action: " + action, context);
|
||||||
@@ -636,19 +638,26 @@ void CommandHandler::handleSetClockEnabledCommand(JsonVariant contents, const Me
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CommandHandler::handleGetDeviceTimeCommand(const MessageContext& context) {
|
void CommandHandler::handleGetDeviceTimeCommand(const MessageContext& context) {
|
||||||
StaticJsonDocument<256> response;
|
StaticJsonDocument<384> response;
|
||||||
response["status"] = "SUCCESS";
|
response["status"] = "SUCCESS";
|
||||||
response["type"] = "device_time";
|
response["type"] = "device_time";
|
||||||
|
|
||||||
if (_timeKeeper) {
|
if (_timeKeeper) {
|
||||||
// Get Unix timestamp from Timekeeper
|
// RTC stores LOCAL time (already timezone-adjusted)
|
||||||
unsigned long timestamp = _timeKeeper->getTime();
|
unsigned long localTimestamp = _timeKeeper->getTime();
|
||||||
response["payload"]["timestamp"] = timestamp;
|
|
||||||
|
// Get timezone offset to calculate UTC
|
||||||
|
const auto& timeConfig = _configManager.getTimeConfig();
|
||||||
|
long totalOffset = timeConfig.gmtOffsetSec + timeConfig.daylightOffsetSec;
|
||||||
|
unsigned long utcTimestamp = localTimestamp - totalOffset;
|
||||||
|
|
||||||
|
response["payload"]["local_timestamp"] = localTimestamp;
|
||||||
|
response["payload"]["utc_timestamp"] = utcTimestamp;
|
||||||
response["payload"]["rtc_available"] = true;
|
response["payload"]["rtc_available"] = true;
|
||||||
|
|
||||||
// Convert to readable format
|
// Convert LOCAL timestamp to readable format using gmtime (no additional offset)
|
||||||
time_t rawTime = (time_t)timestamp;
|
time_t rawTime = (time_t)localTimestamp;
|
||||||
struct tm* timeInfo = localtime(&rawTime);
|
struct tm* timeInfo = gmtime(&rawTime); // Use gmtime to avoid double-offset
|
||||||
response["payload"]["year"] = timeInfo->tm_year + 1900;
|
response["payload"]["year"] = timeInfo->tm_year + 1900;
|
||||||
response["payload"]["month"] = timeInfo->tm_mon + 1;
|
response["payload"]["month"] = timeInfo->tm_mon + 1;
|
||||||
response["payload"]["day"] = timeInfo->tm_mday;
|
response["payload"]["day"] = timeInfo->tm_mday;
|
||||||
@@ -656,7 +665,8 @@ void CommandHandler::handleGetDeviceTimeCommand(const MessageContext& context) {
|
|||||||
response["payload"]["minute"] = timeInfo->tm_min;
|
response["payload"]["minute"] = timeInfo->tm_min;
|
||||||
response["payload"]["second"] = timeInfo->tm_sec;
|
response["payload"]["second"] = timeInfo->tm_sec;
|
||||||
} else {
|
} else {
|
||||||
response["payload"]["timestamp"] = millis() / 1000;
|
response["payload"]["local_timestamp"] = millis() / 1000;
|
||||||
|
response["payload"]["utc_timestamp"] = millis() / 1000;
|
||||||
response["payload"]["rtc_available"] = false;
|
response["payload"]["rtc_available"] = false;
|
||||||
LOG_WARNING("TimeKeeper reference not set for device time request");
|
LOG_WARNING("TimeKeeper reference not set for device time request");
|
||||||
}
|
}
|
||||||
@@ -858,7 +868,37 @@ void CommandHandler::handleGetFullSettingsCommand(const MessageContext& context)
|
|||||||
LOG_DEBUG("Full settings sent (%d bytes)", responseStr.length());
|
LOG_DEBUG("Full settings sent (%d bytes)", responseStr.length());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CommandHandler::handleSyncTimeToLcdCommand(const MessageContext& context) {
|
||||||
|
StaticJsonDocument<256> response;
|
||||||
|
response["status"] = "SUCCESS";
|
||||||
|
response["type"] = "sync_time_to_lcd";
|
||||||
|
|
||||||
|
// Get the local timestamp from TimeKeeper (RTC stores local time)
|
||||||
|
unsigned long localTimestamp = 0;
|
||||||
|
if (_timeKeeper) {
|
||||||
|
localTimestamp = _timeKeeper->getTime();
|
||||||
|
} else {
|
||||||
|
// Fallback to millis if TimeKeeper not available
|
||||||
|
localTimestamp = millis() / 1000;
|
||||||
|
LOG_WARNING("TimeKeeper not available for LCD time sync");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get timezone offset from ConfigManager (in seconds)
|
||||||
|
const auto& timeConfig = _configManager.getTimeConfig();
|
||||||
|
long totalOffset = timeConfig.gmtOffsetSec + timeConfig.daylightOffsetSec;
|
||||||
|
|
||||||
|
// Calculate UTC timestamp by subtracting the offset from local time
|
||||||
|
unsigned long utcTimestamp = localTimestamp - totalOffset;
|
||||||
|
|
||||||
|
response["payload"]["timestamp"] = utcTimestamp;
|
||||||
|
response["payload"]["offset"] = totalOffset;
|
||||||
|
|
||||||
|
String responseStr;
|
||||||
|
serializeJson(response, responseStr);
|
||||||
|
sendResponse(responseStr, context);
|
||||||
|
|
||||||
|
LOG_DEBUG("LCD time sync: UTC=%lu, offset=%ld", utcTimestamp, totalOffset);
|
||||||
|
}
|
||||||
|
|
||||||
void CommandHandler::handleSetNetworkConfigCommand(JsonVariant contents, const MessageContext& context) {
|
void CommandHandler::handleSetNetworkConfigCommand(JsonVariant contents, const MessageContext& context) {
|
||||||
// Validate that we have at least one parameter to update
|
// Validate that we have at least one parameter to update
|
||||||
|
|||||||
@@ -140,6 +140,7 @@ private:
|
|||||||
void handleGetFirmwareStatusCommand(const MessageContext& context);
|
void handleGetFirmwareStatusCommand(const MessageContext& context);
|
||||||
void handleNetworkInfoCommand(const MessageContext& context);
|
void handleNetworkInfoCommand(const MessageContext& context);
|
||||||
void handleGetFullSettingsCommand(const MessageContext& context);
|
void handleGetFullSettingsCommand(const MessageContext& context);
|
||||||
|
void handleSyncTimeToLcdCommand(const MessageContext& context);
|
||||||
|
|
||||||
// Network configuration
|
// Network configuration
|
||||||
void handleSetNetworkConfigCommand(JsonVariant contents, const MessageContext& context);
|
void handleSetNetworkConfigCommand(JsonVariant contents, const MessageContext& context);
|
||||||
|
|||||||
@@ -263,13 +263,6 @@ void Player::loadMelodyInRAM() {
|
|||||||
|
|
||||||
if (BuiltInMelodies::loadBuiltInMelody(uidStr, _melodySteps)) {
|
if (BuiltInMelodies::loadBuiltInMelody(uidStr, _melodySteps)) {
|
||||||
LOG_INFO("✅ Built-in melody loaded successfully: %d steps", _melodySteps.size());
|
LOG_INFO("✅ Built-in melody loaded successfully: %d steps", _melodySteps.size());
|
||||||
|
|
||||||
// Set default speed from built-in melody info
|
|
||||||
const BuiltInMelodies::MelodyInfo* melodyInfo = BuiltInMelodies::findMelodyByUID(uidStr);
|
|
||||||
if (melodyInfo && speed == 0) {
|
|
||||||
speed = melodyInfo->defaultSpeed;
|
|
||||||
LOG_DEBUG("Using default speed: %d ms/beat", speed);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
LOG_ERROR("Failed to load built-in melody: %s", uidStr.c_str());
|
LOG_ERROR("Failed to load built-in melody: %s", uidStr.c_str());
|
||||||
|
|||||||
@@ -64,7 +64,7 @@
|
|||||||
* 👨💻 AUTHOR: BellSystems bonamin
|
* 👨💻 AUTHOR: BellSystems bonamin
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define FW_VERSION "151"
|
#define FW_VERSION "152"
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -79,6 +79,7 @@
|
|||||||
* v138 - Removed Ethernet, added default WiFi creds (Mikrotik AP) and fixed various Clock issues
|
* v138 - Removed Ethernet, added default WiFi creds (Mikrotik AP) and fixed various Clock issues
|
||||||
* v140 - Changed FW Updates to Direct-to-Flash and added manual update functionality with version check
|
* v140 - Changed FW Updates to Direct-to-Flash and added manual update functionality with version check
|
||||||
* v151 - Fixed Clock Alerts not running properly
|
* v151 - Fixed Clock Alerts not running properly
|
||||||
|
* v152 - Fix RTC Time Reports, added sync_time_to_LCD functionality
|
||||||
* ═══════════════════════════════════════════════════════════════════════════════
|
* ═══════════════════════════════════════════════════════════════════════════════
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user