Subsystem Simulator

The Subsystem Simulator mimics the respond of a generic subsystem process. It is used to have an independent validation of the standard interface used between the System Supervisor and subsystems. The Subsystem Simulator is a dummy RAD based application which implements the standard state machine and the standard interface together with few specific features. From now on we will use the term Simulator to refer to the Subsystem Simulator.

The Simulator uses the Redis Database to store run-time information. The Simulator publishes its own status following the requirements for interacting with the System Supervisor.

Simulator State Machine

The Simulator uses a state machine described in a SCXML format that is interpreted by the state machine engine provided by the rad application framework. (SCXML specification).

alternate text

Simulator State Machine Diagram.

Off –> NotReady, event: Startup

The Simulator starts up and goes automatically to NotOperational/NotReady. Main server objects are instantiated including the basic application that uses the State Machine engine. The Simulator reads its own configuration and completes its initialisation.

NotReady –> Ready, event: Init

The Simulator moves from NotReady to Ready state by going through the Initialising transient state. During this transient state, the simulator will wait according to the configured delay time before to reply to the originator.

NotOperational/Ready –> Operational/Idle, event: Enable

The Simulator moves from NotOperational/Ready to Operational/Idle by going through the Enabling transient state. During this transient state, the simulator will wait according to the configured delay time before to reply to the originator.

Operational –> NotOperational/Ready, event: Disable

The Simulator is moved back to NotOperational/Ready substate.

NotOperational/Ready –> NotOperational/NotReady, event Reset

The Simulator is moved back to NotOperational/NotReady substate.

Configuration

SubSystem Simulator Configuration

The server configuration is a file written in yaml format. (YAML specification). YAML is easy to read format that has been adopted temporary until the integration with CII configuration services.

Many resources about YAML can be found on the web. One could also validate the format online, see http://yaml.org/spec/

server_id

This is the id associated with the specific server. This id is used to associate all server configuration parameters as well as the prefix for the DB keys.

<server id>::req_endpoint

This is the endpoint for CII MAL request/reply. The server will listen to incoming commands using this endpoint.

<server id>::pub_endpoint

This is the endpoint for CII MAL pub/sub. The server will publish device topics using this endpoint.

<server id>::db_endpoint

This is the endpoint used by the server for connecting to the Redis DB.

<server id>::db_timeout

This is the server timeout for connecting to the Redis DB.

<server id>::scxml

This is the state machine specification file used by the server.

<server id>::commands

This is the list of commands active in the Simulator configuration. Only commands listed here will be managed by the Simulator.

<server id>::cmdtout

General command timeout.

Each command has its own set of configuration parameters

<command id>::reply_ok

This is a flag to indicate if command replies successfully or not. When it is true, the command replies ok otherwise it returns with an error.

<command id>::reply_delay

This is the delay in milliseconds to be used to reply to the originator.

<command id>::reply_ok_message

This is the message to be used when replying successfully.

<command id>::reply_error_msg

This is the message to be used when replying with an error.

<command id>::reply_error_code

This is a flag to enable/disable accessibility of a subsystem.

An example of a server configuration is provided below.

server_id           : 'subsim1'
subsim1:
    req_endpoint    : "zpb.rr://127.0.0.1:15080/"
    pub_endpoint    : "zpb.ps://127.0.0.1:15040/"
    db_endpoint     : "127.0.0.1:6379"
    db_timeout      : 2
    scxml           : "sup/subsim/server/sm.xml"
    commands      : ['Init', 'Enable', 'Disable']
    cmdtout         : 60000

Init:
    reply_ok: true
    reply_delay: 3000
    reply_ok_message: "OK"
    reply_error_msg: "Init failed - subsystem could not initialize"
    reply_error_code: -1

Enable:
    reply_ok: true
    reply_delay: 3000
    reply_ok_message: "OK"
    reply_error_msg: "ERROR: Enable failed"
    reply_error_code: -1

Disable:
    reply_ok: true
    reply_delay: 0
    reply_error_msg: "OK"
    reply_message: "ERROR: Disable failed"
    reply_error_code: -1

Server configuration

The simulator stores the actual values of the server configuration parameters into the Redis DB . This helps to verify whether the configuration has been loaded correctly. For details of the server configuration parameters, see :ref: sup_sim_config_ref_.

Simulator configuration Redis DB keys

Redis Key

<server id>.cfg.db_endpoint

<server id>.cfg.db_timeout

<server id>.cfg.cmdtout

<server id>.cfg.conntout

<server id>.cfg.filename

<server id>.cfg.loglevel

<server id>.cfg.pub_endpoint

<server id>.cfg.req_endpoint

<server id>.cfg.commands

<server id>.cfg.scxml

<server id>.cfg.<command id>.reply_delay

<server id>.cfg.<command id>.reply_error_msg

<server id>.cfg.<command id>.reply_ok

Server Status

The server stores the string representation of its state and substate into the Redis DB.

Server status Redis DB keys

Redis Key

<instrument id>.<server id>.state_str

<instrument id>.<server id>.substate_str

Commands

Error Handling

Simulator commands throw an exception (subsimif::ExceptionErr) in case of errors or timeouts from Simulator specific commands. For standard commands, the server throws a stdif::Exception. Client applications can catch the exceptions and obtain the error message associated with the function getDesc(). This error does not contain neither the history nor the error stack but it normally indicates precisely where the error occurred.

try {
    auto reply = client->GetState();
 } catch (const stdif::ExceptionErr& e) {
    RAD_LOG_ERROR() << "Error reply " << e.getDesc()  << ").";
}

Serialization

The Subsystem Simulator uses the CII MAL ZPB (ZeroMQ + Google Proto buffers) for serialising commands.

Note

Each command has two parts: a payload and its corresponding reply, see the details in the supif module. The normal replies are plain strings.

Sever Commands

The commands (events) currently supported by the Simulator are:

Simulator commands

Command

Parameters

Interface

Init

“”

stdif

Enable

“”

stdif

Disable

“”

stdif

Reset

“”

stdif

GetState

“”

stdif

GetStatus

“”

stdif

Exit

“”

stdif

SetLog

“<ERROR|INFO|DEBUG|TRACE>”

subsimif

Setup

“”

subsimif

Config

“<config buffer>”

subsimif

GetConfig

“”

subsimif

Setup Command

The Setup command is intended to mimic a change in the run-time configuration.

This command does not really setup anything, it only emulates the behaviour for testing purposes.

Config Command

The Config command is intended to change configuration parameters of the Simulator at run-time.

GetConfig Command

The GetConfig command returns the actual configuration used by the Simulator. This command is useful when starting the process with Nomad where configuration might be rendered.

Publishing

The Subsystem Simulator publishes as any other subsystem its state/substate. This is a requirement for enable visibility from the System Supervisor.

Parameter

end point

status

<ps endpoint>/std/status

Troubleshooting

Logging

The System Supervisor has implemented six logging levels that provide additional information for troubleshooting to the developer.

Name

Verbosity

Description

ERROR

very low

Provide logging only in case of errors.

INFO

low

Provide information for the most important actions (default).

DEBUG

medium

Provide additional information for the developer.

DEBUG2

high

Includes more details such as Node IDs of OPC-UA attributes

DEBUG3

high

Includes the logging of each subscription event.

TRACE

very high

Includes all the function tracing.

To activate a new logging, the command SetLog shall be used. See the example below.

C++ Simulator Client

The client application (supsimClient) is a simple utility allowing to send messages to the Simulator from the command line. In this context we use the words messages and events as synonyms. The supDummyClient uses two interface module (stdif and supsimif) to compose the payload of the messages. For simplicity purposes, the associated interface for each command is hidden to the user. The supsimClient sends the messages using CII MAL request/reply.

Note

This client uses the synchronous version of the stdif and supsimif interfaces.

$ supsimClient <serviceURI> <command> ["<parameters>"]

