forked from moke/spaceapi-tuerpie-nix
sync with dezentrale upstream (#1)
* Next (#1) * switched from interrupt to a simple loop This raspberry pi isn't doing anything all day logn. So why should i noot do it like that? * removed unused enviroment variables --------- Co-authored-by: Moritz Kempe <moritzkempe@mailbox.org> * Integration (#2) * integrated spaceapi-client * added push_door_status blocking --------- Co-authored-by: Moritz Kempe <moritzkempe@mailbox.org> --------- Co-authored-by: tuxa <69870860+mrtuxa@users.noreply.github.com>
This commit is contained in:
parent
75f3e20954
commit
29b2014c80
File diff suppressed because it is too large
Load Diff
|
@ -7,5 +7,6 @@ edition = "2021"
|
|||
|
||||
[dependencies]
|
||||
dotenv = "0.15.0"
|
||||
dotenv_codegen = "0.15.0"
|
||||
futures = "0.3.28"
|
||||
rppal = "0.14.1"
|
||||
spaceapi-dezentrale-client = { git = "https://github.com/dezentrale/spaceapi-rs.git", package = "spaceapi-dezentrale-client", branch = "main" }
|
||||
|
|
|
@ -4,12 +4,9 @@ Feeding our SpaceAPI with Data from our entrance door.
|
|||
|
||||
## Setup
|
||||
|
||||
Please change `DOOR_PIN`, `OPEN_SPACE`, `CLOSE_SPACE` accordingly.
|
||||
Please change `DOOR_PIN` accordingly.
|
||||
|
||||
`DOOR_PIN` defaults to a closed door, when HIGH.
|
||||
|
||||
`OPEN_SPACE` and `CLOSE_SPACE` are scripts, that get launched when the corresponding event starts. (They have to inform
|
||||
the SPACE_API server about the new status)
|
||||
|
||||
You need to provide the environment variables
|
||||
`SPACEAPI_URL` and `API_KEY`. They will be passed on to the scripts.
|
||||
`SPACEAPI_URL` and `API_KEY`.
|
||||
|
|
84
src/main.rs
84
src/main.rs
|
@ -1,54 +1,66 @@
|
|||
use std::env;
|
||||
use std::process::Command;
|
||||
use std::thread::sleep;
|
||||
use std::time::Duration;
|
||||
|
||||
use rppal::gpio::{Gpio, Level};
|
||||
use rppal::gpio::Trigger;
|
||||
use futures::executor::block_on;
|
||||
use rppal::gpio::{Gpio, InputPin, Level};
|
||||
use spaceapi_dezentrale_client::Client;
|
||||
|
||||
// set your scripts for opening and closing the space here
|
||||
static OPEN_SPACE: &str = "OpenSpace";
|
||||
static CLOSE_SPACE: &str = "CloseSpace";
|
||||
static DOOR_PIN: u8 = 13;
|
||||
static RECHECK_DELAY: u64 = 30; // ins seconds
|
||||
static DOOR_PIN: u8 = 27;
|
||||
// delays in seconds
|
||||
static RECHECK_DELAY: u64 = 5;
|
||||
static ANTI_BOUNCE_DELAY: u64 = 1;
|
||||
|
||||
fn main() {
|
||||
// setup
|
||||
let gpio = Gpio::new().unwrap();
|
||||
let mut pin = gpio.get(DOOR_PIN).unwrap().into_input();
|
||||
let pin = gpio.get(DOOR_PIN).unwrap().into_input();
|
||||
|
||||
// Set the trigger for the interrupt
|
||||
pin.set_interrupt(Trigger::Both).unwrap();
|
||||
let spaceapi_client = spaceapi_dezentrale_client::ClientBuilder::new()
|
||||
.api_key(&env::var("API_KEY").unwrap())
|
||||
.base_url(&env::var("SPACEAPI_URL").unwrap())
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
// get initial door status
|
||||
let mut door_status_old = check_door(&pin);
|
||||
block_on(push_door_status(&spaceapi_client, door_status_old));
|
||||
|
||||
loop {
|
||||
// reading space status from door
|
||||
let status = pin.poll_interrupt(true, None).unwrap().unwrap();
|
||||
pin.clear_interrupt().unwrap();
|
||||
let door_open = status == Level::Low;
|
||||
println!("GPIO pin {} triggered an interrupt", pin.pin());
|
||||
println!("Space is online = {}", door_open);
|
||||
|
||||
println!("GPIO pin {} was triggered", DOOR_PIN);
|
||||
push_door_status(door_open);
|
||||
|
||||
// make it more reliable and robust
|
||||
// maybe not the best solution but the pi isn't doing anything else
|
||||
println!("Waiting {} secs to read the door status", RECHECK_DELAY);
|
||||
sleep(Duration::from_secs(RECHECK_DELAY));
|
||||
// check if the door has still the same status, if not push the new status to the api
|
||||
let new_door_open = pin.is_low();
|
||||
if door_open != new_door_open
|
||||
{
|
||||
push_door_status(new_door_open)
|
||||
|
||||
// read new status
|
||||
let door_status_new = check_door(&pin);
|
||||
println!("Read {}", door_status_new);
|
||||
|
||||
// if the new status isn't the old one
|
||||
if door_status_old != door_status_new {
|
||||
// wait for the switch to stop bouncing around
|
||||
println!("Waiting {} secs for recheck", ANTI_BOUNCE_DELAY);
|
||||
sleep(Duration::from_secs(ANTI_BOUNCE_DELAY));
|
||||
// the new read status is still the same after a minute then push it to the api
|
||||
if door_status_new == check_door(&pin)
|
||||
{
|
||||
println!("Check passed, applying new status");
|
||||
println!("Pushing space status: Open = {}", door_status_new);
|
||||
block_on(push_door_status(&spaceapi_client, door_status_new));
|
||||
println!("Saving space status: {}", door_status_new);
|
||||
door_status_old = door_status_new;
|
||||
} else {
|
||||
println!("Check wasn't successfully")
|
||||
}
|
||||
}
|
||||
pin.set_interrupt(Trigger::Both).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
fn push_door_status(open: bool) {
|
||||
let mut command = Command::new("sh");
|
||||
command
|
||||
.arg("-c")
|
||||
.arg(format!("SPACEAPI_URL={}", env::var("SPACEAPI_URL").unwrap()))
|
||||
.arg(format!("API_KEY={}", env::var("API_KEY").unwrap()));
|
||||
if open { command.arg(OPEN_SPACE); } else { command.arg(CLOSE_SPACE); }
|
||||
command.spawn()
|
||||
.expect("Failed to execute process. Push to api failed");
|
||||
fn check_door(pin: &InputPin) -> bool {
|
||||
// reading space status from door
|
||||
pin.read() == Level::Low
|
||||
}
|
||||
|
||||
async fn push_door_status(spaceapi: &Client, open: bool) {
|
||||
if open { spaceapi.open().await.unwrap() } else { spaceapi.close().await.unwrap() }
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue