simbaja / gehome

Python SDK for GE smart appliances
MIT License
42 stars 29 forks source link

Initial support for Cafe Coffee Maker #30

Closed alexanv1 closed 2 years ago

alexanv1 commented 2 years ago

This is initial support for Cafe Coffee Maker. Unfortunately, it's not ready to be merged just yet. I've been able to figure out most of the ERDs (and the remaining ones don't seem relevant for day-to-day operation) but I am stuck on figuring out how to turn off/cancel the brewing operation.

Brewing is turned on by writing to CCM_BREW_SETTINGS (of note, this ERD is only updated when device is polled). The settings are reflected immediately via the "sensor" ERDs (CCM_IS_BREWING, CCM_BREW_STRENGTH, etc).

However, I have not been able to figure out what to set in order to cancel brewing. CCM_IS_BREWING is not writable and the unknown ERDs don't change their state when the coffee maker is brewing vs. not (so I assume they are for something else). All of them are also not writable (I've tried).

Any ideas on how to figure this out would be appreciated. I don't have a rooted Android device to install a MITM proxy on but, from what I've gathered, the app also uses cert pinning so a MITM solution probably wouldn't work...

In addition, it seems that there will be complications integrating the Coffee Maker into Home Assistant since an ability to select all settings and then set them in one shot is needed. This can be handled by implementing a custom service in the integration but it's not ideal since it would requires custom input_* components to set the settings that can then be applied by calling the service. Suggestions on this aspect are very welcome as well :)

I am attaching 2 files for reference: Turn Off.log - coffee maker is already ON when the script is started and is canceled\turned off via app Turn On - coffee maker is turned ON via app after starting the example script

alexanv1 commented 2 years ago

@simbaja any suggestions you have on how to proceed here would be appreciated! Thanks!

simbaja commented 2 years ago

Great work so far. Very odd that the brew status requires polling, haven't seen that behavior with other appliances (but all appliances seem to be a little different, so not surprised).

From the logs, I think the following codes can be set:

0x9013 is a flag indicating the machine is out of water 0x9014 is the current temperature as an int (degrees F).

You're right that the app uses cert pinning and the latest versions are obfuscated as well, which makes the decoding process much more difficult than it should be.

I did a quick pass and didn't see the command to cancel a brew in the official app code. But if it does it should be possible to get it to work since we're doing exactly what the app does under the covers. Can you try making the IS_BREWING and IS_DESCALING codes an ErdOnOff and then you can send an off value to them to cancel the brew/descale. I know you mentioned that it didn't appear to be writable, but these devices can be very picky about the write operation (for example, if you send it two bytes when it expects one, it just ignores the entire command). If we use ErdOnOff, that should give it what it expects (hopefully). If that works, we should probably rename them to something more like CCM_BREW_STATUS and CCM_DESCALE_STATUS. If that doesn't work, the only other clue I see in the app code are that there's some code that sends the value "01" to 0x900c when waiting for brewing and "01" to 0x901b when waiting for descaling. I haven't traced the context where these are called (it's a pain in the butt), but perhaps try sending those values and seeing if it cancels?

For HA support, we can probably leverage the WaterHeater component (pretty much all the settable appliances leverage this at the moment). Basically, we'd define the combinations of operations that we want to support and then those would appear in the pick list. From there, we can assemble the command to send over to the appliance. Take a look at the advantium, microwave, or oven and I think you'll see what we can do for this. It's not perfect, but might work. Another alternative would be to have a few selects for the settings and then pass those into the water heater start. We can work through that on the HA side though, something should be possible and reasonable. HA should have some sort of dedicated entity for cooking devices, but alas, it doesn't yet.

alexanv1 commented 2 years ago

Thanks for the suggestions! I actually started with BREW_STATUS and DESCALE_STATUS and had those as ErdOnOff and that's when I was getting errors about them being non-writable. I will experiment some more and try sending data to 0x900c and 0x901b as well and see what happens...

I've tried decompiling the Android app as well but it didn't seem to decompile correctly and I couldn't find anything meaningful there (that said, I know exactly nothing about Android development so was just poking blindly in the dark).

0x9014 is, indeed, the current temperature although the value jumps around a bit but that's a device issue. I will update to list 0x9013 as "out of water", I assumed one of those ERDs was for that but didn't get around to trying it out yet.

Exposing as a water heater is an interesting idea, I will take a look at that once I get to the HA part.

Thanks again!

simbaja commented 2 years ago

Yeah, decompiling is a pain and it isn't perfect (hence me not trying to track down the context for those two codes). I can probably look in more depth if nothing seems to work.

Also, can you check on something for me? Can you set to Celsius and see what unit of measure the API is reporting the temperature in? I'm getting the sense that it's always Fahrenheit in the API regardless of what the devices are set to (have to try this on other devices too to confirm).

alexanv1 commented 2 years ago

Also, can you check on something for me? Can you set to Celsius and see what unit of measure the API is reporting the temperature in? I'm getting the sense that it's always Fahrenheit in the API regardless of what the devices are set to (have to try this on other devices too to confirm).

Yeah, I actually have the coffee maker set to Celsius. The values at API-level are always Fahrenheit, setting to Celsius only impacts the app\physical device.

alexanv1 commented 2 years ago

@simbaja, you were absolutely correct about 0x900c and 0x901b! Sending "01" to 0x900c cancels brewing, sending "01" to 0x901a starts descaling, and sending "01" to 0x901b cancels descaling

I've updated the PR. Support is now more-or-less complete so I think it's ready to be merged.