1pub mod app_config;
2pub mod rest_client;
3
4use anyhow::Result;
5use chrono::NaiveDate;
6use csv::WriterBuilder;
7use std::process;
8
9use rest_client::{PriceData, RenewablesData, RestClient, SiteDetails, UsageData};
10
11pub async fn get_user_site_id(base_url: String, auth_token: String) -> Result<String> {
13 let user_site_data = get_site_data(base_url, auth_token).await?;
14 let user_site_id = user_site_data[0].id.clone();
15 Ok(user_site_id)
16}
17
18pub async fn get_site_data(base_url: String, auth_token: String) -> Result<Vec<SiteDetails>> {
20 let sites_url = format!("{}/sites", base_url);
21 let mut user_site_details = RestClient::new_client(sites_url, auth_token.clone());
22 let user_site_data = user_site_details.get_site_data().await?;
23
24 Ok(user_site_data)
25}
26
27pub async fn get_prices(
38 base_url: String,
39 auth_token: String,
40 site_id: String,
41 window: String,
42) -> Result<Vec<PriceData>> {
43 let price_url = format!(
44 "{}/sites/{}/prices/{}?&resolution=30",
45 base_url, site_id, window
46 );
47 let mut current_price_details = RestClient::new_client(price_url, auth_token.clone());
48 let current_price_data = current_price_details.get_price_data().await?;
49
50 Ok(current_price_data)
51}
52
53pub async fn get_usage_by_date(
58 base_url: String,
59 auth_token: String,
60 site_id: String,
61 start_date: String,
62 end_date: String,
63) -> Result<Vec<UsageData>> {
64 let start_date = parse_date_naive(start_date).await?;
65 let end_date = parse_date_naive(end_date).await?;
66 let usage_data_url = format!(
67 "{}/sites/{}/usage?startDate={}&endDate={}&resolution=30'",
68 base_url, site_id, start_date, end_date
69 );
70 let mut usage_details = RestClient::new_client(usage_data_url, auth_token.clone());
71 let usage_data = usage_details.get_usage_data().await?;
72 Ok(usage_data)
73}
74
75pub async fn get_renewables(
80 base_url: String,
81 auth_token: String,
82 state: String,
83 window: String,
84) -> Result<Vec<RenewablesData>> {
85 let price_url = format!(
86 "{}/state/{}/renewables/{}?&resolution=30",
87 base_url, state, window
88 );
89 let renewables_request = RestClient::new_client(price_url, auth_token.clone());
90 let renewables_data = renewables_request.get_renewables_data().await?;
91 Ok(renewables_data)
92}
93
94pub async fn parse_date_naive(date: String) -> Result<String> {
98 let naive_date = match NaiveDate::parse_from_str(&date, "%Y-%m-%d") {
99 Ok(date) => date,
100 Err(_error) => {
101 eprintln!("Date must be in the format of year-month-day/yyyy-mm-dd, input of {}, does not match requirements", date);
102 eprintln!("Can not querity Amber Api, exiting.");
103 process::exit(65);
107 }
108 };
109
110 let valid_date = naive_date.to_string();
111 Ok(valid_date)
112}
113
114pub async fn write_data_as_csv_to_file(file_name: String, data: Vec<UsageData>) -> Result<()> {
116 let mut writer = WriterBuilder::new()
120 .has_headers(false)
121 .from_path(file_name.clone())?;
122
123 println!("Writing to file: {}", file_name);
124
125 writer.write_record([
127 "Type",
128 "duration",
129 "date",
130 "end_date",
131 "quality",
132 "kwh",
133 "nem_time",
134 "per_kwh",
135 "channel_type",
136 "channel_identifier",
137 "cost",
138 "renewables",
139 "spot_per_kwh",
140 "start_time",
141 "spike_status",
142 "tariff_information",
143 "descriptor",
144 ])?;
145
146 println!("Writing dataset headers to file...");
147
148 println!("Startng to write records to file...");
149 for data_point in data {
150 writer.serialize(data_point)?;
151 writer.flush()?;
152 }
153 println!("Finished writing records to file");
154 Ok(())
155}