A adição do protocolo iec-104 à scadapy oferece oportunidades adicionais para expandir o sistema, tanto em automação residencial quanto para uso local em pequenas empresas.
Esse protocolo é bastante difícil de aprender, mas no momento, na Internet, você encontra documentação suficiente para se familiarizar.
O que nos dá o uso deste protocolo?
Um fator importante é que o protocolo é assíncrono, diferentemente do modbus, e os dados são transmitidos apenas no caso de alteração do estado atual da variável, o que, por sua vez, reduz a carga nos canais de comunicação. Também é possível obter o registro de data e hora do estado da variável no objeto; no modbus, registros separados são usados para isso.
Os detalhes podem ser lidos
aqui .
No momento, não conseguimos encontrar uma biblioteca adequada para desenvolvimento escrita em Python; portanto, usamos uma biblioteca pronta em C
neste site .
Em seguida, compilou dois utilitários iec104client e iec104server.
Cliente
Ao usar o cliente IEC 60870-5-104, o utilitário iec104client estabelece comunicação com o escravo, após o qual os dados são recebidos do objeto e, inicialmente, o comando (20) é formado - a pesquisa geral (interrogada pelo interrogatório da estação) e o processamento dos dados recebidos, e então existe uma técnica esporádica para alterar o valor das variáveis.
No caso de perda de comunicação com o dispositivo, o utilitário iec104client tentará executar uma recuperação de comunicação por conta própria. Ao retomar uma sessão de comunicação, a equipe de pesquisa em grupo (20) é enviada primeiro e depois a recepção esporádica.
ASDUs suportados:Valores discretos:- <36> M_SP_TB_1 - informações de singleton com um carimbo de data / hora CP56Time2a
- <1> M_SP_NA_1 - informações de singleton
Valores analógicos:- <13> M_ME_NC - valor medido, formato curto de ponto flutuante sem carimbo de hora.
- <36> M_ME_TF_1 - valor medido, formato curto de ponto flutuante com registro de data e hora CP56Time2a.
- <11> M_ME_NB_1 - valor medido, valor escalado
Não é difícil entender o texto fonte, atenção especial deve ser dada à função
static bool asduReceivedHandler (void* parameter, int address, CS101_ASDU asdu).
Todo o processamento dos dados recebidos ocorre nele.
Você pode simplesmente sair
printf("REC type: %s(%i) elements: %i\n", TypeID_toString(CS101_ASDU_getTypeID(asdu)), CS101_ASDU_getTypeID(asdu), CS101_ASDU_getNumberOfElements(asdu));
e depois acompanhe quais dados foram aceitos.

O diagrama acima mostra o princípio do programa.
Após receber o valor de status de um sinal discreto ou analógico, o pacote json udp é transmitido ao servidor de monitoramento ou outro servidor fornecido (usamos o servidor web json).
O formato do pacote não foi alterado: {"nome": "myvar", "dados": [220.001]}
Atualmente, o carimbo de data e hora não é transmitido no pacote devido à falta de necessidade, mas ainda acho que precisará ser adicionado.
O arquivo de configuração do parâmetro iec104client se parece com o seguinte:
Arquivo de configuração do 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" --
}
}
]
Um pequeno exemplo de arquivo de configuração para receber valores de um servidor de baixo nível, interrogando o RPA Sirius 3-LV-03 via Modbus RTU. Nesse caso, estamos interessados apenas em correntes e tensões, e o restante das informações entra no sistema SCADA da SDTU.
Subestação 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
Ao usar o servidor IEC 60870-5-104, o utilitário iec104server atua como um servidor udp, mantém a comunicação com o cliente e, quando o estado da variável é alterado, transfere dados para o canal de comunicação.
O arquivo de configuração do parâmetro iec104server é semelhante a este:
Configuração do 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"
}
}
]

Compilação
Windows:Para construir os utilitários, foi usado o pacote
msys2-i686-20180531 .
Você precisa instalar este pacote, por exemplo, na unidade C:, obtém algo como C: \ msys32. Entramos nesse diretório e executamos o arquivo msys2_shell.cmd.
Uma janela do console aparecerá, na qual você poderá inserir comandos linux.
Você deve instalar as bibliotecas necessárias para compilação:
pacman –S make pacman –S gcc
Agora você precisa fazer o download da fonte para compilação.
Vamos
aqui, faça o download do arquivo, copie a pasta lib60870-C para c: \ msys32.
Na janela do console do msys, compilamos a biblioteca lib60870:
cd /lib60870-C make clean make

Agora faça
cd scadapy104
Começamos a montagem do 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

Iniciamos a montagem do 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

Na pasta
C:\msys32\lib60870-C\scadapy104\bin
haverá dois arquivos iec104client.exe e iec104server.exe.
Para executar esses arquivos,
eram necessários
arquivos dll no Windows 7.8
Em outras versões do Windows não verificou.
Agora, se você executar qualquer um desses utilitários, um prompt de ajuda será exibido.
Linux:Você deve instalar o gcc e criar pacotes se não estiver instalado (usando o Ubuntu):
$ sudo apt install build-essential
Então tudo é compilado de maneira semelhante.
Os arquivos de configuração podem ser criados e testados no "ScadaPy creator".
Para o cliente:

Para servidor:

Todas as bibliotecas e projetos estão
aqui.