Showing
5 changed files
with
105 additions
and
10 deletions
... | ... | @@ -16,9 +16,50 @@ |
16 | 16 | |
17 | 17 | --> |
18 | 18 | <form [formGroup]="mqttDeviceProfileTransportConfigurationFormGroup" style="padding-bottom: 16px;"> |
19 | - <tb-json-object-edit | |
20 | - [required]="required" | |
21 | - label="{{ 'device-profile.transport-type-mqtt' | translate }}" | |
22 | - formControlName="configuration"> | |
23 | - </tb-json-object-edit> | |
19 | + <section formGroupName="configuration"> | |
20 | + <fieldset class="fields-group"> | |
21 | + <legend class="group-title" translate>device-profile.mqtt-device-topic-filters</legend> | |
22 | + <h6 class="mat-body" translate>device-profile.support-level-wildcards</h6> | |
23 | + <div fxLayout="row" fxLayoutGap="8px" fxLayout.xs="column"> | |
24 | + <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-form-field> | |
33 | + <mat-form-field fxFlex> | |
34 | + <mat-label translate>device-profile.rpc-request-topic-filter</mat-label> | |
35 | + <input matInput required | |
36 | + formControlName="deviceRpcRequestTopic" | |
37 | + type="text"> | |
38 | + <mat-error *ngIf="mqttDeviceProfileTransportConfigurationFormGroup.get('configuration.deviceRpcRequestTopic').hasError('required')"> | |
39 | + {{ 'device-profile.rpc-request-topic-filter-required' | translate}} | |
40 | + </mat-error> | |
41 | + </mat-form-field> | |
42 | + </div> | |
43 | + <div fxLayout="row" fxLayoutGap="8px" fxLayout.xs="column"> | |
44 | + <mat-form-field fxFlex> | |
45 | + <mat-label translate>device-profile.attributes-topic-filter</mat-label> | |
46 | + <input matInput required | |
47 | + formControlName="deviceAttributesTopic" | |
48 | + type="text"> | |
49 | + <mat-error *ngIf="mqttDeviceProfileTransportConfigurationFormGroup.get('configuration.deviceAttributesTopic').hasError('required')"> | |
50 | + {{ 'device-profile.attributes-topic-filter-required' | translate}} | |
51 | + </mat-error> | |
52 | + </mat-form-field> | |
53 | + <mat-form-field fxFlex> | |
54 | + <mat-label translate>device-profile.rpc-response-topic-filter</mat-label> | |
55 | + <input matInput required | |
56 | + formControlName="deviceRpcResponseTopic" | |
57 | + type="text"> | |
58 | + <mat-error *ngIf="mqttDeviceProfileTransportConfigurationFormGroup.get('configuration.deviceRpcResponseTopic').hasError('required')"> | |
59 | + {{ 'device-profile.rpc-response-topic-filter-required' | translate}} | |
60 | + </mat-error> | |
61 | + </mat-form-field> | |
62 | + </div> | |
63 | + </fieldset> | |
64 | + </section> | |
24 | 65 | </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 | +:host{ | |
17 | + .fields-group { | |
18 | + padding: 8px; | |
19 | + margin: 10px 0; | |
20 | + border: 1px groove rgba(0, 0, 0, .25); | |
21 | + border-radius: 4px; | |
22 | + | |
23 | + legend { | |
24 | + color: rgba(0, 0, 0, .7); | |
25 | + } | |
26 | + } | |
27 | +} | ... | ... |
... | ... | @@ -23,11 +23,12 @@ import { |
23 | 23 | DeviceProfileTransportConfiguration, |
24 | 24 | DeviceTransportType, MqttDeviceProfileTransportConfiguration |
25 | 25 | } from '@shared/models/device.models'; |
26 | +import { isDefinedAndNotNull } from '../../../../../core/utils'; | |
26 | 27 | |
27 | 28 | @Component({ |
28 | 29 | selector: 'tb-mqtt-device-profile-transport-configuration', |
29 | 30 | templateUrl: './mqtt-device-profile-transport-configuration.component.html', |
30 | - styleUrls: [], | |
31 | + styleUrls: ['./mqtt-device-profile-transport-configuration.component.scss'], | |
31 | 32 | providers: [{ |
32 | 33 | provide: NG_VALUE_ACCESSOR, |
33 | 34 | useExisting: forwardRef(() => MqttDeviceProfileTransportConfigurationComponent), |
... | ... | @@ -65,7 +66,12 @@ export class MqttDeviceProfileTransportConfigurationComponent implements Control |
65 | 66 | |
66 | 67 | ngOnInit() { |
67 | 68 | this.mqttDeviceProfileTransportConfigurationFormGroup = this.fb.group({ |
68 | - configuration: [null, Validators.required] | |
69 | + configuration: this.fb.group({ | |
70 | + deviceAttributesTopic: [null, Validators.required], | |
71 | + deviceTelemetryTopic: [null, Validators.required], | |
72 | + deviceRpcRequestTopic: [null, Validators.required], | |
73 | + deviceRpcResponseTopic: [null, Validators.required] | |
74 | + }) | |
69 | 75 | }); |
70 | 76 | this.mqttDeviceProfileTransportConfigurationFormGroup.valueChanges.subscribe(() => { |
71 | 77 | this.updateModel(); |
... | ... | @@ -82,7 +88,9 @@ export class MqttDeviceProfileTransportConfigurationComponent implements Control |
82 | 88 | } |
83 | 89 | |
84 | 90 | writeValue(value: MqttDeviceProfileTransportConfiguration | null): void { |
85 | - this.mqttDeviceProfileTransportConfigurationFormGroup.patchValue({configuration: value}, {emitEvent: false}); | |
91 | + if (isDefinedAndNotNull(value)) { | |
92 | + this.mqttDeviceProfileTransportConfigurationFormGroup.patchValue({configuration: value}, {emitEvent: false}); | |
93 | + } | |
86 | 94 | } |
87 | 95 | |
88 | 96 | private updateModel() { | ... | ... |
... | ... | @@ -106,6 +106,10 @@ export interface DefaultDeviceProfileTransportConfiguration { |
106 | 106 | } |
107 | 107 | |
108 | 108 | export interface MqttDeviceProfileTransportConfiguration { |
109 | + deviceTelemetryTopic?: string; | |
110 | + deviceAttributesTopic?: string; | |
111 | + deviceRpcRequestTopic?: string; | |
112 | + deviceRpcResponseTopic?: string; | |
109 | 113 | [key: string]: any; |
110 | 114 | } |
111 | 115 | |
... | ... | @@ -156,7 +160,12 @@ export function createDeviceProfileTransportConfiguration(type: DeviceTransportT |
156 | 160 | transportConfiguration = {...defaultTransportConfiguration, type: DeviceTransportType.DEFAULT}; |
157 | 161 | break; |
158 | 162 | case DeviceTransportType.MQTT: |
159 | - const mqttTransportConfiguration: MqttDeviceProfileTransportConfiguration = {}; | |
163 | + const mqttTransportConfiguration: MqttDeviceProfileTransportConfiguration = { | |
164 | + deviceTelemetryTopic: 'v1/devices/me/telemetry', | |
165 | + deviceAttributesTopic: 'v1/devices/me/attributes', | |
166 | + deviceRpcRequestTopic: 'v1/devices/me/rpc/request/', | |
167 | + deviceRpcResponseTopic: 'v1/devices/me/rpc/response/' | |
168 | + }; | |
160 | 169 | transportConfiguration = {...mqttTransportConfiguration, type: DeviceTransportType.MQTT}; |
161 | 170 | break; |
162 | 171 | case DeviceTransportType.LWM2M: | ... | ... |
... | ... | @@ -789,7 +789,17 @@ |
789 | 789 | "set-default-device-profile-title": "Are you sure you want to make the device profile '{{deviceProfileName}}' default?", |
790 | 790 | "set-default-device-profile-text": "After the confirmation the device profile will be marked as default and will be used for new devices with no profile specified.", |
791 | 791 | "no-device-profiles-found": "No device profiles found.", |
792 | - "create-new-device-profile": "Create a new one!" | |
792 | + "create-new-device-profile": "Create a new one!", | |
793 | + "mqtt-device-topic-filters": "MQTT device topic filters", | |
794 | + "support-level-wildcards": "Support single <code>(+)</code> and multi <code>(#)</code> level wildcards", | |
795 | + "telemetry-topic-filter": "Telemetry topic filter", | |
796 | + "telemetry-topic-filter-required": "Telemetry topic filter is required.", | |
797 | + "rpc-request-topic-filter": "RPC request topic filter", | |
798 | + "rpc-request-topic-filter-required": "RPC request topic filter is required.", | |
799 | + "attributes-topic-filter": "Attributes topic filter", | |
800 | + "attributes-topic-filter-required": "Attributes topic filter is required.", | |
801 | + "rpc-response-topic-filter": "RPC response topic filter", | |
802 | + "rpc-response-topic-filter-required": "RPC response topic filter is required." | |
793 | 803 | }, |
794 | 804 | "dialog": { |
795 | 805 | "close": "Close dialog" | ... | ... |