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
10 changes: 5 additions & 5 deletions PyViCare/PyViCare.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@ def initWithExternalOAuth(self, oauth_manager: AbstractViCareOAuthManager) -> No
def initWithBrowserOAuth(self, client_id: str, token_file: str) -> None:
self.initWithExternalOAuth(ViCareBrowserOAuthManager(client_id, token_file))

def __buildService(self, accessor, roles):
def __buildService(self, roles):
if self.cacheDuration > 0:
return ViCareCachedService(self.oauth_manager, accessor, roles, self.cacheDuration)
return ViCareService(self.oauth_manager, accessor, roles)
return ViCareCachedService(self.oauth_manager, roles, self.cacheDuration)
return ViCareService(self.oauth_manager, roles)

def __loadInstallations(self):
installations = self.oauth_manager.get(
Expand All @@ -61,11 +61,11 @@ def __extract_all_devices(self):
for device in gateway.devices:
accessor = ViCareDeviceAccessor(
installation.id, gateway.serial, device.id)
service = self.__buildService(accessor, device.roles)
service = self.__buildService(device.roles)

logger.info("Device found: %s (type=%s)", device.modelId, device.deviceType)

yield PyViCareDeviceConfig(service, device.id, device.modelId, device.status, device.deviceType, device.roles)
yield PyViCareDeviceConfig(accessor, service, device.modelId, device.status, device.deviceType, device.roles)


class DictWrap(object):
Expand Down
23 changes: 12 additions & 11 deletions PyViCare/PyViCareCachedService.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import logging
import threading
from typing import Any, List
from datetime import datetime
from typing import Any, List, Optional

from PyViCare.PyViCareAbstractOAuthManager import AbstractViCareOAuthManager
from PyViCare.PyViCareService import (ViCareDeviceAccessor, ViCareService,
Expand All @@ -18,24 +19,24 @@

class ViCareCachedService(ViCareService):

def __init__(self, oauth_manager: AbstractViCareOAuthManager, accessor: ViCareDeviceAccessor, roles: List[str], cacheDuration: int) -> None:
ViCareService.__init__(self, oauth_manager, accessor, roles)
def __init__(self, oauth_manager: AbstractViCareOAuthManager, roles: List[str], cacheDuration: int) -> None:
ViCareService.__init__(self, oauth_manager, roles)
self.__cacheDuration = cacheDuration
self.__cache = None
self.__cacheTime = None
self.__cache: Optional[dict] = None
self.__cacheTime: Optional[datetime] = None
self.__lock = threading.Lock()

def getProperty(self, property_name: str) -> Any:
data = self.__get_or_update_cache()
def getProperty(self, accessor: ViCareDeviceAccessor, property_name: str) -> Any:
data = self.__get_or_update_cache(accessor)
entities = data["data"]
return readFeature(entities, property_name)

def setProperty(self, property_name, action, data):
response = super().setProperty(property_name, action, data)
def setProperty(self, accessor: ViCareDeviceAccessor, property_name: str, action: str, data: Any) -> Any:
response = super().setProperty(accessor, property_name, action, data)
self.clear_cache()
return response

def __get_or_update_cache(self):
def __get_or_update_cache(self, accessor: ViCareDeviceAccessor):
with self.__lock:
if self.is_cache_invalid():
# we always set the cache time before we fetch the data
Expand All @@ -45,7 +46,7 @@ def __get_or_update_cache(self):
self.__cacheTime = ViCareTimer().now()

try:
data = self.fetch_all_features()
data = self.fetch_all_features(accessor)
except PyViCareNotPaidForError as e:
logger.error("Viessmann API denied access (PACKAGE_NOT_PAID_FOR). Features unavailable: %s", e)
if self.__cache is not None:
Expand Down
9 changes: 5 additions & 4 deletions PyViCare/PyViCareDevice.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from typing import Any

from PyViCare.PyViCareService import ViCareService
from PyViCare.PyViCareService import ViCareDeviceAccessor, ViCareService
from PyViCare.PyViCareUtils import PyViCareNotSupportedFeatureError, handleAPICommandErrors, handleNotSupported


Expand All @@ -11,14 +11,15 @@ class Device:
Note that currently, a new token is generated for each run.
"""

def __init__(self, service: ViCareService) -> None:
def __init__(self, accessor: ViCareDeviceAccessor, service: ViCareService) -> None:
self.accessor = accessor
self.service = service

def getProperty(self, property_name: str) -> Any:
return self.service.getProperty(property_name)
return self.service.getProperty(self.accessor, property_name)

def setProperty(self, property_name: str, action: str, data: Any) -> Any:
return self.service.setProperty(property_name, action, data)
return self.service.setProperty(self.accessor, property_name, action, data)

@handleNotSupported
def getSerial(self):
Expand Down
44 changes: 23 additions & 21 deletions PyViCare/PyViCareDeviceConfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from PyViCare.PyViCareRepeater import Repeater
from PyViCare.PyViCareElectricalEnergySystem import ElectricalEnergySystem
from PyViCare.PyViCareGateway import Gateway
from PyViCare.PyViCareService import ViCareDeviceAccessor, ViCareService
from PyViCare.PyViCareUtils import PyViCareNotPaidForError
from PyViCare.PyViCareVentilationDevice import VentilationDevice

Expand All @@ -25,64 +26,65 @@

class PyViCareDeviceConfig:
# pylint: disable=too-many-arguments,too-many-positional-arguments,too-many-instance-attributes
def __init__(self, service, device_id, device_model, status, device_type=None, roles=None):
def __init__(self, accessor: ViCareDeviceAccessor, service: ViCareService, device_model, status, device_type=None, roles=None):
self.accessor = accessor
self.service = service
self.device_id = device_id
self.device_id = accessor.device_id
self.device_model = device_model
self.status = status
self.device_type = device_type
self.roles = roles if roles is not None else []

def asGeneric(self):
return HeatingDevice(self.service)
return HeatingDevice(self.accessor, self.service)

def asGazBoiler(self):
return GazBoiler(self.service)
return GazBoiler(self.accessor, self.service)

def asFuelCell(self):
return FuelCell(self.service)
return FuelCell(self.accessor, self.service)

def asHeatPump(self):
return HeatPump(self.service)
return HeatPump(self.accessor, self.service)

def asOilBoiler(self):
return OilBoiler(self.service)
return OilBoiler(self.accessor, self.service)

def asPelletsBoiler(self):
return PelletsBoiler(self.service)
return PelletsBoiler(self.accessor, self.service)

def asHybridDevice(self):
return Hybrid(self.service)
return Hybrid(self.accessor, self.service)

def asRadiatorActuator(self):
return RadiatorActuator(self.service)
return RadiatorActuator(self.accessor, self.service)

def asFloorHeating(self):
return FloorHeating(self.service)
return FloorHeating(self.accessor, self.service)

def asFloorHeatingChannel(self):
return FloorHeatingChannel(self.service)
return FloorHeatingChannel(self.accessor, self.service)

def asRoomSensor(self):
return RoomSensor(self.service)
return RoomSensor(self.accessor, self.service)

def asRoomControl(self):
return RoomControl(self.service)
return RoomControl(self.accessor, self.service)

def asRepeater(self):
return Repeater(self.service)
return Repeater(self.accessor, self.service)

def asElectricalEnergySystem(self):
return ElectricalEnergySystem(self.service)
return ElectricalEnergySystem(self.accessor, self.service)

def asGateway(self):
return Gateway(self.service)
return Gateway(self.accessor, self.service)

def asVentilation(self):
return VentilationDevice(self.service)
return VentilationDevice(self.accessor, self.service)

def getConfig(self):
return self.service.accessor
return self.accessor

def getId(self):
return self.device_id
Expand Down Expand Up @@ -144,7 +146,7 @@ def asAutoDetectDevice(self):
def _isHybridByFeatures(self):
"""Check API features to detect hybrid devices (both burners and compressors)."""
try:
features = self.service.fetch_all_features()
features = self.service.fetch_all_features(self.accessor)
feature_names = [f["feature"] for f in features.get("data", [])]
has_burners = any(f.startswith("heating.burners") for f in feature_names)
has_compressors = any(f.startswith("heating.compressors") for f in feature_names)
Expand All @@ -162,7 +164,7 @@ def _isHybridByFeatures(self):
return False

def get_raw_json(self):
return self.service.fetch_all_features()
return self.service.fetch_all_features(self.accessor)

def dump_secure(self, flat=False):
device_info = {
Expand Down
2 changes: 1 addition & 1 deletion PyViCare/PyViCareFuelCell.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def getBurner(self, burner):

@handleNotSupported
def getAvailableBurners(self):
return get_available_burners(self.service)
return get_available_burners(self)

@handleNotSupported
def getReturnTemperature(self):
Expand Down
2 changes: 1 addition & 1 deletion PyViCare/PyViCareGazBoiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def getBurner(self, burner):

@handleNotSupported
def getAvailableBurners(self):
return get_available_burners(self.service)
return get_available_burners(self)

@handleNotSupported
def getGasConsumptionHeatingUnit(self):
Expand Down
8 changes: 4 additions & 4 deletions PyViCare/PyViCareHeatingDevice.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@ def all_set(_list: List[Any]) -> bool:
return all(v is not None for v in _list)


def get_available_burners(service):
def get_available_burners(device):
# workaround starting from 25.01.2022
# see: https://github.com/somm15/PyViCare/issues/243
available_burners = []
for burner in ['0', '1', '2', '3', '4', '5']:
with suppress(PyViCareNotSupportedFeatureError):
if service.getProperty(f"heating.burners.{burner}") is not None:
if device.getProperty(f"heating.burners.{burner}") is not None:
available_burners.append(burner)

return available_burners
Expand Down Expand Up @@ -701,8 +701,8 @@ def getHeatingSchedule(self):

@handleAPICommandErrors
def setHeatingSchedule(self, schedule: dict) -> None:
self.service.setProperty(f"heating.circuits.{self.circuit}.heating.schedule",
"setSchedule", {'newSchedule': schedule})
self.device.setProperty(f"heating.circuits.{self.circuit}.heating.schedule",
"setSchedule", {'newSchedule': schedule})

@handleNotSupported
def getHeatingScheduleModes(self) -> list: # type: ignore[type-arg]
Expand Down
2 changes: 1 addition & 1 deletion PyViCare/PyViCareOilBoiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def getBurner(self, burner):

@handleNotSupported
def getAvailableBurners(self):
return get_available_burners(self.service)
return get_available_burners(self)

@handleNotSupported
def getBoilerTemperature(self):
Expand Down
2 changes: 1 addition & 1 deletion PyViCare/PyViCarePelletsBoiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def getBurner(self, burner) -> PelletsBurner:

@handleNotSupported
def getAvailableBurners(self):
return get_available_burners(self.service)
return get_available_burners(self)

@handleNotSupported
def getBoilerTemperature(self):
Expand Down
Loading
Loading