Desky Standing Desk (ESPHome) [Works with Desky, Uplift, Jiecang, Assmann & others]

Thanks for the advice and also whoops I lied lol, there is a model identifier on it, pics attached.

When I attempted to get the uart debugging setup I noticed this message in the logs:

[W][uart.arduino_esp32:206]:   You're using the same serial port for logging and the UART component. Please disable logging over the serial port by setting logger->baud_rate to 0

A little research led me here and following that guide I started testing with GPIOs 9 and 10 instead of 1 and 3 (because I had noticed you said you had to switch rx/tx on your D1 so I’ve made a point to try with both on this board).

That did bring with it a positive change, which is that the desk no longer randomly moves around when the rx or tx pins are connected. I can also use the buttons on the control panel with either of the pins connected, and sending up/down/stop commands all work fine.

Unfortunately getting the desk height and sending it to a specific one still don’t work, and I am not seeing any uart messages in the logs at all, and definitely not when I press the desk buttons.

Does your control box just have a rj45 port or does it have an rj12 too?

My control box does have both rj45 and rj12.

It would also help debugging if you post some pictures of your control box, wiring, and post your best config. Could be your wiring or you may need to switch rx/tx etc.

Attached pics of control box with model info, wiring pics, and pinout from seller for ESP32 board. Wiring all seems to be solid and as mentioned I’ve been trying switching rx/tx to no avail (both changing the pins specific in config, but also switching between the pins physically without changing the config). Let me know if anything stands out and thanks again for the help.

Simple config used to test for uart debugs (I’ve also tried your more complex config with the same pins/etc and the behavior is the same now that I’ve switched to trying GPIO’s 9 and 10 as rx_pin):

esphome:
  name: desk
  platform: ESP32
  board: node32s

logger:
  level: VERY_VERBOSE ##Uncomment to see UART debug messages 

external_components:
#Fetch ssieb's custom component# https://github.com/ssieb/custom_components/tree/master/components/desky
  - source:
      type: git
      url: https://github.com/ssieb/custom_components
    components: [ desky ]

uart:
  - id: desk_uart
    baud_rate: 9600
    rx_pin: GPIO9
    debug:
      direction: RX
      dummy_receiver: true
      after:
        bytes: 4
      sequence:     
        - lambda: UARTDebug::log_int(direction, bytes, ',');

desky:
  #uart_id: desk_uart  (optional, unless multiple uarts are defined)
  id: my_desky
  height:  # optional sensor publishing the current height
    name: Desk Height
    id: desk_height
    # any other sensor options
  up:    # optional <pin> config
    number: GPIO26
    inverted: true  # probably needed
  down:  # optional <pin> config
    number: GPIO25
    inverted: true  # probably needed
  request:  # optional <pin> config to request height updates at boot
    number: GPIO27
    inverted: true  # probably needed
  stopping_distance: 15  # optional distance from target to turn off moving, default 15
  timeout: 15s  # optional time limit for moving, default is none

binary_sensor:
  - platform: template
    name: Desky moving
    lambda: return id(my_desky).current_operation != desky::DESKY_OPERATION_IDLE;





We want to focus just on the wire that the desk sends messages on.

So try this.

Remove all config relating to the desky component (comment out). Similar to below. We want to focus on just using the uart debug to try to find uart messages.

I don’t think gpio09 is any good for this. See table with green/red etc. Although I’m not sure about that. Try say 21 in both config and wiring or one of the other ones that are all green in that rough number range.

Once you have done your initial flash with usb, you remove the usb cable and should try powering and grounding the esp via the desk. OTA connecting for looking at logs. Then try having just three wires connected to the esp. Gnd, power and the tx (which goes to your nominated rx on esp). See image.

Set that all up and see if you get some uart debug messages.


esphome:
  name: desk
  platform: ESP32
  board: node32s

logger:
  level: VERY_VERBOSE ##Uncomment to see UART debug messages 


uart:
  - id: desk_uart
    baud_rate: 9600
    rx_pin: GPIO21
    debug:
      direction: RX
      dummy_receiver: true
      after:
        bytes: 4
      sequence:     
        - lambda: UARTDebug::log_int(direction, bytes, ',');

Thanks a million, will run through this soon. I had left the power and ground cables disconnected from the ESP32 as the control box wasn’t powering them when I had them connected.

I played around with getting that to work at first without luck, then saw someone with the same issue say that powering from control box worked as long as they used USB power to boot the ESP32. Tried that and I started getting some smoke out of the ESP32 so immediately disconnected and have not tried powering it from the control box since lol. ESP32 seems to run fine despite that incident and the issues I’m having existed before that but who knows, could have fried something in the chip that will stop this from working.

1 Like

The other thing worth checking and confirming is that your pass through wiring is all correct.

It’s easy to make a mistake or for something to be amiss.

To do that check, follow this post.

Basically disconnect all wires from the esp and confirm the desk works as per normal with just the pass through wires in place.

Pass through wiring seems fine, desk controls all work fine when the control panel is run through the breakout and the ESP32 is fully disconnected.

Had some success using the config you suggested with GPIO21 set for uart, after rigging that up I see uart debug messages in the log. I’ve included those below, it doesn’t appear to be very consistent but then I don’t really know what I’m looking at.

Holding the down button:

[17:38:17][D][uart_debug:176]: <<< 255
[17:38:17][D][uart_debug:176]: <<< 255
[17:38:18][D][uart_debug:176]: <<< 255
[17:38:18][D][uart_debug:176]: <<< 255
[17:38:18][D][uart_debug:176]: <<< 255
[17:38:19][D][uart_debug:176]: <<< 255
[17:38:19][D][uart_debug:176]: <<< 255
[17:38:19][D][uart_debug:176]: <<< 255
[17:38:19][D][uart_debug:176]: <<< 255
[17:38:19][D][uart_debug:176]: <<< 255
[17:38:20][D][uart_debug:176]: <<< 255
[17:38:20][D][uart_debug:176]: <<< 255
[17:38:20][D][uart_debug:176]: <<< 255
[17:42:02][D][uart_debug:176]: <<< 255,255,255,255
[17:42:02][D][uart_debug:176]: <<< 127,255,255,255
[17:42:02][D][uart_debug:176]: <<< 255,255,255,255
[17:42:03][D][uart_debug:176]: <<< 255,255
[17:42:03][D][uart_debug:176]: <<< 253,255
[17:42:04][D][uart_debug:176]: <<< 255
[17:42:04][D][uart_debug:176]: <<< 253
[17:42:04][D][uart_debug:176]: <<< 109
[17:42:04][D][uart_debug:176]: <<< 255
[17:42:05][D][uart_debug:176]: <<< 255
[17:42:05][D][uart_debug:176]: <<< 255
[17:42:06][D][uart_debug:176]: <<< 255

Holding up button:

