build(agent): molt-by#23c260 iteration

This commit is contained in:
agent-23c260159794913b 2026-04-16 22:52:44 +02:00
parent fd7a31cbb7
commit c1c97d236d
7 changed files with 147 additions and 1 deletions

View File

@ -21,7 +21,7 @@ Usage
- This repository now includes a lightweight EnergiBridge canonical bridge to map GridResilience primitives to vendor-agnostic representations and starter adapters for IEC 61850 and a microgrid simulator. These scaffolds enable cross-domain interoperability while preserving offline-first operation.
- The EnergiBridge bridge lives at `src/gridresilience_studio/bridge.py` and adapters live under `src/gridresilience_studio/adapters/` as a Python package.
- Adapters scaffold contains: `IEC61850Adapter` and `MicrogridSimulatorAdapter` as starter implementations.
- The MVP wiring includes: 2 starter adapters, a minimal LocalProblem/SharedSignals/PlanDelta sketch, and a toy delta-sync surface that can replay deterministically. See src/gridresilience_studio/energi_bridge.py and adapters/ for details.
- The MVP wiring includes: 2 starter adapters, a minimal LocalDevicePlan/SharedSignal/PlanDelta sketch (via the DSL sketch in src/gridresilience_studio/dsl_sketch.py), and a toy delta-sync surface that can replay deterministically. See src/gridresilience_studio/energi_bridge.py, src/gridresilience_studio/dsl_sketch.py, and adapters/ for details.
- This remains a seed MVP; additional phases will introduce governance ledger, secure identities, and cross-domain dashboards in subsequent iterations.
- Usage

View File

@ -7,3 +7,5 @@ can be composed by orchestration logic.
from .iec61850 import IEC61850Adapter # noqa: F401
from .simulator import MicrogridSimulatorAdapter # noqa: F401
from .water_pump import WaterPumpAdapter # noqa: F401
from .hvac import HVACAdapter # noqa: F401

View File

@ -0,0 +1,25 @@
"""Toy HVAC adapter scaffold for GridResilience Studio.
This adapter demonstrates a simple cross-domain bridge contract for a building HVAC controller.
"""
from __future__ import annotations
from typing import Dict, Any
from gridresilience_studio.core import Object, PlanDelta
class HVACAdapter:
def __init__(self, endpoint: str = "localhost", port: int = 1882):
self.endpoint = endpoint
self.port = port
def connect(self) -> bool:
return True
def apply_delta(self, delta: PlanDelta) -> PlanDelta:
delta.tags["hvac"] = "applied"
return delta
def read_object(self, obj: Object) -> Dict[str, Any]:
return {"id": obj.id, "state": "cooling"}

View File

@ -0,0 +1,29 @@
"""Toy Water Pump adapter scaffold for GridResilience Studio.
This adapter demonstrates a simple cross-domain bridge contract for a water
pump controller. It is intentionally minimal and TLS-wiring is left as a future
enhancement for production readiness.
"""
from __future__ import annotations
from typing import Dict, Any
from gridresilience_studio.core import Object, PlanDelta
class WaterPumpAdapter:
"""Lightweight scaffold for a water pump controller adapter."""
def __init__(self, endpoint: str = "localhost", port: int = 1881):
self.endpoint = endpoint
self.port = port
def connect(self) -> bool:
return True
def apply_delta(self, delta: PlanDelta) -> PlanDelta:
delta.tags["water_pump"] = "updated"
return delta
def read_object(self, obj: Object) -> Dict[str, Any]:
return {"id": obj.id, "state": "operational"}

View File

@ -0,0 +1,37 @@
from __future__ import annotations
from dataclasses import dataclass, field
from typing import Dict, Optional
from .core import Object
@dataclass
class RegistryEntry:
adapter_id: str
contract_version: str
data_contract: Dict[str, object] = field(default_factory=dict)
timestamp: Optional[str] = None
class GraphOfContractsRegistry:
"""In-memory registry for adapter data contracts and schemas.
This is a lightweight scaffold to enable a Graph-of-Contracts-like
registry used by EnergiBridge to negotiate cross-domain interoperability.
"""
def __init__(self):
self._entries: Dict[str, RegistryEntry] = {}
def register(self, key: str, entry: RegistryEntry) -> None:
self._entries[key] = entry
def get(self, key: str) -> RegistryEntry | None:
return self._entries.get(key)
def all(self) -> Dict[str, RegistryEntry]:
return dict(self._entries)
__all__ = ["RegistryEntry", "GraphOfContractsRegistry"]

View File

@ -0,0 +1,44 @@
from __future__ import annotations
from dataclasses import dataclass, field
from typing import Any, Dict, List
from .core import Object, Morphism, PlanDelta
@dataclass
class LocalDevicePlan:
"""DSL sketch for a local device capability description.
This is a lightweight, vendor-agnostic description that can be mapped
to canonical GridResilience Studio primitives (Object) for runtime use.
"""
id: str
asset_type: str
capabilities: Dict[str, Any] = field(default_factory=dict)
@dataclass
class SharedSignal:
"""DSL sketch for a shared telemetry/policy signal between devices."""
id: str
source_id: str
target_id: str
signals: Dict[str, Any] = field(default_factory=dict)
version: int = 0
def to_object(lp: LocalDevicePlan) -> Object:
"""Convert a LocalDevicePlan to a canonical Object."""
return Object(id=lp.id, type=lp.asset_type, properties=lp.capabilities)
def to_morphism(sig: SharedSignal) -> Morphism:
"""Convert a SharedSignal to a canonical Morphism."""
return Morphism(id=sig.id, source=sig.source_id, target=sig.target_id, signals=sig.signals, version=sig.version)
def to_plan_delta(delta_id: str, islanded: bool, actions: List[Dict[str, Any]] | None = None) -> PlanDelta:
"""Create a PlanDelta from high-level islanding actions."""
actions = actions or []
return PlanDelta(delta_id=delta_id, islanded=islanded, actions=actions, tags={})

View File

@ -51,3 +51,12 @@ class EnergiBridge:
__all__ = ["LocalProblem", "SharedSignals", "EnergiBridge"]
# Lightweight extension hooks for DSL sketch interoperability
# These helpers enable easy mapping from the DSL sketch defined in
# dsl_sketch.py to canonical primitives used by the runtime.
try:
from .dsl_sketch import LocalDevicePlan, SharedSignal # type: ignore
except Exception:
LocalDevicePlan = None # type: ignore
SharedSignal = None # type: ignore