Skip to content
 
 

Repository files navigation

Beurer Daylight Therapy Lamps

HACS Default GitHub Release Validate Tests

Home Assistant custom integration for Beurer daylight therapy lamps via Bluetooth Low Energy (BLE).

Motivation

I noticed that most integrations were fragile. After fiddling for some time I found out that one of the main issues is that the integrations were not reviewed for new developments in Home assistant itself. In addition to that, it bugged me, that no integration had the timer feature like the Beurer LightUp App so it was not possible to integrate it into automations with the already built-in device functions. I managed to sniff BLE traffic between the Beurer LightUp app and the TL100 and let AI sift through it (I was way too lazy to use wireshark). So now I got it working. As far as I can say, it's way more stable than the successors I have forked.

I heavily used claude as I did in other projects but focused on keeping it tight and close to Home Assitant standards and guidelines and general coding guidelines. It may still contain bad code, so feel free to review and submit issues or PRs.

Supported Devices

Model Status Notes
TL100 ✅ Tested Full support
TL50 ⚠️ Untested Should work
TL70 ⚠️ Untested Should work
TL80 ⚠️ Untested Should work
TL90 ⚠️ Untested Should work
WL75 ⚠️ Untested Wake-up Light (same protocol family as WL90)
WL90 ⚠️ Untested Wake-up Light with Radio, Speaker, Alarms

Features

Light Control

  • 💡 On/off and brightness control
  • 🎨 RGB color mode with color picker
  • 🌡️ Color temperature (2700K - 6500K)
  • ✨ Light effects (Rainbow, Pulse, Forest, Wave, etc.)
  • 🔆 Separate white/color brightness sliders

Connectivity

  • 📡 Bluetooth auto-discovery
  • 🔄 ESPHome/Shelly Bluetooth Proxy support
  • 📶 Automatic adapter switching to best signal
  • 🔗 Connection status monitoring

Lifestyle Wellness Features

Important: These features are for personal lifestyle tracking and wellness purposes only. This integration is NOT a medical device and should not be used for medical purposes.

  • Sunrise/Sunset Simulation: Native integration layer simulation with gradual brightness and color temperature changes
  • Light Exposure Tracking: Track daily and weekly bright light exposure minutes
  • Daily Goal Progress: Configurable daily light exposure goal with progress sensor
  • Goal Reached Notification: Binary sensor for automation triggers when daily goal is met

Entities Created

Entity Type Name Description
Light Beurer Lamp Main light entity with all controls
Button Identify Blinks lamp 3x to find it
Button Reconnect Forces BLE reconnection
Button Sync time Syncs HA clock to device
Select Effect Dropdown for light effects
Number White brightness Slider 0-100%
Number Color brightness Slider 0-100%
Number Timer Auto-off timer 0-120 min (0 = off, works in both modes)
Number Daily light goal Configurable daily exposure goal (5-120 min)
Sensor Signal strength RSSI in dBm (disabled by default)
Sensor Light exposure today Minutes of bright light today
Sensor Light exposure this week Minutes of bright light this week
Sensor Daily goal progress Percentage of daily goal completed
Binary Sensor Connected BLE connection status
Binary Sensor Bluetooth reachable Device seen by any adapter
Binary Sensor Daily goal reached True when daily exposure goal is met
Switch Feedback sound Enable/disable device beep on button press
Switch Fade Enable/disable smooth brightness transitions
Switch Adaptive Lighting Allow/block Adaptive Lighting (HACS) control
Sensor Reconnect count Total BLE reconnections since startup (diagnostic, disabled)
Sensor Command success rate Percentage of successful BLE commands (diagnostic, disabled)
Sensor Connection uptime Seconds since current connection established (diagnostic, disabled)

WL90-Only Entities

Entity Type Name Description
Media Player FM Radio Radio with on/off, volume, seek, presets
Media Player Bluetooth Speaker BT speaker with on/off, volume
Number Radio volume Radio volume slider 0-10
Number Speaker volume Speaker volume slider 0-10

Entity Notes

  • Timer: Works in both White and RGB mode. Set to 0 to disable. Note: Timer is automatically cancelled when switching modes.
  • Signal Strength: Disabled by default. RSSI values: -30 to -50 dBm = excellent, -50 to -70 = good, < -80 = poor

