From ab605914e46e50b4cce0db0263e87816e1f400ad Mon Sep 17 00:00:00 2001 From: feelingwalnut <34952101+feelingwalnut@users.noreply.github.com> Date: Sat, 20 Jan 2024 15:39:32 -0500 Subject: [PATCH 1/6] Update plugin.py attempt to detect if system is set for celsius or fahrenheit and convert setpoint entries if the latter. --- plugin.py | 37 ++++++++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/plugin.py b/plugin.py index 3ad2bd7..4d7c011 100644 --- a/plugin.py +++ b/plugin.py @@ -15,7 +15,7 @@ rather then more conventional hysteresis methods, so as to achieve a greater comfort.
It is a port to Domoticz of the original Vera plugin from Antor.

Set-up and Configuration

- See domoticz wiki above.
+ See domoticz wiki above.
@@ -27,10 +27,10 @@ - - + @@ -109,6 +109,7 @@ def __init__(self): self.loglevel = None self.intemperror = False self.versionsupported = False + # self.systemTempUnit = "C" # Default to Celsius return @@ -138,6 +139,17 @@ def onStart(self): Domoticz.Error("Minimum domoticz version is 2023.2") return + # Fetch the system settings from the API to determine temperature unit + settingsAPI = DomoticzAPI("type=command¶m=getsettings") + if settingsAPI and "status" in settingsAPI and settingsAPI["status"] == "OK" and "TempUnit" in settingsAPI: + TempUnit = settingsAPI["TempUnit"] + # Correctly set the system temperature unit based on the TempUnit value + self.systemTempUnit = "F" if TempUnit == 1 else "C" + Domoticz.Debug("System temperature unit is: {}".format(self.systemTempUnit)) + else: + Domoticz.Error("Failed to determine system temperature unit, defaulting to Celsius") + self.systemTempUnit = "C" # Default to Celsius if API call fails + # create the child devices if these do not exist yet devicecreated = [] if 1 not in Devices: @@ -180,7 +192,7 @@ def onStart(self): self.WriteLog("Outside Temperature sensors = {}".format(self.OutTempSensors), "Verbose") self.Heaters = parseCSV(Parameters["Mode3"]) self.WriteLog("Heaters = {}".format(self.Heaters), "Verbose") - + # build dict of status of all temp sensors to be used when handling timeouts for sensor in itertools.chain(self.InTempSensors, self.OutTempSensors): self.ActiveSensors[sensor] = True @@ -244,7 +256,22 @@ def onCommand(self, Unit, Command, Level, Color): nvalue = 1 if Level > 0 else 0 svalue = str(Level) - Devices[Unit].Update(nValue=nvalue, sValue=svalue) + # Check if the command is to update a setpoint + if Unit in (4, 5): # Assuming devices 4 and 5 are the setpoints for Normal and Economy modes + try: + # Convert Level to float to handle numeric operations + setpoint = float(Level) + except ValueError: + Domoticz.Error("Invalid setpoint value: {}".format(Level)) + return + + # Check if the setpoint is likely in Fahrenheit and convert to Celsius if necessary + if self.systemTempUnit == "F": + setpoint = (setpoint - 32) * (5.0 / 9.0) + Domoticz.Log("Setpoint is assumed to be in Fahrenheit, converting to Celsius: {}".format(setpoint)) + + # Update the device with the new (converted) setpoint + Devices[Unit].Update(nValue=0, sValue=str(setpoint)) if Unit in (1, 2, 4, 5): # force recalculation if control or mode or a setpoint changed self.nextcalc = datetime.now() From 66acdd5f7e9f153302468a576f39b4a504536af1 Mon Sep 17 00:00:00 2001 From: feelingwalnut <34952101+feelingwalnut@users.noreply.github.com> Date: Sat, 20 Jan 2024 16:13:49 -0500 Subject: [PATCH 2/6] Update plugin.py --- plugin.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/plugin.py b/plugin.py index 4d7c011..9534332 100644 --- a/plugin.py +++ b/plugin.py @@ -109,7 +109,7 @@ def __init__(self): self.loglevel = None self.intemperror = False self.versionsupported = False - # self.systemTempUnit = "C" # Default to Celsius + self.systemTempUnit = "C" # Default to Celsius return @@ -148,7 +148,6 @@ def onStart(self): Domoticz.Debug("System temperature unit is: {}".format(self.systemTempUnit)) else: Domoticz.Error("Failed to determine system temperature unit, defaulting to Celsius") - self.systemTempUnit = "C" # Default to Celsius if API call fails # create the child devices if these do not exist yet devicecreated = [] From ea6662bf871073a1bdaa07044d084602ad3bf346 Mon Sep 17 00:00:00 2001 From: feelingwalnut <34952101+feelingwalnut@users.noreply.github.com> Date: Sat, 20 Jan 2024 16:54:13 -0500 Subject: [PATCH 3/6] Update plugin.py round numbers to second decimal place for cleanliness. --- plugin.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/plugin.py b/plugin.py index 9534332..880037b 100644 --- a/plugin.py +++ b/plugin.py @@ -96,10 +96,10 @@ def __init__(self): self.pauserequestchangedtime = datetime.now() self.forced = False self.boost = True # boost heating when boostgap is reached - self.boostgap = 0.5 # gap in °C between inside temp and setpoint above which turbo mode is active + self.boostgap = 0.5 # gap in °C between inside temp and t above which turbo mode is active self.intemp = 20.0 self.outtemp = 20.0 - self.setpoint = 20.0 + self.t = 20.0 self.endheat = datetime.now() self.nextcalc = self.endheat self.lastcalc = self.endheat @@ -266,7 +266,8 @@ def onCommand(self, Unit, Command, Level, Color): # Check if the setpoint is likely in Fahrenheit and convert to Celsius if necessary if self.systemTempUnit == "F": - setpoint = (setpoint - 32) * (5.0 / 9.0) + # Convert to Celsius and round to two decimal places + setpoint = round((setpoint - 32) * (5.0 / 9.0), 2) Domoticz.Log("Setpoint is assumed to be in Fahrenheit, converting to Celsius: {}".format(setpoint)) # Update the device with the new (converted) setpoint From a0757427f58f20dab02eedcb18e275d43728c516 Mon Sep 17 00:00:00 2001 From: feelingwalnut <34952101+feelingwalnut@users.noreply.github.com> Date: Sat, 20 Jan 2024 16:57:42 -0500 Subject: [PATCH 4/6] Update plugin.py oops --- plugin.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugin.py b/plugin.py index 880037b..c90ce4c 100644 --- a/plugin.py +++ b/plugin.py @@ -96,10 +96,10 @@ def __init__(self): self.pauserequestchangedtime = datetime.now() self.forced = False self.boost = True # boost heating when boostgap is reached - self.boostgap = 0.5 # gap in °C between inside temp and t above which turbo mode is active + self.boostgap = 0.5 # gap in °C between inside temp and setpoint above which turbo mode is active self.intemp = 20.0 self.outtemp = 20.0 - self.t = 20.0 + self.setpoint = 20.0 self.endheat = datetime.now() self.nextcalc = self.endheat self.lastcalc = self.endheat From 892849475125a8b67ec0f92c719485feda539a38 Mon Sep 17 00:00:00 2001 From: feelingwalnut <34952101+feelingwalnut@users.noreply.github.com> Date: Sat, 20 Jan 2024 18:44:25 -0500 Subject: [PATCH 5/6] Update plugin.py --- plugin.py | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/plugin.py b/plugin.py index c90ce4c..ec6f3ea 100644 --- a/plugin.py +++ b/plugin.py @@ -267,7 +267,7 @@ def onCommand(self, Unit, Command, Level, Color): # Check if the setpoint is likely in Fahrenheit and convert to Celsius if necessary if self.systemTempUnit == "F": # Convert to Celsius and round to two decimal places - setpoint = round((setpoint - 32) * (5.0 / 9.0), 2) + setpoint = round((setpoint - 32) * (5.0 / 9.0), 1) Domoticz.Log("Setpoint is assumed to be in Fahrenheit, converting to Celsius: {}".format(setpoint)) # Update the device with the new (converted) setpoint @@ -515,20 +515,20 @@ def readTemps(self): if devicesAPI: for device in devicesAPI["result"]: # parse the devices for temperature sensors idx = int(device["idx"]) - if idx in self.InTempSensors: + if idx in self.InTempSensors or idx in self.OutTempSensors: if "Temp" in device: - Domoticz.Debug("device: {}-{} = {}".format(device["idx"], device["Name"], device["Temp"])) + temp = device["Temp"] + Domoticz.Debug("device: {}-{} = {}".format(device["idx"], device["Name"], temp)) + # Convert temperature from Fahrenheit to Celsius if systemTempUnit is "F" + if self.systemTempUnit == "F": + temp = round((temp - 32) * (5.0 / 9.0), 1) + Domoticz.Debug("Converted temperature to Celsius: {}".format(temp)) # check temp sensor is not timed out if not self.SensorTimedOut(idx, device["Name"], device["LastUpdate"]): - listintemps.append(device["Temp"]) - else: - Domoticz.Error("device: {}-{} is not a Temperature sensor".format(device["idx"], device["Name"])) - elif idx in self.OutTempSensors: - if "Temp" in device: - Domoticz.Debug("device: {}-{} = {}".format(device["idx"], device["Name"], device["Temp"])) - # check temp sensor is not timed out - if not self.SensorTimedOut(idx, device["Name"], device["LastUpdate"]): - listouttemps.append(device["Temp"]) + if idx in self.InTempSensors: + listintemps.append(temp) + elif idx in self.OutTempSensors: + listouttemps.append(temp) else: Domoticz.Error("device: {}-{} is not a Temperature sensor".format(device["idx"], device["Name"])) @@ -565,8 +565,7 @@ def readTemps(self): Domoticz.Debug("Inside Temperature = {}".format(self.intemp)) Domoticz.Debug("Outside Temperature = {}".format(self.outtemp)) return noerror - - + def getUserVar(self): variables = DomoticzAPI("type=command¶m=getuservariables") From b5751ba873006929b5f1a8c76423431e0c365bf9 Mon Sep 17 00:00:00 2001 From: feelingwalnut <34952101+feelingwalnut@users.noreply.github.com> Date: Sun, 21 Jan 2024 08:54:47 -0500 Subject: [PATCH 6/6] Update plugin.py seems to be working now . . . --- plugin.py | 88 +++++++++++++++++++++++++++++++++---------------------- 1 file changed, 53 insertions(+), 35 deletions(-) diff --git a/plugin.py b/plugin.py index ec6f3ea..aa8a717 100644 --- a/plugin.py +++ b/plugin.py @@ -15,7 +15,7 @@ rather then more conventional hysteresis methods, so as to achieve a greater comfort.
It is a port to Domoticz of the original Vera plugin from Antor.

