Haier hOn Oven integration

Hi, I have working in hOn oven integration using rest.

For now, I only have read a some values.

rest:

  resource: https://api-iot.he.services/commands/v1/context?applianceType=OV&category=CYCLE
  method: GET
  params:
    macAddress: !secret oven_mac
  headers:
    id-token: !secret oven_token
    cognito-token: !secret oven_cognito
  
  
  
    

  sensor:
    - name: Horno Temperatura
      value_template: "{{ value_json.payload.shadow.parameters.temp.parNewVal  }}"
      json_attributes:
    
    - name: Horno Temperatura Objetivo
      value_template: "{{ value_json.payload.shadow.parameters.tempSel.parNewVal | float }}"

    - name: Horno Tiempo Restante
      value_template: "{{ value_json.payload.shadow.parameters.remainingTimeMM.parNewVal | float }}"

      
  binary_sensor:
    - name: Horno
      value_template: "{{  value_json.payload.shadow.parameters.onOffStatus.parNewVal }}"
      
    - name: Horno Precalentado
      value_template: "{{  value_json.payload.shadow.parameters.preheatStatus.parNewVal }}" 
      
      
    

You need id and cognito access token and mac of you oven to get data.

I get the mine using mitmproxy, Android emulator and modified hOn apk, but I think you can use the PHP script of @matevo to get the data.

1 Like

This is good work. I think the problem you’ll have is that those tokens will expire. If you paste them into the debugger at http://jwt.io you’ll find an “exp” unix timestamp.
I think what this needs is a full integration as it needs to call a few endpoints in sequence to get the tokens.

You’ll also notice that in the commands/v1/appliance response it lists MQTT endpoints. But I just can’t figure out how to connect to them…

Yes. The tokens they are outdated yet…

I need something to get the token.

For mqtt, I see that the APP use, but, I think that is not necessary. From the REST I can get all data and for send commands there are another REST.

The problem is that I will need create a custom component. The rest sensors can works only for rest.

I am developing a dirty and ugly python api from PHP code.

For now, I can get the tokens and the device information.

import requests


class HonClient:
    id_token = ''
    cognito_token = ''

    username = ''
    password = ''

    def __init__(self, username, password):
        self.username = username
        self.password = password

    def update_tokens(self):

        client = requests.Session()
        response = client.post(
            'https://he-accounts.force.com/SmartHome/s/sfsites/aura?r=3&other.LightningLoginCustom.login=1', data={
                "message": '{"actions":[{"id":"87;a","descriptor":"apex://LightningLoginCustomController/ACTION$login","callingDescriptor":"markup://c:loginForm","params":{"username":"' + self.username + '","password":"' + self.password + '","startUrl":"/SmartHome/setup/secur/RemoteAccessAuthorizationPage.apexp"}}]}',
                "aura.context": '{"mode":"PROD","fwuid":"2yRFfs4WfGnFrNGn9C_dGg","app":"siteforce:loginApp2","loaded":{"[email protected]://siteforce:loginApp2":"PnuMahsrn7JWWgS2n6sUkQ"},"dn":[],"globals":{},"uad":false}',
                "aura.pageURI": '/SmartHome/s/login/?language=en&startURL=%2FSmartHome%2Fsetup%2Fsecur%2FRemoteAccessAuthorizationPage.apexp',
                "aura.token": "null"
            })

        url = response.json()['events'][0]['attributes']['values']['url']
        html = client.get(url).text
        url = html[html.index('https'):html.index('"', html.index('https'))]
        client.get(url)

        oauth = client.get(
            'https://he-accounts.force.com/SmartHome/services/oauth2/authorize?response_type=token+id_token&client_id=3MVG9QDx8IX8nP5T2Ha8ofvlmjLZl5L_gvfbT9.HJvpHGKoAS_dcMN8LYpTSYeVFCraUnV.2Ag1Ki7m4znVO6&redirect_uri=hon%3A%2F%2Fmobilesdk%2Fdetect%2Foauth%2Fdone&display=touch&scope=api%20openid%20refresh_token%20web&nonce=82e9f4d1-140e-4872-9fad-15e25fbf2b7c').text
        self.id_token = oauth[oauth.index("id_token") + 9:oauth.index('&', oauth.index('id_token'))]
        self.cognito_token = client.post("https://api-iot.he.services/auth/v1/login", json={
            "appVersion": "1.39.2",
            "mobileId": "xxxxxxxxxxxxxxxxxx",
            "osVersion": 30,
            "os": "android",
            "deviceModel": "goldfish_x86"
        }, headers={'id-token': self.id_token}).json()['cognitoUser']['Token']

    def _execute_request(self, url, params):
        response = requests.get(url, params=params, headers={
            'cognito-token': self.cognito_token,
            'id-token': self.id_token
        })
        if response.status_code == 401:
            self.update_tokens()
            response = requests.get(url, params=params, headers={
                'cognito-token': self.cognito_token,
                'id-token': self.id_token
            })

        return response.json()

    def get_devices(self):
        return self._execute_request('https://api-iot.he.services/commands/v1/appliance', {})['payload']['appliances']

    def get_status(self, device):
        return self._execute_request('https://api-iot.he.services/commands/v1/context?category=CYCLE',
                                     params={
                                         'applianceType': device['applianceTypeName'],
                                         'macAddress': device['macAddress']
                                     })


    client = HonClient("[email protected]", "mypassword")
    devices = client.get_devices()
    info = client.get_status(devices[0])

4 Likes

Hello MiguelAngelLV,

Great your script
how can we use it?

is it reliable to integrate the products piloted by hOn?

thank you

@chikite for now, It is only test code, not working yet in HA.

I have created a first version of a HA component supporting hOn.
(I used some logic describe above to do it :slight_smile: )

You can test: https://github.com/gvigroux/hon

I’ve implemented the climate platform (tested on a Haier appliance)

1 Like

Great!

I will “copy” you climate logic to create a oven component… Has HA oven component? :confused:

Is username and password all that is needed for it to work?

Correct, I use a direct connection to the hOn server (like the mobile app)

Pull request sent!

It is a initial version that only read some sensors:

  • On/Off
  • Preheating
  • Temperature
  • Target Temperature
  • Program duration
  • Program remaining

It was fast :slight_smile:

1 Like

Go go go!

I am testing to start the oven :wink:

But I don’t have how get the mac address (o other device data) in the service call from entity_id or device_id, so, for now, I need put the MAC manually in the form service.

New PR with oven services