Commit e8d8382c74c7d76f7050618eae1f36cbff329bc6

Authored by Vladyslav Prykhodko
1 parent 2b1317b1

UI: Added device provision to device profile

@@ -107,6 +107,7 @@ import { AlarmRuleKeyFiltersDialogComponent } from './profile/alarm/alarm-rule-k @@ -107,6 +107,7 @@ import { AlarmRuleKeyFiltersDialogComponent } from './profile/alarm/alarm-rule-k
107 import { FilterTextComponent } from './filter/filter-text.component'; 107 import { FilterTextComponent } from './filter/filter-text.component';
108 import { AddDeviceProfileDialogComponent } from './profile/add-device-profile-dialog.component'; 108 import { AddDeviceProfileDialogComponent } from './profile/add-device-profile-dialog.component';
109 import { RuleChainAutocompleteComponent } from './rule-chain/rule-chain-autocomplete.component'; 109 import { RuleChainAutocompleteComponent } from './rule-chain/rule-chain-autocomplete.component';
  110 +import { DeviceProfileProvisionConfigurationComponent } from "./profile/device-profile-provision-configuration.component";
110 111
111 @NgModule({ 112 @NgModule({
112 declarations: 113 declarations:
@@ -196,7 +197,8 @@ import { RuleChainAutocompleteComponent } from './rule-chain/rule-chain-autocomp @@ -196,7 +197,8 @@ import { RuleChainAutocompleteComponent } from './rule-chain/rule-chain-autocomp
196 DeviceProfileComponent, 197 DeviceProfileComponent,
197 DeviceProfileDialogComponent, 198 DeviceProfileDialogComponent,
198 AddDeviceProfileDialogComponent, 199 AddDeviceProfileDialogComponent,
199 - RuleChainAutocompleteComponent 200 + RuleChainAutocompleteComponent,
  201 + DeviceProfileProvisionConfigurationComponent
200 ], 202 ],
201 imports: [ 203 imports: [
202 CommonModule, 204 CommonModule,
@@ -275,7 +277,8 @@ import { RuleChainAutocompleteComponent } from './rule-chain/rule-chain-autocomp @@ -275,7 +277,8 @@ import { RuleChainAutocompleteComponent } from './rule-chain/rule-chain-autocomp
275 DeviceProfileComponent, 277 DeviceProfileComponent,
276 DeviceProfileDialogComponent, 278 DeviceProfileDialogComponent,
277 AddDeviceProfileDialogComponent, 279 AddDeviceProfileDialogComponent,
278 - RuleChainAutocompleteComponent 280 + RuleChainAutocompleteComponent,
  281 + DeviceProfileProvisionConfigurationComponent
279 ], 282 ],
280 providers: [ 283 providers: [
281 WidgetComponentService, 284 WidgetComponentService,
@@ -93,6 +93,14 @@ @@ -93,6 +93,14 @@
93 </tb-device-profile-alarms> 93 </tb-device-profile-alarms>
94 </form> 94 </form>
95 </mat-step> 95 </mat-step>
  96 + <mat-step [stepControl]="provisionConfigurationFormGroup">
  97 + <form [formGroup]="provisionConfigurationFormGroup" style="padding-bottom: 16px;">
  98 + <ng-template matStepLabel>{{'device-profile.device-provisioning' | translate }}</ng-template>
  99 + <tb-device-profile-provision-configuration
  100 + formControlName="provisionConfiguration">
  101 + </tb-device-profile-provision-configuration>
  102 + </form>
  103 + </mat-step>
96 </mat-horizontal-stepper> 104 </mat-horizontal-stepper>
97 </div> 105 </div>
98 <div mat-dialog-actions fxLayout="row wrap" fxLayoutAlign="space-between center"> 106 <div mat-dialog-actions fxLayout="row wrap" fxLayoutAlign="space-between center">
@@ -107,7 +115,7 @@ @@ -107,7 +115,7 @@
107 <button mat-raised-button 115 <button mat-raised-button
108 [disabled]="(isLoading$ | async) || selectedForm().invalid" 116 [disabled]="(isLoading$ | async) || selectedForm().invalid"
109 color="primary" 117 color="primary"
110 - (click)="nextStep()">{{ (selectedIndex === 2 ? 'action.add' : 'action.continue') | translate }}</button> 118 + (click)="nextStep()">{{ (selectedIndex === 3 ? 'action.add' : 'action.continue') | translate }}</button>
111 </div> 119 </div>
112 </div> 120 </div>
113 </div> 121 </div>
@@ -77,6 +77,8 @@ export class AddDeviceProfileDialogComponent extends @@ -77,6 +77,8 @@ export class AddDeviceProfileDialogComponent extends
77 77
78 alarmRulesFormGroup: FormGroup; 78 alarmRulesFormGroup: FormGroup;
79 79
  80 + provisionConfigurationFormGroup: FormGroup;
  81 +
80 constructor(protected store: Store<AppState>, 82 constructor(protected store: Store<AppState>,
81 protected router: Router, 83 protected router: Router,
82 @Inject(MAT_DIALOG_DATA) public data: AddDeviceProfileDialogData, 84 @Inject(MAT_DIALOG_DATA) public data: AddDeviceProfileDialogData,
@@ -111,6 +113,12 @@ export class AddDeviceProfileDialogComponent extends @@ -111,6 +113,12 @@ export class AddDeviceProfileDialogComponent extends
111 alarms: [null] 113 alarms: [null]
112 } 114 }
113 ); 115 );
  116 +
  117 + this.provisionConfigurationFormGroup = this.fb.group(
  118 + {
  119 + provisionConfiguration: [null]
  120 + }
  121 + )
114 } 122 }
115 123
116 private deviceProfileTransportTypeChanged() { 124 private deviceProfileTransportTypeChanged() {
@@ -131,7 +139,7 @@ export class AddDeviceProfileDialogComponent extends @@ -131,7 +139,7 @@ export class AddDeviceProfileDialogComponent extends
131 } 139 }
132 140
133 nextStep() { 141 nextStep() {
134 - if (this.selectedIndex < 2) { 142 + if (this.selectedIndex < 3) {
135 this.addDeviceProfileStepper.next(); 143 this.addDeviceProfileStepper.next();
136 } else { 144 } else {
137 this.add(); 145 this.add();
@@ -146,6 +154,8 @@ export class AddDeviceProfileDialogComponent extends @@ -146,6 +154,8 @@ export class AddDeviceProfileDialogComponent extends
146 return this.transportConfigFormGroup; 154 return this.transportConfigFormGroup;
147 case 2: 155 case 2:
148 return this.alarmRulesFormGroup; 156 return this.alarmRulesFormGroup;
  157 + case 3:
  158 + return this.provisionConfigurationFormGroup;
149 } 159 }
150 } 160 }
151 161
@@ -154,11 +164,17 @@ export class AddDeviceProfileDialogComponent extends @@ -154,11 +164,17 @@ export class AddDeviceProfileDialogComponent extends
154 name: this.deviceProfileDetailsFormGroup.get('name').value, 164 name: this.deviceProfileDetailsFormGroup.get('name').value,
155 type: this.deviceProfileDetailsFormGroup.get('type').value, 165 type: this.deviceProfileDetailsFormGroup.get('type').value,
156 transportType: this.transportConfigFormGroup.get('transportType').value, 166 transportType: this.transportConfigFormGroup.get('transportType').value,
  167 + provisionType: this.provisionConfigurationFormGroup.get('provisionConfiguration').value.type,
  168 + provisionDeviceKey: this.provisionConfigurationFormGroup.get('provisionConfiguration').value.provisionDeviceKey,
