tether_agent::agent

Struct TetherAgent

Source
pub struct TetherAgent { /* private fields */ }

Implementations§

Source§

impl TetherAgent

Source

pub fn is_connected(&self) -> bool

Source

pub fn role(&self) -> &str

Source

pub fn id(&self) -> &str

Source

pub fn description(&self) -> (String, String, String)

Returns the Agent Role, ID (group), Broker URI

Examples found in repository?
examples/custom_options.rs (line 32)
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
fn main() {
    let mut tether_agent = TetherAgentOptionsBuilder::new("example")
        .id(None)
        .host(Some("localhost"))
        .port(Some(1883))
        .username(Some("tether"))
        .password(Some("sp_ceB0ss!"))
        .build()
        .expect("failed to create Tether Agent");

    let output_plug = PlugOptionsBuilder::create_output("anOutput")
        .role(Some("pretendingToBeSomethingElse"))
        .qos(Some(2))
        .retain(Some(true))
        .build(&mut tether_agent)
        .expect("failed to create output plug");
    let input_wildcard_plug = PlugOptionsBuilder::create_input("everything")
        .topic(Some("#"))
        .build(&mut tether_agent);

    let input_customid_plug = PlugOptionsBuilder::create_input("someData")
        .role(None) // i.e., just use default
        .id(Some("specificIDonly"))
        .build(&mut tether_agent);

    println!("Agent looks like this: {:?}", tether_agent.description());
    let (role, id, _) = tether_agent.description();
    assert_eq!(role, "example");
    assert_eq!(id, "any"); // because we set None

    if let PlugDefinition::OutputPlug(p) = &output_plug {
        println!("output plug: {:?}", p);
        assert_eq!(p.topic_str(), "pretendingToBeSomethingElse/any/anOutput");
    }

    println!("wildcard input plug: {:?}", input_wildcard_plug);
    println!("speific ID input plug: {:?}", input_customid_plug);

    let payload =
        rmp_serde::to_vec::<String>(&String::from("boo")).expect("failed to serialise payload");
    tether_agent
        .publish(&output_plug, Some(&payload))
        .expect("failed to publish");

    std::thread::sleep(Duration::from_millis(4000));
}
More examples
Hide additional examples
examples/publish.rs (line 25)
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
fn main() {
    println!("Rust Tether Agent publish example");

    let mut builder = Builder::from_env(Env::default().default_filter_or("info"));
    builder.init();

    debug!("Debugging is enabled; could be verbose");

    let mut tether_agent = TetherAgentOptionsBuilder::new("RustDemo")
        .build()
        .expect("failed to connect Tether");
    let (role, id, _) = tether_agent.description();
    info!("Created agent OK: {}, {}", role, id);

    let empty_message_output = PlugOptionsBuilder::create_output("nothing")
        .build(&mut tether_agent)
        .expect("failed to create output");
    let boolean_message_output = PlugOptionsBuilder::create_output("one")
        .build(&mut tether_agent)
        .expect("failed to create output");
    let custom_output = PlugOptionsBuilder::create_output("two")
        .topic(Some("custom/custom/two"))
        .build(&mut tether_agent)
        .expect("failed to create output");
    let grouped_output_1 = PlugOptionsBuilder::create_output("one")
        .id(Some("groupMessages"))
        .build(&mut tether_agent)
        .expect("failed to create output");
    let grouped_output_2 = PlugOptionsBuilder::create_output("two")
        .id(Some("groupMessages"))
        .build(&mut tether_agent)
        .expect("failed to create output");

    for i in 1..=10 {
        info!("#{i}: Sending empty message...");
        tether_agent.publish(&empty_message_output, None).unwrap();

        let bool = i % 2 == 0;
        info!("#{i}: Sending boolean message...");
        tether_agent
            .publish(&boolean_message_output, Some(&[bool.into()]))
            .unwrap();

        info!("#{i}: Sending custom struct message...");
        let custom_message = CustomStruct {
            id: i,
            name: "hello".into(),
        };
        tether_agent
            .encode_and_publish(&custom_output, custom_message)
            .unwrap();

        info!("#{i}: Sending grouped messages...");
        tether_agent.publish(&grouped_output_1, None).unwrap();
        tether_agent.publish(&grouped_output_2, None).unwrap();

        thread::sleep(Duration::from_millis(1000))
    }
}
Source

