Agregar el protocolo iec-104 a scadapy brinda oportunidades adicionales para expandir el sistema, tanto en domótica como para uso local en pequeñas empresas.
Este protocolo es bastante difícil de aprender, pero en este momento en Internet puede encontrar suficiente documentación para familiarizarse.
¿Qué nos da el uso de este protocolo?
Un factor importante es que el protocolo es asíncrono, a diferencia del modbus, y los datos se transmiten solo en caso de cambiar el estado actual de la variable, lo que a su vez reduce la carga en los canales de comunicación. También es posible obtener la marca de tiempo del estado de la variable en el objeto; en Modbus, se utilizan registros separados para esto.
Los detalles se pueden leer
aquí .
Por el momento, no hemos podido encontrar una biblioteca adecuada para el desarrollo, escrito en Python, por lo que se utiliza una biblioteca confeccionada de C
de este sitio .
Luego compiló dos utilidades iec104client y iec104server.
Cliente
Cuando se usa el cliente IEC 60870-5-104, la utilidad iec104client establece comunicación con el esclavo, después de lo cual se reciben los datos del objeto, e inicialmente se forma el comando (20): el levantamiento general (interrogado por interrogación de estación) y el procesamiento de los datos recibidos, y entonces hay una técnica esporádica para cambiar el valor de las variables.
En caso de pérdida de comunicación con el dispositivo, la utilidad iec104client intentará realizar una recuperación de la comunicación por sí mismo. Al reanudar una sesión de comunicación, primero se envía al equipo de encuesta grupal (20) y luego a la recepción esporádica.
ASDU compatibles:Valores discretos:- <36> M_SP_TB_1: información de un solo tono con una marca de tiempo CP56Time2a
- <1> M_SP_NA_1 - información de singleton
Valores análogos:- <13> M_ME_NC: valor medido, formato corto de coma flotante sin marca de tiempo.
- <36> M_ME_TF_1 - valor medido, formato corto de coma flotante con sello de tiempo CP56Time2a.
- <11> M_ME_NB_1 - valor medido, valor escalado
No es difícil entender el texto fuente, se debe prestar especial atención a la función
static bool asduReceivedHandler (void* parameter, int address, CS101_ASDU asdu).
Todo el procesamiento de los datos recibidos ocurre en él.
Puedes irte
printf("REC type: %s(%i) elements: %i\n", TypeID_toString(CS101_ASDU_getTypeID(asdu)), CS101_ASDU_getTypeID(asdu), CS101_ASDU_getNumberOfElements(asdu));
y luego realizar un seguimiento de los datos que se han aceptado.

El diagrama anterior muestra el principio del programa.
Después de recibir el valor de estado de una señal discreta o analógica, el paquete json udp se transmite al servidor de monitoreo u otro servidor provisto (usamos el servidor web json).
El formato del paquete no ha cambiado: {"nombre": "myvar", "datos": [220.001]}
Actualmente, la marca de tiempo no se transmite en el paquete debido a la falta de necesidad, pero sigo pensando que será necesario agregarla.
El archivo de configuración del parámetro iec104client tiene este aspecto:
Archivo de configuración del cliente[
{ "Client":
{ "UdpPort" :"64000", -- UDP
"UdpIp" :"127.0.0.1", -- IP UDP
"Iec104Port":"2404", -- 104 ( )
"Iec104Ip" :"192.168.0.105", -- IP 104
"Debug" :"1", -- (1 3)
"TimeSync" :"1" -- (1 0)
}
}
,
{ "MeasureValue": --
{
"VarName" : "WaterTemp", --
"IecAddress": "8001", --
"Alias" : " ", --
"VarType" : "int32" --
//int – int 2
//int32 – 4 ( float)
//float –
//
}
}
,
{ "SinglePoint": --
{
"VarName" : "EngineOnOff", --
"IecAddress": "4001", --
"Alias" : " ", --
"VarType" : "bool" --
}
}
]
Un pequeño ejemplo de un archivo de configuración para recibir valores de un servidor de bajo nivel, interrogando a RPA Sirius 3-LV-03 a través de Modbus RTU. En este caso, solo nos interesan las corrientes y los voltajes, y el resto de la información ingresa al sistema SCADA de SDTU.
Subestación de 110 kV[
{ "Client":
{ "UdpPort" :"64000",
"UdpIp" :"0.0.0.0",
"Iec104Port":"2404",
"Iec104Ip" :"...",
"Debug" :"1",
"TimeSync" :"0"
}
}
,
{ "SinglePoint":
{
"VarName" : "alarm",
"IecAddress": "681",
"Alias" : "alarm",
"VarType" : "bool"
}
}
,
{ "MeasureValue":
{
"VarName" : "Ia",
"IecAddress": "372",
"Alias" : "-- Ia --",
"VarType" : "float"
}
}
,
{ "MeasureValue":
{
"VarName" : "Ib",
"IecAddress": "373",
"Alias" : "-- Ib --",
"VarType" : "float"
}
}
,
{ "MeasureValue":
{
"VarName" : "Ic",
"IecAddress": "374",
"Alias" : "-- Ic --",
"VarType" : "float"
}
}
,
{ "MeasureValue":
{
"VarName" : "Uab",
"IecAddress": "369",
"Alias" : "-- Uab --",
"VarType" : "float"
}
}
,
{ "MeasureValue":
{
"VarName" : "Ubc",
"IecAddress": "370",
"Alias" : "-- Ubc --",
"VarType" : "float"
}
}
,
{ "MeasureValue":
{
"VarName" : "Uca",
"IecAddress": "371",
"Alias" : "-- Uca --",
"VarType" : "float"
}
}
]
Servidor
Cuando se utiliza el servidor IEC 60870-5-104, la utilidad iec104server actúa como un servidor udp, mantiene la comunicación con el cliente y, cuando cambia el estado de la variable, transfiere datos al canal de comunicación.
El archivo de configuración del parámetro iec104server tiene este aspecto:
Configuración del servidor[
{ "Server":
{ "UdpPort" :"64002",
"UdpIp" :"127.0.0.1",
"Iec104Port":"2404",
"Iec104Ip" :"192.168.0.103",
"Debug" :"1"
}
}
,
{ "MeasureValue":
{
"VarName" : "WaterTemp",
"IecAddress" : "8001",
"OffSet" : "0", -- (0– ) [100,200,300,400]
"ByteCount" : "2", -- (1,2)
"ByteSequence": "12",-- (1,12,21)
"Koef" : "1", --
"VarType" : "int" –
}
}
,
{ "SinglePoint":
{
"VarName" : "EngineOnOff",
"IecAddress" : "4001",
"OffSet" : "0",
"ByteCount" : "1", --
"ByteSequence": "1", --
"VarType" : "bool"
}
}
]

Compilación
Ventanas:Para construir las utilidades, se utilizó el paquete
msys2-i686-20180531 .
Debe instalar este paquete, por ejemplo, en la unidad C: obtiene algo como C: \ msys32. Entramos en este directorio y ejecutamos el archivo msys2_shell.cmd.
Aparecerá una ventana de consola en la que ahora puede ingresar comandos de Linux.
Debe instalar las bibliotecas necesarias para la compilación:
pacman –S make pacman –S gcc
Ahora necesita descargar la fuente para la compilación.
Vamos
aquí, descarguemos el archivo, copiemos la carpeta lib60870-C en c: \ msys32.
En la ventana de la consola msys, compilamos la biblioteca lib60870:
cd /lib60870-C make clean make

Ahora hacer
cd scadapy104
Comenzamos el ensamblaje del servidor:
gcc -g -g -o ./bin/iec104server.exe iec104server.c ./parson/parson.c -I../src/inc/api -I../src/hal/inc -I../src/tls -I./parson ../build/lib60870.a –lpthread

Comenzamos el montaje del cliente:
gcc -g -g -o ./bin/iec104client.exe iec104client.c ./parson/parson.c -I../src/inc/api -I../src/hal/inc -I../src/tls -I./parson ../build/lib60870.a -lpthread

En la carpeta
C:\msys32\lib60870-C\scadapy104\bin
habrá dos archivos iec104client.exe y iec104server.exe.
Para ejecutar estos archivos, en Windows 7.8
se necesitaban
archivos dll
En otras versiones de Windows no se verificó.
Ahora, si ejecuta alguna de estas utilidades, aparecerá un mensaje de ayuda.
Linux:Debe instalar el gcc y hacer paquetes si no está instalado (usando Ubuntu):
$ sudo apt install build-essential
Entonces todo se compila de manera similar.
Los archivos de configuración se pueden crear y probar en "ScadaPy creator".
Para el cliente:

Para el servidor:

Todas las bibliotecas y proyectos están
aquí.