UDP observations

To receive observations we use UDP. Sensors can use a variety of transports and they tend to be “best-effort”, sometimes repeating events to improve their chances of reaching a destination. The following code illustrates binding to a UDP interface, receiving and deserializing a binary packet and then sending a Post command to the temperature entity.

Rust
source// Messages from sensors are generally small.
const MAX_DATAGRAM_SIZE: usize = 12;

#[derive(Debug, Deserialize, Serialize)]
struct TemperatureUpdated {
    dev_addr: u32,
    temperature: u32,
}

pub async fn task(socket: UdpSocket, temperature_commands: mpsc::Sender<Message<Command>>) {
    let mut recv_buf = [0; MAX_DATAGRAM_SIZE];
    while let Ok((len, _remote_addr)) = socket.recv_from(&mut recv_buf).await {
        if let Ok(event) =
            postcard::from_bytes::<TemperatureUpdated>(&recv_buf[..len.min(MAX_DATAGRAM_SIZE)])
        {
            debug!("Posting : {:?}", event);

            let _ = temperature_commands
                .send(Message::new(
                    event.dev_addr.to_string(),
                    Command::Post {
                        temperature: event.temperature,
                    },
                ))
                .await;
        }
    }
}

We are using Postcard for deserializing messages. Postcard has highly reasonable performance and works well on embedded devices that also use Rust.

What’s next?

  • The main function
Found an error in this documentation? The source code for this page can be found here. Please feel free to edit and contribute a pull request.