Wordclock mirror - ESPHome

Hello,
I have already posted this issue on GitHub . (Clock does not work · Issue #3 · leinich/ha-wordclock-esphome · GitHub) under the post.
Maybe someone can help me here as well…

I bought a “MirrorClock” kit some time ago.
This clock is controlled by remote control (color, brightness, etc.)
The time is fetched via WiFi.

Now I have seen this post.
Since my clock and the one built here are quite similar, I wanted to reprogram my “MirrorClock”.

I have adapted the layout of the letters.

However, nothing happens when I turn on the clock.
I can only control the LEDs as a complete strip like a normal LED strip.

Can you help me there?

I don’t know, if the Header-file “wordclock.h” is included by compiling the .bin file…?

Greetings
SimBu01

@JeePee
in my previous post I missed to mention that you also need add in line 88 to something like:

auto ldr = id(ldr);

@SimBu01
Something i can imagine ist , that you are using the same GPIO in yaml and in wordclock.h
In the yaml file I used a free GPIO (where nothing is attached).
Only in wordclock.h i used the correct GPIO.
So actually the fastledlight is only a dummy for getting the settings withing wordclock.h
Hopes that this makes sense.

@leinich
You’re right, I used the same GPIO.
So I would test it when i have time for.
I already tought why this isn’t the same… But there is also a mistake in the file names (GitHub download).
The .h file is named “wordcloch.h” and in yaml included as “wordclock.h”.

But then this is my fault.
Thank you

Thanks for hint. Fixed the typo.

unfortunately this isn’t resolving the problems completely. For now I’m getting the next message:

In file included from src/main.cpp:34:0:
src/wordclock.h: In member function 'virtual void Wordclock::loop()':
src/wordclock.h:101:21: error: request for member 'get_state' in 'ldr', which is of non-class type 'unsigned char'
             if (ldr.get_state() > 0 ) { brightness = (int)(ldr.get_brightness()*255); }
                     ^
src/wordclock.h:101:64: error: request for member 'get_brightness' in 'ldr', which is of non-class type 'unsigned char'
             if (ldr.get_state() > 0 ) { brightness = (int)(ldr.get_brightness()*255); }

coding is pretty new for me, so any help is appriceated!

We will work this out via direct message and only report the results here :wink:
Please check your messages

I was wondering if LDR-integration was worked out. Would like to implement this to my esphome wordclock

Yes.
Here you are:

1 Like

Thanks, works like a charm!

I made some changes in order to use neopixelbus. This library supports also RGBW ledstrips, which is what I use.

I also used your ‘new’ change integer to detect color changes, in order to directly change the color (instead of only every minute).

            red = (int)(ledlight.get_red()*255);
            green = (int)(ledlight.get_green()*255);
            blue = (int)(ledlight.get_blue()*255);
            white = (int)(ledlight.get_white()*255);

            RgbwColor color2 = RgbwColor(red, green, blue, white);  

            if (color != color2) { 
                change = 1; 
                color = color2;
                // ESP_LOGD("loop", "Color change rgb %i %i %i", red, green, blue);
            }

Okay so today I tried to change the GPIO to an unused in the yaml-file.
But it does not work.
The ESP is online but it doesn’t show any time and nothing is lighten up…

Do you have any other idea to help me?

Can you share your code with neopixelbus? Im having some issues with the fastledlight updating

I really like this project and I’m thinking to do something similar but just with some icons and touch sensitive pads on the back of the mirror.

Is is correct that you cut the foil with the laser cutter/engraver on the back of the mirror and peel off the foil so it’s just clear glass? Do you use any raster for the LEDs? Also don’t you see the LED’s through the glass?

Thanks :slight_smile:

There is no foil involved. The laser just burns down the back of the mirror and leaves a nice opal glas finish. ha-wordclock-esphome/Back_frame.png at 886f0d42099a134c35789cb7e1c24f0d58f9e03e · leinich/ha-wordclock-esphome · GitHub

To controll the light to only shine trough one letter, I added a grid pattern of small MDF stripes between the space of the back of the mirror and teh LEDs. Hopes this makes sense:

1 Like

Sure: GitHub - jjansen85/ha-wordclock-esphome: ESPHome Wordclock - based on esphome

1 Like

Hi all, great project, really appreciate all the work.
$15 Paypal tip for anyone that can help!
I require some expert help.

Tried implementing this, but tweaking it to my specifications, so far all that happens is all LED’s are turned on. Not sure where I’m going wrong with this. Any help would be greatly appreciated.
Scripts are as follows…

wordclock.yaml

esphome:
  name: wordclock
  includes:
    - wordclock.h
  on_boot:
    priority: 800
    then:
      - light.turn_on: 
          id: fastledlight
          
esp8266:
  board: d1_mini
  framework:
    version: 2.7.4
          
substitutions:
  devicename: wordclock
  friendly_name: "Wordclock"

wifi:
  ssid: "UPC7C77516"
  password: "password"

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Horloge Fallback Hotspot"
    password: "password"

# WEB Server
web_server:
  port: 80
  
# Sensors
#sensor:
#  - platform: wifi_signal
#    name: "th0 Signal Wi-Fi"
#    update_interval: 60s
    
# Enable logging
logger:
#    level: VERBOSE
    
# Enable Home Assistant API
api:
  password: "password"

ota:
  password: "password"



light:
  - platform: fastled_clockless
    id: fastledlight
    rgb_order: GRB
    chipset: WS2811
    pin: GPIO02
    restore_mode: RESTORE_DEFAULT_ON
    num_leds: 114
    name: ${friendly_name}
  
time:
  - platform: homeassistant
    id: current_time

custom_component:
- lambda: |-
    auto wordclock = new Wordclock();
    return {wordclock};

wordclock.h

#include "esphome.h"
#include <FastLED.h>

#define NUM_LEDS 114
#define DATA_PIN D4

// esphome dependencies:
// needs: esphome time --> id: current_time
// needs: esphome fastled --> id: fastledlight

// Layout of Clock (X not used chars) - PIN Layout
// ESXISTXFÜNF    1.......11
// ZEHNZWANZIG    22......12
// DREIVIERTEL    23......33
// XXNACHVORXX    44......34
// HALBXZWÖLFX    45......55
// ZWEIXSIEBEN    ....
// XDREIXXFÜNF    ....
// ELFNEUNVIER    ....
// XACHTZEHNRS    ....
// XSECHSXXUHR    109.......101
// ICONS          110.......120
// MINUTES        124.......121

int leds_time_it_is[] = {10, 9, 7, 6, 5}; // ES IST
int leds_minutes[] = {124, 123, 122, 121}; // Minutes LEDS
int leds_skiped[] = {110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120}; // Check Line 101
int leds_time_minutes[][15] = {
    { 60,  61,  62,  63,  64,  65,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1}, // UHR
    { 92,  91,  90,  89,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1}, // FÜNF, NACH
    { 68,  67,  66,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1}, // ZEHN, NACH
    { 77,  78,  80,  81,  82,  83,  84,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1}, // VIERTEL, NACH
    { 98,  97,  96,  95,  94,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1}, // ZWANZIG, NACH
    { 98,  97,  96,  95,  94,  93,  92,  91,  90,  89,  -1,  -1,  -1,  -1,  -1}, // FÜNF, VOR, HALB
    {102, 103, 104, 105,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1}, // HALB
    { 76,  75,  74,  73,  72,  98,  97,  96,  95,  94,  93,  92,  91,  -1,  -1}, // FÜNF, NACH, HALB
    { 76,  75,  74,  73,  72,  98,  97,  96,  95,  94,  -1,  -1,  -1,  -1,  -1}, // ZWANZIG, VOR
    { 76,  75,  74,  73,  72,  74,  75,  80,  87,  82,  83,  84,  -1,  -1,  -1}, // DREIVIERTEL
    { 76,  75,  74,  73,  72,  68,  67,  66,  -1,  -1,  -1,  -1,  -1,  -1,  -1}, // ZEHN, VOR
    { 76,  75,  74,  73,  72,  92,  91,  90,  89,  -1,  -1,  -1,  -1,  -1,  -1}  // FÜNF, VOR
};

int leds_time_hours[][6] = {
    { 54,  53,  52,  51,  -1,  -1}, // ZWÖLF
    { 28,  27,  26,  -1,  -1,  -1}, // EINS
    {  3,   2,   1,   0,  -1,  -1}, // ZWEI
    { 17,  18,  19,  20,  21,  -1}, // DREI
    { 11,  12,  13,  14,  15,  16}, // VIER
    { 40,  41,  42,  43,  -1,  -1}, // FÜNF
    { 37,  38,  39, 105,  -1,  -1}, // SECHS
    { 25,  24,  23,  22,  -1,  -1}, // SIEBEN
    { 33,  34,  35,  36,  -1,  -1}, // ACHT
    { 32,  31,  30,  29,  -1,  -1}, // NEUN
    { 52,  51,  50,  96,  -1,  -1}, // ZEHN
    { 55,  56,  57,  58,  -1,  -1}  // ELF
};

CRGB leds[NUM_LEDS];
int hour = -1;
int minute = -1;
int red = 124;
int green = 124;
int blue = 124;
int brightness = 50;

class Wordclock : public Component, public CustomAPIDevice {
    public:
        void setup() override {
            FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);
            FastLED.setBrightness(brightness);
            // Start all LED with on and default color and brightness to check if everything is working...
            for(int i = 0; i < NUM_LEDS; i++) { leds[i].setRGB(red, 0, 0); FastLED.show(); delay(10); }
            for(int i = 0; i < NUM_LEDS; i++) { leds[i].setRGB(0, green, 0); FastLED.show(); delay(10); }
            for(int i = 0; i < NUM_LEDS; i++) { leds[i].setRGB(0, 0, blue); FastLED.show(); delay(10); }
            for(int i = 0; i < NUM_LEDS; i++) { leds[i].setRGB(0, 0, 0); }
            FastLED.show();
            register_service(&Wordclock::on_setled, "setled", {"number","red", "blue", "green"});
        }
        void on_setled(int number, int red, int blue, int green) {
            if (number < NUM_LEDS || number > 0) {
                ESP_LOGD("setled", "Setting led number %d to color %i %i %i", number, red, green, blue );
                leds[number].setRGB(red, green, blue);
                FastLED.show();
                }
            else { ESP_LOGE("setled", "Not a valid LED Number - out of range"); }
        }
        void loop() override {
            auto time = id(current_time).now();
            int h = time.hour;
            int m = time.minute;
            // 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()*255);
            green = (int)(fastledlight2.get_green()*255);
            blue = (int)(fastledlight2.get_blue()*255);
            brightness = 0;
            //check if light is on and set brightness
            if (fastledlight2.get_state() > 0 ) { brightness = (int)(fastledlight2.get_brightness()*255); }
            else { ESP_LOGD("loop", "fastledlight state off - b: %i rgb %i %i %i", brightness, red, green, blue); delay(500);}
            FastLED.setBrightness(brightness);
            //check if valid time. Blink red,green,blue until valid time is present
            if (time.is_valid() == false) {
                ESP_LOGE("loop", "Got invalid time from current_time Time: %i:%i", h, m );
                leds[0].setRGB(255, 0, 0); FastLED.show(); delay(250);
                leds[0].setRGB(0, 255, 0); FastLED.show(); delay(250);
                leds[0].setRGB(0, 0, 255); FastLED.show(); delay(250);
                leds[0].setRGB(0, 0, 0);   FastLED.show();
            }
            else {
                // only update once in a Minute
                if(h != hour || m != minute) {
                   //ESP_LOGD("loop", "Using b: %i rgb %i %i %i", brightness, red, green, blue);
                    hour = h;
                    minute = m;
                    if (hour >= 0 && time.is_valid() == true){
                        int tmp_hour = hour;
                        int tmp_minute = (minute - (minute % 5));
                        if(tmp_minute >= 25) { tmp_hour += 1; }
                        tmp_minute = tmp_minute / 5;
                        tmp_hour = tmp_hour % 12;
                        int minutessum = minute % 5;
                        // Reset all LED, but skip LED 110 till 120
                        for(int i = 0; i < NUM_LEDS; i++) {     if(i < 110 || i > 120) leds[i].setRGB(0, 0, 0); }
                        for(int i = 0; i < 5; i++) {            leds[leds_time_it_is[i]].setRGB(red, green, blue); }
                        for(int i = 0; i < 15; i++) {           if(leds_time_minutes[tmp_minute][i] >= 0) { leds[leds_time_minutes[tmp_minute][i]].setRGB(red, green, blue); } }
                        for(int i = 0; i < 6; i++) {            if(leds_time_hours[tmp_hour][i] >= 0) { leds[leds_time_hours[tmp_hour][i]].setRGB(red, green, blue); } }
                        for(int i = 0; i < minutessum; i++) {   leds[leds_minutes[i]].setRGB(red, green, blue);}
                        FastLED.show();
                        ESP_LOGD("loop", "Update Time: %i:%i  Brightness: %i RGB: %i-%i-%i", hour, minute, brightness, red, green, blue);
                        ESP_LOGD("loop", "Using tmp_hour: %i tmp_minute: %i minutessum: %i", tmp_hour, tmp_minute, minutessum);
                    }
                }
            }
        }
};

