1use crate::sg::{dcl, dcl::DaVa, ldp::base, uty::NumForm, wk5};
2use askama::Template;
3use regex::{Regex};
6use serde::{Deserialize, Serialize};
7use std::cmp::{PartialOrd};
8use std::sync::Arc;
10use tokio::sync::RwLock;
12use tokio::sync::{OwnedRwLockReadGuard, };
13
14#[derive(Template, Debug)]
15#[template(path = "pg2/wk5f.html", escape = "none")]
16pub struct ReportTemp {
17 pub title: String,
18 pub wk: OwnedRwLockReadGuard<wk5::Wk5Proc>,
19}
20
21fn rp(wk5prc: &wk5::Wk5Proc) -> &Report {
22 &wk5prc.wk5g
23}
24fn sp(wk5prc: &mut wk5::Wk5Proc, rp: Report) {
25 wk5prc.wk5g = rp;
26}
27
28impl ReportTemp {
29 pub fn repo(&self) -> &Report {
30 &self.wk.wk5g
31 }
32 async fn new(wk5prc: Arc<RwLock<wk5::Wk5Proc>>) -> Self {
33 let wk = wk5prc.read_owned().await;
34 let title = "SOLAR ENERGY PROJECTION : WK5G";
35 let title = title.to_string();
36
37 ReportTemp { wk, title }
38 }
39 pub fn sum(&self, c: &usize) -> String {
40 if *c == 0 {
41 return format!("");
42 }
43 match rp(&self.wk).sums[*c] {
44 DaVa::F32(v) => v.form(),
46 DaVa::F64(v) => v.form(),
47 DaVa::USZ(v) => v.form(),
48 DaVa::I32(v) => v.form(),
49 DaVa::I64(v) => v.form(),
50 _ => format!(""),
51 }
52 }
53 pub fn cell(&self, r: &usize, c: &usize) -> String {
54 let mut ce = rp(&self.wk).dava(&self.wk.ssv, *r, *c);
55 if *c == 5 {
56 if let DaVa::F32(v) = ce {
57 let s = rp(&self.wk).rows[*r].s;
58 let f = rp(&self.wk).rows[*r].f;
59 let ss = &self.wk.ssv[s].ssid;
60 let fd = &self.wk.ssv[s].feeders[f].fdid;
61 ce = DaVa::Text(format!(
62 "<a href='/feeder_yrpw01/{}/{}'>{}</a>",
63 ss,
64 fd,
65 v.form()
66 ));
67 }
68 }
69 match ce {
70 DaVa::Text(s) => s,
71 DaVa::F32(f) => ((f * 100.0).floor() / 100.0).form(),
72 DaVa::F64(f) => ((f * 100.0).floor() / 100.0).form(),
73 DaVa::USZ(u) => format!("{}", u),
74 d => format!("{:?}", d),
75 }
76 }
77}
78
79#[derive(Serialize, Deserialize, Debug, Clone, Default)]
80pub struct Report {
81 pub rows: Vec<RepoRow1>,
82 pub cols: Vec<String>,
83 pub sums: Vec<DaVa>,
84}
85
86#[derive(Serialize, Deserialize, Debug, Clone, Default)]
87pub struct RepoRow1 {
88 pub s: usize, pub f: usize, }
91
92const TT: [&str; 4] = ["NO", "NAME", "FDID", "ENERGY:mwh"];
93
94pub async fn make_repo(wk5prc: &mut wk5::Wk5Proc, _acfg: Arc<RwLock<dcl::Config>>) {
95 let mut repo = rp(wk5prc).clone();
96
97 for t in TT {
99 repo.cols.push(t.to_string());
100 repo.sums.push(DaVa::None);
101 }
102 let cfg = base().config.read().await;
103 let syf = cfg.criteria.start_year_from_2022;
104 let imy = cfg.criteria.implement_year;
105 let opy = cfg.criteria.operate_year;
106 let yrl = syf + imy + opy;
107 let yrl = yrl as usize;
108 for i in 0..yrl {
109 let yr = 2022 + i + 1;
110 repo.cols.push(format!("{}:MWh", yr));
111 repo.sums.push(DaVa::None);
112 }
113 let re = Regex::new(r"..._[0-9][0-9].+").unwrap();
114 for s in 0..wk5prc.ssv.len() {
115 for f in 0..wk5prc.ssv[s].feeders.len() {
116 let mut rw = RepoRow1::default();
117 rw.s = s;
118 rw.f = f;
119 let fd = &wk5prc.ssv[s].feeders[f];
120 if re.is_match(fd.fdid.as_str()) {
121 if fd.ev.ev_ds > 0.0 && fd.tx.tx_no > 0 {
123 repo.rows.push(rw);
124 }
125 }
126 }
127 }
128 repo.rows.sort_by(|a, b| {
129 let a0 = &wk5prc.ssv[a.s].prov;
130 let a1 = &wk5prc.ssv[a.s].ssid;
131 let a2 = &wk5prc.ssv[a.s].feeders[a.f].fdid;
132 let b0 = &wk5prc.ssv[b.s].prov;
133 let b1 = &wk5prc.ssv[b.s].ssid;
134 let b2 = &wk5prc.ssv[b.s].feeders[b.f].fdid;
135 if a0!=b0 {
136 a0.partial_cmp(b0).unwrap()
137 } else {
138 if a1!=b1 {
139 a1.partial_cmp(b1).unwrap()
140 } else {
141 a2.partial_cmp(b2).unwrap()
142 }
143 }
144 });
150 sum(&mut repo, &wk5prc.ssv);
151 sp(wk5prc, repo);
152}
153
154impl Report {
155 pub fn dava(&self, ssv: &Vec<wk5::Substation>, r: usize, c: usize) -> dcl::DaVa {
156 let s = self.rows[r].s;
157 let f = self.rows[r].f;
158 let ss = &ssv[s];
159 let fd = &ssv[s].feeders[f];
160 match c {
161 0 => DaVa::USZ(r + 1),
162 1 => DaVa::Text(ss.name.to_string()),
163 2 => DaVa::Text(fd.fdid5.to_string()),
164 3 => DaVa::F32(fd.year_load.power_quality.pos_energy),
165 n => DaVa::F32(fd.solar_energy_series[n - 4]),
167 }
168 }
169}
170
171pub async fn handler() -> ReportTemp {
175 ReportTemp::new(base().wk5prc.clone()).await
176}
177
178fn sum(repo: &mut Report, ssv: &Vec<wk5::Substation>) {
179 if repo.rows.len() > 0 {
180 repo.sums[0] = DaVa::None;
181 for ci in 1..repo.cols.len() {
182 repo.sums[ci] = match repo.dava(ssv, 0, ci) {
183 DaVa::F32(_) => DaVa::F32(0.0),
184 DaVa::F64(_) => DaVa::F64(0.0),
185 DaVa::I32(_) => DaVa::I32(0),
186 DaVa::I64(_) => DaVa::I64(0),
187 DaVa::USZ(_) => DaVa::USZ(0),
188 _ => DaVa::None,
189 };
190 }
191 for (ri, _rr) in repo.rows.iter().enumerate() {
193 if let DaVa::USZ(_v) = repo.dava(ssv, ri, 5) {
194 }
196
197 for ci in 0..repo.cols.len() {
198 repo.sums[ci] = match repo.dava(ssv, ri, ci) {
199 DaVa::F32(v1) => {
200 if let DaVa::F32(v2) = repo.sums[ci] {
201 DaVa::F32(v1 + v2)
202 } else {
203 DaVa::F32(0.0)
204 }
205 }
206 DaVa::F64(v1) => {
207 if let DaVa::F64(v2) = repo.sums[ci] {
208 DaVa::F64(v1 + v2)
209 } else {
210 DaVa::F64(0.0)
211 }
212 }
213 DaVa::I32(v1) => {
214 if let DaVa::I32(v2) = repo.sums[ci] {
215 DaVa::I32(v1 + v2)
216 } else {
217 DaVa::I32(0)
218 }
219 }
220 DaVa::I64(v1) => {
221 if let DaVa::I64(v2) = repo.sums[ci] {
222 DaVa::I64(v1 + v2)
223 } else {
224 DaVa::I64(0)
225 }
226 }
227 DaVa::USZ(v1) => {
228 if let DaVa::USZ(v2) = repo.sums[ci] {
229 DaVa::USZ(v1 + v2)
230 } else {
231 DaVa::USZ(0)
232 }
233 }
234 _ => DaVa::None,
235 };
236 }
237 }
238 }
239}
240