{"id":27858435,"url":"https://github.com/roboplc/iec60870-5","last_synced_at":"2025-10-15T06:29:20.392Z","repository":{"id":247679221,"uuid":"826545386","full_name":"roboplc/iec60870-5","owner":"roboplc","description":"IEC 60870-5 101/104 Rust protocol implementation","archived":false,"fork":false,"pushed_at":"2024-08-11T23:50:09.000Z","size":58,"stargazers_count":19,"open_issues_count":0,"forks_count":3,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-07-11T08:51:17.915Z","etag":null,"topics":["60870-5","iec","industrial","plc","rust","scada"],"latest_commit_sha":null,"homepage":"https://www.bohemia-automation.com/software/libraries/","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/roboplc.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-07-09T23:15:54.000Z","updated_at":"2025-05-05T09:02:01.000Z","dependencies_parsed_at":"2024-07-10T03:16:41.526Z","dependency_job_id":"80d46e31-0692-4476-8005-9932d386fcdc","html_url":"https://github.com/roboplc/iec60870-5","commit_stats":null,"previous_names":["roboplc/iec60870-5"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/roboplc/iec60870-5","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/roboplc%2Fiec60870-5","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/roboplc%2Fiec60870-5/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/roboplc%2Fiec60870-5/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/roboplc%2Fiec60870-5/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/roboplc","download_url":"https://codeload.github.com/roboplc/iec60870-5/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/roboplc%2Fiec60870-5/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":268695436,"owners_count":24292048,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-04T02:00:09.867Z","response_time":79,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["60870-5","iec","industrial","plc","rust","scada"],"created_at":"2025-05-04T14:10:29.946Z","updated_at":"2025-10-15T06:29:15.369Z","avatar_url":"https://github.com/roboplc.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch2\u003e\n  IEC 60870-5 101/104 Rust protocol implementation\n  \u003ca href=\"https://crates.io/crates/iec60870-5\"\u003e\u003cimg alt=\"crates.io page\" src=\"https://img.shields.io/crates/v/iec60870-5.svg\"\u003e\u003c/img\u003e\u003c/a\u003e\n  \u003ca href=\"https://docs.rs/iec60870-5\"\u003e\u003cimg alt=\"docs.rs page\" src=\"https://docs.rs/roboplc-io-ads/badge.svg\"\u003e\u003c/img\u003e\u003c/a\u003e\n\u003c/h2\u003e\n\n# Introduction\n\n[IEC 60870-5](https://en.wikipedia.org/wiki/IEC_60870-5) is a set of standards\nfor telecontrol, teleprotection, and associated telecommunications for electric\npower systems, widely used in the European Union, the United Kingdom and other\nlocations.\n\nThe crate provides a fully Rust-safe transport-agnostic implementation for IEC\n60870-5 101/104 telegrams and common data types. The library contains almost\nthe complete set of types and instruments required to easily write own client\nor server, including time conversion between Rust and IEC 60870-5 formats.\n\nThe crate IS NOT FREE for any commercial or production use. Please refer to\n\u003chttps://github.com/roboplc/iec60870-5/blob/main/LICENSE.md\u003e for more\ninformation.\n\nIEC 60870-5 Rust library is a part of the [RoboPLC](https://roboplc.com)\nproject.\n\nMSRV: 1.68.0\n\n# Examples\n\n## Creating a simple data transmission start IEC 60870-5 104 telegram\n\n```rust\nuse iec60870_5::telegram104::Telegram104;\n\nlet telegram = Telegram104::new_start_dt();\n// The telegram is ready to be sent in any way\nlet mut buffer = std::io::Cursor::new(Vec::new());\ntelegram.write(\u0026mut buffer).unwrap();\n```\n\n## Creating a IEC 60870-5 104 command telegram\n\n```rust\n// A timestamp crate\nuse bma_ts::Timestamp;\nuse iec60870_5::types::datatype::{C_RC_TA_1, DataType, QU, RCO, RCS, SelectExecute};\nuse iec60870_5::types::COT;\nuse iec60870_5::telegram104::{ChatSequenceCounter, Telegram104, Telegram104_I};\n\n// To communicate with the server, the client must have a chat sequence counter\nlet chat_sequence_counter = ChatSequenceCounter::new();\n\nlet mut telegram_i: Telegram104_I = Telegram104_I::new(\n    DataType::C_RC_TA_1, // Data type, regulating step command with CP56Time2a time tag\n    COT::Act, // Cause of transmission: activation\n    15 // ASDU address\n    );\ntelegram_i.append_iou(\n    11, // Information object address,\n    C_RC_TA_1 { // Regulating step command with CP56Time2a time tag\n        rco: RCO {\n            rcs: RCS::Increment,\n            se: SelectExecute::Execute,\n            qu: QU::Persistent,\n        },\n        time: Timestamp::now().try_into().unwrap(),\n    },\n);\nlet mut telegram: Telegram104 = telegram_i.into();\ntelegram.chat_sequence_apply_outgoing(\u0026chat_sequence_counter);\n// The telegram is ready to be sent in any way\nlet mut buffer = std::io::Cursor::new(Vec::new());\ntelegram.write(\u0026mut buffer).unwrap();\n```\n\n## Reading a IEC 60870-5 104 telegram\n\n```rust,no_run\n// A timestamp crate\nuse bma_ts::Timestamp;\nuse iec60870_5::telegram104::{ChatSequenceCounter, Telegram104};\nuse iec60870_5::types::datatype::{DataType, M_EP_TA_1};\n\n// For strict servers, the client must have a chat sequence counter\nlet chat_sequence_counter = ChatSequenceCounter::new();\n\n// Consider that the buffer contains a valid telegram\nlet mut buffer = std::io::Cursor::new(Vec::new());\nlet telegram = Telegram104::read(\u0026mut buffer).unwrap();\ntelegram.chat_sequence_validate_incoming(\u0026chat_sequence_counter).unwrap();\nif let Telegram104::I(i) = telegram {\n    // This is an I-frame\n    if i.data_type() == DataType::M_EP_TA_1 {\n        // This is a M_EP_TA_1 telegram\n        for iou in i.iou() {\n            // Decode MP_EP_TA_1 information object value from the raw IOU buffer\n            let val: M_EP_TA_1 = iou.value().into();\n            // Convert the time tag to a timestamp\n            let dt = Timestamp::try_from(val.time).unwrap();\n            // Output the event state and the timestamp\n            dbg!(val.sep.es, dt);\n        }\n    }\n}\n```\n\n# Troubleshooting\n\n* As IEC 60870-5 is a complex standard, 3rd party hardware/software vendors\nusually do not implement it it full, some functionality may require additional\ndevelopment/workarounds.\n\n* The library has been fully tested in pair with [Beckhoff TwinCAT 3\n  TF6500](https://www.beckhoff.com/en-en/products/automation/twincat/tfxxxx-twincat-3-functions/tf6xxx-connectivity/tf6500.html)\nas well as with certain embedded implementations, used in the European Union\npower grids.\n\n* The most common problem is that the majority of the IEC 60870-5 104 servers\n  require keep-alive frames. Such can be generated either using IEC 60870-5 104\n  S-Frames, or test U-frames out-of-the-box:\n\n```rust\nuse iec60870_5::telegram104::Telegram104;\n\nlet telegram = Telegram104::new_test();\n// Write the telegram to the target\n```\n\n## About the authors\n\n[Bohemia Automation](https://www.bohemia-automation.com) /\n[Altertech](https://www.altertech.com) is a group of companies with 15+ years\nof experience in the enterprise automation and industrial IoT. Our setups\ninclude power plants, factories and urban infrastructure. Largest of them have\n1M+ sensors and controlled devices and the bar raises higher and higher every\nday.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Froboplc%2Fiec60870-5","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Froboplc%2Fiec60870-5","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Froboplc%2Fiec60870-5/lists"}