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]
# ...
# 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"
password = "secret"
site_id = "abc123de"

View File

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

View File

@ -20,20 +20,16 @@ use serde::{Deserialize, Serialize};
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.
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.
#[derive(Clone, Copy, Debug, Serialize)]
struct Status {
@ -60,8 +56,11 @@ fn rocket() -> _ {
.attach(AdHoc::config::<Config>())
.attach(AdHoc::on_liftoff("Updater", |rocket| {
Box::pin(async move {
let config = rocket.figment().extract().expect("Invalid configuration");
let service = services::get("my_autarco", config).expect("Invalid service");
let config = rocket
.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
let _ = rocket::tokio::spawn(update_loop(service));

View File

@ -4,14 +4,22 @@ pub(crate) mod my_autarco;
use enum_dispatch::enum_dispatch;
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).
pub(crate) fn get(service: &str, config: Config) -> color_eyre::Result<Services> {
match service {
"my_autarco" => Ok(Services::MyAutarco(my_autarco::service(config)?)),
_ => panic!("Unsupported service: {service}"),
pub(crate) fn get(config: Config) -> color_eyre::Result<Services> {
match config {
Config::MyAutarco(config) => Ok(Services::MyAutarco(my_autarco::service(config)?)),
}
}

View File

@ -9,7 +9,7 @@ use rocket::async_trait;
use serde::Deserialize;
use url::ParseError;
use crate::{Status, Config};
use crate::Status;
/// The base URL of My Autarco site.
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).
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.
pub(crate) fn service(config: Config) -> Result<Service, reqwest::Error> {
let client = ClientBuilder::new().cookie_store(true).build()?;