Giter Site home page Giter Site logo

eip-rs's People

Contributors

crimsondamask avatar joylei avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

eip-rs's Issues

Bytes

How to use type bytes?

let value: TagValue<Bytes> = client.read_tag(tag).await?;

error[E0412]: cannot find type `Bytes` in this scope
  --> src/main.rs:12:25
   |
12 |     let value: TagValue<Bytes> = client.read_tag(tag.clone()).await?;
   |                         ^^^^^ not found in this scope
   |
help: consider importing one of these items
   |
1  | use core::str::Bytes;
   |
1  | use std::io::Bytes;
   |
1  | use std::str::Bytes;
   |

I have tried all imports suggested by the compiler but did not succeed

Future cannot be sent between threads safely

I have worked through the example you provided in the ReadMe, and it works great! I can read/write tags without a hitch.

The issue arises when I attempt to create a background task to handle the reading/writing of tags. Rust Analyzer gives me the following error:

future cannot be sent between threads safely
the trait `std::marker::Send` is not implemented for `dyn std::future::Future<Output = Result<rseip::client::ab_eip::TagValue<i32>, ClientError>>`rustc
[main.rs(18, 32): ]()future is not `Send` as it awaits another future which is not `Send`
[spawn.rs(127, 21): ]()required by a bound in `tokio::spawn` 

However, in the docs, it specifically says that ClientError is Send and TagValue is Send so long as T is also Send. This might just be my inexperience with tokio, but I am wondering if you could shed some light on how to do this properly.

Here is my sample code:

use rseip::client::ab_eip::*;
use rseip::precludes::*;

#[tokio::main]
async fn main(){
    tokio::spawn(async move {
        background().await;
    });
}

async fn background() -> Result<()> {
    let mut client = AbEipClient::new_host_lookup("192.168.0.83")
        .await?
        .with_connection_path(PortSegment::default());
    let tag = EPath::parse_tag("test_car1_x")?;
    println!("read tag...");
    let value: TagValue<i32> = client.read_tag(tag.clone()).await?;
    println!("tag value: {:?}", value);
    client.write_tag(tag, value).await?;
    println!("write tag - done");
    client.close().await?;
    Ok(())
}

Thank you in advance!

I was not able to read a tag value in a controller..

I was not able to read a tag in a controller with this command:

let mut client =
AbEipConnection::new_host_lookup("xx.xx.xx.xx", OpenOptions::default()).await?;
println!("read tag...{:?}", client);
let tag1 = EPath::from_symbol("Cfg_LoSeverity");
println!("read tag...{:?}", tag1);
let value: TagValue = client.read_tag(tag1.clone()).await?;
println!("read tag...{:?}", value);
client.close().await?;

This is the output:
read tag...Connection { addr: xx.xx.xx.xx:44818, origin_options: OpenOptions { o_t_connection_id: 0, t_o_connection_id: 0, priority_tick_time: 3, timeout_ticks: 250, connection_serial_number: 6332, vendor_id: 255, originator_serial_number: 4294967295, o_t_rpi: 16960, t_o_rpi: 16960, timeout_multiplier: 3, connection_path: EPath([Port(PortSegment { port: 1, link: b"\0" }), Class(2), Instance(1)]), o_t_params: ConnectionParameters { redundant_owner: false, connection_type: P2P, variable_length: Fixed, priority: High, connection_size: 504 }, t_o_params: ConnectionParameters { redundant_owner: false, connection_type: P2P, variable_length: Fixed, priority: High, connection_size: 504 }, transport_direction: Server, transport_class: Class3, transport_trigger: Application, large_open: false }, connected_options: None, service: None, seq_id: 0 }

read tag...EPath([Symbol("Cfg_LoSeverity")])

Error: Custom { kind: "custom", msg: "forward open failed" }


Float values

Hi,

I really appreciate this crate. Thank you for putting it together.

I am new to Ethernet/IP and I have a question.

When trying to read float type tags, I get a compiler error saying that Encode Decode are not implemented for f32. What's the best way to read and write f32 values for REAL type tags on AB PLCs?

Thanks

Can not read a large template

let template = client.find_template(tag_info.1).await?;
println!("template instance:\n{:?}", template);

These statements work for a small (<500 bytes) templates, but do not work for a large (>500 bytes) templates:

let info = client.read_template(&template).call().await?;
println!("template definition:\n{:?}", info);

Backtrace

