Hallo zusammen,
ich habe meinen alten, Schreibtisch gegen einen Yaasa Desk Expert getauscht – und natürlich musste ich ihn direkt in Home Assistant einbinden!
Dank der RJ12-Schnittstelle am Schreibtisch-Controller konnte ich ihn mit ESPHome und meinem Home Assistant-Setup verbinden.
Ihr benötigt einen ESP32 und ein passendes RJ12 Stecker/Kabel.
ESPHome-Integration – Technische Umsetzung
Der Yaasa-Controller nutzt ein serielles Protokoll über UART. Ursprünglich wollte ich einen D1 Mini verwenden, hatte aber Probleme mit dem RX-Pin. Mit einem ESP32 lief alles problemlos. Die Steuerung funktioniert nun nicht nur über Home Assistant, sondern auch über mein Elgato Stream Deck!
Das passende Youtube video findest du hier:
Hier mein ESPHome YAML-Code, falls ihr das nachbauen wollt, ich habe den Code von GitHub - Rocka84/esphome_components noch etwas erweitert:
esphome:
name: yaasaeps32-test
friendly_name: Yaasa Desk Expert
on_boot:
# don't touch if you don't know what you're doing!
priority: 0 # when mostly everything else is done
then:
- lambda: "id(my_desk).request_physical_limits();"
- delay: 0.1s # give controller a chance to handle the response before sending the next command
- lambda: "id(my_desk).request_limits();"
- delay: 0.1s
- lambda: "id(my_desk).request_settings();"
external_components:
- source:
#type: local
# path: rocka84_esphome_components/components/
type: git
url: https://github.com/Rocka84/esphome_components/
components: [ jiecang_desk_controller ]
uart:
id: uart_bus
tx_pin: TX
rx_pin: RX
baud_rate: 9600
logger:
baud_rate: 0 # disable logging over uart, required when using the RX/TX pins for the controller
bluetooth_proxy:
active: false
esp32_ble_tracker:
id: ble_tracker
scan_parameters:
active: false # Whether to send scan-request packets to devices to gather more info (like devicename)
interval: 211ms # suggested 211ms # default 320ms
window: 120ms # suggested 120ms # default 30ms
jiecang_desk_controller:
id: my_desk
sensors:
height:
id: height
name: "Height"
height_pct:
id: height_pct
name: "Height Percent"
height_min:
id: height_min
name: "Height Min"
height_max:
name: "Height Max"
position1:
name: "Position 1"
position2:
name: "Position 2"
position3:
name: "Position 3"
position4:
name: "Position 4"
buttons:
move_up:
name: "Move up"
id: move_up
move_down:
name: "Move down"
id: move_down
stop:
name: "Stop"
id: stop
step_up:
name: "Step up"
id: step_up
step_down:
name: "Step down"
id: step_down
position1:
name: "Position 1"
position2:
name: "Position 2"
position3:
name: "Position 3"
position4:
name: "Position 4"
save_position:
name: "Save Position"
numbers:
height_pct:
name: "Height Percent"
id: height_percent_id
height:
name: "Height"
id: height_id
on_value:
then:
- binary_sensor.template.publish:
id: desk_is_moving
state: True
- delay: 100ms
- binary_sensor.template.publish:
id: desk_is_moving
state: False
cover:
- platform: template
id: deskcover
name: "Desk"
icon: mdi:desk
open_action:
- button.press: move_up
close_action:
- button.press: move_down
stop_action:
- button.press: stop
assumed_state: true
optimistic: true
has_position: true
lambda: |-
if ( !isnan(id(height_pct).state) ) {
float position = id(height_pct).state ;
position = roundf(position ) / 100; // Round to two decimal places
return position; }
device_class: shutter
binary_sensor:
# Didn't end up using this for the cover in the end.
- platform: template
id: desk_is_moving
name: "Desk is Moving"
filters:
- delayed_off: 300ms
button:
- platform: template
name: "Save Position 1"
on_press:
lambda: "id(my_desk).save_position(1);"
- platform: template
name: "Save Position 2"
on_press:
lambda: "id(my_desk).save_position(2);"
- platform: template
name: "Save Position 3"
on_press:
lambda: "id(my_desk).save_position(3);"
- platform: template
name: "Save Position 4"
on_press:
lambda: "id(my_desk).save_position(4);"
- platform: template
name: "Position 2"
on_press:
lambda: "id(my_desk).goto_position(2);"
- platform: restart
name: "Restart"
- platform: template
name: "Reminder"
on_press:
then:
- button.press: step_up
- delay: 1s
- button.press: move_down
# the usual stuff
esp32:
board: esp32dev
framework:
type: esp-idf
version: recommended
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
ap:
ssid: "esphome-desk"
password: "passwort"
captive_portal:
api:
encryption:
key: "key"
reboot_timeout: 0s
ota:
platform: esphome
password: "passwort"
web_server:
port: 80
Ich habe alle Funktionen soweit es gingt in den ESPHome Code integriert.
Es mangelt aktuell nur an der Funktion die Position auch über Home Assistant über die Cover Entity zu steuern. Das wollte mit all meinen Versionen nicht funktionieren.
Daher ergänzt diese Automation noch das gesamte Setup. Wenn du noch eine Idee hast wie das zusätzlich in den ESPHome Code einfließen kann. Lass gerne noch etwas da:
alias: Yaasa Desk Cover Position
description: ""
triggers:
- trigger: event
event_type: call_service
event_data:
domain: cover
service: set_cover_position
service_data:
entity_id: cover.yaasa_desk
conditions: []
actions:
- action: number.set_value
metadata: {}
data:
value: "{{trigger.event.data.service_data.position}}"
target:
entity_id: number.yaasaeps32_test_height_percent
mode: single