Connecting to Midea...
 
Notifications
Clear all

Connecting to Midea MSmartHome using a PC

364 Posts
13 Users
22 Reactions
44.5 K Views
(@derek-m)
Illustrious Member Member
15283 kWhs
Veteran Expert
Joined: 4 years ago
Posts: 4429
 

Posted by: @cathoderay

@batalto - I agree with your observations, my level of understanding of code gets me that far, eg the len property/function. But why does it need to use the length of the string? Normally it would be something like if len > 0 then formula else zero etc. My guess on 0xff is it's the highest possible value, and so is being used as a switch (case) sort of thing, in this case to say the value is none (nothing). But it's the bizarre maths/operators that have really got me baffled.

Body is the message body, which arrives heavily encrypted, I think it is the strings I have posted previously. For example, a 50 character body string yields 25 name:value pairs in what may be json format.I can see code that does the encoding/encrypting and decoding decrypting, but can't make out what exactly it is doing. And still no hint of the way of working out what is where in the 'body', and how to process it to get the right numbers. Why can't outdoor temp in the above example just be the raw numbers? Split into integer/decimal if need be, so 11.24 arrives as 11 and 24, but no absurd encryption. This data is hardly the key to launching nuclear missiles!

That said, I have found a fork of the midea_ac_lan project that looks as though it has done a bit more. HA blew up when I tried to substitute it for the original midea_ac_lan code, I think too many names overlapped. I will have a clear out on HA and see if I can get it working. The fork has recent activity on it, I am hopeful I might be able to get all the key variables included, and then we will have the option of app independent data collection from our Midea controllers.

I don't think that the data is actually encrypted, more likely coded then decoded.

You need to be aware that the serial data transmission is actually performed as bits, 1's and 0's, high voltage and low voltage. End user's would not be too impressed if their computer screen just displayed a very long string of one's and zero's, so the information has to be displayed in a more acceptable format. Each character from the data stream that is display on your computer screen represent 4 bits, which allows 16 individual states to be encoded as shown below.

  8's      4's     2's     1's      0 to 10      0 to 15

bit 3   bit 2   bit 1   bit 0   Decimal   Hexadecimal

  0       0        0        0           0             0

  0       0        0        1           1             1

  0       0        1        0           2             2

  0       0        1        1           3             3

  0       1        0        0           4             4

  0       1        0        1           5             5

  0       1        1        0           6             6

  0       1        1        1           7             7

  1       0        0        0           8             8

  1       0        0        1           9             9

  1       0        1        0          10            A

  1       0        1        1          11            B

  1       1        0        0          12            C

  1       1        0        1          13            D

  1       1        1        0          14            E

  1       1        1        1          15            F

We are all used to counting in 10's using the decimal system, but for computers to count in 10's would require different voltage levels for each number from 0 to 9, and that is without considering the 26 alphabetic characters in lower case, the further 26 in upper case, and all the other characters used in normal correspondence. So computers use the binary system, 1's and 0's, high voltage and low voltage, though high voltage in this instance could be anything between 3.5 volts and 5 volts, and low voltage would be anything below 1 volt and above 0 volts.

In the early days of computing development it was realised that there needed to be a standard protocol, so the American Standard Code for Information Interchange (ASCII) was developed. But 4 bits of data did not allow for all the different characters, so the 8 bit, byte was utilised. 8 bits now allows from 0 to 255 unique characters to be identified, from just 8 bits of data.

The original ASCII Table covers 0 to 127, with an extended table going from 128 to 255. Examples are shown below.

Dec   Hex  Html   Char

 65     41  &#65    A

 97     61  &#97    a

If you are interested just Google ASCII Table.

So a system was developed to not only allow computers to communicate with each other in a standard format, but also those thick humans who insisted upon using the decimal counting system, and those other weird letters and symbols. Though to keep the humans happy, the computers had to code the data for human consumption and then decode it back again for computer use.

