Adding auto-adaptio...
 
Notifications
Clear all

Adding auto-adaption to a Midea heat pump controller

13 Posts
2 Users
1 Reactions
425 Views
cathodeRay
(@cathoderay)
Famed Member Moderator
6888 kWhs
Joined: 2 years ago
Posts: 1390
Topic starter  

I'm starting a new thread for this, because although it has come up in many other threads, there isn't a dedicated thread for the topic yet. By auto-adaption I mean a way of controlling the heat pump that uses more than just OAT (outside air temp) to set the heat pump output, with a view to getting tighter control of the IAT (indoor air temp) in varying conditions that may arise for whatever reason, be it from solar gain to an overnight setback. I will be doing it over modbus, and the principles if not the details should apply to any heat pump that can be monitored and controlled over modbus. It may well be that I am in effect trying to do a DIY attempt at Mitsubishi's auto-adaption, or Homely's control systems, but I have nothing to do with either of those capers, even if my objectives are broadly similar.

I am going to start with the idea that all the many factors that affect the IAT can be summarised in one proxy variable, the difference between the actual IAT (aIAT) and the desired IAT (dIAT). If the aIAT is above the dIAT, then the sum of all the factors heating and cooling the house add up to more heat is being added, or less heat is being lost, than is needed, and vice versa when the aIAT is below the dIAT. This approach greatly simplifies things. I don't need to know what the factors are, let alone measure them, instead, I just monitor the end result, the aIAT, and compare it to the dIAT. I can then adjust the one thing in all the factors that I can adjust, the ends of the weather compensation curve, which can be done over modbus, with a view to moving the aIAT towards the dIAT.

At the moment, there is not a lot going on weatherwise, still relatively mild, with an OAT of arounf 10-12 degrees C, and my aIAT is just a bit above the dIAT of 19 degrees. Here is the chart for the last week, with some other variable also plotted: 

image

 

BTB - emoncms, please note how everything needed to make sense of the chart is on or by the chart.

This chart suggests that, for the prevailing conditions, my WCC (weather compensation curve) is just a little too high. However, I can't tweak the middle of the WCC (which is where we are with the prevailing conditions), only the ends. The 'curve' is in fact, according to the Midea literature, a stepped linear line from the left hand to the right hand end, meaning I will have to adjust the ends. I am going to run this timed python script (the logic should be easily grasped) and see what happens, but before I press the red button (run it in the real world), does anyone have any comments?

import minimalmodbus
import serial
from datetime import datetime
import schedule
import time
import os
import sys

# I think these are needed to keep things running smoothly...
os.fork() and sys.exit()

# set up the wired controller connection
instrument = minimalmodbus.Instrument('/dev/ttyUSB0', 1)  
instrument.serial.port  
instrument.serial.baudrate = 9600         
instrument.serial.bytesize = 8
instrument.serial.parity   = serial.PARITY_NONE
instrument.serial.stopbits = 1
instrument.mode = minimalmodbus.MODE_RTU

# set up the aIAT sensor connection (uses the same serial settings as above)
instrument_MD02 = minimalmodbus.Instrument('/dev/ttyUSB0', 3)
instrument_MD02.mode = minimalmodbus.MODE_RTU

# set the desired IAT
dIAT = 19

def 15minCheck():

    # get a datetime for logging
    now = datetime.now()
    now = now.strftime("%Y-%m-%dT%H:%M:%S")
    
    # get the aIAT (it is reported as x 10, ie 12.6 as 126 so need to divide by 10)
    IAT = instrument_MD02.read_register(1, 0, 4)/10

    # compare the aIAT to the dIAT and set (or don't set) the ends of the WCC accordingly
    if aIAT - dIAT > 1:     # house is too warm, lower ends of WCC by 1 degree C
        instrument.write_register(265, instrument.read_register(265, 0) - 1, 0)  
        instrument.write_register(266. instrument.read_register(266, 0) - 1, 0)
        with open('./modbus/auto_adjust_log.csv', 'a') as f:
            f.write(f'\n{now},{aIAT - dIAT},-1') 

    elif aIAT - dIAT < 1:     # house is too cool, increase ends of WCC by 1 degree C
        instrument.write_register(256, instrument.read_register(265, 0) + 1, 0)  
        instrument.write_register(266, instrument.read_register(266, 0) + 1, 0) 
        with open('./modbus/auto_adjust_log.csv', 'a') as f:
            f.write(f'\n{now},{aIAT - dIAT},+1')

    else:      # house is close to where it should be, do nothing except logging this
        with open('./modbus/auto_adjust_log.csv', 'a') as f:
            f.write(f'\n{now},{aIAT - dIAT},0')
 
