openviess / PyViCare

Python Library to access Viessmann ViCare API
Apache License 2.0
135 stars 87 forks source link

Viessmann ViCare smart thermostat - ZK03840 #342

Closed diricxbart closed 11 months ago

diricxbart commented 11 months ago

Hi,

My setup is a Viessmann Vitodens 222-W B2LA-26 connected to a Vitoconnect OPTO2. Additionally I have several ViCare thermostats (ZK03840). However, these thermostats don't seem to be supported by PyViCare.

device.getModel() returns Smart_Device_eTRV_generic_50

device.dump_secure() returns:

{
    "data": [
        {
            "apiVersion": 1,
            "commands": {},
            "deviceId": "zigbee-6c5deadbeef2",
            "feature": "device.messages.errors.raw",
            "gatewayId": "################",
            "isEnabled": true,
            "isReady": true,
            "properties": {
                "entries": {
                    "type": "array",
                    "value": []
                }
            },
            "timestamp": "2023-11-24T10:41:20.071Z",
            "uri": "https://api.viessmann.com/iot/v1/features/installations/#######/gateways/################/devices/zigbee-6c5deadbeef2/features/device.messages.errors.raw"
        }
    ]
}

The ViCare app allows to read and send temperature per room, this kind of functionality doesn't seem to be exposed, or am I missing something?

Could support for this (and ultimately in the home assistant integration) be added?

Best regards, Bart

CFenner commented 11 months ago

At least there seems to be a test for that: https://github.com/somm15/PyViCare/blob/master/tests/test_zigbee_zk03840.py

Is the data you show from the library itself or from the Home Assistant integration? If it's from HA, do you use the "official" integration or the custom integration?

diricxbart commented 11 months ago

I'm using the standard Viessmann ViCare integration (https://www.home-assistant.io/integrations/vicare/), I wasn't aware of another custom integration... But looking at the changelog of the custom integration, I do see the following "Support for Zigbee thermostats as climate entities" added in 1.0.0-beta.1, which seems interesting...

The above dump can be obtained using the following:

import json
from PyViCare.PyViCare import PyViCare
vicare = PyViCare()
vicare.initWithCredentials(email, password, client_id, "token.save")
device_nr = 2
assert vicare.devices[device_nr].getModel() == "Smart_Device_eTRV_generic_50"
print(json.loads(vicare.devices[2].dump_secure()))

So it's using this repository directly...

Based on your pointer to the unit test, I tried the following:

from PyViCare.PyViCare import PyViCare
from PyViCare.PyViCareRadiatorActuator import RadiatorActuator
vicare = PyViCare()
vicare.initWithCredentials(email, password, client_id, "token.save")
device_nr = 2
assert vicare.devices[device_nr].getModel() == "Smart_Device_eTRV_generic_50"
device = RadiatorActuator(vicare.devices[device_nr].service)
device.getTemperature()

which however yields a PyViCareNotSupportedFeatureError: device.sensors.temperature

If I look at vicare.devices[2].service.__dict__, I see:

{'oauth_manager': <PyViCare.PyViCareOAuthManager.ViCareOAuthManager at 0x7xxxx0>,
 'accessor': <PyViCare.PyViCareService.ViCareDeviceAccessor at 0x7xxxx0>,
 'roles': ['type:actuator',
  'type:legacy',
  'type:radiator',
  'type:smartRoomDevice'],
 '_ViCareCachedService__cacheDuration': 60,
 '_ViCareCachedService__cache': {'data': [{'properties': {'entries': {'type': 'array',
      'value': []}},
    'commands': {},
    'apiVersion': 1,
    'uri': 'https://api.viessmann.com/iot/v1/features/installations/xxxxxx/gateways/xxxxxxxxx/devices/zigbee-6c5xxxxxx0da/features/device.messages.errors.raw',
    'gatewayId': 'xxxxxx',
    'feature': 'device.messages.errors.raw',
    'timestamp': '2023-11-28T19:17:56.144Z',
    'isEnabled': True,
    'isReady': True,
    'deviceId': 'zigbee-6c5xxxxxxx0da'}]},
 '_ViCareCachedService__cacheTime': datetime.datetime(2023, 11, 29, 7, 36, 11, 128479),
 '_ViCareCachedService__lock': <unlocked _thread.lock object at 0x7xxxx0>}

Which is very different from the mock response json defined here: https://github.com/somm15/PyViCare/blob/master/tests/response/zigbee_zk03840.json

I'm especially worried about the device.messages.errors.raw... This also makes me think that as it is now, I should not have any hopes of proper support for my setup in the unofficial integration, as the underlying library returns an error. Or am I missing something?

Note that these devices do work correctly via the Viessmann ViCare app.

CFenner commented 11 months ago

Your accessing device 2 from the code above. But the home assistant native integration does not support multiple devices yet, the custom integration does. But I'm on to that 😉

Can you query the device via the viessmann api? Do you see it in the App? I wonder if there could be some kind of setup issues. I think the dump_secure directly gives the api response. Thus it would be no issue of the library.

diricxbart commented 11 months ago

Can you query the device via the viessmann api? If I do the following:

vicare = PyViCare()
vicare.initWithCredentials(email, password, client_id, "token.save")
installationId = "xxx"
gatewaySerial = "xxx"
deviceId = "zigbee-6xxxa"
print(vicare.oauth_manager.get(f"/equipment/installations/{installationId}/gateways/{gatewaySerial}/devices/{deviceId}/features"))

I receive as response:

{'data': [{'properties': {'entries': {'type': 'array', 'value': []}},
'commands': {},
'apiVersion': 1,
'uri': 'https://api.viessmann.com/iot/v1/equipment/installations/xxx/gateways/xxx/devices/zigbee-6xxxa/features/device.messages.errors.raw',
'gatewayId': 'xxx',
'feature': 'device.messages.errors.raw',
'timestamp': '2023-11-28T19:17:56.144Z',
'isEnabled': True,
'isReady': True,
'deviceId': 'zigbee-6xxxa'}]}

I also tried using the v2 API by exposing a get_v2 in PyViCareAbstractOAuthManager with a v2 base URL on this endpoint: https://api.viessmann.com/iot/v2/features, but received a similar result...

Am I using an incorrect API? Or an incorrect device ID? Or ...?

Do you see it in the App?

I do see all my thermostats in the ViCare app (including per-device signal strength, battery level, temperature, orientation of the temperature on the small display, ...)

diricxbart commented 11 months ago

I suspect I found the reason why this is not working. If you look at the API, there are different pricing options: https://developer.viessmann.com/start/pricing.html (click on the "Show all plan details").

Now I'm using the basic 'free' version, which doesn't include the Smart climate (Single Room Control) option, which when you hover the (i) icon gives as additional information: Supported smart climate devices: Thermostatic radiator valves (TRV), floor heating thermostats (FHT) and climate sensors. My thermostats are TRV's: Smart_Device_eTRV_generic_50.

To enable this option, I would need the Advanced plan, which comes at a whopping 19.99€ / month, and is only available in Germany...

Now I'm thinking: why didn't I buy the Tado devices. I really feel like swearing now...

CFenner commented 11 months ago

🤯 who would pay 20€ for that!

One last idea, looks like the devices are Zigbee. Can you cut them off from ViCare and try to add them to HA directly. Would that make any sense?

diricxbart commented 11 months ago

I know, that's basically blocking off usage of those devices outside of their own app...

The Zigbee device is actually documented: https://www.zigbee2mqtt.io/devices/ZK03840.html But people are struggling with integrating it properly: https://github.com/Koenkk/zigbee2mqtt/discussions/14101 I haven't found a good guide on how to achieve this yet...

But the main reason I'm reluctant to do this, is that now the heater is modulated based on the current and target temperature for the different rooms. If I control those devices directly, I'm opening up a can of worms...