If you are still reading then you must be really interested. 🙄 

Computers count in binary, but 1 byte or 8 bits only allows for numbers from 0 to 255, or +/- 127 if the most significant bit is used to indicate the sign. Using two bytes allows for numbers up to +/- 32767, three bytes takes the number up to +/- 2,147,483,647, whilst 4 bytes gives a number big enough for me to not worry about, though I would not mind it being my bank account total, assuming that it is positive and not negative. 😋 

So I feel fairly confident that for most purposes computers will use 4 consecutive bytes when transmitting numbers, be that number 0 or 123456789.

To try to help answer some of CathodeRay's queries, it may be that integers or real numbers, are transmitted within the system with a fixed precision, such that a LWT of 52C would be transmitted using the binary equivalent of 520, whilst an outside air temperature reading of 10.9C, would be transmitted using the binary equivalent of 109. The receiving computer would be programmed to convert the binary number back to decimal, and then move the decimal point one place to the left. Conversely the data could contain characters which indicate that the following number is an integer, or it could indicate that the following number is real, and the level of precision to apply.

Alternatively the system could be programmed with which numbers are integers and which are real, and the level of precision to apply.

I would suggest trying to obtain a number of samples of data and carrying out a comparison of the differences, which may throw a little more light on the subject.

 

 


   
ReplyQuote
cathodeRay
(@cathoderay)
Famed Member Moderator
9921 kWhs
Joined: 3 years ago
Posts: 1997
Topic starter  

Posted by: @derek-m

If you are still reading then you must be really interested.

I certainly got this far, and to the end. What you have written is an exemplary description of the basics of computing. No need to google it, you have explained it very clearly.

I've done a fair bit more work on this but that blasted wordpress sentry thing won't let me post it, security risk blah blah blah. Will see how I can get past the frigging thing.

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


   
ReplyQuote
cathodeRay
(@cathoderay)
Famed Member Moderator
9921 kWhs
Joined: 3 years ago
Posts: 1997
Topic starter  

@derek - It looks like my post got blocked because it had python code in it, even though it was harmless code. Here is the post without the code, which has been replaced with pointers to where the code can be found in a downloaded copy of midea_ac_lan (link posted earlier to relevant github page). 

Apologies in advance for the length of this post, but I wanted to set down my findings and interpretations as completely as possible.
The reason I think (I may come to revise this to thought) there is encryption/decryption going on is twofold: firstly, others have commented on Midea absurdly excessive levels of security for what is at the end of the day not that sensitive data, and secondly there are very visible encode/encrypt and decode/decrypt functions in the python code. See, for example, the imports in security.py, and further down in the same file various encryption and decryption functions. There are also encode_8370 and decode_8370 functions, and, as I understand it, these functions are part of Midea's Protocol V3, which is used for these communications.

With debug logging enabled, midea_ac_lan logs the strings/messages it receives to the Home Assistant log. I've already posted some of these earlier, here are some more. This triplet is the 'out of the box' request, received message and 'decoded' message:

2023-01-18 19:28:17 DEBUG (Heat Pump Wi-Fi Controller) [custom_components.midea_ac_lan.midea.core.device] [redacted_id] Sending: {'header': 'aa0bc300000000000003', 'body': '01', 'message type': '03', 'body type': '01'}

2023-01-18 19:28:17 DEBUG (Heat Pump Wi-Fi Controller) [custom_components.midea_ac_lan.midea.devices.c3.device] [redacted_id] Received: {'header': 'aa23c300000000000003', 'body': '010d77910303231e323041231905371919053c223c142f0080', 'message type': '03', 'body type': '01'}

