Skip to content
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

Add new notification features #847

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 17 additions & 2 deletions src/main/java/de/rwth/idsg/steve/NotificationFeature.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,23 @@ public enum NotificationFeature {
OcppStationWebSocketConnected(" a JSON charging station connects"),
OcppStationWebSocketDisconnected(" a JSON charging station disconnects"),
OcppTransactionStarted(" a charging station starts a transaction"),
OcppTransactionEnded(" a charging station ends a transaction");

OcppTransactionEnded(" a charging station ends a transaction"),
//
// Charge Point related
//
ChargePointCreated(" a charging station has been created"),
ChargePointDeleted(" a charging station has been deleted"),
ChargePointUpdated(" a charging station has been updated"),
UnidentifiedChargePointProceed(" an unidentified charging station has been proceed"),
UnidentifiedChargePointRemoved(" an unidentified charging station has been removed"),
//
// Ocpp Tag related
//
OcppTagCreated(" an OCPP tag has been created"),
OcppTagDeleted(" an OCPP tag has been deleted"),
OcppTagUpdated(" an OCPP tag has been updated"),
UnidentifiedOcppTagProceed(" an unidentified OCPP tag has been proceed"),
UnidentifiedOcppTagRemoved(" an unidentified OCPP tag has been removed");

@Getter
private final String text;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public interface UserRepository {
List<User.Overview> getOverview(UserQueryForm form);
User.Details getDetails(int userPk);

void add(UserForm form);
int add(UserForm form);
void update(UserForm form);
void delete(int userPk);
}
Original file line number Diff line number Diff line change
Expand Up @@ -117,12 +117,12 @@ public User.Details getDetails(int userPk) {
}

@Override
public void add(UserForm form) {
ctx.transaction(configuration -> {
public int add(UserForm form) {
return ctx.transactionResult(configuration -> {
DSLContext ctx = DSL.using(configuration);
try {
Integer addressId = addressRepository.updateOrInsert(ctx, form.getAddress());
addInternal(ctx, form, addressId);
return addInternal(ctx, form, addressId);

} catch (DataAccessException e) {
throw new SteveException("Failed to add the user", e);
Expand Down Expand Up @@ -214,8 +214,8 @@ private SelectConditionStep<Record1<Integer>> selectOcppTagPk(String ocppIdTag)
.where(OCPP_TAG.ID_TAG.eq(ocppIdTag));
}

private void addInternal(DSLContext ctx, UserForm form, Integer addressPk) {
int count = ctx.insertInto(USER)
private int addInternal(DSLContext ctx, UserForm form, Integer addressPk) {
return ctx.insertInto(USER)
.set(USER.FIRST_NAME, form.getFirstName())
.set(USER.LAST_NAME, form.getLastName())
.set(USER.BIRTH_DAY, form.getBirthDay())
Expand All @@ -225,11 +225,9 @@ private void addInternal(DSLContext ctx, UserForm form, Integer addressPk) {
.set(USER.NOTE, form.getNote())
.set(USER.ADDRESS_PK, addressPk)
.set(USER.OCPP_TAG_PK, selectOcppTagPk(form.getOcppIdTag()))
.execute();

if (count != 1) {
throw new SteveException("Failed to insert the user");
}
.returning(USER.USER_PK)
.fetchOne()
.getUserPk();
}

private void updateInternal(DSLContext ctx, UserForm form, Integer addressPk) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,8 @@ public StatusNotificationResponse statusNotification(
if (parameters.getStatus() == ChargePointStatus.FAULTED) {
applicationEventPublisher.publishEvent(new OcppStationStatusFailure(
chargeBoxIdentity, parameters.getConnectorId(), parameters.getErrorCode().value()));
} else {
// TODO add notification (ChargePointUpdated)
}

return new StatusNotificationResponse();
Expand All @@ -157,6 +159,7 @@ public MeterValuesResponse meterValues(MeterValuesRequest parameters, String cha
parameters.getConnectorId(),
parameters.getTransactionId()
);
// TODO add notification OcppTransactionOnGoing

return new MeterValuesResponse();
}
Expand Down Expand Up @@ -221,6 +224,7 @@ public StopTransactionResponse stopTransaction(StopTransactionRequest parameters
ocppServerRepository.updateTransaction(params);

ocppServerRepository.insertMeterValues(chargeBoxIdentity, parameters.getTransactionData(), transactionId);
// TODO add notification OcppTransactionOnGoing

applicationEventPublisher.publishEvent(new OcppTransactionEnded(params));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,9 @@
import de.rwth.idsg.steve.ocpp.ws.ocpp12.Ocpp12WebSocketEndpoint;
import de.rwth.idsg.steve.ocpp.ws.ocpp15.Ocpp15WebSocketEndpoint;
import de.rwth.idsg.steve.ocpp.ws.ocpp16.Ocpp16WebSocketEndpoint;
import de.rwth.idsg.steve.repository.ChargePointRepository;
import de.rwth.idsg.steve.repository.GenericRepository;
import de.rwth.idsg.steve.repository.dto.ChargePointSelect;
import de.rwth.idsg.steve.repository.dto.ConnectorStatus;
import de.rwth.idsg.steve.service.dto.UnidentifiedIncomingObject;
import de.rwth.idsg.steve.utils.ConnectorStatusCountFilter;
import de.rwth.idsg.steve.utils.DateTimeUtils;
import de.rwth.idsg.steve.web.dto.ConnectorStatusForm;
Expand Down Expand Up @@ -72,22 +70,21 @@ public class ChargePointHelperService {
@Autowired private GenericRepository genericRepository;

// SOAP-based charge points are stored in DB with an endpoint address
@Autowired private ChargePointRepository chargePointRepository;
@Autowired private ChargePointService chargePointService;

// For WebSocket-based charge points, the active sessions are stored in memory
@Autowired private Ocpp12WebSocketEndpoint ocpp12WebSocketEndpoint;
@Autowired private Ocpp15WebSocketEndpoint ocpp15WebSocketEndpoint;
@Autowired private Ocpp16WebSocketEndpoint ocpp16WebSocketEndpoint;

private final UnidentifiedIncomingObjectService unknownChargePointService = new UnidentifiedIncomingObjectService(100);

public Optional<RegistrationStatus> getRegistrationStatus(String chargeBoxId) {
Lock l = isRegisteredLocks.get(chargeBoxId);
l.lock();
try {
Optional<RegistrationStatus> status = getRegistrationStatusInternal(chargeBoxId);
if (status.isEmpty()) {
unknownChargePointService.processNewUnidentified(chargeBoxId);
chargePointService.proceedUnknown(chargeBoxId);
}
return status;
} finally {
Expand All @@ -101,7 +98,7 @@ public Statistics getStats() {
stats.setNumOcpp15JChargeBoxes(ocpp15WebSocketEndpoint.getNumberOfChargeBoxes());
stats.setNumOcpp16JChargeBoxes(ocpp16WebSocketEndpoint.getNumberOfChargeBoxes());

List<ConnectorStatus> latestList = chargePointRepository.getChargePointConnectorStatus();
List<ConnectorStatus> latestList = chargePointService.getChargePointConnectorStatus();
stats.setStatusCountMap(ConnectorStatusCountFilter.getStatusCountMap(latestList));

return stats;
Expand All @@ -114,7 +111,7 @@ public List<ConnectorStatus> getChargePointConnectorStatus(ConnectorStatusForm p

Set<String> connectedJsonChargeBoxIds = new HashSet<>(extractIds(Arrays.asList(ocpp12Map, ocpp15Map, ocpp16Map)));

List<ConnectorStatus> latestList = chargePointRepository.getChargePointConnectorStatus(params);
List<ConnectorStatus> latestList = chargePointService.getChargePointConnectorStatus(params);

// iterate over JSON stations and mark disconnected ones
// https://github.com/RWTH-i5-IDSG/steve/issues/355
Expand All @@ -135,7 +132,7 @@ public List<OcppJsonStatus> getOcppJsonStatus() {
Map<String, Deque<SessionContext>> ocpp16Map = ocpp16WebSocketEndpoint.getACopy();

List<String> idList = extractIds(Arrays.asList(ocpp12Map, ocpp15Map, ocpp16Map));
Map<String, Integer> primaryKeyLookup = chargePointRepository.getChargeBoxIdPkPair(idList);
Map<String, Integer> primaryKeyLookup = chargePointService.getChargeBoxIdPkPair(idList);

DateTime now = DateTime.now();
List<OcppJsonStatus> returnList = new ArrayList<>();
Expand Down Expand Up @@ -163,21 +160,13 @@ public List<ChargePointSelect> getChargePoints(OcppVersion version, List<Registr
}
}

public List<UnidentifiedIncomingObject> getUnknownChargePoints() {
return unknownChargePointService.getObjects();
}

public void removeUnknown(List<String> chargeBoxIdList) {
unknownChargePointService.removeAll(chargeBoxIdList);
}

// -------------------------------------------------------------------------
// Helpers
// -------------------------------------------------------------------------

private Optional<RegistrationStatus> getRegistrationStatusInternal(String chargeBoxId) {
// 1. exit if already registered
Optional<String> status = chargePointRepository.getRegistrationStatus(chargeBoxId);
Optional<String> status = chargePointService.getRegistrationStatus(chargeBoxId);
if (status.isPresent()) {
try {
return Optional.ofNullable(RegistrationStatus.fromValue(status.get()));
Expand All @@ -195,7 +184,7 @@ private Optional<RegistrationStatus> getRegistrationStatusInternal(String charge

// 3. chargeBoxId is unknown and auto-register is enabled. insert chargeBoxId
try {
chargePointRepository.addChargePointList(Collections.singletonList(chargeBoxId));
chargePointService.addChargePointList(Collections.singletonList(chargeBoxId));
log.warn("Auto-registered unknown chargebox '{}'", chargeBoxId);
return Optional.of(RegistrationStatus.ACCEPTED); // default db value is accepted
} catch (Exception e) {
Expand All @@ -210,7 +199,7 @@ private List<ChargePointSelect> getChargePoints(OcppProtocol protocol, List<Regi
.map(RegistrationStatus::value)
.collect(Collectors.toList());

List<ChargePointSelect> returnList = chargePointRepository.getChargePointSelect(protocol, statusFilter);
List<ChargePointSelect> returnList = chargePointService.getChargePointSelect(protocol, statusFilter);
for (String chargeBoxId : jsonEndpoint.getChargeBoxIdList()) {
returnList.add(new ChargePointSelect(OcppTransport.JSON, chargeBoxId));
}
Expand Down
110 changes: 110 additions & 0 deletions src/main/java/de/rwth/idsg/steve/service/ChargePointService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package de.rwth.idsg.steve.service;

import de.rwth.idsg.steve.ocpp.OcppProtocol;
import de.rwth.idsg.steve.repository.ChargePointRepository;
import de.rwth.idsg.steve.repository.dto.ChargePoint;
import de.rwth.idsg.steve.repository.dto.ChargePointSelect;
import de.rwth.idsg.steve.repository.dto.ConnectorStatus;
import de.rwth.idsg.steve.service.dto.UnidentifiedIncomingObject;
import de.rwth.idsg.steve.service.notification.ChargePointCreated;
import de.rwth.idsg.steve.service.notification.ChargePointDeleted;
import de.rwth.idsg.steve.service.notification.ChargePointUpdated;
import de.rwth.idsg.steve.service.notification.UnidentifiedChargePointProceed;
import de.rwth.idsg.steve.service.notification.UnidentifiedChargePointRemoved;
import de.rwth.idsg.steve.web.dto.ChargePointForm;
import de.rwth.idsg.steve.web.dto.ChargePointQueryForm;
import de.rwth.idsg.steve.web.dto.ConnectorStatusForm;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import jooq.steve.db.tables.records.ChargeBoxRecord;
import org.jetbrains.annotations.Nullable;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;

@Service
public class ChargePointService {

@Autowired private ApplicationEventPublisher applicationEventPublisher;
@Autowired private ChargePointRepository chargePointRepository;

private final UnidentifiedIncomingObjectService unknownChargePointService = new UnidentifiedIncomingObjectService(100);

public Optional<String> getRegistrationStatus(String chargeBoxId) {
return chargePointRepository.getRegistrationStatus(chargeBoxId);
}

public List<ChargePointSelect> getChargePointSelect(OcppProtocol protocol, List<String> inStatusFilter) {
return chargePointRepository.getChargePointSelect(protocol, inStatusFilter);
}

public List<String> getChargeBoxIds() {
return chargePointRepository.getChargeBoxIds();
}

public Map<String, Integer> getChargeBoxIdPkPair(List<String> chargeBoxIdList) {
return chargePointRepository.getChargeBoxIdPkPair(chargeBoxIdList);
}

public List<ChargePoint.Overview> getOverview(ChargePointQueryForm form) {
return chargePointRepository.getOverview(form);
}

public ChargePoint.Details getDetails(int chargeBoxPk) {
return chargePointRepository.getDetails(chargeBoxPk);
}

public List<ConnectorStatus> getChargePointConnectorStatus() {
return chargePointRepository.getChargePointConnectorStatus();
}

public List<ConnectorStatus> getChargePointConnectorStatus(@Nullable ConnectorStatusForm form) {
return chargePointRepository.getChargePointConnectorStatus(form);
}

public List<Integer> getNonZeroConnectorIds(String chargeBoxId) {
return chargePointRepository.getNonZeroConnectorIds(chargeBoxId);
}

public void addChargePointList(List<String> chargeBoxIdList) {
chargePointRepository.addChargePointList(chargeBoxIdList);
getChargeBoxIdPkPair(chargeBoxIdList).forEach(
(chargeBoxId, chargeBoxPk) -> applicationEventPublisher.publishEvent(new ChargePointCreated(chargeBoxPk, chargeBoxId))
);
removeUnknown(chargeBoxIdList);
}

public int addChargePoint(ChargePointForm form) {
int chargeBoxPk = chargePointRepository.addChargePoint(form);
applicationEventPublisher.publishEvent(new ChargePointCreated(chargeBoxPk, form.getChargeBoxId()));
removeUnknown(Collections.singletonList(form.getChargeBoxId()));
return chargeBoxPk;
}

public void updateChargePoint(ChargePointForm form) {
chargePointRepository.updateChargePoint(form);
applicationEventPublisher.publishEvent(new ChargePointUpdated(form.getChargeBoxPk(), form.getChargeBoxId()));
}

public void deleteChargePoint(int chargeBoxPk) {
ChargeBoxRecord chargeBox = chargePointRepository.getDetails(chargeBoxPk).getChargeBox();
chargePointRepository.deleteChargePoint(chargeBoxPk);
applicationEventPublisher.publishEvent(new ChargePointDeleted(chargeBoxPk, chargeBox.getChargeBoxId()));
}

public List<UnidentifiedIncomingObject> getUnknownChargePoints() {
return unknownChargePointService.getObjects();
}

public void proceedUnknown(String chargeBoxId) {
unknownChargePointService.processNewUnidentified(chargeBoxId);
applicationEventPublisher.publishEvent(new UnidentifiedChargePointProceed(chargeBoxId));
}

public void removeUnknown(List<String> chargeBoxIdList) {
unknownChargePointService.removeAll(chargeBoxIdList);
chargeBoxIdList.forEach(chargeBoxId -> applicationEventPublisher.publishEvent(new UnidentifiedChargePointRemoved(chargeBoxId)));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
import de.rwth.idsg.steve.ocpp.task.GetLocalListVersionTask;
import de.rwth.idsg.steve.ocpp.task.ReserveNowTask;
import de.rwth.idsg.steve.ocpp.task.SendLocalListTask;
import de.rwth.idsg.steve.repository.OcppTagRepository;
import de.rwth.idsg.steve.repository.ReservationRepository;
import de.rwth.idsg.steve.repository.dto.ChargePointSelect;
import de.rwth.idsg.steve.repository.dto.InsertReservationParams;
Expand All @@ -55,7 +54,6 @@
@Qualifier("ChargePointService15_Client")
public class ChargePointService15_Client extends ChargePointService12_Client {

@Autowired protected OcppTagRepository userRepository;
@Autowired protected OcppTagService ocppTagService;
@Autowired protected ReservationRepository reservationRepository;

Expand Down Expand Up @@ -135,7 +133,7 @@ public int reserveNow(ReserveNowParams params) {
.build();

int reservationId = reservationRepository.insert(res);
String parentIdTag = userRepository.getParentIdtag(params.getIdTag());
String parentIdTag = ocppTagService.getParentIdtag(params.getIdTag());

EnhancedReserveNowParams enhancedParams = new EnhancedReserveNowParams(params, reservationId, parentIdTag);
ReserveNowTask task = new ReserveNowTask(getVersion(), enhancedParams, reservationRepository);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import de.rwth.idsg.steve.service.notification.OcppStationWebSocketDisconnected;
import de.rwth.idsg.steve.service.notification.OcppTransactionEnded;
import de.rwth.idsg.steve.service.notification.OcppTransactionStarted;
import java.util.Set;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
Expand All @@ -49,7 +50,16 @@
*/
@Slf4j
@Service
public class NotificationService {
public class MailNotificationService {

public static final Set<NotificationFeature> SUPPORTED_FEATURES = Set.of(
OcppStationBooted,
OcppStationStatusFailure,
OcppStationWebSocketConnected,
OcppStationWebSocketDisconnected,
OcppTransactionStarted,
OcppTransactionEnded
);

@Autowired private MailService mailService;

Expand Down
Loading