Learn how to connect your Flexispot (LoctekMotion) desk to the internet. This repository contains a collection of scripts to get your started, combined with research and instructions.

Overview

Flexispot Desk with automation logos (image source: Windows Central)

Turn your LoctekMotion/FlexiSpot desk into a smart desk

Recently I acquired a new standing desk from FlexiSpot. During assembly I noticed that the control panel had a RJ45 cable and a second RJ45 port, which sparked my interest. Can we connect my desk to the internet?

Most of the models Flexispot sells are using components from LoctekMotion. LoctekMotion is a manufacturer of lifting columns for height adjustable standing desks. On their website they mention a bluetooth receiver that can be inserted to the control box, but I haven't been able to find this.

This repository will help you to connect your desk to the internet via the serial communication ports (RJ45), for example for use with Home Assistant. Think of scenarios like controlling your desk via voice or creating notifications when you sit for too long. (or just because it is cool 🤓 )

Packages

Use the information in this repository at your own risk and with caution. Tinkering with electronics always has risks.

Name Description
Arduino Custom code to control your desk via an ESP32/ESP8266 module via MQTT.
ESPHome Control your desk via an ESP32/ESP8266 module connected to Home Assistant.
Raspberry Pi Custom code to control your desk via a Raspberry Pi via Python.

For more packaged solutions, see similar projects. Pull requests are welcome.

Research

If you are interested in the internals of the LoctecMotion desk system, have a look at the research below which is composed of my own findings combined with findings of similar projects.

Control Panels

At the time of writing, LoctekMotion sells 11 different control panels. The features can differ per model, but it looks like the serial interface is pretty similar for the more advanced models.

The tables below will show a mapping of the RJ45 pinout to the pinout used by the control panel. Please note that all RJ45 pins are described in the following way;

RJ-45 connector layout

In order to connect the control box to a Raspberry Pi and ESP32/ESP8266 chip I used a RJ45 to RS232 adapter with DuPont cables (jump wires), but you simply can cut and split an ethernet cable as well.

Supported Control Panels


HS13A-1


HS01B-1

If your control panel is missing, feel free to create an issue to discuss the possibilities or create a PR to add your research to this overview.

HS13A-1

  • Desk model: Flexispot EK5
  • Tested with control box: CB38M2B(IB)-1
  • Source: Printed on the PCB of the control box.
RJ45 pin Name Cable Color
8 RESET SWIM Brown
7 PIN 20 White
6 RX Purple
5 TX Red
4 GND1 Green
3 +5V (VDD) Black
2 29V+ Blue
1 29V- Yellow

HS01B-1

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

Other control panels / control boxes could be supported in the same way, but you would need to figure the RJ45 pinout mapping. Most control boxes have an extra RJ45 port for serial communication, but otherwise you would need to place your device in between the control panel and the control box.

Retrieve current height

Based upon the great work of minifloat, it became clear that the control panel utilises a 7-segment display. Fortunately, this is very common in such devices and thus there is a lot of documentation on this topic.

The control box sends the height as 4-bit hexadecimal, which is decoded in the control panel to drive the 7-segment display. The second number on the display also supports an optional decimal point ("8 segment").

Make sure you set the baud rate to 9600. For most LoctekMotion desks, the control box only broadcasts the current height for x seconds after you sent the Wake Up command. Otherwise you will receive 0x00 0x00 0x00 as payload.

source: alselectro

Execute a command

The control box only accepts commands when the 'screen is active'. This can be simulated by setting PIN 20 to HIGH.

Command list

Command name Start Length Type Payload Checksum End
Wake Up 9b 06 02 00 00 6c a1 9d
Up 9b 06 02 01 00 fc a0 9d
Down 9b 06 02 02 00 0c a0 9d
M 9b 06 02 00 ac ac b8 9d
Preset 1 9b 06 02 04 00 ac a3 9d
Preset 2 9b 06 02 08 00 ac a6 9d
Preset 3 9b 06 02 10 00 ac ac 9d
Preset 4 9b 06 02 00 01 ac 60 9d

All bytes combined will become the command to send to the control box. See the packages for sample code.

Similar projects / research

While working on this project, I found out that I am not the only one with this idea. There are a few repositories on GitHub with great research which helped me kickstart this project. ❤️

and a huge thanks to the Tweakers.net community (Dutch), whom helped me to kickstart this project.

Comments
  • Improvement: Still be able to use the control panels

    Improvement: Still be able to use the control panels

    It would be awesome if you could still use the control panel. The ESP8266 would have to read the incoming signals from the control panel and pass them on to the control unit. The same applies the other way round: Everything that is read from the control unit should also be written back to the control panel. Would such a setup be possible?

    | RJ45 PIN | Original cable color | Ethernet cable color | Description | ESP8266 GPIO > Control Unit | ESP8266 GPIO > Control Panel | Control Panel | |----------|----------------------|----------------------|----------------|-----------------------------|------------------------------|----------------| | 1 | brown | white-orange | RES | | | RES | | 2 | white | orange | SWIM | | | SWIM | | 3 | purple | white-green | N/C | | | N/C | | 4 | red | blue | Enable / Awake | D2 | ? | Enable / Awake | | 5 | green | white-blue | RX (of remote) | D6 | D1 | TX (of remote) | | 6 | black | green | TX (of remote) | D5 | D0 | RX (of remote) | | 7 | blue | white-brown | GND | | | GND | | 8 | yellow | brown | VDD (5V) | | | VDD (5V) |

    The ESP8266 itself could be supplied with power via e.g. USB, so that the control panel could use the power supply from the control unit.

    opened by staxDB 11
  • [bug] HS13A-1 stuck on

    [bug] HS13A-1 stuck on "LOC"

    Not sure this is a bug with this library, but I was playing around with connecting my arduino to the standing desk, and now I've noticed when plugging back in my original HS13A-1 keypad, it's stuck in the LOC state. Not 100% sure how to reproduce, but it will not get out of this setting regardless of how I press the buttons. I've tried:

    • hold down M for a long time
    • hold down up and down for a long time
    • powering on and off the control
    • powering on and off the control box itself

    After all of these it still just says LOC and will not move the desk up and down. I'm not sure how to debug whether it's an issue with the keypad itself, or with the box it connects to. Is any state stored in this box? My box model is CB38M2B(IB)-1

    Has anyone else run into this issue? Any ideas how to resolve? Perhaps there's a calibration issue it's experiencing where it thinks the desk is on uneven surface or otherwise has faulty state, and has shut down motor controls into the LOC state? cc @iMicknl @staxDB 🙏

    opened by tsheaff 6
  • [HS01B-1] None of the commands work

    [HS01B-1] None of the commands work

    Hey, damn cool project and just what I was looking for!

    I am having a few issues in my setup though: I have been trying ,to control a flexispot desk remotely. Unfortunately none of the scenarios work. I first tried the ESPHome solution and used an ESP8266. Since this did not work (or my desk did not respond at all), I still tried the variant with the Raspberry Pi - Unfortunately also unsuccessful. I even tried to execute the single "Up" command alone with a Python script, but the desk does not react to it.

    Which setup I have: A Flexispot E5B with an HS01B-1 control unit and a CB38M2A-1 control module. I connected the Raspberry Pi and also the ESP8266 to the control module (CB38M2A-1) via a modified Ethernet cable. For the correct ethernet cable mapping I used this table as a guideline: https://github.com/deskmatik/deskmatik#wiring-flexispot

    Do you have any idea where I made a mistake? Is my control module possibly not compatible, since I also have only one Ethernet port?

    bug 
    opened by staxDB 6
  • Would this work using an USB to RJ45 adapter using a normal linux machine?

    Would this work using an USB to RJ45 adapter using a normal linux machine?

    Hello - I was wondering whether an Ethernet / RJ 45 adapter such as this one attached to a linux machine could potentially work. Since the PI uses Linux anyways, the question to me is:

    • can we send GPIO commands over the serial port?
    • is there anything "special" or incompatible about a USB to Ethernet adapter?

    I might give it a go during the weekend unless someone thinks that there is something fundamentally wrong with this approach.

    opened by edoardo849 4
  • No Bug or issue - but i think i found the Bluetooth Adapter

    No Bug or issue - but i think i found the Bluetooth Adapter

    Hello, first at all - sorry that i need to use the Bug / Issue section, but i didnt found another way to write this publicly^^ i am new to github :).

    As i am not that into programming i searched for the Bluetooth Adatper and i think i found him. It's from Linak, the same company which produces the controller boxes called CBD6S - every flexispot or other standing desk with these type of control boxes should be compatible to this Bluetooth Adatper - this Adapter gives you access through smartphone app and a windows desktop app (should be in windows store).

    Legend: wrong assumption

    The thing is, Linak didn't sell them on their own - or seems to be they just sell their products to other Stores. So i just found a Store and i gonna order one now to try it on my just "new" Flexispot E6.

    Here are the links to the Bluetooth adapter and the compatible control box

    Bluetooth Adatper: https://www.linak-us.com/products/accessories/bluetooth-adapter-desk/

    Control Box: https://www.linak-us.com/products/control-boxes/cbd6s

    Store i found: https://www.kuechenkonsum.de/4260433394794-linak-bluetooth-adapter-desk-ble2lin002-stick-hb11-vollversion.html

    After i tested this adapter i'll get back to you! :)

    Edit: watch out for BLE2LIN002 - this is the full version Adapter - BLE2LIN003 is the limited one and offer "no wireless control through app and no automatic drive"

    BLE2LIN002 Full version Wireless control through app and automatic drive possible

    Edit 2: my bad, i just recognized the control box of flexispot isn't the cbd6s - but i am gonna try this adapter anyway - if it's not gonna work i am able to return it.

    opened by NemesorZahndrekhh 3
  • Add basic config for Flexispot E6

    Add basic config for Flexispot E6

    This adds a basic configuration for Flexispot model E6. I own this desk myself and I have tested that it's basic pinout (TX, RX, GND, +5V, PIN 20) coincides with the pinout of E5B.

    opened by glanch 2
  • Working Setup for CB28M1B-1 (2 RJ45-ports) with HS13A-1 and ESP32dev

    Working Setup for CB28M1B-1 (2 RJ45-ports) with HS13A-1 and ESP32dev

    Disclaimer: I´m from germany and my englisch isn´t very good ... Sorry

    Hello. With help from @iMicknl i was able to get my desk smart. Wanted to share my setup so that others may have an easy way to smart-up their desks :)

    Hardware

    • CB28M1B-1 "Control-Box"
    • HS13A-1 Control-Panel
    • DIGITUS D-Sub 9 zu RJ45 Adapter -> https://www.amazon.de/gp/product/B00FIUO4VI/ref=ppx_yo_dt_b_asin_title_o01_s00?ie=UTF8&th=1
    • ESP32-WROOM-32 -> https://www.amazon.de/gp/product/B074RGW2VQ/ref=ppx_yo_dt_b_asin_title_o02_s00?ie=UTF8&psc=1
    • Some Wires -> https://www.amazon.de/gp/product/B07VCG5YC4/ref=ppx_yo_dt_b_asin_title_o07_s00?ie=UTF8&psc=1
    • RJ45-Network-Cable
    • USB-Power-Supply and Micro-USB-Cable (i´m sure everybody has some of these lying around somewhere)

    Wiring image

    ESPHome

    `substitutions: device_name: Schreibtisch name: esp-schreibtisch min_height: "75.1" # Min height + 0.1 max_height: "109.1" # Max height - 0.1

    esphome: name: ${name} comment: ${device_name} platform: esp32 board: esp32dev includes: - desk_height_sensor.h

    project: name: "imicknl.loctekmotion_iot" version: "1.0.0"

    Wake Desk by sending the "M" command

    This will pull the current height after boot

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

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

    Enable fallback hotspot (captive portal) in case wifi connection fails

    ap: ssid: "Esp-Schreibtisch" password: ""

    captive_portal:

    Enable logging

    logger: level: DEBUG

    level: VERBOSE # Makes uart stream available in esphome logstream

    baud_rate: 0 # Disable logging over uart

    Enable Home Assistant API

    api:

    ota: password: ""

    uart: id: desk_uart baud_rate: 9600 tx_pin: GPIO17 rx_pin: GPIO16

    sensor:

    • platform: wifi_signal name: "WiFi Signal" update_interval: 60s

    • platform: uptime name: Uptime

    • platform: custom lambda: |- auto desk_height_sensor = new DeskHeightSensor(id(desk_uart)); App.register_component(desk_height_sensor); return {desk_height_sensor}; sensors: id: "desk_height" name: Desk Height unit_of_measurement: cm accuracy_decimals: 1 icon: "mdi:counter" state_class: "measurement" 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})); ESP_LOGD("main", "X is %f", x); ESP_LOGD("main", "Current position is %f", position); return position; switch:

    PIN20

    • platform: gpio name: "Virtual Screen" pin: number: GPIO23 mode: OUTPUT restore_mode: ALWAYS_ON entity_category: "config" internal: true

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

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

    button:

    • platform: template name: "Preset 1" icon: mdi:numeric-1-box on_press:

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

      • uart.write: id: desk_uart data: [0x9b, 0x06, 0x02, 0x08, 0x00, 0xac, 0xa6, 0x9d]
    • platform: template name: "Sit" # Preset 3 on some control panels icon: mdi:chair-rolling on_press:

      • uart.write: id: desk_uart data: [0x9b, 0x06, 0x02, 0x00, 0x01, 0xac, 0x60, 0x9d]
    • platform: template name: "Stand" icon: mdi:human-handsup 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: template name: "Alarm" id: button_alarm icon: mdi:alarm on_press:

      • uart.write: id: desk_uart data: [0x9b, 0x06, 0x02, 0x40, 0x00, 0xAC, 0x90, 0x9d]
    • platform: restart name: "Restart" entity_category: "config"

    cover:

    • platform: template id: "desk_cover" icon: mdi:desk # or mdi:human-male-height-variant name: "Desk" device_class: blind # makes it easier to integrate with Google/Alexa has_position: true position_action:

      • logger.log: "Requesting action change"

      Move desk up

      open_action:

      • while: condition: sensor.in_range: id: desk_height below: ${max_height} then: - logger.log: "Executing up command" - cover.template.publish: id: desk_cover current_operation: OPENING - uart.write: id: desk_uart data: [0x9b, 0x06, 0x02, 0x01, 0x00, 0xfc, 0xa0, 0x9d] - delay: 108ms

      Move desk down

      close_action:

      • while: condition: sensor.in_range: id: desk_height above: ${min_height} then: - logger.log: "Executing down command" - cover.template.publish: id: desk_cover current_operation: CLOSING - uart.write: id: desk_uart data: [0x9b, 0x06, 0x02, 0x02, 0x00, 0x0c, 0xa0, 0x9d] - delay: 108ms optimistic: true`
    opened by guevara777 1
  • Working Arduino Code for Flexispot E8

    Working Arduino Code for Flexispot E8

    • tested with HS13A-1 + CB38M2L(IB)-1
    • only works if HS13A-1 is wired like HS01B-1
    • based on flexispot_ek5.ino
    • 'unsigned long' replaced with 'const byte' to prevent compiler errors
    • implements
      • demo()
      • turnon()
      • wake()
      • sit()
      • stand()
    • flushes, enables and disables tx
    opened by foxytocin 1
  • Support request for Control Panels HCB213A-1 (‎E1W-EU model)

    Support request for Control Panels HCB213A-1 (‎E1W-EU model)

    Hello,

    The HCB213A-1 control panel (‎E1W-EU model) does not appear on the supported models page.

    • Model: HCB213A-1
    • Input: 18-33V DC, 10A
    • Output M.1: MAX 33V DC, MAX 4A
    • Output DC: MAX 33V DC, MAX 1.1A
    • Duty Cycle: 2 Minutes ON, 18 Minutes OFF
    • M.D.: 2011

    Here is a picture below:

    HCB213A-1

    Regards

    opened by lboue 0
  • [No Issue] My config; more Buttons/Features/

    [No Issue] My config; more Buttons/Features/ "wakeup"

    Hello, i wanted to share my config with you for Esphome:

    1 2

    Features:

    • Pull Height on boot

    • Set wifi static ip

    • ESP Status

    • ESP restart

    • ESP Home version

    • ESP IP Address

    • ESP SSID

    • On Sit/Stand button get height (after 7.5 seconds, which my table needs to get up/down) set the delay to your need

    • Button Anti Collision for setting up sensitivity (0/1/2/3)

    • Button Child Lock

    • Button 1+2; Does nothing for my E7 so i use it as wakeup which works to get an update of the height (Display goes on)

    • Button M + sitting which shows some letter and numbers at my display. i dont know what it means

    • Button Factory reset to reset the table; for more info see the comment

    The only thing i would like to add would be to get the height when manually driving up/down via display. but im not sure how to do that

    i also changed line 9 in desk_height_sensor.h from float value = NULL; to float value = 0.0;

    to solve the warning in ESPHOME when compiling

    substitutions:
      device_name: Flexispot E7
      name: flexispot_e7
      min_height: "60.5" # Min height + 0.1
      max_height: "126" # Max height - 0.1
    
    esphome:
      name: ${name}
      comment: ${device_name}
      includes:
        - desk_height_sensor.h
      on_boot:
        priority: -10
        then:
          - switch.turn_on: switch_1_2
    
    esp8266:
      board: d1_mini
    
    logger:
      esp8266_store_log_strings_in_flash: false
      #level: DEBUG
      baud_rate: 0
    
    #Enable Home Assistant API
    api:
      encryption:
        key: XXXXXXXXXXXXXXXXXXXXXXX
    
    ota:
      password: XXXXXXXXXXXXXXXXXXXXX
    
    wifi:
      ssid: !secret wifi_ssid
      password: !secret wifi_password
      reboot_timeout: 60min
      manual_ip:
        static_ip: 192.168.0.24
        gateway: XXXXXX
        subnet: XXXXXXX
      fast_connect: true
    
      #Enable fallback hotspot (captive portal) in case wifi connection fails
      ap:
        ssid: "Flexispot-Wemos Fallback Hotspot"
        password: XXXXXXX
    
    captive_portal:
        
    uart:
      id: desk_uart
      baud_rate: 9600
      tx_pin: D5
      rx_pin: D6
      
    binary_sensor:
      - platform: status
        name: "${device_name} Status"
      
    sensor:
      - platform: wifi_signal
        name: "${device_name} WiFi Signal"
        update_interval: 60s
        accuracy_decimals: 0
    
      - platform: uptime
        name: "${device_name} Uptime"
        unit_of_measurement: minutes
        update_interval: 60s
        accuracy_decimals: 0
        filters:
          - lambda: return x / 60.0;
    
      - platform: custom
        lambda: |-
          auto desk_height_sensor = new DeskHeightSensor(id(desk_uart));
          App.register_component(desk_height_sensor);
          return {desk_height_sensor};
        sensors:
          id: "desk_height"
          name: "${device_name} Tischhöhe"
          unit_of_measurement: cm
          accuracy_decimals: 1
          icon: "mdi:counter"
    
    switch:
      - platform: gpio
        name: "Virtual Screen"
        pin:
          number: D2
          mode: OUTPUT
        restore_mode: ALWAYS_OFF
        internal: true
        
      - platform: restart
        name: "${device_name} Restart"
        id: reset
    
      - platform: uart
        name: "${device_name} Preset 1"
        id: switch_preset1
        icon: mdi:numeric-1-box
        data: [0x9b, 0x06, 0x02, 0x04, 0x00, 0xac, 0xa3, 0x9d]
        uart_id: desk_uart
    
      - platform: uart
        name: "${device_name} Preset 2"
        id: switch_preset2
        icon: mdi:numeric-2-box
        data: [0x9b, 0x06, 0x02, 0x08, 0x00, 0xac, 0xa6, 0x9d]
        uart_id: desk_uart
    
      - platform: uart
        name: "${device_name} Sitzen" # Preset 3 on some control panels
        id: switch_sit
        icon: mdi:chair-rolling
        data: [0x9b, 0x06, 0x02, 0x00, 0x01, 0xac, 0x60, 0x9d]
        uart_id: desk_uart
        on_turn_off:
          - delay: 7500ms
          - switch.turn_on: switch_1_2
    
      - platform: uart
        name: "${device_name} Stehen" # Not available for all control panels
        id: switch_stand
        icon: mdi:human-handsup
        data: [0x9b, 0x06, 0x02, 0x10, 0x00, 0xac, 0xac, 0x9d]
        uart_id: desk_uart
        on_turn_off:
          - delay: 7500ms
          - switch.turn_on: switch_1_2
    
      - platform: uart
        name: "${device_name} Hoch"
        id: switch_up
        icon: mdi:arrow-up-bold
        data: [0x9b, 0x06, 0x02, 0x01, 0x00, 0xfc, 0xa0, 0x9d]
        uart_id: desk_uart
        internal: true
    
      - platform: uart
        name: "${device_name} Runter"
        id: switch_down
        icon: mdi:arrow-down-bold
        data: [0x9b, 0x06, 0x02, 0x02, 0x00, 0x0c, 0xa0, 0x9d]
        uart_id: desk_uart
        internal: true
    
      - platform: uart
        name: "${device_name} M"
        id: switch_m
        icon: mdi:alpha-m-circle
        data: [0x9b, 0x06, 0x02, 0x20, 0x00, 0xac, 0xb8, 0x9d]
        uart_id: desk_uart
    
      - platform: uart
        name: "${device_name} (wake up)" # Not available on all control panels
        id: switch_wake_up
        icon: mdi:gesture-tap-button
        data: [0x9b, 0x06, 0x02, 0x00, 0x00, 0x6c, 0xa1, 0x9d]
        uart_id: desk_uart
        
        #https://github.com/Dude88/loctek_IOT_box/blob/main/code_send_by_controllbox
      - platform: uart
        name: "${device_name} Anti Collision"
        id: switch_anti_kollision
        icon: mdi:card-remove
        data: [0x9b, 0x06, 0x02, 0x03, 0x00, 0x9C, 0xa1, 0x9d]
        uart_id: desk_uart
        send_every: 1ms
        on_turn_on:
          - delay: 6000ms
          - switch.turn_off: switch_anti_kollision
        
      - platform: uart
        name: "${device_name} Child Lock"
        id: switch_lock
        icon: mdi:account-lock
        data: [0x9b, 0x06, 0x02, 0x20, 0x00, 0xac, 0xb8, 0x9d]
        uart_id: desk_uart
        send_every: 1ms
        on_turn_on:
          - delay: 5000ms
          - switch.turn_off: switch_lock
        
      - platform: uart
        name: "${device_name} 1 + 2" # Not available for all control panels // Could be used as wake up ?
        id: switch_1_2
        icon: mdi:counter
        data: [0x9b, 0x06, 0x02, 0x0c, 0x01, 0xac, 0x65, 0x9d]
        uart_id: desk_uart
        send_every: 1ms
        on_turn_on:
          - delay: 5000ms
          - switch.turn_off: switch_1_2
        
      - platform: uart
        name: "${device_name} M + sitting" # While holding it shows some numbers / M+sitting
        id: switch_m_sitting
        icon: mdi:script
        data: [0x9b, 0x06, 0x02, 0x20, 0x01, 0x6c, 0x79, 0x9d]
        uart_id: desk_uart
        send_every: 1ms
        on_turn_on:
          - delay: 15500ms
          - switch.turn_off: switch_m_sitting
        
        #RESET TO FACTORY SETTINGS
        #AFTER DISPLAY SHOWS RST, PRESS THE DOWN BUTTON UNTIL THE TABLE REACHES THELOWEST
        #POINT AND REBOUNDS. THAT MEANS RESET IS FINISHED
        #IF DISPLAY SHOED E01 OR E02, RETRY 18 MINUTES LATER
      - platform: uart
        name: "${device_name} Factory Reset" # M+standing 3sec
        id: switch_factory_reset
        icon: mdi:factory
        data: [0x9b, 0x06, 0x02, 0x30, 0x00, 0x6c, 0xb5, 0x9d]
        uart_id: desk_uart
        send_every: 1ms
        on_turn_on:
          - delay: 5000ms
          - switch.turn_off: switch_factory_reset
          
    cover:
      - platform: template
        #icon: mdi:table-chair
        #icon: mdi-human-male-height-variant
        name: "${device_name} Tisch"
        assumed_state: true
    
        #Move desk up
        open_action:
          - while:
              condition:
                sensor.in_range:
                  id: desk_height
                  below: ${max_height}
              then:
              - logger.log: "Executing up command"
              - switch.turn_on: switch_up
              - delay: 10ms
        
        #Move desk down
        close_action:
          - while:
              condition:
                sensor.in_range:
                  id: desk_height
                  above: ${min_height} 
              then:
              - logger.log: "Executing down command"
              - switch.turn_on: switch_down
              - delay: 10ms
        optimistic: true
        
    #Sensors for ESP version and WIFI information
    text_sensor:
      - platform: version
        name: "${device_name} ESPHome Version"
        
      - platform: wifi_info
        ip_address:
          name: "${device_name} ip"
        ssid:
          name: "${device_name} ssid"
    
    opened by KrX3D 0
  • Help figuring out possible support for CB38M2D(PB)-2

    Help figuring out possible support for CB38M2D(PB)-2

    I'm hoping to work out whether or not this can be used with my Flexispot EQ5 model which uses the CB38M2D(PB)-2 control unit with Sanodesk LCD controller. The control unit doesn't have a spare RJ45 port. The LCD button panel connects to the Control box with one cable which splits into two - an RJ45 and a 2 pin connector which both go into the control box. The units appear to be sealed/glued with no easy access so I can't open them to view the boards inside, and with it still being under warranty I'm a bit hesitant to try and split the cases! Pictures to show the units, but I suppose it's a long shot hoping to get this working unless anyone else with the same model has been brave enough to open the units up to investigate?

    20220911_104402 20220911_104412 20220911_110953 20220911_111030 20220911_111054

    opened by Scoff123 0
  • Help with ESP32 HS01B-1 + CB22M2A-1

    Help with ESP32 HS01B-1 + CB22M2A-1

    Hello everyone.

    So for some days I tried to get this working. I wired up my hardware with passthrough like this: image Taken from here: https://github.com/iMicknl/LoctekMotion_IoT/tree/main/packages/esphome#hs01b-1 Correct me if my wiring is wrong. Maybe I misunderstood the wiring for passthrough with esp32.

    It does not work. Display stays dark. Can't control it via home assistant. The buttons also don't work. I checked my wiring a lot of times with multimeter. I'm certain it is correctly wired up just like on the picture.

    Sometimes I had luck (2-3 times) after replugging HS01B-1 the display turns on and the table height is published in home assistant.

    I'm sure my wiring is correct. It must be something else.

    Please help me so I can sleep at night again :) 😅

    opened by copystring 1
  • [No issue] working setup for Home Assistant + ESPHome + esp32dev + CB28M1B-1 + HS13A-1

    [No issue] working setup for Home Assistant + ESPHome + esp32dev + CB28M1B-1 + HS13A-1

    Thank you to @iMicknl for helping me out with this! I´d like to share my working setup with others :)

    Hardware

    • Control-Panel HS13A-1
    • Control-Box CB28M1B-1
    • ESP32-Board (ESP32-WROOM-32) -> https://www.amazon.de/gp/product/B074RGW2VQ/ref=ppx_yo_dt_b_asin_title_o02_s00?ie=UTF8&psc=1
    • Breadboard -> https://www.amazon.de/gp/product/B07VFK5CRP/ref=ppx_yo_dt_b_asin_title_o03_s00?ie=UTF8&psc=1
    • Case -> https://www.amazon.de/gp/product/B09D3YNZSL/ref=ppx_yo_dt_b_asin_title_o07_s00?ie=UTF8&psc=1
    • RJ45-RS232-Adapter -> https://www.amazon.de/gp/product/B00FIUO4VI/ref=ppx_yo_dt_b_asin_title_o01_s00?ie=UTF8&psc=1
    • Jumper-Wires -> https://www.amazon.de/gp/product/B07VCG5YC4/ref=ppx_yo_dt_b_asin_title_o07_s00?ie=UTF8&psc=1
    • "Wago-Klemmen" (for connecting the wires) -> https://www.amazon.de/WAGO-Klemmen-St%C3%BCck-Sortiment-bestehend/dp/B0846QDN1Y/ref=sr_1_5?__mk_de_DE=%C3%85M%C3%85%C5%BD%C3%95%C3%91&crid=2MWWY6SWCP7PO&keywords=wago+klemmen&qid=1647966505&sprefix=wago+klemmen%2Caps%2C77&sr=8-5
    • RJ45-Network-Cable
    • USB Power-Supply + Micro-USB-Cable or power-supply over "V5"-Pin (see picture below)

    Disclaimer: I power my ESP32 with USB. I did not test to power it via V5-Pin. Please check the Documentation of your Board!

    Wiring image

    ESPHome

    Don`t forget to put this file -> https://github.com/iMicknl/LoctekMotion_IoT/blob/main/packages/esphome/desk_height_sensor.h in the same folder as your .yaml-file for esphome!

    substitutions:
      device_name: Schreibtisch # <- Friendlyname of your Device in Home Assistant
      name: esp-schreibtisch # <- name of your device in Home Assistant
      min_height: "75.1" # Min height + 0.1
      max_height: "109.1" # Max height - 0.1
    
    esphome:
      name: ${name}
      comment: ${device_name}
      platform: esp32 # TODO Change to your platform
      board: esp32dev # TODO Change to your board
      includes:
        - desk_height_sensor.h
    
      project:
        name: "imicknl.loctekmotion_iot"
        version: "1.0.0"
    
      # Wake Desk by sending the "M" command
      # This will pull the current height after boot
      on_boot:
        priority: -10
        then:
          - button.press: button_m
    
    wifi:
      ssid: !secret wifi_ssid
      password: !secret wifi_password
    
      # Enable fallback hotspot (captive portal) in case wifi connection fails
      ap:
        ssid: "Esp-Schreibtisch"
        password: "<supersecretpassword>"
    
    captive_portal:
    
    # Enable logging
    logger:
      level: DEBUG
      # level: VERBOSE # Makes uart stream available in esphome logstream
      baud_rate: 0 # Disable logging over uart
    
    
    # Enable Home Assistant API
    api:
    
    ota:
      password: "<supersecretpassword>"
    
    uart:
      id: desk_uart
      baud_rate: 9600
      tx_pin: GPIO17
      rx_pin: GPIO16
    
    sensor:
      - platform: wifi_signal
        name: "WiFi Signal"
        update_interval: 60s
    
      - platform: uptime
        name: Uptime
    
      - platform: custom
        lambda: |-
          auto desk_height_sensor = new DeskHeightSensor(id(desk_uart));
          App.register_component(desk_height_sensor);
          return {desk_height_sensor};
        sensors:
          id: "desk_height"
          name: Desk Height
          unit_of_measurement: cm
          accuracy_decimals: 1
          icon: "mdi:counter"
          state_class: "measurement"
          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}));
                      ESP_LOGD("main", "X is %f", x);
                      ESP_LOGD("main", "Current position is %f", position);
                      return position;
    switch:
      # PIN20
      - platform: gpio
        name: "Virtual Screen"
        pin:
          number: GPIO23
          mode: OUTPUT
        restore_mode: ALWAYS_ON
        entity_category: "config" 
        internal: true
    
      - platform: uart
        name: "Up"
        id: switch_up2
        icon: mdi:arrow-up-bold
        data: [0x9b, 0x06, 0x02, 0x01, 0x00, 0xfc, 0xa0, 0x9d]
        uart_id: desk_uart
        send_every: 108ms
    
      - platform: uart
        name: "Down"
        id: switch_down2
        icon: mdi:arrow-down-bold
        data: [0x9b, 0x06, 0x02, 0x02, 0x00, 0x0c, 0xa0, 0x9d]
        uart_id: desk_uart
        send_every: 108ms
    
    button:
      - platform: template
        name: "Preset 1"
        icon: mdi:numeric-1-box
        on_press:
          - uart.write:
              id: desk_uart
              data: [0x9b, 0x06, 0x02, 0x04, 0x00, 0xac, 0xa3, 0x9d] 
    
      - platform: template
        name: "Preset 2"
        icon: mdi:numeric-2-box
        on_press:
          - uart.write:
              id: desk_uart
              data: [0x9b, 0x06, 0x02, 0x08, 0x00, 0xac, 0xa6, 0x9d]
    
      - platform: template
        name: "Sit" # Preset 3 on some control panels
        icon: mdi:chair-rolling
        on_press:
          - uart.write:
              id: desk_uart
              data: [0x9b, 0x06, 0x02, 0x00, 0x01, 0xac, 0x60, 0x9d]
    
      - platform: template
        name: "Stand"
        icon: mdi:human-handsup
        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: template
        name: "Alarm"
        id: button_alarm
        icon: mdi:alarm
        on_press:
          - uart.write:
              id: desk_uart
              data: [0x9b, 0x06, 0x02, 0x40, 0x00, 0xAC, 0x90, 0x9d]
    
      - platform: restart
        name: "Restart"
        entity_category: "config"
    
    cover:
      - platform: template
        id: "desk_cover" 
        icon: mdi:desk # or mdi:human-male-height-variant
        name: "Desk"
        device_class: blind # makes it easier to integrate with Google/Alexa
        has_position: true
        position_action:
          - logger.log: "Requesting action change"
    
        # Move desk up
        open_action:
          - while:
              condition:
                sensor.in_range:
                  id: desk_height
                  below: ${max_height}
              then:
                - logger.log: "Executing up command"
                - cover.template.publish:
                    id: desk_cover
                    current_operation: OPENING
                - uart.write:
                    id: desk_uart
                    data: [0x9b, 0x06, 0x02, 0x01, 0x00, 0xfc, 0xa0, 0x9d]
                - delay: 108ms
        
        # Move desk down
        close_action:
          - while:
              condition:
                sensor.in_range:
                  id: desk_height
                  above: ${min_height} 
              then:
                - logger.log: "Executing down command"
                - cover.template.publish:
                    id: desk_cover
                    current_operation: CLOSING
                - uart.write:
                    id: desk_uart
                    data: [0x9b, 0x06, 0x02, 0x02, 0x00, 0x0c, 0xa0, 0x9d]
                - delay: 108ms
        optimistic: true
    

    Please add the following code at the botton of the yaml-file if you want to have a position control in Home Assistant. The Position-range is from 0% to 100% and you can use it with alexa like "set desk to 70%" if you populate the cover-entity to alexa (i did it with Nabu-Casa).

        # Move desk to desired position
        position_action:
        #Check if we need to move desk up or down from current position
          if:
            condition:
            #Current height is more than target height, then move desk down
              lambda: |-
                float position = (float(id(desk_height).state) - float(${min_height})) / (float(${max_height}) - float(${min_height}));
                return pos < position;
            then:
              - logger.log: "Schreibtisch muss runter gefahren werden"
              - while:
                  condition:
                    # Move down till the current height is smaller then the target height
                    lambda: |-
                      float position = (float(id(desk_height).state) - float(${min_height})) / (float(${max_height}) - float(${min_height}));
                      return pos < position;
                  then:
                    - logger.log: "Executing down command"
                    - cover.template.publish:
                        id: desk_cover
                        current_operation: CLOSING
                    - uart.write:
                        id: desk_uart
                        data: [0x9b, 0x06, 0x02, 0x02, 0x00, 0x0c, 0xa0, 0x9d]
                    - delay: 108ms
            else:
              - logger.log: "Schreibtisch muss hoch gefahren werden"
              - while:
                  condition:
                    # Move up till the current height is bigger then the target height
                    lambda: |-
                      float position = (float(id(desk_height).state) - float(${min_height})) / (float(${max_height}) - float(${min_height}));
                      return pos > position;
                  then:
                    - logger.log: "Executing up command"
                    - cover.template.publish:
                        id: desk_cover
                        current_operation: OPENING
                    - uart.write:
                        id: desk_uart
                        data: [0x9b, 0x06, 0x02, 0x01, 0x00, 0xfc, 0xa0, 0x9d]
                    - delay: 108ms
    

    Picture of my setup image

    Voice-Control with Alexa You can control your desk via Alexa now. To do so, expose the button.sit and button.stand to alexa (i use Naba Casa for this). In the Alexa App i createt 2 routines that trigger the "Sit" and "Stand"-Scenes with a Voice command like "Alexa, im stehen arbeiten" (Alexa, work standing).

    opened by guevara777 2
Owner
Mick Vleeshouwer
Cloud Solution Architect @microsoft | Software Engineer
Mick Vleeshouwer
A repo for helping people get started with Competitive Programming and Data Structures & Algorithms

Hack CP DSA Update regarding hacktoberfest: please refer this announcement Wanna improve your problem solving skills ❓ Wanna practice collaborating on

TLE MEC 173 Oct 1, 2022
Arduino sample code to help you get started using the Soracom IoT Starter Kit!

Soracom IoT Starter Kit The Soracom IoT Starter Kit includes everything you need to build your first connected device. It includes an Arduino MKR GSM

Soracom Labs 13 Jul 30, 2022
Lets be creative this hacktober fest. Get started with contributing to open source.

Be Creative this Hacktoberfest 2021 Lets be creative this hacktober fest. Get started with contributing to open source. ?? Web-Ideas ?? How Can I Cont

B L A C K F U R Y 10 Nov 20, 2021
This repository contains the tools we used in our research on the Google Titan M chip

Titan M tools In this repository, we publish the tools we used in our research on the Google Titan M chip. We presented our results at Black Hat EU 21

Quarkslab 143 Sep 10, 2022
Conjunto de scripts para treinar um Sistema de Recomendação Híbrido baseado nos algoritmos do scikit-learn

hybrid-rs-trainner Treine suas engines de recomendação with zero code! :) Sumário Sistemas de Recomendação Collaborative Filtering Content-Based Filte

Senior Sistemas SA 11 Jan 24, 2022
Desk lighting with an Arduino

desk-lighting Dimmable RGB Desk Lighting with an Arduino I made a small project for my own desktop where I used: Arduino Uno A couple of LEDs A potent

Pratham 1 Apr 9, 2022
Callisto - A desk clock that uses a Russian IV-18 VFD tube

Callisto Callisto is a digital clock that uses a Russian IV-18 vacuum fluorescent tube for the display. The clock uses an ESP32 to automatically sync

Hiroto Kaku 18 Jan 10, 2022
This Repository is created to help fellow coders learn open source contributions. This Repository is created for Hacktoberfest 2021

Hacktoberfest 2021 Follow the README below to get started! This Repository is created to help fellow coders learn open source contributions This Repos

Somesh Debnath 6 Aug 11, 2022
A combined suite of utilities for exporting images to retro formats.

ImageTools A combined suite of utilities for exporting images to retro formats. It was developed for use on Windows but might compile on other systems

David Walters 4 Dec 6, 2021
This project contains three scripts to help working with the steam-runtime, especially outside of Steam.

This project contains three scripts to help working with the steam-runtime, especially outside of Steam. See these blog posts for more details: steam-

Jørgen P. Tjernø 12 Sep 27, 2022
This repository contains a collection of 42School cursus projects in addition to the pool/piscine days

This repository contains a collection of 42School cursus projects in addition to the pool/piscine days (with a detailed step by step explanation). Enjoy!

Achraf EL Khnissi 77 Oct 3, 2022
A collection of scripts written in many different programming languages and each developed independently to perform very specific tasks (big or small)

Script Collection A collection of scripts written in many different programming languages and each developed independently to perform very specific ta

Giovanni Rebouças 5 Aug 31, 2021
Collection of scripts and writeups

ctf-writeups Tree 0ctf-quals-2017 EasiestPrintf (pwn 150pts) char (pwn 132pts) diethard (pwn 183pts) pages (pwn 647pts) writeup uploadcenter (pwn 523p

david942j 305 Sep 18, 2022
Just getting started with Data Structure and Algorithms? Make your first contribution here and start the journey of learning DSA.

Getting Started ! ✨ If you are just beginning with open source then let's make your first contribution in this repository ! Contributing Tutorial ?? P

amega 3 Apr 18, 2022
Automatic adds AFIX instructions for hydrogen atoms to SHELX input file based on geometry and residual desity

autoHFIX Adds AFIX instructions for hydrogen atoms to SHELX input files based on geometry and residual desity automatically Usage: autoHFIX.exe [-opti

Christian Hübschle 2 Oct 7, 2021
A program for converting instructions from Ben Eater's 8 Bit computer design to binary.

8Bit-Assembler A program for converting instructions from Ben Eater's 8 Bit computer design to binary. We used C because is used for it's mid-level-ne

Marek Borik 2 Nov 21, 2021
A general solution to simulate execution of virtualized instructions (vmprotect/themida, etc.).

vmp_runner A general solution to simulate execution of virtualized instructions (vmprotect/themida, etc.) based on Unicorn. 一个基于Unicorn模拟执行虚拟化指令(vmpro

kakasasa 48 Sep 23, 2022
collection of C/C++ programs that try to get compilers to exploit undefined behavior

------------------------------------------------------------------------------- UB Canaries: A collection of C/C++ programs that detect undefined beh

John Regehr 160 Sep 2, 2022
A repository to contribute and learn OpenSource

HacktoberFest 2021 ?? An opensource intiative organised by DigitalOcean and Intel SO this is an An Open Source repository to Teach people How to contr

BreadBoard Coding Society 19 Jul 27, 2022