EPIC as DNP3 Server/Slave

Hi All,

Before I begin, I want to clear up terminology based on my understanding.

Master DNP3 = Client
Slave DNP3 = Server/Outstation

I know Opto22 has DNP3 integration but that is for SNAP PAC only. This kit can make SNAP PAC as Master and Slave.

While EPIC has Ignition Edge. Ignition Edge has DNP3 driver that I can install but it allows EPIC as Master only. (In configuration, when adding device it shown “connect to DNP3 outstation”).

So, what route should I make to establish my EPIC as DNP3 Slave ?

Hello Mohamad. Welcome to the forums!

I am not sure why you think that the Opto 22 DNP3 kit is for SNAP PAC only… The EPIC runs a PAC Control engine just like the SNAP, so the kit is (to the best of my knowledge) fully compatible.
In fact, since there is no Ignition Slave, or CodeSys implementation of DNP3, the SNAP PAC toolkit is your only option at this time.

Thanks for the reply.

Based on the description https://www.opto22.com/products/pac-int-dnp3 from website it said for SNAP PAC but i not yet tested it with EPIC controller.

Since EPIC control engine same like SNAP PAC, so the integration kit should compatible with EPIC also.

Now, I should focus using the kit to apply my EPIC as DNP3 slave.

Currently Im using SNAP PAC DNP3 kit on EPIC. https://www.opto22.com/products/pac-int-dnp3

What I already change the controller pointer to EPIC and open DNP3 port:20000.

I’m using Opendnp3 simulator as my DNP3 client.

I don’t know whether parameter setting is wrong but currently I configured for 1 bool only.

Code

//Load Pointer, This is the Controler With The DNP3 Charts
//There is a pointer for each PAC Controller that can run the DNP3 charts. Load only one.
//Use (poPAC_DNP_Controller_SNAP_PAC_S1_or_S2) if the controller running the DNP 3 charts is the SNAP-PAC S1 or SNAP-PAC S2
//Use (poPAC_DNP_Controller_SNAP_PAC_R1) if the controller running the DNP 3 charts is the SNAP-PAC R1
//Use (poPAC_DNP_Controller_SNAP_PAC_R2) if the controller running the DNP 3 charts is the SNAP-PAC R2

//Load only the controller running the DNP3 Charts
poPAC_DNP_Controller_GRV_EPIC_PR1 = &PJ023A_BGPH_RTU;//Load Pointer, This is the Controler With The DNP3 Charts

nDNP_Outstation_Address = 1;//Set Outstation Address;
nDNP_Self_Address_Feature = 0;//0 = Disable 1 = Use Address 0xFFFC

//Event Single Buffer Mode

//nDNP_Event_Single_Buffer_Mode
//In the auto event setup you can assign each event to an event buffer for each master configured
//With nDNP_Event_Single_Buffer_Mode set false (0), if an event is placed in a master buffer only that master can read and remove it from its buffer.
//For example if you have 2 masters configured and all event are placed in both buffers (",0011"), when master 0 polls the events from buffer 0 it has no
//effect on the events in master buffer 1. These will need to be removed by master 1.
//If master 1 is a backup for master 0 and is to be inactive until master 0 fails the event buffer for master 1 will overflow because it is not being polled.
//By setting (nDNP_Event_Single_Buffer_Mode) to 1 or true all event are placed in buffer 0. The setting in each auto event group for the buffer is ignored.
//Now if you have 2 masters configured the events will be removed if either master polls for the events.
nDNP_Event_Single_Buffer_Mode = 1;//0 = Individual event buffers 1 = single event buffer

//Confiure how AllStationMessageRecived state is cleared for address 0xFFFF
nDNP_FFFF_All_Call_Condition_For_Clear = 0;//0 = Clear bit after sending first response, 1 = Clear bit after receiving master’s App Layer Confirm

//Select IP Network or Serial per master connection
//4 Master Stations max
//Communication Mode
//0 = Ethernet communication 1 = Serial communication
ntDNP_Serial_Enabled[0] = 0;
//ntDNP_Serial_Enabled[1] = 0;
//ntDNP_Serial_Enabled[2] = 1;
//ntDNP_Serial_Enabled[3] = 1;

//4 Master Stations max
//IP Network
//Used to Open IP session to Master if needed for Unsolicited Response
//This is not used for serial communications.
SetCommunicationHandleValue(“tcp:172.17.23.45:20000”, chMaster_Active_Open_Index_0);
//SetCommunicationHandleValue(“tcp:192.168.1.51:20001”, chMaster_Active_Open_Index_1);
//SetCommunicationHandleValue(“tcp:192.168.1.201:20002”, chMaster_Active_Open_Index_2);
//SetCommunicationHandleValue(“tcp:192.168.1.202:20003”, chMaster_Active_Open_Index_3);

