build(agent): molt-y#23e5c8 iteration

This commit is contained in:
agent-23e5c897f40fd19e 2026-04-15 20:47:42 +02:00
parent 3213f1bbc4
commit 84ffca090b
5 changed files with 113 additions and 48 deletions

View File

@ -1,26 +1,21 @@
# Open-EnergyMesh Offline-First MVP (Node.js) # Open-EnergyMesh MVP: Offline-First Distributed Microgrid Orchestration (0.2 protocol)
This repository provides a minimal Open-EnergyMesh scaffold focused on an offline-first, distributed microgrid orchestration flow. It implements a small in-memory data model (Device, Inverter, Meter, DER, PriceQuote, Forecast) and a lightweight EnergyMesh orchestrator with a simple energy-flow calculation. It also includes a placeholder ADMM-like solver to demonstrate how a compositional optimization layer can be integrated on top of the runtime. This repository contains a minimal Open-EnergyMesh MVP focused on offline-first operation
and displacement of vendor lock-in through a lightweight, pluggable architecture.
What you get in this MVP: - Core MVP: in-memory mesh with Inverter and Meter models and a tiny ADMM-lite integration path
- Core data model for energy devices and components - 0.2 protocol scaffold: LocalProblem / SharedVariables / PlanDelta contracts (protocol.js)
- Basic energy-flow computation: generation minus consumption - Adapters: reference adapters for inverter and meter demonstrating plug-and-play interoperability
- A lightweight ADMM-lite adapter surface (solver_admm.js) - Solver: lightweight ADMM placeholder (solver_admm.js) to illustrate integration points
- Delta-sync helper and an API surface to apply per-device deltas - Delta-sync: MVP delta application via EnergyMesh.applyDeltaSync
- Simple tests that exercise computeFlow, delta-sync, and ADMM integration
- Lightweight, well-scoped scaffolding suitable for MVP testing and iteration
Usage How to run tests
- Install dependencies: npm install - npm install
- Run tests: npm test - npm test
- The repository exports Open-EnergyMesh primitives via src/mesh.js for extension.
Roadmap (high level) Notes
- Finalize a 0.2 core protocol and two starter adapters - This MVP intentionally keeps the surface small and extensible for future CatOpt-style composition and cross-vendor adapters.
- Implement an ADMM-lite local solver with offline/partially-connected rounds (delta-sync) - See src/mesh.js for the current MVP data model and orchestration primitives.
- Add privacy-preserving options and governance hooks
- Provide a small reference adapter SDK and HIL testbed
This project is designed to be extended incrementally. See AGENTS.md for architectural rules and contribution guidelines. Marketing and publishing
- When ready, publish readiness is signaled by creating a READY_TO_PUBLISH file at the repo root.
Commit messages follow a concise rationale-focused style suitable for collaborative reviews.

View File

@ -0,0 +1,26 @@
// Minimal inverter adapter scaffold
// Demonstrates a plug-in adapter exposing a small interface.
class InverterAdapter {
constructor(id) {
this.id = id;
}
// Example: read current state from the device (mock)
readState() {
return {
id: this.id,
outputW: 0
};
}
// Example: apply a command to the device (mock)
applyCommand(cmd) {
// no-op in MVP
return { success: true, command: cmd };
}
}
module.exports = {
InverterAdapter
};

21
adapters/meter_adapter.js Normal file
View File

@ -0,0 +1,21 @@
// Minimal meter adapter scaffold
class MeterAdapter {
constructor(id) {
this.id = id;
}
readState() {
return {
id: this.id,
consumptionW: 0
};
}
applyCommand(cmd) {
return { success: true, command: cmd };
}
}
module.exports = {
MeterAdapter
};

31
src/protocol.js Normal file
View File

@ -0,0 +1,31 @@
// Lightweight protocol scaffold for Open-EnergyMesh 0.2 core ontology
// This file provides tiny, versioned data contracts used by adapters.
class LocalProblem {
constructor(version = '0.2') {
this.version = version;
this.variables = {}; // local optimization variables
this.constraints = []; // local constraints
this.objective = null; // objective description or function reference
}
}
class SharedVariables {
constructor() {
this.variables = {}; // dual/shared variables (e.g., Lagrange multipliers)
this.metadata = {};
}
}
class PlanDelta {
constructor(timestamp = Date.now()) {
this.timestamp = timestamp;
this.changes = {}; // delta payload describing what changed
}
}
module.exports = {
LocalProblem,
SharedVariables,
PlanDelta
};

View File

@ -1,35 +1,27 @@
// Minimal ADMM-lite solver scaffold for Open-EnergyMesh MVP // Minimal ADMM-lite solver placeholder for Open-EnergyMesh MVP
// This is deliberately small and deterministic to support offline-first testing // This module is intentionally lightweight: it provides a skeleton class
// that can be extended by adapters in downstream integrations.
class AdmmSolver { class AdmmSolver {
constructor() { constructor() {
// internal state kept for demonstration purposes // no state for MVP; placeholder for future stateful solvers
this.lastPrimal = null;
this.lastDual = null;
} }
// Simulated solve step for a local problem. Accepts simple objects but does not /**
// perform real optimization in order to keep MVP lightweight. * Solve a local optimization problem given a shared variable state.
step(localProblem, sharedVariables) { * For the MVP, we return null to indicate no local adaptation is applied,
// Very small, deterministic envelope: echo inputs with tiny adjustments * allowing the caller to fall back to baseline flow calculation.
const primal = { *
vars: (localProblem && localProblem.vars) ? { ...localProblem.vars } : {}, * @param {Object} localProblem - simplified representation of the local optimization problem
objective: (localProblem && localProblem.objective) ? localProblem.objective : 0 * @param {Object} sharedVariables - shared variables/state used in ADMM iterations
}; * @returns {Object|null} adaptation results or null to indicate no adaptation
const dual = { */
multipliers: (sharedVariables && sharedVariables.multipliers) ? { ...sharedVariables.multipliers } : {} solve(localProblem, sharedVariables) {
}; // MVP: do not modify flow; keep baseline behavior.
return null;
// Simple synthetic adjustment to demonstrate progress without external solvers
if (primal.vars && typeof primal.vars.value === 'number') {
primal.vars.value = primal.vars.value * 1.0; // no-op, placeholder for real update
primal.objective = (primal.objective || 0) + 0;
}
this.lastPrimal = primal;
this.lastDual = dual;
return { primal, dual };
} }
} }
module.exports = { AdmmSolver }; module.exports = {
AdmmSolver
};