2023-01-18 19:28:17 DEBUG (Heat Pump Wi-Fi Controller) [custom_components.midea_ac_lan.midea.core.device] [redacted_id] Status update: {'zone1_power': True, 'zone2_power': False, 'dhw_power': True, 'disinfect': False, 'fast_dhw': False, 'zone_temp_type': [True, True], 'mode': 3, 'mode_auto': 3, 'zone_target_temp': [35, 30], 'dhw_target_temp': 50, 'room_target_temp': 24.0, 'zone_heating_temp_max': [65, 55], 'zone_heating_temp_min': [35, 25], 'zone_cooling_temp_max': [25, 25], 'zone_cooling_temp_min': [5, 5], 'room_temp_max': 30.0, 'room_temp_min': 17.0, 'dhw_temp_max': 60, 'dhw_temp_min': 20, 'tank_actual_temperature': 47, 'zone1_water_temp_mode': True, 'zone2_water_temp_mode': False, 'zone1_room_temp_mode': False, 'zone2_room_temp_mode': False}

In this triplet, the 50 character long received message 'body' gives rise to 24 name:value pairs in the 'Status update'. Why 24 not 25, 50/2 = 25 not 24? But there seems to be no pattern to the characters and name value pairs eg 'true' and 'false' appear a lot in the Status update, but I can't see a regular corresponding character pair in the message body. By the way, as far as I can tell, the decryption code gets called to operate on the message body, ie the string shown above is the encrypted version.

Here's another received message and status update (there's no 'Sending' log entry for this) :

2023-01-18 19:10:34 DEBUG (Heat Pump Wi-Fi Controller) [custom_components.midea_ac_lan.midea.devices.c3.device] [redacted_id] Received: {'header': 'aa23c300000000000003', 'body': '010d77910303231e323041231905371919053c223c14300080', 'message type': '03', 'body type': '01'}

2023-01-18 19:10:34 DEBUG (Heat Pump Wi-Fi Controller) [custom_components.midea_ac_lan.midea.core.device] [redacted_id] Status update: {'zone1_power': True, 'zone2_power': False, 'dhw_power': True, 'disinfect': False, 'fast_dhw': False, 'zone_temp_type': [True, True], 'mode': 3, 'mode_auto': 3, 'zone_target_temp': [35, 30], 'dhw_target_temp': 50, 'room_target_temp': 24.0, 'zone_heating_temp_max': [65, 55], 'zone_heating_temp_min': [35, 25], 'zone_cooling_temp_max': [25, 25], 'zone_cooling_temp_min': [5, 5], 'room_temp_max': 30.0, 'room_temp_min': 17.0, 'dhw_temp_max': 60, 'dhw_temp_min': 20, 'tank_actual_temperature': 48, 'zone1_water_temp_mode': True, 'zone2_water_temp_mode': False, 'zone1_room_temp_mode': False, 'zone2_room_temp_mode': False}

So far as I can see, the only difference in the Status update is the tank_actual_temperature value, it has gone from 47 to 48. The two message bodies are almost but not quite identical. See chars 5 and 6 in from the right hand end of the string:

010d77910303231e323041231905371919053c223c142f0080
010d77910303231e323041231905371919053c223c14300080
                                                                              

suggesting 2f = 47 and 30 = 48, which of course the do: 2f is hex for decimal 47 and 30 is hex for decimal 48, which suggests the message body may not be encrypted after all! Let's test a bit more: the two chars before 2f/30 are 14, that's hex for 20 decimal, and the value for the name:value pair before the tank temp is 20! Ditto for 3c and 60! But apart from that, it breaks down. Here's a table of all the message body pairs, the decimal equivalents, and the status update name: value pairs:

Hex Dec Status update name:value pairs
01 1 'zone1_power': True
0d 13 'zone2_power': False
77 119 'dhw_power': True
91 145 'disinfect': False
03 3 'fast_dhw': False
03 3 'zone_temp_type': [True, True]
23 35 'mode': 3
1e 30 'mode_auto': 3
32 50 'zone_target_temp': [35, 30]
30 48 'dhw_target_temp': 50
41 65 'room_target_temp': 24.0
23 35 'zone_heating_temp_max': [65, 55]
19 25 'zone_heating_temp_min': [35, 25]
05 5 'zone_cooling_temp_max': [25, 25]
37 55 'zone_cooling_temp_min': [5, 5]
19 25 'room_temp_max': 30.0
19 25 'room_temp_min': 17.0
05 5 'dhw_temp_max': 60
3c 60 'dhw_temp_min': 20
22 34 'tank_actual_temperature': 48
3c 60 'zone1_water_temp_mode': True
14 20 'zone2_water_temp_mode': False
30 48 'zone1_room_temp_mode': False
00 0 'zone2_room_temp_mode': False}
80 128

Now, in message.py we have for example:

self.tank_actual_temperature = body[data_offset + 21] and this almost makes sense, 30 hex/48 decimal is in position 22 (zero based counting), and 48 is the tank_actual_temperature value

and self.dhw_target_temp = body[data_offset + 7] and there is a 32 hex/50 decimal entry at position 8 (zero based counting), and 50 is the dhw_target_temp value

and self.room_temp_max = body[data_offset + 17] / 2 and there is 3c hex/60 decimal as position 18 (zero based counting), and 60/2 = 30, and 30 is the room_temp_max value

and then we have things like:
self.zone_heating_temp_max = [
body[data_offset + 9],
body[data_offset + 13]
]

and sure enough we have decimal 65 at position 10, and 55 decimal at position 14, and these are the correct zone_heating_temp_max values, 65 and 55
but then we have things like:

self.zone1_power = body[data_offset + 0] & 0x01 > 0
self.zone2_power = body[data_offset + 0] & 0x02 > 0

which become True and False respectively... & is a python bitwise operator 'used to compare binary numbers', and it 'sets each bit to 1 if both bits are 1'

Summary: there is some sort of order that doesn't quite make sense in places, but (a) what about the bits that don't make sense eg the +1 position offset, why some things need mathematical adjustment eg divide by 2 while others don't and (b) how on earth can you tell which bit of info is going to be in which position?

Lastly (keeping this for next time), this is only one message body type (0x01) that only contains one useful bit of info, the DHW tank temp, but there are other messages body types eg 0x04, which contains the Total energy consumed/produced, and presumably there are also messages with body types 0x02 and 0x03 which no doubt contain yet more data.

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


   
ReplyQuote
(@derek-m)
Illustrious Member Member
15283 kWhs
Veteran Expert
Joined: 4 years ago
Posts: 4429
 

@cathoderay

Thanks, that is quite interesting, and has revitalised the old 'grey matter' to times long ago when all this was second nature.

What are termed digital inputs, 1 or 0, true or false, would not be transmitted using a full byte for each (not efficient), but instead a byte would be used to transmit up to 8 individual parameter states. So 'zone1_power': True, 'zone2_power': False, 'dhw_power': True, 'disinfect': False, 'fast_dhw': False, 'zone_temp_type': [True, True] could be sent as the binary 01010011, with the most significant bit not being used since there are only 7 parameters. This would give the hexadecimal value 53, which does appear in the data string.

If you have the time, I would suggest that you change, within the controller, the relevant settings, one at a time, and see what is changed within the data string. That way you may be able to confirm the location of each parameter. You should even be able to locate the 'digital' parameters, by say changing 'dhw_power': True, to false, and see if the hex 53 changes to hex 43.


   
ReplyQuote
cathodeRay
(@cathoderay)
Famed Member Moderator
9921 kWhs
Joined: 3 years ago
Posts: 1997
Topic starter  

@derek-m - giving the old grey cells a work out is part of the reason why I do this stuff!

