Commit 6c631a9f146516fd7dbbc839928eb8ea8a74bce7
Committed by
Andrew Shvayka
1 parent
3a7a97dd
UI: Add power mode settings in LwM2M device profile and refactoring lwm2m device…
… profile transport form
Showing
16 changed files
with
266 additions
and
230 deletions
... | ... | @@ -141,7 +141,7 @@ import { DashboardImageDialogComponent } from '@home/components/dashboard-page/d |
141 | 141 | import { WidgetContainerComponent } from '@home/components/widget/widget-container.component'; |
142 | 142 | import { SnmpDeviceProfileTransportModule } from '@home/components/profile/device/snpm/snmp-device-profile-transport.module'; |
143 | 143 | import { DeviceCredentialsModule } from '@home/components/device/device-credentials.module'; |
144 | -import { PowerModeSettingComponent } from '@home/components/profile/device/common/power-mode-setting.component'; | |
144 | +import { DeviceProfileCommonModule } from '@home/components/profile/device/common/device-profile-common.module'; | |
145 | 145 | |
146 | 146 | @NgModule({ |
147 | 147 | declarations: |
... | ... | @@ -260,8 +260,7 @@ import { PowerModeSettingComponent } from '@home/components/profile/device/commo |
260 | 260 | DashboardStateDialogComponent, |
261 | 261 | DashboardImageDialogComponent, |
262 | 262 | EmbedDashboardDialogComponent, |
263 | - DisplayWidgetTypesPanelComponent, | |
264 | - PowerModeSettingComponent | |
263 | + DisplayWidgetTypesPanelComponent | |
265 | 264 | ], |
266 | 265 | imports: [ |
267 | 266 | CommonModule, |
... | ... | @@ -270,7 +269,8 @@ import { PowerModeSettingComponent } from '@home/components/profile/device/commo |
270 | 269 | Lwm2mProfileComponentsModule, |
271 | 270 | SnmpDeviceProfileTransportModule, |
272 | 271 | StatesControllerModule, |
273 | - DeviceCredentialsModule | |
272 | + DeviceCredentialsModule, | |
273 | + DeviceProfileCommonModule | |
274 | 274 | ], |
275 | 275 | exports: [ |
276 | 276 | EntitiesTableComponent, |
... | ... | @@ -371,8 +371,7 @@ import { PowerModeSettingComponent } from '@home/components/profile/device/commo |
371 | 371 | DashboardStateDialogComponent, |
372 | 372 | DashboardImageDialogComponent, |
373 | 373 | EmbedDashboardDialogComponent, |
374 | - DisplayWidgetTypesPanelComponent, | |
375 | - PowerModeSettingComponent | |
374 | + DisplayWidgetTypesPanelComponent | |
376 | 375 | ], |
377 | 376 | providers: [ |
378 | 377 | WidgetComponentService, | ... | ... |
ui-ngx/src/app/modules/home/components/profile/device/common/device-profile-common.module.ts
0 → 100644
1 | +/// | |
2 | +/// Copyright © 2016-2021 The Thingsboard Authors | |
3 | +/// | |
4 | +/// Licensed under the Apache License, Version 2.0 (the "License"); | |
5 | +/// you may not use this file except in compliance with the License. | |
6 | +/// You may obtain a copy of the License at | |
7 | +/// | |
8 | +/// http://www.apache.org/licenses/LICENSE-2.0 | |
9 | +/// | |
10 | +/// Unless required by applicable law or agreed to in writing, software | |
11 | +/// distributed under the License is distributed on an "AS IS" BASIS, | |
12 | +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 | +/// See the License for the specific language governing permissions and | |
14 | +/// limitations under the License. | |
15 | +/// | |
16 | + | |
17 | +import { NgModule } from '@angular/core'; | |
18 | +import { PowerModeSettingComponent } from '@home/components/profile/device/common/power-mode-setting.component'; | |
19 | +import { SharedModule } from '@shared/shared.module'; | |
20 | +import { CommonModule } from '@angular/common'; | |
21 | + | |
22 | +@NgModule({ | |
23 | + declarations: [ | |
24 | + PowerModeSettingComponent | |
25 | + ], | |
26 | + imports: [ | |
27 | + CommonModule, | |
28 | + SharedModule | |
29 | + ], | |
30 | + exports: [ | |
31 | + PowerModeSettingComponent | |
32 | + ] | |
33 | +}) | |
34 | +export class DeviceProfileCommonModule { } | ... | ... |
... | ... | @@ -132,7 +132,7 @@ |
132 | 132 | <mat-option [value]=3>{{ 'device-profile.lwm2m.fw-update-strategy-data' | translate }}</mat-option> |
133 | 133 | </mat-select> |
134 | 134 | </mat-form-field> |
135 | - <mat-form-field class="mat-block" fxFlex *ngIf="isFwUpdateStrategy"> | |
135 | + <mat-form-field class="mat-block" fxFlex *ngIf="lwm2mDeviceProfileFormGroup.get('clientLwM2mSettings.fwUpdateStrategy').value === 2"> | |
136 | 136 | <mat-label>{{ 'device-profile.lwm2m.fw-update-resource' | translate }}</mat-label> |
137 | 137 | <input matInput formControlName="fwUpdateResource" required> |
138 | 138 | <mat-error *ngIf="lwm2mDeviceProfileFormGroup.get('clientLwM2mSettings.fwUpdateResource').hasError('required')"> |
... | ... | @@ -149,7 +149,7 @@ |
149 | 149 | <mat-option [value]=2>{{ 'device-profile.lwm2m.sw-update-strategy-package-uri' | translate }}</mat-option> |
150 | 150 | </mat-select> |
151 | 151 | </mat-form-field> |
152 | - <mat-form-field class="mat-block" fxFlex *ngIf="isSwUpdateStrategy"> | |
152 | + <mat-form-field class="mat-block" fxFlex *ngIf="lwm2mDeviceProfileFormGroup.get('clientLwM2mSettings.swUpdateStrategy').value === 2"> | |
153 | 153 | <mat-label>{{ 'device-profile.lwm2m.sw-update-resource' | translate }}</mat-label> |
154 | 154 | <input matInput formControlName="swUpdateResource" required> |
155 | 155 | <mat-error *ngIf="lwm2mDeviceProfileFormGroup.get('clientLwM2mSettings.swUpdateResource').hasError('required')"> |
... | ... | @@ -159,25 +159,8 @@ |
159 | 159 | </fieldset> |
160 | 160 | <fieldset class="fields-group"> |
161 | 161 | <legend class="group-title" translate>device-profile.power-saving-mode</legend> |
162 | - <mat-form-field class="mat-block" fxFlex> | |
163 | - <mat-label> </mat-label> | |
164 | - <mat-select formControlName="powerMode"> | |
165 | - <mat-option *ngFor="let powerMod of powerMods" [value]="powerMod"> | |
166 | - {{ powerModeTranslationMap.get(powerMod) | translate}} | |
167 | - </mat-option> | |
168 | - </mat-select> | |
169 | - </mat-form-field> | |
170 | - <mat-form-field class="mat-block" fxFlex *ngIf="lwm2mDeviceProfileFormGroup.get('clientLwM2mSettings.powerMode').value === 'E_DRX'"> | |
171 | - <mat-label>{{ 'device-profile.edrx-cycle' | translate }}</mat-label> | |
172 | - <input matInput type="number" min="0" formControlName="edrxCycle" required> | |
173 | - <mat-error *ngIf="lwm2mDeviceProfileFormGroup.get('clientLwM2mSettings.edrxCycle').hasError('required')"> | |
174 | - {{ 'device-profile.edrx-cycle-required' | translate }} | |
175 | - </mat-error> | |
176 | - <mat-error *ngIf="lwm2mDeviceProfileFormGroup.get('clientLwM2mSettings.edrxCycle').hasError('pattern') || | |
177 | - lwm2mDeviceProfileFormGroup.get('clientLwM2mSettings.edrxCycle').hasError('min')"> | |
178 | - {{ 'device-profile.edrx-cycle-pattern' | translate }} | |
179 | - </mat-error> | |
180 | - </mat-form-field> | |
162 | + <tb-power-mode-settings [parentForm]="clientSettingsFormGroup"> | |
163 | + </tb-power-mode-settings> | |
181 | 164 | </fieldset> |
182 | 165 | <mat-slide-toggle class="mat-slider" |
183 | 166 | formControlName="compositeOperationsSupport">{{ 'device-profile.lwm2m.composite-operations-support' | translate }}</mat-slide-toggle> | ... | ... |
... | ... | @@ -16,7 +16,15 @@ |
16 | 16 | |
17 | 17 | import { DeviceProfileTransportConfiguration } from '@shared/models/device.models'; |
18 | 18 | import { Component, forwardRef, Input, OnDestroy } from '@angular/core'; |
19 | -import { ControlValueAccessor, FormBuilder, FormGroup, NG_VALUE_ACCESSOR, Validators } from '@angular/forms'; | |
19 | +import { | |
20 | + ControlValueAccessor, | |
21 | + FormBuilder, | |
22 | + FormGroup, NG_VALIDATORS, | |
23 | + NG_VALUE_ACCESSOR, | |
24 | + ValidationErrors, | |
25 | + Validator, | |
26 | + Validators | |
27 | +} from '@angular/forms'; | |
20 | 28 | import { coerceBooleanProperty } from '@angular/cdk/coercion'; |
21 | 29 | import { |
22 | 30 | ATTRIBUTE, |
... | ... | @@ -30,10 +38,7 @@ import { |
30 | 38 | DEFAULT_NOTIF_IF_DESIBLED, |
31 | 39 | DEFAULT_SW_UPDATE_RESOURCE, |
32 | 40 | getDefaultBootstrapServerSecurityConfig, |
33 | - getDefaultBootstrapServersSecurityConfig, | |
34 | 41 | getDefaultLwM2MServerSecurityConfig, |
35 | - getDefaultProfileClientLwM2mSettingsConfig, | |
36 | - getDefaultProfileObserveAttrConfig, | |
37 | 42 | Instance, |
38 | 43 | INSTANCES, |
39 | 44 | KEY_NAME, |
... | ... | @@ -41,7 +46,6 @@ import { |
41 | 46 | ObjectLwM2M, |
42 | 47 | OBSERVE, |
43 | 48 | PowerMode, |
44 | - PowerModeTranslationMap, | |
45 | 49 | RESOURCES, |
46 | 50 | ServerSecurityConfig, |
47 | 51 | TELEMETRY |
... | ... | @@ -58,13 +62,19 @@ import { takeUntil } from 'rxjs/operators'; |
58 | 62 | selector: 'tb-profile-lwm2m-device-transport-configuration', |
59 | 63 | templateUrl: './lwm2m-device-profile-transport-configuration.component.html', |
60 | 64 | styleUrls: ['./lwm2m-device-profile-transport-configuration.component.scss'], |
61 | - providers: [{ | |
62 | - provide: NG_VALUE_ACCESSOR, | |
63 | - useExisting: forwardRef(() => Lwm2mDeviceProfileTransportConfigurationComponent), | |
64 | - multi: true | |
65 | - }] | |
65 | + providers: [ | |
66 | + { | |
67 | + provide: NG_VALUE_ACCESSOR, | |
68 | + useExisting: forwardRef(() => Lwm2mDeviceProfileTransportConfigurationComponent), | |
69 | + multi: true | |
70 | + }, | |
71 | + { | |
72 | + provide: NG_VALIDATORS, | |
73 | + useExisting: forwardRef(() => Lwm2mDeviceProfileTransportConfigurationComponent), | |
74 | + multi: true | |
75 | + }] | |
66 | 76 | }) |
67 | -export class Lwm2mDeviceProfileTransportConfigurationComponent implements ControlValueAccessor, Validators, OnDestroy { | |
77 | +export class Lwm2mDeviceProfileTransportConfigurationComponent implements ControlValueAccessor, Validator, OnDestroy { | |
68 | 78 | |
69 | 79 | private configurationValue: Lwm2mProfileConfigModels; |
70 | 80 | private requiredValue: boolean; |
... | ... | @@ -76,10 +86,6 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro |
76 | 86 | lwm2mDeviceProfileFormGroup: FormGroup; |
77 | 87 | lwm2mDeviceConfigFormGroup: FormGroup; |
78 | 88 | sortFunction: (key: string, value: object) => object; |
79 | - isFwUpdateStrategy: boolean; | |
80 | - isSwUpdateStrategy: boolean; | |
81 | - powerMods = Object.values(PowerMode); | |
82 | - powerModeTranslationMap = PowerModeTranslationMap; | |
83 | 89 | |
84 | 90 | get required(): boolean { |
85 | 91 | return this.requiredValue; |
... | ... | @@ -116,7 +122,9 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro |
116 | 122 | fwUpdateResource: [{value: '', disabled: true}, []], |
117 | 123 | swUpdateResource: [{value: '', disabled: true}, []], |
118 | 124 | powerMode: [PowerMode.DRX, Validators.required], |
119 | - edrxCycle: [0], | |
125 | + edrxCycle: [{disabled: true, value: 0}, [Validators.required, Validators.min(0), Validators.pattern('[0-9]*')]], | |
126 | + psmActivityTimer: [{disabled: true, value: 0}, [Validators.required, Validators.min(0), Validators.pattern('[0-9]*')]], | |
127 | + pagingTransmissionWindow: [{disabled: true, value: 0}, [Validators.required, Validators.min(0), Validators.pattern('[0-9]*')]], | |
120 | 128 | compositeOperationsSupport: [false] |
121 | 129 | }) |
122 | 130 | }); |
... | ... | @@ -128,42 +136,22 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro |
128 | 136 | ).subscribe((fwStrategy) => { |
129 | 137 | if (fwStrategy === 2) { |
130 | 138 | this.lwm2mDeviceProfileFormGroup.get('clientLwM2mSettings.fwUpdateResource').enable({emitEvent: false}); |
131 | - this.lwm2mDeviceProfileFormGroup.get('clientLwM2mSettings.fwUpdateResource') | |
132 | - .patchValue(DEFAULT_FW_UPDATE_RESOURCE, {emitEvent: false}); | |
133 | - this.isFwUpdateStrategy = true; | |
134 | 139 | } else { |
135 | 140 | this.lwm2mDeviceProfileFormGroup.get('clientLwM2mSettings.fwUpdateResource').disable({emitEvent: false}); |
136 | - this.isFwUpdateStrategy = false; | |
141 | + this.lwm2mDeviceProfileFormGroup.get('clientLwM2mSettings.fwUpdateResource') | |
142 | + .reset(DEFAULT_FW_UPDATE_RESOURCE, {emitEvent: false}); | |
137 | 143 | } |
138 | - this.otaUpdateFwStrategyValidate(true); | |
139 | 144 | }); |
140 | 145 | this.lwm2mDeviceProfileFormGroup.get('clientLwM2mSettings.swUpdateStrategy').valueChanges.pipe( |
141 | 146 | takeUntil(this.destroy$) |
142 | 147 | ).subscribe((swStrategy) => { |
143 | 148 | if (swStrategy === 2) { |
144 | 149 | this.lwm2mDeviceProfileFormGroup.get('clientLwM2mSettings.swUpdateResource').enable({emitEvent: false}); |
145 | - this.lwm2mDeviceProfileFormGroup.get('clientLwM2mSettings.swUpdateResource') | |
146 | - .patchValue(DEFAULT_SW_UPDATE_RESOURCE, {emitEvent: false}); | |
147 | - this.isSwUpdateStrategy = true; | |
148 | 150 | } else { |
149 | - this.isSwUpdateStrategy = false; | |
150 | 151 | this.lwm2mDeviceProfileFormGroup.get('clientLwM2mSettings.swUpdateResource').disable({emitEvent: false}); |
152 | + this.lwm2mDeviceProfileFormGroup.get('clientLwM2mSettings.swUpdateResource') | |
153 | + .reset(DEFAULT_SW_UPDATE_RESOURCE, {emitEvent: false}); | |
151 | 154 | } |
152 | - this.otaUpdateSwStrategyValidate(true); | |
153 | - }); | |
154 | - this.lwm2mDeviceProfileFormGroup.get('clientLwM2mSettings.powerMode').valueChanges.pipe( | |
155 | - takeUntil(this.destroy$) | |
156 | - ).subscribe((powerMode: PowerMode) => { | |
157 | - if (powerMode === PowerMode.E_DRX) { | |
158 | - this.lwm2mDeviceProfileFormGroup.get('clientLwM2mSettings.edrxCycle').enable({emitEvent: false}); | |
159 | - this.lwm2mDeviceProfileFormGroup.get('clientLwM2mSettings.edrxCycle').patchValue(0, {emitEvent: false}); | |
160 | - this.lwm2mDeviceProfileFormGroup.get('clientLwM2mSettings.edrxCycle') | |
161 | - .setValidators([Validators.required, Validators.min(0), Validators.pattern('[0-9]*')]); | |
162 | - } else { | |
163 | - this.lwm2mDeviceProfileFormGroup.get('clientLwM2mSettings.edrxCycle').disable({emitEvent: false}); | |
164 | - this.lwm2mDeviceProfileFormGroup.get('clientLwM2mSettings.edrxCycle').clearValidators(); | |
165 | - } | |
166 | - this.lwm2mDeviceProfileFormGroup.get('clientLwM2mSettings.edrxCycle').updateValueAndValidity({emitEvent: false}); | |
167 | 155 | }); |
168 | 156 | this.lwm2mDeviceProfileFormGroup.valueChanges.pipe( |
169 | 157 | takeUntil(this.destroy$) |
... | ... | @@ -198,24 +186,33 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro |
198 | 186 | } else { |
199 | 187 | this.lwm2mDeviceProfileFormGroup.enable({emitEvent: false}); |
200 | 188 | this.lwm2mDeviceConfigFormGroup.enable({emitEvent: false}); |
189 | + this.lwm2mDeviceProfileFormGroup.get('clientLwM2mSettings.powerMode').updateValueAndValidity({onlySelf: true}); | |
190 | + this.lwm2mDeviceProfileFormGroup.get('clientLwM2mSettings.fwUpdateStrategy').updateValueAndValidity({onlySelf: true}); | |
191 | + this.lwm2mDeviceProfileFormGroup.get('clientLwM2mSettings.swUpdateStrategy').updateValueAndValidity({onlySelf: true}); | |
201 | 192 | } |
202 | 193 | } |
203 | 194 | |
204 | 195 | async writeValue(value: Lwm2mProfileConfigModels | null) { |
205 | - if (isDefinedAndNotNull(value)) { | |
206 | - if (value?.clientLwM2mSettings || value?.observeAttr || value?.bootstrap) { | |
207 | - this.configurationValue = value; | |
208 | - } else { | |
209 | - this.configurationValue = await this.defaultProfileConfig(); | |
210 | - } | |
196 | + if (isDefinedAndNotNull(value) && (value?.clientLwM2mSettings || value?.observeAttr || value?.bootstrap)) { | |
197 | + this.configurationValue = value; | |
198 | + const defaultFormSettings = !(value.observeAttr.attribute.length && value.observeAttr.telemetry.length); | |
211 | 199 | this.lwm2mDeviceConfigFormGroup.patchValue({ |
212 | 200 | configurationJson: this.configurationValue |
213 | - }, {emitEvent: false}); | |
201 | + }, {emitEvent: defaultFormSettings}); | |
202 | + if (defaultFormSettings) { | |
203 | + await this.defaultProfileConfig(); | |
204 | + } | |
214 | 205 | this.initWriteValue(); |
215 | 206 | } |
216 | 207 | } |
217 | 208 | |
218 | - private async defaultProfileConfig(): Promise<Lwm2mProfileConfigModels> { | |
209 | + validate(): ValidationErrors | null { | |
210 | + return this.lwm2mDeviceProfileFormGroup.valid ? null : { | |
211 | + lwm2mDeviceProfile: false | |
212 | + }; | |
213 | + } | |
214 | + | |
215 | + private async defaultProfileConfig(): Promise<void> { | |
219 | 216 | let bootstrap: ServerSecurityConfig; |
220 | 217 | let lwm2m: ServerSecurityConfig; |
221 | 218 | try { |
... | ... | @@ -227,15 +224,15 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro |
227 | 224 | bootstrap = getDefaultBootstrapServerSecurityConfig(); |
228 | 225 | lwm2m = getDefaultLwM2MServerSecurityConfig(); |
229 | 226 | } |
230 | - return { | |
231 | - observeAttr: getDefaultProfileObserveAttrConfig(), | |
232 | - bootstrap: { | |
233 | - servers: getDefaultBootstrapServersSecurityConfig(), | |
234 | - bootstrapServer: bootstrap, | |
235 | - lwm2mServer: lwm2m | |
236 | - }, | |
237 | - clientLwM2mSettings: getDefaultProfileClientLwM2mSettingsConfig() | |
238 | - }; | |
227 | + | |
228 | + this.configurationValue.bootstrap.bootstrapServer = bootstrap; | |
229 | + this.configurationValue.bootstrap.lwm2mServer = lwm2m; | |
230 | + this.lwm2mDeviceConfigFormGroup.patchValue({ | |
231 | + configurationJson: this.configurationValue | |
232 | + }, {emitEvent: false}); | |
233 | + this.lwm2mDeviceProfileFormGroup.patchValue({ | |
234 | + bootstrap: this.configurationValue.bootstrap | |
235 | + }, {emitEvent: false}); | |
239 | 236 | } |
240 | 237 | |
241 | 238 | private initWriteValue = (): void => { |
... | ... | @@ -256,10 +253,6 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro |
256 | 253 | } |
257 | 254 | |
258 | 255 | private updateWriteValue = (value: ObjectLwM2M[]): void => { |
259 | - const fwResource = isDefinedAndNotNull(this.configurationValue.clientLwM2mSettings.fwUpdateResource) ? | |
260 | - this.configurationValue.clientLwM2mSettings.fwUpdateResource : ''; | |
261 | - const swResource = isDefinedAndNotNull(this.configurationValue.clientLwM2mSettings.swUpdateResource) ? | |
262 | - this.configurationValue.clientLwM2mSettings.swUpdateResource : ''; | |
263 | 256 | this.lwm2mDeviceProfileFormGroup.patchValue({ |
264 | 257 | objectIds: value, |
265 | 258 | observeAttrTelemetry: this.getObserveAttrTelemetryObjects(value), |
... | ... | @@ -268,22 +261,19 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro |
268 | 261 | clientOnlyObserveAfterConnect: this.configurationValue.clientLwM2mSettings.clientOnlyObserveAfterConnect, |
269 | 262 | fwUpdateStrategy: this.configurationValue.clientLwM2mSettings.fwUpdateStrategy || 1, |
270 | 263 | swUpdateStrategy: this.configurationValue.clientLwM2mSettings.swUpdateStrategy || 1, |
271 | - fwUpdateResource: fwResource, | |
272 | - swUpdateResource: swResource, | |
264 | + fwUpdateResource: this.configurationValue.clientLwM2mSettings.fwUpdateResource || '', | |
265 | + swUpdateResource: this.configurationValue.clientLwM2mSettings.swUpdateResource || '', | |
273 | 266 | powerMode: this.configurationValue.clientLwM2mSettings.powerMode || PowerMode.DRX, |
274 | 267 | edrxCycle: this.configurationValue.clientLwM2mSettings.edrxCycle || 0, |
275 | 268 | compositeOperationsSupport: this.configurationValue.clientLwM2mSettings.compositeOperationsSupport || false |
276 | 269 | } |
277 | 270 | }, |
278 | 271 | {emitEvent: false}); |
279 | - this.lwm2mDeviceProfileFormGroup.get('clientLwM2mSettings.powerMode') | |
280 | - .patchValue(this.configurationValue.clientLwM2mSettings.powerMode || PowerMode.DRX, {emitEvent: false, onlySelf: true}); | |
281 | - this.configurationValue.clientLwM2mSettings.fwUpdateResource = fwResource; | |
282 | - this.configurationValue.clientLwM2mSettings.swUpdateResource = swResource; | |
283 | - this.isFwUpdateStrategy = this.configurationValue.clientLwM2mSettings.fwUpdateStrategy === 2; | |
284 | - this.isSwUpdateStrategy = this.configurationValue.clientLwM2mSettings.swUpdateStrategy === 2; | |
285 | - this.otaUpdateSwStrategyValidate(); | |
286 | - this.otaUpdateFwStrategyValidate(); | |
272 | + if (!this.disabled) { | |
273 | + this.lwm2mDeviceProfileFormGroup.get('clientLwM2mSettings.powerMode').updateValueAndValidity({onlySelf: true}); | |
274 | + this.lwm2mDeviceProfileFormGroup.get('clientLwM2mSettings.fwUpdateStrategy').updateValueAndValidity({onlySelf: true}); | |
275 | + this.lwm2mDeviceProfileFormGroup.get('clientLwM2mSettings.swUpdateStrategy').updateValueAndValidity({onlySelf: true}); | |
276 | + } | |
287 | 277 | } |
288 | 278 | |
289 | 279 | private updateModel = (): void => { |
... | ... | @@ -576,22 +566,8 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro |
576 | 566 | }); |
577 | 567 | } |
578 | 568 | |
579 | - private otaUpdateFwStrategyValidate(updated = false): void { | |
580 | - if (this.isFwUpdateStrategy) { | |
581 | - this.lwm2mDeviceProfileFormGroup.get('clientLwM2mSettings.fwUpdateResource').setValidators([Validators.required]); | |
582 | - } else { | |
583 | - this.lwm2mDeviceProfileFormGroup.get('clientLwM2mSettings.fwUpdateResource').clearValidators(); | |
584 | - } | |
585 | - this.lwm2mDeviceProfileFormGroup.get('clientLwM2mSettings.fwUpdateResource').updateValueAndValidity({emitEvent: updated}); | |
586 | - } | |
587 | - | |
588 | - private otaUpdateSwStrategyValidate(updated = false): void { | |
589 | - if (this.isSwUpdateStrategy) { | |
590 | - this.lwm2mDeviceProfileFormGroup.get('clientLwM2mSettings.swUpdateResource').setValidators([Validators.required]); | |
591 | - } else { | |
592 | - this.lwm2mDeviceProfileFormGroup.get('clientLwM2mSettings.swUpdateResource').clearValidators(); | |
593 | - } | |
594 | - this.lwm2mDeviceProfileFormGroup.get('clientLwM2mSettings.swUpdateResource').updateValueAndValidity({emitEvent: updated}); | |
569 | + get clientSettingsFormGroup(): FormGroup { | |
570 | + return this.lwm2mDeviceProfileFormGroup.get('clientLwM2mSettings') as FormGroup; | |
595 | 571 | } |
596 | 572 | |
597 | 573 | } | ... | ... |
... | ... | @@ -17,7 +17,7 @@ |
17 | 17 | --> |
18 | 18 | <form [formGroup]="instancesFormGroup" (ngSubmit)="add()" style="min-width: 400px;"> |
19 | 19 | <mat-toolbar fxLayout="row" color="primary"> |
20 | - <b><i>{{data.objectName}}</i></b> (object <<b>{{data.objectId}}</b>>) | |
20 | + <span style="font-weight: 500">{{data.objectName}}</span> #{{data.objectId}} | |
21 | 21 | <span fxFlex></span> |
22 | 22 | <button mat-button mat-icon-button |
23 | 23 | (click)="cancel()" |
... | ... | @@ -31,6 +31,7 @@ |
31 | 31 | <div mat-dialog-content> |
32 | 32 | <fieldset [disabled]="isLoading$ | async"> |
33 | 33 | <tb-profile-lwm2m-object-add-instances-list |
34 | + required | |
34 | 35 | formControlName="instancesIds"> |
35 | 36 | </tb-profile-lwm2m-object-add-instances-list> |
36 | 37 | </fieldset> | ... | ... |
... | ... | @@ -18,40 +18,32 @@ |
18 | 18 | <section [formGroup]="instancesListFormGroup" class="lwm2m-instances-list"> |
19 | 19 | <mat-form-field class="mat-block"> |
20 | 20 | <mat-label>{{ 'device-profile.lwm2m.instances-list' | translate }}</mat-label> |
21 | - <mat-chip-list> | |
21 | + <mat-chip-list #chipList formControlName="instanceList" [required]="required" (focus)="onFocus()"> | |
22 | 22 | <mat-chip |
23 | 23 | *ngFor="let instanceId of instancesId" |
24 | - [selectable]="true" | |
25 | - [removable]="true" | |
24 | + [selectable]="!disabled" | |
25 | + [removable]="!disabled" | |
26 | 26 | (removed)="remove(instanceId)"> |
27 | 27 | {{instanceId}} |
28 | - <mat-icon matChipRemove>close</mat-icon> | |
28 | + <mat-icon matChipRemove *ngIf="!disabled">close</mat-icon> | |
29 | 29 | </mat-chip> |
30 | + <input matInput type="text" | |
31 | + #instanceId | |
32 | + style="max-width: 70px;" | |
33 | + formControlName="instanceId" | |
34 | + [matChipInputFor]="chipList" | |
35 | + [matChipInputSeparatorKeyCodes]="separatorKeysCodes" | |
36 | + matChipInputAddOnBlur | |
37 | + (matChipInputTokenEnd)="add($event)"> | |
30 | 38 | </mat-chip-list> |
31 | - </mat-form-field> | |
32 | - <mat-form-field class="mat-block"> | |
33 | - <mat-label>{{ 'device-profile.lwm2m.instances-input' | translate }}</mat-label> | |
34 | - <input fxFlexFill matInput type='text' | |
35 | - placeholder="{{'device-profile.lwm2m.instances-input-holder' | translate}}" | |
36 | - formControlName="instanceIdInput"> | |
37 | - <button mat-icon-button matSuffix | |
38 | - (click)="add()" type="button"> | |
39 | - <mat-icon>add</mat-icon> | |
40 | - </button> | |
41 | - <mat-error *ngIf="instancesListFormGroup.get('instanceIdInput').hasError('min')"> | |
42 | - {{ 'device-profile.lwm2m.valid-id-instance' | translate: { | |
43 | - count: 2, instance: instanceId, min: instanceIdValueMin | |
44 | - } }} | |
39 | + <mat-error *ngIf="instancesListFormGroup.get('instanceList').hasError('required')"> | |
40 | + {{ 'device-profile.lwm2m.instances-list-required' | translate }} | |
45 | 41 | </mat-error> |
46 | - <mat-error *ngIf="instancesListFormGroup.get('instanceIdInput').hasError('max')"> | |
47 | - {{ 'device-profile.lwm2m.valid-id-instance' | translate: { | |
48 | - count: 1, instance: instanceId, max: instanceIdValueMax | |
49 | - } }} | |
42 | + <mat-error *ngIf="instancesListFormGroup.get('instanceId').hasError('pattern')"> | |
43 | + {{ 'device-profile.lwm2m.instance-id-pattern' | translate }} | |
50 | 44 | </mat-error> |
51 | - <mat-error *ngIf="instancesListFormGroup.get('instanceIdInput').hasError('pattern')"> | |
52 | - {{ 'device-profile.lwm2m.valid-id-instance' | translate: { | |
53 | - count: 0, instance: instanceId, max: instanceIdValueMax | |
54 | - } }} | |
45 | + <mat-error *ngIf="instancesListFormGroup.get('instanceId').hasError('max')"> | |
46 | + {{ 'device-profile.lwm2m.instance-id-max' | translate: {max: instanceIdValueMax} }} | |
55 | 47 | </mat-error> |
56 | 48 | </mat-form-field> |
57 | 49 | </section> | ... | ... |
... | ... | @@ -14,37 +14,76 @@ |
14 | 14 | /// limitations under the License. |
15 | 15 | /// |
16 | 16 | |
17 | -import { Component, forwardRef } from '@angular/core'; | |
18 | -import { ControlValueAccessor, FormBuilder, FormGroup, NG_VALUE_ACCESSOR, Validators } from '@angular/forms'; | |
19 | -import { INSTANCES_ID_VALUE_MAX, INSTANCES_ID_VALUE_MIN, KEY_REGEXP_NUMBER } from './lwm2m-profile-config.models'; | |
17 | +import { Component, ElementRef, forwardRef, Input, ViewChild } from '@angular/core'; | |
18 | +import { | |
19 | + ControlValueAccessor, | |
20 | + FormBuilder, | |
21 | + FormGroup, | |
22 | + NG_VALIDATORS, | |
23 | + NG_VALUE_ACCESSOR, ValidationErrors, Validator, | |
24 | + Validators | |
25 | +} from '@angular/forms'; | |
26 | +import { INSTANCES_ID_VALUE_MAX, INSTANCES_ID_VALUE_MIN } from './lwm2m-profile-config.models'; | |
27 | +import { coerceBooleanProperty } from '@angular/cdk/coercion'; | |
28 | +import { COMMA, ENTER, SEMICOLON } from '@angular/cdk/keycodes'; | |
29 | +import { MatChipInputEvent } from '@angular/material/chips'; | |
20 | 30 | |
21 | 31 | @Component({ |
22 | 32 | selector: 'tb-profile-lwm2m-object-add-instances-list', |
23 | 33 | templateUrl: './lwm2m-object-add-instances-list.component.html', |
24 | - providers: [{ | |
25 | - provide: NG_VALUE_ACCESSOR, | |
26 | - useExisting: forwardRef(() => Lwm2mObjectAddInstancesListComponent), | |
27 | - multi: true | |
28 | - }] | |
34 | + providers: [ | |
35 | + { | |
36 | + provide: NG_VALUE_ACCESSOR, | |
37 | + useExisting: forwardRef(() => Lwm2mObjectAddInstancesListComponent), | |
38 | + multi: true | |
39 | + }, | |
40 | + { | |
41 | + provide: NG_VALIDATORS, | |
42 | + useExisting: forwardRef(() => Lwm2mObjectAddInstancesListComponent), | |
43 | + multi: true | |
44 | + }] | |
29 | 45 | }) |
30 | -export class Lwm2mObjectAddInstancesListComponent implements ControlValueAccessor { | |
46 | +export class Lwm2mObjectAddInstancesListComponent implements ControlValueAccessor, Validator { | |
31 | 47 | |
32 | - private disabled = false; | |
33 | - private dirty = false; | |
48 | + private requiredValue: boolean; | |
49 | + | |
50 | + @Input() | |
51 | + disabled: boolean; | |
52 | + | |
53 | + get required(): boolean { | |
54 | + return this.requiredValue; | |
55 | + } | |
56 | + | |
57 | + @Input() | |
58 | + set required(value: boolean) { | |
59 | + this.requiredValue = coerceBooleanProperty(value); | |
60 | + this.updateValidators(); | |
61 | + } | |
62 | + | |
63 | + @ViewChild('instanceId') instanceId: ElementRef<HTMLInputElement>; | |
34 | 64 | |
35 | 65 | instancesListFormGroup: FormGroup; |
36 | 66 | instancesId = new Set<number>(); |
37 | - instanceIdValueMin = INSTANCES_ID_VALUE_MIN; | |
67 | + separatorKeysCodes = [ENTER, COMMA, SEMICOLON]; | |
38 | 68 | instanceIdValueMax = INSTANCES_ID_VALUE_MAX; |
39 | 69 | |
40 | 70 | private propagateChange = (v: any) => { }; |
41 | 71 | |
42 | 72 | constructor(private fb: FormBuilder) { |
43 | 73 | this.instancesListFormGroup = this.fb.group({ |
44 | - instanceIdInput: [null, [ | |
45 | - Validators.min(this.instanceIdValueMin), | |
46 | - Validators.max(this.instanceIdValueMax), | |
47 | - Validators.pattern(KEY_REGEXP_NUMBER)]] | |
74 | + instanceList: [null], | |
75 | + instanceId: [null, [ | |
76 | + Validators.min(INSTANCES_ID_VALUE_MIN), | |
77 | + Validators.max(INSTANCES_ID_VALUE_MAX), | |
78 | + Validators.pattern('[0-9]*')]] | |
79 | + }); | |
80 | + this.instancesListFormGroup.get('instanceId').statusChanges.subscribe((value) => { | |
81 | + if (value === 'INVALID') { | |
82 | + const errors = this.instancesListFormGroup.get('instanceId').errors; | |
83 | + this.instancesListFormGroup.get('instanceList').setErrors(errors); | |
84 | + } else { | |
85 | + this.instancesListFormGroup.get('instanceList').updateValueAndValidity({onlySelf: true}); | |
86 | + } | |
48 | 87 | }); |
49 | 88 | } |
50 | 89 | |
... | ... | @@ -67,26 +106,41 @@ export class Lwm2mObjectAddInstancesListComponent implements ControlValueAccesso |
67 | 106 | writeValue(value: Set<number>): void { |
68 | 107 | if (value && value.size) { |
69 | 108 | this.instancesId = value; |
109 | + this.instancesListFormGroup.patchValue({instanceList: Array.from(this.instancesId)}, {emitEvent: false}); | |
70 | 110 | } |
71 | - this.dirty = false; | |
72 | 111 | } |
73 | 112 | |
74 | - add = (): void => { | |
75 | - if (this.instancesListFormGroup.get('instanceIdInput').valid && Number.isFinite(Number(this.instanceId))) { | |
76 | - this.instancesId.add(Number(this.instanceId)); | |
77 | - this.instancesListFormGroup.get('instanceIdInput').setValue(null); | |
113 | + validate(): ValidationErrors | null { | |
114 | + return this.instancesListFormGroup.valid ? null : { | |
115 | + instancesListForm: false | |
116 | + }; | |
117 | + } | |
118 | + | |
119 | + add = (event: MatChipInputEvent): void => { | |
120 | + const value = event.value; | |
121 | + if (this.instancesListFormGroup.get('instanceId').valid && value !== '' && Number.isFinite(Number(value))) { | |
122 | + this.instancesId.add(Number(value)); | |
123 | + this.instancesListFormGroup.patchValue({instanceList: Array.from(this.instancesId)}, {emitEvent: false}); | |
124 | + this.instancesListFormGroup.get('instanceId').setValue(null, {emitEvent: false}); | |
78 | 125 | this.propagateChange(this.instancesId); |
79 | - this.dirty = true; | |
80 | 126 | } |
81 | 127 | } |
82 | 128 | |
83 | 129 | remove = (object: number): void => { |
84 | 130 | this.instancesId.delete(object); |
131 | + this.instancesListFormGroup.patchValue({instanceList: Array.from(this.instancesId)}, {emitEvent: false}); | |
85 | 132 | this.propagateChange(this.instancesId); |
86 | - this.dirty = true; | |
87 | 133 | } |
88 | 134 | |
89 | - get instanceId(): number { | |
90 | - return this.instancesListFormGroup.get('instanceIdInput').value; | |
135 | + onFocus() { | |
136 | + setTimeout(() => { | |
137 | + this.instanceId.nativeElement.blur(); | |
138 | + this.instanceId.nativeElement.focus(); | |
139 | + }, 0); | |
140 | + } | |
141 | + | |
142 | + private updateValidators() { | |
143 | + this.instancesListFormGroup.get('instanceList').setValidators(this.required ? [Validators.required] : []); | |
144 | + this.instancesListFormGroup.get('instanceList').updateValueAndValidity({emitEvent: false}); | |
91 | 145 | } |
92 | 146 | } | ... | ... |
... | ... | @@ -16,7 +16,8 @@ |
16 | 16 | |
17 | 17 | --> |
18 | 18 | <mat-form-field appearance="standard" [formGroup]="lwm2mListFormGroup" class="mat-block"> |
19 | - <mat-chip-list #chipList formControlName="objectsList"> | |
19 | + <mat-label translate>device-profile.lwm2m.object-list</mat-label> | |
20 | + <mat-chip-list #chipList formControlName="objectsList" [required]="required"> | |
20 | 21 | <mat-chip |
21 | 22 | *ngFor="let objectLwm2m of objectsList" |
22 | 23 | [selectable]="!disabled" |
... | ... | @@ -25,7 +26,7 @@ |
25 | 26 | {{objectLwm2m.name}} #{{objectLwm2m.keyId}} |
26 | 27 | <mat-icon matChipRemove *ngIf="!disabled">close</mat-icon> |
27 | 28 | </mat-chip> |
28 | - <input matInput type="text" placeholder="{{ !disabled ? ('device-profile.lwm2m.object-list' | translate) : '' }}" | |
29 | + <input matInput type="text" | |
29 | 30 | style="max-width: 200px;" |
30 | 31 | #objectInput |
31 | 32 | (focusin)="onFocus()" | ... | ... |
... | ... | @@ -131,7 +131,7 @@ export class Lwm2mObjectListComponent implements ControlValueAccessor, OnInit, V |
131 | 131 | if (isDisabled) { |
132 | 132 | this.lwm2mListFormGroup.disable({emitEvent: false}); |
133 | 133 | if (isDefined(this.objectInput)) { |
134 | - this.clear(); | |
134 | + this.clear('', false); | |
135 | 135 | } |
136 | 136 | } else { |
137 | 137 | this.lwm2mListFormGroup.enable({emitEvent: false}); |
... | ... | @@ -196,12 +196,14 @@ export class Lwm2mObjectListComponent implements ControlValueAccessor, OnInit, V |
196 | 196 | } |
197 | 197 | } |
198 | 198 | |
199 | - private clear(value: string = '') { | |
199 | + private clear(value = '', emitEvent = true) { | |
200 | 200 | this.objectInput.nativeElement.value = value; |
201 | - this.lwm2mListFormGroup.get('objectLwm2m').patchValue(value); | |
202 | - setTimeout(() => { | |
203 | - this.objectInput.nativeElement.blur(); | |
204 | - this.objectInput.nativeElement.focus(); | |
205 | - }, 0); | |
201 | + this.lwm2mListFormGroup.get('objectLwm2m').patchValue(value, {emitEvent}); | |
202 | + if (emitEvent) { | |
203 | + setTimeout(() => { | |
204 | + this.objectInput.nativeElement.blur(); | |
205 | + this.objectInput.nativeElement.focus(); | |
206 | + }, 0); | |
207 | + } | |
206 | 208 | } |
207 | 209 | } | ... | ... |
... | ... | @@ -28,6 +28,7 @@ import { Lwm2mObjectAddInstancesListComponent } from './lwm2m-object-add-instanc |
28 | 28 | import { CommonModule } from '@angular/common'; |
29 | 29 | import { SharedModule } from '@app/shared/shared.module'; |
30 | 30 | import { Lwm2mObserveAttrTelemetryInstancesComponent } from './lwm2m-observe-attr-telemetry-instances.component'; |
31 | +import { DeviceProfileCommonModule } from '@home/components/profile/device/common/device-profile-common.module'; | |
31 | 32 | |
32 | 33 | @NgModule({ |
33 | 34 | declarations: |
... | ... | @@ -46,7 +47,8 @@ import { Lwm2mObserveAttrTelemetryInstancesComponent } from './lwm2m-observe-att |
46 | 47 | ], |
47 | 48 | imports: [ |
48 | 49 | CommonModule, |
49 | - SharedModule | |
50 | + SharedModule, | |
51 | + DeviceProfileCommonModule | |
50 | 52 | ], |
51 | 53 | exports: [ |
52 | 54 | Lwm2mDeviceProfileTransportConfigurationComponent, | ... | ... |
... | ... | @@ -18,7 +18,6 @@ import { ValidatorFn, Validators } from '@angular/forms'; |
18 | 18 | |
19 | 19 | export const PAGE_SIZE_LIMIT = 50; |
20 | 20 | export const INSTANCES = 'instances'; |
21 | -export const INSTANCE = 'instance'; | |
22 | 21 | export const RESOURCES = 'resources'; |
23 | 22 | export const OBSERVE = 'observe'; |
24 | 23 | export const ATTRIBUTE = 'attribute'; |
... | ... | @@ -38,7 +37,6 @@ export const DEFAULT_BOOTSTRAP_SERVER_ACCOUNT_TIME_OUT = 0; |
38 | 37 | export const LEN_MAX_PUBLIC_KEY_RPK = 182; |
39 | 38 | export const LEN_MAX_PUBLIC_KEY_X509 = 3000; |
40 | 39 | export const KEY_REGEXP_HEX_DEC = /^[-+]?[0-9A-Fa-f]+\.?[0-9A-Fa-f]*?$/; |
41 | -export const KEY_REGEXP_NUMBER = /^(-?|\+?)\d*$/; | |
42 | 40 | export const INSTANCES_ID_VALUE_MIN = 0; |
43 | 41 | export const INSTANCES_ID_VALUE_MAX = 65535; |
44 | 42 | export const DEFAULT_OTA_UPDATE_PROTOCOL = 'coap://'; |
... | ... | @@ -170,6 +168,8 @@ export interface ClientLwM2mSettings { |
170 | 168 | swUpdateResource: string; |
171 | 169 | powerMode: PowerMode; |
172 | 170 | edrxCycle?: number; |
171 | + pagingTransmissionWindow?: number; | |
172 | + psmActivityTimer?: number; | |
173 | 173 | compositeOperationsSupport: boolean; |
174 | 174 | } |
175 | 175 | ... | ... |
... | ... | @@ -16,24 +16,6 @@ |
16 | 16 | |
17 | 17 | --> |
18 | 18 | <form [formGroup]="lwm2mDeviceTransportConfigurationFormGroup" style="padding-bottom: 16px;"> |
19 | - <mat-form-field class="mat-block" fxFlex> | |
20 | - <mat-label translate>device-profile.power-saving-mode</mat-label> | |
21 | - <mat-select formControlName="powerMode"> | |
22 | - <mat-option [value]="null">{{ "device-profile.power-saving-mode-type.default" | translate }}</mat-option> | |
23 | - <mat-option *ngFor="let powerMod of powerMods" [value]="powerMod"> | |
24 | - {{ powerModeTranslationMap.get(powerMod) | translate }} | |
25 | - </mat-option> | |
26 | - </mat-select> | |
27 | - </mat-form-field> | |
28 | - <mat-form-field class="mat-block" fxFlex *ngIf="lwm2mDeviceTransportConfigurationFormGroup.get('powerMode').value === 'E_DRX'"> | |
29 | - <mat-label>{{ 'device-profile.edrx-cycle' | translate }}</mat-label> | |
30 | - <input matInput type="number" min="0" formControlName="edrxCycle" required> | |
31 | - <mat-error *ngIf="lwm2mDeviceTransportConfigurationFormGroup.get('edrxCycle').hasError('required')"> | |
32 | - {{ 'device-profile.edrx-cycle-required' | translate }} | |
33 | - </mat-error> | |
34 | - <mat-error *ngIf="lwm2mDeviceTransportConfigurationFormGroup.get('edrxCycle').hasError('pattern') || | |
35 | - lwm2mDeviceTransportConfigurationFormGroup.get('edrxCycle').hasError('min')"> | |
36 | - {{ 'device-profile.edrx-cycle-pattern' | translate }} | |
37 | - </mat-error> | |
38 | - </mat-form-field> | |
19 | + <tb-power-mode-settings [parentForm]="lwm2mDeviceTransportConfigurationFormGroup" [isDeviceSetting]="true"> | |
20 | + </tb-power-mode-settings> | |
39 | 21 | </form> | ... | ... |
... | ... | @@ -19,8 +19,11 @@ import { ControlValueAccessor, FormBuilder, FormGroup, NG_VALUE_ACCESSOR, Valida |
19 | 19 | import { Store } from '@ngrx/store'; |
20 | 20 | import { AppState } from '@app/core/core.state'; |
21 | 21 | import { coerceBooleanProperty } from '@angular/cdk/coercion'; |
22 | -import { DeviceTransportConfiguration, Lwm2mDeviceTransportConfiguration } from '@shared/models/device.models'; | |
23 | -import { PowerMode, PowerModeTranslationMap } from '@home/components/profile/device/lwm2m/lwm2m-profile-config.models'; | |
22 | +import { | |
23 | + DeviceTransportConfiguration, | |
24 | + DeviceTransportType, | |
25 | + Lwm2mDeviceTransportConfiguration | |
26 | +} from '@shared/models/device.models'; | |
24 | 27 | import { takeUntil } from 'rxjs/operators'; |
25 | 28 | import { Subject } from 'rxjs'; |
26 | 29 | import { isDefinedAndNotNull } from '@core/utils'; |
... | ... | @@ -38,8 +41,6 @@ import { isDefinedAndNotNull } from '@core/utils'; |
38 | 41 | export class Lwm2mDeviceTransportConfigurationComponent implements ControlValueAccessor, OnInit, OnDestroy { |
39 | 42 | |
40 | 43 | lwm2mDeviceTransportConfigurationFormGroup: FormGroup; |
41 | - powerMods = Object.values(PowerMode); | |
42 | - powerModeTranslationMap = PowerModeTranslationMap; | |
43 | 44 | |
44 | 45 | private requiredValue: boolean; |
45 | 46 | get required(): boolean { |
... | ... | @@ -70,21 +71,9 @@ export class Lwm2mDeviceTransportConfigurationComponent implements ControlValueA |
70 | 71 | ngOnInit() { |
71 | 72 | this.lwm2mDeviceTransportConfigurationFormGroup = this.fb.group({ |
72 | 73 | powerMode: [null], |
73 | - edrxCycle: [0] | |
74 | - }); | |
75 | - this.lwm2mDeviceTransportConfigurationFormGroup.get('powerMode').valueChanges.pipe( | |
76 | - takeUntil(this.destroy$) | |
77 | - ).subscribe((powerMode: PowerMode) => { | |
78 | - if (powerMode === PowerMode.E_DRX) { | |
79 | - this.lwm2mDeviceTransportConfigurationFormGroup.get('edrxCycle').enable({emitEvent: false}); | |
80 | - this.lwm2mDeviceTransportConfigurationFormGroup.get('edrxCycle').patchValue(0, {emitEvent: false}); | |
81 | - this.lwm2mDeviceTransportConfigurationFormGroup.get('edrxCycle') | |
82 | - .setValidators([Validators.required, Validators.min(0), Validators.pattern('[0-9]*')]); | |
83 | - } else { | |
84 | - this.lwm2mDeviceTransportConfigurationFormGroup.get('edrxCycle').disable({emitEvent: false}); | |
85 | - this.lwm2mDeviceTransportConfigurationFormGroup.get('edrxCycle').clearValidators(); | |
86 | - } | |
87 | - this.lwm2mDeviceTransportConfigurationFormGroup.get('edrxCycle').updateValueAndValidity({emitEvent: false}); | |
74 | + edrxCycle: [{disabled: true, value: 0}, [Validators.required, Validators.min(0), Validators.pattern('[0-9]*')]], | |
75 | + psmActivityTimer: [{disabled: true, value: 0}, [Validators.required, Validators.min(0), Validators.pattern('[0-9]*')]], | |
76 | + pagingTransmissionWindow: [{disabled: true, value: 0}, [Validators.required, Validators.min(0), Validators.pattern('[0-9]*')]] | |
88 | 77 | }); |
89 | 78 | this.lwm2mDeviceTransportConfigurationFormGroup.valueChanges.pipe( |
90 | 79 | takeUntil(this.destroy$) |
... | ... | @@ -104,15 +93,18 @@ export class Lwm2mDeviceTransportConfigurationComponent implements ControlValueA |
104 | 93 | this.lwm2mDeviceTransportConfigurationFormGroup.disable({emitEvent: false}); |
105 | 94 | } else { |
106 | 95 | this.lwm2mDeviceTransportConfigurationFormGroup.enable({emitEvent: false}); |
96 | + this.lwm2mDeviceTransportConfigurationFormGroup.get('powerMode').updateValueAndValidity({onlySelf: true}); | |
107 | 97 | } |
108 | 98 | } |
109 | 99 | |
110 | 100 | writeValue(value: Lwm2mDeviceTransportConfiguration | null): void { |
111 | 101 | if (isDefinedAndNotNull(value)) { |
112 | - this.lwm2mDeviceTransportConfigurationFormGroup.get('powerMode').patchValue(value.powerMode, {emitEvent: false, onlySelf: true}); | |
113 | - this.lwm2mDeviceTransportConfigurationFormGroup.get('edrxCycle').patchValue(value.edrxCycle || 0, {emitEvent: false}); | |
102 | + this.lwm2mDeviceTransportConfigurationFormGroup.patchValue(value, {emitEvent: false}); | |
114 | 103 | } else { |
115 | - this.lwm2mDeviceTransportConfigurationFormGroup.patchValue({powerMode: null, edrxCycle: 0}, {emitEvent: false}); | |
104 | + this.lwm2mDeviceTransportConfigurationFormGroup.get('powerMode').patchValue(null, {emitEvent: false}); | |
105 | + } | |
106 | + if (!this.disabled) { | |
107 | + this.lwm2mDeviceTransportConfigurationFormGroup.get('powerMode').updateValueAndValidity({onlySelf: true}); | |
116 | 108 | } |
117 | 109 | } |
118 | 110 | |
... | ... | @@ -120,7 +112,7 @@ export class Lwm2mDeviceTransportConfigurationComponent implements ControlValueA |
120 | 112 | let configuration: DeviceTransportConfiguration = null; |
121 | 113 | if (this.lwm2mDeviceTransportConfigurationFormGroup.valid) { |
122 | 114 | configuration = this.lwm2mDeviceTransportConfigurationFormGroup.value; |
123 | - // configuration.type = DeviceTransportType.LWM2M; | |
115 | + configuration.type = DeviceTransportType.LWM2M; | |
124 | 116 | } |
125 | 117 | this.propagateChange(configuration); |
126 | 118 | } | ... | ... |
... | ... | @@ -34,6 +34,7 @@ import { CoapDeviceTransportConfigurationComponent } from './data/coap-device-tr |
34 | 34 | import { Lwm2mDeviceTransportConfigurationComponent } from './data/lwm2m-device-transport-configuration.component'; |
35 | 35 | import { SnmpDeviceTransportConfigurationComponent } from './data/snmp-device-transport-configuration.component'; |
36 | 36 | import { DeviceCredentialsModule } from '@home/components/device/device-credentials.module'; |
37 | +import { DeviceProfileCommonModule } from '@home/components/profile/device/common/device-profile-common.module'; | |
37 | 38 | |
38 | 39 | @NgModule({ |
39 | 40 | declarations: [ |
... | ... | @@ -57,6 +58,7 @@ import { DeviceCredentialsModule } from '@home/components/device/device-credenti |
57 | 58 | HomeComponentsModule, |
58 | 59 | HomeDialogsModule, |
59 | 60 | DeviceCredentialsModule, |
61 | + DeviceProfileCommonModule, | |
60 | 62 | DeviceRoutingModule |
61 | 63 | ] |
62 | 64 | }) | ... | ... |
... | ... | @@ -30,7 +30,14 @@ import { AbstractControl, ValidationErrors } from '@angular/forms'; |
30 | 30 | import { OtaPackageId } from '@shared/models/id/ota-package-id'; |
31 | 31 | import { DashboardId } from '@shared/models/id/dashboard-id'; |
32 | 32 | import { DataType } from '@shared/models/constants'; |
33 | -import { PowerMode } from '@home/components/profile/device/lwm2m/lwm2m-profile-config.models'; | |
33 | +import { | |
34 | + getDefaultBootstrapServerSecurityConfig, | |
35 | + getDefaultBootstrapServersSecurityConfig, | |
36 | + getDefaultLwM2MServerSecurityConfig, | |
37 | + getDefaultProfileClientLwM2mSettingsConfig, | |
38 | + getDefaultProfileObserveAttrConfig, | |
39 | + PowerMode | |
40 | +} from '@home/components/profile/device/lwm2m/lwm2m-profile-config.models'; | |
34 | 41 | |
35 | 42 | export enum DeviceProfileType { |
36 | 43 | DEFAULT = 'DEFAULT', |
... | ... | @@ -369,7 +376,15 @@ export function createDeviceProfileTransportConfiguration(type: DeviceTransportT |
369 | 376 | transportConfiguration = {...coapTransportConfiguration, type: DeviceTransportType.COAP}; |
370 | 377 | break; |
371 | 378 | case DeviceTransportType.LWM2M: |
372 | - const lwm2mTransportConfiguration: Lwm2mDeviceProfileTransportConfiguration = {}; | |
379 | + const lwm2mTransportConfiguration: Lwm2mDeviceProfileTransportConfiguration = { | |
380 | + observeAttr: getDefaultProfileObserveAttrConfig(), | |
381 | + bootstrap: { | |
382 | + servers: getDefaultBootstrapServersSecurityConfig(), | |
383 | + bootstrapServer: getDefaultBootstrapServerSecurityConfig(), | |
384 | + lwm2mServer: getDefaultLwM2MServerSecurityConfig() | |
385 | + }, | |
386 | + clientLwM2mSettings: getDefaultProfileClientLwM2mSettingsConfig() | |
387 | + }; | |
373 | 388 | transportConfiguration = {...lwm2mTransportConfiguration, type: DeviceTransportType.LWM2M}; |
374 | 389 | break; |
375 | 390 | case DeviceTransportType.SNMP: |
... | ... | @@ -404,7 +419,9 @@ export function createDeviceTransportConfiguration(type: DeviceTransportType): D |
404 | 419 | transportConfiguration = {...coapTransportConfiguration, type: DeviceTransportType.COAP}; |
405 | 420 | break; |
406 | 421 | case DeviceTransportType.LWM2M: |
407 | - const lwm2mTransportConfiguration: Lwm2mDeviceTransportConfiguration = {}; | |
422 | + const lwm2mTransportConfiguration: Lwm2mDeviceTransportConfiguration = { | |
423 | + powerMode: null | |
424 | + }; | |
408 | 425 | transportConfiguration = {...lwm2mTransportConfiguration, type: DeviceTransportType.LWM2M}; |
409 | 426 | break; |
410 | 427 | case DeviceTransportType.SNMP: |
... | ... | @@ -592,7 +609,8 @@ export interface CoapDeviceTransportConfiguration { |
592 | 609 | export interface Lwm2mDeviceTransportConfiguration { |
593 | 610 | powerMode?: PowerMode | null; |
594 | 611 | edrxCycle?: number; |
595 | - [key: string]: any; | |
612 | + pagingTransmissionWindow?: number; | |
613 | + psmActivityTimer?: number; | |
596 | 614 | } |
597 | 615 | |
598 | 616 | export enum SnmpDeviceProtocolVersion { | ... | ... |
... | ... | @@ -1242,14 +1242,12 @@ |
1242 | 1242 | "object-list": "Object list", |
1243 | 1243 | "object-list-empty": "No objects selected.", |
1244 | 1244 | "no-objects-matching": "No objects matching '{{object}}' were found.", |
1245 | - "valid-id-instance-no-min": "Instance number '{{instance}}' no validated. Min value='{{min}}'", | |
1246 | - "valid-id-instance-no-max": "Instance number '{{instance}}' no validated. Max value='{{max}}'", | |
1247 | - "valid-id-instance": "Instance number '{{instance}}' no validated. { count, plural, 1 {Max value='{{max}}'} 2 {Min value='{{min}}'} other {Must be only number} }", | |
1248 | 1245 | "model-tab": "LWM2M Model", |
1249 | 1246 | "add-new-instances": "Add new instances", |
1250 | 1247 | "instances-list": "Instances list", |
1251 | - "instances-input": "Input Instance Id value", | |
1252 | - "instances-input-holder": "Input Instance number...", | |
1248 | + "instances-list-required": "Instances list is required.", | |
1249 | + "instance-id-pattern": "Instance id must be a positive integer.", | |
1250 | + "instance-id-max": "Maximum instance id value {{max}}.", | |
1253 | 1251 | "instance": "Instance", |
1254 | 1252 | "resource-label": "#ID Resource name", |
1255 | 1253 | "observe-label": "Observe", | ... | ... |