Offline household energy scheduling and outage resilience simulation
git clone https://github.com/suqinxi/suqinxi.git
cd suqinxi
moon check --deny-warn
moon test -p sujy123456/voltweave --deny-warn
moon run cmd/voltweave -- demomoon run cmd/voltweave -- compact # 紧凑公寓场景
moon run cmd/voltweave -- outage # 风暴停电场景
moon run cmd/voltweave -- compare # 五种目标策略比较
moon run cmd/voltweave -- simulate # 64 次确定性不确定性仿真
moon run cmd/voltweave -- validate # 输入校验报告
moon run cmd/voltweave -- json # JSON 计划结果
moon run cmd/voltweave -- input # JSON 示例输入
moon run cmd/voltweave -- chart # 终端功率曲线moon build web/engine --target wasm-gc --release
cp _build/wasm-gc/release/build/web/engine/engine.wasm web/app/voltweave.wasm
python -m http.server 8765 --directory web/appCopy-Item _build/wasm-gc/release/build/web/engine/engine.wasm web/app/voltweave.wasm
python -m http.server 8765 --directory web/appdomain.mbt 领域类型、JSON 合约与单位约定
validation.mbt 输入校验、稳定错误码与建议
optimizer.mbt 候选搜索、任务调度、电池能源流和 Pareto 比较
simulation.mbt 可复现采样、分布统计与敏感性分析
analytics.mbt 独立结果审计、资源充足性与方案差异
report.mbt Markdown、CSV、ASCII 报告
examples.mbt 三组可运行场景
cmd/voltweave/ MoonBit CLI
web/engine/ Wasm-GC 外部接口
web/app/ 离线单页演示
docs/ 架构、使用、测试和发布文档moon fmt --check
moon check --deny-warn
moon test -p sujy123456/voltweave --deny-warn
moon build cmd/voltweave --target wasm --release
moon check web/engine --target wasm-gc --deny-warn
moon build web/engine --target wasm-gc --release
moon publish --dry-runpub(all) struct AdequacyProfile {
total_demand_wh : Int
total_solar_wh : Int
usable_battery_wh : Int
outage_demand_wh : Int
outage_solar_wh : Int
outage_storage_margin_wh : Int
peak_requested_w : Int
weakest_supply_margin_w : Int
weakest_supply_slot : Int
critical_task_energy_wh : Int
flexible_task_energy_wh : Int
risk_codes : Array[String]
} derive(Eq, ToJson, Debug, FromJson)pub(all) struct AuditFinding {
code : String
severity : AuditSeverity
subject : String
message : String
slot : Int?
expected : Int?
actual : Int?
} derive(Eq, ToJson, Debug, FromJson)fn AuditFinding::new(code : String, severity : AuditSeverity, subject : String, message : String, slot? : Int, expected? : Int, actual? : Int) -> AuditFindingpub(all) struct AuditSummary {
passed : Bool
error_count : Int
warning_count : Int
info_count : Int
maximum_balance_residual_w : Int
maximum_grid_excess_w : Int
minimum_battery_state_wh : Int
maximum_battery_state_wh : Int
findings : Array[AuditFinding]
balances : Array[EnergyBalanceRow]
} derive(Eq, ToJson, Debug, FromJson)pub(all) struct BatterySpec {
name : String
capacity_wh : Int
initial_wh : Int
reserve_wh : Int
minimum_wh : Int
maximum_wh : Int
maximum_charge_w : Int
maximum_discharge_w : Int
charge_efficiency_permille : Int
discharge_efficiency_permille : Int
cycle_cost_micro_per_kwh : Int
} derive(Eq, ToJson, Debug, FromJson)fn BatterySpec::new(name : String, capacity_wh : Int, initial_wh : Int, reserve_wh : Int, maximum_charge_w : Int, maximum_discharge_w : Int) -> BatterySpecpub(all) struct CandidatePlacement {
task_id : String
start_slot : Int
end_slot : Int
energy_cost_component : Int
carbon_component : Int
comfort_component : Int
resilience_component : Int
capacity_excess_w : Int
solar_overlap_wh : Int
total_score : Int
feasible : Bool
} derive(Eq, ToJson, Debug, FromJson)fn Explanation::warning(code : String, subject : String, message : String, slot? : Int) -> Explanationpub(all) struct LoadTask {
id : String
name : String
mode : TaskMode
priority : Priority
power_w : Int
duration_slots : Int
earliest_start : Int
latest_end : Int
preferred_start : Int
fixed_start : Int
minimum_run_slots : Int
maximum_interruptions : Int
comfort_penalty_per_slot : Int
skip_penalty : Int
tags : Array[String]
} derive(Eq, ToJson, Debug, FromJson)fn OutageEvent::blackout(id : String, start_slot : Int, end_slot : Int, description? : String) -> OutageEventpub(all) struct PlanComparison {
baseline : PlanResult
optimized : PlanResult
cost_saving_micro : Int
carbon_saving_g : Int
peak_reduction_w : Int
resilience_gain_permille : Int
recommendation : String
} derive(Eq, ToJson, Debug, FromJson)pub(all) struct PlanDelta {
baseline_title : String
candidate_title : String
cost_delta_micro : Int
carbon_delta_g : Int
peak_delta_w : Int
unserved_delta_wh : Int
critical_unserved_delta_wh : Int
resilience_delta_permille : Int
comfort_delta : Int
completed_task_delta : Int
candidate_dominates : Bool
baseline_dominates : Bool
tradeoff_count : Int
summary : Array[String]
} derive(Eq, ToJson, Debug, FromJson)pub(all) struct PlanMetrics {
imported_energy_wh : Int
exported_energy_wh : Int
solar_used_wh : Int
solar_curtailed_wh : Int
battery_charged_wh : Int
battery_discharged_wh : Int
cost_micro : Int
export_credit_micro : Int
carbon_g : Int
comfort_penalty : Int
unserved_energy_wh : Int
critical_unserved_wh : Int
completed_tasks : Int
skipped_tasks : Int
peak_grid_w : Int
resilience_permille : Int
score : Int64
} derive(Eq, ToJson, Debug, FromJson)pub(all) struct PlanResult {
title : String
status : PlanStatus
slot_minutes : Int
horizon_slots : Int
schedule : Array[ScheduleEntry]
battery_steps : Array[BatteryStep]
load_w : Array[Int]
grid_w : Array[Int]
solar_used_w : Array[Int]
unserved_w : Array[Int]
battery_state_wh : Array[Int]
skipped_task_ids : Array[String]
metrics : PlanMetrics
explanations : Array[Explanation]
} derive(Eq, ToJson, Debug, FromJson)pub(all) struct PlanningInput {
title : String
slot_minutes : Int
horizon_slots : Int
tariff_micro_per_kwh : IntSeries
carbon_g_per_kwh : IntSeries
solar_w : IntSeries
base_load_w : IntSeries
grid_limit_w : IntSeries
tasks : Array[LoadTask]
battery : BatterySpec?
outages : Array[OutageEvent]
weights : ObjectiveWeights
allow_grid_export : Bool
export_credit_micro_per_kwh : Int
random_seed : UInt
} derive(Eq, ToJson, Debug, FromJson)pub(all) struct ScenarioSample {
index : Int
seed : UInt
solar_factor_permille : Int
base_load_factor_permille : Int
tariff_factor_permille : Int
largest_spike_slot : Int
largest_spike_w : Int
outage_start_slots : Array[Int]
outage_duration_slots : Array[Int]
input : PlanningInput
} derive(Eq, ToJson, Debug, FromJson)pub(all) struct SensitivityCase {
id : String
label : String
changed_parameter : String
change_permille : Int
status : PlanStatus
metrics : PlanMetrics
delta_cost_micro : Int
delta_carbon_g : Int
delta_unserved_wh : Int
delta_resilience_permille : Int
} derive(Eq, ToJson, Debug, FromJson)pub(all) struct SimulationRun {
index : Int
seed : UInt
solar_factor_permille : Int
base_load_factor_permille : Int
tariff_factor_permille : Int
largest_spike_slot : Int
largest_spike_w : Int
outage_duration_slots : Array[Int]
status : PlanStatus
metrics : PlanMetrics
scheduled_tasks : Int
explanation_count : Int
} derive(Eq, ToJson, Debug, FromJson)pub(all) struct SimulationSummary {
title : String
requested_runs : Int
completed_runs : Int
feasible_runs : Int
infeasible_runs : Int
risk_band : RiskBand
cost_micro : DistributionSummary
carbon_g : DistributionSummary
unserved_energy_wh : DistributionSummary
critical_unserved_wh : DistributionSummary
peak_grid_w : DistributionSummary
resilience_permille : DistributionSummary
worst_run_index : Int
best_run_index : Int
runs : Array[SimulationRun]
recommendations : Array[String]
} derive(Eq, ToJson, Debug, FromJson)pub(all) struct UncertaintyConfig {
solar_min_permille : Int
solar_max_permille : Int
base_load_min_permille : Int
base_load_max_permille : Int
tariff_min_permille : Int
tariff_max_permille : Int
outage_start_jitter_slots : Int
outage_duration_jitter_slots : Int
temporary_spike_probability_permille : Int
temporary_spike_min_w : Int
temporary_spike_max_w : Int
correlated_signal_permille : Int
} derive(Eq, ToJson, Debug, FromJson)pub(all) enum ValidationCode {
InvalidHorizon
InvalidSlotMinutes
SeriesLengthMismatch
SeriesSlotMismatch
NegativeSeriesValue
InvalidTaskId
DuplicateTaskId
InvalidTaskPower
InvalidTaskDuration
InvalidTaskWindow
FixedTaskOutsideWindow
InvalidInterruptionRule
InvalidBatteryCapacity
InvalidBatteryState
InvalidBatteryPower
InvalidBatteryEfficiency
InvalidBatteryReserve
InvalidOutageWindow
InvalidGridLimit
InvalidObjectiveWeights
ImpossibleRequiredTask
PeakCapacityRisk
MissingTariffVariation
MissingCarbonVariation
ExportWithoutCredit
} derive(Eq, ToJson, Debug, FromJson)pub(all) struct ValidationIssue {
code : ValidationCode
level : IssueLevel
path : String
message : String
hint : String
slot : Int?
task_id : String?
} derive(Eq, ToJson, Debug, FromJson)fn ValidationIssue::advice(code : ValidationCode, path : String, message : String, hint : String) -> ValidationIssuefn ValidationIssue::error(code : ValidationCode, path : String, message : String, hint? : String) -> ValidationIssuefn ValidationIssue::warning(code : ValidationCode, path : String, message : String, hint? : String) -> ValidationIssuefn audit_plan(input : PlanningInput, result : PlanResult, balance_tolerance_w? : Int) -> AuditSummaryfn candidate_placements(input : PlanningInput, task : LoadTask, current_load_w : Array[Int], config? : SolverConfig) -> Array[CandidatePlacement]fn capability_summary() -> Stringfn evaluate_candidate(input : PlanningInput, task : LoadTask, start_slot : Int, current_load_w : Array[Int], config? : SolverConfig) -> CandidatePlacementfn pareto_frontier(results : Array[(PlanningPolicy, PlanResult)]) -> Array[(PlanningPolicy, PlanResult)]fn sample_scenario(input : PlanningInput, config : UncertaintyConfig, index : Int) -> ScenarioSamplefn simulate(input : PlanningInput, runs? : Int, uncertainty? : UncertaintyConfig, solver_config? : SolverConfig) -> SimulationSummaryfn solve_policy_set(input : PlanningInput, config? : SolverConfig) -> Array[(PlanningPolicy, PlanResult)]Offline household energy scheduling and outage resilience simulation