{"id":27858424,"url":"https://github.com/roboplc/roboplc-io-ads","last_synced_at":"2025-05-04T14:09:55.866Z","repository":{"id":236374703,"uuid":"792485658","full_name":"roboplc/roboplc-io-ads","owner":"roboplc","description":"RoboPLC I/O connector for TwinCAT/ADS","archived":false,"fork":false,"pushed_at":"2025-01-11T18:28:13.000Z","size":79,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-05-04T14:09:50.325Z","etag":null,"topics":["ads","linux","plc","realtime","rust","twincat"],"latest_commit_sha":null,"homepage":"https://www.roboplc.com","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}},"created_at":"2024-04-26T19:09:28.000Z","updated_at":"2025-02-26T13:14:47.000Z","dependencies_parsed_at":"2024-04-26T20:28:02.171Z","dependency_job_id":null,"html_url":"https://github.com/roboplc/roboplc-io-ads","commit_stats":null,"previous_names":["roboplc/roboplc-io-ads"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/roboplc%2Froboplc-io-ads","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/roboplc%2Froboplc-io-ads/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/roboplc%2Froboplc-io-ads/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/roboplc%2Froboplc-io-ads/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/roboplc","download_url":"https://codeload.github.com/roboplc/roboplc-io-ads/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252344577,"owners_count":21732981,"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":["ads","linux","plc","realtime","rust","twincat"],"created_at":"2025-05-04T14:09:55.408Z","updated_at":"2025-05-04T14:09:55.858Z","avatar_url":"https://github.com/roboplc.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch2\u003e\n  RoboPLC I/O connector for TwinCAT/ADS\n  \u003ca href=\"https://crates.io/crates/roboplc-io-ads\"\u003e\u003cimg alt=\"crates.io page\" src=\"https://img.shields.io/crates/v/roboplc-io-ads.svg\"\u003e\u003c/img\u003e\u003c/a\u003e\n  \u003ca href=\"https://docs.rs/roboplc-io-ads\"\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\nADS is the native protocol used by programmable logic controllers (PLCs) and\nthe TwinCAT automation system produced by [Beckhoff GmbH](https://www.beckhoff.com/).\n\nThe\n[ADS\nspecification](https://infosys.beckhoff.com/english.php?content=../content/1033/tcinfosys3/11291871243.html\u0026id=6446904803799887467)\ncan be found on Beckhoff Information System pages.\n\n\nThis crate provides I/O connector for [RoboPLC](https://www.roboplc.com/).\n\nThe crate IS NOT FREE for any commercial or production use. Please refer to\n\u003chttps://github.com/roboplc/roboplc-io-ads/blob/main/LICENSE.md\u003e for more\ninformation.\n\n# Example\n\nRoboPLC I/O mapping:\n\n```rust,no_run\nuse ads::client::Client;\nuse roboplc::{comm::Timeouts, io::IoMapping, prelude::binrw};\nuse roboplc_io_ads as ads;\nuse std::time::Duration;\n\n#[binrw]\nstruct MyStruct {\n    field1: u32,\n    field2: f32,\n    field3: [u8; 8],\n    field4: f64\n}\n\n// Open a connection to an ADS device identified by hostname/IP and port.\n// For TwinCAT devices, a route must be set to allow the client to connect.\n// The source AMS address is automatically generated from the local IP,\n// but can be explicitly specified as the third argument.\n\n// The socket is automatically reconnected if the connection is lost.\nlet (client, reader) = Client::new((\"plchost\", ads::PORT),\n    Timeouts::new(Duration::from_secs(1)),\n    ads::Source::Auto).unwrap();\n\n// The reader thread MUST be started manually. Apply real-time settings if needed.\nstd::thread::spawn(move || { reader.run(); });\n\n// Specify the target ADS device to talk to, by NetID and AMS port.\n// Port 851 usually refers to the first PLC instance.\nlet device = client.device(ads::AmsAddr::new([5, 32, 116, 5, 1, 1].into(), 851));\n\n// Create a mapping for a symbol. The mapping contains a handle (automatically recreated on\n// each reconnect) as well as a pre-allocated buffer.\nlet mut mapping = device.mapping(\"MY_SYMBOL\", 24);\n\n// Read a structure from the PLC.\nlet mut data: MyStruct = mapping.read().unwrap();\ndata.field1 += 1;\n// Write the modified structure back to the PLC.\nmapping.write(\u0026data).unwrap();\n```\n\n# Example\n\nDirect usage:\n\n```rust,no_run\nuse ads::client::Client;\nuse roboplc::comm::Timeouts;\nuse roboplc_io_ads as ads;\nuse std::time::Duration;\n\nlet (client, reader) = Client::new((\"plchost\", ads::PORT),\n    Timeouts::new(Duration::from_secs(1)),\n    ads::Source::Auto).unwrap();\n\nstd::thread::spawn(move || { reader.run(); });\n\nlet device = client.device(ads::AmsAddr::new([5, 32, 116, 5, 1, 1].into(), 851));\n\n// Ensure that the PLC instance is running.\nassert!(device.get_state().unwrap().0 == ads::AdsState::Run);\n\n// Request a handle to a named symbol in the PLC instance.\nlet handle = ads::Handle::new(\u0026device, \"MY_SYMBOL\").unwrap();\n\n// Read data in form of an u32 from the handle.\nlet value: u32 = handle.read_value().unwrap();\nprintln!(\"MY_SYMBOL value is {}\", value);\n```\n\nThe API slightly differs from the free version as many methods have been rewritten to less-panic\nand thread-safe code. Certain internal types have been replaced with RoboPLC defaults.\n\nThe crate code is based on \u003chttps://github.com/birkenfeld/ads-rs\u003e project, (c)\nGeorg Brandl, Serhij Symonenko and other contributors.\n\nThe commercial client additionally supports:\n\n- Auto-reconnects\n- Multi-threading\n- Real-time safety\n- Enterprise support from the vendor\n\nNote: as the client has got an asynchronous-manner reader loop, it is HIGHLY RECOMMENDED to use\ntimeouts. In case if a remote does not respond, a request with no timeout gets stuck forever.\n\n## Locking policy\n\nThe crate locking policy is set using the same features as RoboPLC locking\npolicy. The selected policy must be the same.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Froboplc%2Froboplc-io-ads","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Froboplc%2Froboplc-io-ads","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Froboplc%2Froboplc-io-ads/lists"}