0. openems 部署与体验

部署与体验

准备运行环境

github 地址 https://github.com/OpenEMS/openems

在 releases 页下载最新的 openems-edge.jar

可选择 clone 项目到本地,本文不涉及源码但是后续可能会用到

项目 jdk 设置为至少 jdk21,可选将 gradle-wrapper.properties 内的 distributionUrl 修改为 https\://mirrors.cloud.tencent.com/gradle/gradle-xxx-bin.zip 或者其他国内镜像地址

启动 jar 并配置基础组件

启动 jar

启动 openems-edge.jar,控制台会一直报 There are no Schedulers configured! 这是正常的不用管它

管理页

进入 http://localhost:8080/system/console ,这是 felix 的管理页,felix 是一个 OSGI 容器的实现,负责管理模块(Bundle)、服务(Service)和组件(Component)

OSGI 容器负责模块级别的热插拔和动态路由服务,主要为了模块化来避免 "巨石应用"以及提供不停机更新能力,可以类比为是单个 JVM 内的微服务架构,其同样有独立部署单元、注册中心、服务发现等机制(但是其核心目标与实现上和微服务架构同样存在不小差别,最大的区别是 OSGI 没有进程及资源隔离且调用是本地方法调用而不是网络调用)

其页面菜单大致有以下

复制代码
OSGI
	Bundles
	Components
	Configuration
	Log Service
	Servies
Status
	Bundlelist
	Bundles
	Capabilities
	Configurations
	Declarative Services Components
	Framework Properties
	Overview
	Permissions
	Services
	System Properties
	Threads
	Wire Admin
Web Console
	Licenses
	System Information

其中需要重点关注的菜单大都在 OSGI 下

菜单 功能 在 OpenEMS 的作用
Configuration 配置管理-对象级别的管理 最常用的入口。 OpenEMS 把所有业务模块(调度器、控制器、模拟设备)都做成了工厂类。在这里点击 + 填表单保存,Felix 就会在内存里真正实例化出一个对应的跑着业务的设备或算法
Bundles 模块管理-代码级别管理 显示所有独立的 jar 包(Bundle)。可以随时在这里上传新的 jar、停止或启动某个模块。它实现了热部署能力
Components 组件管理-依赖级管理 显示底层组件类的注册状态
Log Service 日志查看 Felix 容器自身的日志和 OpenEMS 抛出的异常
Status -> Threads 线程快照 展示当前 JVM 里所有的线程状态
HelloWord

尝试添加模拟设备闭环一个场景

进入 OSGI -> Configuration 菜单,按顺序添加以下组件

添加方式为点击组件右侧 + 号,添加表单后点击 save 按钮创建

组件 表单(标注为 * 的修改项实际上是默认值,无需修改) 角色 详情
Simulator App 勾选 Is enabled? 提供仿真环境
Simulator Datasource: CSV Predefined id* 修改为 datasource0,Source 修改为 H0_HOUSEHOLD_SUMMER_WEEKDAY_STANDARD_LOAD_PROFILE(这个类型为归一化值,有96个点),Time-Delta 设置为15 (24分钟模拟现实一天) 模拟电表数据源
Simulator Datasource: CSV Predefined id 修改为 datasource1,Source 修改为 H0_HOUSEHOLD_SUMMER_WEEKDAY_PV_PRODUCTION(这个类型为真实值,有1440个点),Factor 修改为 1,Time-Delta 设置为1 (24分钟模拟现实一天) 模拟光伏数据源
Simulator GridMeter Reacting id* 修改为 meter0 模拟电网电表 读到"当前从电网买/卖了多少电"
Simulator NRCMeter Acting id 修改为 load0,Datasource-ID* 修改为 datasource0 模拟总负荷
Simulator EssSymmetric Reacting id* 修改为 ess0 模拟储能 接受充放电指令
Simulator Pv-Inverter id 修改为 pvInverter0,Datasource-ID 修改为 datasource1 模拟光伏 当前光伏发了多少电
Controller Ess Balancing id* 修改为 ctrlBalancing0,Ess-ID 修改为 ess0,Grid-Meter-ID 修改为 meter0 自消纳决策逻辑 核心:看 meter0,算 ess0 该充放多少
Scheduler All Alphabetically id* 修改为 scheduler0,Controller-IDs 修改为 ctrlBalancing0 决定每个 Cycle 跑哪些 Controller 把 ctrlBalancing0 纳入调度
Controller Api REST/JSON Read-Write Port 修改为任一可用端口,本文中将其修改为 18080 提供 REST API 外部观察用,不参与控制逻辑

关键配置及原因

Controller 关联 ess.idmeter.id:Controller 不直接操作设备,而是通过 Channel 读写。它需要知道"我要读哪个电表的功率"和"我要写哪个储能的功率指令"。这就是 OpenEMS 的解耦设计------Controller 只认 Channel,不认协议(Channel 是挂在 Component 下面的子级数据点,每个 Component 内部会声明一堆 Channel,分别代表它的某个具体读值或写值)

Scheduler 把 ctrlBalancing0 放进 controllers.ids:Scheduler 是 Cycle 调度器,它按这个列表决定执行哪些 controllers 以及 controllers 的执行顺序

datasource:模拟电表/光伏不会自己生成数据,它们只是"读 datasource 在当前时间点的值,乘以 factor,作为自己的 ActivePower"(这一点只针对模拟设备,真实设备是绑定 bridge 获取的数据)

注意到上述模拟设备中有 Acting 和 Reacting 两种,它们的区别是 Reacting 模拟设备不会主动决定自己的状态,而是根据系统其它组件的状态实时计算,Acting 模拟设备则主动向系统提供输入数据。在本次配置里,光伏和负荷用 Acting,作为系统的输入源;储能和电网电表用 Reacting,作为系统的响应结果。这样能量平衡公式 Grid = Load - PV - ESS 才能在 meter0 上动态体现出来,否则 Controller 看不到自己动作的反馈,整个闭环就断了。

这套配置构造了一个最小可运行系统,来验证 openems 的动态调整功能

验证

bash 复制代码
# 具体端口号为 Controller Api REST/JSON Read-Write 中设置的端口号
# REST 查询的地址格式是 {ComponentId}/{ChannelId}------前者是在 ConfigMgr 里给组件起的 ID(如 ess0),后者是组件按 Nature 接口规范暴露的数据点
curl -u admin:admin http://localhost:18080/rest/channel/ess0/Soc
curl -u admin:admin http://localhost:18080/rest/channel/ess0/ActivePower
curl -u admin:admin http://localhost:18080/rest/channel/meter0/ActivePower
curl -u admin:admin http://localhost:18080/rest/channel/pvInverter0/ActivePower

四个接口分别是查询储能百分比,储能放电功率,电网放电功率,光伏发电功率

配置的这个 controller 目标为使得电网放电功率接近 0,也就是光伏发电多了会尽量储能,光伏发电不够会从储能放能,实在不够的才会从电网来补充。如果需要实现更复杂的需求例如根据电网峰谷价格储能卖电需要配置其它的 controller 或者通过 scheduler 组合多个 controller 来实现

持续观察这几个接口的返回值应该能看到默认策略起到作用,openems 会根据电网放电功率做动态控制调控储能放电功率,储能百分比也会随着充放电波动

相关推荐
腻害兔1 小时前
【若依项目-产品经理视角】深度拆解 RuoYi-Vue-Pro 商城模块:从商品管理到交易引擎,50 张表撑起一整套电商系统
java·大数据·vue.js·产品经理·ai编程
码智社2 小时前
AES加密原理详解及Java实现加解密实战
java·开发语言
萧瑟余晖3 小时前
JDK 26 新特性详解
java·开发语言
马优晨4 小时前
Freemarker 完整讲解(后端 Java 模板引擎)
java·开发语言·freemarker·freemarker 完整讲解·freemarker模板引擎
维天说7 小时前
CLI-Switch 2026年3月版历史设计:Hook、TTY 隔离与 JSON 状态
java·服务器·json
Zane19947 小时前
并发 vs 并行:别再傻傻分不清了,一文讲透 Java 并发编程的第一课
java·后端
噢,我明白了8 小时前
java中Excel的导入和导出(EasyExcel)
java·开发语言·excel
吠品8 小时前
Zabbix Web界面误报Server未运行的排查与解决
java·服务器·数据库
啊湘8 小时前
天气查询API接口 按月Token鉴权 实时天气 物联网可用 文档齐全
java·后端·struts
Java内核笔记9 小时前
告别十亿美元的错误 : Spring Boot 4 空安全 (JSpecify) 实战
java·spring boot·后端