Skip to content

Commit

Permalink
Merge pull request #70 from iMicknl/v2
Browse files Browse the repository at this point in the history
[v2] Initial release - simplify the repository
  • Loading branch information
iMicknl authored Oct 18, 2024
2 parents 546629d + 2ce9bdd commit a2adf7f
Show file tree
Hide file tree
Showing 38 changed files with 1,604 additions and 332 deletions.
32 changes: 32 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/python
{
"name": "Python 3",
"image": "mcr.microsoft.com/devcontainers/python:1-3.11-bookworm",

// Features to add to the dev container. More info: https://containers.dev/features.
// "features": {},

// Use 'forwardPorts' to make a list of ports inside the container available locally.
// "forwardPorts": [],

// Use 'postCreateCommand' to run commands after the container is created.
"postCreateCommand": "pip3 install --user -r requirements.txt && pre-commit install",

// Configure tool-specific properties.
"customizations": {
"vscode": {
"extensions": [
"GitHub.copilot-chat",
"ESPHome.esphome-vscode",
"redhat.vscode-yaml",
"ms-python.python",
"ms-vscode.cpptools",
"ms-vscode.cpptools-extension-pack"
]
}
}

// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
// "remoteUser": "root"
}
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* @iMicknl
13 changes: 13 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
version: 2
updates:
- package-ecosystem: "devcontainers"
directory: "/"
schedule:
interval: daily
time: "08:00"

- package-ecosystem: pip
directory: "/"
schedule:
interval: "daily"
time: "08:00"
3 changes: 3 additions & 0 deletions .github/workflows/build-and-publish.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# uses: esphome/build-action@v1
# with:
# yaml_file: my_configuration.yaml
29 changes: 29 additions & 0 deletions .github/workflows/lint.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: CI

on:
pull_request:
push:
branches: [main]

jobs:
pre-commit:
name: "Linting and formatting"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Set up Python 3.11
uses: actions/setup-python@v5
with:
python-version: "3.11"
cache: "pip"

- name: "Install Python dependencies"
run: |
python -m pip install --upgrade pip
python -m pip install -r requirements.txt
- uses: pre-commit/[email protected]

# - uses: pre-commit-ci/[email protected]
# if: always()
37 changes: 37 additions & 0 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Test ESPHome configuration files using local components
name: Compile and validate YAML configuration

on:
pull_request:
push:
branches: [main]

jobs:
tests:
name: "${{ matrix.version }}"
runs-on: "ubuntu-latest"

strategy:
fail-fast: false
matrix:
version: ["esp32", "esp8266", "esp32-passthrough", "esp8266-passthrough"]

steps:
- uses: "actions/checkout@v4"

- name: Set up Python 3.11
uses: actions/setup-python@v5
with:
python-version: "3.11"
cache: "pip"

- name: "Install Python dependencies"
run: |
python -m pip install --upgrade pip
python -m pip install -r requirements.txt
- name: "Validate ${{ matrix.version }}"
run: esphome config tests/office-desk-${{ matrix.version }}.yaml

- name: "Compile ${{ matrix.version }}"
run: esphome compile tests/office-desk-${{ matrix.version }}.yaml
37 changes: 37 additions & 0 deletions .github/workflows/validate-packages.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Validate ESPHome packages using latest published components
name: Validate ESPHome packages

on:
pull_request:
push:
branches: [main]

jobs:
tests:
name: "${{ matrix.version }}"
runs-on: "ubuntu-latest"

strategy:
fail-fast: false
matrix:
version: ["esp32"]

steps:
- uses: "actions/checkout@v4"

- name: Set up Python 3.11
uses: actions/setup-python@v5
with:
python-version: "3.11"
cache: "pip"

- name: "Install Python dependencies"
run: |
python -m pip install --upgrade pip
python -m pip install -r requirements.txt
- name: "Validate ${{ matrix.version }}"
run: esphome config tests/office-desk-${{ matrix.version }}.yaml

- name: "Compile ${{ matrix.version }}"
run: esphome compile tests/office-desk-${{ matrix.version }}.yaml
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
venv
.esphome
.esphome