[17:39:10][D][uart_debug:176]: <<< 255
[17:39:11][D][uart_debug:176]: <<< 219,255,251,251
[17:39:11][D][uart_debug:176]: <<< 255,255,255,255
[17:39:11][D][uart_debug:176]: <<< 255,255,255,255
[17:39:11][D][uart_debug:176]: <<< 251
[17:39:11][D][uart_debug:176]: <<< 255,255,255,255
[17:39:11][D][uart_debug:176]: <<< 255
[17:39:12][D][uart_debug:176]: <<< 255,255,255,255
[17:39:12][D][uart_debug:176]: <<< 255,255,255,255
[17:39:12][D][uart_debug:176]: <<< 255,255,255,255
[17:39:12][D][uart_debug:176]: <<< 255,255,255,255
[17:39:12][D][uart_debug:176]: <<< 255,255,255,255
[17:39:12][D][uart_debug:176]: <<< 255,255,255,255
[17:39:12][D][uart_debug:176]: <<< 255,255,255,255
[17:39:12][D][uart_debug:176]: <<< 255,255,255,255
[17:39:12][D][uart_debug:176]: <<< 255,255,255,255
[17:39:12][D][uart_debug:176]: <<< 255,255,255,255
[17:39:12][D][uart_debug:176]: <<< 255,255,255,255
[17:39:13][D][uart_debug:176]: <<< 255,255,255,223
[17:39:13][D][uart_debug:176]: <<< 219,223,255,255
[17:39:13][D][uart_debug:176]: <<< 223,251,251,251
[17:39:13][D][uart_debug:176]: <<< 251,219,255,251
[17:39:13][D][uart_debug:176]: <<< 251,251,251,219
[17:39:13][D][uart_debug:176]: <<< 255,251,255,255
[17:39:13][D][uart_debug:176]: <<< 255,255,251,255
[17:39:13][D][uart_debug:176]: <<< 219,255,255,255
[17:39:13][D][uart_debug:176]: <<< 255,219,251,255
[17:39:13][D][uart_debug:176]: <<< 255,251,251,255
[17:39:13][D][uart_debug:176]: <<< 251,251,223,255
[17:39:13][D][uart_debug:176]: <<< 255,255,223,223
[17:39:14][D][uart_debug:176]: <<< 255,255,223,255
[17:39:14][D][uart_debug:176]: <<< 255,255,255,255
[17:39:14][D][uart_debug:176]: <<< 251,255,255,255
[17:39:14][D][uart_debug:176]: <<< 251,251,251,255
[17:39:14][D][uart_debug:176]: <<< 219,251,251,219
[17:39:14][D][uart_debug:176]: <<< 219,251,219,251
[17:39:14][D][uart_debug:176]: <<< 251,251,219,251
[17:39:14][D][uart_debug:176]: <<< 251,251,251,255
[17:39:14][D][uart_debug:176]: <<< 255,251,251,251
[17:39:14][D][uart_debug:176]: <<< 255,251,251,251
[17:39:14][D][uart_debug:176]: <<< 251,251,251,219
[17:39:14][D][uart_debug:176]: <<< 251,219,219,251
[17:39:14][D][uart_debug:176]: <<< 255,251,251,251
[17:39:14][D][uart_debug:176]: <<< 219,251,251,251
[17:39:15][D][uart_debug:176]: <<< 251,255,255,251
[17:39:15][D][uart_debug:176]: <<< 251,251,251,251
[17:39:15][D][uart_debug:176]: <<< 255,251,219,255
[17:39:15][D][uart_debug:176]: <<< 255,251,251,251
[17:39:15][D][uart_debug:176]: <<< 251,255

I then tried using GPIO21 for the rx_pin in your more complex config and found an interesting result:

  • if the up or down pins are connected the ESP32 stops sending logs to the console and stops responding to network traffic
  • if the request desk height pin is connected the ESP32 maintains network connectivity and the logs show a constant stream of the following:
