Schreibtisch smart machen mit ESP8266

Seit beginn der Corona Pandemie arbeite ich primär im Home Office und habe mir daher einen Schreibtisch gekauft der höhenverstellbar ist. Meine Wahl fiel auf einen Sanodesk EZ1. Hierzu hatte ich ein Video zum Aufbau erstellt, welches du dir hier ansehen kannst. Ich hatte mir nur das Gestell gekauft und darauf eine günstige Tischplatte von IKEA geschraubt, die ich bereits auf meinem vorherigen Schreibtisch genutzt hatte. In dieser Kombination war der Schreibtisch dank Rabattaktion sehr günstig mit knapp 230€.

Zu meiner Verwunderung war die Rechnung aber nicht von Sanodesk sondern von Flexispot! Somit war klar, dass Sanodesk einfach nur eine weitere Marke von Flexispot ist. Glücklicherweise habe ich mich damals für eine Premium Steuerung entschieden, die Funktionen wie Presets, Kindersicherung oder auch eine Hinderniserkennung beinhaltet.

Nun ist das Gestellt seit 2 Jahren im Einsatz und wird täglich mehrmals hoch und runter gefahren. Soweit war ich mit dem gebotenen und dem Funktionsumfang sehr zufrieden. Ein Youtube Zuschauer hatte mich zuletzt gefragt, ob die Steuerung einen USB Port besitzt um den Schreibtisch smart zu machen. Das hat meine neugier geweckt. Einen USB Port habe ich zwar nicht dafür aber zwei RJ45 Ports an der Control Box. Es gibt aber auch Control Panels mit USB Port. Ich habe mich kurzerhand an die Recherche gemacht und bin direkt fündig geworden!

In folgenden möchte ich dir nun zeigen, wie ich meinen Flexispot Schreibtisch samt Sprachsteuerung smart gemacht habe!

AZDelivery 3 x D1 Mini NodeMcu mit ESP8266-12F WLAN Module CH340G Lua kompatibel mit Arduino...
2.702 Bewertungen
AZDelivery 3 x D1 Mini NodeMcu mit ESP8266-12F WLAN Module CH340G Lua kompatibel mit Arduino...
  • ✅ Sichern Sie sich jetzt drei D1 Mini NodeMcu...
  • ✅ Der AZ-Delivery D1 mini ist ein Mini-NodeMcu...
  • ✅ Durch seine ultra-kompakte Bauform lässt sich...
  • ✅ Das AZ-Delivery drathloses D1 Mini...
  • ✅ Dieses Produkt enthält ein E-Book, das...

Loctek Motion Control Panel

Damit die hier gezeigte Lösung funktioniert benötigt es ein Control Panel von Loctek Motion. Ob eine Loctek Motion Steuerung verbaut ist lässt sich nur heraus finden indem das Control Panel aufgeschraubt wird. Bei meinem Panel ist es folgende Version: HS13A-2

Loctek Motion HS13A Control Panel
Loctek Motion HS13A Control Panel

Im Weiteren habe ich unter meinem Schreibtisch eine Control Box des Modells: CB28M1B(IB)

Die Control Box besitzt zwei RJ45 Anschlüsse. An einem Anschluss hängt das Control Panel. Der zweite Anschluss war also frei, um „etwas“ anzuschließen. Mit diesen Informationen habe ich mich nun auf die Suche begeben, um die richtige Vorgehensweise heraus zu finden, den Schreibtisch ins Smarthome zu integrieren. Auf der Projektseite gibt es 3 Methoden:

  • Arduino
  • ESP32
  • Raspberry PI

Schnell habe ich mich für die ESPHome Variante entschieden und den Source Code von der Projektseite herunter geladen. Im ESP32 Order finden sich verschiedene vorgefertigte YAML Konfigurationen, die nur leicht angepasst werden müssen. Dazu aber später. Als erstes habe ich die Hardware vorbereitet. Alles was nötig ist hatte ich zu Hause.

  • ESP8266
  • RJ45 Kabel 0,25cm
  • Dupont Kabel
  • Wage Klemmen

Steuerung mit ESP8266 und RJ45 vorbereiten

Auf der einen Seite habe ich den Stecker des Netzwerkkabel abgeschnitten und die Drähte aufgetrennt. Anschließend abisoliert und verzinnt. Jetzt kam der schwierigste Part!

Die RJ45 Belegung des Netzwerkkabel muss auf den D1 mini gemappt werden als auch auf die Belegung des Loctek Motion Boards. Hierzu hilft es sehr die Belegung auf dem Board zu kennen als auch die Belegung des RJ45 Steckers. Auf dem Kabel sollte aufgedruckt sein, welcher Kabeltyp es ist. Mein Kabel ist vom Typ T-568B

Dan ich ein Control Panel ohne USB Anschluss habe ist auf meinem Board ein Stecker mit 8 Drähten. Bei Control Panles mit USB port sollten es ein Stecker mit 10 Drähten sein. Das folgende Schema ist, das was bei mir funktioniert:

RJ45 Pinout T-568B
RJ45 Pinout T-568B
D1 Mini Wago Setup
D1 Mini Wago Setup

Mit Wago Klemmen habe ich anschließend die Verbindung zwischenESP8266 und RJ45 Kabel hergestellt. Es gibt auch Beispiele, bei denen die Drähte fest verlötet oder direkt auf das Loctek Board gelötet werden. Das wollte ich nicht und finde den Ansatz mit Wago Klemmen sehr flexibel. So lassen sich die Verbindungen bei Bedarf schnell lösen.

Anschluss D1 Mini und RJ45
Anschluss D1 Mini und RJ45

Was richtig cool ist, dass meine Control Box einen 5V Anschluss unterstützt. Damit bekommt der D1 Mini seinen Strom direkt über den RJ45 Anschluss von der Control Box. Ich musste also kein separates USB Kabel für den Strom ziehen.

D1 Mini per RJ45 an Control Box
D1 Mini per RJ45 an Control Box

ESP32 YAML Konfiguration

Technisch ist nun alles soweit vorbereitet. Als letztes habe ich die ESPHome Konfiguration erstellt auf Basis der Vorlage flexispot_ek5.yaml

In der Konfiguration habe ich zwei Anpassungen vorgenommen:

  • Board festgelegt
  • WakeUp definiert
esphome:
  name: ${name}
  comment: ${device_name}
  platform: ESP8266 # TODO Change to your platform
  board: d1_mini # TODO Change to your board
  includes:
    - desk_height_sensor.h

Damit die Control Box Signale empfängt muss das Display aufgeweckt werden. Aufgeweckt ist das Display sobald die Höhe auf dem Display zu sehen ist. Über den WakeUp Schalter hat das zuerst nicht funktioniert. Daher muss folgende Zeile angepasst werden damit der D1 immer Befehle absetzen kann: restore_mode: ALWAYS_ON

switch:
  - platform: gpio
    name: "Virtual Screen"
    pin:
      number: D2
      mode: OUTPUT
    restore_mode: ALWAYS_ON
    internal: true

Home Assistant und Sprachsteuerung

Nachdem die ESPHome Konfiguration erstellt und der ESP8266 Online ist wird eine neues Device erstellt. Dank NabuCasa Abo war es ein Kinderspiel die Steuerung in Alexa als auch Google Home einzubinden. Bei Alexa musste ich noch die Entitäten auswählen. Google hatte die Entitäten direkt übernommen nachdem diese in Home Assistant verfügbar waren.

Flexispot / Sanodesk EZ1 in Home Assistant
Flexispot / Sanodesk EZ1 in Home Assistant

Fazit

Mit diesem Setup bieten sich nun diverse Möglichkeiten den Schreibtisch zu steuern. Ich hoffe dir hilft die Anleitung ebenfalls insofern du die entsprechenden Voraussetzungen hast und deinen Arbeitsplatz smart machen möchtest!

Weitere Artikel zum Thema ESP32 findest du hier!

Falls du noch Fragen haben solltest hinterlasse gerne einen Kommentar!

Den Inhalt des Beitrags findest du ebenfalls auf Youtube im zugehörigen Video:

Vollständiger Flexispot / LocTek Motion YAML Code:

substitutions:
  device_name: Flexispot EK5
  name: flexispot_ek5
  min_height: "71.0" # Min height + 0.1
  max_height: "121.0" # Max height - 0.1

esphome:
  name: ${name}
  comment: ${device_name}
  platform: ESP8266 # TODO Change to your platform
  board: d1_mini # TODO Change to your board
  includes:
    - desk_height_sensor.h

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


captive_portal:

# Enable logging
logger:
  #level: DEBUG
  baud_rate: 9600

# Enable Home Assistant API
api:
ota:


uart:
  id: desk_uart
  baud_rate: 9600
  tx_pin: D5
  rx_pin: D6

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

  - platform: uptime
    name: Uptime

  - platform: custom
    lambda: |-
      auto desk_height_sensor = new DeskHeightSensor(id(desk_uart));
      App.register_component(desk_height_sensor);
      return {desk_height_sensor};
    sensors:
      id: "desk_height"
      name: Desk Height
      unit_of_measurement: cm
      accuracy_decimals: 1
      icon: "mdi:counter"

