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 loadflow parameters controller #82

Merged
merged 22 commits into from
Jan 26, 2024
Merged
Show file tree
Hide file tree
Changes from 8 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
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.gridsuite.loadflow.server.dto.LimitViolationInfos;
import org.gridsuite.loadflow.server.dto.LoadFlowParametersInfos;
import org.gridsuite.loadflow.server.dto.LoadFlowResult;
import org.gridsuite.loadflow.server.dto.LoadFlowStatus;
import org.gridsuite.loadflow.server.service.LoadFlowRunContext;
import org.gridsuite.loadflow.server.service.LoadFlowService;
import org.gridsuite.loadflow.server.service.parameters.LoadFlowParametersService;
import org.gridsuite.loadflow.server.utils.ReportContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
Expand All @@ -42,6 +42,9 @@ public class LoadFlowController {
@Autowired
private LoadFlowService loadFlowService;

@Autowired
private LoadFlowParametersService parametersService;

@PostMapping(value = "/networks/{networkUuid}/run-and-save", produces = APPLICATION_JSON_VALUE)
@Operation(summary = "Run a load flow on a network")
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The load flow has been performed")})
Expand All @@ -53,16 +56,16 @@ public ResponseEntity<UUID> run(@Parameter(description = "Network UUID") @PathVa
@Parameter(description = "reporterId") @RequestParam(name = "reporterId", required = false) String reportName,
@Parameter(description = "The type name for the report") @RequestParam(name = "reportType", required = false, defaultValue = "LoadFlow") String reportType,
@Parameter(description = "The limit reduction") @RequestParam(name = "limitReduction", required = false, defaultValue = "0.8F") Float limitReduction,
@RequestHeader(HEADER_USER_ID) String userId,
@RequestBody(required = false) LoadFlowParametersInfos loadflowParams
@Parameter(description = "parametersUuid") @RequestParam(name = "parametersUuid", required = false) UUID parametersUuid,
@RequestHeader(HEADER_USER_ID) String userId
) {
String providerToUse = provider != null ? provider : loadFlowService.getDefaultProvider();
LoadFlowRunContext loadFlowRunContext = LoadFlowRunContext.builder()
ayolab marked this conversation as resolved.
Show resolved Hide resolved
.networkUuid(networkUuid)
.variantId(variantId)
.receiver(receiver)
.provider(providerToUse)
.parameters(loadflowParams)
.parameters(parametersService.getParametersValues(parametersUuid, providerToUse))
.reportContext(ReportContext.builder().reportId(reportId).reportName(reportName).reportType(reportType).build())
.userId(userId)
.limitReduction(limitReduction)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/**
* Copyright (c) 2023, RTE (http://www.rte-france.com)
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.gridsuite.loadflow.server;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;

import org.gridsuite.loadflow.server.dto.parameters.LoadFlowParametersInfos;
import org.gridsuite.loadflow.server.service.parameters.LoadFlowParametersService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.UUID;

/**
* @author Ayoub LABIDI <ayoub.labidi at rte-france.com>
*/
@RestController
@RequestMapping(value = "/" + LoadFlowApi.API_VERSION + "/parameters")
@Tag(name = "LoadFlow parameters")
public class LoadFlowParametersController {

@Autowired
private LoadFlowParametersService parametersService;

@PostMapping(value = "", consumes = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "Create parameters")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "parameters were created")})
ayolab marked this conversation as resolved.
Show resolved Hide resolved
public ResponseEntity<UUID> createParameters(
@RequestBody LoadFlowParametersInfos parametersInfos) {
return ResponseEntity.ok().body(parametersService.createParameters(parametersInfos));
ayolab marked this conversation as resolved.
Show resolved Hide resolved
}

@PostMapping(value = "")
ayolab marked this conversation as resolved.
Show resolved Hide resolved
@Operation(summary = "Duplicate parameters")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "parameters were duplicated")})
ayolab marked this conversation as resolved.
Show resolved Hide resolved
public ResponseEntity<UUID> createParameters(
ayolab marked this conversation as resolved.
Show resolved Hide resolved
@RequestParam("duplicateFrom") UUID sourceParametersUuid) {
return ResponseEntity.ok().body(parametersService.duplicateParameters(sourceParametersUuid));
}

@GetMapping(value = "/{uuid}", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "Get parameters")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "parameters were returned"),
@ApiResponse(responseCode = "404", description = "parameters were not found")})
ayolab marked this conversation as resolved.
Show resolved Hide resolved
public ResponseEntity<LoadFlowParametersInfos> getParameters(
@Parameter(description = "parameters UUID") @PathVariable("uuid") UUID parametersUuid) {
LoadFlowParametersInfos parameters = parametersService.getParameters(parametersUuid);
return parameters != null ? ResponseEntity.ok().body(parametersService.getParameters(parametersUuid))
flomillot marked this conversation as resolved.
Show resolved Hide resolved
: ResponseEntity.notFound().build();
}

@GetMapping(value = "", produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "Get all parameters")
@ApiResponse(responseCode = "200", description = "The list of all parameters was returned")
public ResponseEntity<List<LoadFlowParametersInfos>> getAllParameters() {
return ResponseEntity.ok().body(parametersService.getAllParameters());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return ResponseEntity.ok().body(parametersService.getAllParameters());
return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(parametersService.getAllParameters());

}

@PutMapping(value = "/{uuid}", consumes = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "Update parameters")
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "parameters were updated")})
ayolab marked this conversation as resolved.
Show resolved Hide resolved
public ResponseEntity<Void> updateParameters(
@Parameter(description = "parameters UUID") @PathVariable("uuid") UUID parametersUuid,
@RequestBody LoadFlowParametersInfos parametersInfos) {
parametersService.updateParameters(parametersUuid, parametersInfos);
return ResponseEntity.ok().build();
}

@DeleteMapping(value = "/{uuid}")
@Operation(summary = "Delete parameters")
@ApiResponse(responseCode = "200", description = "parameters were deleted")
public ResponseEntity<Void> deleteParameters(
@Parameter(description = "parameters UUID") @PathVariable("uuid") UUID parametersUuid) {
parametersService.deleteParameters(parametersUuid);
return ResponseEntity.ok().build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/**
Copyright (c) 2023, RTE (http://www.rte-france.com)
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.gridsuite.loadflow.server.dto.parameters;

import com.powsybl.loadflow.LoadFlowParameters;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.util.Map;
import java.util.UUID;

import org.gridsuite.loadflow.server.entities.parameters.LoadFlowParametersEntity;

/**
* @author Ayoub LABIDI <ayoub.labidi at rte-france.com>
*/
@Getter
@AllArgsConstructor
@Builder
@NoArgsConstructor
public class LoadFlowParametersInfos {

private UUID uuid;

private LoadFlowParameters commonParameters;

private Map<String, Map<String, String>> specificParametersPerProvider;

public LoadFlowParametersEntity toEntity() {
return new LoadFlowParametersEntity(this);
}
}
ayolab marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.gridsuite.loadflow.server.dto;
package org.gridsuite.loadflow.server.dto.parameters;

import com.powsybl.loadflow.LoadFlowParameters;
import lombok.AllArgsConstructor;
Expand All @@ -21,7 +21,7 @@
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class LoadFlowParametersInfos {
public class LoadFlowParametersValues {
ayolab marked this conversation as resolved.
Show resolved Hide resolved

private LoadFlowParameters commonParameters;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
/**
* Copyright (c) 2023, RTE (http://www.rte-france.com)
ayolab marked this conversation as resolved.
Show resolved Hide resolved
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

ayolab marked this conversation as resolved.
Show resolved Hide resolved
package org.gridsuite.loadflow.server.entities.parameters;

import com.powsybl.iidm.network.Country;
import com.powsybl.loadflow.LoadFlowParameters;
import lombok.*;

import jakarta.persistence.*;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;

import org.gridsuite.loadflow.server.dto.parameters.LoadFlowParametersInfos;
import org.gridsuite.loadflow.server.dto.parameters.LoadFlowParametersValues;

/**
* @author Ayoub LABIDI <ayoub.labidi at rte-france.com>
*/
@Builder
@NoArgsConstructor
@AllArgsConstructor
Comment on lines +28 to +29
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To have a constructor without default values

Suggested change
@NoArgsConstructor
@AllArgsConstructor
@NoArgsConstructor
@AllArgsConstructor
@RequiredArgsConstructor

@Getter
@Setter
@Entity
@Table(name = "loadFlowParameters")
public class LoadFlowParametersEntity {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id")
private UUID id;

@Column(name = "voltageInitMode")
@Enumerated(EnumType.STRING)
private LoadFlowParameters.VoltageInitMode voltageInitMode;

@Column(name = "transformerVoltageControlOn", columnDefinition = "boolean default false")
private boolean transformerVoltageControlOn;

@Column(name = "useReactiveLimits", columnDefinition = "boolean default true")
private boolean useReactiveLimits;

@Column(name = "phaseShifterRegulationOn", columnDefinition = "boolean default false")
private boolean phaseShifterRegulationOn;

@Column(name = "twtSplitShuntAdmittance", columnDefinition = "boolean default false")
private boolean twtSplitShuntAdmittance;

@Column(name = "shuntCompensatorVoltageControlOn", columnDefinition = "boolean default false")
private boolean shuntCompensatorVoltageControlOn;

@Column(name = "readSlackBus", columnDefinition = "boolean default true")
private boolean readSlackBus;

@Column(name = "writeSlackBus", columnDefinition = "boolean default false")
private boolean writeSlackBus;

@Column(name = "dc", columnDefinition = "boolean default false")
private boolean dc;

@Column(name = "distributedSlack", columnDefinition = "boolean default true")
private boolean distributedSlack;

@Column(name = "balanceType")
@Enumerated(EnumType.STRING)
private LoadFlowParameters.BalanceType balanceType;

@Column(name = "dcUseTransformerRatio", columnDefinition = "boolean default true")
private boolean dcUseTransformerRatio;

@Column(name = "countriesToBalance")
@ElementCollection
@CollectionTable(foreignKey = @ForeignKey(name = "loadFlowParametersEntity_countriesToBalance_fk1"),
indexes = {@Index(name = "loadFlowParametersEntity_countriesToBalance_idx1",
columnList = "load_flow_parameters_entity_id")})
private Set<String> countriesToBalance;

@Column(name = "connectedComponentMode")
@Enumerated(EnumType.STRING)
private LoadFlowParameters.ConnectedComponentMode connectedComponentMode;

@Column(name = "hvdcAcEmulation", columnDefinition = "boolean default true")
private boolean hvdcAcEmulation;

@Column(name = "dcPowerFactor", columnDefinition = "double default 1.0")
private double dcPowerFactor;
ayolab marked this conversation as resolved.
Show resolved Hide resolved

@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
@JoinColumn(name = "load_flow_parameters_entity_id", foreignKey = @ForeignKey(name = "loadFlowParametersEntity_specificParameters_fk"))
private List<LoadFlowSpecificParameterEntity> specificParameters;

public LoadFlowParametersEntity(LoadFlowParametersInfos loadFlowParametersInfos) {
assignAttributes(loadFlowParametersInfos);
}

public void update(LoadFlowParametersInfos loadFlowParametersInfos) {
assignAttributes(loadFlowParametersInfos);
}

public void assignAttributes(LoadFlowParametersInfos loadFlowParametersInfos) {
LoadFlowParameters allCommonValues;
List<LoadFlowSpecificParameterEntity> allSpecificValuesEntities = new ArrayList<>(List.of());
if (loadFlowParametersInfos == null) {
allCommonValues = LoadFlowParameters.load();
} else {
allCommonValues = loadFlowParametersInfos.getCommonParameters();
if (loadFlowParametersInfos.getSpecificParametersPerProvider() != null) {
loadFlowParametersInfos.getSpecificParametersPerProvider().forEach((provider, paramsMap) -> {
if (paramsMap != null) {
paramsMap.forEach((paramName, paramValue) -> {
if (paramValue != null) {
allSpecificValuesEntities.add(new LoadFlowSpecificParameterEntity(
null,
provider,
paramName,
paramValue));
}
}
);
}
});
}
}
voltageInitMode = allCommonValues.getVoltageInitMode();
transformerVoltageControlOn = allCommonValues.isTransformerVoltageControlOn();
useReactiveLimits = allCommonValues.isUseReactiveLimits();
phaseShifterRegulationOn = allCommonValues.isPhaseShifterRegulationOn();
twtSplitShuntAdmittance = allCommonValues.isTwtSplitShuntAdmittance();
shuntCompensatorVoltageControlOn = allCommonValues.isShuntCompensatorVoltageControlOn();
readSlackBus = allCommonValues.isReadSlackBus();
writeSlackBus = allCommonValues.isWriteSlackBus();
dc = allCommonValues.isDc();
distributedSlack = allCommonValues.isDistributedSlack();
balanceType = allCommonValues.getBalanceType();
dcUseTransformerRatio = allCommonValues.isDcUseTransformerRatio();
countriesToBalance = allCommonValues.getCountriesToBalance().stream().map(Country::toString).collect(Collectors.toSet());
connectedComponentMode = allCommonValues.getConnectedComponentMode();
hvdcAcEmulation = allCommonValues.isHvdcAcEmulation();
dcPowerFactor = allCommonValues.getDcPowerFactor();
if (specificParameters == null) {
specificParameters = allSpecificValuesEntities;
} else {
specificParameters.clear();
if (!allSpecificValuesEntities.isEmpty()) {
specificParameters.addAll(allSpecificValuesEntities);
}
}
}

public LoadFlowParameters toLoadFlowParameters() {
return LoadFlowParameters.load()
.setVoltageInitMode(this.getVoltageInitMode())
.setTransformerVoltageControlOn(this.isTransformerVoltageControlOn())
.setUseReactiveLimits(this.isUseReactiveLimits())
.setPhaseShifterRegulationOn(this.isPhaseShifterRegulationOn())
.setTwtSplitShuntAdmittance(this.isTwtSplitShuntAdmittance())
.setShuntCompensatorVoltageControlOn(this.isShuntCompensatorVoltageControlOn())
.setReadSlackBus(this.isReadSlackBus())
.setWriteSlackBus(this.isWriteSlackBus())
.setDc(this.isDc())
.setDistributedSlack(this.isDistributedSlack())
.setBalanceType(this.getBalanceType())
.setDcUseTransformerRatio(this.isDcUseTransformerRatio())
.setCountriesToBalance(this.getCountriesToBalance().stream().map(Country::valueOf).collect(Collectors.toSet()))
.setConnectedComponentMode(this.getConnectedComponentMode())
.setHvdcAcEmulation(this.isHvdcAcEmulation())
.setDcPowerFactor(this.getDcPowerFactor());
}

public LoadFlowParametersInfos toLoadFlowParametersInfos() {
return LoadFlowParametersInfos.builder()
.uuid(id)
.commonParameters(toLoadFlowParameters())
.specificParametersPerProvider(specificParameters.stream()
.collect(Collectors.groupingBy(LoadFlowSpecificParameterEntity::getProvider,
Collectors.toMap(LoadFlowSpecificParameterEntity::getName,
LoadFlowSpecificParameterEntity::getValue))))
.build();
}

public LoadFlowParametersValues toLoadFlowParametersValues(String provider) {
return LoadFlowParametersValues.builder()
.commonParameters(toLoadFlowParameters())
.specificParameters(specificParameters.stream()
.filter(p -> p.getProvider().equalsIgnoreCase(provider))
.collect(Collectors.toMap(LoadFlowSpecificParameterEntity::getName,
LoadFlowSpecificParameterEntity::getValue)))
.build();
}

public LoadFlowParametersEntity copy() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good !

return toLoadFlowParametersInfos().toEntity();
}
}
Loading
Loading