diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-basic-config/modbus-basic-config.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-basic-config/modbus-basic-config.component.html index 109053c8a7..17f5185bc6 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-basic-config/modbus-basic-config.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-basic-config/modbus-basic-config.component.html @@ -19,10 +19,10 @@ - + - + diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-data-keys-panel/modbus-data-keys-panel.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-data-keys-panel/modbus-data-keys-panel.component.ts index ac448f703e..3f57658443 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-data-keys-panel/modbus-data-keys-panel.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-data-keys-panel/modbus-data-keys-panel.component.ts @@ -67,6 +67,7 @@ export class ModbusDataKeysPanelComponent implements OnInit { readonly ModbusFunctionCodeTranslationsMap = ModbusFunctionCodeTranslationsMap; readonly defaultReadFunctionCodes = [3, 4]; readonly defaultWriteFunctionCodes = [5, 6, 15, 16]; + readonly stringAttrUpdatesWriteFunctionCodes = [6, 16]; constructor(private fb: UntypedFormBuilder) {} @@ -84,7 +85,7 @@ export class ModbusDataKeysPanelComponent implements OnInit { const dataKeyFormGroup = this.fb.group({ tag: ['', [Validators.required, Validators.pattern(noLeadTrailSpacesRegex)]], value: [{value: '', disabled: !this.isMaster}, [Validators.required, Validators.pattern(noLeadTrailSpacesRegex)]], - type: [ModbusDataType.STRING, [Validators.required]], + type: [ModbusDataType.BYTES, [Validators.required]], address: [0, [Validators.required]], objectsCount: [1, [Validators.required]], functionCode: [this.getDefaultFunctionCodes()[0]], @@ -146,6 +147,9 @@ export class ModbusDataKeysPanelComponent implements OnInit { private getFunctionCodes(dataType: ModbusDataType): number[] { if (this.keysType === ModbusValueKey.ATTRIBUTES_UPDATES) { + if (dataType === ModbusDataType.STRING) { + return this.stringAttrUpdatesWriteFunctionCodes; + } return this.defaultWriteFunctionCodes; } const functionCodes = [...this.defaultReadFunctionCodes]; diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-security-config/modbus-security-config.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-security-config/modbus-security-config.component.ts index bf926d3454..f056c9c92f 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-security-config/modbus-security-config.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-security-config/modbus-security-config.component.ts @@ -61,6 +61,7 @@ import { takeUntil } from 'rxjs/operators'; export class ModbusSecurityConfigComponent implements ControlValueAccessor, Validator, OnChanges, OnDestroy { @Input() isMaster = false; + @Input() disabled = false; securityConfigFormGroup: UntypedFormGroup; @@ -90,6 +91,11 @@ export class ModbusSecurityConfigComponent implements ControlValueAccessor, Vali }); this.observeValueChanges(); } + if (this.disabled) { + this.securityConfigFormGroup.disable({emitEvent:false}); + } else { + this.securityConfigFormGroup.enable({emitEvent:false}); + } } ngOnDestroy(): void { @@ -106,8 +112,8 @@ export class ModbusSecurityConfigComponent implements ControlValueAccessor, Vali } validate(): ValidationErrors | null { - return this.securityConfigFormGroup.valid ? null : { - serverConfigFormGroup: { valid: false } + return this.securityConfigFormGroup.valid || this.disabled ? null : { + securityConfigFormGroup: { valid: false } }; } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-slave-config/modbus-slave-config.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-slave-config/modbus-slave-config.component.html index 13f31bdda5..4b0789fb4c 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-slave-config/modbus-slave-config.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-slave-config/modbus-slave-config.component.html @@ -17,6 +17,13 @@ --> {{ 'gateway.hints.modbus-server' | translate }} + + + + {{ 'gateway.enable' | translate }} + + + gateway.server-slave-config @@ -168,13 +175,6 @@ - - - - {{ 'gateway.send-data-TB' | translate }} - - - @@ -203,7 +203,7 @@ - + @@ -251,6 +251,6 @@ gateway.values - + diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-slave-config/modbus-slave-config.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-slave-config/modbus-slave-config.component.ts index 27de908e11..f1234ccfb1 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-slave-config/modbus-slave-config.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-slave-config/modbus-slave-config.component.ts @@ -41,13 +41,13 @@ import { import { SharedModule } from '@shared/shared.module'; import { CommonModule } from '@angular/common'; import { Subject } from 'rxjs'; -import { takeUntil } from 'rxjs/operators'; +import { startWith, takeUntil } from 'rxjs/operators'; import { GatewayPortTooltipPipe } from '@home/pipes/public-api'; import { ModbusSecurityConfigComponent } from '../modbus-security-config/modbus-security-config.component'; import { ModbusValuesComponent, } from '../modbus-values/modbus-values.component'; @Component({ - selector: 'tb-modbus-server-config', + selector: 'tb-modbus-slave-config', templateUrl: './modbus-slave-config.component.html', changeDetection: ChangeDetectionStrategy.OnPush, providers: [ @@ -138,6 +138,7 @@ export class ModbusSlaveConfigComponent implements ControlValueAccessor, Validat }); this.observeTypeChange(); + this.observeFormEnable(); } ngOnDestroy(): void { @@ -162,22 +163,46 @@ export class ModbusSlaveConfigComponent implements ControlValueAccessor, Validat writeValue(slaveConfig: ModbusSlave): void { this.showSecurityControl.patchValue(!!slaveConfig.security); this.updateSlaveConfig(slaveConfig); - this.updateControlsEnabling(slaveConfig.type); + this.updateFormEnableState(slaveConfig.sendDataToThingsBoard); } private observeTypeChange(): void { this.slaveConfigFormGroup.get('type').valueChanges.pipe(takeUntil(this.destroy$)).subscribe(type => { - this.updateControlsEnabling(type); + this.updateFormEnableState(this.slaveConfigFormGroup.get('sendDataToThingsBoard').value); }); } - private updateControlsEnabling(type: ModbusProtocolType): void { + private observeFormEnable(): void { + this.slaveConfigFormGroup.get('sendDataToThingsBoard').valueChanges + .pipe(startWith(this.slaveConfigFormGroup.get('sendDataToThingsBoard').value), takeUntil(this.destroy$)) + .subscribe(value => { + this.updateFormEnableState(value); + }); + } + + private updateFormEnableState(enabled: boolean): void { + if (enabled) { + this.slaveConfigFormGroup.enable({emitEvent: false}); + this.showSecurityControl.enable({emitEvent: false}); + } else { + this.slaveConfigFormGroup.disable({emitEvent: false}); + this.showSecurityControl.disable({emitEvent: false}); + this.slaveConfigFormGroup.get('sendDataToThingsBoard').enable({emitEvent: false}); + } + this.updateEnablingByProtocol(this.slaveConfigFormGroup.get('type').value); + } + + private updateEnablingByProtocol(type: ModbusProtocolType): void { if (type === ModbusProtocolType.Serial) { - this.serialSpecificControlKeys.forEach(key => this.slaveConfigFormGroup.get(key)?.enable({emitEvent: false})); + if (this.slaveConfigFormGroup.get('sendDataToThingsBoard').value) { + this.serialSpecificControlKeys.forEach(key => this.slaveConfigFormGroup.get(key)?.enable({emitEvent: false})); + } this.tcpUdpSpecificControlKeys.forEach(key => this.slaveConfigFormGroup.get(key)?.disable({emitEvent: false})); } else { this.serialSpecificControlKeys.forEach(key => this.slaveConfigFormGroup.get(key)?.disable({emitEvent: false})); - this.tcpUdpSpecificControlKeys.forEach(key => this.slaveConfigFormGroup.get(key)?.enable({emitEvent: false})); + if (this.slaveConfigFormGroup.get('sendDataToThingsBoard').value) { + this.tcpUdpSpecificControlKeys.forEach(key => this.slaveConfigFormGroup.get(key)?.enable({emitEvent: false})); + } } }; diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-slave-dialog/modbus-slave-dialog.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-slave-dialog/modbus-slave-dialog.component.ts index d989478e98..006ae7a482 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-slave-dialog/modbus-slave-dialog.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-slave-dialog/modbus-slave-dialog.component.ts @@ -145,6 +145,12 @@ export class ModbusSlaveDialogComponent extends DialogComponent edit @@ -67,6 +68,7 @@ edit @@ -86,6 +88,7 @@ @@ -107,6 +110,7 @@ edit diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-values/modbus-values.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-values/modbus-values.component.ts index 57acf4a21c..f1df094e8b 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-values/modbus-values.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-values/modbus-values.component.ts @@ -43,6 +43,8 @@ import { ModbusRegisterType, ModbusRegisterValues, ModbusValueKey, + ModbusValues, + ModbusValuesState, } from '@home/components/widget/lib/gateway/gateway-widget.models'; import { SharedModule } from '@shared/shared.module'; import { CommonModule } from '@angular/common'; @@ -87,6 +89,7 @@ import { ModbusDataKeysPanelComponent } from '../modbus-data-keys-panel/modbus-d export class ModbusValuesComponent implements ControlValueAccessor, Validator, OnChanges, OnDestroy { @Input() singleMode = false; + @Input() disabled = false; modbusRegisterTypes: ModbusRegisterType[] = Object.values(ModbusRegisterType); modbusValueKeys = Object.values(ModbusValueKey); @@ -135,8 +138,19 @@ export class ModbusValuesComponent implements ControlValueAccessor, Validator, O this.onTouched = fn; } - writeValue(values: ModbusRegisterValues): void { - this.valuesFormGroup.patchValue(values, {emitEvent: false}); + writeValue(values: ModbusValuesState): void { + if (this.singleMode) { + this.valuesFormGroup.setValue(this.getSingleRegisterState(values as ModbusValues), {emitEvent: false}); + } else { + const registers = values as ModbusRegisterValues; + this.valuesFormGroup.setValue({ + holding_registers: this.getSingleRegisterState(registers.holding_registers), + coils_initializer: this.getSingleRegisterState(registers.coils_initializer), + input_registers: this.getSingleRegisterState(registers.input_registers), + discrete_inputs: this.getSingleRegisterState(registers.discrete_inputs), + }, {emitEvent: false}); + } + this.cdr.markForCheck(); } validate(): ValidationErrors | null { @@ -201,4 +215,13 @@ export class ModbusValuesComponent implements ControlValueAccessor, Validator, O this.onTouched(); }); } + + private getSingleRegisterState(values: ModbusValues): ModbusValues { + return { + attributes: values?.attributes ?? [], + timeseries: values?.timeseries ?? [], + attributeUpdates: values?.attributeUpdates ?? [], + rpc: values?.rpc ?? [], + }; + } } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/gateway-widget.models.ts b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/gateway-widget.models.ts index 394f6c29d0..1204ba087a 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/gateway-widget.models.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/gateway-widget.models.ts @@ -973,12 +973,21 @@ export interface ModbusSlave { sendDataToThingsBoard: boolean; byteOrder: ModbusOrderType; identity: ModbusIdentity; - values: ModbusRegisterValues; + values: ModbusValuesState; port: string | number; security: ModbusSecurity; } +export type ModbusValuesState = ModbusRegisterValues | ModbusValues; + export interface ModbusRegisterValues { + holding_registers: ModbusValues; + coils_initializer: ModbusValues; + input_registers: ModbusValues; + discrete_inputs: ModbusValues; +} + +export interface ModbusValues { attributes: ModbusValue[]; timeseries: ModbusValue[]; attributeUpdates: ModbusValue[]; diff --git a/ui-ngx/src/assets/locale/locale.constant-en_US.json b/ui-ngx/src/assets/locale/locale.constant-en_US.json index 067574b7df..15583665b7 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -2901,6 +2901,7 @@ "device-profile-required": "Device profile required", "download-tip": "Download configuration file", "drop-file": "Drop file here or", + "enable": "Enable", "enable-subscription": "Enable subscription", "extension": "Extension", "extension-hint": "Put your converter classname in the field. Custom converter with such class should be in extension/mqtt folder.",