13 changed files with 1460 additions and 118 deletions
@ -0,0 +1,60 @@ |
|||||
|
<!-- |
||||
|
|
||||
|
Copyright © 2016-2023 The Thingsboard Authors |
||||
|
|
||||
|
Licensed under the Apache License, Version 2.0 (the "License"); |
||||
|
you may not use this file except in compliance with the License. |
||||
|
You may obtain a copy of the License at |
||||
|
|
||||
|
http://www.apache.org/licenses/LICENSE-2.0 |
||||
|
|
||||
|
Unless required by applicable law or agreed to in writing, software |
||||
|
distributed under the License is distributed on an "AS IS" BASIS, |
||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
|
See the License for the specific language governing permissions and |
||||
|
limitations under the License. |
||||
|
|
||||
|
--> |
||||
|
<div class="mat-subtitle-1 title">{{ 'gateway.rpc.templates-title' | translate }}</div> |
||||
|
<mat-expansion-panel hideToggle *ngFor="let template of rpcTemplates"> |
||||
|
<mat-expansion-panel-header> |
||||
|
<mat-panel-title> |
||||
|
{{template.name}} |
||||
|
</mat-panel-title> |
||||
|
<mat-panel-description> |
||||
|
<button mat-icon-button matTooltip="Delete" (click)="deleteTemplate($event)"> |
||||
|
<mat-icon class="material-icons">delete</mat-icon> |
||||
|
</button> |
||||
|
<button mat-icon-button matTooltip="Copy" (click)="copyTemplate($event)"> |
||||
|
<mat-icon class="material-icons">content_copy</mat-icon> |
||||
|
</button> |
||||
|
<button mat-icon-button matTooltip="Use" (click)="useTemplate($event)"> |
||||
|
<mat-icon class="material-icons">play_arrow</mat-icon> |
||||
|
</button> |
||||
|
</mat-panel-description> |
||||
|
</mat-expansion-panel-header> |
||||
|
|
||||
|
<ng-container |
||||
|
*ngFor="let config of template.config | keyvalue : originalOrder" |
||||
|
[ngTemplateOutlet]="RPCTemplateRef" |
||||
|
[ngTemplateOutletContext]="{ $implicit: config, padding: false }"> |
||||
|
</ng-container> |
||||
|
<ng-template #RPCTemplateRef let-config let-padding='padding'> |
||||
|
<div [fxLayout]="isObject(config.value) ? 'column': 'row'" |
||||
|
[fxLayoutAlign]="!isObject(config.value) ? 'space-between center' : ''" |
||||
|
[ngStyle]="{'padding-left': padding ? '16px': '0'}"> |
||||
|
<div class="template-key">{{config.key}}</div> |
||||
|
<div *ngIf="!isObject(config.value) else RPCObjectRow" |
||||
|
[ngClass]="{'boolean-true': config.value === true, |
||||
|
'boolean-false': config.value === false }"> |
||||
|
{{config.value}}</div> |
||||
|
<ng-template #RPCObjectRow> |
||||
|
<ng-container |
||||
|
*ngFor="let subConfig of config.value | keyvalue : originalOrder" |
||||
|
[ngTemplateOutlet]="RPCTemplateRef" |
||||
|
[ngTemplateOutletContext]="{ $implicit: subConfig, padding: true }"> |
||||
|
</ng-container> |
||||
|
</ng-template> |
||||
|
</div> |
||||
|
</ng-template> |
||||
|
</mat-expansion-panel> |
||||
@ -0,0 +1,79 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2023 The Thingsboard Authors |
||||
|
* |
||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
|
* you may not use this file except in compliance with the License. |
||||
|
* You may obtain a copy of the License at |
||||
|
* |
||||
|
* http://www.apache.org/licenses/LICENSE-2.0 |
||||
|
* |
||||
|
* Unless required by applicable law or agreed to in writing, software |
||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
|
* See the License for the specific language governing permissions and |
||||
|
* limitations under the License. |
||||
|
*/ |
||||
|
:host { |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
padding: 0; |
||||
|
|
||||
|
.title { |
||||
|
font-weight: 500; |
||||
|
} |
||||
|
|
||||
|
.template-key { |
||||
|
color: rgba(0, 0, 0, 0.38); |
||||
|
height: 32px; |
||||
|
line-height: 32px; |
||||
|
} |
||||
|
|
||||
|
.boolean-true, .boolean-false { |
||||
|
border-radius: 3px; |
||||
|
height: 32px; |
||||
|
line-height: 32px; |
||||
|
padding: 0 12px; |
||||
|
width: fit-content; |
||||
|
font-size: 14px; |
||||
|
text-transform: capitalize; |
||||
|
} |
||||
|
|
||||
|
.boolean-false { |
||||
|
color: #d12730; |
||||
|
background-color: rgba(209, 39, 48, 0.08); |
||||
|
} |
||||
|
|
||||
|
.boolean-true { |
||||
|
color: #198038; |
||||
|
background-color: rgba(25, 128, 56, 0.08); |
||||
|
} |
||||
|
|
||||
|
.mat-expansion-panel-header-description { |
||||
|
flex-direction: row-reverse; |
||||
|
align-items: center; |
||||
|
margin-right: 0; |
||||
|
|
||||
|
& > mat-icon { |
||||
|
margin-left: 15px; |
||||
|
color: rgba(0, 0, 0, 0.38); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.mat-expansion-panel-header { |
||||
|
padding: 0 0 0 12px; |
||||
|
|
||||
|
&.mat-expansion-panel-header.mat-expanded { |
||||
|
height: 48px; |
||||
|
} |
||||
|
|
||||
|
.mat-content.mat-content-hide-toggle { |
||||
|
margin-right: 0; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
} |
||||
|
|
||||
|
|
||||
@ -0,0 +1,81 @@ |
|||||
|
///
|
||||
|
/// Copyright © 2016-2023 The Thingsboard Authors
|
||||
|
///
|
||||
|
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
/// you may not use this file except in compliance with the License.
|
||||
|
/// You may obtain a copy of the License at
|
||||
|
///
|
||||
|
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
///
|
||||
|
/// Unless required by applicable law or agreed to in writing, software
|
||||
|
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
|
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
/// See the License for the specific language governing permissions and
|
||||
|
/// limitations under the License.
|
||||
|
///
|
||||
|
|
||||
|
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; |
||||
|
import { ConnectorType, RPCTemplate } from '@home/components/widget/lib/gateway/gateway-widget.models'; |
||||
|
import { TranslateService } from '@ngx-translate/core'; |
||||
|
import { KeyValue } from '@angular/common'; |
||||
|
|
||||
|
@Component({ |
||||
|
selector: 'tb-gateway-service-rpc-connector-templates', |
||||
|
templateUrl: './gateway-service-rpc-connector-templates.component.html', |
||||
|
styleUrls: ['./gateway-service-rpc-connector-templates.component.scss'] |
||||
|
}) |
||||
|
export class GatewayServiceRPCConnectorTemplatesComponent implements OnInit { |
||||
|
|
||||
|
@Input() |
||||
|
connectorType: ConnectorType; |
||||
|
|
||||
|
@Output() |
||||
|
saveTemplate: EventEmitter<any> = new EventEmitter(); |
||||
|
|
||||
|
rpcTemplates: Array<RPCTemplate> = []; |
||||
|
|
||||
|
constructor(private translate: TranslateService) { |
||||
|
this.rpcTemplates.push( |
||||
|
{ |
||||
|
name: 'Test Template', |
||||
|
config: { |
||||
|
fieldString: 'string', |
||||
|
fieldNumber: 666, |
||||
|
fieldBool: true, |
||||
|
fieldArray: [111, 222, 333, "String", "444"], |
||||
|
fieldObj: { |
||||
|
subKey1: 'dasd', |
||||
|
subKey2: 666, |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
) |
||||
|
} |
||||
|
|
||||
|
|
||||
|
ngOnInit() { |
||||
|
|
||||
|
} |
||||
|
|
||||
|
public useTemplate($event: Event): void { |
||||
|
$event.stopPropagation(); |
||||
|
console.log("useTemplate") |
||||
|
} |
||||
|
|
||||
|
public copyTemplate($event: Event): void { |
||||
|
$event.stopPropagation(); |
||||
|
console.log("copyTemplate") |
||||
|
} |
||||
|
|
||||
|
public deleteTemplate($event: Event): void { |
||||
|
$event.stopPropagation(); |
||||
|
console.log("deleteTemplate") |
||||
|
} |
||||
|
|
||||
|
public originalOrder = (a: KeyValue<string, any>, b: KeyValue<string, any>): number => { |
||||
|
return 0; |
||||
|
} |
||||
|
public isObject(value: any) { |
||||
|
return value !== null && typeof value === 'object' && !Array.isArray(value); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,531 @@ |
|||||
|
<!-- |
||||
|
|
||||
|
Copyright © 2016-2023 The Thingsboard Authors |
||||
|
|
||||
|
Licensed under the Apache License, Version 2.0 (the "License"); |
||||
|
you may not use this file except in compliance with the License. |
||||
|
You may obtain a copy of the License at |
||||
|
|
||||
|
http://www.apache.org/licenses/LICENSE-2.0 |
||||
|
|
||||
|
Unless required by applicable law or agreed to in writing, software |
||||
|
distributed under the License is distributed on an "AS IS" BASIS, |
||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
|
See the License for the specific language governing permissions and |
||||
|
limitations under the License. |
||||
|
|
||||
|
--> |
||||
|
<div fxLayout="column" class="command-form" [formGroup]="commandForm"> |
||||
|
<div class="mat-subtitle-1 title">{{ 'gateway.rpc.title' | translate: {type: gatewayConnectorDefaultTypesTranslates.get(connectorType)} }}</div> |
||||
|
<ng-template [ngIf]="connectorType"> |
||||
|
<ng-container [ngSwitch]="connectorType"> |
||||
|
<ng-template [ngSwitchCase]="ConnectorType.MQTT"> |
||||
|
<mat-form-field> |
||||
|
<mat-label>{{ 'gateway.rpc.method-filter' | translate }}</mat-label> |
||||
|
<input matInput formControlName="methodFilter" |
||||
|
placeholder="echo"/> |
||||
|
</mat-form-field> |
||||
|
<mat-form-field> |
||||
|
<mat-label>{{ 'gateway.rpc.request-topic-expression' | translate }}</mat-label> |
||||
|
<input matInput formControlName="requestTopicExpression" |
||||
|
placeholder="sensor/${deviceName}/request/${methodName}/${requestId}"/> |
||||
|
</mat-form-field> |
||||
|
<mat-form-field> |
||||
|
<mat-label>{{ 'gateway.rpc.response-topic-expression' | translate }}</mat-label> |
||||
|
<input matInput formControlName="responseTopicExpression" |
||||
|
placeholder="sensor/${deviceName}/response/${methodName}/${requestId}"/> |
||||
|
</mat-form-field> |
||||
|
<mat-form-field> |
||||
|
<mat-label>{{ 'gateway.rpc.response-timeout' | translate }}</mat-label> |
||||
|
<input matInput formControlName="responseTimeout" type="number" |
||||
|
placeholder="10000" min="10" step="1"/> |
||||
|
</mat-form-field> |
||||
|
<mat-form-field> |
||||
|
<mat-label>{{ 'gateway.rpc.value-expression' | translate }}</mat-label> |
||||
|
<input matInput formControlName="valueExpression" |
||||
|
placeholder="${params}"/> |
||||
|
</mat-form-field> |
||||
|
</ng-template> |
||||
|
|
||||
|
<ng-template [ngSwitchCase]="ConnectorType.MODBUS"> |
||||
|
<mat-form-field> |
||||
|
<mat-label>{{ 'gateway.rpc.tag' | translate }}</mat-label> |
||||
|
<input matInput formControlName="tag" placeholder="setValue"/> |
||||
|
</mat-form-field> |
||||
|
<div fxFlex fxLayout="row" fxLayoutGap="10px"> |
||||
|
<mat-form-field fxFlex="50" class="mat-block"> |
||||
|
<mat-label>{{ 'gateway.rpc.type' | translate }}</mat-label> |
||||
|
<mat-select formControlName="type"> |
||||
|
<mat-option *ngFor="let type of modbusCommandTypes" [value]="type"> |
||||
|
{{ type }} |
||||
|
</mat-option> |
||||
|
</mat-select> |
||||
|
</mat-form-field> |
||||
|
<mat-form-field fxFlex="50" class="mat-block"> |
||||
|
<mat-label>{{ 'gateway.rpc.function-code' | translate }}</mat-label> |
||||
|
<mat-select formControlName="functionCode"> |
||||
|
<mat-option *ngFor="let code of codesArray" [value]="code"> |
||||
|
{{ code }} |
||||
|
</mat-option> |
||||
|
</mat-select> |
||||
|
</mat-form-field> |
||||
|
</div> |
||||
|
<div fxFlex fxLayout="row" fxLayoutGap="10px"> |
||||
|
<mat-form-field fxFlex="50"> |
||||
|
<mat-label>{{ 'gateway.rpc.address' | translate }}</mat-label> |
||||
|
<input matInput formControlName="address" type="number" min="0" |
||||
|
placeholder="1" step="1"/> |
||||
|
</mat-form-field> |
||||
|
<mat-form-field fxFlex="50"> |
||||
|
<mat-label>{{ 'gateway.rpc.objects-count' | translate }}</mat-label> |
||||
|
<input matInput formControlName="objectsCount" type="number" min="0" |
||||
|
placeholder="31" step="1"/> |
||||
|
</mat-form-field> |
||||
|
</div> |
||||
|
</ng-template> |
||||
|
|
||||
|
<ng-template [ngSwitchCase]="ConnectorType.BACNET"> |
||||
|
<mat-form-field> |
||||
|
<mat-label>{{ 'gateway.rpc.method-rpc' | translate }}</mat-label> |
||||
|
<input matInput formControlName="method" placeholder="set_state"/> |
||||
|
</mat-form-field> |
||||
|
<mat-form-field class="mat-block"> |
||||
|
<mat-label>{{ 'gateway.rpc.request-type' | translate }}</mat-label> |
||||
|
<mat-select formControlName="requestType"> |
||||
|
<mat-option *ngFor="let type of bACnetRequestTypes" [value]="type"> |
||||
|
{{bACnetRequestTypesTranslates.get(type) | translate}} |
||||
|
</mat-option> |
||||
|
</mat-select> |
||||
|
</mat-form-field> |
||||
|
<mat-form-field> |
||||
|
<mat-label>{{ 'gateway.rpc.request-timeout' | translate }}</mat-label> |
||||
|
<input matInput formControlName="requestTimeout" type="number" |
||||
|
min="10" step="1" placeholder="1000"/> |
||||
|
</mat-form-field> |
||||
|
<div fxFlex fxLayout="row" fxLayoutGap="10px"> |
||||
|
<mat-form-field fxFlex="50" class="mat-block"> |
||||
|
<mat-label>{{ 'gateway.rpc.object-type' | translate }}</mat-label> |
||||
|
<mat-select formControlName="objectType"> |
||||
|
<mat-option *ngFor="let type of bACnetObjectTypes" [value]="type"> |
||||
|
{{bACnetObjectTypesTranslates.get(type) | translate}} |
||||
|
</mat-option> |
||||
|
</mat-select> |
||||
|
</mat-form-field> |
||||
|
<mat-form-field fxFlex="50"> |
||||
|
<mat-label>{{ 'gateway.rpc.identifier' | translate }}</mat-label> |
||||
|
<input matInput formControlName="identifier" type="number" |
||||
|
min="1" step="1" placeholder="1"/> |
||||
|
</mat-form-field> |
||||
|
</div> |
||||
|
<mat-form-field class="mat-block"> |
||||
|
<mat-label>{{ 'gateway.rpc.property-id' | translate }}</mat-label> |
||||
|
<input matInput formControlName="propertyId" placeholder="presentValue"/> |
||||
|
</mat-form-field> |
||||
|
</ng-template> |
||||
|
|
||||
|
<ng-template [ngSwitchCase]="ConnectorType.BLE"> |
||||
|
<mat-form-field> |
||||
|
<mat-label>{{ 'gateway.rpc.method-rpc' | translate }}</mat-label> |
||||
|
<input matInput formControlName="methodRPC" placeholder="rpcMethod1"/> |
||||
|
</mat-form-field> |
||||
|
<mat-form-field> |
||||
|
<mat-label>{{ 'gateway.rpc.characteristic-uuid' | translate }}</mat-label> |
||||
|
<input matInput formControlName="characteristicUUID" placeholder="00002A00-0000-1000-8000-00805F9B34FB"/> |
||||
|
</mat-form-field> |
||||
|
<mat-form-field class="mat-block"> |
||||
|
<mat-label>{{ 'gateway.rpc.method-processing' | translate }}</mat-label> |
||||
|
<mat-select formControlName="methodProcessing"> |
||||
|
<mat-option *ngFor="let type of bLEMethods" [value]="type"> |
||||
|
{{bLEMethodsTranslates.get(type) | translate}} |
||||
|
</mat-option> |
||||
|
</mat-select> |
||||
|
</mat-form-field> |
||||
|
<mat-slide-toggle class="mat-slide" formControlName="withResponse"> |
||||
|
{{ 'gateway.rpc.with-response' | translate }} |
||||
|
</mat-slide-toggle> |
||||
|
</ng-template> |
||||
|
|
||||
|
<ng-template [ngSwitchCase]="ConnectorType.CAN"> |
||||
|
<mat-form-field> |
||||
|
<mat-label>{{ 'gateway.rpc.method-rpc' | translate }}</mat-label> |
||||
|
<input matInput formControlName="method" placeholder="sendSameData"/> |
||||
|
</mat-form-field> |
||||
|
<mat-form-field> |
||||
|
<mat-label>{{ 'gateway.rpc.node-id' | translate }}</mat-label> |
||||
|
<input matInput formControlName="nodeID" type="number" placeholder="4" min="0" step="1"/> |
||||
|
</mat-form-field> |
||||
|
<mat-slide-toggle class="mat-slide margin" formControlName="isExtendedID"> |
||||
|
{{ 'gateway.rpc.is-extended-id' | translate }} |
||||
|
</mat-slide-toggle> |
||||
|
<mat-slide-toggle class="mat-slide margin" formControlName="isFD"> |
||||
|
{{ 'gateway.rpc.is-fd' | translate }} |
||||
|
</mat-slide-toggle> |
||||
|
<mat-slide-toggle class="mat-slide margin" formControlName="bitrateSwitch"> |
||||
|
{{ 'gateway.rpc.bitrate-switch' | translate }} |
||||
|
</mat-slide-toggle> |
||||
|
<div fxFlex fxLayout="row" fxLayoutGap="10px"> |
||||
|
<mat-form-field fxFlex="50"> |
||||
|
<mat-label>{{ 'gateway.rpc.data-length' | translate }}</mat-label> |
||||
|
<input matInput formControlName="dataLength" type="number" placeholder="2" min="1" step="1"/> |
||||
|
</mat-form-field> |
||||
|
<mat-form-field class="mat-block" fxFlex="50"> |
||||
|
<mat-label>{{ 'gateway.rpc.data-byte-order' | translate }}</mat-label> |
||||
|
<mat-select formControlName="dataByteorder"> |
||||
|
<mat-option *ngFor="let order of cANByteOrders" [value]="order"> |
||||
|
{{ order | translate }} |
||||
|
</mat-option> |
||||
|
</mat-select> |
||||
|
</mat-form-field> |
||||
|
</div> |
||||
|
<div fxFlex fxLayout="row" fxLayoutGap="10px"> |
||||
|
<mat-form-field fxFlex="50"> |
||||
|
<mat-label>{{ 'gateway.rpc.data-before' | translate }}</mat-label> |
||||
|
<input matInput formControlName="dataBefore" placeholder="00AA"/> |
||||
|
</mat-form-field> |
||||
|
<mat-form-field fxFlex="50"> |
||||
|
<mat-label>{{ 'gateway.rpc.data-after' | translate }}</mat-label> |
||||
|
<input matInput formControlName="dataAfter" placeholder="0102"/> |
||||
|
</mat-form-field> |
||||
|
</div> |
||||
|
<mat-form-field> |
||||
|
<mat-label>{{ 'gateway.rpc.data-in-hex' | translate }}</mat-label> |
||||
|
<input matInput formControlName="dataInHEX" |
||||
|
placeholder="aa bb cc dd ee ff aa bb aa bb cc d ee ff"/> |
||||
|
</mat-form-field> |
||||
|
<mat-form-field> |
||||
|
<mat-label>{{ 'gateway.rpc.data-expression' | translate }}</mat-label> |
||||
|
<input matInput formControlName="dataExpression" |
||||
|
placeholder="userSpeed if maxAllowedSpeed > userSpeed else maxAllowedSpeed"/> |
||||
|
</mat-form-field> |
||||
|
</ng-template> |
||||
|
|
||||
|
|
||||
|
<ng-template [ngSwitchCase]="ConnectorType.FTP"> |
||||
|
<mat-form-field> |
||||
|
<mat-label>{{ 'gateway.rpc.method-filter' | translate }}</mat-label> |
||||
|
<input matInput formControlName="methodFilter" placeholder="read"/> |
||||
|
</mat-form-field> |
||||
|
<mat-form-field> |
||||
|
<mat-label>{{ 'gateway.rpc.value-expression' | translate }}</mat-label> |
||||
|
<input matInput formControlName="valueExpression" placeholder="${params}"/> |
||||
|
</mat-form-field> |
||||
|
</ng-template> |
||||
|
|
||||
|
<ng-template [ngSwitchCase]="ConnectorType.OCPP"> |
||||
|
<mat-form-field> |
||||
|
<mat-label>{{ 'gateway.rpc.method-rpc' | translate }}</mat-label> |
||||
|
<input matInput formControlName="methodRPC" placeholder="rpc1"/> |
||||
|
</mat-form-field> |
||||
|
<mat-form-field> |
||||
|
<mat-label>{{ 'gateway.rpc.value-expression' | translate }}</mat-label> |
||||
|
<input matInput formControlName="valueExpression" placeholder="${params}"/> |
||||
|
</mat-form-field> |
||||
|
<mat-slide-toggle class="mat-slide margin" formControlName="withResponse"> |
||||
|
{{ 'gateway.rpc.with-response' | translate }} |
||||
|
</mat-slide-toggle> |
||||
|
</ng-template> |
||||
|
|
||||
|
<ng-template [ngSwitchCase]="ConnectorType.SOCKET"> |
||||
|
<mat-form-field> |
||||
|
<mat-label>{{ 'gateway.rpc.method-rpc' | translate }}</mat-label> |
||||
|
<input matInput formControlName="methodRPC" placeholder="rpcMethod1"/> |
||||
|
</mat-form-field> |
||||
|
<mat-form-field class="mat-block"> |
||||
|
<mat-label>{{ 'gateway.rpc.method-processing' | translate }}</mat-label> |
||||
|
<mat-select formControlName="methodProcessing"> |
||||
|
<mat-option *ngFor="let method of socketMethodProcessings" [value]="method"> |
||||
|
{{ SocketMethodProcessingsTranslates.get(method) | translate }} |
||||
|
</mat-option> |
||||
|
</mat-select> |
||||
|
</mat-form-field> |
||||
|
<mat-form-field class="mat-block"> |
||||
|
<mat-label>{{ 'gateway.rpc.encoding' | translate }}</mat-label> |
||||
|
<mat-select formControlName="encoding"> |
||||
|
<mat-option *ngFor="let encoding of socketEncodings" [value]="encoding"> |
||||
|
{{ encoding }} |
||||
|
</mat-option> |
||||
|
</mat-select> |
||||
|
</mat-form-field> |
||||
|
<mat-slide-toggle class="mat-slide margin" formControlName="withResponse"> |
||||
|
{{ 'gateway.rpc.with-response' | translate }} |
||||
|
</mat-slide-toggle> |
||||
|
</ng-template> |
||||
|
|
||||
|
<ng-template [ngSwitchCase]="ConnectorType.XMPP"> |
||||
|
<mat-form-field> |
||||
|
<mat-label>{{ 'gateway.rpc.method-rpc' | translate }}</mat-label> |
||||
|
<input matInput formControlName="methodRPC" placeholder="rpc1"/> |
||||
|
</mat-form-field> |
||||
|
<mat-form-field> |
||||
|
<mat-label>{{ 'gateway.rpc.value-expression' | translate }}</mat-label> |
||||
|
<input matInput formControlName="valueExpression" placeholder="${params}"/> |
||||
|
</mat-form-field> |
||||
|
<mat-slide-toggle class="mat-slide margin" formControlName="withResponse"> |
||||
|
{{ 'gateway.rpc.with-response' | translate }} |
||||
|
</mat-slide-toggle> |
||||
|
</ng-template> |
||||
|
|
||||
|
<ng-template [ngSwitchCase]="ConnectorType.SNMP"> |
||||
|
<mat-form-field> |
||||
|
<mat-label>{{ 'gateway.rpc.request-filter' | translate }}</mat-label> |
||||
|
<input matInput formControlName="requestFilter" placeholder="setData"/> |
||||
|
</mat-form-field> |
||||
|
<mat-form-field class="mat-block"> |
||||
|
<mat-label>{{ 'gateway.rpc.method' | translate }}</mat-label> |
||||
|
<mat-select formControlName="method"> |
||||
|
<mat-option *ngFor="let method of sNMPMethods" [value]="method"> |
||||
|
{{ SNMPMethodsTranslations.get(method) | translate }} |
||||
|
</mat-option> |
||||
|
</mat-select> |
||||
|
</mat-form-field> |
||||
|
<fieldset class="fields border" fxLayout="column" fxLayoutGap="10px" formArrayName="oid"> |
||||
|
<span class="fields-label">{{ 'gateway.rpc.oids' | translate }}*</span> |
||||
|
<div fxFlex fxLayout="row" fxLayoutGap="10px" fxLayoutAlign="center center" |
||||
|
*ngFor="let control of getFormArrayControls('oid'); let i = index"> |
||||
|
<mat-form-field appearance="outline" fxFlex> |
||||
|
<input matInput [formControl]="control"/> |
||||
|
</mat-form-field> |
||||
|
<mat-icon style="cursor:pointer;" |
||||
|
fxFlex="30px" |
||||
|
(click)="removeSNMPoid(i)" |
||||
|
matTooltip="{{ 'gateway.rpc.remove' | translate }}">delete |
||||
|
</mat-icon> |
||||
|
</div> |
||||
|
<button mat-raised-button |
||||
|
fxFlexAlign="start" |
||||
|
(click)="addSNMPoid()"> |
||||
|
{{ 'gateway.rpc.add-oid' | translate }} |
||||
|
</button> |
||||
|
</fieldset> |
||||
|
</ng-template> |
||||
|
|
||||
|
<ng-template [ngSwitchCase]="ConnectorType.REST"> |
||||
|
<mat-form-field> |
||||
|
<mat-label>{{ 'gateway.rpc.method-filter' | translate }}</mat-label> |
||||
|
<input matInput formControlName="methodFilter" placeholder="post_attributes"/> |
||||
|
</mat-form-field> |
||||
|
<div fxFlex fxLayout="row" fxLayoutGap="10px"> |
||||
|
<mat-form-field class="mat-block" fxFlex="33"> |
||||
|
<mat-label>{{ 'gateway.rpc.http-method' | translate }}</mat-label> |
||||
|
<mat-select formControlName="HTTPMethod"> |
||||
|
<mat-option *ngFor="let method of hTTPMethods" [value]="method"> |
||||
|
{{ method }} |
||||
|
</mat-option> |
||||
|
</mat-select> |
||||
|
</mat-form-field> |
||||
|
<mat-form-field fxFlex> |
||||
|
<mat-label>{{ 'gateway.rpc.request-url' | translate }}</mat-label> |
||||
|
<input matInput formControlName="requestUrlExpression" |
||||
|
placeholder="http://127.0.0.1:5000/my_devices"/> |
||||
|
</mat-form-field> |
||||
|
</div> |
||||
|
<div fxFlex fxLayout="row" fxLayoutGap="10px"> |
||||
|
<mat-form-field fxFlex="33"> |
||||
|
<mat-label>{{ 'gateway.rpc.response-timeout' | translate }}</mat-label> |
||||
|
<input matInput formControlName="responseTimeout" type="number" |
||||
|
step="1" min="10" placeholder="10"/> |
||||
|
</mat-form-field> |
||||
|
<mat-form-field fxFlex> |
||||
|
<mat-label>{{ 'gateway.rpc.timeout' | translate }}</mat-label> |
||||
|
<input matInput formControlName="timeout" type="number" |
||||
|
step="1" min="10" placeholder="1000"/> |
||||
|
</mat-form-field> |
||||
|
<mat-form-field fxFlex> |
||||
|
<mat-label>{{ 'gateway.rpc.tries' | translate }}</mat-label> |
||||
|
<input matInput formControlName="tries" type="number" |
||||
|
step="1" min="1" placeholder="3"/> |
||||
|
</mat-form-field> |
||||
|
</div> |
||||
|
<mat-form-field> |
||||
|
<mat-label>{{ 'gateway.rpc.value-expression' | translate }}</mat-label> |
||||
|
<input matInput formControlName="valueExpression" placeholder="${params}"/> |
||||
|
</mat-form-field> |
||||
|
<fieldset class="fields border" fxLayout="column" fxLayoutGap="10px" formArrayName="httpHeaders"> |
||||
|
<span class="fields-label">{{ 'gateway.rpc.http-headers' | translate }}</span> |
||||
|
<div class="border" fxLayout="column" fxLayoutGap="10px" *ngIf="getFormArrayControls('httpHeaders').length"> |
||||
|
<div fxLayout="row" fxLayoutGap="10px" fxLayoutAlign="center center"> |
||||
|
<span fxFlex class="title">{{ 'gateway.rpc.header-name' | translate }}</span> |
||||
|
<span fxFlex class="title">{{ 'gateway.rpc.value' | translate }}</span> |
||||
|
<span fxFlex="30px"></span> |
||||
|
</div> |
||||
|
<mat-divider></mat-divider> |
||||
|
<div fxFlex fxLayout="row" fxLayoutGap="10px" fxLayoutAlign="center center" |
||||
|
*ngFor="let control of getFormArrayControls('httpHeaders'); let i = index"> |
||||
|
<ng-container [formGroupName]="i"> |
||||
|
<mat-form-field appearance="outline" fxFlex> |
||||
|
<input matInput formControlName="headerName"/> |
||||
|
</mat-form-field> |
||||
|
<mat-form-field appearance="outline" fxFlex> |
||||
|
<input matInput formControlName="value" placeholder="application/json"/> |
||||
|
</mat-form-field> |
||||
|
<mat-icon style="cursor:pointer;" |
||||
|
fxFlex="30px" |
||||
|
(click)="removeHTTPHeader(i)" |
||||
|
matTooltip="{{ 'gateway.rpc.remove' | translate }}">delete |
||||
|
</mat-icon> |
||||
|
</ng-container> |
||||
|
</div> |
||||
|
</div> |
||||
|
<button mat-raised-button |
||||
|
fxFlexAlign="start" |
||||
|
(click)="addHTTPHeader()"> |
||||
|
{{ 'gateway.rpc.add-header' | translate }} |
||||
|
</button> |
||||
|
</fieldset> |
||||
|
<fieldset class="fields border" fxLayout="column" fxLayoutGap="10px" formArrayName="security"> |
||||
|
<span class="fields-label">{{ 'gateway.rpc.security' | translate }}</span> |
||||
|
<div class="border" fxLayout="column" fxLayoutGap="10px" *ngIf="getFormArrayControls('security').length"> |
||||
|
<div fxLayout="row" fxLayoutGap="10px" fxLayoutAlign="center center"> |
||||
|
<span fxFlex class="title">{{ 'gateway.rpc.security-name' | translate }}</span> |
||||
|
<span fxFlex class="title">{{ 'gateway.rpc.value' | translate }}</span> |
||||
|
<span fxFlex="30px"></span> |
||||
|
</div> |
||||
|
<mat-divider></mat-divider> |
||||
|
<div fxFlex fxLayout="row" fxLayoutGap="10px" fxLayoutAlign="center center" |
||||
|
*ngFor="let control of getFormArrayControls('security'); let i = index"> |
||||
|
<ng-container [formGroupName]="i"> |
||||
|
<mat-form-field appearance="outline" fxFlex> |
||||
|
<input matInput formControlName="securityName"/> |
||||
|
</mat-form-field> |
||||
|
<mat-form-field appearance="outline" fxFlex> |
||||
|
<input matInput formControlName="value" placeholder="anonymous"/> |
||||
|
</mat-form-field> |
||||
|
<mat-icon style="cursor:pointer;" |
||||
|
fxFlex="30px" |
||||
|
(click)="removeHTTPSecurity(i)" |
||||
|
matTooltip="{{ 'gateway.rpc.remove' | translate }}">delete |
||||
|
</mat-icon> |
||||
|
</ng-container> |
||||
|
</div> |
||||
|
</div> |
||||
|
<button mat-raised-button |
||||
|
fxFlexAlign="start" |
||||
|
(click)="addHTTPSecurity()"> |
||||
|
{{ 'gateway.rpc.add-security' | translate }} |
||||
|
</button> |
||||
|
</fieldset> |
||||
|
</ng-template> |
||||
|
|
||||
|
<ng-template [ngSwitchCase]="ConnectorType.REQUEST"> |
||||
|
<mat-form-field> |
||||
|
<mat-label>{{ 'gateway.rpc.method-filter' | translate }}</mat-label> |
||||
|
<input matInput formControlName="methodFilter" placeholder="echo"/> |
||||
|
</mat-form-field> |
||||
|
<div fxFlex fxLayout="row" fxLayoutGap="10px"> |
||||
|
<mat-form-field class="mat-block" fxFlex="33"> |
||||
|
<mat-label>{{ 'gateway.rpc.method' | translate }}</mat-label> |
||||
|
<mat-select formControlName="httpMethod"> |
||||
|
<mat-option *ngFor="let method of hTTPMethods" [value]="method"> |
||||
|
{{ method }} |
||||
|
</mat-option> |
||||
|
</mat-select> |
||||
|
</mat-form-field> |
||||
|
<mat-form-field fxFlex> |
||||
|
<mat-label>{{ 'gateway.rpc.request-url' | translate }}</mat-label> |
||||
|
<input matInput formControlName="requestUrlExpression" placeholder="http://127.0.0.1:5000/my_devices"/> |
||||
|
</mat-form-field> |
||||
|
</div> |
||||
|
<div fxFlex fxLayout="row" fxLayoutGap="10px"> |
||||
|
<mat-form-field fxFlex="33"> |
||||
|
<mat-label>{{ 'gateway.rpc.response-timeout' | translate }}</mat-label> |
||||
|
<input matInput formControlName="responseTimeout" type="number" |
||||
|
step="1" min="10" placeholder="10"/> |
||||
|
</mat-form-field> |
||||
|
<mat-form-field fxFlex> |
||||
|
<mat-label>{{ 'gateway.rpc.timeout' | translate }}</mat-label> |
||||
|
<input matInput formControlName="timeout" type="number" |
||||
|
step="1" min="10" placeholder="10"/> |
||||
|
</mat-form-field> |
||||
|
<mat-form-field fxFlex> |
||||
|
<mat-label>{{ 'gateway.rpc.tries' | translate }}</mat-label> |
||||
|
<input matInput formControlName="tries" type="number" |
||||
|
step="1" min="1" placeholder="1"/> |
||||
|
</mat-form-field> |
||||
|
</div> |
||||
|
<mat-form-field> |
||||
|
<mat-label>{{ 'gateway.rpc.request-value-expression' | translate }}</mat-label> |
||||
|
<input matInput formControlName="requestValueExpression" placeholder="${params}"/> |
||||
|
</mat-form-field> |
||||
|
<mat-form-field> |
||||
|
<mat-label>{{ 'gateway.rpc.response-value-expression' | translate }}</mat-label> |
||||
|
<input matInput formControlName="responseValueExpression" placeholder="${temp}"/> |
||||
|
</mat-form-field> |
||||
|
<fieldset class="fields border" fxLayout="column" fxLayoutGap="10px" formArrayName="httpHeaders"> |
||||
|
<span class="fields-label">{{ 'gateway.rpc.http-headers' | translate }}</span> |
||||
|
<div class="border" fxLayout="column" fxLayoutGap="10px" *ngIf="getFormArrayControls('httpHeaders').length"> |
||||
|
<div fxLayout="row" fxLayoutGap="10px" fxLayoutAlign="center center"> |
||||
|
<span fxFlex class="title">{{ 'gateway.rpc.header-name' | translate }}</span> |
||||
|
<span fxFlex class="title">{{ 'gateway.rpc.value' | translate }}</span> |
||||
|
<span fxFlex="30px"></span> |
||||
|
</div> |
||||
|
<mat-divider></mat-divider> |
||||
|
<div fxFlex fxLayout="row" fxLayoutGap="10px" fxLayoutAlign="center center" |
||||
|
*ngFor="let control of getFormArrayControls('httpHeaders'); let i = index"> |
||||
|
<ng-container [formGroupName]="i"> |
||||
|
<mat-form-field appearance="outline" fxFlex> |
||||
|
<input matInput formControlName="headerName" placeholder="{{ 'gateway.rpc.set' | translate }}"/> |
||||
|
</mat-form-field> |
||||
|
<mat-form-field appearance="outline" fxFlex> |
||||
|
<input matInput formControlName="value"/> |
||||
|
</mat-form-field> |
||||
|
<mat-icon style="cursor:pointer;" |
||||
|
fxFlex="30px" |
||||
|
(click)="removeHTTPHeader(i)" |
||||
|
matTooltip="{{ 'gateway.rpc.remove' | translate }}">delete |
||||
|
</mat-icon> |
||||
|
</ng-container> |
||||
|
</div> |
||||
|
</div> |
||||
|
<button mat-raised-button |
||||
|
fxFlexAlign="start" |
||||
|
(click)="addHTTPHeader()"> |
||||
|
{{ 'gateway.rpc.add-header' | translate }} |
||||
|
</button> |
||||
|
</fieldset> |
||||
|
</ng-template> |
||||
|
|
||||
|
<ng-template [ngSwitchCase]="ConnectorType.OPCUA_ASYNCIO"> |
||||
|
<ng-container *ngTemplateOutlet="OPCUAForm"></ng-container> |
||||
|
</ng-template> |
||||
|
<ng-template [ngSwitchCase]="ConnectorType.OPCUA" #OPCUAForm> |
||||
|
<mat-form-field> |
||||
|
<mat-label>{{ 'gateway.rpc.method' | translate }}</mat-label> |
||||
|
<input matInput formControlName="method" placeholder="multiply"/> |
||||
|
</mat-form-field> |
||||
|
<fieldset class="fields border" fxLayout="column" fxLayoutGap="10px" formArrayName="arguments"> |
||||
|
<span class="fields-label">{{ 'gateway.rpc.arguments' | translate }}</span> |
||||
|
<div fxFlex fxLayout="row" fxLayoutGap="10px" fxLayoutAlign="center center" |
||||
|
*ngFor="let control of getFormArrayControls('arguments'); let i = index"> |
||||
|
<mat-form-field appearance="outline" fxFlex> |
||||
|
<input matInput [formControl]="control"/> |
||||
|
</mat-form-field> |
||||
|
|
||||
|
<mat-icon style="cursor:pointer;" |
||||
|
fxFlex="30px" |
||||
|
(click)="removeOCPUAArguments(i)" |
||||
|
matTooltip="{{ 'gateway.rpc.remove' | translate }}">delete |
||||
|
</mat-icon> |
||||
|
</div> |
||||
|
<button mat-raised-button |
||||
|
fxFlexAlign="start" |
||||
|
(click)="addOCPUAArguments()"> |
||||
|
{{ 'gateway.rpc.add-argument' | translate }} |
||||
|
</button> |
||||
|
</fieldset> |
||||
|
</ng-template> |
||||
|
</ng-container> |
||||
|
</ng-template> |
||||
|
<div class="template-actions" fxFlex fxLayout="row" fxLayoutAlign="end center" fxLayoutGap="10px"> |
||||
|
<button mat-raised-button |
||||
|
(click)="sendCommand.emit()" |
||||
|
[disabled]="commandForm.invalid"> |
||||
|
{{ 'gateway.rpc-command-save-template' | translate }} |
||||
|
</button> |
||||
|
<button mat-raised-button |
||||
|
color="primary" |
||||
|
(click)="sendCommand.emit()" |
||||
|
[disabled]="commandForm.invalid"> |
||||
|
{{ 'gateway.rpc-command-send' | translate }} |
||||
|
</button> |
||||
|
</div> |
||||
|
</div> |
||||
@ -0,0 +1,85 @@ |
|||||
|
/** |
||||
|
* Copyright © 2016-2023 The Thingsboard Authors |
||||
|
* |
||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
|
* you may not use this file except in compliance with the License. |
||||
|
* You may obtain a copy of the License at |
||||
|
* |
||||
|
* http://www.apache.org/licenses/LICENSE-2.0 |
||||
|
* |
||||
|
* Unless required by applicable law or agreed to in writing, software |
||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
|
* See the License for the specific language governing permissions and |
||||
|
* limitations under the License. |
||||
|
*/ |
||||
|
:host { |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
padding: 0; |
||||
|
|
||||
|
.title { |
||||
|
font-weight: 500; |
||||
|
} |
||||
|
|
||||
|
.command-form { |
||||
|
flex-wrap: nowrap; |
||||
|
|
||||
|
& > button { |
||||
|
margin-top: 10px; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.mat-mdc-slide-toggle.margin { |
||||
|
margin-bottom: 10px; |
||||
|
margin-left: 10px; |
||||
|
} |
||||
|
|
||||
|
.fields { |
||||
|
|
||||
|
::ng-deep .mat-mdc-text-field-wrapper.mdc-text-field--outlined .mat-mdc-form-field-infix { |
||||
|
padding-top: 6px; |
||||
|
padding-bottom: 6px; |
||||
|
min-height: auto; |
||||
|
} |
||||
|
|
||||
|
::ng-deep .mat-mdc-form-field-subscript-wrapper { |
||||
|
display: none; |
||||
|
} |
||||
|
::ng-deep .mdc-text-field--outlined:not(.mdc-text-field--disabled) .mdc-notched-outline__leading, |
||||
|
::ng-deep .mdc-text-field--outlined:not(.mdc-text-field--disabled) .mdc-notched-outline__notch, |
||||
|
::ng-deep .mdc-text-field--outlined:not(.mdc-text-field--disabled) .mdc-notched-outline__trailing { |
||||
|
border-color: #e0e0e0; |
||||
|
} |
||||
|
|
||||
|
.fields-label { |
||||
|
font-weight: 500; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.border { |
||||
|
padding: 16px; |
||||
|
margin-bottom: 10px; |
||||
|
box-shadow: 0 0 0 0 rgb(0 0 0 / 20%), 0 0 0 0 rgb(0 0 0 / 14%), 0 0 0 0 rgb(0 0 0 / 12%); |
||||
|
border: solid 1px #e0e0e0; |
||||
|
border-radius: 4px; |
||||
|
|
||||
|
.title { |
||||
|
color: rgba(0, 0, 0, .54); |
||||
|
} |
||||
|
|
||||
|
.mat-icon { |
||||
|
color: rgba(0, 0, 0, .38); |
||||
|
} |
||||
|
|
||||
|
.mat-divider { |
||||
|
margin-left: -16px; |
||||
|
margin-right: -16px; |
||||
|
margin-bottom: 16px; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
@ -0,0 +1,272 @@ |
|||||
|
///
|
||||
|
/// Copyright © 2016-2023 The Thingsboard Authors
|
||||
|
///
|
||||
|
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
/// you may not use this file except in compliance with the License.
|
||||
|
/// You may obtain a copy of the License at
|
||||
|
///
|
||||
|
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
///
|
||||
|
/// Unless required by applicable law or agreed to in writing, software
|
||||
|
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
|
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
/// See the License for the specific language governing permissions and
|
||||
|
/// limitations under the License.
|
||||
|
///
|
||||
|
|
||||
|
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; |
||||
|
import { FormArray, FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; |
||||
|
import { |
||||
|
BACnetObjectTypes, BACnetObjectTypesTranslates, |
||||
|
BACnetRequestTypes, BACnetRequestTypesTranslates, BLEMethods, BLEMethodsTranslates, |
||||
|
CANByteOrders, |
||||
|
ConnectorType, GatewayConnectorDefaultTypesTranslates, HTTPMethods, |
||||
|
ModbusCommandTypes, |
||||
|
RPCCommand, |
||||
|
SNMPMethods, SNMPMethodsTranslations, |
||||
|
SocketEncodings, |
||||
|
SocketMethodProcessings, SocketMethodProcessingsTranslates |
||||
|
} from '@home/components/widget/lib/gateway/gateway-widget.models'; |
||||
|
import { TranslateService } from "@ngx-translate/core"; |
||||
|
|
||||
|
@Component({ |
||||
|
selector: 'tb-gateway-service-rpc-connector', |
||||
|
templateUrl: './gateway-service-rpc-connector.component.html', |
||||
|
styleUrls: ['./gateway-service-rpc-connector.component.scss'] |
||||
|
}) |
||||
|
export class GatewayServiceRPCConnectorComponent implements OnInit { |
||||
|
|
||||
|
@Input() |
||||
|
connectorType: ConnectorType; |
||||
|
|
||||
|
@Output() |
||||
|
sendCommand: EventEmitter<RPCCommand> = new EventEmitter(); |
||||
|
|
||||
|
commandForm: FormGroup; |
||||
|
|
||||
|
codesArray: Array<number> = [1, 2, 3, 4, 5, 6, 15, 16]; |
||||
|
|
||||
|
readonly ConnectorType = ConnectorType; |
||||
|
|
||||
|
modbusCommandTypes = Object.values(ModbusCommandTypes) as ModbusCommandTypes[]; |
||||
|
bACnetRequestTypes = Object.values(BACnetRequestTypes) as BACnetRequestTypes[]; |
||||
|
bACnetObjectTypes = Object.values(BACnetObjectTypes) as BACnetObjectTypes[]; |
||||
|
bLEMethods = Object.values(BLEMethods) as BLEMethods[]; |
||||
|
cANByteOrders = Object.values(CANByteOrders) as CANByteOrders[]; |
||||
|
socketMethodProcessings = Object.values(SocketMethodProcessings) as SocketMethodProcessings[]; |
||||
|
socketEncodings = Object.values(SocketEncodings) as SocketEncodings[]; |
||||
|
sNMPMethods = Object.values(SNMPMethods) as SNMPMethods[]; |
||||
|
hTTPMethods = Object.values(HTTPMethods) as HTTPMethods[]; |
||||
|
|
||||
|
bACnetRequestTypesTranslates = BACnetRequestTypesTranslates; |
||||
|
bACnetObjectTypesTranslates = BACnetObjectTypesTranslates; |
||||
|
bLEMethodsTranslates = BLEMethodsTranslates; |
||||
|
SocketMethodProcessingsTranslates = SocketMethodProcessingsTranslates; |
||||
|
SNMPMethodsTranslations = SNMPMethodsTranslations; |
||||
|
gatewayConnectorDefaultTypesTranslates = GatewayConnectorDefaultTypesTranslates; |
||||
|
|
||||
|
urlPattern = new RegExp( |
||||
|
'^(https?:\\/\\/)?' + // protocol
|
||||
|
'((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|' + // domain name
|
||||
|
'((\\d{1,3}\\.){3}\\d{1,3}))' + // OR IP (v4) address
|
||||
|
'(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*' + // port and path
|
||||
|
'(\\?[;&a-z\\d%_.~+=-]*)?' + // query string
|
||||
|
'(\\#[-a-z\\d_]*)?$', // fragment locator
|
||||
|
'i' |
||||
|
); |
||||
|
|
||||
|
constructor(private fb: FormBuilder, |
||||
|
private translate: TranslateService) { |
||||
|
} |
||||
|
|
||||
|
|
||||
|
ngOnInit() { |
||||
|
this.commandForm = this.connectorParamsFormGroupByType(this.connectorType) |
||||
|
} |
||||
|
|
||||
|
connectorParamsFormGroupByType(type: ConnectorType): FormGroup { |
||||
|
let formGroup: FormGroup; |
||||
|
|
||||
|
switch (type) { |
||||
|
case ConnectorType.MQTT: |
||||
|
formGroup = this.fb.group({ |
||||
|
methodFilter: [null, [Validators.required]], |
||||
|
requestTopicExpression: [null, [Validators.required]], |
||||
|
responseTopicExpression: [null, []], |
||||
|
responseTimeout: [null, [Validators.min(10), Validators.pattern("^[0-9]*$")]], |
||||
|
valueExpression: [null, [Validators.required]], |
||||
|
}) |
||||
|
break; |
||||
|
case ConnectorType.MODBUS: |
||||
|
formGroup = this.fb.group({ |
||||
|
tag: [null, [Validators.required]], |
||||
|
type: [null, [Validators.required]], |
||||
|
functionCode: [null, [Validators.required]], |
||||
|
address: [null, [Validators.required, Validators.min(0), Validators.pattern("^[0-9]*$")]], |
||||
|
objectsCount: [null, [Validators.required, Validators.min(0), Validators.pattern("^[0-9]*$")]] |
||||
|
}) |
||||
|
break; |
||||
|
case ConnectorType.BACNET: |
||||
|
formGroup = this.fb.group({ |
||||
|
method: [null, [Validators.required]], |
||||
|
requestType: [null, [Validators.required]], |
||||
|
requestTimeout: [null, [Validators.required, Validators.min(10), Validators.pattern("^[0-9]*$")]], |
||||
|
objectType: [null, []], |
||||
|
identifier: [null, [Validators.required, Validators.min(1), Validators.pattern("^[0-9]*$")]], |
||||
|
propertyId: [null, [Validators.required]] |
||||
|
}) |
||||
|
break; |
||||
|
case ConnectorType.BLE: |
||||
|
formGroup = this.fb.group({ |
||||
|
methodRPC: [null, [Validators.required]], |
||||
|
characteristicUUID: [null, [Validators.required]], |
||||
|
methodProcessing: [null, [Validators.required]], |
||||
|
withResponse: [false, []] |
||||
|
}) |
||||
|
break; |
||||
|
case ConnectorType.CAN: |
||||
|
formGroup = this.fb.group({ |
||||
|
method: [null, [Validators.required]], |
||||
|
nodeID: [null, [Validators.required, Validators.min(0), Validators.pattern("^[0-9]*$")]], |
||||
|
isExtendedID: [false, []], |
||||
|
isFD: [false, []], |
||||
|
bitrateSwitch: [false, []], |
||||
|
dataLength: [null, [Validators.min(1), Validators.pattern("^[0-9]*$")]], |
||||
|
dataByteorder: [null, []], |
||||
|
dataBefore: [null, []], |
||||
|
dataAfter: [null, []], |
||||
|
dataInHEX: [null, []], |
||||
|
dataExpression: [null, []] |
||||
|
}) |
||||
|
break; |
||||
|
case ConnectorType.FTP: |
||||
|
formGroup = this.fb.group({ |
||||
|
methodFilter: [null, [Validators.required]], |
||||
|
valueExpression: [null, [Validators.required]] |
||||
|
}) |
||||
|
break; |
||||
|
case ConnectorType.OCPP: |
||||
|
formGroup = this.fb.group({ |
||||
|
methodRPC: [null, [Validators.required]], |
||||
|
valueExpression: [null, [Validators.required]], |
||||
|
withResponse: [false, []] |
||||
|
}) |
||||
|
break; |
||||
|
case ConnectorType.SOCKET: |
||||
|
formGroup = this.fb.group({ |
||||
|
methodRPC: [null, [Validators.required]], |
||||
|
methodProcessing: [null, [Validators.required]], |
||||
|
encoding: [null, [Validators.required]], |
||||
|
withResponse: [false, []] |
||||
|
}) |
||||
|
break; |
||||
|
case ConnectorType.XMPP: |
||||
|
formGroup = this.fb.group({ |
||||
|
methodRPC: [null, [Validators.required]], |
||||
|
valueExpression: [null, [Validators.required]], |
||||
|
withResponse: [false, []] |
||||
|
}) |
||||
|
break; |
||||
|
case ConnectorType.SNMP: |
||||
|
formGroup = this.fb.group({ |
||||
|
requestFilter: [null, [Validators.required]], |
||||
|
method: [null, [Validators.required]], |
||||
|
oid: this.fb.array([], [Validators.required]) |
||||
|
}) |
||||
|
break; |
||||
|
case ConnectorType.REST: |
||||
|
formGroup = this.fb.group({ |
||||
|
methodFilter: [null, [Validators.required]], |
||||
|
HTTPMethod: [null, [Validators.required]], |
||||
|
requestUrlExpression: [null, [Validators.required, Validators.pattern(this.urlPattern)]], |
||||
|
responseTimeout: [null, [Validators.required, Validators.min(10), Validators.pattern("^[0-9]*$")]], |
||||
|
timeout: [null, [Validators.required, Validators.min(10), Validators.pattern("^[0-9]*$")]], |
||||
|
tries: [null, [Validators.required, Validators.min(1), Validators.pattern("^[0-9]*$")]], |
||||
|
valueExpression: [null, [Validators.required]], |
||||
|
httpHeaders: this.fb.array([]), |
||||
|
security: this.fb.array([]) |
||||
|
}) |
||||
|
break; |
||||
|
case ConnectorType.REQUEST: |
||||
|
formGroup = this.fb.group({ |
||||
|
methodFilter: [null, [Validators.required]], |
||||
|
httpMethod: [null, [Validators.required]], |
||||
|
requestUrlExpression: [null, [Validators.required, Validators.pattern(this.urlPattern)]], |
||||
|
responseTimeout: [null, [Validators.required, Validators.min(10), Validators.pattern("^[0-9]*$")]], |
||||
|
timeout: [null, [Validators.required, Validators.min(10), Validators.pattern("^[0-9]*$")]], |
||||
|
tries: [null, [Validators.required, Validators.min(1), Validators.pattern("^[0-9]*$")]], |
||||
|
requestValueExpression: [null, [Validators.required]], |
||||
|
responseValueExpression: [null, []], |
||||
|
httpHeaders: this.fb.array([]), |
||||
|
}) |
||||
|
break; |
||||
|
case ConnectorType.OPCUA: |
||||
|
case ConnectorType.OPCUA_ASYNCIO: |
||||
|
formGroup = this.fb.group({ |
||||
|
method: [null, [Validators.required]], |
||||
|
arguments: this.fb.array([]), |
||||
|
}) |
||||
|
} |
||||
|
return formGroup; |
||||
|
} |
||||
|
|
||||
|
addSNMPoid(value: string = null) { |
||||
|
const oidsFA = this.commandForm.get('oid') as FormArray; |
||||
|
if (oidsFA) { |
||||
|
oidsFA.push(this.fb.control(value, [Validators.required])); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
removeSNMPoid(index: number) { |
||||
|
const oidsFA = this.commandForm.get('oid') as FormArray; |
||||
|
oidsFA.removeAt(index); |
||||
|
} |
||||
|
|
||||
|
addHTTPHeader(value: { headerName: string, value: string } = {headerName: null, value: null}) { |
||||
|
const headerFA = this.commandForm.get('httpHeaders') as FormArray; |
||||
|
const formGroup = this.fb.group({ |
||||
|
headerName: [value.headerName, [Validators.required]], |
||||
|
value: [value.value, [Validators.required]] |
||||
|
}) |
||||
|
if (headerFA) { |
||||
|
headerFA.push(formGroup); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
removeHTTPHeader(index: number) { |
||||
|
const oidsFA = this.commandForm.get('httpHeaders') as FormArray; |
||||
|
oidsFA.removeAt(index); |
||||
|
} |
||||
|
|
||||
|
addHTTPSecurity(value: { securityName: string, value: string } = {securityName: null, value: null}) { |
||||
|
const securityFA = this.commandForm.get('security') as FormArray; |
||||
|
const formGroup = this.fb.group({ |
||||
|
securityName: [value.securityName, [Validators.required]], |
||||
|
value: [value.value, [Validators.required]] |
||||
|
}) |
||||
|
if (securityFA) { |
||||
|
securityFA.push(formGroup); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
removeHTTPSecurity(index: number) { |
||||
|
const oidsFA = this.commandForm.get('security') as FormArray; |
||||
|
oidsFA.removeAt(index); |
||||
|
} |
||||
|
|
||||
|
getFormArrayControls(path: string) { |
||||
|
return (this.commandForm.get(path) as FormArray).controls as FormControl[]; |
||||
|
} |
||||
|
|
||||
|
addOCPUAArguments(value: string = null) { |
||||
|
const oidsFA = this.commandForm.get('arguments') as FormArray; |
||||
|
if (oidsFA) { |
||||
|
oidsFA.push(this.fb.control(value)); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
removeOCPUAArguments(index: number) { |
||||
|
const oidsFA = this.commandForm.get('arguments') as FormArray; |
||||
|
oidsFA.removeAt(index); |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue