Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Add DuoBlock support for computedWaterDelta and computedQuattCop #64

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
46 changes: 46 additions & 0 deletions custom_components/quatt/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,15 @@
entity_registry_enabled_default=False,
suggested_display_precision=2,
),
SensorEntityDescription(
name="HP2 waterDelta",
key="hp2.computedWaterDelta",
icon="mdi:thermometer",
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
device_class=SensorDeviceClass.TEMPERATURE,
entity_registry_enabled_default=False,
suggested_display_precision=2,
),
SensorEntityDescription(
name="HP2 powerInput",
key="hp2.powerInput",
Expand Down Expand Up @@ -228,6 +237,43 @@
suggested_display_precision=2,
state_class="measurement",
),
# Combined
SensorEntityDescription(
name="Total powerInput",
key="computedPowerInput",
icon="mdi:heat-wave",
native_unit_of_measurement="W",
device_class=SensorDeviceClass.POWER,
entity_registry_enabled_default=False,
suggested_display_precision=0,
),
SensorEntityDescription(
name="Total power",
key="computedPower",
icon="mdi:heat-wave",
native_unit_of_measurement="W",
device_class=SensorDeviceClass.POWER,
entity_registry_enabled_default=False,
suggested_display_precision=0,
),
SensorEntityDescription(
name="Total waterDelta",
key="computedWaterDelta",
icon="mdi:thermometer",
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
device_class=SensorDeviceClass.TEMPERATURE,
entity_registry_enabled_default=False,
suggested_display_precision=2,
),
SensorEntityDescription(
name="Total Quatt COP",
key="computedQuattCop",
icon="mdi:heat-pump",
native_unit_of_measurement="CoP",
entity_registry_enabled_default=False,
suggested_display_precision=2,
state_class="measurement",
),
# Boiler
SensorEntityDescription(
name="Boiler temperature water inlet",
Expand Down
80 changes: 64 additions & 16 deletions custom_components/quatt/coordinator.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,73 +85,121 @@ def electicalPower(self):

def computedWaterDelta(self, parent_key: str = None):
"""Compute waterDelta."""
temperatureWaterOut = self.getValue("hp1.temperatureWaterOut")
temperatureWaterIn = self.getValue("hp1.temperatureWaterIn")
LOGGER.debug("computedWaterDelta.temperatureWaterOut %s", temperatureWaterOut)
LOGGER.debug("computedWaterDelta.temperatureWaterIn %s", temperatureWaterIn)
if parent_key is None:
parent_key = ""
temperatureWaterOut = self.getValue("hp2.temperatureWaterOut")
temperatureWaterIn = self.getValue("hp1.temperatureWaterIn")
else:
temperatureWaterOut = self.getValue(parent_key + ".temperatureWaterOut")
temperatureWaterIn = self.getValue(parent_key + ".temperatureWaterIn")

LOGGER.debug("%s.computedWaterDelta.temperatureWaterOut %s", parent_key, temperatureWaterOut)
LOGGER.debug("%s.computedWaterDelta.temperatureWaterIn %s", parent_key, temperatureWaterIn)

if temperatureWaterOut is None or temperatureWaterIn is None:
return None

return round(temperatureWaterOut - temperatureWaterIn, 2)

def computedHeatPower(self, parent_key: str = None):
"""Compute heatPower."""
computedWaterDelta = self.computedWaterDelta()
flowRate = self.getValue("flowMeter.flowRate")

LOGGER.debug("computedHeatPower.computedWaterDelta %s", computedWaterDelta)
LOGGER.debug("computedHeatPower.flowRate %s", flowRate)

if computedWaterDelta is None or flowRate is None:
return None

return round(
computedWaterDelta * flowRate * 1.137888,
2,
)

def computedPowerInput(self, parent_key: str = None):
"""Compute total powerInput."""
powerInputHp1 = self.getValue("hp1.powerInput", 0)
powerInputHp2 = self.getValue("hp2.powerInput", 0)

return float(powerInputHp1) + float(powerInputHp2)

def computedPower(self, parent_key: str = None):
"""Compute total powerInput."""
powerHp1 = self.getValue("hp1.power", 0)
powerHp2 = self.getValue("hp2.power", 0)

return float(powerHp1) + float(powerHp2)

def computedCop(self, parent_key: str = None):
"""Compute COP."""
electicalPower = self.electicalPower()
computedHeatPower = self.computedHeatPower()

LOGGER.debug("computedCop.electicalPower %s", electicalPower)
LOGGER.debug("computedCop.computedHeatPower %s", computedHeatPower)

if electicalPower is None or computedHeatPower is None:
return None

computedHeatPower = float(computedHeatPower)
if computedHeatPower == 0:
return None

electicalPower = float(electicalPower)
if electicalPower == 0:
return None

return round(computedHeatPower / electicalPower, 2)

def computedQuattCop(self, parent_key: str = None):
"""Compute Quatt COP."""
powerInput = self.getValue("hp1.powerInput")
powerOutput = self.getValue("hp1.power")
LOGGER.debug("computedQuattCop.powerInput %s", powerInput)
LOGGER.debug("computedQuattCop.powerOutput %s", powerOutput)
if parent_key is None:
parent_key = ""
powerInput = self.getValue("hp1.powerInput", 0) + self.getValue("hp2.powerInput", 0)
powerOutput = self.getValue("hp1.power", 0) + self.getValue("hp2.power", 0)
else:
powerInput = self.getValue(parent_key + ".powerInput")
powerOutput = self.getValue(parent_key + ".power")

LOGGER.debug("%s.computedQuattCop.powerInput %s", parent_key, powerInput)
LOGGER.debug("%s.computedQuattCop.powerOutput %s", parent_key, powerOutput)

if powerInput is None or powerOutput is None:
return None

powerOutput = float(powerOutput)
if powerOutput == 0:
return None

powerInput = float(powerInput)
if powerInput == 0:
return None

return round(powerOutput / powerInput, 2)

def computedDefrost(self, parent_key: str = None):
"""Compute Quatt Defrost State."""
powerInput = self.getValue("hp1.powerInput")
powerOutput = self.getValue("hp1.power")
LOGGER.debug("computedDefrost.powerInput %s", powerInput)
LOGGER.debug("computedDefrost.powerOutput %s", powerOutput)
if parent_key is None:
return None
else:
powerInput = self.getValue(parent_key + ".powerInput")
powerOutput = self.getValue(parent_key + ".power")

LOGGER.debug("%s.computedDefrost.powerInput %s", parent_key, powerInput)
LOGGER.debug("%s.computedDefrost.powerOutput %s", parent_key, powerOutput)

if powerInput is None or powerOutput is None:
return None

powerOutput = float(powerOutput)
if powerOutput == 0:
return None

powerInput = float(powerInput)
if powerInput == 0:
return None

return powerOutput < -100 and powerInput > 100

def computedSupervisoryControlMode(self, parent_key: str = None):
Expand All @@ -176,14 +224,14 @@ def computedSupervisoryControlMode(self, parent_key: str = None):
else:
return None

def getValue(self, value_path: str):
def getValue(self, value_path: str, default: float = None):
"""Check retrieve a value by dot notation."""
keys = value_path.split(".")
value = self.data
parent_key = None
for key in keys:
if value is None:
return None
return default

if key.isdigit():
key = int(key)
Expand All @@ -194,15 +242,15 @@ def getValue(self, value_path: str):
value_path,
)
LOGGER.debug(" in %s %s", value, type(value))
return None
return default

elif len(key) > 8 and key[0:8] == "computed" and key in dir(self):
method = getattr(self, key)
return method(parent_key)
elif key not in value:
LOGGER.warning("Could not find %s of %s", key, value_path)
LOGGER.debug("in %s", value)
return None
return default
value = value[key]
parent_key = key

Expand Down