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

No problem. Here’s a link. Downloads are in the top-right.
https://a360.co/3P5P0RV

1 Like

If not going for a pass-through you could almost get this to usb stick type sizes I reckon. Not sure on best exact build materials/components.

Just found this amazing item on AliExpress. Check it out! AU $1.62 27%OFF | White RJ45 Tool-less Connector No Crimp Connectors Cat6 Connector Cat5e Connectors Cat5 Connectors
https://a.aliexpress.com/_mtudN7I

https://www.google.com/search?q=atom+light+esp32&tbm=isch&ved=2ahUKEwjIxfqe1rf_AhW0yKACHZJfAgYQ2-cCegQIABAC&oq&gs_lcp=ChJtb2JpbGUtZ3dzLXdpei1pbWcQARgCMgcIIxDqAhAnMgcIIxDqAhAnMgcIIxDqAhAnMgcIIxDqAhAnMgcIIxDqAhAnOgQIIxAnOgUIABCiBFAAWABg00hoAnAAeACAAbMBiAGzAZIBAzAuMZgBAKABAbABBcABAQ&sclient=mobile-gws-wiz-img&ei=TeKDZIjrLLSRg8UPkr-JMA&bih=737&biw=393

@jn3va3 Did you ever try this out with the Timotion, just bought a set of legs that use it and realized after I got them that they were not Jiecang, but Timotion.

@lizaoreo is the control box a TC11?

I really think there is slim to no chance of this project being compatible with Timotion looking at a controller teardown.

https://www.btod.com/blog/problems-autonomous-smartdesk-2he/#timotion

TC15, rather annoyed now. I was sure I was getting a Jiecang. I may just use this as a learning opportunity (as I don’t really want to return at this point) and determine if I’ll even use the stand up functionality. If so, then next time I’ll spend more for a better set of legs where I know what I’m getting. Brand of the legs is AIMEZO on Walmart/Amazon. So I’d avoid if you’re looking to use them with this project, assuming I can’t get this to work somehow. Worst part is I got the ones with just an up/down button because I assumed I could make this work, so I don’t even have memory.

1 Like

Bugger. If you have the time and motivation to try to build your own solution I can help with a few pointers.

First step is probably opening both the handset and controller and figuring out what the control wires are for.

If so, start your own thread along these lines and tag me.

Cheers.

@jaddel Not sure if you found a solution for the maidesite desk? This link posted by Mahko_mahko has loads of info which initial testing appears to work fine using the RJ12 connector on the back of the handset

its a github link,,   can only put 2 links as a new user but the rest of the line is phord/Jarvis

test Yaml for HA/ESPHome

uart:
  - id: desk_uart
    tx_pin: 17  
    rx_pin: 18
    baud_rate: 9600
    debug:
      direction: BOTH
      dummy_receiver: true
      after:
        bytes: 9
      sequence:    
        - lambda: UARTDebug::log_int(direction, bytes, ',');

button:
  - platform: template
    name: Desk UP
    id: my_deskup
    on_press:
      then:
        - logger.log: Button Pressed
        - uart.write: [0xf1, 0xf1, 0x01,0x00,0x01,0x7e]

cable wise I just used one of these https://www.amazon.co.uk/dp/B07YC7DWN5?ref=ppx_yo2ov_dt_b_product_details&th=1 and cut it in half, blue & white cut as not needed, Yellow to GND, Red → ESP32 5v IN, Black → ESP32 Serial out, Green via a resistor arrangement to ESP32 Serial in, used the example from groundfungus Arduino Uno serial communication with ESP32 using voltage divider - Project Guidance - Arduino Forum

now to go play and see what else it can do.

PS. Sorry all as semi unrelated to the rest of the thread, been watching this thread and was going to use the suggested patching between Handset & Controller but then my desk arrived and I got the same controller as Jaddel so can’t hack without voiding the warranty :frowning:

1 Like

For anyone interested, my test code so far is here GitHub - shades66/Maidesite-standing-desk: My experimentations with connecting a Maidesite PRO 2 standing desk controller to HomeAssist

all using the RJ11 connector on the Maidesite standing desk. all the commands it uses seem to be pretty generic so expect this will work on other brands too.

So far working is

  • Button to trigger any of the 4 presets
  • Button to move UP/DOWN
  • Slider to move direct to a height
  • Get current settings for height & presets

Todo

  • Tidy up code (remove test stuff)
  • Make it retrieve the current height automatically (you need to press the test button at the start)
  • Add buttons to create presets based on current height
  • Look into automations to automatically lower after alarms/no-one at desk
2 Likes

Nice and congrats!

From here could you start a seperate thread for your desk please as this is off topic.

Cheers.

1 Like

Hi Mahko_Mahko and ssieb,
Thank you for your great work! I can confirm that the Ergotopia Desktopia Lite also works with the RJ45 dongle. I just built the pass-through adapter yesterday and it neatly integrates into HA. :ok_hand:

1 Like

Thanks for reporting back - I’ve added your model to the works-with list!

Hi,

I’ve also got an Ergotopia Desktopia Lite an wanted to rebuild the pass-through dongle. Since I’ve got some ESP32-WROOM-32 at home I thought I could use these. But following https://community-assets.home-assistant.io/original/3X/9/9/99c36ea684b9d479f26a99b929566d109f7443dc.png this ESP only has a 3.3V pin.

Will this also work?

1 Like

Use VIN which will output the 5V from the USB assuming there’s no diode.

With the main pass through dongle wiring scheme, the esp is actually powered from the desks 5v wire.

So it should just be a matter of using the pin labelled VIN rather than 5V I believe.

@freh

1 Like

Thanks. This project teaches me a lot about esphome.
I’ve managed to build the dongle, but still got some problems by adapting the software to my esp.

This whole thread is really exciting! It is also a bit overwhelming.

I am located in Germany. I plan to build an L-shape desk with my own top plate. Any recommendations for which desk frame to get, because hackability but also because of general quality!?

Thanks!

1 Like

If you describe what you do and don’t have working, I may be able to provide some pointers.

Photos and logs etc typically help.

You could look through the “works with” list in the first post and see if any of the brands sell L shaped legs and ship to your region.

Desky does, but I think they are mainly an Australian seller.

Jiecang is generally seen as “cheaper and lower quality” than say Linak.

It’s worth watching a few of this guys vids.

https://www.btod.com/blog/electric-standing-desk-review-videos/

Hi @Mahko_Mahko ,

First of all thanks so much for this project. I built it and it works perfectly fine with a Desktopia except one tiny thing. Maybe you can help.

I have set it up like this in HA

All the functionality except Desky Sitting Height 1 works for me. It doesn’t matter what value I choose in the slider and then press lower desk it goes down to 87.5. I have so clue where the 87.5 come from.

My questions:

1.) Is the described behaviour how it should work?
2.) Is 87.5 somewhere hardcoded?

The ESP Code I only changed slightly:

####################################################################################################
##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.

esphome:
  name: standingdesk
  platform: ESP8266
  board: d1_mini #pinout: https://i0.wp.com/randomnerdtutorials.com/wp-content/uploads/2019/05/ESP8266-WeMos-D1-Mini-pinout-gpio-pin.png?quality=100&strip=all&ssl=1
  on_boot:
    priority: -100.0
    then:
    #Request a desk height update after boot.
      - delay: 5s
      - switch.turn_on: wake_desk_and_get_height
    
wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

api:
  encryption:
    key: "dreyeQ10Lucl0C2qE9DFdCna9iK0jF3wGoILiB4Ih/8="

ota:
  password: "0746407152149cf59f272ecb06c21855"

# Enable Web server.
web_server:
  port: 80

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

#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: 80
    max_value: 130.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: "Desky Standing Height 1"
    optimistic: true
    unit_of_measurement: cm
    #Limit the range
    min_value: 120
    max_value: 130
    step: 0.1
    restore_value: true
    initial_value: 130
    
#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: "Desky Sitting Height 1"
    optimistic: true
    unit_of_measurement: cm
    #Limit the range
    min_value: 88.0
    max_value: 98.0
    step: 0.1
    restore_value: true
    initial_value: 94.0


      
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

#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
    

Any help is appreciated.

From memory:

  • the lower desk switch will just lower the desk while on. If you’re pushing that it may just be lowering to its lowest point?
  • if you enter a Desk Target Height and then push the button Go To Desky Height x does it move to the entered position?

You use the height presets like this (put this under button:). Not sure why I didn’t include that in my example.

#Define as many single press presets like this as you like  

button: 
  - platform: template
    name: Move Desky to Sit Height 1
    id: desky_move_to_sit_height1
    icon: mdi:seat-passenger
    on_press:
      then:
        - lambda: id(my_desky).move_to(int((id(desky_sit_height_1).state) * 10));  
             
  - platform: template
    name: Move Desky to Stand Height 1
    id: desky_move_to_stand_height1
    icon: mdi:karate
    on_press:
      then:
        - lambda: id(my_desky).move_to(int((id(desky_stand_height_1).state) * 10));  
        
  - platform: template
    name: Move Desky to Stow Height 1
    id: desky_move_to_stow_height1
    icon: mdi:table-chair
    on_press:
      then:
        - lambda: id(my_desky).move_to(int((id(desky_stow_height_1).state) * 10));  
        

You can browse my more advanced config for advanced options.