Commit 9e8e46f139afc65e64ff1237d98c55198b7ca821

Authored by Igor Kulikov
Committed by GitHub
2 parents 1d959321 08693a40

Merge pull request #3749 from vvlladd28/improvement/device-profile/protobuf

UI: Refactoring device-profile payload type protobuf; Refactoring view
... ... @@ -88,7 +88,7 @@ export class DeviceProfileComponent extends EntityComponent<DeviceProfile> {
88 88 this.displayTransportConfiguration = entity && entity.transportType &&
89 89 deviceTransportTypeConfigurationInfoMap.get(entity.transportType).hasProfileConfiguration;
90 90 const deviceProvisionConfiguration: DeviceProvisionConfiguration = {
91   - type: entity?.provisionType ? entity?.provisionType : DeviceProvisionType.DISABLED,
  91 + type: entity?.provisionType ? entity.provisionType : DeviceProvisionType.DISABLED,
92 92 provisionDeviceKey: entity?.provisionDeviceKey,
93 93 provisionDeviceSecret: entity?.profileData?.provisionConfiguration?.provisionDeviceSecret
94 94 };
... ... @@ -162,7 +162,7 @@ export class DeviceProfileComponent extends EntityComponent<DeviceProfile> {
162 162 this.displayTransportConfiguration = entity.transportType &&
163 163 deviceTransportTypeConfigurationInfoMap.get(entity.transportType).hasProfileConfiguration;
164 164 const deviceProvisionConfiguration: DeviceProvisionConfiguration = {
165   - type: entity?.provisionType ? entity?.provisionType : DeviceProvisionType.DISABLED,
  165 + type: entity?.provisionType ? entity.provisionType : DeviceProvisionType.DISABLED,
166 166 provisionDeviceKey: entity?.provisionDeviceKey,
167 167 provisionDeviceSecret: entity?.profileData?.provisionConfiguration?.provisionDeviceSecret
168 168 };
... ...
... ... @@ -16,86 +16,80 @@
16 16
17 17 -->
18 18 <form [formGroup]="mqttDeviceProfileTransportConfigurationFormGroup" style="padding-bottom: 16px;">
19   - <section formGroupName="configuration">
  19 + <fieldset class="fields-group">
  20 + <legend class="group-title" translate>device-profile.mqtt-device-topic-filters</legend>
  21 + <div fxLayoutGap="8px" fxLayout="column">
  22 + <div fxLayout="row" fxLayoutGap="8px" fxLayout.xs="column">
  23 + <mat-form-field fxFlex>
  24 + <mat-label translate>device-profile.telemetry-topic-filter</mat-label>
  25 + <input matInput required
  26 + formControlName="deviceTelemetryTopic"
  27 + type="text">
  28 + <mat-error *ngIf="mqttDeviceProfileTransportConfigurationFormGroup.get('deviceTelemetryTopic').hasError('required')">
  29 + {{ 'device-profile.telemetry-topic-filter-required' | translate}}
  30 + </mat-error>
  31 + <mat-error *ngIf="mqttDeviceProfileTransportConfigurationFormGroup.get('deviceTelemetryTopic').hasError('invalidSingleTopicCharacter')">
  32 + {{ 'device-profile.not-valid-single-character' | translate}}
  33 + </mat-error>
  34 + <mat-error *ngIf="mqttDeviceProfileTransportConfigurationFormGroup.get('deviceTelemetryTopic').hasError('invalidMultiTopicCharacter')">
  35 + {{ 'device-profile.not-valid-multi-character' | translate}}
  36 + </mat-error>
  37 + </mat-form-field>
  38 + <mat-form-field fxFlex>
  39 + <mat-label translate>device-profile.attributes-topic-filter</mat-label>
  40 + <input matInput required
  41 + formControlName="deviceAttributesTopic"
  42 + type="text">
  43 + <mat-error *ngIf="mqttDeviceProfileTransportConfigurationFormGroup.get('deviceAttributesTopic').hasError('required')">
  44 + {{ 'device-profile.attributes-topic-filter-required' | translate}}
  45 + </mat-error>
  46 + <mat-error *ngIf="mqttDeviceProfileTransportConfigurationFormGroup.get('deviceAttributesTopic').hasError('invalidSingleTopicCharacter')">
  47 + {{ 'device-profile.not-valid-single-character' | translate}}
  48 + </mat-error>
  49 + <mat-error *ngIf="mqttDeviceProfileTransportConfigurationFormGroup.get('deviceAttributesTopic').hasError('invalidMultiTopicCharacter')">
  50 + {{ 'device-profile.not-valid-multi-character' | translate}}
  51 + </mat-error>
  52 + </mat-form-field>
  53 + </div>
  54 + <mat-error *ngIf="mqttDeviceProfileTransportConfigurationFormGroup.hasError('unique')">
  55 + {{ 'device-profile.mqtt-device-topic-filters-unique' | translate }}
  56 + </mat-error>
  57 + <div class="tb-hint" innerHTML="{{ 'device-profile.support-level-wildcards' | translate }}"></div>
  58 + <div class="tb-hint" innerHTML="{{ 'device-profile.single-level-wildcards-hint' | translate }}"></div>
  59 + <div class="tb-hint" innerHTML="{{ 'device-profile.multi-level-wildcards-hint' | translate }}"></div>
  60 + </div>
  61 + </fieldset>
  62 + <section formGroupName="transportPayloadTypeConfiguration">
20 63 <fieldset class="fields-group">
21   - <legend class="group-title" translate>device-profile.mqtt-device-topic-filters</legend>
  64 + <legend class="group-title" translate>device-profile.mqtt-device-payload-type</legend>
22 65 <div fxLayoutGap="8px" fxLayout="column">
23   - <div fxLayout="row" fxLayoutGap="8px" fxLayout.xs="column">
  66 + <mat-form-field class="mat-block">
  67 + <mat-select formControlName="transportPayloadType" required>
  68 + <mat-option *ngFor="let type of mqttTransportPayloadTypes" [value]="type">
  69 + {{mqttTransportPayloadTypeTranslations.get(type) | translate}}
  70 + </mat-option>
  71 + </mat-select>
  72 + <mat-error *ngIf="mqttDeviceProfileTransportConfigurationFormGroup.get('transportPayloadTypeConfiguration.transportPayloadType').hasError('required')">
  73 + {{ 'device-profile.mqtt-payload-type-required' | translate }}
  74 + </mat-error>
  75 + </mat-form-field>
  76 + <div *ngIf="protoPayloadType" fxLayout="column">
24 77 <mat-form-field fxFlex>
25   - <mat-label translate>device-profile.telemetry-topic-filter</mat-label>
26   - <input matInput required
27   - formControlName="deviceTelemetryTopic"
28   - type="text">
29   - <mat-error *ngIf="mqttDeviceProfileTransportConfigurationFormGroup.get('configuration.deviceTelemetryTopic').hasError('required')">
30   - {{ 'device-profile.telemetry-topic-filter-required' | translate}}
31   - </mat-error>
32   - <mat-error *ngIf="mqttDeviceProfileTransportConfigurationFormGroup.get('configuration.deviceTelemetryTopic').hasError('invalidSingleTopicCharacter')">
33   - {{ 'device-profile.not-valid-single-character' | translate}}
34   - </mat-error>
35   - <mat-error *ngIf="mqttDeviceProfileTransportConfigurationFormGroup.get('configuration.deviceTelemetryTopic').hasError('invalidMultiTopicCharacter')">
36   - {{ 'device-profile.not-valid-multi-character' | translate}}
  78 + <mat-label translate>device-profile.telemetry-proto-schema</mat-label>
  79 + <textarea matInput required formControlName="deviceTelemetryProtoSchema" rows="5"></textarea>
  80 + <mat-error *ngIf="mqttDeviceProfileTransportConfigurationFormGroup.get('transportPayloadTypeConfiguration.deviceTelemetryProtoSchema').hasError('required')">
  81 + {{ 'device-profile.telemetry-proto-schema-required' | translate}}
37 82 </mat-error>
38 83 </mat-form-field>
39 84 <mat-form-field fxFlex>
40   - <mat-label translate>device-profile.attributes-topic-filter</mat-label>
41   - <input matInput required
42   - formControlName="deviceAttributesTopic"
43   - type="text">
44   - <mat-error *ngIf="mqttDeviceProfileTransportConfigurationFormGroup.get('configuration.deviceAttributesTopic').hasError('required')">
45   - {{ 'device-profile.attributes-topic-filter-required' | translate}}
46   - </mat-error>
47   - <mat-error *ngIf="mqttDeviceProfileTransportConfigurationFormGroup.get('configuration.deviceAttributesTopic').hasError('invalidSingleTopicCharacter')">
48   - {{ 'device-profile.not-valid-single-character' | translate}}
49   - </mat-error>
50   - <mat-error *ngIf="mqttDeviceProfileTransportConfigurationFormGroup.get('configuration.deviceAttributesTopic').hasError('invalidMultiTopicCharacter')">
51   - {{ 'device-profile.not-valid-multi-character' | translate}}
  85 + <mat-label translate>device-profile.attributes-proto-schema</mat-label>
  86 + <textarea matInput required formControlName="deviceAttributesProtoSchema" rows="5"></textarea>
  87 + <mat-error *ngIf="mqttDeviceProfileTransportConfigurationFormGroup.get('transportPayloadTypeConfiguration.deviceAttributesProtoSchema').hasError('required')">
  88 + {{ 'device-profile.attributes-proto-schema-required' | translate}}
52 89 </mat-error>
53 90 </mat-form-field>
54 91 </div>
55   - <mat-error *ngIf="mqttDeviceProfileTransportConfigurationFormGroup.get('configuration').hasError('unique')">
56   - {{ 'device-profile.mqtt-device-topic-filters-unique' | translate }}
57   - </mat-error>
58   - <div class="tb-hint" innerHTML="{{ 'device-profile.support-level-wildcards' | translate }}"></div>
59   - <div class="tb-hint" innerHTML="{{ 'device-profile.single-level-wildcards-hint' | translate }}"></div>
60   - <div class="tb-hint" innerHTML="{{ 'device-profile.multi-level-wildcards-hint' | translate }}"></div>
61 92 </div>
62 93 </fieldset>
63   - <section formGroupName="transportPayloadTypeConfiguration">
64   - <fieldset class="fields-group">
65   - <legend class="group-title" translate>device-profile.mqtt-device-payload-type</legend>
66   - <div fxLayoutGap="8px" fxLayout="column">
67   - <mat-form-field class="mat-block">
68   - <mat-select formControlName="transportPayloadType" required>
69   - <mat-option *ngFor="let type of mqttTransportPayloadTypes" [value]="type">
70   - {{mqttTransportPayloadTypeTranslations.get(type) | translate}}
71   - </mat-option>
72   - </mat-select>
73   - <mat-error *ngIf="mqttDeviceProfileTransportConfigurationFormGroup.get('configuration.transportPayloadTypeConfiguration.transportPayloadType').hasError('required')">
74   - {{ 'device-profile.mqtt-payload-type-required' | translate }}
75   - </mat-error>
76   - </mat-form-field>
77   - <div *ngIf="protoPayloadType" fxLayout="column">
78   - <mat-form-field fxFlex>
79   - <mat-label translate>device-profile.telemetry-proto-schema</mat-label>
80   - <textarea matInput required
81   - formControlName="deviceTelemetryProtoSchema"
82   - rows="5"></textarea>
83   - <mat-error *ngIf="mqttDeviceProfileTransportConfigurationFormGroup.get('configuration.transportPayloadTypeConfiguration.deviceTelemetryProtoSchema').hasError('required')">
84   - {{ 'device-profile.telemetry-proto-schema-required' | translate}}
85   - </mat-error>
86   - </mat-form-field>
87   - <mat-form-field fxFlex>
88   - <mat-label translate>device-profile.attributes-proto-schema</mat-label>
89   - <textarea matInput required
90   - formControlName="deviceAttributesProtoSchema"
91   - rows="5"></textarea>
92   - <mat-error *ngIf="mqttDeviceProfileTransportConfigurationFormGroup.get('configuration.transportPayloadTypeConfiguration.deviceAttributesProtoSchema').hasError('required')">
93   - {{ 'device-profile.attributes-proto-schema-required' | translate}}
94   - </mat-error>
95   - </mat-form-field>
96   - </div>
97   - </div>
98   - </fieldset>
99   - </section>
100 94 </section>
101 95 </form>
... ...
... ... @@ -54,6 +54,34 @@ export class MqttDeviceProfileTransportConfigurationComponent implements Control
54 54
55 55 mqttDeviceProfileTransportConfigurationFormGroup: FormGroup;
56 56
  57 + private defaultTelemetrySchema =
  58 + 'syntax ="proto3";\n' +
  59 + 'package telemetry;\n' +
  60 + '\n' +
  61 + 'message SensorDataReading {\n' +
  62 + '\n' +
  63 + ' double temperature = 1;\n' +
  64 + ' double humidity = 2;\n' +
  65 + ' InnerObject innerObject = 3;\n' +
  66 + '\n' +
  67 + ' message InnerObject {\n' +
  68 + ' string key1 = 1;\n' +
  69 + ' bool key2 = 2;\n' +
  70 + ' double key3 = 3;\n' +
  71 + ' int32 key4 = 4;\n' +
  72 + ' string key5 = 5;\n' +
  73 + ' }\n' +
  74 + '}\n';
  75 +
  76 + private defaultAttributesSchema =
  77 + 'syntax ="proto3";\n' +
  78 + 'package attributes;\n' +
  79 + '\n' +
  80 + 'message SensorConfiguration {\n' +
  81 + ' string firmwareVersion = 1;\n' +
  82 + ' string serialNumber = 2;\n' +
  83 + '}';
  84 +
57 85 private requiredValue: boolean;
58 86
59 87 get required(): boolean {
... ... @@ -83,17 +111,18 @@ export class MqttDeviceProfileTransportConfigurationComponent implements Control
83 111
84 112 ngOnInit() {
85 113 this.mqttDeviceProfileTransportConfigurationFormGroup = this.fb.group({
86   - configuration: this.fb.group({
87 114 deviceAttributesTopic: [null, [Validators.required, this.validationMQTTTopic()]],
88 115 deviceTelemetryTopic: [null, [Validators.required, this.validationMQTTTopic()]],
89 116 transportPayloadTypeConfiguration: this.fb.group({
90   - transportPayloadType: [MqttTransportPayloadType.JSON, Validators.required]
  117 + transportPayloadType: [MqttTransportPayloadType.JSON, Validators.required],
  118 + deviceTelemetryProtoSchema: [this.defaultTelemetrySchema, Validators.required],
  119 + deviceAttributesProtoSchema: [this.defaultAttributesSchema, Validators.required]
91 120 })
92   - }, {validator: this.uniqueDeviceTopicValidator})
93   - });
94   - this.mqttDeviceProfileTransportConfigurationFormGroup.get('configuration.transportPayloadTypeConfiguration.transportPayloadType').valueChanges.subscribe(payloadType => {
95   - this.updateTransportPayloadBasedControls(payloadType);
96   - this.mqttDeviceProfileTransportConfigurationFormGroup.updateValueAndValidity();
  121 + }, {validator: this.uniqueDeviceTopicValidator}
  122 + );
  123 + this.mqttDeviceProfileTransportConfigurationFormGroup.get('transportPayloadTypeConfiguration.transportPayloadType')
  124 + .valueChanges.subscribe(payloadType => {
  125 + this.updateTransportPayloadBasedControls(payloadType, true);
97 126 });
98 127 this.mqttDeviceProfileTransportConfigurationFormGroup.valueChanges.subscribe(() => {
99 128 this.updateModel();
... ... @@ -110,58 +139,41 @@ export class MqttDeviceProfileTransportConfigurationComponent implements Control
110 139 }
111 140
112 141 get protoPayloadType(): boolean {
113   - let transportPayloadType = this.mqttDeviceProfileTransportConfigurationFormGroup.get('configuration.transportPayloadTypeConfiguration.transportPayloadType').value;
  142 + const transportPayloadType = this.mqttDeviceProfileTransportConfigurationFormGroup.get('transportPayloadTypeConfiguration.transportPayloadType').value;
114 143 return transportPayloadType === MqttTransportPayloadType.PROTOBUF;
115 144 }
116 145
117 146 writeValue(value: MqttDeviceProfileTransportConfiguration | null): void {
118 147 if (isDefinedAndNotNull(value)) {
119   - this.updateTransportPayloadBasedControls(value.transportPayloadTypeConfiguration.transportPayloadType);
120   - this.mqttDeviceProfileTransportConfigurationFormGroup.patchValue({configuration: value}, {emitEvent: false});
  148 + this.mqttDeviceProfileTransportConfigurationFormGroup.patchValue(value, {emitEvent: false});
  149 + this.updateTransportPayloadBasedControls(value.transportPayloadTypeConfiguration?.transportPayloadType);
121 150 }
122 151 }
123 152
124 153 private updateModel() {
125 154 let configuration: DeviceProfileTransportConfiguration = null;
126 155 if (this.mqttDeviceProfileTransportConfigurationFormGroup.valid) {
127   - configuration = this.mqttDeviceProfileTransportConfigurationFormGroup.getRawValue().configuration;
  156 + configuration = this.mqttDeviceProfileTransportConfigurationFormGroup.value;
128 157 configuration.type = DeviceTransportType.MQTT;
129 158 }
130 159 this.propagateChange(configuration);
131 160 }
132 161
133   - private updateTransportPayloadBasedControls(type: MqttTransportPayloadType) {
134   - const transportPayloadTypeConfigurationFormGroup = this.mqttDeviceProfileTransportConfigurationFormGroup.get('configuration.transportPayloadTypeConfiguration') as FormGroup;
135   - if (type === MqttTransportPayloadType.PROTOBUF) {
136   - const defaultTelemetrySchema = "syntax =\"proto3\";\n" +
137   - "package telemetry;\n" +
138   - "\n" +
139   - "message SensorDataReading {\n" +
140   - "\n" +
141   - " double temperature = 1;\n" +
142   - " double humidity = 2;\n" +
143   - " InnerObject innerObject = 3;\n" +
144   - "\n" +
145   - " message InnerObject {\n" +
146   - " string key1 = 1;\n" +
147   - " bool key2 = 2;\n" +
148   - " double key3 = 3;\n" +
149   - " int32 key4 = 4;\n" +
150   - " string key5 = 5;\n" +
151   - " }\n" +
152   - "}\n";
153   - const defaultAttributesSchema = "syntax =\"proto3\";\n" +
154   - "package attributes;\n" +
155   - "\n" +
156   - "message SensorConfiguration {\n" +
157   - " string firmwareVersion = 1;\n" +
158   - " string serialNumber = 2;\n" +
159   - "}";
160   - transportPayloadTypeConfigurationFormGroup.registerControl('deviceTelemetryProtoSchema', this.fb.control(defaultTelemetrySchema, Validators.required));
161   - transportPayloadTypeConfigurationFormGroup.registerControl('deviceAttributesProtoSchema', this.fb.control(defaultAttributesSchema, Validators.required));
  162 + private updateTransportPayloadBasedControls(type: MqttTransportPayloadType, forceUpdated = false) {
  163 + const transportPayloadTypeForm = this.mqttDeviceProfileTransportConfigurationFormGroup
  164 + .get('transportPayloadTypeConfiguration') as FormGroup;
  165 + if (forceUpdated) {
  166 + transportPayloadTypeForm.patchValue({
  167 + deviceTelemetryProtoSchema: this.defaultTelemetrySchema,
  168 + deviceAttributesProtoSchema: this.defaultAttributesSchema
  169 + }, {emitEvent: false});
  170 + }
  171 + if (type === MqttTransportPayloadType.PROTOBUF && !this.disabled) {
  172 + transportPayloadTypeForm.get('deviceTelemetryProtoSchema').enable({emitEvent: false});
  173 + transportPayloadTypeForm.get('deviceAttributesProtoSchema').enable({emitEvent: false});
162 174 } else {
163   - transportPayloadTypeConfigurationFormGroup.removeControl('deviceTelemetryProtoSchema');
164   - transportPayloadTypeConfigurationFormGroup.removeControl('deviceAttributesProtoSchema');
  175 + transportPayloadTypeForm.get('deviceTelemetryProtoSchema').disable({emitEvent: false});
  176 + transportPayloadTypeForm.get('deviceAttributesProtoSchema').disable({emitEvent: false});
165 177 }
166 178 }
167 179
... ...
... ... @@ -41,9 +41,9 @@
41 41 </div>
42 42 </mat-tab>
43 43 <mat-tab *ngIf="entity"
44   - label="{{'device-profile.alarm-rules' | translate:
45   - {count: entity.profileData.alarms && entity.profileData.alarms.length ?
46   - entity.profileData.alarms.length : 0} }}" #alarmRules="matTab">
  44 + label="{{'device-profile.alarm-rules-with-count' | translate:
  45 + {count: entity.profileData?.alarms?.length ? entity.profileData.alarms.length : 0}
  46 + }}" #alarmRules="matTab">
47 47 <div class="mat-padding" [formGroup]="detailsForm">
48 48 <div formGroupName="profileData">
49 49 <tb-device-profile-alarms formControlName="alarms"></tb-device-profile-alarms>
... ...