Add webcam command

main
Elnu 1 year ago
parent 502517cfcb
commit 06578475a6

3
.gitignore vendored

@ -2,4 +2,5 @@
.direnv .direnv
result result
.env .env
*.mp3 *.mp3
frame.jpg

175
Cargo.lock generated

@ -2,6 +2,27 @@
# It is not intended for manual editing. # It is not intended for manual editing.
version = 3 version = 3
[[package]]
name = "CoreFoundation-sys"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0e9889e6db118d49d88d84728d0e964d973a5680befb5f85f55141beea5c20b"
dependencies = [
"libc",
"mach 0.1.2",
]
[[package]]
name = "IOKit-sys"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "99696c398cbaf669d2368076bdb3d627fb0ce51a26899d7c61228c5c0af3bf4a"
dependencies = [
"CoreFoundation-sys",
"libc",
"mach 0.1.2",
]
[[package]] [[package]]
name = "addr2line" name = "addr2line"
version = "0.21.0" version = "0.21.0"
@ -35,7 +56,7 @@ dependencies = [
"alsa-sys", "alsa-sys",
"bitflags 1.3.2", "bitflags 1.3.2",
"libc", "libc",
"nix", "nix 0.23.2",
] ]
[[package]] [[package]]
@ -358,10 +379,10 @@ dependencies = [
"js-sys", "js-sys",
"lazy_static", "lazy_static",
"libc", "libc",
"mach", "mach 0.3.2",
"ndk", "ndk",
"ndk-glue", "ndk-glue",
"nix", "nix 0.23.2",
"oboe", "oboe",
"parking_lot 0.11.2", "parking_lot 0.11.2",
"stdweb", "stdweb",
@ -552,8 +573,11 @@ version = "0.1.0"
dependencies = [ dependencies = [
"dotenv", "dotenv",
"lazy_static", "lazy_static",
"num",
"poise", "poise",
"regex", "regex",
"rscam",
"serialport",
"tokio", "tokio",
"tts_rust", "tts_rust",
] ]
@ -1103,6 +1127,26 @@ dependencies = [
"winapi", "winapi",
] ]
[[package]]
name = "libudev"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78b324152da65df7bb95acfcaab55e3097ceaab02fb19b228a9eb74d55f135e0"
dependencies = [
"libc",
"libudev-sys",
]
[[package]]
name = "libudev-sys"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c8469b4a23b962c1396b9b451dda50ef5b283e8dd309d69033475fa9b334324"
dependencies = [
"libc",
"pkg-config",
]
[[package]] [[package]]
name = "lock_api" name = "lock_api"
version = "0.4.11" version = "0.4.11"
@ -1119,6 +1163,15 @@ version = "0.4.20"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
[[package]]
name = "mach"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2fd13ee2dd61cc82833ba05ade5a30bb3d63f7ced605ef827063c63078302de9"
dependencies = [
"libc",
]
[[package]] [[package]]
name = "mach" name = "mach"
version = "0.3.2" version = "0.3.2"
@ -1128,6 +1181,15 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "mach2"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d0d1830bcd151a6fc4aea1369af235b36c1528fe976b8ff678683c9995eade8"
dependencies = [
"libc",
]
[[package]] [[package]]
name = "memchr" name = "memchr"
version = "2.6.4" version = "2.6.4"
@ -1296,6 +1358,17 @@ dependencies = [
"memoffset 0.6.5", "memoffset 0.6.5",
] ]
[[package]]
name = "nix"
version = "0.26.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b"
dependencies = [
"bitflags 1.3.2",
"cfg-if",
"libc",
]
[[package]] [[package]]
name = "nom" name = "nom"
version = "7.1.3" version = "7.1.3"
@ -1306,6 +1379,40 @@ dependencies = [
"minimal-lexical", "minimal-lexical",
] ]
[[package]]
name = "num"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b05180d69e3da0e530ba2a1dae5110317e49e3b7f3d41be227dc5f92e49ee7af"
dependencies = [
"num-bigint",
"num-complex",
"num-integer",
"num-iter",
"num-rational",
"num-traits",
]
[[package]]
name = "num-bigint"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0"
dependencies = [
"autocfg",
"num-integer",
"num-traits",
]
[[package]]
name = "num-complex"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ba157ca0885411de85d6ca030ba7e2a83a28636056c7c699b07c8b6f7383214"
dependencies = [
"num-traits",
]
[[package]] [[package]]
name = "num-derive" name = "num-derive"
version = "0.3.3" version = "0.3.3"
@ -1317,6 +1424,39 @@ dependencies = [
"syn 1.0.109", "syn 1.0.109",
] ]
[[package]]
name = "num-integer"
version = "0.1.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"
dependencies = [
"autocfg",
"num-traits",
]
[[package]]
name = "num-iter"
version = "0.1.43"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252"
dependencies = [
"autocfg",
"num-integer",
"num-traits",
]
[[package]]
name = "num-rational"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0"
dependencies = [
"autocfg",
"num-bigint",
"num-integer",
"num-traits",
]
[[package]] [[package]]
name = "num-traits" name = "num-traits"
version = "0.2.17" version = "0.2.17"
@ -1819,6 +1959,15 @@ dependencies = [
"minimp3", "minimp3",
] ]
[[package]]
name = "rscam"
version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89056084211cd54924fedf2e2199b906409d1f795cfd8e7e3271061742457018"
dependencies = [
"libc",
]
[[package]] [[package]]
name = "rustc-demangle" name = "rustc-demangle"
version = "0.1.23" version = "0.1.23"
@ -1996,6 +2145,24 @@ dependencies = [
"url", "url",
] ]
[[package]]
name = "serialport"
version = "4.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c32634e2bd4311420caa504404a55fad2131292c485c97014cbed89a5899885f"
dependencies = [
"CoreFoundation-sys",
"IOKit-sys",
"bitflags 1.3.2",
"cfg-if",
"libudev",
"mach2",
"nix 0.26.4",
"regex",
"scopeguard",
"winapi",
]
[[package]] [[package]]
name = "sha-1" name = "sha-1"
version = "0.10.1" version = "0.10.1"
@ -2038,7 +2205,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "31ef6ee280cdefba6d2d0b4b78a84a1c1a3f3a4cec98c2d4231c8bc225de0f25" checksum = "31ef6ee280cdefba6d2d0b4b78a84a1c1a3f3a4cec98c2d4231c8bc225de0f25"
dependencies = [ dependencies = [
"libc", "libc",
"mach", "mach 0.3.2",
"winapi", "winapi",
] ]

