rust

This GEM Rust host example uses the code generated from TransSECS using the Native/C++ deployment option. More detailed information is available at Rust Documentation

Most of the complexity is removed by the definitions you created in TransSECS. In Rust you subscribe to receive data and publish values. Complex types are passed as JSON.

Message notifications are received as JSON maps so that each of the published elements in the message are available directly.

For the host,copy the GEMHostRuntime.jar from the TransSECS GEMHost project into the build folder

The samples, even though simple, demonstrates all the features required to collect data from a host.

In the host code, publish variables you need to change in the interface, here the port, hostname, deviceid, etc. and subscribe to elements to receive data updates. Here an event (loaded) and to values (ppid and wafer count). The event is received as a JSON structure.

For example, to set the hostname, you publish to that variable:

    wrapper.publish_string("gemhost/configuration/equipmenthostname", "localhost").unwrap();

And Events (CEIDs) received as JSON Strings that contains the values configured in TransSECS. For example, a subscription to the “loaded” event might deliver a JSON string similar to this:

 { "LOADED": [  { "RPTID103": [ {"LOTID":"", "type":20 },{"PPID":"recipename", "type":20 },{"WaferCount":"1", "type":54 } ], "rptid":103} ], "ceid":7503, "timestamp":"2021-08-10 19:58:28.802"}

The sample code receives and unpacks that structure:

    wrapper.subscribe("gemhost/variables/ceid/loaded", |topic,value| {
        println!("Callback called on {}:", topic);
        if let Value::String(string_value) = value.value {
            // The ceid appears as a json object, which we can parse for example with serde_json
            let parsed:LoadedCeid = serde_json::from_str(&string_value).unwrap();
            // We'll just immediately reserialize the json to demonstrate that we have the fields
            println!("{}", serde_json::to_string_pretty(&parsed).unwrap());
        }
    }).unwrap();

The tool can subscribe to be notified of the change in value of any VID - used for ECIDs and GEM internal variables:

    wrapper.subscribe("gemhost/variables/vid/lotid", |topic,value| {
        println!("Callback called on {} with {:?}", topic, value)
    }).unwrap();

Here's the code sample from the rustwrapper archive:

//! Simple GEM host example showing how to start a host and subscribe to some variables
 
use transsecs::transsecs_wrapper::TransSecsWrapper;
use transsecs::value_object::{Value};
use std::{thread, time};
 
use serde::{Serialize, Deserialize};
 
#[derive(Serialize, Deserialize, Debug)]
struct LoadedCeid {
    #[serde(rename="LOADED")]
    reports:Vec<Report>
}
 
 
#[derive(Serialize, Deserialize, Debug)]
struct Report {
    #[serde(rename="RPTID103")]
    values:Vec<ReportValue>
}
 
#[derive(Serialize, Deserialize, Debug)]
#[serde(untagged)]
enum ReportValue {
    LotID{
        #[serde(rename="LOTID")]
        lot_id:String, 
        #[serde(rename="type")]
        type_int:i32
    },
    PPID{
        #[serde(rename="PPID")]
        ppid:String, 
        #[serde(rename="type")]
        type_int:i32
    },
    WaferCount{
        #[serde(rename="WaferCount")]
        wafer_count:String, 
        #[serde(rename="type")]
        type_int:i32}
}
 
// examples/gem_host_example.rs
fn main() {
    let wrapper = TransSecsWrapper::new("./GEMHostRuntime.jar").unwrap();
 
    let port = 5010;
    wrapper.publish_string("gemhost/configuration/persistencefilename", "/tmp/testpersistence").unwrap();
    wrapper.publish_string("gemhost/configuration/equipmenthostname", "localhost").unwrap();
    wrapper.publish_int("gemhost/configuration/deviceid", 1).unwrap();
    wrapper.publish_int("gemhost/configuration/activeport", port).unwrap();
 
    wrapper.start_main("GEMHost").unwrap();
 
    wrapper.subscribe("gemhost/variables/ceid/loaded", |topic,value| {
        println!("Callback called on {}:", topic);
        if let Value::String(string_value) = value.value {
            // The ceid appears as a json object, which we can parse for example with serde_json
            let parsed:LoadedCeid = serde_json::from_str(&string_value).unwrap();
            // We'll just immediately reserialize the json to demonstrate that we have the fields
            println!("{}", serde_json::to_string_pretty(&parsed).unwrap());
        }
    }).unwrap();
 
    wrapper.subscribe("gemhost/variables/vid/ppid", |topic,value| {
        println!("Callback called on {} with {:?}", topic, value)
    }).unwrap();
 
    wrapper.subscribe("gemhost/variables/vid/lotid", |topic,value| {
        println!("Callback called on {} with {:?}", topic, value)
    }).unwrap();
 
    loop{
        thread::sleep(time::Duration::from_secs(10));
    } // If we drop the wrapper, it will cleanup the jvm
}
  • rust.txt
  • Last modified: 2021/08/11 12:56
  • by wikiadmin