Services

beurer_daylight_lamps.apply_preset

Apply predefined lighting presets:

Preset Description
daylight_therapy Full brightness 5300K for therapy
relax Warm dim light (2700K, 40%)
focus Cool bright light (5000K, 90%)
reading Neutral white (4000K, 80%)
warm_cozy Very warm (2700K, 60%)
cool_bright Cool white full brightness
sunset Orange sunset simulation
night_light Very dim warm light
energize Bright cool light to wake up

Example usage:

service: beurer_daylight_lamps.apply_preset
target:
  entity_id: light.beurer_tl100
data:
  preset: daylight_therapy

beurer_daylight_lamps.set_timer

Set an auto-off timer (1-120 minutes). The lamp will turn off automatically after the specified time. Works in both White and RGB mode.

service: beurer_daylight_lamps.set_timer
target:
  entity_id: light.beurer_tl100
data:
  minutes: 30

beurer_daylight_lamps.start_sunrise

Start a sunrise simulation with gradual brightness and color temperature increase.

Lifestyle Feature: This is a personal wellness feature, not a medical device.

service: beurer_daylight_lamps.start_sunrise
target:
  entity_id: light.beurer_tl100
data:
  duration: 15  # minutes (1-60)
  profile: natural  # gentle, natural, energize, or therapy

Profiles:

Profile Description
gentle Slow, soft transition for sensitive users
natural Mimics natural sunrise timing
energize Faster transition with brighter end point
therapy Optimized for bright light exposure

beurer_daylight_lamps.start_sunset

Start a sunset simulation with gradual brightness decrease and warm color shift.

service: beurer_daylight_lamps.start_sunset
target:
  entity_id: light.beurer_tl100
data:
  duration: 30  # minutes (1-60)
  end_brightness: 0  # 0-100%, 0 = turn off at end

beurer_daylight_lamps.stop_simulation

Stop any running sunrise or sunset simulation.

service: beurer_daylight_lamps.stop_simulation
target:
  entity_id: light.beurer_tl100

beurer_daylight_lamps.set_alarm (WL90 only)

Configure one of 3 alarm slots with sunrise simulation.

service: beurer_daylight_lamps.set_alarm
target:
  entity_id: light.beurer_wl90
data:
  slot: 0                    # Alarm slot 0, 1, or 2
  enabled: true
  hour: 7
  minute: 30
  days: "Mon,Tue,Wed,Thu,Fri"
  tone: 2                    # 0=Buzzer, 1=Radio, 2-11=Melody 1-10
  volume: 5
  snooze: 10                 # 1, 2, 5, 10, 20, or 30 minutes
  sunrise_enabled: true
  sunrise_time: 20           # Start 20 min before alarm
  sunrise_brightness: 50

Requirements

Component Minimum version Notes
Home Assistant Core 2025.12.0 Required for modern Bluetooth + coordinator APIs and Python 3.13.2. Users on older HA should stay on v1.33.0.
Python 3.13 HA Core 2025.2+ requires Python 3.13.
Bluetooth HA Bluetooth integration Built-in BLE adapter, ESPHome BT proxy, or Shelly BT proxy.

Upgrading from < 1.34.0? Make sure your Home Assistant Core is on 2025.12.0 or newer before installing this version. HACS will hide the update on older HA installs. Users still on HA ≤ 2025.11 can continue to use v1.33.0.

Installation

Note: Restart Home Assistant after installation.

HACS (recommended)

  1. Open HACS in Home Assistant
  2. Go to "Integrations"
  3. Search for "Beurer Daylight Lamps"
  4. Click "Download" and install

Manual Installation

git clone https://github.com/moag1000/beurer_daylight_lamps
cd beurer_daylight_lamps
cp -r custom_components/beurer_daylight_lamps ~/.homeassistant/custom_components/

Removal

  1. Go to SettingsDevices & Services
  2. Find the Beurer Daylight Lamps integration
  3. Click the three dots menu → Delete
  4. Restart Home Assistant
  5. (Optional) Remove the integration folder from custom_components/

Setup

