← - Lambda-Beispiele | Inhaltsverzeichnis | Weiter: - Lambda FAQ & Fehlerbehebung →
ESPHome-Integration — Lambda-Referenz
Vollständige Referenz für die Arbeit mit DimmerLink über ESPHome Lambda.
Inhaltsverzeichnis
- 4.1 I2C-Grundlagen in ESPHome
- 4.2 Steuerungsregister (0x00-0x0F)
- 4.3 Dimmer-Register (0x10-0x1F)
- 4.4 Systemregister (0x20-0x2F)
- 4.5 Konfigurationsregister (0x30-0x3F)
- 4.6 Referenztabellen
4.1 I2C-Grundlagen in ESPHome
I2C-Bus-Konfiguration
i2c:
sda: GPIO21
scl: GPIO22
scan: true
frequency: 100kHz
id: bus_a
| Parameter | Beschreibung | Empfehlung |
|---|---|---|
sda |
Daten-Pin | GPIO21 (ESP32-Standard) |
scl |
Takt-Pin | GPIO22 (ESP32-Standard) |
scan |
Bus beim Start scannen | true zum Debuggen |
frequency |
Bus-Frequenz | 100kHz (DimmerLink Standard Mode) |
id |
Bus-Kennung | Erforderlich für Lambda |
Konstanten und Geräteadresse
substitutions:
# DimmerLink I2C address (default)
dimmerlink_addr: "0x50"
Zur Verwendung in Lambda:
// Device address
const uint8_t DIMMERLINK_ADDR = 0x50;
Grundlegende I2C-Operationen
In ein Register schreiben
// Template: write a single byte to a register
uint8_t reg = 0x10; // Register address
uint8_t value = 50; // Value to write
uint8_t data[2] = {reg, value};
id(bus_a).write(DIMMERLINK_ADDR, data, 2, true);
write() Parameters:
- address — I2C device address
- data — pointer to data
- length — number of bytes
- stop — send STOP condition (true usually)
Aus einem Register lesen
// Template: read a single byte from a register
uint8_t reg = 0x10;
uint8_t value = 0;
// 1. Send register address (without STOP)
auto err = id(bus_a).write(DIMMERLINK_ADDR, ®, 1, false);
if (err != i2c::ERROR_OK) {
ESP_LOGW("dimmerlink", "Write error: %d", err);
return {}; // or error handling
}
// 2. Read data
err = id(bus_a).read(DIMMERLINK_ADDR, &value, 1);
if (err != i2c::ERROR_OK) {
ESP_LOGW("dimmerlink", "Read error: %d", err);
return {};
}
// value now contains the read value
Mehrere Bytes lesen
// Reading 2 bytes (e.g., 16-bit value)
uint8_t reg = 0x21;
uint8_t buffer[2] = {0, 0};
id(bus_a).write(DIMMERLINK_ADDR, ®, 1, false);
id(bus_a).read(DIMMERLINK_ADDR, buffer, 2);
uint16_t value = (buffer[1] << 8) | buffer[0]; // Little-endian
Fehlerbehandlung
#include "esphome/components/i2c/i2c.h"
// ESPHome I2C error codes
// i2c::ERROR_OK = 0 — success
// i2c::ERROR_TIMEOUT = 1 — timeout
// i2c::ERROR_NOT_ACKNOWLEDGED = 2 — NACK
// i2c::ERROR_DATA_TOO_LARGE = 3 — too much data
// i2c::ERROR_UNKNOWN = 4 — unknown error
auto err = id(bus_a).write(DIMMERLINK_ADDR, data, 2, true);
if (err == i2c::ERROR_OK) {
ESP_LOGD("dimmerlink", "Success");
} else if (err == i2c::ERROR_NOT_ACKNOWLEDGED) {
ESP_LOGW("dimmerlink", "Device not responding (NACK)");
} else {
ESP_LOGE("dimmerlink", "I2C error: %d", err);
}
Protokollierung
// ESPHome logging levels
ESP_LOGV("tag", "Verbose: %d", value); // Very detailed
ESP_LOGD("tag", "Debug: %d", value); // Debug
ESP_LOGI("tag", "Info: %d", value); // Information
ESP_LOGW("tag", "Warning: %d", value); // Warning
ESP_LOGE("tag", "Error: %d", value); // Error
Hilfsfunktionen (Global)
Für mehr Komfort können Sie Hilfsfunktionen definieren:
esphome:
includes:
- dimmerlink_helpers.h
Datei dimmerlink_helpers.h (im Konfigurationsordner):
#pragma once
#include "esphome.h"
namespace dimmerlink {
const uint8_t ADDR = 0x50;
// Registers
namespace reg {
const uint8_t STATUS = 0x00;
const uint8_t COMMAND = 0x01;
const uint8_t ERROR = 0x02;
const uint8_t VERSION = 0x03;
const uint8_t DIM0_LEVEL = 0x10;
const uint8_t DIM0_CURVE = 0x11;
const uint8_t AC_FREQ = 0x20;
const uint8_t AC_PERIOD_L = 0x21;
const uint8_t AC_PERIOD_H = 0x22;
const uint8_t CALIBRATION = 0x23;
const uint8_t I2C_ADDRESS = 0x30;
}
// Commands
namespace cmd {
const uint8_t NOP = 0x00;
const uint8_t RESET = 0x01;
const uint8_t RECALIBRATE = 0x02;
const uint8_t SWITCH_UART = 0x03;
}
// Curves
namespace curve {
const uint8_t LINEAR = 0;
const uint8_t RMS = 1;
const uint8_t LOG = 2;
}
// DimmerLink errors
namespace error {
const uint8_t OK = 0x00;
const uint8_t SYNTAX = 0xF9;
const uint8_t NOT_READY = 0xFC;
const uint8_t INDEX = 0xFD;
const uint8_t PARAM = 0xFE;
}
} // namespace dimmerlink
Verwendung in Lambda:
uint8_t data[2] = {dimmerlink::reg::DIM0_LEVEL, 50};
id(bus_a).write(dimmerlink::ADDR, data, 2, true);
4.2 Steuerungsregister (0x00-0x0F)
Gerätesteuerung und Statusregister.
STATUS (0x00) — Gerätestatus
| Parameter | Wert |
|---|---|
| Adresse | 0x00 |
| Zugriff | Nur Lesen |
| Größe | 1 Byte |
Bitstruktur:
| Bit | Name | Beschreibung |
|---|---|---|
| 0 | READY | 1 = Gerät bereit (Kalibrierung abgeschlossen) |
| 1 | ERROR | 1 = Letzte Operation mit Fehler beendet |
| 2-7 | — | Reserviert |
Lambda — Status lesen:
// Read full status byte
uint8_t reg = 0x00;
uint8_t status = 0;
if (id(bus_a).write(0x50, ®, 1, false) == i2c::ERROR_OK) {
if (id(bus_a).read(0x50, &status, 1) == i2c::ERROR_OK) {
bool ready = status & 0x01;
bool error = status & 0x02;
ESP_LOGI("dimmerlink", "Status: ready=%d, error=%d", ready, error);
}
}
ESPHome-Entität — Binary Sensor:
binary_sensor:
# Device ready status
- platform: template
name: "DimmerLink Ready"
id: dimmerlink_ready
icon: "mdi:check-circle"
entity_category: "diagnostic"
lambda: |-
uint8_t reg = 0x00;
uint8_t status = 0;
if (id(bus_a).write(0x50, ®, 1, false) == i2c::ERROR_OK) {
if (id(bus_a).read(0x50, &status, 1) == i2c::ERROR_OK) {
return (status & 0x01) != 0;
}
}
return {};
# Error flag
- platform: template
name: "DimmerLink Error Flag"
id: dimmerlink_error_flag
icon: "mdi:alert-circle"
entity_category: "diagnostic"
device_class: problem
lambda: |-
uint8_t reg = 0x00;
uint8_t status = 0;
if (id(bus_a).write(0x50, ®, 1, false) == i2c::ERROR_OK) {
if (id(bus_a).read(0x50, &status, 1) == i2c::ERROR_OK) {
return (status & 0x02) != 0;
}
}
return {};
COMMAND (0x01) — Steuerbefehle
| Parameter | Wert |
|---|---|
| Adresse | 0x01 |
| Zugriff | Nur Schreiben |
| Größe | 1 Byte |
Verfügbare Befehle:
| Wert | Befehl | Beschreibung | Ausführungszeit |
|---|---|---|---|
0x00 |
NOP | Keine Operation | — |
0x01 |
RESET | Software-Reset | ~3 Sek. (Neustart) |
0x02 |
RECALIBRATE | AC-Frequenz neu kalibrieren | ~200 ms |
0x03 |
SWITCH_UART | In UART-Modus wechseln | Sofort |
Lambda — Befehl senden:
// General command sending template
void send_command(uint8_t cmd) {
uint8_t data[2] = {0x01, cmd};
id(bus_a).write(0x50, data, 2, true);
}
// RESET — software reset
uint8_t data[2] = {0x01, 0x01};
id(bus_a).write(0x50, data, 2, true);
ESP_LOGW("dimmerlink", "Reset command sent, device will reboot");
// RECALIBRATE — frequency recalibration
uint8_t data[2] = {0x01, 0x02};
id(bus_a).write(0x50, data, 2, true);
ESP_LOGI("dimmerlink", "Recalibration started");
// SWITCH_UART — switch to UART
// After this command I2C no longer works!
uint8_t data[2] = {0x01, 0x03};
id(bus_a).write(0x50, data, 2, true);
ESP_LOGW("dimmerlink", "Switched to UART mode, I2C disabled");
ESPHome-Entität — Button:
button:
# Software reset
- platform: template
name: "DimmerLink Reset"
id: dimmerlink_reset
icon: "mdi:restart"
entity_category: "config"
on_press:
- lambda: |-
uint8_t data[2] = {0x01, 0x01};
id(bus_a).write(0x50, data, 2, true);
ESP_LOGW("dimmerlink", "Reset command sent");
- delay: 3s
- logger.log:
level: INFO
format: "DimmerLink should be back online"
# Recalibration
- platform: template
name: "DimmerLink Recalibrate"
id: dimmerlink_recalibrate
icon: "mdi:refresh"
entity_category: "config"
on_press:
- lambda: |-
uint8_t data[2] = {0x01, 0x02};
id(bus_a).write(0x50, data, 2, true);
ESP_LOGI("dimmerlink", "Recalibration started");
- delay: 500ms
- component.update: ac_frequency
ERROR (0x02) — Letzter Fehlercode
| Parameter | Wert |
|---|---|
| Adresse | 0x02 |
| Zugriff | Nur Lesen |
| Größe | 1 Byte |
Fehlercodes:
| Code | Name | Beschreibung |
|---|---|---|
0x00 |
OK | Kein Fehler |
0xF9 |
ERR_SYNTAX | Ungültige Registeradresse |
0xFC |
ERR_NOT_READY | Gerät nicht bereit (nicht kalibriert oder FLASH-Fehler) |
0xFD |
ERR_INDEX | Ungültiger Dimmer-Index |
0xFE |
ERR_PARAM | Ungültiger Parameterwert |
Lambda — Fehler lesen:
uint8_t reg = 0x02;
uint8_t error_code = 0;
if (id(bus_a).write(0x50, ®, 1, false) == i2c::ERROR_OK) {
if (id(bus_a).read(0x50, &error_code, 1) == i2c::ERROR_OK) {
switch (error_code) {
case 0x00: ESP_LOGD("dimmerlink", "No error"); break;
case 0xF9: ESP_LOGW("dimmerlink", "ERR_SYNTAX"); break;
case 0xFC: ESP_LOGW("dimmerlink", "ERR_NOT_READY"); break;
case 0xFD: ESP_LOGW("dimmerlink", "ERR_INDEX"); break;
case 0xFE: ESP_LOGW("dimmerlink", "ERR_PARAM"); break;
default: ESP_LOGE("dimmerlink", "Unknown error: 0x%02X", error_code);
}
}
}
ESPHome-Entität — Text Sensor:
text_sensor:
- platform: template
name: "DimmerLink Last Error"
id: dimmerlink_last_error
icon: "mdi:alert"
entity_category: "diagnostic"
update_interval: 10s
lambda: |-
uint8_t reg = 0x02;
uint8_t error_code = 0;
if (id(bus_a).write(0x50, ®, 1, false) != i2c::ERROR_OK) {
return {"I2C Error"};
}
if (id(bus_a).read(0x50, &error_code, 1) != i2c::ERROR_OK) {
return {"Read Error"};
}
switch (error_code) {
case 0x00: return {"OK"};
case 0xF9: return {"ERR_SYNTAX"};
case 0xFC: return {"ERR_NOT_READY"};
case 0xFD: return {"ERR_INDEX"};
case 0xFE: return {"ERR_PARAM"};
default: return {"UNKNOWN (0x" + format_hex_pretty(&error_code, 1) + ")"};
}
ESPHome-Entität — Sensor (numerischer Code):
sensor:
- platform: template
name: "DimmerLink Error Code"
id: dimmerlink_error_code
icon: "mdi:alert-octagon"
entity_category: "diagnostic"
accuracy_decimals: 0
update_interval: 10s
lambda: |-
uint8_t reg = 0x02;
uint8_t error_code = 0;
if (id(bus_a).write(0x50, ®, 1, false) == i2c::ERROR_OK) {
if (id(bus_a).read(0x50, &error_code, 1) == i2c::ERROR_OK) {
return (float)error_code;
}
}
return {};
VERSION (0x03) — Firmware-Version
| Parameter | Wert |
|---|---|
| Adresse | 0x03 |
| Zugriff | Nur Lesen |
| Größe | 1 Byte |
Version Format:
- 0x01 = v1.0
- 0x02 = v2.0
- 0x10 = v1.0 (alternative format, if major.minor)
Lambda — Version lesen:
uint8_t reg = 0x03;
uint8_t version = 0;
if (id(bus_a).write(0x50, ®, 1, false) == i2c::ERROR_OK) {
if (id(bus_a).read(0x50, &version, 1) == i2c::ERROR_OK) {
ESP_LOGI("dimmerlink", "Firmware version: %d", version);
}
}
ESPHome-Entität — Sensor:
sensor:
- platform: template
name: "DimmerLink Firmware Version"
id: dimmerlink_version
icon: "mdi:chip"
entity_category: "diagnostic"
accuracy_decimals: 0
update_interval: never # Read once on startup
lambda: |-
uint8_t reg = 0x03;
uint8_t version = 0;
if (id(bus_a).write(0x50, ®, 1, false) == i2c::ERROR_OK) {
if (id(bus_a).read(0x50, &version, 1) == i2c::ERROR_OK) {
return (float)version;
}
}
return {};
# Read on startup
esphome:
on_boot:
priority: -100
then:
- component.update: dimmerlink_version
4.3 Dimmer-Register (0x10-0x1F)
Register zur Steuerung der Dimmer-Kanäle.
DIM0_LEVEL (0x10) — Helligkeitsstufe
| Parameter | Wert |
|---|---|
| Adresse | 0x10 |
| Zugriff | Lesen/Schreiben |
| Größe | 1 Byte |
| Bereich | 0-100 (%) |
Values:
- 0 — off (TRIAC does not open)
- 1-99 — dimming (phase-cut)
- 100 — full brightness (minimum delay)
Lambda — Stufe schreiben:
// Set brightness 0-100%
uint8_t level = 50; // 50%
if (level > 100) level = 100; // Overflow protection
uint8_t data[2] = {0x10, level};
auto err = id(bus_a).write(0x50, data, 2, true);
if (err == i2c::ERROR_OK) {
ESP_LOGD("dimmerlink", "Level set to %d%%", level);
} else {
ESP_LOGW("dimmerlink", "Failed to set level: %d", err);
}
Lambda — Stufe lesen:
uint8_t reg = 0x10;
uint8_t level = 0;
if (id(bus_a).write(0x50, ®, 1, false) == i2c::ERROR_OK) {
if (id(bus_a).read(0x50, &level, 1) == i2c::ERROR_OK) {
ESP_LOGD("dimmerlink", "Current level: %d%%", level);
return (float)level;
}
}
return {}; // Error
ESPHome-Entität — Output (Basis für Light):
output:
- platform: template
id: dimmerlink_output
type: float
write_action:
- lambda: |-
// state: 0.0 - 1.0, convert to 0-100
uint8_t level = (uint8_t)(state * 100.0f);
if (level > 100) level = 100;
uint8_t data[2] = {0x10, level};
auto err = id(bus_a).write(0x50, data, 2, true);
if (err == i2c::ERROR_OK) {
ESP_LOGD("dimmerlink", "Set level: %d%%", level);
} else {
ESP_LOGW("dimmerlink", "Write error: %d", err);
}
ESPHome-Entität — Light:
light:
- platform: monochromatic
name: "Dimmer"
id: dimmer_light
output: dimmerlink_output
default_transition_length: 1s
gamma_correct: 1.0 # DimmerLink has its own curves
ESPHome-Entität — Number (direkte Steuerung):
number:
- platform: template
name: "Dimmer Level"
id: dimmer_level_number
icon: "mdi:brightness-percent"
unit_of_measurement: "%"
min_value: 0
max_value: 100
step: 1
optimistic: true
set_action:
- lambda: |-
uint8_t level = (uint8_t)x;
uint8_t data[2] = {0x10, level};
id(bus_a).write(0x50, data, 2, true);
ESP_LOGI("dimmerlink", "Level set to %d%%", level);
ESPHome-Entität — Sensor (Rücklesen):
sensor:
- platform: template
name: "Dimmer Level Readback"
id: dimmer_level_sensor
icon: "mdi:brightness-percent"
unit_of_measurement: "%"
accuracy_decimals: 0
update_interval: 5s
lambda: |-
uint8_t reg = 0x10;
uint8_t level = 0;
if (id(bus_a).write(0x50, ®, 1, false) == i2c::ERROR_OK) {
if (id(bus_a).read(0x50, &level, 1) == i2c::ERROR_OK) {
return (float)level;
}
}
return {};
DIM0_CURVE (0x11) — Dimmkurve
| Parameter | Wert |
|---|---|
| Adresse | 0x11 |
| Zugriff | Lesen/Schreiben |
| Größe | 1 Byte |
| Bereich | 0-2 |
Kurventypen:
| Wert | Name | Beschreibung | Anwendung |
|---|---|---|---|
0 |
LINEAR | Lineare Abhängigkeit | Universell |
1 |
RMS | Quadratisch (RMS) | Glühlampen, Halogen |
2 |
LOG | Logarithmisch | LED (entspricht der Augenwahrnehmung) |
Lambda — Kurve setzen:
// Set curve
// 0 = LINEAR, 1 = RMS, 2 = LOG
uint8_t curve = 1; // RMS
if (curve > 2) {
ESP_LOGW("dimmerlink", "Invalid curve: %d", curve);
return;
}
uint8_t data[2] = {0x11, curve};
id(bus_a).write(0x50, data, 2, true);
ESP_LOGI("dimmerlink", "Curve set to %d", curve);
Lambda — Kurve lesen:
uint8_t reg = 0x11;
uint8_t curve = 0;
if (id(bus_a).write(0x50, ®, 1, false) == i2c::ERROR_OK) {
if (id(bus_a).read(0x50, &curve, 1) == i2c::ERROR_OK) {
const char* names[] = {"LINEAR", "RMS", "LOG"};
if (curve <= 2) {
ESP_LOGI("dimmerlink", "Current curve: %s", names[curve]);
}
return (float)curve;
}
}
return {};
ESPHome-Entität — Select:
select:
- platform: template
name: "Dimming Curve"
id: dimming_curve
icon: "mdi:chart-bell-curve"
options:
- "LINEAR"
- "RMS"
- "LOG"
initial_option: "LINEAR"
optimistic: true
set_action:
- lambda: |-
uint8_t curve = 0;
if (x == "RMS") curve = 1;
else if (x == "LOG") curve = 2;
uint8_t data[2] = {0x11, curve};
id(bus_a).write(0x50, data, 2, true);
ESP_LOGI("dimmerlink", "Curve set to: %s (%d)", x.c_str(), curve);
# Read current curve on startup
esphome:
on_boot:
priority: -100
then:
- lambda: |-
uint8_t reg = 0x11;
uint8_t curve = 0;
if (id(bus_a).write(0x50, ®, 1, false) == i2c::ERROR_OK) {
if (id(bus_a).read(0x50, &curve, 1) == i2c::ERROR_OK) {
auto call = id(dimming_curve).make_call();
switch (curve) {
case 0: call.set_option("LINEAR"); break;
case 1: call.set_option("RMS"); break;
case 2: call.set_option("LOG"); break;
}
call.perform();
}
}
ESPHome-Entität — Sensor (numerischer Wert):
sensor:
- platform: template
name: "Dimming Curve Value"
id: dimming_curve_value
icon: "mdi:chart-bell-curve"
entity_category: "diagnostic"
accuracy_decimals: 0
update_interval: 60s
lambda: |-
uint8_t reg = 0x11;
uint8_t curve = 0;
if (id(bus_a).write(0x50, ®, 1, false) == i2c::ERROR_OK) {
if (id(bus_a).read(0x50, &curve, 1) == i2c::ERROR_OK) {
return (float)curve;
}
}
return {};
Reservierte Register (0x12-0x1F)
| Adresse | Name | Beschreibung |
|---|---|---|
0x12 |
DIM1_LEVEL | Kanal 1 — reserviert |
0x13 |
DIM1_CURVE | Kanal 1 — reserviert |
0x14 |
DIM2_LEVEL | Kanal 2 — reserviert |
0x15 |
DIM2_CURVE | Kanal 2 — reserviert |
0x16 |
DIM3_LEVEL | Kanal 3 — reserviert |
0x17 |
DIM3_CURVE | Kanal 3 — reserviert |
0x18-0x1F |
— | Reserviert |
4.4 Systemregister (0x20-0x2F)
Systeminformationen und Kalibrierungsparameter.
AC_FREQ (0x20) — AC-Frequenz
| Parameter | Wert |
|---|---|
| Adresse | 0x20 |
| Zugriff | Nur Lesen |
| Größe | 1 Byte |
| Werte | 50 oder 60 (Hz) |
Lambda — Frequenz lesen:
uint8_t reg = 0x20;
uint8_t freq = 0;
if (id(bus_a).write(0x50, ®, 1, false) == i2c::ERROR_OK) {
if (id(bus_a).read(0x50, &freq, 1) == i2c::ERROR_OK) {
if (freq == 50 || freq == 60) {
ESP_LOGI("dimmerlink", "AC Frequency: %d Hz", freq);
return (float)freq;
} else {
ESP_LOGW("dimmerlink", "Invalid frequency: %d", freq);
}
}
}
return {};
ESPHome-Entität — Sensor:
sensor:
- platform: template
name: "AC Frequency"
id: ac_frequency
icon: "mdi:sine-wave"
unit_of_measurement: "Hz"
accuracy_decimals: 0
device_class: frequency
state_class: measurement
update_interval: 60s
lambda: |-
uint8_t reg = 0x20;
uint8_t freq = 0;
if (id(bus_a).write(0x50, ®, 1, false) == i2c::ERROR_OK) {
if (id(bus_a).read(0x50, &freq, 1) == i2c::ERROR_OK) {
if (freq == 50 || freq == 60) {
return (float)freq;
}
}
}
return {};
AC_PERIOD_L / AC_PERIOD_H (0x21-0x22) — Halbwellenperiode
| Parameter | Wert |
|---|---|
| Adresse | 0x21 (L), 0x22 (H) |
| Zugriff | Nur Lesen |
| Größe | 2 Bytes (16 Bit) |
| Einheiten | Mikrosekunden (µs) |
Expected Values:
- 50 Hz: ~10000 us (9000-11000)
- 60 Hz: ~8333 us (7500-9000)
Lambda — Periode lesen:
uint8_t reg = 0x21;
uint8_t buffer[2] = {0, 0};
if (id(bus_a).write(0x50, ®, 1, false) == i2c::ERROR_OK) {
if (id(bus_a).read(0x50, buffer, 2) == i2c::ERROR_OK) {
uint16_t period_us = (buffer[1] << 8) | buffer[0]; // Little-endian
ESP_LOGI("dimmerlink", "AC Half-period: %d us", period_us);
return (float)period_us;
}
}
return {};
ESPHome-Entität — Sensor:
sensor:
- platform: template
name: "AC Half-Period"
id: ac_period
icon: "mdi:timer-outline"
unit_of_measurement: "us"
accuracy_decimals: 0
entity_category: "diagnostic"
update_interval: 60s
lambda: |-
uint8_t reg = 0x21;
uint8_t buffer[2] = {0, 0};
if (id(bus_a).write(0x50, ®, 1, false) == i2c::ERROR_OK) {
if (id(bus_a).read(0x50, buffer, 2) == i2c::ERROR_OK) {
uint16_t period = (buffer[1] << 8) | buffer[0];
return (float)period;
}
}
return {};
CALIBRATION (0x23) — Kalibrierungsstatus
| Parameter | Wert |
|---|---|
| Adresse | 0x23 |
| Zugriff | Nur Lesen |
| Größe | 1 Byte |
Values:
- 0 — Calibration in progress
- 1 — Calibration complete
Lambda — Kalibrierung prüfen:
uint8_t reg = 0x23;
uint8_t cal_status = 0;
if (id(bus_a).write(0x50, ®, 1, false) == i2c::ERROR_OK) {
if (id(bus_a).read(0x50, &cal_status, 1) == i2c::ERROR_OK) {
bool calibrated = (cal_status == 1);
ESP_LOGI("dimmerlink", "Calibration: %s", calibrated ? "done" : "in progress");
return calibrated;
}
}
return {};
ESPHome-Entität — Binary Sensor:
binary_sensor:
- platform: template
name: "DimmerLink Calibrated"
id: dimmerlink_calibrated
icon: "mdi:tune"
entity_category: "diagnostic"
lambda: |-
uint8_t reg = 0x23;
uint8_t status = 0;
if (id(bus_a).write(0x50, ®, 1, false) == i2c::ERROR_OK) {
if (id(bus_a).read(0x50, &status, 1) == i2c::ERROR_OK) {
return status == 1;
}
}
return {};
4.5 Konfigurationsregister (0x30-0x3F)
Gerätekonfigurationsregister.
I2C_ADDRESS (0x30) — I2C-Geräteadresse
| Parameter | Wert |
|---|---|
| Adresse | 0x30 |
| Zugriff | Lesen/Schreiben |
| Größe | 1 Byte |
| Bereich | 0x08-0x77 |
| Standard | 0x50 |
Prohibited Addresses:
- 0x00-0x07 — reserved by I2C
- 0x78-0x7F — reserved by I2C
Lambda — aktuelle Adresse lesen:
// Assuming the address is known (default 0x50)
uint8_t current_addr = 0x50;
uint8_t reg = 0x30;
uint8_t addr = 0;
if (id(bus_a).write(current_addr, ®, 1, false) == i2c::ERROR_OK) {
if (id(bus_a).read(current_addr, &addr, 1) == i2c::ERROR_OK) {
ESP_LOGI("dimmerlink", "Current I2C address: 0x%02X", addr);
}
}
Lambda — Adresse ändern:
// After this operation the device will only respond at the new address!
uint8_t old_addr = 0x50;
uint8_t new_addr = 0x51;
// Range check
if (new_addr < 0x08 || new_addr > 0x77) {
ESP_LOGE("dimmerlink", "Invalid address: 0x%02X (must be 0x08-0x77)", new_addr);
return;
}
uint8_t data[2] = {0x30, new_addr};
auto err = id(bus_a).write(old_addr, data, 2, true);
if (err == i2c::ERROR_OK) {
ESP_LOGW("dimmerlink", "Address changed from 0x%02X to 0x%02X", old_addr, new_addr);
ESP_LOGW("dimmerlink", "Device now responds ONLY at new address!");
} else {
ESP_LOGE("dimmerlink", "Failed to change address: %d", err);
}
ESPHome-Entität — Number (zur Adressänderung):
# Dangerous operation! After changing you need to reconfigure everything.
number:
- platform: template
name: "DimmerLink I2C Address"
id: dimmerlink_i2c_address
icon: "mdi:identifier"
entity_category: "config"
min_value: 8 # 0x08
max_value: 119 # 0x77
step: 1
mode: box
optimistic: true
set_action:
- lambda: |-
uint8_t new_addr = (uint8_t)x;
if (new_addr < 0x08 || new_addr > 0x77) {
ESP_LOGE("dimmerlink", "Invalid address: 0x%02X", new_addr);
return;
}
uint8_t data[2] = {0x30, new_addr};
// Use current address (default 0x50)
id(bus_a).write(0x50, data, 2, true);
ESP_LOGW("dimmerlink", "Address changed to 0x%02X", new_addr);
ESP_LOGW("dimmerlink", "UPDATE YOUR CONFIG AND REBOOT!");
ESPHome — Unterstützung mehrerer Geräte:
substitutions:
dimmer1_addr: "0x50"
dimmer2_addr: "0x51"
output:
- platform: template
id: dimmer1_output
type: float
write_action:
- lambda: |-
uint8_t level = (uint8_t)(state * 100.0f);
uint8_t data[2] = {0x10, level};
id(bus_a).write(${dimmer1_addr}, data, 2, true);
- platform: template
id: dimmer2_output
type: float
write_action:
- lambda: |-
uint8_t level = (uint8_t)(state * 100.0f);
uint8_t data[2] = {0x10, level};
id(bus_a).write(${dimmer2_addr}, data, 2, true);
light:
- platform: monochromatic
name: "Dimmer 1"
output: dimmer1_output
- platform: monochromatic
name: "Dimmer 2"
output: dimmer2_output
4.6 Referenztabellen
Vollständige Registerkarte
| Adresse | Name | L/S | Größe | Bereich | Beschreibung |
|---|---|---|---|---|---|
0x00 |
STATUS | L | 1 | Bitmap | Gerätestatus |
0x01 |
COMMAND | S | 1 | 0-3 | Steuerbefehle |
0x02 |
ERROR | L | 1 | Enum | Letzter Fehlercode |
0x03 |
VERSION | L | 1 | — | Firmware-Version |
0x04-0x0F |
— | — | — | — | Reserviert |
0x10 |
DIM0_LEVEL | L/S | 1 | 0-100 | Helligkeit Kanal 0 (%) |
0x11 |
DIM0_CURVE | L/S | 1 | 0-2 | Kurve Kanal 0 |
0x12-0x1F |
DIMx | — | — | — | Reserviert (Kanäle 1-3) |
0x20 |
AC_FREQ | L | 1 | 50/60 | AC-Frequenz (Hz) |
0x21 |
AC_PERIOD_L | L | 1 | — | Periode, Low-Byte (µs) |
0x22 |
AC_PERIOD_H | L | 1 | — | Periode, High-Byte |
0x23 |
CALIBRATION | L | 1 | 0-1 | Kalibrierungsstatus |
0x24-0x2F |
— | — | — | — | Reserviert |
0x30 |
I2C_ADDRESS | L/S | 1 | 0x08-0x77 | I2C-Geräteadresse |
0x31-0x3F |
— | — | — | — | Reserviert |
Befehlscodes (Register 0x01)
| Code | Befehl | Beschreibung |
|---|---|---|
0x00 |
NOP | Keine Operation |
0x01 |
RESET | Software-Reset (~3 Sek.) |
0x02 |
RECALIBRATE | Frequenz-Neukalibrierung (~200 ms) |
0x03 |
SWITCH_UART | In UART-Modus wechseln |
Fehlercodes (Register 0x02)
| Code | Name | Beschreibung |
|---|---|---|
0x00 |
OK | Kein Fehler |
0xF9 |
ERR_SYNTAX | Ungültige Registeradresse |
0xFC |
ERR_NOT_READY | Gerät nicht bereit (nicht kalibriert oder FLASH-Fehler) |
0xFD |
ERR_INDEX | Ungültiger Kanal-Index |
0xFE |
ERR_PARAM | Ungültiger Parameterwert |
Kurventypen (Register 0x11)
| Code | Name | Formel | Anwendung |
|---|---|---|---|
0 |
LINEAR | out = in | Universell |
1 |
RMS | out = in^2 | Glühlampen |
2 |
LOG | out = log(in) | LED-Lampen |
Änderungsprotokoll
| Version | Datum | Änderungen |
|---|---|---|
| 1.0 | 2026-02 | Erstversion |
← - Lambda-Beispiele | Inhaltsverzeichnis | Weiter: - Lambda FAQ & Fehlerbehebung →