[4114] Added Modbus version mapping and OPC initial mapping
This commit is contained in:
parent
339f2c3e8f
commit
b142c72247
@ -0,0 +1,72 @@
|
||||
///
|
||||
/// Copyright © 2016-2024 The Thingsboard Authors
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
/// You may obtain a copy of the License at
|
||||
///
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
///
|
||||
/// Unless required by applicable law or agreed to in writing, software
|
||||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
|
||||
import { Directive, inject, Input, OnDestroy, 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<InputBasicConfig, OutputBasicConfig>
|
||||
implements ControlValueAccessor, Validator, OnDestroy {
|
||||
|
||||
@Input() generalTabContent: TemplateRef<any>;
|
||||
|
||||
basicFormGroup: FormGroup;
|
||||
|
||||
protected fb = inject(FormBuilder);
|
||||
protected onChange!: (value: OutputBasicConfig) => void;
|
||||
protected onTouched!: () => void;
|
||||
protected destroy$ = new Subject<void>();
|
||||
|
||||
constructor() {
|
||||
this.basicFormGroup = this.initBasicFormGroup();
|
||||
|
||||
this.basicFormGroup.valueChanges
|
||||
.pipe(takeUntil(this.destroy$))
|
||||
.subscribe((value) => this.onBasicFormGroupChange(value));
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this.destroy$.next();
|
||||
this.destroy$.complete();
|
||||
}
|
||||
|
||||
validate(): ValidationErrors | null {
|
||||
return this.basicFormGroup.valid ? null : { basicFormGroup: { valid: false } };
|
||||
}
|
||||
|
||||
registerOnChange(fn: (value: OutputBasicConfig) => void): void {
|
||||
this.onChange = fn;
|
||||
}
|
||||
|
||||
registerOnTouched(fn: () => void): void {
|
||||
this.onTouched = fn;
|
||||
}
|
||||
|
||||
writeValue(config: OutputBasicConfig): void {
|
||||
this.basicFormGroup.setValue(this.mapConfigToFormValue(config), { emitEvent: false });
|
||||
}
|
||||
|
||||
protected onBasicFormGroupChange(value: InputBasicConfig): void {
|
||||
this.onChange(this.getMappedValue(value));
|
||||
this.onTouched();
|
||||
}
|
||||
|
||||
protected abstract mapConfigToFormValue(config: OutputBasicConfig): InputBasicConfig;
|
||||
protected abstract getMappedValue(config: InputBasicConfig): OutputBasicConfig;
|
||||
protected abstract initBasicFormGroup(): FormGroup;
|
||||
}
|
||||
@ -15,6 +15,7 @@
|
||||
///
|
||||
|
||||
import { GatewayConnector, GatewayVersion } from '@home/components/widget/lib/gateway/gateway-widget.models';
|
||||
import { isString } from '@core/utils';
|
||||
|
||||
export abstract class GatewayConnectorVersionProcessor<BasicConfig> {
|
||||
gatewayVersion: number;
|
||||
@ -48,7 +49,7 @@ export abstract class GatewayConnectorVersionProcessor<BasicConfig> {
|
||||
}
|
||||
|
||||
private parseVersion(version: string): number {
|
||||
return Number(version?.replace(/\./g, ''));
|
||||
return isString(version) ? Number(version.replace(/\./g, '')) : 0;
|
||||
}
|
||||
|
||||
protected abstract getDowngradedVersion(): GatewayConnector<BasicConfig>;
|
||||
|
||||
@ -0,0 +1,67 @@
|
||||
///
|
||||
/// Copyright © 2016-2024 The Thingsboard Authors
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
/// You may obtain a copy of the License at
|
||||
///
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
///
|
||||
/// Unless required by applicable law or agreed to in writing, software
|
||||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
|
||||
import {
|
||||
GatewayConnector,
|
||||
ModbusBasicConfig,
|
||||
ModbusBasicConfig_v3_5_2,
|
||||
ModbusLegacyBasicConfig,
|
||||
ModbusLegacySlave,
|
||||
ModbusMasterConfig,
|
||||
ModbusSlave,
|
||||
} from '../gateway-widget.models';
|
||||
import { GatewayConnectorVersionProcessor } from './gateway-connector-version-processor.abstract';
|
||||
import { ModbusVersionMappingUtil } from '@home/components/widget/lib/gateway/utils/modbus-version-mapping.util';
|
||||
|
||||
export class ModbusVersionProcessor extends GatewayConnectorVersionProcessor<any> {
|
||||
|
||||
constructor(
|
||||
protected gatewayVersionStr: string,
|
||||
protected connector: GatewayConnector<ModbusBasicConfig>
|
||||
) {
|
||||
super(gatewayVersionStr, connector);
|
||||
}
|
||||
getUpgradedVersion(): GatewayConnector<ModbusBasicConfig_v3_5_2> {
|
||||
const configurationJson = this.connector.configurationJson;
|
||||
return {
|
||||
...this.connector,
|
||||
configurationJson: {
|
||||
master: configurationJson.master
|
||||
? ModbusVersionMappingUtil.mapMasterToUpgradedVersion(configurationJson.master)
|
||||
: {} as ModbusMasterConfig,
|
||||
slave: configurationJson.slave
|
||||
? ModbusVersionMappingUtil.mapSlaveToUpgradedVersion(configurationJson.slave as ModbusLegacySlave)
|
||||
: {} as ModbusSlave,
|
||||
},
|
||||
configVersion: this.gatewayVersionStr
|
||||
} as GatewayConnector<ModbusBasicConfig_v3_5_2>;
|
||||
}
|
||||
|
||||
getDowngradedVersion(): GatewayConnector<ModbusLegacyBasicConfig> {
|
||||
const configurationJson = this.connector.configurationJson;
|
||||
return {
|
||||
...this.connector,
|
||||
configurationJson: {
|
||||
...configurationJson,
|
||||
slave: configurationJson.slave
|
||||
? ModbusVersionMappingUtil.mapSlaveToDowngradedVersion(configurationJson.slave as ModbusSlave)
|
||||
: {} as ModbusLegacySlave,
|
||||
master: configurationJson.master,
|
||||
},
|
||||
configVersion: this.gatewayVersionStr
|
||||
} as GatewayConnector<ModbusLegacyBasicConfig>;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,55 @@
|
||||
///
|
||||
/// Copyright © 2016-2024 The Thingsboard Authors
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
/// You may obtain a copy of the License at
|
||||
///
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
///
|
||||
/// Unless required by applicable law or agreed to in writing, software
|
||||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
|
||||
import {
|
||||
GatewayConnector, LegacyServerConfig,
|
||||
OPCBasicConfig,
|
||||
OPCBasicConfig_v3_5_2,
|
||||
OPCLegacyBasicConfig,
|
||||
} from '../gateway-widget.models';
|
||||
import { GatewayConnectorVersionProcessor } from './gateway-connector-version-processor.abstract';
|
||||
import { OpcVersionMappingUtil } from '@home/components/widget/lib/gateway/utils/opc-version-mapping.util';
|
||||
|
||||
export class OpcVersionProcessor extends GatewayConnectorVersionProcessor<OPCBasicConfig> {
|
||||
|
||||
constructor(
|
||||
protected gatewayVersionStr: string,
|
||||
protected connector: GatewayConnector<OPCBasicConfig>
|
||||
) {
|
||||
super(gatewayVersionStr, connector);
|
||||
}
|
||||
getUpgradedVersion(): GatewayConnector<OPCBasicConfig_v3_5_2> {
|
||||
const server = this.connector.configurationJson.server as LegacyServerConfig;
|
||||
return {
|
||||
...this.connector,
|
||||
configurationJson: {
|
||||
server: server ? OpcVersionMappingUtil.mapServerToUpgradedVersion(server) : {},
|
||||
mapping: server.mapping ? OpcVersionMappingUtil.mapMappingToUpgradedVersion(server.mapping) : [],
|
||||
},
|
||||
configVersion: this.gatewayVersionStr
|
||||
} as GatewayConnector<OPCBasicConfig_v3_5_2>;
|
||||
}
|
||||
|
||||
getDowngradedVersion(): GatewayConnector<OPCLegacyBasicConfig> {
|
||||
return {
|
||||
...this.connector,
|
||||
configurationJson: {
|
||||
server: OpcVersionMappingUtil.mapServerToDowngradedVersion(this.connector.configurationJson as OPCBasicConfig_v3_5_2)
|
||||
},
|
||||
configVersion: this.gatewayVersionStr
|
||||
} as GatewayConnector<OPCLegacyBasicConfig>;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,81 @@
|
||||
///
|
||||
/// Copyright © 2016-2024 The Thingsboard Authors
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
/// You may obtain a copy of the License at
|
||||
///
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
///
|
||||
/// Unless required by applicable law or agreed to in writing, software
|
||||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
|
||||
import { Directive } from '@angular/core';
|
||||
import { FormControl, FormGroup, ValidationErrors } from '@angular/forms';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { isEqual } from '@core/utils';
|
||||
import { GatewayConnectorBasicConfigDirective } from '@home/components/widget/lib/gateway/abstract/gateway-connector-basic-config.abstract';
|
||||
import {
|
||||
ModbusBasicConfig,
|
||||
ModbusBasicConfig_v3_5_2,
|
||||
} from '@home/components/widget/lib/gateway/gateway-widget.models';
|
||||
|
||||
@Directive()
|
||||
export abstract class ModbusBasicConfigDirective<BasicConfig>
|
||||
extends GatewayConnectorBasicConfigDirective<ModbusBasicConfig_v3_5_2, BasicConfig> {
|
||||
|
||||
enableSlaveControl: FormControl<boolean> = new FormControl(false);
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.enableSlaveControl.valueChanges
|
||||
.pipe(takeUntil(this.destroy$))
|
||||
.subscribe(enable => {
|
||||
this.updateSlaveEnabling(enable);
|
||||
this.basicFormGroup.get('slave').updateValueAndValidity({ emitEvent: !!this.onChange });
|
||||
});
|
||||
}
|
||||
|
||||
override writeValue(basicConfig: BasicConfig & ModbusBasicConfig): void {
|
||||
super.writeValue(basicConfig);
|
||||
this.onEnableSlaveControl(basicConfig);
|
||||
}
|
||||
|
||||
override validate(): ValidationErrors | null {
|
||||
const { master, slave } = this.basicFormGroup.value;
|
||||
const isEmpty = !master?.slaves?.length && (isEqual(slave, {}) || !slave);
|
||||
if (!this.basicFormGroup.valid || isEmpty) {
|
||||
return { basicFormGroup: { valid: false } };
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected override initBasicFormGroup(): FormGroup {
|
||||
return this.fb.group({
|
||||
master: [],
|
||||
slave: [],
|
||||
});
|
||||
}
|
||||
|
||||
protected override onBasicFormGroupChange(value: ModbusBasicConfig_v3_5_2): void {
|
||||
super.onBasicFormGroupChange(value);
|
||||
this.basicFormGroup.get('slave').updateValueAndValidity({ emitEvent: !!this.onChange });
|
||||
}
|
||||
|
||||
private updateSlaveEnabling(isEnabled: boolean): void {
|
||||
if (isEnabled) {
|
||||
this.basicFormGroup.get('slave').enable({ emitEvent: false });
|
||||
} else {
|
||||
this.basicFormGroup.get('slave').disable({ emitEvent: false });
|
||||
}
|
||||
}
|
||||
|
||||
private onEnableSlaveControl(basicConfig: ModbusBasicConfig): void {
|
||||
this.enableSlaveControl.setValue(!!basicConfig.slave && !isEqual(basicConfig.slave, {}));
|
||||
}
|
||||
}
|
||||
@ -14,28 +14,21 @@
|
||||
/// limitations under the License.
|
||||
///
|
||||
|
||||
import { ChangeDetectionStrategy, Component, forwardRef, Input, OnDestroy, TemplateRef } from '@angular/core';
|
||||
import { ChangeDetectionStrategy, Component, forwardRef } from '@angular/core';
|
||||
import { NG_VALIDATORS, NG_VALUE_ACCESSOR } from '@angular/forms';
|
||||
import {
|
||||
ControlValueAccessor,
|
||||
FormBuilder,
|
||||
FormControl,
|
||||
FormGroup,
|
||||
NG_VALIDATORS,
|
||||
NG_VALUE_ACCESSOR,
|
||||
UntypedFormControl,
|
||||
ValidationErrors,
|
||||
Validator,
|
||||
} from '@angular/forms';
|
||||
import { ModbusBasicConfig } from '@home/components/widget/lib/gateway/gateway-widget.models';
|
||||
import { SharedModule } from '@shared/shared.module';
|
||||
ModbusBasicConfig_v3_5_2,
|
||||
ModbusMasterConfig,
|
||||
ModbusSlave
|
||||
} from '@home/components/widget/lib/gateway/gateway-widget.models';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { Subject } from 'rxjs';
|
||||
|
||||
import { EllipsisChipListDirective } from '@shared/directives/ellipsis-chip-list.directive';
|
||||
import { SharedModule } from '@shared/shared.module';
|
||||
import { ModbusSlaveConfigComponent } from '../modbus-slave-config/modbus-slave-config.component';
|
||||
import { ModbusMasterTableComponent } from '../modbus-master-table/modbus-master-table.component';
|
||||
import { isEqual } from '@core/utils';
|
||||
import { EllipsisChipListDirective } from '@shared/directives/ellipsis-chip-list.directive';
|
||||
import {
|
||||
ModbusBasicConfigDirective
|
||||
} from '@home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-basic-config/modbus-basic-config.abstract';
|
||||
|
||||
@Component({
|
||||
selector: 'tb-modbus-basic-config',
|
||||
@ -63,80 +56,19 @@ import { isEqual } from '@core/utils';
|
||||
],
|
||||
styleUrls: ['./modbus-basic-config.component.scss'],
|
||||
})
|
||||
export class ModbusBasicConfigComponent extends ModbusBasicConfigDirective<ModbusBasicConfig_v3_5_2> {
|
||||
|
||||
export class ModbusBasicConfigComponent implements ControlValueAccessor, Validator, OnDestroy {
|
||||
|
||||
@Input() generalTabContent: TemplateRef<any>;
|
||||
|
||||
basicFormGroup: FormGroup;
|
||||
enableSlaveControl: FormControl<boolean>;
|
||||
|
||||
onChange: (value: ModbusBasicConfig) => void;
|
||||
onTouched: () => void;
|
||||
|
||||
private destroy$ = new Subject<void>();
|
||||
|
||||
constructor(private fb: FormBuilder) {
|
||||
this.basicFormGroup = this.fb.group({
|
||||
master: [],
|
||||
slave: [],
|
||||
});
|
||||
this.enableSlaveControl = new FormControl(false);
|
||||
|
||||
this.basicFormGroup.valueChanges
|
||||
.pipe(takeUntil(this.destroy$))
|
||||
.subscribe(({ master, slave }) => {
|
||||
this.onChange({ master, slave: slave ?? {} });
|
||||
this.onTouched();
|
||||
});
|
||||
|
||||
this.enableSlaveControl.valueChanges
|
||||
.pipe(takeUntil(this.destroy$))
|
||||
.subscribe(enable => {
|
||||
this.updateSlaveEnabling(enable);
|
||||
this.basicFormGroup.get('slave').updateValueAndValidity({emitEvent: !!this.onChange});
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this.destroy$.next();
|
||||
this.destroy$.complete();
|
||||
}
|
||||
|
||||
registerOnChange(fn: (value: ModbusBasicConfig) => void): void {
|
||||
this.onChange = fn;
|
||||
}
|
||||
|
||||
registerOnTouched(fn: () => void): void {
|
||||
this.onTouched = fn;
|
||||
}
|
||||
|
||||
writeValue(basicConfig: ModbusBasicConfig): void {
|
||||
const editedBase = {
|
||||
slave: basicConfig.slave ?? {},
|
||||
master: basicConfig.master ?? {},
|
||||
protected override mapConfigToFormValue(config: ModbusBasicConfig_v3_5_2): ModbusBasicConfig_v3_5_2 {
|
||||
return {
|
||||
master: config.master ?? {} as ModbusMasterConfig,
|
||||
slave: config.slave ?? {} as ModbusSlave,
|
||||
};
|
||||
|
||||
this.basicFormGroup.setValue(editedBase, {emitEvent: false});
|
||||
this.enableSlaveControl.setValue(!!basicConfig.slave && !isEqual(basicConfig.slave, {}));
|
||||
}
|
||||
|
||||
validate(basicFormControl: UntypedFormControl): ValidationErrors | null {
|
||||
const { master, slave } = basicFormControl.value;
|
||||
const isEmpty = !master?.slaves?.length && (isEqual(slave, {}) || !slave);
|
||||
if (!this.basicFormGroup.valid || isEmpty) {
|
||||
return {
|
||||
basicFormGroup: {valid: false}
|
||||
};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private updateSlaveEnabling(isEnabled: boolean): void {
|
||||
if (isEnabled) {
|
||||
this.basicFormGroup.get('slave').enable({emitEvent: false});
|
||||
} else {
|
||||
this.basicFormGroup.get('slave').disable({emitEvent: false});
|
||||
}
|
||||
protected override getMappedValue(value: ModbusBasicConfig_v3_5_2): ModbusBasicConfig_v3_5_2 {
|
||||
return {
|
||||
master: value.master,
|
||||
slave: value.slave,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,76 @@
|
||||
///
|
||||
/// Copyright © 2016-2024 The Thingsboard Authors
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
/// You may obtain a copy of the License at
|
||||
///
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
///
|
||||
/// Unless required by applicable law or agreed to in writing, software
|
||||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
|
||||
import { ChangeDetectionStrategy, Component, forwardRef } from '@angular/core';
|
||||
import { NG_VALIDATORS, NG_VALUE_ACCESSOR } from '@angular/forms';
|
||||
import {
|
||||
ModbusBasicConfig_v3_5_2,
|
||||
ModbusLegacyBasicConfig, ModbusLegacySlave,
|
||||
ModbusMasterConfig,
|
||||
ModbusSlave
|
||||
} from '@home/components/widget/lib/gateway/gateway-widget.models';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { SharedModule } from '@shared/shared.module';
|
||||
import { ModbusSlaveConfigComponent } from '../modbus-slave-config/modbus-slave-config.component';
|
||||
import { ModbusMasterTableComponent } from '../modbus-master-table/modbus-master-table.component';
|
||||
import { EllipsisChipListDirective } from '@shared/directives/ellipsis-chip-list.directive';
|
||||
import { ModbusVersionMappingUtil } from '@home/components/widget/lib/gateway/utils/modbus-version-mapping.util';
|
||||
import {
|
||||
ModbusBasicConfigDirective
|
||||
} from '@home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-basic-config/modbus-basic-config.abstract';
|
||||
|
||||
@Component({
|
||||
selector: 'tb-modbus-legacy-basic-config',
|
||||
templateUrl: './modbus-basic-config.component.html',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
providers: [
|
||||
{
|
||||
provide: NG_VALUE_ACCESSOR,
|
||||
useExisting: forwardRef(() => ModbusLegacyBasicConfigComponent),
|
||||
multi: true
|
||||
},
|
||||
{
|
||||
provide: NG_VALIDATORS,
|
||||
useExisting: forwardRef(() => ModbusLegacyBasicConfigComponent),
|
||||
multi: true
|
||||
}
|
||||
],
|
||||
standalone: true,
|
||||
imports: [
|
||||
CommonModule,
|
||||
SharedModule,
|
||||
ModbusSlaveConfigComponent,
|
||||
ModbusMasterTableComponent,
|
||||
EllipsisChipListDirective,
|
||||
],
|
||||
styleUrls: ['./modbus-basic-config.component.scss'],
|
||||
})
|
||||
export class ModbusLegacyBasicConfigComponent extends ModbusBasicConfigDirective<ModbusLegacyBasicConfig> {
|
||||
|
||||
protected override mapConfigToFormValue(config: ModbusLegacyBasicConfig): ModbusBasicConfig_v3_5_2 {
|
||||
return {
|
||||
master: config.master ? ModbusVersionMappingUtil.mapMasterToUpgradedVersion(config.master) : {} as ModbusMasterConfig,
|
||||
slave: config.slave ? ModbusVersionMappingUtil.mapSlaveToUpgradedVersion(config.slave) : {} as ModbusSlave,
|
||||
};
|
||||
}
|
||||
|
||||
protected override getMappedValue(value: ModbusBasicConfig_v3_5_2): ModbusLegacyBasicConfig {
|
||||
return {
|
||||
master: value.master,
|
||||
slave: value.slave ? ModbusVersionMappingUtil.mapSlaveToDowngradedVersion(value.slave) : {} as ModbusLegacySlave,
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -14,63 +14,33 @@
|
||||
/// limitations under the License.
|
||||
///
|
||||
|
||||
import { ControlValueAccessor, FormBuilder, FormGroup, ValidationErrors, Validator } from '@angular/forms';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { Directive } from '@angular/core';
|
||||
import { FormGroup } from '@angular/forms';
|
||||
import {
|
||||
MappingType,
|
||||
MQTTBasicConfig,
|
||||
MQTTBasicConfig, MQTTBasicConfig_v3_5_2,
|
||||
RequestMappingData,
|
||||
RequestMappingValue,
|
||||
RequestType
|
||||
} from '@home/components/widget/lib/gateway/gateway-widget.models';
|
||||
import { Directive, OnDestroy } from '@angular/core';
|
||||
import { isObject } from '@core/utils';
|
||||
import {
|
||||
GatewayConnectorBasicConfigDirective
|
||||
} from '@home/components/widget/lib/gateway/abstract/gateway-connector-basic-config.abstract';
|
||||
|
||||
@Directive()
|
||||
export abstract class AbstractMqttBasicConfigComponent<BasicConfig> implements ControlValueAccessor, Validator, OnDestroy {
|
||||
export abstract class MqttBasicConfigDirective<BasicConfig>
|
||||
extends GatewayConnectorBasicConfigDirective<MQTTBasicConfig_v3_5_2, BasicConfig> {
|
||||
|
||||
basicFormGroup: FormGroup;
|
||||
MappingType = MappingType;
|
||||
|
||||
private destroy$ = new Subject<void>();
|
||||
|
||||
private onChange: (value: BasicConfig) => void;
|
||||
private onTouched: () => void;
|
||||
|
||||
constructor(protected fb: FormBuilder) {
|
||||
this.basicFormGroup = this.fb.group({
|
||||
protected override initBasicFormGroup(): FormGroup {
|
||||
return this.fb.group({
|
||||
mapping: [],
|
||||
requestsMapping: [],
|
||||
broker: [],
|
||||
workers: [],
|
||||
});
|
||||
|
||||
this.basicFormGroup.valueChanges
|
||||
.pipe(takeUntil(this.destroy$))
|
||||
.subscribe(value => {
|
||||
this.onChange(this.getMappedMQTTConfig(value));
|
||||
this.onTouched();
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this.destroy$.next();
|
||||
this.destroy$.complete();
|
||||
}
|
||||
|
||||
registerOnChange(fn: (value: BasicConfig) => void): void {
|
||||
this.onChange = fn;
|
||||
}
|
||||
|
||||
registerOnTouched(fn: () => void): void {
|
||||
this.onTouched = fn;
|
||||
}
|
||||
|
||||
validate(): ValidationErrors | null {
|
||||
return this.basicFormGroup.valid ? null : {
|
||||
basicFormGroup: {valid: false}
|
||||
};
|
||||
}
|
||||
|
||||
protected getRequestDataArray(value: Record<RequestType, RequestMappingData[]>): RequestMappingData[] {
|
||||
@ -103,6 +73,10 @@ export abstract class AbstractMqttBasicConfigComponent<BasicConfig> implements C
|
||||
});
|
||||
}
|
||||
|
||||
abstract writeValue(basicConfig: BasicConfig): void;
|
||||
protected abstract getMappedMQTTConfig(basicConfig: MQTTBasicConfig): BasicConfig;
|
||||
writeValue(basicConfig: BasicConfig): void {
|
||||
this.basicFormGroup.setValue(this.mapConfigToFormValue(basicConfig), { emitEvent: false });
|
||||
}
|
||||
|
||||
protected abstract override mapConfigToFormValue(config: BasicConfig): MQTTBasicConfig_v3_5_2;
|
||||
protected abstract override getMappedValue(config: MQTTBasicConfig): BasicConfig;
|
||||
}
|
||||
|
||||
@ -14,16 +14,17 @@
|
||||
/// limitations under the License.
|
||||
///
|
||||
|
||||
import { Component, forwardRef, Input, TemplateRef, ChangeDetectionStrategy } from '@angular/core';
|
||||
import { Component, forwardRef, ChangeDetectionStrategy } from '@angular/core';
|
||||
import { NG_VALUE_ACCESSOR, NG_VALIDATORS } from '@angular/forms';
|
||||
import {
|
||||
BrokerConfig,
|
||||
MQTTBasicConfig_v3_5_2,
|
||||
RequestMappingData,
|
||||
RequestMappingValue,
|
||||
RequestType
|
||||
RequestType, WorkersConfig
|
||||
} from '@home/components/widget/lib/gateway/gateway-widget.models';
|
||||
import {
|
||||
AbstractMqttBasicConfigComponent
|
||||
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';
|
||||
@ -33,7 +34,7 @@ import {
|
||||
} from '@home/components/widget/lib/gateway/connectors-configuration/security-config/security-config.component';
|
||||
import {
|
||||
WorkersConfigControlComponent
|
||||
} from '@home/components/widget/lib/gateway/connectors-configuration/workers-config-control/workers-config-control.component';
|
||||
} from '@home/components/widget/lib/gateway/connectors-configuration/mqtt/workers-config-control/workers-config-control.component';
|
||||
import {
|
||||
BrokerConfigControlComponent
|
||||
} from '@home/components/widget/lib/gateway/connectors-configuration/mqtt/broker-config-control/broker-config-control.component';
|
||||
@ -68,27 +69,22 @@ import {
|
||||
MappingTableComponent,
|
||||
],
|
||||
})
|
||||
export class MqttBasicConfigComponent extends AbstractMqttBasicConfigComponent<MQTTBasicConfig_v3_5_2> {
|
||||
export class MqttBasicConfigComponent extends MqttBasicConfigDirective<MQTTBasicConfig_v3_5_2> {
|
||||
|
||||
@Input()
|
||||
generalTabContent: TemplateRef<any>;
|
||||
|
||||
writeValue(basicConfig: MQTTBasicConfig_v3_5_2): void {
|
||||
protected override mapConfigToFormValue(basicConfig: MQTTBasicConfig_v3_5_2): MQTTBasicConfig_v3_5_2 {
|
||||
const { broker, mapping = [], requestsMapping } = basicConfig;
|
||||
const editedBase = {
|
||||
return{
|
||||
workers: broker && (broker.maxNumberOfWorkers || broker.maxMessageNumberPerWorker) ? {
|
||||
maxNumberOfWorkers: broker.maxNumberOfWorkers,
|
||||
maxMessageNumberPerWorker: broker.maxMessageNumberPerWorker,
|
||||
} : {},
|
||||
} : {} as WorkersConfig,
|
||||
mapping: mapping ?? [],
|
||||
broker: broker ?? {},
|
||||
broker: broker ?? {} as BrokerConfig,
|
||||
requestsMapping: this.getRequestDataArray(requestsMapping as Record<RequestType, RequestMappingData[]>),
|
||||
};
|
||||
|
||||
this.basicFormGroup.setValue(editedBase, {emitEvent: false});
|
||||
}
|
||||
|
||||
protected getMappedMQTTConfig(basicConfig: MQTTBasicConfig_v3_5_2): MQTTBasicConfig_v3_5_2 {
|
||||
protected override getMappedValue(basicConfig: MQTTBasicConfig_v3_5_2): MQTTBasicConfig_v3_5_2 {
|
||||
let { broker, workers, mapping, requestsMapping } = basicConfig || {};
|
||||
|
||||
if (isDefinedAndNotNull(workers.maxNumberOfWorkers) || isDefinedAndNotNull(workers.maxMessageNumberPerWorker)) {
|
||||
|
||||
@ -14,18 +14,19 @@
|
||||
/// limitations under the License.
|
||||
///
|
||||
|
||||
import { Component, forwardRef, Input, TemplateRef, ChangeDetectionStrategy } from '@angular/core';
|
||||
import { Component, forwardRef, ChangeDetectionStrategy } from '@angular/core';
|
||||
import { NG_VALUE_ACCESSOR, NG_VALIDATORS } from '@angular/forms';
|
||||
import {
|
||||
BrokerConfig,
|
||||
MQTTBasicConfig_v3_5_2,
|
||||
MQTTLegacyBasicConfig,
|
||||
RequestMappingData,
|
||||
RequestMappingValue,
|
||||
RequestType
|
||||
RequestType, WorkersConfig
|
||||
} from '@home/components/widget/lib/gateway/gateway-widget.models';
|
||||
import { MqttVersionMappingUtil } from '@home/components/widget/lib/gateway/utils/mqtt-version-mapping.util';
|
||||
import {
|
||||
AbstractMqttBasicConfigComponent
|
||||
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';
|
||||
@ -35,7 +36,7 @@ import {
|
||||
} from '@home/components/widget/lib/gateway/connectors-configuration/security-config/security-config.component';
|
||||
import {
|
||||
WorkersConfigControlComponent
|
||||
} from '@home/components/widget/lib/gateway/connectors-configuration/workers-config-control/workers-config-control.component';
|
||||
} from '@home/components/widget/lib/gateway/connectors-configuration/mqtt/workers-config-control/workers-config-control.component';
|
||||
import {
|
||||
BrokerConfigControlComponent
|
||||
} from '@home/components/widget/lib/gateway/connectors-configuration/mqtt/broker-config-control/broker-config-control.component';
|
||||
@ -70,12 +71,9 @@ import {
|
||||
MappingTableComponent,
|
||||
],
|
||||
})
|
||||
export class MqttLegacyBasicConfigComponent extends AbstractMqttBasicConfigComponent<MQTTLegacyBasicConfig> {
|
||||
export class MqttLegacyBasicConfigComponent extends MqttBasicConfigDirective<MQTTLegacyBasicConfig> {
|
||||
|
||||
@Input()
|
||||
generalTabContent: TemplateRef<any>;
|
||||
|
||||
writeValue(basicConfig: MQTTLegacyBasicConfig): void {
|
||||
protected override mapConfigToFormValue(config: MQTTLegacyBasicConfig): MQTTBasicConfig_v3_5_2 {
|
||||
const {
|
||||
broker,
|
||||
mapping = [],
|
||||
@ -84,7 +82,7 @@ export class MqttLegacyBasicConfigComponent extends AbstractMqttBasicConfigCompo
|
||||
attributeRequests = [],
|
||||
attributeUpdates = [],
|
||||
serverSideRpc = []
|
||||
} = basicConfig;
|
||||
} = config as MQTTLegacyBasicConfig;
|
||||
const updatedRequestMapping = MqttVersionMappingUtil.mapRequestsToUpgradedVersion({
|
||||
connectRequests,
|
||||
disconnectRequests,
|
||||
@ -92,20 +90,18 @@ export class MqttLegacyBasicConfigComponent extends AbstractMqttBasicConfigCompo
|
||||
attributeUpdates,
|
||||
serverSideRpc
|
||||
});
|
||||
const editedBase = {
|
||||
return {
|
||||
workers: broker && (broker.maxNumberOfWorkers || broker.maxMessageNumberPerWorker) ? {
|
||||
maxNumberOfWorkers: broker.maxNumberOfWorkers,
|
||||
maxMessageNumberPerWorker: broker.maxMessageNumberPerWorker,
|
||||
} : {},
|
||||
} : {} as WorkersConfig,
|
||||
mapping: MqttVersionMappingUtil.mapMappingToUpgradedVersion(mapping) || [],
|
||||
broker: broker || {},
|
||||
broker: broker || {} as BrokerConfig,
|
||||
requestsMapping: this.getRequestDataArray(updatedRequestMapping),
|
||||
};
|
||||
|
||||
this.basicFormGroup.setValue(editedBase, {emitEvent: false});
|
||||
}
|
||||
|
||||
protected getMappedMQTTConfig(basicConfig: MQTTBasicConfig_v3_5_2): MQTTLegacyBasicConfig {
|
||||
protected override getMappedValue(basicConfig: MQTTBasicConfig_v3_5_2): MQTTLegacyBasicConfig {
|
||||
let { broker, workers, mapping, requestsMapping } = basicConfig || {};
|
||||
|
||||
if (isDefinedAndNotNull(workers.maxNumberOfWorkers) || isDefinedAndNotNull(workers.maxMessageNumberPerWorker)) {
|
||||
|
||||
@ -14,34 +14,25 @@
|
||||
/// limitations under the License.
|
||||
///
|
||||
|
||||
import { ChangeDetectionStrategy, Component, forwardRef, Input, OnDestroy, TemplateRef } from '@angular/core';
|
||||
import { ChangeDetectionStrategy, Component, forwardRef } from '@angular/core';
|
||||
import { FormGroup, NG_VALIDATORS, NG_VALUE_ACCESSOR } from '@angular/forms';
|
||||
import {
|
||||
ControlValueAccessor,
|
||||
FormBuilder,
|
||||
FormGroup,
|
||||
NG_VALIDATORS,
|
||||
NG_VALUE_ACCESSOR,
|
||||
ValidationErrors,
|
||||
Validator,
|
||||
} from '@angular/forms';
|
||||
import {
|
||||
ConnectorType,
|
||||
MappingType,
|
||||
OPCBasicConfig,
|
||||
OPCBasicConfig_v3_5_2,
|
||||
ServerConfig
|
||||
} from '@home/components/widget/lib/gateway/gateway-widget.models';
|
||||
import { SharedModule } from '@shared/shared.module';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { Subject } from 'rxjs';
|
||||
import { SharedModule } from '@shared/shared.module';
|
||||
import { MappingTableComponent } from '@home/components/widget/lib/gateway/connectors-configuration/mapping-table/mapping-table.component';
|
||||
import {
|
||||
SecurityConfigComponent
|
||||
} from '@home/components/widget/lib/gateway/connectors-configuration/security-config/security-config.component';
|
||||
import {
|
||||
MappingTableComponent
|
||||
} from '@home/components/widget/lib/gateway/connectors-configuration/mapping-table/mapping-table.component';
|
||||
import {
|
||||
OpcServerConfigComponent
|
||||
} from '@home/components/widget/lib/gateway/connectors-configuration/opc-server-config/opc-server-config.component';
|
||||
} from '@home/components/widget/lib/gateway/connectors-configuration/opc/opc-server-config/opc-server-config.component';
|
||||
import {
|
||||
GatewayConnectorBasicConfigDirective
|
||||
} from '@home/components/widget/lib/gateway/abstract/gateway-connector-basic-config.abstract';
|
||||
|
||||
@Component({
|
||||
selector: 'tb-opc-ua-basic-config',
|
||||
@ -69,58 +60,28 @@ import {
|
||||
],
|
||||
styleUrls: ['./opc-ua-basic-config.component.scss']
|
||||
})
|
||||
|
||||
export class OpcUaBasicConfigComponent implements ControlValueAccessor, Validator, OnDestroy {
|
||||
@Input() generalTabContent: TemplateRef<any>;
|
||||
export class OpcUaBasicConfigComponent extends GatewayConnectorBasicConfigDirective<OPCBasicConfig_v3_5_2, OPCBasicConfig_v3_5_2> {
|
||||
|
||||
mappingTypes = MappingType;
|
||||
basicFormGroup: FormGroup;
|
||||
|
||||
onChange!: (value: string) => void;
|
||||
onTouched!: () => void;
|
||||
|
||||
protected readonly connectorType = ConnectorType;
|
||||
private destroy$ = new Subject<void>();
|
||||
|
||||
constructor(private fb: FormBuilder) {
|
||||
this.basicFormGroup = this.fb.group({
|
||||
protected override initBasicFormGroup(): FormGroup {
|
||||
return this.fb.group({
|
||||
mapping: [],
|
||||
server: [],
|
||||
});
|
||||
|
||||
this.basicFormGroup.valueChanges
|
||||
.pipe(takeUntil(this.destroy$))
|
||||
.subscribe(value => {
|
||||
this.onChange(value);
|
||||
this.onTouched();
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this.destroy$.next();
|
||||
this.destroy$.complete();
|
||||
}
|
||||
|
||||
registerOnChange(fn: (value: string) => void): void {
|
||||
this.onChange = fn;
|
||||
}
|
||||
|
||||
registerOnTouched(fn: () => void): void {
|
||||
this.onTouched = fn;
|
||||
}
|
||||
|
||||
writeValue(basicConfig: OPCBasicConfig): void {
|
||||
const editedBase = {
|
||||
server: basicConfig.server || {},
|
||||
mapping: basicConfig.mapping || [],
|
||||
protected override mapConfigToFormValue(config: OPCBasicConfig_v3_5_2): OPCBasicConfig_v3_5_2 {
|
||||
return {
|
||||
server: config.server ?? {} as ServerConfig,
|
||||
mapping: config.mapping ?? [],
|
||||
};
|
||||
|
||||
this.basicFormGroup.setValue(editedBase, {emitEvent: false});
|
||||
}
|
||||
|
||||
validate(): ValidationErrors | null {
|
||||
return this.basicFormGroup.valid ? null : {
|
||||
basicFormGroup: {valid: false}
|
||||
protected override getMappedValue(value: OPCBasicConfig_v3_5_2): OPCBasicConfig_v3_5_2 {
|
||||
return {
|
||||
server: value.server,
|
||||
mapping: value.mapping,
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,87 @@
|
||||
///
|
||||
/// Copyright © 2016-2024 The Thingsboard Authors
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
/// You may obtain a copy of the License at
|
||||
///
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
///
|
||||
/// Unless required by applicable law or agreed to in writing, software
|
||||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
|
||||
import { ChangeDetectionStrategy, Component, forwardRef } from '@angular/core';
|
||||
import { FormGroup, NG_VALIDATORS, NG_VALUE_ACCESSOR } from '@angular/forms';
|
||||
import {
|
||||
MappingType,
|
||||
OPCBasicConfig_v3_5_2,
|
||||
OPCLegacyBasicConfig, ServerConfig,
|
||||
} from '@home/components/widget/lib/gateway/gateway-widget.models';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { SharedModule } from '@shared/shared.module';
|
||||
import { MappingTableComponent } from '@home/components/widget/lib/gateway/connectors-configuration/mapping-table/mapping-table.component';
|
||||
import {
|
||||
SecurityConfigComponent
|
||||
} from '@home/components/widget/lib/gateway/connectors-configuration/security-config/security-config.component';
|
||||
import {
|
||||
OpcServerConfigComponent
|
||||
} from '@home/components/widget/lib/gateway/connectors-configuration/opc/opc-server-config/opc-server-config.component';
|
||||
import {
|
||||
GatewayConnectorBasicConfigDirective
|
||||
} from '@home/components/widget/lib/gateway/abstract/gateway-connector-basic-config.abstract';
|
||||
import { OpcVersionMappingUtil } from '@home/components/widget/lib/gateway/utils/opc-version-mapping.util';
|
||||
|
||||
@Component({
|
||||
selector: 'tb-opc-ua-legacy-basic-config',
|
||||
templateUrl: './opc-ua-basic-config.component.html',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
providers: [
|
||||
{
|
||||
provide: NG_VALUE_ACCESSOR,
|
||||
useExisting: forwardRef(() => OpcUaLegacyBasicConfigComponent),
|
||||
multi: true
|
||||
},
|
||||
{
|
||||
provide: NG_VALIDATORS,
|
||||
useExisting: forwardRef(() => OpcUaLegacyBasicConfigComponent),
|
||||
multi: true
|
||||
}
|
||||
],
|
||||
standalone: true,
|
||||
imports: [
|
||||
CommonModule,
|
||||
SharedModule,
|
||||
SecurityConfigComponent,
|
||||
MappingTableComponent,
|
||||
OpcServerConfigComponent,
|
||||
],
|
||||
styleUrls: ['./opc-ua-basic-config.component.scss']
|
||||
})
|
||||
export class OpcUaLegacyBasicConfigComponent extends GatewayConnectorBasicConfigDirective<OPCBasicConfig_v3_5_2, OPCLegacyBasicConfig> {
|
||||
|
||||
mappingTypes = MappingType;
|
||||
|
||||
protected override initBasicFormGroup(): FormGroup {
|
||||
return this.fb.group({
|
||||
mapping: [],
|
||||
server: [],
|
||||
});
|
||||
}
|
||||
|
||||
protected override mapConfigToFormValue(config: OPCLegacyBasicConfig): OPCBasicConfig_v3_5_2 {
|
||||
return {
|
||||
server: config.server ? OpcVersionMappingUtil.mapServerToUpgradedVersion(config.server) : {} as ServerConfig,
|
||||
mapping: config.server?.mapping ? OpcVersionMappingUtil.mapMappingToUpgradedVersion(config.server.mapping) : [],
|
||||
};
|
||||
}
|
||||
|
||||
protected override getMappedValue(value: OPCBasicConfig_v3_5_2): OPCLegacyBasicConfig {
|
||||
return {
|
||||
server: OpcVersionMappingUtil.mapServerToDowngradedVersion(value),
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -186,14 +186,26 @@
|
||||
<tb-mqtt-legacy-basic-config formControlName="basicConfig" [generalTabContent]="generalTabContent"/>
|
||||
</ng-template>
|
||||
</ng-container>
|
||||
<tb-opc-ua-basic-config *ngSwitchCase="ConnectorType.OPCUA"
|
||||
formControlName="basicConfig"
|
||||
[generalTabContent]="generalTabContent">
|
||||
</tb-opc-ua-basic-config>
|
||||
<tb-modbus-basic-config *ngSwitchCase="ConnectorType.MODBUS"
|
||||
formControlName="basicConfig"
|
||||
[generalTabContent]="generalTabContent">
|
||||
</tb-modbus-basic-config>
|
||||
<ng-container *ngSwitchCase="ConnectorType.OPCUA">
|
||||
<tb-opc-ua-basic-config
|
||||
*ngIf="connectorForm.get('configVersion').value === GatewayVersion.Current else legacy"
|
||||
formControlName="basicConfig"
|
||||
[generalTabContent]="generalTabContent"
|
||||
/>
|
||||
<ng-template #legacy>
|
||||
<tb-opc-ua-legacy-basic-config formControlName="basicConfig" [generalTabContent]="generalTabContent"/>
|
||||
</ng-template>
|
||||
</ng-container>
|
||||
<ng-container *ngSwitchCase="ConnectorType.MODBUS">
|
||||
<tb-modbus-basic-config
|
||||
*ngIf="connectorForm.get('configVersion').value === GatewayVersion.Current else legacy"
|
||||
formControlName="basicConfig"
|
||||
[generalTabContent]="generalTabContent"
|
||||
/>
|
||||
<ng-template #legacy>
|
||||
<tb-modbus-legacy-basic-config formControlName="basicConfig" [generalTabContent]="generalTabContent"/>
|
||||
</ng-template>
|
||||
</ng-container>
|
||||
</ng-container>
|
||||
</ng-container>
|
||||
<ng-template #defaultConfig>
|
||||
|
||||
@ -199,9 +199,9 @@ export type ConnectorMappingFormValue = DeviceConnectorMapping | RequestMappingF
|
||||
|
||||
export type ConnectorBaseConfig = ConnectorBaseConfig_v_3_5_2 | ConnectorLegacyConfig;
|
||||
|
||||
export type ConnectorLegacyConfig = ConnectorBaseInfo | MQTTLegacyBasicConfig | OPCBasicConfig | ModbusBasicConfig;
|
||||
export type ConnectorLegacyConfig = ConnectorBaseInfo | MQTTLegacyBasicConfig | OPCLegacyBasicConfig | ModbusBasicConfig;
|
||||
|
||||
export type ConnectorBaseConfig_v_3_5_2 = ConnectorBaseInfo | MQTTBasicConfig_v3_5_2;
|
||||
export type ConnectorBaseConfig_v_3_5_2 = ConnectorBaseInfo | MQTTBasicConfig_v3_5_2 | OPCBasicConfig_v3_5_2;
|
||||
|
||||
export interface ConnectorBaseInfo {
|
||||
name: string;
|
||||
@ -230,16 +230,34 @@ export interface MQTTLegacyBasicConfig {
|
||||
serverSideRpc: LegacyRequestMappingData[];
|
||||
}
|
||||
|
||||
export interface OPCBasicConfig {
|
||||
export type OPCBasicConfig = OPCBasicConfig_v3_5_2 | OPCLegacyBasicConfig;
|
||||
|
||||
export interface OPCBasicConfig_v3_5_2 {
|
||||
mapping: DeviceConnectorMapping[];
|
||||
server: ServerConfig;
|
||||
}
|
||||
|
||||
export interface ModbusBasicConfig {
|
||||
export interface OPCLegacyBasicConfig {
|
||||
server: LegacyServerConfig;
|
||||
}
|
||||
|
||||
export interface LegacyServerConfig extends Omit<ServerConfig, 'enableSubscriptions'> {
|
||||
mapping: LegacyDeviceConnectorMapping[];
|
||||
disableSubscriptions: boolean;
|
||||
}
|
||||
|
||||
export type ModbusBasicConfig = ModbusBasicConfig_v3_5_2 | ModbusLegacyBasicConfig;
|
||||
|
||||
export interface ModbusBasicConfig_v3_5_2 {
|
||||
master: ModbusMasterConfig;
|
||||
slave: ModbusSlave;
|
||||
}
|
||||
|
||||
export interface ModbusLegacyBasicConfig {
|
||||
master: ModbusMasterConfig;
|
||||
slave: ModbusLegacySlave;
|
||||
}
|
||||
|
||||
export interface WorkersConfig {
|
||||
maxNumberOfWorkers: number;
|
||||
maxMessageNumberPerWorker: number;
|
||||
@ -258,12 +276,22 @@ export interface Attribute {
|
||||
value: string;
|
||||
}
|
||||
|
||||
export interface LegacyAttribute {
|
||||
key: string;
|
||||
path: string;
|
||||
}
|
||||
|
||||
export interface Timeseries {
|
||||
key: string;
|
||||
type: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
export interface LegacyTimeseries {
|
||||
key: string;
|
||||
path: string;
|
||||
}
|
||||
|
||||
interface RpcArgument {
|
||||
type: string;
|
||||
value: number;
|
||||
@ -274,12 +302,22 @@ export interface RpcMethod {
|
||||
arguments: RpcArgument[];
|
||||
}
|
||||
|
||||
export interface LegacyRpcMethod {
|
||||
method: string;
|
||||
arguments: unknown[];
|
||||
}
|
||||
|
||||
export interface AttributesUpdate {
|
||||
key: string;
|
||||
type: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
export interface LegacyDeviceAttributeUpdate {
|
||||
attributeOnThingsBoard: string;
|
||||
attributeOnDevice: string;
|
||||
}
|
||||
|
||||
export interface Converter {
|
||||
type: ConvertorType;
|
||||
deviceInfo?: ConnectorDeviceInfo;
|
||||
@ -333,6 +371,15 @@ export interface DeviceConnectorMapping {
|
||||
attributes_updates?: AttributesUpdate[];
|
||||
}
|
||||
|
||||
export interface LegacyDeviceConnectorMapping {
|
||||
deviceNamePattern: string;
|
||||
deviceTypePattern: string;
|
||||
attributes?: LegacyAttribute[];
|
||||
timeseries?: LegacyTimeseries[];
|
||||
rpc_methods?: LegacyRpcMethod[];
|
||||
attributes_updates?: LegacyDeviceAttributeUpdate[];
|
||||
}
|
||||
|
||||
export enum ConnectorType {
|
||||
MQTT = 'mqtt',
|
||||
MODBUS = 'modbus',
|
||||
@ -1069,7 +1116,7 @@ export interface SlaveConfig {
|
||||
pollPeriod: number;
|
||||
unitId: number;
|
||||
deviceName: string;
|
||||
deviceType: string;
|
||||
deviceType?: string;
|
||||
sendDataOnlyOnChange: boolean;
|
||||
connectAttemptTimeMs: number;
|
||||
connectAttemptCount: number;
|
||||
@ -1121,8 +1168,19 @@ export interface ModbusSlave {
|
||||
security: ModbusSecurity;
|
||||
}
|
||||
|
||||
export interface ModbusLegacySlave extends Omit<ModbusSlave, 'values'> {
|
||||
values: ModbusLegacyRegisterValues;
|
||||
}
|
||||
|
||||
export type ModbusValuesState = ModbusRegisterValues | ModbusValues;
|
||||
|
||||
export interface ModbusLegacyRegisterValues {
|
||||
holding_registers: ModbusValues[];
|
||||
coils_initializer: ModbusValues[];
|
||||
input_registers: ModbusValues[];
|
||||
discrete_inputs: ModbusValues[];
|
||||
}
|
||||
|
||||
export interface ModbusRegisterValues {
|
||||
holding_registers: ModbusValues;
|
||||
coils_initializer: ModbusValues;
|
||||
|
||||
@ -17,9 +17,13 @@
|
||||
import {
|
||||
ConnectorType,
|
||||
GatewayConnector,
|
||||
ModbusBasicConfig,
|
||||
MQTTBasicConfig,
|
||||
OPCBasicConfig,
|
||||
} from '@home/components/widget/lib/gateway/gateway-widget.models';
|
||||
import { MqttVersionProcessor } from '@home/components/widget/lib/gateway/abstract/mqtt-version-processor.abstract';
|
||||
import { OpcVersionProcessor } from '@home/components/widget/lib/gateway/abstract/opc-version-processor.abstract';
|
||||
import { ModbusVersionProcessor } from '@home/components/widget/lib/gateway/abstract/modbus-version-processor.abstract';
|
||||
|
||||
export abstract class GatewayConnectorVersionMappingUtil {
|
||||
|
||||
@ -27,6 +31,10 @@ export abstract class GatewayConnectorVersionMappingUtil {
|
||||
switch(connector.type) {
|
||||
case ConnectorType.MQTT:
|
||||
return new MqttVersionProcessor(gatewayVersion, connector as GatewayConnector<MQTTBasicConfig>).getProcessedByVersion();
|
||||
case ConnectorType.OPCUA:
|
||||
return new OpcVersionProcessor(gatewayVersion, connector as GatewayConnector<OPCBasicConfig>).getProcessedByVersion();
|
||||
case ConnectorType.MODBUS:
|
||||
return new ModbusVersionProcessor(gatewayVersion, connector as GatewayConnector<ModbusBasicConfig>).getProcessedByVersion();
|
||||
default:
|
||||
return connector;
|
||||
}
|
||||
|
||||
@ -0,0 +1,77 @@
|
||||
///
|
||||
/// Copyright © 2016-2024 The Thingsboard Authors
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
/// You may obtain a copy of the License at
|
||||
///
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
///
|
||||
/// Unless required by applicable law or agreed to in writing, software
|
||||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
|
||||
import {
|
||||
ModbusDataType,
|
||||
ModbusLegacyRegisterValues,
|
||||
ModbusLegacySlave,
|
||||
ModbusMasterConfig,
|
||||
ModbusRegisterValues,
|
||||
ModbusSlave, ModbusValue, ModbusValues,
|
||||
SlaveConfig
|
||||
} from '@home/components/widget/lib/gateway/gateway-widget.models';
|
||||
|
||||
export class ModbusVersionMappingUtil {
|
||||
static mapMasterToUpgradedVersion(master: ModbusMasterConfig): ModbusMasterConfig {
|
||||
return {
|
||||
slaves: master.slaves.map((slave: SlaveConfig) => ({
|
||||
...slave,
|
||||
deviceType: slave.deviceType ?? 'default',
|
||||
}))
|
||||
};
|
||||
}
|
||||
|
||||
static mapSlaveToDowngradedVersion(slave: ModbusSlave): ModbusLegacySlave {
|
||||
const values = Object.keys(slave.values).reduce((acc, valueKey) => {
|
||||
acc = {
|
||||
...acc,
|
||||
[valueKey]: [
|
||||
slave.values[valueKey]
|
||||
]
|
||||
};
|
||||
return acc;
|
||||
}, {} as ModbusLegacyRegisterValues);
|
||||
return {
|
||||
...slave,
|
||||
values
|
||||
};
|
||||
}
|
||||
|
||||
static mapSlaveToUpgradedVersion(slave: ModbusLegacySlave): ModbusSlave {
|
||||
const values = Object.keys(slave.values).reduce((acc, valueKey) => {
|
||||
acc = {
|
||||
...acc,
|
||||
[valueKey]: this.mapValuesToUpgradedVersion(slave.values[valueKey][0])
|
||||
};
|
||||
return acc;
|
||||
}, {} as ModbusRegisterValues);
|
||||
return {
|
||||
...slave,
|
||||
values
|
||||
};
|
||||
}
|
||||
|
||||
private static mapValuesToUpgradedVersion(registerValues: ModbusValues): ModbusValues {
|
||||
return Object.keys(registerValues).reduce((acc, valueKey) => {
|
||||
acc = {
|
||||
...acc,
|
||||
[valueKey]: registerValues[valueKey].map((value: ModbusValue) =>
|
||||
({ ...value, type: (value.type as string) === 'int' ? ModbusDataType.INT16 : value.type }))
|
||||
};
|
||||
return acc;
|
||||
}, {} as ModbusValues);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,113 @@
|
||||
///
|
||||
/// Copyright © 2016-2024 The Thingsboard Authors
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
/// You may obtain a copy of the License at
|
||||
///
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
///
|
||||
/// Unless required by applicable law or agreed to in writing, software
|
||||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
|
||||
import {
|
||||
DeviceConnectorMapping,
|
||||
LegacyDeviceConnectorMapping,
|
||||
LegacyServerConfig,
|
||||
OPCBasicConfig_v3_5_2,
|
||||
ServerConfig
|
||||
} from '@home/components/widget/lib/gateway/gateway-widget.models';
|
||||
|
||||
export class OpcVersionMappingUtil {
|
||||
static mapServerToUpgradedVersion(server: LegacyServerConfig): ServerConfig {
|
||||
const { mapping, disableSubscriptions, ...restServer } = server;
|
||||
return {
|
||||
...restServer,
|
||||
enableSubscriptions: !disableSubscriptions,
|
||||
};
|
||||
}
|
||||
|
||||
static mapServerToDowngradedVersion(config: OPCBasicConfig_v3_5_2): LegacyServerConfig {
|
||||
const { mapping, server } = config;
|
||||
const { enableSubscriptions, ...restServer } = server;
|
||||
return {
|
||||
...restServer,
|
||||
mapping: mapping ? this.mapMappingToDowngradedVersion(mapping) : [],
|
||||
disableSubscriptions: !enableSubscriptions,
|
||||
};
|
||||
}
|
||||
|
||||
static mapMappingToUpgradedVersion(mapping: LegacyDeviceConnectorMapping[]): DeviceConnectorMapping[] {
|
||||
return mapping?.map((oldMapping: any) => ({
|
||||
...oldMapping,
|
||||
deviceNodeSource: 'path',
|
||||
deviceInfo: {
|
||||
deviceNameExpression: oldMapping.deviceNamePattern,
|
||||
deviceNameExpressionSource: 'path',
|
||||
deviceProfileExpression: oldMapping.deviceTypePattern ?? 'default',
|
||||
deviceProfileExpressionSource: 'path',
|
||||
},
|
||||
attributes: oldMapping.attributes.map(attribute => ({
|
||||
key: attribute.key,
|
||||
type: 'path',
|
||||
value: attribute.path,
|
||||
})),
|
||||
attributes_updates: oldMapping.attributes_updates.map(attributeUpdate => ({
|
||||
key: attributeUpdate.attributeOnThingsBoard,
|
||||
type: 'path',
|
||||
value: attributeUpdate.attributeOnDevice,
|
||||
})),
|
||||
timeseries: oldMapping.timeseries.map(timeseries => ({
|
||||
key: timeseries.key,
|
||||
type: 'path',
|
||||
value: timeseries.path,
|
||||
})),
|
||||
rpc_methods: oldMapping.rpc_methods.map(rpcMethod => ({
|
||||
method: rpcMethod.method,
|
||||
arguments: rpcMethod.arguments.map(arg => ({
|
||||
value: arg,
|
||||
type: this.getArgumentType(arg),
|
||||
}))
|
||||
}))
|
||||
}));
|
||||
}
|
||||
|
||||
static mapMappingToDowngradedVersion(mapping: DeviceConnectorMapping[]): LegacyDeviceConnectorMapping[] {
|
||||
return mapping?.map((newMapping: DeviceConnectorMapping) => ({
|
||||
...newMapping,
|
||||
deviceNamePattern: newMapping.deviceInfo.deviceNameExpression,
|
||||
deviceTypePattern: newMapping.deviceInfo.deviceProfileExpression,
|
||||
attributes: newMapping.attributes.map((attribute: any) => ({
|
||||
key: attribute.key,
|
||||
path: attribute.value,
|
||||
})),
|
||||
attributes_updates: newMapping.attributes_updates.map((attributeUpdate: any) => ({
|
||||
attributeOnThingsBoard: attributeUpdate.key,
|
||||
attributeOnDevice: attributeUpdate.value,
|
||||
})),
|
||||
timeseries: newMapping.timeseries.map((timeseries: any) => ({
|
||||
key: timeseries.key,
|
||||
path: timeseries.value,
|
||||
})),
|
||||
rpc_methods: newMapping.rpc_methods.map((rpcMethod: any) => ({
|
||||
method: rpcMethod.method,
|
||||
arguments: rpcMethod.arguments.map((arg: any) => arg.value)
|
||||
}))
|
||||
}));
|
||||
}
|
||||
|
||||
private static getArgumentType(arg: unknown): string {
|
||||
switch (typeof arg) {
|
||||
case 'boolean':
|
||||
return 'boolean';
|
||||
case 'number':
|
||||
return Number.isInteger(arg) ? 'integer' : 'float';
|
||||
default:
|
||||
return 'string';
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -116,10 +116,10 @@ import {
|
||||
} from '@home/components/widget/lib/gateway/connectors-configuration/mqtt/broker-config-control/broker-config-control.component';
|
||||
import {
|
||||
WorkersConfigControlComponent
|
||||
} from '@home/components/widget/lib/gateway/connectors-configuration/workers-config-control/workers-config-control.component';
|
||||
} from '@home/components/widget/lib/gateway/connectors-configuration/mqtt/workers-config-control/workers-config-control.component';
|
||||
import {
|
||||
OpcServerConfigComponent
|
||||
} from '@home/components/widget/lib/gateway/connectors-configuration/opc-server-config/opc-server-config.component';
|
||||
} from '@home/components/widget/lib/gateway/connectors-configuration/opc/opc-server-config/opc-server-config.component';
|
||||
import {
|
||||
MqttBasicConfigComponent
|
||||
} from '@home/components/widget/lib/gateway/connectors-configuration/mqtt/basic-config/mqtt-basic-config.component';
|
||||
@ -128,7 +128,7 @@ import {
|
||||
} from '@home/components/widget/lib/gateway/connectors-configuration/mapping-table/mapping-table.component';
|
||||
import {
|
||||
OpcUaBasicConfigComponent
|
||||
} from '@home/components/widget/lib/gateway/connectors-configuration/opc-ua-basic-config/opc-ua-basic-config.component';
|
||||
} from '@home/components/widget/lib/gateway/connectors-configuration/opc/opc-ua-basic-config/opc-ua-basic-config.component';
|
||||
import {
|
||||
ModbusBasicConfigComponent
|
||||
} from '@home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-basic-config/modbus-basic-config.component';
|
||||
@ -154,6 +154,12 @@ import {
|
||||
import {
|
||||
GatewayAdvancedConfigurationComponent
|
||||
} from '@home/components/widget/lib/gateway/configuration/advanced/gateway-advanced-configuration.component';
|
||||
import {
|
||||
OpcUaLegacyBasicConfigComponent
|
||||
} from '@home/components/widget/lib/gateway/connectors-configuration/opc/opc-ua-basic-config/opc-ua-legacy-basic-config.component';
|
||||
import {
|
||||
ModbusLegacyBasicConfigComponent
|
||||
} from '@home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-basic-config/modbus-legacy-basic-config.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
@ -245,6 +251,8 @@ import {
|
||||
MqttLegacyBasicConfigComponent,
|
||||
GatewayBasicConfigurationComponent,
|
||||
GatewayAdvancedConfigurationComponent,
|
||||
OpcUaLegacyBasicConfigComponent,
|
||||
ModbusLegacyBasicConfigComponent,
|
||||
],
|
||||
exports: [
|
||||
EntitiesTableWidgetComponent,
|
||||
|
||||
@ -1,246 +1,474 @@
|
||||
{
|
||||
"master": {
|
||||
"slaves": [
|
||||
{
|
||||
"name": "Slave 1",
|
||||
"host": "127.0.0.1",
|
||||
"port": 5021,
|
||||
"type": "tcp",
|
||||
"method": "socket",
|
||||
"timeout": 35,
|
||||
"byteOrder": "LITTLE",
|
||||
"wordOrder": "LITTLE",
|
||||
"retries": true,
|
||||
"retryOnEmpty": true,
|
||||
"retryOnInvalid": true,
|
||||
"pollPeriod": 5000,
|
||||
"unitId": 1,
|
||||
"deviceName": "Temp Sensor",
|
||||
"deviceType": "default",
|
||||
"sendDataOnlyOnChange": true,
|
||||
"connectAttemptTimeMs": 5000,
|
||||
"connectAttemptCount": 5,
|
||||
"waitAfterFailedAttemptsMs": 300000,
|
||||
"attributes": [
|
||||
{
|
||||
"tag": "string_read",
|
||||
"type": "string",
|
||||
"functionCode": 4,
|
||||
"objectsCount": 4,
|
||||
"address": 1
|
||||
},
|
||||
{
|
||||
"tag": "bits_read",
|
||||
"type": "bits",
|
||||
"functionCode": 4,
|
||||
"objectsCount": 1,
|
||||
"address": 5
|
||||
},
|
||||
{
|
||||
"tag": "8int_read",
|
||||
"type": "8int",
|
||||
"functionCode": 4,
|
||||
"objectsCount": 1,
|
||||
"address": 6
|
||||
},
|
||||
{
|
||||
"tag": "16int_read",
|
||||
"type": "16int",
|
||||
"functionCode": 4,
|
||||
"objectsCount": 1,
|
||||
"address": 7
|
||||
},
|
||||
{
|
||||
"tag": "32int_read_divider",
|
||||
"type": "32int",
|
||||
"functionCode": 4,
|
||||
"objectsCount": 2,
|
||||
"address": 8,
|
||||
"divider": 10
|
||||
},
|
||||
{
|
||||
"tag": "8int_read_multiplier",
|
||||
"type": "8int",
|
||||
"functionCode": 4,
|
||||
"objectsCount": 1,
|
||||
"address": 10,
|
||||
"multiplier": 10
|
||||
},
|
||||
{
|
||||
"tag": "32int_read",
|
||||
"type": "32int",
|
||||
"functionCode": 4,
|
||||
"objectsCount": 2,
|
||||
"address": 11
|
||||
},
|
||||
{
|
||||
"tag": "64int_read",
|
||||
"type": "64int",
|
||||
"functionCode": 4,
|
||||
"objectsCount": 4,
|
||||
"address": 13
|
||||
}
|
||||
],
|
||||
"timeseries": [
|
||||
{
|
||||
"tag": "8uint_read",
|
||||
"type": "8uint",
|
||||
"functionCode": 4,
|
||||
"objectsCount": 1,
|
||||
"address": 17
|
||||
},
|
||||
{
|
||||
"tag": "16uint_read",
|
||||
"type": "16uint",
|
||||
"functionCode": 4,
|
||||
"objectsCount": 2,
|
||||
"address": 18
|
||||
},
|
||||
{
|
||||
"tag": "32uint_read",
|
||||
"type": "32uint",
|
||||
"functionCode": 4,
|
||||
"objectsCount": 4,
|
||||
"address": 20
|
||||
},
|
||||
{
|
||||
"tag": "64uint_read",
|
||||
"type": "64uint",
|
||||
"functionCode": 4,
|
||||
"objectsCount": 1,
|
||||
"address": 24
|
||||
},
|
||||
{
|
||||
"tag": "16float_read",
|
||||
"type": "16float",
|
||||
"functionCode": 4,
|
||||
"objectsCount": 1,
|
||||
"address": 25
|
||||
},
|
||||
{
|
||||
"tag": "32float_read",
|
||||
"type": "32float",
|
||||
"functionCode": 4,
|
||||
"objectsCount": 2,
|
||||
"address": 26
|
||||
},
|
||||
{
|
||||
"tag": "64float_read",
|
||||
"type": "64float",
|
||||
"functionCode": 4,
|
||||
"objectsCount": 4,
|
||||
"address": 28
|
||||
}
|
||||
],
|
||||
"attributeUpdates": [
|
||||
{
|
||||
"tag": "shared_attribute_write",
|
||||
"type": "32int",
|
||||
"functionCode": 6,
|
||||
"objectsCount": 2,
|
||||
"address": 29
|
||||
}
|
||||
],
|
||||
"rpc": [
|
||||
{
|
||||
"tag": "setValue",
|
||||
"type": "bits",
|
||||
"functionCode": 5,
|
||||
"objectsCount": 1,
|
||||
"address": 31
|
||||
},
|
||||
{
|
||||
"tag": "getValue",
|
||||
"type": "bits",
|
||||
"functionCode": 1,
|
||||
"objectsCount": 1,
|
||||
"address": 31
|
||||
},
|
||||
{
|
||||
"tag": "setCPUFanSpeed",
|
||||
"type": "32int",
|
||||
"functionCode": 16,
|
||||
"objectsCount": 2,
|
||||
"address": 33
|
||||
},
|
||||
{
|
||||
"tag": "getCPULoad",
|
||||
"type": "32int",
|
||||
"functionCode": 4,
|
||||
"objectsCount": 2,
|
||||
"address": 35
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"slave": {
|
||||
"type": "tcp",
|
||||
"host": "127.0.0.1",
|
||||
"port": 5026,
|
||||
"method": "socket",
|
||||
"deviceName": "Modbus Slave Example",
|
||||
"deviceType": "default",
|
||||
"pollPeriod": 5000,
|
||||
"sendDataToThingsBoard": false,
|
||||
"byteOrder": "LITTLE",
|
||||
"wordOrder": "LITTLE",
|
||||
"unitId": 0,
|
||||
"values": {
|
||||
"holding_registers": {
|
||||
"attributes": [
|
||||
"3.5.1": {
|
||||
"master": {
|
||||
"slaves": [
|
||||
{
|
||||
"address": 1,
|
||||
"type": "string",
|
||||
"tag": "sm",
|
||||
"objectsCount": 1,
|
||||
"value": "ON"
|
||||
}
|
||||
],
|
||||
"timeseries": [
|
||||
{
|
||||
"address": 2,
|
||||
"type": "8int",
|
||||
"tag": "smm",
|
||||
"objectsCount": 1,
|
||||
"value": "12334"
|
||||
}
|
||||
],
|
||||
"attributeUpdates": [
|
||||
{
|
||||
"tag": "shared_attribute_write",
|
||||
"type": "32int",
|
||||
"functionCode": 6,
|
||||
"objectsCount": 2,
|
||||
"address": 29,
|
||||
"value": 1243
|
||||
}
|
||||
],
|
||||
"rpc": [
|
||||
{
|
||||
"tag": "setValue",
|
||||
"type": "bits",
|
||||
"functionCode": 5,
|
||||
"objectsCount": 1,
|
||||
"address": 31,
|
||||
"value": 22
|
||||
"name": "Slave 1",
|
||||
"host": "127.0.0.1",
|
||||
"port": 5021,
|
||||
"type": "tcp",
|
||||
"method": "socket",
|
||||
"timeout": 35,
|
||||
"byteOrder": "LITTLE",
|
||||
"wordOrder": "LITTLE",
|
||||
"retries": true,
|
||||
"retryOnEmpty": true,
|
||||
"retryOnInvalid": true,
|
||||
"pollPeriod": 5000,
|
||||
"unitId": 1,
|
||||
"deviceName": "Temp Sensor",
|
||||
"deviceType": "default",
|
||||
"sendDataOnlyOnChange": true,
|
||||
"connectAttemptTimeMs": 5000,
|
||||
"connectAttemptCount": 5,
|
||||
"waitAfterFailedAttemptsMs": 300000,
|
||||
"attributes": [
|
||||
{
|
||||
"tag": "string_read",
|
||||
"type": "string",
|
||||
"functionCode": 4,
|
||||
"objectsCount": 4,
|
||||
"address": 1
|
||||
},
|
||||
{
|
||||
"tag": "bits_read",
|
||||
"type": "bits",
|
||||
"functionCode": 4,
|
||||
"objectsCount": 1,
|
||||
"address": 5
|
||||
},
|
||||
{
|
||||
"tag": "8int_read",
|
||||
"type": "8int",
|
||||
"functionCode": 4,
|
||||
"objectsCount": 1,
|
||||
"address": 6
|
||||
},
|
||||
{
|
||||
"tag": "16int_read",
|
||||
"type": "16int",
|
||||
"functionCode": 4,
|
||||
"objectsCount": 1,
|
||||
"address": 7
|
||||
},
|
||||
{
|
||||
"tag": "32int_read_divider",
|
||||
"type": "32int",
|
||||
"functionCode": 4,
|
||||
"objectsCount": 2,
|
||||
"address": 8,
|
||||
"divider": 10
|
||||
},
|
||||
{
|
||||
"tag": "8int_read_multiplier",
|
||||
"type": "8int",
|
||||
"functionCode": 4,
|
||||
"objectsCount": 1,
|
||||
"address": 10,
|
||||
"multiplier": 10
|
||||
},
|
||||
{
|
||||
"tag": "32int_read",
|
||||
"type": "32int",
|
||||
"functionCode": 4,
|
||||
"objectsCount": 2,
|
||||
"address": 11
|
||||
},
|
||||
{
|
||||
"tag": "64int_read",
|
||||
"type": "64int",
|
||||
"functionCode": 4,
|
||||
"objectsCount": 4,
|
||||
"address": 13
|
||||
}
|
||||
],
|
||||
"timeseries": [
|
||||
{
|
||||
"tag": "8uint_read",
|
||||
"type": "8uint",
|
||||
"functionCode": 4,
|
||||
"objectsCount": 1,
|
||||
"address": 17
|
||||
},
|
||||
{
|
||||
"tag": "16uint_read",
|
||||
"type": "16uint",
|
||||
"functionCode": 4,
|
||||
"objectsCount": 2,
|
||||
"address": 18
|
||||
},
|
||||
{
|
||||
"tag": "32uint_read",
|
||||
"type": "32uint",
|
||||
"functionCode": 4,
|
||||
"objectsCount": 4,
|
||||
"address": 20
|
||||
},
|
||||
{
|
||||
"tag": "64uint_read",
|
||||
"type": "64uint",
|
||||
"functionCode": 4,
|
||||
"objectsCount": 1,
|
||||
"address": 24
|
||||
},
|
||||
{
|
||||
"tag": "16float_read",
|
||||
"type": "16float",
|
||||
"functionCode": 4,
|
||||
"objectsCount": 1,
|
||||
"address": 25
|
||||
},
|
||||
{
|
||||
"tag": "32float_read",
|
||||
"type": "32float",
|
||||
"functionCode": 4,
|
||||
"objectsCount": 2,
|
||||
"address": 26
|
||||
},
|
||||
{
|
||||
"tag": "64float_read",
|
||||
"type": "64float",
|
||||
"functionCode": 4,
|
||||
"objectsCount": 4,
|
||||
"address": 28
|
||||
}
|
||||
],
|
||||
"attributeUpdates": [
|
||||
{
|
||||
"tag": "shared_attribute_write",
|
||||
"type": "32int",
|
||||
"functionCode": 6,
|
||||
"objectsCount": 2,
|
||||
"address": 29
|
||||
}
|
||||
],
|
||||
"rpc": [
|
||||
{
|
||||
"tag": "setValue",
|
||||
"type": "bits",
|
||||
"functionCode": 5,
|
||||
"objectsCount": 1,
|
||||
"address": 31
|
||||
},
|
||||
{
|
||||
"tag": "getValue",
|
||||
"type": "bits",
|
||||
"functionCode": 1,
|
||||
"objectsCount": 1,
|
||||
"address": 31
|
||||
},
|
||||
{
|
||||
"tag": "setCPUFanSpeed",
|
||||
"type": "32int",
|
||||
"functionCode": 16,
|
||||
"objectsCount": 2,
|
||||
"address": 33
|
||||
},
|
||||
{
|
||||
"tag": "getCPULoad",
|
||||
"type": "32int",
|
||||
"functionCode": 4,
|
||||
"objectsCount": 2,
|
||||
"address": 35
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"coils_initializer": {
|
||||
"attributes": [
|
||||
{
|
||||
"address": 5,
|
||||
"type": "string",
|
||||
"tag": "sm",
|
||||
"objectsCount": 1,
|
||||
"value": "12"
|
||||
"slave": {
|
||||
"type": "tcp",
|
||||
"host": "127.0.0.1",
|
||||
"port": 5026,
|
||||
"method": "socket",
|
||||
"deviceName": "Modbus Slave Example",
|
||||
"deviceType": "default",
|
||||
"pollPeriod": 5000,
|
||||
"sendDataToThingsBoard": false,
|
||||
"byteOrder": "LITTLE",
|
||||
"wordOrder": "LITTLE",
|
||||
"unitId": 0,
|
||||
"values": {
|
||||
"holding_registers": {
|
||||
"attributes": [
|
||||
{
|
||||
"address": 1,
|
||||
"type": "string",
|
||||
"tag": "sm",
|
||||
"objectsCount": 1,
|
||||
"value": "ON"
|
||||
}
|
||||
],
|
||||
"timeseries": [
|
||||
{
|
||||
"address": 2,
|
||||
"type": "8int",
|
||||
"tag": "smm",
|
||||
"objectsCount": 1,
|
||||
"value": "12334"
|
||||
}
|
||||
],
|
||||
"attributeUpdates": [
|
||||
{
|
||||
"tag": "shared_attribute_write",
|
||||
"type": "32int",
|
||||
"functionCode": 6,
|
||||
"objectsCount": 2,
|
||||
"address": 29,
|
||||
"value": 1243
|
||||
}
|
||||
],
|
||||
"rpc": [
|
||||
{
|
||||
"tag": "setValue",
|
||||
"type": "bits",
|
||||
"functionCode": 5,
|
||||
"objectsCount": 1,
|
||||
"address": 31,
|
||||
"value": 22
|
||||
}
|
||||
]
|
||||
},
|
||||
"coils_initializer": {
|
||||
"attributes": [
|
||||
{
|
||||
"address": 5,
|
||||
"type": "string",
|
||||
"tag": "sm",
|
||||
"objectsCount": 1,
|
||||
"value": "12"
|
||||
}
|
||||
],
|
||||
"timeseries": [],
|
||||
"attributeUpdates": [],
|
||||
"rpc": []
|
||||
}
|
||||
],
|
||||
"timeseries": [],
|
||||
"attributeUpdates": [],
|
||||
"rpc": []
|
||||
}
|
||||
}
|
||||
},
|
||||
"legacy": {
|
||||
"master": {
|
||||
"slaves": [
|
||||
{
|
||||
"host": "127.0.0.1",
|
||||
"port": 5021,
|
||||
"type": "tcp",
|
||||
"method": "socket",
|
||||
"timeout": 35,
|
||||
"byteOrder": "LITTLE",
|
||||
"wordOrder": "LITTLE",
|
||||
"retries": true,
|
||||
"retryOnEmpty": true,
|
||||
"retryOnInvalid": true,
|
||||
"pollPeriod": 5000,
|
||||
"unitId": 1,
|
||||
"deviceName": "Temp Sensor",
|
||||
"sendDataOnlyOnChange": true,
|
||||
"connectAttemptTimeMs": 5000,
|
||||
"connectAttemptCount": 5,
|
||||
"waitAfterFailedAttemptsMs": 300000,
|
||||
"attributes": [
|
||||
{
|
||||
"tag": "string_read",
|
||||
"type": "string",
|
||||
"functionCode": 4,
|
||||
"objectsCount": 4,
|
||||
"address": 1
|
||||
},
|
||||
{
|
||||
"tag": "bits_read",
|
||||
"type": "bits",
|
||||
"functionCode": 4,
|
||||
"objectsCount": 1,
|
||||
"address": 5
|
||||
},
|
||||
{
|
||||
"tag": "16int_read",
|
||||
"type": "16int",
|
||||
"functionCode": 4,
|
||||
"objectsCount": 1,
|
||||
"address": 7
|
||||
},
|
||||
{
|
||||
"tag": "32int_read_divider",
|
||||
"type": "32int",
|
||||
"functionCode": 4,
|
||||
"objectsCount": 2,
|
||||
"address": 8,
|
||||
"divider": 10
|
||||
},
|
||||
{
|
||||
"tag": "32int_read",
|
||||
"type": "32int",
|
||||
"functionCode": 4,
|
||||
"objectsCount": 2,
|
||||
"address": 11
|
||||
},
|
||||
{
|
||||
"tag": "64int_read",
|
||||
"type": "64int",
|
||||
"functionCode": 4,
|
||||
"objectsCount": 4,
|
||||
"address": 13
|
||||
}
|
||||
],
|
||||
"timeseries": [
|
||||
{
|
||||
"tag": "16uint_read",
|
||||
"type": "16uint",
|
||||
"functionCode": 4,
|
||||
"objectsCount": 2,
|
||||
"address": 18
|
||||
},
|
||||
{
|
||||
"tag": "32uint_read",
|
||||
"type": "32uint",
|
||||
"functionCode": 4,
|
||||
"objectsCount": 4,
|
||||
"address": 20
|
||||
},
|
||||
{
|
||||
"tag": "64uint_read",
|
||||
"type": "64uint",
|
||||
"functionCode": 4,
|
||||
"objectsCount": 1,
|
||||
"address": 24
|
||||
},
|
||||
{
|
||||
"tag": "16float_read",
|
||||
"type": "16float",
|
||||
"functionCode": 4,
|
||||
"objectsCount": 1,
|
||||
"address": 25
|
||||
},
|
||||
{
|
||||
"tag": "32float_read",
|
||||
"type": "32float",
|
||||
"functionCode": 4,
|
||||
"objectsCount": 2,
|
||||
"address": 26
|
||||
},
|
||||
{
|
||||
"tag": "64float_read",
|
||||
"type": "64float",
|
||||
"functionCode": 4,
|
||||
"objectsCount": 4,
|
||||
"address": 28
|
||||
}
|
||||
],
|
||||
"attributeUpdates": [
|
||||
{
|
||||
"tag": "shared_attribute_write",
|
||||
"type": "32int",
|
||||
"functionCode": 6,
|
||||
"objectsCount": 2,
|
||||
"address": 29
|
||||
}
|
||||
],
|
||||
"rpc": [
|
||||
{
|
||||
"tag": "setValue",
|
||||
"type": "bits",
|
||||
"functionCode": 5,
|
||||
"objectsCount": 1,
|
||||
"address": 31
|
||||
},
|
||||
{
|
||||
"tag": "getValue",
|
||||
"type": "bits",
|
||||
"functionCode": 1,
|
||||
"objectsCount": 1,
|
||||
"address": 31
|
||||
},
|
||||
{
|
||||
"tag": "setCPUFanSpeed",
|
||||
"type": "32int",
|
||||
"functionCode": 16,
|
||||
"objectsCount": 2,
|
||||
"address": 33
|
||||
},
|
||||
{
|
||||
"tag": "getCPULoad",
|
||||
"type": "32int",
|
||||
"functionCode": 4,
|
||||
"objectsCount": 2,
|
||||
"address": 35
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"slave": {
|
||||
"type": "tcp",
|
||||
"host": "127.0.0.1",
|
||||
"port": 5026,
|
||||
"method": "socket",
|
||||
"deviceName": "Modbus Slave Example",
|
||||
"deviceType": "default",
|
||||
"pollPeriod": 5000,
|
||||
"sendDataToThingsBoard": false,
|
||||
"byteOrder": "LITTLE",
|
||||
"wordOrder": "LITTLE",
|
||||
"unitId": 0,
|
||||
"values": {
|
||||
"holding_registers": [
|
||||
{
|
||||
"attributes": [
|
||||
{
|
||||
"address": 1,
|
||||
"type": "string",
|
||||
"tag": "sm",
|
||||
"objectsCount": 1,
|
||||
"value": "ON"
|
||||
}
|
||||
],
|
||||
"timeseries": [
|
||||
{
|
||||
"address": 2,
|
||||
"type": "int",
|
||||
"tag": "smm",
|
||||
"objectsCount": 1,
|
||||
"value": "12334"
|
||||
}
|
||||
],
|
||||
"attributeUpdates": [
|
||||
{
|
||||
"tag": "shared_attribute_write",
|
||||
"type": "32int",
|
||||
"functionCode": 6,
|
||||
"objectsCount": 2,
|
||||
"address": 29,
|
||||
"value": 1243
|
||||
}
|
||||
],
|
||||
"rpc": [
|
||||
{
|
||||
"tag": "setValue",
|
||||
"type": "bits",
|
||||
"functionCode": 5,
|
||||
"objectsCount": 1,
|
||||
"address": 31,
|
||||
"value": 22
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"coils_initializer": [
|
||||
{
|
||||
"attributes": [
|
||||
{
|
||||
"address": 5,
|
||||
"type": "string",
|
||||
"tag": "sm",
|
||||
"objectsCount": 1,
|
||||
"value": "12"
|
||||
}
|
||||
],
|
||||
"timeseries": [],
|
||||
"attributeUpdates": [],
|
||||
"rpc": []
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,66 +1,120 @@
|
||||
{
|
||||
"server": {
|
||||
"url": "localhost:4840/freeopcua/server/",
|
||||
"timeoutInMillis": 5000,
|
||||
"scanPeriodInMillis": 3600000,
|
||||
"pollPeriodInMillis": 5000,
|
||||
"enableSubscriptions": true,
|
||||
"subCheckPeriodInMillis": 100,
|
||||
"showMap": false,
|
||||
"security": "Basic128Rsa15",
|
||||
"identity": {
|
||||
"type": "anonymous"
|
||||
}
|
||||
},
|
||||
"mapping": [{
|
||||
"deviceNodePattern": "Root\\.Objects\\.Device1",
|
||||
"deviceNodeSource": "path",
|
||||
"deviceInfo": {
|
||||
"deviceNameExpression": "Device ${Root\\.Objects\\.Device1\\.serialNumber}",
|
||||
"deviceNameExpressionSource": "path",
|
||||
"deviceProfileExpression": "Device",
|
||||
"deviceProfileExpressionSource": "constant"
|
||||
"3.5.1": {
|
||||
"server": {
|
||||
"url": "localhost:4840/freeopcua/server/",
|
||||
"timeoutInMillis": 5000,
|
||||
"scanPeriodInMillis": 3600000,
|
||||
"pollPeriodInMillis": 5000,
|
||||
"enableSubscriptions": true,
|
||||
"subCheckPeriodInMillis": 100,
|
||||
"showMap": false,
|
||||
"security": "Basic128Rsa15",
|
||||
"identity": {
|
||||
"type": "anonymous"
|
||||
}
|
||||
},
|
||||
"mapping": [{
|
||||
"deviceNodePattern": "Root\\.Objects\\.Device1",
|
||||
"deviceNodeSource": "path",
|
||||
"deviceInfo": {
|
||||
"deviceNameExpression": "Device ${Root\\.Objects\\.Device1\\.serialNumber}",
|
||||
"deviceNameExpressionSource": "path",
|
||||
"deviceProfileExpression": "Device",
|
||||
"deviceProfileExpressionSource": "constant"
|
||||
},
|
||||
"attributes": [
|
||||
{
|
||||
"key": "temperature °C",
|
||||
"type": "path",
|
||||
"value": "${ns=2;i=5}"
|
||||
}
|
||||
],
|
||||
"timeseries": [
|
||||
{
|
||||
"key": "humidity",
|
||||
"type": "path",
|
||||
"value": "${Root\\.Objects\\.Device1\\.TemperatureAndHumiditySensor\\.Humidity}"
|
||||
},
|
||||
{
|
||||
"key": "batteryLevel",
|
||||
"type": "path",
|
||||
"value": "${Battery\\.batteryLevel}"
|
||||
}
|
||||
],
|
||||
"rpc_methods": [
|
||||
{
|
||||
"method": "multiply",
|
||||
"arguments": [
|
||||
{
|
||||
"type": "integer",
|
||||
"value": 2
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"value": 4
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"attributes_updates": [
|
||||
{
|
||||
"key": "deviceName",
|
||||
"type": "path",
|
||||
"value": "Root\\.Objects\\.Device1\\.serialNumber"
|
||||
}
|
||||
]
|
||||
}]
|
||||
},
|
||||
"attributes": [
|
||||
{
|
||||
"key": "temperature °C",
|
||||
"type": "path",
|
||||
"value": "${ns=2;i=5}"
|
||||
}
|
||||
],
|
||||
"timeseries": [
|
||||
{
|
||||
"key": "humidity",
|
||||
"type": "path",
|
||||
"value": "${Root\\.Objects\\.Device1\\.TemperatureAndHumiditySensor\\.Humidity}"
|
||||
},
|
||||
{
|
||||
"key": "batteryLevel",
|
||||
"type": "path",
|
||||
"value": "${Battery\\.batteryLevel}"
|
||||
}
|
||||
],
|
||||
"rpc_methods": [
|
||||
{
|
||||
"method": "multiply",
|
||||
"arguments": [
|
||||
{
|
||||
"type": "integer",
|
||||
"value": 2
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"value": 4
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"attributes_updates": [
|
||||
{
|
||||
"key": "deviceName",
|
||||
"type": "path",
|
||||
"value": "Root\\.Objects\\.Device1\\.serialNumber"
|
||||
}
|
||||
]
|
||||
}]
|
||||
"legacy": {
|
||||
"server": {
|
||||
"name": "OPC-UA Default Server",
|
||||
"url": "localhost:4840/freeopcua/server/",
|
||||
"timeoutInMillis": 5000,
|
||||
"scanPeriodInMillis": 5000,
|
||||
"disableSubscriptions": false,
|
||||
"subCheckPeriodInMillis": 100,
|
||||
"showMap": false,
|
||||
"security": "Basic128Rsa15",
|
||||
"identity": {
|
||||
"type": "anonymous"
|
||||
},
|
||||
"mapping": [
|
||||
{
|
||||
"deviceNodePattern": "Root\\.Objects\\.Device1",
|
||||
"deviceNamePattern": "Device ${Root\\.Objects\\.Device1\\.serialNumber}",
|
||||
"attributes": [
|
||||
{
|
||||
"key": "temperature °C",
|
||||
"path": "${ns=2;i=5}"
|
||||
}
|
||||
],
|
||||
"timeseries": [
|
||||
{
|
||||
"key": "humidity",
|
||||
"path": "${Root\\.Objects\\.Device1\\.TemperatureAndHumiditySensor\\.Humidity}"
|
||||
},
|
||||
{
|
||||
"key": "batteryLevel",
|
||||
"path": "${Battery\\.batteryLevel}"
|
||||
}
|
||||
],
|
||||
"rpc_methods": [
|
||||
{
|
||||
"method": "multiply",
|
||||
"arguments": [
|
||||
2,
|
||||
4
|
||||
]
|
||||
}
|
||||
],
|
||||
"attributes_updates": [
|
||||
{
|
||||
"attributeOnThingsBoard": "deviceName",
|
||||
"attributeOnDevice": "Root\\.Objects\\.Device1\\.serialNumber"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user