From 8144b3acf2b05561b780a6f673ca55ef11b5e153 Mon Sep 17 00:00:00 2001 From: Ryan Summers Date: Wed, 5 May 2021 16:16:54 +0200 Subject: [PATCH] Updating constructors --- Cargo.lock | 1 + Cargo.toml | 1 + src/bin/dual-iir.rs | 52 ++++++++------------------- src/bin/lockin.rs | 51 ++++++++------------------- src/net/mod.rs | 83 ++++++++++++++++++++++++++++++++++++++++---- src/net/telemetry.rs | 36 +++++++++++++++++++ 6 files changed, 145 insertions(+), 79 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 41d1676..b7bfa73 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -763,6 +763,7 @@ dependencies = [ "panic-semihosting", "paste", "serde", + "serde-json-core", "shared-bus", "smoltcp-nal", "stm32h7xx-hal", diff --git a/Cargo.toml b/Cargo.toml index b6279a8..eefadff 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -46,6 +46,7 @@ ad9959 = { path = "ad9959" } generic-array = "0.14" miniconf = "0.1.0" shared-bus = {version = "0.2.2", features = ["cortex-m"] } +serde-json-core = "0.3" [dependencies.mcp23017] git = "https://github.com/mrd0ll4r/mcp23017.git" diff --git a/src/bin/dual-iir.rs b/src/bin/dual-iir.rs index f83ad1c..f02efda 100644 --- a/src/bin/dual-iir.rs +++ b/src/bin/dual-iir.rs @@ -13,10 +13,7 @@ use hardware::{ DigitalInput1, InputPin, SystemTimer, AFE0, AFE1, }; -use net::{ - MiniconfClient, NetworkManager, NetworkProcessor, NetworkUsers, - TelemetryBuffer, UpdateState, -}; +use net::{NetworkUsers, Telemetry, TelemetryBuffer, UpdateState}; const SCALE: f32 = i16::MAX as _; @@ -59,7 +56,7 @@ const APP: () = { digital_inputs: (DigitalInput0, DigitalInput1), adcs: (Adc0Input, Adc1Input), dacs: (Dac0Output, Dac1Output), - network: NetworkUsers, + network: NetworkUsers, settings: Settings, telemetry: TelemetryBuffer, @@ -73,32 +70,13 @@ const APP: () = { // Configure the microcontroller let (mut stabilizer, _pounder) = hardware::setup(c.core, c.device); - let network = { - let stack = stabilizer.net.stack; - let stack_manager = cortex_m::singleton!(: NetworkManager = NetworkManager::new(stack)).unwrap(); - - let processor = NetworkProcessor::new( - stack_manager.acquire_stack(), - stabilizer.net.phy, - stabilizer.cycle_counter, - ); - - let settings = MiniconfClient::new( - stack_manager.acquire_stack(), - "", - &net::get_device_prefix( - env!("CARGO_BIN_NAME"), - stabilizer.net.mac_address, - ), - ); - - // TODO: Add telemetry client - - NetworkUsers { - miniconf: settings, - processor, - } - }; + let network = NetworkUsers::new( + stabilizer.net.stack, + stabilizer.net.phy, + stabilizer.cycle_counter, + env!("CARGO_BIN_NAME"), + stabilizer.net.mac_address, + ); // Spawn a settings update for default settings. c.spawn.settings_update().unwrap(); @@ -223,15 +201,15 @@ const APP: () = { #[task(priority = 1, resources=[network, settings, telemetry], schedule=[telemetry])] fn telemetry(mut c: telemetry::Context) { - let _telemetry = + let telemetry = c.resources.telemetry.lock(|telemetry| telemetry.clone()); - let _gains = c.resources.settings.lock(|settings| settings.afe.clone()); + let gains = c.resources.settings.lock(|settings| settings.afe.clone()); - // TODO: Publish telemetry through the telemetry client here. - //c.resources - // .mqtt - // .publish_telemetry(&telemetry.to_telemetry(gains[0], gains[1])); + c.resources + .network + .telemetry + .publish(&telemetry.to_telemetry(gains[0], gains[1])); let telemetry_period = c .resources diff --git a/src/bin/lockin.rs b/src/bin/lockin.rs index ed7f4f3..de0857f 100644 --- a/src/bin/lockin.rs +++ b/src/bin/lockin.rs @@ -18,9 +18,7 @@ use stabilizer::hardware::{ }; use miniconf::Miniconf; -use stabilizer::net::{ - MiniconfClient, NetworkManager, NetworkProcessor, NetworkUsers, UpdateState, -}; +use net::{NetworkUsers, Telemetry, TelemetryBuffer, UpdateState}; #[derive(Copy, Clone, Debug, Deserialize, Miniconf)] enum Conf { @@ -66,9 +64,9 @@ const APP: () = { afes: (AFE0, AFE1), adcs: (Adc0Input, Adc1Input), dacs: (Dac0Output, Dac1Output), - network: NetworkUsers, + network: NetworkUsers, settings: Settings, - telemetry: net::TelemetryBuffer, + telemetry: TelemetryBuffer, digital_inputs: (DigitalInput0, DigitalInput1), timestamper: InputStamper, @@ -81,32 +79,13 @@ const APP: () = { // Configure the microcontroller let (mut stabilizer, _pounder) = setup(c.core, c.device); - let network = { - let stack = stabilizer.net.stack; - let stack_manager = cortex_m::singleton!(: NetworkManager = NetworkManager::new(stack)).unwrap(); - - let processor = NetworkProcessor::new( - stack_manager.acquire_stack(), - stabilizer.net.phy, - stabilizer.cycle_counter, - ); - - let settings = MiniconfClient::new( - stack_manager.acquire_stack(), - "", - &net::get_device_prefix( - env!("CARGO_BIN_NAME"), - stabilizer.net.mac_address, - ), - ); - - // TODO: Add telemetry client - - NetworkUsers { - miniconf: settings, - processor, - } - }; + let network = NetworkUsers::new( + stabilizer.net.stack, + stabilizer.net.phy, + stabilizer.cycle_counter, + env!("CARGO_BIN_NAME"), + stabilizer.net.mac_address, + ); let settings = Settings::default(); @@ -271,12 +250,12 @@ const APP: () = { c.resources.digital_inputs.1.is_high().unwrap(), ]; - let _gains = c.resources.settings.lock(|settings| settings.afe.clone()); + let gains = c.resources.settings.lock(|settings| settings.afe.clone()); - // TODO: Publish telemetry. - //c.resources - // .mqtt - // .publish_telemetry(&telemetry.to_telemetry(gains[0], gains[1])); + c.resources + .network + .telemetry + .publish(&telemetry.to_telemetry(gains[0], gains[1])); let telemetry_period = c .resources diff --git a/src/net/mod.rs b/src/net/mod.rs index 9601501..41eee45 100644 --- a/src/net/mod.rs +++ b/src/net/mod.rs @@ -1,3 +1,4 @@ +use core::fmt::Write; ///! Stabilizer network management module ///! ///! # Design @@ -6,8 +7,8 @@ ///! streaming over raw UDP/TCP sockets. This module encompasses the main processing routines ///! related to Stabilizer networking operations. use heapless::{consts, String}; - -use core::fmt::Write; +use miniconf::Miniconf; +use serde::Serialize; mod messages; mod mqtt_interface; @@ -15,14 +16,13 @@ mod shared; mod stack_manager; mod telemetry; -use crate::hardware::NetworkStack; +use crate::hardware::{CycleCounter, EthernetPhy, NetworkStack}; use messages::{MqttMessage, SettingsResponse}; -use miniconf::Miniconf; pub use mqtt_interface::MiniconfClient; pub use shared::NetworkManager; pub use stack_manager::NetworkProcessor; -pub use telemetry::{Telemetry, TelemetryBuffer}; +pub use telemetry::{Telemetry, TelemetryBuffer, TelemetryClient}; pub type NetworkReference = shared::NetworkStackProxy<'static, NetworkStack>; @@ -32,9 +32,80 @@ pub enum UpdateState { Updated, } -pub struct NetworkUsers { +pub struct NetworkUsers { pub miniconf: MiniconfClient, pub processor: NetworkProcessor, + pub telemetry: TelemetryClient, +} + +impl NetworkUsers +where + S: Default + Clone + Miniconf, + T: Serialize, +{ + pub fn new( + stack: NetworkStack, + phy: EthernetPhy, + cycle_counter: CycleCounter, + app: &str, + mac: smoltcp_nal::smoltcp::wire::EthernetAddress, + ) -> Self { + let stack_manager = + cortex_m::singleton!(: NetworkManager = NetworkManager::new(stack)) + .unwrap(); + + let processor = NetworkProcessor::new( + stack_manager.acquire_stack(), + phy, + cycle_counter, + ); + + let prefix = get_device_prefix(app, mac); + + let settings = MiniconfClient::new( + stack_manager.acquire_stack(), + &get_client_id(app, "settings", mac), + &prefix, + ); + + let telemetry = TelemetryClient::new( + stack_manager.acquire_stack(), + &get_client_id(app, "tlm", mac), + &prefix, + ); + + NetworkUsers { + miniconf: settings, + processor, + telemetry, + } + } +} + +fn get_client_id( + app: &str, + client: &str, + mac: smoltcp_nal::smoltcp::wire::EthernetAddress, +) -> String { + let mac_string = { + let mut mac_string: String = String::new(); + let mac = mac.as_bytes(); + + // Note(unwrap): 32-bytes is guaranteed to be valid for any mac address, as the address has + // a fixed length. + write!( + &mut mac_string, + "{:02x}-{:02x}-{:02x}-{:02x}-{:02x}-{:02x}", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5] + ) + .unwrap(); + + mac_string + }; + + let mut identifier = String::new(); + write!(&mut identifier, "{}-{}-{}", app, mac_string, client).unwrap(); + identifier } /// Get the MQTT prefix of a device. diff --git a/src/net/telemetry.rs b/src/net/telemetry.rs index dccf3ac..1c22968 100644 --- a/src/net/telemetry.rs +++ b/src/net/telemetry.rs @@ -1,5 +1,10 @@ +use heapless::{consts, String, Vec}; use serde::Serialize; +use super::NetworkReference; +use crate::hardware::design_parameters::MQTT_BROKER; +use minimq::QoS; + use crate::hardware::AfeGain; #[derive(Copy, Clone)] @@ -51,3 +56,34 @@ impl TelemetryBuffer { } } } + +pub struct TelemetryClient { + mqtt: minimq::MqttClient, + telemetry_topic: String, + _telemetry: core::marker::PhantomData, +} + +impl TelemetryClient { + pub fn new(stack: NetworkReference, client_id: &str, prefix: &str) -> Self { + let mqtt = + minimq::MqttClient::new(MQTT_BROKER.into(), client_id, stack) + .unwrap(); + + let mut telemetry_topic: String = String::from(prefix); + telemetry_topic.push_str("/telemetry").unwrap(); + + Self { + mqtt, + telemetry_topic, + _telemetry: core::marker::PhantomData::default(), + } + } + + pub fn publish(&mut self, telemetry: &T) { + let telemetry: Vec = + serde_json_core::to_vec(telemetry).unwrap(); + self.mqtt + .publish(&self.telemetry_topic, &telemetry, QoS::AtMostOnce, &[]) + .ok(); + } +}