Lay-Z-Spa Hot Tub wi-fi pump automation

Ok. I need to check how that is done… Meanwhile i took te pump internals open and heres some pics if someone is interested… Wifi Module is esp-wroom-2uc. I tried to install Https sertificate but don’t really find anything useful information from fiddler while using the app. the address what it uses for communicating is http://usapi.gizwits.com/app/

Update:
I managed to get some data using fiddler. Here’s what i have found:
When controlling pump from app i see POST request made to https://usaepapp.gizwits.com/app/user/control_log with json data:

{
  "appKey": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "data": {
    "uid": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "productKey": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "mac": "XXXXXXXXXXX",
    "did": "xxxxxxxxxxxxxxxxxxxxxxxxxx",
    "command": {
      "power": true
    }
  },
  "type": "appId",
  "version": "1.0"
}

When opening the app this is the first GET request that is made.

GET http://usapi.gizwits.com/app/users/terms?locate=en HTTP/1.1
Host: usapi.gizwits.com
Origin: http://localhost:9099
Accept-Encoding: gzip, deflate
Connection: keep-alive
X-Gizwits-User-token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Accept: */*
User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 14_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148
X-Gizwits-Application-Id: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Referer: http://localhost:9909/
Accept-Language: fi-fi

X-Gizwits-Application-Id is same as appKey on POST requests.

Tried to make manually same POST request via fiddler but device wont respond to it. All i get is this message. (this message also comes when i control pump from my phone).

HTTP/1.1 200
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: X-Gizwits-Application-Id,Accept,Origin,No-Cache,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Version,Authorization
Access-Control-Allow-Methods: POST,GET,OPTIONS,DELETE,PUT
Access-Control-Allow-Origin: *
Access-Control-Max-Age: 3600
Content-Type: application/json;charset=UTF-8
Date: Tue, 05 Jan 2021 19:26:10 GMT
Server: nginx/1.16.1
Vary: Accept-Encoding
X-Application-Context: aep-service-composite:prod-us:8077
Content-Length: 87
Connection: keep-alive

{"code":"200","message":"本次请求成功!","data":null,"display":null,"error":false}

message here says that “This request was successfull”

When logging in to app this POST request is made. but this is one time only if you have logged out from the app.

POST https://usaepapp.gizwits.com/app/smart_home/users/privacy HTTP/1.1
Host: usaepapp.gizwits.com
Content-Type: application/json
Origin: http://localhost:9909
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Accept: */*
Version: 1.0
User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 14_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148
Referer: http://localhost:9909/
Content-Length: 147
Accept-Language: fi-fi

{"appKey":"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx","data":{"privacy":0,"country":"FI","email":"[email protected]"},"type":"appId","version":"1.0"}

Appkey here is same as X-Gizwits-Application-Id and appKey on earlier code.

1 Like

Hi,

Very new here so be gentle. I’m deeply interested in this so thank you all for doing this work! I agree that both the apps (lay-z-spa and bestway hub) are less than ideal. The Lay-z-Spa app is just broken, Bestway Hub works perfectly but only provides remote hands to the spa pump controls. I really want dynamic scheduling

So far I’ve got HACS installed and Ross’ component installed. It’s not working for me however, I get “Unexpected Error” in response to logging in with my lay-z-spa app credentials. I think this is due to my spa currently being connected to the Bestway Hub App. Trying to switch it back to the Lay-Z-Spa app is proving difficult at the moment but I’ll update with my results when I manage it.

This looks like good work on the BestWay App.
Sadly, I switched to BestWay app to take a look and now I can’t switch back to the Lay-Z-Spa app.
So I’ve broken my Hot Tub !

I’m now stuck until one of us figures out this BestWay App.

I can’t seem to get it to respond to replayed commands, so I’m a bit out of my depth.
I’m seeing similar posts and responses to those you have shown above.

The BestWay App and the Lay-Z-Spa app use totally different commands to control the tub.
So the code isn’t interchangeable.
Sadly in investigating the BestWay app for you, I have now broken my own Tub as it won’t switch back to the Lay-Z-Spa app !

Hi Bruce,

I’m also having no luck reverting back to the Lay-z-Spa app. I have a feeling this might have something to do with the lay-z-spa account already having the spa linked to it. I’m very sorry that in your kind attempt to help me you were inconvenienced. I’ll test my theory about the accounts and get back to you.

Hi Bruce,

I’ve just tested this by signing up with a new account.

I cleared the data and storage on the app and signed up using a new email address. This has got me as far as the app finishing the setup process. Once I’ve done that it sits spinning on “we’re just getting your sap’s status.” It’s also thrown up a few “can’t connect to your spa” errors. So it’s not quite working yet.

However I can now add the component in HACS. and that seems to be gathering data which is as far as I have got for now.

Graham

I’ve just tested switching back to the bestway app after working on getting it connected via the lay-z-spa app again.

I used my original email account (the one that no longer works with the lay-z-spa app) and redid the setup process. This worked fine.

As long as you use an entirely new email each time you work with the lay-z-spa app you’ll get somewhere. After switching back to Bestway my second account started throwing the unexpected error.

It’s less than ideal and strongly suggests to me that via the Bestway app might be the path to follow.

That said I assume there must be traffic from the app itself to the spa, probably via some cloud nonsense. I wonder if we can access the Spa’s native API (ie the one that the app talks to) somehow?

Graham

Did you actually manage to get it working back in the Lay-Z-Spa app?
Even if I use a brand new account, I can’t get it to work.

The Lay-Z-Spa component, may give you false hope as it appears to show data even if it isn’t connected.

It looks to me like the BestWay app is a one way street !

Hopefully someone can tell me differently.
Or someone can get the BestWay App turned into a component or at least some REST commands.
At the moment I’m stuck !

btw. my bestWay app connects to:

https://euaepapp.gizwits.com/app/user/control_log

So an EU server, rather than the us server.

Did you actually manage to get it working back in the Lay-Z-Spa app?
Even if I use a brand new account, I can’t get it to work.

I’m afraid I didn’t. If I come up with any new ideas I’ll try it again. TBH if I’m faced with using the lay-z-spa app vs the Bestway app I’ll take the Bestway app. It might lack scheduling but it’s much less janky in general. I appreciate that doesn’t solve your issue though!

Or someone can get the BestWay App turned into a component or at least some REST commands.
At the moment I’m stuck !

This isn’t really an area I’m familiar with but I’m happy to help any way I can. I ended up here while on a search to find a way of discovering APIs and looking to see if someone who already new how to do that had tried first with the Lay-Z-Spa. It might be worth digging into the apk if we can find it, again not something I’ve really tried before but am willing to give it a go if no-one else steps forward.

1 Like

Hey. Found this from spa manual. I started to Wonder if it think that spa is already connected to phone (different app) and thats why it wont connect. I might try this tomorrow.

The device can only be connected to one mobile phone at a time. If you need to connect to another mobile phone, please turn off the On/Off button, and press the Celsius/Fahrenheit button for 3 seconds. When the indicator light flashes slowly, the device will clear the connection information from the previous mobile phone. Please follow the instructions to connect the new phone to the pump.

Also found this. Probably someone with More knowledge could use somekind of esp or similiar to control this straight! https://github.com/mrQ000/layz-rc

Update: https://github.com/visualapproach/WiFi-remote-for-Bestway-Lay-Z-SPA and here is esp remote :grin:

I’ve done the 3 second press.
It doesn’t help.
I suspect that the Bestway app has done a firmware upgrade on the pump and it is no longer compatible with the Bestway app.

Then i suspect our best advice to use spa remotely is to use visualapproaches ESP Module between DISP and CIO.

I really can’t figure out how to replicate the BestWay App.
I can see all the outgoing traffic from the App, but if I try and replay a command it doesn’t work.
I get the response from the gizwits server to say all is good, but the tub doesn’t respond to the command.

I’m stumped, need someone with better skills I think.

I’m particularly interested in the incoming traffic to the pump. I’m currently trying to figure out how to capture that. It would be preferable if you could communicate locally to the pump from HA or your own app rather than sending API calls up to the cloud and back down. This might be ambitious.

I’m a novice at capturing this data so my first attempts are in fact to capture outgoing app data and responses and trying to replicate that. Any pointers on how to get started are much appreciated. FWIW I Am Not A Coder but I do have a lifetime of experience debugging things for coders and as a result understanding what I’m addressing quite well.

I’m guessing you would need something like Wireshark. But I’ve never got that deep into things either !

I’ve installed WS and am planning to see what I can come up with as soon as I have time. I’ll update here as and when. I have no idea when that might be!

1 Like

Hi guys, great research here! Thanks a lot for all the investigations.
I have a Bestway Lay-z-Spa Milan too and searched for MQTT/OpenHAB modules.

Since I am using the Bestway app too, i read your posts about the Bestway app and the sniffed traffic; I did some simple curl research on top of your informations and think found a big puzzle piece:

X-Gizwits-Application-Id:
Seems so be a general App Id on the Gizwits IoT platform for „Bestway“ IoT device or in other words the reference to the „Bestway“ app. So this should be the same for all Bestway app users - i had no time to sniff the traffic between my app and the server yet - so its just a guess and needs to be confirmed.

The API is fully disclosed here:
https://docs.gizwits.com/en-us/cloud/OpenAPI.html

and useful informations here aswell for the device „Heatzy“

E.g. page 13 show a login procedure.

Again: I couldn‘t do any tests until now. Try it next week.

But this should be the key to make it work - hopefully :slight_smile:

That api doc looks more like the la z spa app method.
Doesn’t look to match what the Bestway app is doing.
Happy to be proved wrong.

Thanks.

Hi Bruce, you are right :slight_smile: and that’s good, because it seems it is simply the same :slight_smile:
Just the layzspa method has some kind of gateway in between the communication with gizwits as it seems. You need additionally the AppID in the Bestway App case.

It was quite easy even without sniffing the traffic. I took the Bestway Android APK and unzipped it. Find relevant informations in assets/www/main.js :wink:

The relevant ones:

  • The first IDs block works for me and eu server
    First:
iosAppSecret:"13482b824b934003a8d95106d3d28eeb"
androidAppSecret:"1d69eda66af64662a6f1b31f0b42eab2"
androidAppID:"98754e684ec045528b073876c34c7348"
iosAppID:"43424551921d4ee18dd279140e11e198"
  • Alternative - maybe for other servers?:
iosAppID:"f50095a20a2f4152a3685a01a863ec5a"
iosAppSecret:"20438225160440b7b5a8d87ed8abcad7"
androidAppID:"afb8f41dbb274cb19d0fdf472945fbf3"
androidAppSecret:"3d81fcd4c22e48a286c26a6b3bf29a5b"

Then just use curl for a first test - see the heatzy document in my last post:
1.
curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' --header 'X-Gizwits-Application-Id: 98754e684ec045528b073876c34c7348' -d '{ "username": "[email protected]", "password": "YOURPASSWORD", "lang": "en" }' 'https://euapi.gizwits.com/app/login'

and receive

{ {"token": "YOUR_TOKEN", "uid": "YOUR_UID", "expire_at": } }

  1. get bindings infos with token
    curl -X GET --header 'Accept: application/json' --header 'X-Gizwits-User-token: YOUR_TOKEN' --header 'X-Gizwits-Application-Id: 98754e684ec045528b073876c34c7348' 'https://euapi.gizwits.com/app/bindings?limit=20&skip=0'

and receive something like that

{"devices": [{"protoc": 3, "ws_port": 8080, "port_s": 8883, "is_disabled": false, "gw_did": null, "wifi_soft_version": "WIFI_SOFT_VERSION", "dev_alias": "Milan", "mesh_id": null, "is_online": true, "host": "eum2m.gizwits.com", "sleep_duration": 0, "dev_label": [], "port": 1883, "remark": "", "did": "YOUR_DID", "mac": "YOUR_MAC", "product_key": "YOUR_PRODUCT_KEY", "wss_port": 8880, "state_last_timestamp": TIMESTAMP, "role": "owner", "is_sandbox": false, "passcode": "YOURPASSCODE", "type": "normal", "product_name": "SPA", "is_low_power": false}]}

  1. get the supported Data points
    curl -X GET --header 'Accept: application/json' --header 'X-Gizwits-Application-Id: 98754e684ec045528b073876c34c7348' 'https://euapi.gizwits.com/app/datapoint?product_key=YOUR_PRODUCT_KEY'

and receive the supported data type and attributes.

  1. get the current values of the attributes e.g. temp_now
    curl -X GET --header 'Accept: application/json' --header 'X-Gizwits-Application-Id: 98754e684ec045528b073876c34c7348' 'https://euapi.gizwits.com/app/devdata/YOUR_DID/latest'

  2. e.g. set temperature to 23 degrees (temp_set)

curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' --header 'X-Gizwits-User-token: YOUR_TOKEN' --header 'X-Gizwits-Application-Id: 98754e684ec045528b073876c34c7348' -d '{"attrs": {"temp_set": 23} } ' 'https://euapi.gizwits.com/app/control/YOUR_DID'

With those infos it should not be that big deal to get back control :slight_smile:

Btw the whole thing here looks like MQTT…port 1883…eum2m.gizwits.com…maybe MQTT-Broker M2M…
-> inline update: yes mitt…mentioned here: https://docs.gizwits.com/en-us/cloud/OpenAPI.html
Would be a direct MQTT connection possible?! Perhaps a local connection to the “egg”? I’ll do some research on that…

Enjoy :slight_smile:

Best Chris

P.S.: Maybe its possible to get back control of your app with the informations and the api calls

2 Likes