Anova Precision Oven

Hey all, I’m a long time user of Home Assistant and recently purchased an Anova Precision Oven.

I’d love to be able to control it via Home Assistant but have had limited success in figuring out how to create a custom component and I was hoping someone here might be able to give me a hand or point me in the right direction.

I’ve been able to fully reverse engineer the API used by the Anova Mobile apps which means that implementing the commands via a custom component should be relatively straightforward for someone who is familiar with custom components.

Any pointers/tips/offers of help are appreciated.

2 Likes

Anova Sous Vide Integration There’s another user who has been working on an Anova addon into core H-A. That’s probably the best place to start.

Thanks for the tip, unfortunately the APIs are totally different for the sous-vide sticks compared to the ovens but I’ll reach out and see if there’s interest.

I’m done by research few months back, but so far no progress…

I’m actually looking for the same! Plus, I’m a golang developer/architect by profession and have been looking into writing a few HA Add-Ons, and this might be a great way to get my feet wet. I’ve taken a look at your API docs, and think it shouldn’t be too difficult to put an Add-On together using it. I have a question right off the bat: How do you get the appropriate Firebase Token/Key in order to start the auth process? Is it embedded somewhere in the Anova app? Or a config value you can pull from the app somehow without sniffing network traffic from your cell phone? Or, even better, is the firebase app key/token shared in the API docs the actual one to use?

As far as I can tell, the Firebase API key is unique to the application (not the user or the account). So the one in the API docs from @mcolyer should be OK to use.

However, there seems to be a different problem - as far as I can tell, there is no way to set a password for my Anova account. When logging in, it uses a 6-digit code sent to my email address as the “password”. And once logged in, there is no way of setting an actual password. So what do I send in the initial authentication request??

bogd, Are you logging into Anova.com? Or using the app? I get an email with a 6 digit code when logging into Anova.com (the STORE website), but for some reason, my app uses my gmail address (I’m on an Android) and doesn’t give me a 6-digit code nor prompt for a password; it just logs me in.

The API docs the OP shared do work, but require a password. So, I think we’re both in the same ballpark regardless. If only we can get the OP to reply and let us know how he solved the password prompt issue.

The Android app is also using my gmail account (possibly via automatic login/OAuth, I do not remember exactly how I set it up).

What I tried was logging in to the website ( anovaculinary.com ) using the same email address, hoping that I would be able to set a password (or reset the existing one). That is when I found out that the only login mechanism that seems to be available is via 6-digit code sent by email.

So yes, we have the exact same problem - how do we get the password that the application uses?

I’ve had good luck sniffing the traffic in between the app and the server or in between the app and the oven.

If you’re on iOS I recommend using Proxyman. It will install an SSL cert and a loop-back VPN on your phone that allows you to decrypt the traffic.

I’m sure there’s something similar for Android.

@mcolyer any thoughts on the password issue folks have mentioned? I’d love to see a HA integration for our beloved oven. I’m envisioning a dedicated terminal near my oven with custom recipe icons for the recipes I use the most (toast bread, reheat, etc.) without having to navigate the app. My wife would definitely appreciate this!

1 Like

As I mentioned above, the password can be sniffed from the app. It’s not the best solution, but it does work.

There seems to be a working interface to the cloud API here: GitHub - huangyq23/anova-oven-forwarder: Collect data from Anova Precision Oven
Unfortunately I didn‘t manage to turn it into a running Addin. It may be of help to someone who can though….

Unfortunately, I was unable to sniff it. Using Android and mitmproxy, I was unable to see the application traffic. It appears that you need additional steps to get around certificate pinning, and I had neither the time nor the necessary knowledge to do that :slight_smile:

However, the link @MDinHeaven posted seems to have some interesting info. Including a way to get the API key and tokens from the firebase local storage, using Chrome.

I did manage to make some progress thanks to @MDinHeaven and huangyq23. I am documenting here the steps I took, hoping that someone will be able to help me with what I am missing.

  1. Get the tokens (access token, refresh token) from Chrome local storage. Authenticate to https://oven.anovaculinary.com , F12, Application > Storage > IndexedDB > firebaseLocalStorageDB > firebaseLocalStorage > value > stsTokenManager > accessToken
    I was unable to copy directly from Chrome’s DevTools, so I used an extension ( IndexedDBEdit ).

  2. You should be able to use the access token directly. Or, if it expires, you can get a new access token using the refresh token (docs here):

curl 'https://securetoken.googleapis.com/v1/token?key=[API_KEY]' \
-H 'Content-Type: application/x-www-form-urlencoded' \
--data 'grant_type=refresh_token&refresh_token=[REFRESH_TOKEN]'

(both the API key and the refresh token are also stored in Chrome’s local storage)

