Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion PyViCare/PyViCareDeviceConfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,8 @@ def asAutoDetectDevice(self):
(self.asGateway, r"E3_TCU10_x07", ["type:gateway;TCU300"]),
(self.asElectricalEnergySystem, r"E3_VitoCharge_03", ["type:ees"]),
(self.asVentilation, r"E3_ViAir", ["type:ventilation"]),
(self.asGateway, r"Heatbox1", ["type:gateway;VitoconnectOpto1"])
(self.asGateway, r"Heatbox1", ["type:gateway;VitoconnectOpto1"]),
(self.asGateway, r"Heatbox2", ["type:gateway;VitoconnectOpto2/OT2"])
]

for (creator_method, type_name, roles) in device_types:
Expand Down
8 changes: 1 addition & 7 deletions PyViCare/PyViCareService.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
logger = logging.getLogger('ViCare')
logger.addHandler(logging.NullHandler())


def readFeature(entities, property_name):
feature = next(
(f for f in entities if f["feature"] == property_name), None)
Expand All @@ -18,22 +17,18 @@ def readFeature(entities, property_name):

return feature


def hasRoles(requested_roles: List[str], existing_roles: List[str]) -> bool:
return len(requested_roles) > 0 and set(requested_roles).issubset(set(existing_roles))


def buildSetPropertyUrl(accessor, property_name, action):
return f'/features/installations/{accessor.id}/gateways/{accessor.serial}/devices/{accessor.device_id}/features/{property_name}/commands/{action}'


class ViCareDeviceAccessor:
def __init__(self, _id: int, serial: str, device_id: str) -> None:
self.id = _id
self.serial = serial
self.device_id = device_id


class ViCareService:
def __init__(self, oauth_manager: AbstractViCareOAuthManager, accessor: ViCareDeviceAccessor, roles: List[str]) -> None:
self.oauth_manager = oauth_manager
Expand All @@ -49,12 +44,11 @@ def buildGetPropertyUrl(self, property_name):
return f'/features/installations/{self.accessor.id}/gateways/{self.accessor.serial}/features/{property_name}'
return f'/features/installations/{self.accessor.id}/gateways/{self.accessor.serial}/devices/{self.accessor.device_id}/features/{property_name}'


def hasRoles(self, requested_roles) -> bool:
return hasRoles(requested_roles, self.roles)

def _isGateway(self) -> bool:
return self.hasRoles(["type:gateway;VitoconnectOpto1"]) or self.hasRoles(["type:gateway;TCU300"])
return self.hasRoles(["type:gateway;VitoconnectOpto1"]) or self.hasRoles(["type:gateway;VitoconnectOpto2/OT2"]) or self.hasRoles(["type:gateway;TCU300"])

def setProperty(self, property_name: str, action: str, data: Any) -> Any:
url = buildSetPropertyUrl(
Expand Down
97 changes: 97 additions & 0 deletions tests/response/VitoconnectOpto2.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
{
"data": [
{
"feature": "gateway.devices",
"gatewayId": "##############",
"timestamp": "2024-03-28T05:06:02.633Z",
"isEnabled": true,
"isReady": true,
"apiVersion": 1,
"uri": "https://api.viessmann.com/iot/v1/features/installations/######/gateways/##############/features/gateway.devices",
"properties": {
"devices": {
"type": "DeviceList",
"value": [
{
"id": "gateway",
"fingerprint": "###",
"modelId": "Heatbox2_SRC",
"modelVersion": "###",
"name": "Heatbox 2 SRC, Vitoconnect",
"type": "vitoconnect",
"roles": [
"type:gateway;VitoconnectOpto2/OT2",
"type:hb2",
"type:legacy"
],
"status": "online"
},
{
"id": "0",
"fingerprint": "###",
"modelId": "VPlusHO1_40",
"modelVersion": "###",
"name": "VT 200 (HO1A / HO1B)",
"type": "heating",
"roles": [
"type:boiler",
"type:legacy",
"type:product;VPlusHO1"
],
"status": "online"
},
{
"id": "RoomControl-1",
"fingerprint": "###",
"modelId": "Smart_RoomControl",
"modelVersion": "###",
"name": "Smart_RoomControl_49",
"type": "roomControl",
"roles": [
"capability:monetization;FTDC",
"capability:monetization;OWD",
"capability:zigbeeCoordinator",
"type:legacy",
"type:virtual;smartRoomControl"
],
"status": "online"
},
{
"id": "zigbee-#####",
"fingerprint": "###",
"modelId": "Smart_Device_eTRV_generic_50",
"modelVersion": "ac746d50a111d3eb8fa54146c05971aa2bc5b5cc",
"name": "Smart_Device_eTRV_generic_50",
"type": "zigbee",
"roles": [
"type:actuator",
"type:legacy",
"type:radiator",
"type:smartRoomDevice"
],
"status": "online"
}
]
}
},
"commands": {}
},
{
"feature": "gateway.wifi",
"gatewayId": "##############",
"timestamp": "2024-03-30T17:31:57.758Z",
"isEnabled": true,
"isReady": true,
"apiVersion": 1,
"uri": "https://api.viessmann.com/iot/v1/features/installations/######/gateways/##############/features/gateway.wifi",
"properties": {
"strength": {
"type": "number",
"value": -41,
"unit": ""
}
},
"commands": {}
}
]
}
11 changes: 11 additions & 0 deletions tests/test_PyViCareDeviceConfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,11 @@ def test_autoDetect_VitoconnectOpto1_asGateway(self):
device_type = c.asAutoDetectDevice()
self.assertEqual("Gateway", type(device_type).__name__)

def test_autoDetect_VitoconnectOpto2_asGateway(self):
c = PyViCareDeviceConfig(self.service, "0", "Heatbox2_SRC", "Online")
device_type = c.asAutoDetectDevice()
self.assertEqual("Gateway", type(device_type).__name__)

def test_autoDetect_TCU300_asGateway(self):
c = PyViCareDeviceConfig(self.service, "0", "E3_TCU10_x07", "Online")
device_type = c.asAutoDetectDevice()
Expand All @@ -83,6 +88,12 @@ def test_autoDetect_RoleGateway_asGateway(self):
device_type = c.asAutoDetectDevice()
self.assertEqual("Gateway", type(device_type).__name__)

def test_autoDetect_RoleGateway_asGateway_vc_opto2(self):
self.service.hasRoles = has_roles(["type:gateway;VitoconnectOpto2/OT2"])
c = PyViCareDeviceConfig(self.service, "0", "Unknown", "Online")
device_type = c.asAutoDetectDevice()
self.assertEqual("Gateway", type(device_type).__name__)

def test_autoDetect_RoleGateway_asGateway_TCU300(self):
self.service.hasRoles = has_roles(["type:gateway;TCU300"])
c = PyViCareDeviceConfig(self.service, "0", "Unknown", "Online")
Expand Down
18 changes: 18 additions & 0 deletions tests/test_VitoconnectOpto2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import unittest

from PyViCare.PyViCareGateway import Gateway
from tests.ViCareServiceMock import ViCareServiceMock


class VitoconnectOpto2(unittest.TestCase):
def setUp(self):
self.service = ViCareServiceMock('response/VitoconnectOpto2.json')
self.device = Gateway(self.service)

def test_getSerial(self):
self.assertEqual(
self.device.getSerial(), "##############")

def test_getWifiSignalStrength(self):
self.assertEqual(
self.device.getWifiSignalStrength(), -41)