Skip to content

Commit

Permalink
Merge pull request #64 from marcoboers/53-adjust-computedwaterdelta-c…
Browse files Browse the repository at this point in the history
…omputedquattcop-for-a-quatt-duoblock

Add DuoBlock support for computedWaterDelta and computedQuattCop
  • Loading branch information
marcoboers authored Dec 18, 2023
2 parents 77bee13 + 40eda9d commit 8aef516
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 16 deletions.
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

0 comments on commit 8aef516

Please # to comment.