reinhard-brandstaedter / solarflow-statuspage

A simple statuspage with live-data from Zendure's Solarflow Hub for those who do not want to use the App
23 stars 6 forks source link

No updates on Zendure MQTT broker #52

Open andreheuer opened 1 month ago

andreheuer commented 1 month ago

Hi all,

I have a Hub 2000 and wanted to test the Solarflow status page. Currently, I am using Home Assistant with Mosquitto and subscribed to the mqtt.zen-iot.com. However, I experienced that a lot of messages are not available and the updates are not "real time" or completely missed for hours.

So I tried your implementation and realized that you are using (most likely) the same MQTT broker as the mobile apps (which are showing updates in almost real time).

I have used the current DEV branch (used also master branch before, but same behaviour):

[zendure]
login = m******de
password = *******

# since Zendure introduces regional brokers please set the one where you have registered your device
# Global: mq.zen-iot.com
# EU: mqtteu.zen-iot.com
zen_mqtt = mqtteu.zen-iot.com
# likewise for the API endpoint please select the correct one
# Global: https://app.zendure.tech/v2
# EU: https://app.zendure.tech/eu
zen_api = https://app.zendure.tech/eu

[local]
mqtt_host = 192.168.2.50
mqtt_user = ****
mqtt_pwd = ****

As I am based in Germany, I am expecting that my account is on the EU server. To double-check I have issued the following request:

curl -i -v --json "{'password': '*****','account': '****','appId': '121c83f761305d6cf7e','appType': 'iOS','grantType': 'password','tenantId': ''}" \
-H "Content-Type: application/json" \
-H "Accept-Language: de-DE" \
-H "appVersion: 4.3.1" \
-H "User-Agent: Zendure/4.3.1 (iPhone; iOS 14.4.2; Scale/3.00)" \
-H "Accept: */*" \
-H "Authorization: Basic Q29uc3VtZXJBcHA6NX4qUmRuTnJATWg0WjEyMw==" \
-H "Blade-Auth': 'bearer (null)" \
https://app.zendure.tech/eu/auth/app/token

The reply included also the MQTT broker by Zendure (mqttee.zen-iot.com):

{
   "code": 200,
   "data": {
      "accessToken": "*****",
      "account": "",
      "authority": "",
      "avatar": "https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png",
      "countryCode": "DE",
      "iotPassword": "******",
      "iotUrl": "mqtteu.zen-iot.com",
      "iotUserName": "zenApp",
      "isNew": 1,
      "mallSwitch": 1,
      "oauthId": "",
      "serverH5Url": "https://app.zendure.tech",
      "serverNode": "eu",
      "serverNodeUrl": "https://app.zendure.tech/eu",
      "tenantId": "",
      "userId": "43639",
      "userName": "",
      "userType": "21",
      "whitelist": 0
   },
   "msg": "Vorgang erfolgreich",
   "success": true
}

However, after running the statuspage script in online mode, I am continuously getting in error when connecting to the mqtteu broker:

2024-07-23 14:59:37,325:INFO: Authenticating with Zendure ...
2024-07-23 14:59:40,042:INFO: Getting device list ...
2024-07-23 14:59:40,331:INFO: [
  {
    "id": 93304,
    "deviceKey": "***",
    "snNumber": "****",
    "name": "Hub 2000 Energiespeicher",
    "productId": 66,
    "productKey": "A8yh63",
    "onlineFlag": "00601",
    "productName": "SolarFlow Hub 2000",
    "wifiStatus": true,
    "blueState": false,
    "fourGStatus": false,
    "isShareFlag": "00601",
    "input": false,
    "output": false,
    "electricity": 95,
    "restState": 0,
    "upsMode": false,
    "upgradeStatusDes": "",
    "productType": 8,
    "upgradeStatus": {},
    "bindId": 0,
    "bindStatus": 0,
    "batteryCode": "",
    "packList": [],
    "inputPower": 0,
    "outputPower": 0,
    "slowChargePower": 0,
    "temperature": 0,
    "temperatureUnit": 0,
    "remainOutTime": 0,
    "bindType": 0,
    "seriesMode": 0,
    "parallelMode": 0,
    "networkType": 0,
    "standard": "O",
    "isSwitch": false,
    "url": "",
    "remainOil": 0,
    "genMode": 0,
    "shortCode": "H1",
    "phaseCheck": 0,
    "clusterList": [],
    "clusterNotice": false,
    "nodeStatus": 0,
    "clusterId": null,
    "phase": null
  }
]
2024-07-23 14:59:40,332:INFO: Getting device details for [93304] ...
2024-07-23 14:59:40,756:INFO: {
  "isShare": true,
  "productKey": "A8yh63",
  "productModelId": 40,
  "productName": "SolarFlow Hub 2000",
  "deviceName": "Hub 2000 Energiespeicher",
  "deviceId": 93304,
  "deviceKey": "***",
  "snNumber": "****",
  "onlineFlag": "00601",
  "standard": "",
  "consumerId": ***,
  "shortCode": "H1",
  "productType": 8,
  "priceType": "",
  "id": 22721,
  "masterSwitch": true,
  "restState": 0,
  "restTime": "",
  "hubState": 0,
  "wifiState": true,
  "wifiName": "****",
  "mac": "*****",
  "ip": "192.168.178.151",
  "buzzerSwitch": true,
  "autoHeat": 0,
  "loraInvState": 0,
  "loraAddr": "",
  "ambientSwitch": false,
  "ambientLightMode": 0,
  "ambientLightColor": 0,
  "ambientLightNess": 0,
  "solarInputPower": 0,
  "pvPower1": 0,
  "pvPower2": 0,
  "packInputPower": 0,
  "outputPackPower": 0,
  "outputHomePower": 0,
  "outputInversePower": 0,
  "bindSn": "",
  "invOutputPower": 0,
  "outputLimit": 200,
  "inputLimit": 0,
  "remainOutTime": 59940,
  "remainInputTime": 59940,
  "socSet": 950,
  "minSoc": 130,
  "packState": 0,
  "packNum": 1,
  "electricLevel": 95,
  "isDeleted": 0,
  "createTime": "2024-07-02T15:28:17Z",
  "updateTime": "2024-07-23T12:59:29Z",
  "inverseMaxPower": 800,
  "brandId": 1,
  "cycle": 0,
  "blueOta": 1,
  "solarInputPowerCycle": 0,
  "solarInputPower1Cycle": 0,
  "solarInputPower2Cycle": 0,
  "packInputPowerCycle": 0,
  "outputPackPowerCycle": 0,
  "outputInverseCycle": 0,
  "outputHomePowerCycle": 0,
  "gridInputPowerCycle": 0,
  "gridInputPower": 0,
  "smartMode": 0,
  "smartPower": 0,
  "pass": 0,
  "lowTemperature": 0,
  "heatState": 0,
  "modelName": "Hoymiles-HM-800",
  "passMode": 0,
  "lowTempNotice": 0,
  "autoRecover": 1,
  "acMode": 0,
  "acSwitch": 0,
  "dcSwitch": 0,
  "acOutputPower": 0,
  "dcOutputPower": 0,
  "acOutputPowerCycle": 0,
  "dcOutputPowerCycle": 0,
  "socStatus": 0,
  "gridStandard": "",
  "phaseCheck": null,
  "priority": 0,
  "gridReverse": 0,
  "reverseState": 0,
  "energyPower": 0,
  "lampSwitch": 0,
  "clusterSw": 0,
  "hyperTmp": 0,
  "packDataList": [
    {
      "updateUser": 0,
      "id": 332891,
      "deviceId": 93304,
      "socLevel": 95,
      "state": 0,
      "maxTemp": 312.1,
      "batteryCode": "****",
      "softVersion": 4110,
      "version": "1.0.14",
      "sn": "****",
      "heatState": 0,
      "packType": 2,
      "packName": "",
      "packModel": ""
    }
  ],
  "todayEnergy": 2521.8,
  "temperatureUnit": 0,
  "faultFlag": false,
  "bateUser": false,
  "deviceId2": 93304,
  "autoModel": 6,
  "solarPower1": 0,
  "solarPower2": 0,
  "bindProduct": null,
  "bindName": "",
  "bindDeviceKey": "",
  "bindDeviceState": "",
  "bindId": null,
  "aceSolarPower": 0,
  "clusterId": null,
  "nodeStatus": null,
  "clusterStatus": null,
  "hyperNum": 0,
  "remindTime": ""
}
2024-07-23 14:59:40,757:INFO: Zendure Auth: ZenAuth(productKey='A8yh63', deviceKey='***', clientId='****')
2024-07-23 14:59:41,077:INFO: Connectiong local MQTT: 192.168.2.50:1883
2024-07-23 14:59:41,078:INFO: Connecting to MQTT with: solarflow-statuspage-35
2024-07-23 14:59:41,084:INFO: Subscribing to topics...
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
 * Serving Flask app 'solarflow-status'
 * Debug mode: off
