opensensor 0.4.0

A crate for streaming and archiving measurements from sensors
# OpenSensor - Traits & generics for implementing new sensors

Generics for implementing new sensors that interact with the OpenSensor Infrastructure as Code.

## Requirements

- [rust]https://www.rust-lang.org/: Minimum Supported Rust Version 1.65
- [lld linker]https://lld.llvm.org/: for faster Rust builds.
  - See [.cargo/config.toml].cargo/config.toml for platform-specific installation instructions and the [Rust Performance Book]https://nnethercote.github.io/perf-book/compile-times.html for the reasons for using lld.
- [docker]https://www.docker.com/: Container engine
- [docker compose]https://docs.docker.com/compose/: Multi-container orchestration. NOTE: `docker-compose` is now deprecated and the compose functionality is integrated into the `docker compose` command. To install alongside an existing docker installation, run `sudo apt-get install docker-compose-plugin`. [ref]https://docs.docker.com/compose/#compose-v2-and-the-new-docker-compose-command.

For Debian-based Linux distros, you can install `opensensor-rs`'s dependencies (except Docker, that require special repository configuration documented above) with the following command:

`apt-get install clang build-essential lld clang zstd libzstd-dev make cmake pkg-config libssl-dev`

`opensensor-rs` is tested on Ubuntu 22.04 LTS, but welcomes pull requests to fix Windows or MacOS issues.

## Quick Start

1. Clone repo: ```git clone https://github.com/opensensordotdev/opensensor-rs.git```
  - Ensure all requirements have been installed, especially the lld linker!  Otherwise `opensensor-rs` won't build!
2. `./bootstrap_cluster.sh`: Start the testing Redpanda, MinIO, and monitoring stack.
3. `cargo test`: Verify all cargo tests pass

## Provided Generics

![OpenSensor architecture](transducer_sensor_background.png)

- `Measurement`: The physical data structure representing the discrete unit of data produced by the sensor. Each `Sensor` can produce multiple kinds of `Measurements`.
- `Transducer`: The interface with sensor hardware, producing a stream of `Measurements`.
- `Sensor`: The abstraction between multiple `Transducers` that produce the same kind of `Measurements`, grouping common validation logic together. Consumes from the [mpsc]https://docs.rs/tokio/latest/tokio/sync/mpsc/index.html channel that the `Transducer` sends `Measurements` on, validates them, and produces to Redpanda.

## Adding New Measurements

`Measurements` are notionally serialized using Google [flatbuffers](https://google.github.io/flatbuffers/). For a sample `Measurement`, `Transducer`, and `Sensor` implementation, see the `sensor-simple` crate in the [opensensor](https://github.com/opensensordotdev/opensensor) repository.

## Arrow + Parquet Archiving

In order to make implementing new sensors as straightforward as possible, `opensensor-rs` seeks to provide automatic archiving of `Measurement` implementers to Parquet through Rust's Arrow bindings. Experiments for archiving arbitrary Rust structs to arrow and then parquet are documented in the `archiver` directory and in `arrow.rs`. Ideally, this functionality would be derivable or implementable through traits to allow arbitrary measurements to be serialized to/from parquet.

Filed this [issue](https://github.com/jorgecarleitao/arrow2/issues/1376) on arrow2, but even though their resulting PR fixed the Rust code (the tests in `test_arrow.rs` now pass), the resulting parquet for any nested arrays or structs still can't be deserialized in pyarrow.

The test cases in `test_arrow.rs` are based on the following examples:

- [arrow2 parquet writer]https://github.com/jorgecarleitao/arrow2/blob/main/examples/parquet_write.rs
- [arrow2_convert simple example]https://github.com/DataEngineeringLabs/arrow2-convert/blob/main/examples/simple/src/main.rs
- [arrow2_convert complex example]https://github.com/DataEngineeringLabs/arrow2-convert/blob/main/arrow2_convert/tests/complex_example.rs