[17:47:36][D][uart_debug:176]: <<< 0,192,0,224
[17:47:36][D][uart_debug:176]: <<< 224,254,224,192
[17:47:36][D][uart_debug:176]: <<< 224,192,224,224
[17:47:36][D][uart_debug:176]: <<< 192,224,224,224
[17:47:36][D][uart_debug:176]: <<< 62,254,248,248
[17:47:36][D][uart_debug:176]: <<< 248,224,192,192
[17:47:36][D][uart_debug:176]: <<< 192,192,254,248
[17:47:36][D][uart_debug:176]: <<< 192,240,240,192
[17:47:36][D][uart_debug:176]: <<< 192,192,240,254
[17:47:36][D][uart_debug:176]: <<< 254,248,240,240
[17:47:36][D][uart_debug:176]: <<< 192,248,192,240
[17:47:36][D][uart_debug:176]: <<< 240,192,240,254
[17:47:36][D][uart_debug:176]: <<< 248,248,192,240
[17:47:36][W][component:237]: Component uart took a long time for an operation (193 ms).
[17:47:36][W][component:238]: Components should block for at most 30 ms.
[17:47:36][D][uart_debug:176]: <<< 240,0,0,224
[17:47:36][D][uart_debug:176]: <<< 0,192,0,192
[17:47:36][D][uart_debug:176]: <<< 0,192,0,192
[17:47:36][D][uart_debug:176]: <<< 0,224,0,192
[17:47:36][D][uart_debug:176]: <<< 0,192,0,192
[17:47:36][D][uart_debug:176]: <<< 0,240,0,240
[17:47:36][D][uart_debug:176]: <<< 0,192,0,192
[17:47:36][D][uart_debug:176]: <<< 0,192,0,192
[17:47:36][D][uart_debug:176]: <<< 0,192,0,192
[17:47:36][D][uart_debug:176]: <<< 0,192,0,224
[17:47:37][D][uart_debug:176]: <<< 224,62,254,248
[17:47:37][D][uart_debug:176]: <<< 224,192,224,224
[17:47:37][W][component:237]: Component uart took a long time for an operation (177 ms).
[17:47:37][W][component:238]: Components should block for at most 30 ms.
[17:47:37][D][uart_debug:176]: <<< 224,192,192,224
[17:47:37][D][uart_debug:176]: <<< 254,248,224,248
[17:47:37][D][uart_debug:176]: <<< 224,248,192,224
[17:47:37][D][uart_debug:176]: <<< 224,192,0,192
[17:47:37][D][uart_debug:176]: <<< 0,224,0,192
[17:47:37][D][uart_debug:176]: <<< 0,224,0,192
[17:47:37][D][uart_debug:176]: <<< 0,224,0,192
[17:47:37][D][uart_debug:176]: <<< 0,192,0,224
[17:47:37][D][uart_debug:176]: <<< 0,192,0,240
[17:47:37][D][uart_debug:176]: <<< 0,192,254,254
[17:47:37][D][uart_debug:176]: <<< 248,224,192,224
[17:47:37][D][uart_debug:176]: <<< 192,192,224,192
[17:47:37][D][uart_debug:176]: <<< 192,192,0,224
[17:47:37][W][component:237]: Component uart took a long time for an operation (181 ms).
[17:47:37][W][component:238]: Components should block for at most 30 ms.
[17:47:37][D][uart_debug:176]: <<< 0,192,0,192
[17:47:37][D][uart_debug:176]: <<< 0,224,0,224
[17:47:37][D][uart_debug:176]: <<< 0,192,254,248
[17:47:37][D][uart_debug:176]: <<< 224,192,240,192
[17:47:37][D][uart_debug:176]: <<< 240,240,192,192
[17:47:37][D][uart_debug:176]: <<< 62,254,254,248
[17:47:37][D][uart_debug:176]: <<< 240,240,192,240
[17:47:37][D][uart_debug:176]: <<< 192,192,192,192
[17:47:37][D][uart_debug:176]: <<< 240,192,192,62
[17:47:37][D][uart_debug:176]: <<< 254,248,240,240
[17:47:37][D][uart_debug:176]: <<< 0,224,0,192
[17:47:37][D][uart_debug:176]: <<< 0,192,0,224
[17:47:37][W][component:237]: Component uart took a long time for an operation (169 ms).
[17:47:37][W][component:238]: Components should block for at most 30 ms.
[17:47:37][D][uart_debug:176]: <<< 0,192,0,240
[17:47:37][D][uart_debug:176]: <<< 0,192,0,192
[17:47:37][D][uart_debug:176]: <<< 0,192,0,224
[17:47:37][D][uart_debug:176]: <<< 0,224,0,192
[17:47:37][D][uart_debug:176]: <<< 248,224,224,224
[17:47:37][D][uart_debug:176]: <<< 224,192,224,192
[17:47:37][D][uart_debug:176]: <<< 224,224,254,248
[17:47:37][D][uart_debug:176]: <<< 248,248,224,192
[17:47:37][D][uart_debug:176]: <<< 224,224,192,192
[17:47:37][D][uart_debug:176]: <<< 192,192,192,0
[17:47:37][D][uart_debug:176]: <<< 224,0,192,0
[17:47:37][D][uart_debug:176]: <<< 192,0,192,0
[17:47:37][D][uart_debug:176]: <<< 224,0,192,0
[17:47:37][W][component:237]: Component uart took a long time for an operation (183 ms).
[17:47:37][W][component:238]: Components should block for at most 30 ms.
[17:47:37][D][uart_debug:176]: <<< 254,248,248,248
[17:47:37][D][uart_debug:176]: <<< 192,240,192,192
[17:47:37][D][uart_debug:176]: <<< 192,254,0,240
[17:47:37][D][uart_debug:176]: <<< 0,192,0,192
[17:47:37][D][uart_debug:176]: <<< 0,192,0,240
[17:47:37][D][uart_debug:176]: <<< 0,192,0,192
[17:47:37][D][uart_debug:176]: <<< 0,240,0,240
[17:47:37][D][uart_debug:176]: <<< 0,240,0,192
[17:47:37][D][uart_debug:176]: <<< 0,192,0,192
[17:47:37][D][uart_debug:176]: <<< 0,224,0,192
[17:47:37][D][uart_debug:176]: <<< 0,192,0,224
[17:47:37][D][uart_debug:176]: <<< 0,192,248,248
[17:47:37][W][component:237]: Component uart took a long time for an operation (169 ms).
[17:47:37][W][component:238]: Components should block for at most 30 ms.
[17:47:37][D][uart_debug:176]: <<< 224,248,192,224
[17:47:37][D][uart_debug:176]: <<< 224,224,192,192
[17:47:37][D][uart_debug:176]: <<< 0,192,0,192
[17:47:37][D][uart_debug:176]: <<< 0,224,0,224
[17:47:37][D][uart_debug:176]: <<< 0,192,0,192
[17:47:37][D][uart_debug:176]: <<< 0,192,0,240
[17:47:37][D][uart_debug:176]: <<< 192,62,254,254
[17:47:37][D][uart_debug:176]: <<< 224,192,224,192
[17:47:37][D][uart_debug:176]: <<< 224,192,192,0
[17:47:37][D][uart_debug:176]: <<< 192,0,192,0
[17:47:37][D][uart_debug:176]: <<< 0,240,0,240
[17:47:37][D][uart_debug:176]: <<< 240,62,254,240
[17:47:38][D][uart_debug:176]: <<< 248,240,240,192
[17:47:38][W][component:237]: Component uart took a long time for an operation (181 ms).
[17:47:38][W][component:238]: Components should block for at most 30 ms.
[17:47:38][D][uart_debug:176]: <<< 240,240,240,240
[17:47:38][D][uart_debug:176]: <<< 192,240,254,192
[17:47:38][D][uart_debug:176]: <<< 224,224,224,192
[17:47:38][D][uart_debug:176]: <<< 192,0,192,0
[17:47:38][D][uart_debug:176]: <<< 192,0,192,0
[17:47:38][D][uart_debug:176]: <<< 192,0,192,0
[17:47:38][D][uart_debug:176]: <<< 224,0,224,248
[17:47:38][D][uart_debug:176]: <<< 248,248,192,224
[17:47:38][D][uart_debug:176]: <<< 224,240,192,192
[17:47:38][D][uart_debug:176]: <<< 62,254,254,248
[17:47:38][D][uart_debug:176]: <<< 240,240,192,240
[17:47:38][D][uart_debug:176]: <<< 192,240,192,192
[17:47:38][W][component:237]: Component uart took a long time for an operation (175 ms).
[17:47:38][W][component:238]: Components should block for at most 30 ms.
[17:47:38][D][uart_debug:176]: <<< 240,254,248,254
[17:47:38][D][uart_debug:176]: <<< 248,240,248,192
[17:47:38][D][uart_debug:176]: <<< 240,240,192,0
[17:47:38][D][uart_debug:176]: <<< 192,62,254,248
[17:47:38][D][uart_debug:176]: <<< 224,192,224,192
[17:47:38][D][uart_debug:176]: <<< 224,192,192,192
[17:47:38][D][uart_debug:176]: <<< 62,248,248,224
[17:47:38][D][uart_debug:176]: <<< 248,224,230,192
[17:47:38][W][component:237]: Component uart took a long time for an operation (110 ms).
[17:47:38][W][component:238]: Components should block for at most 30 ms.