I will try changing some values in the wired controller and see how the string changes. The first obvious one is 'dhw_target_temp' which is very easily changed. I can also turn the DHW on and off, in Midea speak this is the same as turning an immersion heater on or off at the wall, ie it is capable of heating, but being 'on' doesn't mean it is actually heating the water, may not be because the water is already at temp, or a timer has the DHW off even though it is on (well at least that is nice and clear!) which should alter the binary/boolean item 'dhw_power' (it's currently true ie on because it is on, even though, because of the timer, it is off). I'll also see what other parameters I can change without upsetting the system too much. 

 

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


   
ReplyQuote
(@derek-m)
Illustrious Member Member
15283 kWhs
Veteran Expert
Joined: 4 years ago
Posts: 4429
 

Posted by: @cathoderay

@derek-m - giving the old grey cells a work out is part of the reason why I do this stuff!

I will try changing some values in the wired controller and see how the string changes. The first obvious one is 'dhw_target_temp' which is very easily changed. I can also turn the DHW on and off, in Midea speak this is the same as turning an immersion heater on or off at the wall, ie it is capable of heating, but being 'on' doesn't mean it is actually heating the water, may not be because the water is already at temp, or a timer has the DHW off even though it is on (well at least that is nice and clear!) which should alter the binary/boolean item 'dhw_power' (it's currently true ie on because it is on, even though, because of the timer, it is off). I'll also see what other parameters I can change without upsetting the system too much. 

 

I think that some of the other parameters are actually the high and low limit settings, so should be easy to change slightly, without causing any problems. Have you located the Cyclic Redundancy Check (CRC) which I believe is normally at the end of the transmission packet.

 


   
ReplyQuote



(@batalto)
Famed Member Member
3655 kWhs
Joined: 4 years ago
Posts: 1091
 

@cathoderay for someone who a few days ago saw this as an impossible challenge you seem to be getting into it!! All I can say is, I'm riding your genius here and willing you (and Derek) on. Interested to see where this is going and hoping you don't end up finding out the data is all crap at the end.

12kW Midea ASHP - 8.4kw solar - 29kWh batteries
262m2 house in Hampshire
Current weather compensation: 47@-2 and 31@17
My current performance can be found - HERE
Heat pump calculator spreadsheet - HERE


   
ReplyQuote
cathodeRay
(@cathoderay)
Famed Member Moderator
9921 kWhs
Joined: 3 years ago
Posts: 1997
Topic starter  

Posted by: @batalto

hoping you don't end up finding out the data is all crap at the end.

This is a real concern. Using this method rather than independent sensors is totally dependent on Midea getting their sensor data right, and furthermore not cooking it in any way behind the scenes. However, there are some things I can check independently without adding new hardware, including total power consumption, which I can already access in HA via midea_ac_lan, against what my dedicated heat pump meter shows, and ambient temp, not yet available via midea_ac_lan, but it should be there somewhere, against local independent weather reports. It will be interesting to see what effect normal heating running and defrost cycles have on the outdoor temperature.

@derek - I certainly wouldn't be able to do all this without your help, thank you so much. I've now seen changes to the DHW target temp change two chars in the string, ditto turning the DHW on and off. The message we have been looking at lately is of body type 01, and contains the 24 items listed above, only a few of which are of real interest. We also know about message body type 04 which contains among other things total energy consumed and produced (the latter is I think suspect, unfortunately suspect) but the debug logged response for body type 04 is less detailed, it only shows the data that will be used by midea_ac_lan, meaning I can't see what the other data might be. Here's an example:

2023-01-19 19:00:33 DEBUG (Heat Pump Wi-Fi Controller) [custom_components.midea_ac_lan.midea.devices.c3.device] [redacted_id] Received: {'header': 'aab9c300000000000004', 'body': '0401000020490000548003231e323033ff01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f3000000000000000000000000000000000014', 'message type': '04', 'body type': '04'}

2023-01-19 19:00:33 DEBUG (Heat Pump Wi-Fi Controller) [custom_components.midea_ac_lan.midea.core.device] [redacted_is] Status update: {'status_heating': True, 'status_dhw': False, 'status_tbh': False, 'status_ibh': False, 'total_energy_consumption': 8265, 'total_produced_energy': 21632}

