-
Notifications
You must be signed in to change notification settings - Fork 182
[WIP] Fix smart charger OCTT test cases #424
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
3b1759e
3433ea1
c2d84c0
350c818
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -53,7 +53,7 @@ void SmartChargingConnector::calculateLimit(const Timestamp &t, ChargeRate& limi | |
| } | ||
|
|
||
| //if no TxProfile limits charging, check the TxDefaultProfiles for this connector | ||
| if (!txLimitDefined && trackTxStart < MAX_TIME) { | ||
| if (!txLimitDefined) { | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This fixes the composite schedules. But also affects the ordinary charge limit output if no transaction is running. I cannot think of scenarios where this would be super bad though. The usage of the global Looks good for now! |
||
| for (int i = MO_ChargeProfileMaxStackLevel; i >= 0; i--) { | ||
| if (TxDefaultProfile[i]) { | ||
| ChargeRate crOut; | ||
|
|
@@ -68,7 +68,7 @@ void SmartChargingConnector::calculateLimit(const Timestamp &t, ChargeRate& limi | |
| } | ||
|
|
||
| //if no appropriate TxDefaultProfile is set for this connector, search in the general TxDefaultProfiles | ||
| if (!txLimitDefined && trackTxStart < MAX_TIME) { | ||
| if (!txLimitDefined) { | ||
| for (int i = MO_ChargeProfileMaxStackLevel; i >= 0; i--) { | ||
| if (ChargePointTxDefaultProfile[i]) { | ||
| ChargeRate crOut; | ||
|
|
@@ -168,19 +168,19 @@ void SmartChargingConnector::loop(){ | |
| MO_DBG_INFO("New limit for connector %u, scheduled at = %s, nextChange = %s, limit = {%.1f, %.1f, %i}", | ||
| connectorId, | ||
| timestamp1, timestamp2, | ||
| limit.power != std::numeric_limits<float>::max() ? limit.power : -1.f, | ||
| limit.current != std::numeric_limits<float>::max() ? limit.current : -1.f, | ||
| limit.nphases != std::numeric_limits<int>::max() ? limit.nphases : -1); | ||
| limit.power != std::numeric_limits<float>::max() ? limit.power : MO_MaxChargingLimitPower, | ||
| limit.current != std::numeric_limits<float>::max() ? limit.current : MO_MaxChargingLimitCurrent, | ||
| limit.nphases != std::numeric_limits<int>::max() ? limit.nphases : MO_MaxChargingLimitNumberPhases); | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would be nice to preserve the |
||
| } | ||
| #endif | ||
|
|
||
| if (trackLimitOutput != limit) { | ||
| if (limitOutput) { | ||
|
|
||
| limitOutput( | ||
| limit.power != std::numeric_limits<float>::max() ? limit.power : -1.f, | ||
| limit.current != std::numeric_limits<float>::max() ? limit.current : -1.f, | ||
| limit.nphases != std::numeric_limits<int>::max() ? limit.nphases : -1); | ||
| limit.power != std::numeric_limits<float>::max() ? limit.power : MO_MaxChargingLimitPower, | ||
| limit.current != std::numeric_limits<float>::max() ? limit.current : MO_MaxChargingLimitCurrent, | ||
| limit.nphases != std::numeric_limits<int>::max() ? limit.nphases : MO_MaxChargingLimitNumberPhases); | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See above |
||
| trackLimitOutput = limit; | ||
| } | ||
| } | ||
|
|
@@ -252,6 +252,9 @@ std::unique_ptr<ChargingSchedule> SmartChargingConnector::getCompositeSchedule(i | |
| Timestamp periodBegin = Timestamp(startSchedule); | ||
| Timestamp periodStop = Timestamp(startSchedule); | ||
|
|
||
| //remember last effective limit we actually *emitted* | ||
| ChargeRate lastLimit; | ||
|
|
||
| while (periodBegin - startSchedule < duration && periods.size() < MO_ChargingScheduleMaxPeriods) { | ||
|
|
||
| //calculate limit | ||
|
|
@@ -267,11 +270,16 @@ std::unique_ptr<ChargingSchedule> SmartChargingConnector::getCompositeSchedule(i | |
| } | ||
| } | ||
|
|
||
| periods.emplace_back(); | ||
| float limit_opt = unit == ChargingRateUnitType_Optional::Watt ? limit.power : limit.current; | ||
| periods.back().limit = limit_opt != std::numeric_limits<float>::max() ? limit_opt : -1.f, | ||
| periods.back().numberPhases = limit.nphases != std::numeric_limits<int>::max() ? limit.nphases : -1; | ||
| periods.back().startPeriod = periodBegin - startSchedule; | ||
| //coalesce: only push when the effective limit actually *changes* | ||
| if (periods.empty() || limit != lastLimit) { | ||
| periods.emplace_back(); | ||
| float limit_opt = unit == ChargingRateUnitType_Optional::Watt ? limit.power : limit.current; | ||
| float fallback_limit = unit == ChargingRateUnitType_Optional::Watt ? MO_MaxChargingLimitPower : MO_MaxChargingLimitCurrent; | ||
| periods.back().limit = limit_opt != std::numeric_limits<float>::max() ? limit_opt : fallback_limit; | ||
| periods.back().numberPhases = limit.nphases != std::numeric_limits<int>::max() ? limit.nphases : MO_MaxChargingLimitNumberPhases; | ||
| periods.back().startPeriod = periodBegin - startSchedule; | ||
| lastLimit = limit; | ||
| } | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice! |
||
|
|
||
| periodBegin = periodStop; | ||
| } | ||
|
|
@@ -521,19 +529,19 @@ void SmartChargingService::loop(){ | |
| MO_DBG_INFO("New limit for connector %u, scheduled at = %s, nextChange = %s, limit = {%.1f, %.1f, %i}", | ||
| 0, | ||
| timestamp1, timestamp2, | ||
| limit.power != std::numeric_limits<float>::max() ? limit.power : -1.f, | ||
| limit.current != std::numeric_limits<float>::max() ? limit.current : -1.f, | ||
| limit.nphases != std::numeric_limits<int>::max() ? limit.nphases : -1); | ||
| limit.power != std::numeric_limits<float>::max() ? limit.power : MO_MaxChargingLimitPower, | ||
| limit.current != std::numeric_limits<float>::max() ? limit.current : MO_MaxChargingLimitCurrent, | ||
| limit.nphases != std::numeric_limits<int>::max() ? limit.nphases : MO_MaxChargingLimitNumberPhases); | ||
| } | ||
| #endif | ||
|
|
||
| if (trackLimitOutput != limit) { | ||
| if (limitOutput) { | ||
|
|
||
| limitOutput( | ||
| limit.power != std::numeric_limits<float>::max() ? limit.power : -1.f, | ||
| limit.current != std::numeric_limits<float>::max() ? limit.current : -1.f, | ||
| limit.nphases != std::numeric_limits<int>::max() ? limit.nphases : -1); | ||
| limit.power != std::numeric_limits<float>::max() ? limit.power : MO_MaxChargingLimitPower, | ||
| limit.current != std::numeric_limits<float>::max() ? limit.current : MO_MaxChargingLimitCurrent, | ||
| limit.nphases != std::numeric_limits<int>::max() ? limit.nphases : MO_MaxChargingLimitNumberPhases); | ||
| trackLimitOutput = limit; | ||
| } | ||
| } | ||
|
|
@@ -692,8 +700,9 @@ std::unique_ptr<ChargingSchedule> SmartChargingService::getCompositeSchedule(uns | |
|
|
||
| periods.push_back(ChargingSchedulePeriod()); | ||
| float limit_opt = unit == ChargingRateUnitType_Optional::Watt ? limit.power : limit.current; | ||
| periods.back().limit = limit_opt != std::numeric_limits<float>::max() ? limit_opt : -1.f; | ||
| periods.back().numberPhases = limit.nphases != std::numeric_limits<int>::max() ? limit.nphases : -1; | ||
| float fallback_limit = unit == ChargingRateUnitType_Optional::Watt ? MO_MaxChargingLimitPower : MO_MaxChargingLimitCurrent; | ||
| periods.back().limit = limit_opt != std::numeric_limits<float>::max() ? limit_opt : fallback_limit; | ||
| periods.back().numberPhases = limit.nphases != std::numeric_limits<int>::max() ? limit.nphases : MO_MaxChargingLimitNumberPhases; | ||
| periods.back().startPeriod = periodBegin - startSchedule; | ||
|
|
||
| periodBegin = periodStop; | ||
|
|
@@ -764,6 +773,8 @@ bool SmartChargingServiceUtils::removeProfile(std::shared_ptr<FilesystemAdapter> | |
| return false; | ||
| } | ||
|
|
||
| MO_DBG_DEBUG("Removing chargingProfile for connector %d, purpose %d, stack level %d, file %s", connectorId, (int) purpose, (int) stackLevel, fn); | ||
|
|
||
| return filesystem->remove(fn); | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,6 +5,21 @@ | |
| #ifndef SMARTCHARGINGSERVICE_H | ||
| #define SMARTCHARGINGSERVICE_H | ||
|
|
||
| // Per OCPP `GetCompositeScheduleResponse` schema, limit must be > 0. | ||
| // Please define a sane value in your implementation (e.g. 32A or 22kW-equivalent) instead of -1 to pass the OCTT tests. | ||
| #ifndef MO_MaxChargingLimitPower | ||
| #define MO_MaxChargingLimitPower -1.f | ||
| #endif | ||
|
|
||
| #ifndef MO_MaxChargingLimitCurrent | ||
| #define MO_MaxChargingLimitCurrent -1.f | ||
| #endif | ||
|
|
||
| // For numberPhases, the field is optional; if unknown you can default to 3 (typical three-phase) instead of -1. | ||
| #ifndef MO_MaxChargingLimitNumberPhases | ||
| #define MO_MaxChargingLimitNumberPhases -1 | ||
| #endif | ||
|
|
||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good and simple solution for most use cases |
||
| #include <functional> | ||
| #include <array> | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch!