Reverse Engineering Senville/Midea SComms

Posting this in case anyone else is working on Senville SComms or similar inverter systems. I’ve confirmed CRC and frame structure and started mapping payload fields in each frame. Would love to compare notes if anyone else is digging into this.

:warning: Before You Touch Anything

A lot of these SComms setups carry mains voltage on or near the control boards. I’m lucky with how mine is configured — most people won’t be.
If you don’t know exactly what you’re doing, you can:

  • Seriously injure yourself
  • Burn your house down
  • Destroy a very expensive inverter/compressor

I’m not responsible for what you do with this information.
This will void your warranty.
This post is just documenting my own setup for educational purposes.

If you’re unsure at all — hire a professional.

The Project

I couldn’t find any documentation on SComms/RS485 for my Senville/Midea central air unit, so I decided to start sniffing the bus myself. Since this is a central air system where the air handler and heat pump have dedicated power feeds, the communication lines in my setup do not carry high voltage. I had the lines tested by a certified electrician before connecting anything.

I’m currently streaming raw hex frames through a Waveshare adapter into a Python script and SQLite database to better understand how the units communicate and react to different operating conditions.

The long-term goal is to bring this into Home Assistant to monitor real performance metrics — compressor frequency, EXV position, bus voltage, demand vs. actual capacity, runtime, etc. Not to control the system, but to gain visibility into how the inverter and air handler are actually operating.

Hardware & Setup

Interface: Waveshare RS485 to Ethernet
Baud Rate: 4800
Bit, Parity, Stop: 8N1
flow: none
transfer protocol: none

CRC-16/MODBUS Checksum

It turns out the checksum is just standard CRC-16/MODBUS. If the CRC doesn’t match, the frame is discarded.

Polynomial: 0x8005 (x16+x15+x2+1) 

Reversed Poly: 0xA001 

Initial Value: 0xFFFF 

Bit Order: Reflected (Least Significant Bit first) 

Calculation Steps:

Initialize a 16-bit register to 0xFFFF.

XOR the data byte with the lower 8 bits of the register.

Shift the register right one bit.

If the bit shifted out was 1, XOR the register with 0xA001.

Repeat the shift 8 times per byte.

When appending to the frame, transmit the low-order byte first.

Traffic Logs

The traffic shows a consistent cycle between the Inverter (0001) and the Air Handler (0100).

Timestamp Source Msg ID Raw Hex Frame
13:51:42.853 Inverter (0001) 20 A00001200C120F000077742604B5010001001D51
13:51:42.946 Air Handler (0100) 20 A00100200C11010F000000170F6C60190000E7B400

After logging traffic for a while, I noticed a consistent rotation pattern: Every exchange starts with a pair of ID 20 messages (Inverter ↔ Air Handler). After each ID 20 exchange, the system cycles through a single secondary message ID before returning to the next ID 20 sync.

The observed rotation is:

20 → 50 → 20 → 51 → 20 → 52 → 20 → 53 → 20 → 91

The data in ID 20 is updated every few hundred milliseconds, while the data in the 50-53 series is updated less frequently as the cycle rotates.

Example Frame Breakdown

[A0] [01 00 20] [0C] […DATA…] [E7 B4]

  • A0 → Header
  • 01 00 20 → Frame ID
  • 0C → Payload Length
  • DATA → Sensor Payload
  • E7 B4 → CRC16-MODBUS

Based on observed bus traffic and correlating values with live system behavior, these are the fields I believe I’ve identified so far. They align consistently with operation, but I have not fully validated payload locations yet — so treat this as interpretation, not absolute mapping.

Indoor Unit (IDU)

  • Mode
  • Capacity demand
  • Setpoint
  • Blower speed
  • Room temperature
  • Coil temperature
  • Actual demand

Outdoor Unit (ODU)

  • Mode
  • Capacity demand
  • Coil temperature
  • Outdoor ambient temperature
  • Outdoor quarter-degree temperature value
  • Discharge temperature
  • Compressor frequency (Hz)
  • Fan speed (target and actual)
  • DC bus voltage (target and actual)
  • Inverter DC bus voltage
  • AC input voltage
  • Current draw (Amps)
  • EXV steps
  • Runtime minutes
  • Runtime hours

These values were derived through observation and calculated scaling, not official documentation. There is still room for interpretation error. If anyone else is working on SComms or similar Midea-based systems and has mapped additional fields, I’d be interested in comparing observations.

3 Likes

Would this assist with decoding and sending values for experimentation on your WaveShare device?

@IOT7712 Thanks for the suggestion. I did look at Protocol Wizard, but this bus doesn’t appear to follow standard Modbus.

While SComms frames use a Modbus-style CRC, the protocol itself is proprietary. Frames start with 0xA0, have dynamic lengths, and the payload structure doesn’t match Modbus registers.

Right now I’m sniffing the bus and parsing the frames with a Python script that validates the CRC and pushes decoded values into Home Assistant via MQTT Auto-Discovery. That automatically builds 30+ sensors without any YAML.

After graphing the data in Home Assistant, some interesting behavior started showing up.

Control loop behavior (PID)

These values appear to relate to the inverter’s control loop. You can see the error spike and the system respond with a step correction before stabilizing.

Electronic Expansion Valve activity

This is the EXV position in steps from the outdoor board. The valve moves quickly during load changes and then settles once the system stabilizes. Notice that after 30 minutes of running at a low load, the EXV spikes simultaneously with the PID error. This is most likely the unit triggering an oil return cycle to pull oil back to the sump.

Still working on confirming the exact meaning of some fields, but the behavior lines up well with what you’d expect from an inverter system managing refrigerant flow.

If anyone has experience with SComms (S1S2) or similar inverter protocols, I’d love to compare notes.

Very cool! Any detail how you have mapped the various sensors into the payload data?

@NyxVale63 I hope this will help

1 Like