From 58bbf7f7e12e3a166206eeeec4038361b0be4b3b Mon Sep 17 00:00:00 2001 From: mpetrov Date: Thu, 26 Sep 2024 20:02:40 +0300 Subject: [PATCH 1/2] Fixed gateway device table view --- .../data/json/tenant/dashboards/gateways.json | 16 ++++++++-------- .../gateway-configuration.component.html | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/application/src/main/data/json/tenant/dashboards/gateways.json b/application/src/main/data/json/tenant/dashboards/gateways.json index 8030d3e731..bd93925053 100644 --- a/application/src/main/data/json/tenant/dashboards/gateways.json +++ b/application/src/main/data/json/tenant/dashboards/gateways.json @@ -2135,17 +2135,17 @@ } }, { - "type": "entity", + "type": "entityCount", "entityAliasId": "a75d9031-ba51-8da4-81be-de65061b72f4", "filterId": "44038462-1bae-e075-7b31-283341cb2295", "dataKeys": [ { "name": "count", - "type": "entityField", + "type": "count", "label": "modbusCount", - "color": "#4caf50", + "color": "#ff5722", "settings": {}, - "_hash": 0.9300660062254784, + "_hash": 0.46402083951505624, "aggregationType": null, "units": null, "decimals": null, @@ -2168,7 +2168,7 @@ { "name": "count", "type": "count", - "label": "grcpCount", + "label": "grpcCount", "color": "#f44336", "settings": {}, "_hash": 0.16110429492126088, @@ -2581,9 +2581,9 @@ "padding": "0px", "settings": { "useMarkdownTextFunction": false, - "markdownTextPattern": "
\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n", + "markdownTextPattern": "
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n", "applyDefaultMarkdownStyle": false, - "markdownCss": ".mat-mdc-form-field-subscript-wrapper {\n display: none !important;\n}" + "markdownCss": ".mat-mdc-form-field-subscript-wrapper {\n display: none !important;\n}\n\n.devices-tabs {\n height: 100%;\n}\n\n::ng-deep .mat-mdc-tab-body-wrapper {\n height: 100%;\n}" }, "title": "Gateway devices", "showTitleIcon": false, @@ -6184,7 +6184,7 @@ } }, "gateway_devices_16": { - "name": "gateway_devices_occp", + "name": "gateway_devices_ocpp", "root": false, "layouts": { "main": { diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/configuration/gateway-configuration.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/configuration/gateway-configuration.component.html index 01fc12f167..7d8e0e78b3 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/configuration/gateway-configuration.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/configuration/gateway-configuration.component.html @@ -18,7 +18,7 @@
-
+

gateway.gateway-configuration

From 8b5e25d719243174c7c8743c96cb36542577aa6f Mon Sep 17 00:00:00 2001 From: mpetrov Date: Fri, 27 Sep 2024 18:51:11 +0300 Subject: [PATCH 2/2] Gateway fixes --- .../modbus-data-keys-panel.component.html | 1 + .../modbus-data-keys-panel.component.ts | 5 +- .../modbus-master-table.component.html | 14 ++- .../modbus-slave-dialog.abstract.ts | 2 + .../modbus-slave-dialog.component.html | 2 +- .../report-strategy.component.ts | 10 +- .../gateway/gateway-connectors.component.html | 7 +- .../gateway/gateway-connectors.component.ts | 103 +++++++++++------- .../lib/gateway/gateway-widget.models.ts | 9 ++ .../assets/locale/locale.constant-en_US.json | 1 - 10 files changed, 104 insertions(+), 50 deletions(-) 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.html b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-data-keys-panel/modbus-data-keys-panel.component.html index ee0f8d944b..890c0428f0 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-data-keys-panel/modbus-data-keys-panel.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-data-keys-panel/modbus-data-keys-panel.component.html @@ -223,6 +223,7 @@
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 f361ae70e7..fcf3d49cf0 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 @@ -28,7 +28,8 @@ import { import { TbPopoverComponent } from '@shared/components/popover.component'; import { ModbusDataType, - ModbusEditableDataTypes, ModbusFormValue, + ModbusEditableDataTypes, + ModbusFormValue, ModbusFunctionCodeTranslationsMap, ModbusObjectCountByDataType, ModbusValue, @@ -37,6 +38,7 @@ import { ModifierTypesMap, noLeadTrailSpacesRegex, nonZeroFloat, + ReportStrategyDefaultValue, } from '@home/components/widget/lib/gateway/gateway-widget.models'; import { CommonModule } from '@angular/common'; import { SharedModule } from '@shared/shared.module'; @@ -91,6 +93,7 @@ export class ModbusDataKeysPanelComponent implements OnInit, OnDestroy { readonly ModbusEditableDataTypes = ModbusEditableDataTypes; readonly ModbusFunctionCodeTranslationsMap = ModbusFunctionCodeTranslationsMap; readonly ModifierTypesMap = ModifierTypesMap; + readonly ReportStrategyDefaultValue = ReportStrategyDefaultValue; private destroy$ = new Subject(); 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 eb3fb8e3f5..0bdfc9ab87 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,6 +62,14 @@
+ + +
{{ 'gateway.device-name' | translate }}
+
+ +
{{ slave['deviceName'] }}
+
+
{{ 'gateway.info' | translate }} @@ -80,7 +88,7 @@ -
{{ 'gateway.client-communication-type' | translate }}
+
{{ 'gateway.type' | translate }}
{{ ModbusProtocolLabelsMap.get(slave['type']) }} @@ -121,8 +129,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 ff2b642621..f9955b839b 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 @@ -35,6 +35,7 @@ import { ModbusSlaveInfo, noLeadTrailSpacesRegex, PortLimits, + ReportStrategyDefaultValue, } from '@home/components/widget/lib/gateway/gateway-widget.models'; import { Subject } from 'rxjs'; import { DialogComponent } from '@shared/components/dialog.component'; @@ -64,6 +65,7 @@ export abstract class ModbusSlaveDialogAbstract extends Dialo readonly ModbusParityLabelsMap = ModbusParityLabelsMap; readonly ModbusProtocolLabelsMap = ModbusProtocolLabelsMap; readonly ModbusMethodLabelsMap = ModbusMethodLabelsMap; + readonly ReportStrategyDefaultValue = ReportStrategyDefaultValue; readonly modbusHelpLink = helpBaseUrl + '/docs/iot-gateway/config/modbus/#section-master-description-and-configuration-parameters'; 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 bb7e90f280..0a480a88ae 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 @@ -218,7 +218,7 @@
- +
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/report-strategy/report-strategy.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/report-strategy/report-strategy.component.ts index fb0819d119..10eaf98f86 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/report-strategy/report-strategy.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/report-strategy/report-strategy.component.ts @@ -34,6 +34,7 @@ import { } from '@angular/forms'; import { ReportStrategyConfig, + ReportStrategyDefaultValue, ReportStrategyType, ReportStrategyTypeTranslationsMap } from '@home/components/widget/lib/gateway/gateway-widget.models'; @@ -43,7 +44,7 @@ import { CommonModule } from '@angular/common'; import { ModbusSecurityConfigComponent } from '@home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-security-config/modbus-security-config.component'; -import { coerceBoolean } from '@shared/decorators/coercion'; +import { coerceBoolean, coerceNumber } from '@shared/decorators/coercion'; @Component({ selector: 'tb-report-strategy', @@ -73,6 +74,9 @@ export class ReportStrategyComponent implements ControlValueAccessor, OnDestroy @coerceBoolean() @Input() isExpansionMode = false; + @coerceNumber() + @Input() defaultValue = ReportStrategyDefaultValue.Key; + reportStrategyFormGroup: UntypedFormGroup; showStrategyControl: FormControl; @@ -90,7 +94,7 @@ export class ReportStrategyComponent implements ControlValueAccessor, OnDestroy this.reportStrategyFormGroup = this.fb.group({ type: [{ value: ReportStrategyType.OnReportPeriod, disabled: true }, []], - reportPeriod: [{ value: 5000, disabled: true }, [Validators.required]], + reportPeriod: [{ value: this.defaultValue, disabled: true }, [Validators.required]], }); this.observeStrategyFormChange(); @@ -109,7 +113,7 @@ export class ReportStrategyComponent implements ControlValueAccessor, OnDestroy if (reportStrategyConfig) { this.reportStrategyFormGroup.enable({emitEvent: false}); } - const { type = ReportStrategyType.OnReportPeriod, reportPeriod = 5000 } = reportStrategyConfig ?? {}; + const { type = ReportStrategyType.OnReportPeriod, reportPeriod = this.defaultValue } = reportStrategyConfig ?? {}; this.reportStrategyFormGroup.setValue({ type, reportPeriod }, {emitEvent: false}); this.onTypeChange(type); } 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 cec81ab637..cad7af4392 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 @@ -23,7 +23,7 @@ @@ -244,7 +244,7 @@
@@ -315,6 +315,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 a4c1985595..8ca92d4ca7 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 @@ -42,7 +42,7 @@ import { MatTableDataSource } from '@angular/material/table'; import { ActionNotificationShow } from '@core/notification/notification.actions'; import { DialogService } from '@core/services/dialog.service'; import { WidgetContext } from '@home/models/widget-component.models'; -import { camelCase, deepClone, generateSecret, isEqual, isString } from '@core/utils'; +import { camelCase, deepClone, isEqual, isString } from '@core/utils'; import { NULL_UUID } from '@shared/models/id/has-uuid'; import { IWidgetSubscription, WidgetSubscriptionOptions } from '@core/api/widget-api.models'; import { DatasourceType, widgetType } from '@shared/models/widget.models'; @@ -60,6 +60,8 @@ import { GatewayLogLevel, noLeadTrailSpacesRegex, GatewayVersion, + ReportStrategyDefaultValue, + ReportStrategyType, } from './gateway-widget.models'; import { MatDialog } from '@angular/material/dialog'; import { AddConnectorDialogComponent } from '@home/components/widget/lib/gateway/dialog/add-connector-dialog.component'; @@ -103,6 +105,7 @@ export class GatewayConnectorComponent extends PageComponent implements AfterVie readonly GatewayConnectorTypesTranslatesMap = GatewayConnectorDefaultTypesTranslatesMap; readonly ConnectorConfigurationModes = ConfigurationModes; readonly GatewayVersion = GatewayVersion; + readonly ReportStrategyDefaultValue = ReportStrategyDefaultValue; pageLink: PageLink; dataSource: MatTableDataSource; @@ -170,18 +173,21 @@ export class GatewayConnectorComponent extends PageComponent implements AfterVie super.ngOnDestroy(); } - saveConnector(isNew = true): void { - const value = this.getConnectorData(); + onSaveConnector(): void { + this.saveConnector(this.getUpdatedConnectorData(this.connectorForm.value), false); + } + + private saveConnector(connector: GatewayConnector, isNew = true): void { const scope = (isNew || this.activeConnectors.includes(this.initialConnector.name)) ? AttributeScope.SHARED_SCOPE : AttributeScope.SERVER_SCOPE; - forkJoin(this.getEntityAttributeTasks(value, scope)).pipe(take(1)).subscribe(_ => { - this.showToast(!this.initialConnector - ? this.translate.instant('gateway.connector-created') - : this.translate.instant('gateway.connector-updated') + forkJoin(this.getEntityAttributeTasks(connector, scope)).pipe(take(1)).subscribe(_ => { + this.showToast(isNew + ? this.translate.instant('gateway.connector-created') + : this.translate.instant('gateway.connector-updated') ); - this.initialConnector = value; + this.initialConnector = connector; this.updateData(true); this.connectorForm.markAsPristine(); }); @@ -237,8 +243,8 @@ export class GatewayConnectorComponent extends PageComponent implements AfterVie } } - private getConnectorData(): GatewayConnector { - const value = { ...this.connectorForm.value }; + private getUpdatedConnectorData(connector: GatewayConnector): GatewayConnector { + const value = {...connector }; value.configuration = `${camelCase(value.name)}.json`; delete value.basicConfig; @@ -249,6 +255,16 @@ export class GatewayConnectorComponent extends PageComponent implements AfterVie delete value.class; } + if (value.type === ConnectorType.MODBUS && value.configVersion === GatewayVersion.Current) { + if (!value.reportStrategy) { + value.reportStrategy = { + type: ReportStrategyType.OnReportPeriod, + reportPeriod: ReportStrategyDefaultValue.Connector + }; + delete value.sendDataOnlyOnChange; + } + } + if (this.gatewayVersion && !value.configVersion) { value.configVersion = this.gatewayVersion; } @@ -472,7 +488,7 @@ export class GatewayConnectorComponent extends PageComponent implements AfterVie return (connector && this.activeConnectors.includes(connectorName)) ? (connector.data[0][1] || 0) : 'Inactive'; } - addConnector(event?: Event): void { + onAddConnector(event?: Event): void { event?.stopPropagation(); this.confirmConnectorChange() @@ -482,25 +498,42 @@ export class GatewayConnectorComponent extends PageComponent implements AfterVie switchMap(() => this.openAddConnectorDialog()), filter(Boolean), ) - .subscribe(value => { - if (this.connectorForm.disabled) { - this.connectorForm.enable(); - } - if (!value.configurationJson) { - value.configurationJson = {} as ConnectorBaseConfig; - } - value.basicConfig = value.configurationJson; - this.initialConnector = value; - this.connectorForm.patchValue(value, {emitEvent: false}); - this.generate('basicConfig.broker.clientId'); - if (this.connectorForm.get('type').value === value.type || !this.allowBasicConfig.has(value.type)) { - this.saveConnector(); - } else { - this.basicConfigInitSubject.pipe(take(1)).subscribe(() => { - this.saveConnector(); - }); - } - }); + .subscribe(connector => this.addConnector(connector)); + } + + private addConnector(connector: GatewayConnector): void { + if (this.connectorForm.disabled) { + this.connectorForm.enable(); + } + if (!connector.configurationJson) { + connector.configurationJson = {} as ConnectorBaseConfig; + } + connector.basicConfig = connector.configurationJson; + this.initialConnector = connector; + + const previousType = this.connectorForm.get('type').value; + + this.setInitialConnectorValues(connector); + + this.saveConnector(this.getUpdatedConnectorData(connector)); + + if (!previousType || previousType === connector.type || !this.allowBasicConfig.has(connector.type)) { + this.patchBasicConfigConnector(connector); + } else { + this.basicConfigInitSubject.pipe(take(1)).subscribe(() => { + this.patchBasicConfigConnector(connector); + }); + } + } + + private setInitialConnectorValues(connector: GatewayConnector): void { + this.toggleReportStrategy(connector.type); + this.connectorForm.get('mode').setValue(this.allowBasicConfig.has(connector.type) + ? connector.mode ?? ConfigurationModes.BASIC + : null, {emitEvent: false} + ); + this.connectorForm.get('configVersion').setValue(connector.configVersion, {emitEvent: false}); + this.connectorForm.get('type').setValue(connector.type, {emitEvent: false}); } private openAddConnectorDialog(): Observable { @@ -514,10 +547,6 @@ export class GatewayConnectorComponent extends PageComponent implements AfterVie }).afterClosed(); } - generate(formControlName: string): void { - this.connectorForm.get(formControlName)?.patchValue('tb_gw_' + generateSecret(5)); - } - uniqNameRequired(): ValidatorFn { return (control: UntypedFormControl) => { const newName = control.value?.trim().toLowerCase(); @@ -607,7 +636,7 @@ export class GatewayConnectorComponent extends PageComponent implements AfterVie 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; + const lastConnectedTime = attributes.find(data => data.key === 'lastConnectTime')?.value; this.isGatewayActive = this.getGatewayStatus(active, lastConnectedTime, lastDisconnectedTime); }); @@ -804,7 +833,6 @@ export class GatewayConnectorComponent extends PageComponent implements AfterVie } private updateConnector(connector: GatewayConnector): void { - this.toggleReportStrategy(connector.type); switch (connector.type) { case ConnectorType.MQTT: case ConnectorType.OPCUA: @@ -819,8 +847,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}); + this.setInitialConnectorValues(connector); if ((!connector.mode || connector.mode === ConfigurationModes.BASIC) && this.connectorForm.get('type').value !== connector.type) { this.basicConfigInitSubject.asObservable().pipe(take(1)).subscribe(() => { this.patchBasicConfigConnector(connector); 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 f1fbd4d0f5..f8f1c99289 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 @@ -123,6 +123,9 @@ export interface GatewayConnectorBase { class?: string; mode?: ConfigurationModes; configVersion?: string; + reportStrategy?: ReportStrategyConfig; + sendDataOnlyOnChange?: boolean; + ts?: number; } export interface GatewayConnector extends GatewayConnectorBase { @@ -645,6 +648,12 @@ export enum ReportStrategyType { OnChangeOrReportPeriod = 'ON_CHANGE_OR_REPORT_PERIOD' } +export enum ReportStrategyDefaultValue { + Connector = 60000, + Device = 30000, + Key = 15000 +} + export const ReportStrategyTypeTranslationsMap = new Map( [ [ReportStrategyType.OnChange, 'gateway.report-strategy.on-change'], 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 bb4fc57e8a..3f22e78672 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -2955,7 +2955,6 @@ "configuration-delete-dialog-confirm": "Turn Off", "connector-duplicate-name": "Connector with such name already exists.", "connector-side": "Connector side", - "client-communication-type": "Client communication type", "payload-type": "Payload type", "platform-side": "Platform side", "JSON": "JSON",