Home Assistant custom integration for Solamagic 2000BT Bluetooth infrared patio heaters.
- ✅ Climate Entity - Control heater with preset modes (33%, 66%, 100%)
- ✅ Real-time Status - Instant updates when changing power level
- ✅ Sensors - Power level, RSSI signal strength, connection status
- ✅ Bluetooth Proxy Support - Works with ESPHome Bluetooth proxies
- ✅ Auto-disconnect - Automatically disconnects after 3 minutes to allow app access
- ✅ Device Picker - Easy device selection in service calls (no more entry_id!)
- ✅ Services - Advanced control via Home Assistant services
- Solamagic 2000BT (Bluetooth-enabled infrared heaters)
- Manufacturer ID: 89
- Bluetooth address pattern:
D0:65:4C:*
- Open HACS in Home Assistant
- Go to "Integrations"
- Click the three dots in the top right
- Select "Custom repositories"
- Add this repository URL:
https://github.com/Pocke01/homeassistant-solamagic - Category: "Integration"
- Click "Add"
- Search for "Solamagic" and install
- Download the latest release
- Copy the
custom_components/solamagicfolder to your Home Assistant'scustom_componentsdirectory - Restart Home Assistant
The integration is configured via the UI:
- Go to Settings → Devices & Services
- Click "+ Add Integration"
- Search for "Solamagic"
- The integration will auto-discover your heater via Bluetooth
- Follow the setup steps
The heater appears as a climate entity with the following controls:
- HVAC Mode: Heat / Off
- Preset Modes:
- Low (33%)
- Medium (66%)
- High (100%)
- Power Level - Current power level in %
- Signal Strength - Bluetooth RSSI in dBm
- Connection Status - Connected or disconnected
Advanced control via services with easy device selection:
Set heater to specific power level (0%, 33%, 66%, or 100%).
Using Device Picker (Easy!):
service: solamagic.set_level
target:
device_id: # Select from dropdown in UI
data:
level: 66 # Options: 0, 33, 66, 100In Automations:
alias: Heater on at sunset
description: ""
triggers:
- trigger: sun
event: sunset
offset: 0
actions:
- action: solamagic.set_level
metadata: {}
data:
level: "66"
device_id: YOUR_DEVICE_IDAdvanced (using entry_id):
service: solamagic.set_level
data:
entry_id: YOUR_ENTRY_ID # Still supported for advanced users
level: 66Send raw Bluetooth commands to handle 0x0028 (advanced users).
service: solamagic.write_handle
target:
device_id: # Select your heater
data:
payload_hex: "01 42" # 66% command
response: false
repeat: 2 # Optional: repeat count
delay_ms: 120 # Optional: delay between repeatsWrite to any Bluetooth handle (for advanced protocol exploration).
service: solamagic.write_handle_any
target:
device_id: # Select your heater
data:
handle: 40 # Decimal handle (0x0028)
payload_hex: "01 64" # 100% command
response: trueWrite to characteristic by UUID (alternative method).
service: solamagic.write_uuid
target:
device_id: # Select your heater
data:
char_uuid: "0000f001-0000-1000-8000-00805f9b34fb"
payload_hex: "01 21" # 33% command
response: falseManually disconnect from heater (useful for troubleshooting or to allow app access).
service: solamagic.disconnect
target:
device_id: # Select your heateralias: "Patio heater on when cold"
description: Turn on when temperature drops
triggers:
- trigger: numeric_state
entity_id: sensor.outdoor_temperature
below: 15
actions:
- action: climate.set_preset_mode
metadata: {}
data:
preset_mode: medium
target:
entity_id: YOUR_ENTITY_ID# Turn on
alias: Evening Heating
triggers:
- trigger: time
at: "18:00:00"
actions:
- action: climate.set_preset_mode
data:
preset_mode: high
target:
entity_id: climate.YOUR_HEATER
---
# Turn off
alias: Night Off
triggers:
- trigger: time
at: "22:00:00"
actions:
- action: climate.set_hvac_mode
data:
hvac_mode: "off"
target:
entity_id: climate.YOUR_HEATERThis integration uses reverse-engineered Bluetooth protocol from the xHeatlink app:
- Initialization: Sends unlock sequence to handle 0x001F
- Commands: Sent to handle 0x0028 without response
- Status: Received via notifications on handle 0x0032
- Power Levels:
- OFF:
00 21(sent 21 times with 16ms delay) - 33%:
01 21 - 66%:
01 42 - 100%:
01 64
- OFF:
The integration follows this initialization sequence:
- Write initialization payload to handle 0x001F
- Enable notifications on handle 0x002F (CCCD 0x0030)
- Enable notifications on handle 0x0032 (CCCD 0x0033)
- Enable notifications on handle 0x0028 (CCCD 0x0029)
All commands use Write Command (no response) for faster execution.
- Ensure Bluetooth is enabled in Home Assistant
- Check that the heater is powered on and within range
- Try restarting Home Assistant
- Verify your device MAC address starts with
D0:65:4C:
- The integration auto-disconnects after 3 minutes to allow xHeatlink app access
- If you need to use the app, wait for auto-disconnect or use the
solamagic.disconnectservice - Check signal strength sensor - poor RSSI (<-80 dBm) may cause issues
- If using Bluetooth proxy, ensure it's online and within range
- Check if Power Level sensor is updating
- Verify Connection Status sensor shows "connected"
- Enable debug logging:
logger: logs: custom_components.solamagic: debug
- Check Home Assistant logs for errors
If you see "Device not found" errors:
- Go to Developer Tools → Services
- Select your service (e.g.,
solamagic.set_level) - Use the device selector dropdown to choose your heater
- This is easier than manually entering
entry_id
- When creating an automation, add an action
- Choose "Call service"
- Search for "Solamagic"
- Use the device selector to pick your heater
- The UI will automatically fill in the correct
device_id
Q: Can I control multiple heaters?
A: Yes! Add each heater separately, and use the device picker to select which one to control.
Q: Does it work with Bluetooth proxies?
A: Yes! Works great with ESPHome Bluetooth proxies. The integration is proxy-aware.
Q: Why does it disconnect after 3 minutes?
A: To allow the xHeatlink mobile app to connect. You can adjust this timeout if needed.
Q: Can I use both the app and Home Assistant?
A: Yes, but not simultaneously. The integration disconnects after 3 minutes to allow app access.
Q: What's the difference between preset modes and service calls?
A: Preset modes (Low/Medium/High) are the easiest way to control via the UI. Services offer more flexibility for automations.
This integration follows Home Assistant best practices:
- Proper error handling with user-friendly messages
- Async/await patterns for non-blocking operations
- Comprehensive logging for debugging
- Device picker support for easy service calls
- English code comments for international collaboration
Found a bug or want to add a feature?
- Check existing issues
- Fork the repository
- Create a feature branch
- Submit a pull request
- Protocol analysis based on Bluetooth sniffing of the xHeatlink app
- Inspired by reverse engineering work on similar BLE devices
- Big thanks to ChatGPT and Claude.ai for helping with endless questions and suggestions!
- Thanks to the Home Assistant community for code reviews and feedback
I do not know Python or how the Bluetooth protocol works. But I know how to solve problems! 😊
This integration is not affiliated with or endorsed by Solamagic. Use at your own risk.
MIT License - see LICENSE file for details.
For issues and feature requests, please use the GitHub issue tracker.
Version: 0.3.25
Status: Production-ready, HACS-compatible
Home Assistant: 2024.1.0+