Add service-specific configuration

Switch to a section/table for the service to make it easier.
This commit is contained in:
Paul van Tilburg 2023-01-09 21:25:35 +01:00
parent 87394f9fb9
commit 3690647c76
5 changed files with 42 additions and 20 deletions

View File

@ -14,7 +14,9 @@ For example for My Autarco:
[default] [default]
# ... # ...
# Put your solar cloud service credentials below # Put your solar cloud service settings below and uncomment them
[default.service]
kind = "MyAutarco"
username = "foo@domain.tld" username = "foo@domain.tld"
password = "secret" password = "secret"
site_id = "abc123de" site_id = "abc123de"

View File

@ -3,6 +3,8 @@ address = "0.0.0.0"
port = 2356 port = 2356
# Put your solar cloud service settings below and uncomment them # Put your solar cloud service settings below and uncomment them
[default.service]
# kind = "MyAutarco"
# username = "foo@domain.tld" # username = "foo@domain.tld"
# password = "secret" # password = "secret"
# site_id = "abc123de" # site_id = "abc123de"

View File

@ -20,20 +20,16 @@ use serde::{Deserialize, Serialize};
use self::update::update_loop; use self::update::update_loop;
/// The configuration necessary to access a cloud service API.
#[derive(Debug, Deserialize)]
struct Config {
/// The username of the account to login with
username: String,
/// The password of the account to login with
password: String,
/// The Autarco site ID to track
site_id: String,
}
/// The global, concurrently accessible current status. /// The global, concurrently accessible current status.
static STATUS: Lazy<Mutex<Option<Status>>> = Lazy::new(|| Mutex::new(None)); static STATUS: Lazy<Mutex<Option<Status>>> = Lazy::new(|| Mutex::new(None));
/// The configuration loaded additionally by Rocket.
#[derive(Debug, Deserialize)]
struct Config {
/// The service-specific configuration
service: services::Config,
}
/// The current photovoltaic invertor status. /// The current photovoltaic invertor status.
#[derive(Clone, Copy, Debug, Serialize)] #[derive(Clone, Copy, Debug, Serialize)]
struct Status { struct Status {
@ -60,8 +56,11 @@ fn rocket() -> _ {
.attach(AdHoc::config::<Config>()) .attach(AdHoc::config::<Config>())
.attach(AdHoc::on_liftoff("Updater", |rocket| { .attach(AdHoc::on_liftoff("Updater", |rocket| {
Box::pin(async move { Box::pin(async move {
let config = rocket.figment().extract().expect("Invalid configuration"); let config = rocket
let service = services::get("my_autarco", config).expect("Invalid service"); .figment()
.extract::<Config>()
.expect("Invalid configuration");
let service = services::get(config.service).expect("Invalid service");
// We don't care about the join handle nor error results?t // We don't care about the join handle nor error results?t
let _ = rocket::tokio::spawn(update_loop(service)); let _ = rocket::tokio::spawn(update_loop(service));

View File

@ -4,14 +4,22 @@ pub(crate) mod my_autarco;
use enum_dispatch::enum_dispatch; use enum_dispatch::enum_dispatch;
use rocket::async_trait; use rocket::async_trait;
use serde::Deserialize;
use crate::{Status, Config}; use crate::Status;
/// The service-specific configuration necessary to access a cloud service API.
#[derive(Debug, Deserialize)]
#[serde(crate = "rocket::serde", tag = "kind")]
pub(crate) enum Config {
/// The configuration of the My Autarco service
MyAutarco(my_autarco::Config),
}
/// Retrieves the service for the provided name (if supported). /// Retrieves the service for the provided name (if supported).
pub(crate) fn get(service: &str, config: Config) -> color_eyre::Result<Services> { pub(crate) fn get(config: Config) -> color_eyre::Result<Services> {
match service { match config {
"my_autarco" => Ok(Services::MyAutarco(my_autarco::service(config)?)), Config::MyAutarco(config) => Ok(Services::MyAutarco(my_autarco::service(config)?)),
_ => panic!("Unsupported service: {service}"),
} }
} }

View File

@ -9,7 +9,7 @@ use rocket::async_trait;
use serde::Deserialize; use serde::Deserialize;
use url::ParseError; use url::ParseError;
use crate::{Status, Config}; use crate::Status;
/// The base URL of My Autarco site. /// The base URL of My Autarco site.
const BASE_URL: &str = "https://my.autarco.com"; const BASE_URL: &str = "https://my.autarco.com";
@ -17,6 +17,17 @@ const BASE_URL: &str = "https://my.autarco.com";
/// The interval between data polls (in seconds). /// The interval between data polls (in seconds).
const POLL_INTERVAL: u64 = 300; const POLL_INTERVAL: u64 = 300;
/// The configuration necessary to access the My Autarco API.
#[derive(Debug, Deserialize)]
pub(crate) struct Config {
/// The username of the account to login with
username: String,
/// The password of the account to login with
password: String,
/// The Autarco site ID to track
site_id: String,
}
/// Instantiates the My Autarco service. /// Instantiates the My Autarco service.
pub(crate) fn service(config: Config) -> Result<Service, reqwest::Error> { pub(crate) fn service(config: Config) -> Result<Service, reqwest::Error> {
let client = ClientBuilder::new().cookie_store(true).build()?; let client = ClientBuilder::new().cookie_store(true).build()?;