Skip to main content

Crate instro_ethernetip

Crate instro_ethernetip 

Source
Expand description

Async EtherNet/IP explicit messaging for simple PLC tag reads and writes.

This crate provides a small, crate-owned API around rust-ethernet-ip for the common explicit-messaging workflow:

The public API intentionally hides backend transport types so callers can work with a stable interface centered on ExplicitSession, Value, and StructuredValue.

§Recovery behavior

The backend client automatically retries or falls back for some protocol-level transient failures before an operation returns. If a read, batch read, or write still returns an error that rust_ethernet_ip::EtherNetIpError::is_retriable marks retriable, ExplicitSession drops the dead client. The failed operation is returned to the caller, and the next read or write automatically reconnects with the same address and route path before issuing the request.

§Features

By default, this crate exposes the async ExplicitSession API. Async callers provide their own Tokio runtime by awaiting the session methods.

Enable the blocking feature to add blocking::ExplicitSession, a synchronous wrapper around the async session. The blocking API supports the same connect, read, write, structured-value, and close operations, and it drives them on a private shared Tokio runtime.

Do not call the blocking API from inside Tokio async code: it uses Handle::block_on, which panics when invoked from an async execution context. Async callers should use the default ExplicitSession API directly.

§Examples

Connect to a target, read a tag, write an updated value, then close the session:

use instro_ethernetip::{ExplicitSession, Result, Value};

let runtime = tokio::runtime::Runtime::new().expect("runtime should build");
runtime.block_on(async {
    let mut session = ExplicitSession::connect("192.168.1.10:44818").await?;

    let motor_running = session.read_tag("MotorRunning").await?;
    assert!(matches!(motor_running, Value::Bool(_)));

    session.write_tag("CommandSpeed", 1_500_i32.into()).await?;
    session.close().await
})

Convert Rust values into crate-owned PLC values without exposing backend types:

use instro_ethernetip::Value;

assert_eq!(Value::from(true), Value::Bool(true));
assert_eq!(Value::from(42_i32), Value::Dint(42));
assert_eq!(Value::from("ready"), Value::String("ready".to_owned()));

Preserve a user-defined type payload as opaque bytes with StructuredValue:

use instro_ethernetip::{StructuredValue, Value};

let payload = StructuredValue {
    symbol_id: Some(7),
    data: vec![0xde, 0xad, 0xbe, 0xef],
};

assert_eq!(Value::from(payload.clone()), Value::Struct(payload));

Structs§

ExplicitSession
An active explicit-messaging EtherNet/IP session for a single target address.
StructuredValue
User-facing wrapper for rust_ethernet_ip::UdtData.

Enums§

BatchReadError
Per-tag failure surfaced by a batched read.
Error
Errors returned by the explicit EtherNet/IP tag API.
Value
User-facing wrapper for rust_ethernet_ip::PlcValue returned by this crate.

Type Aliases§

Result