-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 5840acb
Showing
19 changed files
with
884 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
# Auto detect text files and perform LF normalization | ||
* text=auto |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
# Generated by Cargo | ||
# will have compiled files and executables | ||
debug/ | ||
target/ | ||
|
||
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries | ||
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html | ||
Cargo.lock | ||
|
||
# These are backup files generated by rustfmt | ||
**/*.rs.bk | ||
|
||
# MSVC Windows builds of rustc generate these, which store debugging information | ||
*.pdb | ||
|
||
# Visual Studio Code configuration | ||
.vscode/ | ||
|
||
# Has unique data for testing, no need to share. | ||
tests/test_credentials.txt |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
[package] | ||
name = "se_monitoring_server_api" | ||
version = "0.1.0" | ||
edition = "2021" | ||
description = "Library for accessing the SolarEdge Monitoring Server API" | ||
license = "MIT" | ||
|
||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
|
||
[lib] | ||
name = "se_ms_api" | ||
path = "src/se_ms_api.rs" | ||
|
||
[dependencies] | ||
chrono = "0.4" | ||
reqwest = { version = "0.11", features = ["json", "blocking", "cookies"] } | ||
serde = { version = "1", features = ["derive"] } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
MIT License | ||
|
||
Copyright (c) 2022 Thomas Wrather | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
# se_ms_api | ||
SolarEdge Monitoring Server API |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
//! Module for querying the current API version of the SolarEdge monitoring server. | ||
use crate::SolaredgeCredentials; | ||
use serde::{Deserialize, Serialize}; | ||
|
||
/// Current version request | ||
pub struct CurrentVersionReq {} | ||
|
||
#[derive(Serialize, Deserialize, Debug)] | ||
#[allow(non_snake_case)] | ||
/// Current version response | ||
pub struct CurrentVersionResp { | ||
/// The API version running on the server | ||
pub version: Version, | ||
} | ||
|
||
#[derive(Serialize, Deserialize, Debug)] | ||
#[allow(non_snake_case)] | ||
/// The release version of the server | ||
pub struct Version { | ||
/// The release number running on the server in <major.minor.revision> format. | ||
pub release: String, | ||
} | ||
|
||
impl CurrentVersionReq { | ||
/// Create a current version request message that can be sent to SolarEdge. | ||
pub fn new() -> Self { | ||
CurrentVersionReq {} | ||
} | ||
|
||
/// Send the current version request to Solaredge and return the response. | ||
/// | ||
/// # Arguments | ||
/// | ||
/// * `solaredge` - SolarEdge credentials to use for sending | ||
/// | ||
/// # Returns | ||
/// the SolarEdge response or an error string | ||
pub fn send(&self, solaredge: &SolaredgeCredentials) -> Result<CurrentVersionResp, String> { | ||
let url = format!( | ||
"{}version/current?{}", | ||
solaredge.url_start, solaredge.url_end | ||
); | ||
|
||
let res = match reqwest::blocking::get(&url) { | ||
Ok(r) => r, | ||
Err(e) => return Err(format!("reqwest get error {}", e)), | ||
}; | ||
|
||
let parsed = match res.json::<CurrentVersionResp>() { | ||
Ok(p) => p, | ||
Err(e) => return Err(format!("JSON parse error {}", e)), | ||
}; | ||
|
||
Ok(parsed) | ||
} | ||
} | ||
|
||
impl Default for CurrentVersionReq { | ||
fn default() -> Self { | ||
Self::new() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
//! Module for handling generic date / value pairs returned by the SolarEdge server monitoring API. | ||
use serde::{Deserialize, Serialize}; | ||
|
||
#[derive(Serialize, Deserialize, Debug)] | ||
/// A date and value pair returned from the monitoring API. The value units are specified by the unit | ||
/// field elsewhere in the response. | ||
pub struct DateValue { | ||
/// YYYY-mm-dd HH:MM:SS | ||
pub date: String, | ||
|
||
/// Often an integer, but can be float too. Meaning defined by the context of the response. | ||
pub value: Option<f32>, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
//! Module for specifying the meter type in SolarEdge server monitoring API requests and responses. | ||
use serde::{Deserialize, Serialize}; | ||
|
||
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq)] | ||
/// Meters supported by SolarEdge. | ||
pub enum MeterType { | ||
/// Solar energy produced. | ||
Production, | ||
|
||
/// Total energy consumed (solar + grid) | ||
Consumption, | ||
|
||
/// Solar energy consumed. | ||
SelfConsumption, | ||
|
||
/// Solar energy exported to grid. | ||
FeedIn, | ||
|
||
/// Energy purchased from grid. | ||
Purchased, | ||
} | ||
|
||
impl std::fmt::Display for MeterType { | ||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
match *self { | ||
MeterType::Production => write!(f, "Production"), | ||
MeterType::Consumption => write!(f, "Consumption"), | ||
MeterType::SelfConsumption => write!(f, "SelfConsumption"), | ||
MeterType::FeedIn => write!(f, "FeedIn"), | ||
MeterType::Purchased => write!(f, "Purchased"), | ||
} | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use super::*; | ||
|
||
#[test] | ||
fn meter_type_fmt_unit_test() { | ||
let t = MeterType::Production; | ||
assert_eq!(format!("{}", t), "Production"); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
//! Module for holding values for a specified meter type in SolarEdge server monitoring API responses. | ||
pub use crate::date_value::DateValue; | ||
use crate::meter_type::MeterType; | ||
use serde::{Deserialize, Serialize}; | ||
|
||
#[derive(Serialize, Deserialize, Debug)] | ||
/// Values for the meter type over a range of dates. | ||
pub struct MeterValue { | ||
/// The meter type of the associated values. | ||
pub r#type: MeterType, // had to escape the keyword type to use as a json identifier | ||
|
||
/// Meter readings for each date. | ||
pub values: Vec<DateValue>, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
//! Library to retrieve data from the SolarEdge Monitoring Server. | ||
//! | ||
//! Based on the API define here: | ||
//! <https://www.solaredge.com/sites/default/files/se_monitoring_api.pdf>, | ||
//! released January 2022. | ||
//! | ||
//! The basic use case is: | ||
//! 1) Create a SolarEdge struct that contains the site id and api key | ||
//! that will be used for the requests. (The se_monitoring_api.pdf linked | ||
//! above has instructions for getting your site id and api key. | ||
//! 2) Create a request for the information that you want. | ||
//! 3) Send the request using the SolarEdge struct. | ||
//! 4) Read the response to get the information. | ||
//! | ||
//! ```no_run | ||
//! extern crate se_ms_api; | ||
//! use se_ms_api::{SiteDetailsReq, SolaredgeCredentials}; | ||
//! | ||
//! let site_id = "my_site_id"; | ||
//! let api_key = "my_api_key"; | ||
//! | ||
//! let solar_edge = SolaredgeCredentials::new(&site_id, &api_key); // (1) | ||
//! let req = SiteDetailsReq::new(); // (2) | ||
//! let resp = req.send(&solar_edge); // (3) | ||
//! | ||
//! match resp { // (4) | ||
//! Ok(r) => { | ||
//! println!("My site's status is {}.", r.details.status); | ||
//! } | ||
//! Err(e) => { | ||
//! panic!("Unexpected SiteDetails response: {:?}", e); | ||
//! } | ||
//!} | ||
//! ``` | ||
//! Supported API requests/responses include: | ||
//! * [SiteDetailsReq] / [SiteDetailsResp] | ||
//! * [SiteEnergyDetailedReq] / [SiteEnergyDetailedResp] | ||
//! | ||
#![deny(unused_crate_dependencies)] | ||
#![deny(unused_extern_crates)] | ||
#![warn(missing_docs)] | ||
|
||
pub mod site_details; | ||
pub use site_details::{SiteDetailsReq, SiteDetailsResp}; | ||
pub mod site_energy_detailed; | ||
pub use site_energy_detailed::{SiteEnergyDetailedReq, SiteEnergyDetailedResp}; | ||
pub mod current_version; | ||
pub use current_version::{CurrentVersionReq, CurrentVersionResp}; | ||
pub mod supported_versions; | ||
pub use supported_versions::{SupportedVersionsReq, SupportedVersionsResp}; | ||
pub mod date_value; | ||
pub mod meter_type; | ||
pub use meter_type::MeterType; | ||
pub mod meter_value; | ||
pub mod site_location; | ||
pub mod site_module; | ||
pub mod site_public_settings; | ||
pub mod time_unit; | ||
|
||
const URL_TIME_FORMAT: &str = "%Y-%m-%d %H:%M:%S"; | ||
|
||
/// Struct for accessing SolarEdge's monitoring server for a given site and api key. | ||
/// | ||
/// Used as the parameter for the send() function of all of the possible requests. | ||
pub struct SolaredgeCredentials { | ||
url_start: String, | ||
site_id: String, | ||
url_end: String, | ||
} | ||
|
||
impl SolaredgeCredentials { | ||
const MONITORING_API_URL: &'static str = "https://monitoringapi.solaredge.com/"; | ||
|
||
/// Create a Solaredge destination for the requests from the given site id and api_key. | ||
pub fn new(site_id: &str, api_key: &str) -> Self { | ||
let url_start = SolaredgeCredentials::MONITORING_API_URL.to_string(); | ||
let site_id = site_id.to_string(); | ||
let url_end = format!("api_key={}", api_key); | ||
|
||
SolaredgeCredentials { | ||
url_start, | ||
site_id, | ||
url_end, | ||
} | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use super::*; | ||
|
||
#[test] | ||
fn solaredge_new_unit_test() { | ||
let se = SolaredgeCredentials::new("id", "key"); | ||
assert_eq!(se.url_start, SolaredgeCredentials::MONITORING_API_URL); | ||
assert_eq!(se.site_id, "id"); | ||
assert_eq!(se.url_end, "api_key=key"); | ||
} | ||
} |
Oops, something went wrong.