2021-05-05 22:16:54 +08:00
|
|
|
use heapless::{consts, String, Vec};
|
2021-04-20 20:12:47 +08:00
|
|
|
use serde::Serialize;
|
|
|
|
|
2021-05-05 22:16:54 +08:00
|
|
|
use super::NetworkReference;
|
|
|
|
use crate::hardware::design_parameters::MQTT_BROKER;
|
|
|
|
use minimq::QoS;
|
|
|
|
|
2021-04-29 21:55:36 +08:00
|
|
|
use crate::hardware::AfeGain;
|
|
|
|
|
|
|
|
#[derive(Copy, Clone)]
|
|
|
|
pub struct TelemetryBuffer {
|
2021-04-20 20:12:47 +08:00
|
|
|
pub latest_samples: [i16; 2],
|
2021-04-29 23:39:19 +08:00
|
|
|
pub latest_outputs: [u16; 2],
|
2021-04-20 20:12:47 +08:00
|
|
|
pub digital_inputs: [bool; 2],
|
|
|
|
}
|
|
|
|
|
2021-04-29 21:55:36 +08:00
|
|
|
#[derive(Serialize)]
|
|
|
|
pub struct Telemetry {
|
|
|
|
input_levels: [f32; 2],
|
|
|
|
output_levels: [f32; 2],
|
2021-04-29 23:39:19 +08:00
|
|
|
digital_inputs: [bool; 2],
|
2021-04-29 21:55:36 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Default for TelemetryBuffer {
|
2021-04-20 20:12:47 +08:00
|
|
|
fn default() -> Self {
|
|
|
|
Self {
|
|
|
|
latest_samples: [0, 0],
|
|
|
|
latest_outputs: [0, 0],
|
|
|
|
digital_inputs: [false, false],
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-04-29 21:55:36 +08:00
|
|
|
|
|
|
|
impl TelemetryBuffer {
|
|
|
|
pub fn to_telemetry(self, afe0: AfeGain, afe1: AfeGain) -> Telemetry {
|
2021-04-29 23:39:19 +08:00
|
|
|
let in0_volts =
|
|
|
|
(self.latest_samples[0] as f32 / i16::MAX as f32) * 4.096 / 2.0
|
|
|
|
* 5.0
|
|
|
|
/ afe0.to_multiplier() as f32;
|
|
|
|
let in1_volts =
|
|
|
|
(self.latest_samples[1] as f32 / i16::MAX as f32) * 4.096 / 2.0
|
|
|
|
* 5.0
|
|
|
|
/ afe1.to_multiplier() as f32;
|
2021-04-29 21:55:36 +08:00
|
|
|
|
2021-04-29 23:39:19 +08:00
|
|
|
let out0_volts = (10.24 * 2.0)
|
|
|
|
* (self.latest_outputs[0] as f32 / (u16::MAX as f32))
|
|
|
|
- 10.24;
|
|
|
|
let out1_volts = (10.24 * 2.0)
|
|
|
|
* (self.latest_outputs[1] as f32 / (u16::MAX as f32))
|
|
|
|
- 10.24;
|
2021-04-29 21:55:36 +08:00
|
|
|
|
|
|
|
Telemetry {
|
|
|
|
input_levels: [in0_volts, in1_volts],
|
|
|
|
output_levels: [out0_volts, out1_volts],
|
|
|
|
digital_inputs: self.digital_inputs,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-05-05 22:16:54 +08:00
|
|
|
|
|
|
|
pub struct TelemetryClient<T: Serialize> {
|
|
|
|
mqtt: minimq::MqttClient<minimq::consts::U256, NetworkReference>,
|
|
|
|
telemetry_topic: String<consts::U128>,
|
|
|
|
_telemetry: core::marker::PhantomData<T>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T: Serialize> TelemetryClient<T> {
|
|
|
|
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<consts::U128> = 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<u8, consts::U256> =
|
|
|
|
serde_json_core::to_vec(telemetry).unwrap();
|
|
|
|
self.mqtt
|
|
|
|
.publish(&self.telemetry_topic, &telemetry, QoS::AtMostOnce, &[])
|
|
|
|
.ok();
|
|
|
|
}
|
2021-05-05 22:46:53 +08:00
|
|
|
|
|
|
|
pub fn update(&mut self) {
|
|
|
|
match self.mqtt.poll(|_client, _topic, _message, _properties| {}) {
|
|
|
|
Err(minimq::Error::Network(
|
|
|
|
smoltcp_nal::NetworkError::NoIpAddress,
|
|
|
|
)) => {}
|
|
|
|
|
|
|
|
Err(error) => log::info!("Unexpected error: {:?}", error),
|
|
|
|
_ => {}
|
|
|
|
}
|
|
|
|
}
|
2021-05-05 22:16:54 +08:00
|
|
|
}
|