API¶
Devices¶
devices module contains:
getandsetphysical process’s API methodssendandreceivenetwork layer’s API methods- the user input validation code
Any device can be initialized with any couple of state and
protocol dictionaries.
- List of supported protocols and identifiers:
- Devices with no networking capabilities have to set
protocolequal - to
None.
- Devices with no networking capabilities have to set
- Ethernet/IP subset through
cpppo, use idenip - Mode 0: client only.
- Mode 1: tcp enip server.
- Ethernet/IP subset through
- Modbus through
pymodbus, use idmodbus - Mode 0: client only.
- Mode 1: tcp modbus server.
- Modbus through
- List of supported backends:
- Sqlite through
sqlite3
- Sqlite through
The consistency of the system should be guaranteed by the client, e.g., do NOT init two different PLCs referencing to two different states or speaking two different industrial protocols.
Device subclasses can be specialized overriding their public methods
e.g., PLC pre_loop and main_loop methods.
-
class
minicps.devices.Device(name, protocol, state, disk={}, memory={})[source]¶ Base class.
-
__init__(name, protocol, state, disk={}, memory={})[source]¶ Init a Device object.
Parameters: - name (str) – device name
- protocol (dict) – used to set up the network layer API
- state (dict) – used to set up the physical layer API
- disk (dict) – persistent memory
- memory (dict) – main memory
protocol(when is notNone) is adictcontaining 3 keys:name: addresses a str identifying the protocol name (eg:enip)mode: int identifying the server mode (eg: mode equals1)server: ifmodeequals0is empty,- otherwise it addresses a dict containing the server information such as its address, and a list of data to serve.
stateis adictcontaining 2 keys:path: full (LInux) path to the database (eg: /tmp/test.sqlite)name: table name
Device construction example:
>>> device = Device( >>> name='dev', >>> protocol={ >>> 'name': 'enip', >>> 'mode': 1, >>> 'server': { >>> 'address': '10.0.0.1', >>> 'tags': (('SENSOR1', 1), ('SENSOR2', 1)), >>> } >>> state={ >>> 'path': '/path/to/db.sqlite', >>> 'name': 'table_name', >>> } >>> )
-
get(what)[source]¶ Get (read) a physical process state value.
Parameters: what (tuple) – field[s] identifier[s] Returns: gotten value or TypeErrorifwhatis not atuple
-
receive(what, address, **kwargs)[source]¶ Receive (read) a value from another network host.
kwargsdict is used to pass extra key-value pair according to the used protocol.Parameters: - what (tuple) – field[s] identifier[s]
- address (str) –
ip[:port]
Returns: received value or
TypeErrorifwhatis not atuple
-
send(what, value, address, **kwargs)[source]¶ Send (write) a value to another network host.
kwargsdict is used to pass extra key-value pair according to the used protocol.Parameters: - what (tuple) – field[s] identifier[s]
- value – value to be setted
- address (str) –
ip[:port]
Returns: NoneorTypeErrorifwhatis not atuple
-
set(what, value)[source]¶ Set (write) a physical process state value.
The
valueto be set (Eg: drive an actuator) is identified by thewhattuple, and it is assumed to be already initialize. Indeedsetis not able to create new physical process values.Parameters: - what (tuple) – field[s] identifier[s]
- value – value to be setted
Returns: setted value or
TypeErrorifwhatis not atuple
-
-
class
minicps.devices.HMI(name, protocol, state, disk={}, memory={})[source]¶ Human Machine Interface class.
- HMI provides:
- state APIs: e.g., get a water level indicator
- network APIs: e.g., monitors a PLC’s tag
-
class
minicps.devices.PLC(name, protocol, state, disk={}, memory={})[source]¶ Programmable Logic Controller class.
- PLC provides:
- state APIs: e.g., drive an actuator
- network APIs: e.g., communicate with another Device
-
class
minicps.devices.RTU(name, protocol, state, disk={}, memory={})[source]¶ RTU class.
- RTU provides:
- state APIs: e.g., drive an actuator
- network APIs: e.g., communicate with another Device
-
class
minicps.devices.SCADAServer(name, protocol, state, disk={}, memory={})[source]¶ SCADAServer class.
- SCADAServer provides:
- state APIs: e.g., drive an actuator
- network APIs: e.g., communicate with another Device
-
class
minicps.devices.Tank(name, protocol, state, section, level)[source]¶ Tank class.
- Tank provides:
- state APIs: e.g., set a water level indicator
-
__init__(name, protocol, state, section, level)[source]¶ Parameters: - name (str) – device name
- protocol (dict) – used to set up the network layer API
- state (dict) – used to set up the physical layer API
- section (float) – cross section of the tank in m^2
- level (float) – current level in m
MiniCPS¶
MiniCPS is a container class, you can subclass it with a specialized version targeted for your CPS.
E.g., MyCPS(MiniCPS) once constructed runs an interactive simulation where
each PLC device also run a webserver and the SCADA runs an FTP server.