Imports name this capability’s declared dependencies, which fune builds next to it in your project; each one links to its page.
use super::funejson::Value; ← the fune runtime: the JSON value the test vectors use; fune build keeps it only where a signature takes one
use super::math_round_div::round_div; ← from math.round-div ^1.0.0 · built alongside by fune
// watts x Kk x SF (hundredths) / (1000 W/kW x 100) is kWh.
const DIVISOR: i64 = 100_000;
fn check(what: &str, value: i64, max: i64) {
if value < 0 || value > max {
panic!("{} must be a whole number from 0 to {}, received {}", what, max, value);
}
}
/// Annual AC generation by the MCS method, kWp x Kk x SF, rounded half-up to
/// a whole kWh for each array; the total is the sum of the arrays.
///
/// # Panics
/// Panics on no arrays, or a rating, Kk or shade factor out of range.
pub fn solar_generation(arrays: &[PvArray]) -> SolarEstimate {
if arrays.is_empty() {
panic!("a solar estimate needs at least one array");
}
let kwh: Vec<i64> = arrays
.iter()
.map(|a| {
check("wattsPeak", a.watts_peak, 100_000_000);
check("kk", a.kk, 5000);
check("shadeFactor", a.shade_factor, 100);
round_div(a.watts_peak * a.kk * a.shade_factor, DIVISOR, "half-up")
})
.collect();
let total = kwh.iter().sum();
SolarEstimate { arrays: kwh, total }
}
fn whole(what: &str, max: i64, v: &Value) -> i64 {
if let Value::Float(f) = v {
panic!("{} must be a whole number from 0 to {}, received {}", what, max, f);
}
v.as_i64()
}
pub fn pv_array_from_value(v: &Value) -> PvArray {
PvArray {
watts_peak: whole("wattsPeak", 100_000_000, v.get("wattsPeak")),
kk: whole("kk", 5000, v.get("kk")),
shade_factor: whole("shadeFactor", 100, v.get("shadeFactor")),
}
}
pub fn solar_estimate_to_value(e: &SolarEstimate) -> Value {
Value::obj(vec![
("arrays", Value::Arr(e.arrays.iter().map(|k| Value::Int(*k)).collect())),
("total", Value::Int(e.total)),
])
}
pub fn fune_vector(args: &[Value]) -> Value {
let arrays: Vec<PvArray> = args[0].as_arr().iter().map(pv_array_from_value).collect();
solar_estimate_to_value(&solar_generation(&arrays))
}