Skip to content

Commit 0078f16

Browse files
committed
Added StartTransaction feature to core profile.
1 parent c0cdd59 commit 0078f16

File tree

13 files changed

+632
-12
lines changed

13 files changed

+632
-12
lines changed

ocpp-common/src/main/java/eu/chargetime/ocpp/Client.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,11 @@ private boolean featureContains(Feature feature, Object object) {
111111
return contains;
112112
}
113113

114-
public CompletableFuture<Confirmation> send(Request request) {
114+
public CompletableFuture<Confirmation> send(Request request) throws UnsupportedFeatureException {
115115
Feature feature = findFeature(request);
116+
if (feature == null)
117+
throw new UnsupportedFeatureException();
118+
116119
String id = session.sendRequest(feature.getAction(), request);
117120
CompletableFuture<Confirmation> promise = createPromise(id);
118121
return promise;
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package eu.chargetime.ocpp;
2+
3+
/**
4+
* ChargeTime.eu - Java-OCA-OCPP
5+
* <p>
6+
* MIT License
7+
* <p>
8+
* Copyright (C) 2016 Thomas Volden <[email protected]>
9+
* <p>
10+
* Permission is hereby granted, free of charge, to any person obtaining a copy
11+
* of this software and associated documentation files (the "Software"), to deal
12+
* in the Software without restriction, including without limitation the rights
13+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14+
* copies of the Software, and to permit persons to whom the Software is
15+
* furnished to do so, subject to the following conditions:
16+
* <p>
17+
* The above copyright notice and this permission notice shall be included in all
18+
* copies or substantial portions of the Software.
19+
* <p>
20+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26+
* SOFTWARE.
27+
*/
28+
public class UnsupportedFeatureException extends Exception {
29+
}

ocpp-common/src/test/java/eu/chargetime/ocpp/test/ClientTest.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
package eu.chargetime.ocpp.test;
22

3-
import eu.chargetime.ocpp.*;
3+
import eu.chargetime.ocpp.Client;
4+
import eu.chargetime.ocpp.Session;
5+
import eu.chargetime.ocpp.SessionEvents;
46
import eu.chargetime.ocpp.feature.Feature;
7+
import eu.chargetime.ocpp.feature.profile.Profile;
58
import eu.chargetime.ocpp.model.Confirmation;
69
import eu.chargetime.ocpp.model.Request;
7-
import eu.chargetime.ocpp.feature.profile.Profile;
810
import eu.chargetime.ocpp.model.test.TestConfirmation;
911
import org.junit.Before;
1012
import org.junit.Test;
@@ -14,7 +16,7 @@
1416

1517
import static org.hamcrest.CoreMatchers.instanceOf;
1618
import static org.hamcrest.Matchers.is;
17-
import static org.junit.Assert.*;
19+
import static org.junit.Assert.assertThat;
1820
import static org.mockito.Mockito.*;
1921

2022
/**
@@ -87,7 +89,7 @@ public void connect_connects() {
8789
}
8890

8991
@Test
90-
public void send_aMessage_isCommunicated() {
92+
public void send_aMessage_isCommunicated() throws Exception {
9193
// When
9294
client.send(request);
9395

@@ -96,7 +98,7 @@ public void send_aMessage_isCommunicated() {
9698
}
9799

98100
@Test
99-
public void responseReceived_aMessageWasSend_PromiseIsCompleted() {
101+
public void responseReceived_aMessageWasSend_PromiseIsCompleted() throws Exception {
100102
// Given
101103
String someUniqueId = "Some id";
102104
when(session.sendRequest(any(), any())).thenReturn(someUniqueId);

ocpp-test/src/main/java/eu/chargetime/ocpp/test/FakeCentralSystem.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,10 @@ public boolean hasReceivedMeterValuesRequest() {
126126
return receivedMessage != null && "MeterValues".equals(getAction());
127127
}
128128

129+
public boolean hasReceivedStartTransactionRequest() {
130+
return receivedMessage != null && "StartTransaction".equals(getAction());
131+
}
132+
129133
private JSONObject getCallPayload()
130134
{
131135
return (JSONObject)receivedMessage[3];
@@ -247,7 +251,6 @@ public void sendResetRequest(String type) {
247251
public enum AvailabilityType {
248252
Inoperative, Operative
249253
}
250-
251254
public void sendChangeAvailabilityRequest(int connectorId, AvailabilityType type)
252255
{
253256
String payload = "\"connectorId\":%d,\"type\":\"%s\"";
@@ -257,12 +260,16 @@ public void sendChangeAvailabilityRequest(int connectorId, AvailabilityType type
257260
public enum RegistrationStatus {
258261
Accepted, Pending, Rejected
259262
}
260-
261263
public void sendHeartbeatConfirmation() {
262264
String payload = "\"currentTime\": \"%s\"";
263265
sendConfirmation(String.format(payload, now()));
264266
}
265267

268+
public void sendStartTransactionConfirmation() {
269+
String payload = "\"idTagInfo\": {\"status\": \"Accepted\"}, \"transactionId\": 42";
270+
sendConfirmation(payload);
271+
}
272+
266273
public void sendMeterValuesConfirmation() {
267274
sendConfirmation("");
268275
}

ocpp-test/src/main/java/eu/chargetime/ocpp/test/FakeChargePoint.java

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,15 @@ public void sendMeterValuesRequest() {
133133
}
134134
}
135135

136+
public void sendStartTransactionRequest() {
137+
try {
138+
Request request = core.createStartTransactionRequest(41, "some id", 42, Calendar.getInstance());
139+
send(request);
140+
} catch (PropertyConstraintException ex) {
141+
ex.printStackTrace();
142+
}
143+
}
144+
136145
public void sendDataTransferRequest(String vendorId, String messageId, String data) {
137146
try {
138147
DataTransferRequest request = core.createDataTransferRequest(vendorId);
@@ -146,7 +155,11 @@ public void sendDataTransferRequest(String vendorId, String messageId, String da
146155
}
147156

148157
private void send(Request request) {
149-
client.send(request).whenComplete((s, ex) -> receivedConfirmation = s);
158+
try {
159+
client.send(request).whenComplete((s, ex) -> receivedConfirmation = s);
160+
} catch (UnsupportedFeatureException ex) {
161+
ex.printStackTrace();
162+
}
150163
}
151164

152165
public void hasReceivedBootConfirmation(String status) {
@@ -172,6 +185,10 @@ public void hasReceivedMeterValuesConfirmation() {
172185
assertThat(receivedConfirmation, instanceOf(MeterValuesConfirmation.class));
173186
}
174187

188+
public void hasReceivedStartTransactionConfirmation() {
189+
assertThat(receivedConfirmation, instanceOf(StartTransactionConfirmation.class));
190+
}
191+
175192
public void disconnect() {
176193
client.disconnect();
177194
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package core_features
2+
3+
import eu.chargetime.ocpp.test.FakeCentralSystem
4+
import eu.chargetime.ocpp.test.FakeChargePoint
5+
import spock.lang.Shared
6+
import spock.lang.Specification
7+
import spock.util.concurrent.PollingConditions;
8+
9+
class StartTransaction extends Specification {
10+
@Shared
11+
FakeCentralSystem centralSystem = FakeCentralSystem.getInstance();
12+
@Shared
13+
FakeChargePoint chargePoint = new FakeChargePoint();
14+
15+
def setupSpec() {
16+
// When a Central System is running
17+
centralSystem.started();
18+
}
19+
20+
def setup() {
21+
chargePoint.connect();
22+
}
23+
24+
def cleanup() {
25+
chargePoint.disconnect();
26+
}
27+
28+
def "Charge point sends StartTransaction request and receives a response"() {
29+
def conditions = new PollingConditions(timeout: 1);
30+
when:
31+
chargePoint.sendStartTransactionRequest();
32+
33+
then:
34+
conditions.eventually {
35+
centralSystem.hasReceivedStartTransactionRequest();
36+
}
37+
38+
when:
39+
centralSystem.sendStartTransactionConfirmation();
40+
41+
then:
42+
conditions.eventually {
43+
chargePoint.hasReceivedStartTransactionConfirmation();
44+
}
45+
46+
}
47+
48+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package eu.chargetime.ocpp.feature;
2+
3+
import eu.chargetime.ocpp.feature.profile.Profile;
4+
import eu.chargetime.ocpp.model.Confirmation;
5+
import eu.chargetime.ocpp.model.Request;
6+
import eu.chargetime.ocpp.model.StartTransactionConfirmation;
7+
import eu.chargetime.ocpp.model.StartTransactionRequest;
8+
9+
/**
10+
* ChargeTime.eu - Java-OCA-OCPP
11+
* <p>
12+
* MIT License
13+
* <p>
14+
* Copyright (C) 2016 Thomas Volden <[email protected]>
15+
* <p>
16+
* Permission is hereby granted, free of charge, to any person obtaining a copy
17+
* of this software and associated documentation files (the "Software"), to deal
18+
* in the Software without restriction, including without limitation the rights
19+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
20+
* copies of the Software, and to permit persons to whom the Software is
21+
* furnished to do so, subject to the following conditions:
22+
* <p>
23+
* The above copyright notice and this permission notice shall be included in all
24+
* copies or substantial portions of the Software.
25+
* <p>
26+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
27+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
28+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
29+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
30+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
31+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32+
* SOFTWARE.
33+
*/
34+
public class StartTransactionFeature extends Feature {
35+
public StartTransactionFeature(Profile ownerProfile) {
36+
super(ownerProfile);
37+
}
38+
39+
@Override
40+
public Class<? extends Request> getRequestType() {
41+
return StartTransactionRequest.class;
42+
}
43+
44+
@Override
45+
public Class<? extends Confirmation> getConfirmationType() {
46+
return StartTransactionConfirmation.class;
47+
}
48+
49+
@Override
50+
public String getAction() {
51+
return "StartTransaction";
52+
}
53+
}

ocpp-v1_6/src/main/java/eu/chargetime/ocpp/feature/profile/CoreProfile.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ public CoreProfile(ClientCoreEventHandler handler) {
5454
features.add(new RemoteStartTransactionFeature(this));
5555
features.add(new RemoteStopTransactionFeature(this));
5656
features.add(new ResetFeature(this));
57+
features.add(new StartTransactionFeature(this));
5758
}
5859

5960
public AuthorizeRequest createAuthorizeRequest(String idToken) throws PropertyConstraintException {
@@ -92,6 +93,17 @@ public MeterValuesRequest createMeterValuesRequest(Integer connectorId, MeterVal
9293
return request;
9394
}
9495

96+
public StartTransactionRequest createStartTransactionRequest(Integer connectorId, String idTag, Integer meterStart, Calendar timestamp) throws PropertyConstraintException {
97+
StartTransactionRequest request = new StartTransactionRequest();
98+
request.setConnectorId(connectorId);
99+
IdToken idToken = new IdToken();
100+
idToken.setIdToken(idTag);
101+
request.setIdTag(idToken);
102+
request.setMeterStart(meterStart);
103+
request.setTimestamp(timestamp);
104+
return request;
105+
}
106+
95107
@Override
96108
public Feature[] getFeatureList() {
97109
return features.toArray(new Feature[0]);
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package eu.chargetime.ocpp.model;
2+
3+
/**
4+
* ChargeTime.eu - Java-OCA-OCPP
5+
* <p>
6+
* MIT License
7+
* <p>
8+
* Copyright (C) 2016 Thomas Volden <[email protected]>
9+
* <p>
10+
* Permission is hereby granted, free of charge, to any person obtaining a copy
11+
* of this software and associated documentation files (the "Software"), to deal
12+
* in the Software without restriction, including without limitation the rights
13+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14+
* copies of the Software, and to permit persons to whom the Software is
15+
* furnished to do so, subject to the following conditions:
16+
* <p>
17+
* The above copyright notice and this permission notice shall be included in all
18+
* copies or substantial portions of the Software.
19+
* <p>
20+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26+
* SOFTWARE.
27+
*/
28+
public class StartTransactionConfirmation implements Confirmation {
29+
private IdTagInfo idTagInfo;
30+
private Integer transactionId;
31+
32+
@Override
33+
public boolean validate() {
34+
boolean valid = true;
35+
if (valid &= idTagInfo != null)
36+
valid &= idTagInfo.validate();
37+
return valid;
38+
}
39+
40+
public void setIdTagInfo(IdTagInfo idTagInfo) {
41+
this.idTagInfo = idTagInfo;
42+
}
43+
44+
public IdTagInfo getIdTagInfo() {
45+
return idTagInfo;
46+
}
47+
48+
public void setTransactionId(Integer transactionId) {
49+
this.transactionId = transactionId;
50+
}
51+
52+
public Integer getTransactionId() {
53+
return transactionId;
54+
}
55+
}

0 commit comments

Comments
 (0)