227 lines
9.4 KiB
C++
227 lines
9.4 KiB
C++
#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<void(esphome::Dieplay::Display &)>;
|
|
|
|
|
|
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<uint16_t> *segments);
|
|
void add_minute(uint8_t index, std::vector<uint16_t> *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<uint16_t> * find_hour(uint8_t hour);
|
|
// std::vector<uint16_t> * find_minute(uint8_t minute);
|
|
std::vector<std::vector<uint16_t>> *minutes;
|
|
std::vector<std::vector<uint16_t>> *hours;
|
|
std::vector<uint16_t> *static_segments;
|
|
std::vector<int8_t> *hour_offsets;
|
|
|
|
void start_idle_animation();
|
|
void end_idle_animation();
|
|
|
|
// uint16_t **minutes;
|
|
// uint16_t **hours;
|
|
|
|
bool valid_time{true};
|
|
std::vector<SegmentCoords> *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
|
|
|