pub fn broker_uri(&self) -> String

Return the URI (protocol, IP address, port, path) that was used to connect to the MQTT broker

Source

pub fn set_role(&mut self, role: &str)

Source

pub fn set_id(&mut self, id: &str)

Source

pub fn connect(&mut self) -> Result<()>

Self must be mutable in order to create and assign new Client (with Connection)

Source

pub fn check_messages(&self) -> Option<(TetherOrCustomTopic, Vec<u8>)>

If a message is waiting return ThreePartTopic, Message (String, Message) Messages received on topics that are not parseable as Tether Three Part Topics will be returned with the complete Topic string instead

Examples found in repository?
examples/subscribe.rs (line 66)
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
fn main() {
    println!("Rust Tether Agent subscribe example");

    let mut builder = Builder::from_env(Env::default().default_filter_or("debug"));
    builder.filter_module("tether_agent", log::LevelFilter::Warn);
    builder.filter_module("rumqttc", log::LevelFilter::Warn);
    builder.init();

    debug!("Debugging is enabled; could be verbose");

    let mut tether_agent = TetherAgentOptionsBuilder::new("RustDemo")
        .id(Some("example"))
        .build()
        .expect("failed to init Tether agent");

    let input_one = PlugOptionsBuilder::create_input("one")
        .build(&mut tether_agent)
        .expect("failed to create input");
    info!("input one {} = {}", input_one.name(), input_one.topic());
    let input_two = PlugOptionsBuilder::create_input("two")
        .role(Some("specific"))
        .build(&mut tether_agent)
        .expect("failed to create input");
    info!("input two {} = {}", input_two.name(), input_two.topic());
    let input_empty = PlugOptionsBuilder::create_input("nothing")
        .build(&mut tether_agent)
        .expect("failed to create input");

    let input_everything = PlugOptionsBuilder::create_input("everything")
        .topic(Some("#"))
        .build(&mut tether_agent)
        .expect("failed to create input");

    let input_specify_id = PlugOptionsBuilder::create_input("groupMessages")
        .id(Some("someGroup"))
        .name(None)
        .build(&mut tether_agent)
        .expect("failed to create input");

    debug!(
        "input everything {} = {}",
        input_everything.name(),
        input_everything.topic()
    );

    info!("Checking messages every 1s, 10x...");

    loop {
        debug!("Checking for messages...");
        while let Some((topic, payload)) = tether_agent.check_messages() {
            // debug!(
            //     "........ Received a message topic {:?} => topic parts {:?}",
            //     topic, topic
            // );

            if input_one.matches(&topic) {
                info!(
                            "******** INPUT ONE:\n Received a message for plug named \"{}\" on topic {:?} with length {} bytes",
                            input_one.name(),
                            topic,
                            payload.len()
                        );
                // assert_eq!(parse_plug_name(topic.un), Some("one"));
            }
            if input_two.matches(&topic) {
                info!(
                        "******** INPUT TWO:\n Received a message for plug named \"{}\" on topic {:?} with length {} bytes",
                        input_two.name(),
                        topic,
                        payload.len()
                    );
                // assert_eq!(parse_plug_name(message.topic()), Some("two"));
                // assert_ne!(parse_plug_name(message.topic()), Some("one"));

                // Notice how you must give the from_slice function a type so it knows what to expect
                let decoded = from_slice::<CustomMessage>(&payload);
                match decoded {
                    Ok(d) => {
                        info!("Yes, we decoded the MessagePack payload as: {:?}", d);
                        let CustomMessage { name, id } = d;
                        debug!("Name is {} and ID is {}", name, id);
                    }
                    Err(e) => {
                        warn!("Failed to decode the payload: {}", e)
                    }
                };
            }
            if input_empty.matches(&topic) {
                info!(
                        "******** EMPTY MESSAGE:\n Received a message for plug named \"{}\" on topic {:?} with length {} bytes",
                        input_empty.name(),
                        topic,
                       payload.len()
                    );
                // assert_eq!(parse_plug_name(topic), Some("nothing"));
            }
            if input_everything.matches(&topic) {
                info!(
                    "******** EVERYTHING MATCHES HERE:\n Received a message for plug named \"{}\" on topic {:?} with length {} bytes",
                    input_everything.name(),
                    topic,
                   payload.len()
                );
            }
            if input_specify_id.matches(&topic) {
                info!("******** ID MATCH:\n Should match any role and plug name, but only messages with ID \"groupMessages\"");
                info!(
                    "\n Received a message from plug named \"{}\" on topic {:?} with length {} bytes",
                    input_specify_id.name(),
                    topic,
                    payload.len()
                );
                // assert_eq!(parse_agent_id(message.topic()), Some("groupMessages"));
            }
        }

        thread::sleep(Duration::from_millis(1000))
    }
}
Source

