Full Telemetry for Midea-based Mini-Splits

Unrelated: I’m wondering how the test port works for multi-head mini-splits. I wish I could get my hands on one, connect the inverter tester, and log the tester - ODU communication.

I would also love to test the 4th gen tester: https://www.ebay.com/itm/187815715161

Some initial feedback for your additional set of sensors:

Fan Drive Level

  • No surprise, it’s what I label EEV position

Compressor Frequency fine

  • Generates a plausible chart.
  • Curious how you figured out the addition of those bytes from multiple responses.

Compressor Frequency ODU

  • Generates a plausible chart.
  • I’m wondering how this compares to Compressor Frequency (actual) - the charts are almost identical.

Indoor Demand Frequency

  • Generates a plausible chart.

EEV Zone Command / EEV Zone Row Index / EEV Zone Row

  • Can you elaborate what those sensors mean?

High Output Flag

  • Can you elaborate what this sensors mean?

@fmckee

Well as of now I’m simply taking the full frames from the JSON output and comparing with my S1S2 project. I figures before I start digging for the missing 0x06 or maybe others I would get as much between the 2 protocols and validate some of my sensors. Your project validated my S1S2 IPM temp from a guess to now needing a true temp reading like the rest of my actual sensors.

“Compressor Frequency Fine” is currently in my S1S2 project. Found this months ago and it just seems correct. This also bring your original testport “compressor_frequency_actual” closer to my S1S2 actual Hz and perfectly matches my S1S2 Fine Hz. My added “compressor_frequency_odu” which I have labeled as a copy of Hz is actually closer to my higher def version of Hz.

“EEV Zone Command” plus anther byte I have my my S1S2 is the IDU and ODU searching for a better higher load. So far we only see the IDU command on the testport. This is similar to the “Indoor Demand Frequency” to where the ODU byte would determine the actual zone and also does overrides.



Yellow line is your original EEV, Red is your Original EEV plus the detailed byte and brown my high def S1S2 actual Hz


This is “compressor_frequency_odu” what I thought was just a copy of the EEV but turns out to be the actual in my testport. Makes me wonder if we could poll certain bytes at a higher rate for better accuracy.


The bang your head on a table bytes, EEV zones. Green is my S1S2 “EEV Zone Command”, Blue is the testport “EEV Zone Command” Both are the same byte and this is the IDU commanding the ODU to change zones. When its at 0 the IDU does not have control. Brown is what I consider zones. You will see the zones change with the Hz above.

Thats basically EEV Zone Command


Same as above but removed the IDU command and added my S1S2 “Odu Exv Zone Conf” byte. Notice after 12:10PM when the IDU command and ODU conf both go to 0 but the Hz does not. I have no clue why. Cant figure that out but the blue line doesn’t drop either. ((blue line + brown line) / 100) = f[0x02][3] + f[0x05][2] / 100.0f = The same exact data with a very slight time difference.

“EEV Zone Row Index” and “EEV Zone Row”: no clue. My best guess is one or both might determine why after 12:10PM when IDU command went to 0 but Hz stayed high and when to different zones. Good luck with those.

Im finally glad to have a bus that other people can access to compare with.

Just thought about what to do about all those compressor frequency fields.

Here is what my inverter tester spits out:

Compressor frequency (indoor target)
Compressor frequency (outdoor target)			0x02[2]
Compressor frequency (outdoor control)
Compressor frequency (outdoor operating) 		0x02[3]

Compressor frequency (indoor target) & Compressor frequency (outdoor control) are always 0 (no matter what responses I feed into the inverter tester). This seems to be a gap in the firmware. I’m beginning to wonder whether I bought some crappy counterfeit unit.

My plan how to map the compressor frequency bytes:

Compressor frequency (indoor target) 			0x04[8] (new)
Compressor frequency (outdoor target) 			0x02[2]
Compressor frequency (outdoor control)			0x04[7] (new)
Compressor frequency (outdoor operating) 		0x02[3]
Compressor frequency (outdoor operating fine) 	0x02[3] + 0x05[2] / 100.0f (new)

I now also see some more action on the EEV fields you mapped:

I have still no clue what that actually means.

While tinkering, I accidentally discovered that the bits of 0x02[4] result in different error codes being displayed by the inverter tester. I haven’t looked into how to map that yet, but the manual of my inverter tester contains detailed information how individual bits map to error codes. So I’m mildly confident that support for error codes can be added.

Semi-related: The number of competing compressor-frequency bytes in the protocol is xkcd 927-esque.

I wouldn’t think crappy counterfeit. Most of these units are mini-splits but mine is a full house central air. Im thinking just different protocols. When I go outside and check the little screen on the ODU it references that I am using Firmware version “50”. Maybe this can help to identify testport protocol?

