[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 different device types per bed side. 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.

Updates
v4.1.4

  • [FIXED] Bug when setting lighting from component

v4.1.3

  • [UPDATED] Added sleep sensor capability and ranges for lighting and foot warming courtesy of @kewashi. Details in this post.

v4.1.2

  • [UPDATED] Added ability to skip providing core climate duration, will default to 30 minutes

v4.1.1

  • [UPDATED] Added support for core climate controls

v4.0.2

  • [FIXED] fixed testing glitch that caused async retries all the time

v4.0.1

  • [FIXED] resolved bug in async retry logic that caused a NullPointerException

v4.0.0

  • [UPDATED] Adds support for Climate 360 and P6 beds
  • Removed Virtual Container support

v3.3.2

  • [FIXED] Resolved a bug that was preventing setting the sleep number and sleep number favorite

v3.3.1

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

v3.2.9, v3.3.0

  • [FIXED] bug fix releases

v3.2.8

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

v3.2.7

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

v3.2.6

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

v3.2.5

  • [FIXED] More bug fixes

v3.2.4

  • [FIXED] Bug fixes for issues introduced in 3.2.2

v3.2.3

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

v3.2.2

  • [UPDATED] Multiple optimizations

v3.2.1

  • [UPDATED] Added more help text

v3.2.0

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

v3.1.9

  • [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.

v3.1.8

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

v3.1.7

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

v3.1.6

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

v3.1.5

  • [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.

v3.1.4

  • [FIXED] Fixed bed device creation naming.

v3.1.3

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

v3.1.2

  • [FIXED] Removed bogus log line

v3.1.1

  • [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.

v3.1.0

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

v3.0.9

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

v3.0.8

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

v3.0.7

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

v3.0.6

  • [FIXED] Internal cleanup

v3.0.5

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

v3.0.4

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

v3.0.3

  • [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.

v3.0.2

  • [FIXED] Fixed bug preventing sleep data collection

v3.0.1

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

v3.0

  • [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

v2.3.3

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

v2.3.2

  • [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.

v2.3.1

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

v2.3

  • [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)

v2.2

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

v2.1

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

v2.0.1

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

v2.0

  • [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

v1.9

  • [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.

v1.8

  • [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.

v1.7

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

v1.6

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

v1.5

  • [FIXED] Actually set the sleep number when asked

v1.4

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

v1.3

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

v1.2

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

v1.1

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

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.

1 Like

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

2 Likes

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