Skip to content

arcnode-io/ems

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 

Repository files navigation

EMS 🏭⚡

Overview

This series of repos is designed to teach real world skills when implementing modern energy systems. It covers everything from the sensors, to the UI (mobile and web), to predictive models, to AI agents. The three languages used are

  • 🌊 Typescript: Realtime UIs and APIs
  • 🐍 Python: LLM/ML Apps and Platform Engineering
  • 🦀 Rust: Grid Protocols and Embedded Systems

Project Description

The EMS (Energy Management System) suite is the software that runs on a deployed Arcnode stack. It allows you to model different smart grid systems. For example, you could model a dynamic dlr system with a datacenter load. The bess could be modeled with canbus measurements and the datacenter could be modeled as snmp and bacnet readings.

Diagrams

Deployment*

collections "mock_industrial_protocols**" as mock_industrial_protocols
rectangle  "front of the meter" #line.dashed {
  collections dlr_sensors
  rectangle phase_shift_transformer
}
cloud ercot_api
cloud third_party_apis
rectangle cluster #line.dashed {
    rectangle industrial_gateway
    rectangle line_controller
    rectangle device_api
    database timeseries
    database vector
    database graph
    collections analyst_api
    database document
    collections ems_hmi
    person llm
    rectangle domain_mcp_server
dlr_sensors -d- line_controller
phase_shift_transformer -d- line_controller
mock_industrial_protocols -d- industrial_gateway
ercot_api -r- timeseries
line_controller -d- device_api
industrial_gateway -d- device_api
device_api -d- ems_hmi
device_api -r- document
timeseries -r- analyst_api
domain_mcp_server -u- llm
vector -u- domain_mcp_server
graph -u- domain_mcp_server
analyst_api -d- ems_hmi
llm -u- analyst_api
llm -l- third_party_apis

* MQTT broker ommited for simplicity
** canbus, modbus, dnp3, snmp, bacnet, and ocpp,

Sequence

actor operator
participant device_api
database document
participant industrial_gateway
participant line_controller
participant broker
database timeseries
database vector
database graph
participant domain_mcp_server
participant llm
participant analyst_api
participant ems_hmi
participant ercot_api
collections third_party_apis
operator -> device_api: POST /topology (from DTM)
device_api -> document: generate AsyncAPI v3 spec
== distribute topics ==
industrial_gateway -> device_api: GET /asyncapi
line_controller -> device_api: GET /asyncapi
ems_hmi -> device_api: GET /asyncapi
==  initialize messaging ==
industrial_gateway -> broker: pub grid protocols
line_controller -> broker: pub direct sensor data
broker -> timeseries: writes to db
broker -> ems_hmi: renders live data
== ml workflows ==
ercot_api -> analyst_api: GET /solar-production
timeseries <- analyst_api: trains model
analyst_api -> ems_hmi: renders prediction
== ai agent workflows ==
ems_hmi -> analyst_api: GET /chat/completions  
analyst_api -> llm: query
llm -> domain_mcp_server: tool call
domain_mcp_server -> vector: agentic rag
domain_mcp_server -> graph: graph rag
llm -> third_party_apis: external api tool call
llm -> analyst_api: api prediction tool call
analyst_api -> llm: prediction response
llm -> analyst_api: synthesizes rag dbs and apis call
analyst_api -> ems_hmi: renders chat

Cloud Deployment (AWS)

rectangle ecs_cluster #line.dashed {
    rectangle analyst_agent
    rectangle analyst_model
    rectangle device_api
    queue emqx
    rectangle ems_hmi
    rectangle mlflow
    rectangle prometheus
    rectangle grafana
    rectangle industrial_gateway
    rectangle analyst_server
}

database s3

rectangle managed_persistence #line.dashed {
    cloud timescale_cloud 
    cloud neon_vector
    cloud neon_document
    cloud neo4j_aura 
}

rectangle third_party_apis #line.dashed {
    cloud ercot_api
    cloud openweather
    cloud yes_energy
    cloud permutable
}

On-Prem Deployment (ISO)

rectangle daemons #line.dashed {
    database postgres_timescale 
    database postgres_document 
    database postgres_vector
    database neo4j
    database minio
    rectangle ollama {
      rectangle llama
      rectangle nomic_embed
    }
    }

    rectangle docker_runtime #line.dashed {
    rectangle device_api
    rectangle industrial_gateway
    rectangle analyst_server
    rectangle analyst_agent
    rectangle analyst_model
    rectangle ems_hmi
    rectangle mlflow
    queue emqx
    rectangle prometheus
    rectangle grafana
}

E2E Testing

Nightly job in a staging environment. Exercises the full data flow across all services.

participant ci_runner
participant device_api
participant industrial_gateway
participant industrial_fixtures
queue broker
participant ems_hmi
database timeseries
participant analyst_api

ci_runner -> device_api: POST /topology (test DTM)
device_api -> device_api: generate AsyncAPI spec

industrial_gateway -> device_api: GET /asyncapi
industrial_fixtures -> device_api: GET /asyncapi
ems_hmi -> device_api: GET /asyncapi

== fixture telemetry ==
industrial_fixtures -> broker: publish sim measurements
broker -> industrial_gateway: forward
broker -> ems_hmi: forward
broker -> timeseries: persist

== analyst ==
analyst_api -> timeseries: query
analyst_api -> ci_runner: predictions + chat response

== assertions ==
ci_runner -> timeseries: verify measurements persisted
ci_runner -> ems_hmi: verify render (headless)
ci_runner -> analyst_api: verify predictions + chat

Project Structure

Repositories

The following repositories make up the EMS suite:

About

EMS umbrella — project overview, diagrams, and ADR

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors