TapHome

SolaX Hybrid X1/X3 Gen 4

Modbus RTU
Submitted by
Last updated: 03. 2026
SolaX Hybrid X1/X3 Gen 4

The SolaX X1-HYBRID and X3-HYBRID Gen 4 are energy storage inverters supporting both single-phase (3–7.5 kW) and three-phase (5–15 kW) configurations. The TapHome template communicates via Modbus RTU over RS-485, reading input and holding registers for battery state of charge, PV string power, grid power flow, energy totals, charger mode and night charge SOC. All write scripts are commented out, making the template effectively read-only.

The template also implements comprehensive fault detection by parsing 32-bit inverter error codes and 16-bit manager error codes, reporting individual faults as errors in TapHome.

Hardware connection

The SolaX Gen 4 inverter provides an RS-485 COM port for Modbus RTU communication on the bottom panel. The COM port uses an RJ45 connector.

SolaX X3-HYBRID G4 bottom panel — terminal layout with COM, BMS, Meter/CT, PV, BAT and GRID connections

COM terminal pin assignment (RJ45):

PinAssignmentDescription
1Drycontact_A(in)System switch connection
2Drycontact_B(in)System switch connection
3+13V
4485ARS-485 data+ (for TapHome)
5485BRS-485 data− (for TapHome)
6GNDGround
7Drycontact_A(out)Generator connection
8Drycontact_B(out)Generator connection

Connect TapHome to the inverter COM port:

  • Pin 4 (485A) on inverter COM to A+/D+ on TapHome RS-485
  • Pin 5 (485B) on inverter COM to B-/D- on TapHome RS-485
  • Pin 6 (GND) connection recommended for reliable communication

The inverter itself does not support Modbus TCP natively. Modbus TCP is only available through the SolaX monitoring module (Wi-Fi dongle) and is not used by the TapHome template.

For installations where RS-485 wiring is not practical, the SolaX Inverter (Cloud API) template provides monitoring through the SolaxCloud platform via HTTPS — no physical connection required. It supports all SolaX inverter types, not just the Gen 4 Hybrid.

Some holding registers are marked with limited EEprom write cycles. Excessive write operations can cause irreversible hardware damage. The TapHome template has all write scripts disabled, so this is not a concern with the current template.

Configuration

Enabling Modbus communication

Modbus RTU is available on the inverter’s RS-485 COM port by default. The following parameters must match between the inverter and the TapHome module:

  1. Slave ID – default is 1, configurable on the inverter display
  2. Baud rate – the inverter defaults to 19200 baud, but the TapHome template uses 9600 baud. Adjust one to match the other
  3. Data format – 8 data bits, no parity, 1 stop bit

To configure on the inverter display: Menu > Setting > Advance Setting > Modbus. Set the slave address and baud rate. The baud rate can also be read from holding register H:0x00B0 and written via register 0x00CA (values: 0=115200, 1=57600, 2=56000, 3=38400, 4=19200, 5=14400, 6=9600).

To avoid changing the inverter settings, adjust the baud rate in TapHome module settings to 19200 to match the inverter default.

Communication timing

The protocol requires a minimum interval of 1 second between consecutive Modbus instructions and a character-gap timeout of at least 100 ms. The response timeout is 1 second. The TapHome template uses individual poll intervals per device (2.5 s to 150 s) which satisfy these constraints.

RS-485 COM port function

Register H:0x013E (485CommFunSelect) determines whether the RS-485 port is used for Modbus communication (value 0) or EV Charger communication (value 1). Ensure this is set to 0 (Modbus 485) for TapHome integration.

Device capabilities

Battery monitoring
  • Battery SOC – reads battery state of charge (A:0x1C) as a percentage. The raw register value in 1% units is divided by 100 for the TapHome 0–1 analog input range (e.g. 85% becomes 0.85)
  • Battery Temperature – reads battery temperature (A:0x18) in degrees Celsius. Polled every 80 seconds
Solar PV power
  • PV1 Power – DC power output from PV string 1 (A:0x0A), displayed in kW after /1000 conversion from watts
  • PV2 Power – DC power output from PV string 2 (A:0x0B), displayed in kW after /1000 conversion from watts
Grid power and energy metering
  • Grid Feed-in Power – instantaneous grid power (A:0x46, LittleEndianInt32) in kW. Positive values indicate export to grid, negative values indicate consumption from grid
  • Daily / Actual Energy – combines daily energy output from the inverter AC port (A:0x50, 0.1 kWh resolution) and real-time grid power (A:0x02) in kW. The grid power register is X1-specific (single-phase)
  • Total Energy – lifetime cumulative energy output from the inverter AC port (A:0x52, LittleEndianInt32), displayed in MWh
