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

UI: EVCS add save-button #2299

Merged
merged 14 commits into from
Aug 2, 2023
Merged
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
56 changes: 0 additions & 56 deletions ui/src/app/edge/live/Controller/Evcs/Evcs.html

This file was deleted.

207 changes: 26 additions & 181 deletions ui/src/app/edge/live/Controller/Evcs/Evcs.ts
Original file line number Diff line number Diff line change
@@ -1,184 +1,29 @@
import { Component } from '@angular/core';
import { AbstractFlatWidget } from 'src/app/shared/genericComponents/flat/abstract-flat-widget';

import { ChannelAddress, CurrentData, EdgeConfig, Utils } from '../../../../shared/shared';
import { Controller_EvcsModalComponent } from './modal/modal.page';

@Component({
selector: 'Controller_Evcs',
templateUrl: './Evcs.html'
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { SharedModule } from 'src/app/shared/shared.module';
import { FlatComponent } from './flat/flat';
import { ModalComponent } from './modal/modal';
import { PopoverComponent } from './popover/popover';

@NgModule({
imports: [
BrowserModule,
SharedModule
],
entryComponents: [
FlatComponent,
ModalComponent,
PopoverComponent
],
declarations: [
FlatComponent,
ModalComponent,
PopoverComponent
],
exports: [
FlatComponent
]
})
export class Controller_EvcsComponent extends AbstractFlatWidget {

public controller: EdgeConfig.Component = null;
public evcsComponent: EdgeConfig.Component = null;
public chargeMode: ChargeMode = null;
public status: string;
public isConnectionSuccessful: boolean = false;
public isEnergySinceBeginningAllowed: boolean = false;
public mode: string;
public isChargingEnabled: boolean = false;
public defaultChargeMinPower: number;
public prioritization: string;
public phases: number;
public maxChargingValue: number;
public energySessionLimit: number;
public readonly CONVERT_TO_KILO_WATTHOURS = Utils.CONVERT_TO_KILO_WATTHOURS;
public readonly CONVERT_WATT_TO_KILOWATT = Utils.CONVERT_WATT_TO_KILOWATT;

protected override getChannelAddresses() {
return [
new ChannelAddress(this.componentId, 'ChargePower'),
new ChannelAddress(this.componentId, 'Phases'),
new ChannelAddress(this.componentId, 'Plug'),
new ChannelAddress(this.componentId, 'Status'),
new ChannelAddress(this.componentId, 'State'),
new ChannelAddress(this.componentId, 'EnergySession'),
// channels for modal component, subscribe here for better UX
new ChannelAddress(this.componentId, 'MinimumHardwarePower'),
new ChannelAddress(this.componentId, 'MaximumHardwarePower'),
new ChannelAddress(this.componentId, 'SetChargePowerLimit')
];
}

protected override onCurrentData(currentData: CurrentData) {

// Gets the Controller & Component for the given EVCS - Component.
let controllers = this.config.getComponentsByFactory("Controller.Evcs");
for (let controller of controllers) {
let properties = controller.properties;
if ("evcs.id" in properties && properties["evcs.id"] === this.componentId) {
this.controller = controller;
}
}
this.evcsComponent = this.config.getComponent(this.componentId);
this.isConnectionSuccessful = currentData.allComponents[this.componentId + '/State'] != 3 ? true : false;
this.status = this.getState(currentData.allComponents[this.componentId + "/Status"], currentData.allComponents[this.componentId + "/Plug"]);

// Check if Energy since beginning is allowed
if (currentData.allComponents[this.componentId + '/ChargePower'] > 0 || currentData.allComponents[this.componentId + '/Status'] == 2 || currentData.allComponents[this.componentId + '/Status'] == 7) {
this.isEnergySinceBeginningAllowed = true;
}

// Mode
if (this.isChargingEnabled) {
if (this.chargeMode == 'FORCE_CHARGE') {
this.mode = this.translate.instant('General.manually');
} else if (this.chargeMode == 'EXCESS_POWER') {
this.mode = this.translate.instant('Edge.Index.Widgets.EVCS.OptimizedChargeMode.shortName');
}
}

// Check if Controller is set
if (this.controller) {

// ChargeMode
this.chargeMode = this.controller.properties['chargeMode'];
// Check if Charging is enabled
this.isChargingEnabled = this.controller.properties['enabledCharging'] ? true : false;
// DefaultChargeMinPower
this.defaultChargeMinPower = this.controller.properties['defaultChargeMinPower'];
// Prioritization
this.prioritization =
this.controller.properties['priority'] in Prioritization
? 'Edge.Index.Widgets.EVCS.OptimizedChargeMode.ChargingPriority.' + this.controller.properties['priority'].toLowerCase()
: '';
// MaxChargingValue
if (this.phases) {
this.maxChargingValue = Utils.multiplySafely(this.controller.properties['forceChargeMinPower'], this.phases);
} else {
this.maxChargingValue = Utils.multiplySafely(this.controller.properties['forceChargeMinPower'], 3);
}
// EnergySessionLimit
this.energySessionLimit = this.controller.properties['energySessionLimit'];
}

// Phases
this.phases = currentData.allComponents[this.componentId + '/Phases'];
}

/**
* Returns the state of the EVCS
*
* @param state
* @param plug
*
*/
private getState(state: number, plug: number): string {
if (this.controller != null) {
if (this.controller.properties.enabledCharging != null && this.controller.properties.enabledCharging == false) {
return this.translate.instant('Edge.Index.Widgets.EVCS.chargingStationDeactivated');
}
}
let chargeState = state;
let chargePlug = plug;

if (chargePlug == null) {
if (chargeState == null) {
return this.translate.instant('Edge.Index.Widgets.EVCS.notCharging');
}
} else if (chargePlug != ChargePlug.PLUGGED_ON_EVCS_AND_ON_EV_AND_LOCKED) {
return this.translate.instant('Edge.Index.Widgets.EVCS.cableNotConnected');
}
switch (chargeState) {
case ChargeState.STARTING:
return this.translate.instant('Edge.Index.Widgets.EVCS.starting');
case ChargeState.UNDEFINED:
case ChargeState.ERROR:
return this.translate.instant('Edge.Index.Widgets.EVCS.error');
case ChargeState.READY_FOR_CHARGING:
return this.translate.instant('Edge.Index.Widgets.EVCS.readyForCharging');
case ChargeState.NOT_READY_FOR_CHARGING:
return this.translate.instant('Edge.Index.Widgets.EVCS.notReadyForCharging');
case ChargeState.AUTHORIZATION_REJECTED:
return this.translate.instant('Edge.Index.Widgets.EVCS.notCharging');
case ChargeState.CHARGING:
return this.translate.instant('Edge.Index.Widgets.EVCS.charging');
case ChargeState.ENERGY_LIMIT_REACHED:
return this.translate.instant('Edge.Index.Widgets.EVCS.chargeLimitReached');
case ChargeState.CHARGING_FINISHED:
return this.translate.instant('Edge.Index.Widgets.EVCS.carFull');
}
}

async presentModal() {
const modal = await this.modalController.create({
component: Controller_EvcsModalComponent,
componentProps: {
controller: this.controller,
edge: this.edge,
componentId: this.componentId,
evcsComponent: this.evcsComponent
// getState: this.getState
}
});
return await modal.present();
}
}

enum ChargeState {
UNDEFINED = -1, //Undefined
STARTING, //Starting
NOT_READY_FOR_CHARGING, //Not ready for Charging e.g. unplugged, X1 or "ena" not enabled, RFID not enabled,...
READY_FOR_CHARGING, //Ready for Charging waiting for EV charging request
CHARGING, //Charging
ERROR, //Error
AUTHORIZATION_REJECTED, //Authorization rejected
ENERGY_LIMIT_REACHED, //Energy limit reached
CHARGING_FINISHED //Charging has finished
}
export class Controller_Evcs { }

enum ChargePlug {
UNDEFINED = -1, //Undefined
UNPLUGGED, //Unplugged
PLUGGED_ON_EVCS, //Plugged on EVCS
PLUGGED_ON_EVCS_AND_LOCKED = 3, //Plugged on EVCS and locked
PLUGGED_ON_EVCS_AND_ON_EV = 5, //Plugged on EVCS and on EV
PLUGGED_ON_EVCS_AND_ON_EV_AND_LOCKED = 7 //Plugged on EVCS and on EV and locked
}
enum Prioritization {
CAR,
STORAGE
}

type ChargeMode = 'FORCE_CHARGE' | 'EXCESS_POWER';
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Component, Input, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { ModalController } from '@ionic/angular';
import { TranslateService } from '@ngx-translate/core';
import { Edge, EdgeConfig, Service, Websocket } from '../../../../../../shared/shared';
import { Edge, EdgeConfig, Service, Websocket } from '../../../../../shared/shared';

@Component({
selector: AdministrationComponent.SELECTOR,
Expand Down
59 changes: 59 additions & 0 deletions ui/src/app/edge/live/Controller/Evcs/flat/flat.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<oe-flat-widget button (click)="presentModal()" style="cursor: pointer;" *ngIf="isInitialized"
[title]="evcsComponent.alias" [icon]="{name: 'oe-evcs', color: 'environmental'}">

<!-- Show if Connection is Successful -->
<ng-container *ngIf="isConnectionSuccessful, else noConnection">

<oe-flat-widget-line [name]="'Edge.Index.Widgets.EVCS.status'| translate" [value]="status" leftColumnWidth="20">
</oe-flat-widget-line>

<!-- Check if energy since beginning is allowed to be shown -->
<oe-flat-widget-line *ngIf="isEnergySinceBeginningAllowed"
[name]="'Edge.Index.Widgets.EVCS.energySinceBeginning' | translate"
[channelAddress]="componentId + '/EnergySession'" [converter]="CONVERT_TO_KILO_WATTHOURS">
</oe-flat-widget-line>

<oe-flat-widget-line *ngIf="isChargingEnabled" [name]="'General.mode'| translate" [value]="mode">
</oe-flat-widget-line>

<!-- Show if charging is enabled -->
<ng-container *ngIf="isChargingEnabled">

<!-- Show if chargeMode is EXCESS_POWER -->
<ng-container *ngIf="chargeMode === 'EXCESS_POWER'">

<!-- Show if defaultChargeMinPower greater 0 -->
<ng-container *ngIf="defaultChargeMinPower > 0">
<oe-flat-widget-line [name]="'Edge.Index.Widgets.EVCS.OptimizedChargeMode.minCharging' | translate"
[value]="'General.active' | translate">
</oe-flat-widget-line>

<oe-flat-widget-line
[name]="'Edge.Index.Widgets.EVCS.OptimizedChargeMode.minChargePower' | translate"
[converter]="CONVERT_WATT_TO_KILOWATT" [value]="defaultChargeMinPower" leftColumnWidth="50">
</oe-flat-widget-line>
</ng-container>

<oe-flat-widget-line leftColumnWidth="50" [name]="'Edge.Index.Widgets.EVCS.prioritization' | translate"
[value]="prioritization | translate">
</oe-flat-widget-line>
</ng-container>

<oe-flat-widget-line *ngIf="chargeMode === 'FORCE_CHARGE'"
[name]="'Edge.Index.Widgets.EVCS.ForceChargeMode.maxCharging' | translate"
[converter]="CONVERT_WATT_TO_KILOWATT" [value]="maxChargingValue">
</oe-flat-widget-line>

<oe-flat-widget-line *ngIf="energySessionLimit !== 0"
[name]="'Edge.Index.Widgets.EVCS.energyLimit' | translate" [converter]="CONVERT_TO_KILO_WATTHOURS"
[value]="energySessionLimit"></oe-flat-widget-line>
</ng-container>

</ng-container>

<ng-template #noConnection>
<oe-flat-widget-line leftColumnWidth="100"
[name]="'Edge.Index.Widgets.EVCS.NoConnection.description' | translate">
</oe-flat-widget-line>
</ng-template>
</oe-flat-widget>
Loading