feat: Introduce linear forecasting for SFC and auxiliary parameters and refine actual energy sales calculation.

main
MrWaradana 7 days ago
parent 911254db11
commit a2da393c54

@ -130,6 +130,40 @@ def getproyeksilinier(years, values, iterations=30, target_years=None):
n_projection = iterations - n_hist n_projection = iterations - n_hist
return {start_year + i: _predict(start_year + i) for i in range(n_projection)} return {start_year + i: _predict(start_year + i) for i in range(n_projection)}
def linear_forecast_from_history(values):
"""
Melakukan proyeksi linier (OLS) dari seluruh data history.
Mengembalikan nilai forecast untuk index berikutnya.
"""
# ambil hanya nilai valid (>0)
y = [v for v in values if v is not None and v > 0]
n = len(y)
if n == 0:
return 0.0
if n == 1:
return y[0] # belum bisa regresi
x = list(range(n))
sum_x = sum(x)
sum_y = sum(y)
sum_x2 = sum(i * i for i in x)
sum_xy = sum(i * y[i] for i in x)
denominator = (n * sum_x2 - sum_x ** 2)
if denominator == 0:
return y[-1]
b = (n * sum_xy - sum_x * sum_y) / denominator
a = (sum_y - b * sum_x) / n
# forecast untuk index berikutnya
next_x = n
forecast = a + b * next_x
# safety clamp
return max(forecast, 0.0)
def main(): def main():
@ -361,9 +395,9 @@ def main():
discount_rate = get_param("discount_rate") / 100 discount_rate = get_param("discount_rate") / 100
total_project_cost = get_param("total_project_cost") total_project_cost = get_param("total_project_cost")
daya_mampu_netto = get_param("daya_mampu_netto") daya_mampu_netto = get_param("daya_mampu_netto")
auxiliary = get_param("auxiliary") # auxiliary = get_param("auxiliary")
susut_trafo = get_param("susut_trafo") susut_trafo = get_param("susut_trafo")
sfc = get_param("sfc") # sfc = get_param("sfc")
# Harga listrik berdasarkan tipe # Harga listrik berdasarkan tipe
price_a = get_param("electricity_price_a") price_a = get_param("electricity_price_a")
@ -417,6 +451,9 @@ def main():
eaf_v = 0 eaf_v = 0
eaf_history = [] eaf_history = []
cf_history = [] cf_history = []
sfc_history = []
auxiliary_history = []
# Prefetch master data CF dan EAF sekali saja di luar loop # Prefetch master data CF dan EAF sekali saja di luar loop
cur.execute(""" cur.execute("""
SELECT year as tahun, cf, eaf SELECT year as tahun, cf, eaf
@ -463,7 +500,8 @@ def main():
if data["is_actual"] == 1: if data["is_actual"] == 1:
production_bruto = validate_number(data["production_bruto"]) production_bruto = validate_number(data["production_bruto"])
production_netto = validate_number(data["production_netto"]) production_netto = validate_number(data["production_netto"])
energy_sales = production_netto energy_sales = validate_number(data.get("energy_sales")) if validate_number(
data.get("energy_sales")) is not None else production_netto
fuel_consumption = validate_number(data["fuel_consumption"]) fuel_consumption = validate_number(data["fuel_consumption"])
revenue_a = validate_number(data["revenue_a"]) revenue_a = validate_number(data["revenue_a"])
revenue_b = validate_number(data["revenue_b"]) revenue_b = validate_number(data["revenue_b"])
@ -473,7 +511,25 @@ def main():
cost_bd_om = validate_number(data["cost_bd_om"]) cost_bd_om = validate_number(data["cost_bd_om"])
cost_bd_pm_nonmi = validate_number(data["cost_bd_pm_nonmi"]) cost_bd_pm_nonmi = validate_number(data["cost_bd_pm_nonmi"])
cost_bd_bd = validate_number(data["cost_bd_bd"]) cost_bd_bd = validate_number(data["cost_bd_bd"])
sfc_history.append(fuel_consumption / production_bruto if production_bruto != 0 else 0)
auxiliary_history.append(
(production_bruto - production_netto) / production_bruto * 100 if production_bruto != 0 else 0)
else: else:
# last_3_sfc = sfc_history[-3:]
# avg_last_3_sfc = sum(last_3_sfc) / len(last_3_sfc) if len(last_3_sfc) > 0 else 0
# sfc = avg_last_3_sfc
# sfc_history.append(avg_last_3_sfc)
# last_3_auxiliary = auxiliary_history[-3:]
# avg_last_3_auxiliary = sum(last_3_auxiliary) / len(last_3_auxiliary) if len(last_3_auxiliary) > 0 else 0
# auxiliary = avg_last_3_auxiliary
# auxiliary_history.append(avg_last_3_auxiliary)
sfc = linear_forecast_from_history(sfc_history)
sfc_history.append(sfc)
auxiliary = linear_forecast_from_history(auxiliary_history)
auxiliary_history.append(auxiliary)
production_netto = net_capacity_factor * 8760 * daya_mampu_netto / 100 production_netto = net_capacity_factor * 8760 * daya_mampu_netto / 100
production_bruto = production_netto / (100 - (auxiliary + susut_trafo)) * 100 production_bruto = production_netto / (100 - (auxiliary + susut_trafo)) * 100
energy_sales = production_netto energy_sales = production_netto

Loading…
Cancel
Save