1 个稳定版本
1.0.0 | 2024年8月10日 |
---|
#3 在 #IEC
每月115次下载
18KB
283 行
RoboPLC I/O 连接器用于 IEC 60870-5
简介
IEC 60870-5 是一套关于电力系统遥信、遥测和相关的电信标准的集合,广泛用于欧盟、英国和其他地区。
此库为 RoboPLC 提供I/O连接器。
此库不适用于任何商业或生产用途。请参阅 https://github.com/roboplc/roboplc-io-iec60870-5/blob/main/LICENSE.md 获取更多信息。
客户端还支持
- 自动重连
- 多线程
- 实时安全性
- 来自供应商的企业级支持
注意:由于客户端具有异步方式的读取循环,强烈建议使用超时。如果远程不响应,没有超时的请求将永远卡住。
示例
IEC 60870-5 101 (串行)
此库不提供 IEC 60870-5 101 (串行) 客户端,因为不需要重新连接或特殊的报文处理逻辑。任何通信库加上 IEC 60870-5 库都可以用来创建/解析 IEC 60870-5 101 报文。
IEC 60870-5 104 (TCP)
连接客户端
use roboplc::comm::Timeouts;
use roboplc_io_iec60870_5::iec104::{Client, PingKind};
use std::time::Duration;
// Create a new IEC 60870-5 104 client
let (client, reader) = Client::new("192.168.1.100:2404", Timeouts::default(), 1024).unwrap();
// Get the telegram receiver
let telegram_rx = reader.get_telegram_receiver();
// The reader must be run in a separate thread
std::thread::spawn(move || reader.run());
// Create an optional pinger worker, which can send test/ack frames or
// automatically re-connect the socket
let pinger = client.pinger(PingKind::Test, Duration::from_secs(1));
std::thread::spawn(move || pinger.run());
处理传入的报文
use iec60870_5::{
telegram104::{Telegram104, Telegram104_I},
types::{datatype::{DataType, M_EP_TA_1}, COT},
};
use roboplc::prelude::*;
use std::time::Duration;
while let Ok(telegram) = telegram_rx.recv() {
println!("{:?}", telegram);
if let Telegram104::I(i) = telegram {
if i.data_type() == DataType::M_EP_TA_1 && i.cot() == COT::Cyclic {
for iou in i.iou() {
let v: M_EP_TA_1 = iou.value().into();
let dt = Timestamp::try_from(v.time)
.unwrap()
.try_into_datetime_local()
.unwrap();
dbg!(v.sep.es, Duration::from(v.elapsed), dt);
}
}
}
}
发送报文
客户端提供两种发送报文的方法
iec104::Client::send
用于发送不需要回复的报文iec104::Client::command
用于发送命令报文并等待回复
use iec60870_5::{
telegram104::{Telegram104, Telegram104_I},
types::{datatype::{DataType, SelectExecute, C_RC_TA_1, QU, RCO, RCS}, COT},
};
use roboplc::prelude::*;
let mut telegram: Telegram104_I = Telegram104_I::new(DataType::C_RC_TA_1, COT::Act, 47);
telegram.append_iou(
12,
C_RC_TA_1 {
rco: RCO {
rcs: RCS::Increment,
se: SelectExecute::Execute,
qu: QU::Persistent,
},
time: Timestamp::now().try_into().unwrap(),
},
);
let request: Telegram104 = telegram.into();
let reply = client.command(request).unwrap();
println!("COMMAND REPLY: {:?}", reply);
锁定策略
此库的锁定策略使用与 RoboPLC 锁定策略相同的特性设置。选择的策略必须相同。
依赖项
~9–19MB
~256K SLoC