SSD1306 automate brightness

Trying to use the new SSD1306 brightness feature, automating it from an ambient light sensor (so I don’t have to keep hiding the screen under a mug at night in order to sleep!).

Getting a compile error “TypeError: ‘>’ not supported between instances of ‘ESPLambda’ and ‘int’” when I use the code below:

display:
  - platform: ssd1306_i2c
    id: OLED
    model: "SSD1306 128x64"
    address: 0x3c
    rotation: 180
    brightness: !lambda return "id(${devicename}_ambientlight).state/10.0;"
1 Like

For completeness, fixed by adding code below, with thanks to ssieb on the discord channel for their assistance:

  - platform: bh1750
    name: "${upper_devicename} Ambient Light"
    id: ${devicename}_ambientlight
    address: 0x23
    update_interval: 5s
    on_value:
     then:
      lambda: id(OLED).set_brightness(x / 100.0);

The integer divide will need tweaking for your hardware and light level.

7 Likes

Hi im trying to use the code but im getting TypeError: '>' not supported between instances of 'ESPLambda' and 'int' any sugestions

yaml file

esphome:
  name: master_bedroom_sensor
  platform: ESP32
  board: nodemcu-32s

wifi:
  ssid: "##"
  password: "##"
  power_save_mode: none 
  manual_ip:
#    # Set this to the IP of the ESP
    static_ip: ##
#    # Set this to the IP address of the router. Often ends with .1
    gateway: ##
#    # The subnet of the network. 255.255.255.0 works for most home networks.
    subnet: 255.255.255.0
    dns1: 192.168.1.12

# Enable logging
logger:
  level: debug

# Enable Home Assistant API
api:
  password: "##"

ota:
  password: "##"
  
esp32_ble_tracker:

text_sensor:
  - platform: wifi_info
    ip_address:
      name: "Master Bedroom Sensor IP address"
    ssid:
      name: "Master Bedroom Sensor SSID"
  - platform: version
    name: "Master Bedroom Sensor ESPHome Version"
  - platform: template
    name: Master Bedroom Sensor Uptime
    lambda: |-
      int seconds = (id(uptime_sec).state);
      int days = seconds / (24 * 3600);
      seconds = seconds % (24 * 3600); 
      int hours = seconds / 3600;
      seconds = seconds % 3600;
      int minutes = seconds /  60;
      seconds = seconds % 60;
      return { (String(days) +"d " + String(hours) +"h " + String(minutes) +"m "+ String(seconds) +"s").c_str() };
    icon: mdi:clock-start
    update_interval: 113s    
    
apds9960:
  address: 0x39
  update_interval: 30s    

  
switch:
  - platform: restart
    name: "Master Bedroom Sensor Restart"

  - platform: shutdown
    name: "Master Bedroom Sensor Shutdown" 

binary_sensor:
  - platform: status
    name: "Master Bedroom Sensor Status"   

  - platform: gpio
    pin: 34
    name: "Master Bedroom Motion"
    device_class: motion
    
  - platform: gpio
    pin: 33
    name: "Master Bedroom Sound level"
    filters:
      - delayed_off: 5s  
      
  - platform: ble_presence
    mac_address: ##
    name: "##"   
    
  - platform: ble_presence
    mac_address: ##
    name: "##" 
    
  - platform: ble_presence
    mac_address: ##
    name: "##"  
    
  - platform: apds9960
    name: "Master Bedroom Sensor Up Movement"
    direction: UP
    
  - platform: apds9960
    name: "Master Bedroom Sensor Down Movement"
    direction: DOWN
    
  - platform: apds9960
    name: "Master Bedroom Sensor Left Movement"
    direction: LEFT
    
  - platform: apds9960
    name: "Master Bedroom Sensor Right Movement"
    direction: RIGHT
time:
  - platform: homeassistant
    id: homeassistant_time
    
sensor:
  - platform: bme280
    temperature:
      name: "Master Bedroom Temperature"
      oversampling: 16x
      id: mb_temp
    pressure:
      name: "Master Bedroom Pressure"
      id: mb_press
    humidity:
      name: "Master Bedroom Humidity"
      id: mb_humid
    address: 0x76
    update_interval: 60s
    
  - platform: wifi_signal
    name: "Master Bedroom Sensor WiFi Signal"
    update_interval: 60s 

  - platform: apds9960
    name: "Master Bedroom Clear Channel"
    type: CLEAR
    
  - platform: apds9960
    name: "Master Bedroom Red Channel"
    type: RED
    
  - platform: apds9960
    name: "Master Bedroom Green Channel"
    type: GREEN
    
  - platform: apds9960
    name: "Master Bedroom Blue Channel"
    type: BLUE
    
  - platform: apds9960
    name: "Master Bedroom Proximity Channel"
    type: PROXIMITY
   
  - platform: uptime
    id: uptime_sec
    
  - platform: bh1750
    name: "Master Bedroom Ambient Light"
    id: light
    address: 0x23
    update_interval: 5s
    on_value:
     then:
      lambda: id(OLED).set_brightness(x / 100.0);

display:
  - platform: ssd1306_i2c
    id: OLED
    model: "SSD1306 128x64"
    address: 0x3c
    brightness: !lambda return "id(light).state/10.0;"
    
    lambda: |-
      // Print "Bedroom Sensor" in top center.
      it.printf(64, 0, id(font1), TextAlign::TOP_CENTER, "Bedroom Sensor");
    
    
      // Print Master Bedroom Temperature (from master_bedroom_sensor)
      if (id(mb_temp).has_state()) {
        it.printf(3, 60, id(font2), TextAlign::BASELINE_LEFT , "%.1f°", id(mb_temp).state);
      }

      // Print Master Bedroom Pressure (from master_bedroom_sensor)
      if (id(mb_press).has_state()) {
        it.printf(127, 23, id(font3), TextAlign::TOP_RIGHT , "%.1f°", id(mb_press).state);
      }
      
      // Print Master Bedroom Humidity (from master_bedroom_sensor)
      if (id(mb_humid).has_state()) {
        it.printf(127, 60, id(font3), TextAlign::BASELINE_RIGHT , "%.1f°", id(mb_humid).state);
      }      

