GithubHelp home page GithubHelp logo

Support Climate360 Model about asyncsleepiq HOT 26 CLOSED

kbickar avatar kbickar commented on September 14, 2024
Support Climate360 Model

from asyncsleepiq.

Comments (26)

rvrolyk avatar rvrolyk commented on September 14, 2024 1

@ClayBenson94 - I wrote a SleepNumber integration for Hubitat and someone is asking about this bed as well (and ran into the same problems). Would you mind sharing the request/response info with me as well? If that's ok with you, you can just email them to me at [email protected]. Thanks!

from asyncsleepiq.

ClayBenson94 avatar ClayBenson94 commented on September 14, 2024

Some things I've found so far:

When calling to https://prod-api.sleepiq.sleepnumber.com/rest/bed/{ID}/foundation/system, the response is:

{
  "Error": {
    "Code": 400,
    "Message": "Cannot send the MCR request to Fuzion device"
  }
}

This lines up with what comes back from https://prod-api.sleepiq.sleepnumber.com/rest/bed (with some personal stuff redacted with ...):

{
  "beds": [
    {
      "registrationDate": "...",
      "sleeperRightId": "...",
      "base": null,
      "returnRequestStatus": 0,
      "size": "KING",
      "name": "...",
      "serial": "",
      "isKidsBed": false,
      "dualSleep": true,
      "bedId": "...",
      "status": 1,
      "sleeperLeftId": "...",
      "version": "",
      "accountId": "...",
      "timezone": "US/Eastern",
      "generation": "fuzion",
      "model": "CLIMATE360",
      "purchaseDate": "...",
      "macAddress": "...",
      "sku": "KC360",
      "zipcode": "...",
      "reference": "..."
    }
  ]
}

from asyncsleepiq.

kbickar avatar kbickar commented on September 14, 2024

If you could login to https://sleepiq.sleepnumber.com with the chrome dev tools open to the "network" tab, see if the message to system is different or if there's another message that contains the lights/foundation data

from asyncsleepiq.

ClayBenson94 avatar ClayBenson94 commented on September 14, 2024

Hmm - logged in on the site and I don't hardly see any network requests (or UI, for that matter) that lets me see the lights / foundation state. It all seems to focus on sleep data, wellness profiles, family status, etc.

When you use the site, do you have the ability to edit the base / turn on the light?

from asyncsleepiq.

ClayBenson94 avatar ClayBenson94 commented on September 14, 2024

Perhaps I could use something like ProxyMan to monitor the requests that my mobile app makes, since it definitely has the capacity to view/edit those properties?

from asyncsleepiq.

kbickar avatar kbickar commented on September 14, 2024

Unfortunately they don't include everything on the website. If you're able to get the messages from the mobile app, that would work too

from asyncsleepiq.

ClayBenson94 avatar ClayBenson94 commented on September 14, 2024

Unfortunately they don't include everything on the website. If you're able to get the messages from the mobile app, that would work too

No dice - looks like ProxyMan doesn't allow monitoring SSL requests for which you're not the app owner :(

The only thing I've been able to notice that's different between the requests made by AsyncSleepIQ and the website are that the website seems to tack on an Accept-Version: 4.8.20 header to rest/bed, which makes the response contain a ton more info than without it:

{
  "beds": [
    {
      "generationToExchange": null,
      "registrationDate": "...",
      "sleeperRightId": "...",
      "components": [
        {
          "base": "ADJUSTABLE",
          "productclassification": null,
          "size": "KING",
          "serial": "",
          "parentId": "95014548711:1-1UA2NKE6:P",
          "type": "Bed (double)",
          "installDate": "...",
          "dualSleep": true,
          "status": "INSTALLED",
          "version": "",
          "componentId": "...",
          "installer": "...",
          "subgeneration": "C360",
          "model": "CLIMATE360",
          "purchaseDate": "...",
          "orderNumberToExchange": null,
          "sku": "KC360",
          "reference": "...",
          "hasPendingReturn": false
        },
        {
          "base": null,
          "productclassification": null,
          "size": null,
          "serial": "",
          "parentId": "...",
          "type": "Pump",
          "installDate": "...",
          "dualSleep": false,
          "status": "INSTALLED",
          "version": "",
          "componentId": "...",
          "installer": null,
          "subgeneration": "C360",
          "model": "Smart Control System, King FF23",
          "purchaseDate": "...",
          "orderNumberToExchange": null,
          "sku": "125874",
          "reference": "...",
          "hasPendingReturn": false
        },
        {
          "base": null,
          "productclassification": null,
          "size": null,
          "serial": "",
          "parentId": "...",
          "type": "Base",
          "installDate": "...",
          "dualSleep": false,
          "status": "INSTALLED",
          "version": "",
          "componentId": "...",
          "installer": "...",
          "subgeneration": "C360",
          "model": "King C360 FF Adjustable Base",
          "purchaseDate": "...",
          "orderNumberToExchange": null,
          "sku": "KFAC360",
          "reference": "...",
          "hasPendingReturn": false
        },
        {
          "base": null,
          "productclassification": null,
          "size": null,
          "serial": "",
          "parentId": "...",
          "type": "Thermal Unit",
          "installDate": "...",
          "dualSleep": false,
          "status": "INSTALLED",
          "version": "",
          "componentId": "...",
          "installer": "...",
          "subgeneration": "C360",
          "model": "C360 Thermal Module, Qty 2",
          "purchaseDate": "...",
          "orderNumberToExchange": null,
          "sku": "125818",
          "reference": "...",
          "hasPendingReturn": false
        },
        {
          "base": null,
          "productclassification": null,
          "size": null,
          "serial": "",
          "parentId": "...",
          "type": "Warming",
          "installDate": "...",
          "dualSleep": false,
          "status": "INSTALLED",
          "version": "",
          "componentId": "...",
          "installer": "...",
          "subgeneration": "C360",
          "model": "ASSY,FOOT WARMING,2 UNIT,GEN6",
          "purchaseDate": "...",
          "orderNumberToExchange": null,
          "sku": "126011",
          "reference": "...",
          "hasPendingReturn": false
        }
      ],
      "returnRequestStatus": 0,
      "size": "KING",
      "name": "...",
      "hasSnore": false,
      "fccId": "TLZ-CM276NF",
      "isKidsBed": false,
      "dualSleep": true,
      "bedId": "...",
      "status": 1,
      "sleeperLeftId": "...",
      "accountId": "...",
      "timezone": "US/Eastern",
      "generation": "fuzion",
      "macAddress": "...",
      "zipcode": "..."
    }
  ]
}

from asyncsleepiq.

kbickar avatar kbickar commented on September 14, 2024

Hmm still wouldn't have any way to control the parts

from asyncsleepiq.

ClayBenson94 avatar ClayBenson94 commented on September 14, 2024

@kbickar I have patched my SleepIQ app on my phone to support custom CA certificates, and am proxying requests from the App to my laptop so I can monitor them. I am able to see network requests for things like setting temperature, raising the legs, etc.

It looks pretty different for this bed - what would be a good way to share this with you?

from asyncsleepiq.

kbickar avatar kbickar commented on September 14, 2024

Do you want to just email me the requests to [email protected]?

from asyncsleepiq.

ClayBenson94 avatar ClayBenson94 commented on September 14, 2024

Yeah, I think what I'll do is spend some time with my laptop by the bed trying out different requests so I can see if I can categorize requests by things like setting presets, turning lights on, setting sleep numbers, etc. that way you don't have to just dig through a bunch of random requests. That work? (Might be a day or two before I can totally compile a good list)

from asyncsleepiq.

kbickar avatar kbickar commented on September 14, 2024

That would be great!
Things we need are:

  • address sent to
  • json data in request
  • json data in response

from asyncsleepiq.

ClayBenson94 avatar ClayBenson94 commented on September 14, 2024

I am taking a crack at trying to introduce this feature myself, but one of the big initial roadblocks I'm getting is that when my app calls to /rest/bed, it passes Accept-Version: 4.8.20, which results in a wildly different response format (in my comment) than the normal call to /rest/bed, which is what's used to actually construct the Bed object.

I'll keep cracking at it, but if I can't make it work well with the way stuff's laid out, I'll just send you the annotated responses and hopefully you can help figure out how to best incorporate it @kbickar!

from asyncsleepiq.

ClayBenson94 avatar ClayBenson94 commented on September 14, 2024

@kbickar - I shot an email over to you with the request information. I just want to make sure you got it and if it's what you're looking for!

I haven't dug more into the code here much, as it seems like the overall endpoints that the C360 bed uses is different from the other models (I saw no requests to /foundation for example, all the calls instead seem to be to /rest/sn/v1/accounts/{accountID}/beds/{bedID}/bamkey 🤷

from asyncsleepiq.

kbickar avatar kbickar commented on September 14, 2024

I took a look at it and it does look to be what we need for the most part. What I don't see is anything listing the capabilities. Is there only one light controllable in that model?

It could be that the API calls are dependent on the model, I'll try some of them out against mine to see if any of them work

from asyncsleepiq.

ClayBenson94 avatar ClayBenson94 commented on September 14, 2024

I took a look at it and it does look to be what we need for the most part. What I don't see is anything listing the capabilities. Is there only one light controllable in that model?

It could be that the API calls are dependent on the model, I'll try some of them out against mine to see if any of them work

Hmm - for listing the capabilities, is that a specific API call you're expecting to see? Related to the bed as a whole or the foundation? Like the one in here?

async def fetch_features(self) -> None:
"""Update list of features available for foundation from API."""
have_foundation = await self._api.check(
"bed/" + self.bed_id + "/foundation/system"
)
if not have_foundation:
self.type = ""
return
fs = await self._api.get("bed/" + self.bed_id + "/foundation/system")
features_flags = fs.get("fsBoardFeatures", 0)
self.features["boardIsASingle"] = bool(features_flags & (1 << 0))
self.features["hasMassageAndLight"] = bool(features_flags & (1 << 1))
self.features["hasFootControl"] = bool(features_flags & (1 << 2))
self.features["hasFootWarming"] = bool(features_flags & (1 << 3))
self.features["hasUnderbedLight"] = bool(features_flags & (1 << 4))
type_num = int(fs.get("fsBedType", -1))
if type_num < 0 or type_num > len(FOUNDATION_TYPES) - 1:
self.type = ""
else:
self.type = FOUNDATION_TYPES[type_num]
self.features["leftUnderbedLightPMW"] = fs.get("fsLeftUnderbedLightPWM")
self.features["rightUnderbedLightPMW"] = fs.get("fsRightUnderbedLightPWM")
if "hasMassageAndLight" in self.features:
self.features["hasUnderbedLight"] = True
if "split" in self.type:
self.features["boardIsASingle"] = False

Additionally, this model only has one light - not per side lighting.

from asyncsleepiq.

kbickar avatar kbickar commented on September 14, 2024

Right, something like that which lists the features or like the lights/outlets where they can all be queried to see if they exist. I guess given the components, we could make a database of sorts of the capabilities, but it would be a little easier if there was a way to check. In the data you sent there was all the requests to set different parameters, were there any that show the current status of them?

from asyncsleepiq.

rvrolyk avatar rvrolyk commented on September 14, 2024

It could be that the API calls are dependent on the model, I'll try some of them out against mine to see if any of them work

I tried a random one (foot warming) against mine (an i8) and it didn't work; the logs show a 400 error for me. I haven't tried others but am interested if you find any working (and I'll try more as time permits).

from asyncsleepiq.

ClayBenson94 avatar ClayBenson94 commented on September 14, 2024

Right, something like that which lists the features or like the lights/outlets where they can all be queried to see if they exist. I guess given the components, we could make a database of sorts of the capabilities, but it would be a little easier if there was a way to check. In the data you sent there was all the requests to set different parameters, were there any that show the current status of them?

@kbickar I'm away from home for a week or so, I'll take a second crack at monitoring the requests to see if I can see any requests to list both the features available and the statuses of various items!

from asyncsleepiq.

ClayBenson94 avatar ClayBenson94 commented on September 14, 2024

@kbickar @rvrolyk I just sent over some more request info. As I noted in the email, the request/response data is really cryptic from my point of view, so I tried to organize it in some way.

The other thing I'm trying now is digging through the decompiled source code of the app (which I had to do in order to sniff these requests in the first place) to see if I can make sense of any of the "bamkey"s as they call them. Let me know if you'd like this source code, if it's at all helpful!

from asyncsleepiq.

ClayBenson94 avatar ClayBenson94 commented on September 14, 2024

Good news (ish)

Some Discoveries

It seems like the way that this model operates is pretty fundamentally different from the way this pacakge works. Rather than listing out capabilities via /foundation, it seems that nearly all interactions with the bed (fetching data, turning on heating, lights, setting sleep numbers, pause modes, etc.) is done through the /bamkey endpoint. The behavior of how the /bamkey endpoint works is largely determined by the key and args that get passed in the body.

For example, to retrieve the list of features that the bed supports, /bamkey is called with

{"args":"","key":"SYCG","sourceApplication":"Android Consumer Mobile App"}

and the following response is returned (in my case)

{"cdcResponse":"PASS:dual yes yes yes yes heat_cool yes yes yes yes yes yes yes yes yes yes"}

After diving into the decompiled android source, I believe the response string here represents the following properties:

  • pressureControlEnabledFlag
  • articulationEnableFlag
  • underbedLightEnableFlag
  • rapidSleepSettingEnableFlag
  • thermalControlEnabledFlag
  • rightHeadActuator
  • rightFootActuator
  • leftHeadActuator
  • leftFootActuator
  • flatPreset
  • favoritePreset
  • snorePreset
  • zeroGravityPreset
  • watchTvPreset
  • readPreset

For the sake of this library, it seems that the main things worth paying attention to here are whether or not the actuators, presents, and underbed lighting are enabled (this is analagous to listing features for other models). For an initial implementation, I'd say we shouldn't worry about thermal control, since I don't think that's something this library currently handles for any other model of bed (while actuators, underbed lighting, and presets are handled)

Attached is the output of a script that I wrote that parsed the decompiled android code to grab the names of the bamkeys and their codes:
bamkeys_decoded.csv

My thoughts & Questions

This feels like a big divergence from how the rest of this package is written, and I worry that implementing all these bamkey calls would be a big burden for the maintainers of this repo.

  • I wonder if this has to do with the generation of my device being listed as fuzion - @kbickar does yours show the same? My guess is that fuzion generation beds work this way, while other generation beds might not. If that's the case, we'd probably want to branch off logic for this generation of bed as it's fundamentally different from how the other ones work (a more typical REST API)
  • @kbickar Does this differing implementation from other models of Sleep Number beds warrant a fork, or is this something you think you'd like to try and implement into this library?

from asyncsleepiq.

kbickar avatar kbickar commented on September 14, 2024

This is good progress! That list should allow us to figure out the capabilities to expose

listed as fuzion - @kbickar does yours show the same?
Mine does not.

I think the best way to go about this would be to split this type into a separate class sharing a parent class with the existing bed to maintain the same interface. From a library point of view, it doesn't really matter how it interacts with the API, just that it can control all the lights and actuators and pressure.

Fortunately they all do seem to share the original /bed endpoint so it should be possible to make the decision after that request whether to use the existing API or the bamkey one.

from asyncsleepiq.

ClayBenson94 avatar ClayBenson94 commented on September 14, 2024

split this type into a separate class sharing a parent class with the existing bed to maintain the same interface

I think this approach makes the most sense!

Honestly, I can't say that I'm much of an actual python developer (I can string stuff together to make it work). I could take a crack at making a different class as you've described, and maybe you could lend a hand in guiding the direction of it when it's in PR (or sooner?)

Or, if you'd rather lead the development on it from the responses I've given too, that is alright - and I can serve to help test and validate changes!

from asyncsleepiq.

kbickar avatar kbickar commented on September 14, 2024

I created a new branch with support for this: https://github.com/kbickar/asyncsleepiq/tree/fuzion

Might need to change the user agent and maybe some headers

from asyncsleepiq.

ClayBenson94 avatar ClayBenson94 commented on September 14, 2024

@kbickar Can you open a pull request for this branch and assign me as a reviewer? That should allow me to leave comments and provide feedback more easily as I test.

First thing I run into running this locally, though, is this block here main...fuzion#diff-5f83104cbd42898f96c5540fcbd728257eda78bbb7e988bef9c4671653b58d2dR34-R39

This currently errors with

AttributeError: 'dict' object has no attribute 'append'

I think instead of calling .append, you could just do

        self.beds = {}
        for bed in data["beds"]:
            if data.get("generation", "") == "fuzion":
                self.beds[bed["bedId"]] = SleepIQFuzionBed(self, bed)
            else:
                self.beds[bed["bedId"]] = SleepIQBed(self, bed)

from asyncsleepiq.

ClayBenson94 avatar ClayBenson94 commented on September 14, 2024

@kbickar I created a PR that merges my Fork into your fuzion branch. There were just a few errors (from what I could find) in typing/params that caused some hiccups, but this largely works with my bed from my testing so far!!

#13

from asyncsleepiq.

Related Issues (8)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.