use std::collections::{BTreeMap, HashMap, HashSet};
use serde::{Deserialize, Serialize};
use super::issues::{GoC3Issue, GoC3IssueSeverity};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum GoC3DeviceKind {
Producer,
ProducerStatic,
Consumer,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct AcLineInitialState {
pub on_status: i32,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct TransformerInitialState {
pub on_status: i32,
pub tm: f64,
pub ta: f64,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct DcLineInitialState {
pub pdc_fr: f64,
pub qdc_fr: f64,
pub qdc_to: f64,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct DcLineReactiveBounds {
pub qdc_fr_lb: f64,
pub qdc_fr_ub: f64,
pub qdc_to_lb: f64,
pub qdc_to_ub: f64,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct DcLineReactiveSupportResources {
pub fr: String,
pub to: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BranchRef {
pub from_bus: u32,
pub to_bus: u32,
pub circuit: String,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct GoC3Context {
pub bus_uid_to_number: HashMap<String, u32>,
pub bus_number_to_uid: HashMap<u32, String>,
pub device_uid_to_id: HashMap<String, (u32, String)>,
pub branch_uid_to_ref: HashMap<String, BranchRef>,
pub branch_circuit_by_uid: HashMap<String, u32>,
pub branch_local_index_by_uid: HashMap<String, usize>,
pub dc_line_uid_to_name: HashMap<String, String>,
pub shunt_uid_to_id: HashMap<String, (u32, String)>,
pub device_kind_by_uid: HashMap<String, GoC3DeviceKind>,
pub ac_line_initial: HashMap<String, AcLineInitialState>,
pub transformer_initial: HashMap<String, TransformerInitialState>,
pub dc_line_initial: HashMap<String, DcLineInitialState>,
pub dc_line_q_bounds: HashMap<String, DcLineReactiveBounds>,
pub shunt_initial_steps: HashMap<String, i32>,
pub shunt_step_bounds: HashMap<String, (i32, i32)>,
pub switched_shunt_control_id_to_uid: BTreeMap<String, String>,
pub transformer_tap_bounds: HashMap<String, (f64, f64)>,
pub dc_line_reactive_support_resource_ids: HashMap<String, DcLineReactiveSupportResources>,
pub dc_line_reactive_support_resource_to_output: HashMap<String, (String, String)>,
pub internal_support_commitment_schedule: HashMap<String, Vec<bool>>,
pub device_fixed_p_series_pu: HashMap<String, Vec<f64>>,
pub consumer_dispatchable_resource_ids_by_uid: HashMap<String, Vec<String>>,
pub reserve_product_ids: Vec<String>,
pub explicit_voltage_regulating_resource_ids: HashSet<String>,
pub go_explicit_voltage_regulating_resource_ids: HashSet<String>,
pub slack_bus_numbers: Vec<u32>,
pub issues: Vec<GoC3Issue>,
}
impl GoC3Context {
pub fn new() -> Self {
Self::default()
}
pub fn add_issue(
&mut self,
severity: GoC3IssueSeverity,
code: impl Into<String>,
message: impl Into<String>,
) {
self.issues.push(GoC3Issue {
severity,
code: code.into(),
message: message.into(),
});
}
pub fn add_info(&mut self, code: impl Into<String>, message: impl Into<String>) {
self.issues.push(GoC3Issue::info(code, message));
}
pub fn add_warning(&mut self, code: impl Into<String>, message: impl Into<String>) {
self.issues.push(GoC3Issue::warning(code, message));
}
pub fn add_error(&mut self, code: impl Into<String>, message: impl Into<String>) {
self.issues.push(GoC3Issue::error(code, message));
}
pub fn issue_counts(&self) -> (usize, usize, usize) {
let mut info = 0;
let mut warn = 0;
let mut err = 0;
for issue in &self.issues {
match issue.severity {
GoC3IssueSeverity::Info => info += 1,
GoC3IssueSeverity::Warning => warn += 1,
GoC3IssueSeverity::Error => err += 1,
}
}
(info, warn, err)
}
}