template instance:
Template { instance_id: 1575, handle: 13998, member_count: 233, object_size: 1411, struct_size: 1868 }
thread 'main' panicked at 'assertion failed: self.remaining() >= dst.len()', ../.cargo/registry/src/github.com-1ecc6299db9ec823/bytes-1.1.0/src/buf/buf_impl.rs:253:9
stack backtrace:
0: rust_begin_unwind
at /rustc/6a705566166debf5eff88c57140df607fa409aaa/library/std/src/panicking.rs:584:5
1: core::panicking::panic_fmt
at /rustc/6a705566166debf5eff88c57140df607fa409aaa/library/core/src/panicking.rs:143:14
2: core::panicking::panic
at /rustc/6a705566166debf5eff88c57140df607fa409aaa/library/core/src/panicking.rs:48:5
3: bytes::buf::buf_impl::Buf::copy_to_slice
at ../.cargo/registry/src/github.com-1ecc6299db9ec823/bytes-1.1.0/src/buf/buf_impl.rs:253:9
4: bytes::buf::buf_impl::Buf::get_u16_le
at ../.cargo/registry/src/github.com-1ecc6299db9ec823/bytes-1.1.0/src/buf/buf_impl.rs:354:9
5: <rseip::client::ab_eip::template::decoder::DefaultDefinitionDecoder as rseip::client::ab_eip::template::decoder::DefinitionDecoder>::partial_decode
at ./src/client/ab_eip/template/decoder.rs:60:39
6: rseip::client::ab_eip::template::TemplateRead<T,D>::call::{{closure}}
at ./src/client/ab_eip/template.rs:197:13
7: <core::future::from_generator::GenFuture as core::future::future::Future>::poll
at /rustc/6a705566166debf5eff88c57140df607fa409aaa/library/core/src/future/mod.rs:91:19
8: rseip::main::{{closure}}
at ./src/main.rs:30:54
9: <core::future::from_generator::GenFuture as core::future::future::Future>::poll
at /rustc/6a705566166debf5eff88c57140df607fa409aaa/library/core/src/future/mod.rs:91:19
10: tokio::park::thread::CachedParkThread::block_on::{{closure}}
at ../.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.17.0/src/park/thread.rs:263:54
11: tokio::coop::with_budget::{{closure}}
at ../.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.17.0/src/coop.rs:102:9
12: std::thread::local::LocalKey::try_with
at /rustc/6a705566166debf5eff88c57140df607fa409aaa/library/std/src/thread/local.rs:413:16
13: std::thread::local::LocalKey::with
at /rustc/6a705566166debf5eff88c57140df607fa409aaa/library/std/src/thread/local.rs:389:9
14: tokio::coop::with_budget
at ../.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.17.0/src/coop.rs:95:5
15: tokio::coop::budget
at ../.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.17.0/src/coop.rs:72:5
16: tokio::park::thread::CachedParkThread::block_on
at ../.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.17.0/src/park/thread.rs:263:31
17: tokio::runtime::enter::Enter::block_on
at ../.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.17.0/src/runtime/enter.rs:151:13
18: tokio::runtime::thread_pool::ThreadPool::block_on
at ../.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.17.0/src/runtime/thread_pool/mod.rs:73:9
19: tokio::runtime::Runtime::block_on
at ../.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.17.0/src/runtime/mod.rs:477:43
20: rseip::main
at ./src/main.rs:33:5
21: core::ops::function::FnOnce::call_once
at /rustc/6a705566166debf5eff88c57140df607fa409aaa/library/core/src/ops/function.rs:227:5
note: Some details are omitted, run with RUST_BACKTRACE=full for a verbose backtrace.

Future goals

I happened across this lib just about the time you made your first commit. I am impressed by the rapid development.

I am wonder what your future plans/goals are for this lib.

I actually started writing some code to use your early work to read the template / structure data out of the processor. I then took another look at the repository, and BAM......already there!!!!! Impressive!!!!

infinite reading...

Used the default example and stuck on infinite reading tag with no errors follow...

use anyhow::Result;
use rseip::client::ab_eip::*;
use rseip::precludes::*;

#[tokio::main]
pub async fn main() -> Result<()> {
    let mut client = AbEipClient::new_host_lookup("192.168.1.2")
        .await?
        .with_connection_path(PortSegment::default());
    let tag = EPath::parse_tag("Temperature")?;
    println!("read tag...");
    let value: TagValue<i32> = client.read_tag(tag.clone()).await?;
    println!("tag value: {:?}", value);
    // client.write_tag(tag, value).await?;
    // println!("write tag - done");
    client.close().await?;
    Ok(())
}
Compiling wintek_rust v0.1.0 (/Users/user/git/foam/project)
    Finished dev [unoptimized + debuginfo] target(s) in 0.53s
     Running `target/debug/project`
read tag...

Undefined Behavior with StreamExt::collect

The following snippet produces undefined behavior.

use std::io;
use rseip::precludes::{AbEipClient, PortSegment, AbService};
use futures::stream::StreamExt;

async fn init() -> io::Result<()> {
    let mut client = AbEipClient::new_host_lookup("10.0.10.70")
        .await
        .map_err(|e| io::Error::new(io::ErrorKind::Other, e))?
        .with_connection_path(PortSegment::default());
    
    let tags = client
        .list_tag()
        .call()
        .collect::<Vec<_>>()
        .await
        .into_iter()
        .collect::<Result<Vec<_>, _>>()
        .map_err(|e| io::Error::new(io::ErrorKind::Other, e))?;
    
    for tag in tags {
        println!("{tag:?}")
    }
}