Now, the curious thing is the code in midea_ac_lan uses bitwise operators to get from the string to the values, but in fact we already know the values are hiding in plain site as hex numbers. Energy consumption, 8265, is 2049 in hex, which is in the string starting at position 9, and energy produced, 21632, is 5480 hex, which there starting at position 18 (I wonder if the fact 18 is double 9 is significant?) - highlighted in bold below:

0401000020490000548003231e323033ff01000000000...     

Why all the fancy bitwise stuff when all you need is hex2dec? I have picked up each bitwise left shift is actually the same as multiplying by 2 (obvious when you think about it, dec 2 = binary 0010, left shift 1 gives 0100 which is dec 4) - so why not just multiply by 2? There seems to be an arcane belief computers work faster with binary numbers, but apparently that is now history. Are the bitwise operations essential (no other way of doing it) or are they instead something more awkward, like obfuscation?

In passing, these two decimal numbers 8265 and 21632 for energy consumed/produced give me a lifetime COP of 2.62, which I am strongly minded not to want to believe, which does rather call the numbers into question.

Another thing is the 0x04 string appears to have more data in it than appears to have been extracted - what is the other data? When I convert the other groups of four chars from hex to decimal, the decimal numbers don't jump out as being obviously this or that. For example, the 0323 after the 5480 is decimal 803 which is not an obvious value for this or that. And so on...    

Lastly, we have body types 0x01 and 0x04. Where and what are implied body types 0x02 and 0x03??? I haven't yet worked out how the call for body type 0x04 is initiated, and so can't tweak the code to call for 0x02/0x03 (and, for that matter 0x05 and so on).  

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


   
ReplyQuote
(@derek-m)
Illustrious Member Member
15283 kWhs
Veteran Expert
Joined: 4 years ago
Posts: 4429
 

@cathoderay

I commenced my foray into the delights of computers and computing when the normal CPU was deemed 8 bit, but the Address Bus and the Arithmetic and Logic Unit (ALU) were both 16 bit. At the time I believe that 4 bits were referred as a 'nibble', 8 bits became the ubiquitous 'byte', and I think that 16 bits were deemed a 'word'. Total memory was limited to 64kbytes, because of the size of the address bus, and the processor clock speed was 1 MHz.

Things have changed slightly since then, but the actually functional mode of operation is still the same.

To answer your question about 'so why not just multiply by 2'.

Computers only work in binary, and multiplying in binary is not that simple, whereas moving bits and adding them together is much easier.

Let's consider the first of the two number you mention, hex 2049 = dec 8265. In binary it is represented as 0010000001001001, but because Midea have deemed it necessary to use 4 bytes or 8 nibbles to transmit each integer, the actual representation in the data stream is hex 00002049, which in binary is 00000000000000000010000001001001. This is the actual format in which the number is transmitted. You might think, 'why bother transmitting all those leading zero's', since they are surplus to requirements, let's just transmit 10000001001001, since that string contains all the relevant information.

The problem occurs at the receiving computer, since it is expecting 32 bits and is only getting 14 bits. 'What has gone wrong' the receiving computer thinks to itself, 'is the sending computer having a bad day and can't count past 14', 'has there been a data transmission problem and some of the data has fallen into a black hole at the centre of the Galaxy', or it could just decide that the starting point for the data is correct, and include the following 18 bits from the data packet to produce the required 32 bits, thereby generating a total wrong number.

Like 'husbands', computers have to be given specific instructions by the 'controller'. ☹️ 

It is therefore important that the sending computer has been given specific instructions of how to construct the 'data packet', and that the receiving computer has been provided with the expected format, so that it can decipher the 'data packet'.

