From 4ec5d13c32bcf64c07a052099d9d885976f50758 Mon Sep 17 00:00:00 2001 From: Mikhail Kladkevich Date: Tue, 17 Apr 2018 20:48:46 +0300 Subject: [PATCH] Add tests for SmartCharging. --- .../ocpp/test/FakeCentralSystem.java | 18 ++++- .../chargetime/ocpp/test/FakeChargePoint.java | 4 + .../json/JSONSetChargingProfileSpec.groovy | 81 +++++++++++++++++++ .../ocpp/model/core/ChargingProfile.java | 22 ++++- .../ocpp/model/core/ChargingSchedule.java | 10 ++- .../model/core/ChargingSchedulePeriod.java | 7 ++ .../SetChargingProfileRequest.java | 9 ++- 7 files changed, 141 insertions(+), 10 deletions(-) create mode 100644 ocpp-v1_6-test/src/test/groovy/eu/chargetime/ocpp/test/smartcharging/json/JSONSetChargingProfileSpec.groovy diff --git a/ocpp-v1_6-test/src/main/java/eu/chargetime/ocpp/test/FakeCentralSystem.java b/ocpp-v1_6-test/src/main/java/eu/chargetime/ocpp/test/FakeCentralSystem.java index 8c686dfeb..106e4ff19 100644 --- a/ocpp-v1_6-test/src/main/java/eu/chargetime/ocpp/test/FakeCentralSystem.java +++ b/ocpp-v1_6-test/src/main/java/eu/chargetime/ocpp/test/FakeCentralSystem.java @@ -41,6 +41,8 @@ of this software and associated documentation files (the "Software"), to deal import eu.chargetime.ocpp.model.reservation.CancelReservationRequest; import eu.chargetime.ocpp.model.reservation.ReserveNowConfirmation; import eu.chargetime.ocpp.model.reservation.ReserveNowRequest; +import eu.chargetime.ocpp.model.smartcharging.SetChargingProfileConfirmation; +import eu.chargetime.ocpp.model.smartcharging.SetChargingProfileRequest; import eu.chargetime.ocpp.test.FakeCentral.serverType; import java.util.Calendar; @@ -55,8 +57,6 @@ public class FakeCentralSystem { dummyHandlers = new DummyHandlers(); ServerCoreProfile serverCoreProfile = new ServerCoreProfile(dummyHandlers.createServerCoreEventHandler()); - ServerReservationProfile serverReservationProfile = new ServerReservationProfile(); - ServerLocalAuthListProfile serverLocalAuthListProfile = new ServerLocalAuthListProfile(); if (type == serverType.JSON) { server = new JSONServer(serverCoreProfile); @@ -64,8 +64,6 @@ public class FakeCentralSystem { server = new SOAPServer(serverCoreProfile); } - server.addFeatureProfile(serverReservationProfile); - server.addFeatureProfile(serverLocalAuthListProfile); initializeServer(); isStarted = false; } @@ -82,6 +80,9 @@ private void initializeServer() { ServerLocalAuthListProfile localAuthListProfile = new ServerLocalAuthListProfile(); server.addFeatureProfile(localAuthListProfile); + + ServerReservationProfile serverReservationProfile = new ServerReservationProfile(); + server.addFeatureProfile(serverReservationProfile); } public boolean connected() { @@ -161,6 +162,10 @@ public boolean hasReceivedUpdateFirmwareConfirmation() { return dummyHandlers.wasLatestConfirmation(UpdateFirmwareConfirmation.class); } + public boolean hasReceivedSetChargingProfileConfirmation() { + return dummyHandlers.wasLatestConfirmation(SetChargingProfileConfirmation.class); + } + public boolean hasReceivedChangeAvailabilityConfirmation(String status) { boolean result = false; ChangeAvailabilityConfirmation confirmation = dummyHandlers.getReceivedConfirmation(new ChangeAvailabilityConfirmation()); @@ -299,6 +304,11 @@ public void sendSendLocalListRequest(int listVersion, UpdateType updateType) thr send(request); } + public void sendSetChargingProfileRequest(Integer connectorId, ChargingProfile chargingProfile) throws Exception { + SetChargingProfileRequest request = new SetChargingProfileRequest(connectorId, chargingProfile); + send(request); + } + public boolean hasReceivedResetConfirmation(String status) { boolean result = false; ResetConfirmation confirmation = dummyHandlers.getReceivedConfirmation(new ResetConfirmation()); diff --git a/ocpp-v1_6-test/src/main/java/eu/chargetime/ocpp/test/FakeChargePoint.java b/ocpp-v1_6-test/src/main/java/eu/chargetime/ocpp/test/FakeChargePoint.java index 6ea9a478b..c9825c746 100644 --- a/ocpp-v1_6-test/src/main/java/eu/chargetime/ocpp/test/FakeChargePoint.java +++ b/ocpp-v1_6-test/src/main/java/eu/chargetime/ocpp/test/FakeChargePoint.java @@ -393,6 +393,10 @@ public boolean hasHandledGetLocalListVersionRequest() { return receivedRequest instanceof GetLocalListVersionRequest; } + public boolean hasHandledSetChargingProfileRequest() { + return receivedRequest instanceof SetChargingProfileRequest; + } + public boolean hasHandledChangeConfigurationRequest() { return receivedRequest instanceof ChangeConfigurationRequest; } diff --git a/ocpp-v1_6-test/src/test/groovy/eu/chargetime/ocpp/test/smartcharging/json/JSONSetChargingProfileSpec.groovy b/ocpp-v1_6-test/src/test/groovy/eu/chargetime/ocpp/test/smartcharging/json/JSONSetChargingProfileSpec.groovy new file mode 100644 index 000000000..14d4b7311 --- /dev/null +++ b/ocpp-v1_6-test/src/test/groovy/eu/chargetime/ocpp/test/smartcharging/json/JSONSetChargingProfileSpec.groovy @@ -0,0 +1,81 @@ +package eu.chargetime.ocpp.test.smartcharging.json + +import eu.chargetime.ocpp.model.core.ChargingProfile +import eu.chargetime.ocpp.model.core.ChargingProfileKindType +import eu.chargetime.ocpp.model.core.ChargingProfilePurposeType +import eu.chargetime.ocpp.model.core.ChargingRateUnitType +import eu.chargetime.ocpp.model.core.ChargingSchedule +import eu.chargetime.ocpp.model.core.ChargingSchedulePeriod +import eu.chargetime.ocpp.test.FakeCentral +import eu.chargetime.ocpp.test.FakeCentralSystem +import eu.chargetime.ocpp.test.FakeChargePoint +import spock.lang.Shared +import spock.lang.Specification +import spock.util.concurrent.PollingConditions + +/* + ChargeTime.eu - Java-OCA-OCPP + + MIT License + + Copyright (C) 2016-2018 Thomas Volden + Copyright (C) 2018 Mikhail Kladkevich + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + */ + +class JSONSetChargingProfileSpec extends Specification { + @Shared + FakeCentralSystem centralSystem = FakeCentral.getSystem(FakeCentral.serverType.JSON) + @Shared + FakeChargePoint chargePoint = new FakeChargePoint() + + def setupSpec() { + // When a Central System is running + centralSystem.started() + } + + def setup() { + chargePoint.connect() + } + + def cleanup() { + chargePoint.disconnect() + } + + def "Central System sends a SetChargingProfile request and receives a response"() { + def conditions = new PollingConditions(timeout: 1) + given: + conditions.eventually { + assert centralSystem.connected() + } + + when: + ChargingSchedulePeriod[] chargingSchedulePeriod = new ChargingSchedulePeriod[1] + chargingSchedulePeriod[0] = new ChargingSchedulePeriod(1, 2D) + centralSystem.sendSetChargingProfileRequest(1, new ChargingProfile(1, 2, ChargingProfilePurposeType.ChargePointMaxProfile, ChargingProfileKindType.Recurring, + new ChargingSchedule(ChargingRateUnitType.A, chargingSchedulePeriod))) + + then: + conditions.eventually { + assert chargePoint.hasHandledSetChargingProfileRequest() + assert centralSystem.hasReceivedSetChargingProfileConfirmation() + } + } +} diff --git a/ocpp-v1_6/src/main/java/eu/chargetime/ocpp/model/core/ChargingProfile.java b/ocpp-v1_6/src/main/java/eu/chargetime/ocpp/model/core/ChargingProfile.java index ae847c352..66f3f519c 100644 --- a/ocpp-v1_6/src/main/java/eu/chargetime/ocpp/model/core/ChargingProfile.java +++ b/ocpp-v1_6/src/main/java/eu/chargetime/ocpp/model/core/ChargingProfile.java @@ -46,10 +46,26 @@ public class ChargingProfile implements Validatable { private Calendar validTo; private ChargingSchedule chargingSchedule; + public ChargingProfile() { } + + public ChargingProfile(Integer chargingProfileId, Integer stackLevel, ChargingProfilePurposeType chargingProfilePurpose, ChargingProfileKindType chargingProfileKind, ChargingSchedule chargingSchedule) { + this.chargingProfileId = chargingProfileId; + this.stackLevel = stackLevel; + this.chargingProfilePurpose = chargingProfilePurpose; + this.chargingProfileKind = chargingProfileKind; + this.chargingSchedule = chargingSchedule; + } + + public ChargingProfile(Integer chargingProfileId, Integer stackLevel, ChargingProfilePurposeType chargingProfilePurpose, ChargingProfileKindType chargingProfileKind) { + this.chargingProfileId = chargingProfileId; + this.stackLevel = stackLevel; + this.chargingProfilePurpose = chargingProfilePurpose; + this.chargingProfileKind = chargingProfileKind; + } + @Override public boolean validate() { - boolean valid = true; - valid &= chargingProfileId != null; + boolean valid = chargingProfileId != null; valid &= stackLevel >= 0; valid &= chargingProfilePurpose != null; valid &= transactionId == null || chargingProfilePurpose == ChargingProfilePurposeType.TxProfile; @@ -61,7 +77,7 @@ public boolean validate() { @XmlElement public void setChargingProfileId(Integer chargingProfileId) throws PropertyConstraintException { if (chargingProfileId == null) - throw new PropertyConstraintException("chargingProfileId", chargingProfileId); + throw new PropertyConstraintException("chargingProfileId", null); this.chargingProfileId = chargingProfileId; } diff --git a/ocpp-v1_6/src/main/java/eu/chargetime/ocpp/model/core/ChargingSchedule.java b/ocpp-v1_6/src/main/java/eu/chargetime/ocpp/model/core/ChargingSchedule.java index 6448da175..ebed93518 100644 --- a/ocpp-v1_6/src/main/java/eu/chargetime/ocpp/model/core/ChargingSchedule.java +++ b/ocpp-v1_6/src/main/java/eu/chargetime/ocpp/model/core/ChargingSchedule.java @@ -45,10 +45,16 @@ public class ChargingSchedule implements Validatable { private ChargingSchedulePeriod[] chargingSchedulePeriod; private Double minChargingRate; + public ChargingSchedule() { } + + public ChargingSchedule(ChargingRateUnitType chargingRateUnit, ChargingSchedulePeriod[] chargingSchedulePeriod) { + this.chargingRateUnit = chargingRateUnit; + this.chargingSchedulePeriod = chargingSchedulePeriod; + } + @Override public boolean validate() { - boolean valid = true; - valid &= chargingRateUnit != null; + boolean valid = chargingRateUnit != null; if (valid &= chargingSchedulePeriod != null) { for (ChargingSchedulePeriod period : chargingSchedulePeriod) valid &= period.validate(); diff --git a/ocpp-v1_6/src/main/java/eu/chargetime/ocpp/model/core/ChargingSchedulePeriod.java b/ocpp-v1_6/src/main/java/eu/chargetime/ocpp/model/core/ChargingSchedulePeriod.java index 25d5821ee..53f9fbfac 100644 --- a/ocpp-v1_6/src/main/java/eu/chargetime/ocpp/model/core/ChargingSchedulePeriod.java +++ b/ocpp-v1_6/src/main/java/eu/chargetime/ocpp/model/core/ChargingSchedulePeriod.java @@ -42,6 +42,13 @@ public class ChargingSchedulePeriod implements Validatable { private Double limit; private Integer numberPhases = 3; + public ChargingSchedulePeriod() { } + + public ChargingSchedulePeriod(Integer startPeriod, Double limit) { + this.startPeriod = startPeriod; + this.limit = limit; + } + @Override public boolean validate() { boolean valid = true; diff --git a/ocpp-v1_6/src/main/java/eu/chargetime/ocpp/model/smartcharging/SetChargingProfileRequest.java b/ocpp-v1_6/src/main/java/eu/chargetime/ocpp/model/smartcharging/SetChargingProfileRequest.java index b94f8b994..bdd463685 100644 --- a/ocpp-v1_6/src/main/java/eu/chargetime/ocpp/model/smartcharging/SetChargingProfileRequest.java +++ b/ocpp-v1_6/src/main/java/eu/chargetime/ocpp/model/smartcharging/SetChargingProfileRequest.java @@ -39,6 +39,13 @@ public class SetChargingProfileRequest implements Request { private Integer connectorId; private ChargingProfile chargingProfile; + public SetChargingProfileRequest() { } + + public SetChargingProfileRequest(Integer connectorId, ChargingProfile chargingProfile) { + this.connectorId = connectorId; + this.chargingProfile = chargingProfile; + } + /** * This identifies which connector of the Charge Point is used. * @@ -77,7 +84,7 @@ public ChargingProfile getChargingProfile() { * * @param chargingProfile the {@link ChargingProfile}. */ - @XmlElement + @XmlElement(name = "csChargingProfiles") public void setChargingProfile(ChargingProfile chargingProfile) { this.chargingProfile = chargingProfile; }