use scpi::prelude::*; use scpi::Context; use scpi::error::Result; use log::{trace, info}; use arrayvec::{ArrayVec}; pub trait MqttScpiTranslator { // Unwrap an MQTT publish message into SCPI compatible command // The command part/ MQTT message must follow SCPI standard for parameter formatting fn run_with_mqtt(&mut self, topic: &str, args: &str, response: &mut FMT) -> Result<()>; } impl<'a, T: Device> MqttScpiTranslator for Context<'a, T> { fn run_with_mqtt(&mut self, topic: &str, args: &str, response: &mut FMT) -> Result<()> where FMT: Formatter, { if !topic.starts_with("Urukul/Control") { info!("Received a publish, but not for control! Topic: {}", topic); return Ok(()); } // let command_topic = topic.strip_prefix("Urukul/Control") // .unwrap_or(""); // 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 command_topic.chars() { // if i == '/' { // // The topic separator is colon(':') in SCPI, and slash('/') in MQTT // buffer.try_push(b':') // .map_err(|_| ErrorCode::OutOfMemory)?; // } else { // buffer.try_push(i as u8) // .map_err(|_| ErrorCode::OutOfMemory)?; // } // } // // 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)?; } // Pass the message to SCPI processing unit trace!("Translated MQTT message into SCPI. Translated command: {}", core::str::from_utf8(buffer.as_slice()).unwrap()); self.run(buffer.as_slice(), response) } }