SleepIQ Footwarmers not being added after update
The problem
I have a Climate360 split king. It includes foot warmers and climate.
I updated my HA to 2024.1.1, and the new foot warmer entities are not being added for the SleepIQ integration.
I have deleted the device and added it again, I have deleted the device, rebooted my HA server and went through the flow to add it again and no success.
What version of Home Assistant Core has the issue?
2024.1.1
What was the last working version of Home Assistant Core?
No response
What type of installation are you running?
Home Assistant Container
Integration causing the issue
SleepIQ
Link to integration documentation on our website
https://www.home-assistant.io/integrations/sleepiq/
Diagnostics information
Not available in the UI
Example YAML snippet
No response
Anything in the logs that might be useful for us?
No response
Additional information
No response
Hey there @mfugate1, @kbickar, mind taking a look at this issue as it has been labeled with an integration (sleepiq) you are listed as a code owner for? Thanks!
Code owner commands
Code owners of sleepiq can trigger bot actions by commenting:
@home-assistant closeCloses the issue.@home-assistant rename Awesome new titleRenames the issue.@home-assistant reopenReopen the issue.@home-assistant unassign sleepiqRemoves the current integration label and assignees on the issue, add the integration domain after the command.@home-assistant add-label needs-more-informationAdd a label (needs-more-information, problem in dependency, problem in custom component) to the issue.@home-assistant remove-label needs-more-informationRemove a label (needs-more-information, problem in dependency, problem in custom component) on the issue.
(message by CodeOwnersMention)
sleepiq documentation sleepiq source (message by IssueLinks)
The climate360 line uses a pretty different API. Someone will need to find the codes to send to control them.
How would I do that? Any guides? Or is it just do a MITM and try to capture the commands?
@ClayBenson94 figured it out for the rest of the commands. I think he did it by decompiling the app.
Here's the initial discussion: https://github.com/kbickar/asyncsleepiq/issues/12
Ahh okay. What are next steps?
There are a few codes that might be of interest:
FWPG = "GetFootwarmingPresence"
FWTS = "SetFootwarmingSettings"
FWTG = "GetFootwarmingSettings"
I need to know the json payload sent and the response from those.
Here is what I found after doing a MITM.
FWPG was not present in the 60+ calls the app made.
FWTG
Request
{ "sourceApplication": "iOS Consumer Mobile App", "key": "FWTG", "args": "right"}
Response
{ "cdcResponse": "PASS:low 120 120"}
FWTS
Request
{ "args": "right low 120", "sourceApplication": "iOS Consumer Mobile App", "key": "FWTS"}
Response
{ "cdcResponse": "PASS:"}
I'm guessing the 360 might behave differently from some others because it not only has foot heating but also core heating and core cooling options, so they might represent the options a bit differently.
I can confirm though, that I don't see the door warming stuff in HA with the newest update -- let me know if I can help gathering responses from the app! It's been a while since I set it up but I can take a swing
I did more tracing and did a bit of data mapping.
This includes setting the footwarmer and the climate for the bed.
Let me know what else I can provide. climate_360_requests.csv
This is very helpful! Are you able to see if the GetSystemConfiguration returns something relating to foot warming? Need to know if it's supported on a bed
Sure thing.
This call was not made by the app, so I replicated the calls in Postman and changed the code to test the code SYCG for GetSystemConfiguration.
Here are the results
URL: https://prod-api.sleepiq.sleepnumber.com/rest/sn/v1/accounts/<account-id>/beds/<bed-id>/bamkey
Request Body:
{"sourceApplication":"iOS Consumer Mobile App","args":"","key":"SYCG"}
Response Body:
{"cdcResponse": "PASS:dual yes yes yes yes heat_cool yes yes yes yes yes yes yes yes yes yes"}
Since I was just grabbing requests from my iphone to test your earlier ask about codes, I decided to test the one I couldnt find earlier.
Note: The arguments requires left or right. If you don't pass the arguments it will fail.
FWPG
URL: https://prod-api.sleepiq.sleepnumber.com/rest/sn/v1/accounts/
Request Body:
{"sourceApplication":"iOS Consumer Mobile App","args":"right","key":"FWPG"}
Response Body:
{"cdcResponse": "PASS:1"}
I update the library on this branch: https://github.com/kbickar/asyncsleepiq/tree/fuzion-foot
Are you able to test if that works to set the foot warmer?
Happy to try, how should I test? (Meaning, how do I test your branch?)
Take the example code and add to the end of the main() function:
print(f"Foot Warmers: {bed.foundation.foot_warmers}")
await bed.foundation.foot_warmers[0].set_foot_warming(FootWarmingTemps.HIGH, 20)
This should print out the foot warmer info and then set it to high for 20 seconds
Ignore this, I realized I forgot to import the FootWarmerTemps class. Testing again.
~~Here is the error output~~
Logging in as <my-email>...
Initializing bed data...
Beds:
SleepIQBed(<bed name>, model=CLIMATE360, id=<bed-id>) [SleepIQSleeper[Side.LEFT](<wifes-name>, in_bed=False, sn=70), SleepIQSleeper[Side.RIGHT](<my-name>, in_bed=False, sn=75)] SleepIQFoundation[](lights: 1, features: 23, actuators: 4, presets: 2)
Pause mode: False
New Pause mode: True
Calibrating...
Stopping pump...
Foot Warmers: [SleepIQFootWarmer[Side.LEFT]: Off, 0, OFF, SleepIQFootWarmer[Side.RIGHT]: Off, 0, OFF]
Traceback (most recent call last):
File "C:\Users\<my-username>\downloads\asyncsleepiq-fuzion-foot\main.py", line 38, in <module>
asyncio.get_event_loop().run_until_complete(main())
File "C:\Python311\Lib\asyncio\base_events.py", line 653, in run_until_complete
return future.result()
^^^^^^^^^^^^^^^
File "C:\Users\<my-username>\downloads\asyncsleepiq-fuzion-foot\main.py", line 36, in main
await bed.foundation.foot_warmers[0].set_foot_warming(FootWarmingTemps.HIGH, 20)
^^^^^^^^^^^^^^^^
NameError: name 'FootWarmingTemps' is not defined
Unclosed client session
client_session: <aiohttp.client.ClientSession object at 0x0000027894D84E50>
Unclosed connector
connections: ['[(<aiohttp.client_proto.ResponseHandler object at 0x00000278956BDFD0>, 96867.39)]', '[(<aiohttp.client_proto.ResponseHandler object at 0x00000278956BCF30>, 96878.437)]']
connector: <aiohttp.connector.TCPConnector object at 0x0000027894D84E90>``
Add from asyncsleepiq import AsyncSleepIQ, LOGIN_KEY, FootWarmingTemps at the top
Thanks! I noticed that and was already testing again.
TLDR: It worked!
There was another bug in the API call that I put a quick fix in to get around to test the full flow.
asyncsleepiq\fuzion\foot_warmer.py
Line: 18
Original Code:
args = [SIDES_FULL[self.side].lower(), temperature.name.lower(), time]
My Quick Fix Code:
args = [str(SIDES_FULL[self.side].lower()), str(temperature.name.lower()), str(time)]
The string join complained that there was an int when it was expecting a string. So I just did a cast to string on everything to work around it. I haven't written much in python in a while, so I am not sure what the right permanent fix should be.
Here is the output from the error of the string join.
Logging in as <my-username>...
Initializing bed data...
Beds:
SleepIQBed(<bed-name>, model=CLIMATE360, id=<bed-id>) [SleepIQSleeper[Side.LEFT](<wife's name>, in_bed=False, sn=70), SleepIQSleeper[Side.RIGHT](<my-name>, in_bed=False, sn=75)] SleepIQFoundation[](lights: 1, features: 23, actuators: 4, presets: 2)
Pause mode: True
New Pause mode: False
Calibrating...
Stopping pump...
Foot Warmers: [SleepIQFootWarmer[Side.LEFT]: Off, 0, OFF, SleepIQFootWarmer[Side.RIGHT]: Off, 0, OFF]
Traceback (most recent call last):
File "C:\Users\<username>\downloads\asyncsleepiq-fuzion-foot\main.py", line 38, in <module>
asyncio.get_event_loop().run_until_complete(main())
File "C:\Python311\Lib\asyncio\base_events.py", line 653, in run_until_complete
return future.result()
^^^^^^^^^^^^^^^
File "C:\Users\<username>\downloads\asyncsleepiq-fuzion-foot\main.py", line 36, in main
await bed.foundation.foot_warmers[0].set_foot_warming(FootWarmingTemps.HIGH, 20)
File "C:\Users\<username>\downloads\asyncsleepiq-fuzion-foot\asyncsleepiq-fuzion-foot\asyncsleepiq\fuzion\foot_warmer.py", line 19, in set_foot_warming
await self._api.bamkey(self.bed_id, "SetFootwarmingSettings", args)
File "C:\Users\<username>\downloads\asyncsleepiq-fuzion-foot\asyncsleepiq-fuzion-foot\asyncsleepiq\api.py", line 172, in bamkey
"args": " ".join(args),
^^^^^^^^^^^^^^
TypeError: sequence item 2: expected str instance, int found
Unclosed client session
client_session: <aiohttp.client.ClientSession object at 0x0000022BECD4D250>
Unclosed connector
connections: ['[(<aiohttp.client_proto.ResponseHandler object at 0x0000022BECD45B70>, 97166.296)]', '[(<aiohttp.client_proto.ResponseHandler object at 0x0000022BECD451D0>, 97175.593)]']
connector: <aiohttp.connector.TCPConnector object at 0x0000022BECD4CC50>
Log output of working test after fixing the string join. (I confirmed it showed up in the app too)
Logging in as <username>...
Initializing bed data...
Beds:
SleepIQBed(<bedname>, model=CLIMATE360, id=<bed-id>) [SleepIQSleeper[Side.LEFT](<wife's-name>, in_bed=False, sn=70), SleepIQSleeper[Side.RIGHT](<my-name>, in_bed=False, sn=75)] SleepIQFoundation[](lights: 1, features: 23, actuators: 4, presets: 2)
Pause mode: True
New Pause mode: False
Calibrating...
Stopping pump...
Foot Warmers: [SleepIQFootWarmer[Side.LEFT]: Off, 0, OFF, SleepIQFootWarmer[Side.RIGHT]: Off, 0, OFF]
Unclosed client session
client_session: <aiohttp.client.ClientSession object at 0x0000018A64E1D250>
Unclosed connector
connections: ['[(<aiohttp.client_proto.ResponseHandler object at 0x0000018A64E15B00>, 97708.562)]', '[(<aiohttp.client_proto.ResponseHandler object at 0x0000018A64E15160>, 97719.187)]']
connector: <aiohttp.connector.TCPConnector object at 0x0000018A64E1CC50>
This is probably a different issue that is a feature request.
I would be willing to spend some time testing/developing adding support for the climate (bed heating/cooling) functionality of my bed. Would that be something you're open to adding to the library as well?
Great! I'll make the fix and publish a new release of the library.
For other climate controls that would be a new feature. If you'd like to help we could start a new issue for it: https://github.com/kbickar/asyncsleepiq/issues