Dear adzybee,

on what PIN did you connect the LED stripe?
In wordclock.yaml you need to specify any unused PIN (dummy Pin)
It is only importaint, that in wordclock.h DATA_PIN is set correctly.

It seems to me that you have tryed to specify the same PIN wordclock.yaml and wordclock.h

1 Like

Is it possible to use neopixelbus with WS2812B stripes, because fastled isn’t working anymore on ESPHome for Esp8266

Yes, no problem.
But for the wordclock.h you might need to change some things, it is now based on RGBW strips.

Change all RgbwColor to RgbColor
Change things like RgbwColor(red, green, blue, white) to RgbColor(red, green, blue)

But maybe it also works without these changes, not sure.

Most important is to change line 4, 5 and 9. For WS2812B strip, I would say
NeoPixelBrightnessBus< NeoGrbFeature, NeoWs2812xMethod> strip(PixelCount, PixelPin);

Please read NeoPixelBus object · Makuna/NeoPixelBus Wiki · GitHub

You can also simply downgrade the ardoino version in your wordclock.yaml file. Have a look at the documentation fon ESPHome FastLed:

So you can use the code from leinich. Attached is a code snippet of my yaml file:

esp8266:
  board: nodemcuv2
  framework:
    version: 2.7.4

esphome:
  name: ${devicename}
  # platform: ESP8266

  includes:
    - wordclock.h
  on_boot:
    priority: 800
    then:
      - light.turn_on:
          id: fastledlight
          red: 100%
          green: 0%
          blue: 100%

substitutions:
  devicename: wordclock
  friendly_name: "Wordclock"

light:
  - platform: fastled_clockless
    id: fastledlight
    chipset: WS2812
    pin: GPIO03
    num_leds: 130
    rgb_order: BRG
    name: ${friendly_name}