Skip to content

Repository files navigation

ESPHome Sub-Zero BLE

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.

Overview

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 in ESPHome. The connection state machine lives in YAML + inline C lambdas; JSON parsing is factored into a small external C component (subzero_protocol) that ships with the repo and has host-compiled unit tests (see Parser Component). See Supported Sensors for a list of supported appliance sensors.

Note
There is also a Home Assistant custom integration (eyal0/subzero-ble-homeassistant) that talks to the same BLE protocol, but as an HA integration rather than an ESPHome component. It only works with a Bluetooth adapter connected to the Home Assistant device itself — ESPHome Bluetooth proxies and other remote adapters are not supported.

Requirements

  • An ESP32 board. I’ve had good results with the Everything Presence One and the Waveshare POE ESP32. In general, any ESP32-S3 module should work well and has been tested with up to 5 simultaneous BLE connections. Less capable variants, such as the ESP-C6, support fewer concurrent connections and are typically limited to about three appliances.

  • ESPHome 2026.7.1+

  • Python 3.10+ and a working ESPHome installation

  • The 6-digit PIN from your appliance display (one-time)

Getting Started

1. Install ESPHome

python3 -m venv esphome-venv
source esphome-venv/bin/activate
pip install esphome

2. Create Your Config

Create a YAML file (e.g. subzero.yaml). The external_components: block pulls the native subzero_appliance component directly from this GitHub repo at compile time - no cloning required. Each appliance is then declared as a single subzero_appliance: entry that creates its full set of sensors, switches, numbers, buttons, and the diagnostic Status text sensor.

Each subzero_appliance: entry also auto-creates an ESPHome sub-device using the appliance config id with _device appended, so entities are grouped per appliance in Home Assistant and the ESPHome web UI without needing a separate manual esphome.devices: block.

Pick the appropriate type: for your appliance:

Appliance type:

Sub-Zero refrigerator/freezer

fridge

Cove dishwasher

dishwasher

Wolf range/oven

range

Sub-Zero Refrigerator (complete example)
external_components:                          # (1)
  - source:
      type: git
      url: https://github.com/JonGilmore/esphome-subzero-ble
      ref: v3.7.0 # use latest tag, or main
    components: [subzero_protocol, subzero_appliance]

esphome:
  name: my-subzero
  friendly_name: "My Sub-Zero"
  name_add_mac_suffix: true
  min_version: 2026.7.1                       # (2)

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:
  encryption:
    key: !secret encryption_key
  reboot_timeout: 5min

ota:
  - platform: esphome
    password: !secret ota_password

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

esp32_ble:
  io_capability: keyboard_only
  max_connections: 5

esp32_ble_tracker:
  scan_parameters:
    active: false

ble_client:                                   # (3)
  - mac_address: "00:06:80:XX:XX:XX"
    id: kitchen_fridge_ble
    name: "SZG Kitchen Fridge"
    auto_connect: true

subzero_appliance:                            # (4)
  - type: fridge # or `dishwasher` or `range` # (5)
    id: kitchen_fridge
    ble_client_id: kitchen_fridge_ble
    name: "Kitchen Fridge"
    pin: "123456"                             # (6)
  1. Pulls the C++ parser and the subzero_appliance native component. Both must be loaded. (Configs written for v3.7.0 or earlier also listed patch_acl_reassembly here - that component no longer exists.)

  2. Hard floor - ESPHome 2026.7.1 is the first release built on ESP-IDF 5.5.5, which contains the upstream Bluedroid ACL-reassembly fix this project used to patch in itself.

  3. One ble_client per appliance, with the appliance’s BLE MAC address (Sub-Zero MACs typically start with 00:06:80). auto_connect: true keeps reconnecting on failure.

  4. The native subzero_appliance component creates ~30 read-only sensors plus writable Numbers (set temps), Switches (lights), and 8 control/diagnostic buttons.

  5. The type of appliance - valid types are fridge, dishwasher, range

  6. The 6-digit PIN from your appliance (see 4. Pair Your Appliance below). mode: password masks it in the HA UI.

Multiple Appliances
ble_client:
  - mac_address: "00:06:80:XX:XX:XX"
    id: main_fridge_ble
    name: "SZG Main Fridge"
    auto_connect: true
  - mac_address: "00:06:80:YY:YY:YY"
    id: kitchen_range_ble
    name: "SZG Kitchen Range"
    auto_connect: true

subzero_appliance:
  - type: fridge
    id: main_fridge
    ble_client_id: main_fridge_ble
    name: "Main Fridge"
    pin: "123456"
    poll_offset: 0s                # (1)
  - type: range
    id: kitchen_range
    ble_client_id: kitchen_range_ble
    name: "Kitchen Range"
    pin: "654321"
    poll_offset: 5s                # (1)
  1. When running multiple appliances on one ESP32, stagger their poll cycles with poll_offset (default 0s) - e.g. 0s / 5s / 10s - to avoid concurrent-bonding races on the shared BLE radio. See Reconnect Logic.

Note
esp32_ble: max_connections: 5 supports up to 5 concurrent appliances on one ESP32. Bump it (and see BLE Stack Tuning for additional sdkconfig_options) if you need more.
Tip
Pin to a release tag (e.g. ref: v3.7.0) for stability, or use ref: main to track the latest changes. The minimal copy-paste examples in wolf-minimal-fridge.yaml, wolf-minimal-range.yaml, and cove-minimal-dishwasher.yaml in the repo root track main and are a known-good starting point.

Fridge-Only Options

For units without a freezer or ice maker, you can hide irrelevant sensors. The hide_X flags are inline options on the subzero_appliance: entry:

subzero_appliance:
  - type: fridge
    id: basement_fridge
    ble_client_id: basement_fridge_ble
    name: "Basement Fridge"
    pin: "123456"
    hide_freezer: true
    hide_ice_maker: true
Option Default Hides

hide_freezer

false

Freezer Set Temperature, Freezer Door

hide_ice_maker

false

Ice Maker, plus the derived Ice Maker Mode select when enable_mode_selects: true

hide_sabbath

false

Sabbath Mode

hide_fridge_zone

false

Set Temperature, Door (set true for wine-only or freezer-only models that have no main fridge compartment)

hide_wine

true

Wine Door, Wine Zone Upper/Lower Set Temperature, Wine Temperature Alert

hide_ref_drawer

true

Refrigerator Drawer Set Temperature, Refrigerator Drawer Door

hide_crisper

true

Crisper Drawer Set Temperature

hide_air_filter

true

Air Filter, Air Filter Remaining

hide_water_filter

true

Water Filter Remaining (%)

hide_water_filter_extra

true

Water Filter Gallons Remaining, Water Filter Expires (set false on models that expose these)

hide_vacation_ice_modes

true

Long/Short Vacation Mode, High Usage Mode (+ start/end time), Max Ice Mode (+ start/end time), Night Ice Mode, plus the derived Appliance Mode / Night Mode selects when enable_mode_selects: true

hide_extra_diagnostics

true

Smart Grid Mode, Pairing Window Open, Door Ajar Alarm Timeout, WiFi Network/Signal/Channel/Encryption Type, Active Faults, plus the derived Humidity Control select when enable_mode_selects: true

hide_softener

true

Water Softener Low (dishwasher only)

hide_oven2

true

All Oven 2 sensors (range only - for dual-oven)

Fridge with Refrigerator Drawer (e.g. PRO3650G)
subzero_appliance:
  - type: fridge
    id: fridge
    ble_client_id: fridge_ble
    name: "Fridge"
    pin: "123456"
    hide_ref_drawer: false
Fridge with Crisper & Filters (e.g. DEC3650RID)
subzero_appliance:
  - type: fridge
    id: fridge
    ble_client_id: fridge_ble
    name: "Fridge"
    pin: "123456"
    hide_crisper: false
    hide_air_filter: false
    hide_water_filter: false
Wine Fridge (dual-zone, no freezer or ice maker)
subzero_appliance:
  - type: fridge
    id: wine_fridge
    ble_client_id: wine_fridge_ble
    name: "Wine Fridge"
    pin: "123456"
    hide_freezer: true
    hide_ice_maker: true
    hide_wine: false
Freezer-Only (e.g. DEC3050FI)
subzero_appliance:
  - type: fridge
    id: kitchen_freezer
    ble_client_id: kitchen_freezer_ble
    name: "Kitchen Freezer"
    pin: "123456"
    hide_fridge_zone: true

3. Compile and Flash

esphome run subzero.yaml --device /dev/cu.usbserial-210

See ESPHome Commands for OTA flashing, viewing logs, and more.

4. Pair Your Appliance

You need the 6-digit PIN from your appliance. There are two ways to get it:

  1. 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.

  2. 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 begin with 00:06:80. You can verify this using a Bluetooth scanner app on Android (iOS does not expose BLE MAC addresses), or by scanning BLE advertisements with a spare ESP32. On macOS, connect to the appliance with a Bluetooth scanner, then run system_profiler SPBluetoothDataType in Terminal to retrieve the BLE MAC address.

Troubleshooting

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 \n. This is the most common protocol mistake.

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.

Most sensors stuck at "unknown" / Status sensor reads "Pairing required"

The appliance returned status: 302 to the unlock attempt. This usually means its PIN rotated - some appliances assign a new pairing key after a power cycle, factory reset, or when the official app re-pairs. Press the Start Pairing button for that appliance in HA, watch the appliance display for the new 6-digit PIN, then enter it into the appliance’s PIN text input in HA. The next poll cycle will pick up full state. (You’ll also see [szg:###]: [Appliance] Pairing rejected (status 302) in the ESPHome logs.)

Poll-only sensors (model, uptime, version, diagnostic_status) only refresh every few minutes on a fridge or wall oven

Normal for fw 8.5 appliances. After the first poll on each connection, repeat polls go silent within the same BLE session, so the integration’s zombie detector forces a reconnect every ~3 missed cycles (~3 min). Each reconnect lands a fresh full-state poll which refreshes those fields. Push notifications (door, light, setpoint changes, etc.) continue between cycles, so live state stays current. See Reconnect Logic.

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 fast_connect: true and power_save_mode: none to your WiFi config.

"ACL packet too short" / first push notification lost / occasional Unknown on a fw 8.5 sensor

Fixed upstream - make sure you are on ESPHome 2026.7.1+. This was an ESP-IDF Bluedroid HCI bug that dropped short ACL continuation fragments, leaving the JSON reassembly buffer unbalanced and unparseable. It only ever affected fw 8.5 appliances (40-byte fragments); fw 2.27 (244-byte fragments) was unaffected. The fix landed in ESP-IDF 5.5.5, which ESPHome adopted in 2026.7.1. If you still see this on 2026.7.1+, check that you have not pinned an older framework: version: in your esp32: block. The integration remains tolerant of a bad payload either way: it lets the 60s periodic poll take another shot rather than publishing partial state. See ACL Fragment Drops for details.

Supported Sensors

Refrigerator/Freezer

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). Wine-only and freezer-only models don’t publish this - set hide_fridge_zone: true to hide the entity.

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). On models that wire the main door and drawer to a single switch (e.g. PRO3650G), this mirrors the Refrigerator Door state.

Crisper Drawer Set Temperature

Crisper drawer setpoint (°F) (optional)

Air Filter

Air filter on/off binary sensor (optional). This is the appliance’s "Air Purifier" toggle - confirmed writable, see Fridge Write Support.

Air Filter Remaining

Air filter life remaining (%) (optional)

Water Filter Remaining

Water filter life remaining (%) (optional)

Water Filter Gallons Remaining

Water filter life remaining (gallons), supported on some fridges (optional)

Water Filter Expires

Water filter expiration date (timestamp), supported on some fridges (optional)

Long Vacation Mode

On/off binary sensor (optional, hide_vacation_ice_modes)

Short Vacation Mode

On/off binary sensor (optional, hide_vacation_ice_modes)

High Usage Mode

On/off binary sensor, plus start/end time text sensors (optional, hide_vacation_ice_modes)

Max Ice Mode

On/off binary sensor, plus start/end time text sensors (optional, hide_vacation_ice_modes)

Night Ice Mode

On/off binary sensor (optional, hide_vacation_ice_modes)

Power On

Whether the unit is powered

Smart Grid Mode

Utility demand-response status flag. No corresponding control was found in the app or on the appliance’s display, and writes to it don’t take effect - treat as informational only (optional, hide_extra_diagnostics)

Pairing Window Open

Whether the appliance’s BLE pairing window is currently open (optional, hide_extra_diagnostics)

Door Ajar Alarm Timeout

Minutes before the door-ajar alarm triggers (optional, hide_extra_diagnostics)

WiFi Network / Signal / Channel / Encryption Type

The appliance’s own WiFi connection details, reported over BLE (optional, hide_extra_diagnostics)

Active Faults

Raw fault string, if the appliance reports one (observed as unpopulated on every unit tested so far) (optional, hide_extra_diagnostics)

Service Required

Alerts when the appliance flags a service need

Appliance Model

Model number (e.g. DEU2450R, 313)

Appliance Uptime

Time since last power cycle

Note
In addition to the read-only sensors above, several fridge properties are opt-in writable: setpoints, and the Ice Maker Mode / Appliance Mode / Night Mode / Humidity Control selects plus the Automatic Crisper Temperature / Air Purifier switches. See Fridge Write Support below.

Dishwasher

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. 2026-04-04T07:03)

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. DW2450, DW2450WS)

Appliance Uptime

Time since last power cycle

Range / Oven

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. DF36450GSP)

Appliance Uptime

Time since last power cycle

Dual-Oven Options

For ranges with two ovens, enable the second oven sensors using hide_oven2: "false"

Option Default Hides

hide_oven2

"true"

All Oven 2 sensors (temperature, door, light, probe, cook mode, etc.)

Writable Entities

In addition to the read-only sensors above, several properties are exposed as writable entities - HA’s Number entity for setpoints (with up/down controls and an input field) and HA’s Switch entity for toggleable booleans. Writing to one of these sends a set command to the appliance over BLE; the appliance acks and pushes the new value back, which keeps the entity state in sync if the value is also changed from the appliance’s front panel or the official Sub-Zero app.

Appliance Entity Property

Range

Oven Light, Oven Set Temperature, Probe Set Temperature

Toggle the oven cavity light, adjust the oven target temperature (200-550°F - the appliance won’t accept lower), adjust the meat probe target temperature (100-200°F)

Range (Oven 2)

Oven 2 Light, Oven 2 Set Temperature, Oven 2 Probe Set Temperature

Same as above for the second cavity (gated by hide_oven2)

Important
Oven Set Temperature only adjusts an already-running cycle. The appliance silently ignores writes to cav_set_temp / cav2_set_temp when the cavity is off. To use this entity, first start a cook mode (Bake, Roast, etc.) at the appliance’s front panel - once the oven is actively heating, HA can adjust the target temperature from there. Writing it from the off state does not turn the oven on. Probe Set Temperature behaves the same way (probe must be inserted with the appliance running in a probe-aware mode). This is an appliance-side restriction, not a limitation of the integration.
Note
Dishwasher light is intentionally read-only for now. The appliance acks set light_on (status:0) but the actual state never changes. Until that’s understood, it stays a read-only binary sensor so a misclick can’t risk altering a running appliance. Fridge set temperatures are a different story - see Fridge Write Support below for the actual reason they looked inert.
Note
Writes go to the D5 control channel (the same one used for unlocking and pairing). The appliance must be connected and paired - if the connection is down or the pairing window is closed (status 302), writes are dropped (logged as a WARN - see below) and the entity reverts on the next poll. The standard pairing flow is unchanged.

