Package: volttron-lib-dnp3-driver
volttron-lib-dnp3-driverDistributed Network Protocol (DNP
orDNP3)
has achieved a large-scale acceptance since its introduction in 1993. This
protocol is an immediately deployable solution for monitoring remote sites because it was developed for communication of
critical infrastructure status, allowing for reliable remote control.DNP3 is typically used between centrally located masters and distributed remotes. The master provides the interface
between the human network manager and the monitoring system. The remote (RTUs and intelligent electronic devices)
provides the interface between the master and the physical device(s) being monitored and/or controlled.
The DNP3-Driver is a wrapper on the DNP3 master following
theVOLTTRON driver framework.Note that the DNP3-Driver requires a DNP3 outstation instance to properly function. e.g., polling data, setting point
values, etc. Thednp3-pythoncan provide the essential outstation
functionality, and as part of the DNP3-Driver dependency, it is immediately available after the DNP3-Driver is
installed.PrerequisitesPython 3.10PythonTo install specific Python version (e.g., Python 3.8), we recommend usingpyenv.# install pyenvgitclonehttps://github.com/pyenv/pyenv~/.pyenv# setup pyenv (you should also put these three lines in .bashrc or similar)exportPATH="${HOME}/.pyenv/bin:${PATH}"exportPYENV_ROOT="${HOME}/.pyenv"eval"$(pyenvinit-)"# install Python 3.10pyenvinstall3.10# make it available globallypyenvglobalsystem3.10Quick StartThe following recipe walks through the steps to install and configure a DNP3 Driver. Note that it uses default setup to
work out-of-the-box. Please feel free to refer to related documentations for details.Create and activate a virtual environment.It is recommended to use a virtual environment for installing volttron.python-mvenvenvsourceenv/bin/activate

pipinstallvolttronInstall volttron and start the platform.Note:
According tovolttron-core#readme, setup VOLTTRON_HOME
environment variable is mandatory:... if you have/had in the past, a monolithic VOLTTRON version that used the default VOLTTRON_HOME
$HOME/.volttron. This modular version of VOLTTRON cannot work with volttron_home used by monolithic version of
VOLTTRON(version 8.3 or earlier)# Setup enviornment variableexportVOLTTRON_HOME=/path/to/volttron_home/dir# Start platform with output going to volttron.logvolttron-vv-lvolttron.log&Install the volttron platform driver:Note: for reproducibility, this demo will install platform driver withvip-identity==platform_driver_for_dnp3.
Free feel to specify any agent vip-identity as desired.vctlinstallvolttron-platform-driver--vip-identityplatform_driver_for_dnp3--startVerify with `vctl status`.(env)kefei@ubuntu-22:~/sandbox/dnp3-driver-sandbox$vctlstatus