# do the check every 15 mins
schedule.every(15).minutes.do(15minCheck)

while True:
    schedule.run_pending()
    time.sleep(1)

 

      

This topic was modified 7 months ago 3 times by cathodeRay

Midea 14kW (for now...) ASHP heating both building and DHW


   
Quote
cathodeRay
(@cathoderay)
Famed Member Moderator
6888 kWhs
Joined: 2 years ago
Posts: 1390
Topic starter  

Spotted some typos, hence the three edits for the OP. There may be others...

Midea 14kW (for now...) ASHP heating both building and DHW


   
ReplyQuote
(@derek-m)
Illustrious Member Moderator
13705 kWhs
Veteran Expert
Joined: 3 years ago
Posts: 4163
 

Posted by: @cathoderay

I'm starting a new thread for this, because although it has come up in many other threads, there isn't a dedicated thread for the topic yet. By auto-adaption I mean a way of controlling the heat pump that uses more than just OAT (outside air temp) to set the heat pump output, with a view to getting tighter control of the IAT (indoor air temp) in varying conditions that may arise for whatever reason, be it from solar gain to an overnight setback. I will be doing it over modbus, and the principles if not the details should apply to any heat pump that can be monitored and controlled over modbus. It may well be that I am in effect trying to do a DIY attempt at Mitsubishi's auto-adaption, or Homely's control systems, but I have nothing to do with either of those capers, even if my objectives are broadly similar.

I am going to start with the idea that all the many factors that affect the IAT can be summarised in one proxy variable, the difference between the actual IAT (aIAT) and the desired IAT (dIAT). If the aIAT is above the dIAT, then the sum of all the factors heating and cooling the house add up to more heat is being added, or less heat is being lost, than is needed, and vice versa when the aIAT is below the dIAT. This approach greatly simplifies things. I don't need to know what the factors are, let alone measure them, instead, I just monitor the end result, the aIAT, and compare it to the dIAT. I can then adjust the one thing in all the factors that I can adjust, the ends of the weather compensation curve, which can be done over modbus, with a view to moving the aIAT towards the dIAT.

At the moment, there is not a lot going on weatherwise, still relatively mild, with an OAT of arounf 10-12 degrees C, and my aIAT is just a bit above the dIAT of 19 degrees. Here is the chart for the last week, with some other variable also plotted: 

image

 

BTB - emoncms, please note how everything needed to make sense of the chart is on or by the chart.

This chart suggests that, for the prevailing conditions, my WCC (weather compensation curve) is just a little too high. However, I can't tweak the middle of the WCC (which is where we are with the prevailing conditions), only the ends. The 'curve' is in fact, according to the Midea literature, a stepped linear line from the left hand to the right hand end, meaning I will have to adjust the ends. I am going to run this timed python script (the logic should be easily grasped) and see what happens, but before I press the red button (run it in the real world), does anyone have any comments?

import minimalmodbus
import serial
from datetime import datetime
import schedule
import time
import os
import sys

# I think these are needed to keep things running smoothly...
os.fork() and sys.exit()

# set up the wired controller connection
instrument = minimalmodbus.Instrument('/dev/ttyUSB0', 1)  
instrument.serial.port  
instrument.serial.baudrate = 9600         
instrument.serial.bytesize = 8
instrument.serial.parity   = serial.PARITY_NONE
instrument.serial.stopbits = 1
instrument.mode = minimalmodbus.MODE_RTU

# set up the aIAT sensor connection (uses the same serial settings as above)
instrument_MD02 = minimalmodbus.Instrument('/dev/ttyUSB0', 3)
instrument_MD02.mode = minimalmodbus.MODE_RTU

# set the desired IAT
dIAT = 19

def 15minCheck():

    # get a datetime for logging
    now = datetime.now()
    now = now.strftime("%Y-%m-%dT%H:%M:%S")
    
    # get the aIAT (it is reported as x 10, ie 12.6 as 126 so need to divide by 10)
    IAT = instrument_MD02.read_register(1, 0, 4)/10

    # compare the aIAT to the dIAT and set (or don't set) the ends of the WCC accordingly
    if aIAT - dIAT > 1:     # house is too warm, lower ends of WCC by 1 degree C
        instrument.write_register(265, instrument.read_register(265, 0) - 1, 0)  
        instrument.write_register(266. instrument.read_register(266, 0) - 1, 0)
        with open('./modbus/auto_adjust_log.csv', 'a') as f:
            f.write(f'\n{now},{aIAT - dIAT},-1') 

    elif aIAT - dIAT < 1:     # house is too cool, increase ends of WCC by 1 degree C
        instrument.write_register(256, instrument.read_register(265, 0) + 1, 0)  
        instrument.write_register(266, instrument.read_register(266, 0) + 1, 0) 
        with open('./modbus/auto_adjust_log.csv', 'a') as f:
            f.write(f'\n{now},{aIAT - dIAT},+1')

    else:      # house is close to where it should be, do nothing except logging this
        with open('./modbus/auto_adjust_log.csv', 'a') as f:
            f.write(f'\n{now},{aIAT - dIAT},0')
 
# do the check every 15 mins
schedule.every(15).minutes.do(15minCheck)

while True:
    schedule.run_pending()
    time.sleep(1)

 

      

Hi Ray,

Looking at your code, I suspect that it will continually ramp up or down the WC curve, at a rate of 1C every 15 minutes, until the limits of adjustment are reached.

You may remember that I provided suitable code some time ago, which also allows for fine tuning of the system response.

 


   
ReplyQuote
cathodeRay
(@cathoderay)
Famed Member Moderator
6888 kWhs
Joined: 2 years ago
Posts: 1390
Topic starter  

Posted by: @derek-m

Looking at your code, I suspect that it will continually ramp up or down the WC curve, at a rate of 1C every 15 minutes, until the limits of adjustment are reached.

Good point - that's why I posted the code before running it, greater minds than mine can see the cracks and flaws. Maybe the key thing here is the check interval, needs to be long enough to allow things to change? Or make the increment smaller? Or factor in the rate and direction of change in the aIAT - dIAT, eg if it was 1.5 degrees 15 mins ago and is 1.2 degrees now, then you don't need to change the current WCC ends? The previous and current difference can be stored and compared as variables easily enough.  

Posted by: @derek-m

You may remember that I provided suitable code some time ago, which also allows for fine tuning of the system response.

I do, but I am trying to start simple, and only add complexity when necessary. Even the above suggestion of monitoring the rate and direction of change in the aIAT/dIAT difference only needs simple code... 

  

Midea 14kW (for now...) ASHP heating both building and DHW


   
ReplyQuote
(@derek-m)
Illustrious Member Moderator
13705 kWhs
Veteran Expert
Joined: 3 years ago
Posts: 4163
 

@cathoderay

The code that I provided was actually very simple compared to the equations used within industrial controllers.

I appreciate that you wish to do your own thing, so I will just point out the issues of which you should be aware.

1) The system response will vary quite dramatically from mild weather to cold weather.

2) Your proposed 'Proportional only' control should help reduce the difference between aIAT and dIAT, but may not reduce it to zero.

3) The thermal mass of your home will affect the response of the system.

4) The siting of the room temperature sensor is important for correct control response.


   
ReplyQuote
cathodeRay
(@cathoderay)
Famed Member Moderator
6888 kWhs
Joined: 2 years ago
Posts: 1390
Topic starter  

Perhaps I am already over-complicating things. I certainly don't want an uncontrolled positive feedback loop that melts down my heat pump... 

image

 

Maybe start with static LWTs for the WCC ends, rather than get the current value and add 1 to that, which is what creates the positive feedback loop. For example, if I know that 58/33 degrees LWT for the left hand and right hand ends are generally about right, then the code becomes something like this:

if aIAT - dIAT > 1:     # house is too warm, lower ends of WCC by 1 degree C
     instrument.write_register(265, 57, 0)  
     instrument.write_register(266, 32, 0)

# and possibly add

if aIAT - dIAT > 2:     # house is too warm, lower ends of WCC by 2 degrees C
     instrument.write_register(265, 56, 0)  
     instrument.write_register(266, 31, 0)

 @derek - will respond to your latest comment in a moment.

 

Midea 14kW (for now...) ASHP heating both building and DHW


   
ReplyQuote



cathodeRay
(@cathoderay)
Famed Member Moderator
6888 kWhs
Joined: 2 years ago
Posts: 1390
Topic starter  

Posted by: @derek-m

The code that I provided was actually very simple compared to the equations used within industrial controllers.

I appreciate that you wish to do your own thing, so I will just point out the issues of which you should be aware.

1) The system response will vary quite dramatically from mild weather to cold weather.

2) Your proposed 'Proportional only' control should help reduce the difference between aIAT and dIAT, but may not reduce it to zero.

3) The thermal mass of your home will affect the response of the system.

4) The siting of the room temperature sensor is important for correct control response.

I agree your code is simple compared to that used in industrial controllers, but I am am trying to set up the simplest code that can achieve my aims, and still be easily understood and managed. Your code is helpful, though, it helps me think about what i am trying to do.

On the numbered points:

(1) I am deliberately trying to bypass all those considerations, by looking at the net result, ie I do not need to know each and every factor, just what their net result is, as reflected in the difference between the aIAT and dIAT. A navigational analogy: I can work up my estimated position from all the factors I know about and then set my course from there, even though I still don't really know where I am, or alternatively I can fix my position, which is the net result of all the factors affecting my position, whether I know about them or not, and then set my course from there. My approach is the second approach. 

(2) I am not aiming for zero difference, I can, as implied in my code, live with one degree either side of the dIAT. 

(3) Agreed, but I am hoping I can take this into account by adjusting the time and degree increments by trial an error.

(4) It is sited in the NE corner of the dining room in the middle of the house, in a place where it will never receive direct sunlight, and well away from the radiator in the room. I'm hoping that is as neutral as can be, ie it will provide a reasonable estimate of room temp that is good enough for my purposes.   

Midea 14kW (for now...) ASHP heating both building and DHW


   
ReplyQuote
(@derek-m)
Illustrious Member Moderator
13705 kWhs
Veteran Expert
Joined: 3 years ago
Posts: 4163
 

@cathoderay

I will leave you to have fun working through the problems, but if you require any help then please feel free to ask.


   
ReplyQuote
cathodeRay
(@cathoderay)
Famed Member Moderator
6888 kWhs
Joined: 2 years ago
Posts: 1390
Topic starter  

Posted by: @derek-m

I will leave you to have fun working through the problems, but if you require any help then please feel free to ask.

Thanks, much appreciated. Naturally I am treading carefully, given I am new to controlling a heat pump using controls outside the heat pump controller, but in reality all I am trying to automate is the equivalent of me manually checking the room temp every now and then, and then manually adjusting the WCC settings, if need be. Put very simply, if the house is cold, ramp up the WCC a bit, and vice versa, with the increments determined by trial and error, otherwise do nothing.  

Midea 14kW (for now...) ASHP heating both building and DHW


   
ReplyQuote
cathodeRay
(@cathoderay)
Famed Member Moderator
6888 kWhs
Joined: 2 years ago
Posts: 1390
Topic starter  

Righty-ho, I have started with what i hope is the simplest way of automating changes to the WCC based on the difference between the aIAT and dIAT. The only change is a simple fixed change to the ends of the WCC, with no scope for a positive feedback loop. I have also increased the check interval to one hour. Code:

import minimalmodbus
import serial
from datetime import datetime
import schedule
import time
import os
import sys

# I think these are needed to keep things running smoothly...
os.fork() and sys.exit()

# set up the wired controller connection
instrument = minimalmodbus.Instrument('/dev/ttyUSB0', 1)  
instrument.serial.port  
instrument.serial.baudrate = 9600         
instrument.serial.bytesize = 8
instrument.serial.parity   = serial.PARITY_NONE
instrument.serial.stopbits = 1
instrument.mode = minimalmodbus.MODE_RTU

