From d9d40ad8d855ae1bf239175b8d64d1daaed03625 Mon Sep 17 00:00:00 2001 From: vindaalex Date: Fri, 3 May 2024 23:20:40 +0200 Subject: [PATCH 1/5] depricated EventType --- custom_components/multizone_thermostat/climate.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/custom_components/multizone_thermostat/climate.py b/custom_components/multizone_thermostat/climate.py index 00e3e21..fcee164 100644 --- a/custom_components/multizone_thermostat/climate.py +++ b/custom_components/multizone_thermostat/climate.py @@ -46,7 +46,7 @@ STATE_UNAVAILABLE, STATE_UNKNOWN, ) -from homeassistant.core import DOMAIN as HA_DOMAIN, CoreState, HomeAssistant, callback +from homeassistant.core import DOMAIN as HA_DOMAIN, CoreState, HomeAssistant, callback, Event from homeassistant.exceptions import ConditionError from homeassistant.helpers import condition from homeassistant.helpers.entity_platform import AddEntitiesCallback @@ -60,7 +60,7 @@ from homeassistant.helpers.reload import async_setup_reload_service from homeassistant.helpers.restore_state import RestoreEntity from homeassistant.helpers.template import state_attr -from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType, EventType +from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType from . import DOMAIN, PLATFORMS, UKF_config, hvac_setting, services from .const import ( @@ -997,7 +997,7 @@ async def _async_routine_track_satelites( @callback def _async_indoor_temp_change( - self, event: EventType[EventStateChangedData] + self, event: Event[EventStateChangedData] ) -> None: """Handle temperature change. @@ -1035,7 +1035,7 @@ def _async_indoor_temp_change( @callback def _async_outdoor_temp_change( - self, event: EventType[EventStateChangedData] + self, event: Event[EventStateChangedData] ) -> None: """Handle outdoor temperature changes. @@ -1152,7 +1152,7 @@ def _async_stuck_switch_check(self, now) -> None: ) @callback - def _async_satelite_change(self, event: EventType[EventStateChangedData]) -> None: + def _async_satelite_change(self, event: Event[EventStateChangedData]) -> None: """Handle satelite thermostat changes.""" new_state = event.data.get("new_state") if not new_state: @@ -1197,7 +1197,7 @@ def _async_satelite_change(self, event: EventType[EventStateChangedData]) -> Non # self.schedule_update_ha_state(force_refresh=False) @callback - def _async_switches_change(self, event: EventType[EventStateChangedData]) -> None: + def _async_switches_change(self, event: Event[EventStateChangedData]) -> None: """Handle device switch state changes.""" new_state = event.data.get("new_state") entity_id = event.data.get(ATTR_ENTITY_ID) From 79648b4bab8b2a722b2b3db9b9dcb274ceca0cde Mon Sep 17 00:00:00 2001 From: vindaalex Date: Fri, 3 May 2024 23:21:04 +0200 Subject: [PATCH 2/5] ClimateEntityFeature --- custom_components/multizone_thermostat/climate.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/custom_components/multizone_thermostat/climate.py b/custom_components/multizone_thermostat/climate.py index fcee164..284b81e 100644 --- a/custom_components/multizone_thermostat/climate.py +++ b/custom_components/multizone_thermostat/climate.py @@ -190,6 +190,7 @@ class MultiZoneThermostat(ClimateEntity, RestoreEntity): """Representation of a MultiZone Thermostat device.""" _attr_should_poll = False + _enable_turn_on_off_backwards_compatibility = False def __init__( self, @@ -2128,7 +2129,7 @@ def _is_valve_open(self, hvac_mode: HVACMode | None = None) -> bool: def supported_features(self): """Return the list of supported features.""" return ( - ClimateEntityFeature.PRESET_MODE | ClimateEntityFeature.TARGET_TEMPERATURE + ClimateEntityFeature.TURN_OFF | ClimateEntityFeature.TURN_ON | ClimateEntityFeature.PRESET_MODE | ClimateEntityFeature.TARGET_TEMPERATURE ) @property From cf2a13789f487cbead51f48f6f75a7e1aac40550 Mon Sep 17 00:00:00 2001 From: vindaalex Date: Fri, 3 May 2024 23:21:36 +0200 Subject: [PATCH 3/5] bugfix PID controller variable --- .../multizone_thermostat/hvac_setting.py | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/custom_components/multizone_thermostat/hvac_setting.py b/custom_components/multizone_thermostat/hvac_setting.py index aa0887e..b312177 100644 --- a/custom_components/multizone_thermostat/hvac_setting.py +++ b/custom_components/multizone_thermostat/hvac_setting.py @@ -179,7 +179,7 @@ def calculate( self.run_pid(force) if self._wc and self._pid: # avoid integral run-off when sum is negative - pid = self._pid.PID[PID_CONTROLLER].get_PID_parts + pid = self._pid_cntrl.get_PID_parts if ( pid["p"] < 0 # too warm and pid["i"] < -self._wc[ATTR_CONTROL_PWM_OUTPUT] @@ -216,7 +216,7 @@ def start_master(self, reset: bool = False) -> None: """Init the master mode.""" if reset: self._satelites = {} - + self.nesting = pwm_nesting.Nesting( self._name, operation_mode=self._operation_mode, @@ -230,12 +230,11 @@ def start_master(self, reset: bool = False) -> None: def start_pid(self) -> None: """Init the PID controller.""" self._logger.debug("Init pid settings") - self._pid.PID = {} lower_pwm_scale, upper_pwm_scale = self.pwm_scale_limits(self._pid) kp, ki, kd = self.get_pid_param(self._pid) # pylint: disable=invalid-name - self._pid.PID[PID_CONTROLLER] = pid_controller.PIDController( + self._pid_cntrl = pid_controller.PIDController( self._name, CONF_PID_MODE, self.get_operate_cycle_time.seconds, @@ -314,7 +313,7 @@ def run_pid(self, force: bool = False) -> None: if self.is_hvac_master_mode and current == 0: self._pid[ATTR_CONTROL_PWM_OUTPUT] = 0 else: - self._pid[ATTR_CONTROL_PWM_OUTPUT] = self._pid.PID[PID_CONTROLLER].calc( + self._pid[ATTR_CONTROL_PWM_OUTPUT] = self._pid_cntrl.calc( current, setpoint, force=force ) @@ -719,25 +718,25 @@ def set_pid_param( self._pid[ATTR_KD] = kd if update: - self._pid.PID[PID_CONTROLLER].set_pid_param(kp=kp, ki=ki, kd=kd) + self._pid_cntrl.set_pid_param(kp=kp, ki=ki, kd=kd) def pid_reset_time(self) -> None: """Reset the current time for PID to avoid overflow of the intergral part when switching between hvac modes.""" - self._pid.PID[PID_CONTROLLER].reset_time() + self._pid_cntrl.reset_time() def set_integral(self, integral: float) -> None: """Overwrite integral value.""" - self._pid.PID[PID_CONTROLLER].integral = integral + self._pid_cntrl.integral = integral @property def get_integral(self) -> float: """Get pid integral value.""" - return self._pid.PID[PID_CONTROLLER].integral + return self._pid_cntrl.integral @property def get_velocity(self) -> float: """Get pid velocity value.""" - return self._pid.PID[PID_CONTROLLER].differential + return self._pid_cntrl.differential @property def get_ka_kb_param(self) -> list: @@ -997,7 +996,7 @@ def get_variable_attr(self) -> ConfigType: if self.is_prop_pid_mode: tmp_dict["PID_values"] = self.get_pid_param(self._pid) if self.is_prop_pid_mode: - PID_parts = self._pid.PID[PID_CONTROLLER].get_PID_parts + PID_parts = self._pid_cntrl.get_PID_parts if self.detailed_output: tmp_dict["PID_P"] = round(PID_parts["p"], 3) tmp_dict["PID_I"] = round(PID_parts["i"], 3) From 355106948e822a1c1196865ef1afd2615b980fd9 Mon Sep 17 00:00:00 2001 From: vindaalex Date: Fri, 3 May 2024 23:22:03 +0200 Subject: [PATCH 4/5] bugfix example sensor unit --- examples/multizone thermostat - explained.yaml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/examples/multizone thermostat - explained.yaml b/examples/multizone thermostat - explained.yaml index af4664b..886f2c0 100644 --- a/examples/multizone thermostat - explained.yaml +++ b/examples/multizone thermostat - explained.yaml @@ -94,25 +94,25 @@ sensor: - platform: template sensors: mz_sensor_1: - unit_of_measurement: "degrees" + unit_of_measurement: "°C" value_template: "{{ states('input_number.mz_sensor_temperature_1') | float(0) }}" mz_sensor_2: - unit_of_measurement: "degrees" + unit_of_measurement: "°C" value_template: "{{ states('input_number.mz_sensor_temperature_2') | float(0) }}" mz_sensor_3: - unit_of_measurement: "degrees" + unit_of_measurement: "°C" value_template: "{{ states('input_number.mz_sensor_temperature_3') | float(0) }}" mz_sensor_4: - unit_of_measurement: "degrees" + unit_of_measurement: "°C" value_template: "{{ states('input_number.mz_sensor_temperature_4') | float(0) }}" mz_sensor_5: - unit_of_measurement: "degrees" + unit_of_measurement: "°C" value_template: "{{ states('input_number.mz_sensor_temperature_5') | float(0) }}" mz_sensor_6: - unit_of_measurement: "degrees" + unit_of_measurement: "°C" value_template: "{{ states('input_number.mz_sensor_temperature_6') | float(0) }}" mz_sensor_out_1: - unit_of_measurement: "degrees" + unit_of_measurement: "°C" value_template: "{{ states('input_number.mz_sensor_outdoor_temperature_1') | float(0) }}" filt_sensor1: From d697d540c04ecf692dffa7bd52613222139a3872 Mon Sep 17 00:00:00 2001 From: vindaalex Date: Fri, 3 May 2024 23:36:19 +0200 Subject: [PATCH 5/5] v0.7.1 --- README.md | 105 ++++++++++-------- .../multizone_thermostat/manifest.json | 2 +- 2 files changed, 61 insertions(+), 46 deletions(-) diff --git a/README.md b/README.md index 5a634ef..26e5ae5 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ This is a home assistant custom component. It is a thermostat including various Note: This is only the required software to create a (zoned) thermostat. Especially zoned heating systems will affect the flow in your heating system vy closing and opening valves. Please check your heating system if modifications are requried to handle the flow variations, such as: pump settings, bypass valves etc. + ## Installation: 1. Go to default /homeassistant/.homeassistant/ (it's where your configuration.yaml is) 2. Create /custom_components/ directory if it does not already exist @@ -15,11 +16,47 @@ This is only the required software to create a (zoned) thermostat. Especially zo 5. Set up the multizone_thermostat and have fun -# thanx to: +## thanx to: by borrowing and continuouing on code from: - DB-CL https://github.com/DB-CL/home-assistant/tree/new_generic_thermostat stale pull request with detailed seperation of hvac modes - fabian degger (PID thermostat) originator PID control in generic thermostat, https://github.com/aendle/custom_components + +# Explanatory notes +Within this readme several abbreviations are used to describe the working and used methodolgy. Hereunder the most relevant are described. + +## Pulse Width Modulation (PWM) +"PWM" stands for Pulse Width Modulation. Pulse Width Modulation is a technique often used in conjunction with PID controllers to regulate the amount of power delivered to a system, such as the heating elements in each zone of your underfloor heating system. + +Pulse Width Modulation (PWM) is used to adjust the amount of power delivered to an electronic device by effectively turning the heating (or cooling) on and off at a "fast" rate. The "width" of the "on" time (the pulse) is varied (modulated) to represent a specific power delivery level. When the pulse is wider (meaning the device is on for a longer period), more power is delivered to the heating element, increasing the temperature. Conversely, a narrower pulse delivers less power, reducing the temperature. + +https://en.wikipedia.org/wiki/Pulse-width_modulation + +## proportional–integral–derivative controller (PID) + +The PID controller calculates the difference between a desired setpoint (the target temperature) and the actual temperature measured by the sensors in each zone. Based on this difference (the error), and the rate of temperature change, the PID controller adjusts the PWM signal to increase or decrease the heat output, aiming to minimize the error over time and maintain a stable temperature in each zone. + +The use of PWM in your underfloor heating system allows for precise control over the temperature in each zone by adjusting the duty cycle of the electrical power to the heating elements. This method is efficient and can lead to more uniform temperature control and potentially lower energy consumption, as it adjusts the heating output to the actual need in each zone. + +PID controller explained: +- https://en.wikipedia.org/wiki/PID_controller +- [https://controlguru.com/table-of-contents/](https://controlguru.com/table-of-contents/) + +config examples: +slow low temperature underfloor heating: + PID_mode: + kp: 30 + ki: 0.005 + kd: -24000 + +high temperature radiator: + PID_mode: + kp: 80 + ki: 0.09 + kd: -5000 + +* underfloor heating parameter optimisation: https://www.google.nl/url?sa=t&rct=j&q=&esrc=s&source=web&cd=&cad=rja&uact=8&ved=2ahUKEwi5htyg5_buAhXeQxUIHaZHB5QQFjAAegQIBBAD&url=https%3A%2F%2Fwww.mdpi.com%2F1996-1073%2F13%2F8%2F2068%2Fhtml&usg=AOvVaw3CukGrgPjpIO2eKM619BIn + # Operation modes The multizone thermostat can operate in two modes: - thermostats can operate stand-alone, thus without interaction with others @@ -27,7 +64,7 @@ The multizone thermostat can operate in two modes: Per room a thermostat needs to be configured. A thermostat can operate by either hyesteris (on-off mode) or proportional mode (weather compensation and PID mode). The PID and weather compensation can be combined or one of both can be used. Only a satellite operating in proportional mode can be used as satellite as hysteris operation (on-off by a dT) cannot run in synchronised mode with other satellites and the master. -When a master controller is included it will coordinate for all enlisted satellites the valve opening and closures. When the master hvac mode is heat or cool it will trigger the satellites to update their controller and from that moment it interacts with the master. A satellite interaction with the master will be updated when the master is activated or switched off. When the master is activated to heat or cool, the controller routines of all satellites are synced to the master controller. When the master is switched off the satellite will return to their stand-alone mode with individual settings. The master itself receives the satellite state (pwm signal) and return the moment the satellite has to open or close valves. The master determines the moment when the satellite valves is opened, the satellite itself still determines the valve opening time. +When a master controller is included it will coordinate for all enlisted satellites the valve opening and closures. When the master hvac mode is heat or cool it will trigger the satellites to update their controller and from that moment it interacts with the master. A satellite interaction with the master will be updated when the master is activated or switched off. When the master is activated to heat or cool, the controller routines of all satellites are synced to the master controller. When the master is switched off the satellite will return to their stand-alone mode with individual settings. The master itself receives the satellite state (PWM signal) and return the moment the satellite has to open or close valves. The master determines the moment when the satellite valves is opened, the satellite itself still determines the valve opening time. # Examples See the examples folder for examples. @@ -60,7 +97,7 @@ sensors (at least one sensor needs to be specified): * initial_preset_mode (Optional): Set the default mode. Default is normal operational mode. Allowed alternative is any in 'extra_presets'. The 'inital_preset_mode' needs to be present in the 'extra_presets' of the 'initial_hvac_mode' * precision (Optional): specifiy setpoint precision: 0.1, 0.5 or 1 -* detailed_output (Optional): include detailed control output including PID contributions and sub-control (pwm) output. To include detailed output use 'True'. Use this option limited for debugging and tuning only as it increases the database size. Default = False +* detailed_output (Optional): include detailed control output including PID contributions and sub-control (PWM) output. To include detailed output use 'True'. Use this option limited for debugging and tuning only as it increases the database size. Default = False checks for sensor and switch: * sensor_stale_duration (Optional): safety routine "emergency mode" to turn switches off when sensor has not updated for a specified time period. Specify time period. Activation of emergency mode is visible via a forced climate preset state. Default is not activated. @@ -104,19 +141,19 @@ Two control modes are included to control the proportional thermostat. A single - Weather compensating: control by room- and outdoor temperature The proportional controller is called periodically and specified by control_interval. -If no pwm interval is defined, it will set the state of "heater" from 0 to "pwm_scale" value as for a proportional valve. Else, when "pwm_duration" is specified it will operate in on-off mode and will switch proportionally with the pwm signal. +If no PWM interval is defined, it will set the state of "heater" from 0 to "PWM_scale" value as for a proportional valve. Else, when "PWM_duration" is specified it will operate in on-off mode and will switch proportionally with the PWM signal. * control_interval (Required): interval that controller is updated. The satellites should have a control_interval equal to the master or the master control_interval should be dividable by the satellite control_interval. Specify a time period. -* pwm_duration (Optional): Set period time for pwm signal. If it's not set, pwm is sending proportional value to switch. Specify a time period. For a on-off valve the control_interval should be equal or multiplication of the "control_interval". Default = 0 (proportional valve) -* pwm_scale (Optional): Set analog output offset to 0. Example: If it's 500 the output value can be between 0 and 500. Proportional valve might have 99 as upper max, use 99 in such case. Default = 100 -* pwm_resolution (optional): Set the resolution of the pwm_scale between min and max difference. Default = 50 (50 steps between 0 and pwm_scale) -* pwm_threshold (Optional): Set the minimal difference before activating switch. To avoid very short off-on-off or on-off-on changes. Default is not acitvated -* bounded_scale_to_master(Optional): scale proporitional valves with the master's pwm. 'bounded_scale_to_master' defines the scale limit. For example: +* PWM_duration (Optional): Set period time for PWM signal. If it's not set, PWM is sending proportional value to switch. Specify a time period. For a on-off valve the control_interval should be equal or multiplication of the "control_interval". Default = 0 (proportional valve) +* PWM_scale (Optional): Set analog output offset to 0. Example: If it's 500 the output value can be between 0 and 500. Proportional valve might have 99 as upper max, use 99 in such case. Default = 100 +* PWM_resolution (optional): Set the resolution of the PWM_scale between min and max difference. Default = 50 (50 steps between 0 and PWM_scale) +* PWM_threshold (Optional): Set the minimal difference before activating switch. To avoid very short off-on-off or on-off-on changes. Default is not acitvated +* bounded_scale_to_master(Optional): scale proporitional valves with the master's PWM. 'bounded_scale_to_master' defines the scale limit. For example: - bounded scale = 3 - - prop valve pwm = 15 - - master pwm = 25 - - master pwm scale = 100 - - valve pwm output = 15 / min( 25/100, 3) + - prop valve PWM = 15 + - master PWM = 25 + - master PWM scale = 100 + - valve PWM output = 15 / min( 25/100, 3) Default = 1 (no scaling) @@ -132,8 +169,8 @@ with the data (as sub): * kp (Required): Set PID parameter, p control value. * ki (Required): Set PID parameter, i control value. * kd (Required): Set PID parameter, d control value. -* pwm_scale_low (Optional): Overide lower bound pwm scale for this mode. Default = 0 -* pwm_scale_high (Optional): Overide upper bound pwm scale for this mode. Default = 'pwm_scale' +* PWM_scale_low (Optional): Overide lower bound PWM scale for this mode. Default = 0 +* PWM_scale_high (Optional): Overide upper bound PWM scale for this mode. Default = 'PWM_scale' * window_open_tempdrop (Optional): notice temporarily opened window. Define minimum temperature drop speed below which PID is frozen to avoid integral and derative build-up. drop in Celcius per hour. Should be negative value. Default = off. ##### Weather compensating controller (Optional) (sub of proportional mode) @@ -147,8 +184,8 @@ cool mode: ka negitive, kb positive with the data (as sub): * ka (Required): Set PID parameter, ka control value. * kb (Required): Set PID parameter, kb control value. -* pwm_scale_low (Optional): Overide lower bound pwm scale for this mode. Default = pwm_scale * -1 -* pwm_scale_high (Optional): Overide upper bound pwm scale for this mode. Default = 'pwm_scale' +* PWM_scale_low (Optional): Overide lower bound PWM scale for this mode. Default = PWM_scale * -1 +* PWM_scale_high (Optional): Overide upper bound PWM scale for this mode. Default = 'PWM_scale' # Master configuration The configuration scheme is similar as for a satellite only with the following differences. @@ -190,18 +227,18 @@ The preset mode changes on the master will be synced to the satellites. The master can operate in 'minimal_on', 'balanced' or 'continuous' mode. This will determine the satellite timing scheduling. For the minimal_on mode the master valve is opened as short as possible, for balanced mode the opening time is balanced between heating power and duration and for continuous mode the valve opening time is extended as long as possible. All satellite valves operating as on-off switch are used for the nesting are scheduled in time to get a balanced heat requirement. In 'continuous' mode the satellite timing is scheduled aimed such that a continuous heat requirement is created. The master valve will be opened continuous when sufficient heat is needed. In low demand conditions an on-off mode is maintained. The controller is called periodically and specified by control_interval. -If no pwm interval is defined, it will set the state of "heater" from 0 to "pwm_scale" value as for a proportional valve. Else, when pwm is specified it will operate in on-off mode and will switch proportionally with the pwm signal. +If no PWM interval is defined, it will set the state of "heater" from 0 to "PWM_scale" value as for a proportional valve. Else, when PWM is specified it will operate in on-off mode and will switch proportionally with the PWM signal. with the data (as sub): * satelites (Required): between square brackets defined list of thermostats by their name * operation_mode (Optional): satellite nesting method: "minimal_on", "balanced" or "continuous". Default = "balanced" * lower_load_scale (Optional): For nesting assumed minimum required load heater. Default = 0.15. (a minimum heating capacity of 15% assumed based on 100% when all rooms required heat) * control_interval (Required): interval that controller is updated. The satellites should have a control_interval equal to the master or the master control_interval should be dividable by the satellite control_interval. Specify a time period. -* pwm_duration (Optional): Set period time for pwm signal. If it's not set, pwm is sending proportional value to switch. Specify a time period. Default = 0 -* pwm_scale (Optional): Set analog output offset to 0. Example: If it's 500 the output value can be between 0 and 500. Default = 100 -* pwm_resolution (optional): Set the resolution of the pwm_scale between min and max difference. Default = 50 (50 steps between 0 and 100) -* pwm_threshold (Optional): Set the minimal difference before activating switch. To avoid very short off-on-off or on-off-on changes. Default is not acitvated -* min_opening_for_propvalve (optional): Set the minimal percentage (between 0 and 1) active pwm when a proportional valve requires heat. Default 0 (* pwm_scale) +* PWM_duration (Optional): Set period time for PWM signal. If it's not set, PWM is sending proportional value to switch. Specify a time period. Default = 0 +* PWM_scale (Optional): Set analog output offset to 0. Example: If it's 500 the output value can be between 0 and 500. Default = 100 +* PWM_resolution (optional): Set the resolution of the PWM_scale between min and max difference. Default = 50 (50 steps between 0 and 100) +* PWM_threshold (Optional): Set the minimal difference before activating switch. To avoid very short off-on-off or on-off-on changes. Default is not acitvated +* min_opening_for_propvalve (optional): Set the minimal percentage (between 0 and 1) active PWM when a proportional valve requires heat. Default 0 (* PWM_scale) * compensate_valve_lag (optional): Delay the opening of the master valve to assure that flow is guaranteed. Specify a time period. Default no delay. @@ -211,28 +248,6 @@ The filter intesity is defined by a factor between 0 to 5 (integer). 0 = no filter 5 = max smoothing -# PID controller: -https://en.wikipedia.org/wiki/PID_controller - -examples: -slow low temperature underfloor heating: - PID_mode: - kp: 30 - ki: 0.005 - kd: -24000 - -high temperature radiator: - PID_mode: - kp: 80 - ki: 0.09 - kd: -5000 - -* underfloor heating parameter optimisation: https://www.google.nl/url?sa=t&rct=j&q=&esrc=s&source=web&cd=&cad=rja&uact=8&ved=2ahUKEwi5htyg5_buAhXeQxUIHaZHB5QQFjAAegQIBBAD&url=https%3A%2F%2Fwww.mdpi.com%2F1996-1073%2F13%2F8%2F2068%2Fhtml&usg=AOvVaw3CukGrgPjpIO2eKM619BIn - -PID controller explained. Would recommoned to read some of it: -[https://controlguru.com/table-of-contents/](https://controlguru.com/table-of-contents/) - - # DEBUGGING: debugging is possible by enabling logger in configuration with following configuration ``` diff --git a/custom_components/multizone_thermostat/manifest.json b/custom_components/multizone_thermostat/manifest.json index b25943e..6fa7293 100644 --- a/custom_components/multizone_thermostat/manifest.json +++ b/custom_components/multizone_thermostat/manifest.json @@ -7,5 +7,5 @@ "iot_class": "local_polling", "issue_tracker": "https://github.com/vindaalex/multizone-thermostat/issues", "requirements": ["numpy"], - "version": "0.7" + "version": "0.7.1" }