#pragma once #include "esphome.h" // By now only loosely based on https://github.com/leinich/ha-wordclock-esphome // esphome dependencies: // needs: esphome time --> id: current_time // needs: esphome fastled --> id: fastledlight // #ifdef USE_ESP32 namespace esphome { namespace wordclock { ///// Word Table ///// // .line(0,0,1,0, color); // .line(2,0,3,0, color); // int WORD_IT_IS[5][2] = {{4,0}, {0,0}, {0,1}, {0,3}, {0,4}}; // // .line(2,1,8,1, color); // int WORD_QUARTER[8][2] = {{7,0}, {1,2}, {1,3}, {1,4}, {1,5}, {1,6}, {1,7}, {1,8}}; // // .line(0,2, 5,2, color); // int WORD_TWENTY[7][2] = {{6,0}, {2,0}, {2,1}, {2,2}, {2,3}, {2,4}, {2,5}}; // // .line(6,2, 9,2, color); // int WORD_FIVE_MINUTES[5][2] = {{4,0}, {2,6}, {2,7}, {2,8}, {2,9}}; // // .line(0,3, 3,3, color); // int WORD_HALF[5][2] = {{4,0}, {3,0}, {3,1}, {3,2}, {3,3}}; // // .line(5,3, 7,3, color); // int WORD_TEN_MINUTES[4][2] = {{3,0}, {3,5}, {3,6}, {3,7}}; // // .line(9,3, 10,3, color); // int WORD_TO[3][2] = {{2,0}, {3,9}, {3,10}}; // // .line(0,4, 3,4, color); // int WORD_PAST[5][2] = {{4,0}, {4,0}, {4,1}, {4,2}, {4,3}}; // int WORD_NINE[5][2] = {{4,0}, {4,7}, {4,8}, {4,9}, {4,10}}; // int WORD_ONE[4][2] = {{3,0}, {5,0}, {5,1}, {5,2}}; // int WORD_SIX[4][2] = {{3,0}, {5,3}, {5,4}, {5,5}}; // int WORD_THREE[6][2] = {{5,0}, {5,6}, {5,7}, {5,8}, {5,9}, {5,10}}; // int WORD_FOUR[5][2] = {{4,0}, {6,0}, {6,1}, {6,2}, {6,3}}; // int WORD_FIVE[5][2] = {{4,0}, {6,4}, {6,5}, {6,6}, {6,7}}; // int WORD_TWO[4][2] = {{3,0}, {6,8}, {6,9}, {6,10}}; // int WORD_EIGHT[6][2] = {{5,0}, {7,0}, {7,1}, {7,2}, {7,3}, {7,4}}; // int WORD_ELEVEN[7][2] = {{6,0}, {7,5}, {7,6}, {7,7}, {7,8}, {7,9}, {7,10}}; // int WORD_SEVEN[6][2] = {{5,0}, {8,0}, {8,1}, {8,2}, {8,3}, {8,4}}; // int WORD_TWELFE[7][2] = {{6,0}, {8,5}, {8,6}, {8,7}, {8,8}, {8,9}, {8,10}}; // int WORD_TEN[4][2] = {{3,0}, {9,0}, {9,1}, {9,2}}; // int WORD_OCLOCK[7][2] = {{6,0}, {9,5}, {9,6}, {9,7}, {9,8}, {9,9}, {9,10}}; // using display_writer_t = std::function; struct SegmentCoords { uint16_t x1; uint16_t x2; uint16_t y1; uint16_t y2; }; class Wordclock : public esphome::PollingComponent { public: Wordclock(); Wordclock(esphome::time::RealTimeClock *time, esphome::addressable_light::AddressableLightDisplay *display, esphome::light::AddressableLightState *light_state); void add_segment(SegmentCoords segment); void add_hour(uint8_t index, std::vector *segments); void add_minute(uint8_t index, std::vector *segments); void add_static(uint16_t segment_id); void add_hour_offset(uint8_t index, int8_t offset); void setup(); void update(); // void setup() override { // } // void set_writer(display_writer_t &&writer); // void display_word(const int word[][2], const CRGB& c) { // for (int i=1; i < word[0][0] + 1; i++) { // leds[map_coords_to_strip(word[i][0], word[i][1])].setRGB(c.r, c.g, c.b); // } // } // void display_minutes(int minutes, const CRGB& color) { // int five_minute_chunk = minutes / 5; // switch (five_minute_chunk) // { // case 0: // sharp // display_word(WORD_OCLOCK, color); ESP_LOGD("minute", "oclock "); break; // case 1: // five past // display_word(WORD_FIVE_MINUTES, color); ESP_LOGD("minute", "five past "); break; // case 2: // ten past // display_word(WORD_TEN_MINUTES, color); ESP_LOGD("minute", "ten past "); break; // case 3: // quarter past // display_word(WORD_QUARTER, color); ESP_LOGD("minute", "quarter past "); break; // case 4: // twenty past // display_word(WORD_TWENTY, color); ESP_LOGD("minute", "twenty past "); break; // case 5: // twenty five past // display_word(WORD_TWENTY, color); display_word(WORD_FIVE_MINUTES, color); // ESP_LOGD("minute", "twenty five past "); break; // case 6: // half past // display_word(WORD_HALF, color); ESP_LOGD("minute", "half past "); break; // case 7: // twenty five to // display_word(WORD_TWENTY, color); display_word(WORD_FIVE_MINUTES, color); // ESP_LOGD("minute", "twenty five to "); break; // case 8: // twenty to // display_word(WORD_TWENTY, color); ESP_LOGD("minute", "twenty to "); break; // case 9: // quarter to // display_word(WORD_QUARTER, color); ESP_LOGD("minute", "quarter to "); break; // case 10: // ten to // display_word(WORD_TEN_MINUTES, color); ESP_LOGD("minute", "ten to "); break; // case 11: // five to // display_word(WORD_FIVE_MINUTES, color); ESP_LOGD("minute", "five to "); break; // default: // break; // } // if (five_minute_chunk > 6) { // display_word(WORD_TO, color); // } else if (five_minute_chunk > 0) { // display_word(WORD_PAST, color); // } // } // void display_hour(int hour, int minutes, const CRGB& color) { // int five_minute_chunk = minutes / 5; // if (five_minute_chunk > 6) { // hour += 1; // } // switch (hour % 12) // { // case 0: // twelve // display_word(WORD_TWELFE, color); ESP_LOGD("hour", "twelve "); break; // case 1: // one // display_word(WORD_ONE, color); ESP_LOGD("hour", "one "); break; // case 2: // two // display_word(WORD_TWO, color); ESP_LOGD("hour", "two "); break; // case 3: // three // display_word(WORD_THREE, color); ESP_LOGD("hour", "three "); break; // case 4: // four // display_word(WORD_FOUR, color); ESP_LOGD("hour", "four "); break; // case 5: // five // display_word(WORD_FIVE, color); ESP_LOGD("hour", "five "); break; // case 6: // six // display_word(WORD_SIX, color); ESP_LOGD("hour", "six "); break; // case 7: // seven // display_word(WORD_SEVEN, color); ESP_LOGD("hour", "seven "); break; // case 8: // eight // display_word(WORD_EIGHT, color); ESP_LOGD("hour", "eight "); break; // case 9: // nine // display_word(WORD_NINE, color); ESP_LOGD("hour", "nine "); break; // case 10: // ten // display_word(WORD_TEN, color); ESP_LOGD("hour", "ten "); break; // case 11: // eleven // display_word(WORD_ELEVEN, color); ESP_LOGD("hour", "eleven "); break; // default: // break; // } // } // void display_time(int hour, int minutes, const CRGB& color) { // // clear_all_leds(); // display_word(WORD_IT_IS, color); // display_hour(hour, minutes, color); // display_minutes(minutes, color); // // FastLED.show(); // } // void loop() override { // // auto time = id(current_time).now(); // // https://www.esphome.io/api/classesphome_1_1light_1_1_light_color_values.html LightColorValues Class // // auto fastledlight2 = id(fastledlight).current_values; // //convert float 0.0 till 1.0 into int 0 till 255 // red = (int) (fastledlight2.get_red() * 125); // green = (int) (fastledlight2.get_green() * 125); // blue = (int) (fastledlight2.get_blue() * 125); // brightness = 0; // //check if light is on and set brightness // if (fastledlight2.get_state() > 0 ) { // brightness = (int) (fastledlight2.get_brightness()*125); // } else { // // ESP_LOGD("loop", "fastledlight state off - b: %i rgb %i %i %i", brightness, red, green, blue); delay(100); // } // FastLED.setBrightness(brightness); // FastLED.show(); // //check if valid time. Blink red,green,blue until valid time is present // } protected: void draw_segment(uint16_t segment_id); int8_t find_hour(uint8_t hour); int8_t find_minute(uint8_t minute); // std::vector * find_hour(uint8_t hour); // std::vector * find_minute(uint8_t minute); std::vector> *minutes; std::vector> *hours; std::vector *static_segments; std::vector *hour_offsets; void start_idle_animation(); void end_idle_animation(); // uint16_t **minutes; // uint16_t **hours; bool valid_time{true}; std::vector *segments; esphome::time::RealTimeClock *time; esphome::light::AddressableLight *light; esphome::light::AddressableLightState *light_state; esphome::addressable_light::AddressableLightDisplay *display; light::AddressableRainbowLightEffect *rainbow; light::AddressableTwinkleEffect *twinkle; light::AddressableRandomTwinkleEffect *randomTwinkle; }; } // namespace wordclock } // namespace esphome