Giter Club home page Giter Club logo

hasmartthermostat's Introduction

hacs_badge

Buy Me A Coffee

HASmartThermostat

Smart Thermostat with PID controller for Home Assistant

Create a virtual thermostat with accurate and reactive temperature control through PID controller. Principle of the PID controller. Any heater or air conditioner unit with ON/OFF switch or pilot wire can be controlled using a pulse width modulation that depends on the temperature error and its variation over time.

Installation:

I recommend using HACS for easier installation.

Install using HACS:

Go to HACS, select Integrations, click the three dots menu and select "Custom repositories". Add the path to the Github repository in the first field, select Integration as category and click Add. Once back in integrations panel, click the Install button on the Smart Thermostat PID card to install.
Set up the smart thermostat and have fun.

Manual 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
  3. Copy the smart_thermostat folder into /custom_components/
  4. Set up the smart_thermostat and have fun

Configuration:

The smart thermostat can be added to Home Assistant after installation by adding a climate section to your configuration.yaml file.

Configuration example:

configuration.yaml

climate:
  - platform: smart_thermostat
    name: Smart Thermostat Example
    unique_id: smart_thermostat_example
    heater: switch.on_off_heater
    target_sensor: sensor.ambient_temperature
    min_temp: 7
    max_temp: 28
    ac_mode: False
    target_temp: 19
    keep_alive:
      seconds: 60
    away_temp: 14
    kp: 5
    ki: 0.01
    kd: 500
    pwm: 00:15:00

Usage:

The target sensor measures the ambient temperature while the heater switch controls an ON/OFF heating system.
The PID controller computes the amount of time the heater should remain ON over the PWM period to reach the temperature set point, in example with PWM set to 15 minutes, if output is 100% the heater will be kept on for the next 15 minutes PWM period. If PID output is 33%, the heater will be switched ON for 5 minutes only.

By default, the PID controller will be called each time the target sensor is updated. When using main powered sensor with high sampling rate, the sampling_period parameter should be used to slow down the PID controller refresh rate.

By adjusting the Kp, Ki and Kd gains, you can tune the system response to your liking. You can find many tutorials for guidance on the web. Here are a few useful links:

To make it quick and simple:

  • Kp gain adjusts the proportional part of the error compensation. Higher values means stronger reaction to error. Increase the value for faster rise time.
  • Ki gain adjusts the integral part. Integral compensates the residual error when temperature settles in a cumulative way. The longer the temperature remains below the set point, the higher the integral compensation will be. If your system settles below the set point, increase the Ki value. If it settles over the set point, decrease the Ki value.
  • Kd gain adjusts the derivative part of the compensation. Derivative compensates the inertia of the system. If the sensor temperature increases quickly between two samples, the PID will decrease the PWM level accordingly to limit the overshoot.

PID output value is the weighted sum of the control terms:
error = target_temp - current_temperature
di = temperature change between last two samples
dt = time elapsed between last two samples
P = Kp * error
I = last_I + (Ki * error * dt)
D = -(Kd * di) / dt
output = P + I + D
Output is then limited to 0% to 100% range to control the PWM.

Outdoor temperature compensation

Optionally, when an outdoor temperature sensor entity is provided and ke is set, the thermostat can automatically compensate building losses based on the difference between target temperature and outdoor temperature. An external component E is added to the PID output: E = Ke * (target_temp - outdoor_temp)
output = P + I + D + E
Output is then limited to 0% to 100% range to control the PWM. The Ke gain depends on the insulation of the building, on recent buildings with good insulation, a gain of 0.6 is recommended. This compensation will act like the integral of the PID, but with faster response time, so the integral will be more stable.

Autotune (not always working, not recommended to use):

You can use the autotune feature to find some working PID parameters.
Add the autotune: parameter with the desired tuning rule, and optionally set the noiseband and lookback duration if the default 2 hours doesn't match your HVAC system bandwidth.
Restart Home Assistant to start the thermostat in autotune mode and set the desired temperature on the thermostat. The autotuner will then start analyzing your heating system, measure the sampling rate of the sensor, control the heater switch and monitor the temperature changes.

Wait for the autotune to finish by checking the autotune_status attribute for success. The Kp, Ki and Kd gains will then be computed and set according to the selected rule and the thermostat switches to PID.
The Kp, Ki and Kd gains are also computed using the other rules, and all values are shown in the Home Assistant log like this: "Smart thermostat PID Autotuner output with ziegler-nichols rule: Kp=######, Ki=######, Kd=######".
You should then save for reference the gains computed by the autotuner for future testing.

Warning: The thermostat set point can't be changed once the autotuner has started monitoring the temperature. The temperature regulation will work as a basic hysteresis thermostat based on set point and noise band. If your heating system and temperature monitoring is slow, reducing the noise band will reduce the temperature oscillations around the set point. If the sampling rate of your temperature sensor is too fast (few seconds) or noisy (frequent temperature changes) increase the noise band for system stability.

Warning: The autotuner result is saved in the entity attributes and restored after Home Assistant is restarted.
However, it is recommended to save the new gains in the YAML configuration file to keep it in case of Home Assistant database's is corrupted.

Services

Services can be used in Home Assistant to configure the thermostat.
The following services are available:

Set PID gains: smart_thermostat.set_pid_gain
Use this service to adjust the PID gains without requiring a restart of Home Assistant. Values are saved to Home Assistant database and restored after a restart.
Please consider saving the final gain parameters in YAML configuration file when satisfied to keep it safe in case of database corruption.
Optional parameters : kp, ki and kd, as float.
Example:

service: smart_thermostat.set_pid_gain
data:
  kp: 11.8
  ki: 0.00878
target:
  entity_id: climate.smart_thermostat_example

Set PID mode: smart_thermostat.set_pid_mode
Use this service to set the PID mode to either 'auto' or 'off'.
When in auto, the PID will modulate the heating based on temperature value and variation. When in off, the PID output will be 0% if temperature is above the set point, and 100% if temperature is below the set point.
Mode is saved to Home Assistant database and restored after a restart.
Required parameter : mode as a string in ['auto', 'off'].
Example:

service: smart_thermostat.set_pid_mode
data:
  mode: 'off'
target:
  entity_id: climate.smart_thermostat_example

Set preset modes temperatures: smart_thermostat.set_preset_temp
Use this service to set the temperatures for the preset modes. It can be adjusted for all preset modes, if a preset mode is not enabled through YAML, it will be enabled. You can use any preset temp parameter available in smart thermostat settings.
Please note the value will then be saved in the entity's state in database and restored after restarting Home Assistant, ignoring values in YAML. Use the disable options to remove active presets. Example:

service: smart_thermostat.set_preset_temp
data:
  away_temp: 14.6
  boost_temp: 22.5
  home_temp_disable: true
target:
  entity_id: climate.smart_thermostat_example

Clear the integral part: smart_thermostat.clear_integral
Use this service to reset the integral part of the PID controller to 0. Useful when tuning the PID gains to quickly test the behavior without waiting the integral to stabilize by itself.

