Joining the Renewable Heating Hub forums is completely free and only takes a minute. By registering you’ll be able to ask questions, join discussions, follow topics you’re interested in, bookmark useful threads and receive notifications when someone replies. Non-registered members also do not have access to our AI features. When choosing your username, please note that it cannot be changed later, so we recommend avoiding brand or product names. Before registering, please take a moment to read the Forum Rules & Terms of Use so we can keep the community helpful, respectful and informative for everyone. Thanks for joining!
Connecting Home Assistant to a Midea Heat Pump
NOTE: This is the renamed continuation of Connecting to Midea MSmartHome using a PC
Midea 14kW (for now...) ASHP heating both building and DHW
Posted by: @cathoderayNOTE: This is the renamed continuation of Connecting to Midea MSmartHome using a PC
Having possibly increased the size of the body type from *18 to *25, it may be useful to try adding bytes 23, 24 and 25, to see if the body type has actually been increased.
@derek-m - I don't think it has, recall I checked the actual message length after making the change from *18 to *25, and it stayed exactly the same (see post here).
Meanwhile I am still struggling to get my data back. Like last time, it is still present, but corrupted, and HA refuses to use it.
Midea 14kW (for now...) ASHP heating both building and DHW
Posted by: @cathoderay@derek-m - I don't think it has, recall I checked the actual message length after making the change from *18 to *25, and it stayed exactly the same (see post here).
Meanwhile I am still struggling to get my data back. Like last time, it is still present, but corrupted, and HA refuses to use it.
When you checked the message length, did you add additional items to the requested list? If not it could be just supplying the requested items and have the capability of providing more.
Posted by: @derek-mWhen you checked the message length, did you add additional items to the requested list? If not it could be just supplying the requested items and have the capability of providing more.
I don't think I did, but can't remember for sure. But by the apparent logic of the code (we may of course be wrong about that), *25 should produce a byte array of 25 bytes, and what I would expect to see is a message string longer by 25-18 = 7 bytes, with the added bytes remaining as 00. I am reluctant to add the higher data_offset numbers because in the past doing so has always broken the code (it fails to load).
Possible explanations for observed behaviour:
(a) although it looks as though it might, ''return bytearray([0x00] * 25)" doesn't in fact set up a byte array of 25 bytes. However, some clearer than usual python documentation does appear to suggest that bytearray(n) where n is an integer does create a byte array of size n, all items in the array initialised to null (in plain English, it creates an egg box for n eggs, but with no eggs in it):
Syntax:
bytearray(source, encoding, errors)
Parameters:
source[optional]: Initializes the array of bytes
encoding[optional]: Encoding of the string
errors[optional]: Takes action when encoding fails
If source is an integer, creates an array of that size and initialized with null bytes.
# size of array
size = 3
# will create an array of given size and initialize with null bytes
array1 = bytearray(size)
print(array1)
Output:
bytearray(b'\x00\x00\x00') <= suggests the *25 should produce a byte array of \x00 x 25
(source) <=link)
I wonder, is there a clue in 'bytearray([0x00] * 25)' rather than just 'bytearray(25)'?
(b) "'return bytearray([0x00] * 25)" does initialise a byte array of 25 bytes, but it is only part of he code that does so, ie there is something else involved that we have missed.
Midea 14kW (for now...) ASHP heating both building and DHW
I have been doing some further investigation into the structure of the message body with the following results. The actual length of the whole message, header + body, is actually shown within the header at byte position 2. Looking at a recent message header gives the following:-
aa23c300000000000003
aa is a standard flag, probably used to indicate that it is the header.
23 is the total message length, header + body, which in decimal is 35. Since the header is always 10 bytes, then the message body must be 25.
As a test, reset the * 25 back to * 18, to see if the 23 changes to 1c. If the value does not change then this would indicate that the message length is being set elsewhere.
I can check that by looking at old logs (I have kept some) the header stays the same, always aa23c300000000000003, before and after changing from * 18 to * 25.
While I had core/message.py open (to check current value, it is still 25), I noticed this a few lines above the * 25 line:
@property
def _body(self):
raise NotImplementedError
...
@property
def _body(self):
return bytearray([0x00] * 25) # was 18
Apparently "raise NotImplementedError" is python for "To Do", a sort of place holder. Presumably it is overridden by the later code...
I did a "find in files" for "def _body(" crops up in the device message.py files in multiple places, including this last mention in c3/message.py (still has your suggested additions):
@property
def _body(self):
# Byte 1
zone1_power = 0x01 if self.zone1_power else 0x00
zone2_power = 0x02 if self.zone2_power else 0x00
dhw_power = 0x04 if self.dhw_power else 0x00
# Byte 7
zone1_curve = 0x01 if self.zone1_curve else 0x00
zone2_curve = 0x02 if self.zone2_curve else 0x00
disinfect = 0x04 if self.disinfect else 0x00
fast_dhw = 0x08 if self.fast_dhw else 0x00
room_target_temp = int(self.room_target_temp * 2)
zone1_target_temp = int(self.zone_target_temp[0])
zone2_target_temp = int(self.zone_target_temp[1])
dhw_target_temp = int(self.dhw_target_temp)
outdoor_temperature = int(self.outdoor_temperature) # Add
return bytearray([
zone1_power | zone2_power | dhw_power,
self.mode, zone1_target_temp, zone2_target_temp,
dhw_target_temp, room_target_temp, outdoor_temperature, # Add
zone1_curve | zone2_curve | disinfect | fast_dhw
])
Presumably as it is the last mention, at least in this file, it is the one that gets implemented.
Midea 14kW (for now...) ASHP heating both building and DHW
I have also been trying to figure out where the message type, and hence structure is being selected within the code.
Looking at the header for a type 04 message gives the following:-
aab9c300000000000004
The total message length is shown as b9 (185 bytes), which is indeed correct for the message received. So it would appear that the length of the message body can indeed be changed.
This now bring us to the actual structure of the message body, and whether and/or how it can be changed.
As you have already discovered, MessageType 0x03 initiates the query instruction, where the Python software sends a message to the Midea Controller, instructing it to send data by return. On the other hand the MessageType 0x04, labelled notify1, instructs the Python software to listen for any messages sent out by the Midea Controller, and take a copy of the message.
I have just received your post about message length, which would indicate that the body length is being set elsewhere, either being set by the body_type selection of 0x01 within midea/devices/C3/message.py, or it may even be fixed within the Midea Controller. If it is the latter then it may not be possible to add additional data to that already being obtained.
What we need to establish is where the structure of the different body_type's is being produce, is it coded within the Midea Controller and merely being selected by the Python software, or is it being selected from a list stored elsewhere.
As a test you could try changing the body_type 0x01 some other value. This would need to be done within the code shown below.
midea_ac_lan/custom_components/midea_ac_lan/midea/devices/c3/message.py
class MessageQuery(MessageC3Base):
def __init__(self, device_protocol_version):
super().__init__(
device_protocol_version=device_protocol_version,
message_type=MessageType.query,
body_type=0x01)
class MessageC3Response(MessageResponse):
def __init__(self, message):
super().__init__(message)
body = message[self.HEADER_LENGTH: -1]
if (self._message_type in [MessageType.notify1, MessageType.query] and self._body_type == 0x01) or \
self._message_type == MessageType.notify2:
self._body = C3MessageBody(body, data_offset=1)
self.set_attr()
Even if you do not receive the message body, if the header is produced it may provide some useful information.
When you first discovered the type 04, notify1 message, was the data obtained as provided by recent messages, or did you manage to obtain additional data be modifying the Python code?
@derek-m - that all makes sense, and I think these two (ignore the NotImplementedError) in c3/message.py are indeed where the types given in the full message are set:
class MessageC3Base(MessageRequest):
def __init__(self, device_protocol_version, message_type, body_type):
super().__init__(
device_protocol_version=device_protocol_version,
device_type=0xC3, <= hard wired, because this is a c3 unit
message_type=message_type,
body_type=body_type
)
@property
def _body(self):
raise NotImplementedError
class MessageQuery(MessageC3Base):
def __init__(self, device_protocol_version):
super().__init__(
device_protocol_version=device_protocol_version,
message_type=MessageType.query, <= gets the query message tyoe number from core.message.py
body_type=0x01) <= hard wired
I will try your suggestion, and see what happens.
The class MessageC3Response(MessageResponse) class you show above is not my current version (which you do have, sent as part of recent attachments), my current one looks like this:
class MessageC3Response(MessageResponse):
def __init__(self, message):
super().__init__(message)
body = message[self.HEADER_LENGTH: -1]
if (self._message_type in [MessageType.notify1, MessageType.query] and self._body_type == 0x01) or \
self._message_type == MessageType.notify2:
self._body = C3MessageBody(body, data_offset=1)
elif self._message_type == MessageType.notify1 and self._body_type == 0x04:
self._body = C3Notify1MessageBody(body, data_offset=1)
elif self._message_type == MessageType.notify2 and self._body_type == 0x05:
self._body = C3Notify2MessageBody(body, data_offset=1)
self.set_attr()
Midea 14kW (for now...) ASHP heating both building and DHW
Posted by: @derek-mWhen you first discovered the type 04, notify1 message, was the data obtained as provided by recent messages, or did you manage to obtain additional data be modifying the Python code?
In effect yes, I added code (the key bits are in c3/message.py, with other necessary definitions in midea_devices.py and c3/device.py) and got the byte_09 to byte_16 data, and by deduction worked out byte_09 was almost certainly ambient temp, and byte_14 current set (not actual) LWT.
Midea 14kW (for now...) ASHP heating both building and DHW
Posted by: @cathoderayPosted by: @derek-mWhen you first discovered the type 04, notify1 message, was the data obtained as provided by recent messages, or did you manage to obtain additional data be modifying the Python code?
In effect yes, I added code (the key bits are in c3/message.py, with other necessary definitions in midea_devices.py and c3/device.py) and got the byte_09 to byte_16 data, and by deduction worked out byte_09 was almost certainly ambient temp, and byte_14 current set (not actual) LWT.
What happens if you add byte_17 to byte_25?
- 26 Forums
- 2,607 Topics
- 60.8 K Posts
- 224 Online
- 6,967 Members
Join Us!
Worth Watching
Latest Posts
-
RE: Renewables & Heat Pumps in the News
@editor, I hear that too. I can confirm that out of ...
By ASHP-BOBBA , 4 hours ago
-
End-of-Life Heat Pumps: How Do You Dispose of an ASHP in the UK?
As many of you know, our Global Energy Systems heat pum...
By Mars , 4 hours ago
-
@derbygraham fully agree with James, and it’d be good t...
By Mars , 4 hours ago
-
RE: Indevolt Batteries UK Support & Info Thread
Finally got around to installing and setting up the Sol...
By Mars , 5 hours ago
-
Unfortunately its a function of the physics. Max heat ...
By JamesPa , 6 hours ago
-
RE: Microbore heat pump installs
In principle you are almost certainly right, but in pra...
By JamesPa , 6 hours ago
-
RE: Electricity price predictions
@old_scientist We are a low mileage home, so bulk of ou...
By ChandyKris , 7 hours ago
-
There are just too many unknowns for me to comment on p...
By Transparent , 9 hours ago
-
RE: What is the main ‘dictator’ of Agile’s unit price?
@toodles I keep an eye on wholesale prices and energy m...
By ChandyKris , 9 hours ago
-
RE: Brand and installer questions for ASHP
Strange, perhaps it doesnt use modbus which the third p...
By JamesPa , 11 hours ago
-
RE: Upgrading my system, how far do I go?
For comparison, my PW3 with 11.04kW inverter, will char...
By Old_Scientist , 14 hours ago
-
RE: Changes to Tesla Powerwall Charging Regime?
Elon gate - legendary! I take my hat off to you @toodle...
By Old_Scientist , 17 hours ago
-
RE: Mitsubishi Ecodan not good enough ?
Thanks @goody, appreciate the feedback and sorry you ha...
By marcexec , 1 day ago
-
RE: Minimum and Zero Disrupt Heat Pump Installations
True (first sentence) Thats the reason to consider th...
By JamesPa , 2 days ago
-
RE: High air source heat pump running costs – Vaillant AroTherm Plus
Quite right. I was using a rough guesstimate of doublin...
By Majordennisbloodnok , 2 days ago
-
RE: My Grant R290 9kW Heat Pump Installation
Again, really don't know how accurate this is! &nb...
By petch , 2 days ago
-
RE: MCS Quality Audit – Has Anyone Had One? Did It Lead to Remediation?
@toodles The whole scheme is a shocking waste of money....
By Papahuhu , 2 days ago
-
RE: Anyone concerned about GivEnergy?
Many thanks for your, and the subsequent, answers tk qu...
By KevH , 2 days ago
-
RE: DIY or Don’t Touch? Solarman Smart Meter Install
Yes, and these guys would probably be my preferred inst...
By Batpred , 2 days ago
-
RE: Hot water tank lose heat rapidly on random days
@jamespa Hopefully their reasons are well intended! ...
By Bash , 3 days ago
-
RE: Ecoflow UK Support & Info Thread
As mentioned above, we’ve got our full review of the Ec...
By Mars , 3 days ago
-
RE: Say hello and introduce yourself
@sonosppp welcome to the forums. I see you've posted in...
By Mars , 3 days ago
-
RE: Guidance with installing a new heating system
@bobflux Great, thanks for the advice. The pipe has an ...
By Hamilton , 4 days ago
-
RE: Daikin Altherma 3 LT compressor longevity question
@optimistic-optimiser I have has a Daikin for a few yea...
By madsid , 4 days ago
-
RE: UK DIY Battery: SEPLOS 48V 200Ah x2 + Sunsynk 8K – Safe Installation for Garage Conversion
The rule of thumb is to ensure that you can isolate any...
By Transparent , 4 days ago


