I wanted local control of my Sleep Number bed without relying on the cloud API, so I (with the help of my good pal Claude) reverse engineered the BLE protocol from the SleepIQ android app and built a custom integration that communicates directly with the bed over bluetooth.
Features are extremely limited at the moment:
left/right position preset
firmness
under bed light
working on getting bed presence detection working, but its super flakey so far.
how it works
The beds BAM module (the BLE/WiFi controller under the mattress) exposes a BLE GATT service using a binary protocol called MCR. The integration connects on demand, sends commands, reads status, and disconnects. It does not use a persistent connection.
The protocol was reverse-engineered by decompiling the SleepIQ Android APK and then validated through live testing against an i8 flextop bed.
current limitations
No push notifications - the bed is purely request/response, so presence and firmness must be polled, which sucks - but I’m working to see if we can change this.
Preset state - the bed doesn’t report its current foundation position over BLE, so preset selectors are fire-and-forget
I’d love feedback from anyone with a different Sleep Number bed - hopefully the protocol is similar but I’m sure there are variations. If you run into issues, please open a GitHub issue with your bed model and what’s going on!
i haven’t the slightest idea! but, i’m willing to work with you to try it out if you want - is it controllable via BT only? for example, if you logout of the mobile app, and instead of logging in, you just try to control the bed (It’ll connect via BT). if so, then you can give the HACs integration out
Yes, the standard adjustable base is controlled solely by a physical BT remote. It is not accessible via the SleepNumber app. I have a split king so I have 2 twin xl bases, each with its own BT control module and remote. And I have the i8 mattress. I will try to tinker with this more in the coming days and will share my results. Thanks for being so willing to help!
Ah, interesting - you’ll almost certainly need to take the batteries out of your remote for this to work, just an fyi. I had connection issues with my bed when i had my app open (and BT was connected). keep me posted, i’m happy to help!
This is exactly what I was hoping for but unfortunately it doesn’t work with my sleep number 360 smart bed
Here are the error logs:
This error originated from a custom integration.
Logger: custom_components.sleepnumber_ble.protocol
Source: custom_components/sleepnumber_ble/protocol.py:243
integration: Sleep Number BLE (documentation, issues)
First occurred: 7:51:44 AM (11 occurrences)
Last logged: 7:58:04 AM
Error communicating with bed at 80:16:09:00:74:E7
Traceback (most recent call last):
File "/config/custom_components/sleepnumber_ble/protocol.py", line 243, in async_connect_and_read
client = await self._connect_and_init(device)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/config/custom_components/sleepnumber_ble/protocol.py", line 230, in _connect_and_init
await client.start_notify(MCR_TX_UUID, self._notification_handler)
File "/usr/local/lib/python3.14/site-packages/bleak/__init__.py", line 834, in start_notify
characteristic = _resolve_characteristic(char_specifier, self.services)
File "/usr/local/lib/python3.14/site-packages/bleak/__init__.py", line 411, in _resolve_characteristic
raise BleakCharacteristicNotFoundError(char_specifier)
bleak.exc.BleakCharacteristicNotFoundError: Characteristic ffffd1fd-388d-938b-344a-939d1f6efee1 was not found!
Using nrf connect, here’s the characteristics on my bed:
Dangit, yeah - this was what I was concerned would happen. It looks like the newer beds that use fuzion dont share the same characteristics as the old protocol. I’m guessing that even if we find the right characteristics for tx/rx, there is a good chance that the MCR protocol is different.
so, if you’re willing to work, we can see if we can at least see if MCR is compatible with fuzion. first, make sure that no phones or esp devices are connected to the bed. then, in nrf connect:
connect to the bed, expand the service 09d23fae-90e6-44c2-95b6-0b3d0f1abf25 and for each of the 7 characteristics, note the properties listed (read, write, write without response, notify, indicate). once we have that, we can at least see if we can handshake w/ the bed.
All of them seem to have a Characteristic extended properties of 0x2900 which usually has a value of (0x) 0C-00,except for the 8d4675a5 which has (0x) 04-00 and e8d06e2a which has (0x) 0D-00
The ones with the notify property have a UUID of 0x2902 and the value is notifications enabled.
hm, this is quite different than the legacy beds. for each of those characteristics, can you read and share the hex value returned when you tap the down arrow on each?
Yea all of them are empty except for:
8d4675a5-b5fa-42b2-b587-0ee71c46b709: EXTENDED PROPS, READ
Value: 72-93-48-4A-D9-36-4B-33-99-D0-21-AC-84-07-42-E6
and
e8d06e2a-c987-48f8-93a8-4d18d56b4337: EXTENDED PROPS, READ, WRITE
Value: 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
so, for each of the ones that DO support notify, can you tap the triple down arrow to subscribe to notifications. wait at least 30sec and then perform some operations on the bed and see if they get any data?
This app won’t work for my base but the HA-Adjustable Base via HACS did work. Sleep Number uses the Richmat BLE controller with Legget & Platt motors. Maybe this will help others with a similar setup.
Thanks again for your time, effort and contribution!