Skip to content

Commit

Permalink
Merge pull request #3526 from sap-labs-france/master-labs
Browse files Browse the repository at this point in the history
Version 2.7.6
  • Loading branch information
Claude ROSSI authored Mar 21, 2023
2 parents 72e9236 + fc81c10 commit a80a2c2
Show file tree
Hide file tree
Showing 21 changed files with 240 additions and 80 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "ev-dashboard",
"description": "Dashboard for monitoring the EV Charging Infrastructure",
"homepage": "https://github.com/sap-labs-france/ev-dashboard",
"version": "2.7.5",
"version": "2.7.6",
"engines": {
"node": "^16.15.x",
"npm": "^8.11.x"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -390,10 +390,13 @@ export class ChargingStationsListTableDataSource extends TableDataSource<Chargin
// Edit
if (chargingStation.canUpdate) {
tableActionDef.push(this.editAction);
tableActionDef.push(this.smartChargingAction);
} else {
tableActionDef.push(this.viewAction);
}
// Charging profile
if(chargingStation.canUpdateChargingProfile) {
tableActionDef.push(this.smartChargingAction);
}
// Maintain pricing
if (this.isPricingComponentActive && chargingStation.canMaintainPricingDefinitions) {
tableActionDef.push(this.maintainPricingDefinitionsAction);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ export class SiteAreasListTableDataSource extends TableDataSource<SiteArea> {
private siteAreaGenerateQrCodeConnectorAction = new TableSiteAreaGenerateQrCodeConnectorAction().getActionDef();
private createAction = new TableCreateSiteAreaAction().getActionDef();
private siteAreasAuthorizations: SiteAreasAuthorizations;
private smartChargingSessionParametersActive: boolean;

public constructor(
public spinnerService: SpinnerService,
Expand Down Expand Up @@ -100,6 +101,7 @@ export class SiteAreasListTableDataSource extends TableDataSource<SiteArea> {
// Build TableDef using the initialized auth object
this.setTableDef(this.buildTableDef());
this.createAction.visible = this.siteAreasAuthorizations.canCreate;
this.smartChargingSessionParametersActive = siteAreas.smartChargingSessionParametersActive;
observer.next(siteAreas);
observer.complete();
},
Expand Down Expand Up @@ -284,7 +286,8 @@ export class SiteAreasListTableDataSource extends TableDataSource<SiteArea> {
case SiteAreaButtonAction.CREATE_SITE_AREA:
if (actionDef.action) {
(actionDef as TableCreateSiteAreaActionDef).action(SiteAreaDialogComponent, this.dialog,
{ authorizations: this.siteAreasAuthorizations }, this.refreshData.bind(this));
{ dialogData: {smartChargingSessionParametersActive: this.smartChargingSessionParametersActive} as SiteArea,
authorizations: this.siteAreasAuthorizations }, this.refreshData.bind(this));
}
break;
}
Expand All @@ -296,13 +299,15 @@ export class SiteAreasListTableDataSource extends TableDataSource<SiteArea> {
case SiteAreaButtonAction.EDIT_SITE_AREA:
if (actionDef.action) {
(actionDef as TableEditSiteAreaActionDef).action(SiteAreaDialogComponent, this.dialog,
{ dialogData: siteArea, authorizations: this.siteAreasAuthorizations }, this.refreshData.bind(this));
{ dialogData: {...siteArea, smartChargingSessionParametersActive: this.smartChargingSessionParametersActive},
authorizations: this.siteAreasAuthorizations }, this.refreshData.bind(this));
}
break;
case SiteAreaButtonAction.VIEW_SITE_AREA:
if (actionDef.action) {
(actionDef as TableViewSiteAreaActionDef).action(SiteAreaDialogComponent, this.dialog,
{ dialogData: siteArea, authorizations: this.siteAreasAuthorizations }, this.refreshData.bind(this));
{ dialogData: {...siteArea, smartChargingSessionParametersActive: this.smartChargingSessionParametersActive},
authorizations: this.siteAreasAuthorizations }, this.refreshData.bind(this));
}
break;
case SiteAreaButtonAction.ASSIGN_CHARGING_STATIONS_TO_SITE_AREA:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,4 @@
<form class="form" [formGroup]="formGroup">
<div class="row">
<div class="col-md-12 mb-3">
<div *ngIf="isSmartChargingComponentActive" class="text-left">
<mat-checkbox [formControl]="smartCharging">
{{'site_areas.enable_smart_charging' | translate}}
</mat-checkbox>
</div>
</div>
</div>
<div class="row">
<div class="col-md-4">
<mat-form-field>
Expand All @@ -20,10 +11,10 @@
</div>
<div class="col-md-4">
<mat-form-field>
<mat-label for="numberOfPhases">{{'site_areas.number_of_phases' | translate}}
<mat-label for="numberOfPhases">{{'site_areas.number_of_phases' | translate}}
</mat-label>
<mat-select id="numberOfPhases" [formControl]="numberOfPhases"
(selectionChange)="numberOfPhasesChanged()" required>
<mat-select id="numberOfPhases" [formControl]="numberOfPhases" (selectionChange)="numberOfPhasesChanged()"
required>
<mat-option *ngFor="let phase of phaseMap" [value]="phase.key">
{{phase.description | translate}}
</mat-option>
Expand Down Expand Up @@ -59,4 +50,44 @@
</mat-form-field>
</div>
</div>
<div *ngIf="isSmartChargingComponentActive" class="text-left">
<div class="row">
<div class="col-md-12 mb-3">
<mat-checkbox [formControl]="smartCharging" (change)="smartChargingChanged()">
{{'site_areas.enable_smart_charging' | translate}}
</mat-checkbox>
</div>
</div>
<div *ngIf="smartChargingSessionParametersActive" class="row">
<div class="col-md-4">
<mat-form-field>
<mat-label>{{'settings.smart_charging.session_parameters.departureTime' | translate}}</mat-label>
<input matInput type="time" id="departureTime" name="departureTime" [formControl]="departureTime"/>
<button mat-icon-button matSuffix (click)="resetDepartureTime()" aria-label="Clear">
<mat-icon>clear</mat-icon>
</button>
</mat-form-field>
</div>
<div class="col-md-4">
<mat-form-field>
<input matInput placeholder="{{'settings.smart_charging.session_parameters.carStateOfCharge' | translate}}" type="number"
[formControl]="carStateOfCharge">
<mat-error *ngIf="carStateOfCharge.errors?.min">
{{"general.error_min_value" | translate:{value: 1} }}</mat-error>
<mat-error *ngIf="carStateOfCharge.errors?.max">
{{"general.error_max_value" | translate:{value: 100} }}</mat-error>
</mat-form-field>
</div>
<div class="col-md-4">
<mat-form-field>
<input matInput placeholder="{{'settings.smart_charging.session_parameters.targetStateOfCharge' | translate}}" type="number"
[formControl]="targetStateOfCharge">
<mat-error *ngIf="targetStateOfCharge.errors?.min">
{{"general.error_min_value" | translate:{value: 1} }}</mat-error>
<mat-error *ngIf="targetStateOfCharge.errors?.max">
{{"general.error_max_value" | translate:{value: 100} }}</mat-error>
</mat-form-field>
</div>
</div>
</div>
</form>
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { SiteArea } from '../../../../../types/SiteArea';
})
export class SiteAreaLimitsComponent implements OnInit, OnChanges {
@Input() public siteArea!: SiteArea;
@Input() public smartChargingSessionParametersActive!: boolean;
@Input() public formGroup!: UntypedFormGroup;
@Input() public readOnly: boolean;

Expand All @@ -24,6 +25,10 @@ export class SiteAreaLimitsComponent implements OnInit, OnChanges {
public voltage!: AbstractControl;
public smartCharging!: AbstractControl;
public numberOfPhases!: AbstractControl;
public smartChargingSessionParameters!: UntypedFormGroup;
public departureTime!: AbstractControl;
public carStateOfCharge!: AbstractControl;
public targetStateOfCharge!: AbstractControl;

public phaseMap = [
{ key: 1, description: 'site_areas.single_phased' },
Expand Down Expand Up @@ -58,6 +63,25 @@ export class SiteAreaLimitsComponent implements OnInit, OnChanges {
Validators.required,
])
));
if (this.smartChargingSessionParametersActive) {
this.formGroup.addControl('smartChargingSessionParameters', new UntypedFormGroup({
departureTime: new UntypedFormControl(null),
carStateOfCharge: new UntypedFormControl(null,
Validators.compose([
Validators.min(1),
Validators.max(100),
Validators.pattern('^[+]?[0-9]*$'),
])
),
targetStateOfCharge: new UntypedFormControl(null,
Validators.compose([
Validators.min(1),
Validators.max(100),
Validators.pattern('^[+]?[0-9]*$'),
])
),
}));
}
// Form
this.smartCharging = this.formGroup.controls['smartCharging'];
this.maximumPower = this.formGroup.controls['maximumPower'];
Expand All @@ -67,6 +91,12 @@ export class SiteAreaLimitsComponent implements OnInit, OnChanges {
this.numberOfPhases = this.formGroup.controls['numberOfPhases'];
this.maximumPowerAmpsPerPhase.disable();
this.maximumTotalPowerAmps.disable();
if (this.smartChargingSessionParametersActive) {
this.smartChargingSessionParameters = this.formGroup.controls['smartChargingSessionParameters'] as UntypedFormGroup;
this.departureTime = this.smartChargingSessionParameters.controls['departureTime'];
this.carStateOfCharge = this.smartChargingSessionParameters.controls['carStateOfCharge'];
this.targetStateOfCharge = this.smartChargingSessionParameters.controls['targetStateOfCharge'];
}
this.initialized = true;
this.loadSiteArea();
}
Expand All @@ -88,11 +118,27 @@ export class SiteAreaLimitsComponent implements OnInit, OnChanges {
}
if (this.siteArea.smartCharging) {
this.smartCharging.setValue(this.siteArea.smartCharging);
if (this.smartChargingSessionParametersActive && this.siteArea.smartChargingSessionParameters) {
this.departureTime.setValue(this.siteArea.smartChargingSessionParameters.departureTime);
this.carStateOfCharge.setValue(this.siteArea.smartChargingSessionParameters.carStateOfCharge);
this.targetStateOfCharge.setValue(this.siteArea.smartChargingSessionParameters.targetStateOfCharge);
}
} else {
this.smartCharging.setValue(false);
}
this.refreshMaximumAmps();
}
this.refreshSmartChargingSessionParameters();
}

public smartChargingChanged() {
if(this.smartChargingSessionParametersActive && this.smartCharging) {
if (this.smartCharging.value) {
this.smartChargingSessionParameters.enable();
} else {
this.smartChargingSessionParameters.disable();
}
}
}

public voltageChanged() {
Expand All @@ -107,6 +153,15 @@ export class SiteAreaLimitsComponent implements OnInit, OnChanges {
this.maximumPowerChanged();
}

public refreshSmartChargingSessionParameters(){
this.smartChargingChanged();
}

public resetDepartureTime(){
this.departureTime.setValue(null);
this.departureTime.markAsDirty();
}

public maximumPowerChanged() {
if (!this.maximumPower.errors && this.voltage.value) {
if (this.numberOfPhases.value) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,22 @@ import { Utils } from '../../../../utils/Utils';
import { SiteAreaComponent } from './site-area.component';

@Component({
template: '<app-site-area #appRef [currentSiteAreaID]="siteAreaID" [siteAreasAuthorizations]="siteAreasAuthorizations" [dialogMode]="dialogMode" [dialogRef]="dialogRef"></app-site-area>'
template: '<app-site-area #appRef [currentSiteAreaID]="siteAreaID" [siteAreasAuthorizations]="siteAreasAuthorizations" [dialogMode]="dialogMode" [dialogRef]="dialogRef" [smartChargingSessionParametersActive]="smartChargingSessionParametersActive"></app-site-area>'
})
export class SiteAreaDialogComponent implements AfterViewInit {
@ViewChild('appRef') public appRef!: SiteAreaComponent;
public siteAreaID!: string;
public dialogMode!: DialogMode;
public siteAreasAuthorizations!: SiteAreasAuthorizations;
public smartChargingSessionParametersActive: boolean;

public constructor(
public dialogRef: MatDialogRef<SiteAreaDialogComponent>,
@Inject(MAT_DIALOG_DATA) dialogParams: DialogParamsWithAuth<SiteArea, SiteAreasAuthorizations>) {
this.siteAreaID = dialogParams.dialogData?.id;
this.dialogMode = dialogParams.dialogMode;
this.siteAreasAuthorizations = dialogParams.authorizations;
this.smartChargingSessionParametersActive = dialogParams.dialogData?.smartChargingSessionParametersActive;
}

public ngAfterViewInit() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
<span>{{'site_areas.limits' | translate}}</span>
</ng-template>
<div class="card-body mat-tab-dialog-body-content">
<app-site-area-limits #siteAreaLimitsComponent [formGroup]="formGroup" [siteArea]="siteArea" [readOnly]="readOnly"></app-site-area-limits>
<app-site-area-limits #siteAreaLimitsComponent [formGroup]="formGroup" [siteArea]="siteArea" [smartChargingSessionParametersActive]="smartChargingSessionParametersActive" [readOnly]="readOnly"></app-site-area-limits>
</div>
</mat-tab>
<mat-tab *ngIf="ocpiActive && ocpiHasVisibleFields && formGroup.controls.issuer.value">
Expand All @@ -39,4 +39,4 @@
</button>
</div>
</div>
</div>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export class SiteAreaComponent extends AbstractTabComponent implements OnInit {
@Input() public dialogMode!: DialogMode;
@Input() public dialogRef!: MatDialogRef<any>;
@Input() public siteAreasAuthorizations!: SiteAreasAuthorizations;
@Input() public smartChargingSessionParametersActive!: boolean;

@ViewChild('siteAreaMainComponent') public siteAreaMainComponent!: SiteAreaMainComponent;
@ViewChild('siteAreaLimitsComponent') public siteAreaLimitsComponent!: SiteAreaLimitsComponent;
Expand Down
15 changes: 15 additions & 0 deletions src/app/release-notes/release-notes.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,21 @@ export class ReleaseNotesComponent {
}
public buildReleaseNotes() {
this.releaseNotes = [
{
version: '2.7.6',
date: new Date('2023-03-14'),
componentChanges: [
{
name: 'Dashboard',
changes: [
'Smart Charging - Advanced Parameters for Departure Time',
'Smart Charging - Limit the number of periods to 16 (4 hours)',
'Billing - Stripe Integration - update dependency to the latest API version - 2022-11-15',
'Security - removed vulnerability from strong-soap dependencies'
],
},
],
},
{
version: '2.7.5',
date: new Date('2022-11-21'),
Expand Down
1 change: 1 addition & 0 deletions src/app/types/DataResult.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ export interface SiteUserDataResult extends DataResult<SiteUser>, SiteUsersAutho
}

export interface SiteAreaDataResult extends DataResult<SiteArea> {
smartChargingSessionParametersActive: boolean;
}

export interface TagDataResult extends DataResult<Tag>, TagsAuthorizations {
Expand Down
8 changes: 7 additions & 1 deletion src/app/types/SiteArea.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ import { ChargingStation, Voltage } from './ChargingStation';
import Consumption from './Consumption';
import { Site } from './Site';
import { TableData } from './Table';
import { SmartChargingSessionParameters } from './Transaction';

export interface SiteArea extends TableData, SiteAreaAuthorizationActions {
export interface SiteArea extends TableData, SiteAreaAuthorizationActions, SmartChargingSessionParametersActive {
id: string;
name: string;
image: string;
Expand All @@ -15,6 +16,7 @@ export interface SiteArea extends TableData, SiteAreaAuthorizationActions {
voltage: Voltage;
accessControl: boolean;
smartCharging: boolean;
smartChargingSessionParameters: SmartChargingSessionParameters;
siteID: string;
site: Site;
parentSiteArea?: SiteArea;
Expand All @@ -23,6 +25,10 @@ export interface SiteArea extends TableData, SiteAreaAuthorizationActions {
chargingStations: ChargingStation[];
tariffID?: string;
}
export interface SmartChargingSessionParametersActive {
smartChargingSessionParametersActive?: boolean;
}


export enum SiteAreaValueTypes {
ASSET_CONSUMPTIONS = 'AssetConsumptions',
Expand Down
8 changes: 7 additions & 1 deletion src/app/types/Transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,13 @@ export interface StartTransactionDialogData extends TableData {
}

export interface SmartChargingSessionParameters {
departureTime: number;
departureTime: string;
carStateOfCharge: number;
targetStateOfCharge: number;
}

export interface SmartChargingRuntimeSessionParameters {
departureTime?: Date; // Date of the departure time - taking into account the timezone of the charging station
carStateOfCharge?: number;
targetStateOfCharge?: number;
}
4 changes: 2 additions & 2 deletions src/app/types/User.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Car } from './Car';
import CreatedUpdatedProps from './CreatedUpdatedProps';
import { TableData } from './Table';
import { Tag } from './Tag';
import { SmartChargingSessionParameters, StartTransactionErrorCode } from './Transaction';
import { SmartChargingRuntimeSessionParameters, StartTransactionErrorCode } from './Transaction';

export interface User extends TableData, CreatedUpdatedProps, UserAuthorizationActions {
id: string;
Expand Down Expand Up @@ -74,7 +74,7 @@ export interface UserSessionContext {
car?: Car;
tag?: Tag;
errorCodes?: StartTransactionErrorCode[];
smartChargingSessionParameters?: SmartChargingSessionParameters;
smartChargingSessionParameters?: SmartChargingRuntimeSessionParameters;
}

export interface UserToken {
Expand Down
Loading

0 comments on commit a80a2c2

Please sign in to comment.