|
use gpio_cdev::{Chip, LineRequestFlags}; |
|
use reqwest::blocking::Client; |
|
use serde_json::json; |
|
use std::thread::sleep; |
|
use std::time::{Duration, Instant}; |
|
|
|
// Hue API base URL and credentials |
|
const HUE_API_URL: &str = "http://192.168.0.243/api/c7Gjkq902f8j12g10AfgG39GBj8/lights/5/state"; |
|
|
|
// Function to send a request to the Hue API to change bulb color |
|
fn send_hue_request(on: bool) -> Result<(), Box<dyn std::error::Error>> { |
|
let client = Client::new(); |
|
let color = if on { |
|
json!({ "bri": 254, "hue": 0, "sat": 254, "on": true }) // Red when active |
|
} else { |
|
json!({ "bri": 254, "hue": 46920, "sat": 254, "on": true }) // Purple when inactive |
|
}; |
|
|
|
let response = client |
|
.put(HUE_API_URL) |
|
.json(&color) |
|
.send()?; |
|
|
|
if response.status().is_success() { |
|
println!("Successfully sent request to change light."); |
|
} else { |
|
eprintln!("Failed to change light: {}", response.status()); |
|
} |
|
|
|
Ok(()) |
|
} |
|
|
|
fn main() -> Result<(), Box<dyn std::error::Error>> { |
|
// Open the GPIO chip |
|
let mut chip = Chip::new("/dev/gpiochip0")?; |
|
// Request GPIO line 23 (corresponding to XGPIOA[23] aka GPIO16) as input |
|
let input_line_handle = chip |
|
.get_line(23)? |
|
.request(LineRequestFlags::INPUT, 0, "read-input")?; |
|
// LED output line: GPIO 15 (XGPIOA[15]) as output |
|
let output_line_handle = chip |
|
.get_line(15)? |
|
.request(LineRequestFlags::OUTPUT, 0, "write-output")?; |
|
|
|
println!("Listening for GPIO pin state changes..."); |
|
|
|
let mut last_state = input_line_handle.get_value()?; |
|
let debounce_time = Duration::from_millis(50); // Adjust this if needed |
|
let mut last_change = Instant::now(); // To debounce |
|
|
|
loop { |
|
// Read the current state of the GPIO pin |
|
match input_line_handle.get_value() { |
|
Ok(current_state) => { |
|
// Check for state change with basic debouncing |
|
if current_state != last_state && last_change.elapsed() > debounce_time { |
|
last_change = Instant::now(); // Reset the debounce timer |
|
|
|
if current_state == 1 { |
|
println!("Switch is ON (sending red request)"); |
|
if let Err(e) = send_hue_request(true) { |
|
eprintln!("Failed to send request: {:?}", e); |
|
} |
|
} else { |
|
println!("Switch is OFF (sending purple request)"); |
|
if let Err(e) = send_hue_request(false) { |
|
eprintln!("Failed to send request: {:?}", e); |
|
} |
|
} |
|
|
|
// Update the last known state |
|
last_state = current_state; |
|
|
|
// Toggle the LED output line |
|
output_line_handle.set_value(current_state)?; |
|
} |
|
} |
|
Err(e) => { |
|
eprintln!("Error reading GPIO value: {:?}", e); |
|
} |
|
} |
|
|
|
// Sleep to avoid busy-waiting (this is also part of the debouncing mechanism) |
|
sleep(Duration::from_millis(100)); |
|
} |
|
} |