Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature Request: Desky | Support Height Decoder Variant #40

Open
OkhammahkO opened this issue Nov 9, 2022 · 42 comments
Open

Feature Request: Desky | Support Height Decoder Variant #40

OkhammahkO opened this issue Nov 9, 2022 · 42 comments

Comments

@OkhammahkO
Copy link

OkhammahkO commented Nov 9, 2022

Pasted from our discord chat. Let me know if you need any more info.

We’ve come across a desk which appears to be slightly different in one area.

In summary (and to refresh)...
Most desks send:

But what we’ve found with some Jarvis desks is that they appear to actually send the second “9 byte message” over the RJ45 port. Everything else appears to be the same (including how the bytes are used to calculate height.
https://community.home-assistant.io/t/desky-standing-desk-esphome-works-with-desky-uplift-jiecang-assmann-others/383790/105?u=mahko_mahko

So I think the feature request is to be able to select/switch the protocol.
My thought was the revised config might look a bit like below?

Thank you!

desky:
  #uart_id: desk_uart  (optional, unless multiple uarts are defined)
  id: my_desky
  height_protocol_variant: (optional, 4byte or 9byte, defaults to 4byte)
  height:  # optional sensor publishing the current height
    name: Desk Height
    # any other sensor options
@hraschan
Copy link

Hello @ssieb,

I stumbled across the HA project. I’m one of those users who would need this improvement. Would be amazing to add a second variant vor 9byte. I posted all my infos here:

https://community.home-assistant.io/t/desky-standing-desk-esphome-works-with-desky-uplift-jiecang-assmann-others/383790/296?u=hraschan

I will also look into your code. Maybe I’m able to implement it myself.

Greetings,
Max

@ssieb
Copy link
Owner

ssieb commented May 16, 2024

Any idea what the other bytes of the message are for?

@hraschan
Copy link

Not really. I actually really new to this topic. Maybe the display? My display is black when requesting the height. I only can confirm that 5 and 6 is necessary for calculating the heigh. At least for this desk.

@hraschan
Copy link

hraschan commented May 16, 2024

I looked into your code. Not really familiar with cpp.

Are you combining byte 3 and 4 to calculate the height in the following part?

 while (this->available()) {
    uint8_t c;
    int value;
    this->read_byte(&c);
    switch (state) {
     case 0:
      if (c == 1)
	state = 1;
      break;
     case 1:
      if (c == 1)
	state = 2;
      else
	state = 0;
      break;
     case 2:
      high_byte = c;
      state = 3;
      break;
     case 3:
      value = (high_byte << 8) + c;
      if (this->current_pos_ != value) {
        this->current_pos_ = value;
        if (this->height_sensor_ != nullptr)
          this->height_sensor_->publish_state(value);
      }
      state = 0;
      break;
    }
  }```

@OkhammahkO
Copy link
Author

Any idea what the other bytes of the message are for?

Similar to the most common protocol, I don''t think we ever decoded all bytes.

Interesting some controllers (like mine) appear to use the "common protocol" on the rj45 port and the "Other protocol" on the rj12 port. On some controllers that rj12 port is for a bluetooth dongle.
But on other controllers they appear to just use the "other protocol" on the rj45 port.

https://community.home-assistant.io/t/desky-standing-desk-esphome-works-with-desky-uplift-jiecang-assmann-others/383790/23?u=mahko_mahko

@hraschan
Copy link

Is there an easy way to add the "Other protocol" config?

@OkhammahkO
Copy link
Author

Is there an easy way to add the "Other protocol" config?

That's part of the suggested feature request... So not yet.

@ssieb
Copy link
Owner

ssieb commented May 17, 2024

ok, it should now auto-detect and use the correct protocol.

@OkhammahkO
Copy link
Author

Auto detect!! Classic ssieb... Over achieving on the solution!😜

@hraschan can you please report back here and on the HA thread with how you go with testing?

I might be able to help out a bit with minor config/hardware issues...

@hraschan
Copy link

Omg wow. Thats amazing. I will try that later and let you know.

@hraschan
Copy link

hraschan commented May 17, 2024

@ssieb I tried it at my desk. i get a value in home assistant. But its way off maybe the calculation is wrong?

image
[10:55:55][D][uart_debug:176]: <<< 242,242,1,3,2,230,15,251,126
[10:55:55][D][uart_debug:176]: <<< 242,242,1,3,2,230,15,251,126

Byte 5 and 6
2*256 +230 = 742mm

409.1mm in Home Assistant

on more information. When i move up the desk the height in home assistant is decreasing instead of increasing. Also the "Desky is moving" value is always off.

@OkhammahkO
Copy link
Author

OkhammahkO commented May 17, 2024

Are you using just the basic config @hraschan ? Best to start with that if not.

Maybe share your config as next step.

https://github.com/ssieb/esphome_components/blob/master/components%2Fdesky%2FREADME.md

Can you confirm that the 742mm value you manually calculated from the log is consistent with what's shown on the desk display?

@hraschan
Copy link

hraschan commented May 17, 2024

Yea 742 is the value my desk is showing.

[10:55:55][D][uart_debug:176]: <<< 242,242,1,3,2,230,15,251,126
When calulating byte 7 and 8 then i get the value above:

15, 251

15*256 + 251 = 4091mm => 409.1cm

So the calculation is off. I'm using the config from Mahko_Mahko

        if (this->rx_data_.size() < 7)
          continue;
        value = (this->rx_data_[4] << 8) + this->rx_data_[5];

But this code looks fine to me. Doesn't it?

@OkhammahkO
Copy link
Author

OkhammahkO commented May 17, 2024

Cool let's see what ssieb reckons.

Btw I'm Mahko_Mahko;)

I use a more customised config.

But probably ssieb will find it easier to debug using his intended / designed config.

@hraschan
Copy link

Ohhh hahah. Sorry man. I didn't read your name correctly. If @ssieb is requesting his config I can try any time.

@ssieb
Copy link
Owner

ssieb commented May 17, 2024

Sorry, I forgot to account for the first two bytes being missing, so the offsets were wrong. Try again.

@hraschan
Copy link

Thanks tho 😍 I will try tomorrow.

@hraschan
Copy link

Thank you @ssieb and @OkhammahkO it works like a charm. You can close this issue. I will also comment in the HA Thread.

@jcastro
Copy link

jcastro commented May 18, 2024

I'm also going to give it a try just need to get the latest config setup! thank you all

@jcastro
Copy link

jcastro commented May 18, 2024

@ssieb @hraschan I think everything is working perfectly, except for the height sensor, which sometimes shows the correct value but sometimes shows very random numbers (even out of range of what the desk is capable of moving). If you want, let me know how I can help with debugging this! (using the same config as @hraschan, but with an ESP8266)

image

@ssieb
Copy link
Owner

ssieb commented May 18, 2024

I found a detailed description of the "9" byte protocol, so it looks like I can add checksum verification and also check that it's receiving the correct message type. For now, if you can see in the uart debug log what happens with the bad values, that would be helpful.

@jcastro
Copy link

jcastro commented May 18, 2024

Absolutely, let me know if this video helps.

Memory 1 is 70.1 cm (as shown on the screen)
Memory 2 is 103 cm (as shown on the screen)

@ssieb
Copy link
Owner

ssieb commented May 18, 2024

That video shows that you're losing data, probably because of software serial on the 8266.
I've added message verification, so try it now. You should get warnings in the log instead of bad data.

@jcastro
Copy link

jcastro commented May 18, 2024

looks like now it's working a bit better, at least showing sometimes the right height. I can swap the 8266 for an ESP32 tomorrow (actually, it's the latest 8266 I have at home haha)

New video here

@ssieb
Copy link
Owner

ssieb commented May 18, 2024

@jcastro why is it getting the 4 byte protocol now? And what is that "request desk height" switch?

@jcastro
Copy link

jcastro commented May 18, 2024

I have no idea tbh! but here's my config (from @hraschan)

esphome:
  name: standing-desk
  friendly_name: Standing Desk
  on_boot:
    priority: -100.0
    then:
    #Request a desk height update after boot.
      - delay: 5s
      - switch.turn_on: wake_desk_and_get_height
esp8266:
  board: d1_mini

# Enable logging
logger:
  #level: VERY_VERBOSE
  # baud_rate: 0 #disable logging over uart
# Enable Home Assistant API
api:

ota:

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  use_address: 10.0.10.57

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: TX
    ##You can uncomment the debug section below to see UART messages.
    debug:
      dummy_receiver: true
      after:
        bytes: 9
      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
substitutions:
  #Use your own ESP pin values
  desky_request_height_pin: D5 #Request desk height | white wire  
  desky_purple_pin: D6 #purple wire  
  desky_down_pin: D1 #Move desk down | yellow wire  
  desky_up_pin: D2  #Move desk up | green wire  

output:
  - platform: gpio
    pin: ${desky_up_pin}
    id: up_green_wire
    inverted: true
  - platform: gpio
    pin: ${desky_down_pin}
    id: down_yellow_wire
    inverted: true
  - platform: gpio
    pin: ${desky_purple_pin}
    id: purple_wire
    inverted: true

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: ${desky_request_height_pin}
      inverted: true
    on_turn_on:
    - delay: 100ms
    - switch.turn_off: wake_desk_and_get_height

#Raise the desk 
  - platform: output
    output: up_green_wire
    id: raise_desk
    name: "Raise Desk"    
    on_turn_on:
    #Auto off after 15s just in case
    - delay: 15s
    - switch.turn_off: raise_desk
#Lower the desk 
  - platform: output
    output: down_yellow_wire
    id: lower_desk
    name: "Lower Desk" 
    on_turn_on:
   #Auto off after 15s just in case
    - delay: 15s
    - switch.turn_off: lower_desk

button:
  # Combination Buttons
  - platform: template
    name: "Memory 1"
    id: button_1
    on_press:
      then:
        - output.turn_on: up_green_wire
        - output.turn_on: down_yellow_wire
        - delay: 300ms
        - output.turn_off: down_yellow_wire
        - output.turn_off: up_green_wire
  - platform: output
    output: purple_wire
    name: "Memory 2"
    id: button_2
    duration: 300ms
  - platform: template
    name: "Memory 3"
    id: button_3
    on_press:
      then:
        - output.turn_on: purple_wire
        - output.turn_on: down_yellow_wire
        - delay: 300ms
        - output.turn_off: down_yellow_wire
        - output.turn_off: purple_wire
  - platform: template
    name: "Memory 4"
    id: button_4
    on_press:
      then:
        - output.turn_on: purple_wire
        - output.turn_on: up_green_wire
        - delay: 300ms
        - output.turn_off: up_green_wire
        - output.turn_off: purple_wire
#Stop movement 
  - platform: template
    name: Stop Desk
    id: desky_stop_desk
    on_press:
      then:
        - switch.turn_off: raise_desk
        - switch.turn_off: lower_desk

@hraschan
Copy link

hraschan commented May 18, 2024

Maybe your 8266 is falty. You could also try the esp32

@OkhammahkO
Copy link
Author

OkhammahkO commented May 18, 2024

I found a detailed description of the "9" byte protocol, so it looks like I can add checksum verification and also check that it's receiving the correct message type. For now, if you can see in the uart debug log what happens with the bad values, that would be helpful.

I'm curious about this protocol. Do you have a link?

There's some more info about the protocol from another project here.
https://github.com/phord/Jarvis

@OkhammahkO
Copy link
Author

@jcastro consider using a basic config for debugging so that ssieb doesn't have to navigate all the details of a more complex setup.

https://github.com/ssieb/esphome_components/blob/master/components%2Fdesky%2FREADME.md

Per my advice under software heading here.

https://community.home-assistant.io/t/desky-standing-desk-esphome-works-with-desky-uplift-jiecang-assmann-others/383790/18?u=mahko_mahko

@OkhammahkO
Copy link
Author

OkhammahkO commented May 18, 2024

@jcastro why is it getting the 4 byte protocol now? And what is that "request desk height" switch?

I wonder if the controller might switch protocol depending on the outcome of a handset startup sequence?
The Phord project gives some hint about this.

And there have been other reports of this protocol switching behavior.

That thread mentions also one protocol is broadcast based and the other packet based. Which doesn't mean much to me but might to you.

It also mentions the messages for the 9 byte protocol it can be between 6 and 9 bytes.

@ssieb
Copy link
Owner

ssieb commented May 19, 2024

There's some more info about the protocol from another project here.
https://github.com/phord/Jarvis

That's the one I was referring to.

I wonder if the controller might switch protocol depending on the outcome of a handset startup sequence?

I thought this was intercepting the display interface, so there's no handset involved.

It also mentions the messages for the 9 byte protocol it can be between 6 and 9 bytes.

Yes, that's why I'm also checking the message type in case something else shows up.

@jcastro
Copy link

jcastro commented May 19, 2024

@OkhammahkO @ssieb I've switched to a simple configuration (pasting it below) on an ESP32-S3 and it seems to work fine, except for the desk moving sensor

This video shows me changing the height on the desk controller and then tapping on the Memory 1 button
https://github.com/ssieb/esphome_components/assets/190036/2a8d5820-345a-475c-8d5c-3c22716c2778

Current config

esphome:
  name: standing-desk
  friendly_name: Standing Desk

esp32:
  board: esp32-s3-devkitc-1

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 ]

# Enable logging
logger:
  #level: VERY_VERBOSE
  # baud_rate: 0 # disable logging over uart

# Enable Home Assistant API
api:

ota:

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  use_address: 10.0.10.26

uart:
  - id: desk_uart
    baud_rate: 9600
    rx_pin: GPIO16

desky:
  id: my_desky
  height:  # optional sensor publishing the current height
    name: Desk Height
  up:    # optional <pin> config
    number: GPIO18
    inverted: true  # probably needed
  down:  # optional <pin> config
    number: GPIO21  # Corrected pin number
    inverted: true  # probably needed
  request:  # optional <pin> config to request height updates at boot
    number: GPIO17
    inverted: true  # probably needed
  stopping_distance: 65  # optional distance from target to turn off moving, default 15
  timeout: 15s  # optional time limit for moving, default is none

binary_sensor:
  - platform: template
    name: Desky moving
    lambda: return id(my_desky).current_operation != desky::DESKY_OPERATION_IDLE;

@OkhammahkO
Copy link
Author

OkhammahkO commented May 19, 2024

except for the desk moving sensor

From memory, the desk moving sensor per ssiebs config example only actually works when using the move_to function (ie not when you press a physical button etc).

So you could test and confirm that. On mobile so check indenting etc.

on_...: 
  then: 
    - lambda: id(my_desky).move_to(150);


binary_sensor: 
  - platform: template 
    name: Desky moving 
    lambda: return    id(my_desky).current_operation != desky::DESKY_OPERATION_IDLE;

If you dig around in my config you'll see how I've added an alternative sensor if you need it.

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

@jcastro
Copy link

jcastro commented May 19, 2024

on_...:
then:
- lambda: id(my_desky).move_to(150);

Thanks @OkhammahkO, but if I add this code I get a validation error

INFO ESPHome 2024.5.0
INFO Reading configuration /config/esphome/standing-desk.yaml...
ERROR Unexpected exception while reading configuration:
Traceback (most recent call last):
  File "/usr/local/bin/esphome", line 33, in <module>
    sys.exit(load_entry_point('esphome', 'console_scripts', 'esphome')())
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/esphome/esphome/__main__.py", line 1065, in main
    return run_esphome(sys.argv)
           ^^^^^^^^^^^^^^^^^^^^^
  File "/esphome/esphome/__main__.py", line 1043, in run_esphome
    config = read_config(dict(args.substitution) if args.substitution else {})
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/esphome/esphome/config.py", line 1088, in read_config
    res = load_config(command_line_substitutions)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/esphome/esphome/config.py", line 942, in load_config
    return _load_config(command_line_substitutions)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/esphome/esphome/config.py", line 932, in _load_config
    return validate_config(config, command_line_substitutions)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/esphome/esphome/config.py", line 859, in validate_config
    result.run_validation_steps()
  File "/esphome/esphome/config.py", line 144, in run_validation_steps
    task.step.run(self)
  File "/esphome/esphome/config.py", line 317, in run
    component = get_component(self.domain)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/esphome/esphome/loader.py", line 191, in get_component
    assert "." not in domain
           ^^^^^^^^^^^^^^^^^
AssertionError

@ssieb
Copy link
Owner

ssieb commented May 19, 2024

on_... is not literal... Have you read the automations guide?

@jcastro
Copy link

jcastro commented May 19, 2024

on_... is not literal... Have you read the automations guide?

Omg that explains it, sorry I didn’t even take a look at the code just copy paste.

I will take a look at the options tomorrow but overall the height seems to be correct for now (only moving it from the desk controller)

@OkhammahkO
Copy link
Author

OkhammahkO commented May 19, 2024

@jcastro once you've confirmed your desk is working with the basic move_to function and the 'Desky moving' sensor is working when using move_to we can confirm this feature request as working and then I can give you a hand with a more detailed set up on the main HA thread if you like.

A simple way to test the move_to is to put it under a button and use the on_press action with a hard coded distance in there (make sure the value is within the upper and lower range of your desk - desk will error out if sent beyond limits and need resetting). Below should work (But it would be wise at this point to start understanding what the configs are doing a bit more).

button: 
#Move to test function
  - platform: template
    name: Go To Desky Height x
    id: go_to_desky_preset_height_x
    on_press:
      then:
        - lambda: id(my_desky).move_to(1000); # Check your desk for a suitable value to use.
#Stop movement 
  - platform: template
    name: Stop Desk
    id: desky_stop_desk
    on_press:
      then:
        - lambda: id(my_desky).stop();
        
binary_sensor:
  - platform: template
    name: Desky moving
    lambda: return id(my_desky).current_operation != desky::DESKY_OPERATION_IDLE;
        
        

@jcastro
Copy link

jcastro commented May 20, 2024

@jcastro once you've confirmed your desk is working with the basic move_to function and the 'Desky moving' sensor is working when using move_to we can confirm this feature request as working and then I can give you a hand with a more detailed set up on the main HA thread if you like.

A simple way to test the move_to is to put it under a button and use the on_press action with a hard coded distance in there (make sure the value is within the upper and lower range of your desk - desk will error out if sent beyond limits and need resetting). Below should work (But it would be wise at this point to start understanding what the configs are doing a bit more).

button: 
#Move to test function
  - platform: template
    name: Go To Desky Height x
    id: go_to_desky_preset_height_x
    on_press:
      then:
        - lambda: id(my_desky).move_to(1000); # Check your desk for a suitable value to use.
#Stop movement 
  - platform: template
    name: Stop Desk
    id: desky_stop_desk
    on_press:
      then:
        - lambda: id(my_desky).stop();
        
binary_sensor:
  - platform: template
    name: Desky moving
    lambda: return id(my_desky).current_operation != desky::DESKY_OPERATION_IDLE;
        
        

I have added this to the config, but it looks like after flashing, the height sensor is not working anymore, and I get a checksum mismatch error on the logs when I press up and down on the desk controller.

simpleconfig2.mp4

EDIT: I could try restarting the desk and the ESP32 but wanted to share this first

@OkhammahkO
Copy link
Author

OkhammahkO commented May 20, 2024

Hmm probably needs @ssieb for that. Seems to relate to newer checksum validation code.

If you don't have it in your config it's worth adding back the config for uart debug and posting logs.

uart:
  - id: desk_uart
    baud_rate: 9600
    rx_pin: TX
    debug:
      dummy_receiver: true
      after:
        bytes: 9    # Try 4 if 9 looks weird
      sequence:     
        - lambda: UARTDebug::log_int(direction, bytes, ',');

@jcastro
Copy link

jcastro commented May 20, 2024

thanks @OkhammahkO! Added it back.

Tapping up and down on the desk controller 👇🏼
https://github.com/ssieb/esphome_components/assets/190036/6f00b653-93b6-457f-a349-478c609eb95a

@hraschan
Copy link

hraschan commented May 23, 2024

So unfortunate my height isn't working anymore. I updated yesterday since then it isn't working anymore. I think i just got the checksum commit in. I think the validation is not working properly. @ssieb

Edit: I forked your project and reverted your checksum commit. I can confirm it is now working again. So something is off with your validation. Please let me know if you need any assistance. I can provide logs ect.

@ssieb
Copy link
Owner

ssieb commented May 25, 2024

You need to enable the uart debugging so I can see what data is being received.
I hope you aren't trying to use the component while you have the dummy receiver enabled. That's not going to work at all.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants