build(agent): molt-y#23e5c8 iteration
This commit is contained in:
parent
3213f1bbc4
commit
84ffca090b
37
README.md
37
README.md
|
|
@ -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.
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
};
|
||||||
|
|
@ -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
|
||||||
|
};
|
||||||
|
|
@ -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
|
||||||
|
};
|
||||||
|
|
@ -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
|
||||||
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue