Skip to content

Commit

Permalink
Move mqtt-client to pico-args, show usage if parse_args() returns an …
Browse files Browse the repository at this point in the history
…error
  • Loading branch information
locka99 committed Jan 23, 2020
1 parent ab70fbc commit 7da593a
Show file tree
Hide file tree
Showing 7 changed files with 98 additions and 79 deletions.
8 changes: 4 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions samples/discovery-client/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@ Usage: discovery-client --config [config] --run-demo-slave

const DEFAULT_DISCOVERY_URL: &str = "opc.tcp://localhost:4840/";

fn main() -> Result<(), Box<dyn std::error::Error>> {
let args = Args::parse_args()?;
fn main() -> Result<(), ()> {
let args = Args::parse_args()
.map_err(|_| Args::usage())?;
if args.help {
Args::usage();
} else {
Expand Down
5 changes: 3 additions & 2 deletions samples/modbus-server/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,10 @@ Usage: modbus-server --config [config] --run-demo-slave

const DEFAULT_CONFIG: &str = "./modbus.conf";

fn main() -> Result<(), Box<dyn std::error::Error>> {
fn main() -> Result<(), ()> {
// Read command line arguments
let args = Args::parse_args()?;
let args = Args::parse_args()
.map_err(|_| Args::usage())?;
if args.help {
Args::usage();
} else {
Expand Down
2 changes: 1 addition & 1 deletion samples/mqtt-client/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ authors = ["Adam Lock <[email protected]>"]
edition = "2018"

[dependencies]
clap = "2.33"
pico-args = "0.3"
# This is a completely arbitrary snapshot of rumqtt that happens to work
rumqtt = { git = "https://github.com/AtherEnergy/rumqtt.git", rev = "83b4694525061e2ccef617c0ac867db2044cc4e7" }

Expand Down
147 changes: 81 additions & 66 deletions samples/mqtt-client/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,51 @@
//! values before exiting.
use std::{
path::PathBuf,
sync::{Arc, Mutex, RwLock, mpsc},
sync::{Arc, mpsc, Mutex, RwLock},
thread,
};

use rumqtt::{MqttClient, MqttOptions, QoS};
use clap::{App, Arg, value_t_or_exit};

use opcua_client::prelude::*;

struct Args {
help: bool,
config: String,
endpoint_id: String,
host: String,
port: u16,
}

impl Args {
pub fn parse_args() -> Result<Args, Box<dyn std::error::Error>> {
let mut args = pico_args::Arguments::from_env();
Ok(Args {
help: args.contains(["-h", "--help"]),
config: args.opt_value_from_str("--config")?.unwrap_or(String::from(DEFAULT_CONFIG_FILE)),
endpoint_id: args.opt_value_from_str("--config")?.unwrap_or(String::from("")),
host: args.opt_value_from_str("--host")?.unwrap_or(String::from(DEFAULT_MQTT_HOST)),
port: args.opt_value_from_str("--port")?.unwrap_or(DEFAULT_MQTT_PORT),
})
}

pub fn usage() {
println!(r#"MQTT client
Usage: discovery-client --config [config] --run-demo-slave
-h, --help Show help
--config file Sets the configuration file to read settings and endpoints from (default: {})
--endpoint-id id Sets the endpoint id from the config file to connect to
--host host Address or name of the MQTT server to connect with (default: {})
--port port Port number of MQTT server to connect with (default: {})"#,
DEFAULT_CONFIG_FILE, DEFAULT_MQTT_HOST, DEFAULT_MQTT_PORT);
}
}

const DEFAULT_CONFIG_FILE: &str = "../client.conf/";
const DEFAULT_MQTT_HOST: &str = "broker.hivemq.com";
const DEFAULT_MQTT_PORT: u16 = 1883;


// This client will do the following:
//
// 1. Read a configuration file (either default or the one specified using --config)
Expand All @@ -19,72 +55,51 @@ use opcua_client::prelude::*;
// 4. Publish those values to an MQTT broker (default broker.hivemq.com:1883)
// 5. User can observe result on the broker (e.g. http://www.mqtt-dashboard.com/)

fn main() {
// Read command line arguments
let m = App::new("Simple OPC UA Client")
.arg(Arg::with_name("config")
.long("config")
.help("Sets the configuration file to read settings and endpoints from")
.takes_value(true)
.default_value("../client.conf")
.required(false))
.arg(Arg::with_name("id")
.long("endpoint-id")
.help("Sets the endpoint id from the config file to connect to")
.takes_value(true)
.default_value("")
.required(false))
.arg(Arg::with_name("host")
.long("host")
.help("Address or name of the MQTT server to connect with")
.default_value("broker.hivemq.com")
.takes_value(true)
.required(true))
.arg(Arg::with_name("port")
.long("port")
.help("Port number of MQTT server to connect with")
.default_value("1883")
.takes_value(true)
.required(true))
.get_matches();

let mqtt_host = m.value_of("host").unwrap().to_string();
let mqtt_port = value_t_or_exit!(m, "port", u16);
let config_file = m.value_of("config").unwrap().to_string();
let endpoint_id = m.value_of("id").unwrap().to_string();

// Optional - enable OPC UA logging
opcua_console_logging::init();

// The way this will work is the mqtt connection will live in its own thread, listening for
// events that are sent to it.
let (tx, rx) = mpsc::channel::<(NodeId, DataValue)>();
let _ = thread::spawn(move || {
let mqtt_options = MqttOptions::new("test-id", mqtt_host, mqtt_port).set_keep_alive(10);
let (mut mqtt_client, _) = MqttClient::start(mqtt_options).unwrap();

loop {
let (node_id, data_value) = rx.recv().unwrap();
let topic = format!("opcua-rust/mqtt-client/{}/{}", node_id.namespace, node_id.identifier);
let value = if let Some(ref value) = data_value.value {
format!("{:?}", value)
} else {
"null".to_string()
};
println!("Publishing {} = {}", topic, value);
mqtt_client.publish(topic, QoS::AtLeastOnce, value).unwrap();
}
});

// Use the sample client config to set up a client. The sample config has a number of named
// endpoints one of which is marked as the default.
let mut client = Client::new(ClientConfig::load(&PathBuf::from(config_file)).unwrap());
let endpoint_id: Option<&str> = if !endpoint_id.is_empty() { Some(&endpoint_id) } else { None };
if let Ok(session) = client.connect_to_endpoint_id(endpoint_id) {
let _ = subscription_loop(session, tx).map_err(|err| {
println!("ERROR: Got an error while performing action - {}", err);
fn main() -> Result<(), ()> {
let args = Args::parse_args()
.map_err(|_| Args::usage())?;
if args.help {
Args::usage();
} else {
let mqtt_host = args.host;
let mqtt_port = args.port;
let config_file = args.config;
let endpoint_id = args.endpoint_id;

// Optional - enable OPC UA logging
opcua_console_logging::init();

// The way this will work is the mqtt connection will live in its own thread, listening for
// events that are sent to it.
let (tx, rx) = mpsc::channel::<(NodeId, DataValue)>();
let _ = thread::spawn(move || {
let mqtt_options = MqttOptions::new("test-id", mqtt_host, mqtt_port).set_keep_alive(10);
let (mut mqtt_client, _) = MqttClient::start(mqtt_options).unwrap();

loop {
let (node_id, data_value) = rx.recv().unwrap();
let topic = format!("opcua-rust/mqtt-client/{}/{}", node_id.namespace, node_id.identifier);
let value = if let Some(ref value) = data_value.value {
format!("{:?}", value)
} else {
"null".to_string()
};
println!("Publishing {} = {}", topic, value);
mqtt_client.publish(topic, QoS::AtLeastOnce, value).unwrap();
}
});

// Use the sample client config to set up a client. The sample config has a number of named
// endpoints one of which is marked as the default.
let mut client = Client::new(ClientConfig::load(&PathBuf::from(config_file)).unwrap());
let endpoint_id: Option<&str> = if !endpoint_id.is_empty() { Some(&endpoint_id) } else { None };
if let Ok(session) = client.connect_to_endpoint_id(endpoint_id) {
let _ = subscription_loop(session, tx).map_err(|err| {
println!("ERROR: Got an error while performing action - {}", err);
});
}
}
Ok(())
}

fn subscription_loop(session: Arc<RwLock<Session>>, tx: mpsc::Sender<(NodeId, DataValue)>) -> Result<(), StatusCode> {
Expand Down
5 changes: 3 additions & 2 deletions samples/simple-client/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,10 @@ Usage: simple-client --url [url]

const DEFAULT_URL: &str = "opc.tcp://localhost:4855";

fn main() -> Result<(), Box<dyn std::error::Error>> {
fn main() -> Result<(), ()> {
// Read command line arguments
let args = Args::parse_args()?;
let args = Args::parse_args()
.map_err(|_| Args::usage())?;
if args.help {
Args::usage();
} else {
Expand Down
5 changes: 3 additions & 2 deletions samples/web-client/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,9 @@ Usage: web-client --config [config] --run-demo-slave

const DEFAULT_HTTP_PORT: u16 = 8686;

fn main() -> Result<(), Box<dyn std::error::Error>> {
let args = Args::parse_args()?;
fn main() -> Result<(), ()> {
let args = Args::parse_args()
.map_err(|_| Args::usage())?;
if args.help {
Args::usage();
} else {
Expand Down

0 comments on commit 7da593a

Please sign in to comment.