{
 "manufacturer": "SMA",
 "manufacturer_slug": "sma",
 "model": "Sunny Tripower Storage X / Sunny Island X (SMA Modbus, ennexOS)",
 "model_slug": "sunny-tripower-storage-x-sunny-island-x",
 "short_model": "SMA STPS X / SI X",
 "aliases": [
  "STPS30-20",
  "STPS50-20",
  "STPS27-US-20",
  "STPS60-US-20",
  "SI30-20",
  "SI50-20",
  "SI27-US208-20",
  "SI40-US480-20",
  "SI60-US480-20",
  "Sunny Tripower Storage X 50",
  "Sunny Island X 50"
 ],
 "equipment_type": "Battery inverter",
 "applies_to": "Sunny Tripower Storage X 30/50 (incl. US variants) and Sunny Island X 30/50 (incl. US variants), queried through the System Manager over Modbus TCP.",
 "summary": "These ennexOS battery inverters are read and controlled over Modbus TCP via the device acting as System Manager, using the SMA Modbus profile: unit ID 1 for the communication product, 2 for system values and 3 for each device. Every register is a 32-bit SMA value (U32/S32) with a FIXn decimal format or a tag code. The map covers status, battery state, ratings, active power limits, the external setpoint fallback and the direct battery power window.",
 "transport": [
  "TCP"
 ],
 "defaults": {
  "unit_id": 3,
  "baud": null,
  "parity": null,
  "data_bits": null,
  "stop_bits": null,
  "tcp_port": 502
 },
 "addressing": {
  "convention": "0-based",
  "note": "The SMA tables list 'ADR' as the decimal Modbus register and the TI's own procedure enters ADR directly as the start address in the Modbus master, so the printed number is the wire address (30845 is requested as 30845). Only the SunSpec profile (unit ID 126, from 40001) uses a minus-one offset - that profile is not part of this map."
 },
 "default_word_order": "ABCD",
 "firmware": null,
 "source": {
  "title": "SMA Modbus Interface - Sunny Tripower Storage X / Sunny Island X (Technical Information)",
  "doc_number": "SMAModbus-STPS-X-SI-X-TI-en-11 (Version 1.1)",
  "revision_date": "2026-04-20",
  "url": "https://files.sma.de/downloads/SMAModbus-STPS-X-SI-X-TI-en-11.pdf",
  "pages": "pp. 9-14 (assignment tables, unit IDs 1, 2, 2/3, 3), pp. 15-16 (configuration and battery control procedure)"
 },
 "notes": [
  "Word order: the SMA Modbus ennexOS TI (SMAModbus-ennexOS-TI-en-14, https://files.sma.de/downloads/SMAModbus-ennexOS-TI-en-14.pdf, section 3.4.3) says the big-endian transmission rule also applies to 32/64-bit values ('Big-Big'); its validity list names STPS 30-20/50-20, SI30-20/SI50-20 and Sunny Island X-US. For all variants, including STPS27-US-20/STPS60-US-20, this TI's own battery example writes 10 % to 44449/44451 as 0000 03E8 and shows NaN as 8000 0000, i.e. high word first.",
  "Format to scale: FIX0 = integer (x1), FIX2 = two decimals (x0.01), FIX3 = three decimals (x0.001), DURATION = seconds, per the SMA data formats in the ennexOS TI. TAGLIST/ENUM values are tag codes.",
  "NaN values: U32 0xFFFFFFFF, S32 0x80000000, and status tags (TAGLIST) 16777213 (0xFFFFFD) for 'information not available'.",
  "The unit ID in each name tells where to read the register: 1 = communication product, 2 = system (System Manager view), 3 = individual device; '2/3' registers exist under both and may differ because one is the system view.",
  "Table: 3xxxx registers are listed here as input registers and 4xxxx as holding registers. The TI's procedure reads with function 0x04 and writes with 0x10; the ennexOS TI lists 0x03, 0x04, 0x06 and 0x10 as supported.",
  "Left out: 30233 ('Accumulated connected power of the PV inverter') - its row text describes setting an active power limit while the access is read-only, so the source contradicts itself on what the register is.",
  "Left out: 31391 - named 'Battery state of charge' but documented as returning a status tag (error/off/OK/warning); name and format disagree. Use 30845 for the state of charge in percent.",
  "This TI is deliberately limited to control-related registers; the full device list is in SMA's per-device 'Parameters and Measured Values' document, which was not available as a free download and is not covered here.",
  "Writable RW parameters are meant for long-term settings; SMA marks some that must not be changed more than once a day and marks the grid-management parameters that may be written cyclically. The markings are in SMA's 'Parameters and Measured Values' document, not in this TI."
 ],
 "registers": [
  {
   "table": "input_register",
   "address": 30005,
   "documented": "30005",
   "name": "Serial number (unit ID 1)",
   "description": "Serial number of the device.",
   "data_type": "UINT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 1,
   "scale_factor_ref": null,
   "units": "",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 30051,
   "documented": "30051",
   "name": "Device category (unit ID 1)",
   "description": "Device category tag, e.g. 8009 = hybrid inverter.",
   "data_type": "UINT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 1,
   "scale_factor_ref": null,
   "units": "",
   "access": "R",
   "values": {
    "8009": "Hybrid inverter"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 30201,
   "documented": "30201",
   "name": "Current state of health (unit ID 2/3)",
   "description": "Health status tag (5-minute value).",
   "data_type": "UINT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 1,
   "scale_factor_ref": null,
   "units": "",
   "access": "R",
   "values": {
    "307": "OK"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 30845,
   "documented": "30845",
   "name": "Current battery state of charge (unit ID 2/3)",
   "description": "User SoC: SoC within the configured charge/discharge limits.",
   "data_type": "UINT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 1,
   "scale_factor_ref": null,
   "units": "%",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 30955,
   "documented": "30955",
   "name": "Operating status of battery (unit ID 3)",
   "description": "Battery state tag.",
   "data_type": "UINT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 1,
   "scale_factor_ref": null,
   "units": "",
   "access": "R",
   "values": {
    "303": "Off",
    "2291": "Battery standby",
    "2292": "Battery charging (default)",
    "2293": "Battery discharging"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 33017,
   "documented": "33017",
   "name": "Nominal active power WMaxOutRtg (unit ID 2)",
   "description": "Rated feed-in active power of the system.",
   "data_type": "INT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 1,
   "scale_factor_ref": null,
   "units": "W",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "input_register",
   "address": 33019,
   "documented": "33019",
   "name": "Nominal active power WMaxInRtg (unit ID 2/3)",
   "description": "Rated intake (charging) power, negative, e.g. -50000 W.",
   "data_type": "INT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 1,
   "scale_factor_ref": null,
   "units": "W",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 40018,
   "documented": "40018",
   "name": "Quick shut-down of the inverters (unit ID 2/3)",
   "description": "Fast stop/start of the system (UID 2) or one device (UID 3).",
   "data_type": "UINT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 1,
   "scale_factor_ref": null,
   "units": "",
   "access": "RW",
   "values": {
    "381": "Standby",
    "1467": "Start",
    "1749": "Full stop (AC and DC side)"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 40029,
   "documented": "40029",
   "name": "General operating status (unit ID 2/3)",
   "description": "Overall operating state tag.",
   "data_type": "UINT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 1,
   "scale_factor_ref": null,
   "units": "",
   "access": "R",
   "values": {
    "303": "Off",
    "309": "Operation",
    "569": "Switched on (default)",
    "1295": "Standby",
    "1795": "Blocked",
    "16777213": "Information not available"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 40187,
   "documented": "40187",
   "name": "Nominal battery capacity (unit ID 2/3)",
   "description": "Rated battery capacity.",
   "data_type": "UINT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 1,
   "scale_factor_ref": null,
   "units": "Wh",
   "access": "R",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 40210,
   "documented": "40210",
   "name": "Operating mode active power setpoint (unit ID 3)",
   "description": "Source of the active power setpoint; 1079 needed for battery control.",
   "data_type": "UINT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 1,
   "scale_factor_ref": null,
   "units": "",
   "access": "RW",
   "values": {
    "303": "Off",
    "1077": "Manual setpoint in W",
    "1078": "Manual setpoint in %",
    "1079": "External active power setpoint (default)"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 40212,
   "documented": "40212",
   "name": "Active power limitation, in W (unit ID 3)",
   "description": "Absolute active power limit, 0-60000 W.",
   "data_type": "UINT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 1,
   "scale_factor_ref": null,
   "units": "W",
   "access": "RW",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 40214,
   "documented": "40214",
   "name": "Active power limitation in % (unit ID 3)",
   "description": "Relative active power limit, 0-100 %.",
   "data_type": "UINT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 1,
   "scale_factor_ref": null,
   "units": "%",
   "access": "RW",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 40236,
   "documented": "40236",
   "name": "Operating mode of the BMS (unit ID 3)",
   "description": "Battery management operating mode.",
   "data_type": "UINT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 1,
   "scale_factor_ref": null,
   "units": "",
   "access": "RW",
   "values": {
    "303": "Off",
    "308": "On",
    "2289": "Battery charging (default)",
    "2290": "Battery discharging",
    "2424": "Default setting"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 40472,
   "documented": "40472",
   "name": "Nominal grid voltage (unit ID 2/3)",
   "description": "Nominal grid voltage, e.g. 230 or 400 V.",
   "data_type": "UINT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 1,
   "scale_factor_ref": null,
   "units": "V",
   "access": "RW",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 40721,
   "documented": "40721",
   "name": "Minimum width of deep discharge protection range (unit ID 3)",
   "description": "Default 1 %, recommended above 0 %.",
   "data_type": "UINT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 1,
   "scale_factor_ref": null,
   "units": "%",
   "access": "RW",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 41193,
   "documented": "41193",
   "name": "Behavior during failure of external setpoint (unit ID 2/3)",
   "description": "What happens when external setpoints stop arriving.",
   "data_type": "UINT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 1,
   "scale_factor_ref": null,
   "units": "",
   "access": "RW",
   "values": {
    "2506": "Keep values (default)",
    "2507": "Use fallback values"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 41195,
   "documented": "41195",
   "name": "Timeout for external setpoint (unit ID 2/3)",
   "description": "Setpoint timeout, 1-1800 s, default 600 s.",
   "data_type": "UINT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 1,
   "scale_factor_ref": null,
   "units": "s",
   "access": "RW",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 41315,
   "documented": "41315",
   "name": "Operating mode active power controller (unit ID 2)",
   "description": "Selects open-loop or closed-loop active power control.",
   "data_type": "UINT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 1,
   "scale_factor_ref": null,
   "units": "",
   "access": "RW",
   "values": {
    "3352": "Open-loop control (default)",
    "3353": "Closed-loop control"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 41369,
   "documented": "41369",
   "name": "Activation threshold, grid feed-in (unit ID 2/3)",
   "description": "Default 5 %.",
   "data_type": "INT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 0.001,
   "scale_factor_ref": null,
   "units": "%",
   "access": "RW",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 41371,
   "documented": "41371",
   "name": "Deactivation threshold grid feed-in (unit ID 2/3)",
   "description": "Default 5 %.",
   "data_type": "INT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 0.001,
   "scale_factor_ref": null,
   "units": "%",
   "access": "RW",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 41373,
   "documented": "41373",
   "name": "Activation threshold power consumption (unit ID 2/3)",
   "description": "Default 5 %.",
   "data_type": "INT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 0.001,
   "scale_factor_ref": null,
   "units": "%",
   "access": "RW",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 41375,
   "documented": "41375",
   "name": "Deactivation threshold power consumption (unit ID 2/3)",
   "description": "Default 5 %.",
   "data_type": "INT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 0.001,
   "scale_factor_ref": null,
   "units": "%",
   "access": "RW",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 44001,
   "documented": "44001",
   "name": "Soft start rate P (unit ID 2/3)",
   "description": "Active power soft-start ramp, 1-10000 %/min, default 1200.",
   "data_type": "UINT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 1,
   "scale_factor_ref": null,
   "units": "%/min",
   "access": "RW",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 44013,
   "documented": "44013",
   "name": "Soft start P after a grid fault (unit ID 2/3)",
   "description": "Enables the soft start after a grid fault.",
   "data_type": "UINT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 1,
   "scale_factor_ref": null,
   "units": "",
   "access": "RW",
   "values": {
    "303": "Off",
    "308": "On"
   },
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 44381,
   "documented": "44381",
   "name": "Nominal active power WMaxOut (unit ID 2/3)",
   "description": "Feed-in active power setting, e.g. 12000 W.",
   "data_type": "INT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 1,
   "scale_factor_ref": null,
   "units": "W",
   "access": "RW",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 44383,
   "documented": "44383",
   "name": "Nominal active power WMaxIn (unit ID 2/3)",
   "description": "Intake active power setting, -60000 to 0 W.",
   "data_type": "INT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 1,
   "scale_factor_ref": null,
   "units": "W",
   "access": "RW",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 44449,
   "documented": "44449",
   "name": "Maximum active power battery (unit ID 3)",
   "description": "Upper battery power bound, % of nominal; write together with 44451.",
   "data_type": "INT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 0.01,
   "scale_factor_ref": null,
   "units": "%",
   "access": "W",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 44451,
   "documented": "44451",
   "name": "Minimum active power battery (unit ID 3)",
   "description": "Lower battery power bound, % of nominal; write together with 44449.",
   "data_type": "INT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 0.01,
   "scale_factor_ref": null,
   "units": "%",
   "access": "W",
   "values": null,
   "bits": null,
   "offset": 0
  },
  {
   "table": "holding_register",
   "address": 44505,
   "documented": "44505",
   "name": "Limitation of active power in % (unit ID 2)",
   "description": "System active power limit; 0-100.00 %, default 100 %.",
   "data_type": "UINT32",
   "length": 2,
   "word_order": "ABCD",
   "scale": 0.01,
   "scale_factor_ref": null,
   "units": "%",
   "access": "RW",
   "values": null,
   "bits": null,
   "offset": 0
  }
 ],
 "integration": {
  "summary": "Activate the Modbus TCP server on the System Manager, disable its energy management if a third-party EMS will steer the batteries, then talk to each device on unit ID 3 (port 502). Set 40210 = 1079, 41195 = timeout and 44029 = 303 once, then write 44449 and 44451 together at a regular interval (SMA's example: once per second).",
  "minimum_registers": [
   {
    "table": "input_register",
    "address": 30845,
    "why": "Battery state of charge (%)"
   },
   {
    "table": "input_register",
    "address": 30955,
    "why": "Battery operating status"
   },
   {
    "table": "holding_register",
    "address": 40029,
    "why": "General operating status"
   },
   {
    "table": "holding_register",
    "address": 40210,
    "why": "Active power setpoint mode - must be 1079 for external battery control"
   },
   {
    "table": "holding_register",
    "address": 41195,
    "why": "External setpoint timeout (watchdog)"
   },
   {
    "table": "holding_register",
    "address": 44449,
    "why": "Battery power upper bound (%)"
   },
   {
    "table": "holding_register",
    "address": 44451,
    "why": "Battery power lower bound (%)"
   }
  ],
  "enable": "Log in to the user interface of the device configured as System Manager and activate its Modbus server (TCP only; no RTU or UDP). For direct battery control the energy management in the System Manager must be deactivated, after which the third-party EMS is responsible for battery and inverter protection (basic functions such as deep-discharge protection remain). Set CtlComMssMod to 'Apply fallback values' and FlbWMaxNom/FlbWMinNom to 0 in the parameters.",
  "watchdog": "41195 'Timeout for external setpoint' (1-1800 s, default 600 s) with 41193 choosing 'keep values' (2506, default) or 'use fallback values' (2507) when setpoints stop. SMA's battery procedure uses a 10 s timeout and resends 44449/44451 about once per second.",
  "quirks": [
   "All registers are 32-bit, high word first; always read/write both registers of a value in one request.",
   "No minus-one offset: request the ADR number as printed (unlike SMA's SunSpec profile on unit ID 126, which starts at 40001 = address 40000).",
   "44449 and 44451 are write-only S32 with two decimals (-100.00 % to +100.00 %); positive = discharge, negative = charge; write both in one 4-register FC16 request.",
   "Before the first write 44449/44451 read 8000 0000 8000 0000 (NaN); write zeros to return to neutral.",
   "44029 must be set to 303 (ramps off) for the battery procedure; this register is used in the TI's procedure but has no row in its tables, so it is not listed here."
  ],
  "setup": [
   "Connect over Ethernet to the System Manager's IP address, TCP port 502 by default (pick a free port 49152-65535 if changing).",
   "Unit ID 1 = communication product, 2 = system, 3 = each Sunny Tripower Storage X / Sunny Island X device.",
   "The correct country standard must be selected at commissioning before the Modbus grid-management functions work.",
   "Leave at least 1 s between transfers and transfer no more than five values at once; writes take about 1 s per parameter to be acknowledged."
  ],
  "gotchas": [
   "With energy management disabled the System Manager no longer protects the battery - the external EMS must.",
   "Resetting the product to defaults can disable the Modbus server; check it is still enabled afterwards.",
   "Read-only access needs no password once Modbus is enabled, so keep the Modbus port off the internet."
  ]
 },
 "page": "https://easymodbus.com/modbus-register-maps/sma/sunny-tripower-storage-x-sunny-island-x",
 "address_note": "address = 0-based Modbus wire (PDU) address; documented = as printed in the source.",
 "note": "Re-typed from the manufacturer's public documentation (see source) and verified against it. Registers vary by firmware and options; verify against the live device before writing."
}
