2020-09-15 12:17:42 +08:00
|
|
|
use scpi::prelude::*;
|
|
|
|
use scpi::Context;
|
|
|
|
use scpi::error::Result;
|
2020-09-15 14:03:59 +08:00
|
|
|
use log::trace;
|
|
|
|
use arrayvec::{ArrayVec};
|
2020-09-15 12:17:42 +08:00
|
|
|
|
|
|
|
pub trait MqttScpiTranslator {
|
2020-09-15 13:03:54 +08:00
|
|
|
// Convert an MQTT publish message into SCPI compatible command
|
|
|
|
// The argument part/ MQTT message must follow SCPI standard for parameter formatting
|
|
|
|
fn run_with_mqtt<FMT: Formatter>(&mut self, topic: &str, args: &str, response: &mut FMT) -> Result<()>;
|
2020-09-15 12:17:42 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a, T: Device> MqttScpiTranslator for Context<'a, T> {
|
2020-09-15 13:03:54 +08:00
|
|
|
fn run_with_mqtt<FMT>(&mut self, topic: &str, args: &str, response: &mut FMT) -> Result<()>
|
2020-09-15 12:17:42 +08:00
|
|
|
where
|
|
|
|
FMT: Formatter,
|
|
|
|
{
|
2020-09-15 13:03:54 +08:00
|
|
|
// Create a fixed-size buffer to handle slice operation
|
|
|
|
let mut buffer = ArrayVec::<[u8; 1024]>::new();
|
|
|
|
|
|
|
|
// Copy MQTT topic, convert it into SCPI header format
|
|
|
|
for i in topic.chars() {
|
|
|
|
if i == '/' {
|
|
|
|
// The topic separator is colon(':') in SCPI, and slash('/') in MQTT
|
|
|
|
buffer.try_push(b':')
|
2020-09-15 14:03:59 +08:00
|
|
|
.map_err(|_| ErrorCode::OutOfMemory)?;
|
2020-09-15 12:17:42 +08:00
|
|
|
} else {
|
2020-09-15 13:03:54 +08:00
|
|
|
buffer.try_push(i as u8)
|
2020-09-15 14:03:59 +08:00
|
|
|
.map_err(|_| ErrorCode::OutOfMemory)?;
|
2020-09-15 12:17:42 +08:00
|
|
|
}
|
|
|
|
}
|
2020-09-15 13:03:54 +08:00
|
|
|
|
|
|
|
// Place a space bar between header and parameter
|
|
|
|
buffer.try_push(b' ')
|
|
|
|
.map_err(|_| ErrorCode::OutOfMemory)?;
|
|
|
|
|
|
|
|
// Copy the arguments into the buffer
|
|
|
|
for i in args.chars() {
|
|
|
|
buffer.try_push(i as u8)
|
|
|
|
.map_err(|_| ErrorCode::OutOfMemory)?;
|
|
|
|
}
|
|
|
|
|
2020-09-15 14:03:59 +08:00
|
|
|
// Pass the message to SCPI processing unit
|
|
|
|
trace!("Translated MQTT message into SCPI. Translated command: {}",
|
|
|
|
core::str::from_utf8(buffer.as_slice()).unwrap());
|
2020-09-15 13:03:54 +08:00
|
|
|
self.run(buffer.as_slice(), response)
|
2020-09-15 12:17:42 +08:00
|
|
|
}
|
|
|
|
}
|