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))
};
}
}
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
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..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
@@ -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 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 !lastDisconnectedTime || 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.connectorForm.get('type').value !== connector.type) {
+ 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 f40b053800..f1fbd4d0f5 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
@@ -711,7 +711,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/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' +
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 c66cc6dbd5..23a60fec14 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",
@@ -3317,7 +3318,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": [],