font:
  - file: 'slkscr.ttf'
    id: font1
    size: 8

  - file: 'BebasNeue-Regular.ttf'
    id: font2
    size: 36

  - file: 'arial.ttf'
    id: font3
    size: 14


i2c:
    sda: 21
    scl: 22
    scan: True

Hi jonathanpearce,
Can you please post your full yaml, not working for me.

 - platform: homeassistant
    id: oled_brightness_control
    entity_id: input_number.oled_brightness_control
    internal: true
    on_value:
      then:
        lambda:
          id(my_display).set_brightness(x / 1.0);


display:
  - platform: ssd1306_i2c
    model: "SH1106 128x64"
    address: 0x3C
    rotation: 0

So, I’m having trouble getting this to work as well. It compiles fine and there are no errors in the logs, but it doesn’t actually do anything.

Specifying the brightness: attribute under display: does actually change the brightness, so I feel like the problem is in the lambda implementation? I am using the latest dev version of ESPHome.

I only ever got it to compile, thinking I was victorious. It doesn’t work with the hardware sadly, as you’ve also pointed out.
Alas I’ve not had time to get near it, having moved house and been rather busy taking the house apart and trying to put it back together again.

Hi, i got this to work!
you have to call setup() after altering the brightness to get the display to recognize the change. This makes the screen flicker once, but i guess its better than nothing…

sensor:
  - platform: homeassistant
    id: oled_brightness_control
    entity_id: input_number.oled_brightness_control
    internal: true
    on_value:
      then:
        lambda: |-
          id(my_display).set_brightness(x / 1.0);
          id(my_display).setup();

display:
  - platform: ssd1306_i2c
    id: my_display
    model: "SH1106 128x64"
    address: 0x3C
5 Likes

Yes and thanks arehsan this works now my screen turns off when the lights are off.

A little update:
If you add the following if-condition to your display-lambda, the display will turn off when the brightness is 0 (instead if just turning the display brightness all the way down).

display:
  - platform: ssd1306_i2c
    id: my_display
    model: "SH1106 128x64"
    address: 0x3C
    lambda: |-
      if (id(oled_brightness_control).state > 0)
      {
        // your code
      }
2 Likes

Thanks for this, I used your suggestion of .setup() to get mine working too. It’s really too bad that the .set_brightness() doesn’t apply by itself. I was hoping to use this functionality to gently fade the screen to black. Can’t really do that with a .setup() flicker…

Hi’ guys.

I had similar issue and found this thread. Solution works nicely - but not for long…
As ESP will rapidly run out of memory with the repeated setup calls which allocates new memory block from heap and ESP will end up crashing and rebooting :skull:

Check my issue at ESPHome

Ciao !

1 Like

Hi, I have been trying to make my OLED controllable via Home Assistant. Now i got that to work and i wanted to share my configuration in this topic.

First off: the configuration of the oled is just completely as you would want it to be. No different configuration there.

Then add thesse codelines to be able to control your display brightness

light:
  - platform: monochromatic
    name: "OLED Brightness%"
    output: oled_bc
    
output:
  - platform: template
    id: oled_bc
    type: float
    write_action:
      then:
        - lambda: id(oled).set_brightness(state);

This should just do the trick. oled_bc just stands for oled_brightnesscontrol

latest update change:

then:
  - lambda: id(oled).set_contrast(state);
4 Likes

Worth noting this is now fixed in esphome V15 and you no longer need to call setup, which stops it rebooting/resetting periodically.

Indeed it is fixed by kbx81
You can dynamically set brightness and turn on/off display now.
Using a SSD1309 display you will have to use the turn_on() / turn_off() display commands, as setting brightness at 0% won’t turn off display entirely.

CIao !

1 Like

thank you very much m8! you saved the day!! :slight_smile:

1 Like

Hi have you got an example for me please the my config is not working with the latest version of ESPhome

  - platform: bh1750
    id: oled_brightness_control
   # entity_id: input_number.oled_brightness_control
    internal: true
    on_value:
      then:
        lambda: |-
          id(OLED).set_brightness(x / 1.0);
          id(OLED).setup();

display:
  - platform: ssd1306_i2c
    id: OLED
    model: "SSD1306 128x64"
    address: 0x3c
    #brightness: 20%
    
    
    lambda: |-
      if (id(oled_brightness_control).state > 0)
      // Print "Bedroom Sensor" in top center.
      it.printf(64, 0, id(font1), TextAlign::TOP_CENTER, "Bedroom Sensor");

Brightness has become contrast in the latest release. Update your code to match and it should start working again, mine has.

2 Likes

Thanks for updating, I had no-idea (until getting to the bottom of this thread), of the change from set_brightness() → set_contrast(), this also fixed my code (with out the need for the setup() command).

1 Like

Thanks Bjorn301 !!!
Finally, I can change the brightness on my SH1107 128*128 OLED display.
I share the part and hope to help someone…

display:
  - platform: ssd1306_i2c
    model: 'SH1107 128x128' 
    address: 0x3C
    id: display_oled

number:
  - platform: template
    name: "Brightness Display"
    id: "brightness_display"
    unit_of_measurement: '%'
    mode: slider
    step: 1
    min_value: 0
    max_value: 100
    optimistic: true
    initial_value: 100
    on_value:
      then:
        lambda: id(display_oled).set_contrast(x / 100.0);
1 Like