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

Looking at that (particularly the number of wires), I’m pretty confident that this is not a Jiecang controller or a compatible desk.

The Desky component will not work. If you cannot find another matching project you will need to start your own project (and own thread).

You’ll see another would-be user had to do this here and has made great progress.

thanks for the info.

the main issue is that I can not find the reseller. maybe its easier or me to buy another desk controller, I’m not sure.

Definitely I will open a separate thread.

Apparently this is this desk controller: NT33-2B2 Sit to Stand Up Office Desk Motorized Standing Desk - Buy Sitting Desk, height adjustable desk, high adjustable desk Product on SHAOXING NAITE DRIVE TECHNOLOGY CO.,LTD

1 Like

I’m guessing… But there has been a proliferation of cheap Chinese desks (not sure if this is one?). I suspect many work very similarly.

So I would hunt around other projects and see if you can spot a similar one. Then use or adapt it.

Yes. You basically just use/adapt/add this to trigger the memory presets, which use the soft start/stop.

thanks, so that I understand this. What do I add to trigger the memory presets?

Here’s the relevant excerpt from my config. Note the Purple wire needs to connected to a GPIO.


substitutions:
  #Use your own ESP pin values
  desky_request_height_pin: GPIO32 #Request desk height | white wire  
  desky_purple_pin: GPIO04 #purple wire  
  desky_down_pin: GPIO23 #Move desk down | yellow wire  
  desky_up_pin: GPIO05  #Move desk up | green wire  

output:
  - platform: gpio
    pin: ${desky_up_pin}
    id: up_green_wire
    inverted: true
  - platform: gpio
    pin: ${desky_down_pin}
    id: down_yellow_wire
    inverted: true
  - platform: gpio
    pin: ${desky_purple_pin}
    id: purple_wire
    inverted: true

button:
  # Combination Buttons
  - platform: template
    name: 1
    id: button_1
    on_press:
      then:
        - output.turn_on: up_green_wire
        - output.turn_on: down_yellow_wire
        - delay: 300ms
        - output.turn_off: down_yellow_wire
        - output.turn_off: up_green_wire
  - platform: output
    output: purple_wire
    name: 2
    id: button_2
    duration: 300ms
  - platform: template
    name: 3
    id: button_3
    on_press:
      then:
        - output.turn_on: purple_wire
        - output.turn_on: down_yellow_wire
        - delay: 300ms
        - output.turn_off: down_yellow_wire
        - output.turn_off: purple_wire
  - platform: template
    name: 4
    id: button_4
    on_press:
      then:
        - output.turn_on: purple_wire
        - output.turn_on: up_green_wire
        - delay: 300ms
        - output.turn_off: up_green_wire
        - output.turn_off: purple_wire
    
  # - platform: template
    # name: Set memory 3
    # id: set_memory_3
    # on_press:
      # then:
        # - uart.write:
            # id: desk_uart
            # data: [0xF1, 0xF1, 0x25, 0x00, 0x25, 0x7E]
              # - uart.write: [0xF1, 0xF1, 0x25, 0x00, 0x25, 0x7E]

```

ok thanks!

So, at the moment, I have it wired as suggested above

image

I’ll have to add an extra wire from the purple pin (or slot 3 on the above figure) of the adapter and place it on any of the empty pins on the D1 Mini?

That’s right.

Pick a pin that has “ok” in both the Input and Output columns here.

Best Pins to Use – ESP8266

Awesome! Just did the addition and works very well.

I can now access my button presets and its a soft stop.

This project just keeps getting better and better. thanks again, all.

EDIT: @Mahko_Mahko one thing I’ve noticed is when the D1 board restarts, it goes to one of my presets (i.e. preset #2 in my case). My only concern with this is that on every update or even when the board restarts for whatever reason, it will go to a preset on its own. Is this an intended operation?

Here’s my entire yaml if there is something that is not right.

esphome:
  name: esphome-web-5bdf28   
  on_boot:
    priority: -100.0
    then:
    #Request a desk height update after boot.
      - delay: 5s
      - switch.turn_on: wake_desk_and_get_height

substitutions:
  #Use your own ESP pin values
  desky_request_height_pin: GPIO14 #Request desk height | white wire  
  desky_purple_pin: GPIO12 #purple wire  
  desky_down_pin: GPIO05 #Move desk down | yellow wire  
  desky_up_pin: GPIO04  #Move desk up | green wire  

output:
  - platform: gpio
    pin: ${desky_up_pin}
    id: up_green_wire
    inverted: true
  - platform: gpio
    pin: ${desky_down_pin}
    id: down_yellow_wire
    inverted: true
  - platform: gpio
    pin: ${desky_purple_pin}
    id: purple_wire
    inverted: true

esp8266:
  board: d1_mini

# Enable logging
logger:

# Enable Home Assistant API
api:

ota:

## For Memory Sensor (debug platform in sensor)
debug:
  update_interval: 30s

sensor:
  # Sensors
  - platform: uptime
    name: "Desky Uptime"
  - platform: wifi_signal
    name: "Desky WiFi Signal"
    update_interval: 60s
  - platform: debug
    free:
      name: "Heap Free"
    fragmentation:
      name: "Heap Fragmentation"
    block:
      name: "Heap Max Block"
    loop_time:
      name: "Loop Time"

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

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "[redacted]"
    password: "[redacted]"

captive_portal:

####################################################################################################
##Notes/Info
####################################################################################################

## Home Assistant Thread: https://community.home-assistant.io/t/desky-standing-desk/383790/3
## ssieb who generously donated his time and knowledge to developing the custom component may offer some support on the Discord thread (please read both threads first).
## https://discord.com/channels/429907082951524364/952464939480645642

#Notes:
# 1. Use this component at own risk. It has not had extensive testing. May void warranty or cause desk faults etc.
# 2. This controller may bypass desk safety features like collision detection.
# 3. This component doesn't know about the values stored in your desk. Values in this config are (and must be) set independently.
# 4. ssieb's solution may be a lot simpler and cleaner for most people. I've cobbled together some more features in this config because I can't programn in C++.


#Troubleshooting Tips: 
#If you ever get a flashing ASr message, you might need to reset your desk.
#https://desky.com.au/blogs/news/reset-standing-desk-control-panel#:~:text=When%20ready%2C%20press%20and%20hold,Hooray!


#TODO 
#Ask ssieb to make change requests (move logic to component code)
  # Invert pins
  # Get Desk Height On Boot
  # Interlock Up/Down Pins (If not done already)
  # Interrupt/stop movement function (Stop desk motion)

#other
  # Test collision detection
  # Limit external component fetch to just desky? 
  # Fix Desk Is moving on Boot.

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 #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, ',');
 
desky:
  id: my_desky
  ####################################################################################
  ##Uncomment this block to use Ssieb's move_to componet function.
  # up:    
    # number: 4 #D2
    # inverted: true 
  # down:  
    # number: 5 #D1
    # inverted: true
  # stopping_distance: 15  # optional distance from target to turn off moving, default 15  
  ####################################################################################
  height:  # Sensor publishing the current height
    name: Desky Height
    id: desky_height
    accuracy_decimals: 1
    unit_of_measurement: cm
    #any other sensor options
    filters:
    - delta: 0.05 #Only send values to HA if they change
    - throttle: 200ms #Limit values sent to Ha to 5 per sec.
    - multiply: 0.1 #convert from mm to cm
    on_value:
      then:
          #If the value changes, then the desk is moving
        - binary_sensor.template.publish:
            id: desky_is_moving
            state: ON
        - delay: 300ms
          #Assume it's stopped moving if no height changes after a short time.
        - binary_sensor.template.publish:
            id: desky_is_moving
            state: Off
            
binary_sensor:
  - platform: template
    id: desky_is_moving
    name: "Desky Is Moving"
    filters:
      - delayed_off: 400ms
    #If the desk isn't moving for a bit we better turn off attempts at movement. It's like 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
# Combination Buttons
  - platform: template
    name: Desky Button 1
    id: button_1
    on_press:
      then:
        - output.turn_on: up_green_wire
        - output.turn_on: down_yellow_wire
        - delay: 300ms
        - output.turn_off: down_yellow_wire
        - output.turn_off: up_green_wire
  - platform: output
    output: purple_wire
    name: Desky Button 2
    id: button_2
    duration: 300ms
  - platform: template
    name: Desky Button 3
    id: button_3
    on_press:
      then:
        - output.turn_on: purple_wire
        - output.turn_on: down_yellow_wire
        - delay: 300ms
        - output.turn_off: down_yellow_wire
        - output.turn_off: purple_wire
  - platform: template
    name: Desky Button 4
    id: button_4
    on_press:
      then:
        - output.turn_on: purple_wire
        - output.turn_on: up_green_wire
        - delay: 300ms
        - output.turn_off: up_green_wire
        - output.turn_off: purple_wire

#Move to function
  - platform: template
    name: Go To Desky Height x
    id: go_to_desky_preset_height_x
    on_press:
      then:
      ##Option 1: Uncomment to use Ssieb's move_to componet functions
        # - lambda: id(my_desky).move_to(id(desky_target_height).state*10);  

        
      ##Option 2: Uncomment to use Mahko's lambda alternative 
      #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(desky_target_height).state < id(desky_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 abs((id(desky_height).state - (id(desky_target_height).state)))<(id(stopping_distance_cm).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 abs((id(desky_height).state - (id(desky_target_height).state)))<(id(stopping_distance_cm).state);
                  #Run until the difference between current and target state is <0.3cm
            - switch.turn_off: raise_desk


number:
#Target Height ("Move desk to height x").
    #You should probably limit the range you can move the desk to to within the limits you've set via the control panel, perhaps offset a little within the range.
    #Sending commands higher/lower than this may cause error messages and require desk reset (or worse).
  - platform: template
    id: desky_target_height
    name: "Desky Target Height"
    optimistic: true
    unit_of_measurement: cm
    min_value: 65.0 
    max_value: 122.0
    step: 0.1
    
#Offset correction - Adjust until you get the best accuracy. 
#The desk keeps moving for a little while after the up/down pins are released and we try to account for this.
#1.5cm was about right on mine
  - platform: template
    name: "Desky Stopping Distance cm"
    id: stopping_distance_cm
    unit_of_measurement: cm
    optimistic: true
    min_value: 0
    max_value: 2
    step: 0.1
    restore_value: true
    initial_value: 1.5
    
###############################################
#Define some preset heights.
###############################################
#You can freely define as many adjustable presets as you like.
#These are all seperate/independant of what you've set via the control panel (we can't retrieve them currently).
 
#Standing Height #1 - Set a standing height. 
  - platform: template
    id: desky_standing_height_1
    name: "Standing Height 1"
    optimistic: true
    unit_of_measurement: cm
    #Limit the range
    min_value: 110
    max_value: 120
    step: 0.1
    restore_value: true
    initial_value: 115

#Standing Height #1 - Set a standing height. 
  - platform: template
    id: desky_standing_height_2
    name: "Standing Height 2"
    optimistic: true
    unit_of_measurement: cm
    #Limit the range
    min_value: 115
    max_value: 125
    step: 0.1
    restore_value: true
    initial_value: 120
  
#Sitting Height #1 - Set a sitting height. This is independant of what you've set via the control panel.
  - platform: template
    id: desky_sitting_height_1
    name: "Sitting Height 1"
    optimistic: true
    unit_of_measurement: cm
    #Limit the range
    min_value: 65
    max_value: 69
    step: 0.1
    restore_value: true
    initial_value: 67.0

#Sitting Height #2 - Set a sitting height. This is independant of what you've set via the control panel.
  - platform: template
    id: desky_sitting_height_2
    name: "Sitting Height 2"
    optimistic: true
    unit_of_measurement: cm
    #Limit the range
    min_value: 72.6
    max_value: 82.6
    step: 0.1
    restore_value: true
    initial_value: 77.6
      
switch:
#wake up ther desk and request it sends its height 
  - platform: gpio
    id: wake_desk_and_get_height
    name: "Request Desk Height"
    pin:
      number: D5
      inverted: true
    on_turn_on:
    - delay: 100ms
    - switch.turn_off: wake_desk_and_get_height
  - platform: restart
    name: "Desky Restart"

#Raise the desk 
  - platform: gpio
    id: raise_desk
    name: "Raise Desk"
    pin:
      number: D2
      # mode: INPUT_PULLUP
      inverted: true
    interlock: lower_desk
    on_turn_on:
    #Auto off after 15s just in case
    - delay: 15s
    - switch.turn_off: raise_desk
#Lower the desk 
  - platform: gpio
    id: lower_desk
    name: "Lower Desk" 
    pin:
      number: D1
      # mode: INPUT_PULLUP
      inverted: true
    interlock: raise_desk
    on_turn_on:
   #Auto off after 15s just in case
    - delay: 15s
    - switch.turn_off: lower_desk

I suspect it has something to do with this entry:

- platform: output
  output: purple_wire
  name: Desky Button 2
  id: button_2
  duration: 300ms

If this is the case, how do I make it such that its like Button 1, 3 and 4 and only command on button press. Thanks

Hmm yeah that’s no good.

Sounds like something is pulling the pin low on boot I think.

Maybe try another pin or two (rather than GPIO12) as a next step.

ok thanks for that.

I tried GPIO13, and it did the same thing (when board restarts, it goes to preset 2).

I don’t really have any other options as the other D1 and D2 are already used. May I ask why preset 2 is different in terms of yaml configuration? can the code be change to on_press instead?

EDIT: actually, the on_press may not solve the issue. I actually completely hashed out button 2 (using #) and after restart, it still went to preset 2.

1 Like

The config for that button can be simpler/more direct for that wire as it only uses one wire.

But it shouldn’t be triggered on boot. Mine doesn’t.

I don’t know what’s triggering it and am somewhat out of ideas.

Maybe try activating pullup or pulldown resistors for the pin?

And separately maybe try commenting out the existing on_boot code and see if that changes anything.

And triple check your wiring for that pin.

Also, I recall seeing similar issues on this forum “thing X turns on/off momentarily on restart/ boot”. So maybe dig around to see if you can find a similar issue/solution.

Definitely look at early_pin_init

why you, sir, are a genius @Mahko_Mahko.

I read through all your suggestions but the last one made more sense so I started that first. I set early_pin_init: false and after the board updated and came back online…no desk movement, and even when I rebooted the board manually, no desk movement! problem is solved! thank you

1 Like

hi, I have a desk from a manufacturer where the motor control box has two RJ-45 ports. My question is - can I plug the DIY remote controller in the second RJ-45 slot or do I have to create a passthrough box - so that the original physical controller and the DIY one are on the same connection?

Is it a Jiecang based desk?

hello, it says manufacturer: Loctek ergonomic technology corp.

Then you are probably better off over here.

Where I can see you’ve asked the same question…

Yeah, however, did not hey any response there yet and since then I realized that I actually have the motor from the same vendor. Anyway, my question was a bit generic - if having two rj45 ports pass through is the only way.

Thanks, anyway.

So I got this working a while ago and it’s been amazing. I’m trying to integrate it with some other stuff, and now I’d like to trigger automations based on the direction the desk is moving.

Is there a way to tell? The only way I can think of doing that is comparing the current height a second ago, but I have no clue how to do that.

1 Like