Architecture

The SLM server is a RAD application: a SCXML state machine drives a set of action groups, the OLDB holds the live state, and a status topic is published for the Supervisor.

State Machine

The state machine is defined in slm/framework/resource/config/ifw/slm/sm.xml. Its top-level structure is:

  • On

    • NotOperational

      • NotReady — initial state; Init moves to Ready.

      • ReadyEnable moves to Operational.

    • Operational

      • Idle — the SLM is enabled but loops are not running; RunSlm moves to Running.

      • Running — a parallel region. One orthogonal region dispatches the loop commands; one region per loop holds the loop sub-states:

        • OpenLoop — the loop is idle (not cycling).

        • CloseLoop — the loop is active; a timer posts a Trigger every period_sec which runs one cycle (IdleCycle).

        • Suspended — cycling is paused; Resume returns to CloseLoop.

StopSlm returns to Idle; Disable / Stop return to NotOperational. Leaving Running re-opens every loop (see Loop state reset below).

Action Groups and Activities

  • ActionMgr (actionMgr.cpp) creates and registers every action group and the per-loop execute activities. The action names referenced in sm.xml map to methods registered here.

  • ActionsLM routes the loop commands (CloseLoop/OpenLoop/ SuspendLoop/ResumeLoop/RunSlm/StopSlm) and implements the concise GetStatus reply.

  • BaseLoopActions / BaseLoopCloseActions / BaseLoopSuspendedActions implement the per-loop behaviour for the OpenLoop / CloseLoop / Suspended sub-states. ActionsLoopClose<N> adds the period timer.

  • BaseLoopExecuteActivity runs the user control logic on a separate, killable thread. Its DoExecute() method is the extension point; on return it signals success or error through the LoopCompletionHandler.

Loop State and the OLDB

Per-loop runtime state is written to the OLDB under <oldb_uri_prefix><modname>/sl/loop_<N>/<key>:

Key

Meaning

state

1 = OPEN, 2 = CLOSED, 3 = SUSPENDED

active

true while the loop is closed

timer_period_sec

configured cycle period

cycle_counter

number of cycles started

cycle_nsuccess

successful executions since server start

cycle_nerrors

consecutive failures (reset on success)

cycle_failure

true if the last cycle failed

cycle_last

timestamp of the last execution

cycle_start

timestamp when the loop entered closed-loop (cycling)

cycle_last_success

timestamp of the last successful execution

cycle_last_error

description of the last failure

cycle_value

last value published by the loop

New keys must also be initialised in OldbInterface::InitializeLoopRuntimeState.

Loop state reset

The SLM only enters a loop’s OpenLoop sub-state when it (re-)enters Running. To avoid stale CLOSED loops after the SLM stops, StopSlm and every other exit from Running call ResetAllLoopStates(), which sets each enabled loop back to OPEN and clears its cycle counters.

Auto-open on errors

When a cycle fails, cycle_nerrors is incremented. Once it reaches the loop’s configured max_errors (default 3), the loop is automatically opened and the failure is logged. A successful cycle resets the counter.

Status and the Supervisor

The server decomposes its SCXML status into a summarised state and substate and exposes it three ways:

  • OLDB: mon/state, sm/status/state and sm/status/substate carry the SLM’s own substate, including Running (the GUI enables loop commands only while the substate is Running).

  • GetStatus command: replies with the concise human form "State:Substate" (e.g. Operational:Running).

  • Status topic: stdif::Status is published on <pub_endpoint>std/status as "State;Substate" with the source set to the server module name.

The published substate uses the Supervisor vocabulary (ex/ifw-sup states.hpp): NotReady, Ready, Idle, Busy, Error … Because the Supervisor does not define a Running substate, the SLM reports Running as Idle (operational and available) on the topic only; the GetStatus reply and the OLDB keep Running. The Supervisor in ex/ifw-sup subscribes to this topic and parses the State;Substate string.