Set-up and Configuration

- See domoticz wiki above.
+ See domoticz wiki above.
@@ -30,7 +30,7 @@
- + @@ -109,9 +109,14 @@ def __init__(self): self.loglevel = None self.intemperror = False self.versionsupported = False - self.systemTempUnit = "C" # Default to Celsius return + @staticmethod + def fahrenheitToCelsius(fahrenheit): + """Convert Fahrenheit to Celsius and round to the first decimal point.""" + celsius = (fahrenheit - 32) * 5.0 / 9.0 + return round(celsius, 1) + def onStart(self): @@ -142,13 +147,12 @@ def onStart(self): # Fetch the system settings from the API to determine temperature unit settingsAPI = DomoticzAPI("type=command¶m=getsettings") if settingsAPI and "status" in settingsAPI and settingsAPI["status"] == "OK" and "TempUnit" in settingsAPI: - TempUnit = settingsAPI["TempUnit"] - # Correctly set the system temperature unit based on the TempUnit value - self.systemTempUnit = "F" if TempUnit == 1 else "C" + self.systemTempUnit = "F" if settingsAPI["TempUnit"] == 1 else "C" Domoticz.Debug("System temperature unit is: {}".format(self.systemTempUnit)) else: + self.systemTempUnit = "C" # Default to Celsius Domoticz.Error("Failed to determine system temperature unit, defaulting to Celsius") - + # create the child devices if these do not exist yet devicecreated = [] if 1 not in Devices: @@ -191,7 +195,7 @@ def onStart(self): self.WriteLog("Outside Temperature sensors = {}".format(self.OutTempSensors), "Verbose") self.Heaters = parseCSV(Parameters["Mode3"]) self.WriteLog("Heaters = {}".format(self.Heaters), "Verbose") - + # build dict of status of all temp sensors to be used when handling timeouts for sensor in itertools.chain(self.InTempSensors, self.OutTempSensors): self.ActiveSensors[sensor] = True @@ -255,23 +259,31 @@ def onCommand(self, Unit, Command, Level, Color): nvalue = 1 if Level > 0 else 0 svalue = str(Level) - # Check if the command is to update a setpoint - if Unit in (4, 5): # Assuming devices 4 and 5 are the setpoints for Normal and Economy modes - try: - # Convert Level to float to handle numeric operations - setpoint = float(Level) - except ValueError: - Domoticz.Error("Invalid setpoint value: {}".format(Level)) - return + # Check if the unit is a setpoint device + if Unit in (4, 5): + # Fetch the system settings from the API to determine temperature unit + settingsAPI = DomoticzAPI("type=command¶m=getsettings") + if settingsAPI and "status" in settingsAPI and settingsAPI["status"] == "OK" and "TempUnit" in settingsAPI: + currentSystemTempUnit = "F" if settingsAPI["TempUnit"] == 1 else "C" + Domoticz.Debug("Current system temperature unit is: {}".format(currentSystemTempUnit)) + else: + currentSystemTempUnit = "C" # Default to Celsius + Domoticz.Error("Failed to determine current system temperature unit, defaulting to Celsius") + + # Only convert level from Fahrenheit to Celsius if system is set to Fahrenheit + if currentSystemTempUnit == "F": + # Convert level from Fahrenheit to Celsius + Level = self.fahrenheitToCelsius(Level) + # Update svalue with the converted and clamped level + svalue = str(Level) + else: + # System is set to Celsius, no conversion needed + sValue = str(Level) - # Check if the setpoint is likely in Fahrenheit and convert to Celsius if necessary - if self.systemTempUnit == "F": - # Convert to Celsius and round to two decimal places - setpoint = round((setpoint - 32) * (5.0 / 9.0), 1) - Domoticz.Log("Setpoint is assumed to be in Fahrenheit, converting to Celsius: {}".format(setpoint)) + # Update the system temperature unit to the current setting + self.systemTempUnit = currentSystemTempUnit - # Update the device with the new (converted) setpoint - Devices[Unit].Update(nValue=0, sValue=str(setpoint)) + Devices[Unit].Update(nValue=nvalue, sValue=svalue) if Unit in (1, 2, 4, 5): # force recalculation if control or mode or a setpoint changed self.nextcalc = datetime.now() @@ -515,23 +527,28 @@ def readTemps(self): if devicesAPI: for device in devicesAPI["result"]: # parse the devices for temperature sensors idx = int(device["idx"]) - if idx in self.InTempSensors or idx in self.OutTempSensors: + if idx in self.InTempSensors: if "Temp" in device: - temp = device["Temp"] - Domoticz.Debug("device: {}-{} = {}".format(device["idx"], device["Name"], temp)) - # Convert temperature from Fahrenheit to Celsius if systemTempUnit is "F" - if self.systemTempUnit == "F": - temp = round((temp - 32) * (5.0 / 9.0), 1) - Domoticz.Debug("Converted temperature to Celsius: {}".format(temp)) + Domoticz.Debug("device: {}-{} = {}".format(device["idx"], device["Name"], device["Temp"])) # check temp sensor is not timed out if not self.SensorTimedOut(idx, device["Name"], device["LastUpdate"]): - if idx in self.InTempSensors: - listintemps.append(temp) - elif idx in self.OutTempSensors: - listouttemps.append(temp) + listintemps.append(device["Temp"]) + else: + Domoticz.Error("device: {}-{} is not a Temperature sensor".format(device["idx"], device["Name"])) + elif idx in self.OutTempSensors: + if "Temp" in device: + Domoticz.Debug("device: {}-{} = {}".format(device["idx"], device["Name"], device["Temp"])) + # check temp sensor is not timed out + if not self.SensorTimedOut(idx, device["Name"], device["LastUpdate"]): + listouttemps.append(device["Temp"]) else: Domoticz.Error("device: {}-{} is not a Temperature sensor".format(device["idx"], device["Name"])) + # Convert temperatures from Fahrenheit to Celsius if needed + if self.systemTempUnit == "F": + listintemps = [self.fahrenheitToCelsius(temp) for temp in listintemps] + listouttemps = [self.fahrenheitToCelsius(temp) for temp in listouttemps] + # calculate the average inside temperature nbtemps = len(listintemps) if nbtemps > 0: @@ -565,7 +582,8 @@ def readTemps(self): Domoticz.Debug("Inside Temperature = {}".format(self.intemp)) Domoticz.Debug("Outside Temperature = {}".format(self.outtemp)) return noerror - + + def getUserVar(self): variables = DomoticzAPI("type=command¶m=getuservariables")