Parameters:

  • name (Optional): Name of the thermostat.
  • unique_id (Optional): unique entity_id for the smart thermostat.
  • heater (Required): entity_id for heater control, should be a toggle device or a valve accepting direct input between 0% and 100%. If a valve is used, pwm parameter should be set to 0. Becomes air conditioning switch when ac_mode is set to true.
  • cooler (Optional): entity_id for cooling control, should be a toggle device or a valve accepting direct input between 0% and 100%. If a valve is used, pwm parameter should be set to 0. Becomes air conditioning switch when ac_mode is set to true.
  • invert_heater (Optional): if set to true, inverts the polarity of heater switch (switch is on while idle and off while active). Must be a boolean (defaults to false).
  • target_sensor (Required): entity_id for a temperature sensor, target_sensor.state must be temperature.
  • outdoor_sensor (Optional): entity_id for an outdoor temperature sensor, outdoor_sensor.state must be temperature.
  • keep_alive (Required): sets update interval for the PWM pulse width. If interval is too big, the PWM granularity will be reduced, leading to lower accuracy of temperature control, can be float in seconds, or time hh:mm:ss.
  • kp (Recommended): Set PID parameter, proportional (p) control value (float, default 100).
  • ki (Recommended): Set PID parameter, integral (i) control value (float, default 0).
  • kd (Recommended): Set PID parameter, derivative (d) control value (float, default 0).
  • ke (Optional): Set outdoor temperature compensation gain (e) control value (float, default 0).
  • pwm (Optional): Set period of the pulse width modulation. If too long, the response time of the thermostat will be too slow, leading to lower accuracy of temperature control. Can be float in seconds or time hh:mm:ss (default 15mn). Set to 0 when using heater entity with direct input of 0/100% values like valves.
  • min_cycle_duration (Optional): Set a minimum amount of time that the switch specified in the heater option must be in its current state prior to being switched either off or on (useful to protect boilers). Can be float in seconds or time hh:mm:ss (default 0s).
  • min_off_cycle_duration (Optional): When min_cycle_duration is specified, Set a minimum amount of time that the switch specified in the heater option must remain in OFF state prior to being switched ON. The min_cycle_duration setting is then used for ON cycle only, allowing different minimum cycle time for ON and OFF. Can be float in seconds or time hh:mm:ss (defaults to min_cycle_duration value).
  • min_cycle_duration_pid_off (Optional): This parameter is the same as min_cycle_duration but is used specifically when PID is set to OFF. Defaults to min_cycle_duration value.
  • min_off_cycle_duration_pid_off (Optional): This parameter is the same as min_off_cycle_duration but is used specifically when PID is set to OFF. Defaults to min_cycle_duration_pid_off value.
  • sampling_period (Optional): interval between two computation of the PID. If set to 0, PID computation is called each time the temperature sensor sends an update. Can be float in seconds or time hh:mm:ss (default 0).
  • target_temp_step (Optional): the adjustment step of target temperature (valid are 0.1, 0.5 and 1.0, default 0.5 for Celsius and 1.0 for Fahrenheit).
  • precision (Optional): the displayed temperature precision (valid are 0.1, 0.5 and 1.0, default 0.1 for Celsius and 1.0 for Fahrenheit).
  • min_temp (Optional): Set minimum set point available (default: 7).
  • max_temp (Optional): Set maximum set point available (default: 35).
  • target_temp (Optional): Set initial target temperature. If not set target temperature will be set to null on startup.
  • cold_tolerance (Optional): When PID is off, set a minimum amount of difference between the temperature read by the sensor specified in the target_sensor option and the target temperature that must change prior to being switched on. For example, if the target temperature is 25 and the tolerance is 0.5 the heater will start when the sensor equals or goes below 24.5 (float, default 0.3).
  • hot_tolerance (Optional): When PID is off, set a minimum amount of difference between the temperature read by the sensor specified in the target_sensor option and the target temperature that must change prior to being switched off. For example, if the target temperature is 25 and the tolerance is 0.5 the heater will stop when the sensor equals or goes above 25.5 (float, default 0.3).
  • ac_mode (Optional): Set the switch specified in the heater option to be treated as a heating/cooling device instead of a pure heating device. Should be a boolean (default: false).
  • force_off_state (Optional): If set to true (default value), Home Assistant will force the heater entity to OFF state when the thermostat is in OFF. Set parameter to false to control the heater entity externally while the thermostat is OFF.
  • preset_sync_mode (Optional): If set to sync mode, manually setting a temperature will enable the corresponding preset. In example, if away temperature is set to 14°C, manually setting the temperature to 14°C on the thermostat will automatically enable the away preset mode. Should be a string, either 'sync' or 'none' (default: 'none').
  • boost_pid_off (Optional): When set to true, the PID will be set to OFF state while boost preset is selected, and the thermostat will operate in hysteresis mode. This helps to quickly raise the temperature in a room for a short period of time. Should be a boolean (default: false).
  • away_temp (Optional): Set the default temperature used by the "Away" preset. If this is not specified, away_mode feature will not be available. The temperature can then be adjusted using the set_preset_temp service, new value being restored after restarting HA.
  • eco_temp (Optional): Set the default temperature used by the "Eco" preset. If this is not specified, eco feature will not be available. The temperature can then be adjusted using the set_preset_temp service, new value being restored after restarting HA.
  • boost_temp (Optional): Set the default temperature used by the "Boost" preset. If this is not specified, boost feature will not be available. The temperature can then be adjusted using the set_preset_temp service, new value being restored after restarting HA.
  • comfort_temp (Optional): Set the default temperature used by the "Comfort" preset. If this is not specified, comfort feature will not be available.
  • home_temp (Optional): Set the default temperature used by the "Home" preset. If this is not specified, home feature will not be available. The temperature can then be adjusted using the set_preset_temp service, new value being restored after restarting HA.
  • sleep_temp (Optional): Set the default temperature used by the "Sleep" preset. If this is not specified, sleep feature will not be available. The temperature can then be adjusted using the set_preset_temp service, new value being restored after restarting HA.
  • activity_temp (Optional): Set the default temperature used by the "Activity" preset. If this is not specified, activity feature will not be available. The temperature can then be adjusted using the set_preset_temp service, new value being restored after restarting HA.
  • sensor_stall (Optional): Sets the maximum time period between two sensor updates. If no update received from sensor after this time period, the system considers the sensor as stall and switch to safety mode, the output being forced to output_safety. If set to 0, the feature is disabled. Can be float in seconds or time hh:mm:ss (default 6 hours).
  • output_safety (Optional): Sets the output level of the PID once the thermostat enters safety mode due to unresponsive temperature sensor. This can help to keep a minimum temperature in the room in case of sensor failure. The value should be a float between 0.0 and 100.0 (default 5.0).
  • initial_hvac_mode (Optional): Forces the operation mode after Home Assistant is restarted. If not specified, the thermostat will restore the previous operation mode.
  • debug (Optional): Make the climate entity expose the following internal values as extra states attributes, so they can be accessed in HA with sensor templates for debugging purposes ( helpful to adjust the PID gains), example configuration.yaml:
    sensor:
    - platform: template
      sensors:
        smart_thermostat_output:
          friendly_name: PID Output
          unit_of_measurement: "%"
          value_template: "{{ state_attr('climate.smart_thermostat_example', 'control_output') | float(0) }}"
          smart_thermostat_p:
          friendly_name: PID P
          unit_of_measurement: "%"
          value_template: "{{ state_attr('climate.smart_thermostat_example', 'pid_p') | float(0) }}"
        smart_thermostat_i:
          friendly_name: PID I
          unit_of_measurement: "%"
          value_template: "{{ state_attr('climate.smart_thermostat_example', 'pid_i') | float(0) }}"
        smart_thermostat_d:
          friendly_name: PID D
          unit_of_measurement: "%"
          value_template: "{{ state_attr('climate.smart_thermostat_example', 'pid_d') | float(0) }}"
        smart_thermostat_e:
          friendly_name: PID E
          unit_of_measurement: "%"
          value_template: "{{ state_attr('climate.smart_thermostat_example', 'pid_e') | float(0) }}"
    
    It is strongly recommended to disable the debug mode once the PID Thermostat is working fine, as the added extra states attributes will fill the Home Assistant database quickly.
    Available debug attributes are:
    • pid_p
    • pid_i
    • pid_d
    • pid_e
    • pid_dt
  • noiseband (Optional): set noiseband for autotune (float): Determines by how much the input value must overshoot/undershoot the set point before the state changes (default : 0.5).
  • lookback (Optional): length of the autotune buffer for the signal analysis to detect peaks, can be float in seconds, or time hh:mm:ss (default 2 hours).
  • autotune (Optional): Set the name of the selected rule for autotune settings (ie "ziegler-nichols"). If it's not set, autotune is disabled. The following tuning_rules are available:
rule Kp_divisor Ki_divisor Kd_divisor
"ziegler-nichols" 34 40 160
"tyreus-luyben" 44 9 126
"ciancone-marlin" 66 88 162
"pessen-integral" 28 50 133
"some-overshoot" 60 40 60
"no-overshoot" 100 40 60
"brewing" 2.5 6 380

Credits

This code is a fork from Smart Thermostat PID project: https://github.com/aendle/custom_components
The python PID module with Autotune is based on pid-autotune: https://github.com/hirschmann/pid-autotune

hasmartthermostat's People

Contributors

aendle avatar anhardt avatar bemobolo avatar chupaka avatar davesdevfails avatar flopon avatar gallynero avatar georgedewar avatar mymakibox avatar scratman avatar tdobrovolny avatar vertexodessa avatar ybizeul avatar yury-sannikov avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

hasmartthermostat's Issues

precision not working

Hi, great app, needed the PID
All works great, but the "precision" is not.
Cant operate in 0.1 steps.
Only in 0.5 steps

- platform: smart_thermostat name: Woonkamer heater: switch.virtual_switch_virtual_vv target_sensor: sensor.average_woonkamer_temperatuur min_temp: 19 max_temp: 24 ac_mode: False target_temp: 20.4 keep_alive: seconds: 60 kp : 30 ki : 0.005 kd : -24000 pwm: seconds: 300 precision: 0.1 away_temp: 19.3 sleep_temp: 19.8 comfort_temp: 21

Please advice

When autotune is set and HA is restarting - >error 'SmartThermostat' object has no attribute 'pidController'

When restarting HA and autotune is set, we got an error, cause in that case, pidController did not exists.

Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 382, in async_add_entities
    await asyncio.gather(*tasks)
  File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 607, in _async_add_entity
    await entity.add_to_platform_finish()
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 714, in add_to_platform_finish
    await self.async_added_to_hass()
  File "/config/custom_components/smart_thermostat/climate.py", line 287, in async_added_to_hass
    self.pidController.integral = self.i
AttributeError: 'SmartThermostat' object has no attribute 'pidController'
2021-11-08 13:15:12 ERROR (MainThread) [homeassistant.components.climate] Error while setting up smart_thermostat platform for climate
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 257, in _async_setup_platform
    await asyncio.gather(*pending)
  File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 382, in async_add_entities
    await asyncio.gather(*tasks)
  File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 607, in _async_add_entity
    await entity.add_to_platform_finish()
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 714, in add_to_platform_finish
    await self.async_added_to_hass()
  File "/config/custom_components/smart_thermostat/climate.py", line 287, in async_added_to_hass
    self.pidController.integral = self.i
AttributeError: 'SmartThermostat' object has no attribute 'pidController'

Option for setting an aditional min_cycle_duration for PID off

Is your feature request related to a problem? Please describe.
In regards to smart_thermostat.set_pid_mode service and generic usage of HASmartThermostat
Before HASmartThermostat I've used generic thermostat with min_cycle_duration of 10 seconds and hot/cold tolerance of 0.1 °C so I would get fast response when changing target_temperature. However, seting a cycle duration of 10 seconds in HASmartThermostat is not a viable option (at least for systems with big inertia like gas boilers + radiators; mine for example takes 7-8 seconds to light the flame on) because it would cause short, unnecessary cycles when the error is small. I have found that a min_cycle_duration of 10 to 15 minutes is ideeal for PID auto mode but when PID is off, with a min_cycle_duration of 15 minutes, I get big temperature fluctuations around the target temperature due to the big inertia of the system (the water in the radiators heats up to 60 °C).

Describe the solution you'd like
Adding a pid_off_min_cycle_duration parameter in the config would solve this problem.

Thanks for this awesome component!

Thermostat is constantly switching to Off - Comfort

Whatever mode I set every 30s or so, the thermostat is set to Off - Comfort and then back to "Idle - Home" (for instance) for some seconds.
Somehow it is actually working fine, it turns on and off the switch as expected and it works like a charm (kudos for this great thermostat!!) but in the UI the behaviour is quite strange.
In this screenshot you can see how the target temperature (in purple) is constantly changing from the current preset (sleep 16, home 19, etc.) to the Comfort setting (19.5).
image

This is my config, what am I doing wrong?

  - platform: smart_thermostat
    name: Heating
    heater: switch.heating
    target_sensor: sensor.living_room_temperature
    min_temp: 15
    max_temp: 22
    ac_mode: false
    target_temp: 18
    eco_temp: 18
    home_temp: 19
    comfort_temp: 19.5
    boost_temp: 21
    away_temp: 17
    sleep_temp: 16
    cold_tolerance: 0.2
    hot_tolerance: 0
    min_cycle_duration:
      minutes: 1
    keep_alive:
      seconds: 30
    initial_hvac_mode: "off"
    precision: 0.1

Thanks in advance!

Preset temperatures have a hardcoded maximum value of 30°

When calling the service smart_thermostat.set_preset_temp, the new preset temperatures are not validated against the min_temp and max_temp parameters of the configuration. Instead, they appear to be validated against some fixed values. This effectively prevents the user from setting preset temperatures above 30°.

Steps to reproduce the behavior:
Sample configuration (here, the controller is used to control humidity by switching a dehumidifier, hence the high values)

climate:
  - platform: smart_thermostat
    name: Smart Thermostat Example
    unique_id: smart_thermostat_example
    heater: switch.dehumidifier
    target_sensor: sensor.humidity
    min_temp: 45
    max_temp: 80
    ac_mode: True
    target_temp: 65

Create an automation with a service call as action:

service: smart_thermostat.set_preset_temp
data:
  home_temp: 65
target:
  entity_id: climate.smart_thermostat

The following error is found when debugging the automation:

Stopped because an error was encountered at [DATE] (runtime: 0.04 seconds)

value must be at most 30 for dictionary value @ data['home_temp']

The preset temperature is not updated.

Expected behavior
The preset temperature should be updated to the indicated value (65).

Additional context
Manually changing the set point of the controller to the desired value works as expected. Specifying a preset temperature in the configuration file works as well. Only the change through the service appears to have the faulty validation.

Thank you for the excellent work on this integration!

Attributes are not updated after a calculation

Hi,

Describe the bug
Attributes (control_output, pid_p, pid_i, pid_d) are not updated after a calculation.
Wait for a temperature update, attributes are updated.

Expected behavior
After each PID and output calculation, update attributes.

Additional context
Maybe, add at the end of "calc_output", line #804 :
await self.async_update_ha_state()

Configure Guidelines for a Zigbee Thermostat

Currently Running v2021.11.9-beta2

Looking to configure a existing Zigbee Thermostat for use with the HASmartThermostat.

Looks like its having some issues handling how to gets the current temp.

I have attached a screenshot of how the Thermostat is currently listed in devtools
image

The logs show the following

2021-11-29 13:50:42 DEBUG (MainThread) [custom_components.smart_thermostat.climate] PID Gains: kp = 75.0, ki = 0.001, kd = 70000.0
2021-11-29 13:50:44 DEBUG (MainThread) [custom_components.smart_thermostat.climate] Unable to update from sensor: could not convert string to float: 'heat'
2021-11-29 13:50:44 DEBUG (MainThread) [custom_components.smart_thermostat.climate] Received new temperature sensor input at timestamp 1638211844.2949722 (before None): None (before None)
2021-11-29 13:50:44 DEBUG (MainThread) [custom_components.smart_thermostat.climate] Unable to update from sensor: could not convert string to float: 'heat'
2021-11-29 13:53:15 DEBUG (MainThread) [custom_components.smart_thermostat.climate] Unable to update from sensor: could not convert string to float: 'heat'
2021-11-29 13:53:15 DEBUG (MainThread) [custom_components.smart_thermostat.climate] Received new temperature sensor input at timestamp 1638211995.5093408 (before 1638211844.2949722): None (before None)

and here is the config I'm using:

climate:
  - platform: smart_thermostat
    name: Smart Thermostat
    heater: climate.homehvac_1d6a2c0b_fan_thermostat
    target_sensor: climate.homehvac_1d6a2c0b_fan_thermostat
    min_temp: 44.6
    max_temp: 89.6
    ac_mode: False
    target_temp: 69
    unique_id: homesmartthermostat
    keep_alive:
      seconds: 60
    away_temp: 65
    kp: 75
    ki: 0.001
    kd: 70000
    pwm: 00:15:00

(Update: Looks like complicated templates are going to be required for this)

Error on calling climate.set_preset_mode from an automation

Hello

I just replaced one of my generic_thermostat(s) with this smart_thermostat to experiment with and see if it could be a long term replacement for all my other thermostats, and I'm having an error fitting it with my existing automations (with node red)

I have this error when I call climate.set_preset_mode (inherited from the old generic_thermostat), any help would be much appreciated.

Testing from HA Developer Tools gives the same result

service: climate.set_preset_mode
data:
  preset_mode: none
target:
  entity_id:
    - climate.bathroom

2021-11-29 08:57:04 ERROR (SyncWorker_17) [homeassistant] Error doing job: Task exception was never retrieved
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 863, in async_request_call
    await coro
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 704, in _handle_entity_call
    await result
  File "/config/custom_components/smart_thermostat/climate.py", line 649, in async_set_preset_mode
    self._target_temp = self.presets[preset_mode]
KeyError: 'none'

Preset remains unchanged after changing target temperature

If a preset is activated, when manually changing the target temperature the preset should be automatically changed to "none" but actually it remains unchanged.

To Reproduce
Steps to reproduce the behavior:

  1. Activate a preset
  2. Change target temperature
  3. The preset remains the same instead of switching to "none"

This behaviour creates confusion among users and problems for schedules and automations. Would be useful if it would change to "none". Or even better, keep in sync with target temperature.

Question: do nothing after start

Describe the bug
IMHO something not right, pls check.

Configured entity, restarted HA Core.
After HA started thermostat stay in Idle(Heat).
Actual temp. is 17.5, target 20, but thermostat not switching heater.

Change target to 19.5 - Idle(Heat). Set to 20 - goes to Heating(Heat).
Change back to 19.5 - again Idle(Heat).

Actual temp. all the time 17.5

  climate:
    - platform: smart_thermostat
      name: EntryR Floor ST
      unique_id: tms_entryr_floor_st
      heater: switch.rly_entryr_floor
      target_sensor: sensor.sth_entryr_floor_temperature
      min_temp: 7
      max_temp: 28
      ac_mode: False
      target_temp: 20
      keep_alive:
        seconds: 60
      away_temp: 14
      kp : 5
      ki : 0.01
      kd : 500
      pwm : 00:15:00

If thermostat waiting for new data from temperature sensor - why starts to heat if set back to 20 or more.
And not starting on target 20, if not touching it.

Expected behavior
When target/actual temp. difference is 2 degrees - heater to be switched on as soon as HA started.

Screenshots
image

Desktop (please complete the following information):

  • OS: [Windows 10]
  • Browser [Chrome]
  • Version [95.0.4638.69]

Additional context
HA Core 2021.11.5

PID is refreshed on every temperature change with sampling_period defines

Describe the bug
PID calculation is performed based on sampling_period, but also on keep_alive period.
Maybe it's the normal behavior, but, from my point of view, not.

Parameters
sampling_period: 300
keep_alice: 60

LOG

2021-12-06 21:24:50 DEBUG (MainThread) [custom_components.smart_thermostat.climate] Obtained current control output. 0.00 (error = -0.10, dt = 240.00, p=-25.00, i=17.04, d=-0.00)
... ... ...
2021-12-06 21:28:50 DEBUG (MainThread) [custom_components.smart_thermostat.climate] Received new temperature sensor input at timestamp 1638822530.9548683 (before 1638820465.9386318): 21.0 (before 21.1)
2021-12-06 21:28:50 DEBUG (MainThread) [custom_components.smart_thermostat.climate] Obtained current control output. 0.00 (error = -0.10, dt = 60.00, p=-25.00, i=17.04, d=-0.00)
2021-12-06 21:28:50 INFO (MainThread) [custom_components.smart_thermostat.climate] Request turning off input_boolean.chauffage_sol
2021-12-06 21:28:50 INFO (MainThread) [custom_components.smart_thermostat.climate] Turning off input_boolean.chauffage_sol
2021-12-06 21:29:50 DEBUG (MainThread) [custom_components.smart_thermostat.climate] Obtained current control output. 33.70 (error = 0.00, dt = 240.01, p=0.00, i=17.04, d=16.67)

PID calculation base on sampling period (strange, dt = 240, but difference from previous calculation time should be 300)
Control_output is now set to 33,70

2021-12-06 21:29:50 INFO (MainThread) [custom_components.smart_thermostat.climate] Time until input_boolean.chauffage_sol turns on: 537 sec
2021-12-06 21:30:50 DEBUG (MainThread) [custom_components.smart_thermostat.climate] Obtained current control output. 17.04 (error = 0.00, dt = 60.00, p=0.00, i=17.04, d=-0.00)

New calculation of control_output, set now to 17,04
Time to turn on is recalculated

2021-12-06 21:30:50 INFO (MainThread) [custom_components.smart_thermostat.climate] Time until input_boolean.chauffage_sol turns on: 627 sec
2021-12-06 21:31:50 DEBUG (MainThread) [custom_components.smart_thermostat.climate] Obtained current control output. 17.04 (error = 0.00, dt = 60.00, p=0.00, i=17.04, d=-0.00)
2021-12-06 21:31:50 INFO (MainThread) [custom_components.smart_thermostat.climate] Time until input_boolean.chauffage_sol turns on: 567 sec

Other log, output changes every minutes :

2021-12-06 22:03:50 DEBUG (MainThread) [custom_components.smart_thermostat.climate] Obtained current control output. 55.54 (error = 0.10, dt = 60.00, p=25.00, i=30.54, d=-0.00)
2021-12-06 22:03:50 INFO (MainThread) [custom_components.smart_thermostat.climate] Time until input_boolean.chauffage_sol turns off: 139 sec
2021-12-06 22:04:50 DEBUG (MainThread) [custom_components.smart_thermostat.climate] Obtained current control output. 66.34 (error = 0.10, dt = 240.00, p=25.00, i=41.34, d=-0.00)
2021-12-06 22:04:50 INFO (MainThread) [custom_components.smart_thermostat.climate] Time until input_boolean.chauffage_sol turns off: 177 sec
2021-12-06 22:05:50 DEBUG (MainThread) [custom_components.smart_thermostat.climate] Obtained current control output. 69.04 (error = 0.10, dt = 60.00, p=25.00, i=44.04, d=-0.00)
2

Question about autotune and cycle error

Hi,
I just don't get any values displayed from Autotune.
The following is always reported:

[custom_components.smart_thermostat.climate] Obtained current control output. 0.00 (error = 0.00, dt = 0.00, p=0.00, i=0.00, d=0.00) [custom_components.smart_thermostat.climate] Request turning off switch.thermostat_wohnzimmer_power (MainThread) [custom_components.smart_thermostat.climate] Reject request turning off switch.thermostat_wohnzimmer_power: Cycle is too short