Charger mode and night charge
  • Charger Use Mode – reads the active solar charger mode (H:0x8B): Self Use Mode (0), Feedin Priority (1), Backup Mode (2), or Manual Mode (3). Values 4–9 are reserved. The write register (H:0x1F) exists in the template but is commented out, making this read-only
  • Self-Use Night Charge SOC – reads the upper SOC target for night charging in Self-Use mode (H:0x94) as a percentage. The write register (H:0x63) and enable register (H:0x62) are both commented out, so night charge configuration cannot be changed through TapHome
Fault detection

The module-level ReadScript monitors the inverter run mode (A:0x09) and two error registers:

  • Run Mode faults – triggers an error when Run Mode is 3 (Fault) or 4 (Permanent Fault)
  • Inverter fault codes (A:0x40) – 32-bit bitmap parsed for 28 individual faults including grid voltage/frequency faults, PV voltage faults, battery faults, isolation faults, overtemperature, overcurrent protection, relay faults, and communication errors
  • Manager error codes (A:0x43) – 16-bit bitmap parsed for power type faults, EEPROM errors, NTC sensor issues, battery temperature warnings, meter faults, and fan faults

The Run Mode service attribute on the module displays the current inverter state as text: Waiting, Checking, Normal, Fault, Permanent Fault, Update, Off-grid waiting, Off-grid, Self Testing, Idle, or Standby.

Additional capabilities

The inverter exposes a comprehensive register map with over 300 holding registers and 200 input registers. Notable capabilities not yet implemented in the template include per-PV-string voltage and current monitoring (A:0x03–0x06), battery voltage/current/power readings, BMS connection state, grid on/off status, X3 per-phase grid voltage/current/power (12 registers at A:0x6A–0x75), cumulative grid feed-in and consumption energy (via meter), total solar energy production, BMS user SOC and SOH, and battery cell min/max temperature and voltage. Write capabilities include system ON/OFF control, charger mode selection, manual force charge/discharge, discharge minimum SOC, night charge configuration, and remote power control with active/reactive power targets. These can be added in a future template update.

The template currently reads X1 (single-phase) grid power at A:0x02. For X3 (three-phase) installations, per-phase grid power is available at registers A:0x6C, A:0x70, and A:0x74 but is not included in the current template.

Troubleshooting

No communication with inverter
  1. Verify the RS-485 cable connections: A+ to A+, B- to B-, GND to GND
  2. Check that register H:0x013E is set to 0 (Modbus 485 mode, not EV Charger)
  3. Confirm the baud rate matches between inverter and TapHome – the inverter defaults to 19200 while the template defaults to 9600
  4. Verify the Slave ID in TapHome matches the inverter setting (default: 1)
  5. Ensure no other Modbus master is connected to the same RS-485 bus – Modbus supports only a single master
Battery SOC reading incorrect

The Battery SOC register (A:0x1C) reports values in 1% units. The template divides by 100 for the TapHome 0–1 analog input range. If the displayed value seems wrong, verify the TapHome device is configured as an AnalogInput (0–1 range, not 0–100).

Grid power sign convention

The Grid Feed-in Power (A:0x46) uses a sign convention where positive values mean export (generating/feeding to grid) and negative values mean import (consuming from grid). The Daily/Actual Energy grid power register (A:0x02) may also show negative values during grid consumption.

X1 vs X3 register differences

Some registers are model-specific. Grid voltage (A:0x00), current (A:0x01), and power (A:0x02) are X1 single-phase registers. For X3 three-phase models, the equivalent per-phase readings are at A:0x6A–0x75. The template uses the X1 grid power register, which may not report correctly on X3 models.

Available devices

SolaX Hybrid Gen 4 Module
Service Attributes
Run ModeInverter operating state — Waiting, Checking, Normal, Fault, Permanent Fault, Update, Off-grid waiting, Off-grid, Self Testing, Idle, Standby

SOLAX Hybrid Gen 4

