# Cayenne Low Power Payload for Rust [![build](https://github.com/Octoate/CayenneLPP-rs/actions/workflows/build.yml/badge.svg)](https://github.com/octoate/CayenneLPP-rs/actions) [![codecov](https://codecov.io/github/Octoate/CayenneLPP-rs/graph/badge.svg?token=F58DRE5E0D)](https://codecov.io/github/Octoate/CayenneLPP-rs) ![crates.io](https://img.shields.io/crates/v/cayenne_lpp) ![docs.rs](https://img.shields.io/docsrs/cayenne_lpp) ![license](https://img.shields.io/crates/l/cayenne_lpp.svg) This crate is a port of the [Cayenne Low Power Payload (LPP)](https://docs.mydevices.com/docs/lorawan/cayenne-lpp) API to the Rust programming language. It provides an easy way to send data over LPWAN networks such as LoRaWAN. Cayenne LPP is compliant with payload size restrictions, which can be lowered down to 11 bytes and allows the device to send multiple sensor data at one time. Its focus lies on embedded systems, so it uses the "no_std" attribute to only link the core-crate instead of the std-crate. It also does not depend on any other crates. Additionally, it is also possible to send different sensor data in different frames. To do this, the channel value of the data can be used. The payload is compatible to the integrated payload formatter of the [The Things Network (TTN)](https://www.thethingsnetwork.org) console. It can be enabled for the download or the uplink of a device. More information about the Cayenne LPP payload formatter of the TTN can be found [here](https://www.thethingsindustries.com/docs/integrations/payload-formatters/cayenne/). The original C++ version of Cayenne LPP can be found [here](https://github.com/myDevicesIoT/CayenneLPP). ## Example The following example will show how to add two data types, one digital input value and one temperature value, to the Cayenne LPP payload. Since there is no memory allocator available ("no_std"), the API needs a buffer, that will be filled by it. To create a buffer with the exact size of the payload, use the size constants of the different data types, that are provided by the API. To add two digital inputs, just multiply the size variable by 2 and use this size for the buffer initialization. The buffer needs to be mutable since it will be modified by the API. Note that it is not necessary to exactly define the buffer size, it just needs to be greater or equal to the size of the data types that are added to it. Therefore, it is possible to reuse the buffer with different data types. The CayenneLPP::reset() function can be used to reset the structure. After the buffer initialization, just create a new instance of the CayenneLPP API and add the data types to the payload with the available API functions. After adding all the values, a slice to the buffer can be retrieved by calling the CayenneLPP::payload_slice() function. The slice can be then used to send the data via an external API. ```rust fn main() { // create the buffer for a digital input and a temperature data type let mut buffer: [u8; LPP_DIGITAL_INPUT_SIZE + LPP_TEMPERATURE_SIZE] = [0; LPP_DIGITAL_INPUT_SIZE + LPP_TEMPERATURE_SIZE]; // create a new instance of CayenneLPP struct and initialize it with the buffer let mut lpp = CayenneLPP::new(&mut buffer); // add a digital input with the value 0x55 lpp.add_digital_input(3, 0x55).unwrap(); // add a temperature value of 12.3°C lpp.add_temperature(5, 12.3).unwrap(); // retrieve the payload slice to be able to send the payload via an external API let cayenne_lpp_payload = lpp.payload_slice(); // ... send the data via an external API // reset the API and start from the beginning of the buffer lpp.reset(); // add new values... lpp.add_digital_input(3, 0xAA).unwrap(); lpp.add_temperature(5, 32.1).unwrap(); } ``` ## Future development The API in its current state should be pretty stable to use. Currently it only supports ```no_std```, but it would be possible to support an easier to use API for ```std``` as well. However, if you have any remarks or want to add some functionality feel free to start a discussion or send a PR, but do not forget to add unit tests and / or integration tests, if you want that it gets merged into the repo. # License The crate is released under the MIT license. See [LICENSE](./LICENSE) for more information.