|
@@ -29,6 +29,7 @@ export type SchedulingType =
|
|
|
| 'F/H'
|
|
| 'F/H'
|
|
|
| 'G'
|
|
| 'G'
|
|
|
| 'H'
|
|
| 'H'
|
|
|
|
|
+ | 'noPriority'
|
|
|
| 'unknown'
|
|
| 'unknown'
|
|
|
|
|
|
|
|
const SchedulingMap: Record<SchedulingType, string> = {
|
|
const SchedulingMap: Record<SchedulingType, string> = {
|
|
@@ -42,49 +43,45 @@ const SchedulingMap: Record<SchedulingType, string> = {
|
|
|
'F/H': 'aPower prioritize home / aPower export to the grid(enable aPower export)',
|
|
'F/H': 'aPower prioritize home / aPower export to the grid(enable aPower export)',
|
|
|
G: 'aPower charge from grid', // E 使能电网充电的版本
|
|
G: 'aPower charge from grid', // E 使能电网充电的版本
|
|
|
H: 'aPower export to the grid', // F 使能aPower馈网的版本
|
|
H: 'aPower export to the grid', // F 使能aPower馈网的版本
|
|
|
|
|
+ noPriority: 'Self consumption (No priority)',
|
|
|
unknown: 'unknown',
|
|
unknown: 'unknown',
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+const SchedulingRules: {
|
|
|
|
|
+ match: [number, number, number, number, number, number]
|
|
|
|
|
+ type: SchedulingType
|
|
|
|
|
+}[] = [
|
|
|
|
|
+ { match: [1, 2, 0, 1, 3, 2], type: 'A' }, // Excess solar export to grid
|
|
|
|
|
+ { match: [1, 2, 0, 1, 2, 0], type: 'B' }, // aPower standby
|
|
|
|
|
+ { match: [1, 3, 2, 1, 2, 0], type: 'C' }, // Excess solar charge aPower
|
|
|
|
|
+ { match: [1, 3, 2, 1, 3, 2], type: 'D' }, // Self-consumption
|
|
|
|
|
+ { match: [1, 2, 3, 1, 2, 0], type: 'E/G' }, // aPower charge from solar
|
|
|
|
|
+ { match: [1, 2, 0, 1, 2, 3], type: 'F/H' }, // aPower prioritize home
|
|
|
|
|
+] as const
|
|
|
|
|
+
|
|
|
export interface TimePeriodSchedulingBriefInfo {
|
|
export interface TimePeriodSchedulingBriefInfo {
|
|
|
timePeriod: string // format: HH:MM - HH:MM
|
|
timePeriod: string // format: HH:MM - HH:MM
|
|
|
brief: string
|
|
brief: string
|
|
|
priceColor: PriceColorType // 峰平谷颜色
|
|
priceColor: PriceColorType // 峰平谷颜色
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+function arrayEqual<T>(a: readonly T[], b: readonly T[]) {
|
|
|
|
|
+ return a.length === b.length && a.every((v, i) => v === b[i])
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
export function parseSchedulingBriefInfo(
|
|
export function parseSchedulingBriefInfo(
|
|
|
info: TimeRangeSchedulingInfo,
|
|
info: TimeRangeSchedulingInfo,
|
|
|
): TimePeriodSchedulingBriefInfo {
|
|
): TimePeriodSchedulingBriefInfo {
|
|
|
const result: TimePeriodSchedulingBriefInfo = {
|
|
const result: TimePeriodSchedulingBriefInfo = {
|
|
|
timePeriod: `${info.startTime} - ${info.endTime}`,
|
|
timePeriod: `${info.startTime} - ${info.endTime}`,
|
|
|
brief: ((): string => {
|
|
brief: ((): string => {
|
|
|
- let schedulingType: SchedulingType = 'D' // 没有优先级时,默认 Self consumption
|
|
|
|
|
|
|
+ let schedulingType: SchedulingType = 'noPriority' // 没有优先级时,默认 Self consumption
|
|
|
|
|
|
|
|
// 判断优先级
|
|
// 判断优先级
|
|
|
- if (info.solarPriority != null && info.loadPriority != null) {
|
|
|
|
|
|
|
+ if (info.solarPriority !== undefined && info.loadPriority !== undefined) {
|
|
|
const priority = [...info.solarPriority, ...info.loadPriority]
|
|
const priority = [...info.solarPriority, ...info.loadPriority]
|
|
|
- switch (priority) {
|
|
|
|
|
- case [1, 2, 0, 1, 3, 2]: // A - Excess solar export to grid
|
|
|
|
|
- schedulingType = 'A'
|
|
|
|
|
- break
|
|
|
|
|
- case [1, 2, 0, 1, 2, 0]: // B - aPower standby
|
|
|
|
|
- schedulingType = 'B'
|
|
|
|
|
- break
|
|
|
|
|
- case [1, 3, 2, 1, 2, 0]: // C - Excess solar charge aPower
|
|
|
|
|
- schedulingType = 'C'
|
|
|
|
|
- break
|
|
|
|
|
- case [1, 3, 2, 1, 3, 2]: // D - Self-consumption
|
|
|
|
|
- schedulingType = 'D'
|
|
|
|
|
- break
|
|
|
|
|
- case [1, 2, 3, 1, 2, 0]: // E - aPower charge from solar
|
|
|
|
|
- schedulingType = 'E/G'
|
|
|
|
|
- break
|
|
|
|
|
- case [1, 2, 0, 1, 2, 3]: // F - aPower prioritize home
|
|
|
|
|
- schedulingType = 'F/H'
|
|
|
|
|
- break
|
|
|
|
|
- default:
|
|
|
|
|
- schedulingType = 'unknown'
|
|
|
|
|
- break
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ schedulingType =
|
|
|
|
|
+ SchedulingRules.find((rule) => arrayEqual(priority, rule.match))?.type ?? 'unknown'
|
|
|
}
|
|
}
|
|
|
return SchedulingMap[schedulingType]
|
|
return SchedulingMap[schedulingType]
|
|
|
})(),
|
|
})(),
|
|
@@ -475,34 +472,13 @@ export function parseSchedulingInfo(info: TimeRangeSchedulingInfo): TimePeriodSc
|
|
|
}
|
|
}
|
|
|
})(),
|
|
})(),
|
|
|
scheduling: ((): SchedulingType => {
|
|
scheduling: ((): SchedulingType => {
|
|
|
- let schedulingType: SchedulingType = 'D' // 没有优先级时,默认 Self consumption
|
|
|
|
|
|
|
+ let schedulingType: SchedulingType = 'noPriority' // 没有优先级时,默认 Self consumption
|
|
|
|
|
|
|
|
// 判断优先级
|
|
// 判断优先级
|
|
|
- if (info.solarPriority != null && info.loadPriority != null) {
|
|
|
|
|
|
|
+ if (info.solarPriority !== undefined && info.loadPriority !== undefined) {
|
|
|
const priority = [...info.solarPriority, ...info.loadPriority]
|
|
const priority = [...info.solarPriority, ...info.loadPriority]
|
|
|
- switch (priority) {
|
|
|
|
|
- case [1, 2, 0, 1, 3, 2]: // A - Excess solar export to grid
|
|
|
|
|
- schedulingType = 'A'
|
|
|
|
|
- break
|
|
|
|
|
- case [1, 2, 0, 1, 2, 0]: // B - aPower standby
|
|
|
|
|
- schedulingType = 'B'
|
|
|
|
|
- break
|
|
|
|
|
- case [1, 3, 2, 1, 2, 0]: // C - Excess solar charge aPower
|
|
|
|
|
- schedulingType = 'C'
|
|
|
|
|
- break
|
|
|
|
|
- case [1, 3, 2, 1, 3, 2]: // D - Self-consumption
|
|
|
|
|
- schedulingType = 'D'
|
|
|
|
|
- break
|
|
|
|
|
- case [1, 2, 3, 1, 2, 0]: // E - aPower charge from solar
|
|
|
|
|
- schedulingType = 'E/G'
|
|
|
|
|
- break
|
|
|
|
|
- case [1, 2, 0, 1, 2, 3]: // F - aPower prioritize home
|
|
|
|
|
- schedulingType = 'F/H'
|
|
|
|
|
- break
|
|
|
|
|
- default:
|
|
|
|
|
- schedulingType = 'unknown'
|
|
|
|
|
- break
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ schedulingType =
|
|
|
|
|
+ SchedulingRules.find((rule) => arrayEqual(priority, rule.match))?.type ?? 'unknown'
|
|
|
}
|
|
}
|
|
|
return schedulingType
|
|
return schedulingType
|
|
|
})(),
|
|
})(),
|
|
@@ -571,6 +547,7 @@ export function transformSchedulingType(type: SchedulingType): FlowChartConfig[]
|
|
|
})
|
|
})
|
|
|
break
|
|
break
|
|
|
case 'D':
|
|
case 'D':
|
|
|
|
|
+ case 'noPriority': // 无优先级默认自发自用
|
|
|
configList.push({
|
|
configList.push({
|
|
|
schedulingName: SchedulingMap[type],
|
|
schedulingName: SchedulingMap[type],
|
|
|
schedulingTip: getSchedulingTip(type),
|
|
schedulingTip: getSchedulingTip(type),
|
|
@@ -673,6 +650,8 @@ function getSchedulingTip(type: SchedulingType): string {
|
|
|
return '(使能电网充电)光伏优先充电,多余供载,再剩余馈网\n充电不足市电补充'
|
|
return '(使能电网充电)光伏优先充电,多余供载,再剩余馈网\n充电不足市电补充'
|
|
|
case 'H':
|
|
case 'H':
|
|
|
return '(使能aPower馈网)aPower优先供载,不足光伏补充,再不足市电补充\n光伏供载剩余馈网\naPower满功率放电供载剩余馈网,光伏馈网'
|
|
return '(使能aPower馈网)aPower优先供载,不足光伏补充,再不足市电补充\n光伏供载剩余馈网\naPower满功率放电供载剩余馈网,光伏馈网'
|
|
|
|
|
+ case 'noPriority':
|
|
|
|
|
+ return '无优先级配置,默认自发自用'
|
|
|
case 'unknown':
|
|
case 'unknown':
|
|
|
return '未知调度'
|
|
return '未知调度'
|
|
|
}
|
|
}
|