rstango 0.4.0

Implementation of the Tango distributed control system
Documentation
//! The properties of a device, against a device of the `server` example: they are
//! kept by the database, and the device reads its own at initialization, which `Init` runs
//! again.
//!
//! The `Limit` of the device is changed then put back as it was, and is made invalid on
//! the way, which shows that a device failing to initialize stays reachable, in `FAULT`.
//!
//! ```sh
//! cargo run --example props -- test/motor/1
//! ```

use std::env;

use tango::dev::DevProxy;
use tango::error::Result;


/// Run `Init` on the device, then print what it says of itself and the limit it read.
///
/// An initialization that fails is the failure of `Init` too, and the device stays
/// reachable all the same, which is what is shown after it.
fn init(motor: &DevProxy) -> Result<()> {
    if let Err(err) = motor.init() {
        println!("  Init failed: {}", err.description());
    }
    let limit = motor.read_attr::<f64, _>("limit").map(|read| read.value);
    println!("  {:?}: {}\n  limit = {limit:?}", motor.state()?, motor.status()?.value());
    Ok(())
}


fn main() -> Result<()> {

    let name = env::args().nth(1).unwrap_or_else(|| "test/motor/1".to_string());
    let motor = DevProxy::new(name.as_str());

    // A property is a list of values, empty when it is not set.
    let initial = motor.get_prop::<Vec<f64>, _>("Limit")?.first().copied();
    println!("Limit property: {initial:?}");
    println!("Properties: {:?}", motor.list_prop("*")?);

    // The device does not see a property change until it initializes again.
    motor.set_prop(("Limit", 45.0))?;
    let limit = motor.read_attr::<f64, _>("limit").map(|read| read.value);
    println!("Limit set to 45, before Init: {limit:?}");
    println!("After Init:");
    init(&motor)?;

    // A limit the device refuses: it stays exported, in FAULT, and tells why, the limit
    // attribute it adds at initialization being gone with the model it failed to build.
    motor.set_prop(("Limit", 0.0))?;
    println!("Limit set to 0, after Init:");
    init(&motor)?;

    // Put back as it was, a property that was not set being deleted.
    match initial {
        Some(limit) => motor.set_prop(("Limit", limit))?,
        None => motor.delete_prop("Limit")?,
    }
    println!("Limit put back, after Init:");
    init(&motor)?;

    Ok(())

}