#实时 #工业 #PLC #IEC #标准 #60870-5

roboplc-io-iec60870-5

RoboPLC I/O 连接器用于 TwinCAT/ADS

1 个稳定版本

1.0.0 2024年8月10日

#3#IEC

Download history 89/week @ 2024-08-05 26/week @ 2024-08-12

每月115次下载

自定义许可

18KB
283

RoboPLC I/O 连接器用于 IEC 60870-5 crates.io 页面 docs.rs 页面

简介

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);
            }
        }
    }
}

发送报文

客户端提供两种发送报文的方法

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