Fridge Write Support

Warning
Confirmed via live BLE testing against one appliance (Sub-Zero CL4850UFDID, firmware 2.27) on 2026-07-25 - option encodings and write behavior may differ on other models/firmware, so everything here is opt-in and defaults to the safe read-only behavior.

Two flags on a type: fridge subzero_appliance: entry unlock additional writable entities:

subzero_appliance:
  - type: fridge
    id: main_fridge
    ble_client_id: main_fridge_ble
    name: "Main Fridge"
    pin: "123456"
    enable_temp_control: true    # (1)
    enable_mode_selects: true    # (2)
  1. Turns Set Temperature, Freezer Set Temperature, and Crisper Drawer Set Temperature from read-only Sensors into writable Numbers, and adds an Automatic Crisper Temperature switch.

  2. Adds the Ice Maker Mode, Appliance Mode, Night Mode, and Humidity Control selects, and turns Air Filter into a writable switch.

enable_temp_control

Entity Behavior

Set Temperature

Writable Number. Confirmed to actually move the physical setpoint - verified against the front panel, not just the BLE-reported state.

Freezer Set Temperature

Writable Number. Confirmed via BLE readback (value changes and holds); not independently checked against the physical freezer display.

Automatic Crisper Temperature

New writable switch. The appliance ignores writes to the crisper setpoint whenever this is on (matches the "Automatic crisper temperature" toggle in the official app) - turn it off first.

Crisper Drawer Set Temperature

Writable Number, but the appliance silently ignores the write unless Automatic Crisper Temperature is off. This was previously assumed to be permanently inert (like dishwasher light); it turned out to just be gated by that mode flag.

enable_mode_selects

Entity Behavior

Ice Maker Mode (Off/Normal/Max Ice/Night Ice)

Grouped select - the BLE protocol has no dedicated "set mode" command, so choosing an option writes all three underlying booleans (ice_maker_on/max_ice_on/night_ice_on) individually. All four options confirmed round-tripping correctly.

Appliance Mode (Normal/High Usage/Short Vacation/Long Vacation/Sabbath)

Same grouped-write pattern across high_use_on/short_vacation_on/long_vacation_on/sabbath_on. All five options confirmed, including Sabbath.

Night Mode (Disabled/Enabled)

Single-field select, confirmed both directions. Wire encoding is a plain 0/1.

Humidity Control (Normal/Enhanced)

Single-field select, confirmed both directions. Wire encoding is 1=Normal / 2=Enhanced - notably not 0/1 like Night Mode. An earlier implementation assumed 0/1 here, which meant the write silently no-opped (the appliance ignores the invalid value 0) and the displayed label was backwards.

Air Filter

Turns from a read-only binary sensor into a writable switch. This is the appliance’s "Air Purifier" toggle - confirmed by turning it off on the display and observing this exact BLE field flip, then confirmed independently as a direct BLE write (true/false JSON boolean, not int). Both directions hold.

Note
Smart Grid Mode was briefly a writable switch here too, and has been reverted to a plain read-only sensor. Live testing confirmed writes don’t take effect - toggling it off in HA reverted back to true within seconds - and no corresponding control exists in the official app or the appliance’s own display. It’s documented as a regular sensor above (gated by hide_extra_diagnostics, available regardless of enable_mode_selects).

Every writable entity (both flags) shares one serialized write queue that drains one BLE write roughly every 750ms, regardless of which entity triggered it. Firing several writes back-to-back in the same moment was found to occasionally drop or corrupt one of them under live testing; this pacing is what prevents that.

