RoboPLC I/O connector for IEC 60870-5

Overview

RoboPLC I/O connector for IEC 60870-5 crates.io page docs.rs page

Introduction

IEC 60870-5 is a set of standards for telecontrol, teleprotection, and associated telecommunications for electric power systems, widely used in the European Union, the United Kingdom and other locations.

This crate provides I/O connector for RoboPLC.

The crate IS NOT FREE for any commercial or production use. Please refer to https://github.com/roboplc/roboplc-io-iec60870-5/blob/main/LICENSE.md for more information.

The client additionally supports:

  • Auto-reconnects
  • Multi-threading
  • Real-time safety
  • Enterprise support from the vendor

Note: as the client has got an asynchronous-manner reader loop, it is HIGHLY RECOMMENDED to use timeouts. In case if a remote does not respond, a request with no timeout gets stuck forever.

Example

IEC 60870-5 101 (Serial)

The crate does not provide any client for IEC 60870-5 101 (Serial) as such does not require re-connection or a special telegram processing logic. Any communication library plus IEC 60870-5 crate can be used to create/parse IEC 60870-5 101 telegrams.

IEC 60870-5 104 (TCP)

Connecting a client

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

Handling incoming telegrams

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

Sending telegrams

The client provides two methods to send telegrams:

  • [iec104::Client::send] for sending a telegram with no reply expected
  • [iec104::Client::command] for sending a command telegram and waiting for a reply
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);

Locking policy

The crate locking policy is set using the same features as RoboPLC locking policy. The selected policy must be the same.

You might also like...
Owner
RoboPLC
RoboPLC® open-source eco-system
RoboPLC
Easy c̵̰͠r̵̛̠ö̴̪s̶̩̒s̵̭̀-t̶̲͝h̶̯̚r̵̺͐e̷̖̽ḁ̴̍d̶̖̔ ȓ̵͙ė̶͎ḟ̴͙e̸̖͛r̶̖͗ë̶̱́ṉ̵̒ĉ̷̥e̷͚̍ s̷̹͌h̷̲̉a̵̭͋r̷̫̊ḭ̵̊n̷̬͂g̵̦̃ f̶̻̊ơ̵̜ṟ̸̈́ R̵̞̋ù̵̺s̷̖̅ţ̸͗!̸̼͋

Rust S̵̓i̸̓n̵̉ I̴n̴f̶e̸r̵n̷a̴l mutability! Howdy, friendly Rust developer! Ever had a value get m̵̯̅ð̶͊v̴̮̾ê̴̼͘d away right under your nose just when

null 294 Dec 23, 2022
A temporary repo for ETH connector to be used by EVM

ETH connector for Rainbow bridge Definitions bridgedETH - NEP-141 fungible-token representation of ETH inside Near. nETH - native ETH inside Near EVM.

Project Aurora 36 Jul 26, 2022
🛂Rust implementation of lavaplayer connector

?? mixtape-bot/connector-rs Rust implementation of lavaplayer connector Discord Server Original Implementation ?? Progress Since I'm basically a compl

Mixtape 4 Oct 19, 2022
Rust API connector for Bybit's WebSockets APIs.

rust-bybit English | 简体中文 Unofficial Rust API connector for Bybit's WebSockets APIs. Disclaimer This is an unofficial Rust API connector for Bybit's A

yufuquant 12 Nov 12, 2022
Fork of the Official Python3 API connector for Bybit's HTTP (bybit) and WebSockets APIs to rust

Fork of pybit python libary in Rust For the rust lovers and creators for bybit exchange version 5 Official Python3 API connector for Bybit's HTTP and

Omambia Dauglous 4 Aug 29, 2023