substitutions: device_name: office-desk-control friendly_name: "Office Desk Control" min_height: "65.5" # cm max_height: "131" # cm tx_pin: GPIO1 # TX rx_pin: GPIO3 # RX #tx_pin: GPIO15 # D7/TXD2 #rx_pin: GPIO13 # D8/RXD2 screen_pin: GPIO12 # D6 external_components: source: github://iMicknl/LoctekMotion_IoT components: [ loctekmotion_desk_height ] esphome: name: ${device_name} friendly_name: ${friendly_name} # Delay UART interaction on boot to give the desk controller time to initialize. # After the delay, wake the desk by sending the "M" command to request the current height. on_boot: priority: -100 then: - delay: 10s - button.press: button_wake_screen - delay: 300ms - button.press: button_m esp8266: board: d1_mini # Enable logging logger: # Enable Home Assistant API api: encryption: key: !secret api_encryption_key # OTA ota: - platform: esphome password: !secret ota_password # WiFi Credentials wifi: domain: .lan ssid: !secret wifi_ssid password: !secret wifi_password power_save_mode: LIGHT # Enable fallback hotspot (captive portal) in case wifi connection fails ap: ssid: "${device_name} Hotspot" password: !secret wifi_ap_password captive_portal: uart: - id: desk_uart baud_rate: 9600 tx_pin: ${tx_pin} rx_pin: ${rx_pin} # debug: sensor: - platform: uptime name: Uptime - platform: loctekmotion_desk_height id: "desk_height" name: Desk height on_value_range: - below: ${min_height} then: - switch.turn_off: switch_down - button.press: button_wake_screen - above: ${max_height} then: - switch.turn_off: switch_up - button.press: button_wake_screen on_value: then: - cover.template.publish: id: desk_cover position: !lambda |- // The sensor outputs values from min_height (cm) to max_height (cm) // We need to translate this to 0 - 1 scale. float position = (float(x) - float(${min_height})) / (float(${max_height}) - float(${min_height})); return position; - component.update: set_desk_height switch: - platform: gpio name: "Virtual screen" # PIN20 pin: number: ${screen_pin} mode: OUTPUT restore_mode: ALWAYS_ON entity_category: "config" internal: true - platform: uart name: "Up" id: switch_up icon: mdi:arrow-up-bold data: [0x9b, 0x06, 0x02, 0x01, 0x00, 0xfc, 0xa0, 0x9d] uart_id: desk_uart send_every: 108ms internal: true on_turn_on: - button.press: button_wake_screen - delay: 200ms - platform: uart name: "Down" id: switch_down icon: mdi:arrow-down-bold data: [0x9b, 0x06, 0x02, 0x02, 0x00, 0x0c, 0xa0, 0x9d] uart_id: desk_uart send_every: 108ms internal: true on_turn_on: - button.press: button_wake_screen - delay: 200ms # - platform: uart # name: "Alarm off" # id: switch_alarm # icon: mdi:alarm # data: [0x9b, 0x06, 0x02, 0x40, 0x00, 0xAC, 0x90, 0x9d] # uart_id: desk_uart # send_every: 108ms # on_turn_on: # - delay: 3000ms # - switch.turn_off: switch_alarm # entity_category: "config" - platform: uart name: "Child lock" id: switch_child_lock icon: mdi:account-lock data: [0x9b, 0x06, 0x02, 0x20, 0x00, 0xac, 0xb8, 0x9d] uart_id: desk_uart send_every: 108ms on_turn_on: - delay: 5000ms - switch.turn_off: switch_child_lock entity_category: "config" button: - platform: template name: "Preset 1" icon: mdi:numeric-1-box on_press: - button.press: button_wake_screen - delay: 200ms - uart.write: id: desk_uart data: [0x9b, 0x06, 0x02, 0x04, 0x00, 0xac, 0xa3, 0x9d] - platform: template name: "Preset 2" icon: mdi:numeric-2-box on_press: - button.press: button_wake_screen - delay: 200ms - uart.write: id: desk_uart data: [0x9b, 0x06, 0x02, 0x08, 0x00, 0xac, 0xa6, 0x9d] - platform: template name: "Sit" # Preset 3 on some control panels icon: mdi:chair-rolling on_press: - button.press: button_wake_screen - delay: 200ms - uart.write: id: desk_uart data: [0x9b, 0x06, 0x02, 0x00, 0x01, 0xac, 0x60, 0x9d] - platform: template name: "Stand" # Preset 4 on some control panels icon: mdi:human-handsup on_press: - button.press: button_wake_screen - delay: 200ms - uart.write: id: desk_uart data: [0x9b, 0x06, 0x02, 0x10, 0x00, 0xac, 0xac, 0x9d] - platform: template name: "Memory" id: button_m icon: mdi:alpha-m-box entity_category: "config" on_press: - uart.write: id: desk_uart data: [0x9b, 0x06, 0x02, 0x20, 0x00, 0xac, 0xb8, 0x9d] - platform: template name: "Wake screen" id: button_wake_screen icon: mdi:gesture-tap-button entity_category: "config" on_press: - uart.write: id: desk_uart data: [0x9b, 0x06, 0x02, 0x00, 0x00, 0x6c, 0xa1, 0x9d] # - platform: template # name: "Alarm" # id: button_alarm # icon: mdi:alarm # on_press: # - uart.write: # id: desk_uart # data: [0x9b, 0x06, 0x02, 0x40, 0x00, 0xAC, 0x90, 0x9d] - platform: restart name: "Restart" entity_category: "config" cover: - platform: template id: "desk_cover" icon: mdi:desk # or mdi:human-male-height-variant name: "Desk" device_class: blind # makes it easier to integrate with Google/Alexa has_position: true position_action: - if: condition: - lambda: !lambda |- return pos > id(desk_cover).position; then: - cover.open: desk_cover - wait_until: lambda: |- return id(desk_cover).position >= pos; - cover.stop: desk_cover else: - cover.close: desk_cover - wait_until: lambda: |- return id(desk_cover).position <= pos; - cover.stop: desk_cover stop_action: - switch.turn_off: switch_up - switch.turn_off: switch_down - button.press: button_wake_screen open_action: - switch.turn_off: switch_down - switch.turn_on: switch_up close_action: - switch.turn_off: switch_up - switch.turn_on: switch_down optimistic: false number: - platform: template name: "Desk height" id: set_desk_height min_value: ${min_height} max_value: ${max_height} icon: "mdi:counter" unit_of_measurement: "cm" device_class: "distance" step: 0.1 lambda: !lambda |- return id(desk_height).state; set_action: - if: condition: - lambda: !lambda |- return x > id(desk_height).state; then: - cover.open: desk_cover - wait_until: lambda: |- return id(desk_height).state >= x; - cover.stop: desk_cover else: - cover.close: desk_cover - wait_until: lambda: |- return id(desk_height).state <= x; - cover.stop: desk_cover