Ok I think that’s progress.

I think the messages can be noisy if you’re not grounded properly. Try adding the ground wire like this. Remove it if anything smokes etc;) I think it is ok.
I assume you are still powering via usb?

After looking at logs for that, also, try changing this to 9.

bytes: 9

Move the desk up or down and post logs again please.

If we do hit a dead end with the rj45 port, you can also try your luck with the rj12 port. It’s even potentially preferable.

Also, if you have a multimeter, it’s worth checking you get 5v on the power/gnd desk wires that go to the esp.

So i got this Uppspel IKEA desk and long story short: I’ve built my own little desky, but could not find a suitable enclosure for a USB-C D1 Mini. So i’ve remixed the one from Okham and made a few modifications.

The result is available at Desky Standing Desk DIY Wifi Dongle Enclosure for USB-C D1 mini by CtrlAltProcrastinate - Thingiverse and looks like this:

2 Likes

Nice! Thanks for sharing back!

Hi guys. Looking for help integrating my desk into Home Assistant. I have some “Ergostol” with a 000-DH16_V02 board. No control via RJ connector.
I’ve already searched a bit on the Internet and apparently there are no ready-made projects on this topic yet.
As far as I understand, control is via a connector under the screen (I soldered the wires)? Or is this a connector for flashing the controller?

Can you tell me what to read about this? I don’t have much experience yet, so would appreciate any help

Photos of my controller. Maybe it will make things a little clearer :slight_smile:





It’s best you start your own thread for this.
This thread is for Desky / Jiecang desks.
@ me once you’ve done that and I’ll offer what I can.
Probably you’ll be starting from scratch with this desk so may well have a lot of exploration and learning to do.

Here is an example of what to post and in that thread is also some common starting points.

This is for a Vari Desk, and works great, thank you for getting me going!

I’ve made a few changes and additions to the code, including making functional minimum and maximum values to stop movement, and added presets for sitting and standing (seemed easier than trying to simulate the physical buttons).

I also had to change the throttle on the height from 200ms to 4ms to overcome an issue whereby the height displayed in HA did not match what was displayed on the desk. It also appears to have made it a bit more accurate now as a full run from standing to sitting stopped EXACTLY where it should have, whereby it was previously off .1-.2".

I originally tried going from 200ms to 100ms and it was better, but still off once in a while. I chose 4ms because of this article: https://www.devmire.com/reverse-engineering-a-standing-desk-for-fun-and-profit/ Specifically, there was a comment in the code that stated “Height should be set in bursts of x ms pulses, as it takes 4ms to read the current height”.

I used an ESP32, Dupont jumpers (male/female), and one of these for pass-thru: Amazon.com: Teansic 2PCS RJ45 Ethernet Dual Female Terminal Breakout Board,3.5mm Pitch 8Pin RJ45 Screw Connector Board Shielded Network Adapter Terminal : Electronics All that’s needed for assembly is a tiny little screwdriver - no soldering!

I’ll be designing an enclosure for it in the near future.

Enjoy!

esphome:
  name: small-desk
  friendly_name: Small Desk
  on_boot:
    priority: -100.0
    then:
    #Request a desk height update after boot.
      - delay: 5s
      - switch.turn_on: wake_desk_and_get_height

esp32:
  board: esp32dev
  framework:
    type: arduino

# Enable logging
logger:

# Enable Home Assistant API
api:

ota:

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

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:


external_components:
#Fetch ssieb's custom component# https://github.com/ssieb/custom_components/tree/master/components/desky
  - source:
      type: git
      url: https://github.com/ssieb/custom_components
    components: [ desky ]

uart:
  - id: desk_uart
    baud_rate: 9600
    rx_pin: 1

desky:
  id: desk_controller
  timeout: 15s
  height:
    name: Desk Height
    id: desk_height
    accuracy_decimals: 1
    unit_of_measurement: in
    filters:
    - delta: 0.05
    - throttle: 4ms
    - multiply: 0.1
    on_value:
      then:
          #If the value changes, then the desk is moving
        - binary_sensor.template.publish:
            id: desk_is_moving
            state: ON
        - delay: 300ms
          #Assume it's stopped moving if no height changes after a short time.
        - binary_sensor.template.publish:
            id: desk_is_moving
            state: Off