UUIDAGENTIDENTITYTAGPRIORITYSTATUSHEALTH5volttron-platform-driver-0.2.0rc1platform_driver_for_dnp3running[23217]GOODInstall the "volttron-lib-dnp3-driver" library.There are two options to install the DNP3 Driver. You can install this library using the version on PyPi or install
it from the source code (git clonemight be required.)# option 1: install from pypipipinstallvolttron-lib-dnp3-driver# option 2: install from the source codepipinstall<path-to-the-source-code-root>/volttron-lib-dnp3-driver/Install a DNP3 Driver onto the Platform Driver.Installing a DNP3 driver in the Platform Driver Agent requires adding copies of the device configuration and registry
configuration files to the Platform Driver’s configuration store. For demo purpose, we will use default configure
files.Prepare the default config files:# Create config file place holdersmkdirconfig
touchconfig/dnp3-config.json
touchconfig/dnp3.csvEdit thednp3-config.jsonas follows:{"driver_config":{"master_ip":"0.0.0.0","outstation_ip":"127.0.0.1","master_id":2,"outstation_id":1,"port":20000},"registry_config":"config://dnp3.csv","driver_type":"dnp3","interval":5,"timezone":"UTC","publish_depth_first_all":true,"heart_beat_point":"random_bool"}Edit thednp3.csvas follows:Point Name,Volttron Point Name,Group,Variation,Index,Scaling,Units,Writable,Notes
AnalogInput_index0,AnalogInput_index0,30,6,0,1,NA,FALSE,Double Analogue input without status
AnalogInput_index1,AnalogInput_index1,30,6,1,1,NA,FALSE,Double Analogue input without status
AnalogInput_index2,AnalogInput_index2,30,6,2,1,NA,FALSE,Double Analogue input without status
AnalogInput_index3,AnalogInput_index3,30,6,3,1,NA,FALSE,Double Analogue input without status
BinaryInput_index0,BinaryInput_index0,1,2,0,1,NA,FALSE,Single bit binary input with status
BinaryInput_index1,BinaryInput_index1,1,2,1,1,NA,FALSE,Single bit binary input with status
BinaryInput_index2,BinaryInput_index2,1,2,2,1,NA,FALSE,Single bit binary input with status
BinaryInput_index3,BinaryInput_index3,1,2,3,1,NA,FALSE,Single bit binary input with status
AnalogOutput_index0,AnalogOutput_index0,40,4,0,1,NA,TRUE,Double-precision floating point with flags
AnalogOutput_index1,AnalogOutput_index1,40,4,1,1,NA,TRUE,Double-precision floating point with flags
AnalogOutput_index2,AnalogOutput_index2,40,4,2,1,NA,TRUE,Double-precision floating point with flags
AnalogOutput_index3,AnalogOutput_index3,40,4,3,1,NA,TRUE,Double-precision floating point with flags
BinaryOutput_index0,BinaryOutput_index0,10,2,0,1,NA,TRUE,Binary Output with flags
BinaryOutput_index1,BinaryOutput_index1,10,2,1,1,NA,TRUE,Binary Output with flags
BinaryOutput_index2,BinaryOutput_index2,10,2,2,1,NA,TRUE,Binary Output with flags
BinaryOutput_index3,BinaryOutput_index3,10,2,3,1,NA,TRUE,Binary Output with flagsAdd config to the configuration store:vctl config store platform_driver_for_dnp3 devices/campus/building/dnp3 config/dnp3-config.json
vctl config store platform_driver_for_dnp3 dnp3.csv config/dnp3.csv --csvVerify with `vctl config list` and `vctl config get` command. 
 (Please refer to the `vctl config` documentation for more details.)(env)kefei@ubuntu-22:~/sandbox/dnp3-driver-sandbox$vctlconfiggetplatform_driver_for_dnp3devices/campus/building/dnp3{"driver_config":{"master_ip":"0.0.0.0","outstation_ip":"127.0.0.1","master_id":2,"outstation_id":1,"port":20000},"registry_config":"config://dnp3.csv","driver_type":"dnp3","interval":5,"timezone":"UTC","publish_depth_first_all":true,"heart_beat_point":"random_bool"}(env)kefei@ubuntu-22:~/sandbox/dnp3-driver-sandbox$vctlconfiggetplatform_driver_for_dnp3dnp3.csv[{"Point Name":"AnalogInput_index0","Volttron Point Name":"AnalogInput_index0","Group":"30","Variation":"6","Index":"0",
...]Verify with logging dataWhen the DNP3-Driver is properly installed and configured, we can verify with logging data in "volttron.log".tail -f <path to folder containing volttron.log>/volttron.logExpected logging example...2023-03-1323:26:56,611(volttron-platform-driver-0.2.0rc123666)volttron.driver.base.driver(334)DEBUG:finishpublishing:devices/campus/building/dnp3/all2023-03-1323:26:57,897()volttron.services.auth.auth_service(235)DEBUG:aftergettingpeerlisttosendauthupdates2023-03-1323:26:57,897()volttron.services.auth.auth_service(239)DEBUG:Sendingauthupdatetopeersplatform.control2023-03-1323:26:57,897()volttron.services.auth.auth_service(239)DEBUG:Sendingauthupdatetopeersplatform_driver_for_dnp32023-03-1323:26:57,898()volttron.services.auth.auth_service(239)DEBUG:Sendingauthupdatetopeersplatform.health2023-03-1323:26:57,898()volttron.services.auth.auth_service(239)DEBUG:Sendingauthupdatetopeersplatform.config_store2023-03-1323:26:57,898()volttron.services.auth.auth_service(193)INFO:authfile/home/kefei/.volttron/auth.jsonloaded2023-03-1323:26:57,898()volttron.services.auth.auth_service(172)INFO:loadingauthfile/home/kefei/.volttron/auth.json2023-03-1323:26:57,898()volttron.services.auth.auth_service(185)DEBUG:Sendingauthupdatestopeers2023-03-1323:26:58,241(volttron-platform-driver-0.2.0rc123666)<stdout>(0)INFO:['ms(1678768018241) INFO    tcpclient - Connecting to: 127.0.0.1']2023-03-1323:26:58,241(volttron-platform-driver-0.2.0rc123666)<stdout>(0)INFO:['ms(1678768018241) WARN    tcpclient - Error Connecting: Connection refused']2023-03-1323:26:59,905()volttron.services.auth.auth_service(235)DEBUG:aftergettingpeerlisttosendauthupdates2023-03-1323:26:59,905()volttron.services.auth.auth_service(239)DEBUG:Sendingauthupdatetopeersplatform.control2023-03-1323:26:59,905()volttron.services.auth.auth_service(239)DEBUG:Sendingauthupdatetopeersplatform_driver_for_dnp3...](Optional) Verify with published data polled from outstationTo see data being polled from an outstation and published to the bus, we need toSet up an outstation, andinstall aListener Agent:Set up an outstation: Thednp3-pythonis part of the dnp3-driver
dependency, and it is immediately available after the DNP3-Driver is installed.Open another terminal, and rundnp3demo outstation. For demo purpose, we assign arbitrary values to the
point. (
More details about the "dnp3demo" module, please
seednp3demo-Module.md)====OutstationOperationMENU==================================<ai>-updateanalog-inputpointvalue(forlocalreading)<ao>-updateanalog-outputpointvalue(forlocalcontrol)<bi>-updatebinary-inputpointvalue(forlocalreading)<bo>-updatebinary-outputpointvalue(forlocalcontrol)<dd>-displaydatabase<dc>-displayconfiguration=========================================================================YourInputHere:==(outstation)======aiYouchose<ai>-updateanalog-inputpointvalue(forlocalreading)Typein<float>and<index>.Separatewithspace,thenhitENTER.Type'q','quit','exit'tomainmenu.========YourInputHere:==(outstation)======0.12120{'Analog':{0:0.1212,1:None,2:None,3:None,4:None,5:None,6:None,7:None,8:None,9:None}}Youchose<ai>-updateanalog-inputpointvalue(forlocalreading)Typein<float>and<index>.Separatewithspace,thenhitENTER.Type'q','quit','exit'tomainmenu.========YourInputHere:==(outstation)======1.23231{'Analog':{0:0.1212,1:1.2323,2:None,3:None,4:None,5:None,6:None,7:None,8:None,9:None}}Youchose<ai>-updateanalog-inputpointvalue(forlocalreading)Typein<float>and<index>.Separatewithspace,thenhitENTER.Type'q','quit','exit'tomainmenu.Example of interaction with the `dnp3demo outstation` sub-command(env)kefei@ubuntu-22:~/sandbox/dnp3-driver-sandbox$dnp3demooutstation
dnp3demo.run_outstation{'command':'outstation','outstation_ip=':'0.0.0.0','port=':20000,'master_id=':2,'outstation_id=':1}ms(1678770551216)INFOmanager-Startingthread(0)2023-03-1400:09:11,216control_workflow_demoINFOConnectionConfig2023-03-1400:09:11,216control_workflow_demoINFOConnectionConfig2023-03-1400:09:11,216control_workflow_demoINFOConnectionConfig
ms(1678770551216)INFOserver-Listeningon:0.0.0.0:200002023-03-1400:09:11,216control_workflow_demoDEBUGInitializationcomplete.Outstationincommandloop.2023-03-1400:09:11,216control_workflow_demoDEBUGInitializationcomplete.Outstationincommandloop.2023-03-1400:09:11,216control_workflow_demoDEBUGInitializationcomplete.Outstationincommandloop.
Connectionerror.
ConnectionConfig{'outstation_ip_str':'0.0.0.0','port':20000,'masterstation_id_int':2,'outstation_id_int':1}Startretry...
Connectionerror.
ConnectionConfig{'outstation_ip_str':'0.0.0.0','port':20000,'masterstation_id_int':2,'outstation_id_int':1}ms(1678770565247)INFOserver-Acceptedconnectionfrom:127.0.0.1====OutstationOperationMENU==================================<ai>-updateanalog-inputpointvalue(forlocalreading)<ao>-updateanalog-outputpointvalue(forlocalcontrol)<bi>-updatebinary-inputpointvalue(forlocalreading)<bo>-updatebinary-outputpointvalue(forlocalcontrol)<dd>-displaydatabase
<dc>-displayconfiguration=========================================================================YourInputHere:==(outstation)======ai
Youchose<ai>-updateanalog-inputpointvalue(forlocalreading)Typein<float>and<index>.Separatewithspace,thenhitENTER.
Type'q','quit','exit'tomainmenu.========YourInputHere:==(outstation)======0.12120{'Analog':{0:0.1212,1:None,2:None,3:None,4:None,5:None,6:None,7:None,8:None,9:None}}Youchose<ai>-updateanalog-inputpointvalue(forlocalreading)Typein<float>and<index>.Separatewithspace,thenhitENTER.
Type'q','quit','exit'tomainmenu.========YourInputHere:==(outstation)======1.23231{'Analog':{0:0.1212,1:1.2323,2:None,3:None,4:None,5:None,6:None,7:None,8:None,9:None}}Youchose<ai>-updateanalog-inputpointvalue(forlocalreading)Typein<float>and<index>.Separatewithspace,thenhitENTER.
Type'q','quit','exit'tomainmenu.========YourInputHere:==(outstation)======Install theListener Agent:
Runvctl install volttron-listener --start. Once installed, you should see the data being published by viewing the
Volttron logs file. (i.e.,tail -f <path to folder containing volttron.log>/volttron.log)Note:
it is recommended to restart the Platform Driver after a specific driver is installed and configured. i.e.,
using thevctl restart <agent-uuid>command.) The expected logging will be similar as follows:2023-03-1400:11:55,000(volttron-platform-driver-0.2.0rc024737)volttron.driver.base.driver(277)DEBUG:scrapingdevice:campus/building/dnp32023-03-1400:11:55,805(volttron-platform-driver-0.2.0rc024737)volttron.driver.base.driver(330)DEBUG:publishing:devices/campus/building/dnp3/all2023-03-1400:11:55,810(volttron-listener-0.2.0rc024424)listener.agent(104)INFO:Peer:pubsub,Sender:platform_driver_for_dnp3:,Bus:,Topic:devices/campus/building/dnp3/all,Headers:{'Date':'2023-03-14T05:11:55.805245+00:00','TimeStamp':'2023-03-14T05:11:55.805245+00:00','SynchronizedTimeStamp':'2023-03-14T05:11:55.000000+00:00','min_compatible_version':'3.0','max_compatible_version':''},Message:[{'AnalogInput_index0':0.1212,'AnalogInput_index1':1.2323,'AnalogInput_index2':0.0,'AnalogInput_index3':0.0,'AnalogOutput_index0':0.0,'AnalogOutput_index1':0.0,'AnalogOutput_index2':0.0,'AnalogOutput_index3':0.0,'BinaryInput_index0':False,'BinaryInput_index1':False,'BinaryInput_index2':False,'BinaryInput_index3':False,'BinaryOutput_index0':False,'BinaryOutput_index1':False,'BinaryOutput_index2':False,'BinaryOutput_index3':False},{'AnalogInput_index0':{'type':'integer','tz':'UTC','units':'NA'},'AnalogInput_index1':{'type':'integer','tz':'UTC','units':'NA'},'AnalogInput_index2':{'type':'integer','tz':'UTC','units':'NA'},'AnalogInput_index3':{'type':'integer','tz':'UTC','units':'NA'},'AnalogOutput_index0':{'type':'integer','tz':'UTC','units':'NA'},'AnalogOutput_index1':{'type':'integer','tz':'UTC','units':'NA'},'AnalogOutput_index2':{'type':'integer','tz':'UTC','units':'NA'},'AnalogOutput_index3':{'type':'integer','tz':'UTC','units':'NA'},'BinaryInput_index0':{'type':'integer','tz':'UTC','units':'NA'},'BinaryInput_index1':{'type':'integer','tz':'UTC','units':'NA'},'BinaryInput_index2':{'type':'integer','tz':'UTC','units':'NA'},'BinaryInput_index3':{'type':'integer','tz':'UTC','units':'NA'},'BinaryOutput_index0':{'type':'integer','tz':'UTC','units':'NA'},'BinaryOutput_index1':{'type':'integer','tz':'UTC','units':'NA'},'BinaryOutput_index2':{'type':'integer','tz':'UTC','units':'NA'},'BinaryOutput_index3':{'type':'integer','tz':'UTC','units':'NA'}}]2023-03-1400:11:55,810(volttron-platform-driver-0.2.0rc024737)volttron.driver.base.driver(334)DEBUG:finishpublishing:devices/campus/building/dnp3/all2023-03-1400:11:56,825(volttron-listener-0.2.0rc024424)listener.agent(104)INFO:Peer:pubsub,Sender:volttron-listener-0.2.0rc0_2:,Bus:,Topic:heartbeat/volttron-listener-0.2.0rc0_2,Headers:{'TimeStamp':'2023-03-14T05:11:56.820827+00:00','min_compatible_version':'3.0','max_compatible_version':''},Message:Shutdown the platformvctlshutdown--platformDevelopmentPlease see the following for contributing
guidelinescontributing.Please see the following helpful guide
aboutdeveloping modular VOLTTRON agentsDisclaimer NoticeThis material was prepared as an account of work sponsored by an agency of the
United States Government. Neither the United States Government nor the United
States Department of Energy, nor Battelle, nor any of their employees, nor any
jurisdiction or organization that has cooperated in the development of these
materials, makes any warranty, express or implied, or assumes any legal
liability or responsibility for the accuracy, completeness, or usefulness or any
information, apparatus, product, software, or process disclosed, or represents
that its use would not infringe privately owned rights.Reference herein to any specific commercial product, process, or service by
trade name, trademark, manufacturer, or otherwise does not necessarily
constitute or imply its endorsement, recommendation, or favoring by the United
States Government or any agency thereof, or Battelle Memorial Institute. The
views and opinions of authors expressed herein do not necessarily state or
reflect those of the United States Government or any agency thereof.