more configurations.

This commit is contained in:
Aleksandr Trushkin
2020-11-15 21:28:31 +03:00
parent 350d0dbceb
commit 567512b16e
4 changed files with 110 additions and 22 deletions

3
.env Normal file
View File

@ -0,0 +1,3 @@
ALTEREGO_TELEGRAM_TOKEN=
ALTEREGO_CLIMATE_DSN=
ALTEREGO_HOSTTEMP_CMD=

21
Cargo.lock generated
View File

@ -14,6 +14,7 @@ name = "altherego"
version = "0.1.0"
dependencies = [
"env_logger",
"envconfig",
"log",
"reqwest",
"serde",
@ -184,6 +185,26 @@ dependencies = [
"termcolor",
]
[[package]]
name = "envconfig"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c0ef0470da909709515ab175d5d12f1b20932f758f731589e1ff198561ab9ca"
dependencies = [
"envconfig_derive",
]
[[package]]
name = "envconfig_derive"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ca7511366e70d25663dbc2501911beae6064d51687214794efd2d8f5ad73440"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "fnv"
version = "1.0.7"

View File

@ -16,3 +16,4 @@ serde_json = "1.0.59"
uuid = { version = "0.8.1", features = ["v4"] }
log = "0.4"
env_logger = "0.8.1"
envconfig = "0.9.1"

View File

@ -1,22 +1,51 @@
use std::env;
use teloxide::{prelude::*, utils::command::BotCommand};
use log::{debug, info, warn};
use env_logger;
use envconfig::Envconfig;
use log::{debug, info, warn};
use teloxide::{prelude::*, utils::command::BotCommand};
#[tokio::main]
async fn main() {
run().await
}
#[derive(Envconfig, Clone)]
struct Settings {
#[envconfig(from = "ALTEREGO_TELEGRAM_TOKEN")]
pub telegram_token: String,
#[envconfig(
from = "ALTEREGO_CLIMATE_DSN",
default = "http://127.0.0.1:18081/v1/home/temperature"
)]
pub climate_dsn: String,
#[envconfig(
from = "ALTEREGO_HOSTTEMP_CMD",
default = "/opt/vc/bin/vcgencmd measure_temp"
)]
pub hosttemp_cmd: String,
}
async fn run() {
env_logger::init();
// 170515067:AAElDJ8Sq_oIqo9WaL4DKvUr13nSEIdHCYs
let token = match env::var("ALTHEREGO_TOKEN") {
Ok(token) => token,
Err(_) => "170515067:AAElDJ8Sq_oIqo9WaL4DKvUr13nSEIdHCYs".to_string(),
};
let settings = Settings::init_from_env().expect("reading config values");
let bot = teloxide::Bot::builder().token(token).build();
let bot_name = "AltherEgo";
let bot = teloxide::Bot::builder()
.token(&settings.telegram_token)
.build();
let bot_name = "AlterEgo";
teloxide::commands_repl(bot, bot_name, handler).await;
teloxide::commands_repl(bot, bot_name, move |cx, command| {
let climate = settings.climate_dsn.clone();
let cmd: String = settings.hosttemp_cmd.clone();
let cmd: Vec<&str> = cmd.split(" ").collect();
let console_cmd = cmd.get(0).expect("getting console command").to_string();
let arg: String = cmd.get(1).unwrap_or_else(|| &"").to_string();
async move { handler(cx, command, climate, console_cmd, arg).await }
})
.await;
}
#[derive(serde::Deserialize, Debug)]
@ -25,21 +54,49 @@ struct Climate {
temperature: f32,
}
const CLIMATE_REQ_URL: &str = "http://127.0.0.1:18081/v1/home/temperature";
async fn handler(cx: UpdateWithCx<Message>, command: Command) -> ResponseResult<()> {
async fn handler(
cx: UpdateWithCx<Message>,
command: Command,
dsn: String,
console_command: String,
console_arg: String,
) -> ResponseResult<()> {
let request_id = uuid::Uuid::new_v4();
info!("incoming request xreqid={} command={:?}", request_id, command);
info!(
"incoming request xreqid={} command={:?}",
request_id, command
);
match command {
Command::Help => cx.answer(Command::descriptions()).send().await?,
Command::HostTemperature => {
let cmd = std::process::Command::new(&console_command)
.arg(&console_arg)
.stdout(std::process::Stdio::piped())
.spawn()
.expect("running vcgencmd command");
let output = cmd.wait_with_output().expect("waiting for output");
let parsed =
std::string::String::from_utf8(output.stdout).expect("casting into string");
let parsed = parsed.replace("temp=", "");
cx.answer_str(format!("Your Raspberry PI temperature is {}", parsed))
.await?
}
Command::RoomTemperature => {
let response = match reqwest::get(CLIMATE_REQ_URL).await {
let response = match reqwest::get(&dsn).await {
Ok(response) => response,
Err(err) => {
warn!("unable to handle request xreqid={} error={:?}", request_id, err);
cx.answer_str(format!("something went wrong, reference to {}", request_id)).await?;
warn!(
"unable to handle request xreqid={} error={:?}",
request_id, err
);
cx.answer_str(format!("something went wrong, reference to {}", request_id))
.await?;
return Err(RequestError::NetworkError(err));
}
@ -48,17 +105,21 @@ async fn handler(cx: UpdateWithCx<Message>, command: Command) -> ResponseResult<
let info: Climate = match response.json::<Climate>().await {
Ok(result) => result,
Err(err) => {
warn!("unable to handle request xreqid={} error={:?}", request_id, err);
cx.answer_str(format!("something went wrong, reference to {}", request_id)).await?;
warn!(
"unable to handle request xreqid={} error={:?}",
request_id, err
);
cx.answer_str(format!("something went wrong, reference to {}", request_id))
.await?;
return Err(RequestError::NetworkError(err));
},
}
};
debug!("parsed value: {:?}", info);
cx.answer_str(format!(
"your temperature is {:.2} and humidity is {:.2}",
"Your room temperature is {:.2} and humidity is {:.2}.",
info.temperature, info.humidity
))
.await?
@ -75,4 +136,6 @@ enum Command {
Help,
#[command(description = "temperature of your room.")]
RoomTemperature,
#[command(description = "temperature of raspberry.")]
HostTemperature,
}