sHedC / homeassistant-ambrogio

Home Assistant Integration for the Ambrogio Robot Mowers
MIT License
2 stars 2 forks source link

Device Tracker Improvemeents #22

Open sHedC opened 1 year ago

sHedC commented 1 year ago

Checklist

Is your feature request related to a problem? Please describe.

Device Tracker, can show battery level and icon/ picture, also location seems to be generic home or not home rather than more accurate based on GPS

Describe the solution you'd like

Add ability to add ICON/ Picture for each robot. improve GPS Location Add Battery Level Improve General Device Information based on each robot (one robot one device)

Describe alternatives you've considered

N/A

Additional context

N/A

ufozone commented 1 year ago

Currently I get the accurate GPS (gnss) data from params -> alarms -> robot_state. These are transmitted by several robot models only irregularly. The location data under params -> loc are of the fixType "network" and thus the GMS location determined via triangulation.

Battery level and model (for picture) cannot be determined via the current API approach.

sHedC commented 1 year ago

Thanks yes I noticed thoug the HA Tracker seems to respond home or away at least in my case it was that I was going to look at.

Battery level would be nice, but for the Picture I believe I can maybe have a default and give the option to set on in the config, not sure yet :)

ufozone commented 1 year ago

I have checked the complete flow of the mobile app again. We can find the model via the Firebase API. However, from my point of view, the path is not worth it, since two other APIs have to be connected.

In the first step, we authenticate against the Google API service with email address and password:

POST https://www.googleapis.com/identitytoolkit/v3/relyingparty/verifyPassword?key=AIzaSyCUGSbVrwZ3X7BHU6oiUSmdzQwx-QXypUI HTTP/1.1
Content-Type: application/json
X-Android-Package: it.centrosistemi.ambrogioremote
X-Android-Cert: 4753441615021C6147D5F0946A0DA83877EF3D41
Accept-Language: en-US
X-Client-Version: Android/Fallback/X21000008/FirebaseCore-Android
X-Firebase-GMPID: 1:373506005239:android:07fcd128132313f3
X-Firebase-Client: H4sIAAAAAAAAAKtWykhNLCpJSk0sKVayio7VUSpLLSrOzM9TslIyUqoFAFyivEQfAAAA
Content-Length: 84
User-Agent: Dalvik/2.1.0 (Linux; U; Android 9; Android SDK built for x86_64 Build/PSR1.180720.122)
Host: www.googleapis.com
Connection: Keep-Alive
Accept-Encoding: gzip

{"email":"<yourEmail>","password":"<yourPassword>","returnSecureToken":true}

We get an JSON formatted response with important tokens:

{
  "kind": "identitytoolkit#VerifyPasswordResponse",
  "localId": "<importantLocalId>",
  "email": "<yourEmail>",
  "displayName": "<yourUsername>",
  "idToken": "<importantAccessToken>",
  "registered": true,
  "refreshToken": "<someNotUsesToken>",
  "expiresIn": "3600"
}

Next step, we create a websocket connection to Firebase API

GET wss://centrosistemi-ambrogioremote.firebaseio.com/.ws?ns=centrosistemi-ambrogioremote&v=5 HTTP/1.1
Host: centrosistemi-ambrogioremote.firebaseio.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Version: 13
Sec-WebSocket-Key: nQybC2IH64qOZ05V1ffn9g==
X-Firebase-AppCheck: null
User-Agent: Firebase/5/20.0.6/28/Android
X-Firebase-GMPID: 1:373506005239:android:07fcd128132313f3
content-length: 0

Authentication and get with this account connected lawn mowers:

▼ {"t":"c","d":{"t":"h","d":{"ts":1681166772961,"v":"5","h":"s-usc1a-nss-2058.firebaseio.com","s":"<someUnusedKey>"}}}
▲ {"t":"d","d":{"a":"s","r":0,"b":{"c":{"sdk.android.20-0-6":1,"persistence.android.enabled":1}}}}
▼ {"t":"d","d":{"r":0,"b":{"s":"ok","d":""}}}
▲ {"t":"d","d":{"a":"auth","r":1,"b":{"cred":"<importantAccessToken>"}}}
▼ {"t":"d","d":{"r":1,"b":{"s":"ok","d":{"auth":{"name":"<yourAccountName>","email_verified":false,"provider":"password","email":"<yourEmailAddress>","user_id":"<importantLocalId>","token":{"name":"<yourAccountName>","email_verified":false,"email":"<yourEmailAddress>","exp":1681169388,"user_id":"<importantLocalId>","iat":1681165788,"sub":"<importantLocalId>","aud":"centrosistemi-ambrogioremote","auth_time":1681165788,"iss":"https://securetoken.google.com/centrosistemi-ambrogioremote","firebase":{"identities":{"email":["<yourEmailAddress>"]},"sign_in_provider":"password"}},"uid":"<importantLocalId>"},"expires":1681169388}}}}
▲ {"t":"d","d":{"a":"q","r":2,"b":{"p":"robots\\/ambrogio\\/<importantLocalId>","h":""}}}
▼ {"t":"d","d":{"b":{"p":"robots/ambrogio/<importantLocalId>","d":{"00:00:00:00:00:00":{"boardserial":"AM03500000000000","btAddress":"00:00:00:00:00:00","imei":"350000000000000","modelType":"","name":"L35 Deluxe","password":"0","programId":75,"remoteDisplayAvailable":true,"revision":61532,"timestamp":1682949301697}}},"a":"d"}}

Through this way we could do in config flow the authentication by email and password and get the IMEI of the robots this way. We would then also have the model. However, the path is also more fragile against changes to any of the API.

I believe that we can also determine the model from the serial number that we get via the Devicewise API. In the example above, you can see that I have an L35 Deluxe and my serial number starts with AM035. However, I have too few robots (only one) to verify this. ;-) If we knew more, we could create a mapping.

The mobile app only gets the battery level via bluetooth. We would have to sniff the bluetooth traffic for this. I have not opened this Pandora's box yet.

sHedC commented 1 year ago

In the first step, we authenticate against the Google API service with email address and password:

Was sort of avoiding this as it just got an access key, however yes if we can get the connected mowers I can add this.

I am going to look how to add you as a collaborator direct to my github repo.

sHedC commented 1 year ago

There is a command to trace position on the App, it initiates by this:

{
  "cmd":{
    "command":"method.exec",
    "params":{
      "imei":"1234567890",
      "method":"trace_position",
      "ackTimeout":30,
      "singleton":true
    }
  }
}

Returns command success true then tracks the mower regularly but I don't see any further pushes so wonder if it is then streaming the response.

You can open the robot then the map then you get an option to Trace position. There is a cloud map feature with Infinity+ not tried to activate it yet, but I have just renewed my connection to Infinity+.

ufozone commented 1 year ago

I tried the command several times today when my mower was working. However, I could not see any regular sending of the location. I don't have Infinity+ (yet)

I have implemented the command in the services.

ufozone commented 1 year ago

According to my first tests, the trace_position command works only when the robot is working. In the app, many requests are made to https://clients4.google.com/glm/mmap/api in "trace mode". It seems that the position changes with the displayed points come in directly via the Google Map update: Screenshot_20230506-120653_Ambrogio Remote

Somehow on my Samsung Galaxy S5 test device the websocket connections bypass the MITM proxy, so I guess there is still traffic between the app and Firebase.