Automatic Discovery (recommended)

  1. Turn on your Beurer lamp
  2. Home Assistant will automatically detect the lamp via Bluetooth
  3. A notification will appear - click "Configure"
  4. The lamp will blink to confirm connection
  5. Click "Submit" to complete setup

Manual Setup

  1. Go to SettingsDevices & ServicesAdd Integration
  2. Search for "Beurer Daylight Lamps"
  3. Select your lamp from the list or enter MAC address manually
  4. The lamp will blink to confirm - click "Yes" if it blinked

Bluetooth Proxy Support

This integration fully supports ESPHome and Shelly Bluetooth Proxies:

  • Automatically uses the proxy with the best signal
  • Seamlessly switches between adapters as signal changes
  • No configuration needed - just set up your proxies in Home Assistant

ESP32 Bluetooth Proxy Setup (Important!)

⚠️ Critical: The Beurer TL100 does not support BLE 5.0 PHY negotiation. Standard ESP32 Bluetooth Proxy configurations will fail with error 0x3e (BLE_HCI_CONN_FAIL_ESTABLISH).

Hardware Compatibility

ESP32 Variant Works? Notes
ESP32-S3 ✅ Yes Recommended - Dual-core Xtensa, best WiFi/BLE coexistence
ESP32-WROOM-32 ✅ Yes Dual-core Xtensa, works with BLE 5.0 fix
ESP32-C3 ❌ No Single-core RISC-V, WiFi/BLE conflicts
ESP32-C6 ❌ No Single-core RISC-V, same issues as C3

Why C3/C6 don't work: Single-core RISC-V chips cannot handle WiFi and BLE simultaneously when the BLE connection requires frequent packet exchanges (like the TL100 does).

Required ESP-IDF Configuration

You must disable BLE 5.0 features in your ESPHome configuration:

esp32:
  board: esp32-s3-devkitc-1
  variant: esp32s3
  framework:
    type: esp-idf
    version: recommended
    sdkconfig_options:
      # CRITICAL: Disable BLE 5.0 - TL100 doesn't support PHY negotiation
      CONFIG_BT_BLE_50_FEATURES_SUPPORTED: n
      CONFIG_BT_BLE_42_FEATURES_SUPPORTED: y

      # WiFi/BLE Coexistence
      CONFIG_SW_COEXIST_ENABLE: y
      CONFIG_SW_COEXIST_PREFERENCE_BT: y

Complete ESPHome Example Configuration

# ESP32-S3 Bluetooth Proxy for Beurer Daylight Lamps
# BLE 5.0 disabled - TL100 requires BLE 4.2 only

esphome:
  name: btproxy-beurer
  friendly_name: BT Proxy Beurer

esp32:
  board: esp32-s3-devkitc-1
  variant: esp32s3
  framework:
    type: esp-idf
    version: recommended
    sdkconfig_options:
      # CRITICAL: Disable BLE 5.0 for Beurer TL100 compatibility
      CONFIG_BT_BLE_50_FEATURES_SUPPORTED: n
      CONFIG_BT_BLE_42_FEATURES_SUPPORTED: y

      # WiFi/BLE Coexistence (Dual-Core)
      CONFIG_SW_COEXIST_ENABLE: y
      CONFIG_SW_COEXIST_PREFERENCE_BT: y

      # BLE Connection Parameters
      CONFIG_BT_ACL_CONNECTIONS: "3"
      CONFIG_BT_GATT_MAX_SR_PROFILES: "8"

      # Dual-Core: Pin BT to Core 0
      CONFIG_BT_BLUEDROID_PINNED_TO_CORE: "0"

logger:
  level: DEBUG

api:
  encryption:
    key: !secret api_encryption_key

ota:
  - platform: esphome
    password: !secret ota_password

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

  ap:
    ssid: "BT-Proxy-Fallback"
    password: !secret fallback_password

captive_portal:

esp32_ble:

esp32_ble_tracker:
  scan_parameters:
    interval: 60ms
    window: 30ms
    active: true
    continuous: true

bluetooth_proxy:
  active: true
  cache_services: false

Note: Create a secrets.yaml file with your credentials:

