plctag-rs

a rust wrapper of libplctag, with rust style APIs and useful extensions.

crates.io docs build license

Why plctag-rs

How to use

Add plctag to your Cargo.toml

toml [dependencies] plctag= "0.2"

crates

Examples

read/write tag

```rust use plctag::{Encode, Decode, RawTag}; let timeout = 100;//ms let path="protocol=ab-eip&plc=controllogix&path=1,0&gateway=192.168.1.120&name=MyTag1&elemcount=1&elemsize=16";// YOUR TAG DEFINITION let tag = RawTag::new(path, timeout).unwrap();

//read tag let status = tag.read(timeout); assert!(status.isok()); let offset = 0; let value:u16 = tag.getvalue(offset).unwrap(); println!("tag value: {}", value);

let value = value + 10; tag.set_value(offset, value).unwrap();

//write tag let status = tag.write(timeout); assert!(status.is_ok()); println!("write done!"); ```

UDT

read/write UDT

```rust use plctag::{Decode, Encode, RawTag, Result};

// define your UDT

[derive(Default, Debug, Decode, Encode)]

struct MyUDT { #[tag(offset = 0)] v1: u16, #[tag(offset = 2)] v2: u16, }

fn main() { let timeout = 100; //ms // YOUR TAG DEFINITION let path = "protocol=ab-eip&plc=controllogix&path=1,0&gateway=192.168.1.120&name=MyTag2&elemcount=2&elemsize=16"; let tag = RawTag::new(path, timeout).unwrap();

//read tag
let status = tag.read(timeout);
assert!(status.is_ok());
let offset = 0;
let mut value: MyUDT = tag.get_value(offset).unwrap();
println!("tag value: {:?}", value);

value.v1 = value.v1 + 10;
tag.set_value(offset, value).unwrap();

//write tag
let status = tag.write(timeout);
assert!(status.is_ok());
println!("write done!");

} ```

Note: Do not perform expensive operations when you derives Decode or Encode.

Async

```rust use plctag::futures::{AsyncTag, Error, TagEntry};

use tokio::runtime;

fn main() { let rt = runtime::Runtime::new().unwrap(); let res: Result<_, Error> = rt.blockon(async { let path="protocol=ab-eip&plc=controllogix&path=1,0&gateway=192.168.1.120&name=MyTag1&elemcount=1&elemsize=16"; // YOUR TAG DEFINITION let tag = TagEntry::create(path).await?; let tagref = tag.get().await?; let offset = 0; let value: u16 = tagref.readvalue(offset).await?; println!("tag value: {}", value);

    let value = value + 10;
    tag_ref.write_value(offset, value).await?;
    Ok(())
});
res.unwrap();

}

```

Path Builder

```rust use plctag::builder::*; use plctag::RawTag;

fn main() { let timeout = 100; let path = PathBuilder::default() .protocol(Protocol::EIP) .gateway("192.168.1.120") .plc(PlcKind::ControlLogix) .name("MyTag1") .elementsize(16) .elementcount(1) .path("1,0") .readcachems(0) .build() .unwrap(); let tag = RawTag::new(path, timeout).unwrap(); let status = tag.status(); assert!(status.is_ok()); }

```

Logging adapter for libplctag

```rust use plctag::log::logadapt; use plctag::log::setdebug_level; use plctag::log::DebugLevel;

logadapt(); //register logger setdebug_level(DebugLevel::Info); // set debug level

// now, you can receive log messages by any of logging implementations of crate log

```

Thread-safety

Operations are not thread-safe in this library except async wrappers, please use std::sync::Mutex or something similar to enforce thread-safety.

Build & Test

Please refer to How to use to setup build environment.

Because mutithread will cause troubles, you need to run tests with:

shell cargo test --all -- --test-threads=1

Bench

shell cargo bench

The plots and saved data are stored under target/criterion/$BENCHMARK_NAME/

License

MIT