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]