Skip to main content

Cordex HP Controller (Alpha / EnerSys)

The Cordex HP driver polls an Alpha Technologies (EnerSys) Cordex HP system controller — CXC HP, CXCi HP, or CXCM1 HP — over Modbus TCP and surfaces DC system telemetry as device attributes with history enabled. The Limited Data Set (battery voltage / current / runtime, total load, AC mains, alarm thresholds, system mode) lives at fixed input-register addresses; an extra_register_map lets you pull additional points out of the full DC System and AMPS HP2 register tables.

The integration is read-only. The Cordex HP does not implement Modbus Holding Registers (FC03), so setpoint changes need the controller's HTTP control plane and are out of scope here.

Status

Built against the Alpha Cordex HP Modbus Integrator Guide 0350114-J0 Rev K (08/2021). Limited Data Set addresses are stable across firmware revisions; full data set addresses are dynamic per install.

Prerequisites

  • Modbus enabled on the CXC HP. By default it is off — turn it on under Controller > Configure Controller > Communications > Modbus in the controller web UI.
  • Note the Limited Data Set Device ID (default 247) and any System Device IDs (one per DC system; one per AMPS HP2 inverter system).
  • Outbound TCP/502 from the GEM controller to the Cordex HP IP.
  • For points outside the Limited Data Set: export the controller's Modbus Table CSV from the web UI and translate it into the extra_register_map JSON shape below.

Setup

  1. Enable Modbus on the controller. Note the configured byte order — the CXC HP default is Least significant bytes first, which maps to little_endian on this driver.
  2. Note the device IDs — Limited Data Set ID (default 247), DC System ID (typically 1), AMPS HP2 System ID(s) (typically 2+).
  3. Create the device under System > Devices with driver cordex_hp. Set:
    • ip — controller IP
    • port502 (default)
    • limited_data_set_unit_id — match the controller (default 247)
    • byte_order — match the controller (default little_endian)
  4. (Optional) Add an extra register map for points beyond the Limited Data Set. Paste a JSON array into the extra_register_map attribute. Each entry: {name, unit_id, register, format, unit?, scale?, codes?}.
  5. Watch the device attributes populate after one polling cycle (default 10 s).
tip

The full DC System and AMPS HP2 register addresses are dynamic per install — the controller assigns them as inventory is added or removed. Always pull the live map from the controller's web UI rather than copying from another install. Use the controller's Re-number Modbus Table By Name button before importing if you need address stability across identical sites.

Attributes

Device

AttributeRequiredTypeNotes
ipyesstringController IP.
portnointTCP port. Default 502.
limited_data_set_unit_idnointModbus unit ID for the Limited Data Set. Default 247.
byte_ordernostringlittle_endian (default) | big_endian | mid_big | mid_little. Must match the controller.
polling_ratenointPoll interval in ms. Default 10000. Below 5000 ms can stress the controller under heavy alarm activity.
timeoutnointModbus request timeout in ms. Default 10000.
reconnect_timeoutnointDelay between reconnect attempts in ms. Default 3000.
extra_register_mapnojsonList of additional points to poll. See format below.

Limited Data Set (auto-populated)

Each value is a 32-bit float spanning two consecutive input registers (30001..30036).

AttributeUnit
system_voltageV
total_load_currentA
total_capacity_installedA
system_mode_code— (numeric)
system_modestring (resolved label — Charging, Discharging, etc.)
estimated_rectifier_ac_voltageV
estimated_battery_runtimemin
last_discharge_durationmin
output_voltage_low_alarm_limitV
output_voltage_high_alarm_limitV
battery_runtime_low_alarm_limitmin
ac_mains_voltage_low_alarm_limitV
ac_mains_voltage_high_alarm_limitV
battery_capacity_ratingAh
battery_average_temperature°C
battery_currentA
battery_temp_low_alarm_limit°C
battery_temp_high_alarm_limit°C
battery_charge_current_high_limitA

Extra register map format

[
{ "unit_id": 1, "name": "dc_battery_voltage", "register": 35157, "format": "float32", "unit": "V" },
{ "unit_id": 1, "name": "dc_battery_current", "register": 35159, "format": "float32", "unit": "A" },
{ "unit_id": 2, "name": "ampshp2_inv1_loading_w", "register": 36773, "format": "float32", "unit": "W" },
{ "unit_id": 2, "name": "ampshp2_inv1_ac_output_status", "register": 36775, "format": "float32",
"codes": { "0": "On", "1": "ManualOff", "2": "IrrecoverableError", "3": "RecoverableError" } }
]
FieldNotes
unit_idModbus unit ID for this point. The driver flips the slave ID once per group, not per point.
nameAttribute name written to the device.
registerInput register address (Kohler extended format).
formatfloat32 | float64 | uint32 | int32 | input_status | coil.
unitOptional unit label.
scaleOptional numeric multiplier applied after read.
codesOptional integer→string lookup (e.g., AMPS HP2 AC Output Status).

Commands

NameArgsDescription
get_statusReturn last cached register values.
poll_nowForce an immediate poll cycle.
read_registeraddress, unit_idOne-off Modbus read.
read_input_registersaddress, length, unit_idBulk input register read.
read_input / read_inputsaddress, [length], unit_idDiscrete input read.
read_coil / read_coilsaddress, [length], unit_idCoil read.
scan_unit_idsstart, end, timeout_per_unit, test_registerProbe a unit ID range.
get_diagnostics / clear_diagnostics / get_comm_logDriver-level Modbus diagnostics.

Known limitations

  • Read-only. The controller does not support Modbus Holding Registers (FC03), so setpoint writes are not possible over Modbus.
  • Sentinel translation. 0xFFFFFFFF (NaN as float, -1 as int) means unknown and 999999999 means deprecated in the Cordex spec. Both are translated to null. A bare 0 is left as-is, since it is indistinguishable from a legitimate zero reading.
  • Dynamic full data set. Full DC System / AMPS HP2 register addresses are not stable across installs — the controller assigns them as inventory changes.
  • Single-master. Multiple unit IDs share one TCP connection and the driver flips slave ID per read group. Do not point a second Modbus master at the controller while this driver is polling.

Troubleshooting

SymptomCheck
connection refused on 502Modbus is disabled on the controller. Enable it under Controller > Configure Controller > Communications > Modbus.
Limited Data Set values are all nullbyte_order is wrong. The CXC HP default is Least significant bytes firstlittle_endian.
Extra register map values look scrambledbyte_order mismatch, or the addresses were copied from a different install. Re-export from the live controller's Modbus Table CSV.
Connection alternates up/downPolling rate is too aggressive. Raise polling_rate to 10000+ ms during heavy alarm activity.
Some values read null after firmware updateInventory change may have shifted the dynamic register addresses. Re-export the Modbus Table CSV and update extra_register_map.
  • Modbus — generic Modbus device, scanner, and register browser
  • Devices — device management
  • Subsystems — power subsystem assignment