Commit 3adbb481a17e23d10cd9688f96226d16f95598f1

Authored by Igor Kulikov
1 parent 0759c135

UI: Device profile transport configuration

@@ -181,8 +181,10 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe @@ -181,8 +181,10 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe
181 switch (deviceProfile.getTransportType()){ 181 switch (deviceProfile.getTransportType()){
182 case DEFAULT: 182 case DEFAULT:
183 deviceData.setTransportConfiguration(new DefaultDeviceTransportConfiguration()); 183 deviceData.setTransportConfiguration(new DefaultDeviceTransportConfiguration());
  184 + break;
184 case MQTT: 185 case MQTT:
185 deviceData.setTransportConfiguration(new MqttDeviceTransportConfiguration()); 186 deviceData.setTransportConfiguration(new MqttDeviceTransportConfiguration());
  187 + break;
186 case LWM2M: 188 case LWM2M:
187 deviceData.setTransportConfiguration(new Lwm2mDeviceTransportConfiguration()); 189 deviceData.setTransportConfiguration(new Lwm2mDeviceTransportConfiguration());
188 break; 190 break;
@@ -92,6 +92,8 @@ import { DefaultDeviceProfileConfigurationComponent } from './profile/device/def @@ -92,6 +92,8 @@ import { DefaultDeviceProfileConfigurationComponent } from './profile/device/def
92 import { DeviceProfileConfigurationComponent } from './profile/device/device-profile-configuration.component'; 92 import { DeviceProfileConfigurationComponent } from './profile/device/device-profile-configuration.component';
93 import { DeviceProfileDataComponent } from './profile/device-profile-data.component'; 93 import { DeviceProfileDataComponent } from './profile/device-profile-data.component';
94 import { DeviceProfileComponent } from './profile/device-profile.component'; 94 import { DeviceProfileComponent } from './profile/device-profile.component';
  95 +import { DefaultDeviceProfileTransportConfigurationComponent } from './profile/device/default-device-profile-transport-configuration.component';
  96 +import { DeviceProfileTransportConfigurationComponent } from './profile/device/device-profile-transport-configuration.component';
95 97
96 @NgModule({ 98 @NgModule({
97 declarations: 99 declarations:
@@ -165,6 +167,8 @@ import { DeviceProfileComponent } from './profile/device-profile.component'; @@ -165,6 +167,8 @@ import { DeviceProfileComponent } from './profile/device-profile.component';
165 TenantProfileDialogComponent, 167 TenantProfileDialogComponent,
166 DefaultDeviceProfileConfigurationComponent, 168 DefaultDeviceProfileConfigurationComponent,
167 DeviceProfileConfigurationComponent, 169 DeviceProfileConfigurationComponent,
  170 + DefaultDeviceProfileTransportConfigurationComponent,
  171 + DeviceProfileTransportConfigurationComponent,
168 DeviceProfileDataComponent, 172 DeviceProfileDataComponent,
169 DeviceProfileComponent 173 DeviceProfileComponent
170 ], 174 ],
@@ -229,6 +233,8 @@ import { DeviceProfileComponent } from './profile/device-profile.component'; @@ -229,6 +233,8 @@ import { DeviceProfileComponent } from './profile/device-profile.component';
229 TenantProfileDialogComponent, 233 TenantProfileDialogComponent,
230 DefaultDeviceProfileConfigurationComponent, 234 DefaultDeviceProfileConfigurationComponent,
231 DeviceProfileConfigurationComponent, 235 DeviceProfileConfigurationComponent,
  236 + DefaultDeviceProfileTransportConfigurationComponent,
  237 + DeviceProfileTransportConfigurationComponent,
232 DeviceProfileDataComponent, 238 DeviceProfileDataComponent,
233 DeviceProfileComponent 239 DeviceProfileComponent
234 ], 240 ],
@@ -34,7 +34,10 @@ @@ -34,7 +34,10 @@
34 <div translate>device-profile.transport-configuration</div> 34 <div translate>device-profile.transport-configuration</div>
35 </mat-panel-title> 35 </mat-panel-title>
36 </mat-expansion-panel-header> 36 </mat-expansion-panel-header>
37 - TODO 37 + <tb-device-profile-transport-configuration
  38 + formControlName="transportConfiguration"
  39 + required>
  40 + </tb-device-profile-transport-configuration>
38 </mat-expansion-panel> 41 </mat-expansion-panel>
39 </mat-accordion> 42 </mat-accordion>
40 </div> 43 </div>
@@ -62,7 +62,8 @@ export class DeviceProfileDataComponent implements ControlValueAccessor, OnInit @@ -62,7 +62,8 @@ export class DeviceProfileDataComponent implements ControlValueAccessor, OnInit
62 62
63 ngOnInit() { 63 ngOnInit() {
64 this.deviceProfileDataFormGroup = this.fb.group({ 64 this.deviceProfileDataFormGroup = this.fb.group({
65 - configuration: [null, Validators.required] 65 + configuration: [null, Validators.required],
  66 + transportConfiguration: [null, Validators.required]
66 }); 67 });
67 this.deviceProfileDataFormGroup.valueChanges.subscribe(() => { 68 this.deviceProfileDataFormGroup.valueChanges.subscribe(() => {
68 this.updateModel(); 69 this.updateModel();
@@ -80,6 +81,7 @@ export class DeviceProfileDataComponent implements ControlValueAccessor, OnInit @@ -80,6 +81,7 @@ export class DeviceProfileDataComponent implements ControlValueAccessor, OnInit
80 81
81 writeValue(value: DeviceProfileData | null): void { 82 writeValue(value: DeviceProfileData | null): void {
82 this.deviceProfileDataFormGroup.patchValue({configuration: value?.configuration}, {emitEvent: false}); 83 this.deviceProfileDataFormGroup.patchValue({configuration: value?.configuration}, {emitEvent: false});
  84 + this.deviceProfileDataFormGroup.patchValue({transportConfiguration: value?.transportConfiguration}, {emitEvent: false});
83 } 85 }
84 86
85 private updateModel() { 87 private updateModel() {
@@ -65,6 +65,17 @@ @@ -65,6 +65,17 @@
65 {{ 'device-profile.type-required' | translate }} 65 {{ 'device-profile.type-required' | translate }}
66 </mat-error> 66 </mat-error>
67 </mat-form-field> 67 </mat-form-field>
  68 + <mat-form-field class="mat-block">
  69 + <mat-label translate>device-profile.transport-type</mat-label>
  70 + <mat-select formControlName="transportType" required>
  71 + <mat-option *ngFor="let type of deviceTransportTypes" [value]="type">
  72 + {{deviceTransportTypeTranslations.get(type) | translate}}
  73 + </mat-option>
  74 + </mat-select>
  75 + <mat-error *ngIf="entityForm.get('transportType').hasError('required')">
  76 + {{ 'device-profile.transport-type-required' | translate }}
  77 + </mat-error>
  78 + </mat-form-field>
68 <tb-device-profile-data 79 <tb-device-profile-data
69 formControlName="profileData" 80 formControlName="profileData"
70 required> 81 required>
@@ -27,7 +27,10 @@ import { @@ -27,7 +27,10 @@ import {
27 DeviceProfile, 27 DeviceProfile,
28 DeviceProfileData, 28 DeviceProfileData,
29 DeviceProfileType, 29 DeviceProfileType,
30 - deviceProfileTypeTranslationMap 30 + deviceProfileTypeTranslationMap,
  31 + DeviceTransportType,
  32 + deviceTransportTypeTranslationMap,
  33 + createDeviceProfileTransportConfiguration
31 } from '@shared/models/device.models'; 34 } from '@shared/models/device.models';
32 import { EntityType } from '@shared/models/entity-type.models'; 35 import { EntityType } from '@shared/models/entity-type.models';
33 import { RuleChainId } from '@shared/models/id/rule-chain-id'; 36 import { RuleChainId } from '@shared/models/id/rule-chain-id';
@@ -48,6 +51,10 @@ export class DeviceProfileComponent extends EntityComponent<DeviceProfile> { @@ -48,6 +51,10 @@ export class DeviceProfileComponent extends EntityComponent<DeviceProfile> {
48 51
49 deviceProfileTypeTranslations = deviceProfileTypeTranslationMap; 52 deviceProfileTypeTranslations = deviceProfileTypeTranslationMap;
50 53
  54 + deviceTransportTypes = Object.keys(DeviceTransportType);
  55 +
  56 + deviceTransportTypeTranslations = deviceTransportTypeTranslationMap;
  57 +
51 constructor(protected store: Store<AppState>, 58 constructor(protected store: Store<AppState>,
52 protected translate: TranslateService, 59 protected translate: TranslateService,
53 @Optional() @Inject('entity') protected entityValue: DeviceProfile, 60 @Optional() @Inject('entity') protected entityValue: DeviceProfile,
@@ -68,7 +75,8 @@ export class DeviceProfileComponent extends EntityComponent<DeviceProfile> { @@ -68,7 +75,8 @@ export class DeviceProfileComponent extends EntityComponent<DeviceProfile> {
68 const form = this.fb.group( 75 const form = this.fb.group(
69 { 76 {
70 name: [entity ? entity.name : '', [Validators.required]], 77 name: [entity ? entity.name : '', [Validators.required]],
71 - type: [entity ? entity.type : '', [Validators.required]], 78 + type: [entity ? entity.type : null, [Validators.required]],
  79 + transportType: [entity ? entity.transportType : null, [Validators.required]],
72 profileData: [entity && !this.isAdd ? entity.profileData : {}, []], 80 profileData: [entity && !this.isAdd ? entity.profileData : {}, []],
73 defaultRuleChainId: [entity && entity.defaultRuleChainId ? entity.defaultRuleChainId.id : null, []], 81 defaultRuleChainId: [entity && entity.defaultRuleChainId ? entity.defaultRuleChainId.id : null, []],
74 description: [entity ? entity.description : '', []], 82 description: [entity ? entity.description : '', []],
@@ -77,6 +85,9 @@ export class DeviceProfileComponent extends EntityComponent<DeviceProfile> { @@ -77,6 +85,9 @@ export class DeviceProfileComponent extends EntityComponent<DeviceProfile> {
77 form.get('type').valueChanges.subscribe(() => { 85 form.get('type').valueChanges.subscribe(() => {
78 this.deviceProfileTypeChanged(form); 86 this.deviceProfileTypeChanged(form);
79 }); 87 });
  88 + form.get('transportType').valueChanges.subscribe(() => {
  89 + this.deviceProfileTransportTypeChanged(form);
  90 + });
80 this.checkIsNewDeviceProfile(entity, form); 91 this.checkIsNewDeviceProfile(entity, form);
81 return form; 92 return form;
82 } 93 }
@@ -84,6 +95,7 @@ export class DeviceProfileComponent extends EntityComponent<DeviceProfile> { @@ -84,6 +95,7 @@ export class DeviceProfileComponent extends EntityComponent<DeviceProfile> {
84 private checkIsNewDeviceProfile(entity: DeviceProfile, form: FormGroup) { 95 private checkIsNewDeviceProfile(entity: DeviceProfile, form: FormGroup) {
85 if (entity && !entity.id) { 96 if (entity && !entity.id) {
86 form.get('type').patchValue(DeviceProfileType.DEFAULT, {emitEvent: true}); 97 form.get('type').patchValue(DeviceProfileType.DEFAULT, {emitEvent: true});
  98 + form.get('transportType').patchValue(DeviceTransportType.DEFAULT, {emitEvent: true});
87 } 99 }
88 } 100 }
89 101
@@ -92,16 +104,31 @@ export class DeviceProfileComponent extends EntityComponent<DeviceProfile> { @@ -92,16 +104,31 @@ export class DeviceProfileComponent extends EntityComponent<DeviceProfile> {
92 let profileData: DeviceProfileData = form.getRawValue().profileData; 104 let profileData: DeviceProfileData = form.getRawValue().profileData;
93 if (!profileData) { 105 if (!profileData) {
94 profileData = { 106 profileData = {
95 - configuration: null 107 + configuration: null,
  108 + transportConfiguration: null
96 }; 109 };
97 } 110 }
98 profileData.configuration = createDeviceProfileConfiguration(deviceProfileType); 111 profileData.configuration = createDeviceProfileConfiguration(deviceProfileType);
99 form.patchValue({profileData}); 112 form.patchValue({profileData});
100 } 113 }
101 114
  115 + private deviceProfileTransportTypeChanged(form: FormGroup) {
  116 + const deviceTransportType: DeviceTransportType = form.get('transportType').value;
  117 + let profileData: DeviceProfileData = form.getRawValue().profileData;
  118 + if (!profileData) {
  119 + profileData = {
  120 + configuration: null,
  121 + transportConfiguration: null
  122 + };
  123 + }
  124 + profileData.transportConfiguration = createDeviceProfileTransportConfiguration(deviceTransportType);
  125 + form.patchValue({profileData});
  126 + }
  127 +
102 updateForm(entity: DeviceProfile) { 128 updateForm(entity: DeviceProfile) {
103 this.entityForm.patchValue({name: entity.name}); 129 this.entityForm.patchValue({name: entity.name});
104 this.entityForm.patchValue({type: entity.type}); 130 this.entityForm.patchValue({type: entity.type});
  131 + this.entityForm.patchValue({transportType: entity.transportType});
105 this.entityForm.patchValue({profileData: entity.profileData}); 132 this.entityForm.patchValue({profileData: entity.profileData});
106 this.entityForm.patchValue({defaultRuleChainId: entity.defaultRuleChainId ? entity.defaultRuleChainId.id : null}); 133 this.entityForm.patchValue({defaultRuleChainId: entity.defaultRuleChainId ? entity.defaultRuleChainId.id : null});
107 this.entityForm.patchValue({description: entity.description}); 134 this.entityForm.patchValue({description: entity.description});
  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 +<form [formGroup]="defaultDeviceProfileTransportConfigurationFormGroup" style="padding-bottom: 16px;">
  19 + <tb-json-object-edit
  20 + [required]="required"
  21 + label="{{ 'device-profile.transport-type-default' | translate }}"
  22 + formControlName="configuration">
  23 + </tb-json-object-edit>
  24 +</form>
  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 { ControlValueAccessor, FormBuilder, FormGroup, NG_VALUE_ACCESSOR, Validators } from '@angular/forms';
  19 +import { Store } from '@ngrx/store';
  20 +import { AppState } from '@app/core/core.state';
  21 +import { coerceBooleanProperty } from '@angular/cdk/coercion';
  22 +import {
  23 + DefaultDeviceProfileTransportConfiguration,
  24 + DeviceProfileTransportConfiguration,
  25 + DeviceTransportType
  26 +} from '@shared/models/device.models';
  27 +
  28 +@Component({
  29 + selector: 'tb-default-device-profile-transport-configuration',
  30 + templateUrl: './default-device-profile-transport-configuration.component.html',
  31 + styleUrls: [],
  32 + providers: [{
  33 + provide: NG_VALUE_ACCESSOR,
  34 + useExisting: forwardRef(() => DefaultDeviceProfileTransportConfigurationComponent),
  35 + multi: true
  36 + }]
  37 +})
  38 +export class DefaultDeviceProfileTransportConfigurationComponent implements ControlValueAccessor, OnInit {
  39 +
  40 + defaultDeviceProfileTransportConfigurationFormGroup: FormGroup;
  41 +
  42 + private requiredValue: boolean;
  43 + get required(): boolean {
  44 + return this.requiredValue;
  45 + }
  46 + @Input()
  47 + set required(value: boolean) {
  48 + this.requiredValue = coerceBooleanProperty(value);
  49 + }
  50 +
  51 + @Input()
  52 + disabled: boolean;
  53 +
  54 + private propagateChange = (v: any) => { };
  55 +
  56 + constructor(private store: Store<AppState>,
  57 + private fb: FormBuilder) {
  58 + }
  59 +
  60 + registerOnChange(fn: any): void {
  61 + this.propagateChange = fn;
  62 + }
  63 +
  64 + registerOnTouched(fn: any): void {
  65 + }
  66 +
  67 + ngOnInit() {
  68 + this.defaultDeviceProfileTransportConfigurationFormGroup = this.fb.group({
  69 + configuration: [null, Validators.required]
  70 + });
  71 + this.defaultDeviceProfileTransportConfigurationFormGroup.valueChanges.subscribe(() => {
  72 + this.updateModel();
  73 + });
  74 + }
  75 +
  76 + setDisabledState(isDisabled: boolean): void {
  77 + this.disabled = isDisabled;
  78 + if (this.disabled) {
  79 + this.defaultDeviceProfileTransportConfigurationFormGroup.disable({emitEvent: false});
  80 + } else {
  81 + this.defaultDeviceProfileTransportConfigurationFormGroup.enable({emitEvent: false});
  82 + }
  83 + }
  84 +
  85 + writeValue(value: DefaultDeviceProfileTransportConfiguration | null): void {
  86 + this.defaultDeviceProfileTransportConfigurationFormGroup.patchValue({configuration: value}, {emitEvent: false});
  87 + }
  88 +
  89 + private updateModel() {
  90 + let configuration: DeviceProfileTransportConfiguration = null;
  91 + if (this.defaultDeviceProfileTransportConfigurationFormGroup.valid) {
  92 + configuration = this.defaultDeviceProfileTransportConfigurationFormGroup.getRawValue().configuration;
  93 + configuration.type = DeviceTransportType.DEFAULT;
  94 + }
  95 + this.propagateChange(configuration);
  96 + }
  97 +}
@@ -20,7 +20,7 @@ import { Store } from '@ngrx/store'; @@ -20,7 +20,7 @@ import { Store } from '@ngrx/store';
20 import { AppState } from '@app/core/core.state'; 20 import { AppState } from '@app/core/core.state';
21 import { coerceBooleanProperty } from '@angular/cdk/coercion'; 21 import { coerceBooleanProperty } from '@angular/cdk/coercion';
22 import { DeviceProfileConfiguration, DeviceProfileType } from '@shared/models/device.models'; 22 import { DeviceProfileConfiguration, DeviceProfileType } from '@shared/models/device.models';
23 -import { deepClone } from '../../../../../core/utils'; 23 +import { deepClone } from '@core/utils';
24 24
25 @Component({ 25 @Component({
26 selector: 'tb-device-profile-configuration', 26 selector: 'tb-device-profile-configuration',
  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]="deviceProfileTransportConfigurationFormGroup">
  19 + <div [ngSwitch]="transportType">
  20 + <ng-template [ngSwitchCase]="deviceTransportType.DEFAULT">
  21 + <tb-default-device-profile-configuration
  22 + [required]="required"
  23 + formControlName="configuration">
  24 + </tb-default-device-profile-configuration>
  25 + </ng-template>
  26 + </div>
  27 +</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 { ControlValueAccessor, FormBuilder, FormGroup, NG_VALUE_ACCESSOR, Validators } from '@angular/forms';
  19 +import { Store } from '@ngrx/store';
  20 +import { AppState } from '@app/core/core.state';
  21 +import { coerceBooleanProperty } from '@angular/cdk/coercion';
  22 +import { DeviceProfileTransportConfiguration, DeviceTransportType } from '@shared/models/device.models';
  23 +import { deepClone } from '@core/utils';
  24 +
  25 +@Component({
  26 + selector: 'tb-device-profile-transport-configuration',
  27 + templateUrl: './device-profile-transport-configuration.component.html',
  28 + styleUrls: [],
  29 + providers: [{
  30 + provide: NG_VALUE_ACCESSOR,
  31 + useExisting: forwardRef(() => DeviceProfileTransportConfigurationComponent),
  32 + multi: true
  33 + }]
  34 +})
  35 +export class DeviceProfileTransportConfigurationComponent implements ControlValueAccessor, OnInit {
  36 +
  37 + deviceTransportType = DeviceTransportType;
  38 +
  39 + deviceProfileTransportConfigurationFormGroup: FormGroup;
  40 +
  41 + private requiredValue: boolean;
  42 + get required(): boolean {
  43 + return this.requiredValue;
  44 + }
  45 + @Input()
  46 + set required(value: boolean) {
  47 + this.requiredValue = coerceBooleanProperty(value);
  48 + }
  49 +
  50 + @Input()
  51 + disabled: boolean;
  52 +
  53 + transportType: DeviceTransportType;
  54 +
  55 + private propagateChange = (v: any) => { };
  56 +
  57 + constructor(private store: Store<AppState>,
  58 + private fb: FormBuilder) {
  59 + }
  60 +
  61 + registerOnChange(fn: any): void {
  62 + this.propagateChange = fn;
  63 + }
  64 +
  65 + registerOnTouched(fn: any): void {
  66 + }
  67 +
  68 + ngOnInit() {
  69 + this.deviceProfileTransportConfigurationFormGroup = this.fb.group({
  70 + configuration: [null, Validators.required]
  71 + });
  72 + this.deviceProfileTransportConfigurationFormGroup.valueChanges.subscribe(() => {
  73 + this.updateModel();
  74 + });
  75 + }
  76 +
  77 + setDisabledState(isDisabled: boolean): void {
  78 + this.disabled = isDisabled;
  79 + if (this.disabled) {
  80 + this.deviceProfileTransportConfigurationFormGroup.disable({emitEvent: false});
  81 + } else {
  82 + this.deviceProfileTransportConfigurationFormGroup.enable({emitEvent: false});
  83 + }
  84 + }
  85 +
  86 + writeValue(value: DeviceProfileTransportConfiguration | null): void {
  87 + this.transportType = value?.type;
  88 + const configuration = deepClone(value);
  89 + if (configuration) {
  90 + delete configuration.type;
  91 + }
  92 + this.deviceProfileTransportConfigurationFormGroup.patchValue({configuration}, {emitEvent: false});
  93 + }
  94 +
  95 + private updateModel() {
  96 + let configuration: DeviceProfileTransportConfiguration = null;
  97 + if (this.deviceProfileTransportConfigurationFormGroup.valid) {
  98 + configuration = this.deviceProfileTransportConfigurationFormGroup.getRawValue().configuration;
  99 + configuration.type = this.transportType;
  100 + }
  101 + this.propagateChange(configuration);
  102 + }
  103 +}
@@ -27,7 +27,11 @@ import { DatePipe } from '@angular/common'; @@ -27,7 +27,11 @@ import { DatePipe } from '@angular/common';
27 import { EntityType, entityTypeResources, entityTypeTranslations } from '@shared/models/entity-type.models'; 27 import { EntityType, entityTypeResources, entityTypeTranslations } from '@shared/models/entity-type.models';
28 import { EntityAction } from '@home/models/entity/entity-component.models'; 28 import { EntityAction } from '@home/models/entity/entity-component.models';
29 import { DialogService } from '@core/services/dialog.service'; 29 import { DialogService } from '@core/services/dialog.service';
30 -import { DeviceProfile, deviceProfileTypeTranslationMap } from '@shared/models/device.models'; 30 +import {
  31 + DeviceProfile,
  32 + deviceProfileTypeTranslationMap,
  33 + deviceTransportTypeTranslationMap
  34 +} from '@shared/models/device.models';
31 import { DeviceProfileService } from '@core/http/device-profile.service'; 35 import { DeviceProfileService } from '@core/http/device-profile.service';
32 import { DeviceProfileComponent } from '../../components/profile/device-profile.component'; 36 import { DeviceProfileComponent } from '../../components/profile/device-profile.component';
33 import { DeviceProfileTabsComponent } from './device-profile-tabs.component'; 37 import { DeviceProfileTabsComponent } from './device-profile-tabs.component';
@@ -56,7 +60,10 @@ export class DeviceProfilesTableConfigResolver implements Resolve<EntityTableCon @@ -56,7 +60,10 @@ export class DeviceProfilesTableConfigResolver implements Resolve<EntityTableCon
56 new EntityTableColumn<DeviceProfile>('type', 'device-profile.type', '20%', (deviceProfile) => { 60 new EntityTableColumn<DeviceProfile>('type', 'device-profile.type', '20%', (deviceProfile) => {
57 return this.translate.instant(deviceProfileTypeTranslationMap.get(deviceProfile.type)); 61 return this.translate.instant(deviceProfileTypeTranslationMap.get(deviceProfile.type));
58 }), 62 }),
59 - new EntityTableColumn<DeviceProfile>('description', 'device-profile.description', '60%'), 63 + new EntityTableColumn<DeviceProfile>('transportType', 'device-profile.transport-type', '20%', (deviceProfile) => {
  64 + return this.translate.instant(deviceTransportTypeTranslationMap.get(deviceProfile.transportType));
  65 + }),
  66 + new EntityTableColumn<DeviceProfile>('description', 'device-profile.description', '40%'),
60 new EntityTableColumn<DeviceProfile>('isDefault', 'device-profile.default', '60px', 67 new EntityTableColumn<DeviceProfile>('isDefault', 'device-profile.default', '60px',
61 entity => { 68 entity => {
62 return checkBoxCell(entity.default); 69 return checkBoxCell(entity.default);
@@ -28,12 +28,26 @@ export enum DeviceProfileType { @@ -28,12 +28,26 @@ export enum DeviceProfileType {
28 DEFAULT = 'DEFAULT' 28 DEFAULT = 'DEFAULT'
29 } 29 }
30 30
  31 +export enum DeviceTransportType {
  32 + DEFAULT = 'DEFAULT',
  33 + MQTT = 'MQTT',
  34 + LWM2M = 'LWM2M'
  35 +}
  36 +
31 export const deviceProfileTypeTranslationMap = new Map<DeviceProfileType, string>( 37 export const deviceProfileTypeTranslationMap = new Map<DeviceProfileType, string>(
32 [ 38 [
33 [DeviceProfileType.DEFAULT, 'device-profile.type-default'] 39 [DeviceProfileType.DEFAULT, 'device-profile.type-default']
34 ] 40 ]
35 ); 41 );
36 42
  43 +export const deviceTransportTypeTranslationMap = new Map<DeviceTransportType, string>(
  44 + [
  45 + [DeviceTransportType.DEFAULT, 'device-profile.transport-type-default'],
  46 + [DeviceTransportType.MQTT, 'device-profile.transport-type-mqtt'],
  47 + [DeviceTransportType.LWM2M, 'device-profile.transport-type-lwm2m']
  48 + ]
  49 +);
  50 +
37 export interface DefaultDeviceProfileConfiguration { 51 export interface DefaultDeviceProfileConfiguration {
38 [key: string]: any; 52 [key: string]: any;
39 } 53 }
@@ -44,6 +58,26 @@ export interface DeviceProfileConfiguration extends DeviceProfileConfigurations @@ -44,6 +58,26 @@ export interface DeviceProfileConfiguration extends DeviceProfileConfigurations
44 type: DeviceProfileType; 58 type: DeviceProfileType;
45 } 59 }
46 60
  61 +export interface DefaultDeviceProfileTransportConfiguration {
  62 + [key: string]: any;
  63 +}
  64 +
  65 +export interface MqttDeviceProfileTransportConfiguration {
  66 + [key: string]: any;
  67 +}
  68 +
  69 +export interface Lwm2mDeviceProfileTransportConfiguration {
  70 + [key: string]: any;
  71 +}
  72 +
  73 +export type DeviceProfileTransportConfigurations = DefaultDeviceProfileTransportConfiguration &
  74 + MqttDeviceProfileTransportConfiguration &
  75 + Lwm2mDeviceProfileTransportConfiguration;
  76 +
  77 +export interface DeviceProfileTransportConfiguration extends DeviceProfileTransportConfigurations {
  78 + type: DeviceTransportType;
  79 +}
  80 +
47 export function createDeviceProfileConfiguration(type: DeviceProfileType): DeviceProfileConfiguration { 81 export function createDeviceProfileConfiguration(type: DeviceProfileType): DeviceProfileConfiguration {
48 let configuration: DeviceProfileConfiguration = null; 82 let configuration: DeviceProfileConfiguration = null;
49 if (type) { 83 if (type) {
@@ -57,8 +91,30 @@ export function createDeviceProfileConfiguration(type: DeviceProfileType): Devic @@ -57,8 +91,30 @@ export function createDeviceProfileConfiguration(type: DeviceProfileType): Devic
57 return configuration; 91 return configuration;
58 } 92 }
59 93
  94 +export function createDeviceProfileTransportConfiguration(type: DeviceTransportType): DeviceProfileTransportConfiguration {
  95 + let transportConfiguration: DeviceProfileTransportConfiguration = null;
  96 + if (type) {
  97 + switch (type) {
  98 + case DeviceTransportType.DEFAULT:
  99 + const defaultTransportConfiguration: DefaultDeviceProfileTransportConfiguration = {};
  100 + transportConfiguration = {...defaultTransportConfiguration, type: DeviceTransportType.DEFAULT};
  101 + break;
  102 + case DeviceTransportType.MQTT:
  103 + const mqttTransportConfiguration: MqttDeviceProfileTransportConfiguration = {};
  104 + transportConfiguration = {...mqttTransportConfiguration, type: DeviceTransportType.MQTT};
  105 + break;
  106 + case DeviceTransportType.LWM2M:
  107 + const lwm2mTransportConfiguration: Lwm2mDeviceProfileTransportConfiguration = {};
  108 + transportConfiguration = {...lwm2mTransportConfiguration, type: DeviceTransportType.LWM2M};
  109 + break;
  110 + }
  111 + }
  112 + return transportConfiguration;
  113 +}
  114 +
60 export interface DeviceProfileData { 115 export interface DeviceProfileData {
61 configuration: DeviceProfileConfiguration; 116 configuration: DeviceProfileConfiguration;
  117 + transportConfiguration: DeviceProfileTransportConfiguration;
62 } 118 }
63 119
64 export interface DeviceProfile extends BaseData<DeviceProfileId> { 120 export interface DeviceProfile extends BaseData<DeviceProfileId> {
@@ -67,29 +123,49 @@ export interface DeviceProfile extends BaseData<DeviceProfileId> { @@ -67,29 +123,49 @@ export interface DeviceProfile extends BaseData<DeviceProfileId> {
67 description?: string; 123 description?: string;
68 default: boolean; 124 default: boolean;
69 type: DeviceProfileType; 125 type: DeviceProfileType;
  126 + transportType: DeviceTransportType;
70 defaultRuleChainId?: RuleChainId; 127 defaultRuleChainId?: RuleChainId;
71 profileData: DeviceProfileData; 128 profileData: DeviceProfileData;
72 } 129 }
73 130
74 export interface DeviceProfileInfo extends EntityInfoData { 131 export interface DeviceProfileInfo extends EntityInfoData {
75 type: DeviceProfileType; 132 type: DeviceProfileType;
  133 + transportType: DeviceTransportType;
76 } 134 }
77 135
78 export interface DefaultDeviceConfiguration { 136 export interface DefaultDeviceConfiguration {
79 [key: string]: any; 137 [key: string]: any;
80 } 138 }
81 -export interface Lwm2mDeviceConfiguration {  
82 - [key: string]: any;  
83 -}  
84 139
85 -export type DeviceConfigurations = DefaultDeviceConfiguration & Lwm2mDeviceConfiguration; 140 +export type DeviceConfigurations = DefaultDeviceConfiguration;
86 141
87 export interface DeviceConfiguration extends DeviceConfigurations { 142 export interface DeviceConfiguration extends DeviceConfigurations {
88 type: DeviceProfileType; 143 type: DeviceProfileType;
89 } 144 }
90 145
  146 +export interface DefaultDeviceTransportConfiguration {
  147 + [key: string]: any;
  148 +}
  149 +
  150 +export interface MqttDeviceTransportConfiguration {
  151 + [key: string]: any;
  152 +}
  153 +
  154 +export interface Lwm2mDeviceTransportConfiguration {
  155 + [key: string]: any;
  156 +}
  157 +
  158 +export type DeviceTransportConfigurations = DefaultDeviceTransportConfiguration &
  159 + MqttDeviceTransportConfiguration &
  160 + Lwm2mDeviceTransportConfiguration;
  161 +
  162 +export interface DeviceTransportConfiguration extends DeviceTransportConfigurations {
  163 + type: DeviceTransportType;
  164 +}
  165 +
91 export interface DeviceData { 166 export interface DeviceData {
92 configuration: DeviceConfiguration; 167 configuration: DeviceConfiguration;
  168 + transportConfiguration: DeviceTransportConfiguration;
93 } 169 }
94 170
95 export interface Device extends BaseData<DeviceId> { 171 export interface Device extends BaseData<DeviceId> {
@@ -770,6 +770,11 @@ @@ -770,6 +770,11 @@
770 "type": "Profile type", 770 "type": "Profile type",
771 "type-required": "Profile type is required.", 771 "type-required": "Profile type is required.",
772 "type-default": "Default", 772 "type-default": "Default",
  773 + "transport-type": "Transport type",
  774 + "transport-type-required": "Transport type is required.",
  775 + "transport-type-default": "Default",
  776 + "transport-type-mqtt": "MQTT",
  777 + "transport-type-lwm2m": "LWM2M",
773 "description": "Description", 778 "description": "Description",
774 "default": "Default", 779 "default": "Default",
775 "profile-configuration": "Profile configuration", 780 "profile-configuration": "Profile configuration",