functionality adjustments

This commit is contained in:
mpetrov 2024-07-23 17:59:18 +03:00
parent 84bcc9a5ea
commit 3a9a654fd2
9 changed files with 290 additions and 252 deletions

View File

@ -62,6 +62,13 @@ import { ModbusMasterTableComponent } from '../modbus-master-table/modbus-master
:host {
height: 100%;
}
:host ::ng-deep {
.mat-mdc-tab-body-content {
overflow: hidden !important;
}
}
:host ::ng-deep {
.mat-mdc-tab-group, .mat-mdc-tab-body-wrapper {
height: 100%;

View File

@ -15,243 +15,251 @@
limitations under the License.
-->
<div class="tb-form-panel no-border no-padding padding-top" [formGroup]="slaveConfigFormGroup">
<div class="tb-form-hint tb-primary-fill tb-flex center">{{ 'gateway.hints.modbus-server' | translate }}</div>
<div class="tb-form-row" fxLayoutAlign="space-between center">
<mat-slide-toggle class="mat-slide" formControlName="sendDataToThingsBoard">
<mat-label>
{{ 'gateway.enable' | translate }}
</mat-label>
</mat-slide-toggle>
</div>
<div class="tb-flex row space-between align-center no-gap fill-width">
<div class="fixed-title-width" translate>gateway.server-slave-config</div>
<tb-toggle-select formControlName="type" appearance="fill">
<tb-toggle-option *ngFor="let type of modbusProtocolTypes" [value]="type">{{ ModbusProtocolLabelsMap.get(type) }}</tb-toggle-option>
</tb-toggle-select>
</div>
<div [formGroup]="slaveConfigFormGroup" class="slave-container">
<div class="tb-form-panel no-border no-padding padding-top">
<div *ngIf="this.slaveConfigFormGroup.get('type').value !== ModbusProtocolType.Serial"
class="tb-form-row column-xs"
fxLayoutAlign="space-between center"
>
<div class="fixed-title-width tb-required" translate>gateway.host</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" formControlName="host" placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
matTooltipPosition="above"
matTooltipClass="tb-error-tooltip"
[matTooltip]="('gateway.host-required') | translate"
*ngIf="slaveConfigFormGroup.get('host').hasError('required')
&& slaveConfigFormGroup.get('host').touched"
class="tb-error">
warning
</mat-icon>
</mat-form-field>
</div>
<div class="tb-form-hint tb-primary-fill tb-flex center">{{ 'gateway.hints.modbus-server' | translate }}</div>
<div class="tb-form-row" fxLayoutAlign="space-between center">
<mat-slide-toggle class="mat-slide" formControlName="sendDataToThingsBoard">
<mat-label>
{{ 'gateway.enable' | translate }}
</mat-label>
</mat-slide-toggle>
</div>
<div *ngIf="this.slaveConfigFormGroup.get('type').value !== ModbusProtocolType.Serial else serialPort"
class="tb-form-row column-xs"
fxLayoutAlign="space-between center"
>
<div class="fixed-title-width tb-required" translate>gateway.port</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput type="number" min="{{portLimits.MIN}}" max="{{portLimits.MAX}}"
name="value" formControlName="port" placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
matTooltipPosition="above"
matTooltipClass="tb-error-tooltip"
[matTooltip]="slaveConfigFormGroup.get('port') | getGatewayPortTooltip"
*ngIf="(slaveConfigFormGroup.get('port').hasError('required') ||
slaveConfigFormGroup.get('port').hasError('min') ||
slaveConfigFormGroup.get('port').hasError('max')) &&
slaveConfigFormGroup.get('port').touched"
class="tb-error">
warning
</mat-icon>
</mat-form-field>
</div>
</div>
<div class="slave-content tb-form-panel no-border no-padding padding-top" >
<div class="tb-flex row space-between align-center no-gap fill-width">
<div class="fixed-title-width" translate>gateway.server-slave-config</div>
<tb-toggle-select formControlName="type" appearance="fill">
<tb-toggle-option *ngFor="let type of modbusProtocolTypes" [value]="type">{{ ModbusProtocolLabelsMap.get(type) }}</tb-toggle-option>
</tb-toggle-select>
</div>
<ng-template #serialPort>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="fixed-title-width tb-required" translate>gateway.port</div>
<div class="tb-form-panel no-border no-padding padding-top">
<div *ngIf="this.slaveConfigFormGroup.get('type').value !== ModbusProtocolType.Serial"
class="tb-form-row column-xs"
fxLayoutAlign="space-between center"
>
<div class="fixed-title-width tb-required" translate>gateway.host</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" formControlName="serialPort" placeholder="{{ 'gateway.set' | translate }}"/>
<input matInput name="value" formControlName="host" placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
matTooltipPosition="above"
matTooltipClass="tb-error-tooltip"
[matTooltip]="slaveConfigFormGroup.get('serialPort') | getGatewayPortTooltip"
*ngIf="(slaveConfigFormGroup.get('serialPort').hasError('required') ||
slaveConfigFormGroup.get('serialPort').hasError('min') ||
slaveConfigFormGroup.get('serialPort').hasError('max')) &&
slaveConfigFormGroup.get('serialPort').touched"
[matTooltip]="('gateway.host-required') | translate"
*ngIf="slaveConfigFormGroup.get('host').hasError('required')
&& slaveConfigFormGroup.get('host').touched"
class="tb-error">
warning
</mat-icon>
</mat-form-field>
</div>
</div>
</ng-template>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="fixed-title-width" tb-hint-tooltip-icon="{{ 'gateway.hints.framer-type' | translate }}" translate>
gateway.method
</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<mat-select formControlName="method">
<mat-option *ngFor="let method of slaveConfigFormGroup.get('type').value === ModbusProtocolType.Serial ? modbusSerialMethodTypes : modbusMethodTypes"
[value]="method">{{ ModbusMethodLabelsMap.get(method) }}</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>
</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="fixed-title-width tb-required" translate>gateway.unit-id</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput type="number" min="0" name="value" formControlName="unitId" placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
matTooltipPosition="above"
matTooltipClass="tb-error-tooltip"
[matTooltip]="('gateway.unit-id-required') | translate"
*ngIf="slaveConfigFormGroup.get('unitId').hasError('required') &&
slaveConfigFormGroup.get('unitId').touched"
class="tb-error">
warning
</mat-icon>
</mat-form-field>
</div>
</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="fixed-title-width tb-required" translate>gateway.device-name</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" formControlName="deviceName" placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
matTooltipPosition="above"
matTooltipClass="tb-error-tooltip"
[matTooltip]="('gateway.device-name-required') | translate"
*ngIf="slaveConfigFormGroup.get('deviceName').hasError('required') &&
slaveConfigFormGroup.get('deviceName').touched"
class="tb-error">
warning
</mat-icon>
</mat-form-field>
</div>
</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="fixed-title-width tb-required" translate>gateway.device-profile</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" formControlName="deviceType" placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
matTooltipPosition="above"
matTooltipClass="tb-error-tooltip"
[matTooltip]="('gateway.device-profile-required') | translate"
*ngIf="slaveConfigFormGroup.get('deviceType').hasError('required') &&
slaveConfigFormGroup.get('deviceType').touched"
class="tb-error">
warning
</mat-icon>
</mat-form-field>
</div>
</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="fixed-title-width" translate>gateway.poll-period</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput type="number" min="0" name="value" formControlName="pollPeriod" placeholder="{{ 'gateway.set' | translate }}"/>
</mat-form-field>
</div>
</div>
<div *ngIf="this.slaveConfigFormGroup.get('type').value === ModbusProtocolType.Serial" class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="fixed-title-width" translate>gateway.baudrate</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput type="number" min="0" name="value" formControlName="baudrate" placeholder="{{ 'gateway.set' | translate }}"/>
</mat-form-field>
</div>
</div>
<mat-expansion-panel>
<mat-expansion-panel-header>
<mat-panel-title>
<div class="tb-form-panel-title" translate>gateway.advanced-connection-settings</div>
</mat-panel-title>
</mat-expansion-panel-header>
<div class="tb-form-panel no-border no-padding padding-top" [formGroup]="slaveConfigFormGroup">
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="fixed-title-width" translate>gateway.byte-order</div>
<div *ngIf="this.slaveConfigFormGroup.get('type').value !== ModbusProtocolType.Serial else serialPort"
class="tb-form-row column-xs"
fxLayoutAlign="space-between center"
>
<div class="fixed-title-width tb-required" translate>gateway.port</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<mat-select formControlName="byteOrder">
<mat-option *ngFor="let order of modbusOrderType" [value]="order">{{ order }}</mat-option>
<input matInput type="number" min="{{portLimits.MIN}}" max="{{portLimits.MAX}}"
name="value" formControlName="port" placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
matTooltipPosition="above"
matTooltipClass="tb-error-tooltip"
[matTooltip]="slaveConfigFormGroup.get('port') | getGatewayPortTooltip"
*ngIf="(slaveConfigFormGroup.get('port').hasError('required') ||
slaveConfigFormGroup.get('port').hasError('min') ||
slaveConfigFormGroup.get('port').hasError('max')) &&
slaveConfigFormGroup.get('port').touched"
class="tb-error">
warning
</mat-icon>
</mat-form-field>
</div>
</div>
<ng-template #serialPort>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="fixed-title-width tb-required" translate>gateway.port</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" formControlName="serialPort" placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
matTooltipPosition="above"
matTooltipClass="tb-error-tooltip"
[matTooltip]="slaveConfigFormGroup.get('serialPort') | getGatewayPortTooltip"
*ngIf="(slaveConfigFormGroup.get('serialPort').hasError('required') ||
slaveConfigFormGroup.get('serialPort').hasError('min') ||
slaveConfigFormGroup.get('serialPort').hasError('max')) &&
slaveConfigFormGroup.get('serialPort').touched"
class="tb-error">
warning
</mat-icon>
</mat-form-field>
</div>
</div>
</ng-template>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="fixed-title-width" tb-hint-tooltip-icon="{{ 'gateway.hints.framer-type' | translate }}" translate>
gateway.method
</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<mat-select formControlName="method">
<mat-option *ngFor="let method of slaveConfigFormGroup.get('type').value === ModbusProtocolType.Serial ? modbusSerialMethodTypes : modbusMethodTypes"
[value]="method">{{ ModbusMethodLabelsMap.get(method) }}</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>
<mat-expansion-panel *ngIf="this.slaveConfigFormGroup.get('type').value !== ModbusProtocolType.Serial"
[expanded]="showSecurityControl.value">
<mat-expansion-panel-header class="nested-expansion-header">
</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="fixed-title-width tb-required" translate>gateway.unit-id</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput type="number" min="0" name="value" formControlName="unitId" placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
matTooltipPosition="above"
matTooltipClass="tb-error-tooltip"
[matTooltip]="('gateway.unit-id-required') | translate"
*ngIf="slaveConfigFormGroup.get('unitId').hasError('required') &&
slaveConfigFormGroup.get('unitId').touched"
class="tb-error">
warning
</mat-icon>
</mat-form-field>
</div>
</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="fixed-title-width tb-required" translate>gateway.device-name</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" formControlName="deviceName" placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
matTooltipPosition="above"
matTooltipClass="tb-error-tooltip"
[matTooltip]="('gateway.device-name-required') | translate"
*ngIf="slaveConfigFormGroup.get('deviceName').hasError('required') &&
slaveConfigFormGroup.get('deviceName').touched"
class="tb-error">
warning
</mat-icon>
</mat-form-field>
</div>
</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="fixed-title-width tb-required" translate>gateway.device-profile</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" formControlName="deviceType" placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
matTooltipPosition="above"
matTooltipClass="tb-error-tooltip"
[matTooltip]="('gateway.device-profile-required') | translate"
*ngIf="slaveConfigFormGroup.get('deviceType').hasError('required') &&
slaveConfigFormGroup.get('deviceType').touched"
class="tb-error">
warning
</mat-icon>
</mat-form-field>
</div>
</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="fixed-title-width" translate>gateway.poll-period</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput type="number" min="0" name="value" formControlName="pollPeriod" placeholder="{{ 'gateway.set' | translate }}"/>
</mat-form-field>
</div>
</div>
<div *ngIf="this.slaveConfigFormGroup.get('type').value === ModbusProtocolType.Serial" class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="fixed-title-width" translate>gateway.baudrate</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<mat-select formControlName="baudrate">
<mat-option *ngFor="let rate of modbusBaudrates" [value]="rate">{{ rate }}</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>
<div>
<mat-expansion-panel>
<mat-expansion-panel-header>
<mat-panel-title>
<mat-slide-toggle [formControl]="showSecurityControl" class="mat-slide" (click)="$event.stopPropagation()">
<mat-label>
{{ 'gateway.tls-connection' | translate }}
</mat-label>
</mat-slide-toggle>
<div class="tb-form-panel-title" translate>gateway.advanced-connection-settings</div>
</mat-panel-title>
</mat-expansion-panel-header>
<tb-modbus-security-config formControlName="security" [isMaster]="true"></tb-modbus-security-config>
<div class="tb-form-panel no-border no-padding padding-top" [formGroup]="slaveConfigFormGroup">
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="fixed-title-width" translate>gateway.byte-order</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<mat-select formControlName="byteOrder">
<mat-option *ngFor="let order of modbusOrderType" [value]="order">{{ order }}</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>
<mat-expansion-panel *ngIf="this.slaveConfigFormGroup.get('type').value !== ModbusProtocolType.Serial"
[expanded]="showSecurityControl.value">
<mat-expansion-panel-header class="nested-expansion-header">
<mat-panel-title>
<mat-slide-toggle [formControl]="showSecurityControl" class="mat-slide" (click)="$event.stopPropagation()">
<mat-label>
{{ 'gateway.tls-connection' | translate }}
</mat-label>
</mat-slide-toggle>
</mat-panel-title>
</mat-expansion-panel-header>
<tb-modbus-security-config formControlName="security" [isMaster]="true"></tb-modbus-security-config>
</mat-expansion-panel>
<ng-container [formGroup]="slaveConfigFormGroup.get('identity')">
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="fixed-title-width" translate>gateway.vendor-name</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" formControlName="vendorName" placeholder="{{ 'gateway.set' | translate }}"/>
</mat-form-field>
</div>
</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="fixed-title-width" translate>gateway.product-code</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" formControlName="productCode" placeholder="{{ 'gateway.set' | translate }}"/>
</mat-form-field>
</div>
</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="fixed-title-width" translate>gateway.vendor-url</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" formControlName="vendorUrl" placeholder="{{ 'gateway.set' | translate }}"/>
</mat-form-field>
</div>
</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="fixed-title-width" translate>gateway.product-name</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" formControlName="productName" placeholder="{{ 'gateway.set' | translate }}"/>
</mat-form-field>
</div>
</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="fixed-title-width" translate>gateway.model-name</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" formControlName="modelName" placeholder="{{ 'gateway.set' | translate }}"/>
</mat-form-field>
</div>
</div>
</ng-container>
</div>
</mat-expansion-panel>
<ng-container [formGroup]="slaveConfigFormGroup.get('identity')">
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="fixed-title-width" translate>gateway.vendor-name</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" formControlName="vendorName" placeholder="{{ 'gateway.set' | translate }}"/>
</mat-form-field>
</div>
</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="fixed-title-width" translate>gateway.product-code</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" formControlName="productCode" placeholder="{{ 'gateway.set' | translate }}"/>
</mat-form-field>
</div>
</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="fixed-title-width" translate>gateway.vendor-url</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" formControlName="vendorUrl" placeholder="{{ 'gateway.set' | translate }}"/>
</mat-form-field>
</div>
</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="fixed-title-width" translate>gateway.product-name</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" formControlName="productName" placeholder="{{ 'gateway.set' | translate }}"/>
</mat-form-field>
</div>
</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="fixed-title-width" translate>gateway.model-name</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" formControlName="modelName" placeholder="{{ 'gateway.set' | translate }}"/>
</mat-form-field>
</div>
</div>
</ng-container>
</div>
</mat-expansion-panel>
<div class="tb-form-panel stroked">
<div class="tb-form-panel-title" translate>gateway.values</div>
<tb-modbus-values formControlName="values"></tb-modbus-values>
<div class="tb-form-panel stroked">
<div class="tb-form-panel-title" translate>gateway.values</div>
<tb-modbus-values formControlName="values"></tb-modbus-values>
</div>
</div>
</div>

View File

@ -0,0 +1,18 @@
$server-config-header-height: 132px;
:host {
.nested-expansion-header {
::ng-deep .mat-content {
height: 100%;
}
}
.slave-content {
height: calc(100% - #{$server-config-header-height});
overflow: auto;
}
.slave-container {
display: inherit;
}
}

View File

@ -27,6 +27,7 @@ import {
Validators,
} from '@angular/forms';
import {
ModbusBaudrates,
ModbusMethodLabelsMap,
ModbusMethodType,
ModbusOrderType,
@ -71,15 +72,7 @@ import { ModbusValuesComponent, } from '../modbus-values/modbus-values.component
ModbusSecurityConfigComponent,
GatewayPortTooltipPipe,
],
styles: [`
:host {
.nested-expansion-header {
.mat-content {
height: 100%;
}
}
}
`],
styleUrls: ['modbus-slave-config.component.scss'],
})
export class ModbusSlaveConfigComponent implements ControlValueAccessor, Validator, OnDestroy {
@ -94,6 +87,7 @@ export class ModbusSlaveConfigComponent implements ControlValueAccessor, Validat
readonly modbusSerialMethodTypes = Object.values(ModbusSerialMethodType);
readonly modbusOrderType = Object.values(ModbusOrderType);
readonly ModbusProtocolType = ModbusProtocolType;
readonly modbusBaudrates = ModbusBaudrates;
readonly serialSpecificControlKeys = ['serialPort', 'baudrate'];
readonly tcpUdpSpecificControlKeys = ['port', 'security', 'host'];
@ -110,11 +104,11 @@ export class ModbusSlaveConfigComponent implements ControlValueAccessor, Validat
port: [null, [Validators.required, Validators.min(PortLimits.MIN), Validators.max(PortLimits.MAX)]],
serialPort: ['', [Validators.required, Validators.pattern(noLeadTrailSpacesRegex)]],
method: [ModbusMethodType.RTU, []],
unitId: [null, [Validators.required]],
baudrate: [null, []],
unitId: [0, [Validators.required]],
baudrate: [this.ModbusProtocolType[0], []],
deviceName: ['', [Validators.required, Validators.pattern(noLeadTrailSpacesRegex)]],
deviceType: ['', [Validators.required, Validators.pattern(noLeadTrailSpacesRegex)]],
pollPeriod: [null, []],
pollPeriod: [5000, []],
sendDataToThingsBoard: [false, []],
byteOrder:[ModbusOrderType.BIG, []],
security: [],
@ -240,10 +234,10 @@ export class ModbusSlaveConfigComponent implements ControlValueAccessor, Validat
host: host ?? '',
type: type ?? ModbusProtocolType.TCP,
method: method ?? ModbusMethodType.RTU,
unitId: unitId ?? null,
unitId: unitId ?? 0,
deviceName: deviceName ?? '',
deviceType: deviceType ?? '',
pollPeriod: pollPeriod ?? null,
pollPeriod: pollPeriod ?? 5000,
sendDataToThingsBoard: !!sendDataToThingsBoard,
byteOrder: byteOrder ?? ModbusOrderType.BIG,
security: security ?? {},
@ -256,11 +250,12 @@ export class ModbusSlaveConfigComponent implements ControlValueAccessor, Validat
},
values: values ?? {} as ModbusRegisterValues,
port: port ?? null,
baudrate: baudrate ?? this.modbusBaudrates[0],
};
if (slaveConfig.type === ModbusProtocolType.Serial) {
slaveState = { ...slaveState, baudrate, serialPort: port, host: '', port: null } as ModbusSlave;
slaveState = { ...slaveState, serialPort: port, host: '', port: null } as ModbusSlave;
} else {
slaveState = { ...slaveState, serialPort: '', baudrate: null } as ModbusSlave;
slaveState = { ...slaveState, serialPort: '' } as ModbusSlave;
}
this.slaveConfigFormGroup.setValue(slaveState, {emitEvent: false});
}

View File

@ -136,7 +136,9 @@
<div class="fixed-title-width" translate>gateway.baudrate</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput type="number" min="0" name="value" formControlName="baudrate" placeholder="{{ 'gateway.set' | translate }}"/>
<mat-select formControlName="baudrate">
<mat-option *ngFor="let rate of modbusBaudrates" [value]="rate">{{ rate }}</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>
@ -162,7 +164,7 @@
<div class="fixed-title-width" translate>gateway.parity</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<mat-select formControlName="bytesize">
<mat-select formControlName="parity">
<mat-option *ngFor="let parity of modbusParities" [value]="parity">{{ ModbusParityLabelsMap.get(parity) }}</mat-option>
</mat-select>
</mat-form-field>

View File

@ -25,6 +25,7 @@ import {
} from '@angular/forms';
import {
MappingInfo,
ModbusBaudrates,
ModbusByteSizes,
ModbusMethodLabelsMap,
ModbusMethodType,
@ -100,6 +101,7 @@ export class ModbusSlaveDialogComponent extends DialogComponent<ModbusSlaveDialo
readonly modbusSerialMethodTypes = Object.values(ModbusSerialMethodType);
readonly modbusParities = Object.values(ModbusParity);
readonly modbusByteSizes = ModbusByteSizes;
readonly modbusBaudrates = ModbusBaudrates;
readonly modbusOrderType = Object.values(ModbusOrderType);
readonly ModbusProtocolType = ModbusProtocolType;
readonly ModbusParityLabelsMap = ModbusParityLabelsMap;
@ -129,25 +131,25 @@ export class ModbusSlaveDialogComponent extends DialogComponent<ModbusSlaveDialo
port: [null, [Validators.required, Validators.min(PortLimits.MIN), Validators.max(PortLimits.MAX)]],
serialPort: ['', [Validators.required, Validators.pattern(noLeadTrailSpacesRegex)]],
method: [ModbusMethodType.RTU, []],
baudrate: [null, []],
baudrate: [this.modbusBaudrates[0], []],
stopbits: [null, []],
bytesize: [ModbusByteSizes[0], []],
parity: [ModbusParity.None, []],
strict: [false, []],
unitId: [null, [Validators.required]],
unitId: [0, [Validators.required]],
deviceName: ['', [Validators.required, Validators.pattern(noLeadTrailSpacesRegex)]],
deviceType: ['', [Validators.required, Validators.pattern(noLeadTrailSpacesRegex)]],
sendDataOnlyOnChange: [false, []],
timeout: [],
timeout: [35],
byteOrder: [ModbusOrderType.BIG, []],
wordOrder: [ModbusOrderType.BIG, []],
retries: [false, []],
retryOnEmpty: [false, []],
retryOnInvalid: [false, []],
pollPeriod: [null, []],
connectAttemptTimeMs: [null, []],
connectAttemptCount: [null, []],
waitAfterFailedAttemptsMs: [null, []],
retries: [true, []],
retryOnEmpty: [true, []],
retryOnInvalid: [true, []],
pollPeriod: [5000, []],
connectAttemptTimeMs: [5000, []],
connectAttemptCount: [5, []],
waitAfterFailedAttemptsMs: [300000, []],
values: [{}, []],
security: [{}],
});

View File

@ -84,6 +84,10 @@ import { coerceBoolean } from '@shared/decorators/coercion';
min-height: 320px;
}
}
::ng-deep .mdc-evolution-chip-set__chips {
align-items: center;
}
`]
})

View File

@ -804,17 +804,17 @@ export enum ModbusOrderType {
}
export enum ModbusRegisterType {
HoldingRegister = 'holding_registers',
HoldingRegisters = 'holding_registers',
CoilsInitializer = 'coils_initializer',
InputRegister = 'input_registers',
InputRegisters = 'input_registers',
DiscreteInputs = 'discrete_inputs'
}
export const ModbusRegisterTranslationsMap = new Map<ModbusRegisterType, string>(
[
[ModbusRegisterType.HoldingRegister, 'gateway.holding_registers'],
[ModbusRegisterType.HoldingRegisters, 'gateway.holding_registers'],
[ModbusRegisterType.CoilsInitializer, 'gateway.coils_initializer'],
[ModbusRegisterType.InputRegister, 'gateway.input_registers'],
[ModbusRegisterType.InputRegisters, 'gateway.input_registers'],
[ModbusRegisterType.DiscreteInputs, 'gateway.discrete_inputs']
]
);
@ -1023,3 +1023,5 @@ export interface ModbusIdentity {
productName?: string;
modelName?: string;
}
export const ModbusBaudrates = [4800, 9600, 19200, 38400, 57600, 115200, 230400, 460800, 921600];

View File

@ -2772,7 +2772,7 @@
"delete-value": "Delete value",
"delete-rpc-method": "Delete method",
"delete-rpc-request": "Delete request",
"delete-attribute-update": "Add attribute update",
"delete-attribute-update": "Delete attribute update",
"advanced": "Advanced",
"advanced-connection-settings": "Advanced connection settings",
"attributes": "Attributes",
@ -2821,7 +2821,7 @@
"connectors-table-key": "Key",
"connectors-table-class": "Class",
"connection-timeout": "Connection timeout (s)",
"connect-attempt-time": "Connect attempt time (s)",
"connect-attempt-time": "Connect attempt time (ms)",
"connect-attempt-count": "Connect attempt count",
"copy-username": "Copy username",
"copy-password": "Copy password",
@ -2954,10 +2954,10 @@
"unit-id": "Unit ID",
"host": "Host",
"host-required": "Host is required.",
"holding_registers": "Holding register",
"holding_registers": "Holding registers",
"coils_initializer": "Coils initializer",
"input_registers": "Input register",
"discrete_inputs": "Discrete input",
"input_registers": "Input registers",
"discrete_inputs": "Discrete inputs",
"json-parse": "Not valid JSON.",
"json-required": "Field cannot be empty.",
"JSONPath-hint": "This field supports constants and JSONPath expressions.",
@ -3019,7 +3019,7 @@
"password": "Password",
"password-required": "Password is required.",
"permit-without-calls": "Keep alive permit without calls",
"poll-period": "Poll period (s)",
"poll-period": "Poll period (ms)",
"port": "Port",
"port-required": "Port is required.",
"port-limits-error": "Port should be number from {{min}} to {{max}}.",
@ -3307,7 +3307,7 @@
"exactly-once": "2 - Exactly once"
},
"objects-count": "Objects count",
"wait-after-failed-attempts": "Wait after failed attempts (s)",
"wait-after-failed-attempts": "Wait after failed attempts (ms)",
"tls-path-private-key": "Path to private key on gateway",
"toggle-fullscreen": "Toggle fullscreen",
"transformer-json-config": "Configuration JSON*",