From 278d3c2b1bfc059dcf62eeb256e2fa098d57a429 Mon Sep 17 00:00:00 2001 From: rusikv Date: Tue, 24 Sep 2024 15:40:24 +0300 Subject: [PATCH 1/7] UI: fixed text color of table widgets not applying to action cell buttons --- .../home/components/widget/lib/table-widget.models.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/table-widget.models.ts b/ui-ngx/src/app/modules/home/components/widget/lib/table-widget.models.ts index dcb40cd85d..3e200481fe 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/table-widget.models.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/table-widget.models.ts @@ -464,6 +464,12 @@ export function constructTableCssString(widgetConfig: WidgetConfig): string { '.mat-mdc-table .mat-mdc-cell button.mat-mdc-icon-button[disabled][disabled] mat-icon {\n' + 'color: ' + mdDarkDisabled + ';\n' + '}\n' + + '.mat-mdc-table .mat-mdc-cell button.mat-mdc-icon-button tb-icon {\n' + + 'color: ' + mdDarkSecondary + ';\n' + + '}\n' + + '.mat-mdc-table .mat-mdc-cell button.mat-mdc-icon-button[disabled][disabled] tb-icon {\n' + + 'color: ' + mdDarkDisabled + ';\n' + + '}\n' + '.mat-divider {\n' + 'border-top-color: ' + mdDarkDivider + ';\n' + '}\n' + From fe9b6e2e4294e21646e008725c02726d5308af1b Mon Sep 17 00:00:00 2001 From: mpetrov Date: Wed, 25 Sep 2024 17:22:53 +0300 Subject: [PATCH 2/7] Gateway Fixes --- ...gateway-connector-basic-config.abstract.ts | 9 +- ...ay-connector-version-processor.abstract.ts | 22 ++++- .../opc-version-processor.abstract.ts | 2 +- ...gateway-basic-configuration.component.html | 2 +- .../gateway-configuration.component.ts | 2 +- .../models/gateway-configuration.models.ts | 2 +- .../mapping-data-keys-panel.component.html | 11 ++- .../modbus-master-table.component.html | 20 ++-- .../modbus-slave-dialog.abstract.ts | 1 - .../modbus-slave-dialog.component.html | 17 ---- .../gateway/gateway-connectors.component.html | 23 ++++- .../gateway/gateway-connectors.component.ts | 95 +++++++++++++++---- .../lib/gateway/gateway-widget.models.ts | 2 +- .../gateway/utils/opc-version-mapping.util.ts | 2 +- .../assets/locale/locale.constant-en_US.json | 3 +- .../connector-default-configs/modbus.json | 7 +- 16 files changed, 153 insertions(+), 67 deletions(-) diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/abstract/gateway-connector-basic-config.abstract.ts b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/abstract/gateway-connector-basic-config.abstract.ts index d12e647254..4c90eeb01c 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/abstract/gateway-connector-basic-config.abstract.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/abstract/gateway-connector-basic-config.abstract.ts @@ -14,16 +14,17 @@ /// limitations under the License. /// -import { Directive, inject, Input, OnDestroy, TemplateRef } from '@angular/core'; +import { AfterViewInit, Directive, EventEmitter, inject, Input, OnDestroy, Output, TemplateRef } from '@angular/core'; import { ControlValueAccessor, FormBuilder, FormGroup, ValidationErrors, Validator } from '@angular/forms'; import { Subject } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; @Directive() export abstract class GatewayConnectorBasicConfigDirective - implements ControlValueAccessor, Validator, OnDestroy { + implements AfterViewInit, ControlValueAccessor, Validator, OnDestroy { @Input() generalTabContent: TemplateRef; + @Output() initialized = new EventEmitter(); basicFormGroup: FormGroup; @@ -45,6 +46,10 @@ export abstract class GatewayConnectorBasicConfigDirective { protected constructor(protected gatewayVersionIn: string | number, protected connector: GatewayConnector) { this.gatewayVersion = this.parseVersion(this.gatewayVersionIn); - this.configVersion = this.parseVersion(connector.configVersion); + this.configVersion = this.parseVersion(this.connector.configVersion); } getProcessedByVersion(): GatewayConnector { - if (this.isVersionUpdateNeeded()) { - return this.isVersionUpgradeNeeded() - ? this.getUpgradedVersion() - : this.getDowngradedVersion(); + if (!this.isVersionUpdateNeeded()) { + return this.connector; + } + + return this.processVersionUpdate(); + } + + private processVersionUpdate(): GatewayConnector { + if (this.isVersionUpgradeNeeded()) { + return this.getUpgradedVersion(); + } else if (this.isVersionDowngradeNeeded()) { + return this.getDowngradedVersion(); } return this.connector; @@ -48,6 +56,10 @@ export abstract class GatewayConnectorVersionProcessor { return this.gatewayVersionIn === GatewayVersion.Current && (!this.configVersion || this.configVersion < this.gatewayVersion); } + private isVersionDowngradeNeeded(): boolean { + return this.configVersion && this.connector.configVersion === GatewayVersion.Current && (this.configVersion > this.gatewayVersion); + } + private parseVersion(version: string | number): number { if (isNumber(version)) { return version as number; diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/abstract/opc-version-processor.abstract.ts b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/abstract/opc-version-processor.abstract.ts index e89c48fc28..541e26001f 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/abstract/opc-version-processor.abstract.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/abstract/opc-version-processor.abstract.ts @@ -38,7 +38,7 @@ export class OpcVersionProcessor extends GatewayConnectorVersionProcessor; diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/configuration/basic/gateway-basic-configuration.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/configuration/basic/gateway-basic-configuration.component.html index 5f33f6e00c..af8dc3119c 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/configuration/basic/gateway-basic-configuration.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/configuration/basic/gateway-basic-configuration.component.html @@ -693,7 +693,7 @@ gateway.inactivity-check-period-seconds - + {{ 'gateway.inactivity-check-period-seconds-required' | translate }} diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/configuration/gateway-configuration.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/configuration/gateway-configuration.component.ts index c1fa370b95..670fd57bd4 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/configuration/gateway-configuration.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/configuration/gateway-configuration.component.ts @@ -242,7 +242,7 @@ export class GatewayConfigurationComponent implements AfterViewInit, OnDestroy { consoleHandler: { class: 'logging.StreamHandler', formatter: 'LogFormatter', - level: 'DEBUG', + level: 0, stream: 'ext://sys.stdout' }, databaseHandler: { diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/configuration/models/gateway-configuration.models.ts b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/configuration/models/gateway-configuration.models.ts index 62d8dcc618..4115c6c024 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/configuration/models/gateway-configuration.models.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/configuration/models/gateway-configuration.models.ts @@ -128,7 +128,7 @@ interface LogFormatterConfig { interface StreamHandlerConfig { class: string; formatter: string; - level: string; + level: string | number; stream: string; } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/mapping-data-keys-panel/mapping-data-keys-panel.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/mapping-data-keys-panel/mapping-data-keys-panel.component.html index 31bed344b7..736d9c83c6 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/mapping-data-keys-panel/mapping-data-keys-panel.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/mapping-data-keys-panel/mapping-data-keys-panel.component.html @@ -26,10 +26,13 @@ -
- {{ keyControl.get('key').value }}{{ '-' }} -
-
{{ valueTitle(keyControl) }}
+ +
+ {{ keyControl.get('key').value }} +
+ {{ '-' }} +
+
{{ valueTitle(keyControl) }}
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-master-table/modbus-master-table.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-master-table/modbus-master-table.component.html index 8f8aeaeef7..eb3fb8e3f5 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-master-table/modbus-master-table.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-master-table/modbus-master-table.component.html @@ -62,17 +62,25 @@
- + - {{ 'gateway.name' | translate }} + {{ 'gateway.info' | translate }} - {{ slave['name'] }} +
{{ slave['host'] ?? slave['port'] }}
+
+
+ + + {{ 'gateway.unit-id' | translate }} + + +
{{ slave['unitId'] }}
- {{ 'gateway.client-communication-type' | translate }} +
{{ 'gateway.client-communication-type' | translate }}
{{ ModbusProtocolLabelsMap.get(slave['type']) }} @@ -113,8 +121,8 @@
- - + +
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-slave-dialog/modbus-slave-dialog.abstract.ts b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-slave-dialog/modbus-slave-dialog.abstract.ts index 6d434591d0..ff2b642621 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-slave-dialog/modbus-slave-dialog.abstract.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-slave-dialog/modbus-slave-dialog.abstract.ts @@ -113,7 +113,6 @@ export abstract class ModbusSlaveDialogAbstract extends Dialo private initializeSlaveFormGroup(): void { this.slaveConfigFormGroup = this.fb.group({ - name: ['', [Validators.required, Validators.pattern(noLeadTrailSpacesRegex)]], type: [ModbusProtocolType.TCP], host: ['', [Validators.required, Validators.pattern(noLeadTrailSpacesRegex)]], port: [null, [Validators.required, Validators.min(PortLimits.MIN), Validators.max(PortLimits.MAX)]], diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-slave-dialog/modbus-slave-dialog.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-slave-dialog/modbus-slave-dialog.component.html index d869785589..bb7e90f280 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-slave-dialog/modbus-slave-dialog.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-slave-dialog/modbus-slave-dialog.component.html @@ -27,23 +27,6 @@
-
-
gateway.name
-
- - - - warning - - -
-
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/gateway-connectors.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/gateway-connectors.component.html index 124b698612..cec81ab637 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/gateway-connectors.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/gateway-connectors.component.html @@ -181,9 +181,14 @@ *ngIf="connectorForm.get('configVersion').value === GatewayVersion.Current else legacy" formControlName="basicConfig" [generalTabContent]="generalTabContent" + (initialized)="basicConfigInitSubject.next()" /> - + @@ -191,9 +196,14 @@ *ngIf="connectorForm.get('configVersion').value === GatewayVersion.Current else legacy" formControlName="basicConfig" [generalTabContent]="generalTabContent" + (initialized)="basicConfigInitSubject.next()" /> - + @@ -201,9 +211,14 @@ *ngIf="connectorForm.get('configVersion').value === GatewayVersion.Current else legacy" formControlName="basicConfig" [generalTabContent]="generalTabContent" + (initialized)="basicConfigInitSubject.next()" /> - + @@ -229,7 +244,7 @@
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/gateway-connectors.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/gateway-connectors.component.ts index 2fc806a708..59911f62a9 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/gateway-connectors.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/gateway-connectors.component.ts @@ -31,7 +31,7 @@ import { EntityId } from '@shared/models/id/entity-id'; import { AttributeService } from '@core/http/attribute.service'; import { TranslateService } from '@ngx-translate/core'; import { forkJoin, Observable, of, Subject, Subscription } from 'rxjs'; -import { AttributeScope } from '@shared/models/telemetry/telemetry.models'; +import { AttributeData, AttributeScope } from '@shared/models/telemetry/telemetry.models'; import { PageComponent } from '@shared/components/page.component'; import { PageLink } from '@shared/models/page/page-link'; import { AttributeDatasource } from '@home/models/datasource/attribute-datasource'; @@ -110,8 +110,10 @@ export class GatewayConnectorComponent extends PageComponent implements AfterVie activeConnectors: Array; mode: ConfigurationModes = this.ConnectorConfigurationModes.BASIC; initialConnector: GatewayConnector; + basicConfigInitSubject = new Subject(); private gatewayVersion: string; + private isGatewayActive: boolean; private inactiveConnectors: Array; private attributeDataSource: AttributeDatasource; private inactiveConnectorsDataSource: AttributeDatasource; @@ -124,7 +126,7 @@ export class GatewayConnectorComponent extends PageComponent implements AfterVie private subscriptionOptions: WidgetSubscriptionOptions = { callbacks: { onDataUpdated: () => this.ctx.ngZone.run(() => { - this.onDataUpdated(); + this.onErrorsUpdated(); }), onDataUpdateError: (_, e) => this.ctx.ngZone.run(() => { this.onDataUpdateError(e); @@ -155,8 +157,10 @@ export class GatewayConnectorComponent extends PageComponent implements AfterVie ngAfterViewInit(): void { this.dataSource.sort = this.sort; this.dataSource.sortingDataAccessor = this.getSortingDataAccessor(); + this.ctx.$scope.gatewayConnectors = this; this.loadConnectors(); + this.loadGatewayState(); this.observeModeChange(); } @@ -166,9 +170,9 @@ export class GatewayConnectorComponent extends PageComponent implements AfterVie super.ngOnDestroy(); } - saveConnector(): void { + saveConnector(isNew = true): void { const value = this.getConnectorData(); - const scope = (!this.initialConnector || this.activeConnectors.includes(this.initialConnector.name)) + const scope = (isNew || this.activeConnectors.includes(this.initialConnector.name)) ? AttributeScope.SHARED_SCOPE : AttributeScope.SERVER_SCOPE; @@ -275,7 +279,7 @@ export class GatewayConnectorComponent extends PageComponent implements AfterVie isConnectorSynced(attribute: GatewayAttributeData): boolean { const connectorData = attribute.value; - if (!connectorData.ts || attribute.skipSync) { + if (!connectorData.ts || attribute.skipSync || !this.isGatewayActive) { return false; } const clientIndex = this.activeData.findIndex(data => { @@ -479,7 +483,6 @@ export class GatewayConnectorComponent extends PageComponent implements AfterVie filter(Boolean), ) .subscribe(value => { - this.initialConnector = null; if (this.connectorForm.disabled) { this.connectorForm.enable(); } @@ -487,9 +490,16 @@ export class GatewayConnectorComponent extends PageComponent implements AfterVie value.configurationJson = {} as ConnectorBaseConfig; } value.basicConfig = value.configurationJson; - this.updateConnector(value); + this.initialConnector = value; + this.connectorForm.patchValue(value, {emitEvent: false}); this.generate('basicConfig.broker.clientId'); - setTimeout(() => this.saveConnector()); + if (this.connectorForm.get('type').value === value.type || !this.allowBasicConfig.has(value.type)) { + this.saveConnector(); + } else { + this.basicConfigInitSubject.pipe(take(1)).subscribe(() => { + this.saveConnector(); + }); + } }); } @@ -590,6 +600,19 @@ export class GatewayConnectorComponent extends PageComponent implements AfterVie }); } + private loadGatewayState(): void { + this.attributeService.getEntityAttributes(this.device, AttributeScope.SERVER_SCOPE) + .pipe(takeUntil(this.destroy$)) + .subscribe((attributes: AttributeData[]) => { + + const active = attributes.find(data => data.key === 'active').value; + const lastDisconnectedTime = attributes.find(data => data.key === 'lastDisconnectTime').value; + const lastConnectedTime = attributes.find(data => data.key === 'lastConnectTime').value; + + this.isGatewayActive = this.getGatewayStatus(active, lastConnectedTime, lastDisconnectedTime); + }); + } + private parseConnectors(attribute: GatewayAttributeData[]): string[] { const connectors = attribute?.[0]?.value || []; return isString(connectors) ? JSON.parse(connectors) : connectors; @@ -598,7 +621,14 @@ export class GatewayConnectorComponent extends PageComponent implements AfterVie private observeModeChange(): void { this.connectorForm.get('mode').valueChanges .pipe(takeUntil(this.destroy$)) - .subscribe(() => this.connectorForm.get('mode').markAsPristine()); + .subscribe((mode) => { + this.connectorForm.get('mode').markAsPristine(); + if (mode === ConfigurationModes.BASIC) { + this.basicConfigInitSubject.pipe(take(1)).subscribe(() => { + this.patchBasicConfigConnector({...this.initialConnector, mode: ConfigurationModes.BASIC}); + }); + } + }); } private observeAttributeChange(): void { @@ -664,10 +694,29 @@ export class GatewayConnectorComponent extends PageComponent implements AfterVie console.error(errorText); } - private onDataUpdated(): void { + private onErrorsUpdated(): void { this.cd.detectChanges(); } + private onDataUpdated(): void { + const dataSources = this.ctx.defaultSubscription.data; + + const active = dataSources.find(data => data.dataKey.name === 'active').data[0][1]; + const lastDisconnectedTime = dataSources.find(data => data.dataKey.name === 'lastDisconnectTime').data[0][1]; + const lastConnectedTime = dataSources.find(data => data.dataKey.name === 'lastConnectTime').data[0][1]; + + this.isGatewayActive = this.getGatewayStatus(active, lastConnectedTime, lastDisconnectedTime); + + this.cd.detectChanges(); + } + + private getGatewayStatus(active: boolean, lastConnectedTime: number, lastDisconnectedTime: number): boolean { + if (!active) { + return false; + } + return lastConnectedTime > lastDisconnectedTime; + } + private generateSubscription(): void { if (this.subscription) { this.subscription.unsubscribe(); @@ -760,13 +809,7 @@ export class GatewayConnectorComponent extends PageComponent implements AfterVie case ConnectorType.MQTT: case ConnectorType.OPCUA: case ConnectorType.MODBUS: - this.connectorForm.get('mode').setValue(connector.mode || ConfigurationModes.BASIC, {emitEvent: false}); - this.connectorForm.get('configVersion').setValue(connector.configVersion, {emitEvent: false}); - setTimeout(() => { - this.connectorForm.patchValue(connector, {emitEvent: false}); - this.connectorForm.markAsPristine(); - this.createBasicConfigWatcher(); - }); + this.updateBasicConfigConnector(connector); break; default: this.connectorForm.patchValue({...connector, mode: null}); @@ -775,6 +818,24 @@ export class GatewayConnectorComponent extends PageComponent implements AfterVie this.createJsonConfigWatcher(); } + private updateBasicConfigConnector(connector: GatewayConnector): void { + this.connectorForm.get('mode').setValue(connector.mode || ConfigurationModes.BASIC, {emitEvent: false}); + this.connectorForm.get('configVersion').setValue(connector.configVersion, {emitEvent: false}); + if (!connector.mode || connector.mode === ConfigurationModes.BASIC) { + this.basicConfigInitSubject.asObservable().pipe(take(1)).subscribe(() => { + this.patchBasicConfigConnector(connector); + }); + } else { + this.patchBasicConfigConnector(connector); + } + } + + private patchBasicConfigConnector(connector: GatewayConnector): void { + this.connectorForm.patchValue(connector, {emitEvent: false}); + this.connectorForm.markAsPristine(); + this.createBasicConfigWatcher(); + } + private toggleReportStrategy(type: ConnectorType): void { const reportStrategyControl = this.connectorForm.get('reportStrategy'); if (type === ConnectorType.MODBUS) { 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 bf3bf01d21..c3031331b4 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 @@ -680,7 +680,7 @@ export const HelpLinkByMappingTypeMap = new Map( [ [MappingType.DATA, helpBaseUrl + '/docs/iot-gateway/config/mqtt/#section-mapping'], [MappingType.OPCUA, helpBaseUrl + '/docs/iot-gateway/config/opc-ua/#section-mapping'], - [MappingType.REQUESTS, helpBaseUrl + '/docs/iot-gateway/config/mqtt/#section-mapping'] + [MappingType.REQUESTS, helpBaseUrl + '/docs/iot-gateway/config/mqtt/#requests-mapping'] ] ); diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/utils/opc-version-mapping.util.ts b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/utils/opc-version-mapping.util.ts index 91246b0220..9837f2f15d 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/utils/opc-version-mapping.util.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/utils/opc-version-mapping.util.ts @@ -45,7 +45,7 @@ export class OpcVersionMappingUtil { static mapServerToDowngradedVersion(config: OPCBasicConfig_v3_5_2): LegacyServerConfig { const { mapping, server } = config; - const { enableSubscriptions, ...restServer } = server; + const { enableSubscriptions, ...restServer } = server ?? {} as ServerConfig; return { ...restServer, mapping: mapping ? this.mapMappingToDowngradedVersion(mapping) : [], 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 95314ded5c..b66457cc3d 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -3036,6 +3036,7 @@ "grpc-max-pings-without-data-required": "Max pings without data is required", "grpc-max-pings-without-data-min": "Max pings without data can not be less then 1", "grpc-max-pings-without-data-pattern": "Max pings without data is not valid", + "info": "Info", "identity": "Identity", "inactivity-check-period-seconds": "Inactivity check period (in sec)", "inactivity-check-period-seconds-required": "Inactivity check period is required", @@ -3311,7 +3312,7 @@ "check-connectors-configuration-min": "Check connectors configuration can not be less then 1", "check-connectors-configuration-pattern": "Check connectors configuration is not valid", "add": "Add command", - "timeout": "Timeout", + "timeout": "Timeout (in sec)", "timeout-ms": "Timeout (in ms)", "timeout-required": "Timeout is required", "timeout-min": "Timeout can not be less then 1", diff --git a/ui-ngx/src/assets/metadata/connector-default-configs/modbus.json b/ui-ngx/src/assets/metadata/connector-default-configs/modbus.json index fbace65d78..019d2062f8 100644 --- a/ui-ngx/src/assets/metadata/connector-default-configs/modbus.json +++ b/ui-ngx/src/assets/metadata/connector-default-configs/modbus.json @@ -3,7 +3,6 @@ "master": { "slaves": [ { - "name": "Slave 1", "host": "127.0.0.1", "port": 5021, "type": "tcp", @@ -231,10 +230,10 @@ "attributes": [ { "address": 5, - "type": "string", - "tag": "sm", + "type": "8int", + "tag": "coil", "objectsCount": 1, - "value": "12" + "value": 0 } ], "timeseries": [], From 91c08419b3b776de16081a68ddfc1d610e3947ce Mon Sep 17 00:00:00 2001 From: mpetrov Date: Wed, 25 Sep 2024 17:36:31 +0300 Subject: [PATCH 3/7] json configs --- .../widget_types/gateway_connectors.json | 2 +- .../data/json/tenant/dashboards/gateways.json | 24 +++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/application/src/main/data/json/system/widget_types/gateway_connectors.json b/application/src/main/data/json/system/widget_types/gateway_connectors.json index 765d9043ad..43f95194b8 100644 --- a/application/src/main/data/json/system/widget_types/gateway_connectors.json +++ b/application/src/main/data/json/system/widget_types/gateway_connectors.json @@ -11,7 +11,7 @@ "resources": [], "templateHtml": "", "templateCss": "", - "controllerScript": "self.onInit = function() {\n if (self.ctx.datasources && self.ctx.datasources.length) {\n self.ctx.$scope.entityId = self.ctx.datasources[0].entity.id;\n }\n};\n\nself.typeParameters = function() {\n return {\n dataKeysOptional: true,\n singleEntity: true\n };\n}", + "controllerScript": "self.onInit = function() {\n if (self.ctx.datasources && self.ctx.datasources.length) {\n self.ctx.$scope.entityId = self.ctx.datasources[0].entity.id;\n }\n};\n\nself.onDataUpdated = function() {\n self.ctx.$scope.gatewayConnectors?.onDataUpdated();\n};\n\nself.typeParameters = function() {\n return {\n dataKeysOptional: true,\n singleEntity: true\n };\n}", "settingsSchema": "{}", "dataKeySettingsSchema": "{}\n", "defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Random\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.15479322438769105,\"funcBody\":\"var value = prevValue + Math.random() * 100 - 50;\\nvar multiplier = Math.pow(10, 2 || 0);\\nvar value = Math.round(value * multiplier) / multiplier;\\nif (value < -1000) {\\n\\tvalue = -1000;\\n} else if (value > 1000) {\\n\\tvalue = 1000;\\n}\\nreturn value;\"}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":false,\"backgroundColor\":\"#fff\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"8px\",\"settings\":{},\"title\":\"Gateway connectors\",\"showTitleIcon\":false,\"titleTooltip\":\"\",\"dropShadow\":true,\"enableFullscreen\":false,\"enableDataExport\":false,\"widgetStyle\":{},\"widgetCss\":\"\",\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":500},\"pageSize\":1024,\"noDataDisplayMessage\":\"\",\"showLegend\":false}" diff --git a/application/src/main/data/json/tenant/dashboards/gateways.json b/application/src/main/data/json/tenant/dashboards/gateways.json index 8030d3e731..338762286c 100644 --- a/application/src/main/data/json/tenant/dashboards/gateways.json +++ b/application/src/main/data/json/tenant/dashboards/gateways.json @@ -360,6 +360,30 @@ "color": "#2196f3", "settings": {}, "_hash": 0.7454705362378311 + }, + { + "name": "lastConnectTime", + "type": "attribute", + "label": "lastConnectTime", + "color": "#4caf50", + "settings": {}, + "_hash": 0.7249585632235194 + }, + { + "name": "lastDisconnectTime", + "type": "attribute", + "label": "lastDisconnectTime", + "color": "#f44336", + "settings": {}, + "_hash": 0.9812430092707332 + }, + { + "name": "active", + "type": "attribute", + "label": "active", + "color": "#ffc107", + "settings": {}, + "_hash": 0.9216097189544408 } ] } From fa1c5b84ddc835e46d968f24c50f1021469fbce7 Mon Sep 17 00:00:00 2001 From: mpetrov Date: Wed, 25 Sep 2024 18:34:17 +0300 Subject: [PATCH 4/7] first connection fix --- .../widget/lib/gateway/gateway-connectors.component.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/gateway-connectors.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/gateway-connectors.component.ts index 59911f62a9..a4c1985595 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/gateway-connectors.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/gateway-connectors.component.ts @@ -606,7 +606,7 @@ export class GatewayConnectorComponent extends PageComponent implements AfterVie .subscribe((attributes: AttributeData[]) => { const active = attributes.find(data => data.key === 'active').value; - const lastDisconnectedTime = attributes.find(data => data.key === 'lastDisconnectTime').value; + const lastDisconnectedTime = attributes.find(data => data.key === 'lastDisconnectTime')?.value; const lastConnectedTime = attributes.find(data => data.key === 'lastConnectTime').value; this.isGatewayActive = this.getGatewayStatus(active, lastConnectedTime, lastDisconnectedTime); @@ -714,7 +714,7 @@ export class GatewayConnectorComponent extends PageComponent implements AfterVie if (!active) { return false; } - return lastConnectedTime > lastDisconnectedTime; + return !lastDisconnectedTime || lastConnectedTime > lastDisconnectedTime; } private generateSubscription(): void { @@ -821,7 +821,7 @@ export class GatewayConnectorComponent extends PageComponent implements AfterVie private updateBasicConfigConnector(connector: GatewayConnector): void { this.connectorForm.get('mode').setValue(connector.mode || ConfigurationModes.BASIC, {emitEvent: false}); this.connectorForm.get('configVersion').setValue(connector.configVersion, {emitEvent: false}); - if (!connector.mode || connector.mode === ConfigurationModes.BASIC) { + if ((!connector.mode || connector.mode === ConfigurationModes.BASIC) && this.connectorForm.get('type').value !== connector.type) { this.basicConfigInitSubject.asObservable().pipe(take(1)).subscribe(() => { this.patchBasicConfigConnector(connector); }); From 1778692c3e2e5bf4964be96cc0179ba54dbe5291 Mon Sep 17 00:00:00 2001 From: mpetrov Date: Wed, 25 Sep 2024 18:54:03 +0300 Subject: [PATCH 5/7] gateway config storage text fields fix --- .../basic/gateway-basic-configuration.component.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/configuration/basic/gateway-basic-configuration.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/configuration/basic/gateway-basic-configuration.component.ts index e63a60372e..1cff165f8a 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/configuration/basic/gateway-basic-configuration.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/configuration/basic/gateway-basic-configuration.component.ts @@ -502,14 +502,14 @@ export class GatewayBasicConfigurationComponent implements OnDestroy, ControlVal } private addFileStorageValidators(group: FormGroup): void { - ['data_folder_path', 'max_file_count', 'max_read_records_count', 'max_records_per_file'].forEach(field => { + ['max_file_count', 'max_read_records_count', 'max_records_per_file'].forEach(field => { group.get(field).addValidators([Validators.required, Validators.min(1), Validators.pattern(/^-?[0-9]+$/)]); group.get(field).updateValueAndValidity({ emitEvent: false }); }); } private addSqliteStorageValidators(group: FormGroup): void { - ['data_file_path', 'messages_ttl_check_in_hours', 'messages_ttl_in_days'].forEach(field => { + ['messages_ttl_check_in_hours', 'messages_ttl_in_days'].forEach(field => { group.get(field).addValidators([Validators.required, Validators.min(1), Validators.pattern(/^-?[0-9]+$/)]); group.get(field).updateValueAndValidity({ emitEvent: false }); }); From 3493c51cf746c026762c063d2ba576e7f4d3e329 Mon Sep 17 00:00:00 2001 From: mpetrov Date: Wed, 25 Sep 2024 19:16:17 +0300 Subject: [PATCH 6/7] fixed no workers with mqtt default config --- .../mqtt-basic-config.abstract.ts | 15 +++++++++++-- .../mqtt-basic-config.component.ts | 22 +++++++------------ .../mqtt-legacy-basic-config.component.ts | 19 +++++----------- 3 files changed, 27 insertions(+), 29 deletions(-) diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/mqtt/basic-config/mqtt-basic-config.abstract.ts b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/mqtt/basic-config/mqtt-basic-config.abstract.ts index ce87d80a75..16f5036770 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/mqtt/basic-config/mqtt-basic-config.abstract.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/mqtt/basic-config/mqtt-basic-config.abstract.ts @@ -17,11 +17,14 @@ import { Directive } from '@angular/core'; import { FormGroup } from '@angular/forms'; import { + BrokerConfig, MappingType, - MQTTBasicConfig, MQTTBasicConfig_v3_5_2, + MQTTBasicConfig, + MQTTBasicConfig_v3_5_2, RequestMappingData, RequestMappingValue, - RequestType + RequestType, + WorkersConfig } from '@home/components/widget/lib/gateway/gateway-widget.models'; import { isObject } from '@core/utils'; import { @@ -73,6 +76,14 @@ export abstract class MqttBasicConfigDirective }); } + protected getBrokerMappedValue(broker: BrokerConfig, workers: WorkersConfig): BrokerConfig { + return { + ...broker, + maxNumberOfWorkers: workers.maxNumberOfWorkers ?? 100, + maxMessageNumberPerWorker: workers.maxMessageNumberPerWorker ?? 10, + }; + } + writeValue(basicConfig: BasicConfig): void { this.basicFormGroup.setValue(this.mapConfigToFormValue(basicConfig), { emitEvent: false }); } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/mqtt/basic-config/mqtt-basic-config.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/mqtt/basic-config/mqtt-basic-config.component.ts index 9af627352a..155b91efb6 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/mqtt/basic-config/mqtt-basic-config.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/mqtt/basic-config/mqtt-basic-config.component.ts @@ -26,7 +26,6 @@ import { import { MqttBasicConfigDirective } from '@home/components/widget/lib/gateway/connectors-configuration/mqtt/basic-config/mqtt-basic-config.abstract'; -import { isDefinedAndNotNull } from '@core/utils'; import { CommonModule } from '@angular/common'; import { SharedModule } from '@shared/shared.module'; import { @@ -85,19 +84,14 @@ export class MqttBasicConfigComponent extends MqttBasicConfigDirective + }; } } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/mqtt/basic-config/mqtt-legacy-basic-config.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/mqtt/basic-config/mqtt-legacy-basic-config.component.ts index e4577c653e..6209cef677 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/mqtt/basic-config/mqtt-legacy-basic-config.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/mqtt/basic-config/mqtt-legacy-basic-config.component.ts @@ -102,23 +102,16 @@ export class MqttLegacyBasicConfigComponent extends MqttBasicConfigDirective; return { - broker, + broker: this.getBrokerMappedValue(broker, workers), mapping: MqttVersionMappingUtil.mapMappingToDowngradedVersion(mapping), - ...(MqttVersionMappingUtil.mapRequestsToDowngradedVersion(requestsMapping as Record)) + ...(MqttVersionMappingUtil.mapRequestsToDowngradedVersion(updatedRequestMapping as Record)) }; } } From 6d1d82a8a36784677333c951c8132c151f86a671 Mon Sep 17 00:00:00 2001 From: mpetrov Date: Wed, 25 Sep 2024 19:29:25 +0300 Subject: [PATCH 7/7] opc type value fix --- .../type-value-panel/type-value-panel.component.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/type-value-panel/type-value-panel.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/type-value-panel/type-value-panel.component.html index f40914f3d0..f72a2c18af 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/type-value-panel/type-value-panel.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/type-value-panel/type-value-panel.component.html @@ -70,8 +70,8 @@ matTooltipPosition="above" matTooltipClass="tb-error-tooltip" [matTooltip]="('gateway.value-required') | translate" - *ngIf="keyControl.get(keyControl.get('value').value).hasError('required') - && keyControl.get(keyControl.get('value').value).touched" + *ngIf="keyControl.get(keyControl.get('type').value).hasError('required') + && keyControl.get(keyControl.get('type').value).touched" class="tb-error"> warning