{"id":15725214,"url":"https://github.com/joylei/plctag-rs","last_synced_at":"2025-04-30T07:05:36.768Z","repository":{"id":49650411,"uuid":"292165906","full_name":"Joylei/plctag-rs","owner":"Joylei","description":"a rust wrapper of libplctag, with rust style APIs and useful extensions.","archived":false,"fork":false,"pushed_at":"2025-04-07T01:01:26.000Z","size":646,"stargazers_count":19,"open_issues_count":1,"forks_count":5,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-30T07:05:29.532Z","etag":null,"topics":["cip","ethernet-ip","libplctag","plc","rust"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Joylei.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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}},"created_at":"2020-09-02T03:09:58.000Z","updated_at":"2025-03-31T17:07:21.000Z","dependencies_parsed_at":"2023-02-09T19:31:34.585Z","dependency_job_id":"6b19f85b-1a53-4c59-8435-cc5951a0ae02","html_url":"https://github.com/Joylei/plctag-rs","commit_stats":{"total_commits":206,"total_committers":5,"mean_commits":41.2,"dds":0.1456310679611651,"last_synced_commit":"e93d2bb0d3e3995b412adb0b678f3a859c21fac0"},"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Joylei%2Fplctag-rs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Joylei%2Fplctag-rs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Joylei%2Fplctag-rs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Joylei%2Fplctag-rs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Joylei","download_url":"https://codeload.github.com/Joylei/plctag-rs/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251658200,"owners_count":21622819,"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","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":["cip","ethernet-ip","libplctag","plc","rust"],"created_at":"2024-10-03T22:20:04.496Z","updated_at":"2025-04-30T07:05:36.761Z","avatar_url":"https://github.com/Joylei.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# plctag-rs\r\n\r\na rust wrapper of [libplctag](https://github.com/libplctag/libplctag), with rust style APIs and useful extensions.\r\n\r\n[![crates.io](https://img.shields.io/crates/v/plctag.svg)](https://crates.io/crates/plctag)\r\n[![docs](https://docs.rs/plctag/badge.svg)](https://docs.rs/plctag)\r\n[![build](https://github.com/joylei/plctag-rs/workflows/build/badge.svg?branch=master)](https://github.com/joylei/plctag-rs/actions?query=workflow%3A%22build%22)\r\n[![license](https://img.shields.io/crates/l/plctag.svg)](https://github.com/joylei/plctag-rs/blob/master/LICENSE)\r\n\r\n## How to use\r\n\r\nAdd `plctag` to your Cargo.toml\r\n\r\n```toml\r\n[dependencies]\r\nplctag= \"0.4\"\r\n```\r\n\r\n## crates\r\n\r\n- [plctag](https://crates.io/crates/plctag) reexports everything from below crates.\r\n- [plctag-core](https://crates.io/crates/plctag-core) a rust wrapper of [libplctag](https://github.com/libplctag/libplctag), with rust style APIs and useful extensions.\r\n- [plctag-async](https://crates.io/crates/plctag-async) async wrapper.\r\n- [plctag-log](https://crates.io/crates/plctag-log) log adapter for `libplctag`\r\n- [plctag-derive](https://crates.io/crates/plctag-derive) macros for `plctag`\r\n- [plctag-sys](https://crates.io/crates/plctag-sys) native libplctag binding\r\n\r\n## Examples\r\n\r\n### read/write tag\r\n\r\n```rust\r\nuse plctag::{Encode, Decode, RawTag};\r\nlet timeout = 100;//ms\r\nlet path=\"protocol=ab-eip\u0026plc=controllogix\u0026path=1,0\u0026gateway=192.168.1.120\u0026name=MyTag1\u0026elem_count=1\u0026elem_size=16\";// YOUR TAG DEFINITION\r\nlet tag = RawTag::new(path, timeout).unwrap();\r\n\r\n//read tag\r\nlet status = tag.read(timeout);\r\nassert!(status.is_ok());\r\nlet offset = 0;\r\nlet value:u16 = tag.get_value(offset).unwrap();\r\nprintln!(\"tag value: {}\", value);\r\n\r\nlet value = value + 10;\r\ntag.set_value(offset, value).unwrap();\r\n\r\n//write tag\r\nlet status = tag.write(timeout);\r\nassert!(status.is_ok());\r\nprintln!(\"write done!\");\r\n```\r\n\r\n### UDT\r\n\r\nread/write UDT\r\n\r\n```rust\r\nuse plctag::{Decode, Encode, RawTag, Result};\r\n\r\n// define your UDT\r\n#[derive(Default, Debug, Decode, Encode)]\r\nstruct MyUDT {\r\n    #[tag(offset = 0)]\r\n    v1: u16,\r\n    #[tag(offset = 2)]\r\n    v2: u16,\r\n}\r\n\r\n\r\nlet timeout = 100; //ms\r\n                    // YOUR TAG DEFINITION\r\nlet path = \"protocol=ab-eip\u0026plc=controllogix\u0026path=1,0\u0026gateway=192.168.1.120\u0026name=MyTag2\u0026elem_count=2\u0026elem_size=16\";\r\nlet tag = RawTag::new(path, timeout).unwrap();\r\n\r\n//read tag\r\nlet status = tag.read(timeout);\r\nassert!(status.is_ok());\r\nlet offset = 0;\r\nlet mut value: MyUDT = tag.get_value(offset).unwrap();\r\nprintln!(\"tag value: {:?}\", value);\r\n\r\nvalue.v1 += 10;\r\ntag.set_value(offset, value).unwrap();\r\n\r\n//write tag\r\nlet status = tag.write(timeout);\r\nassert!(status.is_ok());\r\nprintln!(\"write done!\");\r\n\r\n```\r\n\r\nNote:\r\nDo not perform expensive operations when you derives `Decode` or `Encode`.\r\n\r\n### Async\r\n\r\n```rust\r\nuse plctag::futures::{AsyncTag, Error};\r\n\r\nuse tokio::runtime;\r\n\r\nlet rt = runtime::Runtime::new().unwrap();\r\nlet res: Result\u003c_, Error\u003e = rt.block_on(async {\r\n    let path=\"protocol=ab-eip\u0026plc=controllogix\u0026path=1,0\u0026gateway=192.168.1.120\u0026name=MyTag1\u0026elem_count=1\u0026elem_size=16\"; // YOUR TAG DEFINITION\r\n    let tag = AsyncTag::create(path).await?;\r\n    let tag_ref = tag.get().await?;\r\n    let offset = 0;\r\n    let value: u16 = tag_ref.read_value(offset).await?;\r\n    println!(\"tag value: {}\", value);\r\n\r\n    let value = value + 10;\r\n    tag_ref.write_value(offset, value).await?;\r\n    Ok(())\r\n});\r\nres.unwrap();\r\n\r\n```\r\n\r\n### Path Builder\r\n\r\n```rust\r\nuse plctag::builder::*;\r\nuse plctag::RawTag;\r\n\r\nlet timeout = 100;\r\nlet path = PathBuilder::default()\r\n    .protocol(Protocol::EIP)\r\n    .gateway(\"192.168.1.120\")\r\n    .plc(PlcKind::ControlLogix)\r\n    .name(\"MyTag1\")\r\n    .element_size(16)\r\n    .element_count(1)\r\n    .path(\"1,0\")\r\n    .read_cache_ms(0)\r\n    .build()\r\n    .unwrap();\r\nlet tag = RawTag::new(path, timeout).unwrap();\r\nlet status = tag.status();\r\nassert!(status.is_ok());\r\n\r\n```\r\n\r\n### Logging adapter for `libplctag`\r\n\r\n```rust\r\nuse plctag::log::log_adapt;\r\nuse plctag::log::set_debug_level;\r\nuse plctag::log::DebugLevel;\r\n\r\nlog_adapt(); //register logger\r\nset_debug_level(DebugLevel::Info); // set debug level\r\n\r\n// now, you can receive log messages by any of logging implementations of crate `log`\r\n\r\n```\r\n\r\n## Build\r\n\r\nPlease refer to [How to build](https://github.com/Joylei/plctag-rs/tree/master/crates/sys#build) to setup build environment.\r\n\r\n\r\n### Static build\r\nPlease refer to [Static build](https://github.com/Joylei/plctag-rs/tree/master/crates/sys#Static%20build)\r\n\r\n\r\n## Bench\r\n\r\n```shell\r\ncargo bench\r\n```\r\n\r\nThe plots and saved data are stored under target/criterion/$BENCHMARK_NAME/\r\n\r\n### Bench Result\r\n\r\nProcessor: Intel(R) Core(TM) i7-9700KF CPU @ 3.60GHz   3.60 GHz\r\nRAM: 64.0 GB\r\n\r\n```\r\nasync read              time:   [4.3608 ms 4.3937 ms 4.4287 ms]\r\n                        change: [-3.7035% -2.5545% -1.3730%] (p = 0.00 \u003c 0.05)\r\n                        Performance has improved.\r\nFound 7 outliers among 100 measurements (7.00%)\r\n  7 (7.00%) high mild\r\n\r\nasync batch-20 read     time:   [11.852 ms 11.949 ms 12.054 ms]\r\n                        change: [-2.2194% -0.9951% +0.2445%] (p = 0.11 \u003e 0.05)\r\n                        No change in performance detected.\r\nFound 5 outliers among 100 measurements (5.00%)\r\n  1 (1.00%) low mild\r\n  3 (3.00%) high mild\r\n  1 (1.00%) high severe\r\n\r\nsync read               time:   [3.1016 ms 3.1272 ms 3.1553 ms]\r\n                        change: [-2.4462% -1.1947% +0.1535%] (p = 0.07 \u003e 0.05)\r\n                        No change in performance detected.\r\nFound 9 outliers among 100 measurements (9.00%)\r\n  6 (6.00%) high mild\r\n  3 (3.00%) high severe\r\n```\r\n\r\n## License\r\n\r\nMIT\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjoylei%2Fplctag-rs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjoylei%2Fplctag-rs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjoylei%2Fplctag-rs/lists"}