Confirmed NOT exposed over BLE at all (2026-07-25, by diffing a full state poll before/after changing each on the physical display - no BLE field changed for any of these): Celsius/Fahrenheit unit, language, internal water dispenser on/off, interior light options, door alarm sound, and door alarm delay. These all appear to be purely local display preferences that never sync to the BLE state - there’s no known way to read or write them through this integration. (Door alarm on/off specifically wasn’t cleanly isolated during testing and remains untested rather than confirmed absent.)

"Clear Cloud Token" Diagnostic Button

A diagnostic button per appliance (hidden by default in the HA UI under "Diagnostic") sends set remote_svc_reg_token="" to the appliance, which deregisters it from the official Sub-Zero Azure IoT Hub. After pressing this button:

  • The official Sub-Zero/Wolf/Cove mobile app will no longer be able to reach the appliance over the cloud

  • The app will fall back to attempting BLE connections, which will fail because this integration’s ESP32 owns the single BLE connection slot

  • In effect, the appliance becomes "owned" by HA - useful if you want to fully decouple from the manufacturer’s cloud

This is reversible: the official app can re-register the appliance with cloud during a normal pairing flow.

Warning
Pressing this button will break any existing automations or shortcuts that the user (or their family members) have set up in the official app. Only do this if you understand the trade-off.

Diagnostics (All Appliances)

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. 17.5.2.0, 1.1.1.12)

Diagnostic Status

Hex bitmask of internal status flags (e.g. 0x00000003111)

Firmware Version

Main firmware version (e.g. 2.27, 8.5)

API Version

BLE API protocol version (e.g. 5.5)

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. main: 10.11.6877; mcb_ccm_lv: 9.4.4034; uim_typeA: 11.0.13). Sub-fields vary by appliance - parse in a HA template if you need individual values.

Build Date

Firmware build timestamp

Tested Appliances

Brand Model Type Status

Cove

DW2450

Dishwasher

Fully working

Cove

DW2450WS

Dishwasher with water softener

Fully working

Sub-Zero

BI36UFDID

Built-in refrigerator/freezer with ice maker

Fully working

Sub-Zero

CL44750SID

Refrigerator/freezer with ice maker

Fully working

Sub-Zero

CL4850SID

Refrigerator/freezer with ice maker

Fully working

Sub-Zero

CL4850UFDID

Refrigerator/freezer with ice maker (fw 2.27)

Fully working, including write support - temp control, Ice Maker Mode, Appliance Mode, Night Mode, Humidity Control, Automatic Crisper Temperature

Sub-Zero

DEU2450BG

Under-counter beverage center refrigerator

Fully working

Sub-Zero

DEU2450R

Under-counter refrigerator

Fully working

Sub-Zero

DEU2450WDZ

Under-counter wine storage, dual-zone

Fully working

Sub-Zero

IW30R

Wine storage, dual-zone

Fully working

Sub-Zero

IT36CIID

Refrigerator/freezer with ice maker

Fully working

Sub-Zero

313

French-door fridge/freezer with ice maker

Fully working

Sub-Zero

48SID

Refrigerator/freezer with ice maker

Fully working

Wolf

DF36450GSP

Dual-fuel range

Fully working

Wolf

DF48850SP

Dual-fuel range

Fully working

Wolf

IR36550ST

Induction range

Fully working

Wolf

SO3050PESP

Wall oven

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.

Further Reading

License

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.

Acknowledgments

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.

AI Disclaimer

AI was used to assist in inspecting how the Android APK handles BLE pairing and communication as well as creating documentation and troubleshooting steps. ESPHome YAML and C++ code was also generated with AI assistance.

About

Connect Sub-Zero Group kitchen appliances to Home Assistant over Bluetooth Low Energy, using an ESP32 running ESPHome

Topics

Resources

Stars

12 stars

Watchers

4 watching

Forks

Releases

Sponsor this project

Packages

Contributors

Languages