Skip to content

Commit

Permalink
Improve resilience against serial line read errors
Browse files Browse the repository at this point in the history
  • Loading branch information
mthmulders committed Nov 20, 2023
1 parent 92c077b commit cfc82de
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 18 deletions.
40 changes: 23 additions & 17 deletions src/dsmr/reader.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use super::settings;
use super::settings::ParityBitSetting;

use serialport::SerialPort;

use std::borrow::Cow;
use std::io::BufRead;
use std::io::BufReader;
Expand Down Expand Up @@ -80,8 +82,8 @@ fn eat_telegrams<'a>(buffer: &'a str, consumer: &mut dyn super::TelegramConsumer
}
}

fn read_from_serial_port(
port: &mut dyn serialport::SerialPort,
pub fn read_from_serial_port(
port: Box<dyn SerialPort>,
consumer: &mut dyn super::TelegramConsumer,
) {
let reader = &mut BufReader::new(port);
Expand All @@ -90,24 +92,30 @@ fn read_from_serial_port(

let mut buffer = String::new();
loop {
reader.read_line(&mut buffer).expect("Could not read data");

let clone = buffer.clone();

let new_buffer = eat_telegrams(&clone, consumer);

if buffer != new_buffer {
log::trace!("Replacing buffer {} with {}", buffer, new_buffer);
buffer.clear();
buffer.push_str(&new_buffer);
let result = reader.read_line(&mut buffer);

if result.is_err() {
let error = result.expect_err("Expected an error, but there is none?");
log::info!("Read error {}, clearing buffer", error.to_string());
// Just drop this telegram
buffer.clear();
} else {
let clone = buffer.clone();

let new_buffer = eat_telegrams(&clone, consumer);

if buffer != new_buffer {
log::trace!("Replacing buffer {} with {}", buffer, new_buffer);
buffer.clear();
buffer.push_str(&new_buffer);
}
}
}
}

pub fn connect_to_meter(
serial_settings: settings::SerialSettings,
consumer: &mut dyn super::TelegramConsumer,
) {
) -> Box<dyn SerialPort> {
log::info!(
"Connecting to {} using baud rate {}, byte size {} and parity bit {:#?}",
&serial_settings.port,
Expand All @@ -116,16 +124,14 @@ pub fn connect_to_meter(
&serial_settings.parity_bit
);

let mut port = serialport::new(&serial_settings.port, serial_settings.baud_rate)
return serialport::new(&serial_settings.port, serial_settings.baud_rate)
.data_bits(to_databits(&serial_settings.byte_size))
.flow_control(serialport::FlowControl::None)
.parity(to_serial_port_parity_bit(&serial_settings.parity_bit))
.stop_bits(serialport::StopBits::One)
.timeout(Duration::from_secs(20))
.open()
.expect("Failed to open port");

read_from_serial_port(&mut *port, consumer);
}

fn to_serial_port_parity_bit(input: &ParityBitSetting) -> serialport::Parity {
Expand Down
7 changes: 6 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use serialport::SerialPort;

mod dsmr;

fn init_logger(debug_logging: bool) {
Expand Down Expand Up @@ -49,5 +51,8 @@ pub fn main() {
log::info!("dsmr-rs starting...");
let (serial_settings, api_settings) = dsmr::settings::settings(settings).unwrap();
let mut consumer = dsmr::sender::DelegatingConsumer::new(api_settings.hosts);
dsmr::reader::connect_to_meter(serial_settings, &mut consumer);

let port: Box<dyn SerialPort> = dsmr::reader::connect_to_meter(serial_settings);

dsmr::reader::read_from_serial_port(port, &mut consumer);
}

0 comments on commit cfc82de

Please sign in to comment.