So when the receiving computer receives the binary string 00000000000000000010000001001001, it knows that to decipher, and present the number in a format that those 'thick human's' can understand, it must take the first 4 bits and present them in hexadecimal format, which produces 0. It then takes the next 4 bits which produces another 0. The next 4 bits, you've guessed it, gives a further 0, with a further 0 from the next 4 bits. This is getting boring thinks the computer, but wait is that a 1 in the next 4 bits? Yes it is, so the next 4 bits produce the hex value 2, but disappointment returns when the next 4 bits generate another 0. Excitement again when the next 4 bits produce a hex 4, and elation when the remaining 4 bits reveal a hex 9. The complete hex number is now revealed as 00002049, but by this time the computer is fed up with the inferiority of humans, and can't be bothered to further transpose the number from hex to dec.

Of course the receiving computer isn't really interested in decimal or even hexadecimal, it just takes the 32 bits and puts them in a designated memory location for possible use later.

It is difficult to fully decipher CathodeRay's data string 0401000020490000548003231e323033ff01000000000, but it is possible that the 0401 at the start indicates the format of the data being transmitted.

We know that the next section of the data words contains 2 integers, but it is unclear what follows. It is unlikely that this data is numbers, since they would be very large if the specified format is used.

The 03 could indicate boolean data or ASCII 03 = (end of text)

The 23 again could indicate boolean data or ASCII 23 = #

The 32 again could indicate boolean data or ASCII 32 = 2

The 30 again could indicate boolean data or ASCII 30 = 0

The 33 again could indicate boolean data or ASCII 33 = 3

The ff again could indicate boolean data or ASCII ff = (blank)?

The 01 again could indicate boolean data or ASCII 01 = (start of heading)

Perhaps the ##203 has some meaning?

Comparing different data streams may show some further structure, and possibly changing settings within the Midea controller may reveal their location within the data stream.


   
ReplyQuote
cathodeRay
(@cathoderay)
Famed Member Moderator
9921 kWhs
Joined: 3 years ago
Posts: 1997
Topic starter  

@derek-m - thanks again for a very clear explanation. I can see how left shifting binary numbers might be easier than multiplying, but that surely only covers x 2, x 4, x 8 etc, with no obvious way to multiply by 3 or even 2.5. 

I've changed a couple of setting in the wired controller (the easy ones) and got this via midea_ac_lan:

Changing one parameter at a time (bold = changed):

DHW On/Off
on 010d77910303231e323041231905371919053c223c142d0080
off 010977910303231e323041231905371919053c223c142d0080

DHW Set Temp
50 010d77910303231e323041231905371919053c223c142d0080
40 010d77910303231e283041231905371919053c223c142d0080
 

Rather unsurprisingly, 32 hex is 50 decimal and 28 hex is 40 decimal.

 In the meantime, I decided it might be worth having a look at the midea app files I downloaded from my not so smart phone to my PC. They are mostyly javascript files, and in messages.js I found this:

operationMode: r[3],
operationModeAuto: r[4],
zone1TempSet: parseInt(r[5]),
zone2TempSet: parseInt(r[6]),
DHWTempSet: parseInt(r[7]),
roomTempSet: parseInt(r[8]),
zone1HeatSetMax: parseInt(r[9]),
zone1HeatSetMin: parseInt(r[10]),
zone1CoolSetMax: parseInt(r[11]),
zone1CoolSetMin: parseInt(r[12]),
zone2HeatSetMax: parseInt(r[13]),
zone2HeatSetMin: parseInt(r[14]),
zone2CoolSetMax: parseInt(r[15]),
zone2CoolSetMin: parseInt(r[16]),
roomTempSetMax: parseInt(r[17]),
roomTempSetMin: parseInt(r[18]),
DHWTempSetMax: parseInt(r[19]),
DHWTempSetMin: parseInt(r[20]),
tankActualTemp: r[21],

In message.py in midea_ac_lan we have

 self.mode = body[data_offset + 3]
