Fix
This commit is contained in:
45
Technosoftware/DaAeHdaClient/Da/AccessRight.cs
Normal file
45
Technosoftware/DaAeHdaClient/Da/AccessRight.cs
Normal file
@@ -0,0 +1,45 @@
|
||||
#region Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
// Web: https://www.technosoftware.com
|
||||
//
|
||||
// The source code in this file is covered under a dual-license scenario:
|
||||
// - Owner of a purchased license: SCLA 1.0
|
||||
// - GPL V3: everybody else
|
||||
//
|
||||
// SCLA license terms accompanied with this source code.
|
||||
// See SCLA 1.0: https://technosoftware.com/license/Source_Code_License_Agreement.pdf
|
||||
//
|
||||
// GNU General Public License as published by the Free Software Foundation;
|
||||
// version 3 of the License are accompanied with this source code.
|
||||
// See https://technosoftware.com/license/GPLv3License.txt
|
||||
//
|
||||
// This source code is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//-----------------------------------------------------------------------------
|
||||
#endregion Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
|
||||
#region Using Directives
|
||||
#endregion
|
||||
|
||||
namespace Technosoftware.DaAeHdaClient.Da
|
||||
{
|
||||
/// <summary>
|
||||
/// <para>Defines possible item access rights.</para>
|
||||
/// <para align="left">Indicates if this item is read only, write only or read/write.
|
||||
/// This is NOT related to security but rather to the nature of the underlying
|
||||
/// hardware.</para>
|
||||
/// </summary>
|
||||
public enum TsDaAccessRights
|
||||
{
|
||||
/// <summary>The access rights for this item are server.</summary>
|
||||
Unknown = 0x00,
|
||||
/// <summary>The client can read the data item's value.</summary>
|
||||
Readable = 0x01,
|
||||
/// <summary>The client can change the data item's value.</summary>
|
||||
Writable = 0x02,
|
||||
/// <summary>The client can read and change the data item's value.</summary>
|
||||
ReadWritable = 0x03
|
||||
}
|
||||
}
|
||||
93
Technosoftware/DaAeHdaClient/Da/Browse.cs
Normal file
93
Technosoftware/DaAeHdaClient/Da/Browse.cs
Normal file
@@ -0,0 +1,93 @@
|
||||
#region Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
// Web: https://www.technosoftware.com
|
||||
//
|
||||
// The source code in this file is covered under a dual-license scenario:
|
||||
// - Owner of a purchased license: SCLA 1.0
|
||||
// - GPL V3: everybody else
|
||||
//
|
||||
// SCLA license terms accompanied with this source code.
|
||||
// See SCLA 1.0: https://technosoftware.com/license/Source_Code_License_Agreement.pdf
|
||||
//
|
||||
// GNU General Public License as published by the Free Software Foundation;
|
||||
// version 3 of the License are accompanied with this source code.
|
||||
// See https://technosoftware.com/license/GPLv3License.txt
|
||||
//
|
||||
// This source code is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//-----------------------------------------------------------------------------
|
||||
#endregion Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
|
||||
#region Using Directives
|
||||
using System;
|
||||
#endregion
|
||||
|
||||
namespace Technosoftware.DaAeHdaClient.Da
|
||||
{
|
||||
/// <summary>
|
||||
/// Stores the state of a browse operation.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class TsCDaBrowsePosition : IOpcBrowsePosition
|
||||
{
|
||||
#region Fields
|
||||
private TsCDaBrowseFilters browseFilters_;
|
||||
private OpcItem itemId_;
|
||||
#endregion
|
||||
|
||||
#region Constructors, Destructor, Initialization
|
||||
/// <summary>
|
||||
/// Saves the parameters for an incomplete browse information.
|
||||
/// </summary>
|
||||
public TsCDaBrowsePosition(OpcItem itemId, TsCDaBrowseFilters filters)
|
||||
{
|
||||
if (filters == null) throw new ArgumentNullException(nameof(filters));
|
||||
|
||||
itemId_ = (OpcItem)itemId?.Clone();
|
||||
browseFilters_ = (TsCDaBrowseFilters)filters.Clone();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Releases unmanaged resources held by the object.
|
||||
/// </summary>
|
||||
public virtual void Dispose()
|
||||
{
|
||||
// does nothing.
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
/// <summary>
|
||||
/// The item identifier of the branch being browsed.
|
||||
/// </summary>
|
||||
public OpcItem ItemID => itemId_;
|
||||
|
||||
/// <summary>
|
||||
/// The filters applied during the browse operation.
|
||||
/// </summary>
|
||||
public TsCDaBrowseFilters Filters => (TsCDaBrowseFilters)browseFilters_.Clone();
|
||||
|
||||
/// <summary>
|
||||
/// The maximum number of elements that may be returned in a single browse.
|
||||
/// </summary>
|
||||
// ReSharper disable once UnusedMember.Global
|
||||
public int MaxElementsReturned
|
||||
{
|
||||
get => browseFilters_.MaxElementsReturned;
|
||||
set => browseFilters_.MaxElementsReturned = value;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region ICloneable Members
|
||||
/// <summary>
|
||||
/// Creates a deep copy of the object.
|
||||
/// </summary>
|
||||
public virtual object Clone()
|
||||
{
|
||||
return (TsCDaBrowsePosition)MemberwiseClone();
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
87
Technosoftware/DaAeHdaClient/Da/BrowseElement.cs
Normal file
87
Technosoftware/DaAeHdaClient/Da/BrowseElement.cs
Normal file
@@ -0,0 +1,87 @@
|
||||
#region Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
// Web: https://www.technosoftware.com
|
||||
//
|
||||
// The source code in this file is covered under a dual-license scenario:
|
||||
// - Owner of a purchased license: SCLA 1.0
|
||||
// - GPL V3: everybody else
|
||||
//
|
||||
// SCLA license terms accompanied with this source code.
|
||||
// See SCLA 1.0: https://technosoftware.com/license/Source_Code_License_Agreement.pdf
|
||||
//
|
||||
// GNU General Public License as published by the Free Software Foundation;
|
||||
// version 3 of the License are accompanied with this source code.
|
||||
// See https://technosoftware.com/license/GPLv3License.txt
|
||||
//
|
||||
// This source code is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//-----------------------------------------------------------------------------
|
||||
#endregion Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
|
||||
#region Using Directives
|
||||
using System;
|
||||
#endregion
|
||||
|
||||
namespace Technosoftware.DaAeHdaClient.Da
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains a description of an element in the server address space.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class TsCDaBrowseElement : ICloneable
|
||||
{
|
||||
#region Fields
|
||||
private TsCDaItemProperty[] itemProperties_ = new TsCDaItemProperty[0];
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
/// <summary>
|
||||
/// A descriptive name for element that is unique within a branch.
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The primary identifier for the element within the server namespace.
|
||||
/// </summary>
|
||||
public string ItemName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// An secondary identifier for the element within the server namespace.
|
||||
/// </summary>
|
||||
public string ItemPath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether the element refers to an item with data that can be accessed.
|
||||
/// </summary>
|
||||
public bool IsItem { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether the element has children.
|
||||
/// </summary>
|
||||
public bool HasChildren { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The set of properties for the element.
|
||||
/// </summary>
|
||||
public TsCDaItemProperty[] Properties
|
||||
{
|
||||
get => itemProperties_;
|
||||
set => itemProperties_ = value;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region ICloneable Members
|
||||
/// <summary>
|
||||
/// Creates a deep copy of the object.
|
||||
/// </summary>
|
||||
public virtual object Clone()
|
||||
{
|
||||
var clone = (TsCDaBrowseElement)MemberwiseClone();
|
||||
clone.itemProperties_ = (TsCDaItemProperty[])OpcConvert.Clone(itemProperties_);
|
||||
return clone;
|
||||
}
|
||||
#endregion
|
||||
};
|
||||
}
|
||||
48
Technosoftware/DaAeHdaClient/Da/BrowseFilter.cs
Normal file
48
Technosoftware/DaAeHdaClient/Da/BrowseFilter.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
#region Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
// Web: https://www.technosoftware.com
|
||||
//
|
||||
// The source code in this file is covered under a dual-license scenario:
|
||||
// - Owner of a purchased license: SCLA 1.0
|
||||
// - GPL V3: everybody else
|
||||
//
|
||||
// SCLA license terms accompanied with this source code.
|
||||
// See SCLA 1.0: https://technosoftware.com/license/Source_Code_License_Agreement.pdf
|
||||
//
|
||||
// GNU General Public License as published by the Free Software Foundation;
|
||||
// version 3 of the License are accompanied with this source code.
|
||||
// See https://technosoftware.com/license/GPLv3License.txt
|
||||
//
|
||||
// This source code is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//-----------------------------------------------------------------------------
|
||||
#endregion Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
|
||||
#region Using Directives
|
||||
#endregion
|
||||
|
||||
namespace Technosoftware.DaAeHdaClient.Da
|
||||
{
|
||||
/// <summary>
|
||||
/// The type of browse elements to return during a browse.
|
||||
/// </summary>
|
||||
public enum TsCDaBrowseFilter
|
||||
{
|
||||
/// <summary>
|
||||
/// Return all types of browse elements.
|
||||
/// </summary>
|
||||
All,
|
||||
|
||||
/// <summary>
|
||||
/// Return only elements that contain other elements.
|
||||
/// </summary>
|
||||
Branch,
|
||||
|
||||
/// <summary>
|
||||
/// Return only elements that represent items.
|
||||
/// </summary>
|
||||
Item
|
||||
}
|
||||
}
|
||||
97
Technosoftware/DaAeHdaClient/Da/BrowseFilters.cs
Normal file
97
Technosoftware/DaAeHdaClient/Da/BrowseFilters.cs
Normal file
@@ -0,0 +1,97 @@
|
||||
#region Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
// Web: https://www.technosoftware.com
|
||||
//
|
||||
// The source code in this file is covered under a dual-license scenario:
|
||||
// - Owner of a purchased license: SCLA 1.0
|
||||
// - GPL V3: everybody else
|
||||
//
|
||||
// SCLA license terms accompanied with this source code.
|
||||
// See SCLA 1.0: https://technosoftware.com/license/Source_Code_License_Agreement.pdf
|
||||
//
|
||||
// GNU General Public License as published by the Free Software Foundation;
|
||||
// version 3 of the License are accompanied with this source code.
|
||||
// See https://technosoftware.com/license/GPLv3License.txt
|
||||
//
|
||||
// This source code is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//-----------------------------------------------------------------------------
|
||||
#endregion Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
|
||||
#region Using Directives
|
||||
using System;
|
||||
#endregion
|
||||
|
||||
namespace Technosoftware.DaAeHdaClient.Da
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines a set of filters to apply when browsing.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class TsCDaBrowseFilters : ICloneable
|
||||
{
|
||||
#region Fields
|
||||
private TsCDaBrowseFilter browseFilter_ = TsCDaBrowseFilter.All;
|
||||
private TsDaPropertyID[] propertyIds_;
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
/// <summary>
|
||||
/// The maximum number of elements to return. Zero means no limit.
|
||||
/// </summary>
|
||||
public int MaxElementsReturned { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The type of element to return.
|
||||
/// </summary>
|
||||
public TsCDaBrowseFilter BrowseFilter
|
||||
{
|
||||
get => browseFilter_;
|
||||
set => browseFilter_ = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An expression used to match the name of the element.
|
||||
/// </summary>
|
||||
public string ElementNameFilter { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A filter which has semantics that defined by the server.
|
||||
/// </summary>
|
||||
public string VendorFilter { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether all supported properties to return with each element.
|
||||
/// </summary>
|
||||
public bool ReturnAllProperties { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A list of names of the properties to return with each element.
|
||||
/// </summary>
|
||||
public TsDaPropertyID[] PropertyIDs
|
||||
{
|
||||
get => propertyIds_;
|
||||
set => propertyIds_ = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether property values should be returned with the properties.
|
||||
/// </summary>
|
||||
public bool ReturnPropertyValues { get; set; }
|
||||
#endregion
|
||||
|
||||
#region ICloneable Members
|
||||
/// <summary>
|
||||
/// Creates a deep copy of the object.
|
||||
/// </summary>
|
||||
public virtual object Clone()
|
||||
{
|
||||
var clone = (TsCDaBrowseFilters)MemberwiseClone();
|
||||
clone.PropertyIDs = (TsDaPropertyID[])PropertyIDs?.Clone();
|
||||
return clone;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
45
Technosoftware/DaAeHdaClient/Da/EuType.cs
Normal file
45
Technosoftware/DaAeHdaClient/Da/EuType.cs
Normal file
@@ -0,0 +1,45 @@
|
||||
#region Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
// Web: https://www.technosoftware.com
|
||||
//
|
||||
// The source code in this file is covered under a dual-license scenario:
|
||||
// - Owner of a purchased license: SCLA 1.0
|
||||
// - GPL V3: everybody else
|
||||
//
|
||||
// SCLA license terms accompanied with this source code.
|
||||
// See SCLA 1.0: https://technosoftware.com/license/Source_Code_License_Agreement.pdf
|
||||
//
|
||||
// GNU General Public License as published by the Free Software Foundation;
|
||||
// version 3 of the License are accompanied with this source code.
|
||||
// See https://technosoftware.com/license/GPLv3License.txt
|
||||
//
|
||||
// This source code is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//-----------------------------------------------------------------------------
|
||||
#endregion Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
|
||||
#region Using Directives
|
||||
#endregion
|
||||
|
||||
namespace Technosoftware.DaAeHdaClient.Da
|
||||
{
|
||||
/// <summary><para>Defines possible item engineering unit types</para></summary>
|
||||
public enum TsDaEuType
|
||||
{
|
||||
/// <summary>No engineering unit information available</summary>
|
||||
NoEnum = 0x01,
|
||||
/// <summary>
|
||||
/// Analog engineering unit - will contain a SAFE ARRAY of exactly two doubles
|
||||
/// (VT_ARRAY | VT_R8) corresponding to the LOW and HI EU range.
|
||||
/// </summary>
|
||||
Analog = 0x02,
|
||||
/// <summary>
|
||||
/// Enumerated engineering unit - will contain a SAFE ARRAY of strings (VT_ARRAY |
|
||||
/// VT_BSTR) which contains a list of strings (Example: “OPEN”, “CLOSE”, “IN TRANSIT”,
|
||||
/// etc.) corresponding to sequential numeric values (0, 1, 2, etc.)
|
||||
/// </summary>
|
||||
Enumerated = 0x03
|
||||
}
|
||||
}
|
||||
109
Technosoftware/DaAeHdaClient/Da/IServer.cs
Normal file
109
Technosoftware/DaAeHdaClient/Da/IServer.cs
Normal file
@@ -0,0 +1,109 @@
|
||||
#region Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
// Web: https://www.technosoftware.com
|
||||
//
|
||||
// The source code in this file is covered under a dual-license scenario:
|
||||
// - Owner of a purchased license: SCLA 1.0
|
||||
// - GPL V3: everybody else
|
||||
//
|
||||
// SCLA license terms accompanied with this source code.
|
||||
// See SCLA 1.0: https://technosoftware.com/license/Source_Code_License_Agreement.pdf
|
||||
//
|
||||
// GNU General Public License as published by the Free Software Foundation;
|
||||
// version 3 of the License are accompanied with this source code.
|
||||
// See https://technosoftware.com/license/GPLv3License.txt
|
||||
//
|
||||
// This source code is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//-----------------------------------------------------------------------------
|
||||
#endregion Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
|
||||
#region Using Directives
|
||||
#endregion
|
||||
|
||||
namespace Technosoftware.DaAeHdaClient.Da
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines functionality that is common to all OPC Data Access servers.
|
||||
/// </summary>
|
||||
public interface ITsDaServer : IOpcServer
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns the filters applied by the server to any item results returned to the client.
|
||||
/// </summary>
|
||||
/// <returns>A bit mask indicating which fields should be returned in any item results.</returns>
|
||||
int GetResultFilters();
|
||||
|
||||
/// <summary>
|
||||
/// Sets the filters applied by the server to any item results returned to the client.
|
||||
/// </summary>
|
||||
/// <param name="filters">A bit mask indicating which fields should be returned in any item results.</param>
|
||||
void SetResultFilters(int filters);
|
||||
|
||||
/// <summary>
|
||||
/// Returns the current server status.
|
||||
/// </summary>
|
||||
/// <returns>The current server status.</returns>
|
||||
OpcServerStatus GetServerStatus();
|
||||
|
||||
/// <summary>
|
||||
/// Reads the current values for a set of items.
|
||||
/// </summary>
|
||||
/// <param name="items">The set of items to read.</param>
|
||||
/// <returns>The results of the read operation for each item.</returns>
|
||||
TsCDaItemValueResult[] Read(TsCDaItem[] items);
|
||||
|
||||
/// <summary>
|
||||
/// Writes the value, quality and timestamp for a set of items.
|
||||
/// </summary>
|
||||
/// <param name="values">The set of item values to write.</param>
|
||||
/// <returns>The results of the write operation for each item.</returns>
|
||||
OpcItemResult[] Write(TsCDaItemValue[] values);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new subscription.
|
||||
/// </summary>
|
||||
/// <param name="state">The initial state of the subscription.</param>
|
||||
/// <returns>The new subscription object.</returns>
|
||||
ITsCDaSubscription CreateSubscription(TsCDaSubscriptionState state);
|
||||
|
||||
/// <summary>
|
||||
/// Cancels a subscription and releases all resources allocated for it.
|
||||
/// </summary>
|
||||
/// <param name="subscription">The subscription to cancel.</param>
|
||||
void CancelSubscription(ITsCDaSubscription subscription);
|
||||
|
||||
/// <summary>
|
||||
/// Fetches the children of a branch that meet the filter criteria.
|
||||
/// </summary>
|
||||
/// <param name="itemId">The identifier of branch which is the target of the search.</param>
|
||||
/// <param name="filters">The filters to use to limit the set of child elements returned.</param>
|
||||
/// <param name="position">An object used to continue a browse that could not be completed.</param>
|
||||
/// <returns>The set of elements found.</returns>
|
||||
TsCDaBrowseElement[] Browse(
|
||||
OpcItem itemId,
|
||||
TsCDaBrowseFilters filters,
|
||||
out TsCDaBrowsePosition position);
|
||||
|
||||
/// <summary>
|
||||
/// Continues a browse operation with previously specified search criteria.
|
||||
/// </summary>
|
||||
/// <param name="position">An object containing the browse operation state information.</param>
|
||||
/// <returns>The set of elements found.</returns>
|
||||
TsCDaBrowseElement[] BrowseNext(ref TsCDaBrowsePosition position);
|
||||
|
||||
/// <summary>
|
||||
/// Returns the item properties for a set of items.
|
||||
/// </summary>
|
||||
/// <param name="itemIds">A list of item identifiers.</param>
|
||||
/// <param name="propertyIDs">A list of properties to fetch for each item.</param>
|
||||
/// <param name="returnValues">Whether the property values should be returned with the properties.</param>
|
||||
/// <returns>A list of properties for each item.</returns>
|
||||
TsCDaItemPropertyCollection[] GetProperties(
|
||||
OpcItem[] itemIds,
|
||||
TsDaPropertyID[] propertyIDs,
|
||||
bool returnValues);
|
||||
}
|
||||
}
|
||||
226
Technosoftware/DaAeHdaClient/Da/ISubscription.cs
Normal file
226
Technosoftware/DaAeHdaClient/Da/ISubscription.cs
Normal file
@@ -0,0 +1,226 @@
|
||||
#region Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
// Web: https://www.technosoftware.com
|
||||
//
|
||||
// The source code in this file is covered under a dual-license scenario:
|
||||
// - Owner of a purchased license: SCLA 1.0
|
||||
// - GPL V3: everybody else
|
||||
//
|
||||
// SCLA license terms accompanied with this source code.
|
||||
// See SCLA 1.0: https://technosoftware.com/license/Source_Code_License_Agreement.pdf
|
||||
//
|
||||
// GNU General Public License as published by the Free Software Foundation;
|
||||
// version 3 of the License are accompanied with this source code.
|
||||
// See https://technosoftware.com/license/GPLv3License.txt
|
||||
//
|
||||
// This source code is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//-----------------------------------------------------------------------------
|
||||
#endregion Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
|
||||
#region Using Directives
|
||||
using System;
|
||||
#endregion
|
||||
|
||||
namespace Technosoftware.DaAeHdaClient.Da
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// A subscription for a set of items on a single OPC server.
|
||||
/// </summary>
|
||||
public interface ITsCDaSubscription : IDisposable
|
||||
{
|
||||
#region Events
|
||||
/// <summary>
|
||||
/// An event to receive data change updates.
|
||||
/// </summary>
|
||||
event TsCDaDataChangedEventHandler DataChangedEvent;
|
||||
#endregion
|
||||
|
||||
#region Result Filters
|
||||
/// <summary>
|
||||
/// Returns the filters applied by the server to any item results returned to the client.
|
||||
/// </summary>
|
||||
/// <returns>A bit mask indicating which fields should be returned in any item results.</returns>
|
||||
int GetResultFilters();
|
||||
|
||||
/// <summary>
|
||||
/// Sets the filters applied by the server to any item results returned to the client.
|
||||
/// </summary>
|
||||
/// <param name="filters">A bit mask indicating which fields should be returned in any item results.</param>
|
||||
void SetResultFilters(int filters);
|
||||
#endregion
|
||||
|
||||
#region State Management
|
||||
/// <summary>
|
||||
/// Returns the current state of the subscription.
|
||||
/// </summary>
|
||||
/// <returns>The current state of the subscription.</returns>
|
||||
TsCDaSubscriptionState GetState();
|
||||
|
||||
/// <summary>
|
||||
/// Changes the state of a subscription.
|
||||
/// </summary>
|
||||
/// <param name="masks">A bit mask that indicates which elements of the subscription state are changing.</param>
|
||||
/// <param name="state">The new subscription state.</param>
|
||||
/// <returns>The actual subscription state after applying the changes.</returns>
|
||||
TsCDaSubscriptionState ModifyState(int masks, TsCDaSubscriptionState state);
|
||||
#endregion
|
||||
|
||||
#region Item Management
|
||||
/// <summary>
|
||||
/// Adds items to the subscription.
|
||||
/// </summary>
|
||||
/// <param name="items">The set of items to add to the subscription.</param>
|
||||
/// <returns>The results of the add item operation for each item.</returns>
|
||||
TsCDaItemResult[] AddItems(TsCDaItem[] items);
|
||||
|
||||
/// <summary>
|
||||
/// Modifies the state of items in the subscription
|
||||
/// </summary>
|
||||
/// <param name="masks">Specifies which item state parameters are being modified.</param>
|
||||
/// <param name="items">The new state for each item.</param>
|
||||
/// <returns>The results of the modify item operation for each item.</returns>
|
||||
TsCDaItemResult[] ModifyItems(int masks, TsCDaItem[] items);
|
||||
|
||||
/// <summary>
|
||||
/// Removes items from the subscription.
|
||||
/// </summary>
|
||||
/// <param name="items">The identifiers (i.e. server handles) for the items being removed.</param>
|
||||
/// <returns>The results of the remove item operation for each item.</returns>
|
||||
OpcItemResult[] RemoveItems(OpcItem[] items);
|
||||
#endregion
|
||||
|
||||
#region Synchronous I/O
|
||||
/// <summary>
|
||||
/// Reads the values for a set of items in the subscription.
|
||||
/// </summary>
|
||||
/// <param name="items">The identifiers (i.e. server handles) for the items being read.</param>
|
||||
/// <returns>The value for each of items.</returns>
|
||||
TsCDaItemValueResult[] Read(TsCDaItem[] items);
|
||||
|
||||
/// <summary>
|
||||
/// Writes the value, quality and timestamp for a set of items in the subscription.
|
||||
/// </summary>
|
||||
/// <param name="items">The item values to write.</param>
|
||||
/// <returns>The results of the write operation for each item.</returns>
|
||||
OpcItemResult[] Write(TsCDaItemValue[] items);
|
||||
#endregion
|
||||
|
||||
#region Asynchronous I/O
|
||||
/// <summary>
|
||||
/// Begins an asynchronous read operation for a set of items.
|
||||
/// </summary>
|
||||
/// <param name="items">The set of items to read (must include the item name).</param>
|
||||
/// <param name="requestHandle">An identifier for the request assigned by the caller.</param>
|
||||
/// <param name="callback">A delegate used to receive notifications when the request completes.</param>
|
||||
/// <param name="request">An object that contains the state of the request (used to cancel the request).</param>
|
||||
/// <returns>A set of results containing any errors encountered when the server validated the items.</returns>
|
||||
OpcItemResult[] Read(
|
||||
TsCDaItem[] items,
|
||||
object requestHandle,
|
||||
TsCDaReadCompleteEventHandler callback,
|
||||
out IOpcRequest request);
|
||||
|
||||
/// <summary>
|
||||
/// Begins an asynchronous write operation for a set of items.
|
||||
/// </summary>
|
||||
/// <param name="items">The set of item values to write (must include the item name).</param>
|
||||
/// <param name="requestHandle">An identifier for the request assigned by the caller.</param>
|
||||
/// <param name="callback">A delegate used to receive notifications when the request completes.</param>
|
||||
/// <param name="request">An object that contains the state of the request (used to cancel the request).</param>
|
||||
/// <returns>A set of results containing any errors encountered when the server validated the items.</returns>
|
||||
OpcItemResult[] Write(
|
||||
TsCDaItemValue[] items,
|
||||
object requestHandle,
|
||||
TsCDaWriteCompleteEventHandler callback,
|
||||
out IOpcRequest request);
|
||||
|
||||
/// <summary>
|
||||
/// Cancels an asynchronous read or write operation.
|
||||
/// </summary>
|
||||
/// <param name="request">The object returned from the BeginRead or BeginWrite request.</param>
|
||||
/// <param name="callback">The function to invoke when the cancel completes.</param>
|
||||
void Cancel(IOpcRequest request, TsCDaCancelCompleteEventHandler callback);
|
||||
|
||||
/// <summary>
|
||||
/// Causes the server to send a data changed notification for all active items.
|
||||
/// </summary>
|
||||
void Refresh();
|
||||
|
||||
/// <summary>
|
||||
/// Causes the server to send a data changed notification for all active items.
|
||||
/// </summary>
|
||||
/// <param name="requestHandle">An identifier for the request assigned by the caller.</param>
|
||||
/// <param name="request">An object that contains the state of the request (used to cancel the request).</param>
|
||||
/// <returns>A set of results containing any errors encountered when the server validated the items.</returns>
|
||||
void Refresh(
|
||||
object requestHandle,
|
||||
out IOpcRequest request);
|
||||
|
||||
/// <summary>
|
||||
/// Enables or disables data change notifications from the server.
|
||||
/// </summary>
|
||||
/// <param name="enabled">Whether data change notifications are enabled.</param>
|
||||
void SetEnabled(bool enabled);
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether data change notifications from the server are enabled.
|
||||
/// </summary>
|
||||
/// <returns>Whether data change notifications are enabled.</returns>
|
||||
bool GetEnabled();
|
||||
#endregion
|
||||
}
|
||||
|
||||
#region Delegate Declarations
|
||||
/// <summary>
|
||||
/// A delegate to receive data change updates from the server.
|
||||
/// </summary>
|
||||
/// <param name="subscriptionHandle">
|
||||
/// A unique identifier for the subscription assigned by the client. If the parameter
|
||||
/// <see cref="TsCDaSubscriptionState.ClientHandle">ClientHandle</see> is not defined this
|
||||
/// parameter is empty.
|
||||
/// </param>
|
||||
/// <param name="requestHandle">
|
||||
/// An identifier for the request assigned by the caller. This parameter is empty if
|
||||
/// the corresponding parameter in the calls Read(), Write() or Refresh() is not defined.
|
||||
/// Can be used to Cancel an outstanding operation.
|
||||
/// </param>
|
||||
/// <param name="values">
|
||||
/// <para class="MsoBodyText" style="MARGIN: 1pt 0in">The set of changed values.</para>
|
||||
/// <para class="MsoBodyText" style="MARGIN: 1pt 0in">Each value will always have
|
||||
/// item’s ClientHandle field specified.</para>
|
||||
/// </param>
|
||||
public delegate void TsCDaDataChangedEventHandler(object subscriptionHandle, object requestHandle, TsCDaItemValueResult[] values);
|
||||
|
||||
/// <summary>
|
||||
/// A delegate to receive asynchronous read completed notifications.
|
||||
/// </summary>
|
||||
/// <param name="requestHandle">
|
||||
/// An identifier for the request assigned by the caller. This parameter is empty if
|
||||
/// the corresponding parameter in the calls Read(), Write() or Refresh() is not defined.
|
||||
/// Can be used to Cancel an outstanding operation.
|
||||
/// </param>
|
||||
/// <param name="results">The results of the last asynchronous read operation.</param>
|
||||
public delegate void TsCDaReadCompleteEventHandler(object requestHandle, TsCDaItemValueResult[] results);
|
||||
|
||||
/// <summary>
|
||||
/// A delegate to receive asynchronous write completed notifications.
|
||||
/// </summary>
|
||||
/// <param name="requestHandle">
|
||||
/// An identifier for the request assigned by the caller. This parameter is empty if
|
||||
/// the corresponding parameter in the calls Read(), Write() or Refresh() is not defined.
|
||||
/// Can be used to Cancel an outstanding operation.
|
||||
/// </param>
|
||||
/// <param name="results">The results of the last asynchronous write operation.</param>
|
||||
public delegate void TsCDaWriteCompleteEventHandler(object requestHandle, OpcItemResult[] results);
|
||||
|
||||
/// <summary>
|
||||
/// A delegate to receive asynchronous cancel completed notifications.
|
||||
/// </summary>
|
||||
/// <param name="requestHandle">An identifier for the request assigned by the caller.</param>
|
||||
public delegate void TsCDaCancelCompleteEventHandler(object requestHandle);
|
||||
#endregion
|
||||
}
|
||||
150
Technosoftware/DaAeHdaClient/Da/Item.cs
Normal file
150
Technosoftware/DaAeHdaClient/Da/Item.cs
Normal file
@@ -0,0 +1,150 @@
|
||||
#region Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
// Web: https://www.technosoftware.com
|
||||
//
|
||||
// The source code in this file is covered under a dual-license scenario:
|
||||
// - Owner of a purchased license: SCLA 1.0
|
||||
// - GPL V3: everybody else
|
||||
//
|
||||
// SCLA license terms accompanied with this source code.
|
||||
// See SCLA 1.0: https://technosoftware.com/license/Source_Code_License_Agreement.pdf
|
||||
//
|
||||
// GNU General Public License as published by the Free Software Foundation;
|
||||
// version 3 of the License are accompanied with this source code.
|
||||
// See https://technosoftware.com/license/GPLv3License.txt
|
||||
//
|
||||
// This source code is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//-----------------------------------------------------------------------------
|
||||
#endregion Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
|
||||
#region Using Directives
|
||||
using System;
|
||||
#endregion
|
||||
|
||||
namespace Technosoftware.DaAeHdaClient.Da
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes how an item in the server address space should be accessed.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class TsCDaItem : OpcItem
|
||||
{
|
||||
#region Fields
|
||||
private bool active_ = true;
|
||||
private float deadband_;
|
||||
#endregion
|
||||
|
||||
#region Constructors, Destructor, Initialization
|
||||
/// <summary>
|
||||
/// Initializes the object with default values.
|
||||
/// </summary>
|
||||
public TsCDaItem() { }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes object with the specified ItemIdentifier object.
|
||||
/// </summary>
|
||||
public TsCDaItem(OpcItem item)
|
||||
{
|
||||
if (item == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
ItemName = item.ItemName;
|
||||
ItemPath = item.ItemPath;
|
||||
ClientHandle = item.ClientHandle;
|
||||
ServerHandle = item.ServerHandle;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes object with the specified Item object.
|
||||
/// </summary>
|
||||
public TsCDaItem(TsCDaItem item)
|
||||
: base(item)
|
||||
{
|
||||
if (item == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
ReqType = item.ReqType;
|
||||
MaxAge = item.MaxAge;
|
||||
MaxAgeSpecified = item.MaxAgeSpecified;
|
||||
Active = item.Active;
|
||||
ActiveSpecified = item.ActiveSpecified;
|
||||
Deadband = item.Deadband;
|
||||
DeadbandSpecified = item.DeadbandSpecified;
|
||||
SamplingRate = item.SamplingRate;
|
||||
SamplingRateSpecified = item.SamplingRateSpecified;
|
||||
EnableBuffering = item.EnableBuffering;
|
||||
EnableBufferingSpecified = item.EnableBufferingSpecified;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
/// <summary>
|
||||
/// The data type to use when returning the item value.
|
||||
/// </summary>
|
||||
public Type ReqType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The oldest (in milliseconds) acceptable cached value when reading an item.
|
||||
/// </summary>
|
||||
public int MaxAge { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether the Max Age is specified.
|
||||
/// </summary>
|
||||
public bool MaxAgeSpecified { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether the server should send data change updates.
|
||||
/// </summary>
|
||||
public bool Active
|
||||
{
|
||||
get => active_;
|
||||
set => active_ = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether the Active state is specified.
|
||||
/// </summary>
|
||||
public bool ActiveSpecified { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The minimum percentage change required to trigger a data update for an item.
|
||||
/// </summary>
|
||||
public float Deadband
|
||||
{
|
||||
get => deadband_;
|
||||
set => deadband_ = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether the Deadband is specified.
|
||||
/// </summary>
|
||||
public bool DeadbandSpecified { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// How frequently the server should sample the item value.
|
||||
/// </summary>
|
||||
public int SamplingRate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether the Sampling Rate is specified.
|
||||
/// </summary>
|
||||
public bool SamplingRateSpecified { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether the server should buffer multiple data changes between data updates.
|
||||
/// </summary>
|
||||
public bool EnableBuffering { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether the Enable Buffering is specified.
|
||||
/// </summary>
|
||||
public bool EnableBufferingSpecified { get; set; }
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
313
Technosoftware/DaAeHdaClient/Da/ItemCollection.cs
Normal file
313
Technosoftware/DaAeHdaClient/Da/ItemCollection.cs
Normal file
@@ -0,0 +1,313 @@
|
||||
#region Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
// Web: https://www.technosoftware.com
|
||||
//
|
||||
// The source code in this file is covered under a dual-license scenario:
|
||||
// - Owner of a purchased license: SCLA 1.0
|
||||
// - GPL V3: everybody else
|
||||
//
|
||||
// SCLA license terms accompanied with this source code.
|
||||
// See SCLA 1.0: https://technosoftware.com/license/Source_Code_License_Agreement.pdf
|
||||
//
|
||||
// GNU General Public License as published by the Free Software Foundation;
|
||||
// version 3 of the License are accompanied with this source code.
|
||||
// See https://technosoftware.com/license/GPLv3License.txt
|
||||
//
|
||||
// This source code is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//-----------------------------------------------------------------------------
|
||||
#endregion Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
|
||||
#region Using Directives
|
||||
using System;
|
||||
using System.Collections;
|
||||
#endregion
|
||||
|
||||
namespace Technosoftware.DaAeHdaClient.Da
|
||||
{
|
||||
/// <summary>
|
||||
/// A collection of items.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class TsCDaItemCollection : ICloneable, IList
|
||||
{
|
||||
#region Fields
|
||||
private ArrayList items_ = new ArrayList();
|
||||
#endregion
|
||||
|
||||
#region Constructors, Destructor, Initialization
|
||||
/// <summary>
|
||||
/// Initializes object with the default values.
|
||||
/// </summary>
|
||||
public TsCDaItemCollection() { }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes object with the specified ResultCollection object.
|
||||
/// </summary>
|
||||
public TsCDaItemCollection(TsCDaItemCollection items)
|
||||
{
|
||||
if (items == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
foreach (TsCDaItem item in items)
|
||||
{
|
||||
Add(item);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
/// <summary>
|
||||
/// Gets the item at the specified index.
|
||||
/// </summary>
|
||||
public TsCDaItem this[int index]
|
||||
{
|
||||
get => (TsCDaItem)items_[index];
|
||||
set => items_[index] = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the first item with the specified item id.
|
||||
/// </summary>
|
||||
public TsCDaItem this[OpcItem itemId]
|
||||
{
|
||||
get
|
||||
{
|
||||
foreach (TsCDaItem item in items_)
|
||||
{
|
||||
if (itemId.Key == item.Key)
|
||||
{
|
||||
return item;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region ICloneable Members
|
||||
/// <summary>
|
||||
/// Creates a deep copy of the object.
|
||||
/// </summary>
|
||||
public virtual object Clone()
|
||||
{
|
||||
var clone = (TsCDaItemCollection)MemberwiseClone();
|
||||
|
||||
clone.items_ = new ArrayList();
|
||||
|
||||
foreach (TsCDaItem item in items_)
|
||||
{
|
||||
clone.items_.Add(item.Clone());
|
||||
}
|
||||
|
||||
return clone;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region ICollection Members
|
||||
/// <summary>
|
||||
/// Indicates whether access to the ICollection is synchronized (thread-safe).
|
||||
/// </summary>
|
||||
public bool IsSynchronized => false;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of objects in the collection.
|
||||
/// </summary>
|
||||
public int Count => items_?.Count ?? 0;
|
||||
|
||||
/// <summary>
|
||||
/// Copies the objects to an Array, starting at a the specified index.
|
||||
/// </summary>
|
||||
/// <param name="array">The one-dimensional Array that is the destination for the objects.</param>
|
||||
/// <param name="index">The zero-based index in the Array at which copying begins.</param>
|
||||
public void CopyTo(Array array, int index)
|
||||
{
|
||||
items_?.CopyTo(array, index);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copies the objects to an Array, starting at a the specified index.
|
||||
/// </summary>
|
||||
/// <param name="array">The one-dimensional Array that is the destination for the objects.</param>
|
||||
/// <param name="index">The zero-based index in the Array at which copying begins.</param>
|
||||
public void CopyTo(TsCDaItem[] array, int index)
|
||||
{
|
||||
CopyTo((Array)array, index);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether access to the ICollection is synchronized (thread-safe).
|
||||
/// </summary>
|
||||
public object SyncRoot => this;
|
||||
#endregion
|
||||
|
||||
#region IEnumerable Members
|
||||
/// <summary>
|
||||
/// Returns an enumerator that can iterate through a collection.
|
||||
/// </summary>
|
||||
/// <returns>An IEnumerator that can be used to iterate through the collection.</returns>
|
||||
public IEnumerator GetEnumerator()
|
||||
{
|
||||
return items_.GetEnumerator();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region IList Members
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the IList is read-only.
|
||||
/// </summary>
|
||||
public bool IsReadOnly => false;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the element at the specified index.
|
||||
/// </summary>
|
||||
object IList.this[int index]
|
||||
{
|
||||
get => items_[index];
|
||||
|
||||
set
|
||||
{
|
||||
if (!typeof(TsCDaItem).IsInstanceOfType(value))
|
||||
{
|
||||
throw new ArgumentException("May only add Item objects into the collection.");
|
||||
}
|
||||
|
||||
items_[index] = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the IList item at the specified index.
|
||||
/// </summary>
|
||||
/// <param name="index">The zero-based index of the item to remove.</param>
|
||||
public void RemoveAt(int index)
|
||||
{
|
||||
items_.RemoveAt(index);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inserts an item to the IList at the specified position.
|
||||
/// </summary>
|
||||
/// <param name="index">The zero-based index at which value should be inserted.</param>
|
||||
/// <param name="value">The Object to insert into the IList. </param>
|
||||
public void Insert(int index, object value)
|
||||
{
|
||||
if (!typeof(TsCDaItem).IsInstanceOfType(value))
|
||||
{
|
||||
throw new ArgumentException("May only add Item objects into the collection.");
|
||||
}
|
||||
|
||||
items_.Insert(index, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the first occurrence of a specific object from the IList.
|
||||
/// </summary>
|
||||
/// <param name="value">The Object to remove from the IList.</param>
|
||||
public void Remove(object value)
|
||||
{
|
||||
items_.Remove(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the IList contains a specific value.
|
||||
/// </summary>
|
||||
/// <param name="value">The Object to locate in the IList.</param>
|
||||
/// <returns>true if the Object is found in the IList; otherwise, false.</returns>
|
||||
public bool Contains(object value)
|
||||
{
|
||||
return items_.Contains(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes all items from the IList.
|
||||
/// </summary>
|
||||
public void Clear()
|
||||
{
|
||||
items_.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines the index of a specific item in the IList.
|
||||
/// </summary>
|
||||
/// <param name="value">The Object to locate in the IList.</param>
|
||||
/// <returns>The index of value if found in the list; otherwise, -1.</returns>
|
||||
public int IndexOf(object value)
|
||||
{
|
||||
return items_.IndexOf(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds an item to the IList.
|
||||
/// </summary>
|
||||
/// <param name="value">The Object to add to the IList. </param>
|
||||
/// <returns>The position into which the new element was inserted.</returns>
|
||||
public int Add(object value)
|
||||
{
|
||||
if (!typeof(TsCDaItem).IsInstanceOfType(value))
|
||||
{
|
||||
throw new ArgumentException("May only add Item objects into the collection.");
|
||||
}
|
||||
|
||||
return items_.Add(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the IList has a fixed size.
|
||||
/// </summary>
|
||||
public bool IsFixedSize => false;
|
||||
|
||||
/// <summary>
|
||||
/// Inserts an item to the IList at the specified position.
|
||||
/// </summary>
|
||||
/// <param name="index">The zero-based index at which value should be inserted.</param>
|
||||
/// <param name="value">The Object to insert into the IList. </param>
|
||||
public void Insert(int index, TsCDaItem value)
|
||||
{
|
||||
Insert(index, (object)value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the first occurrence of a specific object from the IList.
|
||||
/// </summary>
|
||||
/// <param name="value">The Object to remove from the IList.</param>
|
||||
public void Remove(TsCDaItem value)
|
||||
{
|
||||
Remove((object)value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the IList contains a specific value.
|
||||
/// </summary>
|
||||
/// <param name="value">The Object to locate in the IList.</param>
|
||||
/// <returns>true if the Object is found in the IList; otherwise, false.</returns>
|
||||
public bool Contains(TsCDaItem value)
|
||||
{
|
||||
return Contains((object)value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines the index of a specific item in the IList.
|
||||
/// </summary>
|
||||
/// <param name="value">The Object to locate in the IList.</param>
|
||||
/// <returns>The index of value if found in the list; otherwise, -1.</returns>
|
||||
public int IndexOf(TsCDaItem value)
|
||||
{
|
||||
return IndexOf((object)value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds an item to the IList.
|
||||
/// </summary>
|
||||
/// <param name="value">The Object to add to the IList. </param>
|
||||
/// <returns>The position into which the new element was inserted.</returns>
|
||||
public int Add(TsCDaItem value)
|
||||
{
|
||||
return Add((object)value);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
100
Technosoftware/DaAeHdaClient/Da/ItemProperty.cs
Normal file
100
Technosoftware/DaAeHdaClient/Da/ItemProperty.cs
Normal file
@@ -0,0 +1,100 @@
|
||||
#region Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
// Web: https://www.technosoftware.com
|
||||
//
|
||||
// The source code in this file is covered under a dual-license scenario:
|
||||
// - Owner of a purchased license: SCLA 1.0
|
||||
// - GPL V3: everybody else
|
||||
//
|
||||
// SCLA license terms accompanied with this source code.
|
||||
// See SCLA 1.0: https://technosoftware.com/license/Source_Code_License_Agreement.pdf
|
||||
//
|
||||
// GNU General Public License as published by the Free Software Foundation;
|
||||
// version 3 of the License are accompanied with this source code.
|
||||
// See https://technosoftware.com/license/GPLv3License.txt
|
||||
//
|
||||
// This source code is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//-----------------------------------------------------------------------------
|
||||
#endregion Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
|
||||
#region Using Directives
|
||||
using System;
|
||||
#endregion
|
||||
|
||||
namespace Technosoftware.DaAeHdaClient.Da
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains a description of a single item property.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class TsCDaItemProperty : ICloneable, IOpcResult
|
||||
{
|
||||
#region Fields
|
||||
private OpcResult result_ = OpcResult.S_OK;
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
/// <summary>
|
||||
/// The property identifier.
|
||||
/// </summary>
|
||||
public TsDaPropertyID ID { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A short description of the property.
|
||||
/// </summary>
|
||||
public string Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The data type of the property.
|
||||
/// </summary>
|
||||
public Type DataType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The value of the property.
|
||||
/// </summary>
|
||||
public object Value { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The primary identifier for the property if it is directly accessible as an item.
|
||||
/// </summary>
|
||||
public string ItemName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The secondary identifier for the property if it is directly accessible as an item.
|
||||
/// </summary>
|
||||
public string ItemPath { get; set; }
|
||||
#endregion
|
||||
|
||||
#region IOpcResult Members
|
||||
/// <summary>
|
||||
/// The <see cref="OpcResult" /> object with the result of an operation on an property.
|
||||
/// </summary>
|
||||
public OpcResult Result
|
||||
{
|
||||
get => result_;
|
||||
set => result_ = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Vendor specific diagnostic information (not the localized error text).
|
||||
/// </summary>
|
||||
public string DiagnosticInfo { get; set; }
|
||||
#endregion
|
||||
|
||||
#region ICloneable Members
|
||||
/// <summary>
|
||||
/// Creates a deep copy of the object.
|
||||
/// </summary>
|
||||
public virtual object Clone()
|
||||
{
|
||||
var clone = (TsCDaItemProperty)MemberwiseClone();
|
||||
clone.Value = OpcConvert.Clone(Value);
|
||||
return clone;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
175
Technosoftware/DaAeHdaClient/Da/ItemPropertyCollection.cs
Normal file
175
Technosoftware/DaAeHdaClient/Da/ItemPropertyCollection.cs
Normal file
@@ -0,0 +1,175 @@
|
||||
#region Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
// Web: https://www.technosoftware.com
|
||||
//
|
||||
// The source code in this file is covered under a dual-license scenario:
|
||||
// - Owner of a purchased license: SCLA 1.0
|
||||
// - GPL V3: everybody else
|
||||
//
|
||||
// SCLA license terms accompanied with this source code.
|
||||
// See SCLA 1.0: https://technosoftware.com/license/Source_Code_License_Agreement.pdf
|
||||
//
|
||||
// GNU General Public License as published by the Free Software Foundation;
|
||||
// version 3 of the License are accompanied with this source code.
|
||||
// See https://technosoftware.com/license/GPLv3License.txt
|
||||
//
|
||||
// This source code is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//-----------------------------------------------------------------------------
|
||||
#endregion Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
|
||||
#region Using Directives
|
||||
using System;
|
||||
using System.Collections;
|
||||
#endregion
|
||||
|
||||
namespace Technosoftware.DaAeHdaClient.Da
|
||||
{
|
||||
/// <summary>
|
||||
/// A list of properties for a single item.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class TsCDaItemPropertyCollection : ArrayList, IOpcResult
|
||||
{
|
||||
#region Fields
|
||||
private OpcResult result_ = OpcResult.S_OK;
|
||||
#endregion
|
||||
|
||||
#region Constructors, Destructor, Initialization
|
||||
/// <summary>
|
||||
/// Initializes the object with its default values.
|
||||
/// </summary>
|
||||
public TsCDaItemPropertyCollection()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the object with the specified item identifier.
|
||||
/// </summary>
|
||||
public TsCDaItemPropertyCollection(OpcItem itemId)
|
||||
{
|
||||
if (itemId != null)
|
||||
{
|
||||
ItemName = itemId.ItemName;
|
||||
ItemPath = itemId.ItemPath;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the object with the specified item identifier and result.
|
||||
/// </summary>
|
||||
public TsCDaItemPropertyCollection(OpcItem itemId, OpcResult result)
|
||||
{
|
||||
if (itemId != null)
|
||||
{
|
||||
ItemName = itemId.ItemName;
|
||||
ItemPath = itemId.ItemPath;
|
||||
}
|
||||
|
||||
result_ = result;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
/// <summary>
|
||||
/// The primary identifier for the item within the server namespace.
|
||||
/// </summary>
|
||||
public string ItemName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// An secondary identifier for the item within the server namespace.
|
||||
/// </summary>
|
||||
public string ItemPath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Accesses the items at the specified index.
|
||||
/// </summary>
|
||||
public new TsCDaItemProperty this[int index]
|
||||
{
|
||||
get => (TsCDaItemProperty)base[index];
|
||||
set => base[index] = value;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region IOpcResult Members
|
||||
/// <summary>
|
||||
/// The error id for the result of an operation on an item.
|
||||
/// </summary>
|
||||
public OpcResult Result
|
||||
{
|
||||
get => result_;
|
||||
set => result_ = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Vendor specific diagnostic information (not the localized error text).
|
||||
/// </summary>
|
||||
public string DiagnosticInfo { get; set; }
|
||||
#endregion
|
||||
|
||||
#region ICollection Members
|
||||
/// <summary>
|
||||
/// Copies the objects to an Array, starting at a the specified index.
|
||||
/// </summary>
|
||||
/// <param name="array">The one-dimensional Array that is the destination for the objects.</param>
|
||||
/// <param name="index">The zero-based index in the Array at which copying begins.</param>
|
||||
public void CopyTo(TsCDaItemProperty[] array, int index)
|
||||
{
|
||||
CopyTo((Array)array, index);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region IList Members
|
||||
/// <summary>
|
||||
/// Inserts an item to the IList at the specified position.
|
||||
/// </summary>
|
||||
/// <param name="index">The zero-based index at which value should be inserted.</param>
|
||||
/// <param name="value">The Object to insert into the IList. </param>
|
||||
public void Insert(int index, TsCDaItemProperty value)
|
||||
{
|
||||
Insert(index, (object)value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the first occurrence of a specific object from the IList.
|
||||
/// </summary>
|
||||
/// <param name="value">The Object to remove from the IList.</param>
|
||||
public void Remove(TsCDaItemProperty value)
|
||||
{
|
||||
Remove((object)value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the IList contains a specific value.
|
||||
/// </summary>
|
||||
/// <param name="value">The Object to locate in the IList.</param>
|
||||
/// <returns>true if the Object is found in the IList; otherwise, false.</returns>
|
||||
public bool Contains(TsCDaItemProperty value)
|
||||
{
|
||||
return Contains((object)value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines the index of a specific item in the IList.
|
||||
/// </summary>
|
||||
/// <param name="value">The Object to locate in the IList.</param>
|
||||
/// <returns>The index of value if found in the list; otherwise, -1.</returns>
|
||||
public int IndexOf(TsCDaItemProperty value)
|
||||
{
|
||||
return IndexOf((object)value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds an item to the IList.
|
||||
/// </summary>
|
||||
/// <param name="value">The Object to add to the IList. </param>
|
||||
/// <returns>The position into which the new element was inserted.</returns>
|
||||
public int Add(TsCDaItemProperty value)
|
||||
{
|
||||
return Add((object)value);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
104
Technosoftware/DaAeHdaClient/Da/ItemResult.cs
Normal file
104
Technosoftware/DaAeHdaClient/Da/ItemResult.cs
Normal file
@@ -0,0 +1,104 @@
|
||||
#region Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
// Web: https://www.technosoftware.com
|
||||
//
|
||||
// The source code in this file is covered under a dual-license scenario:
|
||||
// - Owner of a purchased license: SCLA 1.0
|
||||
// - GPL V3: everybody else
|
||||
//
|
||||
// SCLA license terms accompanied with this source code.
|
||||
// See SCLA 1.0: https://technosoftware.com/license/Source_Code_License_Agreement.pdf
|
||||
//
|
||||
// GNU General Public License as published by the Free Software Foundation;
|
||||
// version 3 of the License are accompanied with this source code.
|
||||
// See https://technosoftware.com/license/GPLv3License.txt
|
||||
//
|
||||
// This source code is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//-----------------------------------------------------------------------------
|
||||
#endregion Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
|
||||
#region Using Directives
|
||||
using System;
|
||||
#endregion
|
||||
|
||||
namespace Technosoftware.DaAeHdaClient.Da
|
||||
{
|
||||
/// <summary>
|
||||
/// The results of an operation on a uniquely identifiable item.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class TsCDaItemResult : TsCDaItem, IOpcResult
|
||||
{
|
||||
#region Fields
|
||||
private OpcResult result_ = OpcResult.S_OK;
|
||||
#endregion
|
||||
|
||||
#region Constructors, Destructor, Initialization
|
||||
/// <summary>
|
||||
/// Initializes the object with default values.
|
||||
/// </summary>
|
||||
public TsCDaItemResult() { }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the object with an ItemIdentifier object.
|
||||
/// </summary>
|
||||
public TsCDaItemResult(OpcItem item) : base(item) { }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the object with an ItemIdentifier object and Result.
|
||||
/// </summary>
|
||||
public TsCDaItemResult(OpcItem item, OpcResult resultId)
|
||||
: base(item)
|
||||
{
|
||||
Result = resultId;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the object with an Item object.
|
||||
/// </summary>
|
||||
public TsCDaItemResult(TsCDaItem item) : base(item) { }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the object with an Item object and Result.
|
||||
/// </summary>
|
||||
public TsCDaItemResult(TsCDaItem item, OpcResult resultId)
|
||||
: base(item)
|
||||
{
|
||||
Result = resultId;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes object with the specified ItemResult object.
|
||||
/// </summary>
|
||||
public TsCDaItemResult(TsCDaItemResult item)
|
||||
: base(item)
|
||||
{
|
||||
if (item != null)
|
||||
{
|
||||
Result = item.Result;
|
||||
DiagnosticInfo = item.DiagnosticInfo;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region IOpcResult Members
|
||||
|
||||
/// <summary>
|
||||
/// The error id for the result of an operation on an property.
|
||||
/// </summary>
|
||||
public OpcResult Result
|
||||
{
|
||||
get => result_;
|
||||
set => result_ = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Vendor specific diagnostic information (not the localized error text).
|
||||
/// </summary>
|
||||
public string DiagnosticInfo { get; set; }
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
137
Technosoftware/DaAeHdaClient/Da/ItemValue.cs
Normal file
137
Technosoftware/DaAeHdaClient/Da/ItemValue.cs
Normal file
@@ -0,0 +1,137 @@
|
||||
#region Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
// Web: https://www.technosoftware.com
|
||||
//
|
||||
// The source code in this file is covered under a dual-license scenario:
|
||||
// - Owner of a purchased license: SCLA 1.0
|
||||
// - GPL V3: everybody else
|
||||
//
|
||||
// SCLA license terms accompanied with this source code.
|
||||
// See SCLA 1.0: https://technosoftware.com/license/Source_Code_License_Agreement.pdf
|
||||
//
|
||||
// GNU General Public License as published by the Free Software Foundation;
|
||||
// version 3 of the License are accompanied with this source code.
|
||||
// See https://technosoftware.com/license/GPLv3License.txt
|
||||
//
|
||||
// This source code is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//-----------------------------------------------------------------------------
|
||||
#endregion Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
|
||||
#region Using Directives
|
||||
using System;
|
||||
#endregion
|
||||
|
||||
namespace Technosoftware.DaAeHdaClient.Da
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Contains the value for a single item.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class TsCDaItemValue : OpcItem
|
||||
{
|
||||
#region Fields
|
||||
private TsCDaQuality daQuality_ = TsCDaQuality.Bad;
|
||||
private DateTime timestamp_ = DateTime.MinValue;
|
||||
#endregion
|
||||
|
||||
#region Constructors, Destructor, Initialization
|
||||
/// <summary>
|
||||
/// Initializes the object with default values.
|
||||
/// </summary>
|
||||
public TsCDaItemValue() { }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the object with and ItemIdentifier object.
|
||||
/// </summary>
|
||||
public TsCDaItemValue(OpcItem item)
|
||||
{
|
||||
if (item == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
ItemName = item.ItemName;
|
||||
ItemPath = item.ItemPath;
|
||||
ClientHandle = item.ClientHandle;
|
||||
ServerHandle = item.ServerHandle;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the object with the specified item name.
|
||||
/// </summary>
|
||||
public TsCDaItemValue(string itemName)
|
||||
: base(itemName)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes object with the specified ItemValue object.
|
||||
/// </summary>
|
||||
public TsCDaItemValue(TsCDaItemValue item)
|
||||
: base(item)
|
||||
{
|
||||
if (item == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
Value = OpcConvert.Clone(item.Value);
|
||||
Quality = item.Quality;
|
||||
QualitySpecified = item.QualitySpecified;
|
||||
Timestamp = item.Timestamp;
|
||||
TimestampSpecified = item.TimestampSpecified;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
/// <summary>
|
||||
/// The item value.
|
||||
/// </summary>
|
||||
public object Value { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The quality of the item value.
|
||||
/// </summary>
|
||||
public TsCDaQuality Quality
|
||||
{
|
||||
get => daQuality_;
|
||||
set => daQuality_ = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether the quality is specified.
|
||||
/// </summary>
|
||||
public bool QualitySpecified { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The timestamp for the item value.
|
||||
/// The <see cref="ApplicationInstance.TimeAsUtc">ApplicationInstance.TimeAsUtc</see> property defines
|
||||
/// the time format (UTC or local time).
|
||||
/// </summary>
|
||||
public DateTime Timestamp
|
||||
{
|
||||
get => timestamp_;
|
||||
set => timestamp_ = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether the timestamp is specified.
|
||||
/// </summary>
|
||||
public bool TimestampSpecified { get; set; }
|
||||
#endregion
|
||||
|
||||
#region ICloneable Members
|
||||
/// <summary>
|
||||
/// Creates a deep copy of the object.
|
||||
/// </summary>
|
||||
public override object Clone()
|
||||
{
|
||||
var clone = (TsCDaItemValue)MemberwiseClone();
|
||||
clone.Value = OpcConvert.Clone(Value);
|
||||
return clone;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
123
Technosoftware/DaAeHdaClient/Da/ItemValueResult.cs
Normal file
123
Technosoftware/DaAeHdaClient/Da/ItemValueResult.cs
Normal file
@@ -0,0 +1,123 @@
|
||||
#region Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
// Web: https://www.technosoftware.com
|
||||
//
|
||||
// The source code in this file is covered under a dual-license scenario:
|
||||
// - Owner of a purchased license: SCLA 1.0
|
||||
// - GPL V3: everybody else
|
||||
//
|
||||
// SCLA license terms accompanied with this source code.
|
||||
// See SCLA 1.0: https://technosoftware.com/license/Source_Code_License_Agreement.pdf
|
||||
//
|
||||
// GNU General Public License as published by the Free Software Foundation;
|
||||
// version 3 of the License are accompanied with this source code.
|
||||
// See https://technosoftware.com/license/GPLv3License.txt
|
||||
//
|
||||
// This source code is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//-----------------------------------------------------------------------------
|
||||
#endregion Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
|
||||
#region Using Directives
|
||||
using System;
|
||||
#endregion
|
||||
|
||||
namespace Technosoftware.DaAeHdaClient.Da
|
||||
{
|
||||
/// <summary>
|
||||
/// The results of an operation on a uniquely identifiable item value.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class TsCDaItemValueResult : TsCDaItemValue, IOpcResult
|
||||
{
|
||||
#region Fields
|
||||
private OpcResult result_ = OpcResult.S_OK;
|
||||
#endregion
|
||||
|
||||
#region Constructors, Destructor, Initialization
|
||||
/// <summary>
|
||||
/// Initializes the object with default values.
|
||||
/// </summary>
|
||||
public TsCDaItemValueResult() { }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the object with an ItemIdentifier object.
|
||||
/// </summary>
|
||||
public TsCDaItemValueResult(OpcItem item) : base(item) { }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the object with an ItemValue object.
|
||||
/// </summary>
|
||||
public TsCDaItemValueResult(TsCDaItemValue item) : base(item) { }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes object with the specified ItemValueResult object.
|
||||
/// </summary>
|
||||
public TsCDaItemValueResult(TsCDaItemValueResult item)
|
||||
: base(item)
|
||||
{
|
||||
if (item != null)
|
||||
{
|
||||
Result = item.Result;
|
||||
DiagnosticInfo = item.DiagnosticInfo;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the object with the specified item name and result code.
|
||||
/// </summary>
|
||||
public TsCDaItemValueResult(string itemName, OpcResult resultId)
|
||||
: base(itemName)
|
||||
{
|
||||
Result = resultId;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the object with the specified item name, result code and diagnostic info.
|
||||
/// </summary>
|
||||
public TsCDaItemValueResult(string itemName, OpcResult resultId, string diagnosticInfo)
|
||||
: base(itemName)
|
||||
{
|
||||
Result = resultId;
|
||||
DiagnosticInfo = diagnosticInfo;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initialize object with the specified ItemIdentifier and result code.
|
||||
/// </summary>
|
||||
public TsCDaItemValueResult(OpcItem item, OpcResult resultId)
|
||||
: base(item)
|
||||
{
|
||||
Result = resultId;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the object with the specified ItemIdentifier, result code and diagnostic info.
|
||||
/// </summary>
|
||||
public TsCDaItemValueResult(OpcItem item, OpcResult resultId, string diagnosticInfo)
|
||||
: base(item)
|
||||
{
|
||||
Result = resultId;
|
||||
DiagnosticInfo = diagnosticInfo;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region IOpcResult Members
|
||||
/// <summary>
|
||||
/// The error id for the result of an operation on an property.
|
||||
/// </summary>
|
||||
public OpcResult Result
|
||||
{
|
||||
get => result_;
|
||||
set => result_ = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Vendor specific diagnostic information (not the localized error text).
|
||||
/// </summary>
|
||||
public string DiagnosticInfo { get; set; }
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
44
Technosoftware/DaAeHdaClient/Da/LimitBits.cs
Normal file
44
Technosoftware/DaAeHdaClient/Da/LimitBits.cs
Normal file
@@ -0,0 +1,44 @@
|
||||
#region Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
// Web: https://www.technosoftware.com
|
||||
//
|
||||
// The source code in this file is covered under a dual-license scenario:
|
||||
// - Owner of a purchased license: SCLA 1.0
|
||||
// - GPL V3: everybody else
|
||||
//
|
||||
// SCLA license terms accompanied with this source code.
|
||||
// See SCLA 1.0: https://technosoftware.com/license/Source_Code_License_Agreement.pdf
|
||||
//
|
||||
// GNU General Public License as published by the Free Software Foundation;
|
||||
// version 3 of the License are accompanied with this source code.
|
||||
// See https://technosoftware.com/license/GPLv3License.txt
|
||||
//
|
||||
// This source code is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//-----------------------------------------------------------------------------
|
||||
#endregion Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
|
||||
#region Using Directives
|
||||
#endregion
|
||||
|
||||
namespace Technosoftware.DaAeHdaClient.Da
|
||||
{
|
||||
/// <summary>
|
||||
/// <para>Defines the possible limit status bits.</para>
|
||||
/// <para>The Limit Field is valid regardless of the Quality and Substatus. In some
|
||||
/// cases such as Sensor Failure it can provide useful diagnostic information.</para>
|
||||
/// </summary>
|
||||
public enum TsDaLimitBits
|
||||
{
|
||||
/// <summary>The value is free to move up or down</summary>
|
||||
None = 0x0,
|
||||
/// <summary>The value has ‘pegged’ at some lower limit</summary>
|
||||
Low = 0x1,
|
||||
/// <summary>The value has ‘pegged’ at some high limit</summary>
|
||||
High = 0x2,
|
||||
/// <summary>The value is a constant and cannot move</summary>
|
||||
Constant = 0x3
|
||||
}
|
||||
}
|
||||
328
Technosoftware/DaAeHdaClient/Da/Property.cs
Normal file
328
Technosoftware/DaAeHdaClient/Da/Property.cs
Normal file
@@ -0,0 +1,328 @@
|
||||
#region Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
// Web: https://www.technosoftware.com
|
||||
//
|
||||
// The source code in this file is covered under a dual-license scenario:
|
||||
// - Owner of a purchased license: SCLA 1.0
|
||||
// - GPL V3: everybody else
|
||||
//
|
||||
// SCLA license terms accompanied with this source code.
|
||||
// See SCLA 1.0: https://technosoftware.com/license/Source_Code_License_Agreement.pdf
|
||||
//
|
||||
// GNU General Public License as published by the Free Software Foundation;
|
||||
// version 3 of the License are accompanied with this source code.
|
||||
// See https://technosoftware.com/license/GPLv3License.txt
|
||||
//
|
||||
// This source code is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//-----------------------------------------------------------------------------
|
||||
#endregion Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
|
||||
#region Using Directives
|
||||
#endregion
|
||||
|
||||
namespace Technosoftware.DaAeHdaClient.Da
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines identifiers for well-known properties.
|
||||
/// </summary>
|
||||
public class TsDaProperty
|
||||
{
|
||||
#region Data Access Properties
|
||||
|
||||
/// <summary><para>Item Canonical DataType</para></summary>
|
||||
public static readonly TsDaPropertyID DATATYPE = new TsDaPropertyID("dataType", 1, OpcNamespace.OPC_DATA_ACCESS);
|
||||
|
||||
/// <summary><para>Item Value</para></summary>
|
||||
/// <remarks>
|
||||
/// Note the type of value returned is as indicated by the "Item Canonical DataType"
|
||||
/// and depends on the item. This will behave like a read from DEVICE.
|
||||
/// </remarks>
|
||||
public static readonly TsDaPropertyID VALUE = new TsDaPropertyID("value", 2, OpcNamespace.OPC_DATA_ACCESS);
|
||||
|
||||
/// <summary><para>Item Quality</para></summary>
|
||||
/// <remarks>(OPCQUALITY stored in an I2). This will behave like a read from DEVICE.</remarks>
|
||||
public static readonly TsDaPropertyID QUALITY = new TsDaPropertyID("quality", 3, OpcNamespace.OPC_DATA_ACCESS);
|
||||
|
||||
/// <summary><para>Item Timestamp</para></summary>
|
||||
/// <remarks>
|
||||
/// (will be converted from FILETIME). This will behave like a read from
|
||||
/// DEVICE.
|
||||
/// </remarks>
|
||||
public static readonly TsDaPropertyID TIMESTAMP = new TsDaPropertyID("timestamp", 4, OpcNamespace.OPC_DATA_ACCESS);
|
||||
|
||||
/// <summary><para>Item Access Rights</para></summary>
|
||||
/// <remarks>(OPCACCESSRIGHTS stored in an I4)</remarks>
|
||||
public static readonly TsDaPropertyID ACCESSRIGHTS = new TsDaPropertyID("accessRights", 5, OpcNamespace.OPC_DATA_ACCESS);
|
||||
|
||||
/// <summary><para>Server Scan Rate</para></summary>
|
||||
/// <remarks>
|
||||
/// In Milliseconds. This represents the fastest rate at which the server could
|
||||
/// obtain data from the underlying data source. The nature of this source is not defined
|
||||
/// but is typically a DCS system, a SCADA system, a PLC via a COMM port or network, a
|
||||
/// Device Network, etc. This value generally represents the ‘best case’ fastest
|
||||
/// RequestedUpdateRate which could be used if this item were added to an OPCGroup.<br/>
|
||||
/// The accuracy of this value (the ability of the server to attain ‘best case’
|
||||
/// performance) can be greatly affected by system load and other factors.
|
||||
/// </remarks>
|
||||
public static readonly TsDaPropertyID SCANRATE = new TsDaPropertyID("scanRate", 6, OpcNamespace.OPC_DATA_ACCESS);
|
||||
|
||||
/// <remarks>
|
||||
/// <para>Indicate the type of Engineering Units (EU) information (if any) contained in
|
||||
/// EUINFO.</para>
|
||||
/// <list type="bullet">
|
||||
/// <item>
|
||||
/// 0 - No EU information available (EUINFO will be VT_EMPTY).
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// 1 - Analog - EUINFO will contain a SAFEARRAY of exactly two doubles
|
||||
/// (VT_ARRAY | VT_R8) corresponding to the LOW and HI EU range.
|
||||
/// </item>
|
||||
/// <item>2 - Enumerated - EUINFO will contain a SAFEARRAY of strings (VT_ARRAY |
|
||||
/// VT_BSTR) which contains a list of strings (Example: “OPEN”, “CLOSE”, “IN
|
||||
/// TRANSIT”, etc.) corresponding to sequential numeric values (0, 1, 2,
|
||||
/// etc.)</item>
|
||||
/// </list>
|
||||
/// </remarks>
|
||||
/// <summary><para>Item EU Type</para></summary>
|
||||
public static readonly TsDaPropertyID EUTYPE = new TsDaPropertyID("euType", 7, OpcNamespace.OPC_DATA_ACCESS);
|
||||
|
||||
/// <summary><para>Item EUInfo</para></summary>
|
||||
/// <value>
|
||||
/// <para>
|
||||
/// If EUTYPE is “Analog” EUINFO will contain a SAFEARRAY of exactly two doubles
|
||||
/// (VT_ARRAY | VT_R8) corresponding to the LOW and HI EU range.
|
||||
/// </para>
|
||||
/// <para>If EUTYPE is “Enumerated” - EUINFO will contain a SAFEARRAY of strings
|
||||
/// (VT_ARRAY | VT_BSTR) which contains a list of strings (Example: “OPEN”, “CLOSE”,
|
||||
/// “IN TRANSIT”, etc.) corresponding to sequential numeric values (0, 1, 2,
|
||||
/// etc.)</para>
|
||||
/// </value>
|
||||
public static readonly TsDaPropertyID EUINFO = new TsDaPropertyID("euInfo", 8, OpcNamespace.OPC_DATA_ACCESS);
|
||||
|
||||
/// <summary>
|
||||
/// <para>EU Units</para>
|
||||
/// <para>e.g. "DEGC" or "GALLONS"</para>
|
||||
/// </summary>
|
||||
public static readonly TsDaPropertyID ENGINEERINGUINTS = new TsDaPropertyID("engineeringUnits", 100, OpcNamespace.OPC_DATA_ACCESS);
|
||||
|
||||
/// <summary>
|
||||
/// <para>Item Description</para>
|
||||
/// <para>e.g. "Evaporator 6 Coolant Temp"</para>
|
||||
/// </summary>
|
||||
public static readonly TsDaPropertyID DESCRIPTION = new TsDaPropertyID("description", 101, OpcNamespace.OPC_DATA_ACCESS);
|
||||
|
||||
/// <summary>
|
||||
/// <para>High EU</para>
|
||||
/// <para>Present only for 'analog' data. This represents the highest value likely to
|
||||
/// be obtained in normal operation and is intended for such use as automatically
|
||||
/// scaling a bargraph display.</para>
|
||||
/// <para>e.g. 1400.0</para>
|
||||
/// </summary>
|
||||
public static readonly TsDaPropertyID HIGHEU = new TsDaPropertyID("highEU", 102, OpcNamespace.OPC_DATA_ACCESS);
|
||||
|
||||
/// <summary>
|
||||
/// <para>Low EU</para>
|
||||
/// <para>Present only for 'analog' data. This represents the lowest value likely to be
|
||||
/// obtained in normal operation and is intended for such use as automatically scaling
|
||||
/// a bargraph display.</para>
|
||||
/// <para>e.g. -200.0</para>
|
||||
/// </summary>
|
||||
public static readonly TsDaPropertyID LOWEU = new TsDaPropertyID("lowEU", 103, OpcNamespace.OPC_DATA_ACCESS);
|
||||
|
||||
/// <summary>
|
||||
/// <para>High Instrument Range</para>
|
||||
/// <para>Present only for ‘analog’ data. This represents the highest value that can be
|
||||
/// returned by the instrument.</para>
|
||||
/// <para>e.g. 9999.9</para>
|
||||
/// </summary>
|
||||
public static readonly TsDaPropertyID HIGHIR = new TsDaPropertyID("highIR", 104, OpcNamespace.OPC_DATA_ACCESS);
|
||||
|
||||
/// <summary>
|
||||
/// <para>Low Instrument Range</para>
|
||||
/// <para>Present only for ‘analog’ data. This represents the lowest value that can be
|
||||
/// returned by the instrument.</para>
|
||||
/// <para>e.g. -9999.9</para>
|
||||
/// </summary>
|
||||
public static readonly TsDaPropertyID LOWIR = new TsDaPropertyID("lowIR", 105, OpcNamespace.OPC_DATA_ACCESS);
|
||||
|
||||
/// <summary>
|
||||
/// <para>Contact Close Label</para>
|
||||
/// <para>Present only for ‘discrete' data. This represents a string to be associated
|
||||
/// with this contact when it is in the closed (non-zero) state</para>
|
||||
/// <para>e.g. "RUN", "CLOSE", "ENABLE", "SAFE" ,etc.</para>
|
||||
/// </summary>
|
||||
public static readonly TsDaPropertyID CLOSELABEL = new TsDaPropertyID("closeLabel", 106, OpcNamespace.OPC_DATA_ACCESS);
|
||||
|
||||
/// <summary>
|
||||
/// <para>Contact Open Label</para>
|
||||
/// <para>Present only for ‘discrete' data. This represents a string to be associated
|
||||
/// with this contact when it is in the open (zero) state</para>
|
||||
/// <para>e.g. "STOP", "OPEN", "DISABLE", "UNSAFE" ,etc.</para>
|
||||
/// </summary>
|
||||
public static readonly TsDaPropertyID OPENLABEL = new TsDaPropertyID("openLabel", 107, OpcNamespace.OPC_DATA_ACCESS);
|
||||
|
||||
/// <summary>
|
||||
/// <para>Item Timezone</para>
|
||||
/// <para>The difference in minutes between the items UTC Timestamp and the local time
|
||||
/// in which the item value was obtained.</para>
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// See the OPCGroup TimeBias property. Also see the WIN32 TIME_ZONE_INFORMATION
|
||||
/// structure.
|
||||
/// </remarks>
|
||||
public static readonly TsDaPropertyID TIMEZONE = new TsDaPropertyID("timeZone", 108, OpcNamespace.OPC_DATA_ACCESS);
|
||||
|
||||
/// <summary>
|
||||
/// <para>Condition Status</para>
|
||||
/// <para>The current alarm or condition status associated with the Item<br/>
|
||||
/// e.g. "NORMAL", "ACTIVE", "HI ALARM", etc</para>
|
||||
/// </summary>
|
||||
public static readonly TsDaPropertyID CONDITION_STATUS = new TsDaPropertyID("conditionStatus", 300, OpcNamespace.OPC_DATA_ACCESS);
|
||||
|
||||
/// <summary>
|
||||
/// <para>Alarm Quick Help</para>
|
||||
/// <para>A short text string providing a brief set of instructions for the operator to
|
||||
/// follow when this alarm occurs.</para>
|
||||
/// </summary>
|
||||
public static readonly TsDaPropertyID ALARM_QUICK_HELP = new TsDaPropertyID("alarmQuickHelp", 301, OpcNamespace.OPC_DATA_ACCESS);
|
||||
|
||||
/// <summary>
|
||||
/// <para>Alarm Area List</para>
|
||||
/// <para>An array of stings indicating the plant or alarm areas which include this
|
||||
/// ItemID.</para>
|
||||
/// </summary>
|
||||
public static readonly TsDaPropertyID ALARM_AREA_LIST = new TsDaPropertyID("alarmAreaList", 302, OpcNamespace.OPC_DATA_ACCESS);
|
||||
|
||||
/// <summary>
|
||||
/// <para>Primary Alarm Area</para>
|
||||
/// <para>A string indicating the primary plant or alarm area including this
|
||||
/// ItemID</para>
|
||||
/// </summary>
|
||||
public static readonly TsDaPropertyID PRIMARY_ALARM_AREA = new TsDaPropertyID("primaryAlarmArea", 303, OpcNamespace.OPC_DATA_ACCESS);
|
||||
|
||||
/// <summary>
|
||||
/// <para>Condition Logic</para>
|
||||
/// <para>An arbitrary string describing the test being performed.</para>
|
||||
/// <para>e.g. "High Limit Exceeded" or "TAG.PV >= TAG.HILIM"</para>
|
||||
/// </summary>
|
||||
public static readonly TsDaPropertyID CONDITION_LOGIC = new TsDaPropertyID("conditionLogic", 304, OpcNamespace.OPC_DATA_ACCESS);
|
||||
|
||||
/// <summary>
|
||||
/// <para>Limit Exceeded</para>
|
||||
/// <para>For multistate alarms, the condition exceeded</para>
|
||||
/// <para>e.g. HIHI, HI, LO, LOLO</para>
|
||||
/// </summary>
|
||||
public static readonly TsDaPropertyID LIMIT_EXCEEDED = new TsDaPropertyID("limitExceeded", 305, OpcNamespace.OPC_DATA_ACCESS);
|
||||
|
||||
/// <summary>Deadband</summary>
|
||||
public static readonly TsDaPropertyID DEADBAND = new TsDaPropertyID("deadband", 306, OpcNamespace.OPC_DATA_ACCESS);
|
||||
|
||||
/// <summary>HiHi limit</summary>
|
||||
public static readonly TsDaPropertyID HIHI_LIMIT = new TsDaPropertyID("hihiLimit", 307, OpcNamespace.OPC_DATA_ACCESS);
|
||||
|
||||
/// <summary>Hi Limit</summary>
|
||||
public static readonly TsDaPropertyID HI_LIMIT = new TsDaPropertyID("hiLimit", 308, OpcNamespace.OPC_DATA_ACCESS);
|
||||
|
||||
/// <summary>Lo Limit</summary>
|
||||
public static readonly TsDaPropertyID LO_LIMIT = new TsDaPropertyID("loLimit", 309, OpcNamespace.OPC_DATA_ACCESS);
|
||||
|
||||
/// <summary>LoLo Limit</summary>
|
||||
public static readonly TsDaPropertyID LOLO_LIMIT = new TsDaPropertyID("loloLimit", 310, OpcNamespace.OPC_DATA_ACCESS);
|
||||
|
||||
/// <summary>Rate of Change Limit</summary>
|
||||
public static readonly TsDaPropertyID RATE_CHANGE_LIMIT = new TsDaPropertyID("rangeOfChangeLimit", 311, OpcNamespace.OPC_DATA_ACCESS);
|
||||
|
||||
/// <summary>Deviation Limit</summary>
|
||||
public static readonly TsDaPropertyID DEVIATION_LIMIT = new TsDaPropertyID("deviationLimit", 312, OpcNamespace.OPC_DATA_ACCESS);
|
||||
|
||||
/// <summary>
|
||||
/// <para>Sound File</para>
|
||||
/// <para>e.g. C:\MEDIA\FIC101.WAV, or .MID</para>
|
||||
/// </summary>
|
||||
public static readonly TsDaPropertyID SOUNDFILE = new TsDaPropertyID("soundFile", 313, OpcNamespace.OPC_DATA_ACCESS);
|
||||
#endregion
|
||||
|
||||
#region Complex Data Properties
|
||||
/// <summary>
|
||||
/// <para>Type System ID</para>
|
||||
/// <para>Complex Data Property</para>
|
||||
/// </summary>
|
||||
public static readonly TsDaPropertyID TYPE_SYSTEM_ID = new TsDaPropertyID("typeSystemID", 600, OpcNamespace.OPC_DATA_ACCESS);
|
||||
|
||||
/// <summary>
|
||||
/// <para>Dictionary ID</para>
|
||||
/// <para>Complex Data Property</para>
|
||||
/// </summary>
|
||||
public static readonly TsDaPropertyID DICTIONARY_ID = new TsDaPropertyID("dictionaryID", 601, OpcNamespace.OPC_DATA_ACCESS);
|
||||
|
||||
/// <summary>
|
||||
/// <para>Type ID</para>
|
||||
/// <para>Complex Data Property</para>
|
||||
/// </summary>
|
||||
public static readonly TsDaPropertyID TYPE_ID = new TsDaPropertyID("typeID", 602, OpcNamespace.OPC_DATA_ACCESS);
|
||||
|
||||
/// <summary>
|
||||
/// <para>Dictionary</para>
|
||||
/// <para>Complex Data Property</para>
|
||||
/// </summary>
|
||||
public static readonly TsDaPropertyID DICTIONARY = new TsDaPropertyID("dictionary", 603, OpcNamespace.OPC_DATA_ACCESS);
|
||||
|
||||
/// <summary>
|
||||
/// <para>Type description</para>
|
||||
/// <para>Complex Data Property</para>
|
||||
/// </summary>
|
||||
public static readonly TsDaPropertyID TYPE_DESCRIPTION = new TsDaPropertyID("typeDescription", 604, OpcNamespace.OPC_DATA_ACCESS);
|
||||
|
||||
/// <summary>
|
||||
/// <para>Consistency Window</para>
|
||||
/// <para>Complex Data Property</para>
|
||||
/// </summary>
|
||||
public static readonly TsDaPropertyID CONSISTENCY_WINDOW = new TsDaPropertyID("consistencyWindow", 605, OpcNamespace.OPC_DATA_ACCESS);
|
||||
|
||||
/// <summary>
|
||||
/// <para>Write Behaviour</para>
|
||||
/// <para>Complex Data Property, defaults to “All or Nothing” if the complex data item
|
||||
/// is writable. Not used for Read-Only items.</para>
|
||||
/// </summary>
|
||||
public static readonly TsDaPropertyID WRITE_BEHAVIOR = new TsDaPropertyID("writeBehavior", 606, OpcNamespace.OPC_DATA_ACCESS);
|
||||
|
||||
/// <summary>
|
||||
/// <para>Unconverted Item ID</para>
|
||||
/// <para>Complex Data Property, the ID of the item that exposes the same complex data
|
||||
/// value in its native format. This property is mandatory for items that implement
|
||||
/// complex data type conversions.</para>
|
||||
/// </summary>
|
||||
public static readonly TsDaPropertyID UNCONVERTED_ITEM_ID = new TsDaPropertyID("unconvertedItemID", 607, OpcNamespace.OPC_DATA_ACCESS);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// <para>Unfiltered Item ID</para>
|
||||
/// <para>Complex Data Property, the ID the item that exposes the same complex data
|
||||
/// value without any data filter or with the default query applied to it. It is
|
||||
/// mandatory for items that implement complex data filters or queries.</para>
|
||||
/// </summary>
|
||||
public static readonly TsDaPropertyID UNFILTERED_ITEM_ID = new TsDaPropertyID("unfilteredItemID", 608, OpcNamespace.OPC_DATA_ACCESS);
|
||||
|
||||
/// <summary>
|
||||
/// <para>Data Filter Value</para>
|
||||
/// <para>Complex Data Property, the value of the filter that is currently applied to
|
||||
/// the item. It is mandatory for items that implement complex data filters or
|
||||
/// queries.</para>
|
||||
/// </summary>
|
||||
public static readonly TsDaPropertyID DATA_FILTER_VALUE = new TsDaPropertyID("dataFilterValue", 609, OpcNamespace.OPC_DATA_ACCESS);
|
||||
#endregion
|
||||
|
||||
#region XML Data Access Properties
|
||||
/// <remarks/>
|
||||
public static readonly TsDaPropertyID MINIMUM_VALUE = new TsDaPropertyID("minimumValue", 109, OpcNamespace.OPC_DATA_ACCESS);
|
||||
/// <remarks/>
|
||||
public static readonly TsDaPropertyID MAXIMUM_VALUE = new TsDaPropertyID("maximumValue", 110, OpcNamespace.OPC_DATA_ACCESS);
|
||||
/// <remarks/>
|
||||
public static readonly TsDaPropertyID VALUE_PRECISION = new TsDaPropertyID("valuePrecision", 111, OpcNamespace.OPC_DATA_ACCESS);
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
200
Technosoftware/DaAeHdaClient/Da/PropertyDescription.cs
Normal file
200
Technosoftware/DaAeHdaClient/Da/PropertyDescription.cs
Normal file
@@ -0,0 +1,200 @@
|
||||
#region Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
// Web: https://www.technosoftware.com
|
||||
//
|
||||
// The source code in this file is covered under a dual-license scenario:
|
||||
// - Owner of a purchased license: SCLA 1.0
|
||||
// - GPL V3: everybody else
|
||||
//
|
||||
// SCLA license terms accompanied with this source code.
|
||||
// See SCLA 1.0: https://technosoftware.com/license/Source_Code_License_Agreement.pdf
|
||||
//
|
||||
// GNU General Public License as published by the Free Software Foundation;
|
||||
// version 3 of the License are accompanied with this source code.
|
||||
// See https://technosoftware.com/license/GPLv3License.txt
|
||||
//
|
||||
// This source code is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//-----------------------------------------------------------------------------
|
||||
#endregion Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
|
||||
#region Using Directives
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Reflection;
|
||||
#endregion
|
||||
|
||||
namespace Technosoftware.DaAeHdaClient.Da
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes an item property.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class TsDaPropertyDescription
|
||||
{
|
||||
#region Constructors, Destructor, Initialization
|
||||
/// <summary>
|
||||
/// Initializes the object with the specified values.
|
||||
/// </summary>
|
||||
public TsDaPropertyDescription(TsDaPropertyID id, Type type, string name)
|
||||
{
|
||||
ID = id;
|
||||
Type = type;
|
||||
Name = name;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
/// <summary>
|
||||
/// The unique identifier for the property.
|
||||
/// </summary>
|
||||
public TsDaPropertyID ID { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The .NET data type for the property.
|
||||
/// </summary>
|
||||
public Type Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The short description defined in the OPC specifications.
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
#endregion
|
||||
|
||||
#region Data Access Properties
|
||||
/// <remarks/>
|
||||
public static readonly TsDaPropertyDescription DATATYPE = new TsDaPropertyDescription(TsDaProperty.DATATYPE, typeof(Type), "Item Canonical DataType");
|
||||
/// <remarks/>
|
||||
public static readonly TsDaPropertyDescription VALUE = new TsDaPropertyDescription(TsDaProperty.VALUE, typeof(object), "Item Value");
|
||||
/// <remarks/>
|
||||
public static readonly TsDaPropertyDescription QUALITY = new TsDaPropertyDescription(TsDaProperty.QUALITY, typeof(TsCDaQuality), "Item Quality");
|
||||
/// <remarks/>
|
||||
public static readonly TsDaPropertyDescription TIMESTAMP = new TsDaPropertyDescription(TsDaProperty.TIMESTAMP, typeof(DateTime), "Item Timestamp");
|
||||
/// <remarks/>
|
||||
public static readonly TsDaPropertyDescription ACCESSRIGHTS = new TsDaPropertyDescription(TsDaProperty.ACCESSRIGHTS, typeof(TsDaAccessRights), "Item Access Rights");
|
||||
/// <remarks/>
|
||||
public static readonly TsDaPropertyDescription SCANRATE = new TsDaPropertyDescription(TsDaProperty.SCANRATE, typeof(float), "Server Scan Rate");
|
||||
/// <remarks/>
|
||||
public static readonly TsDaPropertyDescription EUTYPE = new TsDaPropertyDescription(TsDaProperty.EUTYPE, typeof(TsDaEuType), "Item EU Type");
|
||||
/// <remarks/>
|
||||
public static readonly TsDaPropertyDescription EUINFO = new TsDaPropertyDescription(TsDaProperty.EUINFO, typeof(string[]), "Item EU Info");
|
||||
/// <remarks/>
|
||||
public static readonly TsDaPropertyDescription ENGINEERINGUINTS = new TsDaPropertyDescription(TsDaProperty.ENGINEERINGUINTS, typeof(string), "EU Units");
|
||||
/// <remarks/>
|
||||
public static readonly TsDaPropertyDescription DESCRIPTION = new TsDaPropertyDescription(TsDaProperty.DESCRIPTION, typeof(string), "Item Description");
|
||||
/// <remarks/>
|
||||
public static readonly TsDaPropertyDescription HIGHEU = new TsDaPropertyDescription(TsDaProperty.HIGHEU, typeof(double), "High EU");
|
||||
/// <remarks/>
|
||||
public static readonly TsDaPropertyDescription LOWEU = new TsDaPropertyDescription(TsDaProperty.LOWEU, typeof(double), "Low EU");
|
||||
/// <remarks/>
|
||||
public static readonly TsDaPropertyDescription HIGHIR = new TsDaPropertyDescription(TsDaProperty.HIGHIR, typeof(double), "High Instrument Range");
|
||||
/// <remarks/>
|
||||
public static readonly TsDaPropertyDescription LOWIR = new TsDaPropertyDescription(TsDaProperty.LOWIR, typeof(double), "Low Instrument Range");
|
||||
/// <remarks/>
|
||||
public static readonly TsDaPropertyDescription CLOSELABEL = new TsDaPropertyDescription(TsDaProperty.CLOSELABEL, typeof(string), "Contact Close Label");
|
||||
/// <remarks/>
|
||||
public static readonly TsDaPropertyDescription OPENLABEL = new TsDaPropertyDescription(TsDaProperty.OPENLABEL, typeof(string), "Contact Open Label");
|
||||
/// <remarks/>
|
||||
public static readonly TsDaPropertyDescription TIMEZONE = new TsDaPropertyDescription(TsDaProperty.TIMEZONE, typeof(int), "Timezone");
|
||||
/// <remarks/>
|
||||
public static readonly TsDaPropertyDescription CONDITION_STATUS = new TsDaPropertyDescription(TsDaProperty.CONDITION_STATUS, typeof(string), "Condition Status");
|
||||
/// <remarks/>
|
||||
public static readonly TsDaPropertyDescription ALARM_QUICK_HELP = new TsDaPropertyDescription(TsDaProperty.ALARM_QUICK_HELP, typeof(string), "Alarm Quick Help");
|
||||
/// <remarks/>
|
||||
public static readonly TsDaPropertyDescription ALARM_AREA_LIST = new TsDaPropertyDescription(TsDaProperty.ALARM_AREA_LIST, typeof(string), "Alarm Area List");
|
||||
/// <remarks/>
|
||||
public static readonly TsDaPropertyDescription PRIMARY_ALARM_AREA = new TsDaPropertyDescription(TsDaProperty.PRIMARY_ALARM_AREA, typeof(string), "Primary Alarm Area");
|
||||
/// <remarks/>
|
||||
public static readonly TsDaPropertyDescription CONDITION_LOGIC = new TsDaPropertyDescription(TsDaProperty.CONDITION_LOGIC, typeof(string), "Condition Logic");
|
||||
/// <remarks/>
|
||||
public static readonly TsDaPropertyDescription LIMIT_EXCEEDED = new TsDaPropertyDescription(TsDaProperty.LIMIT_EXCEEDED, typeof(string), "Limit Exceeded");
|
||||
/// <remarks/>
|
||||
public static readonly TsDaPropertyDescription DEADBAND = new TsDaPropertyDescription(TsDaProperty.DEADBAND, typeof(double), "Deadband");
|
||||
/// <remarks/>
|
||||
public static readonly TsDaPropertyDescription HIHI_LIMIT = new TsDaPropertyDescription(TsDaProperty.HIHI_LIMIT, typeof(double), "HiHi Limit");
|
||||
/// <remarks/>
|
||||
public static readonly TsDaPropertyDescription HI_LIMIT = new TsDaPropertyDescription(TsDaProperty.HI_LIMIT, typeof(double), "Hi Limit");
|
||||
/// <remarks/>
|
||||
public static readonly TsDaPropertyDescription LO_LIMIT = new TsDaPropertyDescription(TsDaProperty.LO_LIMIT, typeof(double), "Lo Limit");
|
||||
/// <remarks/>
|
||||
public static readonly TsDaPropertyDescription LOLO_LIMIT = new TsDaPropertyDescription(TsDaProperty.LOLO_LIMIT, typeof(double), "LoLo Limit");
|
||||
/// <remarks/>
|
||||
public static readonly TsDaPropertyDescription RATE_CHANGE_LIMIT = new TsDaPropertyDescription(TsDaProperty.RATE_CHANGE_LIMIT, typeof(double), "Rate of Change Limit");
|
||||
/// <remarks/>
|
||||
public static readonly TsDaPropertyDescription DEVIATION_LIMIT = new TsDaPropertyDescription(TsDaProperty.DEVIATION_LIMIT, typeof(double), "Deviation Limit");
|
||||
/// <remarks/>
|
||||
public static readonly TsDaPropertyDescription SOUNDFILE = new TsDaPropertyDescription(TsDaProperty.SOUNDFILE, typeof(string), "Sound File");
|
||||
#endregion
|
||||
|
||||
#region Complex Data Properties
|
||||
/// <remarks/>
|
||||
public static readonly TsDaPropertyDescription TYPE_SYSTEM_ID = new TsDaPropertyDescription(TsDaProperty.TYPE_SYSTEM_ID, typeof(string), "Type System ID");
|
||||
/// <remarks/>
|
||||
public static readonly TsDaPropertyDescription DICTIONARY_ID = new TsDaPropertyDescription(TsDaProperty.DICTIONARY_ID, typeof(string), "Dictionary ID");
|
||||
/// <remarks/>
|
||||
public static readonly TsDaPropertyDescription TYPE_ID = new TsDaPropertyDescription(TsDaProperty.TYPE_ID, typeof(string), "Type ID");
|
||||
/// <remarks/>
|
||||
public static readonly TsDaPropertyDescription DICTIONARY = new TsDaPropertyDescription(TsDaProperty.DICTIONARY, typeof(object), "Dictionary");
|
||||
/// <remarks/>
|
||||
public static readonly TsDaPropertyDescription TYPE_DESCRIPTION = new TsDaPropertyDescription(TsDaProperty.TYPE_DESCRIPTION, typeof(string), "Type Description");
|
||||
/// <remarks/>
|
||||
public static readonly TsDaPropertyDescription CONSISTENCY_WINDOW = new TsDaPropertyDescription(TsDaProperty.CONSISTENCY_WINDOW, typeof(string), "Consistency Window");
|
||||
/// <remarks/>
|
||||
public static readonly TsDaPropertyDescription WRITE_BEHAVIOR = new TsDaPropertyDescription(TsDaProperty.WRITE_BEHAVIOR, typeof(string), "Write Behavior");
|
||||
/// <remarks/>
|
||||
public static readonly TsDaPropertyDescription UNCONVERTED_ITEM_ID = new TsDaPropertyDescription(TsDaProperty.UNCONVERTED_ITEM_ID, typeof(string), "Unconverted Item ID");
|
||||
/// <remarks/>
|
||||
public static readonly TsDaPropertyDescription UNFILTERED_ITEM_ID = new TsDaPropertyDescription(TsDaProperty.UNFILTERED_ITEM_ID, typeof(string), "Unfiltered Item ID");
|
||||
/// <remarks/>
|
||||
public static readonly TsDaPropertyDescription DATA_FILTER_VALUE = new TsDaPropertyDescription(TsDaProperty.DATA_FILTER_VALUE, typeof(string), "Data Filter Value");
|
||||
#endregion
|
||||
|
||||
#region Object Member Overrides
|
||||
/// <summary>
|
||||
/// Converts the description to a string.
|
||||
/// </summary>
|
||||
public override string ToString()
|
||||
{
|
||||
return Name;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Public Methods
|
||||
/// <summary>
|
||||
/// Returns the description for the specified property.
|
||||
/// </summary>
|
||||
public static TsDaPropertyDescription Find(TsDaPropertyID id)
|
||||
{
|
||||
var fields = typeof(TsDaPropertyDescription).GetFields(BindingFlags.Static | BindingFlags.Public);
|
||||
|
||||
foreach (var field in fields)
|
||||
{
|
||||
var property = (TsDaPropertyDescription)field.GetValue(typeof(TsDaPropertyDescription));
|
||||
|
||||
if (property.ID == id)
|
||||
{
|
||||
return property;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns an array of all well-known property descriptions.
|
||||
/// </summary>
|
||||
public static TsDaPropertyDescription[] Enumerate()
|
||||
{
|
||||
var values = new ArrayList();
|
||||
|
||||
var fields = typeof(TsDaPropertyDescription).GetFields(BindingFlags.Static | BindingFlags.Public);
|
||||
|
||||
Array.ForEach(fields, field => values.Add(field.GetValue(typeof(TsDaPropertyDescription))));
|
||||
|
||||
return (TsDaPropertyDescription[])values.ToArray(typeof(TsDaPropertyDescription));
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
198
Technosoftware/DaAeHdaClient/Da/PropertyID.cs
Normal file
198
Technosoftware/DaAeHdaClient/Da/PropertyID.cs
Normal file
@@ -0,0 +1,198 @@
|
||||
#region Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
// Web: https://www.technosoftware.com
|
||||
//
|
||||
// The source code in this file is covered under a dual-license scenario:
|
||||
// - Owner of a purchased license: SCLA 1.0
|
||||
// - GPL V3: everybody else
|
||||
//
|
||||
// SCLA license terms accompanied with this source code.
|
||||
// See SCLA 1.0: https://technosoftware.com/license/Source_Code_License_Agreement.pdf
|
||||
//
|
||||
// GNU General Public License as published by the Free Software Foundation;
|
||||
// version 3 of the License are accompanied with this source code.
|
||||
// See https://technosoftware.com/license/GPLv3License.txt
|
||||
//
|
||||
// This source code is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//-----------------------------------------------------------------------------
|
||||
#endregion Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
|
||||
#region Using Directives
|
||||
using System;
|
||||
using System.Xml;
|
||||
using System.Runtime.Serialization;
|
||||
#endregion
|
||||
|
||||
namespace Technosoftware.DaAeHdaClient.Da
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains a unique identifier for a property.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public struct TsDaPropertyID : ISerializable
|
||||
{
|
||||
#region Names Class
|
||||
/// <summary>
|
||||
/// A set of names for fields used in serialization.
|
||||
/// </summary>
|
||||
private class Names
|
||||
{
|
||||
internal const string Name = "NA";
|
||||
internal const string Namespace = "NS";
|
||||
internal const string Code = "CO";
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Fields
|
||||
private int code_;
|
||||
private XmlQualifiedName qualifiedName_;
|
||||
#endregion
|
||||
|
||||
#region Constructors, Destructor, Initialization
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a property identified by a qualified name.
|
||||
/// </summary>
|
||||
public TsDaPropertyID(XmlQualifiedName name) { qualifiedName_ = name; code_ = 0; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a property identified by an integer.
|
||||
/// </summary>
|
||||
public TsDaPropertyID(int code) { qualifiedName_ = null; code_ = code; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a property identified by a property description.
|
||||
/// </summary>
|
||||
public TsDaPropertyID(string name, int code, string ns) { qualifiedName_ = new XmlQualifiedName(name, ns); code_ = code; }
|
||||
|
||||
///<remarks>
|
||||
/// During deserialization, SerializationInfo is passed to the class using the constructor provided for this purpose. Any visibility
|
||||
/// constraints placed on the constructor are ignored when the object is deserialized; so you can mark the class as public,
|
||||
/// protected, internal, or private. However, it is best practice to make the constructor protected unless the class is sealed, in which case
|
||||
/// the constructor should be marked private. The constructor should also perform thorough input validation. To avoid misuse by malicious code,
|
||||
/// the constructor should enforce the same security checks and permissions required to obtain an instance of the class using any other
|
||||
/// constructor.
|
||||
/// </remarks>
|
||||
/// <summary>
|
||||
/// Constructs a server by de-serializing its OpcUrl from the stream.
|
||||
/// </summary>
|
||||
private TsDaPropertyID(SerializationInfo info, StreamingContext context)
|
||||
{
|
||||
var enumerator = info.GetEnumerator();
|
||||
var name = "";
|
||||
var ns = "";
|
||||
enumerator.Reset();
|
||||
while (enumerator.MoveNext())
|
||||
{
|
||||
if (enumerator.Current.Name.Equals(Names.Name))
|
||||
{
|
||||
name = (string)enumerator.Current.Value;
|
||||
continue;
|
||||
}
|
||||
if (enumerator.Current.Name.Equals(Names.Namespace))
|
||||
{
|
||||
ns = (string)enumerator.Current.Value;
|
||||
}
|
||||
}
|
||||
qualifiedName_ = new XmlQualifiedName(name, ns);
|
||||
code_ = (int)info.GetValue(Names.Code, typeof(int));
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
/// <summary>
|
||||
/// Used for properties identified by a qualified name.
|
||||
/// </summary>
|
||||
public XmlQualifiedName Name => qualifiedName_;
|
||||
|
||||
/// <summary>
|
||||
/// Used for properties identified by a integer.
|
||||
/// </summary>
|
||||
public int Code => code_;
|
||||
#endregion
|
||||
|
||||
#region Public Methods
|
||||
/// <summary>
|
||||
/// Returns true if the objects are equal.
|
||||
/// </summary>
|
||||
public static bool operator ==(TsDaPropertyID a, TsDaPropertyID b)
|
||||
{
|
||||
return a.Equals(b);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the objects are not equal.
|
||||
/// </summary>
|
||||
public static bool operator !=(TsDaPropertyID a, TsDaPropertyID b)
|
||||
{
|
||||
return !a.Equals(b);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Serialization Functions
|
||||
/// <summary>
|
||||
/// Serializes a server into a stream.
|
||||
/// </summary>
|
||||
public void GetObjectData(SerializationInfo info, StreamingContext context)
|
||||
{
|
||||
if (qualifiedName_ != null)
|
||||
{
|
||||
info.AddValue(Names.Name, qualifiedName_.Name);
|
||||
info.AddValue(Names.Namespace, qualifiedName_.Namespace);
|
||||
}
|
||||
info.AddValue(Names.Code, code_);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Object Member Overrides
|
||||
/// <summary>
|
||||
/// Returns true if the target object is equal to the object.
|
||||
/// </summary>
|
||||
public override bool Equals(object target)
|
||||
{
|
||||
if (target != null && target.GetType() == typeof(TsDaPropertyID))
|
||||
{
|
||||
var propertyId = (TsDaPropertyID)target;
|
||||
|
||||
// compare by integer if both specify valid integers.
|
||||
if (propertyId.Code != 0 && Code != 0)
|
||||
{
|
||||
return (propertyId.Code == Code);
|
||||
}
|
||||
|
||||
// compare by name if both specify valid names.
|
||||
if (propertyId.Name != null && Name != null)
|
||||
{
|
||||
return (propertyId.Name == Name);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a useful hash code for the object.
|
||||
/// </summary>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
if (Code != 0) return Code.GetHashCode();
|
||||
if (Name != null) return Name.GetHashCode();
|
||||
return base.GetHashCode();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the property id to a string.
|
||||
/// </summary>
|
||||
public override string ToString()
|
||||
{
|
||||
if (Name != null && Code != 0) return $"{Name.Name} ({Code})";
|
||||
if (Name != null) return Name.Name;
|
||||
if (Code != 0) return $"{Code}";
|
||||
return "";
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
251
Technosoftware/DaAeHdaClient/Da/Quality.cs
Normal file
251
Technosoftware/DaAeHdaClient/Da/Quality.cs
Normal file
@@ -0,0 +1,251 @@
|
||||
#region Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
// Web: https://www.technosoftware.com
|
||||
//
|
||||
// The source code in this file is covered under a dual-license scenario:
|
||||
// - Owner of a purchased license: SCLA 1.0
|
||||
// - GPL V3: everybody else
|
||||
//
|
||||
// SCLA license terms accompanied with this source code.
|
||||
// See SCLA 1.0: https://technosoftware.com/license/Source_Code_License_Agreement.pdf
|
||||
//
|
||||
// GNU General Public License as published by the Free Software Foundation;
|
||||
// version 3 of the License are accompanied with this source code.
|
||||
// See https://technosoftware.com/license/GPLv3License.txt
|
||||
//
|
||||
// This source code is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//-----------------------------------------------------------------------------
|
||||
#endregion Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
|
||||
#region Using Directives
|
||||
using System;
|
||||
#endregion
|
||||
|
||||
namespace Technosoftware.DaAeHdaClient.Da
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Contains the quality field for an item value.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public struct TsCDaQuality
|
||||
{
|
||||
#region Fields
|
||||
private TsDaQualityBits qualityBits_;
|
||||
private TsDaLimitBits limitBits_;
|
||||
private byte vendorBits_;
|
||||
#endregion
|
||||
|
||||
#region Constructors, Destructor, Initialization
|
||||
/// <summary>
|
||||
/// Initializes the object with the specified quality.
|
||||
/// </summary>
|
||||
public TsCDaQuality(TsDaQualityBits quality)
|
||||
{
|
||||
qualityBits_ = quality;
|
||||
limitBits_ = TsDaLimitBits.None;
|
||||
vendorBits_ = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the object from the contents of a 16 bit integer.
|
||||
/// </summary>
|
||||
public TsCDaQuality(short code)
|
||||
{
|
||||
qualityBits_ = (TsDaQualityBits)(code & (short)TsDaQualityMasks.QualityMask);
|
||||
limitBits_ = (TsDaLimitBits)(code & (short)TsDaQualityMasks.LimitMask);
|
||||
vendorBits_ = (byte)((code & (short)TsDaQualityMasks.VendorMask) >> 8);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
/// <summary>
|
||||
/// The value in the quality bits field.
|
||||
/// </summary>
|
||||
public TsDaQualityBits QualityBits
|
||||
{
|
||||
get => qualityBits_;
|
||||
set => qualityBits_ = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The value in the limit bits field.
|
||||
/// </summary>
|
||||
public TsDaLimitBits LimitBits
|
||||
{
|
||||
get => limitBits_;
|
||||
set => limitBits_ = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The value in the quality bits field.
|
||||
/// </summary>
|
||||
public byte VendorBits
|
||||
{
|
||||
get => vendorBits_;
|
||||
set => vendorBits_ = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A 'good' quality value.
|
||||
/// </summary>
|
||||
public static readonly TsCDaQuality Good = new TsCDaQuality(TsDaQualityBits.Good);
|
||||
|
||||
/// <summary>
|
||||
/// An 'bad' quality value.
|
||||
/// </summary>
|
||||
public static readonly TsCDaQuality Bad = new TsCDaQuality(TsDaQualityBits.Bad);
|
||||
#endregion
|
||||
|
||||
#region Public Methods
|
||||
/// <summary>
|
||||
/// Returns the quality as a 16 bit integer.
|
||||
/// </summary>
|
||||
public short GetCode()
|
||||
{
|
||||
ushort code = 0;
|
||||
|
||||
code |= (ushort)QualityBits;
|
||||
code |= (ushort)LimitBits;
|
||||
code |= (ushort)(VendorBits << 8);
|
||||
|
||||
return (code <= short.MaxValue) ? (short)code : (short)-((ushort.MaxValue + 1 - code));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the quality from a 16 bit integer.
|
||||
/// </summary>
|
||||
public void SetCode(short code)
|
||||
{
|
||||
qualityBits_ = (TsDaQualityBits)(code & (short)TsDaQualityMasks.QualityMask);
|
||||
limitBits_ = (TsDaLimitBits)(code & (short)TsDaQualityMasks.LimitMask);
|
||||
vendorBits_ = (byte)((code & (short)TsDaQualityMasks.VendorMask) >> 8);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the objects are equal.
|
||||
/// </summary>
|
||||
public static bool operator ==(TsCDaQuality a, TsCDaQuality b)
|
||||
{
|
||||
return a.Equals(b);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the objects are not equal.
|
||||
/// </summary>
|
||||
public static bool operator !=(TsCDaQuality a, TsCDaQuality b)
|
||||
{
|
||||
return !a.Equals(b);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Object Member Overrides
|
||||
/// <summary>
|
||||
/// Converts a quality to a string with the format: 'quality[limit]:vendor'.
|
||||
/// </summary>
|
||||
public override string ToString()
|
||||
{
|
||||
string text = null;
|
||||
|
||||
switch (QualityBits)
|
||||
{
|
||||
case TsDaQualityBits.Good:
|
||||
text += "(Good";
|
||||
break;
|
||||
case TsDaQualityBits.GoodLocalOverride:
|
||||
text += "(Good:Local Override";
|
||||
break;
|
||||
case TsDaQualityBits.Bad:
|
||||
text += "(Bad";
|
||||
break;
|
||||
case TsDaQualityBits.BadConfigurationError:
|
||||
text += "(Bad:Configuration Error";
|
||||
break;
|
||||
case TsDaQualityBits.BadNotConnected:
|
||||
text += "(Bad:Not Connected";
|
||||
break;
|
||||
case TsDaQualityBits.BadDeviceFailure:
|
||||
text += "(Bad:Device Failure";
|
||||
break;
|
||||
case TsDaQualityBits.BadSensorFailure:
|
||||
text += "(Bad:Sensor Failure";
|
||||
break;
|
||||
case TsDaQualityBits.BadLastKnownValue:
|
||||
text += "(Bad:Last Known Value";
|
||||
break;
|
||||
case TsDaQualityBits.BadCommFailure:
|
||||
text += "(Bad:Communication Failure";
|
||||
break;
|
||||
case TsDaQualityBits.BadOutOfService:
|
||||
text += "(Bad:Out of Service";
|
||||
break;
|
||||
case TsDaQualityBits.BadWaitingForInitialData:
|
||||
text += "(Bad:Waiting for Initial Data";
|
||||
break;
|
||||
case TsDaQualityBits.Uncertain:
|
||||
text += "(Uncertain";
|
||||
break;
|
||||
case TsDaQualityBits.UncertainLastUsableValue:
|
||||
text += "(Uncertain:Last Usable Value";
|
||||
break;
|
||||
case TsDaQualityBits.UncertainSensorNotAccurate:
|
||||
text += "(Uncertain:Sensor not Accurate";
|
||||
break;
|
||||
case TsDaQualityBits.UncertainEUExceeded:
|
||||
text += "(Uncertain:Engineering Unit exceeded";
|
||||
break;
|
||||
case TsDaQualityBits.UncertainSubNormal:
|
||||
text += "(Uncertain:Sub Normal";
|
||||
break;
|
||||
}
|
||||
|
||||
if (LimitBits != TsDaLimitBits.None)
|
||||
{
|
||||
text += $":[{LimitBits.ToString()}]";
|
||||
}
|
||||
else
|
||||
{
|
||||
text += ":Not Limited";
|
||||
}
|
||||
|
||||
if (VendorBits != 0)
|
||||
{
|
||||
text += $":{VendorBits,0:X})";
|
||||
}
|
||||
else
|
||||
{
|
||||
text += ")";
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified Object is equal to the current Quality
|
||||
/// </summary>
|
||||
public override bool Equals(object target)
|
||||
{
|
||||
if (target == null || target.GetType() != typeof(TsCDaQuality)) return false;
|
||||
|
||||
var quality = (TsCDaQuality)target;
|
||||
|
||||
if (QualityBits != quality.QualityBits) return false;
|
||||
if (LimitBits != quality.LimitBits) return false;
|
||||
if (VendorBits != quality.VendorBits) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns hash code for the current Quality.
|
||||
/// </summary>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return GetCode();
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
114
Technosoftware/DaAeHdaClient/Da/QualityBits.cs
Normal file
114
Technosoftware/DaAeHdaClient/Da/QualityBits.cs
Normal file
@@ -0,0 +1,114 @@
|
||||
#region Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
// Web: https://www.technosoftware.com
|
||||
//
|
||||
// The source code in this file is covered under a dual-license scenario:
|
||||
// - Owner of a purchased license: SCLA 1.0
|
||||
// - GPL V3: everybody else
|
||||
//
|
||||
// SCLA license terms accompanied with this source code.
|
||||
// See SCLA 1.0: https://technosoftware.com/license/Source_Code_License_Agreement.pdf
|
||||
//
|
||||
// GNU General Public License as published by the Free Software Foundation;
|
||||
// version 3 of the License are accompanied with this source code.
|
||||
// See https://technosoftware.com/license/GPLv3License.txt
|
||||
//
|
||||
// This source code is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//-----------------------------------------------------------------------------
|
||||
#endregion Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
|
||||
#region Using Directives
|
||||
#endregion
|
||||
|
||||
namespace Technosoftware.DaAeHdaClient.Da
|
||||
{
|
||||
/// <summary>
|
||||
/// <para>Defines the possible quality status bits.</para>
|
||||
/// <para>These flags represent the quality state for an item's data value. This is
|
||||
/// intended to be similar to but slightly simpler than the Field-bus Data Quality
|
||||
/// Specification (section 4.4.1 in the H1 Final Specifications). This design makes it
|
||||
/// fairly easy for both servers and client applications to determine how much
|
||||
/// functionality they want to implement.</para>
|
||||
/// </summary>
|
||||
public enum TsDaQualityBits
|
||||
{
|
||||
/// <summary>The Quality of the value is Good.</summary>
|
||||
Good = 0x000000C0,
|
||||
/// <summary>The value has been Overridden. Typically this means the input has been disconnected and a manually entered value has been 'forced'.</summary>
|
||||
GoodLocalOverride = 0x000000D8,
|
||||
/// <summary>The value is bad but no specific reason is known.</summary>
|
||||
Bad = 0x00000000,
|
||||
/// <summary>
|
||||
/// There is some server specific problem with the configuration. For example the
|
||||
/// item in question has been deleted from the configuration.
|
||||
/// </summary>
|
||||
BadConfigurationError = 0x00000004,
|
||||
/// <summary>
|
||||
/// The input is required to be logically connected to something but is not. This
|
||||
/// quality may reflect that no value is available at this time, for reasons like the value
|
||||
/// may have not been provided by the data source.
|
||||
/// </summary>
|
||||
BadNotConnected = 0x00000008,
|
||||
/// <summary>A device failure has been detected.</summary>
|
||||
BadDeviceFailure = 0x0000000c,
|
||||
/// <summary>
|
||||
/// A sensor failure had been detected (the ’Limits’ field can provide additional
|
||||
/// diagnostic information in some situations).
|
||||
/// </summary>
|
||||
BadSensorFailure = 0x00000010,
|
||||
/// <summary>
|
||||
/// Communications have failed. However, the last known value is available. Note that
|
||||
/// the ‘age’ of the value may be determined from the time stamp in the item state.
|
||||
/// </summary>
|
||||
BadLastKnownValue = 0x00000014,
|
||||
/// <summary>Communications have failed. There is no last known value is available.</summary>
|
||||
BadCommFailure = 0x00000018,
|
||||
/// <summary>
|
||||
/// The block is off scan or otherwise locked. This quality is also used when the
|
||||
/// active state of the item or the subscription containing the item is InActive.
|
||||
/// </summary>
|
||||
BadOutOfService = 0x0000001C,
|
||||
/// <summary>
|
||||
/// After Items are added to a subscription, it may take some time for the server to
|
||||
/// actually obtain values for these items. In such cases the client might perform a read
|
||||
/// (from cache), or establish a ConnectionPoint based subscription and/or execute a
|
||||
/// Refresh on such a subscription before the values are available. This sub-status is only
|
||||
/// available from OPC DA 3.0 or newer servers.
|
||||
/// </summary>
|
||||
BadWaitingForInitialData = 0x00000020,
|
||||
/// <summary>There is no specific reason why the value is uncertain.</summary>
|
||||
Uncertain = 0x00000040,
|
||||
/// <summary>
|
||||
/// Whatever was writing this value has stopped doing so. The returned value should
|
||||
/// be regarded as ‘stale’. Note that this differs from a BAD value with sub-status
|
||||
/// badLastKnownValue (Last Known Value). That status is associated specifically with a
|
||||
/// detectable communications error on a ‘fetched’ value. This error is associated with the
|
||||
/// failure of some external source to ‘put’ something into the value within an acceptable
|
||||
/// period of time. Note that the ‘age’ of the value can be determined from the time stamp
|
||||
/// in the item state.
|
||||
/// </summary>
|
||||
UncertainLastUsableValue = 0x00000044,
|
||||
/// <summary>
|
||||
/// Either the value has ‘pegged’ at one of the sensor limits (in which case the
|
||||
/// limit field should be set to low or high) or the sensor is otherwise known to be out of
|
||||
/// calibration via some form of internal diagnostics (in which case the limit field should
|
||||
/// be none).
|
||||
/// </summary>
|
||||
UncertainSensorNotAccurate = 0x00000050,
|
||||
/// <summary>
|
||||
/// The returned value is outside the limits defined for this parameter. Note that in
|
||||
/// this case (per the Field-bus Specification) the ‘Limits’ field indicates which limit has
|
||||
/// been exceeded but does NOT necessarily imply that the value cannot move farther out of
|
||||
/// range.
|
||||
/// </summary>
|
||||
UncertainEUExceeded = 0x00000054,
|
||||
/// <summary>
|
||||
/// The value is derived from multiple sources and has less than the required number
|
||||
/// of Good sources.
|
||||
/// </summary>
|
||||
UncertainSubNormal = 0x00000058
|
||||
}
|
||||
}
|
||||
40
Technosoftware/DaAeHdaClient/Da/QualityMasks.cs
Normal file
40
Technosoftware/DaAeHdaClient/Da/QualityMasks.cs
Normal file
@@ -0,0 +1,40 @@
|
||||
#region Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
// Web: https://www.technosoftware.com
|
||||
//
|
||||
// The source code in this file is covered under a dual-license scenario:
|
||||
// - Owner of a purchased license: SCLA 1.0
|
||||
// - GPL V3: everybody else
|
||||
//
|
||||
// SCLA license terms accompanied with this source code.
|
||||
// See SCLA 1.0: https://technosoftware.com/license/Source_Code_License_Agreement.pdf
|
||||
//
|
||||
// GNU General Public License as published by the Free Software Foundation;
|
||||
// version 3 of the License are accompanied with this source code.
|
||||
// See https://technosoftware.com/license/GPLv3License.txt
|
||||
//
|
||||
// This source code is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//-----------------------------------------------------------------------------
|
||||
#endregion Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
|
||||
#region Using Directives
|
||||
#endregion
|
||||
|
||||
namespace Technosoftware.DaAeHdaClient.Da
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines bit masks for the quality.
|
||||
/// </summary>
|
||||
public enum TsDaQualityMasks : int
|
||||
{
|
||||
/// <summary>Quality related bits</summary>
|
||||
QualityMask = +0x00FC,
|
||||
/// <summary>Limit related bits</summary>
|
||||
LimitMask = +0x0003,
|
||||
/// <summary>Vendor specific bits</summary>
|
||||
VendorMask = -0x00FD
|
||||
}
|
||||
}
|
||||
70
Technosoftware/DaAeHdaClient/Da/Request.cs
Normal file
70
Technosoftware/DaAeHdaClient/Da/Request.cs
Normal file
@@ -0,0 +1,70 @@
|
||||
#region Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
// Web: https://www.technosoftware.com
|
||||
//
|
||||
// The source code in this file is covered under a dual-license scenario:
|
||||
// - Owner of a purchased license: SCLA 1.0
|
||||
// - GPL V3: everybody else
|
||||
//
|
||||
// SCLA license terms accompanied with this source code.
|
||||
// See SCLA 1.0: https://technosoftware.com/license/Source_Code_License_Agreement.pdf
|
||||
//
|
||||
// GNU General Public License as published by the Free Software Foundation;
|
||||
// version 3 of the License are accompanied with this source code.
|
||||
// See https://technosoftware.com/license/GPLv3License.txt
|
||||
//
|
||||
// This source code is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//-----------------------------------------------------------------------------
|
||||
#endregion Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
|
||||
#region Using Directives
|
||||
using System;
|
||||
#endregion
|
||||
|
||||
namespace Technosoftware.DaAeHdaClient.Da
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes the state of a subscription.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class TsCDaRequest : IOpcRequest
|
||||
{
|
||||
#region Fields
|
||||
private ITsCDaSubscription subscription_;
|
||||
private object handle_;
|
||||
#endregion
|
||||
|
||||
#region Constructors, Destructor, Initialization
|
||||
/// <summary>
|
||||
/// Initializes the object with a subscription and a unique id.
|
||||
/// </summary>
|
||||
public TsCDaRequest(ITsCDaSubscription subscription, object handle)
|
||||
{
|
||||
subscription_ = subscription;
|
||||
handle_ = handle;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
/// <summary>
|
||||
/// The subscription processing the request.
|
||||
/// </summary>
|
||||
public ITsCDaSubscription Subscription => subscription_;
|
||||
|
||||
/// <summary>
|
||||
/// An unique identifier, assigned by the client, for the request.
|
||||
/// </summary>
|
||||
public object Handle => handle_;
|
||||
#endregion
|
||||
|
||||
#region Public Methods
|
||||
/// <summary>
|
||||
/// Cancels the request, if possible.
|
||||
/// </summary>
|
||||
public void Cancel(TsCDaCancelCompleteEventHandler callback) { subscription_.Cancel(this, callback); }
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
75
Technosoftware/DaAeHdaClient/Da/ResultFilter.cs
Normal file
75
Technosoftware/DaAeHdaClient/Da/ResultFilter.cs
Normal file
@@ -0,0 +1,75 @@
|
||||
#region Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
// Web: https://www.technosoftware.com
|
||||
//
|
||||
// The source code in this file is covered under a dual-license scenario:
|
||||
// - Owner of a purchased license: SCLA 1.0
|
||||
// - GPL V3: everybody else
|
||||
//
|
||||
// SCLA license terms accompanied with this source code.
|
||||
// See SCLA 1.0: https://technosoftware.com/license/Source_Code_License_Agreement.pdf
|
||||
//
|
||||
// GNU General Public License as published by the Free Software Foundation;
|
||||
// version 3 of the License are accompanied with this source code.
|
||||
// See https://technosoftware.com/license/GPLv3License.txt
|
||||
//
|
||||
// This source code is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//-----------------------------------------------------------------------------
|
||||
#endregion Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
|
||||
#region Using Directives
|
||||
using System;
|
||||
#endregion
|
||||
|
||||
namespace Technosoftware.DaAeHdaClient.Da
|
||||
{
|
||||
/// <summary>
|
||||
/// Filters applied by the server before returning item results.
|
||||
/// </summary>
|
||||
[Flags]
|
||||
public enum TsCDaResultFilter
|
||||
{
|
||||
/// <summary>
|
||||
/// Include the ItemName in the ItemIdentifier if bit is set.
|
||||
/// </summary>
|
||||
ItemName = 0x01,
|
||||
|
||||
/// <summary>
|
||||
/// Include the ItemPath in the ItemIdentifier if bit is set.
|
||||
/// </summary>
|
||||
ItemPath = 0x02,
|
||||
|
||||
/// <summary>
|
||||
/// Include the ClientHandle in the ItemIdentifier if bit is set.
|
||||
/// </summary>
|
||||
ClientHandle = 0x04,
|
||||
|
||||
/// <summary>
|
||||
/// Include the Timestamp in the ItemValue if bit is set.
|
||||
/// </summary>
|
||||
ItemTime = 0x08,
|
||||
|
||||
/// <summary>
|
||||
/// Include verbose, localized error text with result if bit is set.
|
||||
/// </summary>
|
||||
ErrorText = 0x10,
|
||||
|
||||
/// <summary>
|
||||
/// Include additional diagnostic information with result if bit is set.
|
||||
/// </summary>
|
||||
DiagnosticInfo = 0x20,
|
||||
|
||||
/// <summary>
|
||||
/// Include the ItemName and Timestamp if bit is set.
|
||||
/// </summary>
|
||||
Minimal = ItemName | ItemTime,
|
||||
|
||||
/// <summary>
|
||||
/// Include all information in the results if bit is set.
|
||||
/// </summary>
|
||||
All = 0x3F
|
||||
}
|
||||
}
|
||||
500
Technosoftware/DaAeHdaClient/Da/Server.cs
Normal file
500
Technosoftware/DaAeHdaClient/Da/Server.cs
Normal file
@@ -0,0 +1,500 @@
|
||||
#region Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
// Web: https://www.technosoftware.com
|
||||
//
|
||||
// The source code in this file is covered under a dual-license scenario:
|
||||
// - Owner of a purchased license: SCLA 1.0
|
||||
// - GPL V3: everybody else
|
||||
//
|
||||
// SCLA license terms accompanied with this source code.
|
||||
// See SCLA 1.0: https://technosoftware.com/license/Source_Code_License_Agreement.pdf
|
||||
//
|
||||
// GNU General Public License as published by the Free Software Foundation;
|
||||
// version 3 of the License are accompanied with this source code.
|
||||
// See https://technosoftware.com/license/GPLv3License.txt
|
||||
//
|
||||
// This source code is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//-----------------------------------------------------------------------------
|
||||
#endregion Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
|
||||
#region Using Directives
|
||||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Collections.Generic;
|
||||
#endregion
|
||||
|
||||
namespace Technosoftware.DaAeHdaClient.Da
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// This class is the main interface to access an OPC Data Access server.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class TsCDaServer : OpcServer, ITsDaServer
|
||||
{
|
||||
#region Names Class
|
||||
/// <summary>A set of names for fields used in serialization.</summary>
|
||||
private class Names
|
||||
{
|
||||
internal const string Filters = "Filters";
|
||||
internal const string Subscriptions = "Subscription";
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Fields
|
||||
/// <summary>
|
||||
/// A list of subscriptions for the server.
|
||||
/// </summary>
|
||||
private TsCDaSubscriptionCollection subscriptions_ = new TsCDaSubscriptionCollection();
|
||||
|
||||
/// <summary>
|
||||
/// The local copy of the result filters.
|
||||
/// </summary>
|
||||
private int filters_ = (int)TsCDaResultFilter.All | (int)TsCDaResultFilter.ClientHandle;
|
||||
#endregion
|
||||
|
||||
#region Constructors, Destructor, Initialization
|
||||
/// <summary>
|
||||
/// Initializes the object.
|
||||
/// </summary>
|
||||
public TsCDaServer()
|
||||
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the object with a factory and a default OpcUrl.
|
||||
/// </summary>
|
||||
/// <param name="factory">The OpcFactory used to connect to remote servers.</param>
|
||||
/// <param name="url">The network address of a remote server.</param>
|
||||
public TsCDaServer(OpcFactory factory, OpcUrl url)
|
||||
:
|
||||
base(factory, url)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a server by de-serializing its OpcUrl from the stream.
|
||||
/// </summary>
|
||||
protected TsCDaServer(SerializationInfo info, StreamingContext context)
|
||||
:
|
||||
base(info, context)
|
||||
{
|
||||
filters_ = (int)info.GetValue(Names.Filters, typeof(int));
|
||||
|
||||
var subscriptions = (TsCDaSubscription[])info.GetValue(Names.Subscriptions, typeof(TsCDaSubscription[]));
|
||||
|
||||
if (subscriptions != null)
|
||||
{
|
||||
Array.ForEach(subscriptions, subscription => subscriptions_.Add(subscription));
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
/// <summary>
|
||||
/// Returns an array of all subscriptions for the server.
|
||||
/// </summary>
|
||||
public TsCDaSubscriptionCollection Subscriptions => subscriptions_;
|
||||
|
||||
/// <summary>
|
||||
/// The current result filters applied by the server.
|
||||
/// </summary>
|
||||
public int Filters => filters_;
|
||||
#endregion
|
||||
|
||||
#region Class properties serialization helpers
|
||||
/// <summary>Serializes a server into a stream.</summary>
|
||||
public override void GetObjectData(SerializationInfo info, StreamingContext context)
|
||||
{
|
||||
base.GetObjectData(info, context);
|
||||
|
||||
info.AddValue(Names.Filters, filters_);
|
||||
|
||||
TsCDaSubscription[] subscriptions = null;
|
||||
|
||||
if (subscriptions_.Count > 0)
|
||||
{
|
||||
subscriptions = new TsCDaSubscription[subscriptions_.Count];
|
||||
|
||||
for (var ii = 0; ii < subscriptions.Length; ii++)
|
||||
{
|
||||
subscriptions[ii] = subscriptions_[ii];
|
||||
}
|
||||
}
|
||||
|
||||
info.AddValue(Names.Subscriptions, subscriptions);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Public Methods
|
||||
/// <summary>Returns an unconnected copy of the server with the same OpcUrl.</summary>
|
||||
public override object Clone()
|
||||
{
|
||||
// clone the base object.
|
||||
var clone = (TsCDaServer)base.Clone();
|
||||
|
||||
// clone subscriptions.
|
||||
if (clone.subscriptions_ != null)
|
||||
{
|
||||
var subscriptions = new TsCDaSubscriptionCollection();
|
||||
|
||||
foreach (TsCDaSubscription subscription in clone.subscriptions_)
|
||||
{
|
||||
subscriptions.Add(subscription.Clone());
|
||||
}
|
||||
|
||||
clone.subscriptions_ = subscriptions;
|
||||
}
|
||||
|
||||
// return clone.
|
||||
return clone;
|
||||
}
|
||||
|
||||
/// <summary>Connects to the server with the specified OpcUrl and credentials.</summary>
|
||||
/// <exception caption="OpcResultException Class" cref="OpcResultException">If an OPC specific error occur this exception is raised. The Result field includes then the OPC specific code.</exception>
|
||||
/// <param name="url">The network address of the remote server.</param>
|
||||
/// <param name="connectData">Any protocol configuration or user authentication information.</param>
|
||||
public override void Connect(OpcUrl url, OpcConnectData connectData)
|
||||
{
|
||||
LicenseHandler.ValidateFeatures(LicenseHandler.ProductFeature.DataAccess);
|
||||
// connect to server.
|
||||
base.Connect(url, connectData);
|
||||
|
||||
// all done if no subscriptions.
|
||||
if (subscriptions_ == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// create subscriptions (should only happen if server has been deserialized).
|
||||
var subscriptions = new TsCDaSubscriptionCollection();
|
||||
|
||||
foreach (TsCDaSubscription template in subscriptions_)
|
||||
{
|
||||
// create subscription for template.
|
||||
try
|
||||
{
|
||||
subscriptions.Add(EstablishSubscription(template));
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Ignore exceptions here
|
||||
}
|
||||
}
|
||||
|
||||
// save new set of subscriptions.
|
||||
subscriptions_ = subscriptions;
|
||||
}
|
||||
|
||||
/// <summary>Disconnects from the server and releases all network resources.</summary>
|
||||
public override void Disconnect()
|
||||
{
|
||||
if (Server == null) throw new NotConnectedException();
|
||||
|
||||
// dispose of all subscriptions first.
|
||||
if (subscriptions_ != null)
|
||||
{
|
||||
foreach (TsCDaSubscription subscription in subscriptions_)
|
||||
{
|
||||
subscription.Dispose();
|
||||
}
|
||||
|
||||
subscriptions_ = null;
|
||||
}
|
||||
|
||||
// disconnect from server.
|
||||
base.Disconnect();
|
||||
}
|
||||
|
||||
/// <summary>Returns the filters applied by the server to any item results returned to the client.</summary>
|
||||
/// <returns>A bit mask indicating which fields should be returned in any item results.</returns>
|
||||
public int GetResultFilters()
|
||||
{
|
||||
LicenseHandler.ValidateFeatures(LicenseHandler.ProductFeature.DataAccess);
|
||||
if (Server == null) throw new NotConnectedException();
|
||||
|
||||
// update local cache.
|
||||
filters_ = ((ITsDaServer)Server).GetResultFilters();
|
||||
|
||||
// return filters.
|
||||
return filters_;
|
||||
}
|
||||
|
||||
/// <summary>Sets the filters applied by the server to any item results returned to the client.</summary>
|
||||
/// <param name="filters">A bit mask indicating which fields should be returned in any item results.</param>
|
||||
public void SetResultFilters(int filters)
|
||||
{
|
||||
LicenseHandler.ValidateFeatures(LicenseHandler.ProductFeature.DataAccess);
|
||||
if (Server == null) throw new NotConnectedException();
|
||||
|
||||
// set filters on server.
|
||||
((ITsDaServer)Server).SetResultFilters(filters);
|
||||
|
||||
// cache updated filters.
|
||||
filters_ = filters;
|
||||
}
|
||||
|
||||
/// <summary>Returns the current server status.</summary>
|
||||
/// <returns>The current server status.</returns>
|
||||
public OpcServerStatus GetServerStatus()
|
||||
{
|
||||
LicenseHandler.ValidateFeatures(LicenseHandler.ProductFeature.DataAccess);
|
||||
if (Server == null) throw new NotConnectedException();
|
||||
|
||||
var status = ((ITsDaServer)Server).GetServerStatus();
|
||||
|
||||
if (status != null)
|
||||
{
|
||||
if (status.StatusInfo == null)
|
||||
{
|
||||
status.StatusInfo = GetString($"serverState.{status.ServerState}");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotConnectedException();
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/// <summary>Reads the current values for a set of items.</summary>
|
||||
/// <returns>The results of the read operation for each item.</returns>
|
||||
/// <requirements>OPC XML-DA Server or OPC Data Access Server V3.x</requirements>
|
||||
/// <param name="items">The set of items to read.</param>
|
||||
public TsCDaItemValueResult[] Read(TsCDaItem[] items)
|
||||
{
|
||||
LicenseHandler.ValidateFeatures(LicenseHandler.ProductFeature.DataAccess);
|
||||
if (Server == null) throw new NotConnectedException();
|
||||
|
||||
return ((ITsDaServer)Server).Read(items);
|
||||
}
|
||||
|
||||
/// <summary>Writes the value, quality and timestamp for a set of items.</summary>
|
||||
/// <returns>The results of the write operation for each item.</returns>
|
||||
/// <requirements>OPC XML-DA Server or OPC Data Access Server V3.x</requirements>
|
||||
/// <param name="items">The set of item values to write.</param>
|
||||
public OpcItemResult[] Write(TsCDaItemValue[] items)
|
||||
{
|
||||
LicenseHandler.ValidateFeatures(LicenseHandler.ProductFeature.DataAccess);
|
||||
if (Server == null) throw new NotConnectedException();
|
||||
|
||||
return ((ITsDaServer)Server).Write(items);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new subscription.
|
||||
/// </summary>
|
||||
/// <returns>The new subscription object.</returns>
|
||||
/// <requirements>OPC XML-DA Server or OPC Data Access Server V2.x / V3.x</requirements>
|
||||
/// <param name="state">The initial state of the subscription.</param>
|
||||
public virtual ITsCDaSubscription CreateSubscription(TsCDaSubscriptionState state)
|
||||
{
|
||||
LicenseHandler.ValidateFeatures(LicenseHandler.ProductFeature.DataAccess);
|
||||
if (state == null) throw new ArgumentNullException(nameof(state));
|
||||
if (Server == null) throw new NotConnectedException();
|
||||
|
||||
// create subscription on server.
|
||||
var subscription = ((ITsDaServer)Server).CreateSubscription(state);
|
||||
|
||||
// set filters.
|
||||
subscription.SetResultFilters(filters_);
|
||||
|
||||
// append new subscription to existing list.
|
||||
var subscriptions = new TsCDaSubscriptionCollection();
|
||||
|
||||
if (subscriptions_ != null)
|
||||
{
|
||||
foreach (TsCDaSubscription value in subscriptions_)
|
||||
{
|
||||
subscriptions.Add(value);
|
||||
}
|
||||
}
|
||||
|
||||
subscriptions.Add(CreateSubscription(subscription));
|
||||
|
||||
// save new subscription list.
|
||||
subscriptions_ = subscriptions;
|
||||
|
||||
// return new subscription.
|
||||
return subscriptions_[subscriptions_.Count - 1];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the appropriate subscription object.
|
||||
/// </summary>
|
||||
/// <param name="subscription">The remote subscription object.</param>
|
||||
protected virtual TsCDaSubscription CreateSubscription(ITsCDaSubscription subscription)
|
||||
{
|
||||
LicenseHandler.ValidateFeatures(LicenseHandler.ProductFeature.DataAccess);
|
||||
return new TsCDaSubscription(this, subscription);
|
||||
}
|
||||
|
||||
/// <summary>Cancels a subscription and releases all resources allocated for it.</summary>
|
||||
/// <requirements>OPC XML-DA Server or OPC Data Access Server V2.x / V3.x</requirements>
|
||||
/// <param name="subscription">The subscription to cancel.</param>
|
||||
public virtual void CancelSubscription(ITsCDaSubscription subscription)
|
||||
{
|
||||
LicenseHandler.ValidateFeatures(LicenseHandler.ProductFeature.DataAccess);
|
||||
if (subscription == null) throw new ArgumentNullException(nameof(subscription));
|
||||
if (Server == null) throw new NotConnectedException();
|
||||
|
||||
// validate argument.
|
||||
if (!typeof(TsCDaSubscription).IsInstanceOfType(subscription))
|
||||
{
|
||||
throw new ArgumentException(@"Incorrect object type.", nameof(subscription));
|
||||
}
|
||||
|
||||
if (!Equals(((TsCDaSubscription)subscription).Server))
|
||||
{
|
||||
throw new ArgumentException(@"Server subscription.", nameof(subscription));
|
||||
}
|
||||
|
||||
// search for subscription in list of subscriptions.
|
||||
var subscriptions = new TsCDaSubscriptionCollection();
|
||||
|
||||
foreach (TsCDaSubscription current in subscriptions_)
|
||||
{
|
||||
if (!subscription.Equals(current))
|
||||
{
|
||||
subscriptions.Add(current);
|
||||
}
|
||||
}
|
||||
|
||||
// check if subscription was not found.
|
||||
if (subscriptions.Count == subscriptions_.Count)
|
||||
{
|
||||
throw new ArgumentException(@"Subscription not found.", nameof(subscription));
|
||||
}
|
||||
|
||||
// remove subscription from list of subscriptions.
|
||||
subscriptions_ = subscriptions;
|
||||
|
||||
// cancel subscription on server.
|
||||
((ITsDaServer)Server).CancelSubscription(((TsCDaSubscription)subscription).Subscription);
|
||||
}
|
||||
|
||||
/// <summary>Fetches all the children of the root branch that meet the filter criteria.</summary>
|
||||
/// <returns>The set of elements found.</returns>
|
||||
/// <requirements>OPC Data Access Server V2.x / V3.x</requirements>
|
||||
/// <param name="filters">The filters to use to limit the set of child elements returned.</param>
|
||||
private TsCDaBrowseElement[] Browse(
|
||||
TsCDaBrowseFilters filters)
|
||||
{
|
||||
LicenseHandler.ValidateFeatures(LicenseHandler.ProductFeature.DataAccess);
|
||||
if (Server == null) throw new NotConnectedException();
|
||||
TsCDaBrowsePosition position;
|
||||
var elementsList = new List<TsCDaBrowseElement>();
|
||||
|
||||
var elements = ((ITsDaServer)Server).Browse(null, filters, out position);
|
||||
|
||||
if (elements != null)
|
||||
{
|
||||
Browse(elements, filters, ref elementsList);
|
||||
}
|
||||
|
||||
return elementsList.ToArray();
|
||||
}
|
||||
|
||||
private void Browse(TsCDaBrowseElement[] elements, TsCDaBrowseFilters filters, ref List<TsCDaBrowseElement> elementsList)
|
||||
{
|
||||
LicenseHandler.ValidateFeatures(LicenseHandler.ProductFeature.DataAccess);
|
||||
TsCDaBrowsePosition position;
|
||||
|
||||
foreach (var element in elements)
|
||||
{
|
||||
if (element.HasChildren)
|
||||
{
|
||||
var itemId = new OpcItem(element.ItemPath, element.ItemName);
|
||||
|
||||
var childElements = ((ITsDaServer)Server).Browse(itemId, filters, out position);
|
||||
if (childElements != null)
|
||||
{
|
||||
Browse(childElements, filters, ref elementsList);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
elementsList.Add(element);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Fetches the children of a branch that meet the filter criteria.</summary>
|
||||
/// <returns>The set of elements found.</returns>
|
||||
/// <requirements>OPC XML-DA Server or OPC Data Access Server V2.x / V3.x</requirements>
|
||||
/// <param name="itemId">The identifier of branch which is the target of the search.</param>
|
||||
/// <param name="filters">The filters to use to limit the set of child elements returned.</param>
|
||||
/// <param name="position">An object used to continue a browse that could not be completed.</param>
|
||||
public TsCDaBrowseElement[] Browse(
|
||||
OpcItem itemId,
|
||||
TsCDaBrowseFilters filters,
|
||||
out TsCDaBrowsePosition position)
|
||||
{
|
||||
LicenseHandler.ValidateFeatures(LicenseHandler.ProductFeature.DataAccess);
|
||||
if (Server == null) throw new NotConnectedException();
|
||||
return ((ITsDaServer)Server).Browse(itemId, filters, out position);
|
||||
}
|
||||
|
||||
/// <summary>Continues a browse operation with previously specified search criteria.</summary>
|
||||
/// <returns>The set of elements found.</returns>
|
||||
/// <requirements>OPC XML-DA Server or OPC Data Access Server V2.x / V3.x</requirements>
|
||||
/// <param name="position">An object containing the browse operation state information.</param>
|
||||
public TsCDaBrowseElement[] BrowseNext(ref TsCDaBrowsePosition position)
|
||||
{
|
||||
LicenseHandler.ValidateFeatures(LicenseHandler.ProductFeature.DataAccess);
|
||||
if (Server == null) throw new NotConnectedException();
|
||||
return ((ITsDaServer)Server).BrowseNext(ref position);
|
||||
}
|
||||
|
||||
/// <summary>Returns the item properties for a set of items.</summary>
|
||||
/// <param name="itemIds">A list of item identifiers.</param>
|
||||
/// <param name="propertyIDs">A list of properties to fetch for each item.</param>
|
||||
/// <param name="returnValues">Whether the property values should be returned with the properties.</param>
|
||||
/// <returns>A list of properties for each item.</returns>
|
||||
public TsCDaItemPropertyCollection[] GetProperties(
|
||||
OpcItem[] itemIds,
|
||||
TsDaPropertyID[] propertyIDs,
|
||||
bool returnValues)
|
||||
{
|
||||
LicenseHandler.ValidateFeatures(LicenseHandler.ProductFeature.DataAccess);
|
||||
if (Server == null) throw new NotConnectedException();
|
||||
return ((ITsDaServer)Server).GetProperties(itemIds, propertyIDs, returnValues);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Private Methods
|
||||
/// <summary>
|
||||
/// Establishes a subscription based on the template provided.
|
||||
/// </summary>
|
||||
private TsCDaSubscription EstablishSubscription(TsCDaSubscription template)
|
||||
{
|
||||
// create subscription.
|
||||
var subscription = new TsCDaSubscription(this, ((ITsDaServer)Server).CreateSubscription(template.State));
|
||||
|
||||
// set filters.
|
||||
subscription.SetResultFilters(template.Filters);
|
||||
|
||||
// add items.
|
||||
try
|
||||
{
|
||||
subscription.AddItems(template.Items);
|
||||
}
|
||||
catch
|
||||
{
|
||||
subscription.Dispose();
|
||||
subscription = null;
|
||||
}
|
||||
|
||||
// return new subscription.
|
||||
return subscription;
|
||||
}
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
68
Technosoftware/DaAeHdaClient/Da/ServerState.cs
Normal file
68
Technosoftware/DaAeHdaClient/Da/ServerState.cs
Normal file
@@ -0,0 +1,68 @@
|
||||
#region Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
// Web: https://www.technosoftware.com
|
||||
//
|
||||
// The source code in this file is covered under a dual-license scenario:
|
||||
// - Owner of a purchased license: SCLA 1.0
|
||||
// - GPL V3: everybody else
|
||||
//
|
||||
// SCLA license terms accompanied with this source code.
|
||||
// See SCLA 1.0: https://technosoftware.com/license/Source_Code_License_Agreement.pdf
|
||||
//
|
||||
// GNU General Public License as published by the Free Software Foundation;
|
||||
// version 3 of the License are accompanied with this source code.
|
||||
// See https://technosoftware.com/license/GPLv3License.txt
|
||||
//
|
||||
// This source code is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//-----------------------------------------------------------------------------
|
||||
#endregion Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
|
||||
#region Using Directives
|
||||
#endregion
|
||||
|
||||
namespace Technosoftware.DaAeHdaClient.Da
|
||||
{
|
||||
/// <summary>
|
||||
/// The set of possible server states.
|
||||
/// </summary>
|
||||
public enum TsCDaServerState
|
||||
{
|
||||
/// <summary>
|
||||
/// The server state is not known.
|
||||
/// </summary>
|
||||
Unknown,
|
||||
|
||||
/// <summary>
|
||||
/// The server is running normally.
|
||||
/// </summary>
|
||||
Running,
|
||||
|
||||
/// <summary>
|
||||
/// The server is not functioning due to a fatal error.
|
||||
/// </summary>
|
||||
Failed,
|
||||
|
||||
/// <summary>
|
||||
/// The server cannot load its configuration information.
|
||||
/// </summary>
|
||||
NoConfig,
|
||||
|
||||
/// <summary>
|
||||
/// The server has halted all communication with the underlying hardware.
|
||||
/// </summary>
|
||||
Suspended,
|
||||
|
||||
/// <summary>
|
||||
/// The server is disconnected from the underlying hardware.
|
||||
/// </summary>
|
||||
Test,
|
||||
|
||||
/// <summary>
|
||||
/// The server cannot communicate with the underlying hardware.
|
||||
/// </summary>
|
||||
CommFault
|
||||
}
|
||||
}
|
||||
92
Technosoftware/DaAeHdaClient/Da/StateMask.cs
Normal file
92
Technosoftware/DaAeHdaClient/Da/StateMask.cs
Normal file
@@ -0,0 +1,92 @@
|
||||
#region Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
// Web: https://www.technosoftware.com
|
||||
//
|
||||
// The source code in this file is covered under a dual-license scenario:
|
||||
// - Owner of a purchased license: SCLA 1.0
|
||||
// - GPL V3: everybody else
|
||||
//
|
||||
// SCLA license terms accompanied with this source code.
|
||||
// See SCLA 1.0: https://technosoftware.com/license/Source_Code_License_Agreement.pdf
|
||||
//
|
||||
// GNU General Public License as published by the Free Software Foundation;
|
||||
// version 3 of the License are accompanied with this source code.
|
||||
// See https://technosoftware.com/license/GPLv3License.txt
|
||||
//
|
||||
// This source code is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//-----------------------------------------------------------------------------
|
||||
#endregion Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
|
||||
#region Using Directives
|
||||
using System;
|
||||
#endregion
|
||||
|
||||
namespace Technosoftware.DaAeHdaClient.Da
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines masks to be used when modifying the subscription or item state.
|
||||
/// </summary>
|
||||
[Flags]
|
||||
public enum TsCDaStateMask
|
||||
{
|
||||
/// <summary>
|
||||
/// The name of the subscription.
|
||||
/// </summary>
|
||||
Name = 0x0001,
|
||||
|
||||
/// <summary>
|
||||
/// The client assigned handle for the item or subscription.
|
||||
/// </summary>
|
||||
ClientHandle = 0x0002,
|
||||
|
||||
/// <summary>
|
||||
/// The locale to use for results returned to the client from the subscription.
|
||||
/// </summary>
|
||||
Locale = 0x0004,
|
||||
|
||||
/// <summary>
|
||||
/// Whether the item or subscription is active.
|
||||
/// </summary>
|
||||
Active = 0x0008,
|
||||
|
||||
/// <summary>
|
||||
/// The maximum rate at which data update notifications are sent.
|
||||
/// </summary>
|
||||
UpdateRate = 0x0010,
|
||||
|
||||
/// <summary>
|
||||
/// The longest period between data update notifications.<br/>
|
||||
/// <strong>Note:</strong> This feature is only supported with OPC Data Access 3.0
|
||||
/// Servers.
|
||||
/// </summary>
|
||||
KeepAlive = 0x0020,
|
||||
|
||||
/// <summary>
|
||||
/// The requested data type for the item.
|
||||
/// </summary>
|
||||
ReqType = 0x0040,
|
||||
|
||||
/// <summary>
|
||||
/// The deadband for the item or subscription.
|
||||
/// </summary>
|
||||
Deadband = 0x0080,
|
||||
|
||||
/// <summary>
|
||||
/// The rate at which the server should check for changes to an item value.
|
||||
/// </summary>
|
||||
SamplingRate = 0x0100,
|
||||
|
||||
/// <summary>
|
||||
/// Whether the server should buffer multiple changes to a single item.
|
||||
/// </summary>
|
||||
EnableBuffering = 0x0200,
|
||||
|
||||
/// <summary>
|
||||
/// All fields are valid.
|
||||
/// </summary>
|
||||
All = 0xFFFF
|
||||
}
|
||||
}
|
||||
571
Technosoftware/DaAeHdaClient/Da/Subscription.cs
Normal file
571
Technosoftware/DaAeHdaClient/Da/Subscription.cs
Normal file
@@ -0,0 +1,571 @@
|
||||
#region Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
// Web: https://www.technosoftware.com
|
||||
//
|
||||
// The source code in this file is covered under a dual-license scenario:
|
||||
// - Owner of a purchased license: SCLA 1.0
|
||||
// - GPL V3: everybody else
|
||||
//
|
||||
// SCLA license terms accompanied with this source code.
|
||||
// See SCLA 1.0: https://technosoftware.com/license/Source_Code_License_Agreement.pdf
|
||||
//
|
||||
// GNU General Public License as published by the Free Software Foundation;
|
||||
// version 3 of the License are accompanied with this source code.
|
||||
// See https://technosoftware.com/license/GPLv3License.txt
|
||||
//
|
||||
// This source code is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//-----------------------------------------------------------------------------
|
||||
#endregion Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
|
||||
#region Using Directives
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Runtime.Serialization;
|
||||
#endregion
|
||||
|
||||
namespace Technosoftware.DaAeHdaClient.Da
|
||||
{
|
||||
/// <summary>
|
||||
/// An in-process object used to access subscriptions on OPC Data Access servers.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class TsCDaSubscription : ITsCDaSubscription, ISerializable, ICloneable
|
||||
{
|
||||
#region Names Class
|
||||
|
||||
/// <summary>
|
||||
/// A set of names for fields used in serialization.
|
||||
/// </summary>
|
||||
private class Names
|
||||
{
|
||||
internal const string State = "State";
|
||||
internal const string Filters = "Filters";
|
||||
internal const string Items = "Items";
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Fields
|
||||
|
||||
private bool disposed_;
|
||||
|
||||
/// <summary>
|
||||
/// The containing server object.
|
||||
/// </summary>
|
||||
private TsCDaServer server_;
|
||||
|
||||
/// <summary>
|
||||
/// The remote subscription object.
|
||||
/// </summary>
|
||||
internal ITsCDaSubscription Subscription;
|
||||
|
||||
/// <summary>
|
||||
/// The local copy of the subscription state.
|
||||
/// </summary>
|
||||
private TsCDaSubscriptionState subscriptionState_ = new TsCDaSubscriptionState();
|
||||
|
||||
/// <summary>
|
||||
/// The local copy of all subscription items.
|
||||
/// </summary>
|
||||
private TsCDaItem[] daItems_;
|
||||
|
||||
/// <summary>
|
||||
/// Whether data callbacks are enabled.
|
||||
/// </summary>
|
||||
private bool enabled_ = true;
|
||||
|
||||
/// <summary>
|
||||
/// The local copy of the result filters.
|
||||
/// </summary>
|
||||
private int filters_ = (int)TsCDaResultFilter.All | (int)TsCDaResultFilter.ClientHandle;
|
||||
#endregion
|
||||
|
||||
#region Constructors, Destructor, Initialization
|
||||
/// <summary>
|
||||
/// Initializes object with default values.
|
||||
/// </summary>
|
||||
public TsCDaSubscription(TsCDaServer server, ITsCDaSubscription subscription)
|
||||
{
|
||||
server_ = server ?? throw new ArgumentNullException(nameof(server));
|
||||
Subscription = subscription ?? throw new ArgumentNullException(nameof(subscription));
|
||||
|
||||
GetResultFilters();
|
||||
GetState();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a server by de-serializing its OpcUrl from the stream.
|
||||
/// </summary>
|
||||
protected TsCDaSubscription(SerializationInfo info, StreamingContext context)
|
||||
{
|
||||
subscriptionState_ = (TsCDaSubscriptionState)info.GetValue(Names.State, typeof(TsCDaSubscriptionState));
|
||||
filters_ = (int)info.GetValue(Names.Filters, typeof(int));
|
||||
daItems_ = (TsCDaItem[])info.GetValue(Names.Items, typeof(TsCDaItem[]));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The finalizer implementation.
|
||||
/// </summary>
|
||||
~TsCDaSubscription()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This must be called explicitly by clients to ensure the remote server is released.
|
||||
/// </summary>
|
||||
public virtual void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
// Take yourself off the Finalization queue
|
||||
// to prevent finalization code for this object
|
||||
// from executing a second time.
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispose(bool disposing) executes in two distinct scenarios.
|
||||
/// If disposing equals true, the method has been called directly
|
||||
/// or indirectly by a user's code. Managed and unmanaged resources
|
||||
/// can be disposed.
|
||||
/// If disposing equals false, the method has been called by the
|
||||
/// runtime from inside the finalizer and you should not reference
|
||||
/// other objects. Only unmanaged resources can be disposed.
|
||||
/// </summary>
|
||||
/// <param name="disposing">If true managed and unmanaged resources can be disposed. If false only unmanaged resources.</param>
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
// Check to see if Dispose has already been called.
|
||||
if (!disposed_)
|
||||
{
|
||||
// If disposing equals true, dispose all managed
|
||||
// and unmanaged resources.
|
||||
if (disposing)
|
||||
{
|
||||
if (Subscription != null)
|
||||
{
|
||||
Subscription.Dispose();
|
||||
|
||||
server_ = null;
|
||||
Subscription = null;
|
||||
daItems_ = null;
|
||||
}
|
||||
}
|
||||
// Release unmanaged resources. If disposing is false,
|
||||
// only the following code is executed.
|
||||
}
|
||||
disposed_ = true;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
/// <summary>
|
||||
/// The server that the subscription is attached to.
|
||||
/// </summary>
|
||||
public TsCDaServer Server => server_;
|
||||
|
||||
/// <summary>
|
||||
/// The name assigned to the subscription by the client.
|
||||
/// </summary>
|
||||
public string Name => subscriptionState_.Name;
|
||||
|
||||
/// <summary>
|
||||
/// The handle assigned to the subscription by the client.
|
||||
/// </summary>
|
||||
public object ClientHandle => subscriptionState_.ClientHandle;
|
||||
|
||||
/// <summary>
|
||||
/// The handle assigned to the subscription by the server.
|
||||
/// </summary>
|
||||
public object ServerHandle => subscriptionState_.ServerHandle;
|
||||
|
||||
/// <summary>
|
||||
/// Whether the subscription is active.
|
||||
/// </summary>
|
||||
public bool Active => subscriptionState_.Active;
|
||||
|
||||
/// <summary>
|
||||
/// Whether data callbacks are enabled.
|
||||
/// </summary>
|
||||
public bool Enabled => enabled_;
|
||||
|
||||
/// <summary>
|
||||
/// The current locale used by the subscription.
|
||||
/// </summary>
|
||||
public string Locale => subscriptionState_.Locale;
|
||||
|
||||
/// <summary>
|
||||
/// The current result filters applied by the subscription.
|
||||
/// </summary>
|
||||
public int Filters => filters_;
|
||||
|
||||
/// <summary>
|
||||
/// Returns a copy of the current subscription state.
|
||||
/// </summary>
|
||||
public TsCDaSubscriptionState State => (TsCDaSubscriptionState)subscriptionState_.Clone();
|
||||
|
||||
/// <summary>
|
||||
/// The items belonging to the subscription.
|
||||
/// </summary>
|
||||
public TsCDaItem[] Items {
|
||||
get {
|
||||
if (daItems_ == null) return new TsCDaItem[0];
|
||||
var items = new TsCDaItem[daItems_.Length];
|
||||
for (var ii = 0; ii < daItems_.Length; ii++) items[ii] = (TsCDaItem)daItems_[ii].Clone();
|
||||
return items;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Public Methods
|
||||
/// <summary>
|
||||
/// Serializes a server into a stream.
|
||||
/// </summary>
|
||||
public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
|
||||
{
|
||||
info.AddValue(Names.State, subscriptionState_);
|
||||
info.AddValue(Names.Filters, filters_);
|
||||
info.AddValue(Names.Items, daItems_);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns an unconnected copy of the subscription with the same items.
|
||||
/// </summary>
|
||||
public virtual object Clone()
|
||||
{
|
||||
// do a memberwise clone.
|
||||
var clone = (TsCDaSubscription)MemberwiseClone();
|
||||
|
||||
// place clone in disconnected state.
|
||||
clone.server_ = null;
|
||||
clone.Subscription = null;
|
||||
clone.subscriptionState_ = (TsCDaSubscriptionState)subscriptionState_.Clone();
|
||||
|
||||
// clear server handles.
|
||||
clone.subscriptionState_.ServerHandle = null;
|
||||
|
||||
// always make cloned subscriptions inactive.
|
||||
clone.subscriptionState_.Active = false;
|
||||
|
||||
// clone items.
|
||||
if (clone.daItems_ != null)
|
||||
{
|
||||
var items = new ArrayList();
|
||||
|
||||
Array.ForEach(clone.daItems_, item => items.Add(item.Clone()));
|
||||
|
||||
clone.daItems_ = (TsCDaItem[])items.ToArray(typeof(TsCDaItem));
|
||||
}
|
||||
|
||||
// return clone.
|
||||
return clone;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets default result filters for the server.
|
||||
/// </summary>
|
||||
public int GetResultFilters()
|
||||
{
|
||||
filters_ = Subscription.GetResultFilters();
|
||||
return filters_;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets default result filters for the server.
|
||||
/// </summary>
|
||||
public void SetResultFilters(int filters)
|
||||
{
|
||||
Subscription.SetResultFilters(filters);
|
||||
filters_ = filters;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the current subscription state.
|
||||
/// </summary>
|
||||
public TsCDaSubscriptionState GetState()
|
||||
{
|
||||
subscriptionState_ = Subscription.GetState();
|
||||
return subscriptionState_;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the current subscription state.
|
||||
/// </summary>
|
||||
public TsCDaSubscriptionState ModifyState(int masks, TsCDaSubscriptionState state)
|
||||
{
|
||||
subscriptionState_ = Subscription.ModifyState(masks, state);
|
||||
return subscriptionState_;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds items to the subscription.
|
||||
/// </summary>
|
||||
public virtual TsCDaItemResult[] AddItems(TsCDaItem[] items)
|
||||
{
|
||||
LicenseHandler.ValidateFeatures(LicenseHandler.ProductFeature.DataAccess);
|
||||
if (items == null) throw new ArgumentNullException(nameof(items));
|
||||
|
||||
// check if there is nothing to do.
|
||||
if (items.Length == 0)
|
||||
{
|
||||
return new TsCDaItemResult[0];
|
||||
}
|
||||
|
||||
// add items.
|
||||
var results = Subscription.AddItems(items);
|
||||
|
||||
if (results == null || results.Length == 0)
|
||||
{
|
||||
throw new OpcResultException(new OpcResult(OpcResult.E_FAIL.Code, OpcResult.FuncCallType.SysFuncCall, null), "The browse operation cannot continue");
|
||||
}
|
||||
|
||||
// update locale item list.
|
||||
var itemList = new ArrayList();
|
||||
if (daItems_ != null) itemList.AddRange(daItems_);
|
||||
|
||||
for (var ii = 0; ii < results.Length; ii++)
|
||||
{
|
||||
// check for failure.
|
||||
if (results[ii].Result.Failed())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// create locale copy of the item.
|
||||
// item name, item path and client handle may not be returned by server.
|
||||
var item = new TsCDaItem(results[ii]) { ItemName = items[ii].ItemName, ItemPath = items[ii].ItemPath, ClientHandle = items[ii].ClientHandle };
|
||||
|
||||
itemList.Add(item);
|
||||
}
|
||||
|
||||
// save the new item list.
|
||||
daItems_ = (TsCDaItem[])itemList.ToArray(typeof(TsCDaItem));
|
||||
|
||||
// update the local state.
|
||||
GetState();
|
||||
|
||||
// return results.
|
||||
return results;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Modifies items that are already part of the subscription.
|
||||
/// </summary>
|
||||
public virtual TsCDaItemResult[] ModifyItems(int masks, TsCDaItem[] items)
|
||||
{
|
||||
LicenseHandler.ValidateFeatures(LicenseHandler.ProductFeature.DataAccess);
|
||||
if (items == null) throw new ArgumentNullException(nameof(items));
|
||||
|
||||
// check if there is nothing to do.
|
||||
if (items.Length == 0)
|
||||
{
|
||||
return new TsCDaItemResult[0];
|
||||
}
|
||||
|
||||
// modify items.
|
||||
var results = Subscription.ModifyItems(masks, items);
|
||||
|
||||
if (results == null || results.Length == 0)
|
||||
{
|
||||
throw new OpcResultException(new OpcResult(OpcResult.E_FAIL.Code, OpcResult.FuncCallType.SysFuncCall, null), "The browse operation cannot continue");
|
||||
}
|
||||
|
||||
// update local item - modify item success means all fields were updated successfully.
|
||||
for (var ii = 0; ii < results.Length; ii++)
|
||||
{
|
||||
// check for failure.
|
||||
if (results[ii].Result.Failed())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// search local item list.
|
||||
for (var jj = 0; jj < daItems_.Length; jj++)
|
||||
{
|
||||
if (daItems_[jj].ServerHandle.Equals(items[ii].ServerHandle))
|
||||
{
|
||||
// update locale copy of the item.
|
||||
// item name, item path and client handle may not be returned by server.
|
||||
var item = new TsCDaItem(results[ii]) { ItemName = daItems_[jj].ItemName, ItemPath = daItems_[jj].ItemPath, ClientHandle = daItems_[jj].ClientHandle };
|
||||
|
||||
daItems_[jj] = item;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// update the local state.
|
||||
GetState();
|
||||
|
||||
// return results.
|
||||
return results;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes items from a subscription.
|
||||
/// </summary>
|
||||
public virtual OpcItemResult[] RemoveItems(OpcItem[] items)
|
||||
{
|
||||
LicenseHandler.ValidateFeatures(LicenseHandler.ProductFeature.DataAccess);
|
||||
if (items == null) throw new ArgumentNullException(nameof(items));
|
||||
|
||||
// check if there is nothing to do.
|
||||
if (items.Length == 0)
|
||||
{
|
||||
return new OpcItemResult[0];
|
||||
}
|
||||
|
||||
// remove items from server.
|
||||
var results = Subscription.RemoveItems(items);
|
||||
|
||||
if (results == null || results.Length == 0)
|
||||
{
|
||||
throw new OpcResultException(new OpcResult(OpcResult.E_FAIL.Code, OpcResult.FuncCallType.SysFuncCall, null), "The browse operation cannot continue");
|
||||
}
|
||||
|
||||
// remove items from local list if successful.
|
||||
var itemList = new ArrayList();
|
||||
|
||||
foreach (var item in daItems_)
|
||||
{
|
||||
var removed = false;
|
||||
|
||||
for (var ii = 0; ii < results.Length; ii++)
|
||||
{
|
||||
if (item.ServerHandle.Equals(items[ii].ServerHandle))
|
||||
{
|
||||
removed = results[ii].Result.Succeeded();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!removed) itemList.Add(item);
|
||||
}
|
||||
|
||||
// update local list.
|
||||
daItems_ = (TsCDaItem[])itemList.ToArray(typeof(TsCDaItem));
|
||||
|
||||
// update the local state.
|
||||
GetState();
|
||||
|
||||
// return results.
|
||||
return results;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads a set of subscription items.
|
||||
/// </summary>
|
||||
public TsCDaItemValueResult[] Read(TsCDaItem[] items)
|
||||
{
|
||||
LicenseHandler.ValidateFeatures(LicenseHandler.ProductFeature.DataAccess);
|
||||
return Subscription.Read(items);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a set of subscription items.
|
||||
/// </summary>
|
||||
public OpcItemResult[] Write(TsCDaItemValue[] items)
|
||||
{
|
||||
LicenseHandler.ValidateFeatures(LicenseHandler.ProductFeature.DataAccess);
|
||||
return Subscription.Write(items);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Begins an asynchronous read operation for a set of items.
|
||||
/// </summary>
|
||||
/// <param name="items">The set of items to read (must include the item name).</param>
|
||||
/// <param name="requestHandle">An identifier for the request assigned by the caller.</param>
|
||||
/// <param name="callback">A delegate used to receive notifications when the request completes.</param>
|
||||
/// <param name="request">An object that contains the state of the request (used to cancel the request).</param>
|
||||
/// <returns>A set of results containing any errors encountered when the server validated the items.</returns>
|
||||
public OpcItemResult[] Read(
|
||||
TsCDaItem[] items,
|
||||
object requestHandle,
|
||||
TsCDaReadCompleteEventHandler callback,
|
||||
out IOpcRequest request)
|
||||
{
|
||||
LicenseHandler.ValidateFeatures(LicenseHandler.ProductFeature.DataAccess);
|
||||
return Subscription.Read(items, requestHandle, callback, out request);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Begins an asynchronous write operation for a set of items.
|
||||
/// </summary>
|
||||
/// <param name="items">The set of item values to write (must include the item name).</param>
|
||||
/// <param name="requestHandle">An identifier for the request assigned by the caller.</param>
|
||||
/// <param name="callback">A delegate used to receive notifications when the request completes.</param>
|
||||
/// <param name="request">An object that contains the state of the request (used to cancel the request).</param>
|
||||
/// <returns>A set of results containing any errors encountered when the server validated the items.</returns>
|
||||
public OpcItemResult[] Write(
|
||||
TsCDaItemValue[] items,
|
||||
object requestHandle,
|
||||
TsCDaWriteCompleteEventHandler callback,
|
||||
out IOpcRequest request)
|
||||
{
|
||||
LicenseHandler.ValidateFeatures(LicenseHandler.ProductFeature.DataAccess);
|
||||
return Subscription.Write(items, requestHandle, callback, out request);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cancels an asynchronous request.
|
||||
/// </summary>
|
||||
public void Cancel(IOpcRequest request, TsCDaCancelCompleteEventHandler callback)
|
||||
{
|
||||
LicenseHandler.ValidateFeatures(LicenseHandler.ProductFeature.DataAccess);
|
||||
Subscription.Cancel(request, callback);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tells the server to send an data change update for all subscription items.
|
||||
/// </summary>
|
||||
public void Refresh() { Subscription.Refresh(); }
|
||||
|
||||
/// <summary>
|
||||
/// Causes the server to send a data changed notification for all active items.
|
||||
/// </summary>
|
||||
/// <param name="requestHandle">An identifier for the request assigned by the caller.</param>
|
||||
/// <param name="request">An object that contains the state of the request (used to cancel the request).</param>
|
||||
/// <returns>A set of results containing any errors encountered when the server validated the items.</returns>
|
||||
public void Refresh(
|
||||
object requestHandle,
|
||||
out IOpcRequest request)
|
||||
{
|
||||
LicenseHandler.ValidateFeatures(LicenseHandler.ProductFeature.DataAccess);
|
||||
Subscription.Refresh(requestHandle, out request);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets whether data change callbacks are enabled.
|
||||
/// </summary>
|
||||
public void SetEnabled(bool enabled)
|
||||
{
|
||||
LicenseHandler.ValidateFeatures(LicenseHandler.ProductFeature.DataAccess);
|
||||
Subscription.SetEnabled(enabled);
|
||||
enabled_ = enabled;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets whether data change callbacks are enabled.
|
||||
/// </summary>
|
||||
public bool GetEnabled()
|
||||
{
|
||||
LicenseHandler.ValidateFeatures(LicenseHandler.ProductFeature.DataAccess);
|
||||
enabled_ = Subscription.GetEnabled();
|
||||
return enabled_;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region ISubscription
|
||||
/// <summary>
|
||||
/// An event to receive data change updates.
|
||||
/// </summary>
|
||||
public event TsCDaDataChangedEventHandler DataChangedEvent {
|
||||
add => Subscription.DataChangedEvent += value;
|
||||
remove => Subscription.DataChangedEvent -= value;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
316
Technosoftware/DaAeHdaClient/Da/SubscriptionCollection.cs
Normal file
316
Technosoftware/DaAeHdaClient/Da/SubscriptionCollection.cs
Normal file
@@ -0,0 +1,316 @@
|
||||
#region Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
// Web: https://www.technosoftware.com
|
||||
//
|
||||
// The source code in this file is covered under a dual-license scenario:
|
||||
// - Owner of a purchased license: SCLA 1.0
|
||||
// - GPL V3: everybody else
|
||||
//
|
||||
// SCLA license terms accompanied with this source code.
|
||||
// See SCLA 1.0: https://technosoftware.com/license/Source_Code_License_Agreement.pdf
|
||||
//
|
||||
// GNU General Public License as published by the Free Software Foundation;
|
||||
// version 3 of the License are accompanied with this source code.
|
||||
// See https://technosoftware.com/license/GPLv3License.txt
|
||||
//
|
||||
// This source code is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//-----------------------------------------------------------------------------
|
||||
#endregion Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
|
||||
#region Using Directives
|
||||
using System;
|
||||
using System.Collections;
|
||||
#endregion
|
||||
|
||||
namespace Technosoftware.DaAeHdaClient.Da
|
||||
{
|
||||
/// <summary>A collection of subscriptions.</summary>
|
||||
[Serializable]
|
||||
public class TsCDaSubscriptionCollection : ICollection, ICloneable, IList
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
#region Fields
|
||||
|
||||
private ArrayList _subscriptions = new ArrayList();
|
||||
|
||||
#endregion
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
#region Constructors, Destructor, Initialization
|
||||
|
||||
/// <summary>
|
||||
/// Initializes object with the default values.
|
||||
/// </summary>
|
||||
public TsCDaSubscriptionCollection() { }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes object with the specified SubscriptionCollection object.
|
||||
/// </summary>
|
||||
public TsCDaSubscriptionCollection(TsCDaSubscriptionCollection subscriptions)
|
||||
{
|
||||
if (subscriptions != null)
|
||||
{
|
||||
foreach (TsCDaSubscription subscription in subscriptions)
|
||||
{
|
||||
Add(subscription);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
#region Properties
|
||||
|
||||
/// <summary>
|
||||
/// Gets the item at the specified index.
|
||||
/// </summary>
|
||||
public TsCDaSubscription this[int index]
|
||||
{
|
||||
get => (TsCDaSubscription)_subscriptions[index];
|
||||
set => _subscriptions[index] = value;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
#region ICloneable Members
|
||||
|
||||
/// <summary>
|
||||
/// Creates a deep copy of the object.
|
||||
/// </summary>
|
||||
public virtual object Clone()
|
||||
{
|
||||
var clone = (TsCDaSubscriptionCollection)MemberwiseClone();
|
||||
|
||||
clone._subscriptions = new ArrayList();
|
||||
|
||||
foreach (TsCDaSubscription subscription in _subscriptions)
|
||||
{
|
||||
clone._subscriptions.Add(subscription.Clone());
|
||||
}
|
||||
|
||||
return clone;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
#region ICollection Members
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether access to the ICollection is synchronized (thread-safe).
|
||||
/// </summary>
|
||||
public bool IsSynchronized => false;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of objects in the collection.
|
||||
/// </summary>
|
||||
public int Count => (_subscriptions != null) ? _subscriptions.Count : 0;
|
||||
|
||||
/// <summary>
|
||||
/// Copies the objects to an Array, starting at a the specified index.
|
||||
/// </summary>
|
||||
/// <param name="array">The one-dimensional Array that is the destination for the objects.</param>
|
||||
/// <param name="index">The zero-based index in the Array at which copying begins.</param>
|
||||
public void CopyTo(Array array, int index)
|
||||
{
|
||||
if (_subscriptions != null)
|
||||
{
|
||||
_subscriptions.CopyTo(array, index);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copies the objects to an Array, starting at a the specified index.
|
||||
/// </summary>
|
||||
/// <param name="array">The one-dimensional Array that is the destination for the objects.</param>
|
||||
/// <param name="index">The zero-based index in the Array at which copying begins.</param>
|
||||
public void CopyTo(TsCDaSubscription[] array, int index)
|
||||
{
|
||||
CopyTo((Array)array, index);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether access to the ICollection is synchronized (thread-safe).
|
||||
/// </summary>
|
||||
public object SyncRoot => this;
|
||||
|
||||
#endregion
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
#region IEnumerable Members
|
||||
|
||||
/// <summary>
|
||||
/// Returns an enumerator that can iterate through a collection.
|
||||
/// </summary>
|
||||
/// <returns>An IEnumerator that can be used to iterate through the collection.</returns>
|
||||
public IEnumerator GetEnumerator()
|
||||
{
|
||||
return _subscriptions.GetEnumerator();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
#region IList Members
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the IList is read-only.
|
||||
/// </summary>
|
||||
public bool IsReadOnly => false;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the element at the specified index.
|
||||
/// </summary>
|
||||
object IList.this[int index]
|
||||
{
|
||||
get => _subscriptions[index];
|
||||
|
||||
set
|
||||
{
|
||||
if (!typeof(TsCDaSubscription).IsInstanceOfType(value))
|
||||
{
|
||||
throw new ArgumentException("May only add Subscription objects into the collection.");
|
||||
}
|
||||
|
||||
_subscriptions[index] = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the IList subscription at the specified index.
|
||||
/// </summary>
|
||||
/// <param name="index">The zero-based index of the subscription to remove.</param>
|
||||
public void RemoveAt(int index)
|
||||
{
|
||||
_subscriptions.RemoveAt(index);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inserts an subscription to the IList at the specified position.
|
||||
/// </summary>
|
||||
/// <param name="index">The zero-based index at which value should be inserted.</param>
|
||||
/// <param name="value">The Object to insert into the IList. </param>
|
||||
public void Insert(int index, object value)
|
||||
{
|
||||
if (!typeof(TsCDaSubscription).IsInstanceOfType(value))
|
||||
{
|
||||
throw new ArgumentException("May only add Subscription objects into the collection.");
|
||||
}
|
||||
|
||||
_subscriptions.Insert(index, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the first occurrence of a specific object from the IList.
|
||||
/// </summary>
|
||||
/// <param name="value">The Object to remove from the IList.</param>
|
||||
public void Remove(object value)
|
||||
{
|
||||
_subscriptions.Remove(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the IList contains a specific value.
|
||||
/// </summary>
|
||||
/// <param name="value">The Object to locate in the IList.</param>
|
||||
/// <returns>true if the Object is found in the IList; otherwise, false.</returns>
|
||||
public bool Contains(object value)
|
||||
{
|
||||
return _subscriptions.Contains(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes all subscriptions from the IList.
|
||||
/// </summary>
|
||||
public void Clear()
|
||||
{
|
||||
_subscriptions.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines the index of a specific subscription in the IList.
|
||||
/// </summary>
|
||||
/// <param name="value">The Object to locate in the IList.</param>
|
||||
/// <returns>The index of value if found in the list; otherwise, -1.</returns>
|
||||
public int IndexOf(object value)
|
||||
{
|
||||
return _subscriptions.IndexOf(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds an subscription to the IList.
|
||||
/// </summary>
|
||||
/// <param name="value">The Object to add to the IList. </param>
|
||||
/// <returns>The position into which the new element was inserted.</returns>
|
||||
public int Add(object value)
|
||||
{
|
||||
if (!typeof(TsCDaSubscription).IsInstanceOfType(value))
|
||||
{
|
||||
throw new ArgumentException("May only add Subscription objects into the collection.");
|
||||
}
|
||||
|
||||
return _subscriptions.Add(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the IList has a fixed size.
|
||||
/// </summary>
|
||||
public bool IsFixedSize => false;
|
||||
|
||||
/// <summary>
|
||||
/// Inserts an subscription to the IList at the specified position.
|
||||
/// </summary>
|
||||
/// <param name="index">The zero-based index at which value should be inserted.</param>
|
||||
/// <param name="value">The Object to insert into the IList. </param>
|
||||
public void Insert(int index, TsCDaSubscription value)
|
||||
{
|
||||
Insert(index, (object)value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the first occurrence of a specific object from the IList.
|
||||
/// </summary>
|
||||
/// <param name="value">The Object to remove from the IList.</param>
|
||||
public void Remove(TsCDaSubscription value)
|
||||
{
|
||||
Remove((object)value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the IList contains a specific value.
|
||||
/// </summary>
|
||||
/// <param name="value">The Object to locate in the IList.</param>
|
||||
/// <returns>true if the Object is found in the IList; otherwise, false.</returns>
|
||||
public bool Contains(TsCDaSubscription value)
|
||||
{
|
||||
return Contains((object)value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines the index of a specific subscription in the IList.
|
||||
/// </summary>
|
||||
/// <param name="value">The Object to locate in the IList.</param>
|
||||
/// <returns>The index of value if found in the list; otherwise, -1.</returns>
|
||||
public int IndexOf(TsCDaSubscription value)
|
||||
{
|
||||
return IndexOf((object)value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds an subscription to the IList.
|
||||
/// </summary>
|
||||
/// <param name="value">The Object to add to the IList. </param>
|
||||
/// <returns>The position into which the new element was inserted.</returns>
|
||||
public int Add(TsCDaSubscription value)
|
||||
{
|
||||
return Add((object)value);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
172
Technosoftware/DaAeHdaClient/Da/SubscriptionState.cs
Normal file
172
Technosoftware/DaAeHdaClient/Da/SubscriptionState.cs
Normal file
@@ -0,0 +1,172 @@
|
||||
#region Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
// Web: https://www.technosoftware.com
|
||||
//
|
||||
// The source code in this file is covered under a dual-license scenario:
|
||||
// - Owner of a purchased license: SCLA 1.0
|
||||
// - GPL V3: everybody else
|
||||
//
|
||||
// SCLA license terms accompanied with this source code.
|
||||
// See SCLA 1.0: https://technosoftware.com/license/Source_Code_License_Agreement.pdf
|
||||
//
|
||||
// GNU General Public License as published by the Free Software Foundation;
|
||||
// version 3 of the License are accompanied with this source code.
|
||||
// See https://technosoftware.com/license/GPLv3License.txt
|
||||
//
|
||||
// This source code is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
// or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//-----------------------------------------------------------------------------
|
||||
#endregion Copyright (c) 2011-2023 Technosoftware GmbH. All rights reserved
|
||||
|
||||
#region Using Directives
|
||||
using System;
|
||||
#endregion
|
||||
|
||||
namespace Technosoftware.DaAeHdaClient.Da
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes the state of a subscription.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class TsCDaSubscriptionState : ICloneable
|
||||
{
|
||||
#region Fields
|
||||
private bool active_ = true;
|
||||
private int updateRate_ = 500;
|
||||
private float deadband_;
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
/// <summary>
|
||||
/// A unique name for the subscription controlled by the client.
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A unique identifier for the subscription assigned by the client.
|
||||
/// </summary>
|
||||
public object ClientHandle { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A unique subscription identifier assigned by the server.
|
||||
/// </summary>
|
||||
public object ServerHandle { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The locale used for any error messages or results returned to the client.
|
||||
/// </summary>
|
||||
public string Locale { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether the subscription is scanning for updates to send to the client.
|
||||
/// </summary>
|
||||
public bool Active
|
||||
{
|
||||
get => active_;
|
||||
set => active_ = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The rate in milliseconds at which the server checks of updates to send to the
|
||||
/// client.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Client Specifies the fastest rate at which data changes may be sent to the
|
||||
/// <see cref="TsCDaDataChangedEventHandler">DataChangedHandler</see>
|
||||
/// for items in this subscription. This also indicates the desired accuracy of Cached
|
||||
/// Data. This is intended only to control the behavior of the interface. How the
|
||||
/// server deals with the update rate and how often it actually polls the hardware
|
||||
/// internally is an implementation detail. Passing 0 indicates the server should use
|
||||
/// the fastest practical rate.
|
||||
/// </remarks>
|
||||
public int UpdateRate
|
||||
{
|
||||
get => updateRate_;
|
||||
set => updateRate_ = value;
|
||||
}
|
||||
|
||||
/// <summary><para>The maximum period in milliseconds between updates sent to the client.</para></summary>
|
||||
/// <remarks>
|
||||
/// <para>Clients can set the keep-alive time for a subscription to cause the server to
|
||||
/// provide client callbacks on the subscription when there are no new events to
|
||||
/// report. Clients can then be assured of the health of the server and subscription
|
||||
/// without resorting to pinging the server with calls to GetStatus().</para>
|
||||
/// <para>Using this facility, a client can expect a callback (data or keep-alive)
|
||||
/// within the specified keep-alive time.</para>
|
||||
/// <para>Servers shall reset their keep-alive timers when real data is sent (i.e. it
|
||||
/// is not acceptable to constantly send the keep-alive callback at a fixed period
|
||||
/// equal to the keep-alive time irrespective of data callbacks).</para>
|
||||
/// <para>
|
||||
/// The keep-alive callback consists of a call to the
|
||||
/// <see cref="TsCDaDataChangedEventHandler">DataChangedEventHandler</see>
|
||||
/// with an empty value list.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// Keep-alive callbacks will not occur when the subscription is inactive.
|
||||
/// Keep-alive callbacks do not affect the value of the
|
||||
/// <see cref="OpcServerStatus.LastUpdateTime">LastUpdateTime</see> returned by
|
||||
/// <see cref="TsCDaServer.GetServerStatus">GetServerStatus()</see> .
|
||||
/// </para>
|
||||
/// <para><strong>Available only for OPC Data Access 3.0 and OPC XML-DA
|
||||
/// servers.</strong></para>
|
||||
/// </remarks>
|
||||
public int KeepAlive { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The minimum percentage change from 0.0 to 100.0 required to trigger a data update
|
||||
/// for an item.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>The range of the Deadband is from 0.0 to 100.0 Percent. Deadband will only
|
||||
/// apply to items in the subscription that have a dwEUType of Analog available. If the
|
||||
/// EU Type is Analog, then the EU Low and EU High values for the item can be used to
|
||||
/// calculate the range for the item. This range will be multiplied with the Deadband
|
||||
/// to generate an exception limit. An exception is determined as follows:</para>
|
||||
/// <blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
|
||||
/// <para>Exception if (absolute value of (last cached value - current value) >
|
||||
/// (pPercentDeadband/100.0) * (EU High - EU Low) )</para>
|
||||
/// </blockquote>
|
||||
/// <para>The PercentDeadband can be set when CreateSubscription is called, allowing
|
||||
/// the same PercentDeadband to be used for all items within that particular
|
||||
/// subscription. However, with OPC DA 3.0, it is allowable to set the PercentDeadband
|
||||
/// on a per item basis. This means that each item can potentially override the
|
||||
/// PercentDeadband set for the subscription it resides within.</para>
|
||||
/// <para>If the exception limit is exceeded, then the last cached value is updated
|
||||
/// with the new value and a notification will be sent to the client’s callback (if
|
||||
/// any). The PercentDeadband is an optional behavior for the server. If the client
|
||||
/// does not specify this value on a server that does support the behavior, the default
|
||||
/// value of 0 (zero) will be assumed, and all value changes will update the CACHE.
|
||||
/// Note that the timestamp will be updated regardless of whether the cached value is
|
||||
/// updated. A server which does not support deadband should return an error
|
||||
/// (OPC_E_DEADBANDNOTSUPPORTED) if the client requests a deadband other than
|
||||
/// 0.0.</para>
|
||||
/// <para>The UpdateRate for a subscription or the sampling rate of the item, if set,
|
||||
/// determines time between when a value is checked to see if the exception limit has
|
||||
/// been exceeded. The PercentDeadband is used to keep noisy signals from updating the
|
||||
/// client unnecessarily.</para>
|
||||
/// </remarks>
|
||||
public float Deadband
|
||||
{
|
||||
get => deadband_;
|
||||
set => deadband_ = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// TimeZone Bias of Group (in minutes).
|
||||
/// </summary>
|
||||
public int TimeBias { get; set; }
|
||||
#endregion
|
||||
|
||||
#region ICloneable Members
|
||||
/// <summary>
|
||||
/// Creates a shallow copy of the object.
|
||||
/// </summary>
|
||||
public virtual object Clone()
|
||||
{
|
||||
return MemberwiseClone();
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user