title: 调度配置脚本化
待与Cola Ji核对。
为适应用户多变的调度需求,在EMS中实现了一套调度配置解析功能,通过云后台下发设备调度配置脚本给EMS,实现EMS的实时调度定制化功能。
sequenceDiagram
云后台-->>+EMS: 355 - 查询调度策略
EMS-->>-云后台: 356 - 响应当前调度策略
协议格式
请求
// 355 - 查询调度策略
{
opt: number, // 操作项:1-查询调度策略列表;2-查询调度策略详情
sn: string, // 设备序列号
// opt=2时,填写项
id: number // 指定调度策略ID
}
响应
// 356 - 能量调度策略查询应答
{
opt: number, // 操作项:1-查询调度策略列表;2-查询调度策略详情
result: number, // 请求结果:0-成功;1-失败
// opt=1时,返回项
current_id: number, // 当前应用的调度策略ID
list: [ // EMS存在的调度策略总表
{
id: number, // 调度策略ID
name: string, // 调度策略名
electricity_type: number, // 电价类型:1-分时电价;2-阶梯电价;3-固定电价;4-分时&阶梯电价;5-BB套餐;6-Peak Demand
reserved_soc: number, // 备电预留SOC(用户设定)
scheduling_type: number // 调度模式类型:1-TOU;2-自发自用;3-仅备电
},
...
],
// opt=2时,返回项
data: Schedule // 详细电度策略(后面章节详细介绍)
}
sequenceDiagram
云后台-->>+EMS: 357 - 增加调度策略
EMS-->>-云后台: 358 - 响应操作成功或失败
云后台-->>+EMS: 357 - 删除调度策略
EMS-->>-云后台: 358 - 响应操作成功或失败
云后台-->>+EMS: 357 - 切换当前调度策略
EMS-->>-云后台: 358 - 响应操作成功或失败
协议格式
请求
// 357 - 能量调度策略增加、删除和应用设置
{
opt: number, // 操作项:1-增加或编辑(覆盖);2-删除;3-切换当前调度策略
sn: string,
// opt=1时,填写项
data: Schedule, // 详细电度策略(后面章节详细介绍)
// opt=2时,填写项
id: number[], // 电度策略ID的数组,要删除的策略ID
// opt=3时,填写项
current_id: number // 需要切换的调度策略ID
}
响应
// 358 - 能量调度策略增加、删除和应用设置应答
{
opt: number, // 操作项:1-增加或编辑(覆盖);2-删除;3-切换当前调度策略
result: number // 操作结果:0-成功;1-失败
}
脚本数据基本格式为JSON格式
// Schedule
{
yearStra: number[], // 年策略选择表,表中数值代表策略ID,最多366个数据,每个数据代表1天,从1月1日开始。
calendar: // 日历表???
name: string, // 策略表名称
id: number, // 策略表ID
startTime: string, // 策略表生效时间,格式:“YYYY-MM-DD hh:mm:ss”,eg:”2024-03-05 13:41:00”,基于设备时区
duration: number, // 策略表生效持续时间,单位:秒,0表示生效后永久持续
intervalTime: number, // 间隔时间,单位:秒,默认0-无间隔 ???如何执行
startEvent: number, // 开始事件,被关联的事件触发后,执行本策略表。填写事件ID,默认0-无关联事件 ???理解是否正确
endEvent: number, // 结束事件,被关联的事件触发后,退出本策略表。填写事件ID,默认0-无关联事件 ???理解是否正确,退出会进入哪个策略表?
nextmode: number, // 事假退出后,运行的模式。默认2-自发自用模式(系统标准模式) ???是否可以填写策略ID,退到进入前的策略表?
electricity_type: number, // 电价类型:1-分时电价;2-阶梯电价;3-固定电价;4-分时&阶梯电价;5-BB套餐;6-Peak Demand
scheduling_type: number, // 调度模式类型:1-TOU;2-自发自用;3-仅备电
reserved_soc: number, // 备电预留SOC,默认20%,只支持整数,精度1%
loop: number, // 模式执行次数 ???如何理解这个循环
priority: number, // 模式优先级,可选,默认为 0,0 优先级最低,数字越⼤优先级越⾼ ???优先级如何应用?
env: number, // 模式使⽤条件,可选,默认为 0,⽬前包括是否安装光伏,是否允许馈⽹,是否允许电⽹充电。
// bit0~1:00,不涉及,01,未安装光伏,10,已安装光伏;
// bit2~bit3:00,不涉及,01,不允许馈⽹,10,允许馈⽹;
// bit4~bit5:00,不涉及,01,不允许电⽹充电,10,允许电⽹充电;其他预留
list: [ // 策略类型表,年策略选择表中使用的数据出自这个list,将策略设置到每一天
{
id: number, // 策略ID
season: string, // 季节名,也可以是别的名称,用于用户标识策略的范围,可自定义填写
dayType: string, // 日期类型,可自定义填写,一般为:workday、weekday、everyday等
list: [ // 时间段策略表,所有配置的时间需覆盖一整天
{
start_time: string, // 开始时间,格式:“hh:mm”
end_time: string, // 结束时间,格式:“hh:mm”,end_time需与下一个start_time重叠
flag: number, // 峰平⾕定义,可选,0:谷;1:平;2:峰;3:尖峰;4:低谷
name: string, // 时段名,可自定义,一般为:supper-off-peak、off-peak、mid-peak、on-peak、supper-on-peak等
describe: string, // 时段描述
solar_priority: [number, number, number], // 光伏供电优先级,[0]:市电, [1]:负载, [2]:FHP;优先级为0/1/2/3
// 可相同,若相同则表明需要按比例或者功率分配,0为不涉及,数字越大优先级越高
load_priority: [number, number, number], // 负载取电优先级,可选,[0]:市电, [1]:光伏, [2]:FHP;优先级为 0/1/2/3
// 可相同,若相同则表明需要按⽐例或者功率分配,0 为不涉及,数字越⼤优先级越⾼
grid_feed_max: number, // 电⽹允许最⼤馈⽹功率,0:不允许,-1:不限制,-2:未设置,可选,默认-2(aPbox 功率算在这⾥吗?不算)LoadSide也不算?
grid_max: number, // 电⽹允许最⼤取电功率,0:不允许,-1:不限制,可选,默认-1不限制 ???包括负载功率吗?
grid_discharge_max: number, // 电池最⼤允许馈⽹功率,可选,默认0不能馈⽹;0:不可馈⽹,-1:不限制;默认不使能,如果使能之后没有设置值,则为5kw*N(⽤-2标识) ???此处5kw*N是否有问题?
grid_charge_max: number, // 电⽹允许最⼤充电功率,可选,默认0不允许;0:不允许,-1:不限制;默认不使能,如果使能之后没有设置值,则为5kw*N(⽤-2标识) ???此处5kw*N是否有问题?
charge_max: number, // 电池最⼤允许充电功率,可选,按单台功率计算,-1:⽆限制,默认-1
discharge_max: number, // 电池最⼤允许放电功率,可选,按单台功率计算,-1:⽆限制,默认-1
charge_power: number, // 设置固定电池充电功率,可选,按单台功率计算,默认为-1:未设置
discharge_power: number, // 设置固定电池放电功率,可选,按单台功率计算,默认为-1:未设置
GCAO_max: number, // GCAO(grid charge after an outage),设备补电至预留SOC的单台市电取电功率
// 可选;0:不允许,-1:不限制;默认未设置(-3);如果使能之后没有设置值,则为5kw*N(⽤-2标识)
min_discharge_soc: number, // 放电截⽌SOC,预留 SOC,达到此SOC后电池不放电,可选,默认 0%,如果reserved_soc大于min_discharge_soc,则以reserved_soc为准。 ???需确认是否正确
max_charge_soc: number, // 充电截⽌SOC,可选,默认 100%
heat_enable: number, // 充电加热使能,0:未设置,1:不使能,2:使能,默认0未设置 ???生效项目?和充电是什么关系
ramp_time: number, // 爬坡时间,默认值 0,BB 套餐默认 300
poweroff_apower: number[], // 主动关闭 APower,可选,0:不控制(默认);1:关机;2:开机(预留)
off_grid: number, // 主动断开市电继电器,可选,0:不控制(默认);1:断开;2:闭合(预留)
solar_cutoff: number // 主动断开光伏继电器,可选,0:不控制(默认);1:断开;2:闭合(预留)
// 注:以上涉及到的所有功率值设置均以单台aPower为基准,计算总功率需乘以台数N。单位均为w。 ???此处是w还是kw,还是每个不同
},
...
]
},
...
]
}
算法与PCS相关联,待PCS文档完成后补充相关内容
单台aPower最终充电功率限制计算: $$ P_{apower-chrg-max} = \min(\verb|gridmax| - P{Load}, \verb|grid_charge_max|, \verb|charge_max|) $$
单台固定aPower充电功率计算: $$ P_{apower-chrg} = \min(\verb|chargepower|, P{apower-chrg-max}) $$
单台aPower最终放电功率限制计算: $$ P_{apower-dsch-max} = \min(\verb|grid_feedmax| - P{PV}, \verb|grid_discharge_max|, \verb|discharge_max|) $$
单台固定aPower放电功率计算: $$ P_{apower-dsch} = \min(\verb|dischargepower|, P{apower-dsch-max}) $$
当$P_{PV} > \verb|grid_feed_max|$是,设备会切断部分或全部光伏继电器,以削减光伏输出功率。
基础工作模式:
字符标识说明:
调度配置中,包含两个调度优先级的配置,光伏供电优先级(solar_priority)和负载取电优先级(load_priority)。
光伏供电优先级
光伏供电优先级是一个三个数值组成的一个数组配置,三个值分别代表三个供电目标的优先级:[市电,负载,aPower]。数值越大优先级越高,但0为特殊值,代表不为此目标供电。
负载取电优先级
负载优先级是一个三个数值组成的一个数组配置,三个值分别代表三个供电源的优先级:[市电,光伏,aPower]。数值越大优先级越高,但0为特殊值,代表不使用此供电源。
优先级配置表 <NormalTable :config="[
{
title: '光伏供电优先级',
key: 'PvPriority',
children: [
{
title: 'Grid',
align: 'center',
vertical: true
},
{
title: 'Load',
align: 'center',
vertical: true
},
{
title: 'aPower',
align: 'center',
vertical: true
}
]
},
{
title: '负载取电优先级',
key: 'LoadPriority',
children: [
{
title: 'Grid',
align: 'center',
vertical: true
},
{
title: 'PV',
align: 'center',
vertical: true
},
{
title: 'aPower',
align: 'center',
vertical: true
}
]
},
'说明'
]" :data="[
{
'PvPriority.Grid': {
text: 'a',
rowspan: 4
},
'PvPriority.Load': {
text: 'z',
rowspan: 4
},
'PvPriority.aPower': {
text: 'x',
rowspan: 4
},
'LoadPriority.Grid': 'a',
'LoadPriority.PV': 'z',
'LoadPriority.aPower': 'x',
'说明': '- 光伏优先供载,不足FHP补充,再不足市电补充。\n- 光伏剩余FHP充电。'
},
{
'LoadPriority.Grid': 'x',
'LoadPriority.PV': 'z',
'LoadPriority.aPower': 'a',
'说明': '- 光伏优先供载,不足市电补充,再不足FHP(到达市电取电限额)。\n- 光伏剩余FHP充电。'
},
{
'LoadPriority.Grid': '=',
'LoadPriority.PV': 'z',
'LoadPriority.aPower': '=',
'说明': '- 光伏优先供载,不足市电补充,FHP不放电(是否不符合配置?)。\n- 光伏剩余FHP充电。'
},
{
'LoadPriority.Grid': 'o',
'LoadPriority.PV': 'o',
'LoadPriority.aPower': 'o',
'说明': '- 光伏优先供载,不足市电补充。\n- 光伏剩余倒送电网。\n- FHP不充放电。'
},
{
'PvPriority.Grid': {
text: 'o',
rowspan: 4
},
'PvPriority.Load': {
text: 'z',
rowspan: 4
},
'PvPriority.aPower': {
text: 'o',
rowspan: 4
},
'LoadPriority.Grid': 'a',
'LoadPriority.PV': 'z',
'LoadPriority.aPower': 'x',
'说明': '- 光伏优先供载,不足FHP补充,再不足市电补充。\n- 光伏剩余倒送电网。\n- FHP不充电。'
},
{
'LoadPriority.Grid': 'o',
'LoadPriority.PV': 'z',
'LoadPriority.aPower': 'o',
'说明': '- 光伏优先供载,不足市电补充。\n- 光伏剩余倒送电网。\n- FHP不充放电。'
},
{
'LoadPriority.Grid': 'a',
'LoadPriority.PV': 'x',
'LoadPriority.aPower': 'z',
'说明': '设置电网放电(为何设置电网充电?)\n- FHP优先供载,不足光伏补充,在不足市电不足。\n- 剩余光伏倒送市电。'
},
{
'LoadPriority.Grid': 'o',
'LoadPriority.PV': 'o',
'LoadPriority.aPower': 'z',
'说明': '设置电网放电(为何设置电网充电?)\n- 光伏优先供载,不足市电补充。\n- 光伏剩余倒送电网。\n- FHP不充放电。'
},
{
'LoadPriority.Grid': 'o',
'LoadPriority.PV': 'o',
'LoadPriority.aPower': 'o',
'说明': '- 光伏优先供载,不足市电补充。\n- 光伏剩余倒送电网。\n- FHP不充放电。'
},
{
'PvPriority.Grid': 'a',
'PvPriority.Load': 'x',
'PvPriority.aPower': 'z',
'LoadPriority.Grid': 'x',
'LoadPriority.PV': 'x',
'LoadPriority.aPower': 'x',
'说明': '设置电网充电(为何设置电网充电?)\n- 光伏优先给FHP充电,剩余供载,再剩余倒送电网。\n- 光伏无剩余,电网供载。'
},
{
'PvPriority.Grid': 'o',
'PvPriority.Load': 'o',
'PvPriority.aPower': 'z',
'LoadPriority.Grid': 'x',
'LoadPriority.PV': 'x',
'LoadPriority.aPower': 'x',
'说明': '设置电网充电(为何设置电网充电?)\n- 光伏优先供载,不足市电补充。\n- 光伏剩余倒送电网。\n- FHP不充放电。'
},
{
'PvPriority.Grid': 'o',
'PvPriority.Load': 'o',
'PvPriority.aPower': 'o',
'LoadPriority.Grid': 'x',
'LoadPriority.PV': 'x',
'LoadPriority.aPower': 'x',
'说明': '- 光伏优先供载,不足市电补充。\n- 光伏剩余倒送电网。\n- FHP不充放电。'
},
]" />
:::info 注 x: 代表任意数值 \ y: 代表非0任意数值 \ z: 代表优先级最高数值 \ a: 代表优先级最低数值 \ =: 代表与其他=的优先级数值相同 \ o: 代表other,未说明的其他情况,其他优先配置 \ null: 无意义数值,即无论是几都没有意义 :::
:::warning 以上配置表已覆盖所有优先级配置的可能性,但有些配置执行情况可能与优先级表层逻辑相违背或不合理,但这是目前代码实际设计逻辑,待优化。。。 :::
优先级控制逻辑图
光伏优先级:[1,2,0],负载优先级:[1,3,2]
aPower不充电
---
config:
sankey:
showValues: false
---
sankey-beta
%% source,target,value
%% 剩余 -> Surplus
%% 更多剩余 -> More surplus
%% 优先补充 -> Priority supplement
%% 补充 -> Supplement
PV,Home loads,60
PV,Surplus,20
Surplus,Electricity grid exports,20
aPower discharge,Priority supplement,30
Priority supplement,Home loads,30
Electricity grid imports,Supplement,10
Supplement,Home loads,10
光伏优先级:[1,2,0],负载优先级:[1,2,3]
aPower不充电
---
config:
sankey:
showValues: false
---
sankey-beta
%% source,target,value
%% 剩余 -> Surplus
%% 更多剩余 -> More surplus
%% 优先补充 -> Priority supplement
%% 补充 -> Supplement
PV,Priority supplement,40
Priority supplement,Home loads,40
PV,Surplus,60
Surplus,Electricity grid exports,60
aPower discharge,Home loads,100
Electricity grid imports,Supplement,10
Supplement,Home loads,10
光伏优先级:[1,2,0],负载优先级:[1,2,0]
aPower待机
---
config:
sankey:
showValues: false
---
sankey-beta
%% source,target,value
%% 剩余 -> Surplus
%% 更多剩余 -> More surplus
%% 优先补充 -> Priority supplement
%% 补充 -> Supplement
PV,Home loads,60
PV,Surplus,20
Surplus,Electricity grid exports,20
Electricity grid imports,Supplement,20
Supplement,Home loads,20
光伏优先级:[1,2,0],负载优先级:[1,3,1] ??? 这里能写成[1,2,1]吗?
aPower不充电
---
config:
sankey:
showValues: false
---
sankey-beta
%% source,target,value
%% 剩余 -> Surplus
%% 更多剩余 -> More surplus
%% 优先补充 -> Priority supplement
%% 补充 -> Supplement
PV,Home loads,60
PV,Surplus,20
Surplus,Electricity grid exports,20
aPower discharge,Supplement,15
Electricity grid imports,Supplement,15
Supplement,Home loads,30
光伏优先级:[1,3,2],负载优先级:[1,2,0]
aPower不放电
---
config:
sankey:
showValues: false
---
sankey-beta
%% source,target,value
%% 剩余 -> Surplus
%% 更多剩余 -> More surplus
%% 优先补充 -> Priority supplement
%% 补充 -> Supplement
PV,Home loads,60
PV,Surplus,20
PV,More surplus,10
Surplus,aPower charge,20
More surplus,Electricity grid exports,10
Electricity grid imports,Supplement,30
Supplement,Home loads,30
光伏优先级:[1,3,2],负载优先级:[1,3,2]
光伏供载不足,由aPower支持,再不足由市电支持
---
config:
sankey:
showValues: false
---
sankey-beta
%% source,target,value
%% 剩余 -> Surplus
%% 更多剩余 -> More surplus
%% 优先补充 -> Priority supplement
%% 补充 -> Supplement
PV,Home loads,60
PV,Surplus,20
PV,More surplus,10
Surplus,aPower charge,20
More surplus,Electricity grid exports,10
aPower discharge,Priority supplement,30
Priority supplement,Home loads,30
Electricity grid imports,Supplement,10
Supplement,Home loads,10
光伏优先级:[1,3,2],负载优先级:[2,3,1]
光伏供载不足,由市电支持,再不足由aPower支持(可能是限制市电取电功率等情况,如诶限制则等同于L[1,2,0])
---
config:
sankey:
showValues: false
---
sankey-beta
%% source,target,value
%% 剩余 -> Surplus
%% 更多剩余 -> More surplus
%% 优先补充 -> Priority supplement
%% 补充 -> Supplement
PV,Home loads,60
PV,Surplus,20
PV,More surplus,10
Surplus,aPower charge,20
More surplus,Electricity grid exports,10
Electricity grid imports,Priority supplement,30
Priority supplement,Home loads,30
aPower discharge,Supplement,10
Supplement,Home loads,10
光伏优先级:[1,2,3],负载优先级:[1,2,0]
aPower不放电
---
config:
sankey:
showValues: false
---
sankey-beta
%% source,target,value
%% 剩余 -> Surplus
%% 更多剩余 -> More surplus
%% 优先补充 -> Priority supplement
%% 补充 -> Supplement
PV,aPower charge,60
PV,Surplus,20
PV,More surplus,10
Surplus,Home loads,20
More surplus,Electricity grid exports,10
Electricity grid imports,Supplement,30
Supplement,Home loads,30
光伏优先级:[1,2,2],负载优先级:[1,2,2]
???这是什么样的场景?
常规调度配置,只提供时间段策略的JSON配置。
标准自发自用模版使用P[1,3,2] - L[1,3,2]优先级组合配置。
// Time period schedule
{
start_time: "xx:xx",
end_time: "xx:xx",
flag: x,
name: "xx-peak",
describe: "Self-consumption",
solar_priority: [1,3,2],
load_priority: [1,3,2],
...
}
标准仅备电模版通过设置不限制电网充电和设置aPower固定采用最大功率充电,实现仅备电调度,强制给aPower充满,且持续保持aPower处于满电状态。
// Time period schedule
{
start_time: "xx:xx",
end_time: "xx:xx",
flag: x,
name: "xx-peak",
describe: "Emergency backup",
grid_charge_max: -1, // 设置不限制电网充电
charge_power: 8000, // 8Kw,当前单台aPower最大充电功率
...
}
强制aPower放电模版通过设置不限制aPower倒送电网和设置aPower固定采用最大功率放电,实现电池馈网调度(赚钱馈网收益),强制给aPower放电至用户设定的预留SOC。
// Time period schedule
{
start_time: "xx:xx",
end_time: "xx:xx",
flag: x,
name: "xx-peak",
describe: "Emergency backup",
grid_discharge_max: -1, // 设置不限制aPower馈网
discharge_power: 10000, // 10Kw,当前单台aPower最大放电功率
...
}