999LV / SmartVirtualThermostat

Smart Virtual Thermostat python plugin for Domoticz home automation system
MIT License
42 stars 31 forks source link

Some suggestions #42

Open ultrasuperpingu opened 3 years ago

ultrasuperpingu commented 3 years ago

I'm not sure this is the best place to do those suggestion. Sorry if it's not the best way...

I hope this help :)

Carterkrieg commented 3 years ago

Hi, long time user here, your work is highly appreciated. and also, those are excelent suggestions, especially the one about delayed calculation start, when system is restarted- but why only random, if you have several heat zones, it would be best to set some sort of hard offset between them, so there is as little overlap between them as posible to avoid using heaters on max power. If I may, I have one more - I am using plugin to control radiator valves, it works flawlessly, but valves have opening time about 2-3 minutes, so, when set to short periodes, it practicly ignores the shorter heating times and mess with constants. The suggestion is to add user constant, something like opening_time_delay or something like that (divided by period duration) and just add it to calculated heating percent. Keep it up guys. Sincerely, John.

ultrasuperpingu commented 3 years ago

@Carterkrieg You're right, configurable offset for heating start would do the job, but needs more parameters... Random start could do the job too without the needing to add parameters. But I really think the plugin need a different way to provide parameters because the 6 input fields provided by domoticz is clearly not enough.

For the opening time of valves, it should be easy to implement a minimum heating time/not heating time I guess. Once again, we need more parameters though...

ultrasuperpingu commented 3 years ago

I finally managed to make the thermostat work more or less accurately with my inertia heaters. I hope that with some more learning days, it will be fine. But I had multiple issues with it. First of all, I first used a too small calculation_period. I first tried with 45min and saw after just one cycle that it won't work because when heaters are cold, they need half an hour to start to heat the room so I changed to 90 min. After 2 days, the thermostat was still overheat to more than 1 degre when switching from economy to confort and the temperature has still oscillating a lot before stabilization. I saw that the problem was that the AutoCalib method was not called when temperature was above setpoint+deltamax at the end of heating cycle. I increased the deltamax, calculation_period (120min) and manually set the ConstC and ConstT to help the algorithm. It was way better but still not very good because when maintaning the current temperature, the thermostat only heat at the beginning of the cycle. So, I subdivided the heat cycle. The number of subdivision is computed depending of the difference beetween setpoint and current temperature (for example, if setpoint=20 and temp=17, nb subcycles=1 and if setpoint=20 and temp=20, nb subcycles=6). So, if the thermostat need to heat 30 min during the 2h cycles, it will heat, for example, 5min every 20min. It provides both a more stable temperature and a better confort over the heating cycle. I can provide a PR if needed.

rrozema commented 3 years ago

Do you have an outside sensor configured? I think you do, as it's not use to play with ConstT if you don't. The outside temperature conrrection is the most complicated part of the calculations, and it's dependent on the inside calculations. You could try getting the thermostat work correctly first without the outside sensor defined. That should be easier to achieve. Then, once you got that working reasonably well, add the outside sensor.

I think, as was suggested above also, that the deltamax is indeed far too small. deltamax acts as a 'safety' to the PID process: if the tempature goes more than the deltamax value over the setpoint, the PID process is overruled. Overruling the PID process however also means that it can't learn frm it's mistakes. In other words: if we don't let the thermostat overheat the room, it will never know what it did wrong and it will do the same thing the next time. This process is a PID-controller, not an on/off switch. It needs to oscillate around the setpoint before it will learn how to get to the setpoint fastest without overshooting (or only a little). I'm not a specialist on PID controllers, but from what I've read so far it seems that if they're either configured to respond too agressively or too slowly, the process may even never find the proper setting. But I'm sure that with the deltamax set so small it will never learn the proper values for your room.

Having a high inertia heating doesn't automatically mean you need to set a large cycle time. Having a large cycle period DOES mean that it will be unconfortable: the PID controller will be very slow to respond to changes and your room will cool down a lot before the thermostat will switch on again. I.e. I think having a long cycle time is not such a good idea at all. The thermostat will learn the long response time of the heating: the ConstC value is it's 'memory' (The I for Integral in PID) by which it learns from past experience However, I think the fixed value of 50 for max nbCC is important in how well the PID learns in a high inertia situation: This means that the thermostat initially will learn very fast, but at the time nbCC is at 50, only 1/50 of the output is used as feedback into the learning; the thermostat will only very slowly correct an error. I think we need to identify what the Kp (the coefficient for how strongly the current error will influence the next output), the Ki (coefficient for how much past experience influences the output) and Kd (the damping coefficient, reducing the change in output) in the ConstC calculation are so that we can try to influence them. My guess so far is that the 1 to 50 increasing nbCC is actually the Ki, which increases over time. This may be intended behavior, but I do think that in some situations 50 may be to much and in others it may be to small. Again, not sure, but I think for high inertia systems Ki needs to be high, whereas for lower inertia systems it can be a lower than 50. ConstC is just the 'memory', we need to be able to control the other values.

jakenl commented 3 years ago

I read some interesting stuff in the comments here above and I recognize most of the issues they address myself:

accumulated energy in my floor heating - long calculation periods - heating only in the first part of the cycle - 'hot' and 'cold' starts - 2-3 minutes waiting time before remote controlled valves open.

ultrasuperpingu commented 3 years ago

@rrozema Yes, I have an outside sensor configured. You're right, it's part of the problem of the learning not being accurate and you're suggestion to remove it at first to learn independantly the ConstC is a probably a good idea. But I don't think it will fix totally the problem. When my heaters are cold, set the heaters to on won't increase the temperature at all in the room for the first 30min. But when the heater is already at it's maximum temperature, the room temperature will increase for like 45min even if the heaters are off. So if set the calculation period too short (let's say 20min), there is no ConstC that will provide an accurate behaviour... That's why I set the calculation time to a large value. This is why my current implementation split the calculation period into sub period. It is far from perfect but kind of do the job for me for now but I'm not sure it fits anybody needs, that's why I didn't provided a PR.

For the PID comparison, with my small knowledge about it, ConstC looks more like the P parameter of a PID controller (power = round((self.setpoint - self.intemp) * self.Internals["ConstC"], 1)). The command is simply proportional to the error.

I think the I (Ki) parameter would need to save the last error: self.lasterror = self.setpoint - self.intemp and use it with something like : power = ((self.setpoint - self.intemp) - self.lasterror)/self.calculation_period * self.Internals["Ki"]

Maybe I'm wrong, please correct me if it is the case.