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:
OnNotOperationalNotReady— initial state;Initmoves toReady.Ready—Enablemoves toOperational.
OperationalIdle— the SLM is enabled but loops are not running;RunSlmmoves toRunning.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 aTriggereveryperiod_secwhich runs one cycle (Idle↔Cycle).Suspended— cycling is paused;Resumereturns toCloseLoop.
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 insm.xmlmap to methods registered here.ActionsLMroutes the loop commands (CloseLoop/OpenLoop/SuspendLoop/ResumeLoop/RunSlm/StopSlm) and implements the conciseGetStatusreply.BaseLoopActions/BaseLoopCloseActions/BaseLoopSuspendedActionsimplement the per-loop behaviour for theOpenLoop/CloseLoop/Suspendedsub-states.ActionsLoopClose<N>adds the period timer.BaseLoopExecuteActivityruns the user control logic on a separate, killable thread. ItsDoExecute()method is the extension point; on return it signals success or error through theLoopCompletionHandler.
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 |
|---|---|
|
1 = OPEN, 2 = CLOSED, 3 = SUSPENDED |
|
true while the loop is closed |
|
configured cycle period |
|
number of cycles started |
|
successful executions since server start |
|
consecutive failures (reset on success) |
|
true if the last cycle failed |
|
timestamp of the last execution |
|
timestamp when the loop entered closed-loop (cycling) |
|
timestamp of the last successful execution |
|
description of the last failure |
|
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/stateandsm/status/substatecarry the SLM’s own substate, includingRunning(the GUI enables loop commands only while the substate isRunning).GetStatus command: replies with the concise human form
"State:Substate"(e.g.Operational:Running).Status topic:
stdif::Statusis published on<pub_endpoint>std/statusas"State;Substate"with thesourceset 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.