Output:

SymbolInstance { id: 0x01, name: "��\0\0\u{c}\0M", symbol_type: SymbolType { type: "atomic", dims: 0, type_code: 0x69 } }
SymbolInstance { id: 0x02, name: "Rev��\0\0\u{c}\0", symbol_type: SymbolType { type: "atomic", dims: 0, type_code: 0xc4 } }
SymbolInstance { id: 0x03, name: "_Ava��\0\0\u{c}\0M", symbol_type: SymbolType { type: "atomic", dims: 0, type_code: 0x70 } }
SymbolInstance { id: 0x04, name: "Ret�\u{742}\0\0\u{8}\0Man", symbol_type: SymbolType { type: "atomic", dims: 0, type_code: 0x68 } }
SymbolInstance { id: 0x05, name: "\u{2}\0\0\u{c}\0Man_M6_C_Rev��\0\0", symbol_type: SymbolType { type: "struct", dims: 0, instance_id: 0xf83 } }
SymbolInstance { id: 0x06, name: "_C�\u{80}\0\u{c}\0Ma", symbol_type: SymbolType { type: "atomic", dims: 0, type_code: 0xc4 } }
SymbolInstance { id: 0x07, name: "ev��", symbol_type: SymbolType { type: "atomic", dims: 0, type_code: 0xc4 } }
SymbolInstance { id: 0x08, name: "8_C_Rev��\0\u{f}\0Man_Palet_OK_L", symbol_type: SymbolType { type: "atomic", dims: 0, type_code: 0xc4 } }
SymbolInstance { id: 0x09, name: "\0Man_Retroce", symbol_type: SymbolType { type: "atomic", dims: 0, type_code: 0x69 } }
SymbolInstance { id: 0x0a, name: "\0�\0\u{8}\0Marcha_C��\0", symbol_type: SymbolType { type: "atomic", dims: 0, type_code: 0x7e } }
SymbolInstance { id: 0x0b, name: "cuadra_Pla", symbol_type: SymbolType { type: "struct", dims: 0, instance_id: 0xdba } }
SymbolInstance { id: 0x0c, name: "\0\0\u{13}\0Mem_Fi", symbol_type: SymbolType { type: "struct", dims: 0, instance_id: 0xb24 } }
SymbolInstance { id: 0x0d, name: "eta_C��\0\u{f}\0Me", symbol_type: SymbolType { type: "atomic", dims: 0, type_code: 0x69 } }
SymbolInstance { id: 0x0e, name: "OK_L9��\0\u{14}\0Mem_Laye", symbol_type: SymbolType { type: "atomic", dims: 0, type_code: 0x7e } }
SymbolInstance { id: 0x0f, name: "te_C��\0\u{13}\0M", symbol_type: SymbolType { type: "struct", dims: 0, instance_id: 0xb9d } }
thread 'main' panicked at 'byte index 15 is out of bounds of `_Encoder_C��`', library/core/src/fmt/mod.rs:2472:30
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

reading integer

trying to read the data from omron controller.
Getting this error

Error: custom - cip error: message reply status CIP general status: 1, extended status: 516
        timeout

What could be wrong? Type or what? With python I am able to read the data using CPPPO library btw so the problem not related to controller and it's settings

How to read SLC 500 addresses?

I was just wondering how I would read an address like O:1/0 from a SLC 500 style PLC. Trying to use something like this let tag = EPath::parse_tag("O:1/0")?; does not work.

Question: Can eip-rs Read UDTs?

Can eip-rs Read and Write UDTs?

I need a grab a UDT instance from my CompactLogix PLCs, can that be done? And then Mapped to a struct?

Example UDT on PLC

- Type: MyUDT
  - MyDint1 : DINT
  - MyDint2: DINT
  - MyString1 : STRING
  - MyString2 : STRING

Path to an instance on PLC that is in Program1
\Program1.MyUdtInstance1

Rust Type:

struct MyUDT {
    MyDint1: i32,
    MyDint2: i32,
    MyString1 : String
    MyString2 : String
}

PortSegment configuration.

Hi my name is Francisco, I'm from Brazil and I am a industrial automation engineer. I'm a beginner rust user. I working in a project to collect data from 4 logix controllers and I'm using yours lib. I can connect with 1 controller using the default port segment, but in my case, the other 3 controllers are connected in a 1756-EN2T module, so I have:
The backplane, on slot 0 1756-L82ES (172.16.1.130), on slot 6 1756-EN2T (192.168.0.1) where I have the other 3 controllers, connected on another backplane by 1756-EN2TR on slot 3 (192.168.0.2). Is it possible to do that communication? Could you help me?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.