Hardware

To disassemble the lamp, simply remove the three screws hidden underneath the rubber pads on the bottom panel, then follow the Tasmota documentation [Archive] to solder the necessary wires to the ESP module:

pinout

Source: https://github.com/gsimon75/Tasmota_MiDeskLamp_Notes

  1. Black: GND, to any of PIN3, 5, 6, 7, 15, 16, 19 or 20
  2. White: Vcc (+3.3 V), to PIN8
  3. Gray: UART RxD, to PIN17
  4. Purple: UART TxD, to PIN18
wiring

Also short PIN4 (GPIO0) and PIN3 (GND), then short PIN9 (RST) and PIN7 (GND) with tweezers and release, to reset the ESP module and enter flashing mode.

Software

ESPHome configuration example:

Source: https://github.com/syssi/esphome-mi-desk-lamp

substitutions:
  default_color_temperature: '250.0'  # adjust it to your liking (in mireds, 1000000 / 4000 K = 250 mireds)

esphome:
  name: lamp
  comment: 'Xiaomi Mijia desk lamp'

esp8266:
  board: esp01_1m  # 1 MB flash size
  restore_from_flash: true

logger:
  level: WARN
  baud_rate: 115200

wifi:
  fast_connect: true
  networks:
    - ssid: !secret wifi_ssid
      bssid: !secret wifi_bssid
      password: !secret wifi_password
  domain: !secret domain_name

api:
ota:
  password: !secret ota_password

button:
  # for hard restart
  - platform: restart
    id: restart_button
    name: 'Restart Lamp'
    entity_category: diagnostic

globals:
  - id: color_temperature
    type: float
    restore_value: no
    initial_value: ${default_color_temperature}

sensor:
  - platform: rotary_encoder
    id: rotation
    pin_a: 13
    pin_b: 12
    resolution: 2
    on_value:
      then:
        - if:
            condition:
              # check if the rotary encoder is pressed while rotating
              lambda: 'return id(rotary_encoder_button).state;'
            then:
              # if it's pressed, change color temperature
              - lambda: |-
                  auto min_temp = id(light_).get_traits().get_min_mireds();
                  auto max_temp = id(light_).get_traits().get_max_mireds();
                  auto cur_temp = id(light_).current_values.get_color_temperature();
                  id(color_temperature) = max(min_temp, min(max_temp, cur_temp + (x * 10)));
                  auto call = id(light_).turn_on();
                  call.set_color_temperature(id(color_temperature));
                  call.perform();
            else:
              # if it's not pressed, change brightness
              - light.dim_relative:
                  id: light_
                  relative_brightness: !lambda 'return x / 25.0;'
        # reset rotation
        - sensor.rotary_encoder.set_value:
            id: rotation
            value: 0
    internal: true

binary_sensor:
  - platform: gpio
    id: rotary_encoder_button
    pin:
      number: 2
      inverted: true
    on_multi_click:
      # on double click, reset color temperature to default
      - timing:
          - ON for at most 1s
          - OFF for at most 1s
          - ON for at most 1s
          - OFF for at least 0.2s
        then:
          - lambda: |-
              id(color_temperature) = ${default_color_temperature};
              auto call = id(light_).turn_on();
              call.set_color_temperature(id(color_temperature));
              call.set_transition_length(500);  // adjust it to your liking (in milliseconds)
              call.perform();
      # on single click, toggle light
      - timing:
          - ON for at most 1s
          - OFF for at least 0.5s
        then:
          - light.toggle:
              id: light_
              transition_length: 0.5s  # adjust it to your liking
    internal: true

  # use the reset button for hard restarting
  - platform: gpio
    id: reset_button
    pin:
      number: 14
      inverted: true
    internal: true
    on_release:
      then:
        - button.press: restart_button
    internal: true

output:
  # cold white channel
  - platform: esp8266_pwm
    id: output_cold
    pin: 4
  # warm white channel
  - platform: esp8266_pwm
    id: output_warm
    pin: 5

light:
  - platform: cwww
    id: light_
    name: 'Lamp'
    icon: mdi:desk-lamp
    cold_white: output_cold
    warm_white: output_warm
    cold_white_color_temperature: 6500 K
    warm_white_color_temperature: 2700 K
    default_transition_length: 0s
    constant_brightness: true
    gamma_correct: 0
    on_turn_on:
      - light.control:
          id: light_
          state: on
          color_temperature: !lambda 'return id(color_temperature);'
    on_turn_off:
      - lambda: 'id(color_temperature) = id(light_).current_values.get_color_temperature();'
    restore_mode: RESTORE_DEFAULT_OFF

After resetting the ESP module, wait a minute for Home Assistant to automatically discover the new ESPHome device, then simply select to adopt it. After that, you can add a native light card with brightness and color temperature control to Lovelace.

lovelace-card

About Extra Features

Previously, according to the last section [Archive] in the Tasmota documentation,

As the lamp has external power supply, and the LEDs are in the upper part of the lamp, the temperature of the base is the same as of the ambient, and by its nature the lamp is situated on your desk, so it's a perfect place for temp+humidity measurements.

So I connected a DHT22 temperature and humidity sensor to GPIO0. However, after some time I found it's not working well, the temperature reading would rise by about 5 ℃ as soon as the lamp was turned on.


0 Comments

Leave a Reply

Avatar placeholder

Your email address will not be published. Required fields are marked *