switch:
  - platform: gpio
    name: "Virtual Screen"
    pin:
      number: D2
      mode: OUTPUT
    restore_mode: ALWAYS_ON
    internal: true

  - platform: uart
    name: "Preset 1"
    id: switch_preset1
    icon: mdi:numeric-1-box
    data: [0x9b, 0x06, 0x02, 0x04, 0x00, 0xac, 0xa3, 0x9d]
    uart_id: desk_uart

  - platform: uart
    name: "Preset 2"
    id: switch_preset2
    icon: mdi:numeric-2-box
    data: [0x9b, 0x06, 0x02, 0x08, 0x00, 0xac, 0xa6, 0x9d]
    uart_id: desk_uart

  - platform: uart
    name: "Sit" # Preset 3 on some control panels
    id: switch_sit
    icon: mdi:chair-rolling
    data: [0x9b, 0x06, 0x02, 0x00, 0x01, 0xac, 0x60, 0x9d]
    uart_id: desk_uart

  - platform: uart
    name: "Stand" # Not available for all control panels
    id: switch_stand
    icon: mdi:human-handsup
    data: [0x9b, 0x06, 0x02, 0x10, 0x00, 0xac, 0xac, 0x9d]
    uart_id: desk_uart

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

  - platform: uart
    name: "M"
    id: switch_m
    icon: mdi:alpha-m-circle
    data: [0x9b, 0x06, 0x02, 0x20, 0x00, 0xac, 0xb8, 0x9d]
    uart_id: desk_uart

  - platform: uart
    name: "(wake up)" # Not available on all control panels
    id: switch_wake_up
    icon: mdi:gesture-tap-button
    data: [0x9b, 0x06, 0x02, 0x00, 0x00, 0x6c, 0xa1, 0x9d]
    uart_id: desk_uart

cover:
  - platform: template
    has_position: true
    id: desk_cover
    icon: mdi:human-male-height-variant
    name: "Desk"
    #assumed_state: true
    device_class: blind 

    # Move desk up
    open_action:
      - while:
          condition:
            sensor.in_range:
              id: desk_height
              below: ${max_height}
          then:
            - logger.log: "Executing up command"
            - cover.template.publish:
                id: desk_cover
                current_operation: OPENING
            - uart.write:
                id: desk_uart
                data: [0x9b, 0x06, 0x02, 0x01, 0x00, 0xfc, 0xa0, 0x9d]
            - delay: 150ms
    
    # Move desk down
    close_action:
      - while:
          condition:
            sensor.in_range:
              id: desk_height
              above: ${min_height} 
          then:
          - logger.log: "Executing down command"
          - switch.turn_on: switch_down
          - delay: 150ms
    optimistic: true

    # Move desk to desired position
    position_action:
    #Check if we need to move desk up or down from current position
      if:
        condition:
        #Current height is more than target height, then move desk down
          lambda: |-
            float position = (float(id(desk_height).state) - float(${min_height})) / (float(${max_height}) - float(${min_height}));
            return pos < position;
        then:
          - logger.log: "Schreibtisch muss runter gefahren werden"
          - while:
              condition:
                # Move down till the current height is smaller then the target height
                lambda: |-
                  float position = (float(id(desk_height).state) - float(${min_height})) / (float(${max_height}) - float(${min_height}));
                  return pos < position;
              then:
                - logger.log: "Executing down command"
                - cover.template.publish:
                    id: desk_cover
                    current_operation: CLOSING
                - uart.write:
                    id: desk_uart
                    data: [0x9b, 0x06, 0x02, 0x02, 0x00, 0x0c, 0xa0, 0x9d]
                - delay: 150ms
        else:
          - logger.log: "Schreibtisch muss hoch gefahren werden"
          - while:
              condition:
                # Move up till the current height is bigger then the target height
                lambda: |-
                  float position = (float(id(desk_height).state) - float(${min_height})) / (float(${max_height}) - float(${min_height}));
                  return pos > position;
              then:
                - logger.log: "Executing up command"
                - cover.template.publish:
                    id: desk_cover
                    current_operation: OPENING
                - uart.write:
                    id: desk_uart
                    data: [0x9b, 0x06, 0x02, 0x01, 0x00, 0xfc, 0xa0, 0x9d]
                - delay: 150ms

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert