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 会根据电网放电功率做动态控制调控储能放电功率,储能百分比也会随着充放电波动

相关推荐
TanYYF1 小时前
spring ai入门教程一
java·人工智能·spring
掉鱼的猫1 小时前
用 ChatModel 构建 LLM 驱动的 Java 应用
java·llm
4154111 小时前
JTS 空间运算实战:线 × 线、线 × 面、面 × 面叠加分析
java·jts·叠加分析
.Hypocritical.2 小时前
数据结构笔记——链表成环/反转 + 有序二叉树(BST)构建、遍历、删除
java·数据结构
只会写代码2 小时前
一套开箱即用实体反射Lambda链式工具,彻底告别原生反射样板代码
java·程序员·源码
AI人工智能+电脑小能手2 小时前
【大白话说Java面试题 第151题】【06_Spring篇】第11题:说一下 Spring Bean 的生命周期?
java·开发语言·后端·spring·面试
骑士雄师2 小时前
java面试题:jvm ,mybatis
java·jvm·mybatis
广州浮点FLOATLIC2 小时前
Creo 许可证利用率怎么优化:制造企业该先看共享规则,还是先看模块占用结构
java·开发语言
2601_962440842 小时前
计算机毕业设计之jsp教室管理系统
java·开发语言·笔记·分布式·算法·课程设计·推荐算法