My findings getting this desk working with ESPHome
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
I was following another great thread on here around how to integrate with HA/ESPHome by tapping into the control & serial lines between the controller & handset but when I received my standing desk it looks like Maidesite changed the design so instead of a separate control box & handset everything is now contained within the handset itself. While I suspect a lot of what others have found would be do-able on this new handset it could easily void any warranties/guarantees pretty quickly I decided to see what could be done via the RJ12 socket which this machine does have. It has no mention Jiecang anywhere on the hardware/instructions I started playing with some information found off that thread and pretty quickly got the basics working. The hardest part was trying to get information to make the desk move to a specific position but eventually found someone had created a spreadsheet with a ton of useful information which suggests the controller is probably made by Jiecang or based on their design so is possibly usable by other brands that have an RJ12 connector.
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
hope it is of use to someone else with this desk.
Great work @Shades66.
I am planing to automate my Maidesite Desk, just waiting for the RJ12 cable to arrive.
By any chance could you add a photo / pic with the esp wiring. The devider for the TX connection is confusing me a bit.
Thanks a lot.
Edit: The cable arrived, but the colors are different. I think I have managed to work out the connections.
I have set up the eps32. Now when I trigger the TEST button, the desk control pannel lights up and the following is printed to the console. The rest of the sensors are unavailable.
It seem I’ve got some data send to the desk, but looks like nothing is getting from the desk to the ESP32.
[21:49:35][D][uart_debug:176]: >>> 241,241,7,0,7,126,241,241,8
[21:49:35][D][uart_debug:176]: >>> 0,8,126,241,241,9,0,9,126
[21:49:35][D][uart_debug:176]: >>> 241,241,12,0,12,126,241,241,14
[21:49:35][W][component:204]: Component api took a long time for an operation (0.05 s).
[21:49:35][W][component:205]: Components should block for at most 20-30ms.
[21:49:35][D][uart_debug:176]: >>> 0,14,12
Edit 2:
Got there at the end. Works well. Can’t wait to automate my daily standing routine
Thanks again for your work!!!
Hey, sorry I didn’t see anyone had responded to this, Glad to hear you got it working
I’ll add an image of the wiring to make it easier to identify the correct colours at some point over the weekend
anyone else wanting to know the circuit diagram I used the circuit from this page (just the resistors part into the ESP’s RX pin) Arduino Uno serial communication with ESP32 using voltage divider - #2 by groundFungus - Project Guidance - Arduino Forum
Nice work, i’ve got my cable and begin my work these days… thanks for your effort! Will tell you, if i was successful
Hi Mark,
I’m a bit lost as unfortunately not as technical as I once was… do you have a photo of your wiring etc please if possible linked to the ESP 32?
Do I flash desk.h onto the board and load dskcontrol.yaml into my configuration on Home Assistant?
Thanks
Richard
Hi guys!
I’m following the GitHub project to integrate my Maidesite desk as well.
Code on the ESP seems to be OK but I’m stuck at the very same first edit of @tomino
[21:18:05][D][button:010]: 'Desk test' Pressed.
[21:18:05][D][main:495]: TEST Pressed
[21:18:05][D][uart_debug:176]: >>> 241,241,7,0,7,126,241,241,8
[21:18:05][D][uart_debug:176]: >>> 0,8,126,241,241,9,0,9,126
[21:18:05][D][uart_debug:176]: >>> 241,241,12,0,12,126,241,241,14
[21:18:05][D][uart_debug:176]: >>> 0,14,126
No infos from the desk and as far as I can tell no other button are functioning. Any clues are welcome. What did I do wrong?
Hoping to read from you, as I revived this aging topic…
My bad!…
I was missing the home assistant’s entity to enable desk movement.
All’s up&running! Big up for the awesome work.
Hey, how did you manage to make it work in the end?
I got to the point where I can send the signals to the desk and make it move up/down, but I’m not getting any data from the desk back (current height, M1-4 heights). Do you happen to have a photo of your setup?
Hey, my problem was with the connections to uart. I had them mixed up.
Hi. I’m about to dive into your solution.
Has there been any progress on the remaining todo list?
I have a hard time to get it running.
I have a nodemcu esp-c3-32s-kit a151, the 5V from the RJ Connector is enough to power it. (Still tried the USB power to make sure)
But I had trouble finding the correct TX and RX pins for the esphome config. Turns out, I could not use the uart0 pins (U0RX U0TX). Instead I had to use others.
Receiving data now works, I get the memory profiles and the current height.
Sending data does not work, except the “Desk test” to trigger re-receiving the data.
But all commands dont do anything. Changed to different pins made no difference.
I also redid the whole connection, first I had a really long cable. Also I can beep it through with my multimeter. So I find it a bit strange that receiving works, but sending (that’s just a plain connection) does not.
Any ideas?
Added: my working wiring (maybe you need 5V and GND from USB - esp32-c3-devkitm-1 got enough power over RJ14, esp32dev (wroom rev1) did not)
From top to bottom:
purple GND
green TX
blue 5V
white RX
I have a RJ14, that works too(same connector, but only 4 pins in use)
My bad!…
I was missing the home assistant’s entity to enable desk movement.
I finally found out what was the problem. This. I didn’t understood what HobbitBen ment. It took me very long to figure it out myself.
Also the documentation is very unclear about this “feature”.
I also expected, that when I manually turn on that switch, it should stay on.
For anyone else that stumbles over this problem:
There is a home assistant entitiy binary_sensor.presence
that is imported into ESPhome, and it only works if that is “on”.
- So either update the ESPhome config to reflect that binary sensor name, if you have any presence detection. (under t
ext_sensor:
) - Or create a dummy
binary_sensor.presence
that is always on. - Or disable the check in the ESPhome config:
switch:
- platform: template
name: "Desk Enable"
...
return true;
} else {
return true; # <--- instead of false
}
...
Can someone maybe post a picture of the final set up.
I have a MAIDeSITe T2 Pro desk which I understand is the same as what @Shades66 has.
My understanding is that to get the control of the desk to HomeAssistant one needs a ESP board connected via RJ12 to the second (free) port to the motor controller (see picture at the bottom) and a usb power cable to provide power to the ESP.
Then deskcontrol.yaml
and desk.h
are used with ESPHome and that should be all.
Am I wrong?
I suspect that this project will work for the Maidesite desks on the RJ12 port.
I’ve tested it and it works well on my Desky Desk.
The RJ12 dongle is also easier to make than the RJ45 dongle.
Probably you can even get a basic solution with yaml only like this:
Yaml only solution
# You probably won't need the stuff under platformio_options: and framework: , I'm just using a weird board.
esphome:
name: "jiecang-desk-controller-rj12-c3"
friendly_name: Desk Controller RJ12 C3
comment: Desk Controller for Jiecang Controllers via RJ12 port
platformio_options:
board_build.flash_mode: dio
on_boot:
priority: 0
then:
- button.press: cmdFetchHeightValue # Request height on boot.
esp32:
board: esp32-c3-devkitm-1
framework:
type: esp-idf
sdkconfig_options:
CONFIG_BT_BLE_42_FEATURES_SUPPORTED: y
CONFIG_BT_BLE_50_FEATURES_SUPPORTED: y
CONFIG_ESP_TASK_WDT_TIMEOUT_S: "10"
variant: ESP32C3 # lolin c3 pico pinout | https://arduino-projekte.info/wp-content/uploads/2023/01/Wemos-Lolin-C3-Pico-Pinout.webp
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
manual_ip:
static_ip: 192.168.1.XXX # I like to set static IPs.
gateway: 192.168.1.1
subnet: 255.255.255.0
api:
ota:
logger:
level: VERBOSE # Required for uart debug messages.
uart:
tx_pin: GPIO21
rx_pin: GPIO20
baud_rate: 9600
debug:
direction: BOTH
dummy_receiver: true
after:
delimiter: [0x7E]
# timeout: 5ms
sequence:
# Use mulcmu's method for reading uart without a custome component: https://community.home-assistant.io/t/how-to-uart-read-without-custom-component/491950?u=mahko_mahko
- lambda: |-
UARTDebug::log_int(direction, bytes, ','); // Log the message as int. Good for height message checks.
UARTDebug::log_hex(direction, bytes, ','); // Log the message in hex. Good for checking against protocol documentation.
ESP_LOGD("custom", "Bytes size: %d", bytes.size()); // Logs how many bytes in the message, useful for protocol and message identification.
if (direction == UART_DIRECTION_RX)
{
if (bytes.size() == 9) // Only parse messages with 9 bytes.
{
// Do some validation that it is a height message by checking some bytes.
if (bytes[0] == 0xF2 && bytes[1] == 0xF2 && bytes[2] == 0x01 && bytes[8] == 0x7E)
{
int height = (bytes[4] * 256) + bytes[5];
id(desk_height).publish_state(height);
}
}
}
sensor:
- platform: template
name: "Desk Height"
id: desk_height
update_interval: never
- platform: uptime
icon: mdi:sort-clock-descending
name: Uptime
id: uptime_sensor
update_interval: 5s
accuracy_decimals: 0
unit_of_measurement: s
number:
- platform: template
name: "Go To Height cm"
id: go_to_height_value
optimistic: true
min_value: 80.0
max_value: 250.0
step: 0.1
button:
- platform: uart
id: "cmdStop"
name: "Stop"
data: [0xF1, 0xF1, 0x2B, 0x00, 0x2B, 0x7E]
# Memory Presets
- platform: uart
id: "cmdGotoMemory1"
name: "Go To Memory 1"
data: [0xF1, 0xF1, 0x05, 0x00, 0x05, 0x7E]
- platform: uart
id: "cmdGotoMemory2"
name: "Go To Memory 2"
data: [0xF1, 0xF1, 0x06, 0x00, 0x06, 0x7E]
- platform: uart
id: "cmdGotoMemory3"
name: "Go To Memory 3"
data: [0xF1, 0xF1, 0x27, 0x00, 0x27, 0x7E]
- platform: template
name: "Go to specific height X"
on_press:
then:
- uart.write:
data: !lambda |-
float height_cm = id(go_to_height_value).state;
int height_mm = static_cast<int>(height_cm * 10); // Convert cm to mm
std::vector<uint8_t> bArr(8);
bArr[0] = 0xF1;
bArr[1] = 0xF1;
bArr[2] = 0x1B;
bArr[3] = 0x02;
bArr[4] = static_cast<uint8_t>(height_mm / 256);
bArr[5] = static_cast<uint8_t>(height_mm % 256);
bArr[6] = static_cast<uint8_t>((bArr[2] + bArr[3] + bArr[4] + bArr[5]) % 256); // Calculate checksum
bArr[7] = 0x7E;
return bArr;
- platform: uart
id: "cmdDown"
name: "Nudge Down"
data: [0xF1, 0xF1, 0x02, 0x00, 0x02, 0x7E]
- platform: uart
id: "cmdUp"
name: "Nudge Up"
data: [0xF1, 0xF1, 0x01, 0x00, 0x01, 0x7E]
- platform: uart
id: "cmdMemory1"
name: "Set Memory 1"
data: [0xF1, 0xF1, 0x03, 0x00, 0x03, 0x7E]
- platform: uart
id: "cmdMemory2"
name: "Set Memory 2"
data: [0xF1, 0xF1, 0x04, 0x00, 0x04, 0x7E]
- platform: uart
id: "cmdMemory3"
name: "Set Memory 3"
data: [0xF1, 0xF1, 0x25, 0x00, 0x25, 0x7E]
- platform: uart
id: "cmdFetchHeightValue"
name: "Fetch Height Value"
data: [0xF1, 0xF1, 0x07, 0x00, 0x07, 0x7E]
# If you need anything more than the above you should probably move across to another method / project.
# - platform: uart
# id: "cmdFetchAllTime"
# name: "Fetch All Time"
# data: [0xF1, 0xF1, 0xAA, 0x00, 0xAA, 0x7E]
# - platform: uart
# id: "cmdFetchHeightRange"
# name: "Fetch Height Range"
# data: [0xF1, 0xF1, 0x0C, 0x00, 0x0C, 0x7E]
# - platform: uart
# id: "cmdFetchHeightValue"
# name: "Fetch Height Value"
# data: [0xF1, 0xF1, 0x07, 0x00, 0x07, 0x7E]
# - platform: uart
# id: "cmdFetchHighestLowestLimit"
# name: "Fetch Highest Lowest Limit"
# data: [0xF1, 0xF1, 0x20, 0x00, 0x20, 0x7E]
# - platform: uart
# id: "cmdFetchStandTime"
# name: "Fetch Stand Time"
# data: [0xF1, 0xF1, 0xA6, 0x01, 0xA7, 0x7E]
# - platform: uart
# id: "cmdPatch"
# name: "Patch"
# data: [0xF1, 0xF1, 0xA0, 0x00, 0xA0, 0x7E]