Skip to content

String Array Datatype

Stephen Chryn edited this page Aug 3, 2026 · 1 revision

String Array Datatype

SSTRINGARRAY is a fixed-size array of short CIP strings. It follows the same list-operation conventions as the other array types, with one difference: the empty slot sentinel is "" (an empty string).

Type Accessor Element type Max element length
SSTRINGARRAY actions.sstringarray SSTRING 82 chars
from ethernetip_emulator.server.device import actions

# Tag definition
("O_Labels", actions.type.SSTRINGARRAY(["", "", "", ""]))
("O_Queue",  actions.type.SSTRINGARRAY(["A", "B", "", ""]))

Slot Convention

An empty slot is any element that equals "" (empty string). A non-empty string of any length is considered occupied. There is no tolerance — the comparison is an exact equality check.

  • "" → empty slot ✓
  • " " (single space) → occupied
  • "0" → occupied

Core Read / Write

get_val(name, key?)

Returns the full array or a sub-range as a list[str].

Parameter Type Default Description
name str — Tag name.
key slice | None full array Sub-range to read.
actions.sstringarray.get_val("O_Queue")               # → ["A", "B", "", ""]
actions.sstringarray.get_val("O_Queue", slice(0, 2))  # → ["A", "B"]

set_val(name, value, key?)

Writes a list of strings to the array or a sub-range.

Parameter Type Default Description
name str — Tag name.
value list[str] — Values to write.
key slice | None full array Sub-range to write.
actions.sstringarray.set_val("O_Queue", ["A", "B", "", ""])
actions.sstringarray.set_val("O_Queue", ["C"], slice(2, 3))  # write only index 2

Inspection

size(name)

Returns the total number of elements, or None if the tag does not exist.

actions.sstringarray.size("O_Queue")   # → 4

count(name, key?)

Returns the number of non-empty elements.

# ["A", "B", "", ""]
actions.sstringarray.count("O_Queue")   # → 2

is_full(name, key?)

Returns True if every element is a non-empty string.

actions.sstringarray.is_full("O_Queue")   # → False

is_empty(name, key?)

Returns True if every element is "".

actions.sstringarray.is_empty("O_Queue")   # → False

find(name, value, key?)

Returns the zero-based index of the first element that exactly matches value, or None if not found.

# ["A", "B", "", ""]
actions.sstringarray.find("O_Queue", "B")    # → 1
actions.sstringarray.find("O_Queue", "Z")    # → None

List Operations

append(name, value, key?)

Writes value into the first "" slot (scanning left to right). Returns True on success, False if no empty slot is available.

# ["A", "B", "", ""]
actions.sstringarray.append("O_Queue", "C")   # → True
# ["A", "B", "C", ""]

prepend(name, value, key?)

Writes value into the last "" slot (scanning right to left). Returns True on success, False if no empty slot is available.

# ["A", "B", "C", ""]
actions.sstringarray.prepend("O_Queue", "D")   # → True
# ["A", "B", "C", "D"]

pop(name, key?)

Clears (sets to "") the last non-empty element and returns its value. Returns None if all elements are "".

# ["A", "B", "C", "D"]
actions.sstringarray.pop("O_Queue")   # → "D"
# ["A", "B", "C", ""]

insert(name, index, value, key?)

Inserts value at index, shifting all subsequent elements one position to the right. The last element is lost if the array is full. Returns False if there is no room (last element is non-empty), True on success.

# ["A", "B", "C", ""]
actions.sstringarray.insert("O_Queue", 1, "X")   # → True
# ["A", "X", "B", "C"]

remove(name, index, key?)

Removes the element at index, shifting subsequent elements one position to the left. The last element is set to "". Returns the removed value, or None if the element at index was already "".

# ["A", "X", "B", "C"]
actions.sstringarray.remove("O_Queue", 1)   # → "X"
# ["A", "B", "C", ""]

Bulk Mutations

clear(name, key?)

Sets all elements (or a sub-range) to "".

actions.sstringarray.clear("O_Queue")
# ["", "", "", ""]

Listening for Changes

on_change defaults to the full array slice when no key is provided.

# Fires when any element in the array is written
@actions.sstringarray.on_change("O_Queue")
def any_changed(attr, key, value):
    print(f"Queue updated: {actions.sstringarray.get_val('O_Queue')}")

# Fires only when index 0 is written
@actions.sstringarray.on_change("O_Queue", key=slice(0, 1))
def slot_0_changed(attr, key, value):
    print(f"Slot 0 is now '{value[0]}'")

See Working with Actions for full documentation on key and defer.

Method Reference

Method Description
get_val(name, key?) Read the full array or a sub-range as list[str]
set_val(name, value, key?) Write a list of strings to the array or a sub-range
size(name) Return the total number of elements
count(name, key?) Count non-empty elements
is_full(name, key?) True if all elements are non-empty strings
is_empty(name, key?) True if all elements are ""
find(name, value, key?) Return the index of the first exactly matching element
append(name, value, key?) Write into the first "" slot
prepend(name, value, key?) Write into the last "" slot
pop(name, key?) Clear and return the last non-empty element
insert(name, index, value, key?) Insert at index, shifting right
remove(name, index, key?) Remove at index, shifting left
clear(name, key?) Set all elements to ""
on_change(name, callback?, key?, defer?) Register a change listener

Clone this wiki locally