# set up the aIAT sensor connection (uses the same serial settings as above)
instrument_MD02 = minimalmodbus.Instrument('/dev/ttyUSB0', 3)
instrument_MD02.mode = minimalmodbus.MODE_RTU

# set the desired IAT
dIAT = 19

#baseline standard WCC is 58 left hand end / 33 right hand end

def hrCheck():

    # get a datetime for logging
    now = datetime.now()
    now = now.strftime("%Y-%m-%dT%H:%M:%S")
    
    # get the aIAT (it is reported as x 10, ie 12.6 as 126 so need to divide by 10)
    aIAT = instrument_MD02.read_register(1, 0, 4)/10

    # compare the aIAT to the dIAT and set (or don't set) the ends of the WCC accordingly
    if aIAT - dIAT > 1:     # house is too warm, lower ends of WCC by 1 degree C
        instrument.write_register(265, 57, 0)  
        instrument.write_register(266, 32, 0)
        with open('./modbus/auto_adjust_log.csv', 'a') as f:
            f.write(f'\n{now},{aIAT - dIAT},-1') 

    elif aIAT - dIAT < 1:     # house is too cool, increase ends of WCC by 1 degree C
        instrument.write_register(256, 59, 0)  
        instrument.write_register(266, 34, 0) 
        with open('./modbus/auto_adjust_log.csv', 'a') as f:
            f.write(f'\n{now},{aIAT - dIAT},+1')

    else:      # house is close to where it should be, do nothing except logging this
        with open('./modbus/auto_adjust_log.csv', 'a') as f:
            f.write(f'\n{now},{aIAT - dIAT},0')
        


# do the check every hour at 1m 30s past the hour (won't accept '00' for minutes)
schedule.every().hour.at("01:30").do(hrCheck)

while True:
    schedule.run_pending()
    time.sleep(1)

The MD02 sensor is currently showing 20.6 degrees C, meaning the above code should, if the IAT/MD02 temp stays above 20 degrees, lower the WCC by one degree at 1m 30s past 1900h. I will check the wired controller manually soon afterwards to see if it has.

1902h: an error in the code, aIAT not defined, corrected (here and on the headless PC) and script restarted...

This post was modified 7 months ago by cathodeRay

Midea 14kW (for now...) ASHP heating both building and DHW


   
ReplyQuote
cathodeRay
(@cathoderay)
Famed Member Moderator
6888 kWhs
Joined: 2 years ago
Posts: 1390
Topic starter  

2002h yesterday evening: got a no response error. Gave up for the day...

This morning I added a short sleep between the different instrument calls, to reduce so called bus collisions, and bingo! No errors at 08:01:30 and a log entry in auto_adjust_log.csv:

datetime,aIAT-dIAT,changeWCC
2023-10-30T08:01:30,1.39,-1 

ie datetime, house is 1.39 degrees C above desired IAT, WCC has had both ends lowered by 1 degree C. I've just checked manually on the wired controller, and it sure has had both ends lowered by 1 degree. Result!

Next step: go away and do something else, leaving the system and monitoring to do its thing, and then check back later to see what has happened.

Midea 14kW (for now...) ASHP heating both building and DHW


   
Derek M reacted
ReplyQuote
(@derek-m)
Illustrious Member Moderator
13705 kWhs
Veteran Expert
Joined: 3 years ago
Posts: 4163
 

@cathoderay

I am pleased to see that you are resisting the urge to 'tinker'. I think that you will find it could takes several hours for the IAT to reduce and stabilise.

One improvement that you may wish to consider is varying the offset dependent upon the size of the deviation.

Something along the lines of:-

If the deviation is <0.5C, do nothing.

If the deviation is =>0.5C, offset by 1C.

If the deviation is =>1.5C, offset by 2C.


   
ReplyQuote



Page 1 / 2
Share:

Join Us!

Latest Posts

Heat Pump Humour

Members Online

 No online members at the moment

x  Powerful Protection for WordPress, from Shield Security
This Site Is Protected By
Shield Security