On your unit the EEV fields “Row index and Row bound” you are mapping are not the same as mine. I have a guess on how they work but something is strange about them :thinking: The EEV command still looks correct though. Im unsure how EEV command works in your unit but I would think if you went back to your LNS protocol and found the EEV Command on one of the IDU frames it would validate the IDU commanding the ODU the zones 0x05[2]

I haven’t thought about it but just like getting a high-level documentation of these protocols for these buses maybe doing the same with these bytes would make since. Ive labeled things randomly but there’s obvious true labels to most of these fields.

This is from a random Mr Cool unit manual I was recent looking at. Of course doesnt have to be this but what gets labeled with this testport I can duplicate on S1S2 and also eventually get something going with HAHB.

@NyxVale63

Just curious on how this relates to your S1S2 protocol. Are you seeing more sensors on the testport vs your S1S2? I don’t see anything new yet but maybe you do?

Couple of thoughts: I will provide decoded values for the core set of sensors that are supported by the inverter tester. Beyond that, I will make it easy to access raw bytes but leave it up to users to decode more esoteric fields (like the EEV Zone Command / EEV Zone Row Index / EEV Zone Row Bound).

Trying to provide mappings for every possible parameter that work across firmware versions and hardware isn’t a hill that I want to climb.

What I really like is the idea to use the standard labels. I will update my documentation and dashboards to incorporate those. I might start a high-level documentation covering UART, LNS + TEST port after I’ve ironed out some more kinks for the telemetry project. But I’m also happy to contribute if someone else (wink wink) creates something first.

Unrelated: I think I now understand what those 4 compressor frequency bytes (5 if you count the one that you contributed) actually mean:

Actual:

  • Whatever the actual RPM is

Indoor Target:

  • The target as per IDU

Outdoor Target:

  • Target per IDU with some modifications (e.g., increased frequency at the beginning of a cooling cycle).
  • I’ve read people speculating about whether that’s for oil circulation / oil return.

Outdoor Control:

  • The frequency that the compressor is asked to operate at.
  • Main difference to Outdoor Target seems to be that transitioned are incremental, not 0 to 60

@fmckee

That makes since. Way to many types of units out there and hopefully the core sensors stay true for all the units.

From the code chart:

oT Target Frequency calculated by indoor / Indoor Target: 0x04[8]: First come the indoor unit request sent to the outdoor unit. I think the indoor unit calculates the request with its own PID loops.

FT Targeted Frequency / Outdoor Target: 0x02[2] - Followed by the outdoor demand. You see it in your charts but its where the outdoor unit overrides the indoor units request with its own PID loops and also maintenance overrides like oil returns as seen in the images.

Fr Actual Frequency / Outdoor Compressor Actual Hz: 0x04[7] - Actual Hz. Updates roughly every 3.5 seconds on my testport and S1S2. Hz = second | Hz * 60 = RPM


Pink is oT indoor request. Orange is FT outdoor demand with a maintenance override


I have a cheat sheet to help determine the true Hz byte. Blue line is my S1S2 true Hz. Purple line is the Testport ture Hz byte based on the update timing. This is based off of 3.5 second testport updates


Blue is my S1S2 Hz fine. Green is the Testport Hz fine. Not labled on the chart. Still based off the same 3.5 seconds updates. These bytes could have a total different meaning but I haven’t came up with anything. They could also be 2 unrelated bytes but seems like they go together. I personally think with the added details it looks like a reference for energy.

Very interesting note on the last image. The Testport green line is in front of the S1S2 blue line. Learn the timing might make for a better update interval


:thinking:

I just realized you keep referencing a “Control frequency”. I do not know what that is so I went looking. I do not remember seeing it in any documentation to any of these units but finally found it in your Smart Tools Manual. Did the tool help you find the actual frequency byte? If so maybe what I’m considering Actual high def frequency is the Control. This would actually align with how the outdoor EXV updates and just by the name Control it sounds like a limit the compressor needs to stay within so maybe it needs fast updates.

How quick does the Smart Tool update sensors?

Thanks for posting the comparison charts!

Regarding control frequency: The inverter tester displays 4 properties related to compressor frequency:

  • Indoor target frequency (always 0)
  • Outdoor target frequency (equivalent to compressor_frequency_outdoor_target / 0x02[2])
  • Outdoor control frequency (always 0)
  • Outdoor operating frequency (equivalent to compressor_frequency_actual_int / 0x02[3])

I can emulate the ODU with all payload bytes set to 255 - it still displays zero for Indoor target frequency & Outdoor control frequency.

Here is the fake ODU data that I sent to the inverter tester:

uint8_t responsePayloads[NUM_RESPONSES][FRAME_BYTES] = {
  {0x55, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB2},
  {0x55, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB1},
  {0x55, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB0},
  {0x55, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAF},
  {0x55, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAE},
  {0x55, 0x05, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAD},
  {0x55, 0x06, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAC},
};

Here is what it displays:

With Google translate:

I mapped compressor_frequency_outdoor_control & compressor_frequency_indoor_target based on the mappings you shared earlier in the thread:

compressor_frequency_outdoor_control:
    {"compressor_frequency_odu",     0x04, {7},    1, [](const uint8_t f[][FRAME_SIZE]) { return (float) f[0x04][7]; }},

compressor_frequency_indoor_target:
    {"indoor_demand_frequency",      0x04, {8},    1, [](const uint8_t f[][FRAME_SIZE]) { 

It’s nothing I can confirm with the inverter tester, so I just took your newly discovered mappings and connected some dots (in a somewhat random manner). I have no idea if that’s correct. And I have no idea what the control frequency means.

Here is the latest list of mappings related to compressor frequency:

It takes probably 2-3 seconds for a value to update on the screen. That’s either way as fast as it gets given that the bus is relatively slow.

@fmckee

Im not emulating, Im simply requesting. My board sends the AA requests and the ODU answers.

Makes sense.

I only use a modified firmware that generates fake ODU responses to see where the inverter tester gets its data from. E.g., I set everything to zero, and change 1 byte at a time and see if something on the display changes.

What I wanted to convey with my emulation detour: I believe that my inverter tester simply hard-codes indoor target frequency and control frequency to be zero. It never reads those values from the ODU responses.

One thing that I can’t make sense of: As expected, the current mostly correlates with compressor frequency:

Some times, I see compressor frequency go up and current go down (or vice versa):

Has anybody else observed this odd behavior?

I didn’t catch that. So the Dr Smart Tool even though it shows in the manual, you can’t see all 4 Frequency fields? It doesn’t actually show the “Target” or “Control” Frequencies? but you do actually see them with your ESP Testport code?

When I installed my unit I converted my IDU from 208/230V to 115V. Manual showed that the minimum amps goes up by doing the conversion. I’m assuming the same with the ODU. When DC volts are low the amps goes up and vice-versa. I didn’t realize my unit was doing the same as yours until you pointed it out. Thanks

Google agrees but I have no clue how to determine power usage or any kind of conversions yet. Ill end up buying something to measure something for a true measurement. Where is a Electrician when you need to ask questions.

Correct. 2 out of the 4 frequency parameters displayed by the inverter tester are always zero. Even though the test port spits out 4 separate frequency parameters.

Yep, same counter-intuitive behavior. I’m going to install a standalone current logger check if the measurements line up with the data from the test port.

Another weird one is the IPM Temperature field:

The mapping is based on @NyxVale63’s mapping:

I only see activity in the IPM chart when the demand is at it’s daily peak. Beyond that, it’s a flat line.

Does the IPM temperature look similar on your units?

My IPM Temp reads all day and while idle it sits right above outdoor temp. So mine seems correct. Your looks like it belongs with those EEV row index 0x03[5] and EEV row bound 0x03[4] I mislabeled for your Testport. I’m not saying it’s not IPM temp but why report a temp like that.

Just a thought. True sensor data updates way faster than 10 seconds. Even faster than my 3.5 second updates on S1S2 and Testport. Looking back at my both buses this IPM temp byte updates every 10+ seconds. This to me seems to be more of a calculated, target, average.. kind of byte. This still doesn’t mean it’s not IPM temp.

Now I see it, too. My IPM Temp byte and 0x03[4] indeed look somewhat related:

@fmckee

My Testport IPM vs outdoor temp. Looks good but what should it actually look like? I’ve had to relabel some other bytes because of your Testport.

In my unit the IPM byte has a min raw value of 114 which locks the decoded value close to my setpoint. During idle it never goes below 114, even during winter. That seems strange in winter when its 32F outside and the IPM temp is still close to my 73F setpoint. I fully think this byte is an average due to the 10+ second updates vs other temp sensors but the only reference to a byte like that is the temp difference between the High and Low pressure temp average of the previous 10 seconds found on my ODU Point Check Function, but this byte doesn’t seem like that, maybe.

I’ve had the assumption of IPM temp for this byte for a while so I’ll keep it that, but its weird. Maybe a different decoding to make it fit better.

Are you able to put the 0x03[4] - 3.5 and 0x03[5] + 3.5 on the same chart to see what it like like?

Your IPM / Outdoor temp at least looks plausible. Here is what mine looks like over a 4-day period:


Almost looks like I’m looking at 1 byte of a 2-byte sensor.

Here is 0x03[4] - 3.5 and 0x03[5] + 3.5 with some additional charts for context:

Found it… I see that the raw value of your IPM is 179+ from one of your previous images. Most days on my unit the value is between 114 and 176 but sometimes it gets into the 190 range. My guess is that its IPM temp but only reports when it’s getting very high. Maybe some of those other bytes do the same with your firmware, absolutely no clue what they are though.


On your bus only temps above 122F+, raw value 179+ would report on your unit. Maybe.


I found on my unit it once got to 197 and very quickly went down so maybe 200 is the limit. I still think the decoding might be off somehow.