999LV / SmartVirtualThermostat

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

ConstT calculation should compare outside temp to inside temp not setpoint #53

Open rrozema opened 3 years ago

rrozema commented 3 years ago

A functional error exists -in my opinion- in the calculation of the ConstT: this factor should compensate for differences between the inside temperature and the outside temperature. Current implementation however seems to compare outside temperature with the setpoint value. Heatloss however is not dependent on the setpoint but the the inside temperature.

jakenl commented 3 years ago

Makes sense. Is there somewhere a explanation of this calculation method? My experience with the cold (in Holland) last week was that the setpoint wasn't reached anymore after heating. Clearly having to do with the outside temperature. I therefore reduced the NBCT parameter to 10, to speed up self-learning. I expected my ConstT to rise from 1.5 to a higher value. To my surprise ConstT is currently at -0.2 with a NBCT of 33. So, the colder it gets outside, the lower the heating percentage will be. Crazy. I manually put ConstT to 1.8 and NBCT to 50. This self learning seems to go wrong somewhere.

I have deltamax increased to 0.9 to accommodate the slow response of floor heating with it's high energy capacity and long cycle times (120 minutes). However, I now assume that any overshoot of temperature (due to more people downstairs for instance) is taken part of the recalculation of constT, resulting in an unrealistic value.

999LV commented 3 years ago

Agree this makes sense... this piece of your PRs I’ll merge

rrozema commented 3 years ago

I have not found an explanation of the ConstT calculations yet. The ConstC calculation looks a lot like a PID calculation to my untrained eye. That wiki page on PID controllers looked very impressive to me and I couldn't do much with it. But then I found an implementation of a PID in an arduino library called autopid autopid and then it made a lot more sense to me. I was trying to re-implement the constc calculation, as I think the constc re-calculation should be done every cycle, not only when the temperature rises. But I thought I'd get my other ideas in the main source set first and my attempt at rewriting constc didn't work too well yet anyway ;-). So I restored the original constc and const calculations for the moment and put the smaller fixes in a pull request.

I combined this with a formula to calculate the power needed to heat up a body of some material, which is P = m c delta t * 1/3600. Where P is the power in kW, m is the mass of the medium to be heated in 1 hour, c is a factor for the type of material you're heating (in kJ/kg.K) and delta t is the difference in temperature to be achieved. Most of the numbers in that formula are unknown to us. Plus a very important factor is missing: the amount of energy lost to the environment while we're heating the material. But we don't really need to know those values: they will all be in the constc value we're finding by having the thermostat experiment with the temperature in our room/value: it inputs an X amount of power, (i.e. it puts on the heater for X % of the cycle time), and then at the end of the cycle it looks at the result achieved to adjust the constc value: temperature too high -> lower constc, temperature too low -> raise constc. The components m and c are fixed, determined by the room/house. The only component that varies is the heatloss, and this is what ConstT is used for, to compensate for the differences in heatloss due to the varying delta t between inside and outside temperature. This is not a propoertional relationship, but since the thermostat keeps adjusting the parameters while the seasons pass, it will do nicely. We'll probably see different values for constt in summer, fall, winter and spring.

The reason why I think the constc calculation should be done every cycle is that it should also learn to deal with cycles when the temperature doesn't change, even though we did apply power, plus cycles where the temperature still changes even though we did not apply, but we applied power in previous cycles. Ultimately we want the thermostat to keep the temperature exactly at the setpoint and never fall below it. To do so it should already start the heater before the temperature falls below the setpoint. This is even more important when the heater takes a long time to start delivering heat. This is why I think the only cycles when no constc learning should take place is when either the thermostat is in 'Off' or in 'Full force' mode plus any cycles where it is not possible to learn because insufficient data on the prevous cycle is available, like for example the 1st cycle after leaving 'Off' or 'Full force' mode.

I also have some more ideas on the ConstT calculations, but these still need a lot more thought... Like you I noticed that the ConstT value went into negative numbers, which seemed odd at first, but then I realised that it is only a correction on the power calculated from the constc value. That correction can be either positive or negative depending on the in- and outside temperatures in the period that constc was learned and the current in- and outside temperatures.

One of the other observations I made is that the differences calculated for the constc and constt values are often completely lost because of the rounding to 1 digit. I don't know yet what is a proper rounding, but I do know that 1 digit is to little for the both factors. In my attempt I've completely removed the rounding so that every little difference could be learned. and this resulted in -during the short periods I tested it- the resulting temperature getting slowly better instead of jumping around the setpoint every time.

rrozema commented 3 years ago

There is no fix for this issue yet in my pr #52 . ConstT relies on ConstC, so I first need to get the constc calculation more reliable. What I've put in the pr are just small improvements, to make the calculations of the thermostat better predictable.

jakenl commented 3 years ago

Thanks for the explanation. The correction that constT brings in, seems to be too aggressive in learning. Although it might sound logical that the outside temperature constantly changes and therefore needs adaption of ConstT, it is not correct. Outside temperature is al part of the equation.

I lowered the learning cycles back from 50 to 10 and within 2 days ConstT was already at 33 cycles and ConstC only at 13, therefore ConstT was doing the complete job of adjusting, resulting in a negative value.

The negative value is a clear example that the calculation method is not correct. This because it can't be that the colder it becomes outside, the less heat is needed. The ConstT should never be allowed to be a negative value!

EDIT: Since I still didn't understand why ConstT is learned much quicker than ConstC, I checked the rules once again and finally found the reason: The code checks 2 things: self.intemp > self.Internals['LastInT'] and self.Internals['LastSetPoint'] > self.Internals['LastInT']

In a stable situation the calculation to enable heat is always executed when the system is above setpoint. Therefore it hardly ever triggers ConstC learning. I now changed the line for this: self.intemp > self.Internals['LastInT']

I will see how this goed for the next couple of days

rrozema commented 3 years ago

I have a feeling that learning constC should take place every cycle, not only when setpoint's temperature is not reached. ConstC is not only about heating, it also contains a factor for the heatloss (i.e. energy that was put into the system but didn't result in a rise of the inside temperature.). Otherwise, how could the thermostat work without an outside sensor?

EDIT: your constT learns much quicker because there is only a limited window in which the constC will be corrected in the existing implementation. If your situation is anything like mine, most of the cycles your room is overshot and no constc adjustment takes place. This is why I added the power meter so I could log into my influx db what the thermostat is doing ad makes graphs from that. In my situation I see that most of the time my house is over setpoint. When the temperature drops below setpoint an "insane" amount of power is applied and the next few cycles the thermostat will be over setpoint and maybe even in overshoot mode. Only very rarely the temperature ever drops to the setpoint temperature. Again this behavior makes me believe that the way the power per period is calculated is not correct . What should be calculated is the amount of power that needs to be applied to end up exactly at the setpoint on the end of the upcoming cycle. This means for example that it may have to apply power while we're currently still over the setpoint! We need to predict -using the constc and constt factors as our memory on how the system behaves- what the situation will be at the end of the cycle and apply power to compensate for that, not for what the current situation is.

jakenl commented 2 years ago

@rrozema the winter season is around the corner. With the explosion in had prices, it is even more important to have a good working thermostat that avoids overshoot, but still keeps the house comfortable.

I have read the above texts again and I wonder if we should learn constC only when the setpoint is stable and ConstT when the setpoint is increased

rrozema commented 2 years ago

As I already said on February 7th, I think constC should be re-calculated every cycle when the mode is not set to 'Off' or 'Full Force' and also not when it is the first cycle after either of these modes was set (because then no valid delta value can be determined). No matter if heating was applied or not. Also a change in setpoint value should not be a reason not to re-calculate constC.

For constT I have no concrete ideas yet how and when to re-calculate that. I'm leaning towards re-calculating constT every cycle we did not apply heating, but I'm not sure this is completely right because we may have not applied heating this last cycle, but the heating system may still have radiated heat we applied in some previous cycle(s): it is therefor probably not as simple as switching learning constT on or off, we may need somehow some factor that fades out the heat applied in previous cycles. I am pretty sure though that any constT calculations should compare the resulting temperature change against the outside temperature, not the setpoint temperature as the current code seems to do.

I don't have my heating on yet but when I do switch it on, I will start monitoring it again and see if I can make any improvements. My alternative project (zone-heating in every room) doesn't make any progress anyway, as the thermostat mode devices in openzwave still don't work properly. So I think I'll be at least one more heating season on SVT.

jakenl commented 2 years ago

I just had the idea to start monitoring heat loss at night time, when the central heating is not yet used. It should give an accurate measure of heat loss of the house. I have a 7 day window for accurate logging anyway, worthwhile to save before the heating season starts. Let's see if I can make any sense of that data set.

Regarding the zwave radiator valves. I have them too, but are very disappointed. They seem to lose connection quite frequently and their response time can not be made shorter than 5 minutes. This is a lot for the intended rooms with convector heating.

jakenl commented 2 years ago

I collected my 7 days of data during a holiday. No heating from the boiler, no influence of people heating the room.

My hypothesis:

What I did:

Between midnight and 7 am (to out-rule false results due to solar heating, mostly in the afternoon in my house): Calculate average inside and outside temperature Calculate delta temperature inside / outside Calculate temperature drop inside

Graph (delta temperature inside / outside) versus (temperature drop inside) image

This made 'some' sense. I could calculate a constant value.

However, I applied that to the data of last night (no heating from the boiler at night) and the calculated temperature drop from 20.8'C at midnight was 0.8, so the result this morning should be 20.0'C. In reality it was 1.5 degrees lower: 19.3'C

Possible reason: we had the wood stove on until 21:00. This generates radiation heat, but mostly convection heat due to an extra fan that heats the circulating air through the heat-exchanger in the stove. As soon as the wood stove goes off, the temperature will drop quite rapidly in the room, since it is mostly the air that was warmed. Result: much faster temperature drop than during the holiday week where the mass of all materials in the room would be the same temperature.

Conclusion: I can't use the results of this experiment to optimize the heating accuracy of the house

altserg commented 2 years ago

My experience: simple man solution - just limit max power. I have done it in my system, results are ok

rrozema commented 2 years ago

The problem with limiting max power is that it effectively reduces the thermostat to a simple on-off thermostat. svt as it is now is not working properly: temperature isn't optimally held at the setpoint and as a result energy is wasted. I want my thermostat to be better than an average thermostat, not as good as or even below that. So I'm trying to write my own alternative now as I think the algortihm used in svt can be improved. I am new to the matter of controllers however, plus I have no experience with python, so it's costing me time.

One of the things I want to improve is that svt claims to be 'smart', yet when the temperature is at the setpoint, svt's algorithm only acts after the temperature has fallen under the setpoint. I think a realy smart thermostat would learn to predict how much energy should be injected into the system to keep the temperature at the setpoint without ever falling under it. Given that the thermostat's heating cycle is rather large (i've got mine set to 10 minutes, but I read in the forum people having it set to 2 or even 3 hours), this can result in uncomfortable temperature drops during those cycles. Another thing I want to improve is that svt overshoots too much, causing long periods of no-heat in between heating cycles. As the temperature sensors used for svt are in the ground floor and this is the best isolated area in my house, the temperatures in the other rooms in my house fall far below their desired tempererature in those long no-heat periods. I want my thermostat to better divide the energy injections, keeping the water in my system from cooling down too much during the no-heating periods. And for that the overshoot must be reduced: I'm aiming for having a short burst every cycle, just enough to make the temperature never drop below the setpoint.

altserg commented 2 years ago

I have experimented with SVT and my own algo's last winter (I'm also not a signal processing expert). I have a very good isolated house (temperature drop around 1 degree per 24h at delta T inside/outside 10 degrees. Basically, the house should not be heated if average outside temperature is above 15 degrees). Right now the SVT setting for me is 6h cycle time with 20% minimal heating. I understand that SVT has problems, so there are my poor man solutions to them:

  1. I have put the temp sensor in the coldest room. I use Xiaomi BLE sensors with ESP32 Tasmota hub, so the positioning is not a problem. Please also read the temp sensor installation guidelines form any installation manual of a regular thermostat. I see from the practice that sensor position does make the difference
  2. In warmer parts of the house I have installed the temperature sensors and underfloor heating closing actuators. The heating valves are closed once the target temp is reached
  3. I have compensated the SVT overshoot by limiting the max power to 60% in the past. But right now I have changed the plugin to check for the overshoot every at every 10% power step during the heating. I will play with this version, and will submit the PR against your branch in case I'm satisfied with it. In general, I do not care too much if the temperature falls little below the setpoint, especially at night. Trying to predict the temperature fall, and compensate for it using out of cycle shorter bursts will only cost you more gas, see point 6 as well. Maybe this method will work better for the radiators (but for the radiators the SVT has ECO mode that you can turn on at night). I prefer longer active heating periods due to reasons in point 7. My target is to save as much gas as possible while keeping close to the acceptable level of comfort. Something like "soft realtime" software: It's not a nuclear powerplant and it's OK if the control software fails to keep desired parameters for some period of time
  4. I have played with short bursts in the past, but in my case I see little effect. They indeed keep the water warm but not the floor :). Maybe it will for work for the radiators, but not for the underflow heating. You can also try it by setting "apply min heating every time" parameter of SVT
  5. IMHO setting cycle time to 10 min effectively makes it on/off thermostat, I think that the heating cycle should be at least 30 min or even 1h as the system needs some time to learn
  6. Regulating the power using in/out difference like you described is very similar to weather dependent steering ( "weersafhankelijke regeling" in Dutch). I have played with it with my original Bosch smart thermostat, but I see that this mode is very ineffective: it burns a lot of gas, and overshoots. That's why I have moved to SVT. I also have talked to Bosh representative about it, and he acknowledged that the thermostat works like I was experienced. It was very disappointing as I expect that Bosch has much more experience with heating control than I, and they also are supposed to know the internals of their boilers.
  7. In my case the heating and cooling curves are not linear - they are somewhat exponential or quadratic. Applying small amount of power makes very small difference first, but if you keep heating at one moment the temperature rises very fast, and overshoots for quite a long time. The same with cooling but reverse - first it cools slowly, and at certain moment it goes faster, but not as dramatic as with heating

Bottom line: I'm still searching for a better algo :)

If you have your new algo, I can try it, assuming that you provide me the branch with working plugin.py compatible with SVT, and using the same devices. I'm also ok if it logs some data outside to your database for analysis

altserg commented 2 years ago

You can have a look at following research: https://pdfs.semanticscholar.org/8ec7/20b80c482493a91fa4739725d5446a68f2ba.pdf?_ga=2.172426787.1282315939.1641485059-982587281.1641485059

rrozema commented 2 years ago

Thanks alterg, I'll add that to my list of 'must read's. You've got some nice observations there. I do however not agree with your thought on needing to have a longer heating cycle. Having a long heating cycle means you're going to make it very uncomfortable: if for whatever reason the temperature drops (for example, because an outside door has been open for a few minutes), it can take up to almost 3 hours before your thermostat will take corrective action by switching on the heater. Also, by having a long cycle you let the water in your floor cool down. To show the effect of that I have to excagerate it a little bit, but you'll get the idea from that: when no more heat is applied for a long time, at some point when the water is cool enough; it will start moving heat away from your floor, effectively cooling the floor and thereby making the temperature drop even faster than without the heating. This is why I think it will be beneficial to not let the the water temperature in your system drop below some point or at least keep it as much as possible around the same temperature. A floor heating system has a large inertia: there is a lot of mass that needs to be heated before it actually starts 'paying off' in the form of a higher (output) temperature in the room. My idea is instead of making the cycle longer, keep the cycle short and keep checking often for the result. The thermostat needs not only learn how much poer to apply but also how many cycles of input are needed before the results show at the output.

altserg commented 2 years ago

I agree with what you said above. However, the topic of radiated floor heating system is a complex one. Even professional companies seem to use quite simple algo's. Algo's with feedback should be used for heating control, and even their performance depends on individual characteristics of each particular system.

I think that some derivative of PID algo can be used. It's implemented in Tasmota and as Domoticz plugin for radiator valwe control https://github.com/worops/Domoticz-VirtualThermostat-PID. But I'm not sure how to use it for the boiler. Maybe it's worth to read this thread: https://www.domoticz.com/forum/viewtopic.php?t=15075

In my case, there is no place under for heat to go out as I have 15cm of insulation under the floor, the heat can only go up :) . Opened doors and windows also do not make a prolonging cooling effect on a heated floor in my case - yesterday I had a failure trying to apply my culinary talents, and had to open all windows for about 30 min. Temperature has dropped, but then restored very quickly after everything was closed.

Bottom line: I think that there a limit on what you can achieve empirically experimenting with different settings and SVT algo improvements. The topic should be studied first and one of researched and proven algo's implemented. But from what I have read, the saving even with best algo is 15% max, 10% is probably a good initial shot.

Feedback to your idea: I think that making 10min cycle will turn SVT into on/off thermostat, but I would like to see the results of your experiments. Maybe it will work better if you use OpenTherm for that to control delta T to optimum point of your boiler. For my boiler the optimum point is delta T 10 degrees at 35 degrees output, kind of optimized for underfloor heating but the floor heats up very slowly in my case. I plan to to add opentherm support via Tasmota for my boiler but most probably it will happen during the summer

pcdahle commented 6 months ago

Hello, I have ported the SVT to my own python standalone implementation (which has nothing to do with Domoticz) and logged the evolvement of the (filtered) ConstC and ConstT and I see some remarkable behavior that ConstC (before going into the window filter) may become very large thus affecting the filtered value significantly. I also observe an almost resonant behavior, I think:

image

(I must of course hold it open that my ported code may still contain errors, but I have checked it several times and it looks right still.)

And there is one thing that is obvious from the original implementation: ConstC = (self.Internals['ConstC'] * ((self.Internals['LastSetPoint'] - self.Internals['LastInT']) / (self.intemp - self.Internals['LastInT']) * (timedelta.total_seconds(now - self.lastcalc) / (self.calculate_period * 60))))

if first denominator (self.intemp - self.Internals['LastInT'] becomes zero then ConstC goes to infinity. This seems to me not only unphysical but also will cause a runtime error.

Any comments to this? Is there some way this is not of importance, will not happen or it's taken care of somehow? (Maybe this is off topic to original topic and should be opened as a new issue. Reason I wrote here is that this is the only issue that seems to deal with the actualy physical/mathematical model behind the SVT. )

jakenl commented 6 months ago

Hello, I have ported the SVT to my own python standalone implementation (which has nothing to do with Domoticz) and logged the evolvement of the (filtered) ConstC and ConstT and I see some remarkable behavior that ConstC (before going into the window filter) may become very large thus affecting the filtered value significantly. I also observe an almost resonant behavior, I think:

image

(I must of course hold it open that my ported code may still contain errors, but I have checked it several times and it looks right still.)

And there is one thing that is obvious from the original implementation: ConstC = (self.Internals['ConstC'] * ((self.Internals['LastSetPoint'] - self.Internals['LastInT']) / (self.intemp - self.Internals['LastInT']) * (timedelta.total_seconds(now - self.lastcalc) / (self.calculate_period * 60))))

if first denominator (self.intemp - self.Internals['LastInT'] becomes zero then ConstC goes to infinity. This seems to me not only unphysical but also will cause a runtime error.

Any comments to this? Is there some way this is not of importance, will not happen or it's taken care of somehow? (Maybe this is off topic to original topic and should be opened as a new issue. Reason I wrote here is that this is the only issue that seems to deal with the actualy physical/mathematical model behind the SVT. )

I experienced the same results of the SVT plugin and rewrote the calculation 2 years ago. My experience with it, is very good, very stable with floor heating in the living room! The basis of the calculation is: With the given ConstC and ConstT the calculation is made and the furnace is run At the next calculation cycle, the plugin now checks the reached temperature With the reached temperature, you can calculate what the ConstC should have been to reach that! temperature. Those new calculated ConstC and T values are than fed back the same way as the original way. I think I used an average of 25 items instead of 50. So my formula there is : (Existing ConstC x 25 + calculated ConstC ) / 26

As said, this has proven to reach stable ConstC and ConstT values. ConstC: 38.848, ConstT: 1.576 without touching it for 2 years.

Btw: I also have added the code to split the calculation period in 2 when the previous heating cycle was 0%. This improves the stability of temperature when the living room was heated by the sun or by the wood stove. (my calculation period is 110 minutes due to the slow response times of floor heating)

pcdahle commented 6 months ago

Thank you @jakenl that seems to be a very reasonable way to do it, also easier to understand. I have searched the web for the physics/math behind the orig implementation but I can't find it. And allthough I'm an engineering physicist I cannot fully work out why the formulas are as they are and have a feeling something is not quite right. Also I agree that the algo is not really "smart", as someone said. I hope to spend some time during Christmas to think about this.

jakenl commented 6 months ago

to cut the next calculation period in half, when the current cycle does not require heat, I added this in the IF statement for power =0:

        if power == 0:
            self.switchHeat(False)
            Domoticz.Debug("No heating requested !")

 ##Modification jakenl##

            now = datetime.now()
            self.nextcalc = now + timedelta(minutes= 0.5 * self.calculate_period)
            self.WriteLog("Next calculation time will be half the calculation period of " + str(self.calculate_period) + " minutes: " + str(self.nextcalc), "Verbose")

The modified ConstC and ConstT calculation based on the above described function:

    def AutoCallib(self):

        now = datetime.now()
        if self.Internals['ALStatus'] != 1:  # not initalized... do nothing
            Domoticz.Debug("Fist pass at AutoCallib... no callibration")
            pass
        elif self.Internals['LastPwr'] == 0:  # heater was off last time, do nothing
            Domoticz.Debug("Last power was zero... no callibration")
            pass
        elif self.Internals['LastPwr'] == 100 and self.intemp < self.Internals['LastSetPoint']:
            # heater was on max but setpoint was not reached... no learning
            Domoticz.Debug("Last power was 100% but setpoint not reached... no callibration")
            pass
#$ Modification jakenl (learn ConstT, than 'if' the constC with 1 indentation instead of 'elif' on the same level##
        else:
            if (self.outtemp is not None and self.Internals['LastOutT'] is not None) and \
                     self.Internals['LastSetPoint'] > self.Internals['LastOutT']:
                self.WriteLog("Temperatures: Last Inside = {} / Last Outside = {} and Last Power = {}".format(self.Internals['LastInT'], self.Internals['LastOutT'], self.Internals['LastPwr']), "Verbose")
                # learning ConstT
                # ConstT calculation: calculate ConstT value assuming that the reached 'intemp' was the requested setpoint, based on LastPwr. 
                    #Use the heating calculation formula (deltaT in * ConstC + deltaT out * ConstT= Power)
                    #ConstT = (Power - (intemp - last intemp) * ConstC) / (intemp - last outtemp) (length of calculation cycle correction not necessary anymore)
                ConstT = ((self.Internals['LastPwr'] - (self.intemp - self.Internals['LastInT']) * self.Internals['ConstC']) /
                                                        (self.intemp - self.Internals['LastOutT']))
                self.WriteLog("New calc for ConstT = {}".format(ConstT), "Verbose")
                self.Internals['ConstT'] = round((self.Internals['ConstT'] * self.Internals['nbCT'] + ConstT) /
                                                 (self.Internals['nbCT'] + 1), 3)
                self.Internals['nbCT'] = min(self.Internals['nbCT'] + 1, 25) ### 50 --> 25
                self.WriteLog("ConstT updated to {}".format(self.Internals['ConstT']), "Verbose")
            if self.intemp > self.Internals['LastInT'] and self.Internals['LastSetPoint'] > self.Internals['LastInT']: #when the reached intemp > started intemp AND the setpoint was higher than intemp at start of the heating cycle
                # learning ConstC
                ConstC = (self.Internals['ConstC'] * ((self.Internals['LastSetPoint'] - self.Internals['LastInT']) /
                                                      (self.intemp - self.Internals['LastInT']) *
                                                      (timedelta.total_seconds(now - self.lastcalc) /
                                                       (self.calculate_period * 60))))
                self.WriteLog("New calc for ConstC = {}".format(ConstC), "Verbose")
                self.Internals['ConstC'] = round((self.Internals['ConstC'] * self.Internals['nbCC'] + ConstC) /
                                                 (self.Internals['nbCC'] + 1), 3)
                self.Internals['nbCC'] = min(self.Internals['nbCC'] + 1, 25)
                self.WriteLog("ConstC updated to {}".format(self.Internals['ConstC']), "Verbose")
        #below script moved to top
        #elif (self.outtemp is not None and self.Internals['LastOutT'] is not None) and \
        #         self.Internals['LastSetPoint'] > self.Internals['LastOutT']:
            # learning ConstT
            #ConstT = (self.Internals['ConstT'] + ((self.Internals['LastSetPoint'] - self.intemp) /
            #                                      (self.Internals['LastSetPoint'] - self.Internals['LastOutT']) *
            #                                      self.Internals['ConstC'] *
            #                                      (timedelta.total_seconds(now - self.lastcalc) /
            #                                      (self.calculate_period * 60))

    def switchHeat(self, switch):
pcdahle commented 6 months ago

Thanks for sharing this. Let's see if we all together can work out a even better algorithm here.

A couple of comments/questions:

I can see your change of implementation of ConstT based on LastPwr.

Calculation of ConstC is identical to original code, but you stated above "With the reached temperature, you can calculate what the ConstC should have been to reach that! temperature."

For info I have experimented by capping the ConstC to 250 so that no value higher than 250 can go into the filtered ConstC. Incidently I made this change exactly when the weather shifted and temperature is now so high so the house doesn't really require the electrical heating anymore, so I cannot see the effects yet...

@999LV do you have any comments on this zero-denominator topic?