improve power calculation
This commit is contained in:
parent
a90b1fa6c6
commit
aefe383504
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -139,7 +139,7 @@ checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "energyPulseCounter"
|
name = "energyPulseCounter"
|
||||||
version = "1.0.1"
|
version = "1.0.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"crossbeam",
|
"crossbeam",
|
||||||
"mqtt-client",
|
"mqtt-client",
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "energyPulseCounter"
|
name = "energyPulseCounter"
|
||||||
version = "1.0.1"
|
version = "1.0.2"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|||||||
7
build.sh
Normal file
7
build.sh
Normal file
@ -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
|
||||||
@ -1,8 +1,9 @@
|
|||||||
use crossbeam::atomic::AtomicCell;
|
use crossbeam::atomic::AtomicCell;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use rppal::gpio::{Gpio, Trigger};
|
use rppal::gpio::{Gpio, Trigger};
|
||||||
|
use std::time::{SystemTime, UNIX_EPOCH};
|
||||||
|
|
||||||
pub fn pulse_counter(pulses: Arc<AtomicCell<u32>>) {
|
pub fn pulse_counter(pulses: Arc<AtomicCell<u32>>, last_time: Arc<AtomicCell<Option<u128>>>, power: Arc<AtomicCell<f64>>) {
|
||||||
let gpio = Gpio::new().expect("failt to get gpio driver");
|
let gpio = Gpio::new().expect("failt to get gpio driver");
|
||||||
let mut pulse_gpio = gpio.get(23)
|
let mut pulse_gpio = gpio.get(23)
|
||||||
.expect("failt to get gpio pin")
|
.expect("failt to get gpio pin")
|
||||||
@ -13,7 +14,18 @@ pub fn pulse_counter(pulses: Arc<AtomicCell<u32>>) {
|
|||||||
loop {
|
loop {
|
||||||
match pulse_gpio.poll_interrupt(true, None) {
|
match pulse_gpio.poll_interrupt(true, None) {
|
||||||
Ok(_) => {
|
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")
|
Err(_) => panic!("failt to pull interupt")
|
||||||
}
|
}
|
||||||
|
|||||||
17
src/main.rs
17
src/main.rs
@ -5,7 +5,7 @@ use crossbeam::atomic::AtomicCell;
|
|||||||
|
|
||||||
mod publischer;
|
mod publischer;
|
||||||
mod counter;
|
mod counter;
|
||||||
use publischer::PulseTx;
|
use publischer::{PulseTx, Data};
|
||||||
use counter::pulse_counter;
|
use counter::pulse_counter;
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
@ -53,22 +53,31 @@ fn main() {
|
|||||||
Ok(conf) =>{
|
Ok(conf) =>{
|
||||||
|
|
||||||
let pulses: Arc<AtomicCell<u32>> = Arc::new(AtomicCell::new(0));
|
let pulses: Arc<AtomicCell<u32>> = Arc::new(AtomicCell::new(0));
|
||||||
|
let last_pulse_time: Arc<AtomicCell<Option<u128>>> = Arc::new(AtomicCell::new(None));
|
||||||
|
let avg_power: Arc<AtomicCell<f64>> = Arc::new(AtomicCell::new(0.0));
|
||||||
|
|
||||||
let pulses_counter = pulses.clone();
|
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()
|
let _ = thread::Builder::new()
|
||||||
.name("counter".to_string())
|
.name("counter".to_string())
|
||||||
.spawn(move || {
|
.spawn(move || {
|
||||||
pulse_counter(pulses_counter);
|
pulse_counter(pulses_counter, last_pulse_time_counter, avg_power_counter);
|
||||||
});
|
});
|
||||||
|
|
||||||
mqtt_client::run::<Arc<AtomicCell<u32>>, PulseTx>(
|
let config: Data = Data {
|
||||||
|
pulses: pulses.clone(),
|
||||||
|
avg_power: avg_power.clone(),
|
||||||
|
};
|
||||||
|
|
||||||
|
mqtt_client::run::<Data, PulseTx>(
|
||||||
conf.mqtt.host,
|
conf.mqtt.host,
|
||||||
conf.mqtt.port,
|
conf.mqtt.port,
|
||||||
conf.mqtt.client,
|
conf.mqtt.client,
|
||||||
conf.mqtt.user,
|
conf.mqtt.user,
|
||||||
conf.mqtt.pass,
|
conf.mqtt.pass,
|
||||||
pulses.clone()
|
config
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
Err(_) => {}
|
Err(_) => {}
|
||||||
|
|||||||
@ -6,9 +6,14 @@ use crossbeam::atomic::AtomicCell;
|
|||||||
use mqtt_client::{MqttMessage, Sender, Receiver, QoS};
|
use mqtt_client::{MqttMessage, Sender, Receiver, QoS};
|
||||||
use mqtt_client::mqtt_client;
|
use mqtt_client::mqtt_client;
|
||||||
|
|
||||||
|
pub struct Data {
|
||||||
|
pub pulses: Arc<AtomicCell<u32>>,
|
||||||
|
pub avg_power: Arc<AtomicCell<f64>>
|
||||||
|
}
|
||||||
|
|
||||||
pub struct PulseTx {
|
pub struct PulseTx {
|
||||||
tx: Sender<mqtt_client::MqttMessage>,
|
tx: Sender<mqtt_client::MqttMessage>,
|
||||||
pulses: Arc<AtomicCell<u32>>
|
pulses: Data
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -28,7 +33,8 @@ impl PulseTx {
|
|||||||
Err(e) =>
|
Err(e) =>
|
||||||
println!("ERROR: message_in: clock/time/minute has invalid payload ({:?})", e),
|
println!("ERROR: message_in: clock/time/minute has invalid payload ({:?})", e),
|
||||||
Ok(_) => {
|
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 {
|
self.tx({ mqtt_client::MqttMessage {
|
||||||
topic: String::from("/kees/energy/metalbox/pulses"),
|
topic: String::from("/kees/energy/metalbox/pulses"),
|
||||||
payload: pulses.to_string(),
|
payload: pulses.to_string(),
|
||||||
@ -37,13 +43,13 @@ impl PulseTx {
|
|||||||
}});
|
}});
|
||||||
self.tx({ mqtt_client::MqttMessage {
|
self.tx({ mqtt_client::MqttMessage {
|
||||||
topic: String::from("/kees/energy/metalbox/watt"),
|
topic: String::from("/kees/energy/metalbox/watt"),
|
||||||
payload: (pulses * 60).to_string(),
|
payload: power.to_string(),
|
||||||
retain: false,
|
retain: false,
|
||||||
qos: mqtt_client::QoS::AtMostOnce,
|
qos: mqtt_client::QoS::AtMostOnce,
|
||||||
}});
|
}});
|
||||||
self.tx({ mqtt_client::MqttMessage {
|
self.tx({ mqtt_client::MqttMessage {
|
||||||
topic: String::from("/kees/energy/metalbox/data"),
|
topic: String::from("/kees/energy/metalbox/data"),
|
||||||
payload: format!("{{\"pulses\":{pulses},\"watt\":{}}}", pulses * 60),
|
payload: format!("{{\"pulses\":{pulses},\"watt\":{power}}}"),
|
||||||
retain: false,
|
retain: false,
|
||||||
qos: mqtt_client::QoS::AtMostOnce,
|
qos: mqtt_client::QoS::AtMostOnce,
|
||||||
}});
|
}});
|
||||||
@ -55,8 +61,8 @@ impl PulseTx {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl mqtt_client::MqttTool<Arc<AtomicCell<u32>>> for PulseTx {
|
impl mqtt_client::MqttTool<Data> for PulseTx {
|
||||||
fn new(client: mqtt_client::Client, tx: Sender<mqtt_client::MqttMessage>, pulses: Arc<AtomicCell<u32>>) -> PulseTx {
|
fn new(client: mqtt_client::Client, tx: Sender<mqtt_client::MqttMessage>, pulses: Data) -> PulseTx {
|
||||||
|
|
||||||
match client.subscribe("clock/time/minute", QoS::AtMostOnce) {
|
match client.subscribe("clock/time/minute", QoS::AtMostOnce) {
|
||||||
Err(e) =>
|
Err(e) =>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user