Skip to content

Commit

Permalink
Added the Railway Stations Sensor-Signal System Control PLC Simulator…
Browse files Browse the repository at this point in the history
… readme document.
  • Loading branch information
LiuYuancheng committed Jul 26, 2023
1 parent 4e1c87d commit 369cee6
Show file tree
Hide file tree
Showing 8 changed files with 257 additions and 22 deletions.
Binary file modified doc/designDoc.pptx
Binary file not shown.
Binary file added doc/img/stationPlc/operatingLogic.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 6 additions & 7 deletions doc/sensorsPLCSimu_readme.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
# Railway Sensor-Signal System Control PLC Simulator
# Railway Junctions Sensor-Signal System Control PLC Simulator

**Project Design :** we want to create a Programmable Logic Controllers(PLC) set with 3 PLCs to below tasks:

1. Read the 39 train sensors (connect to PLCs' input) state from the real-word emulator to PLCs' holding register state.
2. Run the pre-set ladder logic (flip-flop latching relay) to change the 19 real-world signals (connect to PLCs' output coils) state.
3. Create a ModBus server to handle the HMI's ModBus TCP request to update/change register/coils value.
3. Create a Modbus server to handle the HMI's Modbus TCP request to update/change register/coils value.

This simulator will simulate 3 standard Siemens S71200 PLCs (16 input + 8 output / total 48 input + 24 output) PLCs connected under master and salve mode with rs422 multi-drop cable as below:

![](img/sensorPlc/readme0.png)

So the HMI can control 3 PLCs' state by connecting master PLC's ip address through ModBus TCP protocol.
So the HMI can control 3 PLCs' state by connecting master PLC's ip address through Modbus TCP protocol.

[TOC]

------

### Introduction

Railway Sensor-Signal System Control PLC Simulator is part of the Railway IT/OT System security test platform. It is used to control the sensors-signals system of the railway junctions. You can refer the system topology diagram to check its function in the system by below link:
Railway Junction Sensor-Signal System Control PLC Simulator is part of the Railway IT/OT System security test platform. It is used to control the sensors-signals system of the railway junctions. You can refer the system topology diagram to check its function in the system by below link:

- [Railway IT/OT System security test platform system structure diagram](img/networkCommDesign.png)
- [Railway IT/OT System security test platform network topology diagram](img/networkDesign.png)
Expand Down Expand Up @@ -111,8 +111,6 @@ VM Deploy Config:

### Program Usage



##### Edit Configuration File

Open config file `plcConfig.txt`
Expand Down Expand Up @@ -173,4 +171,5 @@ Refer to `doc/ProblemAndSolution.md`

------

> last edit by LiuYuancheng ([email protected]) by 26/07/2023 if you have any problem, please send me a message.
> last edit by LiuYuancheng ([email protected]) by 26/07/2023 if you have any problem, please send me a message.
172 changes: 172 additions & 0 deletions doc/stationPLCSimu_readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
# Railway Stations Sensor-Signal System Control PLC Simulator

**Project Design :** we want to create a Programmable Logic Controllers(PLC) set with 3 PLCs to below tasks:

1. Read the 22 train stations' train dock sensors (connect to PLCs' input) from the real-word emulator to PLCs' holding register state.
2. Run the pre-set ladder logic (direct trigger latching relay) to change the 44 real-world station enter/exit signals (connect to PLCs' output coils) state.
3. Create a Modbus server to handle the HMI's Modbus TCP request to update/change register/coils value.

This simulator will simulate 3 standard Siemens S71200 PLCs (16 input + 8 output / total 48 input + 24 output) PLCs connected under master and salve mode with rs422 multi-drop cable as below:

![](img/sensorPlc/readme0.png)

So the HMI can control 3 PLCs' state by connecting master PLC's ip address through Modbus TCP protocol.

[TOC]

------

### Introduction

Railway Station Sensor-Signal System Control PLC Simulator is part of the Railway IT/OT System security test platform. It is used to control the trains' docking process in the railway system. You can refer the system topology diagram to check its function in the system by below link:

- [Railway IT/OT System security test platform system structure diagram](img/networkCommDesign.png)
- [Railway IT/OT System security test platform network topology diagram](img/networkDesign.png)

Three PLC (PLC-03, PLC-04, PLC05) are involved in this program, PLC-03 is the master and PLC-04, PLC-05 are the salve. This program is used to control the railway's station system. There will be 22 input and 22 output and 22 ladder logic in this PLC set.

Each station is controlled by one train docking sensor and 2 train block signals(enter/exit), Below diagram shows the wire connection and steps of how one of the 22 ladder logic controls a station.

- When a docking sensor is trigger, station will raise exit block signal to total stop the train, then raise enter block signal to avoid other train enter.
- When the docking train finishes, station will turn off the exit block signal to release the train, the turn off the enter block signal to allow other trains dock.

![](img/stationPlc/operatingLogic.png)

**Program version:** `v0.1.2`

Code base: https://github.com/LiuYuancheng/Metro_emulator/tree/main/src/plcCtrl/stationPlcEmu



------

The program contents 3 main thread :

- Real-world communication thread to fetch junction sensors data and set signals state.
- Ladder logic execution state, once there is holding registers' state change, executed the related binding logic to change the coils state.
- Modbus server thread to handling the Modbus TCP request from HMI.

This is the program modules workflow diagram:

![](img/sensorPlc/workflow.png)

##### System ladder logic

The system contents 19 ladder logic which shown in the introduction. The PLC input => Holding register => ladder logic => Coil => PLC output map is shown below:

![](img/stationPlc.png)

You can also check the excel file `ladderConnectionMap.xlsx` to see the mapping detail.



##### Program module files list

| Idx | Program File | Execution Env | Description |
| ---- | ------------------------------------ | ------------- | ------------------------------------------------------------ |
| 1 | stationPlcEmu/plcConfig.txt | | System config file. |
| 2 | stationPlcEmu/plcSimGlobalStation.py | python 3 | System needs global file, the system config file's contents will be saved in the global parameters. |
| 3 | stationPlcEmu/plcSimulatorStation.py | python 3 | Main PLC simulation program. |
| | | | |

Libraries required code base: https://github.com/LiuYuancheng/Metro_emulator/tree/main/src/lib



------

### Program Setup

###### Development Environment : python 3.7.4

###### Additional Lib/Software Need

1. **pyModbusTCP** : https://github.com/sourceperl/pyModbusTCP

```
pip install pyModbusTCP
```

###### Hardware Needed : None

###### Execution environment

```
OS : ubuntu 20.04 server
Display mode:
- Display output: No
VM Deploy Config:
- NIC number: 2
- SSH: enable
- NIC 1: IP address: 10.0.10.12, gateway: 10.0.10.1
- NIC 2: IP address: 192.168.100.12, gateway: 192.168.100.1
```



------

### Program Usage

##### Edit Configuration File

Open config file `plcConfig.txt`

```
# This is the config file template for the module <monitorApp.py>
# Setup the paramter with below format (every line follow <key>:<val> format, the
# key can not be changed):
# Set the master PLC's name
PLC_NAME:PLC-03
# Define the ip addresses allowed to read PLC state:
# json list fomat: ["masterIP", "slave1IP", ...]
ALLOW_R_L:["127.0.0.1", "192.168.0.10"]
# Define the ip addresses allowed to change PLC state:
# json list fomat: ["masterIP", "slave1IP", ...]
ALLOW_W_L:["127.0.0.1"]
# Define Realworld emulator ip
RW_IP:127.0.0.1
# Define Realworld emulator connection port
RW_PORT:3001
# Define PLC clock interval
CLK_INT:0.9
# Define modbus TCP host IP, use 0.0.0.0 or localhost
MD_BUS_IP:localhost
# Define modbus TCP host Port, normally use 502
MD_BUS_PORT:503
```



##### Program Execution

After follow the instruction in the file `metroConfig.txt` to setup all the parameters, you can run the program:

```
python plcSimulatorStation.py
```

or double click the file `runStationPlcCtrlEmu_win.bat`



------

#### Problem and Solution

Refer to `doc/ProblemAndSolution.md`



------

> last edit by LiuYuancheng ([email protected]) by 26/07/2023 if you have any problem, please send me a message.
29 changes: 29 additions & 0 deletions src/plcCtrl/stationPlcEmu/plcConfig_tamplate.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# This is the config file template for the module <monitorApp.py>
# Setup the paramter with below format (every line follow <key>:<val> format, the
# key can not be changed):

# Set the master PLC's name
PLC_NAME:PLC-03

# Define the ip addresses allowed to read PLC state:
# json list fomat: ["masterIP", "slave1IP", ...]
ALLOW_R_L:["127.0.0.1", "192.168.0.10"]

# Define the ip addresses allowed to change PLC state:
# json list fomat: ["masterIP", "slave1IP", ...]
ALLOW_W_L:["127.0.0.1"]

# Define Realworld emulator ip
RW_IP:127.0.0.1

# Define Realworld emulator connection port
RW_PORT:3001

# Define PLC clock interval
CLK_INT:0.9

# Define modbus TCP host IP, use 0.0.0.0 or localhost
MD_BUS_IP:localhost

# Define modbus TCP host Port, normally use 502
MD_BUS_PORT:503
28 changes: 20 additions & 8 deletions src/plcCtrl/stationPlcEmu/plcSimGlobalStation.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@
# Author: Yuancheng Liu
#
# Created: 2010/08/26
# Copyright:
# License:
# Version: v0.1.2
# Copyright: Copyright (c) 2023 Singapore National Cybersecurity R&D Lab LiuYuancheng
# License: MIT License
#-----------------------------------------------------------------------------
"""
For good coding practice, follow the following naming convention:
Expand All @@ -26,6 +27,7 @@

TOPDIR = 'src'
LIBDIR = 'lib'
CONFIG_FILE_NAME = 'plcConfig.txt'

idx = dirpath.find(TOPDIR)
gTopDir = dirpath[:idx + len(TOPDIR)] if idx != -1 else dirpath # found it - truncate right after TOPDIR
Expand All @@ -43,16 +45,27 @@
LOG_ERR = 2
LOG_EXCEPT = 3

# Init the PLC info.
PLC_NAME = 'PLC-03'
ALLOW_R_L = ['127.0.0.1', '192.168.0.10']
ALLOW_W_L = ['127.0.0.1']
#-----------------------------------------------------------------------------
# Init the configure file loader.
import ConfigLoader
gGonfigPath = os.path.join(dirpath, CONFIG_FILE_NAME)
iConfigLoader = ConfigLoader.ConfigLoader(gGonfigPath, mode='r')
if iConfigLoader is None:
print("Error: The config file %s is not exist.Program exit!" %str(gGonfigPath))
exit()
CONFIG_DICT = iConfigLoader.getJson()

# Init the PLC info.
PLC_NAME = CONFIG_DICT['PLC_NAME']
ALLOW_R_L = CONFIG_DICT['ALLOW_R_L']
ALLOW_W_L = CONFIG_DICT['ALLOW_W_L']

#-------<GLOBAL VARIABLES (start with "g")>------------------------------------
# VARIABLES are the built in data type.
gRealWordIP = ('127.0.0.1', 3001)
gInterval = 0.9
gRealWordIP = (CONFIG_DICT['RW_IP'], int(CONFIG_DICT['RW_PORT']))
gInterval = float(CONFIG_DICT['CLK_INT'])
gModBusIP = (CONFIG_DICT['MD_BUS_IP'], int(CONFIG_DICT['MD_BUS_PORT']))

def gDebugPrint(msg, prt=True, logType=None):
if prt: print(msg)
Expand All @@ -65,7 +78,6 @@ def gDebugPrint(msg, prt=True, logType=None):
elif logType == LOG_INFO or DEBUG_FLG:
Log.info(msg)


#-------<GLOBAL PARAMTERS>-----------------------------------------------------
iMBhandler = None # modbus TCP data handler.
iMBservice = None # modbus TCP service
Expand Down
16 changes: 9 additions & 7 deletions src/plcCtrl/stationPlcEmu/plcSimulatorStation.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
class directConnLadderLogic(modbusTcpCom.ladderLogic):
""" A Direct connection ladder logic diagram set
""" A direct connection ladder logic diagram set, holding registers will
trigger the connected coils.
"""
def __init__(self, parent, ladderName) -> None:
super().__init__(parent, ladderName=ladderName)
Expand All @@ -43,8 +44,7 @@ def initLadderInfo(self):
self.srcCoilsInfo['offset'] = None
self.destCoilsInfo['address'] = 0
self.destCoilsInfo['offset'] = 22
# Init the flipflop coils and registers config:
# For total 39 holding registers connected addresses
# For total 22 holding registers connected addresses
# address: 0 - 9: weline stations
# address: 10 - 15: nsline stations
# address: 16 - 21: ccline sensors.
Expand All @@ -71,8 +71,9 @@ class stationPlcSet(plcSimulator.plcSimuInterface):
the output coils state based on the ladder logic.
- Send the signal setup request to the real world emulator to change the signal.
"""
def __init__(self, parent, plcID, addressInfoDict, ladderObj):
super().__init__(parent, plcID, addressInfoDict, ladderObj)
def __init__(self, parent, plcID, addressInfoDict, ladderObj, updateInt=0.6):
super().__init__(parent, plcID, addressInfoDict, ladderObj,
updateInt=updateInt)

def initInputState(self):
self.regsAddrs = (0, 22)
Expand Down Expand Up @@ -104,12 +105,13 @@ def main():
gv.gDebugPrint("Start Init the PLC: %s" %str(gv.PLC_NAME), logType=gv.LOG_INFO)
gv.iLadderLogic = directConnLadderLogic(None, ladderName='Direct_connection')
addressInfoDict = {
'hostaddress': ('localhost', 503),
'hostaddress': gv.gModBusIP,
'realworld':gv.gRealWordIP,
'allowread':gv.ALLOW_R_L,
'allowwrite': gv.ALLOW_W_L
}
plc = stationPlcSet(None, gv.PLC_NAME, addressInfoDict, gv.iLadderLogic)
plc = stationPlcSet(None, gv.PLC_NAME, addressInfoDict,
gv.iLadderLogic, updateInt=gv.gInterval)
plc.run()

if __name__ == "__main__":
Expand Down
21 changes: 21 additions & 0 deletions src/plcCtrl/stationPlcEmu/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Railway Stations Sensor-Signal System Control PLC Simulator

### Introduction

**Please refer to the Railway Stations Sensor-Signal System Control PLC Simulator Readme file in the document fold with the below section: **

- Introduction
- Program design
- Program Setup steps
- Execute the program
- Problem and solution

**Click below link to jump to the readme file:**

[ Railway Sensor-Signal System Control PLC Simulator Readme file ](../../doc/stationPLCSimu_readme.md)



------

> last edit by LiuYuancheng ([email protected]) by 26/07/2023 if you have any problem, please send me a message.

0 comments on commit 369cee6

Please sign in to comment.