i read that you should set min_cycle_duration to avoid this error, but this did not work for me either.
My config looks like this:

  • platform: smart_thermostat
    name: Smart Thermostat - Wohnzimmer
    heater: switch.thermostat_wohnzimmer_power
    target_sensor: sensor.average_wohnzimmer
    min_temp: 8
    max_temp: 28
    ac_mode: false
    target_temp: 24
    keep_alive:
    seconds: 60
    away_temp: 22
    comfort_temp: 25
    boost_temp: 26
    sleep_temp: 21.5
    home_temp: 23
    target_temp_step: 0.5
    min_cycle_duration: 00:15:00
    pwm: 00:15:00
    autotune: "ziegler-nichols"

additionally I had tried it once with "sampling_period", unfortunately also nothing. I have installed the current beta 3.
can you tell me where the error lies?
the fritz thermostats have an interval of 15 minutes, so that should fit or not?

big thanks for your help!

sleep_temp attribute change is ignored

Describe the bug
sleep_temp: 12 is ignored and reset to sleep_temp: 15

To Reproduce
Steps to reproduce the behavior:

  1. Define a smart_thermostat in .yaml with sleep_temp: 15
  2. Restart Home Assistant
  3. Edit the yaml to say sleep_temp: 12
  4. Restart Home Assistant

Expected behavior
When selecting preset "sleep" from the dropdown in the frontend thermostat, I expect the temperature to be set to 12
When checking the state in developer tools, I expect the sleep_temp: attribute to be 12

System:

  • OS: HASSio on Raspberry 3B+
  • Browser: Firefox

Additional context
I also edited the attribute from the state editor. It gets reset to 15℃ always

HA Restart Integral should be a float

Hello,
When restart HA, I have this error:

`Logger: homeassistant.components.climate
Source: custom_components/smart_thermostat/pid_controller/init.py:74
Integration: Thermostat (documentation, issues)
First occurred: 22:00:56 (4 occurrences)
Last logged: 22:00:56

Error adding entities for domain climate with platform smart_thermostat
Error while setting up smart_thermostat platform for climate
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 382, in async_add_entities
await asyncio.gather(*tasks)
File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 607, in _async_add_entity
await entity.add_to_platform_finish()
File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 714, in add_to_platform_finish
await self.async_added_to_hass()
File "/config/custom_components/smart_thermostat/climate.py", line 295, in async_added_to_hass
self.pidController.integral = self.i
File "/config/custom_components/smart_thermostat/pid_controller/init.py", line 74, in integral
assert isinstance(i, float), "Integral should be a float"
AssertionError: Integral should be a float`

There is no influence in my case cause Integral part is configured in yaml and not reloaded from a previous state.

Integral component keeps constant in some cases

Describe the bug
A clear and concise description of what the bug is.

Integral component does not reduce when temperature is over setpoint. It keeps constant.

To Reproduce
Steps to reproduce the behavior:
Change setpoint under actual temperature

Expected behavior
It should reduce itself to 0 smoothly.

Screenshots
If applicable, add screenshots to help explain your problem.

Desktop (please complete the following information):

  • OS: [e.g. iOS]
  • Browser [e.g. chrome, safari]
  • Version [e.g. 22]
    N/A

Smartphone (please complete the following information):

  • Device: [e.g. iPhone6]
  • OS: [e.g. iOS8.1]
  • Browser [e.g. stock browser, safari]
  • Version [e.g. 22]
    N/A

Additional context
The problem can be solved changing this line in pid_controller/init.py:

if self._out_min < self._last_output < self._out_max and \
to:
if self._out_min <= self._last_output <= self._out_max and \

As it is now, when output falls to 0 and do not change, the integral component do not vary.

Missing hot & cold tolerance

When PID is switched off, the thermostat acts like generic thermostat but is missing the hot and cold tolerance.

float division by zero

Bonjour,

J'essaye de calibrer deux thermostats et j'obtiens les erreurs suivantes:

Describe the bug

Logger: homeassistant.components.websocket_api.http.connection
Source: custom_components/smart_thermostat/pid_controller/__init__.py:305
Integration: Home Assistant WebSocket API (documentation, issues)
First occurred: 06:48:48 (2 occurrences)
Last logged: 06:48:53

[140041979602688] float division by zero
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/websocket_api/commands.py", line 185, in handle_call_service
    await hass.services.async_call(
  File "/usr/src/homeassistant/homeassistant/core.py", line 1495, in async_call
    task.result()
  File "/usr/src/homeassistant/homeassistant/core.py", line 1530, in _execute_service
    await handler.job.target(service_call)
  File "/usr/src/homeassistant/homeassistant/helpers/entity_component.py", line 209, in handle_service
    await self.hass.helpers.service.entity_service_call(
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 663, in entity_service_call
    future.result()  # pop exception if have
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 896, in async_request_call
    await coro
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 700, in _handle_entity_call
    await result
  File "/config/custom_components/smart_thermostat/climate.py", line 646, in async_set_hvac_mode
    await self._async_control_heating(calc_pid=True)
  File "/config/custom_components/smart_thermostat/climate.py", line 823, in _async_control_heating
    await self.async_update_ha_state()
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 492, in async_update_ha_state
    self._async_write_ha_state()
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 541, in _async_write_ha_state
    extra_state_attributes = self.extra_state_attributes
  File "/config/custom_components/smart_thermostat/climate.py", line 621, in extra_state_attributes
    "autotune_buffer_full": round(self._pidAutotune.buffer_full, 2),
  File "/config/custom_components/smart_thermostat/pid_controller/__init__.py", line 305, in buffer_full
    return len(self._inputs) / float(self._inputs.maxlen)
ZeroDivisionError: float division by zero
Cette erreur provient d'une intégration personnalisée

Logger: homeassistant.helpers.event
Source: custom_components/smart_thermostat/pid_controller/__init__.py:305
Integration: smart_thermostat (documentation, issues)
First occurred: 06:19:07 (14 occurrences)
Last logged: 08:23:07

Error while processing state change for switch.sonoff_4ch_relay_4
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/event.py", line 269, in _async_state_change_dispatcher
    hass.async_run_hass_job(job, event)
  File "/usr/src/homeassistant/homeassistant/core.py", line 433, in async_run_hass_job
    hassjob.target(*args)
  File "/usr/src/homeassistant/homeassistant/helpers/event.py", line 209, in state_change_listener
    state_change_dispatcher(event)
  File "/usr/src/homeassistant/homeassistant/helpers/event.py", line 196, in state_change_dispatcher
    hass.async_run_hass_job(
  File "/usr/src/homeassistant/homeassistant/core.py", line 433, in async_run_hass_job
    hassjob.target(*args)
  File "/config/custom_components/smart_thermostat/climate.py", line 783, in _async_switch_changed
    self.async_schedule_update_ha_state()
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 660, in async_schedule_update_ha_state
    self.async_write_ha_state()
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 505, in async_write_ha_state
    self._async_write_ha_state()
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 541, in _async_write_ha_state
    extra_state_attributes = self.extra_state_attributes
  File "/config/custom_components/smart_thermostat/climate.py", line 621, in extra_state_attributes
    "autotune_buffer_full": round(self._pidAutotune.buffer_full, 2),
  File "/config/custom_components/smart_thermostat/pid_controller/__init__.py", line 305, in buffer_full
    return len(self._inputs) / float(self._inputs.maxlen)
ZeroDivisionError: float division by zero
Cette erreur provient d'une intégration personnalisée

Logger: homeassistant
Source: custom_components/smart_thermostat/pid_controller/__init__.py:305
Integration: smart_thermostat (documentation, issues)
First occurred: 06:19:07 (355 occurrences)
Last logged: 08:36:47

Error doing job: Task exception was never retrieved
Traceback (most recent call last):
  File "/config/custom_components/smart_thermostat/climate.py", line 765, in _async_sensor_changed
    await self._async_control_heating(calc_pid=True)
  File "/config/custom_components/smart_thermostat/climate.py", line 823, in _async_control_heating
    await self.async_update_ha_state()
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 492, in async_update_ha_state
    self._async_write_ha_state()
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 541, in _async_write_ha_state
    extra_state_attributes = self.extra_state_attributes
  File "/config/custom_components/smart_thermostat/climate.py", line 621, in extra_state_attributes
    "autotune_buffer_full": round(self._pidAutotune.buffer_full, 2),
  File "/config/custom_components/smart_thermostat/pid_controller/__init__.py", line 305, in buffer_full
    return len(self._inputs) / float(self._inputs.maxlen)
ZeroDivisionError: float division by zero

To Reproduce

climate:
  - platform: smart_thermostat
    name: Thermostat salon
    unique_id: smart_thermostat_salon
    heater: switch.sonoff_4ch_relay_3
    target_sensor: sensor.temperature_salon
    outdoor_sensor: sensor.wemos_teleinfo_temperature
    min_temp: 18
    max_temp: 25
    ac_mode: False
    target_temp: 21
    target_temp_step: 0.1
    keep_alive:
      seconds: 60
    away_temp: 18
    kp: 3.6834316626861
    ki: 0.030695589940704194
    kd: 110.50177598710151
    ke: 0.01
    pwm: 00:15:00
    autotune: "ziegler-nichols"
    lookback: 02:00:00
    noiseband: 0.2
  - platform: smart_thermostat
    name: Thermostat bureau
    unique_id: smart_thermostat_bureau
    heater: switch.sonoff_4ch_relay_4
    target_sensor: sensor.temperature_bureau
    outdoor_sensor: sensor.wemos_teleinfo_temperature
    min_temp: 18
    max_temp: 25
    ac_mode: False
    target_temp: 21
    target_temp_step: 0.1
    keep_alive:
      seconds: 60
    away_temp: 18
    kp: 5
    ki: 0.01
    kd: 500
    ke: 0.01
    pwm: 00:15:00
    autotune: "ziegler-nichols"
    lookback: 0024:00:00
    noiseband: 0.2

Merci !

Add to the attributes the next switch change.

Is your feature request related to a problem? Please describe.
At the moment this value is present on the HA log and I need to keep open the terminal to read the values.

Describe the solution you'd like
Would be the best having this in an attribute to read directly from the an HA lovelace card.

Describe alternatives you've considered
Value already present in the log.

Additional context
this is an example:
Time until switch.gas_miki_office turns on for Smart Miki Office (climate.smart_miki_office): 2063 sec

Time_next_change: 2036 sec.

And thank to the developer for this amazing integration. Really it works so well.

Responsiveness is slow

When I change the preferred temp it always takes a while to turn off or on.
I noticed it's exactly 5 min, which is what I have set in the sampling period parameter.
Is this a bug or expected behavior?

I remember it use to respond directly to user input.

climate.set_preset_mode forces preset mode to Away

Describe the bug
climate.set_preset_mode forces preset mode to Away of I call it with preset_mode: "none" since release 2021.12.5

To Reproduce
Steps to reproduce the behavior:

  1. From HA Dev Tools
  2. Call climate.set_preset_mode with preset mode
service: climate.set_preset_mode
data: 
  preset_mode: "none"
  entity_id: "all"
  1. Thermostat is set to Away mode.

Expected behavior
A clear and concise description of what you expected to happen.

Screenshots
If applicable, add screenshots to help explain your problem.

Desktop (please complete the following information):

  • OS: [e.g. iOS]
  • Browser [e.g. chrome, safari]
  • Version [e.g. 22]

Smartphone (please complete the following information):

  • Device: [e.g. iPhone6]
  • OS: [e.g. iOS8.1]
  • Browser [e.g. stock browser, safari]
  • Version [e.g. 22]

Additional context
Reverted to 2021.12.4 and correct behavior was restored

No unique_id

The generic thermostat has a unique_id property so that we can explicitly specify the id instead of getting a random one. It would be nice if we can have that in this component. :)

Preset values not updated

After changing the preset values in the configuration.yaml the thermostat still uses the previous values.
I did restart HA.

configuration.yaml

`climate:

  • platform: smart_thermostat
    name: Smart Thermostat
    unique_id: my_smart_thermostat
    heater: switch.verwarming
    target_sensor: sensor.thermometer
    outdoor_sensor: sensor.buienradar_temperature
    preset_sync_mode: sync
    target_temp_step: 0.1
    sampling_period: 900
    min_temp: 14
    max_temp: 21
    ac_mode: False
    keep_alive:
    seconds: 60
    comfort_temp: 20
    home_temp: 19
    eco_temp: 18
    away_temp: 14
    noiseband: 0.3
    kp : 100
    ki : 40
    kd : 60
    `

Screenshot 2022-01-01 at 12 05 24

Use attribute of entity for outdoor_sensor

I don't have an outdoor sensor to use but I was thinking that I could use a cloud sensor instead, such as AccuWeather. Problem is that the temperature is an attribute of the weather entity. Is it somehow possible to use it?

entity_id: weather.home
attribute: temperature

Unresponsiveness initial_hvac_mode: "off"

Despite initial hvac_mode: is set to "off" after every new ha restart it remain on the old state.
The same issue is involving target_temp: value.

Steps to reproduce the behavior:
Restart Home Assistant
OS: Raspberry PI OS
All the browser
HA ver.: core-2021.11.5

How to change presets?

I installed and configured this component successfully, but what i can only do is set a target temperature, I see no where to change the defined presets.. I want to put it into sleep mode when I'm sleeping.

Also in the entity page, it suggests "This entity ('climate.smart_thermostat_living_room') does not have a unique ID, therefore its settings cannot be managed from the UI. See the documentation for more detail."

Switches off on temp change

Whenever the temp changes by 0,1 the heater switches off -> on -> off, and remains off even if its below the target temp.
Also doesn't automatically turn on when below target temp.

Integral part of the PID controller accumulates gain for error during the period the thermostat was in OFF state

Describe the bug
I have three floor heating circuits regulated by the Smart Thermostat. I am forced to shut them down during peak hours. When the thermostat is turned back ON (usually after 1 hour) the temperature drop is accumulated into the integral part for the whole duration it was OFF. See attached recent chart of the pid_i attribute of one of the thermostats. The flat lines are during the OFF periods, the immediate jumps are right after it is turned back on. I have highlighted the parts I am referring to.

To Reproduce
Steps to reproduce the behavior:

  1. turn thermostat OFF,
  2. wait for the temperature to drop by one or a couple of degrees over a "significant" period (from the controller perspective, i.e. an hour),
  3. turn back ON - the next pid_i update will jump by the overall accumulated error, including the off period.

Expected behavior
The integral part of the thermostat should not account for the time it has spent in the OFF state and keep the value unchanged until there is an update (temperature change / sampling period). It was obviously not missing the target temperature furing OFF period, because it could not act to achieve it.

*Screenshots
pid_i
*

On/Off adjustment duration causes heater not switching on

Hi @ScratMan

I'm testing your v2021.12.5-beta3 version.
When the min_cycle_duration is greater than time_on duration, time_off duration is extended.
set_control_value starts waiting for time_off duration before switching on heaters, but, heater never switch on.

image

I think there's a bug line #949:

                if self._active:
                    _LOGGER.info("Request turning off %s", self._heater_entity_id)
                    await self._async_heater_turn_off()
                    self._time_changed = time.time()

self._time_changed is set to current time on every keep_alive cycle, when the thermostat is "_active" (and, _active is set to true when the thermostat received the fisrt temperature sensor value.

I think you should turn off heaters only when the heaters are on, by testing self._is_device_active instead if self._active:

                if self._is_device_active:
                    _LOGGER.info("Request turning off %s", self._heater_entity_id)
                    await self._async_heater_turn_off()
                    self._time_changed = time.time() 

You can also see in logs that the request to turn off heaters is called on every keep_alive cycle

2021-12-21 08:45:09 INFO (MainThread) [custom_components.smart_thermostat.climate] Reject request turning off switch.chauffage_entree: Cycle is too short
2021-12-21 08:45:39 INFO (MainThread) [custom_components.smart_thermostat.climate] Time until input_boolean.chauffage_sol turns on: 742 sec
2021-12-21 08:45:39 INFO (MainThread) [custom_components.smart_thermostat.climate] Request turning off switch.chauffage_entree
2021-12-21 08:45:39 INFO (MainThread) [custom_components.smart_thermostat.climate] Turning off switch.chauffage_entree
2021-12-21 08:46:09 INFO (MainThread) [custom_components.smart_thermostat.climate] Time until input_boolean.chauffage_sol turns on: 712 sec
2021-12-21 08:46:09 INFO (MainThread) [custom_components.smart_thermostat.climate] Request turning off switch.chauffage_entree
2021-12-21 08:46:09 INFO (MainThread) [custom_components.smart_thermostat.climate] Reject request turning off switch.chauffage_entree: Cycle is too short
2021-12-21 08:46:39 INFO (MainThread) [custom_components.smart_thermostat.climate] Time until input_boolean.chauffage_sol turns on: 682 sec
2021-12-21 08:46:39 INFO (MainThread) [custom_components.smart_thermostat.climate] Request turning off switch.chauffage_entree
2021-12-21 08:46:39 INFO (MainThread) [custom_components.smart_thermostat.climate] Reject request turning off switch.chauffage_entree: Cycle is too short
2021-12-21 08:47:09 INFO (MainThread) [custom_components.smart_thermostat.climate] Time until input_boolean.chauffage_sol turns on: 652 sec
2021-12-21 08:47:09 INFO (MainThread) [custom_components.smart_thermostat.climate] Request turning off switch.chauffage_entree
2021-12-21 08:47:09 INFO (MainThread) [custom_components.smart_thermostat.climate] Turning off switch.chauffage_entree

Regards,

Delay in updating pid_p, pid_i and pid_d in case of target temperature changes.

I noticed that in case of modification of the "temperature" parameter (target temperature), the parameters:
pid_p:
pid_i:
pid_d:
are not updated "instantly" but the update is performed only at the first variation of the "current_temperature".

This leads to a delay in the action of the thermostat and an overshoot of the temperature in case of a decrease in target_temperature.

Multiple heater entities

Hello, very good integration to control. But I have a question. Is it possible to set more entities to heater property e.g.?

heater:
switch.on_off_relay_pin_1
switch.on_off_relay_pin_2
switch.on_off_relay_pin_3
switch.on_off_relay_pin_4

[Feature request] Optional numerical output instead of ON/OFF

I have Radiator valves which can be controlled by a 0-100 percentage, so it would be nice if the Thermostat could also output these values, as I want to control the TRV with an external Sensor.

So a numerical output, basically just the value which is then converted to PWM, would be very useful in my setup.

I don't know how difficult this is, or if you are interested in this feature but I just wanted to suggest it as the problem came up for me.

Shared values between several thermostat

Hello,

I'm using several thermostat. Each have different settings but it seems they all shared the same limits defines in the first one.

E.g. with this:

climate:
  - platform: smart_thermostat
    name: Thermostat salon
    unique_id: smart_thermostat_salon
    heater: switch.sonoff_4ch_relay_3
    target_sensor: sensor.temperature_salon
    outdoor_sensor: sensor.wemos_teleinfo_temperature
    min_temp: 18
    max_temp: 25
    ac_mode: False
    target_temp: 21
    target_temp_step: 0.1
    keep_alive:
      seconds: 60
    away_temp: 18
    home_temp: 21
    kp: 3.6834316626861
    ki: 0.030695589940704194
    kd: 110.50177598710151
    ke: 0.6
    pwm: 00:05:00
  - platform: smart_thermostat
    name: Thermostat sous-sol
    unique_id: smart_thermostat_sous_sol
    heater: group.chauffage_sous_sol
    target_sensor: sensor.emoncms_temp_sous_sol
    outdoor_sensor: sensor.wemos_teleinfo_temperature
    min_temp: 10
    max_temp: 22
    ac_mode: False
    target_temp: 14
    target_temp_step: 0.1
    keep_alive:
      seconds: 60
    away_temp: 14
    home_temp: 19
    kp: 0.93620554759938432805225743160303
    ki: 1.929150825356307100228894101485
    kd: 131.30282805081365200932910478232
    ke: 0.6
    pwm: 00:05:00

If for example I tried to change the limits of the second one this way:

service: smart_thermostat.set_preset_temp
data:
  away_temp: 10
target:
  entity_id: climate.smart_thermostat_sous_sol

I get this error:

Logger: homeassistant.components.websocket_api.http.connection
Source: components/websocket_api/connection.py:141
Integration: Home Assistant WebSocket API (documentation, issues)
First occurred: 22:45:28 (1 occurrences)
Last logged: 22:45:28

[140471625016224] Error handling message: value must be at least 18.0 for dictionary value @ data['away_temp']. Got None

10 is supposed to be in the accepted range of the second one but he give a value of 18 which is the lower limit of the first one.

min_cycle_duration parameter possible?

Home Assistant's generic_thermostat integration has a great parameter named min_cycle_duration which is useful to prevent damage to the heating or cooling equipment due to too often switching it on and off.

I tried your component and this is how it behaves:
kép

As you can see there are very short periods, of only a few seconds, for which the gas burner is turned off or on. This is problematic, because turning on the the gas burner is a process of at least 40-60 seconds (pump starts first for 20 seconds, pre-heats with small flame for another 20 seconds, and slowly increases flame to full afterwards). The PID algorithm makes too fast decisions, and turns on the gas for 30-40 seconds and it turns it off. Zero heat was sent to the house during during this. If this happens too fast the boiler will be damaged.

Normally one cycle of burning the gas for a central heating boiler should be at least 10 minutes, and after turning off another minimum 10 minutes should be waited before starting to burn again. This should be configurable with min_cycle_duration depending on the heating or cooling device type the user has.
Can you please add this kind of override to the component?

Intermittent disruptions in temperature measurements cause huge pid_d spikes

Describe the bug
When temperature reporting device disconnects and reconnects, pid_d spikes: it results in values much larger than required by the actual derivative.

To Reproduce
Make target_sensor disconnect so that home-assistant reports it as unavailable, then reconnect. Repeat a few times if necessary.

Expected behavior
pid_d results purely from temperature measurements.

Screenshots
pid_d
image

target_sensor
image

Additional context
Used device is a Shelly 1PM wifi relay with DS18B20 temperature sensor addon. The disconnecting is a separate problem - but it appears to reveal this problem I report here. Home-assistant and hasmartthermostat are up to date.

Overrride PID on Boost mode

Is your feature request related to a problem? Please describe.
It would be nice to change the Boost mode from just setting the temperature to boost_temp, to completely ignore the PID calculations and behave like a generic_thermostat, and then back to "PID" mode once the boost_temp is reached.

This will allow to really boost the temperature temporarily and go back to normal

Describe the solution you'd like
A clear and concise description of what you want to happen.

Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.

Additional context
Add any other context or screenshots about the feature request here.

heating duration exceeds min_cycle_duration

Hi,

Be careful with float values.
My parameters:

  • keep_alive: 30
  • min_cycle_duration: 90

The heater is on more than time_on value.

In this example, time_on is too low, and, heaters will switch on for min_cycle_duration.

2021-12-22 07:57:42 INFO (MainThread) [custom_components.smart_thermostat.climate] Request turning on input_boolean.chauffage_sol
2021-12-22 07:57:42 INFO (MainThread) [custom_components.smart_thermostat.climate] Turning on input_boolean.chauffage_sol

Turning on at 7:57

2021-12-22 07:58:12 INFO (MainThread) [custom_components.smart_thermostat.climate] Time until input_boolean.chauffage_sol turns off: 60 sec
2021-12-22 07:58:42 INFO (MainThread) [custom_components.smart_thermostat.climate] Time until input_boolean.chauffage_sol turns off: 30 sec
2021-12-22 07:59:12 INFO (MainThread) [custom_components.smart_thermostat.climate] Time until input_boolean.chauffage_sol turns off: 0 sec

Should turn off (90 seconds after turning on), and, log says "0 sec", but, in fact, the heater will be switch off on next keep_alive cycle
Total heating duration is 120 seconds

2021-12-22 07:59:42 INFO (MainThread) [custom_components.smart_thermostat.climate] Request turning off input_boolean.chauffage_sol
2021-12-22 07:59:42 INFO (MainThread) [custom_components.smart_thermostat.climate] Turning off input_boolean.chauffage_sol

To have a better result, I'll change min_cycle_duration to 89 instead of 90.
but, I think this issue is due to float, time_on and time_off should be cast into integer (in seconds)

ZeroDivisionError

After the last update my logs are flooded with this...
:(

Logger: homeassistant
Source: custom_components/smart_thermostat/climate.py:918
Integration: smart_thermostat (documentation, issues)
First occurred: 10:43:16 PM (5 occurrences)
Last logged: 10:43:17 PM

Error doing job: Task exception was never retrieved
Traceback (most recent call last):
File "/config/custom_components/smart_thermostat/climate.py", line 799, in _async_control_heating
await self.set_control_value()
File "/config/custom_components/smart_thermostat/climate.py", line 918, in set_control_value
time_off *= self._min_on_cycle_duration.seconds / time_on
ZeroDivisionError: float division by zero

Turning off the "operation" on the thermostat does not turn off related heater switch

First of all, thank you for an excellent integration. I still have some tweaking of the parameters to do, but I love the idea and appreciate the work you have done so far.

Describe the bug
Turning the operation of the smart thermostat to "off" does not turn off configured heater switch immediately - I am not sure if it is waiting for temperature change, min_cycle_duration, or pwm period. In fact, it appears it does not attempt to switch it off at all.

To Reproduce
Steps to reproduce the behavior:
Wait for the thermostat to turn heating on, set operation to "off". Switch is not turned off immediately.

Expected behavior
I expect the configured heater switch to turn off immediately.

Additional context
Why I need it to turn off immediately:
In my setup I have z-wave relays that are "lost" when they lose power - this happens several times a day because the utility company remotely switches off heating circuits during predefined times of peak demand. I get cheaper electricity as a result.
If there are attempts to communicate with these relays during this time they get marked dead by the z-wave controller.

To prevent this from happening I turn the thermostat off preemptively using a script and predefined schedule - this makes sure the thermostat is not attempting to turn it on. I turn the thermostat back to operation mode "heat" once power is detected on related circuits.

I have been doing this for over a year using the core "generic thermostat" and have switched this week to smart thermostat and noticed this behavior. At worst I will modify my scripts to turn off the thermostats and related switches "manually".

Round P / I / D / Control Output values

Hi ScratLan,

I've set a min_cycle_duration to 120 (my valve takes more than 1 minutes to be fully opened).
But, after some times, due to values with lot of number after comma, the I or D values were close to 0, but not really (0,00...),
and the output_control was very small (0,05%), and the valve was opened 2 minutes (min_cycle_duration).
My PWM is 900, so 0,05% is 0,45 secondes.

image

Value copied from developpers screen in HA :
control_output: 0.05850523519505746
pid_p: 0
pid_i: 0
pid_d: -0.0

Maybe, some values should be rounded.

Regards,

Strange behaviour after calling smart_thermostat: reload service

Describe the bug
After calling smart_thermostat: reload service I get strange behaviour of the target temperature. It always reverts to the value before reload. Only a restart of the HA core resolves this problem.

To Reproduce
Steps to reproduce the behavior:

  1. Call smart_thermostat: reload service
  2. Change the target temperature
  3. Wait a few seconds
  4. The target temperature reverts by itself to the value set before the reload

Screenshots
Untitled

Additional context
I haven't found any other cause or corelation for this behaviour. I don't have any automations or scripts or schedules or other stuff that messes with the target temperature. I've looked everywhere. The generic_thermostat works fine. Everything is fine after a HA core restart but the issue comes right back after smart_thermostat: reload service.

Output is set to 0 when temperature sensor is stable more then 3 hours

Hi @ScratMan

Unfortunately, I've got temperature sensors that send an update only when the value changes.
This night, when the PID values were stable (P:0, I:7, D:0), and the temperature also, the output suddenly cames to 0, and, cut off the heaters until the temperature drops.

This is due to these lines (#731) :

            if time.time() - self._last_sensor_update > 10800:
                # sensor not updated for more than 3 hours, considered as stall, set to 0 for safety
                self._control_output = 0

Maybe this value of "10800" should be a parameter, and, if the value is "0", this safety rule will be disabled

PWM calculation

Wonderful job!
I would like to give a little advice about autotune. My autotune calculated the coefficients well, but I did not know how to define appropriate PWM. However, that it is easy enough to define - just look at the autotune graph. if I understood correctly, then the average period of time during which the heater was active is the PWM (it was ~3h with my electric Kospel ECKO). Is it worth mentioning in the documentation about the definition of PWM? I think it is possible to log it as one of autotune suggestions in the system log.

image

Can I somehow get Control Output with both positive and negative values?

Is your feature request related to a problem? Please describe.
I want to try using PID for controlling the target temperature of my heat pump. Currently it only gives either positive or negative output, and cuts out at zero.

Describe the solution you'd like
I would like to get a Control Output (using a template sensor), that works both ways.

Describe alternatives you've considered
I currently use a Python script with quasi-proportional control. I need it to warm up the surrounding air in excess, then switch to fan_only mode to spread it around the home. Otherwise it will just warm it's own surroundings to the target temperature, and everywhere else will be too cold. In the summer it's the opposite.

Additional context
I think PID is the right solution to my problem - and an elegant/cool one.

[Request] Set preset temperatures at run time

Discussed in #14

Originally posted by nagyrobi November 17, 2021
One of the problems of HA's built-in generic_thermostat is that the temperature for away mode is hardcoded in the configuration, it cannot be adjusted at run time.

Thankfully smart_thermostat supports away, eco, boost, comfort, home, sleep, activity each with its own temperature value configurable.

It would be nice to have the possibility to adjust these during runtime, and use HA's history database to always restore to the last known value after restart.

Features request PWM disabled -> Raw output

Hi,
first of all congratulations for this component. It is very useful to me.
In the old version 0.5.1 by not specifying the "pwm" parameter, the output in pwm was disabled in order to have the raw output (0 100%). I understand that it is no longer possible in the latest versions. It's correct? Now the "pwm" has a default right?
If i'm wrong please can you explain me how to do it?

In case I am right, i think having this feature could be very usefull. For instace I am controlling the temperature of my guinea pigs house with a shelly dimmer ( https://shelly.cloud/products/shelly-dimmer-2-smart-home-light-controller/ ) that drive an heat light bulb. That doesn't need to be just turned off and on but can keep all the value in the rage 0 - 100%. Imaging also a light bulb turning on and off in the cage like a disco party! Funny yes, but not always :)
Moreover this custom component can be used ( out of the box ) also for other application like illuminance controller (that is in some way what i do)
What do you think @ScratMan ?

Precision not working 0.1 values

Precision not working.

precision (Optional): the displayed temperature precision (valid are 0.1, 0.5 and 1.0, default 0.1 for Celsius and 1.0 for Fahrenheit)

Not working at 0.1 values

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.