Where
      <serviceURI> destination of the command (e.g. zpb.rr://127.0.0.1:12081)
      <command>    command to be sent to the server (e.g. Init)
      <parameters> optional parameters of the command.

Examples

$ supsimClient zpb.rr://134.171.3.48:30519 Init

Note

The Config command is not supported by the C++ client.

Python Client Library

It is possible to communicate with the Subsystem Simulator through clients developed in Python. The Simulator provides a library that simplifies the interaction with the System Supervisor (subsimclib).

Users might want to interact directly with Supervisor ICD binding methods. This is, of course possible, but it is outside the scope of this library.

Note

The Supervisor python library uses the synchronous mal interface.

Error Handling

The subsimclib reports as a RuntimeError exceptions that may be delivered by the Simulator.

Classes

The subsimclib library provides one class that encapsulates the interface with the Supervisor. This class is the SubsimCommands class.

SubsimCommands

The constructor of the SubsimCommands class support two parameters: uri and timeout. The timeout is optional and has a default of one minute, expressed in milliseconds.

The class handles two MAL client interfaces to deal with standard commands and Simulator specific commands. The correct interface will be selected according to the method used so this is hidden to the user.

Methods for Command Interface

Method

parameters

interface

setup

<setup buffer>

subsimif

config

None

subsimif

get_config

None

subsimif

get_state

None

stdif

get_status

None

stdif

init

None

stdif

enable

None

stdif

disable

None

stdif

reset

None

stdif

stop

None

stdif

Additional Methods

The SubsimCommands class provides additional methods which uses the Config command to facilitate the update of the configuration at run-time.

Method

parameters

interface

cfgreply

<cmd>, <flag>

subsimif

cfgdelay

<cmd>, <delay>

subsimif

cfgerrmsg

<cmd>, <msg>

subsimif

Examples

Retrieving the Status

import subsimclib.subsimCommands as subsim

uri = "zpb.rr://134.171.3.48:28206"
subsimif = subsim.SubsimCommands(uri)
print(subsimif.get_status())

Simulator CLI

The Simulator CLI (subsimcli) provides a experimental command shell with simple commands aiming to simplify the interaction with the Simulator. The Simulator shell can be invoked issuing the command subsimcli.

The subsimcli offers few command line parameters. If no parameters are specified. The subsimcli shell commands are not necessary using the same names as the MAL interfaces with the purpose to shorten the commands names. Commands that could take long time, are executed in a dedicated thread to allow the shell to continue being responsive while waiting for the answer from the previous command. Asynchronous CII cannot be used here because unlike in C++, it is not really asynchronous in python (see ECII-365)

Parameter

Description

–uri

if the URI is specified, the subsimcli will use it to connect to the server

–name

When using nomad, one could specify the name of the service instead of the URI

Warning

The subsimcli shell assumes NOMAD/CONSUL services are up and running. If this is not the case then only –uri parameter can be used.

Note

The subsimcli shell was created for the Simulator but since it uses the standard interface, it can be used for any server implementing this interface, although only for the standard events like init, enable, disable, etc.

subsimcli --uri zpb.rr://134.171.3.48:30269
subsimSh>?
Available command list:
 -  cfgdelay
 -  cfgreply
 -  cfgerrmsg
 -  disable
 -  enable
 -  help
 -  init
 -  reset
 -  setup
 -  get_config
 -  state
 -  status

Command

Parameters

Description

disable

sends the disable (stdif) event to the connected server

enable

sends the enable (stdif) event to the connected server

help

print the list of supported commands

init

sends the init (stdif) event to the connected server

reset

sends the reset (stdif) event to the connected server

setup

sends the setup (subsimif) event to the connected server

get_config

sends the GetConfig (subsimif) event to the connected server

cfgreply

<cmd>,<true|false>

Configure reply flag for a given command. If flag is true, the command will return successfully otherwise with an error.

cfgdelay

<cmd>,<delay>

Configure reply delay for a given command in milliseconds.

cfgerrmsg

<cmd>,<msg>

Configure reply error message for a given command. The reply flag has to be false to take any effect.

ctrl-d

Stop the shell

Forcing Init command to finalize with an error:

subsimSh> cfgreply Init,false
reply> = OK
subsimSh>

Changing delay time for Init command:

subsimSh> cfgdelay Init,3000
reply> = OK
subsimSh>