157 description: this.deviceProfileDetailsFormGroup.get('description').value, 169 description: this.deviceProfileDetailsFormGroup.get('description').value,
158 profileData: { 170 profileData: {
159 configuration: createDeviceProfileConfiguration(DeviceProfileType.DEFAULT), 171 configuration: createDeviceProfileConfiguration(DeviceProfileType.DEFAULT),
160 transportConfiguration: this.transportConfigFormGroup.get('transportConfiguration').value, 172 transportConfiguration: this.transportConfigFormGroup.get('transportConfiguration').value,
161 - alarms: this.alarmRulesFormGroup.get('alarms').value 173 + alarms: this.alarmRulesFormGroup.get('alarms').value,
  174 + provisionConfiguration: {
  175 + type: this.provisionConfigurationFormGroup.get('provisionConfiguration').value.type,
  176 + provisionDeviceSecret: this.provisionConfigurationFormGroup.get('provisionConfiguration').value.provisionDeviceSecret
  177 + }
162 } 178 }
163 }; 179 };
164 if (this.deviceProfileDetailsFormGroup.get('defaultRuleChainId').value) { 180 if (this.deviceProfileDetailsFormGroup.get('defaultRuleChainId').value) {
@@ -51,5 +51,15 @@ @@ -51,5 +51,15 @@
51 formControlName="alarms"> 51 formControlName="alarms">
52 </tb-device-profile-alarms> 52 </tb-device-profile-alarms>
53 </mat-expansion-panel> 53 </mat-expansion-panel>
  54 + <mat-expansion-panel [expanded]="true">
  55 + <mat-expansion-panel-header>
  56 + <mat-panel-title>
  57 + <div translate>device-profile.device-provisioning</div>
  58 + </mat-panel-title>
  59 + </mat-expansion-panel-header>
  60 + <tb-device-profile-provision-configuration
  61 + formControlName="provisionConfiguration">
  62 + </tb-device-profile-provision-configuration>
  63 + </mat-expansion-panel>
54 </mat-accordion> 64 </mat-accordion>
55 </div> 65 </div>
@@ -72,7 +72,8 @@ export class DeviceProfileDataComponent implements ControlValueAccessor, OnInit @@ -72,7 +72,8 @@ export class DeviceProfileDataComponent implements ControlValueAccessor, OnInit
72 this.deviceProfileDataFormGroup = this.fb.group({ 72 this.deviceProfileDataFormGroup = this.fb.group({
73 configuration: [null, Validators.required], 73 configuration: [null, Validators.required],
74 transportConfiguration: [null, Validators.required], 74 transportConfiguration: [null, Validators.required],
75 - alarms: [null] 75 + alarms: [null],
  76 + provisionConfiguration: [null]
76 }); 77 });
77 this.deviceProfileDataFormGroup.valueChanges.subscribe(() => { 78 this.deviceProfileDataFormGroup.valueChanges.subscribe(() => {
78 this.updateModel(); 79 this.updateModel();
@@ -98,6 +99,7 @@ export class DeviceProfileDataComponent implements ControlValueAccessor, OnInit @@ -98,6 +99,7 @@ export class DeviceProfileDataComponent implements ControlValueAccessor, OnInit
98 this.deviceProfileDataFormGroup.patchValue({configuration: value?.configuration}, {emitEvent: false}); 99 this.deviceProfileDataFormGroup.patchValue({configuration: value?.configuration}, {emitEvent: false});
99 this.deviceProfileDataFormGroup.patchValue({transportConfiguration: value?.transportConfiguration}, {emitEvent: false}); 100 this.deviceProfileDataFormGroup.patchValue({transportConfiguration: value?.transportConfiguration}, {emitEvent: false});
100 this.deviceProfileDataFormGroup.patchValue({alarms: value?.alarms}, {emitEvent: false}); 101 this.deviceProfileDataFormGroup.patchValue({alarms: value?.alarms}, {emitEvent: false});
  102 + this.deviceProfileDataFormGroup.patchValue({provisionConfiguration: value?.provisionConfiguration}, {emitEvent: false});
101 } 103 }
102 104
103 private updateModel() { 105 private updateModel() {
  1 +<!--
  2 +
  3 + Copyright © 2016-2020 The Thingsboard Authors
  4 +
  5 + Licensed under the Apache License, Version 2.0 (the "License");
  6 + you may not use this file except in compliance with the License.
  7 + You may obtain a copy of the License at
  8 +
  9 + http://www.apache.org/licenses/LICENSE-2.0
  10 +
  11 + Unless required by applicable law or agreed to in writing, software
  12 + distributed under the License is distributed on an "AS IS" BASIS,
  13 + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14 + See the License for the specific language governing permissions and
  15 + limitations under the License.
  16 +
  17 +-->
  18 +<div [formGroup]="provisionConfigurationFormGroup">
  19 + <mat-form-field class="mat-block">
  20 + <mat-label translate>device-profile.provision-strategy</mat-label>
  21 + <mat-select formControlName="type" required>
  22 + <mat-option *ngFor="let type of deviceProvisionTypes" [value]="type">
  23 + {{deviceProvisionTypeTranslateMap.get(type) | translate}}
  24 + </mat-option>
  25 + </mat-select>
  26 + <mat-error *ngIf="provisionConfigurationFormGroup.get('type').hasError('required')">
  27 + {{ 'device-profile.provision-strategy-required' | translate }}
  28 + </mat-error>
  29 + </mat-form-field>
  30 + <section *ngIf="provisionConfigurationFormGroup.get('type').value !== deviceProvisionType.DISABLED" fxLayoutGap.gt-xs="8px" fxLayout="row" fxLayout.xs="column">
  31 + <mat-form-field fxFlex class="mat-block">
  32 + <mat-label translate>device-profile.provision-device-secret</mat-label>
  33 + <input matInput formControlName="provisionDeviceSecret" required/>
  34 + <mat-error *ngIf="provisionConfigurationFormGroup.get('provisionDeviceSecret').hasError('required')">
  35 + {{ 'device-profile.provision-device-secret-required' | translate }}
  36 + </mat-error>
  37 + </mat-form-field>
  38 + <mat-form-field fxFlex class="mat-block">
  39 + <mat-label translate>device-profile.provision-device-key</mat-label>
  40 + <input matInput formControlName="provisionDeviceKey" required/>
  41 + <mat-error *ngIf="provisionConfigurationFormGroup.get('provisionDeviceKey').hasError('required')">
  42 + {{ 'device-profile.provision-device-key-required' | translate }}
  43 + </mat-error>
  44 + </mat-form-field>
  45 + </section>
  46 +</div>
  1 +///
  2 +/// Copyright © 2016-2020 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 { Component, forwardRef, Input, OnInit } from "@angular/core";
  18 +import {
  19 + ControlValueAccessor,
  20 + FormBuilder,
  21 + FormControl,
  22 + FormGroup,
  23 + NG_VALIDATORS,
  24 + NG_VALUE_ACCESSOR,
  25 + ValidationErrors,
  26 + Validator,
  27 + Validators
  28 +} from "@angular/forms";
  29 +import { coerceBooleanProperty } from "@angular/cdk/coercion";
  30 +import {
  31 + DeviceProvisionConfiguration,
  32 + DeviceProvisionType,
  33 + deviceProvisionTypeTranslationMap
  34 +} from "@shared/models/device.models";
  35 +import { isDefinedAndNotNull } from "@core/utils";
  36 +
  37 +@Component({
  38 + selector: 'tb-device-profile-provision-configuration',
  39 + templateUrl: './device-profile-provision-configuration.component.html',
  40 + styleUrls: [],
  41 + providers: [
  42 + {
  43 + provide: NG_VALUE_ACCESSOR,
  44 + useExisting: forwardRef(() => DeviceProfileProvisionConfigurationComponent),
  45 + multi: true
  46 + },
  47 + {
  48 + provide: NG_VALIDATORS,
  49 + useExisting: forwardRef(() => DeviceProfileProvisionConfigurationComponent),
  50 + multi: true,
  51 + }
  52 + ]
  53 +})
  54 +export class DeviceProfileProvisionConfigurationComponent implements ControlValueAccessor, OnInit, Validator {
  55 +
  56 + provisionConfigurationFormGroup: FormGroup;
  57 +
  58 + deviceProvisionType = DeviceProvisionType;
  59 + deviceProvisionTypes = Object.keys(DeviceProvisionType);
  60 + deviceProvisionTypeTranslateMap = deviceProvisionTypeTranslationMap;
  61 +
  62 + private requiredValue: boolean;
  63 + get required(): boolean {
  64 + return this.requiredValue;
  65 + }
  66 + @Input()
  67 + set required(value: boolean) {
  68 + this.requiredValue = coerceBooleanProperty(value);
  69 + }
  70 +
  71 + @Input()
  72 + disabled: boolean;
  73 +
  74 + private propagateChange = (v: any) => { };
  75 +
  76 + constructor(private fb: FormBuilder) {
  77 + }
  78 +
  79 + ngOnInit(): void {
  80 + this.provisionConfigurationFormGroup = this.fb.group({
  81 + type: [DeviceProvisionType.DISABLED, Validators.required],
  82 + provisionDeviceSecret: [{value: null, disabled: true}, Validators.required],
  83 + provisionDeviceKey: [{value: null, disabled: true}, Validators.required]
  84 + });
  85 + this.provisionConfigurationFormGroup.get('type').valueChanges.subscribe((type) => {
  86 + if(type === DeviceProvisionType.DISABLED) {
  87 + this.provisionConfigurationFormGroup.get('provisionDeviceSecret').disable({emitEvent: false});
  88 + this.provisionConfigurationFormGroup.get('provisionDeviceSecret').patchValue(null,{emitEvent: false});
  89 + this.provisionConfigurationFormGroup.get('provisionDeviceKey').disable({emitEvent: false});
  90 + this.provisionConfigurationFormGroup.get('provisionDeviceKey').patchValue(null);
  91 + } else {
  92 + this.provisionConfigurationFormGroup.get('provisionDeviceSecret').enable({emitEvent: false});
  93 + this.provisionConfigurationFormGroup.get('provisionDeviceKey').enable({emitEvent: false});
  94 + }
  95 + });
  96 + this.provisionConfigurationFormGroup.valueChanges.subscribe(() => {
  97 + this.updateModel();
  98 + });
  99 + }
  100 +
  101 + registerOnChange(fn: any): void {
  102 + this.propagateChange = fn;
  103 + }
  104 +
  105 + registerOnTouched(fn: any): void {
  106 + }
  107 +
  108 + writeValue(value: DeviceProvisionConfiguration | null): void {
  109 + if(isDefinedAndNotNull(value)){
  110 + this.provisionConfigurationFormGroup.patchValue(value, {emitEvent: false});
  111 + } else {
  112 + this.provisionConfigurationFormGroup.patchValue({type: DeviceProvisionType.DISABLED});
  113 + }
  114 + }
  115 +
  116 + setDisabledState(isDisabled: boolean){
  117 + this.disabled = isDisabled;
  118 + if(this.disabled){
  119 + this.provisionConfigurationFormGroup.disable();
  120 + } else {
  121 + this.provisionConfigurationFormGroup.enable({emitEvent: false});
  122 + }
  123 + }
  124 +
  125 + validate(c: FormControl): ValidationErrors | null {
  126 + return (this.provisionConfigurationFormGroup.valid) ? null : {
  127 + provisionConfiguration: {
  128 + valid: false,
  129 + },
  130 + };
  131 + }
  132 +
  133 + private updateModel(): void {
  134 + let deviceProvisionConfiguration: DeviceProvisionConfiguration = null;
  135 + if (this.provisionConfigurationFormGroup.valid) {
  136 + deviceProvisionConfiguration = this.provisionConfigurationFormGroup.getRawValue();
  137 + }
  138 + this.propagateChange(deviceProvisionConfiguration);
  139 + }
  140 +}
@@ -126,6 +126,10 @@ export class DeviceProfileComponent extends EntityComponent<DeviceProfile> { @@ -126,6 +126,10 @@ export class DeviceProfileComponent extends EntityComponent<DeviceProfile> {
126 } 126 }
127 127
128 updateForm(entity: DeviceProfile) { 128 updateForm(entity: DeviceProfile) {
  129 + if(entity?.profileData?.provisionConfiguration) {
  130 + entity.profileData.provisionConfiguration.provisionDeviceKey = entity?.provisionDeviceKey;
  131 + }
  132 +
129 this.entityForm.patchValue({name: entity.name}); 133 this.entityForm.patchValue({name: entity.name});
130 this.entityForm.patchValue({type: entity.type}, {emitEvent: false}); 134 this.entityForm.patchValue({type: entity.type}, {emitEvent: false});
131 this.entityForm.patchValue({transportType: entity.transportType}, {emitEvent: false}); 135 this.entityForm.patchValue({transportType: entity.transportType}, {emitEvent: false});
@@ -138,7 +142,11 @@ export class DeviceProfileComponent extends EntityComponent<DeviceProfile> { @@ -138,7 +142,11 @@ export class DeviceProfileComponent extends EntityComponent<DeviceProfile> {
138 if (formValue.defaultRuleChainId) { 142 if (formValue.defaultRuleChainId) {
139 formValue.defaultRuleChainId = new RuleChainId(formValue.defaultRuleChainId); 143 formValue.defaultRuleChainId = new RuleChainId(formValue.defaultRuleChainId);
140 } 144 }
141 - return formValue; 145 + formValue.provisionType = formValue.profileData.provisionConfiguration.type;
  146 + formValue.provisionDeviceKey = formValue.profileData.provisionConfiguration.provisionDeviceKey;
  147 + delete formValue.profileData.provisionConfiguration.provisionDeviceKey;
  148 +
  149 + return super.prepareFormValue(formValue);
142 } 150 }
143 151
144 onDeviceProfileIdCopied(event) { 152 onDeviceProfileIdCopied(event) {
@@ -36,6 +36,12 @@ export enum DeviceTransportType { @@ -36,6 +36,12 @@ export enum DeviceTransportType {
36 LWM2M = 'LWM2M' 36 LWM2M = 'LWM2M'
37 } 37 }
38 38
  39 +export enum DeviceProvisionType {
  40 + DISABLED = 'DISABLED',
  41 + ALLOW_CREATE_NEW_DEVICES = 'ALLOW_CREATE_NEW_DEVICES',
  42 + CHECK_PRE_PROVISIONED_DEVICES = 'CHECK_PRE_PROVISIONED_DEVICES'
  43 +}
  44 +
39 export interface DeviceConfigurationFormInfo { 45 export interface DeviceConfigurationFormInfo {
40 hasProfileConfiguration: boolean; 46 hasProfileConfiguration: boolean;
41 hasDeviceConfiguration: boolean; 47 hasDeviceConfiguration: boolean;
@@ -67,6 +73,15 @@ export const deviceTransportTypeTranslationMap = new Map<DeviceTransportType, st @@ -67,6 +73,15 @@ export const deviceTransportTypeTranslationMap = new Map<DeviceTransportType, st
67 ] 73 ]
68 ); 74 );
69 75
  76 +
  77 +export const deviceProvisionTypeTranslationMap = new Map<DeviceProvisionType, string>(
  78 + [
  79 + [DeviceProvisionType.DISABLED, 'device-profile.provision-strategy-disabled'],
  80 + [DeviceProvisionType.ALLOW_CREATE_NEW_DEVICES, 'device-profile.provision-strategy-created-new'],
  81 + [DeviceProvisionType.CHECK_PRE_PROVISIONED_DEVICES, 'device-profile.provision-strategy-check-pre-provisioned']
  82 + ]
  83 +)
  84 +
70 export const deviceTransportTypeConfigurationInfoMap = new Map<DeviceTransportType, DeviceConfigurationFormInfo>( 85 export const deviceTransportTypeConfigurationInfoMap = new Map<DeviceTransportType, DeviceConfigurationFormInfo>(
71 [ 86 [
72 [ 87 [
@@ -125,6 +140,12 @@ export interface DeviceProfileTransportConfiguration extends DeviceProfileTransp @@ -125,6 +140,12 @@ export interface DeviceProfileTransportConfiguration extends DeviceProfileTransp
125 type: DeviceTransportType; 140 type: DeviceTransportType;
126 } 141 }
127 142
  143 +export interface DeviceProvisionConfiguration {
  144 + type: DeviceProvisionType;
  145 + provisionDeviceSecret?: string;
  146 + provisionDeviceKey?: string;
  147 +}
  148 +
128 export function createDeviceProfileConfiguration(type: DeviceProfileType): DeviceProfileConfiguration { 149 export function createDeviceProfileConfiguration(type: DeviceProfileType): DeviceProfileConfiguration {
129 let configuration: DeviceProfileConfiguration = null; 150 let configuration: DeviceProfileConfiguration = null;
130 if (type) { 151 if (type) {
@@ -220,6 +241,7 @@ export interface DeviceProfileData { @@ -220,6 +241,7 @@ export interface DeviceProfileData {
220 configuration: DeviceProfileConfiguration; 241 configuration: DeviceProfileConfiguration;
221 transportConfiguration: DeviceProfileTransportConfiguration; 242 transportConfiguration: DeviceProfileTransportConfiguration;
222 alarms?: Array<DeviceProfileAlarm>; 243 alarms?: Array<DeviceProfileAlarm>;
  244 + provisionConfiguration?: DeviceProvisionConfiguration;
223 } 245 }
224 246
225 export interface DeviceProfile extends BaseData<DeviceProfileId> { 247 export interface DeviceProfile extends BaseData<DeviceProfileId> {
@@ -229,6 +251,8 @@ export interface DeviceProfile extends BaseData<DeviceProfileId> { @@ -229,6 +251,8 @@ export interface DeviceProfile extends BaseData<DeviceProfileId> {
229 default?: boolean; 251 default?: boolean;
230 type: DeviceProfileType; 252 type: DeviceProfileType;
231 transportType: DeviceTransportType; 253 transportType: DeviceTransportType;
  254 + provisionType: DeviceProvisionType;
  255 + provisionDeviceKey?: string;
232 defaultRuleChainId?: RuleChainId; 256 defaultRuleChainId?: RuleChainId;
233 profileData: DeviceProfileData; 257 profileData: DeviceProfileData;
234 } 258 }
@@ -840,7 +840,17 @@ @@ -840,7 +840,17 @@
840 "alarm-details": "Alarm details", 840 "alarm-details": "Alarm details",
841 "alarm-rule-condition": "Alarm rule condition", 841 "alarm-rule-condition": "Alarm rule condition",
842 "enter-alarm-rule-condition-prompt": "Please add alarm rule condition", 842 "enter-alarm-rule-condition-prompt": "Please add alarm rule condition",
843 - "edit-alarm-rule-condition": "Edit alarm rule condition" 843 + "edit-alarm-rule-condition": "Edit alarm rule condition",
  844 + "device-provisioning": "Device provisioning",
  845 + "provision-strategy": "Provision strategy",
  846 + "provision-strategy-required": "Provision strategy is required.",
  847 + "provision-strategy-disabled": "Disabled",
  848 + "provision-strategy-created-new": "Allow create new devices",
  849 + "provision-strategy-check-pre-provisioned": "Check pre provisioned devices",
  850 + "provision-device-key": "Provision device key",
  851 + "provision-device-key-required": "Provision device key is required.",
  852 + "provision-device-secret": "Provision device secret",
  853 + "provision-device-secret-required": "Provision device secret is required."
844 }, 854 },
845 "dialog": { 855 "dialog": {
846 "close": "Close dialog" 856 "close": "Close dialog"