self.mode_auto = body[data_offset + 4]
self.zone_target_temp = [
body[data_offset + 5],
body[data_offset + 6]
]
self.dhw_target_temp = body[data_offset + 7]
self.room_target_temp = body[data_offset + 8] / 2
self.zone_heating_temp_max = [
body[data_offset + 9],
body[data_offset + 13]
]
self.zone_heating_temp_min = [
body[data_offset + 10],
body[data_offset + 14]
]
self.zone_cooling_temp_max = [
body[data_offset + 11],
body[data_offset + 15]
]
self.zone_cooling_temp_min = [
body[data_offset + 12],
body[data_offset + 16]
]
self.room_temp_max = body[data_offset + 17] / 2
self.room_temp_min = body[data_offset + 18] / 2
self.dhw_temp_max = body[data_offset + 19]
self.dhw_temp_min = body[data_offset + 20]
self.tank_actual_temperature = body[data_offset + 21]

and blow me down if the parameter offsets/positions are all the same, eg DHW set/target temp is at 7, DHW actual temp is at 21.

That's useful confirmation of a sort, but that's as far as it goes. Although the app displays things like ambient temp and energy consumed and produced, I can't for the like of me see how it gets or processes those other parameters from other messages. 

Nor does it throw much light on the location of say DHW Set Temp in the message body strings. In the above JS and python code it is at position/offset 7, but in the strings it seems to be further offset. Previously, we established that DHW tank actual temp is in chars 5 and 6 in from the right hand end of the string, but that seems to bear no relation to position/offset 21. The fact the DHW on/off changes the second pair also suggests those left hand chars contain data, not metadata about the message. As the plot thickens, so does my brain curdle...  

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


   
ReplyQuote
(@derek-m)
Illustrious Member Member
15283 kWhs
Veteran Expert
Joined: 4 years ago
Posts: 4429
 

Hi CathodeRay,

I have had to send this as a Word document as the 'website police' kept blocking it for some reason.


   
ReplyQuote
cathodeRay
(@cathoderay)
Famed Member Moderator
9921 kWhs
Joined: 3 years ago
Posts: 1997
Topic starter  

@derek-m - the WP police can be very tiresome. I have the same problem with this reply. I can however get this past the censor:

The decimal values in yout hex to decimal conversions strike me as having a higher proportion of multiples of 5 (20, 25, 30, 35 etc) than you would expect by chance, and many of the set temps are also in multiples of five, so I think you may well be right, the data is in there. I will try to do some real time matching.

The binary coding for DHW on/off is interesting, all the more so when looking as how this gets processed in message.py in midea_ac_lan:

class C3MessageBody(MessageBody):
def __init__(self, body, data_offset=0):
super().__init__(body)
self.zone1_power = body[data_offset + 0] & 0x01 > 0
self.zone2_power = body[data_offset + 0] & 0x02 > 0
self.dhw_power = body[data_offset + 0] & 0x04 > 0   

& is the bitwise 'and' operator and from what I have read that means the result for each position is 1 if both numbers are 1 otherwise zero. Applying this to the DHW binary numbers:

hex 0d = 00001101  (=on)
hex 09 = 00001001  (=off)

and 0x04 (hex) is 00000100  

then 

00001101 &
00000100 gives
00000100

and 

00001001 &
00000100 gives
00000000

then maybe the code makes sense: 00000100 > 0 evaluates to true and 00000000 > 0 evaluates to false, ie it is converting the binary number to a boolean value. Sheesh, this ain't exactly simple, is it!

 

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


   
ReplyQuote



Page 4 / 31
Share:

Join Us!

Heat Pump Dramas?

Thinking about installing a heat pump but unsure where to start? Already have one but it’s not performing as expected? Or are you locked in a frustrating dispute with an installer or manufacturer? We’re here to help.

Pre-Installation Planning
Post-Installation Troubleshooting
Performance Optimisation
✅ Complaint Support (Manufacturer & Installer)

👉 Book a one-to-one consultation now.

Latest Posts

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