Read (module)
var reg := MODBUSR(A, 0x09, UInt16);
IF(reg = 3, ADDERROR("Run Mode Fault"));
IF(reg = 4, ADDERROR("Run Mode Permanent Fault"));
#error table  2-3 for x3
var x3 := MODBUSR(A, 0x0040, Uint32);
IF(GETBIT(x3, 0) = 1, ADDERROR("TZ Protect Fault"));
IF(GETBIT(x3, 1) = 1, ADDERROR("Grid Lost Fault"));
IF(GETBIT(x3, 2) = 1, ADDERROR("Grid Volt Fault"));
IF(GETBIT(x3, 3) = 1, ADDERROR("Grid Freq Fault"));
IF(GETBIT(x3, 4) = 1, ADDERROR("PV Volt Fault"));
IF(GETBIT(x3, 5) = 1, ADDERROR("Bus Volt Fault"));
IF(GETBIT(x3, 6) = 1, ADDERROR("Bat Volt Fault"));
IF(GETBIT(x3, 7) = 1, ADDERROR("AC10mins Volt Fault"));
IF(GETBIT(x3, 8) = 1, ADDERROR("DCI OCP Fault"));
IF(GETBIT(x3, 9) = 1, ADDERROR("DCV OCP Fault"));
IF(GETBIT(x3, 10) = 1, ADDERROR("SW OCP Fault"));
IF(GETBIT(x3, 11) = 1, ADDERROR("RC OCP Fault"));
IF(GETBIT(x3, 12) = 1, ADDERROR("Isolation Fault"));
IF(GETBIT(x3, 13) = 1, ADDERROR("Temp Over Fault"));
IF(GETBIT(x3, 14) = 1, ADDERROR("BatConnDir Fault"));
IF(GETBIT(x3, 15) = 1, ADDERROR("Off-grid Overload"));
IF(GETBIT(x3, 16) = 1, ADDERROR("Overload"));
IF(GETBIT(x3, 17) = 1, ADDERROR("Bat Power Low"));
IF(GETBIT(x3, 18) = 1, ADDERROR("BMS Lost"));
IF(GETBIT(x3, 19) = 1, ADDERROR("Fan Fault"));
IF(GETBIT(x3, 20) = 1, ADDERROR("Low Temp Fault"));
IF(GETBIT(x3, 23) = 1, ADDERROR("INV Volt Sample Fault"));
IF(GETBIT(x3, 24) = 1, ADDERROR("Inner Comm Fault"));
IF(GETBIT(x3, 25) = 1, ADDERROR("INV EEPROM Fault"));
IF(GETBIT(x3, 26) = 1, ADDERROR("RCD Fault"));
IF(GETBIT(x3, 27) = 1, ADDERROR("Grid Relay Fault"));
IF(GETBIT(x3, 28) = 1, ADDERROR("Off-grid Relay Fault"));
IF(GETBIT(x3, 29) = 1, ADDERROR("PV ConnDir Fault"));
IF(GETBIT(x3, 30) = 1, ADDERROR("Charger Relay Fault"));
IF(GETBIT(x3, 31) = 1, ADDERROR("Earth Relay Fault"));

#error 2-5 Manager error code
var err := MODBUSR(A, 0x0043, Uint16);
IF(GETBIT(err, 0) = 1, ADDERROR("Power Type Fault"));
IF(GETBIT(err, 1) = 1, ADDERROR("Port OC Warning"));
IF(GETBIT(err, 2) = 1, ADDERROR("Mgr EEPROM Fault"));
IF(GETBIT(err, 4) = 1, ADDERROR("NTC Sample Invalid"));
IF(GETBIT(err, 5) = 1, ADDERROR("Battery Temperature Low"));
IF(GETBIT(err, 6) = 1, ADDERROR("Battery Temperature High"));
IF(GETBIT(err, 9) = 1, ADDERROR("Meter Fault"));
IF(GETBIT(err, 10) = 1, ADDERROR("Bypass Relay Fault"));
IF(GETBIT(err, 11) = 1, ADDERROR("Fan 2 Fault"));
Service Attributes
Run Mode
SWITCH(MODBUSR(A, 0x09, UInt16), 
0, "Waiting",
1, "Checking",
2, "Normal",
3, "Fault",
4, "Permanent Fault",
5, "Update",
6, "Off-grid waiting",
7, "Off-grid",
8, "Self Testing ",
9, "Idle",
10, "Standby",
"Other"
);
Battery SOC Analog Input Read-only

Battery state of charge as percentage (0-100%) — displayed as 0-1 analog input in TapHome

Register: A:0x1C UInt16 Unit: % numeric

Battery SOC

Read input level
MODBUSR(A, 0x1C, UInt16)/100
Battery Temperature Temperature Sensor Read-only
Register: A:0x18 UInt16 Unit: °C numeric

Battery Temperature

Read temperature
MODBUSR(A,0x0018, UInt16)
Daily / Actual Energy Electricity Meter Read-only

Combines daily energy output to grid (kWh) and real-time grid power (kW) — negative grid power indicates import

Register: A:0x50, A:0x02 UInt16, Int16 Unit: kWh / kW numeric

Daily / Actual Energy

Read total consumption
MODBUSR(A, 0x50, UInt16) /10
Read demand
MODBUSR(A,0x02, Int16)/1000
Charger Use Mode Multi-value Switch Read-only

Active solar charger mode — Self Use, Feedin Priority, Backup, or Manual (read-only)

Register: H:0x8BH:0x1F UInt16 numeric
Values / States: Self Use Mode · Feedin Priority · Backup Mode · Manual Mode

Charger Use Mode

Read switch state
MODBUSR(H, 0x008B, Uint16)
Write switch state
#MODBUSW(H, 0x001F, uint16, Mu)
Grid Feed-in Power Variable Read-only

Instantaneous grid power in kW — positive values indicate export, negative values indicate import

Register: A:0x46 LittleEndianInt32 Unit: kW numeric

Grid Feed-in Power

Read
MODBUSR(A, 0x46,LittleEndianInt32)/1000
PV1 Power Variable Read-only
Register: A:0x0A UInt16 Unit: kW numeric

PV1 Power

Read
MODBUSR(A,0x0a, UInt16)/1000
PV2 Power Variable Read-only
Register: A:0x0B UInt16 Unit: kW numeric

PV2 Power

Read
MODBUSR(A,0x0b, UInt16)/1000
Self-Use Night Charge SOC Dimmer Read-only

Upper SOC target for night charging in Self-Use mode (read-only, 10-100%)

Register: H:0x94H:0x63 UInt16 Unit: % numeric

Self-Use Night Charge SOC

Initialize
#MODBUSWNE(H, 0x0062, Uint16, 1);
Read level
MODBUSR(H, 0x0094, Uint16) / 100
Write level
#MODBUSW(H, 0x0063, Uint16, Le * 100)
Total Energy Variable Read-only

Lifetime cumulative energy output from inverter AC port in MWh

Register: A:0x52 LittleEndianInt32 Unit: MWh numeric

Total Energy

Read
MODBUSR(A, 0x52,LittleEndianInt32) / 1000
Connection: Modbus RTU • 9600 baud• 8N1 • Slave ID: $[SlaveId]
Possible improvements (25)
  • A:0x00 Grid Voltage (X1) — 0.1V, UInt16. X3 per-phase voltages at A:0x6A/0x6E/0x72
  • A:0x01 Grid Current (X1) — 0.1A, Int16. X3 per-phase currents at A:0x6B/0x6F/0x73
  • A:0x03, A:0x04 PV Voltage 1 & 2 — 0.1V, UInt16. Useful for string-level diagnostics
  • A:0x05, A:0x06 PV Current 1 & 2 — 0.1A, UInt16. Useful for string-level diagnostics
  • A:0x08 Radiator Temperature — 1°C, Int16. Inverter internal radiator/heatsink temperature
  • A:0x14 Battery Voltage — 0.1V, Int16. Battery pack voltage
  • A:0x15 Battery Current — 0.1A, Int16. Positive=charge, negative=discharge
  • A:0x16 Battery Power — 1W, Int16. Positive=charging, negative=discharging
  • A:0x17 BMS Connect State — 0=Disconnected, 1=Connected. Critical for battery health monitoring
  • A:0x1A Grid Status — 0=OnGrid, 1=OffGrid. Important for backup/off-grid scenarios
  • A:0x48–0x49 Feed-in Energy Total (Meter) — 0.01kWh, UInt32 LE. Cumulative energy exported to grid via meter
  • A:0x4A–0x4B Consumed Energy Total (Meter) — 0.01kWh, UInt32 LE. Cumulative energy consumed from grid via meter
  • A:0x6A–0x75 X3 Per-Phase Grid Readings — Voltage/current/power/frequency per phase R/S/T. 12 registers total. Essential for 3-phase monitoring
  • A:0x94–0x95 Solar Energy Total — 0.1kWh, UInt32 LE. Cumulative PV production (both strings combined)
  • A:0x96 Solar Energy Today — 0.1kWh, UInt16. Today PV production
  • A:0xBE BMS User SOC — 1%, UInt16. SOC as reported by BMS (may differ from A:0x1C)
  • A:0xBF BMS User SOH — 1%, UInt16. Battery state of health
  • Write 0x001C System ON/OFF — 0=OFF, 1=ON. Remote system power control
  • Write 0x001F Charger Use Mode (write) — Write register exists in template but is COMMENTED OUT. 0=Self Use, 1=Feed-in, 2=Backup, 3=Manual
  • Write 0x0020 Manual Mode — 0=Stop, 1=Force charge, 2=Force discharge. Requires Charger Use Mode = 3 (Manual)
  • Write 0x0061 SelfUse Discharge Min SOC — 10%–100%. Minimum SOC before discharge stops in Self-Use mode
  • H:0x8C Manual Mode Readback — 0=Stop, 1=Force charge, 2=Force discharge. Readback of current manual mode setting
  • A:0xBA, A:0xBB Battery Temp High/Low — 0.1°C, Int16. Min/max battery cell temperatures
  • A:0xBC, A:0xBD Cell Voltage High/Low — 0.001V, UInt16. Min/max individual cell voltages. Important for battery health
  • Write 0x007C–0x0082 Remote Power Control — Active/reactive power targets, duration. Enables advanced energy management and grid services

Sources