// // Created by lukas on 06.03.21. // #include "Types.h" #include "Clock.h" Clock::Clock() : strip(NUMPIXELS, STRIPPIN, NEO_GRB + NEO_KHZ800), animator(), refreshTicker() { } void Clock::init() { strip.begin(); // initialize clock ticker turnOn(); } void Clock::turnOff() { strip.clear(); strip.show(); refreshTicker.detach(); } void Clock::turnOn() { if (!refreshTicker.active()) refreshTicker.attach(10, [this]() { this->refreshTime(); }); this->refreshTime(); } void Clock::paintAlwaysOnLeds() { printWord(types::es, Adafruit_NeoPixel::Color(150, 150, 0)); printWord(types::ist, Adafruit_NeoPixel::Color(150, 0, 150)); } void Clock::printWord(const std::vector& word, uint32_t color) { for (const uint8_t i : word) { strip.setPixelColor(i, color); } } void Clock::refreshTime() { // grab the current instant in unix seconds time_t now = time(nullptr); if (now <= 604800) { animator.startLoadAnimation(&strip); return; } animator.stopLoadAnimation(); strip.clear(); tm* loctime = localtime(&now); const uint8_t hour = loctime->tm_hour; const uint8_t minute = loctime->tm_min; paintAlwaysOnLeds(); setTime(hour, minute, this->twentyAfterSyntax, this->clockAlwaysOn); strip.show(); Serial.printf("Time now: %uh %uM\n", hour, minute); } void Clock::setTime(uint8_t hour, uint8_t minute, bool twentyAfterSyntax, bool alwaysClockWord) { const uint8_t minuteselector = minute / 5; // if minuteselector >= 4 +1 to hour if (twentyAfterSyntax ? minuteselector >= 5 : minuteselector >= 4) hour++; // convert to 12h format if (hour >= 12) hour = hour - 12; std::vector hourWord; hourWord = hour == 1 ? (minuteselector == 0 ? types::ein : types::eins) // eins only on a full hour : hour == 2 ? types::zwei : hour == 3 ? types::drei2 : hour == 4 ? types::vier : hour == 5 ? types::fuenf2 : hour == 6 ? types::sechs : hour == 7 ? types::sieben : hour == 8 ? types::acht : hour == 9 ? types::neun : hour == 10 ? types::zehn2 : hour == 11 ? types::elf : hour == 0 || hour == 12 ? types::zwoelf : hourWord; printWord(hourWord, Adafruit_NeoPixel::Color(0, 0, 150)); // print the minute words and the corresponding after/before half words printMinutes(minuteselector, twentyAfterSyntax); // uhr if (minuteselector == 0 || alwaysClockWord) printWord(types::uhr, Adafruit_NeoPixel::Color(150, 0, 0)); } void Clock::printMinutes(uint8_t minuteSelector, bool twentyAfterSyntax) { // fuenf / zehn / viertl word std::vector minuteWord; if (minuteSelector == 1 || minuteSelector == 5 || minuteSelector == 7 || minuteSelector == 11) { minuteWord = types::fuenf; } else if (minuteSelector == 2 || minuteSelector == 4 || minuteSelector == 8 || minuteSelector == 10) { // check if we use the twenty after syntax if ((minuteSelector == 4 || minuteSelector == 8) && twentyAfterSyntax) minuteWord = types::zwanzig; else minuteWord = types::zehn; } else if (minuteSelector == 3) minuteWord = types::viertel; else if (minuteSelector == 9) minuteWord = types::dreiviertel; else if (minuteSelector == 6) minuteWord = types::halb; printWord(minuteWord, Adafruit_NeoPixel::Color(0, 150, 0)); // vor / nach std::vector vornachWord; if (minuteSelector == 1 || minuteSelector == 2 || minuteSelector == 3 || ((minuteSelector == 8) && !twentyAfterSyntax) || // check if twentyafter syntax is enabled - if not display the the after minuteSelector == 7 || ((minuteSelector == 4) && twentyAfterSyntax)) // check if twentyafter syntax is enabled - if yes display the the after vornachWord = types::nach; else if (minuteSelector == 5 || ((minuteSelector == 4) && !twentyAfterSyntax) // check if twentyafter enabled if not -- display vor || minuteSelector == 10 || minuteSelector == 11 || ((minuteSelector == 8) && twentyAfterSyntax)) // check if twentyafter enabled if yess -- display vor vornachWord = types::vor; printWord(vornachWord, Adafruit_NeoPixel::Color(150, 150, 150)); // halb if (minuteSelector >= 4 && minuteSelector <= 8) { // only 3 times if twentyafter syntax is on if (!twentyAfterSyntax || (minuteSelector >= 5 && minuteSelector <= 7)) printWord(types::halb, Adafruit_NeoPixel::Color(150, 0, 0)); } } void Clock::useTwentyAfterSyntax(bool twentyAFterSyntax) { this->twentyAfterSyntax = twentyAFterSyntax; } void Clock::useAlwaysOnUhrSyntax(bool alwaysOnUhr) { this->clockAlwaysOn = alwaysOnUhr; } void Clock::update() { if (refreshTicker.active()) this->refreshTime(); }