pub struct R4DCB08;tokio-rtu or tokio-tcp only.Expand description
Asynchronous client for interacting with the R4DCB08 temperature module over Modbus.
This struct provides methods to read sensor data and configure the module’s
operational parameters by wrapping tokio-modbus asynchronous operations.
All methods that interact with the Modbus device are async and return Futures.
Implementations§
Source§impl R4DCB08
impl R4DCB08
Sourcepub async fn read_temperatures(ctx: &mut Context) -> Result<Temperatures, Error>
pub async fn read_temperatures(ctx: &mut Context) -> Result<Temperatures, Error>
Reads the current temperatures from all 8 available channels in degrees Celsius (°C).
If a channel’s sensor is not connected or reports an error, the corresponding
proto::Temperature value will be proto::Temperature::NAN.
§Returns
A Result<proto::Temperatures> containing the temperatures for all channels,
or a Modbus error.
§Errors
tokio_modbus::Errorif a Modbus communication error occurs (e.g., IO error, timeout handled by wrapper, Modbus exception).tokio_modbus::Error::Transportwithstd::io::ErrorKind::InvalidDataif the device returns an unexpected number of registers.
§Examples
let temperatures = tokio::time::timeout(Duration::from_secs(2), R4DCB08::read_temperatures(&mut modbus_ctx)).await??;
println!("Temperatures read successfully:");
for (i, temp) in temperatures.iter().enumerate() {
println!(" Channel {}: {}", i, temp); // `temp` uses Display impl from protocol
}Sourcepub async fn read_temperature_correction(
ctx: &mut Context,
) -> Result<TemperatureCorrection, Error>
pub async fn read_temperature_correction( ctx: &mut Context, ) -> Result<TemperatureCorrection, Error>
Reads the configured temperature correction values (°C) for all 8 channels.
A proto::Temperature value of 0.0 typically means no correction is applied,
while proto::Temperature::NAN might indicate an uninitialized or error state for a correction value if read.
§Returns
A Result<proto::TemperatureCorrection> containing correction values for each channel,
or a Modbus error.
§Errors
tokio_modbus::Errorfor Modbus communication errors.tokio_modbus::Error::Transportwithstd::io::ErrorKind::InvalidDataif the device returns an unexpected number of registers.
§Examples
let corrections = tokio::time::timeout(Duration::from_secs(2), R4DCB08::read_temperature_correction(&mut modbus_ctx)).await??;
println!("Temperature correction values: {}", corrections);Sourcepub async fn set_temperature_correction(
ctx: &mut Context,
channel: Channel,
correction: Temperature,
) -> Result<(), Error>
pub async fn set_temperature_correction( ctx: &mut Context, channel: Channel, correction: Temperature, ) -> Result<(), Error>
Sets a temperature correction value for a specific channel.
The correction value will be added to the raw temperature reading by the module.
Setting a correction value of 0.0 effectively disables it for that channel.
§Arguments
channel- Theproto::Channelto configure.correction- Theproto::Temperaturecorrection value to apply (in °C). This type ensures the temperature value is within the representable range.
§Returns
A Result<()> indicating success or failure of the write operation.
§Errors
tokio_modbus::Errorfor Modbus communication errors.tokio_modbus::Error::Transportwithstd::io::ErrorKind::InvalidInputif thecorrectionvalue isNAN.
§Examples
use r4dcb08_lib::protocol::{Channel, Temperature, Error};
use std::time::Duration;
// Set the temperature correction for channel 3 to +1.3°C.
let channel = Channel::try_from(3)?;
let correction_value = Temperature::try_from(1.3)?;
tokio::time::timeout(Duration::from_secs(2), R4DCB08::set_temperature_correction(&mut modbus_ctx, channel, correction_value)).await??;
println!("Correction for channel {} set to {}.", channel, correction_value);Sourcepub async fn read_automatic_report(
ctx: &mut Context,
) -> Result<AutomaticReport, Error>
pub async fn read_automatic_report( ctx: &mut Context, ) -> Result<AutomaticReport, Error>
Reads the automatic temperature reporting interval.
An interval of 0 seconds (proto::AutomaticReport::DISABLED) means automatic reporting is off.
§Returns
A Result<proto::AutomaticReport> indicating the configured reporting interval,
or a Modbus error.
§Errors
tokio_modbus::Errorfor Modbus communication errors.tokio_modbus::Error::Transportwithstd::io::ErrorKind::InvalidDataif the device returns malformed data.
§Examples
let report = tokio::time::timeout(Duration::from_secs(2), R4DCB08::read_automatic_report(&mut modbus_ctx)).await??;
if report.is_disabled() {
println!("Automatic reporting is disabled.");
} else {
println!("Automatic report interval: {} seconds.", report.as_secs());
}Sourcepub async fn set_automatic_report(
ctx: &mut Context,
report: AutomaticReport,
) -> Result<(), Error>
pub async fn set_automatic_report( ctx: &mut Context, report: AutomaticReport, ) -> Result<(), Error>
Sets the automatic temperature reporting interval.
When enabled (interval > 0), the module may periodically send temperature data unsolicitedly over the RS485 bus (behavior depends on module firmware).
§Arguments
report- Theproto::AutomaticReportinterval (0 = disabled, 1-255 seconds). Theproto::AutomaticReporttype ensures the value is within the valid hardware range.
§Returns
A Result<()> indicating success or failure of the write operation.
§Errors
tokio_modbus::Errorfor Modbus communication errors.
§Examples
use r4dcb08_lib::protocol::{AutomaticReport, Error};
use std::time::Duration;
let report_interval = AutomaticReport::try_from(Duration::from_secs(10))?;
tokio::time::timeout(Duration::from_secs(2), R4DCB08::set_automatic_report(&mut modbus_ctx, report_interval)).await??;
println!("Automatic report interval set to 10 seconds.");Sourcepub async fn read_baud_rate(ctx: &mut Context) -> Result<BaudRate, Error>
pub async fn read_baud_rate(ctx: &mut Context) -> Result<BaudRate, Error>
Reads the current Modbus communication baud rate setting from the device.
§Returns
A Result<proto::BaudRate> containing the configured baud rate,
or a Modbus error.
§Errors
tokio_modbus::Errorfor Modbus communication errors.tokio_modbus::Error::Transportwithstd::io::ErrorKind::InvalidDataif the device returns an invalid baud rate code.
§Examples
let baud_rate = tokio::time::timeout(Duration::from_secs(2), R4DCB08::read_baud_rate(&mut modbus_ctx)).await??;
println!("Current baud rate: {}", baud_rate);Sourcepub async fn set_baud_rate(
ctx: &mut Context,
baud_rate: BaudRate,
) -> Result<(), Error>
pub async fn set_baud_rate( ctx: &mut Context, baud_rate: BaudRate, ) -> Result<(), Error>
Sets the Modbus communication baud rate for the device.
Important: The new baud rate setting will only take effect after the R4DCB08 module is power cycled (turned off and then on again).
§Arguments
baud_rate- The desiredproto::BaudRateto set.
§Returns
A Result<()> indicating success or failure of the write operation.
§Errors
tokio_modbus::Errorfor Modbus communication errors.
§Examples
use r4dcb08_lib::protocol::{BaudRate, Error};
use std::time::Duration;
// Set the baud rate to 19200.
let new_baud_rate = BaudRate::B19200; // Direct enum variant
// Or from u16:
// let new_baud_rate = BaudRate::try_from(19200)?;
tokio::time::timeout(Duration::from_secs(2), R4DCB08::set_baud_rate(&mut modbus_ctx, new_baud_rate)).await??;
println!("Baud rate set to {}. Power cycle the device for changes to take effect.", new_baud_rate);Sourcepub async fn factory_reset(ctx: &mut Context) -> Result<(), Error>
pub async fn factory_reset(ctx: &mut Context) -> Result<(), Error>
Resets the R4DCB08 module to its factory default settings.
This resets all configurable parameters like Modbus Address, Baud Rate, Temperature Corrections, etc., to their original defaults.
Important:
- After this command is successfully sent, the module may become unresponsive on the Modbus bus until it is power cycled.
- A power cycle (turning the device off and then on again) is required to complete the factory reset process and for the default settings to be applied.
§Returns
A Result<()> indicating if the reset command was sent successfully.
It does not confirm the reset is complete, only that the Modbus write was acknowledged.
§Errors
tokio_modbus::Errorfor Modbus communication errors. A timeout error after this command might be expected as the device resets and may not send a response.
§Examples
println!("Attempting to send factory reset command...");
match tokio::time::timeout(Duration::from_secs(2), R4DCB08::factory_reset(&mut modbus_ctx)).await {
Ok(Ok(())) => println!("Factory reset command sent. Power cycle the device to complete."),
Ok(Err(e)) => eprintln!("Modbus error during factory reset: {}", e),
Err(e) => {
// After the a successful factory reset we get no response :-(
println!("Factory reset command sent. Device timed out as expected. Power cycle to complete.");
}
}Sourcepub async fn read_address(ctx: &mut Context) -> Result<Address, Error>
pub async fn read_address(ctx: &mut Context) -> Result<Address, Error>
Reads the current Modbus device address (Slave ID) from the module.
Important Usage Notes:
- This command is typically used when the device’s
current address is unknown. To do this, the Modbus request must be sent to
the broadcast address (
proto::Address::BROADCAST). - Single Device Only: Only one R4DCB08 module should be connected to the Modbus bus when executing this command with the broadcast address. If multiple devices are present, they might all respond, leading to data collisions and errors.
§Returns
A Result<proto::Address> containing the device’s configured Modbus address,
or a Modbus error.
§Errors
tokio_modbus::Errorfor Modbus communication errors.tokio_modbus::Error::Transportwithstd::io::ErrorKind::InvalidDataif the device returns a malformed or out-of-range address.
§Examples
use r4dcb08_lib::tokio_async::R4DCB08;
use r4dcb08_lib::protocol;
use std::time::Duration;
// Requires serial port features enabled in tokio-modbus
let builder = tokio_serial::new("/dev/ttyUSB0", 9600) // Baud rate 9600
.parity(tokio_serial::Parity::None)
.stop_bits(tokio_serial::StopBits::One)
.data_bits(tokio_serial::DataBits::Eight)
.flow_control(tokio_serial::FlowControl::None);
let port = tokio_serial::SerialStream::open(&builder)?;
// Assume only one device connected, use broadcast address for reading
let mut modbus_ctx = tokio_modbus::client::rtu::attach_slave(port, tokio_modbus::Slave(*protocol::Address::BROADCAST));
println!("Attempting to read device address using broadcast...");
let device_address = tokio::time::timeout(Duration::from_secs(2), R4DCB08::read_address(&mut modbus_ctx)).await??;
println!("Successfully read device address: {}", device_address);Sourcepub async fn set_address(
ctx: &mut Context,
new_address: Address,
) -> Result<(), Error>
pub async fn set_address( ctx: &mut Context, new_address: Address, ) -> Result<(), Error>
Sets a new Modbus device address.
Warning:
- This permanently changes the device’s Modbus address.
- This command must be sent while addressing the device using its current Modbus address.
- After successfully changing the address, subsequent communication with the device must use the new address.
§Arguments
new_address- The newproto::Addressto assign to the device.
§Returns
A Result<()> indicating success or failure of the write operation.
§Errors
tokio_modbus::Errorfor Modbus communication errors.
§Examples
use r4dcb08_lib::tokio_async::R4DCB08;
use r4dcb08_lib::protocol::{Address, Error};
use std::time::Duration;
// Requires serial port features enabled in tokio-modbus
let builder = tokio_serial::new("/dev/ttyUSB0", 9600) // Baud rate 9600
.parity(tokio_serial::Parity::None)
.stop_bits(tokio_serial::StopBits::One)
.data_bits(tokio_serial::DataBits::Eight)
.flow_control(tokio_serial::FlowControl::None);
// --- Assume device is currently at address 1 ---
let current_device_address = Address::try_from(1)?;
let port = tokio_serial::SerialStream::open(&builder)?;
let mut modbus_ctx = tokio_modbus::client::rtu::attach_slave(port, tokio_modbus::Slave(*current_device_address));
// --- New address we want to set ---
let new_device_address = Address::try_from(10)?;
println!("Attempting to change device address from {} to {}...", current_device_address, new_device_address);
tokio::time::timeout(Duration::from_secs(2), R4DCB08::set_address(&mut modbus_ctx, new_device_address)).await??;
println!("Device address successfully changed to {}.", new_device_address);
println!("You will need to reconnect using the new address for further communication.");