*.pyc
__pycache__/
21 changes: 21 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.6.0
hooks:
- id: check-yaml
args: ['--unsafe'] # required for !secret
- id: trailing-whitespace
- id: end-of-file-fixer

# - repo: https://github.com/pocc/pre-commit-hooks
# rev: v1.3.5
# hooks:
# - id: clang-format
# - id: clang-tidy
# - id: cppcheck
# - id: cpplint
- repo: https://github.com/pre-commit/mirrors-clang-format
rev: v18.1.6
hooks:
- id: clang-format
types_or: [c++, c, cuda]
101 changes: 57 additions & 44 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ This repository will help you to connect your desk to the internet via the seria

> Use the information in this repository at your own risk and with caution. Tinkering with electronics always has risks.
| Name | Description |
| ------------------------------------- | -------------------------------------------------------------------------- |
| [Arduino](packages/arduino) | Custom code to control your desk via an ESP32/ESP8266 module via MQTT. |
| [ESPHome](packages/esphome) | Control your desk via an ESP32/ESP8266 module connected to Home Assistant. |
| [Raspberry Pi](packages/raspberry-pi) | Custom code to control your desk via a Raspberry Pi via Python. |
| Name | Description |
| ------------------------------------ | -------------------------------------------------------------------------------------------------------------------- |
| [ESPHome](packages/office-desk.yaml) | Control your desk via an ESP32 module connected to Home Assistant. Can be adapted to ESP8266 or other ESP32 variant. |

The V1 packages, including the Arduino and Raspberry Pi ones, can be found in the `archive` directory.

For more packaged solutions, see [similar projects](#similar-projects--research). Pull requests are welcome.

Expand All @@ -30,10 +30,15 @@ If you are interested in the internals of the LoctecMotion desk system, have a l

At the time of writing, LoctekMotion sells [11 different control panels](https://www.loctekmotion.com/product/control-panel/). 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;
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](images/RJ-45_connector.jpg)

The most common [color convention](https://www.showmecables.com/blog/post/rj45-pinout)
for wiring RJ45 for network cables is:

![RJ45 T568B colors](images/RJ45-Pinout-T568B.jpg)

In order to connect the control box to a Raspberry Pi and ESP32/ESP8266 chip I used a [RJ45 to RS232 adapter](https://www.allekabels.nl/rs232-kabel/4568/1041186/rj45-naar-rs232.html) with DuPont cables (jump wires), but you simply can cut and split an ethernet cable as well.

#### Supported Control Panels
Expand All @@ -49,70 +54,73 @@ In order to connect the control box to a Raspberry Pi and ESP32/ESP8266 chip I u
<!-- markdownlint-enable -->
<!-- prettier-ignore-end -->

If your control panel is missing, feel free to [create an issue](https://github.com/iMicknl/LoctekMotion_IoT/issues/new) to discuss the possibilities or create a PR to add your research to this overview.
If your control panel is missing, feel free to [create an issue](https://github.com/iMicknl/LoctekMotion_IoT/issues/new) to discuss the possibilities or create a PR to add your research to this overview.

#### HS13B-1

- **Desk model**: Flexispot E7
- **Tested with control box**: CB38M2J(IB)-1
- **Source**: Printed on the PCB of the control box.

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

Note that RX and TX is defined like this on receiver (control panel) side. So RX can be used to receive data, TX to send data.
| 1 | RESET | Brown | White-Orange |
| 2 | SWIM | White | Orange |
| 3 | EMPTY | Purple | White-Green |
| 4 | PIN 20 | Red | Blue |
| 5 | RX | Green | White-Blue |
| 6 | TX | Black | Green |
| 7 | GND | Blue | White-Brown |
| 8 | +5V (VDD) | Yellow | Brown |

Note that RX and TX is defined like this on receiver (control panel) side.
So the custom controller also uses RX to receive data and TX to send data.

#### 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 | Original Cable Color | Ethernet cable color (T568B) |
| -------- | ---------- | -------------------- | ---------------------------- |
| 8 | RESET SWIM | Brown | White-Orange |
| 7 | PIN 20 | White | Orange |
| 6 | RX | Purple | White-Green |
| 5 | TX | Red | Blue |
| 4 | GND1 | Green | White-Blue |
| 3 | +5V (VDD) | Black | Green |
| 2 | 29V+ | Blue | White-Brown |
| 1 | 29V- | Yellow | Brown |

Note that RX and TX is defined like this on receiver (control panel) side. So RX can be used to receive data, TX to send data.
| 1 | RESET SWIM | Brown | White-Orange |
| 2 | PIN 20 | White | Orange |
| 3 | RX | Purple | White-Green |
| 4 | TX | Red | Blue |
| 5 | GND1 | Green | White-Blue |
| 6 | +5V (VDD) | Black | Green |
| 7 | 29V+ | Blue | White-Brown |
| 8 | 29V- | Yellow | Brown |

Note that RX and TX is defined like this on receiver (control panel) side.
So the custom controller also uses RX to receive data and TX to send data.

#### HS01B-1

- **Desk model**: Flexispot E5B
- **Tested with control box**: CB38M2A-1
- **Source**: [nv1t/standing-desk-interceptor](https://github.com/nv1t/standing-desk-interceptor)

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

Note that RX and TX is defined like this on receiver (control panel) side. So RX can be used to receive data, TX to send data.

| RJ45 pin | Name |
| -------- | --------- |
| 8 | +5V (VDD) |
| 7 | GND |
| 6 | TX |
| 5 | RX |
| 4 | PIN 20 |
| 3 | (unknown) |
| 2 | SWIM |
| 1 | RES |

Note that RX and TX is defined like this on receiver (control panel) side.
So the custom controller also uses RX to receive data and TX to send data.

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](https://www.mikrocontroller.net/topic/493524), it became clear that the control panel utilises a [7-segment display](https://en.wikipedia.org/wiki/Seven-segment_display). Fortunately, this is very common in such devices and thus there is a lot of [documentation](https://lastminuteengineers.com/seven-segment-arduino-tutorial/) on this topic.
Based upon the great work of [minifloat](https://www.mikrocontroller.net/topic/493524), it became clear that the control panel utilises a [7-segment display](https://en.wikipedia.org/wiki/Seven-segment_display). Fortunately, this is very common in such devices and thus there is a lot of [documentation](https://lastminuteengineers.com/seven-segment-arduino-tutorial/) 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").

Expand All @@ -122,6 +130,11 @@ Make sure you set the baud rate to 9600. For most LoctekMotion desks, the contro

source: [alselectro](https://alselectro.wordpress.com/2015/03/03/8051-tutorials-3-interfacing-7-segment-display/)


### Known issues
- Number entity may overshoot. For more accurate positioning, use the provided presets.


### Execute a command

The control box only accepts commands when the 'screen is active'. To activate the screen, `PIN 20` needs to be set to HIGH for about 1 second. The screen gets disabled automatically again after some amount of time receiving no commands.
Expand All @@ -146,7 +159,7 @@ All bytes combined will become the command to send to the control box. See the [
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. ❤️

- [grssmnn / ha-flexispot-standing-desk](https://github.com/grssmnn/ha-flexispot-standing-desk) - Home Assistant integration via MQTT (micropython)
- [Dude88 / loctek_IOT_box](https://github.com/Dude88/loctek_IOT_box) - Arduino code to control via Alexa and MQTT
- [Dude88 / loctek_IOT_box](https://github.com/Dude88/loctek_IOT_box) - Arduino code to control via Alexa and MQTT
- [nv1t / standing-desk-interceptor](https://github.com/nv1t/standing-desk-interceptor) - Research on intercepting commands from Flexispot desks
- [VinzSpring / LoctekReverseengineering](https://github.com/VinzSpring/LoctekReverseengineering#assumptions) - Research and Python samples

Expand Down
File renamed without changes.
Loading

0 comments on commit a2adf7f

Please sign in to comment.