From: Greg Burri Date: Sun, 3 Nov 2024 00:30:01 +0000 (+0100) Subject: Initial commit X-Git-Url: http://git.euphorik.ch/index.cgi?a=commitdiff_plain;h=aca0f76a7def77d8e60615479d2c9d3472cd3178;p=rpi_keep_alive.git Initial commit --- aca0f76a7def77d8e60615479d2c9d3472cd3178 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9a5d03d --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +/target +config.ron +Cargo.lock +deploy-to-ek.nu diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..2a692d9 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "rpi_keep_alive" +version = "0.1.0" +authors = ["Greg Burri "] +edition = "2021" + +[dependencies] +rand = "0.8" + +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" +ron = "0.8" + +ping = "0.5" + +anyhow = "1" + +[profile.release] +codegen-units = 1 +lto = true +panic = 'abort' diff --git a/deploy.nu b/deploy.nu new file mode 100644 index 0000000..a30499b --- /dev/null +++ b/deploy.nu @@ -0,0 +1,35 @@ +# 'zigbuild' is needed to build for target 'x86_64-unknown-linux-gnu' on linux: +# https://github.com/rust-cross/cargo-zigbuild + +def main [host: string, destination: string, ssh_key: path] { + let ssh_args = [-i $ssh_key $host] + let scp_args = [-r -i $ssh_key] + let target = "x86_64-unknown-linux-gnu" + let app_name = "rpi_keep_alive" + let build = "release" # "debug" or "release". + + def invoke_ssh [command: string] { + let args = $ssh_args ++ $command + print $"Executing: ssh ($args)" + ssh ...$args + } + + def copy_ssh [source: string, destination: string] { + let args = $scp_args ++ [$source $"($host):($destination)"] + print $"Executing: scp ($args)" + scp ...$args + } + + # Don't know how to dynamically pass variable arguments. + if $build == "release" { + cargo zigbuild --target $target --release + } else { + cargo zigbuild --target $target + } + + # invoke_ssh $"systemctl stop ($app_name)" + copy_ssh ./target/($target)/($build)/($app_name) $destination + invoke_ssh $"chmod u+x ($destination)/($app_name)" + # invoke_ssh $"systemctl start ($app_name)" + print "Deployment finished" +} \ No newline at end of file diff --git a/src/config.rs b/src/config.rs new file mode 100644 index 0000000..09d81dd --- /dev/null +++ b/src/config.rs @@ -0,0 +1,36 @@ +use std::{fs::File, time::Duration}; + +use anyhow::Result; +use ron::{ + de::from_reader, + ser::{to_writer_pretty, PrettyConfig}, +}; +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Deserialize, Serialize)] +pub struct Config { + pub address: String, + pub duration: Duration, +} + +impl Config { + pub fn default() -> Self { + Config { + address: "192.168.2.1".to_string(), + duration: Duration::from_secs(60), + } + } + + pub fn read(file_path: &str) -> Result { + match File::open(file_path) { + Ok(file) => from_reader(file).map_err(|e| e.into()), + // The file doesn't exit -> create it with default values. + Err(_) => { + let file = File::create(file_path)?; + let default_config = Config::default(); + to_writer_pretty(file, &default_config, PrettyConfig::new())?; + Ok(default_config) + } + } + } +} diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..6d877bb --- /dev/null +++ b/src/main.rs @@ -0,0 +1,45 @@ +use std::{ + fmt, + net::{IpAddr, Ipv4Addr, UdpSocket}, + str::FromStr, + thread, + time::{self, Duration}, +}; + +use anyhow::Result; +use ping::rawsock::ping; + +use crate::config::Config; + +mod config; + +const FILE_CONF: &str = "config.ron"; +const PING_TIMEOUT: Duration = Duration::from_secs(5); + +fn main() -> Result<()> { + println!("Raspberry Keep Alive"); + + let config = Config::read(FILE_CONF)?; + let ip_addr = IpAddr::V4(Ipv4Addr::from_str(&config.address)?); + + println!("Configuration: {:?}", config); + + loop { + let time_beginning_loop = time::Instant::now(); + + println!("Sending a ping to {}", config.address); + + if let Err(error) = ping(ip_addr, Some(PING_TIMEOUT), None, None, None, None) { + println!("Error during ping: {:?}", error); + } + + // println!("Time: {:?}", time::Instant::now() - time_beginning_loop); + + let elapsed = time::Instant::now() - time_beginning_loop; + + if elapsed < config.duration { + let to_wait = config.duration - elapsed; + thread::sleep(to_wait); + } + } +}