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

Support for HS36B-1 #102

Open
mploetner opened this issue Nov 14, 2024 · 6 comments
Open

Support for HS36B-1 #102

mploetner opened this issue Nov 14, 2024 · 6 comments

Comments

@mploetner
Copy link

Hey do you think it would be possible to support the HS36B-1 controller? How can I help here?

@iMicknl
Copy link
Owner

iMicknl commented Nov 26, 2024

Can you share more information on the controller? Pictures from the outside and inside of your desk controller.

Feel free to join our Discord as well to chat with like-minded people. Invite link can be found in the README.

@claviger-pc
Copy link

I have the same controller and have taken pictures of the controller itself and the driver box, which is a CB38M2L.

I am happy to do testing. It seems that the ethernet cord follows the colors in the connector to the controller itself. Let me know if anything else could be of help. I would be happy to do some testing.

IMG_0179
IMG_0178
IMG_0177
IMG_0176
IMG_0175
IMG_0174
IMG_0173
IMG_0171

@NotClear
Copy link

NotClear commented Dec 3, 2024

HS36B-1 Pin-out

The PCB is different but the pin-out is the same as the HS13B-1

RJ45 pin Name Original Cable Color
1 RESET Brown
2 SWIM White
3 EMPTY Purple
4 PIN 20 Red
5 RX Green
6 TX Black
7 GND Blue
8 +5V (VDD) Yellow

IMG_0691

@claviger-pc
Copy link

@NotClear, thank you for letting me know. I will check this out and confirm that it works and then hopefully file a PR.

@NotClear
Copy link

NotClear commented Dec 4, 2024

This is my adapter, which I quickly built for testing purposes.

IMG_0695

Below is the configuration I tested for the FlexiSpot E2Q with the CB38M2L(IB)-1 controller box and the HS36B-1 control panel:

substitutions:
  upper_devicename: Flexispot E2Q
  devicename: office-desk-flexispot-e2q
  min_height: "73"
  max_height: "123"
  tx_pin: GPIO16
  rx_pin: GPIO12
  screen_pin: GPIO14

external_components:
  source: github://iMicknl/LoctekMotion_IoT
  components: [ loctekmotion_desk_height ]

esp8266:
  board: d1_mini

esphome:
  name: ${devicename}
  friendly_name: ${upper_devicename}
  comment: Used to control your ${upper_devicename} standing desk via Home Assistant.

  on_boot:
    priority: -10
    then:
      - button.press: button_m

logger:

api:
  encryption:
    key: "KEY!"

ota:

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  ap:
    ssid: ${upper_devicename} Fallback Hotspot
    password: "WIFIPASSWORD!"

captive_portal:

uart:
  - id: desk_uart
    baud_rate: 9600
    tx_pin: ${tx_pin}
    rx_pin: ${rx_pin}

sensor:
  - platform: loctekmotion_desk_height
    id: "desk_height"
    name: Desk Height
    on_value_range:
    - below: ${min_height}
      then:
        - switch.turn_off: switch_down
    - above: ${max_height}
      then:
        - switch.turn_off: switch_up
    on_value:
      then:
        - cover.template.publish:
            id: desk_cover
            position: !lambda |-
                // The sensor outputs values from min_height (cm) to max_height (cm)
                // We need to translate this to 0 - 1 scale.
                float position = (float(x) - float(${min_height})) / (float(${max_height}) - float(${min_height}));
                return position;
        - component.update: set_desk_height

switch:
  - platform: gpio
    name: "Virtual Screen"
    pin:
      number: ${screen_pin}
      mode: OUTPUT
    restore_mode: ALWAYS_ON
    entity_category: "config"
    internal: true

  - platform: uart
    name: "Up"
    id: switch_up
    icon: mdi:arrow-up-bold
    data: [0x9b, 0x06, 0x02, 0x01, 0x00, 0xfc, 0xa0, 0x9d]
    uart_id: desk_uart
    send_every: 108ms
    internal: true

  - platform: uart
    name: "Down"
    id: switch_down
    icon: mdi:arrow-down-bold
    data: [0x9b, 0x06, 0x02, 0x02, 0x00, 0x0c, 0xa0, 0x9d]
    uart_id: desk_uart
    send_every: 108ms
    internal: true