//This if for IP Network
//Listen for Master to open session
//This is not used for serial communications.
//The strategy uses chMaster_Listen_Index Communication Handles to determine the last used index 0 - 3)
//Only set the Communication Handle needed starting with chMaster_Listen_Index_0 first
//then chMaster_Listen_Index_1 then chMaster_Listen_Index_2 then chMaster_Listen_Index_3
//last, if all are needed.
//In this example only the first three are used

//There are 4 comm handles that can be set (chMaster_Listen_Index_0, chMaster_Listen_Index_1, chMaster_Listen_Index_2, chMaster_Listen_Index_3)
//Set 0 then 1 then 2 then 3. Do not skip one
//example: set chMaster_Listen_Index_0 and chMaster_Listen_Index_1 to have two masters.
//Bad example: set chMaster_Listen_Index_0 and chMaster_Listen_Index_2 = This will not work
//If the Master and Outstation charts are on the same controller they must listen on different ports

SetCommunicationHandleValue(“tcp:20000”, chMaster_Listen_Index_0);
//SetCommunicationHandleValue(“tcp:20001”, chMaster_Listen_Index_1);
//SetCommunicationHandleValue(“tcp:20002”, chMaster_Listen_Index_2);
//SetCommunicationHandleValue(“tcp:20003”, chMaster_Listen_Index_3);

//Serial
//Set Comm Handles. This will work with serial modules or the controller serial port
//This is for Serial
//Example used for serial Module SetCommunicationHandleValue(“tcp:192.168.1.226:22526”, chMaster_Listen_Index_0);
//Example used for serial Module SetCommunicationHandleValue(“tcp:192.168.1.226:22527”, chMaster_Listen_Index_1);
//SetCommunicationHandleValue(“ser:1,9600,n,8,1”, chMaster_Listen_Index_2);
//SetCommunicationHandleValue(“ser:1,9600,n,8,1”, chMaster_Listen_Index_3);

//This is for Serial
//fNL_Serial_Wait_Time = 2.0;//Set Wait Time For Complete Serial Message in Seconds. Not used for IP Network

//This sets the connection type for the same index as (potDNP_Master_Listen_Table).
//0 = Listening End Point 1 = Datagram End Point 2 = Duel End Point
ntDNP_Connection_Type[0] = 2;//Set Duel End Type
//ntDNP_Connection_Type[1] = 0;//Set Listening End Type
//ntDNP_Connection_Type[2] = 2;//Set Listening End Type
//ntDNP_Connection_Type[3] = 2;//Set Listening End Type

//Used To Validate Connection
ntDNP_Master_DNP_Address[0] = 3;//This is the source address from master at index of (potDNP_Master_Listen_Table).
//ntDNP_Master_DNP_Address[1] = 55;//This is the source address from master at index of (potDNP_Master_Listen_Table).
//ntDNP_Master_DNP_Address[2] = 10;//This is the source address from master at index of (potDNP_Master_Listen_Table).
//ntDNP_Master_DNP_Address[3] = 4;//This is the source address from master at index of (potDNP_Master_Listen_Table).

//Numbers of Retries 0 = No Retries
ntDLLPrimaryRetry[0] = 10;//Set number of retries for each master
//ntDLLPrimaryRetry[1] = 0;//Set number of retries for each master
//ntDLLPrimaryRetry[2] = 0;//Set number of retries for each master
//ntDLLPrimaryRetry[3] = 0;//Set number of retries for each master

//This is used To Enable or Disable Unsolicited Response
pntDNP_Unsolicited_Response_Mode[0] = 1;//0 = Disable Unsolicited Response 1 = Enable Unsolicited Response For Master at Index 0
//pntDNP_Unsolicited_Response_Mode[1] = 0;//0 = Disable Unsolicited Response 1 = Enable Unsolicited Response For Master at Index 1
//pntDNP_Unsolicited_Response_Mode[2] = 0;//0 = Disable Unsolicited Response 1 = Enable Unsolicited Response For Master at Index 2
//pntDNP_Unsolicited_Response_Mode[3] = 0;//0 = Disable Unsolicited Response 1 = Enable Unsolicited Response For Master at Index 3

//Number of retries for an Unsolicited Response
ntULUnsRetry[0] = 10;//Unsolicited Response Retry For Master at Index 0
//ntULUnsRetry[1] = 4;//Unsolicited Response Retry For Master at Index 1
//ntULUnsRetry[2] = 4;//Unsolicited Response Retry For Master at Index 2
//ntULUnsRetry[3] = 4;//Unsolicited Response Retry For Master at Index 3

