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