Now, I am trying to use the API documented by @mcolyer:

  1. Connect to wss://app.oven.anovaculinary.io . Using postman, or an online WSS tester like Online Websockets Tester - Debug Client Tool

  2. Send the authentication message:

{
  "command": "AUTH_TOKEN",
  "payload": "[ID_TOKEN]"
}

[ No comma at the end, before } - the API seems to have problems if we keep that comma! ]

The token is correct, I am getting back a
{"response":"AUTH_TOKEN_RESPONSE"}

However, I am also getting a {"response":"OVEN_COMMAND_RESPONSE","requestId":"xyz","deviceId":"anova0123456789","success":false,"error":"12 UNIMPLEMENTED: Method not found."}

The WSS connection stays up (so authentication does seem to be successful), but I cannot get any further. There are no periodic messages from the oven, and if I try to send a command like this:

{
  "command": "SEND_OVEN_COMMAND",
  "payload": {
    "deviceId": "anova0123456789",
    "command": {
	  "id": "001a",
	  "type": "stopCook"
	},
    "requestId": "01a"
  }
}

I get the same
"success":false,"error":"12 UNIMPLEMENTED: Method not found."}

If anybody knows what I am missing, please let me know…

I finally managed to get some info, but using an entirely different API than the one documented by @mcolyer . My guess is that the app.oven.anovaculinary.io has either been deprecated or modified by Anova in the meantime. :frowning: However, it is much more likely that I missed something in that documentation, so instead of editing the previous message in place I am posting this as an alternative option.

The method I actually got to work was based on the source code of GitHub - huangyq23/anova-oven-forwarder: Collect data from Anova Precision Oven .

The first 2 steps (getting the access token and refresh token) are the same ones as above.

In step 3, connect to wss://devices.anovaculinary.io
Make sure to set the following query parameters:

  • token: the access token you got in previous steps
  • supportedAccessories: APO
  • platform: ios ( “android” also seems to work, but it might require generating a different access token )

Also, set a header of Sec-WebSocket-Protocol: ANOVA_V2

Once connected, you should start seeing the status messages from the oven. They look very similar to what @mcolyer has documented, but with some differences (for example, they all contain "command": "CMD_APO_STATE").

I was also able to interact with the oven and send commands (again, based on the source code linked above). For example, a “stop cook” command now looks like this:

{
  "command": "CMD_APO_STOP", 
  "payload": {
    "type": "CMD_APO_STOP",
	"id": "0123456789abcdef"
  },
  "requestId": "1cddc2c8-d1f1-446b-b76d-334221134"
}

Now if I could only figure out the “new” syntax for “startCook” commands…

@bogd

Anova replaced the oven API between July and August 2023, so any docs prior to that would be the old Firebase API. Not sure what they moved it to. New API is for oven firmware 1.1.x and beyond.

@ragzilla - thank you for the docs! They confirm what I suspected from reading the code - the fact that Anova switched to a different infrastructure, and in the process they also changed the API.

As far as I can tell, the new API is still on Firebase, but with a different endpoint and different syntax (including different authentication mechanisms).

Now the problem is that (just like the old API) this new one is also not documented anywhere (because Anova are being d.cks* about it and simply refuse to open/publish/document anything related to the API). And all the hard work that @mcolyer has done at the start of this thread is no longer valid :frowning: . And since I am still unable to sniff the traffic from the Android app, there is no way I can figure out the new “startCook” syntax. Hopefully someone else will be able to sniff that traffic, and post the syntax somewhere…

  • ducks. I meant “ducks”. What did you think I meant? :stuck_out_tongue:

FINALLY!!! I was able to get the missing info, and figure out the syntax for the startCook (now called CMD_APO_START) command!

I will post all the details (including the ones I already listed above in this thread) in this repo, which I will update as I find out more information.

Hopefully, this will help someone write an actual HAss integration for the device.

1 Like

Looks like I hit the jackpot - this is not just “the Oven API” :slight_smile: . It is the new API, for both oven and sous-vide cookers. You just need to set the “supportedAccessories” header to “APC”, and you start receiving “EVENT_APC_STATE” with the state of the sous-vide cooker.

Also, if you set the header to “APC,APO” you can see the status of both, and control both.

I will continue updating the repo with the details of the API. I have also posted some working Go code for interacting with the oven, and I can get started on a Python module for it.

Unfortunately, my experience with writing HAss integrations is close to zero (it took me 3 days to even get the HAss development environment up :slight_smile: ). Is there anyone who could help write a real integration for these devices?

2 Likes

Hey so sorry I missed all of these updates, for some reason I don’t seem to get email notifications, I’ll have to look into that.

Sounds like you were able to get the new API figured out, anything else you need help with?