pub fn publish( &self, plug_definition: &PlugDefinition, payload: Option<&[u8]>, ) -> Result<()>

Given a plug definition and a raw (u8 buffer) payload, generate a message on an appropriate topic and with the QOS specified in the Plug Definition

Examples found in repository?
examples/custom_options.rs (line 48)
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
fn main() {
    let mut tether_agent = TetherAgentOptionsBuilder::new("example")
        .id(None)
        .host(Some("localhost"))
        .port(Some(1883))
        .username(Some("tether"))
        .password(Some("sp_ceB0ss!"))
        .build()
        .expect("failed to create Tether Agent");

    let output_plug = PlugOptionsBuilder::create_output("anOutput")
        .role(Some("pretendingToBeSomethingElse"))
        .qos(Some(2))
        .retain(Some(true))
        .build(&mut tether_agent)
        .expect("failed to create output plug");
    let input_wildcard_plug = PlugOptionsBuilder::create_input("everything")
        .topic(Some("#"))
        .build(&mut tether_agent);

    let input_customid_plug = PlugOptionsBuilder::create_input("someData")
        .role(None) // i.e., just use default
        .id(Some("specificIDonly"))
        .build(&mut tether_agent);

    println!("Agent looks like this: {:?}", tether_agent.description());
    let (role, id, _) = tether_agent.description();
    assert_eq!(role, "example");
    assert_eq!(id, "any"); // because we set None

    if let PlugDefinition::OutputPlug(p) = &output_plug {
        println!("output plug: {:?}", p);
        assert_eq!(p.topic_str(), "pretendingToBeSomethingElse/any/anOutput");
    }

    println!("wildcard input plug: {:?}", input_wildcard_plug);
    println!("speific ID input plug: {:?}", input_customid_plug);

    let payload =
        rmp_serde::to_vec::<String>(&String::from("boo")).expect("failed to serialise payload");
    tether_agent
        .publish(&output_plug, Some(&payload))
        .expect("failed to publish");

    std::thread::sleep(Duration::from_millis(4000));
}
More examples
Hide additional examples
examples/publish.rs (line 49)
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
fn main() {
    println!("Rust Tether Agent publish example");

    let mut builder = Builder::from_env(Env::default().default_filter_or("info"));
    builder.init();

    debug!("Debugging is enabled; could be verbose");

    let mut tether_agent = TetherAgentOptionsBuilder::new("RustDemo")
        .build()
        .expect("failed to connect Tether");
    let (role, id, _) = tether_agent.description();
    info!("Created agent OK: {}, {}", role, id);

    let empty_message_output = PlugOptionsBuilder::create_output("nothing")
        .build(&mut tether_agent)
        .expect("failed to create output");
    let boolean_message_output = PlugOptionsBuilder::create_output("one")
        .build(&mut tether_agent)
        .expect("failed to create output");
    let custom_output = PlugOptionsBuilder::create_output("two")
        .topic(Some("custom/custom/two"))
        .build(&mut tether_agent)
        .expect("failed to create output");
    let grouped_output_1 = PlugOptionsBuilder::create_output("one")
        .id(Some("groupMessages"))
        .build(&mut tether_agent)
        .expect("failed to create output");
    let grouped_output_2 = PlugOptionsBuilder::create_output("two")
        .id(Some("groupMessages"))
        .build(&mut tether_agent)
        .expect("failed to create output");

    for i in 1..=10 {
        info!("#{i}: Sending empty message...");
        tether_agent.publish(&empty_message_output, None).unwrap();

        let bool = i % 2 == 0;
        info!("#{i}: Sending boolean message...");
        tether_agent
            .publish(&boolean_message_output, Some(&[bool.into()]))
            .unwrap();

        info!("#{i}: Sending custom struct message...");
        let custom_message = CustomStruct {
            id: i,
            name: "hello".into(),
        };
        tether_agent
            .encode_and_publish(&custom_output, custom_message)
            .unwrap();

        info!("#{i}: Sending grouped messages...");
        tether_agent.publish(&grouped_output_1, None).unwrap();
        tether_agent.publish(&grouped_output_2, None).unwrap();

        thread::sleep(Duration::from_millis(1000))
    }
}
Source