binary_sensor:
  - platform: template
    id: desk_is_moving
    name: "Desk Is Moving"
    filters:
      - delayed_off: 400ms
    #If the desk isn't moving for a bit we better turn off attempts at movement. Poor man's collision detection? 
    on_release:
      then:
        - button.press: desky_stop_desk

button: 
#Stop movement 
  - platform: template
    name: Stop Desk
    id: desky_stop_desk
    on_press:
      then:
        - switch.turn_off: raise_desk
        - switch.turn_off: lower_desk

#Go to height x
  - platform: template
    name: Go To Height x
    id: go_to_preset_height_x
    on_press:
      then:
      #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: |-
              return id(desk_target_height).state < id(desk_height).state;
          then:
            - switch.turn_on: lower_desk
            - wait_until:
              #Run until the difference between current and target state is < stopping distance 
                condition:
                  lambda: return (id(desk_height).state)<((id(desk_target_height).state) + (id(stopping_distance_in).state));
            - switch.turn_off: lower_desk
          else:
          #Current height is less than target height, move desk up
            - switch.turn_on: raise_desk
            - wait_until:
                condition:
                  lambda: return (id(desk_height).state)>((id(desk_target_height).state) - (id(stopping_distance_in).state));
                  #Run until the difference between current and target state is <0.3cm
            - switch.turn_off: raise_desk

#Go to sitting height
  - platform: template
    name: Go To Sitting Height
    id: go_to_sitting_preset_height
    on_press:
      then:
      #Check if we need to move desk up or down from current position      
        if:
          condition:
          #Current height is more than sitting height, then move desk down
            lambda: |-
              return id(desk_sitting_height).state < id(desk_height).state;
          then:
            - switch.turn_on: lower_desk
            - wait_until:
              #Run until the difference between current and sitting height is < stopping distance 
                condition:
                  lambda: return (id(desk_height).state)<((id(desk_sitting_height).state) + (id(stopping_distance_in).state));
            - switch.turn_off: lower_desk
          else:
          #Current height is less than target height, move desk up
            - switch.turn_on: raise_desk
            - wait_until:
                condition:
                  lambda: return (id(desk_height).state)>((id(desk_sitting_height).state) - (id(stopping_distance_in).state));
                  #Run until the difference between current and sitting height < stopping distance
            - switch.turn_off: raise_desk


#Go to standing height
  - platform: template
    name: Go To Standing Height
    id: go_to_standing_preset_height
    on_press:
      then:
      #Check if we need to move desk up or down from current position      
        if:
          condition:
          #Current height is more than standing height, then move desk down
            lambda: |-
              return id(desk_standing_height).state < id(desk_height).state;
          then:
            - switch.turn_on: lower_desk
            - wait_until:
              #Run until the difference between current and standing height is < stopping distance 
                condition:
                  lambda: return (id(desk_height).state)<((id(desk_standing_height).state) + (id(stopping_distance_in).state));
            - switch.turn_off: lower_desk
          else:
          #Current height is less than target height, move desk up
            - switch.turn_on: raise_desk
            - wait_until:
                condition:
                  lambda: return (id(desk_height).state)>((id(desk_standing_height).state) - (id(stopping_distance_in).state));
                  #Run until the difference between current and standing height < stopping distance
            - switch.turn_off: raise_desk

number:
  - platform: template
    id: desk_target_height
    name: "Target Height x"
    optimistic: true
    unit_of_measurement: in
    min_value: 29
    max_value: 49
    step: 0.1

  - platform: template
    id: lower_limit
    name: "Lower Limit"
    optimistic: True
    unit_of_measurement: in
    min_value: 27
    max_value: 29
    step: 0.1
    restore_value: True
    initial_value: 28

  - platform: template
    id: upper_limit
    name: "Upper Limit"
    optimistic: True
    unit_of_measurement: in
    min_value: 48
    max_value: 50
    step: 0.1
    restore_value: True
    initial_value: 49
  
  - platform: template
    name: "Stopping Distance Offset"
    id: stopping_distance_in
    unit_of_measurement: in
    optimistic: true
    min_value: .1
    max_value: 1
    step: 0.1
    restore_value: true
    initial_value: .4

  - platform: template
    id: desk_standing_height
    name: "Standing Height"
    optimistic: true
    unit_of_measurement: in
    #Limit the range
    min_value: 45
    max_value: 49
    step: 0.1
    restore_value: true
    initial_value: 48

  - platform: template
    id: desk_sitting_height
    name: "Sitting Height"
    optimistic: true
    unit_of_measurement: in
    #Limit the range
    min_value: 28.5
    max_value: 32
    step: 0.1
    restore_value: true
    initial_value: 30

switch:
#wake up the desk and request it sends its height 
  - platform: gpio
    id: wake_desk_and_get_height
    name: "Request Desk Height"
    pin:
      number: 14
      inverted: true
    on_turn_on:
    - delay: 100ms
    - switch.turn_off: wake_desk_and_get_height

#Raise the desk 
  - platform: gpio
    id: raise_desk
    name: "Raise Desk"
    pin:
      number: 4
      # mode: INPUT_PULLUP
      inverted: true
    interlock: lower_desk
    on_turn_on:
    - wait_until:
     #Run until current > upper limit + stopping distance 
        condition:
          lambda: return (id(desk_height).state)>((id(upper_limit).state) - (id(stopping_distance_in).state));
    - switch.turn_off: raise_desk
#Lower the desk 
  - platform: gpio
    id: lower_desk
    name: "Lower Desk" 
    pin:
      number: 5
      # mode: INPUT_PULLUP
      inverted: true
    interlock: raise_desk
    on_turn_on:
    - wait_until:
     #Run until current < lower limit + stopping distance 
        condition:
          lambda: return (id(desk_height).state)<((id(lower_limit).state) + (id(stopping_distance_in).state));
   #Auto off after 15s just in case
    - switch.turn_off: lower_desk
1 Like

Good to hear. I’ve added Vari Desk to the “works with” list.

I’ve noticed that this doesn’t pick up height changes if I operate the desk via the factory control panel. Is that a limitation that can be overcome?

It should.
That is unexpected behaviour.
Do you mean desk height doesn’t change?

Correct. If I press the physical button, the desk moves without issue, but the height does not update in the home assistant dashboard. Additionally, when I press the button to retrieve height, nothing happens.

Right. Could you enable uart debug and post some logs while you do both actions please.

logger:
  level: VERBOSE # Uncomment to see UART debug messages 


uart:
  - id: desk_uart
    baud_rate: 9600
    rx_pin: 1 #Labelled TX on my D1mini clone (mislabelled?)
    ##You can uncomment the debug section below to see UART messages.
    # debug:
      # direction: RX
      # dummy_receiver: true
      # after:
        # bytes: 4
      # sequence:     
        # - lambda: UARTDebug::log_int(direction, bytes, ',');

I’m curious why you are re-implementing the component functionality. There’s a move_to method to automatically move to a specific position.

I just made some changes to the component that should make it work better. There can be an issue with the ESP sharing the wires with the display unit, so I’ve made it possible for the ESP to be mitm instead. Note that the pin names have been changed because there’s an in and an out for the up and down pins. You also need to configure the tx pin to go to the display. Don’t use the intercept: option. It’s for a future feature to have triggers for the display buttons instead of passing them through, but it’s not implemented yet. Also, don’t invert the pins any more. The code handles that directly.

The new code is in a branch since it hasn’t been tested yet, so if anyone wants to test it, that would be appreciated. If anyone wants to discuss it or finds an issue, please find me on the esphome discord server. It’s easier there.

external_components:
  - source:
      type: git
      url: https://github.com/ssieb/esphome_components
      ref: desky
    components: [ desky ]
    refresh: 1min

You can see the updated README at
https://github.com/ssieb/esphome_components/tree/desky/components/desky

1 Like

Probably my fault there.

In the early days I was tinkering with doing things outside of your component and my yaml example probably leads people down wrong paths.

I saw that, but there were notes in the code about wiring it differently, and I didn’t see a wiring diagram for how I was supposed to wire it, or where the tx/rx wires were supposed to go (from what pin on the RJ45 jack to what pin on the ESP32) so rather than guess and mess it up, I went the other way. I’ll take a look at the readme and see if that helps.