button:
  - platform: template
    name: "Stand"
    icon: mdi:human-handsup
    on_press:
      - uart.write:
          id: desk_uart
          data: [0x9b, 0x06, 0x02, 0x04, 0x00, 0xac, 0xa3, 0x9d]

  - platform: template
    name: "Sit"
    icon: mdi:chair-rolling
    on_press:
      - uart.write:
          id: desk_uart
          data: [0x9b, 0x06, 0x02, 0x08, 0x00, 0xac, 0xa6, 0x9d]

  - platform: template
    name: "Preset 3"
    icon: mdi:numeric-3-box
    on_press:
      - uart.write:
          id: desk_uart
          data: [0x9b, 0x06, 0x02, 0x00, 0x01, 0xac, 0x60, 0x9d]

  - platform: template
    name: "Preset 4"
    icon: mdi:numeric-4-box
    on_press:
      - uart.write:
          id: desk_uart
          data: [0x9b, 0x06, 0x02, 0x10, 0x00, 0xac, 0xac, 0x9d]

  - platform: template
    name: "Memory"
    id: button_m
    icon: mdi:alpha-m-box
    entity_category: "config"
    on_press:
      - uart.write:
          id: desk_uart
          data: [0x9b, 0x06, 0x02, 0x20, 0x00, 0xac, 0xb8, 0x9d]

  - platform: template
    name: "Wake Screen"
    id: button_wake_screen
    icon: mdi:gesture-tap-button
    entity_category: "config"
    on_press:
      - uart.write:
          id: desk_uart
          data: [0x9b, 0x06, 0x02, 0x00, 0x00, 0x6c, 0xa1, 0x9d]

  - platform: restart
    name: "Restart"
    entity_category: "config"

cover:
  - platform: template
    id: "desk_cover"
    icon: mdi:desk
    name: "Desk"
    device_class: blind
    has_position: true
    position_action:
      - if:
          condition:
            - lambda: !lambda |-
                return pos > id(desk_cover).position;
          then:
            - cover.open: desk_cover
            - wait_until:
                lambda: |-
                  return id(desk_cover).position  >= pos;
            - cover.stop: desk_cover
          else:
            - cover.close: desk_cover
            - wait_until:
                lambda: |-
                  return id(desk_cover).position <= pos;
            - cover.stop: desk_cover
    stop_action:
      - switch.turn_off: switch_up
      - switch.turn_off: switch_down
    open_action:
      - switch.turn_off: switch_down
      - switch.turn_on: switch_up
    close_action:
      - switch.turn_off: switch_up
      - switch.turn_on: switch_down
    optimistic: false

number:
  - platform: template
    name: "Desk Height"
    id: set_desk_height
    min_value: ${min_height}
    max_value: ${max_height}
    icon: "mdi:counter"
    unit_of_measurement: "cm"
    device_class: "distance"
    step: 0.1
    lambda: !lambda |-
      return id(desk_height).state;
    set_action:
      - if:
          condition:
            - lambda: !lambda |-
                return x > id(desk_height).state;
          then:
            - cover.open: desk_cover
            - wait_until:
                lambda: |-
                  return id(desk_height).state  >= x;
            - cover.stop: desk_cover
          else:
            - cover.close: desk_cover
            - wait_until:
                lambda: |-
                  return id(desk_height).state <= x;
            - cover.stop: desk_cover

@claviger-pc
Copy link

I can confirm that this works, and that the E5Q, using the the above controllers, is supported!!

Thanks @iMicknl and @NotClear. @mploetner: you can follow the instructions for the HS13B-1 as suggested above!

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