Retrieving temp/humidity data.

This commit is contained in:
Félix Baylac-Jacqué 2022-06-17 11:54:29 +02:00
commit aaa9838cc4
No known key found for this signature in database
GPG Key ID: EFD315F31848DBA4
5 changed files with 104 additions and 0 deletions

1
.envrc Normal file
View File

@ -0,0 +1 @@
use nix

8
Makefile Normal file
View File

@ -0,0 +1,8 @@
CC=rustc
build:
$(CC) -O main.rs -o temp-prometheus
install: build
install -d $(PREFIX)/bin/
install -m 755 ./temp-prometheus $(PREFIX)/bin/

12
README.md Normal file
View File

@ -0,0 +1,12 @@
# Prometheus Temperature Exporter
This small software reads some temperature/humidity data from a serial
USB device before exposing the data using the Prometheus file format.
Note: you'll have to use Nginx or another webserver to expose the prometheus file to the web.
## Usage
```sh
./temp-prometheus USB-DEV PROMETHEUS-FILE
```

9
default.nix Normal file
View File

@ -0,0 +1,9 @@
{ pkgs ? import <nixpkgs> {}}:
pkgs.stdenv.mkDerivation {
pname = "temp-prometheus";
version = "1.0";
src = ./.;
nativeBuildInputs = [ pkgs.rustc ];
makeFlags = [ "PREFIX=$(out)" ];
}

74
main.rs Normal file
View File

@ -0,0 +1,74 @@
use std::fs::File;
use std::io::{BufReader, BufRead, Write};
use std::sync::{Arc,Mutex};
use std::thread;
struct Metrics {
humidity: String,
temperature: String
}
/*
We'll have two threads:
- One in charge of parsing the CLI args, then in charge of parsing the
data coming from the serial interface.
- Another one in charge of writing the results in the prometheus
format on the disk every 30 seconds.
*/
fn main() -> std::io::Result<()> {
let dev = std::env::args().nth(1).expect("Missing USB-DEV");
let prometheus_file_path = std::env::args().nth(2).expect("Missing LISTEN-ADDR");
let file = File::open(dev)?;
let mut buf_reader = BufReader::new(file);
let mut buffer = String::with_capacity(12);
let metrics = Metrics{
humidity: String::from("0"),
temperature: String::from("0")
};
let metrics = Mutex::new(metrics);
let metrics = Arc::new(metrics);
let thread_metrics = metrics.clone();
thread::spawn(move || {
loop {
{
match File::create(prometheus_file_path.to_owned()) {
Ok(mut file) => {
if let Ok(m) = thread_metrics.lock() {
let prom_str = format!("officetemp_humidity {}\nofficetemp_temperature {}\n", m.humidity, m.temperature);
match file.write_all(prom_str.as_bytes()) {
Ok(()) => (),
Err(err) => {
eprintln!("Cannot write to {}: {}", prometheus_file_path, err);
}
};
}
},
Err(err) => {
eprintln!("Cannot write to {}: {}", prometheus_file_path, err);
}
};
}
thread::sleep(std::time::Duration::from_secs(30));
}
});
let thread_metrics = metrics.clone();
loop {
match buf_reader.read_line(&mut buffer) {
Ok(result) => {
if result == 12 {
if let Ok(mut m) = thread_metrics.lock() {
let vec: Vec<&str> = buffer.split(";").collect();
m.humidity = vec[0].to_string();
m.temperature = vec[1].to_string();
buffer.clear();
}
}
},
Err(_) => ()
}
}
}