Connect Sub-Zero, Wolf, and Cove kitchen appliances to Home Assistant over Bluetooth Low Energy (BLE), using an ESP32 running ESPHome. FULLY LOCAL.
|
Warning
|
This project is in an extreme alpha phase. It does work for me, but I have a limited number of appliances that I can test with. I’m looking for more people to help me test and someone that has knowledge of the BT stack and connection handling. |
Sub-Zero Group (SZG) appliances include a BLE radio that the official Sub-Zero Group Owner mobile app (Android/iOS) uses for configuration and monitoring. This project reverse-engineers that BLE protocol and reimplements the connection, pairing, and polling logic entirely in ESPHome YAML + inline C++ lambdas - no custom components or external libraries required. See Supported Sensors for a list of supported appliance sensors.
-
An ESP32 board. The Everything Presence One and Waveshare POE ESP32 are what I have experience with and seem to work well.
-
ESPHome 2024.6+ (tested on 2026.3.0)
-
Python 3.10+ and a working ESPHome installation
-
The 6-digit PIN from your appliance display (one-time)
python3 -m venv esphome-venv
source esphome-venv/bin/activate
pip install esphomeCreate a YAML file (e.g. subzero.yaml). The packages: block pulls the appliance package directly from this GitHub repo at compile time - no cloning required.
Choose the package file for your appliance type:
| Appliance Type | Package File |
|---|---|
Sub-Zero refrigerator/freezer |
|
Cove dishwasher |
|
Wolf range/oven |
|
packages:
- url: https://github.com/JonGilmore/esphome-subzero-ble
ref: v1.0.0 # use latest tag, or main
files:
- path: subzero_fridge.yaml
vars:
prefix: "szg"
appliance_name: "Kitchen Fridge"
appliance_mac: "00:06:80:XX:XX:XX" # (1)
appliance_pin: "123456" # (2)
esphome:
name: my-subzero
friendly_name: "My Sub-Zero"
name_add_mac_suffix: true
esp32:
board: esp32dev
framework:
type: esp-idf
sdkconfig_options:
CONFIG_BT_GATTC_CACHE_NVS_FLASH: "n"
logger:
level: DEBUG
logs:
esp32_ble_client: INFO
ble_client: DEBUG
ble_sensor: WARN
esp32_ble_tracker: WARN
BT_GATTC: WARN
api:
reboot_timeout: 5min
ota:
- platform: esphome
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
fast_connect: true
power_save_mode: none
esp32_ble_tracker:-
Your appliance’s BLE MAC address (Sub-Zero MACs typically start with
00:06:80) -
The 6-digit PIN from your appliance (see 4. Pair Your Appliance below)
packages:
- url: https://github.com/JonGilmore/esphome-subzero-ble
ref: v1.0.0 # use latest tag, or main
files:
- path: subzero_dishwasher.yaml
vars:
prefix: "szg"
appliance_name: "Dishwasher"
appliance_mac: "00:06:80:XX:XX:XX"
appliance_pin: "123456"packages:
- url: https://github.com/JonGilmore/esphome-subzero-ble
ref: v1.0.0 # use latest tag, or main
files:
- path: subzero_range.yaml
vars:
prefix: "szg"
appliance_name: "Kitchen Range"
appliance_mac: "00:06:80:XX:XX:XX"
appliance_pin: "123456"packages:
- url: https://github.com/JonGilmore/esphome-subzero-ble
ref: v1.0.0 # use latest tag, or main
files:
- path: subzero_fridge.yaml
vars:
prefix: "szg"
appliance_name: "Main Fridge"
appliance_mac: "00:06:80:XX:XX:XX"
appliance_pin: "123456"
- path: subzero_range.yaml
vars:
prefix: "szg2"
appliance_name: "Kitchen Range"
appliance_mac: "00:06:80:YY:YY:YY"
appliance_pin: "654321"|
Note
|
Use a unique prefix for each appliance (e.g. szg, szg2, szg3). The base package sets max_connections: 5 in esp32_ble, which supports up to 5 appliances on one ESP32. If you need more, add esp32_ble: max_connections: 6 (or higher) to your device YAML. See BLE Stack Tuning for additional sdkconfig_options when running 2+ concurrent connections.
|
|
Tip
|
Pin to a release tag (e.g. ref: v1.0.0) for stability, or use ref: main to track the latest changes
|
For units without a freezer or ice maker, you can hide irrelevant sensors:
vars:
prefix: "szg"
appliance_name: "Basement Fridge"
appliance_mac: "00:06:80:XX:XX:XX"
appliance_pin: "123456"
hide_freezer: "true"
hide_ice_maker: "true"| Option | Default | Hides |
|---|---|---|
|
|
Freezer Set Temperature, Freezer Door |
|
|
Ice Maker |
|
|
Sabbath Mode |
|
|
Wine Door, Wine Zone Upper Set Temperature, Wine Zone Lower Set Temperature, Wine Temperature Alert |
|
|
Refrigerator Drawer Set Temperature, Refrigerator Drawer Door |
|
|
Crisper Drawer Set Temperature |
|
|
Air Filter, Air Filter Remaining |
|
|
Water Filter Remaining |
|
|
Water softener on a dishwasher |
vars:
prefix: "szg"
appliance_name: "Fridge"
appliance_mac: "00:06:80:XX:XX:XX"
appliance_pin: "123456"
hide_ref_drawer: "false"vars:
prefix: "szg"
appliance_name: "Fridge"
appliance_mac: "00:06:80:XX:XX:XX"
appliance_pin: "123456"
hide_crisper: "false"
hide_air_filter: "false"
hide_water_filter: "false"vars:
prefix: "szg"
appliance_name: "Wine Fridge"
appliance_mac: "00:06:80:XX:XX:XX"
appliance_pin: "123456"
hide_freezer: "true"
hide_ice_maker: "true"
hide_wine: "false"esphome run subzero.yaml --device /dev/cu.usbserial-210See ESPHome Commands for OTA flashing, viewing logs, and more.
You need the 6-digit PIN from your appliance. There are two ways to get it:
-
From the official app: Open the Sub-Zero Group Owner app, connect to your appliance, and note the PIN shown during pairing. You will have to delete the BT pairing from your phone after this to allow the ESP32 to connect.
-
From the appliance display: After the ESP32 connects and bonds, press the "Start Pairing" button in Home Assistant. The PIN will appear on the appliance’s physical display for 30 seconds.
|
Tip
|
Sub-Zero appliance BLE MAC addresses typically start with 00:06:80. You can confirm with a Bluetooth scanner app on your phone or use a spare ESP32 to scan for BLE advertisements.
|
| Symptom | Fix |
|---|---|
D5 characteristic not found |
Normal on first connect. The code automatically handles encryption, GATT refresh, and rediscovery. Wait 15-20 seconds. |
"No sensor characteristic found" warning |
Expected. ESPHome’s BLE sensor component looks for D5 before encryption exposes it. The code injects the correct handle later. |
Passkey request but no PIN |
Enter your PIN via the text input in Home Assistant, then press "Submit PIN & Unlock." |
Commands sent but no response |
Make sure every command string ends with |
Crash loop (abort/reboot cycle) |
Out of memory. See Memory Considerations. Flash via USB to recover. |
Appliance disconnects after 5 minutes |
This is the reconnect timeout working as designed. The ESP32 will automatically reconnect. |
Auth failures overnight (auth fail reason=102) |
The BLE bond went stale. The integration automatically detects this after 3 consecutive failures, clears the old bond, and re-pairs. No action needed. |
Dishwasher disconnects after ~10 seconds |
Normal for Cove dishwashers. The integration uses a fast reconnect path with cached GATT handles to complete polling within the connection window. |
Range disconnects before data arrives |
Wolf ranges have tight BLE windows. Add |
"ACL packet too short" / first push notification lost |
Known ESP-IDF Bluedroid HCI bug on ESP32-S3. When an appliance sends a rapid burst of push notifications (e.g. activating gourmet mode on a wall oven), the first message may be dropped due to ACL fragment reassembly failure. The integration detects this and recovers for subsequent messages, but the first state change in the burst is lost. This seems to primarily affect appliances using 40-byte indication fragments (fw 8.5); appliances using 244-byte fragments (fw 2.27) are unaffected since their push notifications fit in a single indication. |
|
Note
|
Sub-Zero fridge firmware only exposes set points over BLE - actual/measured compartment temperatures are not available. Wolf ranges do expose measured cavity temperatures (see below). |
| Sensor | Description |
|---|---|
Refrigerator Set Temperature |
Current fridge setpoint (°F). For standalone freezer units, falls back to the freezer setpoint. |
Freezer Set Temperature |
Current freezer setpoint (°F) (optional) |
Refrigerator Door |
Open/closed binary sensor |
Freezer Door |
Open/closed binary sensor (optional) |
Ice Maker |
On/off binary sensor (optional) |
Sabbath Mode |
On/off binary sensor (optional) |
Wine Door |
Open/closed binary sensor (optional) |
Wine Zone Upper Set Temperature |
Upper zone setpoint (°F) (optional) |
Wine Zone Lower Set Temperature |
Lower zone setpoint (°F) (optional) |
Wine Temperature Alert |
Temperature alert binary sensor (optional) |
Refrigerator Drawer Set Temperature |
Drawer compartment setpoint (°F) (optional) |
Refrigerator Drawer Door |
Drawer open/closed binary sensor (optional) |
Crisper Drawer Set Temperature |
Crisper drawer setpoint (°F) (optional) |
Air Filter |
Air filter on/off binary sensor (optional) |
Air Filter Remaining |
Air filter life remaining (%) (optional) |
Water Filter Remaining |
Water filter life remaining (%) (optional) |
Service Required |
Alerts when the appliance flags a service need |
Appliance Model |
Model number (e.g. |
Appliance Uptime |
Time since last power cycle |
| Sensor | Description |
|---|---|
Door |
Open/closed binary sensor |
Wash Cycle Active |
Whether a wash cycle is currently running |
Wash Status |
Numeric wash status code |
Wash Cycle |
Current wash cycle number |
Wash Time Remaining |
Minutes remaining in the current wash cycle |
Wash Cycle End Time |
Estimated completion time (e.g. |
Heated Dry |
Heated dry option enabled |
Extended Dry |
Extended dry option enabled |
High Temp Wash |
High temperature wash option enabled |
Sanitize Rinse |
Sanitize rinse option enabled |
Rinse Aid Low |
Rinse aid level is low (problem sensor) |
Softener Low |
Water softener level is low (problem sensor, DW2450WS only) |
Light |
Interior light on/off |
Remote Ready |
Appliance is ready for remote commands |
Delay Start |
Delay start timer is active |
Service Required |
Alerts when the appliance flags a service need |
Appliance Model |
Model number (e.g. |
Appliance Uptime |
Time since last power cycle |
| Sensor | Description |
|---|---|
Oven Temperature |
Current cavity temperature (°F) |
Oven Set Temperature |
Target cavity temperature (°F) |
Cook Mode |
Numeric cook mode code |
Gourmet Recipe |
Current gourmet recipe number |
Probe Temperature |
Meat probe current temperature (°F) |
Probe Set Temperature |
Meat probe target temperature (°F) |
Door |
Open/closed binary sensor |
Oven |
Oven is on/off |
Oven At Temperature |
Cavity has reached set temperature |
Oven Light |
Oven light on/off |
Oven Remote Ready |
Oven is ready for remote commands |
Probe Inserted |
Meat probe is plugged in |
Probe At Temperature |
Probe has reached set temperature |
Probe Within 10° |
Probe is within 10° of set temperature |
Gourmet Mode |
Gourmet mode is active |
Cook Timer Complete |
Cook timer has finished |
Cook Timer Within 1 Min |
Cook timer is within 1 minute of finishing |
Kitchen Timer Active |
Kitchen timer 1 is running |
Kitchen Timer Complete |
Kitchen timer 1 has finished |
Kitchen Timer Within 1 Min |
Kitchen timer 1 is within 1 minute of finishing |
Kitchen Timer End Time |
Kitchen timer 1 estimated end time |
Kitchen Timer 2 Active |
Kitchen timer 2 is running |
Kitchen Timer 2 Complete |
Kitchen timer 2 has finished |
Kitchen Timer 2 Within 1 Min |
Kitchen timer 2 is within 1 minute of finishing |
Kitchen Timer 2 End Time |
Kitchen timer 2 estimated end time |
Oven 2 Temperature |
Second cavity temperature (°F) (optional) |
Oven 2 Set Temperature |
Second cavity target temperature (°F) (optional) |
Oven 2 Cook Mode |
Second cavity cook mode code (optional) |
Oven 2 Probe Temperature |
Second cavity probe current temperature (°F) (optional) |
Oven 2 Probe Set Temperature |
Second cavity probe target temperature (°F) (optional) |
Oven 2 Door |
Second cavity open/closed (optional) |
Oven 2 |
Second oven is on/off (optional) |
Oven 2 At Temperature |
Second cavity has reached set temperature (optional) |
Oven 2 Light |
Second oven light on/off (optional) |
Oven 2 Remote Ready |
Second oven is ready for remote commands (optional) |
Oven 2 Probe Inserted |
Second cavity meat probe is plugged in (optional) |
Oven 2 Probe At Temperature |
Second cavity probe has reached set temperature (optional) |
Oven 2 Probe Within 10° |
Second cavity probe is within 10° of set temperature (optional) |
Oven 2 Gourmet Mode |
Second cavity gourmet mode is active (optional) |
Oven 2 Cook Timer Complete |
Second cavity cook timer has finished (optional) |
Service Required |
Alerts when the appliance flags a service need |
Appliance Model |
Model number (e.g. |
Appliance Uptime |
Time since last power cycle |
These diagnostic text sensors are exposed under HA’s Diagnostic section for every supported appliance type. Not every appliance populates every field - missing keys leave the sensor unknown. Useful for troubleshooting firmware-version-specific behavior or sharing context in bug reports.
| Sensor | Description |
|---|---|
Appliance Serial |
Hardware serial number (trimmed of padding spaces) |
Appliance Type |
Product type code (e.g. |
Diagnostic Status |
Hex bitmask of internal status flags (e.g. |
Firmware Version |
Main firmware version (e.g. |
API Version |
BLE API protocol version (e.g. |
BLE App Version |
BLE application version |
OS Version |
Underlying OS version |
RTApp Version |
Realtime application version |
Appliance Board Version |
Raw composite string of sub-board versions (e.g. |
Build Date |
Firmware build timestamp |
| Brand | Model | Type | Status |
|---|---|---|---|
Sub-Zero |
DEU2450R |
Under-counter refrigerator |
Fully working |
Sub-Zero |
313 |
French-door fridge/freezer with ice maker |
Fully working |
Cove |
DW2450 |
Dishwasher |
Fully working |
Cove |
DW2450WS |
Dishwasher (with water softener) |
Fully working |
Wolf |
DF36450GSP |
Dual-fuel range |
Fully working |
Wolf |
SO3050PESP |
Wall oven |
Fully working |
Sub-Zero |
IW30R |
Wine storage (dual-zone) |
Fully working |
Sub-Zero |
IT36CIID |
Refrigerator/Freezer with Ice Maker |
Fully working |
Sub-Zero |
48SID |
Refrigerator/Freezer with Ice Maker |
Fully working |
Sub-Zero |
BI36UFDID |
Built-in Refrigerator/Freezer with Ice Maker |
Fully working |
Wolf |
IR36550ST |
Induction Range |
Fully working |
Other Sub-Zero, Wolf, and Cove appliances with BLE should work - they all use the same protocol. If you test with a different model, please open an issue or PR to update this table. See Debug Mode for how to capture your appliance’s data.
-
BLE Protocol Reference - GATT service structure, connection flow, command reference, and example JSON responses
-
Advanced Configuration & Usage - ESPHome commands, BLE stack tuning for multiple appliances, memory considerations, and debug mode
This project is provided as-is for personal, non-commercial use. I have no affiliation with or endorsement by Sub-Zero Group, Inc. Reverse-engineering was done independently for educational purposes. Use at your own risk.
Protocol details were reverse-engineered from the Sub-Zero Group Owner Android APK and validated through live BLE traffic analysis using an ESP32 and Python bleak scripts. I reached out to Sub-Zero support to inquire about a local API, but they declined to provide any technical information and stated that they had no plans to support it.