//0 = Send On First Event If Unsolicited Response is Enabled
ntUns_Number_Of_Queued_Events[0] = 5;//Number of Events Before Send If Unsolicited Response is Enabled For Master at Index 0
//ntUns_Number_Of_Queued_Events[1] = 5;//Number of Events Before Send If Unsolicited Response is Enabled For Master at Index 1
//ntUns_Number_Of_Queued_Events[2] = 5;//Number of Events Before Send If Unsolicited Response is Enabled For Master at Index 2
//ntUns_Number_Of_Queued_Events[3] = 5;//Number of Events Before Send If Unsolicited Response is Enabled For Master at Index 3

//0 = Send With No Delay On First Event If Unsolicited Response is Enabled
ftUns_Hold_Time_Queued_Events[0] = 5;//Hold Time In Seconds of Events Before Send If Unsolicited Response is Enabled For Master at Index 0
//ftUns_Hold_Time_Queued_Events[1] = 5;//Hold Time In Seconds of Events Before Send If Unsolicited Response is Enabled For Master at Index 1
//ftUns_Hold_Time_Queued_Events[2] = 5;//Hold Time In Seconds of Events Before Send If Unsolicited Response is Enabled For Master at Index 2
//ftUns_Hold_Time_Queued_Events[3] = 5;//Hold Time In Seconds of Events Before Send If Unsolicited Response is Enabled For Master at Index 3

//Maximun size of Transport Layer Segment
nTF_Segment_Maximum_Octets = 250;//Set Size in Octets

fUL_CROB_Default_Off_Time = 2000;//Set Default Off Time in ms. Used by CROB if No Off Time is Sent From Master.
fUL_CROB_Default_On_Time = 2000;//Set Default On Time in ms. Used by CROB if No On Time is Sent From Master

fUL_CROB_Wait_For_FC_4 = 10.0;//Set Wait Time After Receiving FC 3 in Seconds.

fDNP_Keep_Alive_Time = 300;//Set Keep-Alive Time in Seconds
fDNP_Keep_Alive_Disable_Time = 5;//Delay to wait for Response for Keep-Alive

fDLL_Sol_Confirm_Time = 10.0;//Set Wait Time For DLL Confirm in Seconds

fAL_Sol_Confirm_Time = 10.0;//Set Wait Time For AL Confirm in Seconds

fAL_UnSol_Confirm_Time = 10.0;//Set Wait Time For Unsolicited Confirm in Seconds

fUns_Timeout_Disable_Time = 600.0;//Set Wait Time For Unsolicited Disable in Seconds After Timeout

//Load all binary (digital) inputs used by DNP3 in this pointer table. Also load
// all virtual binary (integer_32 or integer 32 table element) inputs. Virtual points must have the state of 0 or 1 only.
//For every index with a virtual point you must also set a 1 or 2 in the table (ntDNP_Variable_32_Group_1_Flag) at the same index.
//For every index with a virtual table point must also set the index used in the table (ntDNP_Table_Index_Group_1_Flag) at the same index.
//Virtual points must be integer 32 variables or integer 32 table indexes
potDNP_Binary_Inputs_GP_1[0] = &nVirtual_Binary_Input_1;
//potDNP_Binary_Inputs_GP_1[1] = &nVirtual_Binary_Input_1;//Must set a 1 in table(ntDNP_Variable_32_Group_1_Flag)
//potDNP_Binary_Inputs_GP_1[2] = &nVirtual_Binary_Input_2;//Must set a 1 in table(ntDNP_Variable_32_Group_1_Flag)
//potDNP_Binary_Inputs_GP_1[3] = &diSwitch_D1;
//potDNP_Binary_Inputs_GP_1[4] = &nVirtual_Binary_Input_3;//Must set a 1 in table(ntDNP_Variable_32_Group_1_Flag)
//potDNP_Binary_Inputs_GP_1[5] = &ntVirtual_Binary_Input_Table;//Must set a 2 in table(ntDNP_Variable_32_Group_1_Flag)
//potDNP_Binary_Inputs_GP_1[6] = &ntVirtual_Binary_Input_Table;//Must set a 2 in table(ntDNP_Variable_32_Group_1_Flag)

//This table marks all the virtual point for the strategy. (1 = integer 32 variable, 2 = integer 32 table).
ntDNP_Variable_32_Group_1_Flag[0] = 1;
//ntDNP_Variable_32_Group_1_Flag[2] = 1;
//ntDNP_Variable_32_Group_1_Flag[4] = 1;
//ntDNP_Variable_32_Group_1_Flag[5] = 2;
//ntDNP_Variable_32_Group_1_Flag[6] = 2;

Is there any code I’m missing to change since the kit originally for SNAP PAC?

Now I can setup my epic as DNP3 outstation. Wrong config on the simulator.

2 Likes