2024-07-23 14:59:41,087:INFO:  * Running on all addresses (0.0.0.0)
   WARNING: This is a development server. Do not use it in a production deployment.
 * Running on http://127.0.0.1:10001
 * Running on http://192.168.2.225:10001 (Press CTRL+C to quit)
2024-07-23 14:59:41,098:ERROR: Failed to connect, return code 4

2024-07-23 14:59:41,098:WARNING: Unexpected Zendure disconnection.Disconnecting reason  5
2024-07-23 14:59:41,099:INFO: Authenticating with Zendure ...
2024-07-23 14:59:41,136:INFO: Connected to MQTT Broker: Local MQTT (192.168.2.50:1883)
[...]

Then, I changed the broker to mq.zen-iot.com to which I could connect. However, I do not receive any messages and thus updates from this broker and the values on the status page are not updating.

Is there a way to explicitly change the broker "region"? Or is there any other advice?

BR André

reinhard-brandstaedter commented 1 month ago

Hi Andre,

in your case, I’d recommend to take the hub offline and have it completely report to your local MQTT (via sf-bt-manager). You can then have all native device telemetry locally and even control the hub via HA. Or you also run sf-control on top to get a sophisten automation of your hub.

kr, Reinhard

z-master42 commented 1 month ago

A bit off-topic, but are the lists of device details all MQTT topics? I noticed that there is a totalEnergy there, which is not provided via MQTT...

andreheuer commented 1 month ago

Hi Andre,

in your case, I’d recommend to take the hub offline and have it completely report to your local MQTT (via sf-bt-manager). You can then have all native device telemetry locally and even control the hub via HA. Or you also run sf-control on top to get a sophisten automation of your hub.

kr, Reinhard

Hi Reinhard,

thank you for your quick response. I will try this as next step.

But I am wondering: the username and password are hard-coded here: https://github.com/reinhard-brandstaedter/solarflow-statuspage/blob/cd5eb05676552cdd5588b4f5412b312dfa97e470/src/solarflow-status.py#L244 This is independent of the server (mqtteu... or mq...), so I should be able to connect anyhow. Or do I misunderstand here something?

BR André

edit: I have checked the DNS requests of my phone: it is requesting the mqtteu.zen-iot.com server when running the Zendure app...

reinhard-brandstaedter commented 1 month ago

Hi Andre,

you are right. The user/pwd of the App to MQTT is identical for everyone, thus it is hardcoded. Zendure uses the clientId for authorization purposes. This clientId is retrieved from the Zendure API and changes on every user login (which is your Zendure Account password). This is how Zendure protects what you (or your device can see in MQTT). I haven't really followed which additional mqtt brokers Zendure has now introduced and if/how they changed over time but mqtteu is correct when registering your device in Germany. However there is also a different API for Germany/EU and the login there should also work with your user/pwd there.

Unexpected Zendure disconnection.Disconnecting reason 5 means unauthorized thoug on the mqtt side...

reinhard-brandstaedter commented 1 month ago

A bit off-topic, but are the lists of device details all MQTT topics? I noticed that there is a totalEnergy there, which is not provided via MQTT...

No they ae not all MQTT topics, some of them are likely just server-side calculated or other details.