connectors templates
This commit is contained in:
parent
bccb2e7e8c
commit
6ee6ccaa36
@ -0,0 +1,54 @@
|
|||||||
|
<!--
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
-->
|
||||||
|
<mat-toolbar color="primary">
|
||||||
|
<h2 translate>gateway.rpc.save-template</h2>
|
||||||
|
<span fxFlex></span>
|
||||||
|
<button mat-icon-button
|
||||||
|
(click)="close()"
|
||||||
|
type="button">
|
||||||
|
<mat-icon class="material-icons">close</mat-icon>
|
||||||
|
</button>
|
||||||
|
</mat-toolbar>
|
||||||
|
<div mat-dialog-content style="width: 600px" class="mat-content" fxLayout="column">
|
||||||
|
<mat-form-field class="mat-block tb-value-type" style="flex-grow: 0">
|
||||||
|
<mat-label translate>gateway.rpc.template-name</mat-label>
|
||||||
|
<input matInput [formControl]="templateNameCtrl" required/>
|
||||||
|
<mat-error
|
||||||
|
*ngIf="templateNameCtrl.hasError('required')">
|
||||||
|
{{ 'gateway.rpc.template-name-required' | translate }}
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
<div class="mat-mdc-form-field-error"
|
||||||
|
style="margin-top: -15px; padding-left: 10px; font-size: 14px;"
|
||||||
|
*ngIf="validateDuplicateName(templateNameCtrl)">
|
||||||
|
{{ 'gateway.rpc.template-name-duplicate' | translate }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div mat-dialog-actions fxLayoutAlign="end center">
|
||||||
|
<button mat-button
|
||||||
|
type="button"
|
||||||
|
(click)="close()">
|
||||||
|
{{ 'action.cancel' | translate }}
|
||||||
|
</button>
|
||||||
|
<button mat-raised-button color="primary"
|
||||||
|
type="button"
|
||||||
|
[disabled]="!templateNameCtrl.valid"
|
||||||
|
(click)="save()">
|
||||||
|
{{ 'action.save' | translate }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
@ -0,0 +1,62 @@
|
|||||||
|
///
|
||||||
|
/// 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, Inject } from '@angular/core';
|
||||||
|
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||||
|
import { Store } from '@ngrx/store';
|
||||||
|
import { AppState } from '@core/core.state';
|
||||||
|
import { DialogComponent } from '@shared/components/dialog.component';
|
||||||
|
import { Router } from '@angular/router';
|
||||||
|
import { FormBuilder, FormControl, UntypedFormControl, Validators } from '@angular/forms';
|
||||||
|
import { RPCTemplate, SaveRPCTemplateData } from '@home/components/widget/lib/gateway/gateway-widget.models';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'gateway-service-rpc-connector-template-dialog',
|
||||||
|
templateUrl: './gateway-service-rpc-connector-template-dialog.html'
|
||||||
|
})
|
||||||
|
|
||||||
|
export class GatewayServiceRPCConnectorTemplateDialogComponent extends DialogComponent<GatewayServiceRPCConnectorTemplateDialogComponent, boolean> {
|
||||||
|
|
||||||
|
config: {
|
||||||
|
[key: string]: any;
|
||||||
|
};
|
||||||
|
templates: Array<RPCTemplate>;
|
||||||
|
templateNameCtrl: FormControl;
|
||||||
|
|
||||||
|
constructor(protected store: Store<AppState>,
|
||||||
|
protected router: Router,
|
||||||
|
@Inject(MAT_DIALOG_DATA) public data: SaveRPCTemplateData,
|
||||||
|
public dialogRef: MatDialogRef<GatewayServiceRPCConnectorTemplateDialogComponent, boolean>,
|
||||||
|
public fb: FormBuilder) {
|
||||||
|
super(store, router, dialogRef);
|
||||||
|
this.config = this.data.config;
|
||||||
|
this.templates = this.data.templates;
|
||||||
|
this.templateNameCtrl = this.fb.control('', [Validators.required])
|
||||||
|
}
|
||||||
|
|
||||||
|
validateDuplicateName(c: UntypedFormControl) {
|
||||||
|
const name = c.value.trim();
|
||||||
|
return !!this.templates.find((template) => template.name === name);
|
||||||
|
};
|
||||||
|
|
||||||
|
close(): void {
|
||||||
|
this.dialogRef.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
save(): void {
|
||||||
|
this.dialogRef.close(this.templateNameCtrl.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -22,13 +22,10 @@
|
|||||||
{{template.name}}
|
{{template.name}}
|
||||||
</mat-panel-title>
|
</mat-panel-title>
|
||||||
<mat-panel-description>
|
<mat-panel-description>
|
||||||
<button mat-icon-button matTooltip="Delete" (click)="deleteTemplate($event)">
|
<button mat-icon-button matTooltip="Delete" (click)="deleteTemplate($event, template)">
|
||||||
<mat-icon class="material-icons">delete</mat-icon>
|
<mat-icon class="material-icons">delete</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
<button mat-icon-button matTooltip="Copy" (click)="copyTemplate($event)">
|
<button mat-icon-button matTooltip="Use" (click)="applyTemplate($event, template)">
|
||||||
<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>
|
<mat-icon class="material-icons">play_arrow</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
</mat-panel-description>
|
</mat-panel-description>
|
||||||
@ -37,13 +34,15 @@
|
|||||||
<ng-container
|
<ng-container
|
||||||
*ngFor="let config of template.config | keyvalue : originalOrder"
|
*ngFor="let config of template.config | keyvalue : originalOrder"
|
||||||
[ngTemplateOutlet]="RPCTemplateRef"
|
[ngTemplateOutlet]="RPCTemplateRef"
|
||||||
[ngTemplateOutletContext]="{ $implicit: config, padding: false }">
|
[ngTemplateOutletContext]="{ $implicit: config, innerValue: false }">
|
||||||
</ng-container>
|
</ng-container>
|
||||||
<ng-template #RPCTemplateRef let-config let-padding='padding'>
|
<ng-template #RPCTemplateRef let-config let-innerValue='innerValue'>
|
||||||
<div [fxLayout]="isObject(config.value) ? 'column': 'row'"
|
<div [fxLayout]="isObject(config.value) ? 'column': 'row'"
|
||||||
[fxLayoutAlign]="!isObject(config.value) ? 'space-between center' : ''"
|
[fxLayoutAlign]="!isObject(config.value) ? 'space-between center' : ''"
|
||||||
[ngStyle]="{'padding-left': padding ? '16px': '0'}">
|
[ngStyle]="{'padding-left': innerValue ? '16px': '0'}">
|
||||||
<div class="template-key">{{config.key}}</div>
|
<div class="template-key">
|
||||||
|
{{!innerValue ? ('gateway.rpc.' + config.key | translate) : config.key}}
|
||||||
|
</div>
|
||||||
<div *ngIf="!isObject(config.value) else RPCObjectRow"
|
<div *ngIf="!isObject(config.value) else RPCObjectRow"
|
||||||
[ngClass]="{'boolean-true': config.value === true,
|
[ngClass]="{'boolean-true': config.value === true,
|
||||||
'boolean-false': config.value === false }">
|
'boolean-false': config.value === false }">
|
||||||
@ -52,7 +51,7 @@
|
|||||||
<ng-container
|
<ng-container
|
||||||
*ngFor="let subConfig of config.value | keyvalue : originalOrder"
|
*ngFor="let subConfig of config.value | keyvalue : originalOrder"
|
||||||
[ngTemplateOutlet]="RPCTemplateRef"
|
[ngTemplateOutlet]="RPCTemplateRef"
|
||||||
[ngTemplateOutletContext]="{ $implicit: subConfig, padding: true }">
|
[ngTemplateOutletContext]="{ $implicit: subConfig, innerValue: true }">
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -50,6 +50,11 @@
|
|||||||
background-color: rgba(25, 128, 56, 0.08);
|
background-color: rgba(25, 128, 56, 0.08);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mat-expansion-panel {
|
||||||
|
margin-top: 10px;
|
||||||
|
overflow: visible;
|
||||||
|
}
|
||||||
|
|
||||||
.mat-expansion-panel-header-description {
|
.mat-expansion-panel-header-description {
|
||||||
flex-direction: row-reverse;
|
flex-direction: row-reverse;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|||||||
@ -15,9 +15,16 @@
|
|||||||
///
|
///
|
||||||
|
|
||||||
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
||||||
import { ConnectorType, RPCTemplate } from '@home/components/widget/lib/gateway/gateway-widget.models';
|
import {
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
ConnectorType,
|
||||||
|
RPCTemplate
|
||||||
|
} from '@home/components/widget/lib/gateway/gateway-widget.models';
|
||||||
import { KeyValue } from '@angular/common';
|
import { KeyValue } from '@angular/common';
|
||||||
|
import { EntityType } from '@shared/models/entity-type.models';
|
||||||
|
import { AttributeScope } from '@shared/models/telemetry/telemetry.models';
|
||||||
|
import { AttributeService } from '@core/http/attribute.service';
|
||||||
|
import { WidgetContext } from '@home/models/widget-component.models';
|
||||||
|
import { MatDialog } from '@angular/material/dialog';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'tb-gateway-service-rpc-connector-templates',
|
selector: 'tb-gateway-service-rpc-connector-templates',
|
||||||
@ -29,52 +36,52 @@ export class GatewayServiceRPCConnectorTemplatesComponent implements OnInit {
|
|||||||
@Input()
|
@Input()
|
||||||
connectorType: ConnectorType;
|
connectorType: ConnectorType;
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
ctx: WidgetContext;
|
||||||
|
|
||||||
@Output()
|
@Output()
|
||||||
saveTemplate: EventEmitter<any> = new EventEmitter();
|
saveTemplate: EventEmitter<any> = new EventEmitter();
|
||||||
|
|
||||||
rpcTemplates: Array<RPCTemplate> = [];
|
@Output()
|
||||||
|
useTemplate: EventEmitter<any> = new EventEmitter();
|
||||||
|
|
||||||
constructor(private translate: TranslateService) {
|
@Input()
|
||||||
this.rpcTemplates.push(
|
rpcTemplates: Array<RPCTemplate>;
|
||||||
{
|
|
||||||
name: 'Test Template',
|
|
||||||
config: {
|
|
||||||
fieldString: 'string',
|
|
||||||
fieldNumber: 666,
|
|
||||||
fieldBool: true,
|
|
||||||
fieldArray: [111, 222, 333, "String", "444"],
|
|
||||||
fieldObj: {
|
|
||||||
subKey1: 'dasd',
|
|
||||||
subKey2: 666,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
constructor(private attributeService: AttributeService) {
|
||||||
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public useTemplate($event: Event): void {
|
public applyTemplate($event: Event, template: RPCTemplate): void {
|
||||||
$event.stopPropagation();
|
$event.stopPropagation();
|
||||||
console.log("useTemplate")
|
this.useTemplate.emit(template);
|
||||||
}
|
}
|
||||||
|
|
||||||
public copyTemplate($event: Event): void {
|
public deleteTemplate($event: Event, template: RPCTemplate): void {
|
||||||
$event.stopPropagation();
|
$event.stopPropagation();
|
||||||
console.log("copyTemplate")
|
const index = this.rpcTemplates.findIndex(data => {
|
||||||
|
return data.name == template.name;
|
||||||
|
})
|
||||||
|
this.rpcTemplates.splice(index, 1);
|
||||||
|
const key = `${this.connectorType}_template`;
|
||||||
|
this.attributeService.saveEntityAttributes(
|
||||||
|
{
|
||||||
|
id: this.ctx.defaultSubscription.targetDeviceId,
|
||||||
|
entityType: EntityType.DEVICE
|
||||||
|
}
|
||||||
|
, AttributeScope.SERVER_SCOPE, [{
|
||||||
|
key,
|
||||||
|
value: this.rpcTemplates
|
||||||
|
}]).subscribe(() => {
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
public deleteTemplate($event: Event): void {
|
public originalOrder = (a, b): number => {
|
||||||
$event.stopPropagation();
|
|
||||||
console.log("deleteTemplate")
|
|
||||||
}
|
|
||||||
|
|
||||||
public originalOrder = (a: KeyValue<string, any>, b: KeyValue<string, any>): number => {
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public isObject(value: any) {
|
public isObject(value: any) {
|
||||||
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,7 +16,8 @@
|
|||||||
|
|
||||||
-->
|
-->
|
||||||
<div fxLayout="column" class="command-form" [formGroup]="commandForm">
|
<div fxLayout="column" class="command-form" [formGroup]="commandForm">
|
||||||
<div class="mat-subtitle-1 title">{{ 'gateway.rpc.title' | translate: {type: gatewayConnectorDefaultTypesTranslates.get(connectorType)} }}</div>
|
<div
|
||||||
|
class="mat-subtitle-1 title">{{ 'gateway.rpc.title' | translate: {type: gatewayConnectorDefaultTypesTranslates.get(connectorType)} }}</div>
|
||||||
<ng-template [ngIf]="connectorType">
|
<ng-template [ngIf]="connectorType">
|
||||||
<ng-container [ngSwitch]="connectorType">
|
<ng-container [ngSwitch]="connectorType">
|
||||||
<ng-template [ngSwitchCase]="ConnectorType.MQTT">
|
<ng-template [ngSwitchCase]="ConnectorType.MQTT">
|
||||||
@ -26,27 +27,26 @@
|
|||||||
placeholder="echo"/>
|
placeholder="echo"/>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>{{ 'gateway.rpc.request-topic-expression' | translate }}</mat-label>
|
<mat-label>{{ 'gateway.rpc.requestTopicExpression' | translate }}</mat-label>
|
||||||
<input matInput formControlName="requestTopicExpression"
|
<input matInput formControlName="requestTopicExpression"
|
||||||
placeholder="sensor/${deviceName}/request/${methodName}/${requestId}"/>
|
placeholder="sensor/${deviceName}/request/${methodName}/${requestId}"/>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>{{ 'gateway.rpc.response-topic-expression' | translate }}</mat-label>
|
<mat-label>{{ 'gateway.rpc.responseTopicExpression' | translate }}</mat-label>
|
||||||
<input matInput formControlName="responseTopicExpression"
|
<input matInput formControlName="responseTopicExpression"
|
||||||
placeholder="sensor/${deviceName}/response/${methodName}/${requestId}"/>
|
placeholder="sensor/${deviceName}/response/${methodName}/${requestId}"/>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>{{ 'gateway.rpc.response-timeout' | translate }}</mat-label>
|
<mat-label>{{ 'gateway.rpc.responseTimeout' | translate }}</mat-label>
|
||||||
<input matInput formControlName="responseTimeout" type="number"
|
<input matInput formControlName="responseTimeout" type="number"
|
||||||
placeholder="10000" min="10" step="1"/>
|
placeholder="10000" min="10" step="1"/>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>{{ 'gateway.rpc.value-expression' | translate }}</mat-label>
|
<mat-label>{{ 'gateway.rpc.valueExpression' | translate }}</mat-label>
|
||||||
<input matInput formControlName="valueExpression"
|
<input matInput formControlName="valueExpression"
|
||||||
placeholder="${params}"/>
|
placeholder="${params}"/>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
|
||||||
<ng-template [ngSwitchCase]="ConnectorType.MODBUS">
|
<ng-template [ngSwitchCase]="ConnectorType.MODBUS">
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>{{ 'gateway.rpc.tag' | translate }}</mat-label>
|
<mat-label>{{ 'gateway.rpc.tag' | translate }}</mat-label>
|
||||||
@ -62,7 +62,7 @@
|
|||||||
</mat-select>
|
</mat-select>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<mat-form-field fxFlex="50" class="mat-block">
|
<mat-form-field fxFlex="50" class="mat-block">
|
||||||
<mat-label>{{ 'gateway.rpc.function-code' | translate }}</mat-label>
|
<mat-label>{{ 'gateway.rpc.functionCode' | translate }}</mat-label>
|
||||||
<mat-select formControlName="functionCode">
|
<mat-select formControlName="functionCode">
|
||||||
<mat-option *ngFor="let code of codesArray" [value]="code">
|
<mat-option *ngFor="let code of codesArray" [value]="code">
|
||||||
{{ code }}
|
{{ code }}
|
||||||
@ -77,20 +77,19 @@
|
|||||||
placeholder="1" step="1"/>
|
placeholder="1" step="1"/>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<mat-form-field fxFlex="50">
|
<mat-form-field fxFlex="50">
|
||||||
<mat-label>{{ 'gateway.rpc.objects-count' | translate }}</mat-label>
|
<mat-label>{{ 'gateway.rpc.objectsCount' | translate }}</mat-label>
|
||||||
<input matInput formControlName="objectsCount" type="number" min="0"
|
<input matInput formControlName="objectsCount" type="number" min="0"
|
||||||
placeholder="31" step="1"/>
|
placeholder="31" step="1"/>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</div>
|
</div>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
|
||||||
<ng-template [ngSwitchCase]="ConnectorType.BACNET">
|
<ng-template [ngSwitchCase]="ConnectorType.BACNET">
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>{{ 'gateway.rpc.method-rpc' | translate }}</mat-label>
|
<mat-label>{{ 'gateway.rpc.methodRPC' | translate }}</mat-label>
|
||||||
<input matInput formControlName="method" placeholder="set_state"/>
|
<input matInput formControlName="method" placeholder="set_state"/>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<mat-form-field class="mat-block">
|
<mat-form-field class="mat-block">
|
||||||
<mat-label>{{ 'gateway.rpc.request-type' | translate }}</mat-label>
|
<mat-label>{{ 'gateway.rpc.requestType' | translate }}</mat-label>
|
||||||
<mat-select formControlName="requestType">
|
<mat-select formControlName="requestType">
|
||||||
<mat-option *ngFor="let type of bACnetRequestTypes" [value]="type">
|
<mat-option *ngFor="let type of bACnetRequestTypes" [value]="type">
|
||||||
{{bACnetRequestTypesTranslates.get(type) | translate}}
|
{{bACnetRequestTypesTranslates.get(type) | translate}}
|
||||||
@ -98,13 +97,13 @@
|
|||||||
</mat-select>
|
</mat-select>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>{{ 'gateway.rpc.request-timeout' | translate }}</mat-label>
|
<mat-label>{{ 'gateway.rpc.requestTimeout' | translate }}</mat-label>
|
||||||
<input matInput formControlName="requestTimeout" type="number"
|
<input matInput formControlName="requestTimeout" type="number"
|
||||||
min="10" step="1" placeholder="1000"/>
|
min="10" step="1" placeholder="1000"/>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<div fxFlex fxLayout="row" fxLayoutGap="10px">
|
<div fxFlex fxLayout="row" fxLayoutGap="10px">
|
||||||
<mat-form-field fxFlex="50" class="mat-block">
|
<mat-form-field fxFlex="50" class="mat-block">
|
||||||
<mat-label>{{ 'gateway.rpc.object-type' | translate }}</mat-label>
|
<mat-label>{{ 'gateway.rpc.objectType' | translate }}</mat-label>
|
||||||
<mat-select formControlName="objectType">
|
<mat-select formControlName="objectType">
|
||||||
<mat-option *ngFor="let type of bACnetObjectTypes" [value]="type">
|
<mat-option *ngFor="let type of bACnetObjectTypes" [value]="type">
|
||||||
{{bACnetObjectTypesTranslates.get(type) | translate}}
|
{{bACnetObjectTypesTranslates.get(type) | translate}}
|
||||||
@ -118,22 +117,21 @@
|
|||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</div>
|
</div>
|
||||||
<mat-form-field class="mat-block">
|
<mat-form-field class="mat-block">
|
||||||
<mat-label>{{ 'gateway.rpc.property-id' | translate }}</mat-label>
|
<mat-label>{{ 'gateway.rpc.propertyId' | translate }}</mat-label>
|
||||||
<input matInput formControlName="propertyId" placeholder="presentValue"/>
|
<input matInput formControlName="propertyId" placeholder="presentValue"/>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
|
||||||
<ng-template [ngSwitchCase]="ConnectorType.BLE">
|
<ng-template [ngSwitchCase]="ConnectorType.BLE">
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>{{ 'gateway.rpc.method-rpc' | translate }}</mat-label>
|
<mat-label>{{ 'gateway.rpc.methodRPC' | translate }}</mat-label>
|
||||||
<input matInput formControlName="methodRPC" placeholder="rpcMethod1"/>
|
<input matInput formControlName="methodRPC" placeholder="rpcMethod1"/>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>{{ 'gateway.rpc.characteristic-uuid' | translate }}</mat-label>
|
<mat-label>{{ 'gateway.rpc.characteristicUUID' | translate }}</mat-label>
|
||||||
<input matInput formControlName="characteristicUUID" placeholder="00002A00-0000-1000-8000-00805F9B34FB"/>
|
<input matInput formControlName="characteristicUUID" placeholder="00002A00-0000-1000-8000-00805F9B34FB"/>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<mat-form-field class="mat-block">
|
<mat-form-field class="mat-block">
|
||||||
<mat-label>{{ 'gateway.rpc.method-processing' | translate }}</mat-label>
|
<mat-label>{{ 'gateway.rpc.methodProcessing' | translate }}</mat-label>
|
||||||
<mat-select formControlName="methodProcessing">
|
<mat-select formControlName="methodProcessing">
|
||||||
<mat-option *ngFor="let type of bLEMethods" [value]="type">
|
<mat-option *ngFor="let type of bLEMethods" [value]="type">
|
||||||
{{bLEMethodsTranslates.get(type) | translate}}
|
{{bLEMethodsTranslates.get(type) | translate}}
|
||||||
@ -141,35 +139,34 @@
|
|||||||
</mat-select>
|
</mat-select>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<mat-slide-toggle class="mat-slide" formControlName="withResponse">
|
<mat-slide-toggle class="mat-slide" formControlName="withResponse">
|
||||||
{{ 'gateway.rpc.with-response' | translate }}
|
{{ 'gateway.rpc.withResponse' | translate }}
|
||||||
</mat-slide-toggle>
|
</mat-slide-toggle>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
|
||||||
<ng-template [ngSwitchCase]="ConnectorType.CAN">
|
<ng-template [ngSwitchCase]="ConnectorType.CAN">
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>{{ 'gateway.rpc.method-rpc' | translate }}</mat-label>
|
<mat-label>{{ 'gateway.rpc.methodRPC' | translate }}</mat-label>
|
||||||
<input matInput formControlName="method" placeholder="sendSameData"/>
|
<input matInput formControlName="method" placeholder="sendSameData"/>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>{{ 'gateway.rpc.node-id' | translate }}</mat-label>
|
<mat-label>{{ 'gateway.rpc.nodeID' | translate }}</mat-label>
|
||||||
<input matInput formControlName="nodeID" type="number" placeholder="4" min="0" step="1"/>
|
<input matInput formControlName="nodeID" type="number" placeholder="4" min="0" step="1"/>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<mat-slide-toggle class="mat-slide margin" formControlName="isExtendedID">
|
<mat-slide-toggle class="mat-slide margin" formControlName="isExtendedID">
|
||||||
{{ 'gateway.rpc.is-extended-id' | translate }}
|
{{ 'gateway.rpc.isExtendedID' | translate }}
|
||||||
</mat-slide-toggle>
|
</mat-slide-toggle>
|
||||||
<mat-slide-toggle class="mat-slide margin" formControlName="isFD">
|
<mat-slide-toggle class="mat-slide margin" formControlName="isFD">
|
||||||
{{ 'gateway.rpc.is-fd' | translate }}
|
{{ 'gateway.rpc.isFD' | translate }}
|
||||||
</mat-slide-toggle>
|
</mat-slide-toggle>
|
||||||
<mat-slide-toggle class="mat-slide margin" formControlName="bitrateSwitch">
|
<mat-slide-toggle class="mat-slide margin" formControlName="bitrateSwitch">
|
||||||
{{ 'gateway.rpc.bitrate-switch' | translate }}
|
{{ 'gateway.rpc.bitrateSwitch' | translate }}
|
||||||
</mat-slide-toggle>
|
</mat-slide-toggle>
|
||||||
<div fxFlex fxLayout="row" fxLayoutGap="10px">
|
<div fxFlex fxLayout="row" fxLayoutGap="10px">
|
||||||
<mat-form-field fxFlex="50">
|
<mat-form-field fxFlex="50">
|
||||||
<mat-label>{{ 'gateway.rpc.data-length' | translate }}</mat-label>
|
<mat-label>{{ 'gateway.rpc.dataLength' | translate }}</mat-label>
|
||||||
<input matInput formControlName="dataLength" type="number" placeholder="2" min="1" step="1"/>
|
<input matInput formControlName="dataLength" type="number" placeholder="2" min="1" step="1"/>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<mat-form-field class="mat-block" fxFlex="50">
|
<mat-form-field class="mat-block" fxFlex="50">
|
||||||
<mat-label>{{ 'gateway.rpc.data-byte-order' | translate }}</mat-label>
|
<mat-label>{{ 'gateway.rpc.dataByteorder' | translate }}</mat-label>
|
||||||
<mat-select formControlName="dataByteorder">
|
<mat-select formControlName="dataByteorder">
|
||||||
<mat-option *ngFor="let order of cANByteOrders" [value]="order">
|
<mat-option *ngFor="let order of cANByteOrders" [value]="order">
|
||||||
{{ order | translate }}
|
{{ order | translate }}
|
||||||
@ -179,59 +176,55 @@
|
|||||||
</div>
|
</div>
|
||||||
<div fxFlex fxLayout="row" fxLayoutGap="10px">
|
<div fxFlex fxLayout="row" fxLayoutGap="10px">
|
||||||
<mat-form-field fxFlex="50">
|
<mat-form-field fxFlex="50">
|
||||||
<mat-label>{{ 'gateway.rpc.data-before' | translate }}</mat-label>
|
<mat-label>{{ 'gateway.rpc.dataBefore' | translate }}</mat-label>
|
||||||
<input matInput formControlName="dataBefore" placeholder="00AA"/>
|
<input matInput formControlName="dataBefore" placeholder="00AA"/>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<mat-form-field fxFlex="50">
|
<mat-form-field fxFlex="50">
|
||||||
<mat-label>{{ 'gateway.rpc.data-after' | translate }}</mat-label>
|
<mat-label>{{ 'gateway.rpc.dataAfter' | translate }}</mat-label>
|
||||||
<input matInput formControlName="dataAfter" placeholder="0102"/>
|
<input matInput formControlName="dataAfter" placeholder="0102"/>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</div>
|
</div>
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>{{ 'gateway.rpc.data-in-hex' | translate }}</mat-label>
|
<mat-label>{{ 'gateway.rpc.dataInHEX' | translate }}</mat-label>
|
||||||
<input matInput formControlName="dataInHEX"
|
<input matInput formControlName="dataInHEX"
|
||||||
placeholder="aa bb cc dd ee ff aa bb aa bb cc d ee ff"/>
|
placeholder="aa bb cc dd ee ff aa bb aa bb cc d ee ff"/>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>{{ 'gateway.rpc.data-expression' | translate }}</mat-label>
|
<mat-label>{{ 'gateway.rpc.dataExpression' | translate }}</mat-label>
|
||||||
<input matInput formControlName="dataExpression"
|
<input matInput formControlName="dataExpression"
|
||||||
placeholder="userSpeed if maxAllowedSpeed > userSpeed else maxAllowedSpeed"/>
|
placeholder="userSpeed if maxAllowedSpeed > userSpeed else maxAllowedSpeed"/>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
|
||||||
|
|
||||||
<ng-template [ngSwitchCase]="ConnectorType.FTP">
|
<ng-template [ngSwitchCase]="ConnectorType.FTP">
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>{{ 'gateway.rpc.method-filter' | translate }}</mat-label>
|
<mat-label>{{ 'gateway.rpc.methodFilter' | translate }}</mat-label>
|
||||||
<input matInput formControlName="methodFilter" placeholder="read"/>
|
<input matInput formControlName="methodFilter" placeholder="read"/>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>{{ 'gateway.rpc.value-expression' | translate }}</mat-label>
|
<mat-label>{{ 'gateway.rpc.valueExpression' | translate }}</mat-label>
|
||||||
<input matInput formControlName="valueExpression" placeholder="${params}"/>
|
<input matInput formControlName="valueExpression" placeholder="${params}"/>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
|
||||||
<ng-template [ngSwitchCase]="ConnectorType.OCPP">
|
<ng-template [ngSwitchCase]="ConnectorType.OCPP">
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>{{ 'gateway.rpc.method-rpc' | translate }}</mat-label>
|
<mat-label>{{ 'gateway.rpc.methodRPC' | translate }}</mat-label>
|
||||||
<input matInput formControlName="methodRPC" placeholder="rpc1"/>
|
<input matInput formControlName="methodRPC" placeholder="rpc1"/>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>{{ 'gateway.rpc.value-expression' | translate }}</mat-label>
|
<mat-label>{{ 'gateway.rpc.valueExpression' | translate }}</mat-label>
|
||||||
<input matInput formControlName="valueExpression" placeholder="${params}"/>
|
<input matInput formControlName="valueExpression" placeholder="${params}"/>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<mat-slide-toggle class="mat-slide margin" formControlName="withResponse">
|
<mat-slide-toggle class="mat-slide margin" formControlName="withResponse">
|
||||||
{{ 'gateway.rpc.with-response' | translate }}
|
{{ 'gateway.rpc.withResponse' | translate }}
|
||||||
</mat-slide-toggle>
|
</mat-slide-toggle>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
|
||||||
<ng-template [ngSwitchCase]="ConnectorType.SOCKET">
|
<ng-template [ngSwitchCase]="ConnectorType.SOCKET">
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>{{ 'gateway.rpc.method-rpc' | translate }}</mat-label>
|
<mat-label>{{ 'gateway.rpc.methodRPC' | translate }}</mat-label>
|
||||||
<input matInput formControlName="methodRPC" placeholder="rpcMethod1"/>
|
<input matInput formControlName="methodRPC" placeholder="rpcMethod1"/>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<mat-form-field class="mat-block">
|
<mat-form-field class="mat-block">
|
||||||
<mat-label>{{ 'gateway.rpc.method-processing' | translate }}</mat-label>
|
<mat-label>{{ 'gateway.rpc.methodProcessing' | translate }}</mat-label>
|
||||||
<mat-select formControlName="methodProcessing">
|
<mat-select formControlName="methodProcessing">
|
||||||
<mat-option *ngFor="let method of socketMethodProcessings" [value]="method">
|
<mat-option *ngFor="let method of socketMethodProcessings" [value]="method">
|
||||||
{{ SocketMethodProcessingsTranslates.get(method) | translate }}
|
{{ SocketMethodProcessingsTranslates.get(method) | translate }}
|
||||||
@ -247,27 +240,25 @@
|
|||||||
</mat-select>
|
</mat-select>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<mat-slide-toggle class="mat-slide margin" formControlName="withResponse">
|
<mat-slide-toggle class="mat-slide margin" formControlName="withResponse">
|
||||||
{{ 'gateway.rpc.with-response' | translate }}
|
{{ 'gateway.rpc.withResponse' | translate }}
|
||||||
</mat-slide-toggle>
|
</mat-slide-toggle>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
|
||||||
<ng-template [ngSwitchCase]="ConnectorType.XMPP">
|
<ng-template [ngSwitchCase]="ConnectorType.XMPP">
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>{{ 'gateway.rpc.method-rpc' | translate }}</mat-label>
|
<mat-label>{{ 'gateway.rpc.methodRPC' | translate }}</mat-label>
|
||||||
<input matInput formControlName="methodRPC" placeholder="rpc1"/>
|
<input matInput formControlName="methodRPC" placeholder="rpc1"/>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>{{ 'gateway.rpc.value-expression' | translate }}</mat-label>
|
<mat-label>{{ 'gateway.rpc.valueExpression' | translate }}</mat-label>
|
||||||
<input matInput formControlName="valueExpression" placeholder="${params}"/>
|
<input matInput formControlName="valueExpression" placeholder="${params}"/>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<mat-slide-toggle class="mat-slide margin" formControlName="withResponse">
|
<mat-slide-toggle class="mat-slide margin" formControlName="withResponse">
|
||||||
{{ 'gateway.rpc.with-response' | translate }}
|
{{ 'gateway.rpc.withResponse' | translate }}
|
||||||
</mat-slide-toggle>
|
</mat-slide-toggle>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
|
||||||
<ng-template [ngSwitchCase]="ConnectorType.SNMP">
|
<ng-template [ngSwitchCase]="ConnectorType.SNMP">
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>{{ 'gateway.rpc.request-filter' | translate }}</mat-label>
|
<mat-label>{{ 'gateway.rpc.requestFilter' | translate }}</mat-label>
|
||||||
<input matInput formControlName="requestFilter" placeholder="setData"/>
|
<input matInput formControlName="requestFilter" placeholder="setData"/>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<mat-form-field class="mat-block">
|
<mat-form-field class="mat-block">
|
||||||
@ -298,15 +289,14 @@
|
|||||||
</button>
|
</button>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
|
||||||
<ng-template [ngSwitchCase]="ConnectorType.REST">
|
<ng-template [ngSwitchCase]="ConnectorType.REST">
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>{{ 'gateway.rpc.method-filter' | translate }}</mat-label>
|
<mat-label>{{ 'gateway.rpc.methodFilter' | translate }}</mat-label>
|
||||||
<input matInput formControlName="methodFilter" placeholder="post_attributes"/>
|
<input matInput formControlName="methodFilter" placeholder="post_attributes"/>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<div fxFlex fxLayout="row" fxLayoutGap="10px">
|
<div fxFlex fxLayout="row" fxLayoutGap="10px">
|
||||||
<mat-form-field class="mat-block" fxFlex="33">
|
<mat-form-field class="mat-block" fxFlex="33">
|
||||||
<mat-label>{{ 'gateway.rpc.http-method' | translate }}</mat-label>
|
<mat-label>{{ 'gateway.rpc.HTTPMethod' | translate }}</mat-label>
|
||||||
<mat-select formControlName="HTTPMethod">
|
<mat-select formControlName="HTTPMethod">
|
||||||
<mat-option *ngFor="let method of hTTPMethods" [value]="method">
|
<mat-option *ngFor="let method of hTTPMethods" [value]="method">
|
||||||
{{ method }}
|
{{ method }}
|
||||||
@ -314,14 +304,14 @@
|
|||||||
</mat-select>
|
</mat-select>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<mat-form-field fxFlex>
|
<mat-form-field fxFlex>
|
||||||
<mat-label>{{ 'gateway.rpc.request-url' | translate }}</mat-label>
|
<mat-label>{{ 'gateway.rpc.requestUrlExpression' | translate }}</mat-label>
|
||||||
<input matInput formControlName="requestUrlExpression"
|
<input matInput formControlName="requestUrlExpression"
|
||||||
placeholder="http://127.0.0.1:5000/my_devices"/>
|
placeholder="http://127.0.0.1:5000/my_devices"/>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</div>
|
</div>
|
||||||
<div fxFlex fxLayout="row" fxLayoutGap="10px">
|
<div fxFlex fxLayout="row" fxLayoutGap="10px">
|
||||||
<mat-form-field fxFlex="33">
|
<mat-form-field fxFlex="33">
|
||||||
<mat-label>{{ 'gateway.rpc.response-timeout' | translate }}</mat-label>
|
<mat-label>{{ 'gateway.rpc.responseTimeout' | translate }}</mat-label>
|
||||||
<input matInput formControlName="responseTimeout" type="number"
|
<input matInput formControlName="responseTimeout" type="number"
|
||||||
step="1" min="10" placeholder="10"/>
|
step="1" min="10" placeholder="10"/>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
@ -337,11 +327,11 @@
|
|||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</div>
|
</div>
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>{{ 'gateway.rpc.value-expression' | translate }}</mat-label>
|
<mat-label>{{ 'gateway.rpc.valueExpression' | translate }}</mat-label>
|
||||||
<input matInput formControlName="valueExpression" placeholder="${params}"/>
|
<input matInput formControlName="valueExpression" placeholder="${params}"/>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<fieldset class="fields border" fxLayout="column" fxLayoutGap="10px" formArrayName="httpHeaders">
|
<fieldset class="fields border" fxLayout="column" fxLayoutGap="10px" formArrayName="httpHeaders">
|
||||||
<span class="fields-label">{{ 'gateway.rpc.http-headers' | translate }}</span>
|
<span class="fields-label">{{ 'gateway.rpc.httpHeaders' | translate }}</span>
|
||||||
<div class="border" fxLayout="column" fxLayoutGap="10px" *ngIf="getFormArrayControls('httpHeaders').length">
|
<div class="border" fxLayout="column" fxLayoutGap="10px" *ngIf="getFormArrayControls('httpHeaders').length">
|
||||||
<div fxLayout="row" fxLayoutGap="10px" fxLayoutAlign="center center">
|
<div fxLayout="row" fxLayoutGap="10px" fxLayoutAlign="center center">
|
||||||
<span fxFlex class="title">{{ 'gateway.rpc.header-name' | translate }}</span>
|
<span fxFlex class="title">{{ 'gateway.rpc.header-name' | translate }}</span>
|
||||||
@ -405,15 +395,14 @@
|
|||||||
</button>
|
</button>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
|
||||||
<ng-template [ngSwitchCase]="ConnectorType.REQUEST">
|
<ng-template [ngSwitchCase]="ConnectorType.REQUEST">
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>{{ 'gateway.rpc.method-filter' | translate }}</mat-label>
|
<mat-label>{{ 'gateway.rpc.methodFilter' | translate }}</mat-label>
|
||||||
<input matInput formControlName="methodFilter" placeholder="echo"/>
|
<input matInput formControlName="methodFilter" placeholder="echo"/>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<div fxFlex fxLayout="row" fxLayoutGap="10px">
|
<div fxFlex fxLayout="row" fxLayoutGap="10px">
|
||||||
<mat-form-field class="mat-block" fxFlex="33">
|
<mat-form-field class="mat-block" fxFlex="33">
|
||||||
<mat-label>{{ 'gateway.rpc.method' | translate }}</mat-label>
|
<mat-label>{{ 'gateway.rpc.httpMethod' | translate }}</mat-label>
|
||||||
<mat-select formControlName="httpMethod">
|
<mat-select formControlName="httpMethod">
|
||||||
<mat-option *ngFor="let method of hTTPMethods" [value]="method">
|
<mat-option *ngFor="let method of hTTPMethods" [value]="method">
|
||||||
{{ method }}
|
{{ method }}
|
||||||
@ -421,13 +410,13 @@
|
|||||||
</mat-select>
|
</mat-select>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<mat-form-field fxFlex>
|
<mat-form-field fxFlex>
|
||||||
<mat-label>{{ 'gateway.rpc.request-url' | translate }}</mat-label>
|
<mat-label>{{ 'gateway.rpc.requestUrlExpression' | translate }}</mat-label>
|
||||||
<input matInput formControlName="requestUrlExpression" placeholder="http://127.0.0.1:5000/my_devices"/>
|
<input matInput formControlName="requestUrlExpression" placeholder="http://127.0.0.1:5000/my_devices"/>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</div>
|
</div>
|
||||||
<div fxFlex fxLayout="row" fxLayoutGap="10px">
|
<div fxFlex fxLayout="row" fxLayoutGap="10px">
|
||||||
<mat-form-field fxFlex="33">
|
<mat-form-field fxFlex="33">
|
||||||
<mat-label>{{ 'gateway.rpc.response-timeout' | translate }}</mat-label>
|
<mat-label>{{ 'gateway.rpc.responseTimeout' | translate }}</mat-label>
|
||||||
<input matInput formControlName="responseTimeout" type="number"
|
<input matInput formControlName="responseTimeout" type="number"
|
||||||
step="1" min="10" placeholder="10"/>
|
step="1" min="10" placeholder="10"/>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
@ -443,15 +432,15 @@
|
|||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</div>
|
</div>
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>{{ 'gateway.rpc.request-value-expression' | translate }}</mat-label>
|
<mat-label>{{ 'gateway.rpc.requestValueExpression' | translate }}</mat-label>
|
||||||
<input matInput formControlName="requestValueExpression" placeholder="${params}"/>
|
<input matInput formControlName="requestValueExpression" placeholder="${params}"/>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>{{ 'gateway.rpc.response-value-expression' | translate }}</mat-label>
|
<mat-label>{{ 'gateway.rpc.responseValueExpression' | translate }}</mat-label>
|
||||||
<input matInput formControlName="responseValueExpression" placeholder="${temp}"/>
|
<input matInput formControlName="responseValueExpression" placeholder="${temp}"/>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<fieldset class="fields border" fxLayout="column" fxLayoutGap="10px" formArrayName="httpHeaders">
|
<fieldset class="fields border" fxLayout="column" fxLayoutGap="10px" formArrayName="httpHeaders">
|
||||||
<span class="fields-label">{{ 'gateway.rpc.http-headers' | translate }}</span>
|
<span class="fields-label">{{ 'gateway.rpc.httpHeaders' | translate }}</span>
|
||||||
<div class="border" fxLayout="column" fxLayoutGap="10px" *ngIf="getFormArrayControls('httpHeaders').length">
|
<div class="border" fxLayout="column" fxLayoutGap="10px" *ngIf="getFormArrayControls('httpHeaders').length">
|
||||||
<div fxLayout="row" fxLayoutGap="10px" fxLayoutAlign="center center">
|
<div fxLayout="row" fxLayoutGap="10px" fxLayoutAlign="center center">
|
||||||
<span fxFlex class="title">{{ 'gateway.rpc.header-name' | translate }}</span>
|
<span fxFlex class="title">{{ 'gateway.rpc.header-name' | translate }}</span>
|
||||||
@ -483,7 +472,6 @@
|
|||||||
</button>
|
</button>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
|
||||||
<ng-template [ngSwitchCase]="ConnectorType.OPCUA_ASYNCIO">
|
<ng-template [ngSwitchCase]="ConnectorType.OPCUA_ASYNCIO">
|
||||||
<ng-container *ngTemplateOutlet="OPCUAForm"></ng-container>
|
<ng-container *ngTemplateOutlet="OPCUAForm"></ng-container>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
@ -513,11 +501,27 @@
|
|||||||
</button>
|
</button>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
<ng-template ngSwitchDefault>
|
||||||
|
{{'dsadas'}}
|
||||||
|
<mat-form-field>
|
||||||
|
<mat-label>{{ 'gateway.statistics.command' | translate }}</mat-label>
|
||||||
|
<input matInput formControlName="command"/>
|
||||||
|
</mat-form-field>
|
||||||
|
<mat-form-field fxFlex>
|
||||||
|
<mat-label>{{ 'widget-config.datasource-parameters' | translate }}</mat-label>
|
||||||
|
<input matInput formControlName="params" type="JSON"/>
|
||||||
|
<mat-icon class="material-icons-outlined" aria-hidden="false" aria-label="help-icon"
|
||||||
|
matIconSuffix style="cursor:pointer;"
|
||||||
|
(click)="openEditJSONDialog($event)"
|
||||||
|
matTooltip="{{ 'gateway.rpc-command-edit-params' | translate }}">edit
|
||||||
|
</mat-icon>
|
||||||
|
</mat-form-field>
|
||||||
|
</ng-template>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
<div class="template-actions" fxFlex fxLayout="row" fxLayoutAlign="end center" fxLayoutGap="10px">
|
<div class="template-actions" fxFlex fxLayout="row" fxLayoutAlign="end center" fxLayoutGap="10px">
|
||||||
<button mat-raised-button
|
<button mat-raised-button
|
||||||
(click)="sendCommand.emit()"
|
(click)="save()"
|
||||||
[disabled]="commandForm.invalid">
|
[disabled]="commandForm.invalid">
|
||||||
{{ 'gateway.rpc-command-save-template' | translate }}
|
{{ 'gateway.rpc-command-save-template' | translate }}
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@ -14,27 +14,57 @@
|
|||||||
/// limitations under the License.
|
/// limitations under the License.
|
||||||
///
|
///
|
||||||
|
|
||||||
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
import { Component, EventEmitter, forwardRef, Input, OnInit, Output } from '@angular/core';
|
||||||
import { FormArray, FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';
|
|
||||||
import {
|
import {
|
||||||
BACnetObjectTypes, BACnetObjectTypesTranslates,
|
ControlValueAccessor,
|
||||||
BACnetRequestTypes, BACnetRequestTypesTranslates, BLEMethods, BLEMethodsTranslates,
|
FormArray,
|
||||||
|
FormBuilder,
|
||||||
|
FormControl,
|
||||||
|
FormGroup,
|
||||||
|
NG_VALUE_ACCESSOR,
|
||||||
|
Validators
|
||||||
|
} from '@angular/forms';
|
||||||
|
import {
|
||||||
|
BACnetObjectTypes,
|
||||||
|
BACnetObjectTypesTranslates,
|
||||||
|
BACnetRequestTypes,
|
||||||
|
BACnetRequestTypesTranslates,
|
||||||
|
BLEMethods,
|
||||||
|
BLEMethodsTranslates,
|
||||||
CANByteOrders,
|
CANByteOrders,
|
||||||
ConnectorType, GatewayConnectorDefaultTypesTranslates, HTTPMethods,
|
ConnectorType,
|
||||||
|
GatewayConnectorDefaultTypesTranslates,
|
||||||
|
HTTPMethods,
|
||||||
ModbusCommandTypes,
|
ModbusCommandTypes,
|
||||||
RPCCommand,
|
RPCCommand,
|
||||||
SNMPMethods, SNMPMethodsTranslations,
|
RPCTemplateConfig,
|
||||||
|
SNMPMethods,
|
||||||
|
SNMPMethodsTranslations,
|
||||||
SocketEncodings,
|
SocketEncodings,
|
||||||
SocketMethodProcessings, SocketMethodProcessingsTranslates
|
SocketMethodProcessings,
|
||||||
|
SocketMethodProcessingsTranslates
|
||||||
} from '@home/components/widget/lib/gateway/gateway-widget.models';
|
} from '@home/components/widget/lib/gateway/gateway-widget.models';
|
||||||
import { TranslateService } from "@ngx-translate/core";
|
import { MatDialog } from '@angular/material/dialog';
|
||||||
|
import {
|
||||||
|
JsonObjectEditDialogComponent,
|
||||||
|
JsonObjectEditDialogData
|
||||||
|
} from '@shared/components/dialog/json-object-edit-dialog.component';
|
||||||
|
import { jsonRequired } from '@shared/components/json-object-edit.component';
|
||||||
|
import { deepClone } from '@core/utils';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'tb-gateway-service-rpc-connector',
|
selector: 'tb-gateway-service-rpc-connector',
|
||||||
templateUrl: './gateway-service-rpc-connector.component.html',
|
templateUrl: './gateway-service-rpc-connector.component.html',
|
||||||
styleUrls: ['./gateway-service-rpc-connector.component.scss']
|
styleUrls: ['./gateway-service-rpc-connector.component.scss'],
|
||||||
|
providers: [
|
||||||
|
{
|
||||||
|
provide: NG_VALUE_ACCESSOR,
|
||||||
|
useExisting: forwardRef(() => GatewayServiceRPCConnectorComponent),
|
||||||
|
multi: true
|
||||||
|
}
|
||||||
|
]
|
||||||
})
|
})
|
||||||
export class GatewayServiceRPCConnectorComponent implements OnInit {
|
export class GatewayServiceRPCConnectorComponent implements OnInit, ControlValueAccessor {
|
||||||
|
|
||||||
@Input()
|
@Input()
|
||||||
connectorType: ConnectorType;
|
connectorType: ConnectorType;
|
||||||
@ -42,6 +72,9 @@ export class GatewayServiceRPCConnectorComponent implements OnInit {
|
|||||||
@Output()
|
@Output()
|
||||||
sendCommand: EventEmitter<RPCCommand> = new EventEmitter();
|
sendCommand: EventEmitter<RPCCommand> = new EventEmitter();
|
||||||
|
|
||||||
|
@Output()
|
||||||
|
saveTemplate: EventEmitter<RPCTemplateConfig> = new EventEmitter();
|
||||||
|
|
||||||
commandForm: FormGroup;
|
commandForm: FormGroup;
|
||||||
|
|
||||||
codesArray: Array<number> = [1, 2, 3, 4, 5, 6, 15, 16];
|
codesArray: Array<number> = [1, 2, 3, 4, 5, 6, 15, 16];
|
||||||
@ -74,14 +107,41 @@ export class GatewayServiceRPCConnectorComponent implements OnInit {
|
|||||||
'(\\#[-a-z\\d_]*)?$', // fragment locator
|
'(\\#[-a-z\\d_]*)?$', // fragment locator
|
||||||
'i'
|
'i'
|
||||||
);
|
);
|
||||||
|
private propagateChange = (v: any) => {
|
||||||
|
}
|
||||||
|
|
||||||
constructor(private fb: FormBuilder,
|
constructor(private fb: FormBuilder,
|
||||||
private translate: TranslateService) {
|
private dialog: MatDialog,) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.commandForm = this.connectorParamsFormGroupByType(this.connectorType)
|
this.commandForm = this.connectorParamsFormGroupByType(this.connectorType);
|
||||||
|
this.commandForm.valueChanges.subscribe(value => {
|
||||||
|
const httpHeaders = {};
|
||||||
|
const security = {};
|
||||||
|
switch (this.connectorType) {
|
||||||
|
case ConnectorType.REST:
|
||||||
|
value.httpHeaders.forEach(data => {
|
||||||
|
httpHeaders[data.headerName] = data.value;
|
||||||
|
})
|
||||||
|
value.httpHeaders = httpHeaders;
|
||||||
|
value.security.forEach(data => {
|
||||||
|
security[data.securityName] = data.value;
|
||||||
|
})
|
||||||
|
value.security = security;
|
||||||
|
break;
|
||||||
|
case ConnectorType.REQUEST:
|
||||||
|
value.httpHeaders.forEach(data => {
|
||||||
|
httpHeaders[data.headerName] = data.value;
|
||||||
|
})
|
||||||
|
value.httpHeaders = httpHeaders;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (this.commandForm.valid) {
|
||||||
|
this.propagateChange({...this.commandForm.value,...value});
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
connectorParamsFormGroupByType(type: ConnectorType): FormGroup {
|
connectorParamsFormGroupByType(type: ConnectorType): FormGroup {
|
||||||
@ -206,6 +266,13 @@ export class GatewayServiceRPCConnectorComponent implements OnInit {
|
|||||||
method: [null, [Validators.required]],
|
method: [null, [Validators.required]],
|
||||||
arguments: this.fb.array([]),
|
arguments: this.fb.array([]),
|
||||||
})
|
})
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
formGroup = this.fb.group({
|
||||||
|
command: [null, [Validators.required]],
|
||||||
|
params: ['{}', [jsonRequired]],
|
||||||
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
return formGroup;
|
return formGroup;
|
||||||
}
|
}
|
||||||
@ -213,7 +280,7 @@ export class GatewayServiceRPCConnectorComponent implements OnInit {
|
|||||||
addSNMPoid(value: string = null) {
|
addSNMPoid(value: string = null) {
|
||||||
const oidsFA = this.commandForm.get('oid') as FormArray;
|
const oidsFA = this.commandForm.get('oid') as FormArray;
|
||||||
if (oidsFA) {
|
if (oidsFA) {
|
||||||
oidsFA.push(this.fb.control(value, [Validators.required]));
|
oidsFA.push(this.fb.control(value, [Validators.required]), {emitEvent: false});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -229,7 +296,7 @@ export class GatewayServiceRPCConnectorComponent implements OnInit {
|
|||||||
value: [value.value, [Validators.required]]
|
value: [value.value, [Validators.required]]
|
||||||
})
|
})
|
||||||
if (headerFA) {
|
if (headerFA) {
|
||||||
headerFA.push(formGroup);
|
headerFA.push(formGroup, {emitEvent: false});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -245,7 +312,7 @@ export class GatewayServiceRPCConnectorComponent implements OnInit {
|
|||||||
value: [value.value, [Validators.required]]
|
value: [value.value, [Validators.required]]
|
||||||
})
|
})
|
||||||
if (securityFA) {
|
if (securityFA) {
|
||||||
securityFA.push(formGroup);
|
securityFA.push(formGroup, {emitEvent: false});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -261,7 +328,7 @@ export class GatewayServiceRPCConnectorComponent implements OnInit {
|
|||||||
addOCPUAArguments(value: string = null) {
|
addOCPUAArguments(value: string = null) {
|
||||||
const oidsFA = this.commandForm.get('arguments') as FormArray;
|
const oidsFA = this.commandForm.get('arguments') as FormArray;
|
||||||
if (oidsFA) {
|
if (oidsFA) {
|
||||||
oidsFA.push(this.fb.control(value));
|
oidsFA.push(this.fb.control(value), {emitEvent: false});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -269,4 +336,86 @@ export class GatewayServiceRPCConnectorComponent implements OnInit {
|
|||||||
const oidsFA = this.commandForm.get('arguments') as FormArray;
|
const oidsFA = this.commandForm.get('arguments') as FormArray;
|
||||||
oidsFA.removeAt(index);
|
oidsFA.removeAt(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
openEditJSONDialog($event: Event) {
|
||||||
|
if ($event) {
|
||||||
|
$event.stopPropagation();
|
||||||
|
}
|
||||||
|
this.dialog.open<JsonObjectEditDialogComponent, JsonObjectEditDialogData, object>(JsonObjectEditDialogComponent, {
|
||||||
|
disableClose: true,
|
||||||
|
panelClass: ['tb-dialog', 'tb-fullscreen-dialog'],
|
||||||
|
data: {
|
||||||
|
jsonValue: JSON.parse(this.commandForm.get('params').value),
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
}).afterClosed().subscribe(
|
||||||
|
(res) => {
|
||||||
|
if (res) {
|
||||||
|
this.commandForm.get('params').setValue(JSON.stringify(res));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
save() {
|
||||||
|
this.saveTemplate.emit();
|
||||||
|
}
|
||||||
|
|
||||||
|
registerOnChange(fn: any): void {
|
||||||
|
this.propagateChange = fn;
|
||||||
|
}
|
||||||
|
|
||||||
|
registerOnTouched(fn: any): void {
|
||||||
|
}
|
||||||
|
|
||||||
|
clearFromArrayByName(name: string) {
|
||||||
|
const formArray = this.commandForm.get(name) as FormArray;
|
||||||
|
while (formArray.length !== 0) {
|
||||||
|
formArray.removeAt(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
writeValue(value: RPCTemplateConfig): void {
|
||||||
|
if (typeof value == "object") {
|
||||||
|
value = deepClone(value);
|
||||||
|
switch (this.connectorType) {
|
||||||
|
case ConnectorType.SNMP:
|
||||||
|
this.clearFromArrayByName("oids");
|
||||||
|
value.oids.forEach(value => {
|
||||||
|
this.addSNMPoid(value)
|
||||||
|
})
|
||||||
|
delete value.oids;
|
||||||
|
break;
|
||||||
|
case ConnectorType.REQUEST:
|
||||||
|
this.clearFromArrayByName("httpHeaders");
|
||||||
|
value.httpHeaders && Object.entries(value.httpHeaders).forEach(httpHeader => {
|
||||||
|
this.addHTTPHeader({headerName: httpHeader[0], value: httpHeader[1] as string})
|
||||||
|
})
|
||||||
|
delete value.httpHeaders;
|
||||||
|
break;
|
||||||
|
case ConnectorType.REST:
|
||||||
|
this.clearFromArrayByName("httpHeaders");
|
||||||
|
this.clearFromArrayByName("security");
|
||||||
|
value.security && Object.entries(value.security).forEach(securityHeader => {
|
||||||
|
this.addHTTPSecurity({securityName: securityHeader[0], value: securityHeader[1] as string})
|
||||||
|
})
|
||||||
|
delete value.security;
|
||||||
|
value.httpHeaders && Object.entries(value.httpHeaders).forEach(httpHeader => {
|
||||||
|
this.addHTTPHeader({headerName: httpHeader[0], value: httpHeader[1] as string})
|
||||||
|
})
|
||||||
|
delete value.httpHeaders;
|
||||||
|
break;
|
||||||
|
case ConnectorType.OPCUA:
|
||||||
|
case ConnectorType.OPCUA_ASYNCIO:
|
||||||
|
this.clearFromArrayByName("arguments");
|
||||||
|
value.arguments.forEach(value => {
|
||||||
|
this.addOCPUAArguments(value)
|
||||||
|
})
|
||||||
|
delete value.arguments;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this.commandForm.patchValue(value, {onlySelf: false});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -41,7 +41,8 @@
|
|||||||
</button>
|
</button>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
<ng-template #connectorForm>
|
<ng-template #connectorForm>
|
||||||
<tb-gateway-service-rpc-connector [connectorType]="connectorType" (sendCommand)="sendCommand()"/>
|
<tb-gateway-service-rpc-connector formControlName="params" [connectorType]="connectorType"
|
||||||
|
(sendCommand)="sendCommand()" (saveTemplate)="saveTemplate()"/>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
</div>
|
</div>
|
||||||
<section class="result-block" [formGroup]="commandForm">
|
<section class="result-block" [formGroup]="commandForm">
|
||||||
@ -52,4 +53,6 @@
|
|||||||
<tb-json-content [contentType]="contentTypes.JSON" readonly="true" formControlName="result"></tb-json-content>
|
<tb-json-content [contentType]="contentTypes.JSON" readonly="true" formControlName="result"></tb-json-content>
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
<tb-gateway-service-rpc-connector-templates fxFlex="30" *ngIf="isConnector" class="border"></tb-gateway-service-rpc-connector-templates>
|
<tb-gateway-service-rpc-connector-templates fxFlex="30" *ngIf="isConnector" class="border" [rpcTemplates]="templates"
|
||||||
|
[ctx]="ctx" [connectorType]="connectorType" (useTemplate)="useTemplate($event)">
|
||||||
|
</tb-gateway-service-rpc-connector-templates>
|
||||||
|
|||||||
@ -14,17 +14,28 @@
|
|||||||
/// limitations under the License.
|
/// limitations under the License.
|
||||||
///
|
///
|
||||||
|
|
||||||
import { OnInit, Component, Input } from '@angular/core';
|
import { ChangeDetectorRef, Component, Input, OnInit } from '@angular/core';
|
||||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||||
import { MatDialog, MatDialogRef } from '@angular/material/dialog';
|
import { MatDialog, MatDialogRef } from '@angular/material/dialog';
|
||||||
import { WidgetContext } from '@home/models/widget-component.models';
|
import { WidgetContext } from '@home/models/widget-component.models';
|
||||||
import { ContentType } from '@shared/models/constants';
|
import { ContentType } from '@shared/models/constants';
|
||||||
import {
|
|
||||||
JsonObjectEditDialogComponent,
|
|
||||||
JsonObjectEditDialogData
|
|
||||||
} from '@shared/components/dialog/json-object-edit-dialog.component';
|
|
||||||
import { jsonRequired } from '@shared/components/json-object-edit.component';
|
import { jsonRequired } from '@shared/components/json-object-edit.component';
|
||||||
import { ConnectorType, RPCCommand } from '@home/components/widget/lib/gateway/gateway-widget.models';
|
import {
|
||||||
|
ConnectorType,
|
||||||
|
RPCCommand,
|
||||||
|
RPCTemplate,
|
||||||
|
RPCTemplateConfig,
|
||||||
|
SaveRPCTemplateData
|
||||||
|
} from '@home/components/widget/lib/gateway/gateway-widget.models';
|
||||||
|
import {
|
||||||
|
GatewayServiceRPCConnectorTemplateDialogComponent
|
||||||
|
} from '@home/components/widget/lib/gateway/gateway-service-rpc-connector-template-dialog';
|
||||||
|
import { AttributeService } from '@core/http/attribute.service';
|
||||||
|
import { AttributeScope } from '@shared/models/telemetry/telemetry.models';
|
||||||
|
import { EntityType } from '@shared/models/entity-type.models';
|
||||||
|
import { DatasourceType, widgetType } from '@shared/models/widget.models';
|
||||||
|
import { IWidgetSubscription, WidgetSubscriptionOptions } from '@core/api/widget-api.models';
|
||||||
|
import { UtilsService } from '@core/services/utils.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'tb-gateway-service-rpc',
|
selector: 'tb-gateway-service-rpc',
|
||||||
@ -58,9 +69,27 @@ export class GatewayServiceRPCComponent implements OnInit {
|
|||||||
];
|
];
|
||||||
|
|
||||||
public connectorType: ConnectorType;
|
public connectorType: ConnectorType;
|
||||||
|
public templates: Array<RPCTemplate> = [];
|
||||||
|
|
||||||
|
private subscription: IWidgetSubscription;
|
||||||
|
private subscriptionOptions: WidgetSubscriptionOptions = {
|
||||||
|
callbacks: {
|
||||||
|
onDataUpdated: () => this.ctx.ngZone.run(() => {
|
||||||
|
this.updateTemplates()
|
||||||
|
}),
|
||||||
|
onDataUpdateError: (subscription, e) => this.ctx.ngZone.run(() => {
|
||||||
|
this.onDataUpdateError(e);
|
||||||
|
}),
|
||||||
|
dataLoading: () => {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
constructor(private fb: FormBuilder,
|
constructor(private fb: FormBuilder,
|
||||||
private dialog: MatDialog) {
|
private dialog: MatDialog,
|
||||||
|
private utils: UtilsService,
|
||||||
|
private cd: ChangeDetectorRef,
|
||||||
|
private attributeService: AttributeService) {
|
||||||
this.commandForm = this.fb.group({
|
this.commandForm = this.fb.group({
|
||||||
command: [null, [Validators.required]],
|
command: [null, [Validators.required]],
|
||||||
time: [60, [Validators.required, Validators.min(1)]],
|
time: [60, [Validators.required, Validators.min(1)]],
|
||||||
@ -75,6 +104,17 @@ export class GatewayServiceRPCComponent implements OnInit {
|
|||||||
this.commandForm.get('command').setValue(this.RPCCommands[0]);
|
this.commandForm.get('command').setValue(this.RPCCommands[0]);
|
||||||
} else {
|
} else {
|
||||||
this.connectorType = this.ctx.stateController.getStateParams().connector_rpc.value.type;
|
this.connectorType = this.ctx.stateController.getStateParams().connector_rpc.value.type;
|
||||||
|
const subscriptionInfo = [{
|
||||||
|
type: DatasourceType.entity,
|
||||||
|
entityType: EntityType.DEVICE,
|
||||||
|
entityId: this.ctx.defaultSubscription.targetDeviceId,
|
||||||
|
entityName: 'Connector',
|
||||||
|
attributes: [{name: `${this.connectorType}_template`}]
|
||||||
|
}];
|
||||||
|
this.ctx.subscriptionApi.createSubscriptionFromInfo(widgetType.latest, subscriptionInfo,
|
||||||
|
this.subscriptionOptions, false, true).subscribe(subscription => {
|
||||||
|
this.subscription = subscription;
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,7 +122,9 @@ export class GatewayServiceRPCComponent implements OnInit {
|
|||||||
this.resultTime = null;
|
this.resultTime = null;
|
||||||
const formValues = value || this.commandForm.value;
|
const formValues = value || this.commandForm.value;
|
||||||
const commandPrefix = this.isConnector ? `${this.connectorType}_` : 'gateway_';
|
const commandPrefix = this.isConnector ? `${this.connectorType}_` : 'gateway_';
|
||||||
this.ctx.controlApi.sendTwoWayCommand(commandPrefix + formValues.command.toLowerCase(), formValues.params, formValues.time).subscribe({
|
const command = !this.isConnector ? formValues.command.toLowerCase() : this.getCommandFromParamsByType(formValues.params);
|
||||||
|
const params = formValues.params;
|
||||||
|
this.ctx.controlApi.sendTwoWayCommand(commandPrefix + command, params, formValues.time).subscribe({
|
||||||
next: resp => {
|
next: resp => {
|
||||||
this.resultTime = new Date().getTime();
|
this.resultTime = new Date().getTime();
|
||||||
this.commandForm.get('result').setValue(JSON.stringify(resp))
|
this.commandForm.get('result').setValue(JSON.stringify(resp))
|
||||||
@ -95,23 +137,86 @@ export class GatewayServiceRPCComponent implements OnInit {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
openEditJSONDialog($event: Event) {
|
getCommandFromParamsByType(params: RPCTemplateConfig) {
|
||||||
if ($event) {
|
switch (this.connectorType) {
|
||||||
$event.stopPropagation();
|
case ConnectorType.MQTT:
|
||||||
|
case ConnectorType.FTP:
|
||||||
|
case ConnectorType.SNMP:
|
||||||
|
case ConnectorType.REST:
|
||||||
|
case ConnectorType.REQUEST:
|
||||||
|
return params.methodFilter;
|
||||||
|
case ConnectorType.MODBUS:
|
||||||
|
return params.tag;
|
||||||
|
case ConnectorType.BACNET:
|
||||||
|
case ConnectorType.CAN:
|
||||||
|
case ConnectorType.OPCUA:
|
||||||
|
case ConnectorType.OPCUA_ASYNCIO:
|
||||||
|
return params.method;
|
||||||
|
case ConnectorType.BLE:
|
||||||
|
case ConnectorType.OCPP:
|
||||||
|
case ConnectorType.SOCKET:
|
||||||
|
case ConnectorType.XMPP:
|
||||||
|
return params.methodRPC;
|
||||||
|
default:
|
||||||
|
return params.command;
|
||||||
}
|
}
|
||||||
this.dialog.open<JsonObjectEditDialogComponent, JsonObjectEditDialogData, object>(JsonObjectEditDialogComponent, {
|
}
|
||||||
|
|
||||||
|
saveTemplate() {
|
||||||
|
this.dialog.open<GatewayServiceRPCConnectorTemplateDialogComponent, SaveRPCTemplateData>
|
||||||
|
(GatewayServiceRPCConnectorTemplateDialogComponent, {
|
||||||
disableClose: true,
|
disableClose: true,
|
||||||
panelClass: ['tb-dialog', 'tb-fullscreen-dialog'],
|
panelClass: ['tb-dialog', 'tb-fullscreen-dialog'],
|
||||||
data: {
|
data: {config: this.commandForm.value.params, templates: this.templates}
|
||||||
jsonValue: JSON.parse(this.commandForm.get('params').value),
|
|
||||||
required: true
|
|
||||||
}
|
|
||||||
}).afterClosed().subscribe(
|
}).afterClosed().subscribe(
|
||||||
(res) => {
|
(res) => {
|
||||||
if (res) {
|
const templateAttribute: RPCTemplate = {
|
||||||
this.commandForm.get('params').setValue(JSON.stringify(res));
|
name: res,
|
||||||
|
config: this.commandForm.value.params
|
||||||
}
|
}
|
||||||
|
const templatesArray = this.templates;
|
||||||
|
const existingIndex = templatesArray.findIndex(template=>{
|
||||||
|
return template.name == templateAttribute.name;
|
||||||
|
})
|
||||||
|
if (existingIndex > -1 ){
|
||||||
|
templatesArray.splice(existingIndex, 1)
|
||||||
|
}
|
||||||
|
templatesArray.push(templateAttribute)
|
||||||
|
const key = `${this.connectorType}_template`;
|
||||||
|
this.attributeService.saveEntityAttributes(
|
||||||
|
{
|
||||||
|
id: this.ctx.defaultSubscription.targetDeviceId,
|
||||||
|
entityType: EntityType.DEVICE
|
||||||
|
}
|
||||||
|
, AttributeScope.SERVER_SCOPE, [{
|
||||||
|
key,
|
||||||
|
value: templatesArray
|
||||||
|
}]).subscribe(() => {
|
||||||
|
})
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
useTemplate($event) {
|
||||||
|
this.commandForm.get('params').patchValue($event.config);
|
||||||
|
}
|
||||||
|
|
||||||
|
private updateTemplates() {
|
||||||
|
this.templates = this.subscription.data[0].data[0][1].length ?
|
||||||
|
JSON.parse(this.subscription.data[0].data[0][1]) : [];
|
||||||
|
if (this.templates.length && this.commandForm.get('params').value == "{}") {
|
||||||
|
this.commandForm.get('params').patchValue(this.templates[0].config);
|
||||||
|
}
|
||||||
|
this.cd.detectChanges();
|
||||||
|
}
|
||||||
|
|
||||||
|
private onDataUpdateError(e: any) {
|
||||||
|
const exceptionData = this.utils.parseException(e);
|
||||||
|
let errorText = exceptionData.name;
|
||||||
|
if (exceptionData.message) {
|
||||||
|
errorText += ': ' + exceptionData.message;
|
||||||
|
}
|
||||||
|
console.error(errorText);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -261,10 +261,17 @@ export enum SocketEncodings {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface RPCTemplate {
|
export interface RPCTemplate {
|
||||||
name: string;
|
name?: string;
|
||||||
config: {
|
config: RPCTemplateConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RPCTemplateConfig {
|
||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
};
|
}
|
||||||
|
|
||||||
|
export interface SaveRPCTemplateData {
|
||||||
|
config: RPCTemplateConfig,
|
||||||
|
templates: Array<RPCTemplate>
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface LogLink {
|
export interface LogLink {
|
||||||
|
|||||||
@ -74,6 +74,9 @@ import { ValueChartCardWidgetComponent } from '@home/components/widget/lib/cards
|
|||||||
import { ProgressBarWidgetComponent } from '@home/components/widget/lib/cards/progress-bar-widget.component';
|
import { ProgressBarWidgetComponent } from '@home/components/widget/lib/cards/progress-bar-widget.component';
|
||||||
import { LiquidLevelWidgetComponent } from '@home/components/widget/lib/indicator/liquid-level-widget.component';
|
import { LiquidLevelWidgetComponent } from '@home/components/widget/lib/indicator/liquid-level-widget.component';
|
||||||
import { DoughnutWidgetComponent } from '@home/components/widget/lib/chart/doughnut-widget.component';
|
import { DoughnutWidgetComponent } from '@home/components/widget/lib/chart/doughnut-widget.component';
|
||||||
|
import {
|
||||||
|
GatewayServiceRPCConnectorTemplateDialogComponent
|
||||||
|
} from '@home/components/widget/lib/gateway/gateway-service-rpc-connector-template-dialog';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations:
|
declarations:
|
||||||
@ -107,6 +110,7 @@ import { DoughnutWidgetComponent } from '@home/components/widget/lib/chart/dough
|
|||||||
DeviceGatewayCommandComponent,
|
DeviceGatewayCommandComponent,
|
||||||
GatewayConfigurationComponent,
|
GatewayConfigurationComponent,
|
||||||
GatewayRemoteConfigurationDialogComponent,
|
GatewayRemoteConfigurationDialogComponent,
|
||||||
|
GatewayServiceRPCConnectorTemplateDialogComponent,
|
||||||
ValueCardWidgetComponent,
|
ValueCardWidgetComponent,
|
||||||
AggregatedValueCardWidgetComponent,
|
AggregatedValueCardWidgetComponent,
|
||||||
CountWidgetComponent,
|
CountWidgetComponent,
|
||||||
@ -154,6 +158,7 @@ import { DoughnutWidgetComponent } from '@home/components/widget/lib/chart/dough
|
|||||||
DeviceGatewayCommandComponent,
|
DeviceGatewayCommandComponent,
|
||||||
GatewayConfigurationComponent,
|
GatewayConfigurationComponent,
|
||||||
GatewayRemoteConfigurationDialogComponent,
|
GatewayRemoteConfigurationDialogComponent,
|
||||||
|
GatewayServiceRPCConnectorTemplateDialogComponent,
|
||||||
ValueCardWidgetComponent,
|
ValueCardWidgetComponent,
|
||||||
AggregatedValueCardWidgetComponent,
|
AggregatedValueCardWidgetComponent,
|
||||||
CountWidgetComponent,
|
CountWidgetComponent,
|
||||||
|
|||||||
@ -2776,54 +2776,54 @@
|
|||||||
"rpc": {
|
"rpc": {
|
||||||
"title": "{{type}} Connector RPC parameters",
|
"title": "{{type}} Connector RPC parameters",
|
||||||
"templates-title": "Connector RPC Templates",
|
"templates-title": "Connector RPC Templates",
|
||||||
"method-filter": "Method filter",
|
"methodFilter": "Method filter",
|
||||||
"request-topic-expression": "Request topic expression",
|
"requestTopicExpression": "Request topic expression",
|
||||||
"response-topic-expression": "Response topic expression",
|
"responseTopicExpression": "Response topic expression",
|
||||||
"response-timeout": "Response Time",
|
"responseTimeout": "Response Time",
|
||||||
"value-expression": "Value Expression",
|
"valueExpression": "Value Expression",
|
||||||
"tag": "Tag",
|
"tag": "Tag",
|
||||||
"type": "Type",
|
"type": "Type",
|
||||||
"function-code": "Function Code",
|
"functionCode": "Function Code",
|
||||||
"objects-count": "Objects Count",
|
"objectsCount": "Objects Count",
|
||||||
"address": "Address",
|
"address": "Address",
|
||||||
"method": "Method",
|
"method": "Method",
|
||||||
"request-type": "Request Type",
|
"requestType": "Request Type",
|
||||||
"request-timeout": "Request Timeout",
|
"requestTimeout": "Request Timeout",
|
||||||
"object-type": "Object type",
|
"objectType": "Object type",
|
||||||
"identifier": "Identifier",
|
"identifier": "Identifier",
|
||||||
"property-id": "Property ID",
|
"propertyId": "Property ID",
|
||||||
"method-rpc": "Method RPC name",
|
"methodRPC": "Method RPC name",
|
||||||
"with-response": "With Response",
|
"withResponse": "With Response",
|
||||||
"characteristic-uuid": "Characteristic UUID",
|
"characteristicUUID": "Characteristic UUID",
|
||||||
"method-processing": "Method Processing",
|
"methodProcessing": "Method Processing",
|
||||||
"node-id": "Node ID",
|
"nodeID": "Node ID",
|
||||||
"is-extended-id": "Is Extended ID",
|
"isExtendedID": "Is Extended ID",
|
||||||
"is-fd": "Is FD",
|
"isFD": "Is FD",
|
||||||
"bitrate-switch": "Bitrate Switch",
|
"bitrateSwitch": "Bitrate Switch",
|
||||||
"data-in-hex": "Data In HEX",
|
"dataInHEX": "Data In HEX",
|
||||||
"data-length": "Data Length",
|
"dataLength": "Data Length",
|
||||||
"data-byte-order": "Data Byte Order",
|
"dataByteorder": "Data Byte Order",
|
||||||
"data-before": "Data Before",
|
"dataBefore": "Data Before",
|
||||||
"data-after": "Data After",
|
"dataAfter": "Data After",
|
||||||
"data-expression": "Data Expression",
|
"dataExpression": "Data Expression",
|
||||||
"encoding": "Encoding",
|
"encoding": "Encoding",
|
||||||
"oid": "OID",
|
"oid": "OID",
|
||||||
"add-oid": "Add OID",
|
"add-oid": "Add OID",
|
||||||
"add-header": "Add header",
|
"add-header": "Add header",
|
||||||
"add-security": "Add security",
|
"add-security": "Add security",
|
||||||
"remove": "Remove",
|
"remove": "Remove",
|
||||||
"request-filter": "Request Filter",
|
"requestFilter": "Request Filter",
|
||||||
"request-url": "Request URL Expression",
|
"requestUrlExpression": "Request URL Expression",
|
||||||
"http-method": "HTTP Method",
|
"HTTPMethod": "HTTP Method",
|
||||||
"timeout": "Timeout",
|
"timeout": "Timeout",
|
||||||
"tries": "Tries",
|
"tries": "Tries",
|
||||||
"http-headers": "HTTP Headers",
|
"httpHeaders": "HTTP Headers",
|
||||||
"header-name": "Header name",
|
"header-name": "Header name",
|
||||||
"security-name": "Security name",
|
"security-name": "Security name",
|
||||||
"value": "Value",
|
"value": "Value",
|
||||||
"security": "Security",
|
"security": "Security",
|
||||||
"response-value-expression": "Response Value Expression",
|
"responseValueExpression": "Response Value Expression",
|
||||||
"request-value-expression": "Request Value Expression",
|
"requestValueExpression": "Request Value Expression",
|
||||||
"arguments": "Arguments",
|
"arguments": "Arguments",
|
||||||
"add-argument": "Add argument",
|
"add-argument": "Add argument",
|
||||||
"write-property": "Write property",
|
"write-property": "Write property",
|
||||||
@ -2843,7 +2843,12 @@
|
|||||||
"multi-get": "Multiget",
|
"multi-get": "Multiget",
|
||||||
"get-next": "Get next",
|
"get-next": "Get next",
|
||||||
"bulk-get": "Bulk get",
|
"bulk-get": "Bulk get",
|
||||||
"walk": "Walk"
|
"walk": "Walk",
|
||||||
|
"save-template": "Save template",
|
||||||
|
"template-name": "Template name",
|
||||||
|
"template-name-required": "Template name is required.",
|
||||||
|
"template-name-duplicate": "The name is already used."
|
||||||
|
|
||||||
|
|
||||||
},
|
},
|
||||||
"other": "Other",
|
"other": "Other",
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user