Porque en este tutorial vamos a hacer precisamente eso: convertir una mesa regulable de Flexispot en una mesa inteligente, capaz de gestionar automatizaciones de manera eficiente.


¿Te ha llamado la atención el título? ¡Perfecto! Porque en este tutorial vamos a hacer precisamente eso: convertir una mesa regulable de Flexispot en una mesa inteligente, capaz de gestionar automatizaciones de manera eficiente. Prepárate para transformar tu espacio de trabajo en algo mucho más avanzado y funcional.

Mi mesa: Flexispot E1

Desde hace algún tiempo, utilizo una mesa regulable por motor como mi estación de trabajo, tanto para mis tareas personales como para trabajar en remoto. Debo decir que ha sido una inversión que realmente vale la pena. Pasar hasta 8 horas sentado puede resultar agotador para la espalda, y poder alternar entre estar sentado y de pie es un gran alivio.

Mi mesa incluye un controlador (Modelo HCB213A-1) que permite ajustar la altura fácilmente, además de contar con cuatro memorias para guardar diferentes posiciones preestablecidas. También tiene una pantalla LED que muestra la altura en centímetros, lo cual es muy práctico.

Cuando adquirí la mesa, noté que en la parte trasera, además de los conectores para el motor y la corriente, había un conector RJ45.

Sospecho que este conector tiene un propósito básico, ya sea para conectar algún dispositivo adicional, como un módulo Bluetooth para control remoto, o simplemente para facilitar la instalación y actualización del firmware en fábrica, un conector que quizás no retiraron tras el ensamblaje.

Aquí es donde entra en juego la creatividad de la comunidad. Aprovechando este conector, he implementado un proyecto increíble en mi mesa, y te voy a explicar cómo puedes hacerlo también, ya sea que tengas este modelo o uno superior.

Materiales para el montaje

A continuación, os dejo un listado de todo el material necesario para implementar este proyecto:

  • ESP32 8266 (también conocido como D1 Mini Pro)
  • Cable de red (de cualquier categoria)
  • Cables dupon
  • Funda termoretractil para los cables

Herramientas necesarias

  • Soldador y estaño
  • Conector RJ45
  • Grimpadora para RJ45

Esquema para el controlador HCB213A-1

Básicamente tenemos que hacer las siguientes conexiones y soldar los siguientes cables de red con cables dupon:

Num Cable Col Cable Con ESP32
1 Blanco/Naranja VIN (5V)
2 Naranja GND
3 Blanco/Verde TX
4 Azul RX
5 Blanco/Azul D2
6 Verde
7 Blanco/Marrón
8 Marron

Explicación del montaje

Lo primero tendremos que montar un cable de red por un extremo del cable, utilizaremos el código de colores conocido como T-568B y que se puede ver a continuación.

Cuando tengamos montado un pin RJ45 por un lado del cable, por el otro lado tendremos que soldar los cables correspondientes a los conectores dupon. Podemos utilizar luego fundas termoretractil individuales para cada conexión que hagamos y luego una para unirlas todas.

Para el modelo de controlador de Flexispot que tengo, he encontrado información en este Issue del proyecto.

Si tenéis otro controlador, podéis ver toda la información en el siguiente enlace:

GitHub - iMicknl/LoctekMotion_IoT: Learn how to connect your Flexispot (LoctekMotion) desk to the internet. This repository contains a collection of scripts to get your started, combined with research and instructions.
Learn how to connect your Flexispot (LoctekMotion) desk to the internet. This repository contains a collection of scripts to get your started, combined with research and instructions. - iMicknl/Loc…

Preparar ESP32 en Home Assistant

Como ya hemos visto en otro tutorial, primero deberéis de configurar e instalar el firmware de ESP32 en la D1 Mini Pro, para ello deberéis de seguir este otro tutorial.

Añadir dispositivo en ESPHome en Home Assistant
Cómo añadir un dispositivo en ESPHome y conectarlo a tu instancia de Home Assistant, permitiéndote automatizar y gestionar dispositivos IoT de manera eficiente.

Una vez tengamos todo preparado, para el controlador de la mesa HCB213A-1 he utilizado esta configuración:

📢
ACTUALIZACIÓN 24/02/2024
El artículo tiene unos meses ya y han ido actualizado la versión del yaml para adaptarlo a las nuevas actualizaciones de ESPHome. Si tenéis alguna duda sobre que configuración usar, ahora han habilitado un fichero en el repositorio oficial del proyecto.
📢
Este código está adaptado para ser usado con ESP32 8266 específicamente, si usas otro modelo, revisa el fichero que hay en el repositorio.
substitutions:
  device_name: Flexispot E1
  name: flexispot-e11
  min_height: "71" # cm
  max_height: "121" # cm
  tx_pin: GPIO17 # TXD 2
  rx_pin: GPIO16 # RXD 2
  screen_pin: GPIO23
  encryption_key: "XXXXX"

external_components:
  source: github://iMicknl/LoctekMotion_IoT
  components: [ loctekmotion_desk_height ]

esp8266:
  board: esp01_1m1

esphome:
  name: ${name}
  friendly_name: ${device_name}
  comment: Used to control your ${device_name} standing desk via Home Assistant.

  # Wake Desk by sending the "M" command
  # This will pull the current height after boot
  on_boot:
    priority: -10
    then:
      - button.press: button_m


# Enable logging
logger:
  baud_rate: 0

# Enable Home Assistant API
api:
  encryption:
    key: "XXXXXX"

ota:
  platform: esphome
  password: "XXXXX"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

captive_portal:

uart:
  - id: desk_uart
    baud_rate: 9600
    tx_pin: ${tx_pin}
    rx_pin: ${rx_pin}
    # debug:

sensor:
  - platform: wifi_signal
    name: "WiFi Signal"
    update_interval: 60s

  - 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
    - above: ${max_height}
      then:
        - switch.turn_off: switch_up
    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

  - 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

  - 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:
      - 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:
      - 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:
      - 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:
      - 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
    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

En el repositorio de Github se encuentra un fichero llamado desk_height_sensor.h que sirve para saber la altura de la mesa, y es necesario que sea copiado dentro del directorio config/esphome de tu Home Assistant.

LoctekMotion_IoT/packages/esphome/desk_height_sensor.h at main · iMicknl/LoctekMotion_IoT
Learn how to connect your Flexispot (LoctekMotion) desk to the internet. This repository contains a collection of scripts to get your started, combined with research and instructions. - iMicknl/Loc…

Una vez instaléis la configuración del dispositivo, deberíais de tener acceso remoto desde Home Assistant.

Ideas de automatizaciones

A continuación os dejo algunas ideas para crear automatizaciones con nuestra mesa inteligente que hemos creado.

Una que me gusta mucho y que uso a diario, normalmente cuando trabajo en remoto, me gusta atender llamadas y videollamadas de pié, así noto el cansando y no me lio mucho con las llamadas. Así que he creado una automatización que a una hora concreta se eleva le mesa. Esto es útil si por ejemplo haces un daily en equipo siempre a la misma hora.

Otra automatización que tengo es que cada vez que me pasan una llamada al teléfono, la mesa se eleva si estoy en la habitación. De esta forma, puedo atender al llamada de pie.

Algo interesante, es que puedes configurar la altura de la mesa al principio de tu jornada, por ejemplo si quieres empezar siempre de pie porque aún estás dormido/a/e y quieres despejarte, es una forma interesante para crear una automatización y hacer que se eleve la mesa minutos antes de que llegues a la habitación.

Pero sin duda, la automatización que más utilizo, es una por comando de voz y Assist, el asistente de Home Assistant. Le puedo decir "estoy cansado" y se baja la mesa. También puedo decirle "Me levanto" y se eleva la mesa.

Haz que cada palabra cuente: tu donación nos inspira a seguir creando contenido. Accede al apartado de Donación para hacer tu aportación