@ -8,7 +8,10 @@ edition = "2021"
[dependencies] [dependencies]
dotenv = "0.15.0" dotenv = "0.15.0"
lazy_static = "1.4.0" lazy_static = "1.4.0"
num = "0.4.1"
poise = "0.5.7" poise = "0.5.7"
regex = "1.10.2" regex = "1.10.2"
rscam = "0.5.5"
serialport = "4.2.2"
tokio = { version = "1.33.0", features = ["macros", "signal", "rt-multi-thread"] } tokio = { version = "1.33.0", features = ["macros", "signal", "rt-multi-thread"] }
tts_rust = "0.3.5" tts_rust = "0.3.5"

@ -4,6 +4,7 @@ use poise::{serenity_prelude::{self as serenity, GatewayIntents}, Event, command
use regex::Regex; use regex::Regex;
use tts_rust::{ tts::GTTSClient, languages::Languages }; use tts_rust::{ tts::GTTSClient, languages::Languages };
use lazy_static::lazy_static; use lazy_static::lazy_static;
use std::time::Duration;
type Error = Box<dyn std::error::Error + Send + Sync>; type Error = Box<dyn std::error::Error + Send + Sync>;
type Context<'a> = poise::Context<'a, Data, Error>; type Context<'a> = poise::Context<'a, Data, Error>;
@ -25,6 +26,9 @@ lazy_static! {
tld: "com", tld: "com",
} }
}; };
static ref SERIAL: std::sync::Mutex<Box<dyn serialport::SerialPort>> = serialport::new("/dev/ttyACM0", 115_200)
.timeout(Duration::from_millis(1000))
.open().expect("Failed to open port").into();
} }
async fn event_handler( async fn event_handler(
@ -71,7 +75,7 @@ async fn register(ctx: Context<'_>) -> Result<(), Error> {
Ok(()) Ok(())
} }
#[command(slash_command, owners_only)] #[command(slash_command, prefix_command, owners_only)]
async fn toggle_dnd(ctx: Context<'_>) -> Result<(), Error> { async fn toggle_dnd(ctx: Context<'_>) -> Result<(), Error> {
let dnd = { let dnd = {
// Put into closure so Mutex isn't locked across an await point // Put into closure so Mutex isn't locked across an await point
@ -87,6 +91,49 @@ async fn toggle_dnd(ctx: Context<'_>) -> Result<(), Error> {
Ok(()) Ok(())
} }
#[command(slash_command, prefix_command)]
async fn webcam(
ctx: Context<'_>,
#[description = "Angle"] angle: Option<f32>,
) -> Result<(), Error> {
// Move servo to angle if provided, wait for motion
if let Some(angle) = angle {
let angle = num::clamp(angle, 0.0, 180.0) as u8;
SERIAL.lock().unwrap().write(&[angle]).unwrap();
std::thread::sleep(Duration::from_secs(2));
}
// Take the image
let mut camera = rscam::new("/dev/video0").unwrap();
camera.start(&rscam::Config {
interval: (1, 30), // 30 fps.
resolution: (1920, 1080),
format: b"MJPG",
..Default::default()
}).unwrap();
let frame = camera.capture().unwrap();
// Take image
const FILENAME: &str = "frame.jpg";
use tokio::fs::File;
use tokio::io::AsyncWriteExt;
let mut file = File::create(FILENAME).await.unwrap();
file.write_all(&frame).await.unwrap();
file.sync_all().await.unwrap();
let file = File::open(FILENAME).await.unwrap();
// Send
ctx.send(|f| f
.attachment(serenity::AttachmentType::File {
file: &file,
filename: FILENAME.to_owned(),
})
.reply(true)
).await.unwrap();
Ok(())
}
#[tokio::main] #[tokio::main]
async fn main() { async fn main() {
// This will load the environment variables located at `./.env`, relative to // This will load the environment variables located at `./.env`, relative to
@ -103,6 +150,7 @@ async fn main() {
commands: vec![ commands: vec![
register(), register(),
toggle_dnd(), toggle_dnd(),
webcam(),
], ],
event_handler: |_ctx, event, _framework, _data| { event_handler: |_ctx, event, _framework, _data| {
Box::pin(event_handler(_ctx, event, _framework, _data)) Box::pin(event_handler(_ctx, event, _framework, _data))
@ -123,4 +171,4 @@ async fn main() {
.setup(move |_ctx, _ready, _framework| Box::pin(async move { Result::<Data, Error>::Ok(Data { dnd: Mutex::new(false) }) })); .setup(move |_ctx, _ready, _framework| Box::pin(async move { Result::<Data, Error>::Ok(Data { dnd: Mutex::new(false) }) }));
framework.run().await.unwrap(); framework.run().await.unwrap();
} }

@ -35,7 +35,12 @@ Some utility commands:
rustSettings = with pkgs; { rustSettings = with pkgs; {
src = ./.; src = ./.;
nativeBuildInputs = [ pkg-config ]; nativeBuildInputs = [ pkg-config ];
buildInputs = [ openssl alsa-lib ]; buildInputs = [
openssl
alsa-lib
libudev-zero
libv4l
];
cargoHash = nixpkgs.lib.fakeHash; cargoHash = nixpkgs.lib.fakeHash;
}; };
meta = with nixpkgs.lib; { meta = with nixpkgs.lib; {

Loading…
Cancel
Save