From cdbc099d625611ce03bcea12805f7da7b23a0152 Mon Sep 17 00:00:00 2001 From: Ray Labbe Date: Thu, 5 Mar 2026 21:11:32 -0500 Subject: [PATCH 01/16] doc: cleanup for v1.0 release --- Kepware-ConfigAPI-SDK-dotnet.sln | 3 +-- Kepware.Api/README.md | 15 ++++++++------- README.md | 14 +++++++++----- docs/nuget-README.md | 6 ++++-- 4 files changed, 22 insertions(+), 16 deletions(-) diff --git a/Kepware-ConfigAPI-SDK-dotnet.sln b/Kepware-ConfigAPI-SDK-dotnet.sln index 9113207..f293df4 100644 --- a/Kepware-ConfigAPI-SDK-dotnet.sln +++ b/Kepware-ConfigAPI-SDK-dotnet.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 18 -VisualStudioVersion = 18.3.11505.172 d18.3 +VisualStudioVersion = 18.3.11505.172 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kepware.SyncService", "KepwareSync.Service\Kepware.SyncService.csproj", "{19B2841F-01D1-4A7E-BE26-A93CF8C57628}" EndProject @@ -13,7 +13,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SolutionFiles", "SolutionFi Directory.Build.props = Directory.Build.props LICENSE.txt = LICENSE.txt README.md = README.md - version.json = version.json EndProjectSection EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kepware.Api", "Kepware.Api\Kepware.Api.csproj", "{ABB368B9-7D95-4946-9579-F7AA7A5750F7}" diff --git a/Kepware.Api/README.md b/Kepware.Api/README.md index 40625b1..f3d4122 100644 --- a/Kepware.Api/README.md +++ b/Kepware.Api/README.md @@ -1,13 +1,14 @@ # Kepware.Api -[![Build Status](https://github.com/PTCInc/Kepware-ConfigAPI-SDK-dotnet/actions/workflows/nuget-test-and-build.yml/badge.svg)](https://github.com/PTCInc/Kepware-ConfigAPI-SDK-dotnet/actions) [![NuGet](https://img.shields.io/nuget/v/Kepware.Api.svg)](https://www.nuget.org/packages/Kepware.Api/) +![Dynamic XML Badge](https://img.shields.io/badge/dynamic/xml?url=https%3A%2F%2Fraw.githubusercontent.com%2FPTCInc%2FKepware-ConfigAPI-SDK-dotnet%2Frefs%2Fheads%2Fmain%2FKepware.Api%2FKepware.Api.csproj&query=%2F%2FTargetFrameworks&logo=.net&label=versions) +[![Build Status](https://github.com/PTCInc/Kepware-ConfigAPI-SDK-dotnet/actions/workflows/nuget-test-and-build.yml/badge.svg)](https://github.com/PTCInc/Kepware-ConfigAPI-SDK-dotnet/actions) +![NuGet Downloads](https://img.shields.io/nuget/dt/Kepware.Api?label=nuget%20downloads) ## Overview The `Kepware.Api` library provides a robust client implementation to interact with the Kepware Configuration API. It supports managing channels, devices, tags, and other configurations programmatically while ensuring secure and efficient communication. -This package is designed to work with all versions of Kepware that support the Configuration API including Kepware Server (KS), and Kepware Edge (KE). For reference, Kepware Server in this documentation will also imply Thingworx Kepware Server and KEPServerEX versions prior to v7.0 when v6.x is referenced. - +This package is designed to work with all versions of Kepware that support the Configuration API including Kepware Server (KS), Kepware Edge (KE), Thingworx Kepware Server (TKS), and KEPServerEX (KEP). For reference, when Kepware Server v6.x is referenced in this documentation, this implies Thingworx Kepware Server and KEPServerEX branded products. ## Features 1. Connect to Kepware Configuration APIs securely with HTTPS and optional certificate validation. @@ -20,12 +21,12 @@ This package is designed to work with all versions of Kepware that support the C | **Administration**
*(User Groups, Users, UA Endpoints, Local License Server)* | Y[^1] | Y | | **Product Info and Health Status** | Y[^4] | Y | | **Export Project** | Y[^2] | Y | -| **Import Project (via JsonProjectLoad Service)** | N[^2] | N | +| **Import Project (via JsonProjectLoad Service)[^3]** | N | N | | **Import Project (via CompareAndApply)[^3]** | Y | Y | [^1]: UA Endpoints and Local License Server supported for Kepware Edge only -[^2]: JsonProjectLoad was added to Kepware Server v6.17 and later builds, the SDK detects the server version and uses the appropriate service or loads the project by multiple requests if using KepwareApiClient.LoadProject. -[^3]: CompareAndApply is handled by the SDK, it compares the source project with the server project and applies the changes. The JsonProjectLoad service is a direct call to the server to load a project. +[^2]: Json serialization for the whole project was added to Kepware Server v6.17 and later builds, the SDK detects the server version and uses the appropriate service or exports the project by multiple requests if using KepwareApiClient.LoadProject. +[^3]: CompareAndApply is handled by the SDK, it compares the source project with the server project and applies the changes. The JsonProjectLoad service (added v6.17 and later) is a direct call to the server to load a new project serialize JSON configuration to the server/edge instance. [^4]: Added to Kepware Server v6.13 and later builds 3. Configuration API *Services* implemented: @@ -35,7 +36,7 @@ This package is designed to work with all versions of Kepware that support the C | **TagGeneration**
*(for supported drivers)* | Y | Y | | **ReinitializeRuntime** | Y* | Y | | **ProjectLoad and ProjectSave** | N | N | -| **JsonProjectLoad\*\***
*(used for import project feature)* | Y | Y | +| **JsonProjectLoad\*\***
*(used for import project feature)* | N | N | 4. Synchronize configurations between your application and Kepware server. 5. Supports advanced operations like project comparison, entity synchronization, and driver property queries. diff --git a/README.md b/README.md index 60759c7..9f41637 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,23 @@ -# Kepware Configuration API SDK for .NET (Currently in Beta) +# Kepware Configuration API SDK for .NET +[![NuGet](https://img.shields.io/nuget/v/Kepware.Api.svg)](https://www.nuget.org/packages/Kepware.Api/) +![Dynamic XML Badge](https://img.shields.io/badge/dynamic/xml?url=https%3A%2F%2Fraw.githubusercontent.com%2FPTCInc%2FKepware-ConfigAPI-SDK-dotnet%2Frefs%2Fheads%2Fmain%2FKepware.Api%2FKepware.Api.csproj&query=%2F%2FTargetFrameworks&logo=.net&label=versions) [![Build Status](https://github.com/PTCInc/Kepware-ConfigAPI-SDK-dotnet/actions/workflows/nuget-test-and-build.yml/badge.svg)](https://github.com/PTCInc/Kepware-ConfigAPI-SDK-dotnet/actions) +![NuGet Downloads](https://img.shields.io/nuget/dt/Kepware.Api?label=nuget%20downloads) + [![Build Status](https://github.com/PTCInc/Kepware-ConfigAPI-SDK-dotnet/actions/workflows/docker-build-and-push.yml/badge.svg)](https://github.com/PTCInc/Kepware-ConfigAPI-SDK-dotnet/actions) [![Build Status](https://github.com/PTCInc/Kepware-ConfigAPI-SDK-dotnet/actions/workflows/syncservice-build.yml/badge.svg)](https://github.com/PTCInc/Kepware-ConfigAPI-SDK-dotnet/actions) -[![NuGet](https://img.shields.io/nuget/v/Kepware.Api.svg)](https://www.nuget.org/packages/Kepware.Api/) + ## Overview The Kepware Configuration API SDK for .NET provides tools and libraries to interact with the Kepware Configuration REST API, enabling configuration management for Kepware servers. This repository includes examples and utilities to streamline development for deployment tools, including a service for continuous synchronization and an API client library. -This package is designed to work with all versions of Kepware that support the Configuration API including Kepware Server (KS), Kepware Edge (KE), Thingworx Kepware Server (TKS), and KEPServerEX (KEP). For reference, Kepware Server in this documentation will also imply Thingworx Kepware Server and KEPServerEX versions prior to v7.0 when v6.x is referenced. +This package is designed to work with all versions of Kepware that support the Configuration API including Kepware Server (KS), Kepware Edge (KE), Thingworx Kepware Server (TKS), and KEPServerEX (KEP). For reference, when Kepware Server v6.x is referenced in this documentation, this implies Thingworx Kepware Server and KEPServerEX branded products. ## Features - [**API Client Library**](./Kepware.Api/README.md): Simplify interaction with the Kepware Configuration API. -- [**Service for Synchronization**](./KepwareSync.Service/README.md): +- [**Service for Synchronization** (Currently in Beta)](./KepwareSync.Service/README.md): - Bi-directional synchronization between Kepware servers and local filesystems. - Support for one-way and two-way synchronization modes. - [**Sample Applications**](./Kepware.Api.Sample/README.md): Demonstrates API usage with real-world examples. @@ -29,7 +33,7 @@ A .NET library providing an easy-to-use client for interacting with the Kepware **API reference documentation is available on [Github Pages](https://ptcinc.github.io/Kepware-ConfigAPI-SDK-dotnet/api/Kepware.Api.html)** -### 2. `KepwareSync.Service` +### 2. `KepwareSync.Service` (Currently in Beta) A service application for synchronizing configurations between Kepware servers and the local filesystem. It supports monitoring and synchronization in real time. [Readme for KepwareSync.Service](./KepwareSync.Service/README.md) diff --git a/docs/nuget-README.md b/docs/nuget-README.md index b3e9a6c..f5e0f06 100644 --- a/docs/nuget-README.md +++ b/docs/nuget-README.md @@ -1,11 +1,13 @@ # Kepware.Api +[![NuGet](https://img.shields.io/nuget/v/Kepware.Api.svg)](https://www.nuget.org/packages/Kepware.Api/) +![Dynamic XML Badge](https://img.shields.io/badge/dynamic/xml?url=https%3A%2F%2Fraw.githubusercontent.com%2FPTCInc%2FKepware-ConfigAPI-SDK-dotnet%2Frefs%2Fheads%2Fmain%2FKepware.Api%2FKepware.Api.csproj&query=%2F%2FTargetFrameworks&logo=.net&label=versions) [![Build Status](https://github.com/PTCInc/Kepware-ConfigAPI-SDK-dotnet/actions/workflows/nuget-test-and-build.yml/badge.svg)](https://github.com/PTCInc/Kepware-ConfigAPI-SDK-dotnet/actions) ## Overview -The `Kepware.Api` library provides a robust client implementation to interact with the Kepware Configuration API. It supports managing channels, devices, tags, and other configurations programmatically while ensuring secure and efficient communication. +The `Kepware.Api` library provides a robust client implementation to interact with the Kepware Configuration REST API. It supports managing channels, devices, tags, and other configurations programmatically while ensuring secure and efficient communication. -This package is designed to work with all versions of Kepware that support the Configuration API including Thingworx Kepware Server (TKS), Thingworx Kepware Edge (TKE) and KEPServerEX (KEP). For reference, Kepware Server in this documentation will refer to both TKS and KEP versions. +This package is designed to work with all versions of Kepware that support the Configuration API including Kepware Server (KS), Kepware Edge (KE), Thingworx Kepware Server (TKS), and KEPServerEX (KEP). For reference, Kepware Server in this documentation will also imply Thingworx Kepware Server and KEPServerEX versions prior to v7.0 when v6.x is referenced. ## Licensing This SDK is provided "as is" under the MIT License. See the [LICENSE](https://github.com/PTCInc/Kepware-ConfigAPI-SDK-dotnet/blob/main/LICENSE.txt) file for details. From 5e521158d4bd33e6b0d4c738d8de87b4b49642a6 Mon Sep 17 00:00:00 2001 From: Ray Labbe Date: Thu, 5 Mar 2026 21:12:16 -0500 Subject: [PATCH 02/16] chore(test): added WSL test environment for VS --- testEnvironments.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 testEnvironments.json diff --git a/testEnvironments.json b/testEnvironments.json new file mode 100644 index 0000000..a3e2af5 --- /dev/null +++ b/testEnvironments.json @@ -0,0 +1,12 @@ +{ + "version": "1", + "environments": [ + // See https://aka.ms/remotetesting for more details + // about how to configure remote environments. + { + "name": "WSL Ubuntu", + "type": "wsl", + "wslDistribution": "Ubuntu-24.04" + } + ] +} \ No newline at end of file From 3b9fc652fd171a355a3407213a1a54658207c92e Mon Sep 17 00:00:00 2001 From: Ray Labbe Date: Thu, 5 Mar 2026 21:13:44 -0500 Subject: [PATCH 03/16] chore(test): Added WSL debug option for Sync Service --- KepwareSync.Service/Properties/launchSettings.json | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/KepwareSync.Service/Properties/launchSettings.json b/KepwareSync.Service/Properties/launchSettings.json index 4b7bf41..40fb1af 100644 --- a/KepwareSync.Service/Properties/launchSettings.json +++ b/KepwareSync.Service/Properties/launchSettings.json @@ -26,6 +26,17 @@ }, "Container (Dockerfile)": { "commandName": "Docker" + }, + // For WSL2, ensure that the distribution name is set to your WSL distribution (e.g., "Ubuntu-20.04") if you + // want to specify the specific distribution to run the project in. If left empty, it will use the default WSL distribution. + // You can find the distribution names and defaults by running `wsl -l -v` in a command prompt. + "WSL": { + "commandName": "WSL2", + "environmentVariables": { + "DOTNET_ENVIRONMENT": "Development", + "MODBUS_HOST": "HostByEnv" + }, + "distributionName": "" } }, "$schema": "https://json.schemastore.org/launchsettings.json" From 92fd80e465bb3aa9f6f516c5bf6cda3ea08cbff4 Mon Sep 17 00:00:00 2001 From: Ray Labbe Date: Thu, 5 Mar 2026 21:14:14 -0500 Subject: [PATCH 04/16] feat(api): v1.0 release --- Kepware.Api/version.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Kepware.Api/version.json b/Kepware.Api/version.json index 14b3ad2..2bd0bfe 100644 --- a/Kepware.Api/version.json +++ b/Kepware.Api/version.json @@ -1,6 +1,6 @@ { "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/main/src/NerdBank.GitVersioning/version.schema.json", - "version": "1.0-beta", + "version": "1.0", "pathFilters": [ "." ], "publicReleaseRefSpec": [ "^refs/heads/main$", From a1ace8eed6fdb82f0994e34f9dceea281ec83093 Mon Sep 17 00:00:00 2001 From: Ray Labbe Date: Fri, 13 Mar 2026 17:55:47 -0400 Subject: [PATCH 05/16] chore(test): Update file name --- .../ApiClient/{GetProductInfo.cs => GetProductInfoTests.cs} | 0 .../ApiClient/{TestConnection.cs => TestConnectionTests.cs} | 0 .../ApiClient/{GetProductInfo.cs => GetProductInfoTests.cs} | 0 .../ApiClient/{LoadEntity.cs => LoadEntityTests.cs} | 0 .../ApiClient/{TestConnection.cs => TestConnectionTests.cs} | 0 5 files changed, 0 insertions(+), 0 deletions(-) rename Kepware.Api.Test/ApiClient/{GetProductInfo.cs => GetProductInfoTests.cs} (100%) rename Kepware.Api.Test/ApiClient/{TestConnection.cs => TestConnectionTests.cs} (100%) rename Kepware.Api.TestIntg/ApiClient/{GetProductInfo.cs => GetProductInfoTests.cs} (100%) rename Kepware.Api.TestIntg/ApiClient/{LoadEntity.cs => LoadEntityTests.cs} (100%) rename Kepware.Api.TestIntg/ApiClient/{TestConnection.cs => TestConnectionTests.cs} (100%) diff --git a/Kepware.Api.Test/ApiClient/GetProductInfo.cs b/Kepware.Api.Test/ApiClient/GetProductInfoTests.cs similarity index 100% rename from Kepware.Api.Test/ApiClient/GetProductInfo.cs rename to Kepware.Api.Test/ApiClient/GetProductInfoTests.cs diff --git a/Kepware.Api.Test/ApiClient/TestConnection.cs b/Kepware.Api.Test/ApiClient/TestConnectionTests.cs similarity index 100% rename from Kepware.Api.Test/ApiClient/TestConnection.cs rename to Kepware.Api.Test/ApiClient/TestConnectionTests.cs diff --git a/Kepware.Api.TestIntg/ApiClient/GetProductInfo.cs b/Kepware.Api.TestIntg/ApiClient/GetProductInfoTests.cs similarity index 100% rename from Kepware.Api.TestIntg/ApiClient/GetProductInfo.cs rename to Kepware.Api.TestIntg/ApiClient/GetProductInfoTests.cs diff --git a/Kepware.Api.TestIntg/ApiClient/LoadEntity.cs b/Kepware.Api.TestIntg/ApiClient/LoadEntityTests.cs similarity index 100% rename from Kepware.Api.TestIntg/ApiClient/LoadEntity.cs rename to Kepware.Api.TestIntg/ApiClient/LoadEntityTests.cs diff --git a/Kepware.Api.TestIntg/ApiClient/TestConnection.cs b/Kepware.Api.TestIntg/ApiClient/TestConnectionTests.cs similarity index 100% rename from Kepware.Api.TestIntg/ApiClient/TestConnection.cs rename to Kepware.Api.TestIntg/ApiClient/TestConnectionTests.cs From 2d7b193cbbb26f25336edcfab7515177b04d727c Mon Sep 17 00:00:00 2001 From: Ray Labbe Date: Sat, 14 Mar 2026 17:47:47 -0400 Subject: [PATCH 06/16] feat(api): Query Parameter support for Load Methods and Serialize handling --- .../ApiClient/GenericHandleTests.cs | 116 ++++++++++++++ .../ApiClient/LoadEntityTests.cs | 43 +++++- Kepware.Api/ClientHandler/AdminApiHandler.cs | 24 +-- .../ClientHandler/GenericApiHandler.cs | 145 +++++++++++++++--- 4 files changed, 295 insertions(+), 33 deletions(-) create mode 100644 Kepware.Api.Test/ApiClient/GenericHandleTests.cs diff --git a/Kepware.Api.Test/ApiClient/GenericHandleTests.cs b/Kepware.Api.Test/ApiClient/GenericHandleTests.cs new file mode 100644 index 0000000..ac0c0be --- /dev/null +++ b/Kepware.Api.Test/ApiClient/GenericHandleTests.cs @@ -0,0 +1,116 @@ +using System; +using System.Collections.Generic; +using System.Net.Http; +using System.Reflection; +using System.Threading.Tasks; +using Kepware.Api.Model; +using Kepware.Api.Test.ApiClient; +using Microsoft.Extensions.Logging; +using Moq; +using Moq.Contrib.HttpClient; +using Xunit; + +namespace Kepware.Api.Test.ApiClient +{ + public class GenericHandler : TestApiClientBase + { + [Fact] + public void AppendQueryString_PrivateMethod_EncodesAndSkipsNullsAndAppendsCorrectly() + { + // Arrange + var method = typeof(Kepware.Api.ClientHandler.GenericApiHandler) + .GetMethod("AppendQueryString", BindingFlags.NonPublic | BindingFlags.Static); + Assert.NotNull(method); + + var query = new[] + { + new KeyValuePair("a", "b"), + new KeyValuePair("space", "x y"), + new KeyValuePair("skip", null) // should be skipped + }; + + // Act + var result1 = (string)method!.Invoke(null, new object[] { "https://api/config", query })!; + var result2 = (string)method!.Invoke(null, new object[] { "https://api/config?existing=1", query })!; + + // Assert + Assert.Equal("https://api/config?a=b&space=x%20y", result1); + Assert.Equal("https://api/config?existing=1&a=b&space=x%20y", result2); + } + + [Fact] + public async Task LoadCollectionAsync_AppendsQueryAndReturnsCollection() + { + // Arrange + var channelsJson = """ + [ + { + "PROJECT_ID": 676550906, + "common.ALLTYPES_NAME": "Channel1", + "common.ALLTYPES_DESCRIPTION": "Example Simulator Channel", + "servermain.MULTIPLE_TYPES_DEVICE_DRIVER": "Simulator" + }, + { + "PROJECT_ID": 676550906, + "common.ALLTYPES_NAME": "Data Type Examples", + "common.ALLTYPES_DESCRIPTION": "Example Simulator Channel", + "servermain.MULTIPLE_TYPES_DEVICE_DRIVER": "Simulator" + } + ] + """; + + var query = new[] + { + new KeyValuePair("status", "active"), + new KeyValuePair("name", "John Doe"), + new KeyValuePair("skip", null) + }; + + // Expect encoded space in "John Doe" and null entry skipped + _httpMessageHandlerMock.SetupRequest(HttpMethod.Get, TEST_ENDPOINT + "/config/v1/project/channels?status=active&name=John%20Doe") + .ReturnsResponse(channelsJson, "application/json"); + + // Act + var result = await _kepwareApiClient.GenericConfig.LoadCollectionAsync((string?)null, query); + + // Assert + Assert.NotNull(result); + Assert.Equal(2, result.Count); + Assert.Contains(result, c => c.Name == "Channel1"); + Assert.Contains(result, c => c.Name == "Data Type Examples"); + } + + [Fact] + public async Task LoadEntityAsync_AppendsQueryAndReturnsEntity() + { + // Arrange + var channelJson = """ + { + "PROJECT_ID": 676550906, + "common.ALLTYPES_NAME": "Channel1", + "common.ALLTYPES_DESCRIPTION": "Example Simulator Channel", + "servermain.MULTIPLE_TYPES_DEVICE_DRIVER": "Simulator" + } + """; + + var query = new[] + { + new KeyValuePair("status", "active"), + new KeyValuePair("name", "John Doe"), + new KeyValuePair("skip", null) + }; + + // Expect encoded space in "John Doe" and null entry skipped + _httpMessageHandlerMock.SetupRequest(HttpMethod.Get, TEST_ENDPOINT + "/config/v1/project/channels/Channel1?status=active&name=John%20Doe") + .ReturnsResponse(channelJson, "application/json"); + + // Act + var result = await _kepwareApiClient.GenericConfig.LoadEntityAsync("Channel1", query); + + // Assert + Assert.NotNull(result); + Assert.Equal("Channel1", result.Name); + Assert.Equal("Example Simulator Channel", result.Description); + } + } +} diff --git a/Kepware.Api.TestIntg/ApiClient/LoadEntityTests.cs b/Kepware.Api.TestIntg/ApiClient/LoadEntityTests.cs index f1ebfc3..c688852 100644 --- a/Kepware.Api.TestIntg/ApiClient/LoadEntityTests.cs +++ b/Kepware.Api.TestIntg/ApiClient/LoadEntityTests.cs @@ -276,7 +276,7 @@ public async Task LoadEntityAsync_ShouldReturnTagCollection_WhenApiRespondsSucce [Fact] public async Task LoadEntityAsync_ShouldReturnTagGroupCollectionInTagGroup_WhenApiRespondsSuccessfully() { - // TODO: Currently this test fails due to issue in EndpointResolver. + // TODO: Clean up test. Fix was made and test is successful. // Arrange try { @@ -335,5 +335,46 @@ public async Task LoadEntityAsync_ShouldReturnTagCollectionFromTagGroup_WhenApiR await DeleteAllChannelsAsync(); } #endregion + + #region LoadEntityAsync - Return Channel Collection with all children - Serialize query + [SkippableFact] + public async Task LoadEntityAsync_ShouldReturnChannelAndChildren_WhenApiRespondsSuccessfully() + { + // Skip the test if the serialize feature is not supported by server version. + Skip.If(!_productInfo.SupportsJsonProjectLoadService, "Test only applicable for versions that support JsonProjectLoad"); + + // Arrange + var channel = await AddTestChannel(); + var device = await AddTestDevice(channel); + var tagGroup = await AddTestTagGroup(device); + var tagGroup2 = await AddTestTagGroup(tagGroup, "TagGroup2"); + + var query = new[] + { + new KeyValuePair("content", "serialize"), + }; + + // Act + var result = await _kepwareApiClient.GenericConfig.LoadEntityAsync(channel.Name, query); + + // Assert + Assert.NotNull(result); + Assert.NotNull(result.Devices); + Assert.Contains(result.Devices, g => g.Name == device.Name); + + var foundDevice = result.Devices.Find(d => d.Name == device.Name); + Assert.NotNull(foundDevice); + Assert.NotNull(foundDevice.TagGroups); + Assert.Contains(foundDevice.TagGroups, tg => tg.Name == tagGroup.Name); + + var foundTagGroup = foundDevice.TagGroups.Find(tg => tg.Name == tagGroup.Name); + Assert.NotNull(foundTagGroup); + Assert.NotNull(foundTagGroup.TagGroups); + Assert.Contains(foundTagGroup.TagGroups, tg => tg.Name == tagGroup2.Name); + + // Cleanup + await DeleteAllChannelsAsync(); + } + #endregion } } diff --git a/Kepware.Api/ClientHandler/AdminApiHandler.cs b/Kepware.Api/ClientHandler/AdminApiHandler.cs index 6173cfc..eea1215 100644 --- a/Kepware.Api/ClientHandler/AdminApiHandler.cs +++ b/Kepware.Api/ClientHandler/AdminApiHandler.cs @@ -42,7 +42,7 @@ public AdminApiHandler(KepwareApiClient kepwareApiClient, ILoggerThe current or null if retrieval fails. public Task GetAdminSettingsAsync(CancellationToken cancellationToken = default) { - return m_kepwareApiClient.GenericConfig.LoadEntityAsync(name: null, cancellationToken); + return m_kepwareApiClient.GenericConfig.LoadEntityAsync(name: null, cancellationToken: cancellationToken); } /// @@ -117,7 +117,7 @@ public async Task SetAdminSettingsAsync(AdminSettings settings, Cancellati /// The configuration, or null if not found. public Task GetUaEndpointAsync(string name, CancellationToken cancellationToken = default) { - return m_kepwareApiClient.GenericConfig.LoadEntityAsync(name, cancellationToken); + return m_kepwareApiClient.GenericConfig.LoadEntityAsync(name, cancellationToken: cancellationToken); } /// @@ -135,7 +135,7 @@ public async Task CreateOrUpdateUaEndpointAsync(UaEndpoint endpoint, Cance try { var endpointUrl = EndpointResolver.ResolveEndpoint([endpoint.Name]); - var currentEndpoint = await m_kepwareApiClient.GenericConfig.LoadEntityByEndpointAsync(endpointUrl, cancellationToken); + var currentEndpoint = await m_kepwareApiClient.GenericConfig.LoadEntityByEndpointAsync(endpointUrl, cancellationToken: cancellationToken); if (currentEndpoint == null) { @@ -162,7 +162,7 @@ public async Task CreateOrUpdateUaEndpointAsync(UaEndpoint endpoint, Cance /// A token that can be used to request cancellation of the operation. /// True if the endpoint was successfully deleted; otherwise, false. public Task DeleteUaEndpointAsync(string name, CancellationToken cancellationToken = default) - => m_kepwareApiClient.GenericConfig.DeleteItemAsync(name, cancellationToken); + => m_kepwareApiClient.GenericConfig.DeleteItemAsync(name, cancellationToken: cancellationToken); #endregion @@ -186,7 +186,7 @@ public Task DeleteUaEndpointAsync(string name, CancellationToken cancellat /// The configuration, or null if not found. public Task GetServerUserGroupAsync(string name, CancellationToken cancellationToken = default) { - return m_kepwareApiClient.GenericConfig.LoadEntityAsync(name, cancellationToken); + return m_kepwareApiClient.GenericConfig.LoadEntityAsync(name, cancellationToken: cancellationToken); } /// @@ -204,7 +204,7 @@ public async Task CreateOrUpdateServerUserGroupAsync(ServerUserGroup userG try { var endpointUrl = EndpointResolver.ResolveEndpoint([userGroup.Name]); - var currentGroup = await m_kepwareApiClient.GenericConfig.LoadEntityByEndpointAsync(endpointUrl, cancellationToken); + var currentGroup = await m_kepwareApiClient.GenericConfig.LoadEntityByEndpointAsync(endpointUrl, cancellationToken: cancellationToken); if (currentGroup == null) { @@ -231,7 +231,7 @@ public async Task CreateOrUpdateServerUserGroupAsync(ServerUserGroup userG /// A token that can be used to request cancellation of the operation. /// True if the group was successfully deleted; otherwise, false. public Task DeleteServerUserGroupAsync(string name, CancellationToken cancellationToken = default) - => m_kepwareApiClient.GenericConfig.DeleteItemAsync(name, cancellationToken); + => m_kepwareApiClient.GenericConfig.DeleteItemAsync(name, cancellationToken: cancellationToken); #endregion @@ -254,7 +254,7 @@ public Task DeleteServerUserGroupAsync(string name, CancellationToken canc /// The configuration, or null if not found. public Task GetServerUserAsync(string name, CancellationToken cancellationToken = default) { - return m_kepwareApiClient.GenericConfig.LoadEntityAsync(name, cancellationToken); + return m_kepwareApiClient.GenericConfig.LoadEntityAsync(name, cancellationToken: cancellationToken); } /// @@ -272,7 +272,7 @@ public async Task CreateOrUpdateServerUserAsync(ServerUser user, Cancellat try { var endpointUrl = EndpointResolver.ResolveEndpoint([user.Name]); - var currentUser = await m_kepwareApiClient.GenericConfig.LoadEntityByEndpointAsync(endpointUrl, cancellationToken); + var currentUser = await m_kepwareApiClient.GenericConfig.LoadEntityByEndpointAsync(endpointUrl, cancellationToken: cancellationToken); if (currentUser == null) { @@ -309,7 +309,7 @@ public async Task CreateOrUpdateServerUserAsync(ServerUser user, Cancellat /// A token that can be used to request cancellation of the operation. /// True if the user was successfully deleted; otherwise, false. public Task DeleteServerUserAsync(string name, CancellationToken cancellationToken = default) - => m_kepwareApiClient.GenericConfig.DeleteItemAsync(name, cancellationToken); + => m_kepwareApiClient.GenericConfig.DeleteItemAsync(name, cancellationToken: cancellationToken); #endregion @@ -345,7 +345,7 @@ public Task DeleteServerUserAsync(string name, CancellationToken cancellat public Task GetProjectPermissionAsync(string serverUserGroupName, ProjectPermissionName projectPermissionName, CancellationToken cancellationToken = default) { var endpoint = EndpointResolver.ResolveEndpoint([serverUserGroupName, projectPermissionName]); - return m_kepwareApiClient.GenericConfig.LoadEntityByEndpointAsync(endpoint, cancellationToken); + return m_kepwareApiClient.GenericConfig.LoadEntityByEndpointAsync(endpoint, cancellationToken: cancellationToken); } /// @@ -371,7 +371,7 @@ public async Task UpdateProjectPermissionAsync(string serverUserGroupName, try { var endpointUrl = EndpointResolver.ResolveEndpoint([serverUserGroupName, projectPermission.Name]); - var existingPermission = await m_kepwareApiClient.GenericConfig.LoadEntityByEndpointAsync(endpointUrl, cancellationToken); + var existingPermission = await m_kepwareApiClient.GenericConfig.LoadEntityByEndpointAsync(endpointUrl, cancellationToken: cancellationToken); if (existingPermission == null) { diff --git a/Kepware.Api/ClientHandler/GenericApiHandler.cs b/Kepware.Api/ClientHandler/GenericApiHandler.cs index 5793852..bf510c6 100644 --- a/Kepware.Api/ClientHandler/GenericApiHandler.cs +++ b/Kepware.Api/ClientHandler/GenericApiHandler.cs @@ -159,7 +159,7 @@ public async Task UpdateItemsAsync(List<(K item, K? oldItem)> item foreach (var pair in items) { var endpoint = $"{collectionEndpoint}/{Uri.EscapeDataString(pair.oldItem!.Name)}"; - var currentEntity = await LoadEntityByEndpointAsync(endpoint, cancellationToken).ConfigureAwait(false); + var currentEntity = await LoadEntityByEndpointAsync(endpoint, cancellationToken: cancellationToken).ConfigureAwait(false); if (currentEntity == null) { m_logger.LogError("Failed to load {TypeName} from {Endpoint}", typeof(K).Name, endpoint); @@ -478,13 +478,16 @@ public async Task DeleteItemsAsync(List items, NamedEntity? owner /// /// The type of the entity to load. /// The name of the entity to load. If null, loads the default entity. + /// Optional query parameters to append to the request URI. /// A token that can be used to request cancellation of the operation. /// The loaded entity of type or null if not found. - public Task LoadEntityAsync(string? name = default, CancellationToken cancellationToken = default) + public Task LoadEntityAsync(string? name = default, IEnumerable>? query = null, CancellationToken cancellationToken = default) where T : BaseEntity, new() { var endpoint = EndpointResolver.ResolveEndpoint(string.IsNullOrEmpty(name) ? [] : [name]); - return LoadEntityByEndpointAsync(endpoint, cancellationToken); + endpoint = AppendQueryString(endpoint, query); + var serializedRequest = query != null && query.Any(kv => kv.Key.Equals("content", StringComparison.OrdinalIgnoreCase) && kv.Value == "serialize"); + return LoadEntityByEndpointAsync(endpoint, serialized: serializedRequest, cancellationToken: cancellationToken); } /// @@ -492,13 +495,16 @@ public async Task DeleteItemsAsync(List items, NamedEntity? owner /// /// The type of the entity to load. /// The owner of the entity. + /// Optional query parameters to append to the request URI. /// A token that can be used to request cancellation of the operation. /// The loaded entity of type or null if not found. - public Task LoadEntityAsync(IEnumerable owner, CancellationToken cancellationToken = default) + public Task LoadEntityAsync(IEnumerable owner, IEnumerable>? query = null, CancellationToken cancellationToken = default) where T : BaseEntity, new() { var endpoint = EndpointResolver.ResolveEndpoint(owner); - return LoadEntityByEndpointAsync(endpoint, cancellationToken); + endpoint = AppendQueryString(endpoint, query); + var serializedRequest = query != null && query.Any(kv => kv.Key.Equals("content", StringComparison.OrdinalIgnoreCase) && kv.Value == "serialize"); + return LoadEntityByEndpointAsync(endpoint, serialized: serializedRequest, cancellationToken: cancellationToken); } /// @@ -507,14 +513,18 @@ public async Task DeleteItemsAsync(List items, NamedEntity? owner /// The type of the entity to load. /// The name of the entity to load. /// The owner of the entity. + /// Optional query parameters to append to the request URI. /// A token that can be used to request cancellation of the operation. /// The loaded entity of type or null if not found. - public async Task LoadEntityAsync(string name, NamedEntity owner, CancellationToken cancellationToken = default) + public async Task LoadEntityAsync(string name, NamedEntity owner, IEnumerable>? query = null, CancellationToken cancellationToken = default) where T : BaseEntity, new() { var endpoint = EndpointResolver.ResolveEndpoint(owner, name); + endpoint = AppendQueryString(endpoint, query); - var entity = await LoadEntityByEndpointAsync(endpoint, cancellationToken); + var serializedRequest = query != null && query.Any(kv => kv.Key.Equals("content", StringComparison.OrdinalIgnoreCase) && kv.Value == "serialize"); + + var entity = await LoadEntityByEndpointAsync(endpoint, serialized: serializedRequest, cancellationToken: cancellationToken); if (entity is IHaveOwner ownable) { @@ -523,7 +533,7 @@ public async Task DeleteItemsAsync(List items, NamedEntity? owner return entity; } - protected internal async Task LoadEntityByEndpointAsync(string endpoint, CancellationToken cancellationToken = default) + protected internal async Task LoadEntityByEndpointAsync(string endpoint, bool serialized = false, CancellationToken cancellationToken = default) where T : BaseEntity, new() { try @@ -536,8 +546,16 @@ public async Task DeleteItemsAsync(List items, NamedEntity? owner m_logger.LogWarning("Failed to load {TypeName} from {Endpoint}: {ReasonPhrase}", typeof(T).Name, endpoint, response.ReasonPhrase); return default; } + var entity = default(T); - var entity = await DeserializeJsonAsync(response, cancellationToken).ConfigureAwait(false); + if (serialized) + { + entity = await DeserializeJsonLoadSerializedAsync(response, cancellationToken).ConfigureAwait(false); + } + else + { + entity = await DeserializeJsonAsync(response, cancellationToken).ConfigureAwait(false); + } return entity; } @@ -558,22 +576,24 @@ public async Task DeleteItemsAsync(List items, NamedEntity? owner /// /// The type of the entity collection to load. /// The owner of the entity collection. + /// Optional query parameters to append to the request URI. /// A token that can be used to request cancellation of the operation. /// The loaded collection of entities of type or null if not found. - public Task LoadCollectionAsync(string? owner = default, CancellationToken cancellationToken = default) + public Task LoadCollectionAsync(string? owner = default, IEnumerable>? query = null, CancellationToken cancellationToken = default) where T : EntityCollection, new() - => LoadCollectionAsync(owner, cancellationToken); + => LoadCollectionAsync(owner, query, cancellationToken); /// /// Loads a collection of entities of type asynchronously by its owner from the Kepware server. /// /// The type of the entity collection to load. /// The owner of the entity collection. + /// Optional query parameters to append to the request URI. /// A token that can be used to request cancellation of the operation. /// The loaded collection of entities of type or null if not found. - public Task LoadCollectionAsync(NamedEntity owner, CancellationToken cancellationToken = default) + public Task LoadCollectionAsync(NamedEntity owner, IEnumerable>? query = null, CancellationToken cancellationToken = default) where T : EntityCollection, new() - => LoadCollectionAsync(owner, cancellationToken); + => LoadCollectionAsync(owner, query, cancellationToken); /// /// Loads a collection of entities of type asynchronously by its owner from the Kepware server. @@ -581,12 +601,13 @@ public async Task DeleteItemsAsync(List items, NamedEntity? owner /// The type of the entity collection to load. /// The type of the entities in the collection. /// The owner of the entity collection. + /// Optional query parameters to append to the request URI. /// A token that can be used to request cancellation of the operation. /// The loaded collection of entities of type or null if not found. - public Task LoadCollectionAsync(string? owner = default, CancellationToken cancellationToken = default) + public Task LoadCollectionAsync(string? owner = default, IEnumerable>? query = null, CancellationToken cancellationToken = default) where T : EntityCollection, new() where K : BaseEntity, new() - => LoadCollectionAsync(string.IsNullOrEmpty(owner) ? [] : [owner], cancellationToken); + => LoadCollectionAsync(string.IsNullOrEmpty(owner) ? [] : [owner], query, cancellationToken); /// /// Loads a collection of entities of type asynchronously by its owner from the Kepware server. @@ -594,13 +615,14 @@ public async Task DeleteItemsAsync(List items, NamedEntity? owner /// The type of the entity collection to load. /// The type of the entities in the collection. /// The owner of the entity collection. + /// Optional query parameters to append to the request URI. /// A token that can be used to request cancellation of the operation. /// The loaded collection of entities of type or null if not found. - public async Task LoadCollectionAsync(NamedEntity owner, CancellationToken cancellationToken = default) + public async Task LoadCollectionAsync(NamedEntity owner, IEnumerable>? query = null, CancellationToken cancellationToken = default) where T : EntityCollection, new() where K : BaseEntity, new() { - var collection = await LoadCollectionByEndpointAsync(EndpointResolver.ResolveEndpoint(owner), cancellationToken); + var collection = await LoadCollectionByEndpointAsync(AppendQueryString(EndpointResolver.ResolveEndpoint(owner), query), cancellationToken); if (collection != null) { collection.Owner = owner; @@ -618,12 +640,13 @@ public async Task DeleteItemsAsync(List items, NamedEntity? owner /// The type of the entity collection to load. /// The type of the entities in the collection. /// The owner of the entity collection. + /// Optional query parameters to append to the request URI. /// A token that can be used to request cancellation of the operation. /// The loaded collection of entities of type or null if not found. - public Task LoadCollectionAsync(IEnumerable owner, CancellationToken cancellationToken = default) + public Task LoadCollectionAsync(IEnumerable owner, IEnumerable>? query = null, CancellationToken cancellationToken = default) where T : EntityCollection, new() where K : BaseEntity, new() - => LoadCollectionByEndpointAsync(EndpointResolver.ResolveEndpoint(owner), cancellationToken); + => LoadCollectionByEndpointAsync(AppendQueryString(EndpointResolver.ResolveEndpoint(owner), query), cancellationToken); protected internal async Task LoadCollectionByEndpointAsync(string endpoint, CancellationToken cancellationToken = default) where T : EntityCollection, new() @@ -823,6 +846,57 @@ public async Task DeleteItemsAsync(List items, NamedEntity? owner return null; } } + + /// + /// Special deserialization method for responses from endpoints with `?content=serialize` that wrap the actual object in an additional + /// layer with the object name as the property name, e.g. `{ "Channel": { ... } }`. This is required to properly handle dynamic properties + /// on channels/devices/etc that conform to a different model from JSON type info for the base entity. This would cause + /// deserialization to fail if we tried to deserialize directly to the target type. + /// + /// + /// + /// + /// + protected Task DeserializeJsonLoadSerializedAsync(HttpResponseMessage httpResponse, CancellationToken cancellationToken = default) + where K : BaseEntity, new() => DeserializeJsonLoadSerializedAsync(httpResponse, KepJsonContext.GetJsonTypeInfo(), cancellationToken); + + /// + /// Special deserialization method for responses from endpoints with `?content=serialize` that wrap the actual object in an additional + /// layer with the object name as the property name, e.g. `{ "Channel": { ... } }`. This is required to properly handle dynamic properties + /// on channels/devices/etc that conform to a different model from JSON type info for the base entity. This would cause + /// deserialization to fail if we tried to deserialize directly to the target type. + /// + /// + /// + /// + /// + /// + protected async Task DeserializeJsonLoadSerializedAsync(HttpResponseMessage httpResponse, JsonTypeInfo jsonTypeInfo, CancellationToken cancellationToken = default) + where K : BaseEntity, new() + { + try + { + using var stream = await httpResponse.Content.ReadAsStreamAsync(cancellationToken); + var wrapper = await JsonSerializer.DeserializeAsync>( + stream, KepJsonContext.Default.DictionaryStringJsonElement, cancellationToken).ConfigureAwait(false) + ?? throw new JsonException("Response was not a JSON object."); + + var first = wrapper.Values.FirstOrDefault(); + if (first.ValueKind != JsonValueKind.Object) + throw new JsonException("Expected the first property to be a JSON object."); + + return first.Deserialize(jsonTypeInfo: KepJsonContext.GetJsonTypeInfo()) + ?? throw new JsonException("Failed to deserialize channel object."); + //return await JsonSerializer.DeserializeAsync(stream, jsonTypeInfo, cancellationToken); + } + catch (JsonException ex) + { + m_logger.LogError(ex, "JSON Deserialization failed"); + return default; + } + } + + #endregion /// @@ -841,5 +915,36 @@ internal void InvalidateCaches() #endregion + /// + /// Append query parameters to an endpoint string. Encodes keys and values with Uri.EscapeDataString. + /// Null or empty values are skipped. If `endpoint` already contains a query, parameters are appended with &. + /// + private static string AppendQueryString(string endpoint, IEnumerable>? query) + { + if (query == null) + return endpoint; + + var sb = new StringBuilder(); + foreach (var kv in query) + { + if (kv.Key == null) + continue; + // Skip parameters with null values to match typical REST filter behavior. + if (kv.Value is null) + continue; + + if (sb.Length > 0) + sb.Append('&'); + + sb.Append(Uri.EscapeDataString(kv.Key)); + sb.Append('='); + sb.Append(Uri.EscapeDataString(kv.Value)); + } + + if (sb.Length == 0) + return endpoint; + + return endpoint + (endpoint.Contains('?') ? "&" : "?") + sb.ToString(); + } } -} +} \ No newline at end of file From d022f5544ad9fa765bd00a60d7c9e9dbd4988f32 Mon Sep 17 00:00:00 2001 From: Ray Labbe Date: Mon, 16 Mar 2026 14:25:16 -0400 Subject: [PATCH 07/16] feat(api): Enhanced LoadProject to use content=serialze option in an optimized recursion --- .../ApiClient/ProjectLoadTests.cs | 6 +- .../ApiClient/ProjectLoadTests.cs | 97 ++++++- .../ApiClient/_TestIntgApiClientBase.cs | 8 +- .../ClientHandler/ProjectApiHandler.cs | 271 ++++++++++++++---- .../Model/Project/Channel.Properties.cs | 5 + .../Model/Project/Device.Properties.cs | 25 ++ Kepware.Api/Model/Project/Project.cs | 5 + 7 files changed, 349 insertions(+), 68 deletions(-) create mode 100644 Kepware.Api/Model/Project/Device.Properties.cs diff --git a/Kepware.Api.Test/ApiClient/ProjectLoadTests.cs b/Kepware.Api.Test/ApiClient/ProjectLoadTests.cs index af3ed55..171618f 100644 --- a/Kepware.Api.Test/ApiClient/ProjectLoadTests.cs +++ b/Kepware.Api.Test/ApiClient/ProjectLoadTests.cs @@ -98,7 +98,7 @@ public async Task LoadProject_ShouldLoadCorrectly_BasedOnProductSupport( await ConfigureToServeEndpoints(); } - var project = await _kepwareApiClient.Project.LoadProject(true); + var project = await _kepwareApiClient.Project.LoadProjectAsync(true); project.IsLoadedByProjectLoadService.ShouldBe(supportsJsonLoad); @@ -182,7 +182,7 @@ public async Task LoadProject_NotFull_ShouldLoadCorrectly_BasedOnProductSupport( await ConfigureToServeEndpoints(); - var project = await _kepwareApiClient.Project.LoadProject(blnLoadFullProject: false); + var project = await _kepwareApiClient.Project.LoadProjectAsync(blnLoadFullProject: false); project.ShouldNotBeNull(); project.Channels.ShouldBeNull("Channels list should be null."); @@ -201,7 +201,7 @@ public async Task LoadProject_ShouldReturnEmptyProject_WhenHttpRequestFails() .ThrowsAsync(new HttpRequestException()); // Act - var project = await _kepwareApiClient.Project.LoadProject(true); + var project = await _kepwareApiClient.Project.LoadProjectAsync(true); // Assert project.ShouldNotBeNull(); diff --git a/Kepware.Api.TestIntg/ApiClient/ProjectLoadTests.cs b/Kepware.Api.TestIntg/ApiClient/ProjectLoadTests.cs index 6127e3f..bfde274 100644 --- a/Kepware.Api.TestIntg/ApiClient/ProjectLoadTests.cs +++ b/Kepware.Api.TestIntg/ApiClient/ProjectLoadTests.cs @@ -110,6 +110,99 @@ private static void CompareTagGroupsRecursive(DeviceTagGroupCollection? expected } } + [Fact] + public async Task LoadProject_Full_ShouldLoadCorrectly_BasedOnProductSupport() + { + // Arrange + var channel = await AddTestChannel(); + var device = await AddTestDevice(channel); + var tags = await AddSimulatorTestTags(device); + var tagGroup = await AddTestTagGroup(device); + var tagGroup2 = await AddTestTagGroup(tagGroup, "TagGroup2"); + + var channel2 = await AddTestChannel("Channel2"); + var device2 = await AddTestDevice(channel2); + var tags2 = await AddSimulatorTestTags(device2); + var tagGroup_2 = await AddTestTagGroup(device2); + var tagGroup2_2 = await AddTestTagGroup(tagGroup_2, "TagGroup2"); + + var pro = new Project(); + + // Act + var project = await _kepwareApiClient.Project.LoadProjectAsync(blnLoadFullProject: true); + + // Assert + Assert.NotNull(project); + Assert.NotNull(project.Channels); + Assert.Contains(project.Channels, c => c.Name == channel.Name); + + var foundChannel = project.Channels.Find(c => c.Name == channel.Name); + Assert.NotNull(foundChannel); + Assert.NotNull(foundChannel.Devices); + Assert.Contains(foundChannel.Devices, d => d.Name == device.Name); + + var foundDevice = foundChannel.Devices.Find(d => d.Name == device.Name); + Assert.NotNull(foundDevice); + Assert.NotNull(foundDevice.Tags); + Assert.Equal(tags.Count, foundDevice.Tags.Count); + Assert.NotNull(foundDevice.TagGroups); + Assert.Contains(foundDevice.TagGroups, tg => tg.Name == tagGroup.Name); + + var foundTagGroup = foundDevice.TagGroups.Find(tg => tg.Name == tagGroup.Name); + Assert.NotNull(foundTagGroup); + Assert.NotNull(foundTagGroup.TagGroups); + Assert.Contains(foundTagGroup.TagGroups, tg => tg.Name == tagGroup2.Name); + + + // Clean up + await DeleteAllChannelsAsync(); + } + + [Fact] + public async Task LoadProject_Full_LargeProject_ShouldLoadCorrectly_BasedOnProductSupport() + { + // Arrange + var channel = await AddTestChannel(); + var device = await AddTestDevice(channel); + var tags = await AddSimulatorTestTags(device, count: 10000); + var tagGroup = await AddTestTagGroup(device); + var tagGroup2 = await AddTestTagGroup(tagGroup, "TagGroup2"); + + var channel2 = await AddTestChannel("Channel2"); + var device2 = await AddTestDevice(channel2); + var tags2 = await AddSimulatorTestTags(device2); + var tagGroup_2 = await AddTestTagGroup(device2); + var tagGroup2_2 = await AddTestTagGroup(tagGroup_2, "TagGroup2"); + + // Act + var project = await _kepwareApiClient.Project.LoadProjectAsync(blnLoadFullProject: true); + + // Assert + Assert.NotNull(project); + Assert.NotNull(project.Channels); + Assert.Contains(project.Channels, c => c.Name == channel.Name); + + var foundChannel = project.Channels.Find(c => c.Name == channel.Name); + Assert.NotNull(foundChannel); + Assert.NotNull(foundChannel.Devices); + Assert.Contains(foundChannel.Devices, d => d.Name == device.Name); + + var foundDevice = foundChannel.Devices.Find(d => d.Name == device.Name); + Assert.NotNull(foundDevice); + Assert.NotNull(foundDevice.Tags); + Assert.Equal(tags.Count, foundDevice.Tags.Count); + Assert.NotNull(foundDevice.TagGroups); + Assert.Contains(foundDevice.TagGroups, tg => tg.Name == tagGroup.Name); + + var foundTagGroup = foundDevice.TagGroups.Find(tg => tg.Name == tagGroup.Name); + Assert.NotNull(foundTagGroup); + Assert.NotNull(foundTagGroup.TagGroups); + Assert.Contains(foundTagGroup.TagGroups, tg => tg.Name == tagGroup2.Name); + + + // Clean up + await DeleteAllChannelsAsync(); + } [Fact] public async Task LoadProject_NotFull_ShouldLoadCorrectly_BasedOnProductSupport() { @@ -119,7 +212,7 @@ public async Task LoadProject_NotFull_ShouldLoadCorrectly_BasedOnProductSupport( var tags = await AddSimulatorTestTags(device); // Act - var project = await _kepwareApiClient.Project.LoadProject(blnLoadFullProject: false); + var project = await _kepwareApiClient.Project.LoadProjectAsync(blnLoadFullProject: false); // Assert project.ShouldNotBeNull(); @@ -139,7 +232,7 @@ public async Task LoadProject_ShouldReturnEmptyProject_WhenHttpRequestFails() { // Act - var project = await _badCredKepwareApiClient.Project.LoadProject(true); + var project = await _badCredKepwareApiClient.Project.LoadProjectAsync(true); // Assert project.ShouldNotBeNull(); diff --git a/Kepware.Api.TestIntg/ApiClient/_TestIntgApiClientBase.cs b/Kepware.Api.TestIntg/ApiClient/_TestIntgApiClientBase.cs index fbf1a9d..23beace 100644 --- a/Kepware.Api.TestIntg/ApiClient/_TestIntgApiClientBase.cs +++ b/Kepware.Api.TestIntg/ApiClient/_TestIntgApiClientBase.cs @@ -153,25 +153,25 @@ protected async Task AddSimulatorTestTag(DeviceTagGroup owner, string name protected List CreateSimulatorTestTags(string name = "Tag", string address = "K000", int count = 2) { - return Enumerable.Range(1, count) + return Enumerable.Range(0, count-1) .Select(i => CreateTestTag(name: $"{name}{i}", address: $"{address}{i}")) .ToList(); } protected async Task> AddSimulatorTestTags(Device owner, string name = "Tag", string address = "K000", int count = 2) { - var tagsList = CreateSimulatorTestTags(name, address); + var tagsList = CreateSimulatorTestTags(name, address, count); foreach (var tag in tagsList) { tag.Owner = owner; } - await _kepwareApiClient.GenericConfig.InsertItemsAsync(tagsList, owner: owner); + await _kepwareApiClient.GenericConfig.InsertItemsAsync(tagsList, pageSize: count ,owner: owner); return tagsList; } protected async Task> AddSimulatorTestTags(DeviceTagGroup owner, string name = "Tag1", string address = "K000", int count = 2) { - var tagsList = CreateSimulatorTestTags(name, address); + var tagsList = CreateSimulatorTestTags(name, address, count); foreach (var tag in tagsList) { tag.Owner = owner; diff --git a/Kepware.Api/ClientHandler/ProjectApiHandler.cs b/Kepware.Api/ClientHandler/ProjectApiHandler.cs index 54bb2e5..be89a90 100644 --- a/Kepware.Api/ClientHandler/ProjectApiHandler.cs +++ b/Kepware.Api/ClientHandler/ProjectApiHandler.cs @@ -61,7 +61,7 @@ public ProjectApiHandler(KepwareApiClient kepwareApiClient, ChannelApiHandler ch /// A task that represents the asynchronous operation. The task result contains a tuple with the counts of inserts, updates, and deletes. public async Task<(int inserts, int updates, int deletes)> CompareAndApply(Project sourceProject, CancellationToken cancellationToken = default) { - var projectFromApi = await LoadProject(blnLoadFullProject: true, cancellationToken: cancellationToken); + var projectFromApi = await LoadProjectAsync(blnLoadFullProject: true, cancellationToken: cancellationToken); await projectFromApi.Cleanup(m_kepwareApiClient, true, cancellationToken).ConfigureAwait(false); return await CompareAndApply(sourceProject, projectFromApi, cancellationToken).ConfigureAwait(false); } @@ -217,6 +217,21 @@ public async Task SetProjectPropertiesAsync(Project project, CancellationT #endregion #region LoadProject + + /// + /// Does the same as but is marked as obsolete. + /// + /// Indicates whether to load the full project. + /// The cancellation token. + /// A task that represents the asynchronous operation. The task result contains the loaded . + /// Deprecated in v1.1.0; will be removed in future release + [Obsolete("Use LoadProjectAsync() instead. This will be removed in future release", false)] + [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public async Task LoadProject(bool blnLoadFullProject = false, CancellationToken cancellationToken = default) + { + return await LoadProjectAsync(blnLoadFullProject, cancellationToken).ConfigureAwait(false); + } + /// /// Loads the project from the Kepware server. If is true, it loads the full project, otherwise only /// the project properties will be returned. @@ -224,9 +239,9 @@ public async Task SetProjectPropertiesAsync(Project project, CancellationT /// Indicates whether to load the full project. /// The cancellation token. /// A task that represents the asynchronous operation. The task result contains the loaded . - /// NOTE: When loading a full project, the project will be loaded via the JsonProjectLoad service if supported by the server. (Kepware Server 6.17+ - /// and Thingworx Kepware Server 1.10+) Otherwise, the project will be loaded by recursively loading all objects in the project. - public async Task LoadProject(bool blnLoadFullProject = false, CancellationToken cancellationToken = default) + /// NOTE: When loading a full project, the project will be loaded either via the JsonProjectLoad service, an "optimized" + /// recursion that uses the content=serialize query or a basic recurion through project tree. + public async Task LoadProjectAsync(bool blnLoadFullProject = false, CancellationToken cancellationToken = default) { Stopwatch stopwatch = Stopwatch.StartNew(); @@ -249,41 +264,59 @@ public async Task LoadProject(bool blnLoadFullProject = false, Cancella var productInfo = await m_kepwareApiClient.GetProductInfoAsync(cancellationToken).ConfigureAwait(false); - if (blnLoadFullProject && productInfo?.SupportsJsonProjectLoadService == true) + if (productInfo?.SupportsJsonProjectLoadService == true) { try { - var response = await m_kepwareApiClient.HttpClient.GetAsync(ENDPONT_FULL_PROJECT, cancellationToken).ConfigureAwait(false); - if (response.IsSuccessStatusCode) + // Optimized recursive loading approach that uses the content=serialize query parameter. + // This approach significantly reduces the number of API calls when loading projects with a large number of tags and prevents + // timeout errors with large projects. + + // TODO: change threshold to configurable option + // Currently hardcoded to 100000 tags as the threshold to use content=serialize based loading or full recursive loading. + var tagLimit = 100000; + if (int.TryParse(project.GetDynamicProperty(Properties.ProjectSettings.TagsDefined), out int count) && count > tagLimit) { - var prjRoot = await JsonSerializer.DeserializeAsync( - await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false), - KepJsonContext.Default.JsonProjectRoot, cancellationToken).ConfigureAwait(false); + m_logger.LogInformation("Project has greater than {TagLimit} tags defined. Loading project via optimized recursion...", tagLimit); + + project = await LoadProjectOptimizedRecurisveAsync(project, tagLimit, cancellationToken).ConfigureAwait(false); + + if (!project.IsEmpty) + { + SetOwnersFullProject(project); + m_logger.LogInformation("Loaded project via optimized recursion in {ElapsedMilliseconds} ms", stopwatch.ElapsedMilliseconds); + } + return project; + } - if (prjRoot?.Project != null) + // If project has less than tagLimit number of tags, load full project via JsonProjectLoad service. + else + { + m_logger.LogInformation("Project has less than {TagLimit} tags defined. Loading project via JsonProjectLoad Service...", tagLimit); + var response = await m_kepwareApiClient.HttpClient.GetAsync(ENDPONT_FULL_PROJECT, cancellationToken).ConfigureAwait(false); + if (response.IsSuccessStatusCode) { - prjRoot.Project.IsLoadedByProjectLoadService = true; + var prjRoot = await JsonSerializer.DeserializeAsync( + await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false), + KepJsonContext.Default.JsonProjectRoot, cancellationToken).ConfigureAwait(false); - if (prjRoot.Project.Channels != null) - foreach (var channel in prjRoot.Project.Channels) - { - if (channel.Devices != null) - foreach (var device in channel.Devices) - { - device.Owner = channel; - - if (device.Tags != null) - foreach (var tag in device.Tags) - tag.Owner = device; - - if (device.TagGroups != null) - SetOwnerRecursive(device.TagGroups, device); - } - } + // Set the Owner property for all loaded entities. + if (prjRoot?.Project != null) + { + prjRoot.Project.IsLoadedByProjectLoadService = true; + + SetOwnersFullProject(prjRoot.Project); - m_logger.LogInformation("Loaded project via JsonProjectLoad Service in {ElapsedMilliseconds} ms", stopwatch.ElapsedMilliseconds); - return prjRoot.Project; + m_logger.LogInformation("Loaded project via JsonProjectLoad Service in {ElapsedMilliseconds} ms", stopwatch.ElapsedMilliseconds); + project = prjRoot.Project; + } + else + { + m_logger.LogWarning("Failed to deserialize project loaded via JsonProjectLoad Service"); + project = new Project(); + } } + return project; } } catch (HttpRequestException httpEx) @@ -297,28 +330,92 @@ await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false } else { - project = await m_kepwareApiClient.GenericConfig.LoadEntityAsync(cancellationToken: cancellationToken).ConfigureAwait(false); + project = await LoadProjectRecursiveAsync(project, cancellationToken).ConfigureAwait(false); - if (project == null) + if (!project.IsEmpty) { - m_logger.LogWarning("Failed to load project"); - project = new Project(); + m_logger.LogInformation("Loaded project in via non-optimized recursion {ElapsedMilliseconds} ms", stopwatch.ElapsedMilliseconds); + } + + return project; + } + } + + private static void SetOwnersFullProject(Project project) + { + if (project.Channels != null) + foreach (var channel in project.Channels) + { + if (channel.Devices != null) + foreach (var device in channel.Devices) + { + device.Owner = channel; + + if (device.Tags != null) + foreach (var tag in device.Tags) + tag.Owner = device; + + if (device.TagGroups != null) + SetOwnerRecursive(device.TagGroups, device); + } } - else if (blnLoadFullProject) + } + + private async Task LoadProjectOptimizedRecurisveAsync(Project project, int tagLimit, CancellationToken cancellationToken = default) + { + project.Channels = await m_kepwareApiClient.GenericConfig.LoadCollectionAsync(cancellationToken: cancellationToken); + if (project.Channels != null) + { + int totalChannelCount = project.Channels.Count; + int loadedChannelCount = 0; + await Task.WhenAll(project.Channels.Select(async (channel, c_index) => { - project.Channels = await m_kepwareApiClient.GenericConfig.LoadCollectionAsync(cancellationToken: cancellationToken).ConfigureAwait(false); - if (project.Channels != null) + if (channel.GetDynamicProperty(Properties.Channel.StaticTagCount) < tagLimit) { - int totalChannelCount = project.Channels.Count; - int loadedChannelCount = 0; - await Task.WhenAll(project.Channels.Select(async channel => + var query = new[] + { + new KeyValuePair("content", "serialize") + }; + var loadedChannel = await m_kepwareApiClient.GenericConfig.LoadEntityAsync(channel.Name, query, cancellationToken: cancellationToken); + if (loadedChannel != null) { - channel.Devices = await m_kepwareApiClient.GenericConfig.LoadCollectionAsync(channel, cancellationToken).ConfigureAwait(false); + project.Channels[c_index] = loadedChannel; + } + else + { + // Failed to load channel, log warning and end without incrementing completion. + m_logger.LogWarning("Failed to load {ChannelName}", channel.Name); + return; + } + } + else + { + channel.Devices = await m_kepwareApiClient.GenericConfig.LoadCollectionAsync(channel, cancellationToken: cancellationToken).ConfigureAwait(false); - if (channel.Devices != null) + if (channel.Devices != null) + { + await Task.WhenAll(channel.Devices.Select(async (device, d_index) => { - await Task.WhenAll(channel.Devices.Select(async device => + if (device.GetDynamicProperty(Properties.Device.StaticTagCount) < tagLimit) + { + var query = new[] + { + new KeyValuePair("content", "serialize") + }; + var loadedDevice = await m_kepwareApiClient.GenericConfig.LoadEntityAsync(device.Name, channel, query, cancellationToken: cancellationToken).ConfigureAwait(false); + if (loadedDevice != null) + { + project.Channels[c_index].Devices![d_index] = loadedDevice; + } + else + { + // Failed to load device, log warning and end without incrementing completion. + m_logger.LogWarning("Failed to load {DeviceName} in channel {ChannelName}", device.Name, channel.Name); + return; + } + } + else { device.Tags = await m_kepwareApiClient.GenericConfig.LoadCollectionAsync(device, cancellationToken: cancellationToken).ConfigureAwait(false); device.TagGroups = await m_kepwareApiClient.GenericConfig.LoadCollectionAsync(device, cancellationToken: cancellationToken).ConfigureAwait(false); @@ -327,27 +424,83 @@ await Task.WhenAll(channel.Devices.Select(async device => { await LoadTagGroupsRecursiveAsync(m_kepwareApiClient, device.TagGroups, cancellationToken: cancellationToken).ConfigureAwait(false); } - })); - } - // Log information, loaded channel x of y - loadedChannelCount++; - if (totalChannelCount == 1) - { - m_logger.LogInformation("Loaded channel {ChannelName}", channel.Name); - } - else + } + + })); + } + + } + // Log information, loaded channel x of y + loadedChannelCount++; + if (totalChannelCount == 1) + { + m_logger.LogInformation("Loaded channel {ChannelName}", channel.Name); + } + else + { + m_logger.LogInformation("Loaded channel {ChannelName} {LoadedChannelCount} of {TotalChannelCount}", channel.Name, loadedChannelCount, totalChannelCount); + } + + })); + + // If loaded channel count doesn't match total channel count, log warning that some channels may have failed to load. + // Return empty project to avoid returning a partially loaded project which may cause issues for consumers of the API. + if (loadedChannelCount != totalChannelCount) + { + m_logger.LogWarning("Only loaded {LoadedChannelCount} of {TotalChannelCount} channels. Some channels may have fail to load.", loadedChannelCount, totalChannelCount); + project = new Project(); + } + } + + return project; + } + + private async Task LoadProjectRecursiveAsync(Project project, CancellationToken cancellationToken = default) + { + project.Channels = await m_kepwareApiClient.GenericConfig.LoadCollectionAsync(cancellationToken: cancellationToken).ConfigureAwait(false); + + if (project.Channels != null) + { + int totalChannelCount = project.Channels.Count; + int loadedChannelCount = 0; + await Task.WhenAll(project.Channels.Select(async channel => + { + channel.Devices = await m_kepwareApiClient.GenericConfig.LoadCollectionAsync(channel, cancellationToken: cancellationToken).ConfigureAwait(false); + + if (channel.Devices != null) + { + await Task.WhenAll(channel.Devices.Select(async device => + { + device.Tags = await m_kepwareApiClient.GenericConfig.LoadCollectionAsync(device, cancellationToken: cancellationToken).ConfigureAwait(false); + device.TagGroups = await m_kepwareApiClient.GenericConfig.LoadCollectionAsync(device, cancellationToken: cancellationToken).ConfigureAwait(false); + + if (device.TagGroups != null) { - m_logger.LogInformation("Loaded channel {ChannelName} {LoadedChannelCount} of {TotalChannelCount}", channel.Name, loadedChannelCount, totalChannelCount); + await LoadTagGroupsRecursiveAsync(m_kepwareApiClient, device.TagGroups, cancellationToken: cancellationToken).ConfigureAwait(false); } - })); } + // Log information, loaded channel x of y + loadedChannelCount++; + if (totalChannelCount == 1) + { + m_logger.LogInformation("Loaded channel {ChannelName}", channel.Name); + } + else + { + m_logger.LogInformation("Loaded channel {ChannelName} {LoadedChannelCount} of {TotalChannelCount}", channel.Name, loadedChannelCount, totalChannelCount); + } - m_logger.LogInformation("Loaded project in {ElapsedMilliseconds} ms", stopwatch.ElapsedMilliseconds); + })); + // If loaded channel count doesn't match total channel count, log warning that some channels may have failed to load. + // Return empty project to avoid returning a partially loaded project which may cause issues for consumers of the API. + if (loadedChannelCount != totalChannelCount) + { + m_logger.LogWarning("Only loaded {LoadedChannelCount} of {TotalChannelCount} channels. Some channels may have fail to load.", loadedChannelCount, totalChannelCount); + project = new Project(); } - - return project; } + return project; } #endregion @@ -429,8 +582,8 @@ internal static async Task LoadTagGroupsRecursiveAsync(KepwareApiClient apiClien foreach (var tagGroup in tagGroups) { // Load the Tag Groups and Tags of the current Tag Group - tagGroup.TagGroups = await apiClient.GenericConfig.LoadCollectionAsync(tagGroup, cancellationToken).ConfigureAwait(false); - tagGroup.Tags = await apiClient.GenericConfig.LoadCollectionAsync(tagGroup, cancellationToken).ConfigureAwait(false); + tagGroup.TagGroups = await apiClient.GenericConfig.LoadCollectionAsync(tagGroup, cancellationToken: cancellationToken).ConfigureAwait(false); + tagGroup.Tags = await apiClient.GenericConfig.LoadCollectionAsync(tagGroup, cancellationToken: cancellationToken).ConfigureAwait(false); // Recursively load the Tag Groups and Tags of the child Tag Groups if (tagGroup.TagGroups != null && tagGroup.TagGroups.Count > 0) diff --git a/Kepware.Api/Model/Project/Channel.Properties.cs b/Kepware.Api/Model/Project/Channel.Properties.cs index a9a0208..2b0e131 100644 --- a/Kepware.Api/Model/Project/Channel.Properties.cs +++ b/Kepware.Api/Model/Project/Channel.Properties.cs @@ -45,6 +45,11 @@ public static class Channel /// public const string DiagnosticsCapture = "servermain.CHANNEL_DIAGNOSTICS_CAPTURE"; + /// + /// Value of the static tag count for the channel. + /// + public const string StaticTagCount = "servermain.CHANNEL_STATIC_TAG_COUNT"; + } } } \ No newline at end of file diff --git a/Kepware.Api/Model/Project/Device.Properties.cs b/Kepware.Api/Model/Project/Device.Properties.cs new file mode 100644 index 0000000..006c64f --- /dev/null +++ b/Kepware.Api/Model/Project/Device.Properties.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Kepware.Api.Model +{ + public partial class Properties + { + public static class Device + { + /// + /// The driver used by this channel. + /// + public const string DeviceDriver = "servermain.MULTIPLE_TYPES_DEVICE_DRIVER"; + + /// + /// Value of the static tag count for the channel. + /// + public const string StaticTagCount = "servermain.DEVICE_STATIC_TAG_COUNT"; + + } + } +} diff --git a/Kepware.Api/Model/Project/Project.cs b/Kepware.Api/Model/Project/Project.cs index bfbcceb..f441603 100644 --- a/Kepware.Api/Model/Project/Project.cs +++ b/Kepware.Api/Model/Project/Project.cs @@ -24,6 +24,11 @@ public class Project : DefaultEntity /// public bool IsLoadedByProjectLoadService { get; internal set; } = false; + /// + /// If this is true, it indicates that this is an empty project object that was instantiated without data from the server. + /// + public bool IsEmpty => Channels == null && DynamicProperties.Count == 0; + /// /// Initializes a new instance of the class. /// From e27b4fcf58f180f70cbd0e8680bc21e595bc1455 Mon Sep 17 00:00:00 2001 From: Ray Labbe Date: Mon, 16 Mar 2026 18:31:43 -0400 Subject: [PATCH 08/16] feat(api): Added ProjectLoadTagLimit as a configurable property for controlling optimized recursion load behavior. --- .../ApiClient/ProjectLoadTests.cs | 68 +- .../ApiClient/_TestApiClientBase.cs | 48 +- Kepware.Api.Test/Kepware.Api.Test.csproj | 2 +- .../projectLoadSerializeData/Channel1.json | 52 + .../dataTypeExamples.16bitDevice.json | 926 ++++++++++++++++++ .../projectProperties.json | 80 ++ .../simulationExamples.json | 250 +++++ Kepware.Api.Test/_data/simdemo_en-us.json | 6 +- .../ApiClient/ProjectLoadTests.cs | 54 + .../ApiClient/_TestIntgApiClientBase.cs | 2 +- .../ClientHandler/ProjectApiHandler.cs | 161 +-- Kepware.Api/KepwareApiClientOptions.cs | 11 + 12 files changed, 1582 insertions(+), 78 deletions(-) create mode 100644 Kepware.Api.Test/_data/projectLoadSerializeData/Channel1.json create mode 100644 Kepware.Api.Test/_data/projectLoadSerializeData/dataTypeExamples.16bitDevice.json create mode 100644 Kepware.Api.Test/_data/projectLoadSerializeData/projectProperties.json create mode 100644 Kepware.Api.Test/_data/projectLoadSerializeData/simulationExamples.json diff --git a/Kepware.Api.Test/ApiClient/ProjectLoadTests.cs b/Kepware.Api.Test/ApiClient/ProjectLoadTests.cs index 171618f..6554f41 100644 --- a/Kepware.Api.Test/ApiClient/ProjectLoadTests.cs +++ b/Kepware.Api.Test/ApiClient/ProjectLoadTests.cs @@ -15,6 +15,7 @@ using Kepware.Api.Test.ApiClient; using Kepware.Api.Util; using Shouldly; +using Xunit.Sdk; namespace Kepware.Api.Test.ApiClient { @@ -98,7 +99,7 @@ public async Task LoadProject_ShouldLoadCorrectly_BasedOnProductSupport( await ConfigureToServeEndpoints(); } - var project = await _kepwareApiClient.Project.LoadProjectAsync(true); + var project = await _kepwareApiClient.Project.LoadProjectAsync(blnLoadFullProject: true); project.IsLoadedByProjectLoadService.ShouldBe(supportsJsonLoad); @@ -140,6 +141,71 @@ public async Task LoadProject_ShouldLoadCorrectly_BasedOnProductSupport( } } + [Theory] + [InlineData("KEPServerEX", "12", 6, 17, true)] + [InlineData("ThingWorxKepwareServer", "12", 6, 17, true)] + [InlineData("ThingWorxKepwareEdge", "13", 1, 10, true)] + [InlineData("Kepware Edge", "13", 1, 0, true)] + public async Task LoadProject_ShouldLoadCorrectly_Serialize_BasedOnProductSupport( + string productName, string productId, int majorVersion, int minorVersion, bool supportsJsonLoad) + { + ConfigureConnectedClient(productName, productId, majorVersion, minorVersion); + + if (supportsJsonLoad) + { + await ConfigureToServeEndpoints(); + } + else + { + // Skip this test case at runtime because it expects the server to serve a full JSON project. + throw SkipException.ForSkip($"Product {productName} v{majorVersion}.{minorVersion} (id={productId}) does not support JSON project load. Skipping full-project test case."); + } + + var tagLimitOverride = 100; // Set a high tag limit to ensure all tags are loaded for comparison + + var project = await _kepwareApiClient.Project.LoadProjectAsync(blnLoadFullProject: true, projectLoadTagLimit: tagLimitOverride); + + // Optimized recursion is done for this test, which will result in false. + project.IsLoadedByProjectLoadService.ShouldBeFalse(); + + project.ShouldNotBeNull(); + project.Channels.ShouldNotBeEmpty("Channels list should not be empty."); + + var testProject = await LoadJsonTestDataAsync(); + var compareResult = EntityCompare.Compare(testProject?.Project?.Channels, project?.Channels); + + compareResult.ShouldNotBeNull(); + compareResult.UnchangedItems.ShouldNotBeEmpty("All channels should be unchanged."); + compareResult.ChangedItems.ShouldBeEmpty("No channels should be changed."); + compareResult.ItemsOnlyInLeft.ShouldBeEmpty("No channels should exist only in the test data."); + compareResult.ItemsOnlyInRight.ShouldBeEmpty("No channels should exist only in the loaded project."); + + foreach (var (ExpectedChannel, LoadedChannel) in testProject?.Project?.Channels?.Zip(project?.Channels ?? []) ?? []) + { + var deviceCompareResult = EntityCompare.Compare(ExpectedChannel.Devices, LoadedChannel.Devices); + deviceCompareResult.ShouldNotBeNull(); + deviceCompareResult.UnchangedItems.ShouldNotBeEmpty($"All devices in channel {ExpectedChannel.Name} should be unchanged."); + deviceCompareResult.ChangedItems.ShouldBeEmpty($"No devices in channel {ExpectedChannel.Name} should be changed."); + deviceCompareResult.ItemsOnlyInLeft.ShouldBeEmpty($"No devices should exist only in the test data for channel {ExpectedChannel.Name}."); + deviceCompareResult.ItemsOnlyInRight.ShouldBeEmpty($"No devices should exist only in the loaded project for channel {ExpectedChannel.Name}."); + + foreach (var (ExpectedDevice, LoadedDevice) in ExpectedChannel.Devices?.Zip(LoadedChannel.Devices ?? []) ?? []) + { + if (ExpectedDevice.Tags?.Count > 0 || LoadedDevice.Tags?.Count > 0) + { + var tagCompareResult = EntityCompare.Compare(ExpectedDevice.Tags, LoadedDevice.Tags); + tagCompareResult.ShouldNotBeNull(); + tagCompareResult.UnchangedItems.ShouldNotBeEmpty($"All tags in device {ExpectedDevice.Name} should be unchanged."); + tagCompareResult.ChangedItems.ShouldBeEmpty($"No tags in device {ExpectedDevice.Name} should be changed."); + tagCompareResult.ItemsOnlyInLeft.ShouldBeEmpty($"No tags should exist only in the test data for device {ExpectedDevice.Name}."); + tagCompareResult.ItemsOnlyInRight.ShouldBeEmpty($"No tags should exist only in the loaded project for device {ExpectedDevice.Name}."); + } + + CompareTagGroupsRecursive(ExpectedDevice.TagGroups, LoadedDevice.TagGroups, ExpectedDevice.Name); + } + } + } + private static void CompareTagGroupsRecursive(DeviceTagGroupCollection? expected, DeviceTagGroupCollection? actual, string parentName) { if ((expected?.Count ?? 0) == 0 && (actual?.Count ?? 0) == 0) diff --git a/Kepware.Api.Test/ApiClient/_TestApiClientBase.cs b/Kepware.Api.Test/ApiClient/_TestApiClientBase.cs index eb3133e..725a6b1 100644 --- a/Kepware.Api.Test/ApiClient/_TestApiClientBase.cs +++ b/Kepware.Api.Test/ApiClient/_TestApiClientBase.cs @@ -146,7 +146,21 @@ protected async Task ConfigureToServeEndpoints(string filePath = "_data/simdemo_ { var projectData = await LoadJsonTestDataAsync(filePath); - var channels = projectData.Project?.Channels?.Select(c => new Channel { Name = c.Name, Description = c.Description, DynamicProperties = c.DynamicProperties }).ToList() ?? []; + + var channels = projectData.Project?.Channels? + .Select(c => + { + var ch = new Channel { Name = c.Name, Description = c.Description, DynamicProperties = c.DynamicProperties }; + int staticCount = c.Name switch + { + "Channel1" => 2, + "Simulation Examples" => 24, + "Data Type Examples" => 216, + _ => 0 + }; + ch.SetDynamicProperty(Properties.Channel.StaticTagCount, staticCount); + return ch; + }).ToList() ?? new List(); // Serve project details _httpMessageHandlerMock.SetupRequest(HttpMethod.Get, TEST_ENDPOINT + "/config/v1/project") @@ -163,7 +177,21 @@ protected async Task ConfigureToServeEndpoints(string filePath = "_data/simdemo_ if (channel.Devices != null) { - var devices = channel.Devices.Select(d => new Device { Name = d.Name, Description = d.Description, DynamicProperties = d.DynamicProperties }).ToList(); + var devices = channel.Devices + .Select(d => + { + var dev = new Device { Name = d.Name, Description = d.Description, DynamicProperties = d.DynamicProperties }; + int staticCount = d.Name switch + { + "Device1" => 2, + "Functions" => 24, + "16 Bit Device" => 98, + "8 Bit Device" => 118, + _ => 0 + }; + dev.SetDynamicProperty(Properties.Device.StaticTagCount, staticCount); + return dev; + }).ToList() ?? new List(); _httpMessageHandlerMock.SetupRequest(HttpMethod.Get, TEST_ENDPOINT + $"/config/v1/project/channels/{channel.Name}/devices") .ReturnsResponse(JsonSerializer.Serialize(devices), "application/json"); @@ -181,6 +209,22 @@ protected async Task ConfigureToServeEndpoints(string filePath = "_data/simdemo_ } } } + + // Additional endpoints for content=serialize mocking + var projectPropertiesString = await File.ReadAllTextAsync("_data/projectLoadSerializeData/projectProperties.json"); + var channel1String = await File.ReadAllTextAsync("_data/projectLoadSerializeData/channel1.json"); + var sixteenBitDeviceString = await File.ReadAllTextAsync("_data/projectLoadSerializeData/dataTypeExamples.16BitDevice.json"); + var simExamplesChannelString = await File.ReadAllTextAsync("_data/projectLoadSerializeData/simulationExamples.json"); + + _httpMessageHandlerMock.SetupRequest(HttpMethod.Get, TEST_ENDPOINT + "/config/v1/project") + .ReturnsResponse(projectPropertiesString, "application/json"); + _httpMessageHandlerMock.SetupRequest(HttpMethod.Get, TEST_ENDPOINT + "/config/v1/project/channels/Channel1?content=serialize") + .ReturnsResponse(channel1String, "application/json"); + _httpMessageHandlerMock.SetupRequest(HttpMethod.Get, TEST_ENDPOINT + "/config/v1/project/channels/Data Type Examples/devices/16 Bit Device?content=serialize") + .ReturnsResponse(sixteenBitDeviceString, "application/json"); + _httpMessageHandlerMock.SetupRequest(HttpMethod.Get, TEST_ENDPOINT + "/config/v1/project/channels/Simulation Examples?content=serialize") + .ReturnsResponse(simExamplesChannelString, "application/json"); + } private void ConfigureToServeEndpointsTagGroupsRecursive(string endpoint, IEnumerable tagGroups) { diff --git a/Kepware.Api.Test/Kepware.Api.Test.csproj b/Kepware.Api.Test/Kepware.Api.Test.csproj index a9e2f77..e120c72 100644 --- a/Kepware.Api.Test/Kepware.Api.Test.csproj +++ b/Kepware.Api.Test/Kepware.Api.Test.csproj @@ -34,7 +34,7 @@ - + PreserveNewest diff --git a/Kepware.Api.Test/_data/projectLoadSerializeData/Channel1.json b/Kepware.Api.Test/_data/projectLoadSerializeData/Channel1.json new file mode 100644 index 0000000..8ece78c --- /dev/null +++ b/Kepware.Api.Test/_data/projectLoadSerializeData/Channel1.json @@ -0,0 +1,52 @@ +{ + "channels": { + "common.ALLTYPES_NAME": "Channel1", + "common.ALLTYPES_DESCRIPTION": "Example Simulator Channel", + "servermain.MULTIPLE_TYPES_DEVICE_DRIVER": "Simulator", + "servermain.CHANNEL_DIAGNOSTICS_CAPTURE": false, + "servermain.CHANNEL_UNIQUE_ID": 1704486747, + "servermain.CHANNEL_WRITE_OPTIMIZATIONS_METHOD": 2, + "servermain.CHANNEL_WRITE_OPTIMIZATIONS_DUTY_CYCLE": 10, + "servermain.CHANNEL_NON_NORMALIZED_FLOATING_POINT_HANDLING": 0, + "simulator.CHANNEL_ITEM_PERSISTENCE": false, + "simulator.CHANNEL_ITEM_PERSISTENCE_DATA_FILE": "C:\\ProgramData\\PTC\\Kepware Server\\V7\\Simulator\\Channel1.dat", + "devices": [ + { + "common.ALLTYPES_NAME": "Device1", + "common.ALLTYPES_DESCRIPTION": "Example Simulator Device", + "servermain.MULTIPLE_TYPES_DEVICE_DRIVER": "Simulator", + "servermain.DEVICE_MODEL": 0, + "servermain.DEVICE_UNIQUE_ID": 1808204482, + "servermain.DEVICE_ID_FORMAT": 1, + "servermain.DEVICE_ID_STRING": "1", + "servermain.DEVICE_ID_HEXADECIMAL": 1, + "servermain.DEVICE_ID_DECIMAL": 1, + "servermain.DEVICE_ID_OCTAL": 1, + "servermain.DEVICE_DATA_COLLECTION": true, + "servermain.DEVICE_SCAN_MODE": 0, + "servermain.DEVICE_SCAN_MODE_RATE_MS": 1000, + "servermain.DEVICE_SCAN_MODE_PROVIDE_INITIAL_UPDATES_FROM_CACHE": false, + "tags": [ + { + "common.ALLTYPES_NAME": "Tag1", + "common.ALLTYPES_DESCRIPTION": "Ramping Read/Write tag used to verify client connection", + "servermain.TAG_ADDRESS": "R0001", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Tag2", + "common.ALLTYPES_DESCRIPTION": "Constant Read/Write tag used to verify client connection", + "servermain.TAG_ADDRESS": "K0001", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + } + ] + } + ] + } +} \ No newline at end of file diff --git a/Kepware.Api.Test/_data/projectLoadSerializeData/dataTypeExamples.16bitDevice.json b/Kepware.Api.Test/_data/projectLoadSerializeData/dataTypeExamples.16bitDevice.json new file mode 100644 index 0000000..6b491dc --- /dev/null +++ b/Kepware.Api.Test/_data/projectLoadSerializeData/dataTypeExamples.16bitDevice.json @@ -0,0 +1,926 @@ +{ + "devices": { + "common.ALLTYPES_NAME": "16 Bit Device", + "common.ALLTYPES_DESCRIPTION": "Example Simulator Device", + "servermain.MULTIPLE_TYPES_DEVICE_DRIVER": "Simulator", + "servermain.DEVICE_MODEL": 0, + "servermain.DEVICE_UNIQUE_ID": 18472794, + "servermain.DEVICE_ID_FORMAT": 1, + "servermain.DEVICE_ID_STRING": "3", + "servermain.DEVICE_ID_HEXADECIMAL": 3, + "servermain.DEVICE_ID_DECIMAL": 3, + "servermain.DEVICE_ID_OCTAL": 3, + "servermain.DEVICE_DATA_COLLECTION": true, + "servermain.DEVICE_SCAN_MODE": 0, + "servermain.DEVICE_SCAN_MODE_RATE_MS": 1000, + "servermain.DEVICE_SCAN_MODE_PROVIDE_INITIAL_UPDATES_FROM_CACHE": false, + "tag_groups": [ + { + "common.ALLTYPES_NAME": "B Registers", + "common.ALLTYPES_DESCRIPTION": "Boolean registers", + "tags": [ + { + "common.ALLTYPES_NAME": "Boolean1", + "common.ALLTYPES_DESCRIPTION": "Boolean register", + "servermain.TAG_ADDRESS": "B0001", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Boolean2", + "common.ALLTYPES_DESCRIPTION": "Boolean register", + "servermain.TAG_ADDRESS": "B0002", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Boolean3", + "common.ALLTYPES_DESCRIPTION": "Boolean register", + "servermain.TAG_ADDRESS": "B0003", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Boolean4", + "common.ALLTYPES_DESCRIPTION": "Boolean register", + "servermain.TAG_ADDRESS": "B0004", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "BooleanArray", + "common.ALLTYPES_DESCRIPTION": "Array of 4 Boolean Registers", + "servermain.TAG_ADDRESS": "B0010 [4]", + "servermain.TAG_DATA_TYPE": 21, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + } + ] + }, + { + "common.ALLTYPES_NAME": "K Registers", + "common.ALLTYPES_DESCRIPTION": "Constant Registers", + "tags": [ + { + "common.ALLTYPES_NAME": "Boolean1", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "K0100.00", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Boolean2", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "K0100.01", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Boolean3", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "K0100.02", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Boolean4", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "K0100.03", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double1", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0400", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double2", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0404", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double3", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0408", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double4", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0412", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DoubleArray", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point array", + "servermain.TAG_ADDRESS": "K0440 [4]", + "servermain.TAG_DATA_TYPE": 29, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord1", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0500", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord2", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0502", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord3", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0504", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord4", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0506", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWordArray", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer array", + "servermain.TAG_ADDRESS": "K0550 [4]", + "servermain.TAG_DATA_TYPE": 27, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float1", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0600", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float2", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0602", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float3", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0604", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float4", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0606", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "FloatArray", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point array", + "servermain.TAG_ADDRESS": "K0660 [4]", + "servermain.TAG_DATA_TYPE": 28, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong1", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "K1200", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong2", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "K1204", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong3", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "K1208", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong4", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "K1212", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLongArray", + "common.ALLTYPES_DESCRIPTION": "64-bit signed integer array", + "servermain.TAG_ADDRESS": "K1240 [4]", + "servermain.TAG_DATA_TYPE": 33, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long1", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "K0700", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long2", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "K0702", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long3", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "K0704", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long4", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "K0706", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LongArray", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer array", + "servermain.TAG_ADDRESS": "K0770 [4]", + "servermain.TAG_DATA_TYPE": 26, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord1", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "K1100", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord2", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "K1104", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord3", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "K1108", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord4", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "K1112", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWordArray", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned Integer array", + "servermain.TAG_ADDRESS": "K1140 [4]", + "servermain.TAG_DATA_TYPE": 34, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short1", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "K0800", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short2", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "K0801", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short3", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "K0802", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short4", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "K0803", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "ShortArray", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer array", + "servermain.TAG_ADDRESS": "K0880 [4]", + "servermain.TAG_DATA_TYPE": 24, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word1", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0900", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word2", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0901", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word3", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0902", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word4", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0903", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "WordArray", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer array", + "servermain.TAG_ADDRESS": "K0990 [4]", + "servermain.TAG_DATA_TYPE": 25, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + } + ] + }, + { + "common.ALLTYPES_NAME": "R Registers", + "common.ALLTYPES_DESCRIPTION": "Ramping Registers", + "tags": [ + { + "common.ALLTYPES_NAME": "Boolean1", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "R0100.00", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Boolean2", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "R0100.01", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Boolean3", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "R0100.02", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Boolean4", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "R0100.03", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double1", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "R0400", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double2", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "R0404", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double3", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "R0408", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double4", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "R0412", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DoubleArray", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point array", + "servermain.TAG_ADDRESS": "R0440 [4]", + "servermain.TAG_DATA_TYPE": 29, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord1", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "R0500", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord2", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "R0502", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord3", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "R0504", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord4", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "R0506", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWordArray", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer array", + "servermain.TAG_ADDRESS": "R0550 [4]", + "servermain.TAG_DATA_TYPE": 27, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float1", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "R0600", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float2", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "R0602", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float3", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "R0604", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float4", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "R0606", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "FloatArray", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point array", + "servermain.TAG_ADDRESS": "R0660 [4]", + "servermain.TAG_DATA_TYPE": 28, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong1", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "R1200", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong2", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "R1204", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong3", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "R1208", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong4", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "R1212", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLongArray", + "common.ALLTYPES_DESCRIPTION": "64-bit signed integer array", + "servermain.TAG_ADDRESS": "R1240 [4]", + "servermain.TAG_DATA_TYPE": 33, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long1", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "R0700", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long2", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "R0702", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long3", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "R0704", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long4", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "R0706", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LongArray", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer array", + "servermain.TAG_ADDRESS": "R0770 [4]", + "servermain.TAG_DATA_TYPE": 26, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord1", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "R1100", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord2", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "R1104", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord3", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "R1108", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord4", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "R1112", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWordArray", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned Integer array", + "servermain.TAG_ADDRESS": "R1140 [4]", + "servermain.TAG_DATA_TYPE": 34, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short1", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "R0800", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short2", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "R0801", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short3", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "R0802", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short4", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "R0803", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "ShortArray", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer array", + "servermain.TAG_ADDRESS": "R0880 [4]", + "servermain.TAG_DATA_TYPE": 24, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word1", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "R0900", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word2", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "R0901", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word3", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "R0902", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word4", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "R0903", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "WordArray", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer array", + "servermain.TAG_ADDRESS": "R0990 [4]", + "servermain.TAG_DATA_TYPE": 25, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + } + ] + }, + { + "common.ALLTYPES_NAME": "S Registers", + "common.ALLTYPES_DESCRIPTION": "String Registers", + "tags": [ + { + "common.ALLTYPES_NAME": "String1", + "common.ALLTYPES_DESCRIPTION": "Null terminated Unicode string", + "servermain.TAG_ADDRESS": "S0001", + "servermain.TAG_DATA_TYPE": 0, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "String2", + "common.ALLTYPES_DESCRIPTION": "Null terminated Unicode string", + "servermain.TAG_ADDRESS": "S0002", + "servermain.TAG_DATA_TYPE": 0, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "String3", + "common.ALLTYPES_DESCRIPTION": "Null terminated Unicode string", + "servermain.TAG_ADDRESS": "S0003", + "servermain.TAG_DATA_TYPE": 0, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "String4", + "common.ALLTYPES_DESCRIPTION": "Null terminated Unicode string", + "servermain.TAG_ADDRESS": "S0004", + "servermain.TAG_DATA_TYPE": 0, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "StringArray[4]", + "common.ALLTYPES_DESCRIPTION": "Null terminated Unicode string array", + "servermain.TAG_ADDRESS": "S0010 [4]", + "servermain.TAG_DATA_TYPE": 20, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + } + ] + } + ] + } +} \ No newline at end of file diff --git a/Kepware.Api.Test/_data/projectLoadSerializeData/projectProperties.json b/Kepware.Api.Test/_data/projectLoadSerializeData/projectProperties.json new file mode 100644 index 0000000..27a7a92 --- /dev/null +++ b/Kepware.Api.Test/_data/projectLoadSerializeData/projectProperties.json @@ -0,0 +1,80 @@ +{ + "PROJECT_ID": 960924075, + "common.ALLTYPES_DESCRIPTION": "Example project utilizing Simulator Driver.", + "servermain.PROJECT_TITLE": "Simulation Driver Demo", + "servermain.PROJECT_TAGS_DEFINED": "246", + "opcdaserver.PROJECT_OPC_DA_1_ENABLED": true, + "opcdaserver.PROJECT_OPC_DA_2_ENABLED": true, + "opcdaserver.PROJECT_OPC_DA_3_ENABLED": true, + "opcdaserver.PROJECT_OPC_SHOW_HINTS_ON_BROWSE": false, + "opcdaserver.PROJECT_OPC_SHOW_TAG_PROPERTIES_ON_BROWSE": false, + "opcdaserver.PROJECT_OPC_SHUTDOWN_WAIT_SEC": 15, + "opcdaserver.PROJECT_OPC_SYNC_REQUEST_WAIT_SEC": 15, + "opcdaserver.PROJECT_OPC_ENABLE_DIAGS": false, + "opcdaserver.PROJECT_OPC_MAX_CONNECTIONS": 512, + "opcdaserver.PROJECT_OPC_MAX_TAG_GROUPS": 2000, + "opcdaserver.PROJECT_OPC_REJECT_UNSUPPORTED_LANG_ID": true, + "opcdaserver.PROJECT_OPC_IGNORE_DEADBAND_ON_CACHE": false, + "opcdaserver.PROJECT_OPC_IGNORE_BROWSE_FILTER": false, + "opcdaserver.PROJECT_OPC_205A_DATA_TYPE_SUPPORT": true, + "opcdaserver.PROJECT_OPC_SYNC_READ_ERROR_ON_BAD_QUALITY": false, + "opcdaserver.PROJECT_OPC_RETURN_INITIAL_UPDATES_IN_SINGLE_CALLBACK": false, + "opcdaserver.PROJECT_OPC_RESPECT_CLIENT_LANG_ID": true, + "opcdaserver.PROJECT_OPC_COMPLIANT_DATA_CHANGE": true, + "opcdaserver.PROJECT_OPC_IGNORE_GROUP_UPDATE_RATE": false, + "wwtoolkitinterface.ENABLED": false, + "wwtoolkitinterface.SERVICE_NAME": "server_runtime", + "wwtoolkitinterface.CLIENT_UPDATE_INTERVAL_MS": 100, + "ddeserver.ENABLE": false, + "ddeserver.SERVICE_NAME": "ptcdde", + "ddeserver.ADVANCED_DDE": true, + "ddeserver.XLTABLE": true, + "ddeserver.CF_TEXT": true, + "ddeserver.CLIENT_UPDATE_INTERVAL_MS": 100, + "ddeserver.REQUEST_TIMEOUT_SEC": 15, + "uaserverinterface.PROJECT_OPC_UA_ENABLE": true, + "uaserverinterface.PROJECT_OPC_UA_DIAGNOSTICS": false, + "uaserverinterface.PROJECT_OPC_UA_ANONYMOUS_LOGIN": false, + "uaserverinterface.PROJECT_OPC_UA_MAX_CONNECTIONS": 128, + "uaserverinterface.PROJECT_OPC_UA_MIN_SESSION_TIMEOUT_SEC": 15, + "uaserverinterface.PROJECT_OPC_UA_MAX_SESSION_TIMEOUT_SEC": 60, + "uaserverinterface.PROJECT_OPC_UA_TAG_CACHE_TIMEOUT_SEC": 5, + "uaserverinterface.PROJECT_OPC_UA_BROWSE_TAG_PROPERTIES": false, + "uaserverinterface.PROJECT_OPC_UA_BROWSE_ADDRESS_HINTS": false, + "uaserverinterface.PROJECT_OPC_UA_MAX_DATA_QUEUE_SIZE": 2, + "uaserverinterface.PROJECT_OPC_UA_MAX_RETRANSMIT_QUEUE_SIZE": 10, + "uaserverinterface.PROJECT_OPC_UA_MAX_NOTIFICATION_PER_PUBLISH": 65536, + "aeserverinterface.ENABLE_AE_SERVER": false, + "aeserverinterface.ENABLE_SIMPLE_EVENTS": true, + "aeserverinterface.MAX_SUBSCRIPTION_BUFFER_SIZE": 100, + "aeserverinterface.MIN_SUBSCRIPTION_BUFFER_TIME_MS": 1000, + "aeserverinterface.MIN_KEEP_ALIVE_TIME_MS": 1000, + "hdaserver.ENABLE": false, + "hdaserver.ENABLE_DIAGNOSTICS": false, + "thingworxinterface.ENABLED": false, + "thingworxinterface.HOSTNAME": "localhost", + "thingworxinterface.PORT": 443, + "thingworxinterface.RESOURCE": "/Thingworx/WS", + "thingworxinterface.APPKEY": "", + "thingworxinterface.ALLOW_SELF_SIGNED_CERTIFICATE": false, + "thingworxinterface.TRUST_ALL_CERTIFICATES": false, + "thingworxinterface.DISABLE_ENCRYPTION": false, + "thingworxinterface.MAX_THING_COUNT": 500, + "thingworxinterface.THING_NAME": "Kepware Server", + "thingworxinterface.PUBLISH_FLOOR_MSEC": 1000, + "thingworxinterface.LOGGING_ENABLED": false, + "thingworxinterface.LOG_LEVEL": 3, + "thingworxinterface.VERBOSE": false, + "thingworxinterface.STORE_AND_FORWARD_ENABLED": false, + "thingworxinterface.STORAGE_PATH": "C:\\ProgramData\\PTC\\Kepware Server\\V7", + "thingworxinterface.DATASTORE_MAXSIZE": 2048, + "thingworxinterface.FORWARD_MODE": 0, + "thingworxinterface.DATASTORE_ID": 421728385, + "thingworxinterface.DELAY_BETWEEN_PUBLISHES": 0, + "thingworxinterface.MAX_UPDATES_PER_PUBLISH": 25000, + "thingworxinterface.PROXY_ENABLED": false, + "thingworxinterface.PROXY_HOST": "localhost", + "thingworxinterface.PROXY_PORT": 3128, + "thingworxinterface.PROXY_USERNAME": "", + "thingworxinterface.PROXY_PASSWORD": "" +} \ No newline at end of file diff --git a/Kepware.Api.Test/_data/projectLoadSerializeData/simulationExamples.json b/Kepware.Api.Test/_data/projectLoadSerializeData/simulationExamples.json new file mode 100644 index 0000000..9729550 --- /dev/null +++ b/Kepware.Api.Test/_data/projectLoadSerializeData/simulationExamples.json @@ -0,0 +1,250 @@ +{ + "channels": { + "common.ALLTYPES_NAME": "Simulation Examples", + "common.ALLTYPES_DESCRIPTION": "Example Simulator Channel", + "servermain.MULTIPLE_TYPES_DEVICE_DRIVER": "Simulator", + "servermain.CHANNEL_DIAGNOSTICS_CAPTURE": false, + "servermain.CHANNEL_UNIQUE_ID": 2691320731, + "servermain.CHANNEL_WRITE_OPTIMIZATIONS_METHOD": 2, + "servermain.CHANNEL_WRITE_OPTIMIZATIONS_DUTY_CYCLE": 10, + "servermain.CHANNEL_NON_NORMALIZED_FLOATING_POINT_HANDLING": 0, + "simulator.CHANNEL_ITEM_PERSISTENCE": false, + "simulator.CHANNEL_ITEM_PERSISTENCE_DATA_FILE": "C:\\ProgramData\\PTC\\Kepware Server\\V7\\Simulator\\Simulation Examples.dat", + "devices": [ + { + "common.ALLTYPES_NAME": "Functions", + "common.ALLTYPES_DESCRIPTION": "Example Simulator Device", + "servermain.MULTIPLE_TYPES_DEVICE_DRIVER": "Simulator", + "servermain.DEVICE_MODEL": 0, + "servermain.DEVICE_UNIQUE_ID": 2266623120, + "servermain.DEVICE_ID_FORMAT": 1, + "servermain.DEVICE_ID_STRING": "4", + "servermain.DEVICE_ID_HEXADECIMAL": 4, + "servermain.DEVICE_ID_DECIMAL": 4, + "servermain.DEVICE_ID_OCTAL": 4, + "servermain.DEVICE_DATA_COLLECTION": true, + "servermain.DEVICE_SCAN_MODE": 0, + "servermain.DEVICE_SCAN_MODE_RATE_MS": 1000, + "servermain.DEVICE_SCAN_MODE_PROVIDE_INITIAL_UPDATES_FROM_CACHE": false, + "tags": [ + { + "common.ALLTYPES_NAME": "Ramp1", + "common.ALLTYPES_DESCRIPTION": "Value increments by 4 from 35 to 100 every 120 ms", + "servermain.TAG_ADDRESS": "RAMP (120, 35, 100, 4)", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 0, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Ramp2", + "common.ALLTYPES_DESCRIPTION": "Value decrements by 0.25 from 200.50 to 150.75 every 300 ms", + "servermain.TAG_ADDRESS": "RAMP (300, 150.750000, 200.500000, -0.250000)", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 0, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Ramp3", + "common.ALLTYPES_DESCRIPTION": "Value increments by 1 from 0 to 1000 every 250 ms", + "servermain.TAG_ADDRESS": "RAMP (250, 0, 1000, 1)", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 0, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Ramp4", + "common.ALLTYPES_DESCRIPTION": "Value decrements by 5 from 1000 to -1000 every 2000 ms", + "servermain.TAG_ADDRESS": "RAMP (2000, -1000, 1000, -5)", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 0, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Ramp5", + "common.ALLTYPES_DESCRIPTION": "Value decrements by 500 from 1000000 to -1000000 every 250 ms", + "servermain.TAG_ADDRESS": "RAMP (250, -1000000, 1000000, -500)", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 0, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Ramp6", + "common.ALLTYPES_DESCRIPTION": "Value increments by 1250 from 0 to 1 billion every 1000 ms", + "servermain.TAG_ADDRESS": "RAMP (1000, 0, 1000000000, 1250)", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 0, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Ramp7", + "common.ALLTYPES_DESCRIPTION": "Value decrements by 1 billion to -1 billion every 1000 ms", + "servermain.TAG_ADDRESS": "RAMP (1000, -1000000000, 1000000000, -5555)", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 0, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Ramp8", + "common.ALLTYPES_DESCRIPTION": "Value decrements by 0.25 from 200.50 to 150.75 every 300 ms", + "servermain.TAG_ADDRESS": "RAMP (1000, 150.750000, 200.500000, -0.250000)", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 0, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Random1", + "common.ALLTYPES_DESCRIPTION": "Random values from -20 to 75 that change every 30 ms", + "servermain.TAG_ADDRESS": "RANDOM (30, -20, 75)", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 0, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Random2", + "common.ALLTYPES_DESCRIPTION": "Random values from 0 to 1000 that change every 100 ms", + "servermain.TAG_ADDRESS": "RANDOM (100, 0, 1000)", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 0, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Random3", + "common.ALLTYPES_DESCRIPTION": "Random values from -1000 to 0 that change every 100 ms", + "servermain.TAG_ADDRESS": "RANDOM (100, -1000, 0)", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 0, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Random4", + "common.ALLTYPES_DESCRIPTION": "Random values from -999 to 999 that change every 1000 ms", + "servermain.TAG_ADDRESS": "RANDOM (1000, -999, 999)", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 0, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Random5", + "common.ALLTYPES_DESCRIPTION": "Random values from -1000000000 to 1000000000 that change every 100 ms", + "servermain.TAG_ADDRESS": "RANDOM (100, -1000000000, 1000000000)", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 0, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Random6", + "common.ALLTYPES_DESCRIPTION": "Random values from -1000000 to 1000000 that change every 1000 ms", + "servermain.TAG_ADDRESS": "RANDOM (1000, -1000000, 1000000)", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 0, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Random7", + "common.ALLTYPES_DESCRIPTION": "Random values from 0 to 1000000000 that change every 1000 ms", + "servermain.TAG_ADDRESS": "RANDOM (1000, 0, 1000000000)", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 0, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Random8", + "common.ALLTYPES_DESCRIPTION": "Random values from 0 to 1000000 that change every 100 ms", + "servermain.TAG_ADDRESS": "RANDOM (100, 0, 1000000)", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 0, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Sine1", + "common.ALLTYPES_DESCRIPTION": "Sine values between -40 and 40 at 0.05 Hz with 0 phase shift", + "servermain.TAG_ADDRESS": "SINE (10, -40.000000, 40.000000, 0.050000, 0)", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 0, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Sine2", + "common.ALLTYPES_DESCRIPTION": "Sine values between -40 and 40 at 0.05 Hz with 180 phase shift", + "servermain.TAG_ADDRESS": "SINE (10, -40.000000, 40.000000, 0.050000, 180)", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 0, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Sine3", + "common.ALLTYPES_DESCRIPTION": "Sine values between -40 and 40 at 0.1 Hz with 0 phase shift", + "servermain.TAG_ADDRESS": "SINE (10, -40.000000, 40.000000, 0.100000, 0)", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 0, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Sine4", + "common.ALLTYPES_DESCRIPTION": "Sine values between -40 and 40 at 0.1 Hz with 360 phase shift", + "servermain.TAG_ADDRESS": "SINE (10, -40.000000, 40.000000, 0.100000, 360)", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 0, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "User1", + "common.ALLTYPES_DESCRIPTION": "Sequential string values that change every 1000 ms", + "servermain.TAG_ADDRESS": "USER (1000,Hello,world!,This,is,a,test.)", + "servermain.TAG_DATA_TYPE": 0, + "servermain.TAG_READ_WRITE_ACCESS": 0, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "User2", + "common.ALLTYPES_DESCRIPTION": "Sequential float values that change every 250 ms", + "servermain.TAG_ADDRESS": "USER (250,15.16,23.42,4.8)", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 0, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "User3", + "common.ALLTYPES_DESCRIPTION": "Sequential Boolean values that change every 200 ms", + "servermain.TAG_ADDRESS": "USER (200,1,0,0,1,0,0,1,0,0,0,1,0,1,0,1,0,0,0,1,0,1,0,1,0,0,0)", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 0, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "User4", + "common.ALLTYPES_DESCRIPTION": "A comma is a delimiter unless it is preceded with a backslash", + "servermain.TAG_ADDRESS": "USER (1500,To display a comma\\, place,a backslash in front of it.)", + "servermain.TAG_DATA_TYPE": 0, + "servermain.TAG_READ_WRITE_ACCESS": 0, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + } + ] + } + ] + } +} \ No newline at end of file diff --git a/Kepware.Api.Test/_data/simdemo_en-us.json b/Kepware.Api.Test/_data/simdemo_en-us.json index ce4243c..e93f6ce 100644 --- a/Kepware.Api.Test/_data/simdemo_en-us.json +++ b/Kepware.Api.Test/_data/simdemo_en-us.json @@ -13,7 +13,7 @@ "servermain.CHANNEL_WRITE_OPTIMIZATIONS_DUTY_CYCLE": 10, "servermain.CHANNEL_NON_NORMALIZED_FLOATING_POINT_HANDLING": 0, "simulator.CHANNEL_ITEM_PERSISTENCE": false, - "simulator.CHANNEL_ITEM_PERSISTENCE_DATA_FILE": "C:\\ProgramData\\Kepware\\KEPServerEX\\V6\\Simulator\\Channel1.dat", + "simulator.CHANNEL_ITEM_PERSISTENCE_DATA_FILE": "C:\\ProgramData\\PTC\\Kepware Server\\V7\\Simulator\\Channel1.dat", "devices": [ { "common.ALLTYPES_NAME": "Device1", @@ -63,7 +63,7 @@ "servermain.CHANNEL_WRITE_OPTIMIZATIONS_DUTY_CYCLE": 10, "servermain.CHANNEL_NON_NORMALIZED_FLOATING_POINT_HANDLING": 0, "simulator.CHANNEL_ITEM_PERSISTENCE": false, - "simulator.CHANNEL_ITEM_PERSISTENCE_DATA_FILE": "C:\\ProgramData\\Kepware\\KEPServerEX\\V6\\Simulator\\Data Type Examples.dat", + "simulator.CHANNEL_ITEM_PERSISTENCE_DATA_FILE": "C:\\ProgramData\\PTC\\Kepware Server\\V7\\Simulator\\Data Type Examples.dat", "devices": [ { "common.ALLTYPES_NAME": "16 Bit Device", @@ -2105,7 +2105,7 @@ "servermain.CHANNEL_WRITE_OPTIMIZATIONS_DUTY_CYCLE": 10, "servermain.CHANNEL_NON_NORMALIZED_FLOATING_POINT_HANDLING": 0, "simulator.CHANNEL_ITEM_PERSISTENCE": false, - "simulator.CHANNEL_ITEM_PERSISTENCE_DATA_FILE": "C:\\ProgramData\\Kepware\\KEPServerEX\\V6\\Simulator\\Simulation Examples.dat", + "simulator.CHANNEL_ITEM_PERSISTENCE_DATA_FILE": "C:\\ProgramData\\PTC\\Kepware Server\\V7\\Simulator\\Simulation Examples.dat", "devices": [ { "common.ALLTYPES_NAME": "Functions", diff --git a/Kepware.Api.TestIntg/ApiClient/ProjectLoadTests.cs b/Kepware.Api.TestIntg/ApiClient/ProjectLoadTests.cs index bfde274..bc01688 100644 --- a/Kepware.Api.TestIntg/ApiClient/ProjectLoadTests.cs +++ b/Kepware.Api.TestIntg/ApiClient/ProjectLoadTests.cs @@ -203,6 +203,60 @@ public async Task LoadProject_Full_LargeProject_ShouldLoadCorrectly_BasedOnProdu // Clean up await DeleteAllChannelsAsync(); } + + + [Fact] + public async Task LoadProject_Full_OverrideForOptimizedRecursion_ShouldLoadCorrectly_BasedOnProductSupport() + { + // Arrange + var channel = await AddTestChannel(); + var device = await AddTestDevice(channel); + var tags = await AddSimulatorTestTags(device, count: 200); + var tagGroup = await AddTestTagGroup(device); + var tagGroup2 = await AddTestTagGroup(tagGroup, "TagGroup2"); + var tagsTagGroup2 = await AddSimulatorTestTags(tagGroup2, count: 10); + + var channel2 = await AddTestChannel("Channel2"); + var device2 = await AddTestDevice(channel2); + var tags2 = await AddSimulatorTestTags(device2); + var tagGroup_2 = await AddTestTagGroup(device2); + var tagGroup2_2 = await AddTestTagGroup(tagGroup_2, "TagGroup2"); + + // Act + var project = await _kepwareApiClient.Project.LoadProjectAsync(blnLoadFullProject: true, projectLoadTagLimit: 100); + + // Assert + Assert.NotNull(project); + Assert.NotNull(project.Channels); + Assert.Contains(project.Channels, c => c.Name == channel.Name); + + var foundChannel = project.Channels.Find(c => c.Name == channel.Name); + Assert.NotNull(foundChannel); + Assert.NotNull(foundChannel.Devices); + Assert.Contains(foundChannel.Devices, d => d.Name == device.Name); + + var foundDevice = foundChannel.Devices.Find(d => d.Name == device.Name); + Assert.NotNull(foundDevice); + Assert.NotNull(foundDevice.Tags); + Assert.Equal(tags.Count, foundDevice.Tags.Count); + Assert.NotNull(foundDevice.TagGroups); + Assert.Contains(foundDevice.TagGroups, tg => tg.Name == tagGroup.Name); + + var foundTagGroup = foundDevice.TagGroups.Find(tg => tg.Name == tagGroup.Name); + Assert.NotNull(foundTagGroup); + Assert.NotNull(foundTagGroup.TagGroups); + Assert.Contains(foundTagGroup.TagGroups, tg => tg.Name == tagGroup2.Name); + + var foundTagGroup2 = foundTagGroup.TagGroups.Find(tg => tg.Name == tagGroup2.Name); + Assert.NotNull(foundTagGroup2); + Assert.NotNull(foundTagGroup2.Tags); + Assert.Equal(tagsTagGroup2.Count, foundTagGroup2.Tags.Count); + + + // Clean up + await DeleteAllChannelsAsync(); + } + [Fact] public async Task LoadProject_NotFull_ShouldLoadCorrectly_BasedOnProductSupport() { diff --git a/Kepware.Api.TestIntg/ApiClient/_TestIntgApiClientBase.cs b/Kepware.Api.TestIntg/ApiClient/_TestIntgApiClientBase.cs index 23beace..1f16211 100644 --- a/Kepware.Api.TestIntg/ApiClient/_TestIntgApiClientBase.cs +++ b/Kepware.Api.TestIntg/ApiClient/_TestIntgApiClientBase.cs @@ -153,7 +153,7 @@ protected async Task AddSimulatorTestTag(DeviceTagGroup owner, string name protected List CreateSimulatorTestTags(string name = "Tag", string address = "K000", int count = 2) { - return Enumerable.Range(0, count-1) + return Enumerable.Range(0, count) .Select(i => CreateTestTag(name: $"{name}{i}", address: $"{address}{i}")) .ToList(); } diff --git a/Kepware.Api/ClientHandler/ProjectApiHandler.cs b/Kepware.Api/ClientHandler/ProjectApiHandler.cs index be89a90..c0d41c7 100644 --- a/Kepware.Api/ClientHandler/ProjectApiHandler.cs +++ b/Kepware.Api/ClientHandler/ProjectApiHandler.cs @@ -219,7 +219,7 @@ public async Task SetProjectPropertiesAsync(Project project, CancellationT #region LoadProject /// - /// Does the same as but is marked as obsolete. + /// Does the same as but is marked as obsolete. /// /// Indicates whether to load the full project. /// The cancellation token. @@ -229,7 +229,7 @@ public async Task SetProjectPropertiesAsync(Project project, CancellationT [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] public async Task LoadProject(bool blnLoadFullProject = false, CancellationToken cancellationToken = default) { - return await LoadProjectAsync(blnLoadFullProject, cancellationToken).ConfigureAwait(false); + return await LoadProjectAsync(blnLoadFullProject, m_kepwareApiClient.ClientOptions.ProjectLoadTagLimit ,cancellationToken).ConfigureAwait(false); } /// @@ -237,11 +237,15 @@ public async Task LoadProject(bool blnLoadFullProject = false, Cancella /// the project properties will be returned. /// /// Indicates whether to load the full project. + /// The tag count threshold to determine whether to use optimized content=serialize + /// loading or basic recursive loading when loading the full project. This is only applicable for projects loaded with + /// the full project load option and when the JsonProjectLoad service is supported by the server. /// The cancellation token. /// A task that represents the asynchronous operation. The task result contains the loaded . /// NOTE: When loading a full project, the project will be loaded either via the JsonProjectLoad service, an "optimized" - /// recursion that uses the content=serialize query or a basic recurion through project tree. - public async Task LoadProjectAsync(bool blnLoadFullProject = false, CancellationToken cancellationToken = default) + /// recursion that uses the content=serialize query or a basic recurion through project tree. Putting a value for + /// will override the value set in during initial client creation. + public async Task LoadProjectAsync(bool blnLoadFullProject = false, int projectLoadTagLimit = 0, CancellationToken cancellationToken = default) { Stopwatch stopwatch = Stopwatch.StartNew(); @@ -266,20 +270,23 @@ public async Task LoadProjectAsync(bool blnLoadFullProject = false, Can if (productInfo?.SupportsJsonProjectLoadService == true) { + // Set by as the threshold to use content=serialize based loading or full recursive loading. Default + // set by class. + if (projectLoadTagLimit <= 0) + projectLoadTagLimit = m_kepwareApiClient.ClientOptions.ProjectLoadTagLimit; + try { + // Optimized recursive loading approach that uses the content=serialize query parameter. // This approach significantly reduces the number of API calls when loading projects with a large number of tags and prevents // timeout errors with large projects. - - // TODO: change threshold to configurable option - // Currently hardcoded to 100000 tags as the threshold to use content=serialize based loading or full recursive loading. - var tagLimit = 100000; - if (int.TryParse(project.GetDynamicProperty(Properties.ProjectSettings.TagsDefined), out int count) && count > tagLimit) + + if (int.TryParse(project.GetDynamicProperty(Properties.ProjectSettings.TagsDefined), out int count) && count > projectLoadTagLimit) { - m_logger.LogInformation("Project has greater than {TagLimit} tags defined. Loading project via optimized recursion...", tagLimit); + m_logger.LogInformation("Project has greater than {TagLimit} tags defined. Loading project via optimized recursion...", projectLoadTagLimit); - project = await LoadProjectOptimizedRecurisveAsync(project, tagLimit, cancellationToken).ConfigureAwait(false); + project = await LoadProjectOptimizedRecurisveAsync(project, projectLoadTagLimit, cancellationToken).ConfigureAwait(false); if (!project.IsEmpty) { @@ -292,7 +299,7 @@ public async Task LoadProjectAsync(bool blnLoadFullProject = false, Can // If project has less than tagLimit number of tags, load full project via JsonProjectLoad service. else { - m_logger.LogInformation("Project has less than {TagLimit} tags defined. Loading project via JsonProjectLoad Service...", tagLimit); + m_logger.LogInformation("Project has less than {TagLimit} tags defined. Loading project via JsonProjectLoad Service...", projectLoadTagLimit); var response = await m_kepwareApiClient.HttpClient.GetAsync(ENDPONT_FULL_PROJECT, cancellationToken).ConfigureAwait(false); if (response.IsSuccessStatusCode) { @@ -368,80 +375,94 @@ private async Task LoadProjectOptimizedRecurisveAsync(Project project, { int totalChannelCount = project.Channels.Count; int loadedChannelCount = 0; - await Task.WhenAll(project.Channels.Select(async (channel, c_index) => - { - if (channel.GetDynamicProperty(Properties.Channel.StaticTagCount) < tagLimit) + // Create a list of tasks by iterating indices to avoid modifying the collection while it's being enumerated. + var channelTasks = new List(); + for (int c_index = 0; c_index < project.Channels.Count; c_index++) + { + int channelIndex = c_index; + var channel = project.Channels[channelIndex]; + channelTasks.Add(Task.Run(async () => { - var query = new[] - { - new KeyValuePair("content", "serialize") - }; - var loadedChannel = await m_kepwareApiClient.GenericConfig.LoadEntityAsync(channel.Name, query, cancellationToken: cancellationToken); - if (loadedChannel != null) + if (channel.GetDynamicProperty(Properties.Channel.StaticTagCount) < tagLimit) { - project.Channels[c_index] = loadedChannel; + var query = new[] + { + new KeyValuePair("content", "serialize") + }; + var loadedChannel = await m_kepwareApiClient.GenericConfig.LoadEntityAsync(channel.Name, query, cancellationToken: cancellationToken).ConfigureAwait(false); + if (loadedChannel != null) + { + project.Channels[channelIndex] = loadedChannel; + } + else + { + // Failed to load channel, log warning and end without incrementing completion. + m_logger.LogWarning("Failed to load {ChannelName}", channel.Name); + return; + } } else { - // Failed to load channel, log warning and end without incrementing completion. - m_logger.LogWarning("Failed to load {ChannelName}", channel.Name); - return; - } - } - else - { - channel.Devices = await m_kepwareApiClient.GenericConfig.LoadCollectionAsync(channel, cancellationToken: cancellationToken).ConfigureAwait(false); + channel.Devices = await m_kepwareApiClient.GenericConfig.LoadCollectionAsync(channel, cancellationToken: cancellationToken).ConfigureAwait(false); - if (channel.Devices != null) - { - await Task.WhenAll(channel.Devices.Select(async (device, d_index) => - { - if (device.GetDynamicProperty(Properties.Device.StaticTagCount) < tagLimit) + if (channel.Devices != null) { - var query = new[] + var deviceTasks = new List(); + for (int d_index = 0; d_index < channel.Devices.Count; d_index++) { + int deviceIndex = d_index; + var device = channel.Devices[deviceIndex]; + deviceTasks.Add(Task.Run(async () => + { + if (device.GetDynamicProperty(Properties.Device.StaticTagCount) < tagLimit) + { + var query = new[] + { new KeyValuePair("content", "serialize") }; - var loadedDevice = await m_kepwareApiClient.GenericConfig.LoadEntityAsync(device.Name, channel, query, cancellationToken: cancellationToken).ConfigureAwait(false); - if (loadedDevice != null) - { - project.Channels[c_index].Devices![d_index] = loadedDevice; - } - else - { - // Failed to load device, log warning and end without incrementing completion. - m_logger.LogWarning("Failed to load {DeviceName} in channel {ChannelName}", device.Name, channel.Name); - return; + var loadedDevice = await m_kepwareApiClient.GenericConfig.LoadEntityAsync(device.Name, channel, query, cancellationToken: cancellationToken).ConfigureAwait(false); + if (loadedDevice != null) + { + project.Channels[channelIndex].Devices![deviceIndex] = loadedDevice; + } + else + { + // Failed to load device, log warning and end without incrementing completion. + m_logger.LogWarning("Failed to load {DeviceName} in channel {ChannelName}", device.Name, channel.Name); + return; + } + } + else + { + device.Tags = await m_kepwareApiClient.GenericConfig.LoadCollectionAsync(device, cancellationToken: cancellationToken).ConfigureAwait(false); + device.TagGroups = await m_kepwareApiClient.GenericConfig.LoadCollectionAsync(device, cancellationToken: cancellationToken).ConfigureAwait(false); + + if (device.TagGroups != null) + { + await LoadTagGroupsRecursiveAsync(m_kepwareApiClient, device.TagGroups, cancellationToken: cancellationToken).ConfigureAwait(false); + } + } + })); } + await Task.WhenAll(deviceTasks).ConfigureAwait(false); } - else - { - device.Tags = await m_kepwareApiClient.GenericConfig.LoadCollectionAsync(device, cancellationToken: cancellationToken).ConfigureAwait(false); - device.TagGroups = await m_kepwareApiClient.GenericConfig.LoadCollectionAsync(device, cancellationToken: cancellationToken).ConfigureAwait(false); - - if (device.TagGroups != null) - { - await LoadTagGroupsRecursiveAsync(m_kepwareApiClient, device.TagGroups, cancellationToken: cancellationToken).ConfigureAwait(false); - } - } - - })); } - } - // Log information, loaded channel x of y - loadedChannelCount++; - if (totalChannelCount == 1) - { - m_logger.LogInformation("Loaded channel {ChannelName}", channel.Name); - } - else - { - m_logger.LogInformation("Loaded channel {ChannelName} {LoadedChannelCount} of {TotalChannelCount}", channel.Name, loadedChannelCount, totalChannelCount); - } + // Log information, loaded channel x of y + System.Threading.Interlocked.Increment(ref loadedChannelCount); + if (totalChannelCount == 1) + { + m_logger.LogInformation("Loaded channel {ChannelName}", channel.Name); + } + else + { + m_logger.LogInformation("Loaded channel {ChannelName} {LoadedChannelCount} of {TotalChannelCount}", channel.Name, loadedChannelCount, totalChannelCount); + } + })); + } - })); + await Task.WhenAll(channelTasks).ConfigureAwait(false); // If loaded channel count doesn't match total channel count, log warning that some channels may have failed to load. // Return empty project to avoid returning a partially loaded project which may cause issues for consumers of the API. diff --git a/Kepware.Api/KepwareApiClientOptions.cs b/Kepware.Api/KepwareApiClientOptions.cs index 7cd951d..26c7622 100644 --- a/Kepware.Api/KepwareApiClientOptions.cs +++ b/Kepware.Api/KepwareApiClientOptions.cs @@ -60,5 +60,16 @@ public class KepwareApiClientOptions /// Gets or sets an optional tag object for additional configuration metadata. /// public object? Tag { get; init; } + + /// + /// Gets the maximum number of tags that can be loaded in a single action when using ProjectLoad methods. + /// This limit is crucial for managing performance and resource utilization when working with large projects, + /// as it helps to prevent excessive memory usage and potential timeouts that may occur when attempting to + /// load an excessively large number of tags at once. + /// + /// This property is initialized to a default value of 100,000. It is important to + /// consider this limit when working with projects that may contain a large number of tags, as exceeding this + /// limit may result in performance degradation or incomplete data loading. + public int ProjectLoadTagLimit { get; init; } = 100000; } } From 7dd31afa3e1b4578518735fc4647ac208cff2d52 Mon Sep 17 00:00:00 2001 From: Ray Labbe Date: Mon, 16 Mar 2026 18:32:12 -0400 Subject: [PATCH 09/16] feat(api): added DeviceDriver to device model --- Kepware.Api/Model/Project/Device.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Kepware.Api/Model/Project/Device.cs b/Kepware.Api/Model/Project/Device.cs index e0015aa..9dc3944 100644 --- a/Kepware.Api/Model/Project/Device.cs +++ b/Kepware.Api/Model/Project/Device.cs @@ -70,6 +70,12 @@ public Device(string name, string channelName) [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public DeviceTagGroupCollection? TagGroups { get; set; } + /// + /// Gets the driver used by this device. + /// + [YamlIgnore, JsonIgnore] + public string? DeviceDriver => GetDynamicProperty(Properties.Device.DeviceDriver); + /// /// Gets the unique ID key for the device. /// From b19ee4cf80ef45f500cd3cdc0e9957a6c3499ec3 Mon Sep 17 00:00:00 2001 From: Ray Labbe Date: Mon, 16 Mar 2026 18:33:15 -0400 Subject: [PATCH 10/16] chore: translated comment --- Kepware.Api.Test/ApiClient/LoadEntity.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Kepware.Api.Test/ApiClient/LoadEntity.cs b/Kepware.Api.Test/ApiClient/LoadEntity.cs index 8d12269..761b948 100644 --- a/Kepware.Api.Test/ApiClient/LoadEntity.cs +++ b/Kepware.Api.Test/ApiClient/LoadEntity.cs @@ -379,7 +379,7 @@ public async Task LoadEntityAsync_ShouldThrowInvalidOperationException_WhenLoadR #endregion - #region LoadEntityAsync - Single Tag mit DynamicProperties + #region LoadEntityAsync - Single Tag with DynamicProperties [Fact] public async Task LoadEntityAsync_ShouldReturnTag_WithCorrectDynamicProperties() From b178ba26e7f5d4baedec66594f5ae9448ce2d9ac Mon Sep 17 00:00:00 2001 From: Ray Labbe Date: Mon, 16 Mar 2026 18:33:46 -0400 Subject: [PATCH 11/16] chore: ensure _data files are output in build --- Kepware.Api.TestIntg/Kepware.Api.TestIntg.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Kepware.Api.TestIntg/Kepware.Api.TestIntg.csproj b/Kepware.Api.TestIntg/Kepware.Api.TestIntg.csproj index 884ad48..6283af0 100644 --- a/Kepware.Api.TestIntg/Kepware.Api.TestIntg.csproj +++ b/Kepware.Api.TestIntg/Kepware.Api.TestIntg.csproj @@ -42,7 +42,7 @@ PreserveNewest - + PreserveNewest From 7c60442c51f15805e099ba5e4bba62371de33526 Mon Sep 17 00:00:00 2001 From: Ray Labbe Date: Tue, 17 Mar 2026 18:38:47 -0400 Subject: [PATCH 12/16] feat(api): extended optimized recursion ProjectLoad to tag groups --- .../ApiClient/ProjectLoadTests.cs | 84 +- .../ApiClient/_TestApiClientBase.cs | 102 +- .../dte.8bitDevice.Breg.json | 53 + .../dte.8bitDevice.Kreg.json | 494 +++ .../dte.8bitDevice.Rreg.json | 494 +++ .../dte.8bitDevice.Sreg.json | 53 + .../opt.recursionDevice.Breg.json | 53 + .../opt.recursionDevice.Kreg.json | 404 +++ ....recursionDevice.RecursionTest.Level1.json | 806 +++++ ....recursionDevice.RecursionTest.Level2.json | 403 +++ ....recursionDevice.RecursionTest.Level3.json | 403 +++ ....recursionDevice.RecursionTest.Level4.json | 403 +++ .../opt.recursionDevice.Rreg.json | 404 +++ .../opt.recursionDevice.Sreg.json | 53 + Kepware.Api.Test/_data/simdemo_en-us.json | 3022 ++++++++++++++++- .../ClientHandler/ProjectApiHandler.cs | 61 +- Kepware.Api/KepwareApiClient.cs | 8 + .../Project/DeviceTagGroup.Properties.cs | 25 + Kepware.Api/Model/Project/DeviceTagGroup.cs | 22 +- 19 files changed, 7266 insertions(+), 81 deletions(-) create mode 100644 Kepware.Api.Test/_data/projectLoadSerializeData/dte.8bitDevice.Breg.json create mode 100644 Kepware.Api.Test/_data/projectLoadSerializeData/dte.8bitDevice.Kreg.json create mode 100644 Kepware.Api.Test/_data/projectLoadSerializeData/dte.8bitDevice.Rreg.json create mode 100644 Kepware.Api.Test/_data/projectLoadSerializeData/dte.8bitDevice.Sreg.json create mode 100644 Kepware.Api.Test/_data/projectLoadSerializeData/opt.recursionDevice.Breg.json create mode 100644 Kepware.Api.Test/_data/projectLoadSerializeData/opt.recursionDevice.Kreg.json create mode 100644 Kepware.Api.Test/_data/projectLoadSerializeData/opt.recursionDevice.RecursionTest.Level1.json create mode 100644 Kepware.Api.Test/_data/projectLoadSerializeData/opt.recursionDevice.RecursionTest.Level2.json create mode 100644 Kepware.Api.Test/_data/projectLoadSerializeData/opt.recursionDevice.RecursionTest.Level3.json create mode 100644 Kepware.Api.Test/_data/projectLoadSerializeData/opt.recursionDevice.RecursionTest.Level4.json create mode 100644 Kepware.Api.Test/_data/projectLoadSerializeData/opt.recursionDevice.Rreg.json create mode 100644 Kepware.Api.Test/_data/projectLoadSerializeData/opt.recursionDevice.Sreg.json create mode 100644 Kepware.Api/Model/Project/DeviceTagGroup.Properties.cs diff --git a/Kepware.Api.Test/ApiClient/ProjectLoadTests.cs b/Kepware.Api.Test/ApiClient/ProjectLoadTests.cs index 6554f41..cd1991c 100644 --- a/Kepware.Api.Test/ApiClient/ProjectLoadTests.cs +++ b/Kepware.Api.Test/ApiClient/ProjectLoadTests.cs @@ -22,63 +22,6 @@ namespace Kepware.Api.Test.ApiClient public class ProjectLoadTests : TestApiClientBase { - //private async Task ConfigureToServeEndpoints() - //{ - // var projectData = await LoadJsonTestDataAsync(); - - // var channels = projectData.Project?.Channels?.Select(c => new Channel { Name = c.Name, Description = c.Description, DynamicProperties = c.DynamicProperties }).ToList() ?? []; - - // // Serve project details - // _httpMessageHandlerMock.SetupRequest(HttpMethod.Get, TEST_ENDPOINT + "/config/v1/project") - // .ReturnsResponse(JsonSerializer.Serialize(new Project { Description = projectData?.Project?.Description, DynamicProperties = projectData?.Project?.DynamicProperties ?? [] }), "application/json"); - - // // Serve channels without nested devices - // _httpMessageHandlerMock.SetupRequest(HttpMethod.Get, TEST_ENDPOINT + "/config/v1/project/channels") - // .ReturnsResponse(JsonSerializer.Serialize(channels), "application/json"); - - // foreach (var channel in projectData?.Project?.Channels ?? []) - // { - // _httpMessageHandlerMock.SetupRequest(HttpMethod.Get, TEST_ENDPOINT + $"/config/v1/project/channels/{channel.Name}") - // .ReturnsResponse(JsonSerializer.Serialize(new Channel { Name = channel.Name, Description = channel.Description, DynamicProperties = channel.DynamicProperties }), "application/json"); - - // if (channel.Devices != null) - // { - // var devices = channel.Devices.Select(d => new Device { Name = d.Name, Description = d.Description, DynamicProperties = d.DynamicProperties }).ToList(); - // _httpMessageHandlerMock.SetupRequest(HttpMethod.Get, TEST_ENDPOINT + $"/config/v1/project/channels/{channel.Name}/devices") - // .ReturnsResponse(JsonSerializer.Serialize(devices), "application/json"); - - // foreach (var device in channel.Devices) - // { - // var deviceEndpoint = TEST_ENDPOINT + $"/config/v1/project/channels/{channel.Name}/devices/{device.Name}"; - // _httpMessageHandlerMock.SetupRequest(HttpMethod.Get, deviceEndpoint) - // .ReturnsResponse(JsonSerializer.Serialize(new Device { Name = device.Name, Description = device.Description, DynamicProperties = device.DynamicProperties }), "application/json"); - - - // _httpMessageHandlerMock.SetupRequest(HttpMethod.Get, deviceEndpoint + "/tags") - // .ReturnsResponse(JsonSerializer.Serialize(device.Tags), "application/json"); - - // ConfigureToServeEndpointsTagGroupsRecursive(deviceEndpoint, device.TagGroups ?? []); - // } - // } - // } - //} - - //private void ConfigureToServeEndpointsTagGroupsRecursive(string endpoint, IEnumerable tagGroups) - //{ - // var tagGroupEndpoint = endpoint + "/tag_groups"; - - // _httpMessageHandlerMock.SetupRequest(HttpMethod.Get, tagGroupEndpoint) - // .ReturnsResponse(JsonSerializer.Serialize(tagGroups), "application/json"); - - // foreach (var tagGroup in tagGroups) - // { - // _httpMessageHandlerMock.SetupRequest(HttpMethod.Get, string.Concat(tagGroupEndpoint, "/", tagGroup.Name, "/tags")) - // .ReturnsResponse(JsonSerializer.Serialize(tagGroup.Tags), "application/json"); - - // ConfigureToServeEndpointsTagGroupsRecursive(string.Concat(tagGroupEndpoint, "/", tagGroup.Name), tagGroup.TagGroups ?? []); - // } - //} - [Theory] [InlineData("KEPServerEX", "12", 6, 17, true)] [InlineData("KEPServerEX", "12", 6, 16, false)] @@ -88,6 +31,12 @@ public class ProjectLoadTests : TestApiClientBase public async Task LoadProject_ShouldLoadCorrectly_BasedOnProductSupport( string productName, string productId, int majorVersion, int minorVersion, bool supportsJsonLoad) { + // This test will validate that the LoadProjectAsync method correctly loads the project structure and + // content based on whether the connected server version supports JsonProjectLoad. It will compare the loaded project against expected test data to ensure accuracy. + // For servers that support JsonProjectLoad, the test will configure the mock server to serve a full JSON project + // and validate that the loaded project matches the test data exactly. + + // Arrange ConfigureConnectedClient(productName, productId, majorVersion, minorVersion); if (supportsJsonLoad) @@ -99,8 +48,10 @@ public async Task LoadProject_ShouldLoadCorrectly_BasedOnProductSupport( await ConfigureToServeEndpoints(); } + // Act var project = await _kepwareApiClient.Project.LoadProjectAsync(blnLoadFullProject: true); + // Assert project.IsLoadedByProjectLoadService.ShouldBe(supportsJsonLoad); project.ShouldNotBeNull(); @@ -149,6 +100,11 @@ public async Task LoadProject_ShouldLoadCorrectly_BasedOnProductSupport( public async Task LoadProject_ShouldLoadCorrectly_Serialize_BasedOnProductSupport( string productName, string productId, int majorVersion, int minorVersion, bool supportsJsonLoad) { + // This test will validate that the LoadProjectAsync method correctly loads the project structure using the optimized recursion method. + // It will compare the loaded project against expected test data to ensure accuracy. The test will configure the mock server to serve + // endpoints to support an optimized recursion load and validate that the loaded project matches the test data exactly. + + // Arrange ConfigureConnectedClient(productName, productId, majorVersion, minorVersion); if (supportsJsonLoad) @@ -161,10 +117,16 @@ public async Task LoadProject_ShouldLoadCorrectly_Serialize_BasedOnProductSuppor throw SkipException.ForSkip($"Product {productName} v{majorVersion}.{minorVersion} (id={productId}) does not support JSON project load. Skipping full-project test case."); } - var tagLimitOverride = 100; // Set a high tag limit to ensure all tags are loaded for comparison + // Override the tag limit to ensure that we are testing the optimized recursion and selectively load objects based on the tag limit. + // See _data/simdemo_en.json and json chunks in _data/projectLoadSerializeData for data that is served by the mock server for this test. + var tagLimitOverride = 100; + + // Act var project = await _kepwareApiClient.Project.LoadProjectAsync(blnLoadFullProject: true, projectLoadTagLimit: tagLimitOverride); + + // Assert // Optimized recursion is done for this test, which will result in false. project.IsLoadedByProjectLoadService.ShouldBeFalse(); @@ -204,6 +166,12 @@ public async Task LoadProject_ShouldLoadCorrectly_Serialize_BasedOnProductSuppor CompareTagGroupsRecursive(ExpectedDevice.TagGroups, LoadedDevice.TagGroups, ExpectedDevice.Name); } } + + // Verify expected number of calls to the project load endpoints to ensure that the optimized recursion is selectively loading objects based on the tag limit. + foreach (var uri in _optimizedRecursionUris) + { + _httpMessageHandlerMock.VerifyRequest(HttpMethod.Get, uri); + } } private static void CompareTagGroupsRecursive(DeviceTagGroupCollection? expected, DeviceTagGroupCollection? actual, string parentName) diff --git a/Kepware.Api.Test/ApiClient/_TestApiClientBase.cs b/Kepware.Api.Test/ApiClient/_TestApiClientBase.cs index 725a6b1..7e3e006 100644 --- a/Kepware.Api.Test/ApiClient/_TestApiClientBase.cs +++ b/Kepware.Api.Test/ApiClient/_TestApiClientBase.cs @@ -28,6 +28,11 @@ public abstract class TestApiClientBase protected readonly Mock _loggerFactoryMock; protected readonly KepwareApiClient _kepwareApiClient; + /// + /// URIs used to optimize recursion endpoints for tests. Populated via . + /// + protected readonly List _optimizedRecursionUris = new List(); + protected TestApiClientBase() { _httpMessageHandlerMock = new Mock(); @@ -156,6 +161,7 @@ protected async Task ConfigureToServeEndpoints(string filePath = "_data/simdemo_ "Channel1" => 2, "Simulation Examples" => 24, "Data Type Examples" => 216, + "OptRecursionTest" => 318, _ => 0 }; ch.SetDynamicProperty(Properties.Channel.StaticTagCount, staticCount); @@ -187,6 +193,7 @@ protected async Task ConfigureToServeEndpoints(string filePath = "_data/simdemo_ "Functions" => 24, "16 Bit Device" => 98, "8 Bit Device" => 118, + "RecursionTestDevice" => 318, _ => 0 }; dev.SetDynamicProperty(Properties.Device.StaticTagCount, staticCount); @@ -198,6 +205,8 @@ protected async Task ConfigureToServeEndpoints(string filePath = "_data/simdemo_ foreach (var device in channel.Devices) { var deviceEndpoint = TEST_ENDPOINT + $"/config/v1/project/channels/{channel.Name}/devices/{device.Name}"; + + _httpMessageHandlerMock.SetupRequest(HttpMethod.Get, deviceEndpoint) .ReturnsResponse(JsonSerializer.Serialize(new Device { Name = device.Name, Description = device.Description, DynamicProperties = device.DynamicProperties }), "application/json"); @@ -215,25 +224,114 @@ protected async Task ConfigureToServeEndpoints(string filePath = "_data/simdemo_ var channel1String = await File.ReadAllTextAsync("_data/projectLoadSerializeData/channel1.json"); var sixteenBitDeviceString = await File.ReadAllTextAsync("_data/projectLoadSerializeData/dataTypeExamples.16BitDevice.json"); var simExamplesChannelString = await File.ReadAllTextAsync("_data/projectLoadSerializeData/simulationExamples.json"); + var dte8BitBRegTagGroupString = await File.ReadAllTextAsync("_data/projectLoadSerializeData/dte.8bitDevice.Breg.json"); + var dte8BitKRegTagGroupString = await File.ReadAllTextAsync("_data/projectLoadSerializeData/dte.8bitDevice.Kreg.json"); + var dte8BitRRegTagGroupString = await File.ReadAllTextAsync("_data/projectLoadSerializeData/dte.8bitDevice.Rreg.json"); + var dte8BitSRegTagGroupString = await File.ReadAllTextAsync("_data/projectLoadSerializeData/dte.8bitDevice.Sreg.json"); + var optRecursionDeviceBRegTagGroupString = await File.ReadAllTextAsync("_data/projectLoadSerializeData/opt.recursionDevice.Breg.json"); + var optRecursionDeviceKRegTagGroupString = await File.ReadAllTextAsync("_data/projectLoadSerializeData/opt.recursionDevice.Kreg.json"); + var optRecursionDeviceRRegTagGroupString = await File.ReadAllTextAsync("_data/projectLoadSerializeData/opt.recursionDevice.Rreg.json"); + var optRecursionDeviceSRegTagGroupString = await File.ReadAllTextAsync("_data/projectLoadSerializeData/opt.recursionDevice.Sreg.json"); + var optRecursionDeviceRecursionTestLevel1String = await File.ReadAllTextAsync("_data/projectLoadSerializeData/opt.recursionDevice.RecursionTest.Level1.json"); + var optRecursionDeviceRecursionTestLevel2String = await File.ReadAllTextAsync("_data/projectLoadSerializeData/opt.recursionDevice.RecursionTest.Level2.json"); + var optRecursionDeviceRecursionTestLevel3String = await File.ReadAllTextAsync("_data/projectLoadSerializeData/opt.recursionDevice.RecursionTest.Level3.json"); + var optRecursionDeviceRecursionTestLevel4String = await File.ReadAllTextAsync("_data/projectLoadSerializeData/opt.recursionDevice.RecursionTest.Level4.json"); _httpMessageHandlerMock.SetupRequest(HttpMethod.Get, TEST_ENDPOINT + "/config/v1/project") .ReturnsResponse(projectPropertiesString, "application/json"); + _optimizedRecursionUris.Add(TEST_ENDPOINT + "/config/v1/project"); + _httpMessageHandlerMock.SetupRequest(HttpMethod.Get, TEST_ENDPOINT + "/config/v1/project/channels/Channel1?content=serialize") .ReturnsResponse(channel1String, "application/json"); + _optimizedRecursionUris.Add(TEST_ENDPOINT + "/config/v1/project/channels/Channel1?content=serialize"); + _httpMessageHandlerMock.SetupRequest(HttpMethod.Get, TEST_ENDPOINT + "/config/v1/project/channels/Data Type Examples/devices/16 Bit Device?content=serialize") .ReturnsResponse(sixteenBitDeviceString, "application/json"); + _optimizedRecursionUris.Add(TEST_ENDPOINT + "/config/v1/project/channels/Data Type Examples/devices/16 Bit Device?content=serialize"); + _httpMessageHandlerMock.SetupRequest(HttpMethod.Get, TEST_ENDPOINT + "/config/v1/project/channels/Simulation Examples?content=serialize") .ReturnsResponse(simExamplesChannelString, "application/json"); + _optimizedRecursionUris.Add(TEST_ENDPOINT + "/config/v1/project/channels/Simulation Examples?content=serialize"); + + _httpMessageHandlerMock.SetupRequest(HttpMethod.Get, TEST_ENDPOINT + "/config/v1/project/channels/Data Type Examples/devices/8 Bit Device/tag_groups/B Registers?content=serialize") + .ReturnsResponse(dte8BitBRegTagGroupString, "application/json"); + _optimizedRecursionUris.Add(TEST_ENDPOINT + "/config/v1/project/channels/Data Type Examples/devices/8 Bit Device/tag_groups/B Registers?content=serialize"); + + _httpMessageHandlerMock.SetupRequest(HttpMethod.Get, TEST_ENDPOINT + "/config/v1/project/channels/Data Type Examples/devices/8 Bit Device/tag_groups/K Registers?content=serialize") + .ReturnsResponse(dte8BitKRegTagGroupString, "application/json"); + _optimizedRecursionUris.Add(TEST_ENDPOINT + "/config/v1/project/channels/Data Type Examples/devices/8 Bit Device/tag_groups/K Registers?content=serialize"); + + _httpMessageHandlerMock.SetupRequest(HttpMethod.Get, TEST_ENDPOINT + "/config/v1/project/channels/Data Type Examples/devices/8 Bit Device/tag_groups/R Registers?content=serialize") + .ReturnsResponse(dte8BitRRegTagGroupString, "application/json"); + _optimizedRecursionUris.Add(TEST_ENDPOINT + "/config/v1/project/channels/Data Type Examples/devices/8 Bit Device/tag_groups/R Registers?content=serialize"); + + _httpMessageHandlerMock.SetupRequest(HttpMethod.Get, TEST_ENDPOINT + "/config/v1/project/channels/Data Type Examples/devices/8 Bit Device/tag_groups/S Registers?content=serialize") + .ReturnsResponse(dte8BitSRegTagGroupString, "application/json"); + _optimizedRecursionUris.Add(TEST_ENDPOINT + "/config/v1/project/channels/Data Type Examples/devices/8 Bit Device/tag_groups/S Registers?content=serialize"); + + _httpMessageHandlerMock.SetupRequest(HttpMethod.Get, TEST_ENDPOINT + "/config/v1/project/channels/OptRecursionTest/devices/RecursionTestDevice/tag_groups/B Registers?content=serialize") + .ReturnsResponse(optRecursionDeviceBRegTagGroupString, "application/json"); + _optimizedRecursionUris.Add(TEST_ENDPOINT + "/config/v1/project/channels/OptRecursionTest/devices/RecursionTestDevice/tag_groups/B Registers?content=serialize"); + + _httpMessageHandlerMock.SetupRequest(HttpMethod.Get, TEST_ENDPOINT + "/config/v1/project/channels/OptRecursionTest/devices/RecursionTestDevice/tag_groups/K Registers?content=serialize") + .ReturnsResponse(optRecursionDeviceKRegTagGroupString, "application/json"); + _optimizedRecursionUris.Add(TEST_ENDPOINT + "/config/v1/project/channels/OptRecursionTest/devices/RecursionTestDevice/tag_groups/K Registers?content=serialize"); + + _httpMessageHandlerMock.SetupRequest(HttpMethod.Get, TEST_ENDPOINT + "/config/v1/project/channels/OptRecursionTest/devices/RecursionTestDevice/tag_groups/R Registers?content=serialize") + .ReturnsResponse(optRecursionDeviceRRegTagGroupString, "application/json"); + _optimizedRecursionUris.Add(TEST_ENDPOINT + "/config/v1/project/channels/OptRecursionTest/devices/RecursionTestDevice/tag_groups/R Registers?content=serialize"); + + _httpMessageHandlerMock.SetupRequest(HttpMethod.Get, TEST_ENDPOINT + "/config/v1/project/channels/OptRecursionTest/devices/RecursionTestDevice/tag_groups/S Registers?content=serialize") + .ReturnsResponse(optRecursionDeviceSRegTagGroupString, "application/json"); + _optimizedRecursionUris.Add(TEST_ENDPOINT + "/config/v1/project/channels/OptRecursionTest/devices/RecursionTestDevice/tag_groups/S Registers?content=serialize"); + + _httpMessageHandlerMock.SetupRequest(HttpMethod.Get, TEST_ENDPOINT + "/config/v1/project/channels/OptRecursionTest/devices/RecursionTestDevice/tag_groups/RecursionTest/tag_groups/Level1?content=serialize") + .ReturnsResponse(optRecursionDeviceRecursionTestLevel1String, "application/json"); + _optimizedRecursionUris.Add(TEST_ENDPOINT + "/config/v1/project/channels/OptRecursionTest/devices/RecursionTestDevice/tag_groups/RecursionTest/tag_groups/Level1?content=serialize"); + + _httpMessageHandlerMock.SetupRequest(HttpMethod.Get, TEST_ENDPOINT + "/config/v1/project/channels/OptRecursionTest/devices/RecursionTestDevice/tag_groups/RecursionTest/tag_groups/Level2?content=serialize") + .ReturnsResponse(optRecursionDeviceRecursionTestLevel2String, "application/json"); + _optimizedRecursionUris.Add(TEST_ENDPOINT + "/config/v1/project/channels/OptRecursionTest/devices/RecursionTestDevice/tag_groups/RecursionTest/tag_groups/Level2?content=serialize"); + + _httpMessageHandlerMock.SetupRequest(HttpMethod.Get, TEST_ENDPOINT + "/config/v1/project/channels/OptRecursionTest/devices/RecursionTestDevice/tag_groups/RecursionTest/tag_groups/Level3?content=serialize") + .ReturnsResponse(optRecursionDeviceRecursionTestLevel3String, "application/json"); + _optimizedRecursionUris.Add(TEST_ENDPOINT + "/config/v1/project/channels/OptRecursionTest/devices/RecursionTestDevice/tag_groups/RecursionTest/tag_groups/Level3?content=serialize"); + + _httpMessageHandlerMock.SetupRequest(HttpMethod.Get, TEST_ENDPOINT + "/config/v1/project/channels/OptRecursionTest/devices/RecursionTestDevice/tag_groups/RecursionTest/tag_groups/Level4?content=serialize") + .ReturnsResponse(optRecursionDeviceRecursionTestLevel4String, "application/json"); + _optimizedRecursionUris.Add(TEST_ENDPOINT + "/config/v1/project/channels/OptRecursionTest/devices/RecursionTestDevice/tag_groups/RecursionTest/tag_groups/Level4?content=serialize"); } private void ConfigureToServeEndpointsTagGroupsRecursive(string endpoint, IEnumerable tagGroups) { var tagGroupEndpoint = endpoint + "/tag_groups"; + var updatedTagGroups = tagGroups + .Select(tg => + { + var tagGrp = tg; + int staticCount = tg.Name switch + { + "B Registers" => 5, + "K Registers" => 54, + "R Registers" => 54, + "S Registers" => 5, + "RecursionTest" => 220, + "Level1" => 88, + "Level2" => 44, + "Level3" => 44, + "Level4" => 44, + "Level1_1" => 44, + _ => 0 + }; + tagGrp.SetDynamicProperty(Properties.DeviceTagGroup.TotalTagCount, staticCount); + return tagGrp; + }).ToList() ?? new List(); + _httpMessageHandlerMock.SetupRequest(HttpMethod.Get, tagGroupEndpoint) - .ReturnsResponse(JsonSerializer.Serialize(tagGroups), "application/json"); + .ReturnsResponse(JsonSerializer.Serialize(updatedTagGroups), "application/json"); - foreach (var tagGroup in tagGroups) + foreach (var tagGroup in updatedTagGroups) { _httpMessageHandlerMock.SetupRequest(HttpMethod.Get, string.Concat(tagGroupEndpoint, "/", tagGroup.Name, "/tags")) .ReturnsResponse(JsonSerializer.Serialize(tagGroup.Tags), "application/json"); diff --git a/Kepware.Api.Test/_data/projectLoadSerializeData/dte.8bitDevice.Breg.json b/Kepware.Api.Test/_data/projectLoadSerializeData/dte.8bitDevice.Breg.json new file mode 100644 index 0000000..cf3dfee --- /dev/null +++ b/Kepware.Api.Test/_data/projectLoadSerializeData/dte.8bitDevice.Breg.json @@ -0,0 +1,53 @@ +{ + "tag_groups": { + "common.ALLTYPES_NAME": "B Registers", + "common.ALLTYPES_DESCRIPTION": "Boolean registers", + "tags": [ + { + "common.ALLTYPES_NAME": "Boolean1", + "common.ALLTYPES_DESCRIPTION": "Boolean register", + "servermain.TAG_ADDRESS": "B0001", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Boolean2", + "common.ALLTYPES_DESCRIPTION": "Boolean register", + "servermain.TAG_ADDRESS": "B0002", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Boolean3", + "common.ALLTYPES_DESCRIPTION": "Boolean register", + "servermain.TAG_ADDRESS": "B0003", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Boolean4", + "common.ALLTYPES_DESCRIPTION": "Boolean register", + "servermain.TAG_ADDRESS": "B0004", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "BooleanArray", + "common.ALLTYPES_DESCRIPTION": "Array of 4 Boolean Registers", + "servermain.TAG_ADDRESS": "B0010 [4]", + "servermain.TAG_DATA_TYPE": 21, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + } + ] + } +} \ No newline at end of file diff --git a/Kepware.Api.Test/_data/projectLoadSerializeData/dte.8bitDevice.Kreg.json b/Kepware.Api.Test/_data/projectLoadSerializeData/dte.8bitDevice.Kreg.json new file mode 100644 index 0000000..0a35190 --- /dev/null +++ b/Kepware.Api.Test/_data/projectLoadSerializeData/dte.8bitDevice.Kreg.json @@ -0,0 +1,494 @@ +{ + "tag_groups": { + "common.ALLTYPES_NAME": "K Registers", + "common.ALLTYPES_DESCRIPTION": "Constant Registers", + "tags": [ + { + "common.ALLTYPES_NAME": "Boolean1", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "K0100.00", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Boolean2", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "K0100.01", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Boolean3", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "K0100.02", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Boolean4", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "K0100.03", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Byte1", + "common.ALLTYPES_DESCRIPTION": "8-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0200", + "servermain.TAG_DATA_TYPE": 3, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Byte2", + "common.ALLTYPES_DESCRIPTION": "8-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0201", + "servermain.TAG_DATA_TYPE": 3, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Byte3", + "common.ALLTYPES_DESCRIPTION": "8-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0202", + "servermain.TAG_DATA_TYPE": 3, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Byte4", + "common.ALLTYPES_DESCRIPTION": "8-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0203", + "servermain.TAG_DATA_TYPE": 3, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "ByteArray", + "common.ALLTYPES_DESCRIPTION": "8-Bit unsigned integer array", + "servermain.TAG_ADDRESS": "K0220 [4]", + "servermain.TAG_DATA_TYPE": 23, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Char1", + "common.ALLTYPES_DESCRIPTION": "8-Bit signed integer", + "servermain.TAG_ADDRESS": "K0300", + "servermain.TAG_DATA_TYPE": 2, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Char2", + "common.ALLTYPES_DESCRIPTION": "8-Bit signed integer", + "servermain.TAG_ADDRESS": "K0301", + "servermain.TAG_DATA_TYPE": 2, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Char3", + "common.ALLTYPES_DESCRIPTION": "8-Bit signed integer", + "servermain.TAG_ADDRESS": "K0302", + "servermain.TAG_DATA_TYPE": 2, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Char4", + "common.ALLTYPES_DESCRIPTION": "8-Bit signed integer", + "servermain.TAG_ADDRESS": "K0303", + "servermain.TAG_DATA_TYPE": 2, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "CharArray", + "common.ALLTYPES_DESCRIPTION": "8-Bit signed integer array", + "servermain.TAG_ADDRESS": "K0330 [4]", + "servermain.TAG_DATA_TYPE": 22, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double1", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0400", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double2", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0408", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double3", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0416", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double4", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0424", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DoubleArray", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point array", + "servermain.TAG_ADDRESS": "K0440 [4]", + "servermain.TAG_DATA_TYPE": 29, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord1", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0500", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord2", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0504", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord3", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0508", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord4", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0512", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWordArray", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer array", + "servermain.TAG_ADDRESS": "K0550 [4]", + "servermain.TAG_DATA_TYPE": 27, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float1", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0600", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float2", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0604", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float3", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0608", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float4", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0612", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "FloatArray", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point array", + "servermain.TAG_ADDRESS": "K0660 [4]", + "servermain.TAG_DATA_TYPE": 28, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong1", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "K1200", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong2", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "K1208", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong3", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "K1216", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong4", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "K1224", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLongArray", + "common.ALLTYPES_DESCRIPTION": "64-bit signed integer array", + "servermain.TAG_ADDRESS": "K1240 [4]", + "servermain.TAG_DATA_TYPE": 33, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long1", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "K0700", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long2", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "K0704", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long3", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "K0708", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long4", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "K0712", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LongArray", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer array", + "servermain.TAG_ADDRESS": "K0770 [4]", + "servermain.TAG_DATA_TYPE": 26, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord1", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "K1100", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord2", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "K1108", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord3", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "K1116", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord4", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "K1124", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWordArray", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned Integer array", + "servermain.TAG_ADDRESS": "K1140 [4]", + "servermain.TAG_DATA_TYPE": 34, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short1", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "K0800", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short2", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "K0802", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short3", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "K0804", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short4", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "K0806", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "ShortArray", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer array", + "servermain.TAG_ADDRESS": "K0880 [4]", + "servermain.TAG_DATA_TYPE": 24, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word1", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0900", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word2", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0902", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word3", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0904", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word4", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0906", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "WordArray", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer array", + "servermain.TAG_ADDRESS": "K0990 [4]", + "servermain.TAG_DATA_TYPE": 25, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + } + ] + } +} \ No newline at end of file diff --git a/Kepware.Api.Test/_data/projectLoadSerializeData/dte.8bitDevice.Rreg.json b/Kepware.Api.Test/_data/projectLoadSerializeData/dte.8bitDevice.Rreg.json new file mode 100644 index 0000000..f7dbe82 --- /dev/null +++ b/Kepware.Api.Test/_data/projectLoadSerializeData/dte.8bitDevice.Rreg.json @@ -0,0 +1,494 @@ +{ + "tag_groups": { + "common.ALLTYPES_NAME": "R Registers", + "common.ALLTYPES_DESCRIPTION": "Ramping Registers", + "tags": [ + { + "common.ALLTYPES_NAME": "Boolean1", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "R0100.00", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Boolean2", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "R0100.01", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Boolean3", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "R0100.02", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Boolean4", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "R0100.03", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Byte1", + "common.ALLTYPES_DESCRIPTION": "8-Bit unsigned integer", + "servermain.TAG_ADDRESS": "R0200", + "servermain.TAG_DATA_TYPE": 3, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Byte2", + "common.ALLTYPES_DESCRIPTION": "8-Bit unsigned integer", + "servermain.TAG_ADDRESS": "R0201", + "servermain.TAG_DATA_TYPE": 3, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Byte3", + "common.ALLTYPES_DESCRIPTION": "8-Bit unsigned integer", + "servermain.TAG_ADDRESS": "R0202", + "servermain.TAG_DATA_TYPE": 3, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Byte4", + "common.ALLTYPES_DESCRIPTION": "8-Bit unsigned integer", + "servermain.TAG_ADDRESS": "R0203", + "servermain.TAG_DATA_TYPE": 3, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "ByteArray", + "common.ALLTYPES_DESCRIPTION": "8-Bit unsigned integer array", + "servermain.TAG_ADDRESS": "R0220 [4]", + "servermain.TAG_DATA_TYPE": 23, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Char1", + "common.ALLTYPES_DESCRIPTION": "8-Bit signed integer", + "servermain.TAG_ADDRESS": "R0300", + "servermain.TAG_DATA_TYPE": 2, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Char2", + "common.ALLTYPES_DESCRIPTION": "8-Bit signed integer", + "servermain.TAG_ADDRESS": "R0301", + "servermain.TAG_DATA_TYPE": 2, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Char3", + "common.ALLTYPES_DESCRIPTION": "8-Bit signed integer", + "servermain.TAG_ADDRESS": "R0302", + "servermain.TAG_DATA_TYPE": 2, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Char4", + "common.ALLTYPES_DESCRIPTION": "8-Bit signed integer", + "servermain.TAG_ADDRESS": "R0303", + "servermain.TAG_DATA_TYPE": 2, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "CharArray", + "common.ALLTYPES_DESCRIPTION": "8-Bit signed integer array", + "servermain.TAG_ADDRESS": "R0330 [4]", + "servermain.TAG_DATA_TYPE": 22, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double1", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "R0400", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double2", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "R0408", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double3", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "R0416", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double4", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "R0424", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DoubleArray", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point array", + "servermain.TAG_ADDRESS": "R0440 [4]", + "servermain.TAG_DATA_TYPE": 29, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord1", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "R0500", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord2", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "R0504", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord3", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "R0508", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord4", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "R0512", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWordArray", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer array", + "servermain.TAG_ADDRESS": "R0550 [4]", + "servermain.TAG_DATA_TYPE": 27, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float1", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "R0600", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float2", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "R0604", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float3", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "R0608", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float4", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "R0612", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "FloatArray", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point array", + "servermain.TAG_ADDRESS": "R0660 [4]", + "servermain.TAG_DATA_TYPE": 28, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong1", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "R1200", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong2", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "R1208", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong3", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "R1216", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong4", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "R1224", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLongArray", + "common.ALLTYPES_DESCRIPTION": "64-bit signed integer array", + "servermain.TAG_ADDRESS": "R1240 [4]", + "servermain.TAG_DATA_TYPE": 33, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long1", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "R0700", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long2", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "R0704", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long3", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "R0708", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long4", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "R0712", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LongArray", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer array", + "servermain.TAG_ADDRESS": "R0770 [4]", + "servermain.TAG_DATA_TYPE": 26, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord1", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "R1100", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord2", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "R1108", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord3", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "R1116", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord4", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "R1124", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWordArray", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned Integer array", + "servermain.TAG_ADDRESS": "R1140 [4]", + "servermain.TAG_DATA_TYPE": 34, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short1", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "R0800", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short2", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "R0802", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short3", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "R0804", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short4", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "R0806", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "ShortArray", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer array", + "servermain.TAG_ADDRESS": "R0880 [4]", + "servermain.TAG_DATA_TYPE": 24, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word1", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "R0900", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word2", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "R0902", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word3", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "R0904", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word4", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "R0906", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "WordArray", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer array", + "servermain.TAG_ADDRESS": "R0990 [4]", + "servermain.TAG_DATA_TYPE": 25, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + } + ] + } +} \ No newline at end of file diff --git a/Kepware.Api.Test/_data/projectLoadSerializeData/dte.8bitDevice.Sreg.json b/Kepware.Api.Test/_data/projectLoadSerializeData/dte.8bitDevice.Sreg.json new file mode 100644 index 0000000..718fa10 --- /dev/null +++ b/Kepware.Api.Test/_data/projectLoadSerializeData/dte.8bitDevice.Sreg.json @@ -0,0 +1,53 @@ +{ + "tag_groups": { + "common.ALLTYPES_NAME": "S Registers", + "common.ALLTYPES_DESCRIPTION": "String Registers", + "tags": [ + { + "common.ALLTYPES_NAME": "String1", + "common.ALLTYPES_DESCRIPTION": "Null terminated Unicode string", + "servermain.TAG_ADDRESS": "S0001", + "servermain.TAG_DATA_TYPE": 0, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "String2", + "common.ALLTYPES_DESCRIPTION": "Null terminated Unicode string", + "servermain.TAG_ADDRESS": "S0002", + "servermain.TAG_DATA_TYPE": 0, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "String3", + "common.ALLTYPES_DESCRIPTION": "Null terminated Unicode string", + "servermain.TAG_ADDRESS": "S0003", + "servermain.TAG_DATA_TYPE": 0, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "String4", + "common.ALLTYPES_DESCRIPTION": "Null terminated Unicode string", + "servermain.TAG_ADDRESS": "S0004", + "servermain.TAG_DATA_TYPE": 0, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "StringArray[4]", + "common.ALLTYPES_DESCRIPTION": "Null terminated Unicode string array", + "servermain.TAG_ADDRESS": "S0010 [4]", + "servermain.TAG_DATA_TYPE": 20, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + } + ] + } +} \ No newline at end of file diff --git a/Kepware.Api.Test/_data/projectLoadSerializeData/opt.recursionDevice.Breg.json b/Kepware.Api.Test/_data/projectLoadSerializeData/opt.recursionDevice.Breg.json new file mode 100644 index 0000000..cf3dfee --- /dev/null +++ b/Kepware.Api.Test/_data/projectLoadSerializeData/opt.recursionDevice.Breg.json @@ -0,0 +1,53 @@ +{ + "tag_groups": { + "common.ALLTYPES_NAME": "B Registers", + "common.ALLTYPES_DESCRIPTION": "Boolean registers", + "tags": [ + { + "common.ALLTYPES_NAME": "Boolean1", + "common.ALLTYPES_DESCRIPTION": "Boolean register", + "servermain.TAG_ADDRESS": "B0001", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Boolean2", + "common.ALLTYPES_DESCRIPTION": "Boolean register", + "servermain.TAG_ADDRESS": "B0002", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Boolean3", + "common.ALLTYPES_DESCRIPTION": "Boolean register", + "servermain.TAG_ADDRESS": "B0003", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Boolean4", + "common.ALLTYPES_DESCRIPTION": "Boolean register", + "servermain.TAG_ADDRESS": "B0004", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "BooleanArray", + "common.ALLTYPES_DESCRIPTION": "Array of 4 Boolean Registers", + "servermain.TAG_ADDRESS": "B0010 [4]", + "servermain.TAG_DATA_TYPE": 21, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + } + ] + } +} \ No newline at end of file diff --git a/Kepware.Api.Test/_data/projectLoadSerializeData/opt.recursionDevice.Kreg.json b/Kepware.Api.Test/_data/projectLoadSerializeData/opt.recursionDevice.Kreg.json new file mode 100644 index 0000000..939be19 --- /dev/null +++ b/Kepware.Api.Test/_data/projectLoadSerializeData/opt.recursionDevice.Kreg.json @@ -0,0 +1,404 @@ +{ + "tag_groups": { + "common.ALLTYPES_NAME": "K Registers", + "common.ALLTYPES_DESCRIPTION": "Constant Registers", + "tags": [ + { + "common.ALLTYPES_NAME": "Boolean1", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "K0100.00", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Boolean2", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "K0100.01", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Boolean3", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "K0100.02", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Boolean4", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "K0100.03", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double1", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0400", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double2", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0404", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double3", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0408", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double4", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0412", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DoubleArray", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point array", + "servermain.TAG_ADDRESS": "K0440 [4]", + "servermain.TAG_DATA_TYPE": 29, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord1", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0500", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord2", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0502", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord3", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0504", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord4", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0506", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWordArray", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer array", + "servermain.TAG_ADDRESS": "K0550 [4]", + "servermain.TAG_DATA_TYPE": 27, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float1", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0600", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float2", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0602", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float3", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0604", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float4", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0606", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "FloatArray", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point array", + "servermain.TAG_ADDRESS": "K0660 [4]", + "servermain.TAG_DATA_TYPE": 28, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong1", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "K1200", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong2", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "K1204", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong3", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "K1208", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong4", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "K1212", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLongArray", + "common.ALLTYPES_DESCRIPTION": "64-bit signed integer array", + "servermain.TAG_ADDRESS": "K1240 [4]", + "servermain.TAG_DATA_TYPE": 33, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long1", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "K0700", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long2", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "K0702", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long3", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "K0704", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long4", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "K0706", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LongArray", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer array", + "servermain.TAG_ADDRESS": "K0770 [4]", + "servermain.TAG_DATA_TYPE": 26, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord1", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "K1100", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord2", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "K1104", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord3", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "K1108", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord4", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "K1112", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWordArray", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned Integer array", + "servermain.TAG_ADDRESS": "K1140 [4]", + "servermain.TAG_DATA_TYPE": 34, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short1", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "K0800", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short2", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "K0801", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short3", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "K0802", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short4", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "K0803", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "ShortArray", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer array", + "servermain.TAG_ADDRESS": "K0880 [4]", + "servermain.TAG_DATA_TYPE": 24, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word1", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0900", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word2", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0901", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word3", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0902", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word4", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0903", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "WordArray", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer array", + "servermain.TAG_ADDRESS": "K0990 [4]", + "servermain.TAG_DATA_TYPE": 25, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + } + ] + } +} \ No newline at end of file diff --git a/Kepware.Api.Test/_data/projectLoadSerializeData/opt.recursionDevice.RecursionTest.Level1.json b/Kepware.Api.Test/_data/projectLoadSerializeData/opt.recursionDevice.RecursionTest.Level1.json new file mode 100644 index 0000000..e708b5f --- /dev/null +++ b/Kepware.Api.Test/_data/projectLoadSerializeData/opt.recursionDevice.RecursionTest.Level1.json @@ -0,0 +1,806 @@ +{ + "tag_groups": { + "common.ALLTYPES_NAME": "Level1", + "tags": [ + { + "common.ALLTYPES_NAME": "Boolean1", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "K0100.00", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Boolean2", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "K0100.01", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Boolean3", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "K0100.02", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Boolean4", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "K0100.03", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double1", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0400", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double2", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0404", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double3", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0408", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double4", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0412", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DoubleArray", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point array", + "servermain.TAG_ADDRESS": "K0440 [4]", + "servermain.TAG_DATA_TYPE": 29, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord1", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0500", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord2", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0502", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord3", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0504", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord4", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0506", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWordArray", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer array", + "servermain.TAG_ADDRESS": "K0550 [4]", + "servermain.TAG_DATA_TYPE": 27, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float1", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0600", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float2", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0602", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float3", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0604", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float4", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0606", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "FloatArray", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point array", + "servermain.TAG_ADDRESS": "K0660 [4]", + "servermain.TAG_DATA_TYPE": 28, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong1", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "K1200", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong2", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "K1204", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong3", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "K1208", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong4", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "K1212", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLongArray", + "common.ALLTYPES_DESCRIPTION": "64-bit signed integer array", + "servermain.TAG_ADDRESS": "K1240 [4]", + "servermain.TAG_DATA_TYPE": 33, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long1", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "K0700", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long2", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "K0702", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long3", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "K0704", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long4", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "K0706", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LongArray", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer array", + "servermain.TAG_ADDRESS": "K0770 [4]", + "servermain.TAG_DATA_TYPE": 26, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord1", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "K1100", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord2", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "K1104", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord3", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "K1108", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord4", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "K1112", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWordArray", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned Integer array", + "servermain.TAG_ADDRESS": "K1140 [4]", + "servermain.TAG_DATA_TYPE": 34, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short1", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "K0800", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short2", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "K0801", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short3", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "K0802", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short4", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "K0803", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "ShortArray", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer array", + "servermain.TAG_ADDRESS": "K0880 [4]", + "servermain.TAG_DATA_TYPE": 24, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word1", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0900", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word2", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0901", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word3", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0902", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word4", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0903", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "WordArray", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer array", + "servermain.TAG_ADDRESS": "K0990 [4]", + "servermain.TAG_DATA_TYPE": 25, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + } + ], + "tag_groups": [ + { + "common.ALLTYPES_NAME": "Level1_1", + "tags": [ + { + "common.ALLTYPES_NAME": "Boolean1", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "K0100.00", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Boolean2", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "K0100.01", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Boolean3", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "K0100.02", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Boolean4", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "K0100.03", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double1", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0400", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double2", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0404", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double3", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0408", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double4", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0412", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DoubleArray", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point array", + "servermain.TAG_ADDRESS": "K0440 [4]", + "servermain.TAG_DATA_TYPE": 29, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord1", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0500", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord2", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0502", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord3", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0504", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord4", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0506", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWordArray", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer array", + "servermain.TAG_ADDRESS": "K0550 [4]", + "servermain.TAG_DATA_TYPE": 27, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float1", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0600", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float2", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0602", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float3", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0604", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float4", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0606", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "FloatArray", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point array", + "servermain.TAG_ADDRESS": "K0660 [4]", + "servermain.TAG_DATA_TYPE": 28, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong1", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "K1200", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong2", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "K1204", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong3", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "K1208", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong4", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "K1212", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLongArray", + "common.ALLTYPES_DESCRIPTION": "64-bit signed integer array", + "servermain.TAG_ADDRESS": "K1240 [4]", + "servermain.TAG_DATA_TYPE": 33, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long1", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "K0700", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long2", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "K0702", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long3", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "K0704", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long4", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "K0706", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LongArray", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer array", + "servermain.TAG_ADDRESS": "K0770 [4]", + "servermain.TAG_DATA_TYPE": 26, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord1", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "K1100", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord2", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "K1104", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord3", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "K1108", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord4", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "K1112", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWordArray", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned Integer array", + "servermain.TAG_ADDRESS": "K1140 [4]", + "servermain.TAG_DATA_TYPE": 34, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short1", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "K0800", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short2", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "K0801", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short3", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "K0802", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short4", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "K0803", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "ShortArray", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer array", + "servermain.TAG_ADDRESS": "K0880 [4]", + "servermain.TAG_DATA_TYPE": 24, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word1", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0900", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word2", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0901", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word3", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0902", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word4", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0903", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "WordArray", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer array", + "servermain.TAG_ADDRESS": "K0990 [4]", + "servermain.TAG_DATA_TYPE": 25, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + } + ] + } + ] + } +} \ No newline at end of file diff --git a/Kepware.Api.Test/_data/projectLoadSerializeData/opt.recursionDevice.RecursionTest.Level2.json b/Kepware.Api.Test/_data/projectLoadSerializeData/opt.recursionDevice.RecursionTest.Level2.json new file mode 100644 index 0000000..71954e4 --- /dev/null +++ b/Kepware.Api.Test/_data/projectLoadSerializeData/opt.recursionDevice.RecursionTest.Level2.json @@ -0,0 +1,403 @@ +{ + "tag_groups": { + "common.ALLTYPES_NAME": "Level2", + "tags": [ + { + "common.ALLTYPES_NAME": "Boolean1", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "K0100.00", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Boolean2", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "K0100.01", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Boolean3", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "K0100.02", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Boolean4", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "K0100.03", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double1", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0400", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double2", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0404", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double3", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0408", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double4", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0412", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DoubleArray", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point array", + "servermain.TAG_ADDRESS": "K0440 [4]", + "servermain.TAG_DATA_TYPE": 29, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord1", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0500", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord2", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0502", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord3", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0504", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord4", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0506", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWordArray", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer array", + "servermain.TAG_ADDRESS": "K0550 [4]", + "servermain.TAG_DATA_TYPE": 27, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float1", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0600", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float2", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0602", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float3", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0604", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float4", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0606", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "FloatArray", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point array", + "servermain.TAG_ADDRESS": "K0660 [4]", + "servermain.TAG_DATA_TYPE": 28, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong1", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "K1200", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong2", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "K1204", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong3", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "K1208", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong4", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "K1212", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLongArray", + "common.ALLTYPES_DESCRIPTION": "64-bit signed integer array", + "servermain.TAG_ADDRESS": "K1240 [4]", + "servermain.TAG_DATA_TYPE": 33, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long1", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "K0700", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long2", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "K0702", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long3", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "K0704", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long4", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "K0706", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LongArray", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer array", + "servermain.TAG_ADDRESS": "K0770 [4]", + "servermain.TAG_DATA_TYPE": 26, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord1", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "K1100", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord2", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "K1104", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord3", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "K1108", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord4", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "K1112", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWordArray", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned Integer array", + "servermain.TAG_ADDRESS": "K1140 [4]", + "servermain.TAG_DATA_TYPE": 34, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short1", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "K0800", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short2", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "K0801", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short3", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "K0802", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short4", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "K0803", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "ShortArray", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer array", + "servermain.TAG_ADDRESS": "K0880 [4]", + "servermain.TAG_DATA_TYPE": 24, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word1", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0900", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word2", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0901", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word3", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0902", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word4", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0903", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "WordArray", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer array", + "servermain.TAG_ADDRESS": "K0990 [4]", + "servermain.TAG_DATA_TYPE": 25, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + } + ] + } +} \ No newline at end of file diff --git a/Kepware.Api.Test/_data/projectLoadSerializeData/opt.recursionDevice.RecursionTest.Level3.json b/Kepware.Api.Test/_data/projectLoadSerializeData/opt.recursionDevice.RecursionTest.Level3.json new file mode 100644 index 0000000..8b86cb6 --- /dev/null +++ b/Kepware.Api.Test/_data/projectLoadSerializeData/opt.recursionDevice.RecursionTest.Level3.json @@ -0,0 +1,403 @@ +{ + "tag_groups": { + "common.ALLTYPES_NAME": "Level3", + "tags": [ + { + "common.ALLTYPES_NAME": "Boolean1", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "K0100.00", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Boolean2", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "K0100.01", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Boolean3", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "K0100.02", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Boolean4", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "K0100.03", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double1", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0400", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double2", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0404", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double3", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0408", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double4", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0412", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DoubleArray", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point array", + "servermain.TAG_ADDRESS": "K0440 [4]", + "servermain.TAG_DATA_TYPE": 29, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord1", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0500", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord2", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0502", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord3", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0504", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord4", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0506", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWordArray", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer array", + "servermain.TAG_ADDRESS": "K0550 [4]", + "servermain.TAG_DATA_TYPE": 27, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float1", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0600", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float2", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0602", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float3", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0604", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float4", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0606", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "FloatArray", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point array", + "servermain.TAG_ADDRESS": "K0660 [4]", + "servermain.TAG_DATA_TYPE": 28, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong1", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "K1200", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong2", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "K1204", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong3", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "K1208", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong4", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "K1212", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLongArray", + "common.ALLTYPES_DESCRIPTION": "64-bit signed integer array", + "servermain.TAG_ADDRESS": "K1240 [4]", + "servermain.TAG_DATA_TYPE": 33, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long1", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "K0700", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long2", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "K0702", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long3", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "K0704", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long4", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "K0706", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LongArray", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer array", + "servermain.TAG_ADDRESS": "K0770 [4]", + "servermain.TAG_DATA_TYPE": 26, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord1", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "K1100", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord2", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "K1104", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord3", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "K1108", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord4", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "K1112", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWordArray", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned Integer array", + "servermain.TAG_ADDRESS": "K1140 [4]", + "servermain.TAG_DATA_TYPE": 34, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short1", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "K0800", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short2", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "K0801", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short3", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "K0802", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short4", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "K0803", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "ShortArray", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer array", + "servermain.TAG_ADDRESS": "K0880 [4]", + "servermain.TAG_DATA_TYPE": 24, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word1", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0900", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word2", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0901", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word3", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0902", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word4", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0903", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "WordArray", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer array", + "servermain.TAG_ADDRESS": "K0990 [4]", + "servermain.TAG_DATA_TYPE": 25, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + } + ] + } +} \ No newline at end of file diff --git a/Kepware.Api.Test/_data/projectLoadSerializeData/opt.recursionDevice.RecursionTest.Level4.json b/Kepware.Api.Test/_data/projectLoadSerializeData/opt.recursionDevice.RecursionTest.Level4.json new file mode 100644 index 0000000..d7688fe --- /dev/null +++ b/Kepware.Api.Test/_data/projectLoadSerializeData/opt.recursionDevice.RecursionTest.Level4.json @@ -0,0 +1,403 @@ +{ + "tag_groups": { + "common.ALLTYPES_NAME": "Level4", + "tags": [ + { + "common.ALLTYPES_NAME": "Boolean1", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "K0100.00", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Boolean2", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "K0100.01", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Boolean3", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "K0100.02", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Boolean4", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "K0100.03", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double1", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0400", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double2", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0404", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double3", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0408", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double4", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0412", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DoubleArray", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point array", + "servermain.TAG_ADDRESS": "K0440 [4]", + "servermain.TAG_DATA_TYPE": 29, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord1", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0500", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord2", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0502", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord3", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0504", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord4", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0506", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWordArray", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer array", + "servermain.TAG_ADDRESS": "K0550 [4]", + "servermain.TAG_DATA_TYPE": 27, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float1", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0600", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float2", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0602", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float3", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0604", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float4", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0606", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "FloatArray", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point array", + "servermain.TAG_ADDRESS": "K0660 [4]", + "servermain.TAG_DATA_TYPE": 28, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong1", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "K1200", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong2", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "K1204", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong3", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "K1208", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong4", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "K1212", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLongArray", + "common.ALLTYPES_DESCRIPTION": "64-bit signed integer array", + "servermain.TAG_ADDRESS": "K1240 [4]", + "servermain.TAG_DATA_TYPE": 33, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long1", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "K0700", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long2", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "K0702", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long3", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "K0704", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long4", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "K0706", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LongArray", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer array", + "servermain.TAG_ADDRESS": "K0770 [4]", + "servermain.TAG_DATA_TYPE": 26, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord1", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "K1100", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord2", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "K1104", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord3", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "K1108", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord4", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "K1112", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWordArray", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned Integer array", + "servermain.TAG_ADDRESS": "K1140 [4]", + "servermain.TAG_DATA_TYPE": 34, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short1", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "K0800", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short2", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "K0801", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short3", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "K0802", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short4", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "K0803", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "ShortArray", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer array", + "servermain.TAG_ADDRESS": "K0880 [4]", + "servermain.TAG_DATA_TYPE": 24, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word1", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0900", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word2", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0901", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word3", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0902", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word4", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0903", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "WordArray", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer array", + "servermain.TAG_ADDRESS": "K0990 [4]", + "servermain.TAG_DATA_TYPE": 25, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + } + ] + } +} \ No newline at end of file diff --git a/Kepware.Api.Test/_data/projectLoadSerializeData/opt.recursionDevice.Rreg.json b/Kepware.Api.Test/_data/projectLoadSerializeData/opt.recursionDevice.Rreg.json new file mode 100644 index 0000000..f4043f2 --- /dev/null +++ b/Kepware.Api.Test/_data/projectLoadSerializeData/opt.recursionDevice.Rreg.json @@ -0,0 +1,404 @@ +{ + "tag_groups": { + "common.ALLTYPES_NAME": "R Registers", + "common.ALLTYPES_DESCRIPTION": "Ramping Registers", + "tags": [ + { + "common.ALLTYPES_NAME": "Boolean1", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "R0100.00", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Boolean2", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "R0100.01", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Boolean3", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "R0100.02", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Boolean4", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "R0100.03", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double1", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "R0400", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double2", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "R0404", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double3", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "R0408", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double4", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "R0412", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DoubleArray", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point array", + "servermain.TAG_ADDRESS": "R0440 [4]", + "servermain.TAG_DATA_TYPE": 29, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord1", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "R0500", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord2", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "R0502", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord3", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "R0504", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord4", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "R0506", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWordArray", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer array", + "servermain.TAG_ADDRESS": "R0550 [4]", + "servermain.TAG_DATA_TYPE": 27, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float1", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "R0600", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float2", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "R0602", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float3", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "R0604", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float4", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "R0606", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "FloatArray", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point array", + "servermain.TAG_ADDRESS": "R0660 [4]", + "servermain.TAG_DATA_TYPE": 28, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong1", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "R1200", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong2", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "R1204", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong3", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "R1208", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong4", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "R1212", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLongArray", + "common.ALLTYPES_DESCRIPTION": "64-bit signed integer array", + "servermain.TAG_ADDRESS": "R1240 [4]", + "servermain.TAG_DATA_TYPE": 33, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long1", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "R0700", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long2", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "R0702", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long3", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "R0704", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long4", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "R0706", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LongArray", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer array", + "servermain.TAG_ADDRESS": "R0770 [4]", + "servermain.TAG_DATA_TYPE": 26, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord1", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "R1100", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord2", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "R1104", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord3", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "R1108", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord4", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "R1112", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWordArray", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned Integer array", + "servermain.TAG_ADDRESS": "R1140 [4]", + "servermain.TAG_DATA_TYPE": 34, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short1", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "R0800", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short2", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "R0801", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short3", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "R0802", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short4", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "R0803", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "ShortArray", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer array", + "servermain.TAG_ADDRESS": "R0880 [4]", + "servermain.TAG_DATA_TYPE": 24, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word1", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "R0900", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word2", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "R0901", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word3", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "R0902", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word4", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "R0903", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "WordArray", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer array", + "servermain.TAG_ADDRESS": "R0990 [4]", + "servermain.TAG_DATA_TYPE": 25, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + } + ] + } +} \ No newline at end of file diff --git a/Kepware.Api.Test/_data/projectLoadSerializeData/opt.recursionDevice.Sreg.json b/Kepware.Api.Test/_data/projectLoadSerializeData/opt.recursionDevice.Sreg.json new file mode 100644 index 0000000..718fa10 --- /dev/null +++ b/Kepware.Api.Test/_data/projectLoadSerializeData/opt.recursionDevice.Sreg.json @@ -0,0 +1,53 @@ +{ + "tag_groups": { + "common.ALLTYPES_NAME": "S Registers", + "common.ALLTYPES_DESCRIPTION": "String Registers", + "tags": [ + { + "common.ALLTYPES_NAME": "String1", + "common.ALLTYPES_DESCRIPTION": "Null terminated Unicode string", + "servermain.TAG_ADDRESS": "S0001", + "servermain.TAG_DATA_TYPE": 0, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "String2", + "common.ALLTYPES_DESCRIPTION": "Null terminated Unicode string", + "servermain.TAG_ADDRESS": "S0002", + "servermain.TAG_DATA_TYPE": 0, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "String3", + "common.ALLTYPES_DESCRIPTION": "Null terminated Unicode string", + "servermain.TAG_ADDRESS": "S0003", + "servermain.TAG_DATA_TYPE": 0, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "String4", + "common.ALLTYPES_DESCRIPTION": "Null terminated Unicode string", + "servermain.TAG_ADDRESS": "S0004", + "servermain.TAG_DATA_TYPE": 0, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "StringArray[4]", + "common.ALLTYPES_DESCRIPTION": "Null terminated Unicode string array", + "servermain.TAG_ADDRESS": "S0010 [4]", + "servermain.TAG_DATA_TYPE": 20, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + } + ] + } +} \ No newline at end of file diff --git a/Kepware.Api.Test/_data/simdemo_en-us.json b/Kepware.Api.Test/_data/simdemo_en-us.json index e93f6ce..a1069e4 100644 --- a/Kepware.Api.Test/_data/simdemo_en-us.json +++ b/Kepware.Api.Test/_data/simdemo_en-us.json @@ -2,6 +2,8 @@ "project": { "common.ALLTYPES_DESCRIPTION": "Example project utilizing Simulator Driver.", "servermain.PROJECT_TITLE": "Simulation Driver Demo", + "servermain.CREATE_USER": "", + "servermain.CREATE_TIME": 1773769017, "channels": [ { "common.ALLTYPES_NAME": "Channel1", @@ -2095,6 +2097,2954 @@ } ] }, + { + "common.ALLTYPES_NAME": "OptRecursionTest", + "servermain.MULTIPLE_TYPES_DEVICE_DRIVER": "Simulator", + "servermain.CHANNEL_DIAGNOSTICS_CAPTURE": false, + "servermain.CHANNEL_UNIQUE_ID": 2764480803, + "servermain.CHANNEL_WRITE_OPTIMIZATIONS_METHOD": 2, + "servermain.CHANNEL_WRITE_OPTIMIZATIONS_DUTY_CYCLE": 10, + "servermain.CHANNEL_NON_NORMALIZED_FLOATING_POINT_HANDLING": 0, + "simulator.CHANNEL_ITEM_PERSISTENCE": false, + "simulator.CHANNEL_ITEM_PERSISTENCE_DATA_FILE": "C:\\ProgramData\\PTC\\Kepware Server\\V7\\Simulator\\OptRecursionTest.dat", + "devices": [ + { + "common.ALLTYPES_NAME": "RecursionTestDevice", + "servermain.MULTIPLE_TYPES_DEVICE_DRIVER": "Simulator", + "servermain.DEVICE_MODEL": 0, + "servermain.DEVICE_UNIQUE_ID": 2797076252, + "servermain.DEVICE_ID_FORMAT": 1, + "servermain.DEVICE_ID_STRING": "1", + "servermain.DEVICE_ID_HEXADECIMAL": 1, + "servermain.DEVICE_ID_DECIMAL": 1, + "servermain.DEVICE_ID_OCTAL": 1, + "servermain.DEVICE_DATA_COLLECTION": true, + "servermain.DEVICE_SCAN_MODE": 0, + "servermain.DEVICE_SCAN_MODE_RATE_MS": 1000, + "servermain.DEVICE_SCAN_MODE_PROVIDE_INITIAL_UPDATES_FROM_CACHE": false, + "tag_groups": [ + { + "common.ALLTYPES_NAME": "B Registers", + "common.ALLTYPES_DESCRIPTION": "Boolean registers", + "tags": [ + { + "common.ALLTYPES_NAME": "Boolean1", + "common.ALLTYPES_DESCRIPTION": "Boolean register", + "servermain.TAG_ADDRESS": "B0001", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Boolean2", + "common.ALLTYPES_DESCRIPTION": "Boolean register", + "servermain.TAG_ADDRESS": "B0002", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Boolean3", + "common.ALLTYPES_DESCRIPTION": "Boolean register", + "servermain.TAG_ADDRESS": "B0003", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Boolean4", + "common.ALLTYPES_DESCRIPTION": "Boolean register", + "servermain.TAG_ADDRESS": "B0004", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "BooleanArray", + "common.ALLTYPES_DESCRIPTION": "Array of 4 Boolean Registers", + "servermain.TAG_ADDRESS": "B0010 [4]", + "servermain.TAG_DATA_TYPE": 21, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + } + ] + }, + { + "common.ALLTYPES_NAME": "K Registers", + "common.ALLTYPES_DESCRIPTION": "Constant Registers", + "tags": [ + { + "common.ALLTYPES_NAME": "Boolean1", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "K0100.00", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Boolean2", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "K0100.01", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Boolean3", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "K0100.02", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Boolean4", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "K0100.03", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double1", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0400", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double2", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0404", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double3", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0408", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double4", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0412", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DoubleArray", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point array", + "servermain.TAG_ADDRESS": "K0440 [4]", + "servermain.TAG_DATA_TYPE": 29, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord1", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0500", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord2", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0502", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord3", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0504", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord4", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0506", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWordArray", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer array", + "servermain.TAG_ADDRESS": "K0550 [4]", + "servermain.TAG_DATA_TYPE": 27, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float1", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0600", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float2", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0602", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float3", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0604", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float4", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0606", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "FloatArray", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point array", + "servermain.TAG_ADDRESS": "K0660 [4]", + "servermain.TAG_DATA_TYPE": 28, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong1", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "K1200", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong2", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "K1204", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong3", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "K1208", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong4", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "K1212", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLongArray", + "common.ALLTYPES_DESCRIPTION": "64-bit signed integer array", + "servermain.TAG_ADDRESS": "K1240 [4]", + "servermain.TAG_DATA_TYPE": 33, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long1", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "K0700", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long2", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "K0702", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long3", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "K0704", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long4", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "K0706", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LongArray", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer array", + "servermain.TAG_ADDRESS": "K0770 [4]", + "servermain.TAG_DATA_TYPE": 26, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord1", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "K1100", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord2", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "K1104", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord3", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "K1108", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord4", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "K1112", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWordArray", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned Integer array", + "servermain.TAG_ADDRESS": "K1140 [4]", + "servermain.TAG_DATA_TYPE": 34, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short1", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "K0800", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short2", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "K0801", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short3", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "K0802", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short4", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "K0803", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "ShortArray", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer array", + "servermain.TAG_ADDRESS": "K0880 [4]", + "servermain.TAG_DATA_TYPE": 24, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word1", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0900", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word2", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0901", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word3", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0902", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word4", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0903", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "WordArray", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer array", + "servermain.TAG_ADDRESS": "K0990 [4]", + "servermain.TAG_DATA_TYPE": 25, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + } + ] + }, + { + "common.ALLTYPES_NAME": "R Registers", + "common.ALLTYPES_DESCRIPTION": "Ramping Registers", + "tags": [ + { + "common.ALLTYPES_NAME": "Boolean1", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "R0100.00", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Boolean2", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "R0100.01", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Boolean3", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "R0100.02", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Boolean4", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "R0100.03", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double1", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "R0400", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double2", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "R0404", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double3", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "R0408", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double4", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "R0412", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DoubleArray", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point array", + "servermain.TAG_ADDRESS": "R0440 [4]", + "servermain.TAG_DATA_TYPE": 29, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord1", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "R0500", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord2", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "R0502", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord3", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "R0504", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord4", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "R0506", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWordArray", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer array", + "servermain.TAG_ADDRESS": "R0550 [4]", + "servermain.TAG_DATA_TYPE": 27, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float1", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "R0600", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float2", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "R0602", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float3", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "R0604", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float4", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "R0606", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "FloatArray", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point array", + "servermain.TAG_ADDRESS": "R0660 [4]", + "servermain.TAG_DATA_TYPE": 28, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong1", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "R1200", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong2", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "R1204", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong3", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "R1208", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong4", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "R1212", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLongArray", + "common.ALLTYPES_DESCRIPTION": "64-bit signed integer array", + "servermain.TAG_ADDRESS": "R1240 [4]", + "servermain.TAG_DATA_TYPE": 33, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long1", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "R0700", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long2", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "R0702", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long3", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "R0704", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long4", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "R0706", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LongArray", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer array", + "servermain.TAG_ADDRESS": "R0770 [4]", + "servermain.TAG_DATA_TYPE": 26, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord1", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "R1100", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord2", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "R1104", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord3", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "R1108", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord4", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "R1112", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWordArray", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned Integer array", + "servermain.TAG_ADDRESS": "R1140 [4]", + "servermain.TAG_DATA_TYPE": 34, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short1", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "R0800", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short2", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "R0801", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short3", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "R0802", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short4", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "R0803", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "ShortArray", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer array", + "servermain.TAG_ADDRESS": "R0880 [4]", + "servermain.TAG_DATA_TYPE": 24, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word1", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "R0900", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word2", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "R0901", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word3", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "R0902", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word4", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "R0903", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "WordArray", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer array", + "servermain.TAG_ADDRESS": "R0990 [4]", + "servermain.TAG_DATA_TYPE": 25, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + } + ] + }, + { + "common.ALLTYPES_NAME": "RecursionTest", + "tag_groups": [ + { + "common.ALLTYPES_NAME": "Level1", + "tags": [ + { + "common.ALLTYPES_NAME": "Boolean1", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "K0100.00", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Boolean2", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "K0100.01", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Boolean3", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "K0100.02", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Boolean4", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "K0100.03", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double1", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0400", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double2", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0404", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double3", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0408", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double4", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0412", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DoubleArray", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point array", + "servermain.TAG_ADDRESS": "K0440 [4]", + "servermain.TAG_DATA_TYPE": 29, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord1", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0500", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord2", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0502", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord3", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0504", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord4", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0506", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWordArray", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer array", + "servermain.TAG_ADDRESS": "K0550 [4]", + "servermain.TAG_DATA_TYPE": 27, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float1", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0600", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float2", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0602", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float3", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0604", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float4", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0606", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "FloatArray", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point array", + "servermain.TAG_ADDRESS": "K0660 [4]", + "servermain.TAG_DATA_TYPE": 28, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong1", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "K1200", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong2", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "K1204", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong3", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "K1208", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong4", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "K1212", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLongArray", + "common.ALLTYPES_DESCRIPTION": "64-bit signed integer array", + "servermain.TAG_ADDRESS": "K1240 [4]", + "servermain.TAG_DATA_TYPE": 33, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long1", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "K0700", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long2", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "K0702", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long3", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "K0704", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long4", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "K0706", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LongArray", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer array", + "servermain.TAG_ADDRESS": "K0770 [4]", + "servermain.TAG_DATA_TYPE": 26, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord1", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "K1100", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord2", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "K1104", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord3", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "K1108", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord4", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "K1112", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWordArray", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned Integer array", + "servermain.TAG_ADDRESS": "K1140 [4]", + "servermain.TAG_DATA_TYPE": 34, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short1", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "K0800", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short2", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "K0801", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short3", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "K0802", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short4", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "K0803", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "ShortArray", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer array", + "servermain.TAG_ADDRESS": "K0880 [4]", + "servermain.TAG_DATA_TYPE": 24, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word1", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0900", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word2", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0901", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word3", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0902", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word4", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0903", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "WordArray", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer array", + "servermain.TAG_ADDRESS": "K0990 [4]", + "servermain.TAG_DATA_TYPE": 25, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + } + ], + "tag_groups": [ + { + "common.ALLTYPES_NAME": "Level1_1", + "tags": [ + { + "common.ALLTYPES_NAME": "Boolean1", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "K0100.00", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Boolean2", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "K0100.01", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Boolean3", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "K0100.02", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Boolean4", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "K0100.03", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double1", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0400", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double2", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0404", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double3", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0408", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double4", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0412", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DoubleArray", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point array", + "servermain.TAG_ADDRESS": "K0440 [4]", + "servermain.TAG_DATA_TYPE": 29, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord1", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0500", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord2", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0502", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord3", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0504", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord4", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0506", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWordArray", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer array", + "servermain.TAG_ADDRESS": "K0550 [4]", + "servermain.TAG_DATA_TYPE": 27, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float1", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0600", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float2", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0602", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float3", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0604", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float4", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0606", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "FloatArray", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point array", + "servermain.TAG_ADDRESS": "K0660 [4]", + "servermain.TAG_DATA_TYPE": 28, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong1", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "K1200", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong2", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "K1204", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong3", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "K1208", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong4", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "K1212", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLongArray", + "common.ALLTYPES_DESCRIPTION": "64-bit signed integer array", + "servermain.TAG_ADDRESS": "K1240 [4]", + "servermain.TAG_DATA_TYPE": 33, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long1", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "K0700", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long2", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "K0702", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long3", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "K0704", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long4", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "K0706", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LongArray", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer array", + "servermain.TAG_ADDRESS": "K0770 [4]", + "servermain.TAG_DATA_TYPE": 26, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord1", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "K1100", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord2", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "K1104", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord3", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "K1108", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord4", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "K1112", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWordArray", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned Integer array", + "servermain.TAG_ADDRESS": "K1140 [4]", + "servermain.TAG_DATA_TYPE": 34, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short1", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "K0800", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short2", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "K0801", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short3", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "K0802", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short4", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "K0803", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "ShortArray", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer array", + "servermain.TAG_ADDRESS": "K0880 [4]", + "servermain.TAG_DATA_TYPE": 24, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word1", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0900", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word2", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0901", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word3", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0902", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word4", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0903", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "WordArray", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer array", + "servermain.TAG_ADDRESS": "K0990 [4]", + "servermain.TAG_DATA_TYPE": 25, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + } + ] + } + ] + }, + { + "common.ALLTYPES_NAME": "Level2", + "tags": [ + { + "common.ALLTYPES_NAME": "Boolean1", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "K0100.00", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Boolean2", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "K0100.01", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Boolean3", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "K0100.02", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Boolean4", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "K0100.03", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double1", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0400", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double2", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0404", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double3", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0408", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double4", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0412", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DoubleArray", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point array", + "servermain.TAG_ADDRESS": "K0440 [4]", + "servermain.TAG_DATA_TYPE": 29, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord1", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0500", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord2", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0502", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord3", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0504", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord4", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0506", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWordArray", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer array", + "servermain.TAG_ADDRESS": "K0550 [4]", + "servermain.TAG_DATA_TYPE": 27, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float1", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0600", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float2", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0602", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float3", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0604", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float4", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0606", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "FloatArray", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point array", + "servermain.TAG_ADDRESS": "K0660 [4]", + "servermain.TAG_DATA_TYPE": 28, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong1", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "K1200", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong2", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "K1204", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong3", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "K1208", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong4", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "K1212", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLongArray", + "common.ALLTYPES_DESCRIPTION": "64-bit signed integer array", + "servermain.TAG_ADDRESS": "K1240 [4]", + "servermain.TAG_DATA_TYPE": 33, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long1", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "K0700", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long2", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "K0702", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long3", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "K0704", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long4", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "K0706", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LongArray", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer array", + "servermain.TAG_ADDRESS": "K0770 [4]", + "servermain.TAG_DATA_TYPE": 26, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord1", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "K1100", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord2", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "K1104", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord3", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "K1108", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord4", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "K1112", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWordArray", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned Integer array", + "servermain.TAG_ADDRESS": "K1140 [4]", + "servermain.TAG_DATA_TYPE": 34, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short1", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "K0800", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short2", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "K0801", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short3", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "K0802", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short4", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "K0803", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "ShortArray", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer array", + "servermain.TAG_ADDRESS": "K0880 [4]", + "servermain.TAG_DATA_TYPE": 24, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word1", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0900", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word2", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0901", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word3", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0902", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word4", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0903", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "WordArray", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer array", + "servermain.TAG_ADDRESS": "K0990 [4]", + "servermain.TAG_DATA_TYPE": 25, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + } + ] + }, + { + "common.ALLTYPES_NAME": "Level3", + "tags": [ + { + "common.ALLTYPES_NAME": "Boolean1", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "K0100.00", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Boolean2", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "K0100.01", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Boolean3", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "K0100.02", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Boolean4", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "K0100.03", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double1", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0400", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double2", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0404", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double3", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0408", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double4", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0412", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DoubleArray", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point array", + "servermain.TAG_ADDRESS": "K0440 [4]", + "servermain.TAG_DATA_TYPE": 29, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord1", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0500", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord2", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0502", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord3", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0504", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord4", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0506", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWordArray", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer array", + "servermain.TAG_ADDRESS": "K0550 [4]", + "servermain.TAG_DATA_TYPE": 27, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float1", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0600", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float2", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0602", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float3", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0604", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float4", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0606", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "FloatArray", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point array", + "servermain.TAG_ADDRESS": "K0660 [4]", + "servermain.TAG_DATA_TYPE": 28, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong1", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "K1200", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong2", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "K1204", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong3", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "K1208", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong4", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "K1212", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLongArray", + "common.ALLTYPES_DESCRIPTION": "64-bit signed integer array", + "servermain.TAG_ADDRESS": "K1240 [4]", + "servermain.TAG_DATA_TYPE": 33, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long1", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "K0700", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long2", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "K0702", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long3", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "K0704", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long4", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "K0706", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LongArray", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer array", + "servermain.TAG_ADDRESS": "K0770 [4]", + "servermain.TAG_DATA_TYPE": 26, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord1", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "K1100", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord2", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "K1104", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord3", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "K1108", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord4", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "K1112", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWordArray", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned Integer array", + "servermain.TAG_ADDRESS": "K1140 [4]", + "servermain.TAG_DATA_TYPE": 34, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short1", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "K0800", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short2", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "K0801", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short3", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "K0802", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short4", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "K0803", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "ShortArray", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer array", + "servermain.TAG_ADDRESS": "K0880 [4]", + "servermain.TAG_DATA_TYPE": 24, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word1", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0900", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word2", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0901", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word3", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0902", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word4", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0903", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "WordArray", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer array", + "servermain.TAG_ADDRESS": "K0990 [4]", + "servermain.TAG_DATA_TYPE": 25, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + } + ] + }, + { + "common.ALLTYPES_NAME": "Level4", + "tags": [ + { + "common.ALLTYPES_NAME": "Boolean1", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "K0100.00", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Boolean2", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "K0100.01", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Boolean3", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "K0100.02", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Boolean4", + "common.ALLTYPES_DESCRIPTION": "1-Bit Boolean", + "servermain.TAG_ADDRESS": "K0100.03", + "servermain.TAG_DATA_TYPE": 1, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double1", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0400", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double2", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0404", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double3", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0408", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Double4", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0412", + "servermain.TAG_DATA_TYPE": 9, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DoubleArray", + "common.ALLTYPES_DESCRIPTION": "64-Bit IEEE floating point array", + "servermain.TAG_ADDRESS": "K0440 [4]", + "servermain.TAG_DATA_TYPE": 29, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord1", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0500", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord2", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0502", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord3", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0504", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWord4", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0506", + "servermain.TAG_DATA_TYPE": 7, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "DWordArray", + "common.ALLTYPES_DESCRIPTION": "32-Bit unsigned integer array", + "servermain.TAG_ADDRESS": "K0550 [4]", + "servermain.TAG_DATA_TYPE": 27, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float1", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0600", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float2", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0602", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float3", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0604", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Float4", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point", + "servermain.TAG_ADDRESS": "K0606", + "servermain.TAG_DATA_TYPE": 8, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "FloatArray", + "common.ALLTYPES_DESCRIPTION": "32-Bit IEEE floating point array", + "servermain.TAG_ADDRESS": "K0660 [4]", + "servermain.TAG_DATA_TYPE": 28, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong1", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "K1200", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong2", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "K1204", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong3", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "K1208", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLong4", + "common.ALLTYPES_DESCRIPTION": "64 bit signed integer", + "servermain.TAG_ADDRESS": "K1212", + "servermain.TAG_DATA_TYPE": 13, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LLongArray", + "common.ALLTYPES_DESCRIPTION": "64-bit signed integer array", + "servermain.TAG_ADDRESS": "K1240 [4]", + "servermain.TAG_DATA_TYPE": 33, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long1", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "K0700", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long2", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "K0702", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long3", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "K0704", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Long4", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer", + "servermain.TAG_ADDRESS": "K0706", + "servermain.TAG_DATA_TYPE": 6, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "LongArray", + "common.ALLTYPES_DESCRIPTION": "32-Bit signed integer array", + "servermain.TAG_ADDRESS": "K0770 [4]", + "servermain.TAG_DATA_TYPE": 26, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord1", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "K1100", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord2", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "K1104", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord3", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "K1108", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWord4", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned integer", + "servermain.TAG_ADDRESS": "K1112", + "servermain.TAG_DATA_TYPE": 14, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "QWordArray", + "common.ALLTYPES_DESCRIPTION": "64-bit unsigned Integer array", + "servermain.TAG_ADDRESS": "K1140 [4]", + "servermain.TAG_DATA_TYPE": 34, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short1", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "K0800", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short2", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "K0801", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short3", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "K0802", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Short4", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer", + "servermain.TAG_ADDRESS": "K0803", + "servermain.TAG_DATA_TYPE": 4, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "ShortArray", + "common.ALLTYPES_DESCRIPTION": "16-Bit signed integer array", + "servermain.TAG_ADDRESS": "K0880 [4]", + "servermain.TAG_DATA_TYPE": 24, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word1", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0900", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word2", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0901", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word3", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0902", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "Word4", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer", + "servermain.TAG_ADDRESS": "K0903", + "servermain.TAG_DATA_TYPE": 5, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "WordArray", + "common.ALLTYPES_DESCRIPTION": "16-Bit unsigned integer array", + "servermain.TAG_ADDRESS": "K0990 [4]", + "servermain.TAG_DATA_TYPE": 25, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + } + ] + } + ] + }, + { + "common.ALLTYPES_NAME": "S Registers", + "common.ALLTYPES_DESCRIPTION": "String Registers", + "tags": [ + { + "common.ALLTYPES_NAME": "String1", + "common.ALLTYPES_DESCRIPTION": "Null terminated Unicode string", + "servermain.TAG_ADDRESS": "S0001", + "servermain.TAG_DATA_TYPE": 0, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "String2", + "common.ALLTYPES_DESCRIPTION": "Null terminated Unicode string", + "servermain.TAG_ADDRESS": "S0002", + "servermain.TAG_DATA_TYPE": 0, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "String3", + "common.ALLTYPES_DESCRIPTION": "Null terminated Unicode string", + "servermain.TAG_ADDRESS": "S0003", + "servermain.TAG_DATA_TYPE": 0, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "String4", + "common.ALLTYPES_DESCRIPTION": "Null terminated Unicode string", + "servermain.TAG_ADDRESS": "S0004", + "servermain.TAG_DATA_TYPE": 0, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + }, + { + "common.ALLTYPES_NAME": "StringArray[4]", + "common.ALLTYPES_DESCRIPTION": "Null terminated Unicode string array", + "servermain.TAG_ADDRESS": "S0010 [4]", + "servermain.TAG_DATA_TYPE": 20, + "servermain.TAG_READ_WRITE_ACCESS": 1, + "servermain.TAG_SCAN_RATE_MILLISECONDS": 100, + "servermain.TAG_SCALING_TYPE": 0 + } + ] + } + ] + } + ] + }, { "common.ALLTYPES_NAME": "Simulation Examples", "common.ALLTYPES_DESCRIPTION": "Example Simulator Channel", @@ -2361,6 +5311,21 @@ "aeserverinterface.MIN_SUBSCRIPTION_BUFFER_TIME_MS": 1000, "aeserverinterface.MIN_KEEP_ALIVE_TIME_MS": 1000 }, + { + "common.ALLTYPES_NAME": "ddeserver", + "ddeserver.ENABLE": false, + "ddeserver.SERVICE_NAME": "ptcdde", + "ddeserver.ADVANCED_DDE": true, + "ddeserver.XLTABLE": true, + "ddeserver.CF_TEXT": true, + "ddeserver.CLIENT_UPDATE_INTERVAL_MS": 100, + "ddeserver.REQUEST_TIMEOUT_SEC": 15 + }, + { + "common.ALLTYPES_NAME": "hdaserver", + "hdaserver.ENABLE": false, + "hdaserver.ENABLE_DIAGNOSTICS": false + }, { "common.ALLTYPES_NAME": "opcdaserver", "opcdaserver.PROJECT_OPC_DA_1_ENABLED": true, @@ -2394,13 +5359,13 @@ "thingworxinterface.TRUST_ALL_CERTIFICATES": false, "thingworxinterface.DISABLE_ENCRYPTION": false, "thingworxinterface.MAX_THING_COUNT": 500, - "thingworxinterface.THING_NAME": "KEPServerEX", + "thingworxinterface.THING_NAME": "Kepware Server", "thingworxinterface.PUBLISH_FLOOR_MSEC": 1000, "thingworxinterface.LOGGING_ENABLED": false, "thingworxinterface.LOG_LEVEL": 3, "thingworxinterface.VERBOSE": false, "thingworxinterface.STORE_AND_FORWARD_ENABLED": false, - "thingworxinterface.STORAGE_PATH": "C:\\ProgramData\\Kepware\\KEPServerEX\\V6\\", + "thingworxinterface.STORAGE_PATH": "C:\\ProgramData\\PTC\\Kepware Server\\V7", "thingworxinterface.DATASTORE_MAXSIZE": 2048, "thingworxinterface.FORWARD_MODE": 0, "thingworxinterface.DATASTORE_ID": 421728385, @@ -2426,6 +5391,59 @@ "uaserverinterface.PROJECT_OPC_UA_MAX_DATA_QUEUE_SIZE": 2, "uaserverinterface.PROJECT_OPC_UA_MAX_RETRANSMIT_QUEUE_SIZE": 10, "uaserverinterface.PROJECT_OPC_UA_MAX_NOTIFICATION_PER_PUBLISH": 65536 + }, + { + "common.ALLTYPES_NAME": "wwtoolkitinterface", + "wwtoolkitinterface.ENABLED": false, + "wwtoolkitinterface.SERVICE_NAME": "server_runtime", + "wwtoolkitinterface.CLIENT_UPDATE_INTERVAL_MS": 100 + } + ], + "_ua_gateway": [ + { + "common.ALLTYPES_NAME": "_UA_Gateway", + "common.ALLTYPES_DESCRIPTION": "The parent interface of the OPC UA Gateway. Configuring this interface and managing the Instance Certificate view will allow communication between the UA Gateway service, its children interfaces, and the rest of Kepware+.", + "ua_client_interfaces": [ + { + "common.ALLTYPES_NAME": "Client Interface", + "common.ALLTYPES_DESCRIPTION": "The client interface of the OPC UA Gateway. Configuring this interface and adding client connections will allow communication between the OPC UA Gateway and other OPC UA servers.", + "client_instance_certificates": [ + { + "common.ALLTYPES_NAME": "Client Instance Certificate", + "common.ALLTYPES_DESCRIPTION": "The Client Interface Instance Certificate.", + "ua_gateway.UA_DISTINGUISHED_NAMES": "CN = PTC OPC UA Gateway Client Interface\n" + } + ] + } + ], + "ua_server_interfaces": [ + { + "common.ALLTYPES_NAME": "Server Interface", + "common.ALLTYPES_DESCRIPTION": "The server interface of the OPC UA Gateway. Configuring this interface and adding server endpoints will allow other OPC UA clients to connect to the OPC UA Gateway.", + "ua_gateway.UA_SERVER_INTERFACE_USER_IDENTITY_POLICY_ANONYMOUS": false, + "ua_gateway.UA_SERVER_INTERFACE_USER_IDENTITY_POLICY_USERNAME_PASSWORD": true, + "ua_gateway.UA_SERVER_INTERFACE_USER_IDENTITY_POLICY_X509": true, + "ua_gateway.UA_SERVER_INTERFACE_SECURITY_POLICIES_NONE": false, + "ua_gateway.UA_SERVER_INTERFACE_SECURITY_POLICIES_BASIC256SHA256": 2, + "ua_gateway.UA_SERVER_INTERFACE_SECURITY_POLICIES_AES128_SHA256_RSAOAEP": 0, + "ua_gateway.UA_SERVER_INTERFACE_SECURITY_POLICIES_AES256_SHA256_RSAPSS": 0, + "ua_gateway.LDS_REGISTRATION_ENABLED": false, + "ua_gateway.LDS_MAX_REGISTRATION_INTERVAL": 30000, + "ua_gateway.UA_SERVER_INTERFACE_MAX_SUBSCRIPTION_LIFETIME": 3600000, + "ua_gateway.UA_SERVER_INTERFACE_MIN_SUBSCRIPTION_LIFETIME": 10000, + "ua_gateway.UA_SERVER_INTERFACE_MAX_SESSION_TIMEOUT": 3600000, + "ua_gateway.UA_SERVER_INTERFACE_MIN_SESSION_TIMEOUT": 10000, + "ua_gateway.UA_SERVER_INTERFACE_MAX_NOTIFICATIONS_PER_PUBLISH": 1000, + "ua_gateway.UA_SERVER_INTERFACE_MAX_NOTIFICATIONS_QUEUE_SIZE": 100, + "server_instance_certificates": [ + { + "common.ALLTYPES_NAME": "Server Instance Certificate", + "common.ALLTYPES_DESCRIPTION": "The Server Interface Instance Certificate.", + "ua_gateway.UA_DISTINGUISHED_NAMES": "CN = PTC OPC UA Gateway Server Interface\n" + } + ] + } + ] } ] } diff --git a/Kepware.Api/ClientHandler/ProjectApiHandler.cs b/Kepware.Api/ClientHandler/ProjectApiHandler.cs index c0d41c7..32b9d34 100644 --- a/Kepware.Api/ClientHandler/ProjectApiHandler.cs +++ b/Kepware.Api/ClientHandler/ProjectApiHandler.cs @@ -270,8 +270,9 @@ public async Task LoadProjectAsync(bool blnLoadFullProject = false, int if (productInfo?.SupportsJsonProjectLoadService == true) { - // Set by as the threshold to use content=serialize based loading or full recursive loading. Default - // set by class. + // Check to see if projectLoadTagLimit parameter is set on call. If not or an invalid value, use value ] + // set by as the threshold to use content=serialize + // based loading or full recursive loading. if (projectLoadTagLimit <= 0) projectLoadTagLimit = m_kepwareApiClient.ClientOptions.ProjectLoadTagLimit; @@ -373,6 +374,10 @@ private async Task LoadProjectOptimizedRecurisveAsync(Project project, project.Channels = await m_kepwareApiClient.GenericConfig.LoadCollectionAsync(cancellationToken: cancellationToken); if (project.Channels != null) { + var query = new[] + { + new KeyValuePair("content", "serialize") + }; int totalChannelCount = project.Channels.Count; int loadedChannelCount = 0; @@ -386,10 +391,6 @@ private async Task LoadProjectOptimizedRecurisveAsync(Project project, { if (channel.GetDynamicProperty(Properties.Channel.StaticTagCount) < tagLimit) { - var query = new[] - { - new KeyValuePair("content", "serialize") - }; var loadedChannel = await m_kepwareApiClient.GenericConfig.LoadEntityAsync(channel.Name, query, cancellationToken: cancellationToken).ConfigureAwait(false); if (loadedChannel != null) { @@ -417,10 +418,6 @@ private async Task LoadProjectOptimizedRecurisveAsync(Project project, { if (device.GetDynamicProperty(Properties.Device.StaticTagCount) < tagLimit) { - var query = new[] - { - new KeyValuePair("content", "serialize") - }; var loadedDevice = await m_kepwareApiClient.GenericConfig.LoadEntityAsync(device.Name, channel, query, cancellationToken: cancellationToken).ConfigureAwait(false); if (loadedDevice != null) { @@ -440,7 +437,7 @@ private async Task LoadProjectOptimizedRecurisveAsync(Project project, if (device.TagGroups != null) { - await LoadTagGroupsRecursiveAsync(m_kepwareApiClient, device.TagGroups, cancellationToken: cancellationToken).ConfigureAwait(false); + await LoadTagGroupsRecursiveAsync(m_kepwareApiClient, device.TagGroups, optimizedRecursion: true, tagLimit: tagLimit, cancellationToken: cancellationToken).ConfigureAwait(false); } } })); @@ -596,20 +593,48 @@ private static void SetOwnerRecursive(IEnumerable tagGroups, Nam /// /// The API client. /// The tag groups to load. + /// A flag indicating whether to use optimized recursion with content=serialize or basic recursion. + /// This is only applicable for projects loaded with the full project load option and when the JsonProjectLoad service is + /// supported by the server. + /// Tag Limit if overridden by method call. /// The cancellation token. /// A task that represents the asynchronous operation. - internal static async Task LoadTagGroupsRecursiveAsync(KepwareApiClient apiClient, IEnumerable tagGroups, CancellationToken cancellationToken = default) + internal static async Task LoadTagGroupsRecursiveAsync(KepwareApiClient apiClient, IEnumerable tagGroups, bool optimizedRecursion = false, int tagLimit = 0, CancellationToken cancellationToken = default) { + // Falls back to the value set by if tagLimit parameter is not set or an invalid value is provided. + if (tagLimit <= 0) + tagLimit = apiClient.ClientOptions.ProjectLoadTagLimit; foreach (var tagGroup in tagGroups) { // Load the Tag Groups and Tags of the current Tag Group - tagGroup.TagGroups = await apiClient.GenericConfig.LoadCollectionAsync(tagGroup, cancellationToken: cancellationToken).ConfigureAwait(false); - tagGroup.Tags = await apiClient.GenericConfig.LoadCollectionAsync(tagGroup, cancellationToken: cancellationToken).ConfigureAwait(false); - - // Recursively load the Tag Groups and Tags of the child Tag Groups - if (tagGroup.TagGroups != null && tagGroup.TagGroups.Count > 0) + if (optimizedRecursion && tagGroup.TotalTagCount < tagLimit) { - await LoadTagGroupsRecursiveAsync(apiClient, tagGroup.TagGroups, cancellationToken).ConfigureAwait(false); + var query = new[] + { + new KeyValuePair("content", "serialize") + }; + var loadedTagGroup = await apiClient.GenericConfig.LoadEntityAsync(tagGroup.Name, tagGroup.Owner!, query, cancellationToken: cancellationToken).ConfigureAwait(false); + if (loadedTagGroup != null) + { + tagGroup.Tags = loadedTagGroup.Tags; + tagGroup.TagGroups = loadedTagGroup.TagGroups; + } + else + { + // Failed to load tag group, log warning and end without loading child tag groups. + apiClient.Logger.LogWarning("Failed to load {TagGroupName} in {OwnerName}", tagGroup.Name, tagGroup.Owner?.Name); + continue; + } + } + else + { + tagGroup.TagGroups = await apiClient.GenericConfig.LoadCollectionAsync(tagGroup, cancellationToken: cancellationToken).ConfigureAwait(false); + tagGroup.Tags = await apiClient.GenericConfig.LoadCollectionAsync(tagGroup, cancellationToken: cancellationToken).ConfigureAwait(false); + // Recursively load the Tag Groups and Tags of the child Tag Groups + if (tagGroup.TagGroups != null && tagGroup.TagGroups.Count > 0) + { + await LoadTagGroupsRecursiveAsync(apiClient, tagGroup.TagGroups, optimizedRecursion, tagLimit, cancellationToken).ConfigureAwait(false); + } } } } diff --git a/Kepware.Api/KepwareApiClient.cs b/Kepware.Api/KepwareApiClient.cs index fe59e48..f37018a 100644 --- a/Kepware.Api/KepwareApiClient.cs +++ b/Kepware.Api/KepwareApiClient.cs @@ -43,6 +43,14 @@ public partial class KepwareApiClient : IKepwareDefaultValueProvider private bool? m_hasValidCredentials = null; private ProductInfo? m_productInfo = null; + /// + /// Gets the logger instance used for logging operations. + /// + /// This property provides access to the logger, which can be used to log messages at + /// various levels. Ensure that the logger is properly initialized before use. + public ILogger Logger => m_logger; + + /// /// Gets the name of the client instance. /// diff --git a/Kepware.Api/Model/Project/DeviceTagGroup.Properties.cs b/Kepware.Api/Model/Project/DeviceTagGroup.Properties.cs new file mode 100644 index 0000000..0181cb9 --- /dev/null +++ b/Kepware.Api/Model/Project/DeviceTagGroup.Properties.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Kepware.Api.Model +{ + public partial class Properties + { + public static class DeviceTagGroup + { + + /// + /// Represents the constant name used to identify the count of tags in the local tag group. + /// + public const string LocalTagCount = Properties.NonSerialized.TagGrpTagCount; + + /// + /// Represents the constant name used to identify the total count of tags in the tag group, including all child tag groups. + /// + public const string TotalTagCount = Properties.NonSerialized.TagGrpTotalTagCount; + } + } +} diff --git a/Kepware.Api/Model/Project/DeviceTagGroup.cs b/Kepware.Api/Model/Project/DeviceTagGroup.cs index a062935..e51eadc 100644 --- a/Kepware.Api/Model/Project/DeviceTagGroup.cs +++ b/Kepware.Api/Model/Project/DeviceTagGroup.cs @@ -48,12 +48,32 @@ public DeviceTagGroup(string name, DeviceTagGroup owner) public DeviceTagGroupCollection? TagGroups { get; set; } /// - /// Get a flag indicating if the tag group is autogenerated + /// Get a flag indicating if the tag group was autogenerated /// [YamlIgnore] [JsonIgnore] public bool IsAutogenerated => GetDynamicProperty(Properties.NonSerialized.TagGroupAutogenerated); + /// + /// Gets the number of tags that are defined locally within this tag group. + /// + /// Use this property to determine how many tags are associated with the current + /// instance, excluding tags in children tag groups. NOTE: Provides the count from the Kepware instance + /// and only updates when loading the tag group configuration. + [YamlIgnore] + [JsonIgnore] + public int LocalTagCount => GetDynamicProperty(Properties.DeviceTagGroup.LocalTagCount); + + /// + /// Gets the total number of tags included in the tag group and all children tag groups. + /// + /// Use this property to determine how many tags are associated with the current + /// instance, including tags in children tag groups. NOTE: Provides the count from the Kepware instance + /// and only updates when loading the tag group configuration. + [YamlIgnore] + [JsonIgnore] + public int TotalTagCount => GetDynamicProperty(Properties.DeviceTagGroup.TotalTagCount); + /// /// Recursively cleans up the tag group and all its children /// From 4579a071f777c32cba2dde1a65be53cae5204ae7 Mon Sep 17 00:00:00 2001 From: Ray Labbe Date: Tue, 17 Mar 2026 18:40:11 -0400 Subject: [PATCH 13/16] refactor: various property and comment cleanup --- Kepware.Api/Model/Project/Channel.Properties.cs | 2 +- Kepware.Api/Model/Project/Device.Properties.cs | 6 +++--- Kepware.Api/Model/Project/Project.Properties.cs | 3 +-- Kepware.Api/Model/Properties.cs | 6 +++--- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/Kepware.Api/Model/Project/Channel.Properties.cs b/Kepware.Api/Model/Project/Channel.Properties.cs index 2b0e131..6f1a805 100644 --- a/Kepware.Api/Model/Project/Channel.Properties.cs +++ b/Kepware.Api/Model/Project/Channel.Properties.cs @@ -48,7 +48,7 @@ public static class Channel /// /// Value of the static tag count for the channel. /// - public const string StaticTagCount = "servermain.CHANNEL_STATIC_TAG_COUNT"; + public const string StaticTagCount = Properties.NonSerialized.ChannelStaticTagCount; } } diff --git a/Kepware.Api/Model/Project/Device.Properties.cs b/Kepware.Api/Model/Project/Device.Properties.cs index 006c64f..e4de536 100644 --- a/Kepware.Api/Model/Project/Device.Properties.cs +++ b/Kepware.Api/Model/Project/Device.Properties.cs @@ -11,14 +11,14 @@ public partial class Properties public static class Device { /// - /// The driver used by this channel. + /// The driver used by this device. /// public const string DeviceDriver = "servermain.MULTIPLE_TYPES_DEVICE_DRIVER"; /// - /// Value of the static tag count for the channel. + /// Constant value for the key of the static tag count for the device. /// - public const string StaticTagCount = "servermain.DEVICE_STATIC_TAG_COUNT"; + public const string StaticTagCount = Properties.NonSerialized.DeviceStaticTagCount; } } diff --git a/Kepware.Api/Model/Project/Project.Properties.cs b/Kepware.Api/Model/Project/Project.Properties.cs index 207fba2..af0fb24 100644 --- a/Kepware.Api/Model/Project/Project.Properties.cs +++ b/Kepware.Api/Model/Project/Project.Properties.cs @@ -20,8 +20,7 @@ public static class ProjectSettings /// /// Count of tags identified in the project. /// - // TODO: Does this need to be moved to non-seralized properties? - public const string TagsDefined = "servermain.PROJECT_TAGS_DEFINED"; + public const string TagsDefined = Properties.NonSerialized.ProjectTagsDefined; #endregion diff --git a/Kepware.Api/Model/Properties.cs b/Kepware.Api/Model/Properties.cs index c77aeb2..4aacaa4 100644 --- a/Kepware.Api/Model/Properties.cs +++ b/Kepware.Api/Model/Properties.cs @@ -71,13 +71,13 @@ public static class NonSerialized /// public const string TagGrpTotalTagCount = "servermain.TAGGROUP_TOTAL_TAG_COUNT"; /// - /// The local tag count in a tag group property key. + /// The local tag count in a tag group property key. Used for tag groups within devices. /// public const string TagGrpTagCount = "servermain.TAGGROUP_LOCAL_TAG_COUNT"; /// /// The static tag count in a channel property key. /// - public const string ChannelTagCount = "servermain.CHANNEL_STATIC_TAG_COUNT"; + public const string ChannelStaticTagCount = "servermain.CHANNEL_STATIC_TAG_COUNT"; /// /// The autogenerated tag group property key. /// @@ -104,7 +104,7 @@ public static class NonSerialized ChannelAssignment, TagGrpTotalTagCount, TagGrpTagCount, - ChannelTagCount, + ChannelStaticTagCount, TagGroupAutogenerated, TagAutogenerated , DeviceStaticTagCount, From 2c288723d5c2ce509e63c60c07dcabfb34ad823d Mon Sep 17 00:00:00 2001 From: Ray Labbe Date: Thu, 19 Mar 2026 20:53:23 -0400 Subject: [PATCH 14/16] doc: updated readme --- Kepware.Api/README.md | 39 ++++++++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/Kepware.Api/README.md b/Kepware.Api/README.md index 40625b1..b793350 100644 --- a/Kepware.Api/README.md +++ b/Kepware.Api/README.md @@ -19,15 +19,17 @@ This package is designed to work with all versions of Kepware that support the C | **Connectivity**
*(Channel, Devices, Tags, Tag Groups)* | Y | Y | | **Administration**
*(User Groups, Users, UA Endpoints, Local License Server)* | Y[^1] | Y | | **Product Info and Health Status** | Y[^4] | Y | -| **Export Project** | Y[^2] | Y | +| **Export Project** | Y | Y | | **Import Project (via JsonProjectLoad Service)** | N[^2] | N | | **Import Project (via CompareAndApply)[^3]** | Y | Y | [^1]: UA Endpoints and Local License Server supported for Kepware Edge only -[^2]: JsonProjectLoad was added to Kepware Server v6.17 and later builds, the SDK detects the server version and uses the appropriate service or loads the project by multiple requests if using KepwareApiClient.LoadProject. -[^3]: CompareAndApply is handled by the SDK, it compares the source project with the server project and applies the changes. The JsonProjectLoad service is a direct call to the server to load a project. +[^2]: JsonProjectLoad was added to Kepware Server v6.17 and later builds. +[^3]: [CompareAndApply](/Kepware.Api/ClientHandler/ProjectApiHandler.cs) is handled by the SDK. It compares the source project with another server project and applies the changes. [^4]: Added to Kepware Server v6.13 and later builds +**NOTE:** Exporting a project from a Kepware server is done using the KepwareApiClient.LoadProjectAsync method. This detects the server version and uses the appropriate method to either export/load the whole project or loads the project by multiple requests. This ensures that large projects can be exported/loaded from the Kepware instance as optimally as possible based on the current API design. See [LoadProjectAsync](/Kepware.Api/ClientHandler/ProjectApiHandler.cs) for more details. + 3. Configuration API *Services* implemented: | Services | KS | KE | @@ -37,9 +39,8 @@ This package is designed to work with all versions of Kepware that support the C | **ProjectLoad and ProjectSave** | N | N | | **JsonProjectLoad\*\***
*(used for import project feature)* | Y | Y | -4. Synchronize configurations between your application and Kepware server. -5. Supports advanced operations like project comparison, entity synchronization, and driver property queries. -6. Built-in support for Dependency Injection to simplify integration. +4. Supports advanced operations like project comparison, entity synchronization, and driver property queries. +5. Built-in support for Dependency Injection to simplify integration. ## Installation @@ -51,16 +52,36 @@ Kepware.Api NuGet package is available from NuGet repository. ``` 2. Register the `KepwareApiClient` in your application using Dependency Injection: + ```csharp services.AddKepwareApiClient( name: "default", baseUrl: "https://localhost:57512", apiUserName: "Administrator", apiPassword: "StrongAdminPassword2025!", - disableCertificateValidation: true + disableCertificateValidation: false ); ``` + or + + ```csharp + var clientOptions = new KepwareClientOptions + { + HostUri = new Uri("https://localhost:57512"), + Username = "Administrator", + Password = "StrongAdminPassword2025!", + Timeout = TimeSpan.FromSeconds(60), + DisableCertifcateValidation = false, + ProjectLoadTagLimit = 100000 + }; + + services.AddKepwareApiClient( + name: "default", + options: clientOptions + ); + ``` + ## Key Methods ### Connection and Status @@ -77,9 +98,9 @@ Kepware.Api NuGet package is available from NuGet repository. Retrieves product information about the Kepware server. ### Project Management -- **Load Project:** +- **Export / Load Project:** ```csharp - var project = await api.LoadProject(blnLoadFullProject:true); + var project = await api.LoadProjectAsync(blnLoadFullProject:true); ``` Loads the current project from the Kepware server. From 13a64f639eced93edee7aa23e6446009370acb2d Mon Sep 17 00:00:00 2001 From: Ray Labbe Date: Thu, 19 Mar 2026 21:16:42 -0400 Subject: [PATCH 15/16] chore: updated with new LoadProjectAsync method call name --- KepwareSync.Service/SyncService.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/KepwareSync.Service/SyncService.cs b/KepwareSync.Service/SyncService.cs index a3811ac..a524220 100644 --- a/KepwareSync.Service/SyncService.cs +++ b/KepwareSync.Service/SyncService.cs @@ -122,7 +122,7 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken) private static async Task FetchCurrentProjectIdAsync(KepwareApiClient client, CancellationToken cancellationToken) { - var project = await client.Project.LoadProject(false, cancellationToken).ConfigureAwait(false); + var project = await client.Project.LoadProjectAsync(false, cancellationToken: cancellationToken).ConfigureAwait(false); return project?.ProjectId ?? -1; } @@ -166,7 +166,7 @@ private async Task ProcessChangeAsync(ChangeEvent changeEvent, CancellationToken internal async Task SyncFromPrimaryKepServerAsync(CancellationToken cancellationToken = default) { m_logger.LogInformation("Synchronizing full project from primary Kepware..."); - var project = await m_kepServerClient.Project.LoadProject(true); + var project = await m_kepServerClient.Project.LoadProjectAsync(true); await project.Cleanup(m_kepServerClient, true, cancellationToken); if (m_kepServerClient.ClientOptions.Tag is KepwareSyncTarget targetOptions && @@ -239,7 +239,7 @@ private async Task SyncFromSecondaryKepServerAsync(CancellationToken cancellatio m_logger.LogInformation("Syncing from secondary client {ClientHostName}...", clientToSyncFrom.ClientHostName); } - var projectFromSecondary = await clientToSyncFrom.Project.LoadProject(true, cancellationToken).ConfigureAwait(false); + var projectFromSecondary = await clientToSyncFrom.Project.LoadProjectAsync(true, cancellationToken: cancellationToken).ConfigureAwait(false); await SyncProjectToKepServerAsync("secondary", projectFromSecondary, m_kepServerClient, "Primary", onSyncedWithChanges: () => NotifyChange(new ChangeEvent { Source = ChangeSource.PrimaryKepServer, Reason = "Sync from secondary kepserver" }), cancellationToken: cancellationToken).ConfigureAwait(false); From 779b1d601ff5c12b3945f987c24c2ce889e613fe Mon Sep 17 00:00:00 2001 From: Ray Labbe Date: Fri, 20 Mar 2026 10:20:59 -0400 Subject: [PATCH 16/16] fix(test): fixed file name for case sensitive linux environments --- Kepware.Api.Test/ApiClient/_TestApiClientBase.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Kepware.Api.Test/ApiClient/_TestApiClientBase.cs b/Kepware.Api.Test/ApiClient/_TestApiClientBase.cs index 7e3e006..ffc2200 100644 --- a/Kepware.Api.Test/ApiClient/_TestApiClientBase.cs +++ b/Kepware.Api.Test/ApiClient/_TestApiClientBase.cs @@ -221,7 +221,7 @@ protected async Task ConfigureToServeEndpoints(string filePath = "_data/simdemo_ // Additional endpoints for content=serialize mocking var projectPropertiesString = await File.ReadAllTextAsync("_data/projectLoadSerializeData/projectProperties.json"); - var channel1String = await File.ReadAllTextAsync("_data/projectLoadSerializeData/channel1.json"); + var channel1String = await File.ReadAllTextAsync("_data/projectLoadSerializeData/Channel1.json"); var sixteenBitDeviceString = await File.ReadAllTextAsync("_data/projectLoadSerializeData/dataTypeExamples.16BitDevice.json"); var simExamplesChannelString = await File.ReadAllTextAsync("_data/projectLoadSerializeData/simulationExamples.json"); var dte8BitBRegTagGroupString = await File.ReadAllTextAsync("_data/projectLoadSerializeData/dte.8bitDevice.Breg.json");