implement wait feature in ssh-cli
All checks were successful
Build Container / Build Container (push) Successful in 4m16s

This commit is contained in:
lilly 2026-07-19 20:47:27 +02:00
commit 7c64d57eb5
Signed by: lilly
SSH key fingerprint: SHA256:y9T5GFw2A20WVklhetIxG1+kcg/Ce0shnQmbu1LQ37g
4 changed files with 82 additions and 45 deletions

67
ssh-cli/Cargo.lock generated
View file

@ -152,7 +152,7 @@ checksum = "1ac70aa55017e108007fbaf5aa0f54b021c98f92ff8af59d42eda9da96e3dd4f"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn 2.0.119",
] ]
[[package]] [[package]]
@ -562,7 +562,7 @@ dependencies = [
"quote", "quote",
"rustc_version", "rustc_version",
"simd_cesu8", "simd_cesu8",
"syn", "syn 2.0.119",
] ]
[[package]] [[package]]
@ -581,7 +581,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264" checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264"
dependencies = [ dependencies = [
"quote", "quote",
"syn", "syn 2.0.119",
] ]
[[package]] [[package]]
@ -708,9 +708,9 @@ dependencies = [
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.106" version = "1.0.107"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9"
dependencies = [ dependencies = [
"unicode-ident", "unicode-ident",
] ]
@ -774,9 +774,9 @@ dependencies = [
[[package]] [[package]]
name = "quote" name = "quote"
version = "1.0.46" version = "1.0.47"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dfbc457d0c7a0759a614551b11a6409e5951f6c7537be1f1b7682b9ae9230368" checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
] ]
@ -1012,9 +1012,9 @@ checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd"
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.228" version = "1.0.229"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba"
dependencies = [ dependencies = [
"serde_core", "serde_core",
"serde_derive", "serde_derive",
@ -1022,22 +1022,22 @@ dependencies = [
[[package]] [[package]]
name = "serde_core" name = "serde_core"
version = "1.0.228" version = "1.0.229"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48"
dependencies = [ dependencies = [
"serde_derive", "serde_derive",
] ]
[[package]] [[package]]
name = "serde_derive" name = "serde_derive"
version = "1.0.228" version = "1.0.229"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn 3.0.0",
] ]
[[package]] [[package]]
@ -1152,6 +1152,17 @@ dependencies = [
"unicode-ident", "unicode-ident",
] ]
[[package]]
name = "syn"
version = "3.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2fac314a64dc9a36e61a9eb4261a5e9bbfbc922b27e518af97bc32b926cf967"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]] [[package]]
name = "sync_wrapper" name = "sync_wrapper"
version = "1.0.2" version = "1.0.2"
@ -1169,7 +1180,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn 2.0.119",
] ]
[[package]] [[package]]
@ -1195,22 +1206,22 @@ dependencies = [
[[package]] [[package]]
name = "thiserror" name = "thiserror"
version = "2.0.18" version = "2.0.19"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" checksum = "09a43598840e33d5b0331f38c5e30d13bb11c11210a4b58f0d9b18a5a5eefcd9"
dependencies = [ dependencies = [
"thiserror-impl", "thiserror-impl",
] ]
[[package]] [[package]]
name = "thiserror-impl" name = "thiserror-impl"
version = "2.0.18" version = "2.0.19"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" checksum = "43cbfe0cf76104d42a574802844187e84a305e531ed54455f11fbde0f10541cd"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn 3.0.0",
] ]
[[package]] [[package]]
@ -1264,13 +1275,13 @@ dependencies = [
[[package]] [[package]]
name = "tokio-macros" name = "tokio-macros"
version = "2.7.0" version = "2.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496" checksum = "6328af13490e73a9b4694030fafd93f8c8c6a9dede33e821c3fc63eddf8042ba"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn 2.0.119",
] ]
[[package]] [[package]]
@ -1360,7 +1371,7 @@ checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn 2.0.119",
] ]
[[package]] [[package]]
@ -1507,7 +1518,7 @@ dependencies = [
"bumpalo", "bumpalo",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn 2.0.119",
"wasm-bindgen-shared", "wasm-bindgen-shared",
] ]
@ -1700,7 +1711,7 @@ checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn 2.0.119",
"synstructure", "synstructure",
] ]
@ -1721,7 +1732,7 @@ checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn 2.0.119",
"synstructure", "synstructure",
] ]
@ -1761,7 +1772,7 @@ checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn 2.0.119",
] ]
[[package]] [[package]]

View file

@ -8,6 +8,6 @@ eyre = "0.6.12"
reqwest = { version = "0.13.4", features = ["json"] } reqwest = { version = "0.13.4", features = ["json"] }
serde = { version = "1.0.228", features = ["derive"] } serde = { version = "1.0.228", features = ["derive"] }
simple-eyre = "0.3.1" simple-eyre = "0.3.1"
tokio = { version = "1.53.0", features = ["macros", "rt"] } tokio = { version = "1.53.0", features = ["macros", "rt", "time"] }
tracing = "0.1.44" tracing = "0.1.44"
tracing-subscriber = "0.3.23" tracing-subscriber = "0.3.23"

