Showing
5 changed files
with
105 additions
and
10 deletions
@@ -16,9 +16,50 @@ | @@ -16,9 +16,50 @@ | ||
16 | 16 | ||
17 | --> | 17 | --> |
18 | <form [formGroup]="mqttDeviceProfileTransportConfigurationFormGroup" style="padding-bottom: 16px;"> | 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 | </form> | 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,11 +23,12 @@ import { | ||
23 | DeviceProfileTransportConfiguration, | 23 | DeviceProfileTransportConfiguration, |
24 | DeviceTransportType, MqttDeviceProfileTransportConfiguration | 24 | DeviceTransportType, MqttDeviceProfileTransportConfiguration |
25 | } from '@shared/models/device.models'; | 25 | } from '@shared/models/device.models'; |
26 | +import { isDefinedAndNotNull } from '../../../../../core/utils'; | ||
26 | 27 | ||
27 | @Component({ | 28 | @Component({ |
28 | selector: 'tb-mqtt-device-profile-transport-configuration', | 29 | selector: 'tb-mqtt-device-profile-transport-configuration', |
29 | templateUrl: './mqtt-device-profile-transport-configuration.component.html', | 30 | templateUrl: './mqtt-device-profile-transport-configuration.component.html', |
30 | - styleUrls: [], | 31 | + styleUrls: ['./mqtt-device-profile-transport-configuration.component.scss'], |
31 | providers: [{ | 32 | providers: [{ |
32 | provide: NG_VALUE_ACCESSOR, | 33 | provide: NG_VALUE_ACCESSOR, |
33 | useExisting: forwardRef(() => MqttDeviceProfileTransportConfigurationComponent), | 34 | useExisting: forwardRef(() => MqttDeviceProfileTransportConfigurationComponent), |
@@ -65,7 +66,12 @@ export class MqttDeviceProfileTransportConfigurationComponent implements Control | @@ -65,7 +66,12 @@ export class MqttDeviceProfileTransportConfigurationComponent implements Control | ||
65 | 66 | ||
66 | ngOnInit() { | 67 | ngOnInit() { |
67 | this.mqttDeviceProfileTransportConfigurationFormGroup = this.fb.group({ | 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 | this.mqttDeviceProfileTransportConfigurationFormGroup.valueChanges.subscribe(() => { | 76 | this.mqttDeviceProfileTransportConfigurationFormGroup.valueChanges.subscribe(() => { |
71 | this.updateModel(); | 77 | this.updateModel(); |
@@ -82,7 +88,9 @@ export class MqttDeviceProfileTransportConfigurationComponent implements Control | @@ -82,7 +88,9 @@ export class MqttDeviceProfileTransportConfigurationComponent implements Control | ||
82 | } | 88 | } |
83 | 89 | ||
84 | writeValue(value: MqttDeviceProfileTransportConfiguration | null): void { | 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 | private updateModel() { | 96 | private updateModel() { |
@@ -106,6 +106,10 @@ export interface DefaultDeviceProfileTransportConfiguration { | @@ -106,6 +106,10 @@ export interface DefaultDeviceProfileTransportConfiguration { | ||
106 | } | 106 | } |
107 | 107 | ||
108 | export interface MqttDeviceProfileTransportConfiguration { | 108 | export interface MqttDeviceProfileTransportConfiguration { |
109 | + deviceTelemetryTopic?: string; | ||
110 | + deviceAttributesTopic?: string; | ||
111 | + deviceRpcRequestTopic?: string; | ||
112 | + deviceRpcResponseTopic?: string; | ||
109 | [key: string]: any; | 113 | [key: string]: any; |
110 | } | 114 | } |
111 | 115 | ||
@@ -156,7 +160,12 @@ export function createDeviceProfileTransportConfiguration(type: DeviceTransportT | @@ -156,7 +160,12 @@ export function createDeviceProfileTransportConfiguration(type: DeviceTransportT | ||
156 | transportConfiguration = {...defaultTransportConfiguration, type: DeviceTransportType.DEFAULT}; | 160 | transportConfiguration = {...defaultTransportConfiguration, type: DeviceTransportType.DEFAULT}; |
157 | break; | 161 | break; |
158 | case DeviceTransportType.MQTT: | 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 | transportConfiguration = {...mqttTransportConfiguration, type: DeviceTransportType.MQTT}; | 169 | transportConfiguration = {...mqttTransportConfiguration, type: DeviceTransportType.MQTT}; |
161 | break; | 170 | break; |
162 | case DeviceTransportType.LWM2M: | 171 | case DeviceTransportType.LWM2M: |
@@ -789,7 +789,17 @@ | @@ -789,7 +789,17 @@ | ||
789 | "set-default-device-profile-title": "Are you sure you want to make the device profile '{{deviceProfileName}}' default?", | 789 | "set-default-device-profile-title": "Are you sure you want to make the device profile '{{deviceProfileName}}' default?", |
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.", | 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 | "no-device-profiles-found": "No device profiles found.", | 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 | "dialog": { | 804 | "dialog": { |
795 | "close": "Close dialog" | 805 | "close": "Close dialog" |