Skip to content
Draft
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
2 changes: 1 addition & 1 deletion PyViCare/PyViCare.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ def __extract_devices(self):
for installation in self.installations:
for gateway in installation.gateways:
for device in gateway.devices:
if device.deviceType not in ["heating", "zigbee", "vitoconnect", "electricityStorage", "tcu", "ventilation"]:
if device.deviceType not in ["heating", "zigbee", "vitoconnect", "electricityStorage", "tcu", "ventilation", "roomControl"]:
continue # we are only interested in heating, photovoltaic, electricityStorage, and ventilation devices

accessor = ViCareDeviceAccessor(
Expand Down
10 changes: 10 additions & 0 deletions PyViCare/PyViCareDevice.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,16 @@ def _isTypeDevice(self, deviceType: str):
except PyViCareNotSupportedFeatureError:
return False

class DeviceWithComponent:

def __init__(self, device: Device, component: str) -> None:
self.service = device.service
self.component = component
self.device = device

@property
def id(self) -> str:
return self.component

class ZigbeeDevice(Device):

Expand Down
9 changes: 7 additions & 2 deletions PyViCare/PyViCareDeviceConfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import re

from PyViCare.PyViCareFloorHeating import FloorHeating, FloorHeatingChannel
from PyViCare.PyViCareRoomControl import RoomControl
from PyViCare.PyViCareFuelCell import FuelCell
from PyViCare.PyViCareGazBoiler import GazBoiler
from PyViCare.PyViCareHeatingDevice import HeatingDevice
Expand Down Expand Up @@ -58,6 +59,9 @@ def asFloorHeating(self):
def asFloorHeatingChannel(self):
return FloorHeatingChannel(self.service)

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

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

Expand Down Expand Up @@ -99,8 +103,9 @@ def asAutoDetectDevice(self):
(self.asVentilation, r"E3_ViAir", ["type:ventilation;central"]),
(self.asVentilation, r"E3_VitoPure", ["type:ventilation;purifier"]),
(self.asRadiatorActuator, r"E3_RadiatorActuator", ["type:radiator"]),
(self.asFloorHeating, r"Smart_zigbee_fht_main|E3_FloorHeatingCircuitDistributorBox", ["type:fhtMain"]),
(self.asFloorHeatingChannel, r"Smart_zigbee_fht_channel", ["type:fhtChannel"]),
(self.asFloorHeating, r"E3_FloorHeatingCircuitDistributorBox|Smart_zigbee_fht_main|E3_FloorHeatingCircuitDistributorBox", ["type:fhtMain"]),
(self.asFloorHeatingChannel, r"E3_FloorHeatingCircuitChannel|Smart_zigbee_fht_channel", ["type:fhtChannel"]),
(self.asRoomControl, r"E3_RoomControl_One_525", ["type:virtual;smartRoomControl"]),
(self.asRoomSensor, r"E3_RoomSensor", ["type:climateSensor"]),
(self.asRepeater, r"E3_Repeater", ["type:repeater"]),
(self.asGateway, r"E3_TCU41_x04", ["type:gateway;TCU100"]),
Expand Down
13 changes: 13 additions & 0 deletions PyViCare/PyViCareFloorHeatingCircuitChannel.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from PyViCare.PyViCareDevice import Device
from PyViCare.PyViCareUtils import handleNotSupported


class FloorHeatingCircuitChannel(Device):

@handleNotSupported
def getSerial(self):
return self.service.getProperty("device.name")["deviceId"]

@handleNotSupported
def getName(self):
return self.service.getProperty("device.name")["properties"]["name"]["value"]
223 changes: 223 additions & 0 deletions PyViCare/PyViCareRoomControl.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,223 @@
from typing import Any, List

from PyViCare.PyViCareDevice import Device, DeviceWithComponent
from PyViCare.PyViCareUtils import handleNotSupported, handleAPICommandErrors


class RoomControl(Device):

@property
def rooms(self) -> List[Any]:
return list([self.getRoom(x) for x in self.getAvailableRooms()])

def getRoom(self, room):
return Room(self, room)

@handleNotSupported
def getAvailableRooms(self):
return self.service.getProperty("rooms")["properties"]["enabled"]["value"]


class Room(DeviceWithComponent):
@property
def room(self) -> str:
return self.component

@handleNotSupported
def getType(self):
return self.service.getProperty(f"rooms.{self.room}")["properties"]["type"]["value"]

@handleNotSupported
def getName(self):
return self.service.getProperty(f"rooms.{self.room}")["properties"]["name"]["value"]

@property
def actors(self) -> List[Any]:
return list([self.getActor(x) for x in self.getAvailableActors()])

def getActor(self, actor):
return Actor(self, actor)

@handleNotSupported
def getAvailableActors(self):
return list(map(lambda _: _["deviceId"],
self.service.getProperty(f"rooms.{self.room}")["properties"]["actors"]["value"]))

@handleNotSupported
def getOperatingStateLevel(self) -> str:
return str(self.service.getProperty(f"rooms.{self.room}.operating.state")["properties"]["level"]["value"])

@handleNotSupported
def getOperatingStateDemand(self) -> str:
return str(self.service.getProperty(f"rooms.{self.room}.operating.state")["properties"]["demand"]["value"])

@handleNotSupported
def getOperatingStateReason(self) -> str:
return str(self.service.getProperty(f"rooms.{self.room}.operating.state")["properties"]["reason"]["value"])

@handleNotSupported
def getOperatingStateModifier(self) -> str:
return str(self.service.getProperty(f"rooms.{self.room}.operating.state")["properties"]["modifier"]["value"])

@handleNotSupported
def getSensorTemperature(self) -> float:
return float(self.service.getProperty(f"rooms.{self.room}.sensors.temperature")["properties"]["value"]["value"])

@handleNotSupported
def getSensorTemperatureStatus(self) -> str:
return str(self.service.getProperty(f"rooms.{self.room}.sensors.temperature")["properties"]["status"]["value"])

@handleNotSupported
def getSensorHumidity(self) -> float:
return float(self.service.getProperty(f"rooms.{self.room}.sensors.humidity")["properties"]["value"]["value"])

@handleNotSupported
def getSensorHumidityStatus(self) -> str:
return str(self.service.getProperty(f"rooms.{self.room}.sensors.humidity")["properties"]["status"]["value"])

@handleNotSupported
def getSensorCO2(self) -> float:
return float(self.service.getProperty(f"rooms.{self.room}.sensors.co2")["properties"]["value"]["value"])

@handleNotSupported
def getSensorCO2Status(self) -> str:
return str(self.service.getProperty(f"rooms.{self.room}.sensors.co2")["properties"]["status"]["value"])

@handleNotSupported
def getNormalHeatingTemperature(self) -> float:
return float(self.service.getProperty(f"rooms.{self.room}.operating.programs.normalHeating")["properties"][
"temperature"]["value"])

@handleNotSupported
def getNormalHeatingActive(self) -> bool:
return bool(
self.service.getProperty(f"rooms.{self.room}.operating.programs.normalHeating")["properties"]["active"][
"value"])

@handleAPICommandErrors
def setNormalHeatingTemperature(self, temperature: float) -> Any:
return self.service.setProperty(f"rooms.{self.room}.operating.programs.normalHeating", "setTemperature",
{'targetTemperature': temperature})

@handleNotSupported
def getReducedHeatingTemperature(self) -> float:
return float(self.service.getProperty(f"rooms.{self.room}.operating.programs.reducedHeating")["properties"][
"temperature"]["value"])

@handleNotSupported
def getReducedHeatingActive(self) -> bool:
return bool(
self.service.getProperty(f"rooms.{self.room}.operating.programs.reducedHeating")["properties"]["active"][
"value"])

@handleAPICommandErrors
def setReducedHeatingTemperature(self, temperature: float) -> Any:
return self.service.setProperty(f"rooms.{self.room}.operating.programs.reducedHeating", "setTemperature",
{'targetTemperature': temperature})

@handleNotSupported
def getComfortHeatingTemperature(self) -> float:
return float(self.service.getProperty(f"rooms.{self.room}.operating.programs.comfortHeating")["properties"][
"temperature"]["value"])

@handleNotSupported
def getComfortHeatingActive(self) -> bool:
return bool(
self.service.getProperty(f"rooms.{self.room}.operating.programs.comfortHeating")["properties"]["active"][
"value"])

@handleAPICommandErrors
def setComfortHeatingTemperature(self, temperature: float) -> Any:
return self.service.setProperty(f"rooms.{self.room}.operating.programs.comfortHeating", "setTemperature",
{'targetTemperature': temperature})

@handleNotSupported
def getNormalCoolingTemperature(self) -> float:
return float(self.service.getProperty(f"rooms.{self.room}.operating.programs.normalCooling")["properties"][
"temperature"]["value"])

@handleNotSupported
def getNormalCoolingActive(self) -> bool:
return bool(
self.service.getProperty(f"rooms.{self.room}.operating.programs.normalCooling")["properties"]["active"][
"value"])

@handleAPICommandErrors
def setNormalCoolingTemperature(self, temperature: float) -> Any:
return self.service.setProperty(f"rooms.{self.room}.operating.programs.normalCooling", "setTemperature",
{'targetTemperature': temperature})

@handleNotSupported
def getReducedCoolingTemperature(self) -> float:
return float(self.service.getProperty(f"rooms.{self.room}.operating.programs.reducedCooling")["properties"][
"temperature"]["value"])

@handleNotSupported
def getReducedCoolingActive(self) -> bool:
return bool(
self.service.getProperty(f"rooms.{self.room}.operating.programs.reducedCooling")["properties"]["active"][
"value"])

@handleAPICommandErrors
def setReducedCoolingTemperature(self, temperature: float) -> Any:
return self.service.setProperty(f"rooms.{self.room}.operating.programs.reducedCooling", "setTemperature",
{'targetTemperature': temperature})

@handleNotSupported
def getComfortCoolingTemperature(self) -> float:
return float(self.service.getProperty(f"rooms.{self.room}.operating.programs.comfortCooling")["properties"][
"temperature"]["value"])

@handleNotSupported
def getComfortCoolingActive(self) -> bool:
return bool(
self.service.getProperty(f"rooms.{self.room}.operating.programs.comfortCooling")["properties"]["active"][
"value"])

@handleAPICommandErrors
def setComfortCoolingTemperature(self, temperature: float) -> Any:
return self.service.setProperty(f"rooms.{self.room}.operating.programs.comfortCooling", "setTemperature",
{'targetTemperature': temperature})

@handleNotSupported
def getSchedule(self):
properties = self.service.getProperty(
f"rooms.{self.room}.schedule")["properties"]
return {
"active": properties["active"]["value"],
"mon": properties["entries"]["value"]["mon"],
"tue": properties["entries"]["value"]["tue"],
"wed": properties["entries"]["value"]["wed"],
"thu": properties["entries"]["value"]["thu"],
"fri": properties["entries"]["value"]["fri"],
"sat": properties["entries"]["value"]["sat"],
"sun": properties["entries"]["value"]["sun"]
}

# TODO: Set schedule

@handleNotSupported
def getManualTillNextScheduleActive(self) -> bool:
return bool(
self.service.getProperty(f"rooms.{self.room}.quickmodes.manualTillNextSchedule")["properties"]["active"][
"value"])

@handleAPICommandErrors
def setManualTillNextScheduleTemperature(self, temperature: float) -> Any:
return self.service.setProperty(f"rooms.{self.room}.quickmodes.manualTillNextSchedule", "setTemperature",
{'targetTemperature': temperature})

@handleAPICommandErrors
def activateManualTillNextSchedule(self, temperature: float) -> Any:
return self.service.setProperty(f"rooms.{self.room}.quickmodes.manualTillNextSchedule", "activate",
{'temperature': temperature})

@handleAPICommandErrors
def deactivateManualTillNextSchedule(self) -> Any:
return self.service.setProperty(f"rooms.{self.room}.quickmodes.manualTillNextSchedule", "deactivate", {})


class Actor(DeviceWithComponent):
@property
def actor(self) -> str:
return self.component
Loading