Commit 9e8e46f139afc65e64ff1237d98c55198b7ca821
Committed by
GitHub
Merge pull request #3749 from vvlladd28/improvement/device-profile/protobuf
UI: Refactoring device-profile payload type protobuf; Refactoring view
Showing
4 changed files
with
123 additions
and
117 deletions
... | ... | @@ -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> | ... | ... |