diff --git a/Cargo.lock b/Cargo.lock index ba855f4..bd208ae 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -139,7 +139,7 @@ checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] name = "energyPulseCounter" -version = "1.0.1" +version = "1.0.2" dependencies = [ "crossbeam", "mqtt-client", diff --git a/Cargo.toml b/Cargo.toml index 31894b4..752f44a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "energyPulseCounter" -version = "1.0.1" +version = "1.0.2" edition = "2021" [dependencies] diff --git a/build.sh b/build.sh new file mode 100644 index 0000000..eb690e2 --- /dev/null +++ b/build.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +cross build --target aarch64-unknown-linux-gnu --release +# cargo build --release + +cp target/aarch64-unknown-linux-gnu/release/energyPulseCounter energyPulseCounter-aarch64 +# cp target/release/energyPulseCounter energyPulseCounter-x86_64 diff --git a/src/counter.rs b/src/counter.rs index 82c2033..b2d567b 100644 --- a/src/counter.rs +++ b/src/counter.rs @@ -1,8 +1,9 @@ use crossbeam::atomic::AtomicCell; use std::sync::Arc; use rppal::gpio::{Gpio, Trigger}; +use std::time::{SystemTime, UNIX_EPOCH}; -pub fn pulse_counter(pulses: Arc>) { +pub fn pulse_counter(pulses: Arc>, last_time: Arc>>, power: Arc>) { let gpio = Gpio::new().expect("failt to get gpio driver"); let mut pulse_gpio = gpio.get(23) .expect("failt to get gpio pin") @@ -13,7 +14,18 @@ pub fn pulse_counter(pulses: Arc>) { loop { match pulse_gpio.poll_interrupt(true, None) { Ok(_) => { - pulses.fetch_add(1); + let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_millis(); + let count = pulses.fetch_add(1); + match last_time.swap(Some(now)) { + Some(last) => { + // time between pulses in hours + let time = f64::from(u32::try_from(now - last).unwrap()) / (60.0 * 60.0 * 1000.0); + let watt = 1.0 / time; + let avg = power.load(); + power.store(avg + (watt-avg)/f64::from(count)); + }, + None => {} + } }, Err(_) => panic!("failt to pull interupt") } diff --git a/src/main.rs b/src/main.rs index f0e2690..9cf7211 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,7 +5,7 @@ use crossbeam::atomic::AtomicCell; mod publischer; mod counter; -use publischer::PulseTx; +use publischer::{PulseTx, Data}; use counter::pulse_counter; #[derive(Deserialize)] @@ -53,22 +53,31 @@ fn main() { Ok(conf) =>{ let pulses: Arc> = Arc::new(AtomicCell::new(0)); + let last_pulse_time: Arc>> = Arc::new(AtomicCell::new(None)); + let avg_power: Arc> = Arc::new(AtomicCell::new(0.0)); let pulses_counter = pulses.clone(); + let last_pulse_time_counter = last_pulse_time.clone(); + let avg_power_counter = avg_power.clone(); let _ = thread::Builder::new() .name("counter".to_string()) .spawn(move || { - pulse_counter(pulses_counter); + pulse_counter(pulses_counter, last_pulse_time_counter, avg_power_counter); }); - mqtt_client::run::>, PulseTx>( + let config: Data = Data { + pulses: pulses.clone(), + avg_power: avg_power.clone(), + }; + + mqtt_client::run::( conf.mqtt.host, conf.mqtt.port, conf.mqtt.client, conf.mqtt.user, conf.mqtt.pass, - pulses.clone() + config ); }, Err(_) => {} diff --git a/src/publischer.rs b/src/publischer.rs index 70b3f6e..761d3ad 100644 --- a/src/publischer.rs +++ b/src/publischer.rs @@ -6,9 +6,14 @@ use crossbeam::atomic::AtomicCell; use mqtt_client::{MqttMessage, Sender, Receiver, QoS}; use mqtt_client::mqtt_client; +pub struct Data { + pub pulses: Arc>, + pub avg_power: Arc> +} + pub struct PulseTx { tx: Sender, - pulses: Arc> + pulses: Data } @@ -28,7 +33,8 @@ impl PulseTx { Err(e) => println!("ERROR: message_in: clock/time/minute has invalid payload ({:?})", e), Ok(_) => { - let pulses = self.pulses.swap(0); + let pulses = self.pulses.pulses.swap(0); + let power = self.pulses.avg_power.swap(0.0); self.tx({ mqtt_client::MqttMessage { topic: String::from("/kees/energy/metalbox/pulses"), payload: pulses.to_string(), @@ -37,13 +43,13 @@ impl PulseTx { }}); self.tx({ mqtt_client::MqttMessage { topic: String::from("/kees/energy/metalbox/watt"), - payload: (pulses * 60).to_string(), + payload: power.to_string(), retain: false, qos: mqtt_client::QoS::AtMostOnce, }}); self.tx({ mqtt_client::MqttMessage { topic: String::from("/kees/energy/metalbox/data"), - payload: format!("{{\"pulses\":{pulses},\"watt\":{}}}", pulses * 60), + payload: format!("{{\"pulses\":{pulses},\"watt\":{power}}}"), retain: false, qos: mqtt_client::QoS::AtMostOnce, }}); @@ -55,8 +61,8 @@ impl PulseTx { } -impl mqtt_client::MqttTool>> for PulseTx { - fn new(client: mqtt_client::Client, tx: Sender, pulses: Arc>) -> PulseTx { +impl mqtt_client::MqttTool for PulseTx { + fn new(client: mqtt_client::Client, tx: Sender, pulses: Data) -> PulseTx { match client.subscribe("clock/time/minute", QoS::AtMostOnce) { Err(e) =>