UI: Add CoAP device profile power mode setting

This commit is contained in:
Vladyslav_Prykhodko 2021-07-16 15:10:20 +03:00 committed by Andrew Shvayka
parent a9a032a212
commit d27326122c
3 changed files with 129 additions and 29 deletions

View File

@ -15,7 +15,7 @@
limitations under the License.
-->
<form [formGroup]="coapDeviceProfileTransportConfigurationFormGroup" style="padding-bottom: 16px;">
<form [formGroup]="coapTransportConfigurationFormGroup" style="padding-bottom: 16px;">
<section formGroupName="coapDeviceTypeConfiguration">
<fieldset class="fields-group">
<legend class="group-title" translate>device-profile.coap-device-type</legend>
@ -23,10 +23,10 @@
<mat-form-field class="mat-block">
<mat-select formControlName="coapDeviceType" required>
<mat-option *ngFor="let type of coapTransportDeviceTypes" [value]="type">
{{coapTransportDeviceTypeTranslations.get(type) | translate}}
{{ coapTransportDeviceTypeTranslations.get(type) | translate}}
</mat-option>
</mat-select>
<mat-error *ngIf="coapDeviceProfileTransportConfigurationFormGroup.get('coapDeviceTypeConfiguration.coapDeviceType').hasError('required')">
<mat-error *ngIf="coapTransportConfigurationFormGroup.get('coapDeviceTypeConfiguration.coapDeviceType').hasError('required')">
{{ 'device-profile.coap-device-type-required' | translate }}
</mat-error>
</mat-form-field>
@ -39,10 +39,10 @@
<mat-form-field class="mat-block">
<mat-select formControlName="transportPayloadType" required>
<mat-option *ngFor="let type of transportPayloadTypes" [value]="type">
{{transportPayloadTypeTranslations.get(type) | translate}}
{{ transportPayloadTypeTranslations.get(type) | translate}}
</mat-option>
</mat-select>
<mat-error *ngIf="coapDeviceProfileTransportConfigurationFormGroup.get('coapDeviceTypeConfiguration.transportPayloadTypeConfiguration.transportPayloadType').hasError('required')">
<mat-error *ngIf="coapTransportConfigurationFormGroup.get('coapDeviceTypeConfiguration.transportPayloadTypeConfiguration.transportPayloadType').hasError('required')">
{{ 'device-profile.mqtt-payload-type-required' | translate }}
</mat-error>
</mat-form-field>
@ -50,21 +50,21 @@
<mat-form-field fxFlex>
<mat-label translate>device-profile.telemetry-proto-schema</mat-label>
<textarea matInput required formControlName="deviceTelemetryProtoSchema" rows="5"></textarea>
<mat-error *ngIf="coapDeviceProfileTransportConfigurationFormGroup.get('coapDeviceTypeConfiguration.transportPayloadTypeConfiguration.deviceTelemetryProtoSchema').hasError('required')">
<mat-error *ngIf="coapTransportConfigurationFormGroup.get('coapDeviceTypeConfiguration.transportPayloadTypeConfiguration.deviceTelemetryProtoSchema').hasError('required')">
{{ 'device-profile.telemetry-proto-schema-required' | translate}}
</mat-error>
</mat-form-field>
<mat-form-field fxFlex>
<mat-label translate>device-profile.attributes-proto-schema</mat-label>
<textarea matInput required formControlName="deviceAttributesProtoSchema" rows="5"></textarea>
<mat-error *ngIf="coapDeviceProfileTransportConfigurationFormGroup.get('coapDeviceTypeConfiguration.transportPayloadTypeConfiguration.deviceAttributesProtoSchema').hasError('required')">
<mat-error *ngIf="coapTransportConfigurationFormGroup.get('coapDeviceTypeConfiguration.transportPayloadTypeConfiguration.deviceAttributesProtoSchema').hasError('required')">
{{ 'device-profile.attributes-proto-schema-required' | translate}}
</mat-error>
</mat-form-field>
<mat-form-field style="padding-bottom: 20px" fxFlex>
<mat-label translate>device-profile.rpc-request-proto-schema</mat-label>
<textarea matInput required formControlName="deviceRpcRequestProtoSchema" rows="5"></textarea>
<mat-error *ngIf="coapDeviceProfileTransportConfigurationFormGroup.get('coapDeviceTypeConfiguration.transportPayloadTypeConfiguration.deviceRpcRequestProtoSchema').hasError('required')">
<mat-error *ngIf="coapTransportConfigurationFormGroup.get('coapDeviceTypeConfiguration.transportPayloadTypeConfiguration.deviceRpcRequestProtoSchema').hasError('required')">
{{ 'device-profile.rpc-request-proto-schema-required' | translate}}
</mat-error>
<mat-hint class="tb-hint" translate>device-profile.rpc-request-proto-schema-hint</mat-hint>
@ -72,7 +72,7 @@
<mat-form-field fxFlex>
<mat-label translate>device-profile.rpc-response-proto-schema</mat-label>
<textarea matInput required formControlName="deviceRpcResponseProtoSchema" rows="5"></textarea>
<mat-error *ngIf="coapDeviceProfileTransportConfigurationFormGroup.get('coapDeviceTypeConfiguration.transportPayloadTypeConfiguration.deviceRpcResponseProtoSchema').hasError('required')">
<mat-error *ngIf="coapTransportConfigurationFormGroup.get('coapDeviceTypeConfiguration.transportPayloadTypeConfiguration.deviceRpcResponseProtoSchema').hasError('required')">
{{ 'device-profile.rpc-response-proto-schema-required' | translate}}
</mat-error>
</mat-form-field>
@ -81,4 +81,52 @@
</fieldset>
</div>
</section>
<section formGroupName="clientSettings">
<fieldset class="fields-group">
<legend class="group-title" translate>device-profile.power-saving-mode</legend>
<mat-form-field class="mat-block" fxFlex>
<mat-label> </mat-label>
<mat-select formControlName="powerMode">
<mat-option *ngFor="let powerMod of powerMods" [value]="powerMod">
{{ powerModeTranslationMap.get(powerMod) | translate}}
</mat-option>
</mat-select>
</mat-form-field>
<section class="mat-block" fxFlex *ngIf="coapTransportConfigurationFormGroup.get('clientSettings.powerMode').value === 'E_DRX'">
<mat-form-field class="mat-block" fxFlex>
<mat-label>{{ 'device-profile.edrx-cycle' | translate }}</mat-label>
<input matInput type="number" min="0" formControlName="edrxCycle" required>
<mat-error *ngIf="coapTransportConfigurationFormGroup.get('clientSettings.edrxCycle').hasError('required')">
{{ 'device-profile.edrx-cycle-required' | translate }}
</mat-error>
<mat-error *ngIf="coapTransportConfigurationFormGroup.get('clientSettings.edrxCycle').hasError('pattern') ||
coapTransportConfigurationFormGroup.get('clientSettings.edrxCycle').hasError('min')">
{{ 'device-profile.edrx-cycle-pattern' | translate }}
</mat-error>
</mat-form-field>
<mat-form-field class="mat-block" fxFlex>
<mat-label>{{ 'device-profile.paging-transmission-window' | translate }}</mat-label>
<input matInput type="number" min="0" formControlName="pagingTransmissionWindow" required>
<mat-error *ngIf="coapTransportConfigurationFormGroup.get('clientSettings.pagingTransmissionWindow').hasError('required')">
{{ 'device-profile.paging-transmission-window-required' | translate }}
</mat-error>
<mat-error *ngIf="coapTransportConfigurationFormGroup.get('clientSettings.pagingTransmissionWindow').hasError('pattern') ||
coapTransportConfigurationFormGroup.get('clientSettings.pagingTransmissionWindow').hasError('min')">
{{ 'device-profile.paging-transmission-window-pattern' | translate }}
</mat-error>
</mat-form-field>
</section>
<mat-form-field class="mat-block" fxFlex *ngIf="coapTransportConfigurationFormGroup.get('clientSettings.powerMode').value === 'PSM'">
<mat-label>{{ 'device-profile.psm-activity-timer' | translate }}</mat-label>
<input matInput type="number" min="0" formControlName="psmActivityTimer" required>
<mat-error *ngIf="coapTransportConfigurationFormGroup.get('clientSettings.psmActivityTimer').hasError('required')">
{{ 'device-profile.psm-activity-timer-required' | translate }}
</mat-error>
<mat-error *ngIf="coapTransportConfigurationFormGroup.get('clientSettings.psmActivityTimer').hasError('pattern') ||
coapTransportConfigurationFormGroup.get('clientSettings.psmActivityTimer').hasError('min')">
{{ 'device-profile.psm-activity-timer-pattern' | translate }}
</mat-error>
</mat-form-field>
</fieldset>
</section>
</form>

View File

@ -35,6 +35,7 @@ import {
import { isDefinedAndNotNull } from '@core/utils';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { PowerMode, PowerModeTranslationMap } from '@home/components/profile/device/lwm2m/lwm2m-profile-config.models';
@Component({
selector: 'tb-coap-device-profile-transport-configuration',
@ -48,15 +49,16 @@ import { takeUntil } from 'rxjs/operators';
})
export class CoapDeviceProfileTransportConfigurationComponent implements ControlValueAccessor, OnInit, OnDestroy {
coapTransportDeviceTypes = Object.keys(CoapTransportDeviceType);
coapTransportDeviceTypes = Object.values(CoapTransportDeviceType);
coapTransportDeviceTypeTranslations = coapDeviceTypeTranslationMap;
transportPayloadTypes = Object.keys(TransportPayloadType);
transportPayloadTypes = Object.values(TransportPayloadType);
transportPayloadTypeTranslations = transportPayloadTypeTranslationMap;
coapDeviceProfileTransportConfigurationFormGroup: FormGroup;
powerMods = Object.values(PowerMode);
powerModeTranslationMap = PowerModeTranslationMap;
coapTransportConfigurationFormGroup: FormGroup;
private destroy$ = new Subject();
private requiredValue: boolean;
@ -95,19 +97,48 @@ export class CoapDeviceProfileTransportConfigurationComponent implements Control
}
ngOnInit() {
this.coapDeviceProfileTransportConfigurationFormGroup = this.fb.group({
this.coapTransportConfigurationFormGroup = this.fb.group({
coapDeviceTypeConfiguration: this.fb.group({
coapDeviceType: [CoapTransportDeviceType.DEFAULT, Validators.required],
transportPayloadTypeConfiguration: this.transportPayloadTypeConfiguration
})
}
coapDeviceType: [CoapTransportDeviceType.DEFAULT, Validators.required],
transportPayloadTypeConfiguration: this.transportPayloadTypeConfiguration,
}),
clientSettings: this.fb.group({
powerMode: [PowerMode.DRX, Validators.required],
edrxCycle: [{disabled: true, value: 0}],
psmActivityTimer: [{disabled: true, value: 0}],
pagingTransmissionWindow: [{disabled: true, value: 0}]
})}
);
this.coapDeviceProfileTransportConfigurationFormGroup.get('coapDeviceTypeConfiguration.coapDeviceType').valueChanges.pipe(
this.coapTransportConfigurationFormGroup.get('coapDeviceTypeConfiguration.coapDeviceType').valueChanges.pipe(
takeUntil(this.destroy$)
).subscribe(coapDeviceType => {
this.updateCoapDeviceTypeBasedControls(coapDeviceType, true);
});
this.coapDeviceProfileTransportConfigurationFormGroup.valueChanges.pipe(
this.coapTransportConfigurationFormGroup.get('clientSettings.powerMode').valueChanges.pipe(
takeUntil(this.destroy$)
).subscribe((powerMode: PowerMode) => {
if (powerMode === PowerMode.E_DRX) {
this.coapTransportConfigurationFormGroup.get('clientSettings.edrxCycle').enable({emitEvent: false});
this.coapTransportConfigurationFormGroup.get('clientSettings.pagingTransmissionWindow').enable({emitEvent: false});
this.coapTransportConfigurationFormGroup.get('clientSettings.edrxCycle')
.setValidators([Validators.required, Validators.min(0), Validators.pattern('[0-9]*')]);
this.coapTransportConfigurationFormGroup.get('clientSettings.pagingTransmissionWindow')
.setValidators([Validators.required, Validators.min(0), Validators.pattern('[0-9]*')]);
this.clearValidatorsPSKMode();
} else if (powerMode === PowerMode.PSM) {
this.coapTransportConfigurationFormGroup.get('clientSettings.psmActivityTimer').enable({emitEvent: false});
this.coapTransportConfigurationFormGroup.get('clientSettings.psmActivityTimer')
.setValidators([Validators.required, Validators.min(0), Validators.pattern('[0-9]*')]);
this.clearValidatorsEdrxMode();
} else {
this.clearValidatorsEdrxMode();
this.clearValidatorsPSKMode();
}
this.coapTransportConfigurationFormGroup.get('clientSettings.edrxCycle').updateValueAndValidity({emitEvent: false});
this.coapTransportConfigurationFormGroup.get('clientSettings.pagingTransmissionWindow').updateValueAndValidity({emitEvent: false});
this.coapTransportConfigurationFormGroup.get('clientSettings.psmActivityTimer').updateValueAndValidity({emitEvent: false});
});
this.coapTransportConfigurationFormGroup.valueChanges.pipe(
takeUntil(this.destroy$)
).subscribe(() => {
this.updateModel();
@ -120,19 +151,19 @@ export class CoapDeviceProfileTransportConfigurationComponent implements Control
}
get coapDeviceTypeDefault(): boolean {
const coapDeviceType = this.coapDeviceProfileTransportConfigurationFormGroup.get('coapDeviceTypeConfiguration.coapDeviceType').value;
const coapDeviceType = this.coapTransportConfigurationFormGroup.get('coapDeviceTypeConfiguration.coapDeviceType').value;
return coapDeviceType === CoapTransportDeviceType.DEFAULT;
}
get protoPayloadType(): boolean {
const transportPayloadTypePath = 'coapDeviceTypeConfiguration.transportPayloadTypeConfiguration.transportPayloadType';
const transportPayloadType = this.coapDeviceProfileTransportConfigurationFormGroup.get(transportPayloadTypePath).value;
const transportPayloadType = this.coapTransportConfigurationFormGroup.get(transportPayloadTypePath).value;
return transportPayloadType === TransportPayloadType.PROTOBUF;
}
private updateCoapDeviceTypeBasedControls(type: CoapTransportDeviceType, forceUpdated = false) {
const coapDeviceTypeConfigurationFormGroup = this.coapDeviceProfileTransportConfigurationFormGroup
const coapDeviceTypeConfigurationFormGroup = this.coapTransportConfigurationFormGroup
.get('coapDeviceTypeConfiguration') as FormGroup;
if (forceUpdated) {
coapDeviceTypeConfigurationFormGroup.patchValue({
@ -149,26 +180,41 @@ export class CoapDeviceProfileTransportConfigurationComponent implements Control
setDisabledState(isDisabled: boolean): void {
this.disabled = isDisabled;
if (this.disabled) {
this.coapDeviceProfileTransportConfigurationFormGroup.disable({emitEvent: false});
this.coapTransportConfigurationFormGroup.disable({emitEvent: false});
} else {
this.coapDeviceProfileTransportConfigurationFormGroup.enable({emitEvent: false});
this.coapTransportConfigurationFormGroup.enable({emitEvent: false});
this.coapTransportConfigurationFormGroup.get('clientSettings.powerMode').updateValueAndValidity({onlySelf: true});
}
}
writeValue(value: CoapDeviceProfileTransportConfiguration | null): void {
if (isDefinedAndNotNull(value)) {
this.coapDeviceProfileTransportConfigurationFormGroup.patchValue(value, {emitEvent: false});
this.coapTransportConfigurationFormGroup.patchValue(value, {emitEvent: false});
this.updateCoapDeviceTypeBasedControls(value.coapDeviceTypeConfiguration?.coapDeviceType);
}
}
private updateModel() {
let configuration: DeviceProfileTransportConfiguration = null;
if (this.coapDeviceProfileTransportConfigurationFormGroup.valid) {
configuration = this.coapDeviceProfileTransportConfigurationFormGroup.value;
if (this.coapTransportConfigurationFormGroup.valid) {
configuration = this.coapTransportConfigurationFormGroup.value;
configuration.type = DeviceTransportType.COAP;
}
this.propagateChange(configuration);
}
private clearValidatorsPSKMode() {
this.coapTransportConfigurationFormGroup.get('clientSettings.psmActivityTimer').disable({emitEvent: false});
this.coapTransportConfigurationFormGroup.get('clientSettings.psmActivityTimer').reset(0, {emitEvent: false});
this.coapTransportConfigurationFormGroup.get('clientSettings.psmActivityTimer').clearValidators();
}
private clearValidatorsEdrxMode() {
this.coapTransportConfigurationFormGroup.get('clientSettings.edrxCycle').disable({emitEvent: false});
this.coapTransportConfigurationFormGroup.get('clientSettings.edrxCycle').reset(0, {emitEvent: false});
this.coapTransportConfigurationFormGroup.get('clientSettings.edrxCycle').clearValidators();
this.coapTransportConfigurationFormGroup.get('clientSettings.pagingTransmissionWindow').disable({emitEvent: false});
this.coapTransportConfigurationFormGroup.get('clientSettings.pagingTransmissionWindow').reset(0, {emitEvent: false});
this.coapTransportConfigurationFormGroup.get('clientSettings.pagingTransmissionWindow').clearValidators();
}
}

View File

@ -1232,6 +1232,12 @@
"edrx-cycle": "eDRX cycle in milliseconds",
"edrx-cycle-required": "eDRX cycle is required.",
"edrx-cycle-pattern": "eDRX cycle must be a positive integer.",
"paging-transmission-window": "Paging Transmission Window in milliseconds",
"paging-transmission-window-required": "Paging transmission window is required.",
"paging-transmission-window-pattern": "Paging transmission window must be a positive integer.",
"psm-activity-timer": "PSM Activity Timer in milliseconds",
"psm-activity-timer-required": "PSM activity timer is required.",
"psm-activity-timer-pattern": "PSM activity timer must be a positive integer.",
"lwm2m": {
"object-list": "Object list",
"object-list-empty": "No objects selected.",