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

Hey if there was any way you could capture the up and down UART commands on the Bluetooth port if you have time, I think that could potentially be quite useful.

I’m not sure, but I think that might be a matter of hooking up the MT and MR to ESPHome rx/tx and watching for the messages using the debug.

https://fccid.io/2ANKDJCP35NBLT/Internal-Photos/Internal-Photos-3727739

I’m guessing the protocol that is sent from the app to the dongle is different than between the dongle and the controller? I don’t know much about these things.

This would enable people to build a WiFi dongle that goes into the Bluetooth port, rather than a pass-through dongle on the RJ45 port.

Debug settings are up here (for rx)

And you still cannot fathom how appreciative I am of it.
I am standing sooooooooooo much more during the day, which is much better for my knees by the end of it, as well as improving my concentration - as I tend to step away from the desk so am not tempted to use the keyboard & mouse during calls.

1 Like

I was originally going to implement an up/down schedule (maybe 1hr sitting then 20min standing). But I’ve decided to trial “push-up mode”. After 1hr of sitting the desk will raise and you stand until you want to sit.

For me I “forget to stand until it’s probably a little late”.

I should have some details of my almost finished control panel V2 in the next week.

Awesome. I originally wanted it to be based on an hour of sitting as well, but then didn’t want it to be in the middle of typing or focusing.
For me, I find standing is most effective when I want to be creative (ie. writing/thinking) as I can easily pace around, as well as in meetings as it helps me pay attention (I have ADHD, so distraction is a problem).

1 Like

That’s the great thing about being able to customise! Set it up for what works for you!

1 Like

Option #2: Custom Control Panel
(Will refine this post and add detail)

Summary:

  • By passing-through at the “JST Control Panel Connector” (PH 2.0mm 8Pin) rather than the RJ45, it’s a bit easier to locate the ESP “within reach”.
  • Then you can add all kinds of sensor and interface options (I added screens, LEDs, a buzzer, a PIR, a ToF, and an Endstop for my keyboard drawer). I originally had a lux sensor but broke it and decided to just swap it out with the PIR.

Key features:

  • Presence & Sitting detection (multi-pronged) using PIR, ToF, desk height, keyboard drawer position, BLE smart band detection.
  • One-press button toggles sit/stand.
  • Implemented a “push-up” mode. Desk moves to standing after x minutes of sitting.
  • Display time until you need to stand and time in current position
  • Other button: Long press to toggle activating push-up mode. Short press extends time until standing if time nearly up.

Cracks me up that even though the control panel it is “much smarter”, it looks pretty vintage;)

Parts list:

  • An ESP32 (you’ll need lots of pins): I decided to use a LILYGO® TTGO T7 Mini32 V1.5 for this, but I’m sure other decent ESP32’s which fits in the enclosure would be fine. I wouldn’t go too cheap. You could take a look here.
  • 2 x LED’s (recommend two different colours of your choice). I used these ones. They have a built in resistor.
  • 2 x push buttons: I got these ones. I think they’re ok. I have occasional reliability issues though. Not sure if it’s related to quality of buttons or something else.
  • 1 x RTTL buzzer: I’ve been using these ones.
  • 2 x screens: These SSD1306’s have been fine.
  • A ToF sensor: These VL53L0X’s have been fine.
  • A motion sensor: I bought a few different types of these to try. Can’t recall which one I used. Can find out if needed.
  • If you want to throw in a light sensor, I’d go with a BH1750
  • Wire, solder, duponts etc…

Here’s a copy of the enclosure (updated 2024-01-25)
https://www.printables.com/model/737413-desky-custom-control-panel-option-2

It’s ok but could benefit from further tweaking. In hindsight I think just using two RJ45 breakouts and passing through like this might be neater. https://www.tindie.com/products/tjhorner/wifi-standing-desk-controller/

Config:
Hmmm… too big to upload.
I’ve just dumped a snapshot here.

2 Likes

File this under things I didn’t know I needed! I’ve been thinking about making my Uplift desk smart just by tapping into the existing controls to nudge me to stand more often but this panel opens up so many more options. Very interested to hear more and see a parts list when you have time. Was this a custom PCB?

1 Like

I’ll add the parts list and config in the next few days for you.

It’s just an esp32.

It’s been working quite well.

I’ve added a parts list, my config and a link to the enclosure on Thingiverse to the main post . Cheers.

1 Like

Thank you guys for all the hard work. I adjusted the yaml file to treat the desk as cover that provides the following:

  • Standing position configuration
  • Sitting position configuration
  • Cover with standing/sitting actions and adjustable positions
substitutions:
  descriptor: 'Office Desk'
  unit_of_measurement: 'in'
  min_height: '30.5'
  max_height: '56.1'
  default_standing_height: '35.5'
  stopping_distance: '1'

esphome:
  name: desk-controller
  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

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  ap:
    ssid: desk-controller
    password: !secret wifi_ap_password

api:
ota:

logger:

external_components:
  - 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
  up:    
    number: 4 #D2
    inverted: true 
  down:  
    number: 5 #D1
    inverted: true
  request:
    number: 14 #D6
    inverted: true
  stopping_distance: ${stopping_distance}
  timeout: 15s
  height:
    id: desk_height
    accuracy_decimals: 1
    unit_of_measurement: ${unit_of_measurement}
    filters:
    - delta: 0.05
    - throttle: 200ms
    - multiply: 0.1
cover:
  - platform: template
    name: ${descriptor}
    device_class: blind
    icon: mdi:desk
    lambda: |-
      if (id(desk_height).state >= id(desk_standing_height).state) {
        return COVER_OPEN;
      } else {
        return COVER_CLOSED;
      }
    open_action:
      - lambda: id(desk_controller).move_to(id(desk_standing_height).state * 10);  
    close_action:
      - lambda: id(desk_controller).move_to(id(desk_sitting_height).state * 10);  
    stop_action:
      - lambda: id(desk_controller).stop();
    tilt_lambda: |-
        return (id(desk_height).state - ${min_height}) / (${max_height} - ${min_height});
    tilt_action:
      - lambda: id(desk_controller).move_to(((tilt * (${max_height} - ${min_height})) + ${min_height}) * 10);  

number:
  - platform: template
    id: desk_sitting_height
    name: ${descriptor} Sitting Height
    optimistic: true
    unit_of_measurement: ${unit_of_measurement}
    min_value: ${min_height}
    max_value: ${default_standing_height}
    step: 0.1
    restore_value: true
    initial_value: ${min_height}
    mode: box
    icon: mdi:arrow-down
    
  - platform: template
    id: desk_standing_height
    name: ${descriptor} Standing Height
    optimistic: true
    unit_of_measurement: ${unit_of_measurement}
    min_value: ${default_standing_height}
    max_value: ${max_height}
    step: 0.1
    restore_value: true
    initial_value: ${default_standing_height}
    mode: box
    icon: mdi:arrow-up
3 Likes

Nice one. Thanks for sharing that back.

I was thinking about something similar but wasn’t sure how good a fit the mapping to a cover would work. I think covers like a % open/closed? I just skimmed your config and will look closer.

Keen you hear if that works well for you.

Do you have a Desky desk or something else?

Cheers…

With the way the cover is configured, there is an open and close action that will go to the configured standing and sitting positions. There is also the ability to give a percentage a position. For example a 100% is the maximum height the desk could go to. My standing position happens to be around 60%.

I am using this with an uplift desk.

1 Like

Totally doing this!
Thanks

1 Like

I assume the Bluetooth dongle Omnidesk are selling is the same one across all the same controllers.
It looks the same to the pictures I’ve seen.
I’d much prefer to try and work out how to use the port the dongle uses.

Omnidesk Bluetooth Controller

Yeah that’s the Jiecang one.

My findings on that port are here

I think it needs someone who owns a dongle to sniff the commands though:

1 Like

I tried using PWM to test if I could slow the desk on approach to its target height (like the controller does), but haven’t had any luck. I’ve never played with PWM before.

Here’s what I had in config.


output:
  - platform: ledc
    id: pwm_up
    pin: ${desky_up_pin}
    inverted: true

light:
  - platform: monochromatic
    name: "PWM Up"
    output: pwm_up
    internal: false
    gamma_correct: 1

switch:
  - platform: template
    name: test PWM Up
    id: test_pwm_up
    optimistic: true
    restore_state: true
    turn_on_action:
      - output.turn_on: pwm_up
      # ####################################################
      # Frequency sets the wave size
      # ####################################################
      - output.ledc.set_frequency:
          id: pwm_up
          frequency: "1000Hz"
      # #####################################################
      # level sets the %age time the PWM is on
      # #####################################################
      - output.set_level:
          id: pwm_up
          level: "20%"
      - delay: 2s 
      - output.set_level:
          id: pwm_up
          level: "40%"
      - delay: 2s 
      - output.set_level:
          id: pwm_up
          level: "60%"
      - delay: 2s 
      - output.set_level:
          id: pwm_up
          level: "80%"
      - delay: 2s 
      - output.turn_off: pwm_up
      - switch.turn_off: test_pwm_up
    turn_off_action:
      - output.turn_off: pwm_up
      - switch.turn_off: test_pwm_up

Also tried changing “brightness” of above light (when “on”). Desk moves when light is on, but it does not slow the desk.

unknown-5

I have a logic analyser but am not quite motivated enough to take this further at this point. So will leave this here and maybe someone else will crack it as we gather more users.

Hello,

I’ve begun to put this together but when checking the wiring, I remembered I have the simple touch capacitive switch for up/down control (actually a mistake when ordering, but never got around to sorting it)

From some quick testing, and following your diagram:

Green/White + Brown = Desk moves down
Green/White + Brown/White = Desk Moves Up.

I haven’t got as far as examining the code, but was wondering if the chip needed wiring up any differently to connect these cables.

The cables from the switch are coloured differently too, but for wiring to the chip translate as:
Brown = up
Brown/White = down
Blue/white = +5v
Green/white = 0v

Sounds like you might need to test a bit more to confirm.

Some links/photos might help me understand your set-up better. Does your control panel display height? Or have presets? Or is it just up and down? How many wires does it have? Is this a Desky desk?

But basically you need to identify 4 wires for control. A wake wire which makes the desk controller send height data, an RX wire to get the desks height, and up/down pins. It’s possible you may not need wake/rx connected on the control panel, but I think you’d still want to identify and connect them on the controller side.

Hey,

Thanks for the reply. So, I think the excellent work you’ve done doesn’t apply when there is only a simple up/down switch on the desk.

I’m not that familiar with ESP type devices, but when I have some more time will see if it can be made to simply go up / down. I only really wanted an automated reminder to stand up (and move the desk) anyway.

No presets, no heights, just up and down.

It’s a Jarvis Fully desk, I’m confident your method will work, but I probably need different code.

I think if it is a Jiecang controller box similar to the one linked in my initial posts, then the full solution should work with some adjustment (ie you should be able to get desk height and move to desk height), regardless of the simpler control panel (I think).

I’m happy enough to help you work through some of it when you’re ready, as I’d been keen to see it work with more desk types.

A simpler up/down control only set-up should be pretty easy by just using some gpio switches. But without knowing the desk height, you’d really just have a virtual version of your control panel and limited smarts you could build around that.