Summary
This spec covers the APC UPS-Link Communications Protocol — an ASCII-based control language over RS-232 ("smart signaling") used by APC by Schneider Electric Smart-UPS products (including the North America / 100/120/208 Vac voltage versions and their derivatives such as RM and XL). The protocol exposes UPS control (power on/off, battery test, bypass), status and power inquiry (line voltage, battery voltage, load, run time, hex-coded status registers), EEPROM customizing (transfer voltages, sensitivity, delays, alarms), and asynchronous alert messages (line fail, low battery, replace battery, abnormal condition). A Measure-UPS accessory extends the command set with ambient temperature, humidity, contact-closure, and alarm-limit commands. This spec applies to all Smart-UPS models that support smart signaling via the computer interface port; it does NOT cover "standard" contact-closure signaling.
Transport
protocols:
- serial
serial:
baud_rate: 2400 # source §2.1: "Baud Rate: 2400 bits/second"
data_bits: 8 # source §2.1: "Bits Per Character: 8"
parity: none # source §2.1: "Parity: none"
stop_bits: 1 # source §2.1: "Stop Bits: 1"
flow_control: none # source §2.1: "Handshaking, flow control: none"
auth:
type: none # inferred: no auth procedure in source
# Notes from source §2.1 / §3.0:
# - Terminal type: ANSI.
# - Computer interface port pin-out is nonstandard; use only APC-supplied
# or APC-authorized UPS monitoring cables.
# - To enter smart mode, host must send ASCII uppercase "Y" after UPS turn-on;
# UPS responds with "SM". Until then the UPS is in standard signaling mode.
# - All command responses are followed by CR/LF.
# - Asynchronous alert messages are NOT followed by CR/LF.
# - Minimum time between transmissions: see source Appendix I (not reproduced
# in refined excerpt).
# port: N/A # serial-only device; no TCP/UDP/HTTP transport described in source
Traits
traits:
- powerable # inferred: K/K, S, Z/Z, @ddd, Ctrl N (turn on/off commands present)
- queryable # inferred: X, >, <, G, V, g, f, 9, Q, ~, ', 8, 7, n, m, j, y, a, b, Ctrl A, /, \, B, C, F, L, M, N, O, P, t, h, v, i, J (query commands present)
- testable # inferred: A, W, D (self-test / calibration commands present) - non-standard trait, retained because UPS-Link is explicitly test-oriented
# routable: N/A (no input/output routing commands in source)
# levelable: N/A (no continuous level set commands; EEPROM edit cycles through fixed enum lists)
Actions
# All opcodes documented in source §3.1-§3.5 and §4.1-§4.3 are enumerated.
# Per coverage rule, each distinct opcode/mnemonic = ONE action. Parameter
# ranges and enum lists inside one opcode do NOT multiply into separate
# actions (e.g. the "u" upper-transfer-voltage list of per-voltage-version
# values is one parameterized action, not N rows).
# `kind` values used: action | query | setting | modifier.
# Source §3.0: "Commands sent to a UPS must be in the case (upper or lower)
# indicated in each command description." OpCodes below preserve source case.
# ----- §3.1 UPS Control Commands -----
- id: set_smart_mode
label: Set UPS to Smart Mode
kind: action
command: "Y"
params: []
response: "SM"
notes: "Must be sent when UPS is turned on to enter smart signaling mode. Disables standard signaling outputs."
- id: test_lights_beeper
label: Test Lights and Beeper
kind: action
command: "A"
params: []
response: "OK"
notes: "Illuminates all front panel LEDs and sounds beeper for 2 seconds."
- id: turn_off_after_delay
label: Turn Off after Delay
kind: action
command: "K(>1.5s)K"
params: []
response: "OK | * | NA"
notes: "Two uppercase 'K' chars with >1.5 s delay between them. Turns off using Shutdown Delay (p command). Not supported on Smart-UPS 250/400/370ci."
- id: shutdown_on_battery
label: Shut Down UPS on Battery
kind: action
command: "S"
params: []
response: "OK | NA"
notes: "Only honored while on-battery. Output returns when utility restored. Following commands return NA: K(>1.5s)K, U, W, Z(>1.5s)Z, @ddd, -."
- id: simulate_power_failure
label: Simulate Power Failure
kind: action
command: "U"
params: []
response: "OK | NA"
notes: "Forces brief switch to battery operation."
- id: battery_test
label: Battery Test
kind: action
command: "W"
params: []
response: "OK | NA"
notes: "Runs ~8 s battery test. Result saved 5 min for retrieval via X command. Auto-test scheduling via E command."
- id: turn_off_immediate
label: Turn Off UPS
kind: action
command: "Z(>1.5s)Z"
params: []
response: "OK | * | NA"
notes: "Two uppercase 'Z' chars with >1.5 s delay. Immediate turn-off. Not supported on Smart-UPS 250/400/370ci."
- id: shutdown_delayed_wake
label: Shut Down with Delayed Wake Up
kind: action
command: "@{tenths}"
params:
- name: tenths
type: integer
description: "Wake-up delay in tenths of an hour (3 ASCII digits ddd). e.g. @126 = restart after 12.6 h."
response: "OK | * | NA"
notes: "Turns off per Shutdown Delay (p), then restores load after ddd tenths of an hour plus Turn On Delay (r). UPS ignores invalid (non-numeric) chars after '@'."
- id: abort_shutdown
label: Abort Shutdown
kind: action
command: "DEL"
params: []
response: "OK | NO"
notes: "ASCII DEL char. Aborts @ddd, S, and K(>1.5s)K (K abort only during the delay). Valid on Matrix-UPS and newer Smart-UPS."
- id: run_time_calibration
label: Run Time Calibration
kind: action
command: "D"
params: []
response: "OK | NO | NA"
notes: "Discharges to <25% capacity (<35% on Matrix-UPS). Begins only if battery = 100%; else 'NO'. Send D again to abort. Not on Smart-UPS v/s or Back-UPS Pro."
- id: ups_to_bypass_toggle
label: UPS to Bypass Toggle
kind: action
command: "^"
params: []
response: "BYP | INV | ERR"
notes: "Toggles between on-line and bypass. BYP = transferring to bypass; INV = returning to inverter; ERR = unable. Matrix-UPS only."
- id: turn_ups_on
label: Turn UPS On
kind: action
command: "Ctrl N(>1.5s)Ctrl N"
params: []
notes: "Ctrl+N or Ctrl+n twice with >1.5 s delay. Equivalent to pressing front ON button. Newer Smart-UPS only."
- id: return_to_simple_mode
label: Return to Simple Mode
kind: action
command: "R"
params: []
response: "BYE"
notes: "Forces UPS out of Smart mode. Send Y to re-enter. Valid on 3G Smart-UPS, Smart-UPS v/s, Back-UPS Pro. Not valid on Matrix-UPS."
# ----- §3.2 UPS Status Inquiry Commands -----
- id: battery_test_result
label: Battery Test Result
kind: query
command: "X"
params: []
response: "OK | BT | NG | NO"
notes: "OK=good, BT=fail (insufficient capacity), NG=invalid (overload), NO=no result available."
- id: num_battery_packs
label: Number of Battery Packs
kind: query
command: ">"
params: []
response: "ddd (3-digit count)"
notes: "Inquiry form. Valid only on UPSs that auto-sense SmartCell packs (Matrix-UPS). For 3G Smart-UPS XL manual config, see 'battery_pack_config' which shares the '>' opcode."
- id: num_bad_battery_packs
label: Number of Bad Battery Packs
kind: query
command: "<"
params: []
response: "ddd (3-digit count)"
notes: "Matrix-UPS only."
- id: transfer_cause
label: Transfer Cause
kind: query
command: "G"
params: []
response: "R | H | L | T | O | S"
notes: "R=rate-of-change, H=high line, L=low line, T=notch/spike, O=none yet, S=command/test induced."
- id: firmware_version
label: Firmware Version
kind: query
command: "V"
params: []
response: "3-char alphanumeric"
notes: "Char 1 = base model type, char 2 = firmware letter (3G Smart-UPS = 'W'), char 3 = utility voltage version. Not on Smart-UPS v/s or Back-UPS Pro."
- id: nominal_battery_voltage
label: UPS Nominal Battery Voltage Rating
kind: query
command: "g"
params: []
response: "ddd (3-digit, e.g. 024/018/048)"
- id: battery_capacity
label: Battery Capacity
kind: query
command: "f"
params: []
response: "ddd.d (percent of full charge)"
- id: acceptable_line_quality
label: Acceptable Line Quality
kind: query
command: "9"
params: []
response: "FF | 00"
notes: "FF=acceptable utility line quality, 00=unacceptable."
- id: ups_status_register
label: UPS Status (Q register)
kind: query
command: "Q"
params: []
response: "2-hex (8-bit register)"
notes: "Bits: 7=replace battery, 6=low battery, 5=overloaded, 4=on-battery, 3=on-line, 2=SmartBoost, 1=SmartTrim, 0=run time calibration running."
- id: state_register
label: State Register (~)
kind: query
command: "~"
params: []
response: "2-hex (8-bit register)"
notes: "Bits 7/6 reported by 3G Smart-UPS, v/s, Back-UPS Pro; full bit set only on Matrix-UPS. See source table §3.2."
- id: trip1_register
label: Trip1 Register
kind: query
command: "'"
params: []
response: "2-hex (8-bit register)"
notes: "Apostrophe opcode. Mainly fault conditions (bad output V, relay faults, fan failures). Matrix-UPS reports all bits except 7,6."
- id: trip_register
label: Trip Register
kind: query
command: "8"
params: []
response: "2-hex (8-bit register)"
notes: "Bits: over-temp, bypass relay fault, charger failure, S-shutdown, @ddd-sleep, main relay fault, overload-blocked-transfer, low-battery shutdown."
- id: dip_switch_position
label: DIP Switch Position
kind: query
command: "7"
params: []
response: "2-hex (8-bit register)"
notes: "Bits 3-0 map to option switches 1-4. Models without DIP switches return '00'."
- id: ups_serial_number
label: UPS Serial Number
kind: query
command: "n"
params: []
response: ">=8 chars (12 chars on newer Smart-UPS)"
- id: ups_manufacture_date
label: UPS Manufacture Date
kind: query
command: "m"
params: []
response: "dd/mm/yy (8 chars)"
- id: run_time_remaining
label: Run Time Remaining
kind: query
command: "j"
params: []
response: "dddd: (minutes)"
notes: "Returns '>>>>:' when undeterminable."
- id: copyright
label: Copyright
kind: query
command: "y"
params: []
response: "(C) APCC"
notes: "Validates UPS as genuine APC. Requires firmware letter later than 'O'."
- id: all_commands_available
label: All Commands Available from UPS
kind: query
command: "a"
params: []
response: "x.x.x.x[,]x.x.x.x"
notes: "Format: 'UPS-Link level'.'async chars'.'single-char commands'."
- id: version_in_decimal
label: Version in Decimal
kind: query
command: "b"
params: []
response: "xxx.xxx.x"
notes: "Fields: SKU.firmware.country_code (I/D/A/M/J)."
- id: ups_model_name
label: UPS Model
kind: query
command: "Ctrl A"
params: []
response: "<32-char ASCII model name"
# ----- §3.3 UPS Power Inquiry Commands -----
- id: load_current
label: Load Current
kind: query
command: "/"
params: []
response: "dd.dd (true RMS amps)"
notes: "Matrix-UPS only."
- id: apparent_load_power
label: Apparent Load Power
kind: query
command: "\\"
params: []
response: "ddd.dd (percent of rated VA)"
notes: "Matrix-UPS only."
- id: battery_voltage
label: Battery Voltage
kind: query
command: "B"
params: []
response: "dd.dd (Vdc)"
- id: ups_internal_temperature
label: UPS Internal Temperature
kind: query
command: "C"
params: []
response: "ddd.d (°C)"
- id: operating_frequency
label: UPS & Utility Operating Frequency
kind: query
command: "F"
params: []
response: "dd.dd (Hz)"
- id: line_voltage
label: Line Voltage
kind: query
command: "L"
params: []
response: "ddd.d (Vac input)"
- id: max_line_voltage
label: Maximum Line Voltage
kind: query
command: "M"
params: []
response: "ddd.d (Vac)"
notes: "Max since previous M query."
- id: min_line_voltage
label: Minimum Line Voltage
kind: query
command: "N"
params: []
response: "ddd.d (Vac)"
notes: "Min since previous N query."
- id: output_voltage
label: Output Voltage
kind: query
command: "O"
params: []
response: "ddd.d (Vac)"
- id: load_power
label: Load Power
kind: query
command: "P"
params: []
response: "ddd.d (percent of rated W)"
# ----- §3.4 UPS Customizing Commands -----
- id: read_all_eeprom
label: Read All Configurable EEPROM Parameters
kind: query
command: "Ctrl Z"
params: []
response: "#dddddddd... (multi-item string)"
notes: "Matrix-UPS and newer Smart-UPS only. Format described in source §3.4."
- id: reset_eeprom
label: Reset UPS EEPROM Variables
kind: action
command: "z"
params: []
response: "CLEAR"
notes: "Restores defaults for all customizing commands except c and x."
- id: edit_next
label: Edit (advance to next setting)
kind: modifier
command: "-"
params: []
response: "OK | NO | NA"
notes: "Sent immediately after a customizing command (u/l/o/s/q/k/p/r/e/E/w/[/]/{/}/I) to advance to the next enum value. After 'c' or 'x', allows direct ASCII entry. Disallowed when any option switch is OFF (except DIP #4 on 250/370ci/400)."
- id: output_voltage_selection
label: Output Voltage Selection
kind: setting
command: "Ctrl V"
params: []
response: "A | M | I"
notes: "A=auto, M=208 Vac, I=240 Vac. Matrix-UPS only; newer Smart-UPS returns NA."
- id: front_panel_language
label: Front Panel Language Selection
kind: setting
command: "Ctrl L"
params: []
response: "E | F | G | S | 1 | 2 | 3 | 4"
notes: "E=English, F=French, G=German, S=Spanish. Matrix-UPS only."
- id: auto_battery_test_setting
label: Automatic Battery Test
kind: setting
command: "E"
params: []
response: "336 | 168 | ON | OFF"
notes: "336=every 14 days, 168=every 7 days, ON=upon startup, OFF=none. 'ON' has trailing space."
- id: ups_id
label: UPS ID
kind: setting
command: "c"
params:
- name: name
type: string
description: "Exactly 8 ASCII chars (use spaces if needed). Hyphen '-' not allowed. Set via Edit (-) then direct entry."
response: "8-char string | OK (after edit)"
- id: battery_replacement_date
label: Battery Replacement Date
kind: setting
command: "x"
params:
- name: date
type: string
description: "8 chars dd/mm/yy. Set via Edit (-) then direct entry."
response: "dd/mm/yy | OK (after edit)"
- id: upper_transfer_voltage
label: Upper Transfer Voltage
kind: setting
command: "u"
params: []
response: "3-digit Vac (per-version enum list)"
notes: "Enum list varies by utility voltage version (100/120/208/220-240 Vac, plus Matrix-UPS configs). See source table §3.4."
- id: lower_transfer_voltage
label: Lower Transfer Voltage
kind: setting
command: "l"
params: []
response: "3-digit Vac (per-version enum list)"
notes: "Not valid on Matrix-UPS (returns NO)."
- id: min_battery_capacity_restart
label: Minimum Battery Capacity to Restart
kind: setting
command: "e"
params: []
response: "00 | 15 | 50 | 90 (newer Smart-UPS) OR 00 | 10 | 25 | 90 (other models)"
notes: "Percent of full capacity. Not valid on Matrix-UPS (returns NO)."
- id: output_voltage_setting
label: Output Voltage
kind: setting
command: "o"
params: []
response: "3-digit Vac"
notes: "100/120/208 Vac versions return fixed '100'/'115'/'208'. 220-240 Vac configurable: 225/230/240/220."
- id: utility_failure_sensitivity
label: Utility Failure Sensitivity
kind: setting
command: "s"
params: []
response: "H | M | L | A"
notes: "H/M/L on Smart-UPS (L repeated as 4th); A=auto-adjust on Matrix-UPS only."
- id: low_battery_warning
label: Low Battery Warning Interval
kind: setting
command: "q"
params: []
response: "02 | 05 | 07 | 10 (minutes)"
- id: audible_alarm
label: Audible Alarm
kind: setting
command: "k"
params: []
response: "0 | T | L | N"
notes: "0=immediate, T=delayed 30 s on utility fail, L=low-battery only, N=disabled."
- id: shutdown_delay
label: Shutdown Delay
kind: setting
command: "p"
params: []
response: "020 | 180 | 300 | 600 (seconds)"
- id: turn_on_delay
label: Turn On Delay
kind: setting
command: "r"
params: []
response: "000 | 060 | 180 | 300 (seconds)"
- id: run_time_conservation
label: Run Time Conservation
kind: setting
command: "w"
params: []
response: "NO | 02 | 05 | 08 (minutes after low-battery warning)"
notes: "Matrix-UPS only."
- id: battery_pack_config
label: Battery Pack Configuration
kind: setting
command: ">"
params: []
response: "new count | NA"
notes: "Shares '>' opcode with num_battery_packs inquiry. For 3G Smart-UPS XL that cannot auto-sense: send '>' then '+'/'-' (Edit) to increment/decrement count by 1 and return the new setting."
# ----- §4.1 Measure-UPS Inquiry Commands -----
# (Accessory; pass-through only when a Measure-UPS is connected downstream.)
- id: ambient_temperature
label: Ambient Temperature
kind: query
command: "t"
params: []
response: "dd.dd (°C, Measure-UPS)"
notes: "Measure-UPS accessory. Not on Smart-UPS v/s."
- id: humidity
label: Humidity
kind: query
command: "h"
params: []
response: "ddd.d (% RH, Measure-UPS)"
- id: measureups_firmware
label: Measure-UPS Firmware Version
kind: query
command: "v"
params: []
response: "3-char (model '4' + firmware letter + 'x')"
notes: "Measure-UPS accessory."
- id: dip_external_contact_status
label: DIP Switch & External Contact Status
kind: query
command: "i"
params: []
response: "2-hex (8-bit register, Measure-UPS)"
notes: "Bits 7-4 = contact inputs #4-#1 (0=open,1=closed); bits 3-0 = DIP switches #4-#1 (0=NO,1=NC)."
- id: alarm_status
label: Alarm Status
kind: query
command: "J"
params: []
response: "2-hex (8-bit register, Measure-UPS)"
notes: "Temp/humidity limits exceeded + per-channel contact alarm states."
# ----- §4.2 Measure-UPS Customizing Commands -----
# Note: "-" Edit opcode is shared with UPS customizing; see edit_next above.
- id: upper_temp_alarm_limit
label: Upper Temperature Alarm Limit
kind: setting
command: "["
params: []
response: "32.13 | 45.90 | 54.06 | 23.97 (°C, Measure-UPS)"
- id: lower_temp_alarm_limit
label: Lower Temperature Alarm Limit
kind: setting
command: "]"
params: []
response: "04.08 | 09.94 | 14.02 | 18.10 (°C, Measure-UPS)"
- id: upper_rh_alarm_limit
label: Upper Relative Humidity Alarm Limit
kind: setting
command: "{"
params: []
response: "070.0 | 080.0 | 084.5 | 090.1 (% RH, Measure-UPS)"
- id: lower_rh_alarm_limit
label: Lower Relative Humidity Alarm Limit
kind: setting
command: "}"
params: []
response: "010.0 | 020.1 | 030.2 | 040.3 (% RH, Measure-UPS)"
- id: alarm_enable
label: Alarm Enable
kind: setting
command: "I"
params:
- name: mask
type: string
description: "2-hex byte; bit=1 enables alarm for that condition. Bit 7=upper temp, 6=lower temp, 5=upper RH, 4=lower RH, 3-0=contact channels #4-#1."
response: "2-hex current mask | OK (after valid edit)"
notes: "Set via Edit (-) then 2-hex entry. Measure-UPS ignores invalid hex."
Feedbacks
# Discrete query responses (also see Actions with kind: query for full opcode set).
# Below: observable state values most useful for control-loop feedback.
- id: power_state
type: enum
values: [on_line, on_battery, bypass, sleep, off]
source_query: ups_status_register # Q command bits 4/3 + state_register ~ bits
- id: battery_test_state
type: enum
values: [ok, failed, invalid_overload, no_result]
source_query: battery_test_result # X command
- id: transfer_cause_state
type: enum
values: [rate_of_change, high_line, low_line, notch_spike, none, command_test]
source_query: transfer_cause # G command
- id: line_quality_state
type: enum
values: [acceptable, unacceptable]
source_query: acceptable_line_quality # 9 command
- id: battery_capacity_percent
type: number
unit: percent
source_query: battery_capacity # f command
- id: run_time_remaining_minutes
type: number
unit: minutes
source_query: run_time_remaining # j command
- id: line_voltage_vac
type: number
unit: Vac
source_query: line_voltage # L command
- id: output_voltage_vac
type: number
unit: Vac
source_query: output_voltage # O command
- id: battery_voltage_vdc
type: number
unit: Vdc
source_query: battery_voltage # B command
- id: internal_temperature_c
type: number
unit: degC
source_query: ups_internal_temperature # C command
- id: load_power_percent
type: number
unit: percent
source_query: load_power # P command
- id: status_register_q
type: hex_byte
bit_map:
bit7: replace_battery_condition
bit6: low_battery_condition
bit5: overloaded_output
bit4: on_battery_mode
bit3: on_line_mode
bit2: smart_boost_mode
bit1: smart_trim_mode
bit0: run_time_calibration_running
source_query: ups_status_register # Q
- id: trip_register_8
type: hex_byte
bit_map:
bit7: fault_internal_over_temperature
bit6: fault_bypass_relay_malfunction
bit5: fault_battery_charger_failure
bit4: shutdown_via_S_command
bit3: sleep_via_at_ddd_command
bit2: fault_main_relay_malfunction
bit1: unable_to_transfer_on_battery_overload
bit0: output_unpowered_low_battery_shutdown
source_query: trip_register # 8
- id: trip1_register
type: hex_byte
source_query: trip1_register # '
notes: "Fault conditions; bit map per source §3.2."
- id: state_register
type: hex_byte
source_query: state_register # ~
notes: "Bypass / ready-to-power state; bit map per source §3.2."
- id: dip_switch_register
type: hex_byte
source_query: dip_switch_position # 7
# UNRESOLVED: Measure-UPS feedback values (t/h/J/i) share the same opcode shapes
# as their Actions; their typed Feedbacks can be added when a Measure-UPS target
# is in scope.
Variables
# Settable EEPROM parameters are modeled as Actions (kind: setting) above because
# each has a dedicated opcode and is exercised via the Edit (-) modifier. No
# additional free-floating variables are documented in the source.
# UNRESOLVED: source does not document a separate variable-address space beyond
# the EEPROM customizing commands.
Events
# Asynchronous alert messages from source §3.5 (UPS) and §4.3 (Measure-UPS).
# Per source §3.0 these are NOT followed by CR/LF and do NOT interrupt any
# command currently being processed.
- id: line_fail
opcode: "!"
description: "UPS transferred to on-battery operation. Repeated every 30 s during extended outage until low battery."
- id: return_from_line_fail
opcode: "$"
description: "UPS returned from on-battery. Sent only if '!' was sent first."
- id: low_battery
opcode: "%"
description: "Low battery condition. Not on Smart-UPS v/s or Back-UPS Pro."
- id: return_from_low_battery
opcode: "+"
description: "Battery recharged to sufficient capacity. Sent only if '%' was sent first."
- id: abnormal_condition
opcode: "?"
description: "UPS entered abnormal state (overload shutdown, low-battery shutdown, PC reboot). Also auto-sent within 10 min of turn-on."
- id: return_from_abnormal_condition
opcode: "="
description: "UPS recovered from abnormal condition. Sent only if '?' was sent first; not sent after the turn-on '?'."
- id: ups_about_to_turn_load_off
opcode: "*"
description: "UPS commanded to turn off; no further commands processed. Not on newer Smart-UPS, v/s, or Back-UPS Pro."
- id: replace_battery
opcode: "#"
description: "Battery test found replace-battery condition. Repeats every 5 h until new test passes or UPS turned off."
- id: eeprom_variable_change
opcode: "|"
description: "Any UPS EEPROM variable changed via Customizing Commands. Newer Smart-UPS and Matrix-UPS only."
- id: measureups_alarm
opcode: "&"
description: "Measure-UPS: ambient temp/humidity outside limits, or a contact-closure input changed from its normal state. Sent every 2 min while alarm condition exists. Cause via J query."
Macros
# No multi-step command sequences are formally defined in the source beyond
# the implicit enter-smart-mode handshake (Y -> SM) and the per-customizing-
# command Edit (-) sequence. These are documented inline on the relevant
# Actions rather than as named macros.
# UNRESOLVED: source does not define higher-level scripted sequences.
Safety
confirmation_required_for:
- turn_off_after_delay # K(>1.5s)K - removes load power
- turn_off_immediate # Z(>1.5s)Z - removes load power immediately
- shutdown_on_battery # S - removes load power
- shutdown_delayed_wake # @ddd - removes load power on a timer
- simulate_power_failure # U - forces on-battery
- run_time_calibration # D - discharges battery below 25%
- ups_to_bypass_toggle # ^ - bypasses inverter protection
- turn_ups_on # Ctrl N(>1.5s)Ctrl N - energizes output
- reset_eeprom # z - restores defaults; may change transfer voltages / alarms
interlocks:
- "Y command must be sent after UPS turn-on before any other command is accepted in smart mode (source §3.0)."
- "shutdown_on_battery (S) is honored only while on-battery; following commands return NA: K(>1.5s)K, U, W, Z(>1.5s)Z, @ddd, - (source §3.1 'S')."
- "Edit (-) is disallowed when any DIP option switch is OFF, except DIP #4 on Smart-UPS 250/370ci/400 which may be in any position (source §3.4)."
- "Matrix-UPS battery charger is disabled when shut off via K(>1.5s)K or Z(>1.5s)Z; do not operate Matrix-UPS in this mode for extended periods or batteries may discharge (source §3.1)."
- "Automatic turn-on feature on Smart-UPS 400 and UPS 370ci must be disabled via option switch for S and @ddd commands to take effect (source §3.1)."
- "Use only APC-supplied or APC-authorized UPS monitoring cables; the computer interface port pin-out is nonstandard (source §2.1)."
- "Source §2.0: use ONLY the commands documented in this specification; any others are APC-internal and can produce unintended results."
# UNRESOLVED: source does not provide formal power-on sequencing voltage/timing
# specs; only operational interlocks are documented.
Notes
- Voltage-version scope. Source targets all APC UPSs supporting smart signaling. The 1st-character model table in §3.2 ("V" command) enumerates Smart-UPS 250/400/600/900/1250/2000 and 3G 450/700/1000/1400/2200/3000 (plus RM/XL derivatives) and Matrix-UPS 3000/5000. The 3rd-character voltage table covers 100/120/208/220-230-240 Vac. "Smart UPS (North America)" most plausibly maps to the 100/120/208 Vac columns; confirm against the actual SKU before relying on per-version enum lists (u, l, o).
- Protocol entry handshake. Host must send ASCII uppercase
Yafter UPS turn-on; UPS respondsSM. Until then the UPS is in standard signaling mode and smart commands are ignored. A stray?alert is auto-sent at turn-on. - Case sensitivity. Commands must be sent in the exact case documented (e.g.
S≠s,c≠C). Responses are uppercase except forc,n,m,xwhich may be mixed case. - Line endings. Command responses are CR/LF-terminated; asynchronous alerts are NOT CR/LF-terminated.
- Timing.
K(>1.5s)K,Z(>1.5s)Z,Ctrl N(>1.5s)Ctrl Nrequire >1.5 s between the two characters or the UPS will not recognize the command; any other command interleaved invalidates the sequence. - Measure-UPS accessory. Commands in §4.x (t, h, v, i, J, [, ], {, }, I, &) apply only when a Measure-UPS accessory is connected downstream. The Measure-UPS passes through all §3.x UPS commands.
- Model exclusions. Many commands are explicitly unavailable on Smart-UPS v/s, Back-UPS Pro, Smart-UPS 250/400/370ci, or Matrix-UPS; see per-action
notes. - Quirks.
@dddignores invalid (non-numeric) chars after@and must be retried.j(run time) may return>>>>:when undeterminable.c/xcannot be reset byzand cannot contain-.
Provenance
source_domains:
- manuals.zedt.eu
- store.controlworks.com
source_urls:
- http://manuals.zedt.eu/apc-sua-ups/UPS-Link_Protocol_Specification.pdf
- https://store.controlworks.com/product_resources/documentation/APC_SmartUPS_Module_Help_v1.pdf
retrieved_at: 2026-06-14T21:11:17.558Z
last_checked_at: 2026-06-16T07:00:46.449Z
Verification Summary
verdict: verified
checked_at: 2026-06-16T07:00:46.449Z
matched_actions: 72
action_count: 72
confidence: medium
summary: "All 72 spec actions matched verbatim in the source and the source's full 72-command catalogue is completely covered; transport parameters confirmed in 2.1. (11 unresolved item(s) noted in Known Gaps.)"
Known Gaps
- "exact Smart-UPS model SKUs covered by the \"Smart UPS (North America)\" family are not enumerated in the source; the source lists reference models (250/400/600/900/1250/2000 and 3G 450/700/1000/1400/2200/3000 plus RM/XL derivatives) as examples only."
- "source notes UPS-Link applies to all APC products supporting smart signaling; applicability to SURTD/SRT/SMX/SMT without AP9620 LCC is not addressed here."
- "Measure-UPS feedback values (t/h/J/i) share the same opcode shapes"
- "source does not document a separate variable-address space beyond"
- "source does not define higher-level scripted sequences."
- "source does not provide formal power-on sequencing voltage/timing"
- "firmware-version compatibility matrix per command (source only states \"not available on v/s or Back-UPS Pro\" qualitatively; no version ranges)."
- "actual SKU list for \"Smart UPS (North America)\" family — source gives reference models only."
- "minimum time between transmissions (source defers to Appendix I, not present in refined excerpt)."
- "ACK/NAK timing budgets and command-queue depth — not specified."
- "whether this UPS-Link spec also applies to SURTD/SRT/SMX/SMT without AP9620 LCC (see recovery notes)."
From the AI4AV catalog (https://ai4av.net) · ODbL-1.0