View file

@ -15,9 +15,9 @@ pub struct ApiLockStatus {
#[serde(default)] #[serde(default)]
pub is_low_batteray: bool, pub is_low_batteray: bool,
pub is_error_jammed: bool, pub is_error_jammed: bool,
pub lock_target_level: String, pub lock_target_level: LockTargetLevel,
pub lock_state: String, pub lock_state: LockState,
pub activity_state: String, pub activity_state: LockActivityState,
} }
#[allow(unused)] #[allow(unused)]

View file

@ -13,13 +13,13 @@ mod api_client;
mod api_models; mod api_models;
mod cli; mod cli;
use std::process::exit; use std::{process::exit, time::Duration};
use eyre::eyre; use eyre::eyre;
use crate::{ use crate::{
api_client::ApiClient, api_client::ApiClient,
api_models::{ApiLock, DesiredLockState}, api_models::{ApiLock, DesiredLockState, LockState},
}; };
#[tokio::main(flavor = "current_thread")] #[tokio::main(flavor = "current_thread")]
@ -71,9 +71,10 @@ async fn main() -> eyre::Result<()> {
api.operate_lock(&lock.id, DesiredLockState::CLOSED).await?; api.operate_lock(&lock.id, DesiredLockState::CLOSED).await?;
if wait_until_done { if wait_until_done {
tracing::warn!( wait_for_lock_state(&api, &lock_name, LockState::LOCKED).await?;
"wait feature is not yet implemented. lock should be turning now >~<" println!("Lock is now closed. Enjoy <3");
); } else {
println!("Lock is now closing. Enjoy <3");
} }
exit(0); exit(0);
@ -89,9 +90,10 @@ async fn main() -> eyre::Result<()> {
api.operate_lock(&lock.id, DesiredLockState::OPEN).await?; api.operate_lock(&lock.id, DesiredLockState::OPEN).await?;
if wait_until_done { if wait_until_done {
tracing::warn!( wait_for_lock_state(&api, &lock_name, LockState::UNLOCKED).await?;
"wait feature is not yet implemented. lock should be turning now >~<" println!("Lock is now opened. Enjoy <3");
); } else {
println!("Lock is now opening. Enjoy <3");
} }
exit(0); exit(0);
@ -111,9 +113,9 @@ async fn main() -> eyre::Result<()> {
if i_lock.status.is_error_jammed { if i_lock.status.is_error_jammed {
println!(" !!! Lock is jammed !!!"); println!(" !!! Lock is jammed !!!");
} }
println!(" State: {}", i_lock.status.lock_state); println!(" State: {:?}", i_lock.status.lock_state);
println!(" Desired State: {}", i_lock.status.lock_target_level); println!(" Desired State: {:?}", i_lock.status.lock_target_level);
println!(" Acitivty: {}", i_lock.status.activity_state); println!(" Acitivty: {:?}", i_lock.status.activity_state);
println!(); println!();
} }
@ -124,13 +126,37 @@ async fn main() -> eyre::Result<()> {
async fn find_lock(api: &ApiClient, name: &str) -> eyre::Result<ApiLock> { async fn find_lock(api: &ApiClient, name: &str) -> eyre::Result<ApiLock> {
let locks = api.fetch_locks().await?; let locks = api.fetch_locks().await?;
tracing::debug!("Comparing locks from API for one with name {name:?}"); tracing::trace!("Comparing locks from API for one with name {name:?}");
let lock = locks let lock = locks
.into_iter() .into_iter()
.find(|i_lock| i_lock.name.eq_ignore_ascii_case(&name)) .find(|i_lock| i_lock.name.eq_ignore_ascii_case(&name))
.ok_or_else(|| { .ok_or_else(|| {
eyre!("No lock named {name:?} exists. See \"list-locks\" for a list of valid locks.") eyre!("No lock named {name:?} exists. See \"list-locks\" for a list of valid locks.")
})?; })?;
tracing::debug!(lock = ?lock,"Identified lock with name matching {name:?}"); tracing::trace!(lock = ?lock, "Identified lock with name matching {name:?}");
Ok(lock) Ok(lock)
} }
async fn wait_for_lock_state(
api: &ApiClient,
lock_name: &str,
desired_state: LockState,
) -> eyre::Result<()> {
tokio::time::sleep(Duration::from_millis(200)).await;
let lock = find_lock(&api, &lock_name).await?;
let mut interval = tokio::time::interval(Duration::from_millis(500));
let mut last_status = lock.status;
while last_status.lock_state != desired_state {
interval.tick().await;
let lock = find_lock(&api, &lock_name).await?;
if lock.status != last_status {
println!(
"Lock state changed to {:?} (activity={:?})",
lock.status.lock_state, lock.status.activity_state
);
last_status = lock.status;
}
}
Ok(())
}