wifi_ssid: "YourWiFiNetwork"
wifi_password: "YourWiFiPassword"
api_encryption_key: "your-32-byte-base64-key"
ota_password: "your-ota-password"
fallback_password: "fallback-ap-password"

Troubleshooting ESP32 Proxy

Problem Solution
Error 0x3e on connect Missing CONFIG_BT_BLE_50_FEATURES_SUPPORTED: n
Connection drops with C3/C6 Switch to ESP32-S3 or WROOM-32
Slow response Enable CONFIG_SW_COEXIST_PREFERENCE_BT: y
Device not found Increase scan_parameters.window to 50ms

Light Effects

The following effects are available (matching the Beurer LightUp app):

Effect Description
Off No effect
Random Random color changes
Rainbow Smooth rainbow cycle
Rainbow Slow Slower rainbow cycle
Fusion Color fusion effect
Pulse Pulsing brightness
Wave Wave-like transitions
Chill Relaxing color changes
Action Dynamic color changes
Forest Green/nature tones
Summer Warm summer colors

Blueprints

Three ready-to-use blueprints for common lighting scenarios. Click the badge to import directly into Home Assistant!

Morning Light Therapy

Import Blueprint

Wake up naturally with a sunrise simulation followed by bright light therapy.

  • Gradual warm-to-cool transition (2700K -> 5300K)
  • Configurable sunrise duration (0-30 min)
  • Therapy session at full brightness (10-60 min)
  • Schedule: Workdays, weekends, or every day
  • End behavior: Off, stay on, or switch to reading light

Evening Wind Down

Import Blueprint

Prepare for sleep by gradually dimming to warm light.

  • Triggers at sunset or fixed time
  • Gradual dimming over 15-120 minutes
  • Warm light only (2700K) to avoid blue light
  • Configurable start and end brightness

Focus Work Session

Import Blueprint

Optimize your work environment with alerting cool light.

  • Cool, alerting light (4000K-6500K configurable)
  • Optional Pomodoro-style break reminders
  • Work sessions from 15-120 minutes
  • End with relaxing light or turn off

Manual Installation

Alternatively, copy the blueprint files manually:

  1. Download the YAML files from blueprints/automation/beurer_daylight_lamps/
  2. Copy to config/blueprints/automation/beurer_daylight_lamps/ in your Home Assistant
  3. Restart Home Assistant or reload automations

Example Automations

Wake-up Light with Preset

automation:
  - alias: "Wake-up light"
    trigger:
      - platform: time
        at: "06:30:00"
    condition:
      - condition: workday
        country: DE
    action:
      - service: beurer_daylight_lamps.apply_preset
        target:
          entity_id: light.beurer_tl100
        data:
          preset: energize

Gradual Wake-up

automation:
  - alias: "Gradual wake-up light"
    trigger:
      - platform: time
        at: "06:30:00"
    action:
      - service: light.turn_on
        target:
          entity_id: light.beurer_tl100
        data:
          color_temp_kelvin: 2700
          brightness: 25
      - delay: "00:05:00"
      - service: light.turn_on
        target:
          entity_id: light.beurer_tl100
        data:
          color_temp_kelvin: 4000
          brightness: 128
      - delay: "00:05:00"
      - service: light.turn_on
        target:
          entity_id: light.beurer_tl100
        data:
          color_temp_kelvin: 5300
          brightness: 255

Evening Mood Light

automation:
  - alias: "Evening mood light"
    trigger:
      - platform: sun
        event: sunset
    action:
      - service: beurer_daylight_lamps.apply_preset
        target:
          entity_id: light.beurer_tl100
        data:
          preset: sunset

Light Therapy Session

automation:
  - alias: "Morning light therapy"
    trigger:
      - platform: time
        at: "07:00:00"
    action:
      - service: beurer_daylight_lamps.apply_preset
        target:
          entity_id: light.beurer_tl100
        data:
          preset: daylight_therapy
      - delay: "00:30:00"
      - service: light.turn_off
        target:
          entity_id: light.beurer_tl100

Data Updates & Communication

How Data is Updated

