[RELEASE] Sleep Number Controller - control your Sleep Number bed and use it for presence

[RELEASE] Sleep Number Controller - control your Sleep Number bed and use it for presence

Inspired by the SleepIQ App I was using and requests for new features in that thread, I created a new app + driver that allows more control of a Sleep Number bed.

This can be used to create up to 4 device types per bed side, optionally collected in a Virtual Container. Each device exposes the same basic commands but differs in how on/off/dim behave so that you can control the different parts of the bed using a voice assistant.

  1. Presence: This is assumed to be the basic type if you only install one and dimmer will set the Sleep Number value.
  2. Head: This allows controlling the head of the bed via dimmer.
  3. Foot: This allows controlling the foot of the bed via dimmer.
  4. Foot Warmer: This allows controlling the foot warmer of the bed via dimmer and on/off.
  5. Underbed Lighting: on/off
  6. Outlets (if your bed has them): on/off

In 1, 2 and 3, on/off toggles between a preset and flat (where preset is a preference for that device).

More details along with installation notes can be found here which describes how the different settings work as well as other supported commands like privacy mode.

Feel free to leave questions here or if you find bugs, you can note them here or in the github issue tracker and I'll do my best to answer (or fix) them as time permits.

Note: This does not work properly with the new SleepNumber Climate360 beds yet. SN has changed the entire control API to a new format and it will take some time to integrate this into the existing code (and I'll have to work with a volunteer to test as I do so).


  • [UPDATED] submitOnChange is now false for password field to avoid autofill problems on iOS

v3.2.9, v3.3.0

  • [FIXED] bug fix releases


  • [UPDATED] Performance improvements contributed by imnotbob
  • [ADDED] Now supports setting sleep number favorite (also contributed by imnotbob)


  • [FIXED] Only dispatch connection state event upon a change


  • [FIXED] Changed ordering of bed lighting calls to make sure it works correctly (SN is order dependent apparently)


  • [FIXED] More bug fixes


  • [FIXED] Bug fixes for issues introduced in 3.2.2


  • [UPDATED] Added new connection state to the driver to show API status


  • [UPDATED] Multiple optimizations


  • [UPDATED] Added more help text


  • [UPDATED] Added multiple bed support (courtesy of Peter Nealy).


  • [UPDATED] Added ability to set responsive air (this will change the value but no attribute is updated, if you need the attribute see the next feature)
  • [UPDATED] Added attribute for responsive air, optional based on preference (it will require an additional HTTP request during polling)
  • [UPDATED] Beta: Use AWS OAuth instead of SleepNumber cookie for login. Toggle this in the app.


  • [FIXED] Changed login handling to allow more special characters in the password.


  • [FIXED] Allows logLevel to be null (unset). If this happens, it will be treated as info level logging.


  • [UPDATED] Added ability to select desired log level.


  • [UPDATED] Added a switch to disable refreshes. Useful if you'll be on vacation for a while and want to minimize traffic to SleepNumber servers.


  • [FIXED] Fixed bed device creation naming.


  • [FIXED] Updated refresh interval handling to fix bug changing from day to night.


  • [FIXED] Removed bogus log line


  • [UPDATED] Added ability to use modes instead of time to control refresh intervals.
  • [UPDATED] Added ability to set a numeric value in minutes controlling how often an error log will be emitted during request failures.


  • [UPDATED] Added a request queue for foundation adjustments so that multiple sequential requests won't clobber each other.


  • [FIXED] Resolved but that was breaking sleep data.


  • [UPDATED] Minor bug fixes and avoids untyped objects (mostly) in driver.


  • [FIXED] Avoid errors when level isn't yet available on child devices.


  • [FIXED] Internal cleanup


  • [ADDED] Now supports variable refresh interval schedules (day/night) in order to reduce hub and SleepIQ load during the day.


  • [FIXED] Improved error handling for outlet and lighting so that errors aren't repeated in a single update pass.


  • [FIXED] Now uses head/foot device presence to determine when to poll for foundation status. Note if this emits errors for you and your bed has distinct head/foot controls in the SleepIQ app, please DM me so we can sort out details. If you do not have distinct head/foot then removing the devices will eliminate the errors.
  • [UPDATED] No longer sends child events if the values have not changed. This avoids needless descriptionText logging.


  • [FIXED] Fixed bug preventing sleep data collection


  • [FIXED] Now always send events to child devices to make sure state is correct


  • [ADDED] New parent/child driver structure leveraging HE Generic Component devices for simpler code. (Note: for now the old structure is also available).
  • [ADDED] Ability to pause app.
  • [ADDED] Outlet control
  • [UPDATED] New device listing to show parent/child devices and also now link to devices


  • [FIXED] fix from imnotbob to avoid using same method for schedule and runIn (apparently not good in HE)


  • [FIXED] changed how cache works to (hopefully) avoid NPE when updating child data. For now this only resets cache if a preference (say refresh interval) is updated.


  • [FIXED] no longer caches bed info when preferences are updated so that integrated bases and other changes are properly detected.


  • [UPDATED] Added control of underbed lighting
  • [FIXED] Now properly honors mode setting in app and won't automatically poll when modes are selected but the current mode is not in the selected list
  • [FIXED] If the base is integrated, now skip foundation status (which apparently is unavailable on these bases)


  • [UPDATED] Added setSleepNumberFavorite command and favorite attribute to device.
  • [UPDATED] Added status indicator to app label (for easy visibility in app list)


  • [FIXED] Bug due to missing setLevel with duration argument
  • [FIXED] Bug collecting sleep data when there are no sessions.


  • [UPDATED] Added diagnostics support for arbitrary HTTP commands and there's now a device id per row in the bed summary section.


  • [UPDATED] Added CSS selectors to sleep tiles
  • [FIXED] Refreshed HTTP handling to try to avoid repeated failing calls
  • [FIXED] Will now refresh sleep data attributes when preference is enabled


  • [UPDATED] Changed sleep data tiles to rely on viewport size for font size and removed 2x wide preference. The font should now resize based on browser size being used.


  • [ADDED] new ability to collect sleep data and present individual attributes as well as summary tiles. See documentation for more details and a sample tile.


  • [FIXED] Now sets level per sleep number for presence device type


  • [FIXED] Bug updating beds when there's no base/foundation.


  • [FIXED] Actually set the sleep number when asked


  • [FIXED] Login issues with some username/password variations


  • [FIXED] app will reinitialize bed info state when new beds are added


  • [ADDED] app now uses bed information to avoid processing foot warmer unless a warming component is present


  • [ADDED] new diagnostics page in app to show bed information

Nice - Thanks for developing this and making it available!

Thank you! I will add this to my growing number of things to hopefully help me automate one of my beds in future. I have one side with Alexa integration and the other uses 2.4ghz RF remote (Leggett & Platt Comfort Elite) and Iā€™m trying to devise a way to control it, even if that means switching out the entire control unit to a 433mhz receiver on the bed itself.

1 Like

There is a LOT of work in this driver and app, thank you for all of your time and effort!

I was able to add the app code and driver code with no errors. When I go to the Add User App I can enter my username/password, but when I hit "Create New Bed" I get an Unexpected Error with "Error: Cannot invoke method size() on null object". I enabled Debug in the App and in the logs I see what looks to me like maybe a failure to process the login via the API. Here is what I see in the log:

It repeats the login over and over with the "Bad Request", I only get the error referring to line 193 when I try to "Create New Bed". I can somewhat follow the code, to me it looks like homePage calls findBedPage, which calls getBedData, which calls getFamilyStatus, which doesn't have a login function, so I'm not sure how that gets included. Unfortunately I am not familiar with Groovy, so I'm stuck and cannot determine where the failure is happening. The "SleepIQ Manager" app works with the same username/password, so my account should be fine.
Any idea where the failure is occurring? Is there a way to get the app to dump everything it's doing? Maybe there are more detailed errors that could help determine where the problem could be.

Sorry it's not working for you. getFamilyStatus calls httpRequest which has logic to try to login if needed. It looks like login is failing with a Bad Request error which leads to an invalid response to /rest/bed/familyStatus and subsequently the NPE.

It's interesting you say SleepIQ Manager works because the login method used there is pretty similar. One thing I notice, which may matter, is that I didn't quote the json values. Can you try changing line 673 to:
body: "{'login':'${settings.login}', 'password':'${settings.password}'}="

and let me know? If that fixes it, I'll update the repo with a new version and if not I'll keep thinking :slight_smile:

Yep, that fixed it. I never would have found that. Thank you!

Interesting, it must be character dependent then as it works fine with my username and password. I'll get an updated version out later tonight or tomorrow and if you're using the HPM install method you should just get the fix (which will replace your manual fix).

[edit] an update has been published, version 1.4 has the fix

That would make sense. I use a random password generator so I'm sure I have a couple of "special characters" in there that would have confused the process. Thanks again for the help, and the quick reply!

Sorry, I have one more question. When I go to the device and set the sleep number, I see "setSleepNumber(45)" in the log. I see that in the driver:
def setSleepNumber(val) {
debug "setSleepNumber(${val})"
Since it isn't doing anything except logging the request I'm guessing it is possible through the API (or you wouldn't have bothered creating the item in the App), it just hasn't been coded yet, correct? If that is the case, I can try writing that section, and if it works, send it to you. I ask so I'm not trying to write something you may be working on behind the scenes.

Oops, how embarrassing :confounded: I totally meant to wire that up and must've completely spaced. It's not something I ever use so I didn't notice I'd missed it (I added it to the doc though so clearly thought I'd done it). Thanks for flagging it!

I can definitely get that added later tonight and feel somewhat dumb for missing it. It involves a pretty small amount of code to add:

  1. a new setter in the app that looks like setFoundationPreset but the number is the pressure/sleepnumber the http request is for /rest/bed/<bedid>/sleepNumber
  2. the driver needs to call sendToParent with the right values

Edit: Updated to v1.5 which fixes the sleep number plumbing (and a typo).

No worries. I don't know Groovy, but I do a lot in PHP (for fun), and I have added functions and then forgot to link to them to anything. It's always fun when I go back into the code and realize I already wrote something, just never enabled it. :slight_smile: Thank you for the quick response and update!

Which Sleep Number models does this work with?

I only have a Flexfit3 foundation + i8 bed to test with but it should work with any bed that can be controlled via the SleepIQ mobile app. If you find it doesn't, please turn on debugging and provide a screenshot or paste of the logs along with what went wrong and I'll try to take a look.

1 Like

Installed using hubitat package installer. Ran the setup on the app and created beds for the left and right side, just the basic as all I have on mine is presence and sleep number. However, when adding to the dashboards, I get no sliders. Is there a reason for that?

What shows up on the dashboard depends on the template you choose and I think, by default, it picks presence. If you select dimmer, you should get a slider which, for your selected device, should be the sleep number setting.

Screen Shot 2020-08-27 at 8.52.13 AM Screen Shot 2020-08-27 at 8.52.27 AM


Okay, added the tile with the slider. However, it doesn't appear to be changing anything. Manually used my SleepIQ app to set 100. Then moved the slider to 65. No change. So I toggled the dimmer on. Still no change. Toggled it back off, still no change.

Also, both beds are empty but showing as present. :man_shrugging:

You have to change in increments of 5 i believe.

No Joy on that either. Will keep playing around

Check the log for failures. Enable debug logging if you dont see anything.

Correct, it's increments of 5.

@tray_e - if you turn on debug logs and then post logs when you make changes I can try to help. Also, if you post your dashboard and the device that'd be helpful as they should match (unclear if you're saying they don't or not).