pub fn encode_and_publish<T: Serialize>( &self, plug_definition: &PlugDefinition, data: T, ) -> Result<()>

Similar to publish but serializes the data automatically before sending

Examples found in repository?
examples/publish.rs (line 63)
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
fn main() {
    println!("Rust Tether Agent publish example");

    let mut builder = Builder::from_env(Env::default().default_filter_or("info"));
    builder.init();

    debug!("Debugging is enabled; could be verbose");

    let mut tether_agent = TetherAgentOptionsBuilder::new("RustDemo")
        .build()
        .expect("failed to connect Tether");
    let (role, id, _) = tether_agent.description();
    info!("Created agent OK: {}, {}", role, id);

    let empty_message_output = PlugOptionsBuilder::create_output("nothing")
        .build(&mut tether_agent)
        .expect("failed to create output");
    let boolean_message_output = PlugOptionsBuilder::create_output("one")
        .build(&mut tether_agent)
        .expect("failed to create output");
    let custom_output = PlugOptionsBuilder::create_output("two")
        .topic(Some("custom/custom/two"))
        .build(&mut tether_agent)
        .expect("failed to create output");
    let grouped_output_1 = PlugOptionsBuilder::create_output("one")
        .id(Some("groupMessages"))
        .build(&mut tether_agent)
        .expect("failed to create output");
    let grouped_output_2 = PlugOptionsBuilder::create_output("two")
        .id(Some("groupMessages"))
        .build(&mut tether_agent)
        .expect("failed to create output");

    for i in 1..=10 {
        info!("#{i}: Sending empty message...");
        tether_agent.publish(&empty_message_output, None).unwrap();

        let bool = i % 2 == 0;
        info!("#{i}: Sending boolean message...");
        tether_agent
            .publish(&boolean_message_output, Some(&[bool.into()]))
            .unwrap();

        info!("#{i}: Sending custom struct message...");
        let custom_message = CustomStruct {
            id: i,
            name: "hello".into(),
        };
        tether_agent
            .encode_and_publish(&custom_output, custom_message)
            .unwrap();

        info!("#{i}: Sending grouped messages...");
        tether_agent.publish(&grouped_output_1, None).unwrap();
        tether_agent.publish(&grouped_output_2, None).unwrap();

        thread::sleep(Duration::from_millis(1000))
    }
}
Source

pub fn publish_raw( &self, topic: &str, payload: &[u8], qos: Option<i32>, retained: Option<bool>, ) -> Result<()>

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

impl<T> ErasedDestructor for T
where T: 'static,

Source§

impl<T> MaybeSendSync for T