This integration uses Bluetooth Low Energy (BLE) for communication:

  • State Updates: The lamp sends BLE notifications when its state changes. These are processed in real-time.
  • RSSI Updates: Signal strength is updated whenever the lamp sends a Bluetooth advertisement (typically every few seconds).
  • Adaptive Polling: Periodic refresh ensures state consistency with intervals that adapt to device state:
    • 30 seconds when light is on (responsive updates)
    • 5 minutes when light is off (save resources)
    • 15 minutes when device unavailable (minimal polling)
  • Command Timing: Commands are rate-limited to 100ms minimum between sends to prevent overwhelming the device.
  • Mode Changes: Mode switches (white <-> RGB) include a 500ms delay to allow the hardware to stabilize.

Latency Expectations

Operation Typical Latency
On/Off 100-300ms
Brightness change 100-200ms
Color change 150-300ms
Effect change 200-500ms
Status update Real-time (push)

Known Limitations

Note: These are design constraints, not bugs.

  1. Timer cancels on mode switch: The auto-off timer works in both White and RGB mode, but is automatically cancelled when switching between modes. This is hardware behavior.

  2. Bluetooth LED always on: The small Bluetooth indicator LED on the lamp stays illuminated while connected to Home Assistant. This cannot be disabled.

  3. Single connection: The lamp can only maintain one BLE connection at a time. You cannot use the Beurer LightUp app while connected to Home Assistant.

  4. Connection after reboot: Connection may fail a few times after Home Assistant reboots while the Bluetooth stack initializes. The integration will auto-reconnect.

  5. Light exposure tracking resets daily: The therapy/exposure tracking resets at midnight. Historical data beyond the current week is not retained.

  6. Simulation requires connection: Sunrise/sunset simulations require an active BLE connection. If the connection drops, the simulation will pause and resume when reconnected.

  7. Color temperature approximation: Color temperatures are approximated using RGB values since the lamp doesn't have a native CT mode. Results may vary slightly from true Kelvin values.

  8. White brightness capped at 99%: Some device firmware versions switch to red/RGB mode when white brightness is set to exactly 100%. The integration caps white brightness at 99% to work around this firmware bug. The visual difference is imperceptible.

Diagnostics

To download diagnostic information for troubleshooting:

  1. Go to SettingsDevices & Services
  2. Click on the Beurer Daylight Lamps integration
  3. Click the three dots menu → Download diagnostics

The diagnostic file contains device state, connection info, and configuration (MAC address is redacted).

Troubleshooting

Lamp not discovered

  1. Ensure the lamp is powered on and not connected to another device (e.g., Beurer LightUp app)
  2. Check that your Home Assistant host has Bluetooth enabled
  3. Move the lamp closer to your Home Assistant host (within 10 meters)
  4. Try restarting the lamp by unplugging and plugging it back in
  5. Check SettingsSystemRepairs for any connection issues

Connection keeps dropping

  1. Check the signal strength sensor (enable it under the device's disabled entities)
  2. If RSSI is below -80 dBm, move the lamp closer or use a Bluetooth adapter with better range
  3. Ensure no other devices are interfering with Bluetooth (e.g., USB 3.0 devices near the adapter)
  4. Recommended: Use an ESPHome Bluetooth Proxy for better range and reliability

Lamp responds slowly

  1. The integration limits commands to prevent overwhelming the BLE device
  2. Multiple rapid commands may be queued (100ms minimum between commands)
  3. This is normal behavior to ensure reliable communication

Entity shows unavailable

  1. The lamp may have lost Bluetooth connection
  2. Check SettingsSystemRepairs for repair issues
  3. Try using the "Reconnect" button entity
  4. Try turning the lamp off and on again
  5. The integration will automatically try to reconnect

Effects not showing correctly

  1. Some effects only work at specific brightness levels
  2. Try setting brightness to 100% first, then apply the effect
  3. The "Off" effect disables all effects and returns to static color

Debugging

Enable debug logging in configuration.yaml:

logger:
  default: warn
  logs:
    custom_components.beurer_daylight_lamps: debug

For detailed debugging and reverse engineering information, see CONTRIBUTING.md.

BLE Protocol

For developers interested in the BLE protocol or contributing new features, see:

Credits

Based on work by:

License

This project is licensed under the MIT License.

About

Home Assistant integration for BLE based Beurer

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

4 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages