This project uses a KY-040 rotary encoder and an ESP32 to measure the rotation steps of a garage motor shaft.
By counting the steps, the system calculates the garage door position in percent (0–100%).
It is designed to work with ESPHome and Home Assistant.
- ✅ ESP32 Dev Board
- ✅ KY-040 Rotary Encoder
- ✅ 3D printed mounting parts (from
/STLsfolder)Hörmann_Ritzel_Rev.D_Final.stlHörmann_Halter_RevD_Final.stl
Print the files from the STLs folder:
- Hörmann_Ritzel_Rev.D_Final.stl → Gear for the motor shaft
- Hörmann_Halter_RevD_Final.stl → Mounting bracket for the encoder
Mount the KY-040 encoder so it rotates together with the garage motor shaft.
| KY-040 Pin | ESP32 Pin |
|---|---|
| CLK (A) | GPIO16 |
| DT (B) | GPIO17 |
| + | 3.3V |
| GND | GND |
- Copy the YAML file from the
/YAMLsfolder. - Adjust:
- WiFi credentials
- Static IP settings (
CHANGE_ME) - Secrets in
secrets.yaml
- Upload to ESP32 via ESPHome.
The rotary encoder:
- Counts from 0 to 1000 steps
- Has debounce filtering
- Publishes values to Home Assistant
You can reset the counter using the Home Assistant service:
esphome.garage_rotary_reset_rotary
This is where the percentage calculation happens.
Create an Input Number Helper:
- Name:
maximale_Inkrementzahl_Garage - Min:
0 - Max:
1000 - Step:
1
This represents the maximum number of steps when the garage is fully open.
Add this template sensor:
{% set value = (float(states('sensor.garage_rotary_garagerotary')) * (1 / float(states('input_number.maximale_inkrementzahl_garage')))) * 100 %}
{% if value > 100 %}
100
{% elif value < 0 %}
0
{% else %}
{{ value | round(2) }}
{% endif %}Name it:
Position Garage in Prozent
This converts the rotary steps into a 0–100% position value.
To ensure the rotary encoder always stays synchronized with the real garage door position, an automation is used.
When the garage door reports closed, the rotary counter is automatically reset to 0.
Example automation:
alias: Reset Garage Rotary when Door Closes
description: Resets the rotary encoder to 0 when the garage door closes
triggers:
- entity_id: binary_sensor.garagentor_zustand_input
to: "off"
trigger: state
conditions: []
actions:
- data: {}
action: esphome.garage_rotary_reset_rotary
mode: single- When the garage door state changes to closed
- Home Assistant calls:
esphome.garage_rotary_reset_rotary
- The ESP32 sets the rotary encoder value to 0
This ensures:
- No long-term drift
- Clean recalibration after every full close
- Reliable percentage calculation
- Garage door moves
- Motor shaft rotates
- KY-040 counts steps
- ESP32 sends step value to Home Assistant
- If door closes → automation resets steps to
0 - Template sensor converts steps → percentage
- Ensure the door is fully closed (automation resets value to
0). - Fully open the garage.
- Note the maximum step value.
- Enter that value into:
maximale_Inkrementzahl_Garage
Now the percentage sensor will show the correct position.
Because the counter resets automatically when the door closes, recalibration is rarely needed.
- Live position in %
- ESP web interface enabled
- OTA updates
- WiFi signal monitoring
- Debug sensors
- Manual reset service
- Use 3.3V only for the KY-040.
- Ensure the encoder is mounted without slipping.
- Adjust
max_valuein YAML if your garage requires more than 1000 steps. - Static IP is recommended.
/STLs → 3D print files
/YAMLs → ESPHome configuration
README.md → This file
Free to use and modify.