Skip to content
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions BootstrapBlazor.Extensions.sln
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,14 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTestSvgIcon", "test\Uni
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BootstrapBlazor.FluentSystemIcon", "src\components\BootstrapBlazor.FluentSystemIcon\BootstrapBlazor.FluentSystemIcon.csproj", "{30449D30-0B4E-40FD-85BE-C9BAAC820162}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BootstrapBlazor.OpcUa", "src\components\BootstrapBlazor.OpcUa\BootstrapBlazor.OpcUa.csproj", "{6114A9DF-9DF5-474E-A5B0-25CDF0268B52}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTestOpcUa", "test\UnitTestOpcUa\UnitTestOpcUa.csproj", "{98373A64-E224-4715-AE02-A8C6DAFF3338}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BootstrapBlazor.OpcDa", "src\extensions\BootstrapBlazor.OpcDa\BootstrapBlazor.OpcDa.csproj", "{01007B10-7C3C-4136-83FF-981CA39AD3D4}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTestOpcDa", "test\UnitTestOpcDa\UnitTestOpcDa.csproj", "{835C8BA9-A9CC-4EA0-9002-34A20F8B2E86}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -522,6 +530,22 @@ Global
{30449D30-0B4E-40FD-85BE-C9BAAC820162}.Debug|Any CPU.Build.0 = Debug|Any CPU
{30449D30-0B4E-40FD-85BE-C9BAAC820162}.Release|Any CPU.ActiveCfg = Release|Any CPU
{30449D30-0B4E-40FD-85BE-C9BAAC820162}.Release|Any CPU.Build.0 = Release|Any CPU
{6114A9DF-9DF5-474E-A5B0-25CDF0268B52}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6114A9DF-9DF5-474E-A5B0-25CDF0268B52}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6114A9DF-9DF5-474E-A5B0-25CDF0268B52}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6114A9DF-9DF5-474E-A5B0-25CDF0268B52}.Release|Any CPU.Build.0 = Release|Any CPU
{98373A64-E224-4715-AE02-A8C6DAFF3338}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{98373A64-E224-4715-AE02-A8C6DAFF3338}.Debug|Any CPU.Build.0 = Debug|Any CPU
{98373A64-E224-4715-AE02-A8C6DAFF3338}.Release|Any CPU.ActiveCfg = Release|Any CPU
{98373A64-E224-4715-AE02-A8C6DAFF3338}.Release|Any CPU.Build.0 = Release|Any CPU
{01007B10-7C3C-4136-83FF-981CA39AD3D4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{01007B10-7C3C-4136-83FF-981CA39AD3D4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{01007B10-7C3C-4136-83FF-981CA39AD3D4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{01007B10-7C3C-4136-83FF-981CA39AD3D4}.Release|Any CPU.Build.0 = Release|Any CPU
{835C8BA9-A9CC-4EA0-9002-34A20F8B2E86}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{835C8BA9-A9CC-4EA0-9002-34A20F8B2E86}.Debug|Any CPU.Build.0 = Debug|Any CPU
{835C8BA9-A9CC-4EA0-9002-34A20F8B2E86}.Release|Any CPU.ActiveCfg = Release|Any CPU
{835C8BA9-A9CC-4EA0-9002-34A20F8B2E86}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -612,6 +636,10 @@ Global
{10D35EE5-FA31-4C80-B113-CD7A0FB76B4E} = {B6A98ADE-D26A-4D0B-8978-AB7AC915F5AE}
{7CAD5915-CE3E-31ED-B1AC-15C61C3ED8C3} = {B6A98ADE-D26A-4D0B-8978-AB7AC915F5AE}
{30449D30-0B4E-40FD-85BE-C9BAAC820162} = {FF1089BE-C704-4374-B629-C57C08E1798F}
{6114A9DF-9DF5-474E-A5B0-25CDF0268B52} = {FF1089BE-C704-4374-B629-C57C08E1798F}
{98373A64-E224-4715-AE02-A8C6DAFF3338} = {B6A98ADE-D26A-4D0B-8978-AB7AC915F5AE}
{01007B10-7C3C-4136-83FF-981CA39AD3D4} = {7B29E81D-92DE-46C8-8EDC-1B48C8F12BC2}
{835C8BA9-A9CC-4EA0-9002-34A20F8B2E86} = {B6A98ADE-D26A-4D0B-8978-AB7AC915F5AE}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {D5EB1960-6F30-4CE1-B375-EAE1F787D6FF}
Expand Down
1 change: 1 addition & 0 deletions NuGet.Config
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@
<configuration>
<packageSources>
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
<add key="Opc" value="C:\Program Files (x86)\OPC Foundation\NuGetPackages" />
</packageSources>
</configuration>
21 changes: 21 additions & 0 deletions src/components/BootstrapBlazor.OpcUa/BootstrapBlazor.OpcUa.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">

<PropertyGroup>
<Version>9.0.1</Version>
</PropertyGroup>

<PropertyGroup>
<PackageTags>Bootstrap Blazor WebAssembly wasm UI Components Opc Ua Client</PackageTags>
<Description>Bootstrap UI components extensions of OpcUa</Description>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="BootstrapBlazor" Version="$(BBVersion)" />
<PackageReference Include="OPCFoundation.NetStandard.Opc.Ua.Client" Version="1.5.376.235" />
</ItemGroup>

<ItemGroup>
<Using Include="BootstrapBlazor.Components" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
// Website: https://www.blazor.zone or https://argozhang.github.io/

namespace Microsoft.Extensions.DependencyInjection;

/// <summary>
/// OpcUa 服务扩展类
/// </summary>
public static class ServiceCollectionExtensions
{
/// <summary>
/// 增加 OpcUa 数据服务
/// </summary>
/// <param name="services"></param>
/// <returns></returns>
public static IServiceCollection AddBootstrapBlazorOpcUaService(this IServiceCollection services)
{
return services;
}
}
1 change: 1 addition & 0 deletions src/components/BootstrapBlazor.OpcUa/_Imports.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@using Microsoft.AspNetCore.Components.Web
51 changes: 51 additions & 0 deletions src/extensions/BootstrapBlazor.OpcDa/BootstrapBlazor.OpcDa.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<Version>9.0.0-beta01</Version>
<RootNamespace>BootstrapBlazor.OpcDa</RootNamespace>
</PropertyGroup>

<PropertyGroup>
<PackageTags>Bootstrap Blazor WebAssembly wasm UI Components SqlSugar</PackageTags>
<Description>Bootstrap UI components extensions of SqlSugar</Description>
</PropertyGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net6.0'">
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.*" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net7.0'">
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.*" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net8.0'">
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.*" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net9.0'">
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.*" />
</ItemGroup>

<ItemGroup>
<None Include="lib\OpcComRcw.dll" Pack="true" PackagePath="lib\net6.0" />
<None Include="lib\OpcNetApi.dll" Pack="true" PackagePath="lib\net6.0" />
<None Include="lib\OpcNetApi.Com.dll" Pack="true" PackagePath="lib\net6.0" />
</ItemGroup>

<ItemGroup>
<Reference Include="OpcComRcw" HintPath="lib\OpcComRcw.dll" Private="true" PackageCopyToOutput="true" />
<Reference Include="OpcNetApi" HintPath="lib\OpcComRcw.dll" Private="true" PackageCopyToOutput="true" />
<Reference Include="OpcNetApi.Com" HintPath="lib\OpcComRcw.dll" Private="true" PackageCopyToOutput="true" />
</ItemGroup>

<ItemGroup>
<Content Include="build\*.targets" PackagePath="build" />
</ItemGroup>

<ItemGroup>
<Using Remove="BootstrapBlazor.Components" />
<Using Remove="Microsoft.AspNetCore.Components" />
<Using Remove="Microsoft.Extensions.DependencyInjection" />
</ItemGroup>

</Project>
23 changes: 23 additions & 0 deletions src/extensions/BootstrapBlazor.OpcDa/Extensions/Extensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
// Website: https://www.blazor.zone or https://argozhang.github.io/

namespace BootstrapBlazor.OpcDa;

/// <summary>
/// 扩展方法类
/// </summary>
internal static class Extensions
{
public static Quality ToQuality(this Opc.Da.Quality quality)
{
return quality.QualityBits == Opc.Da.qualityBits.good
? Quality.Good
: Quality.Bad;
}

public static ISubscription ToOpcSubscription(this Opc.Da.ISubscription subscription)
{
return new OpcSubscription(subscription);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
// Website: https://www.blazor.zone or https://argozhang.github.io/

using BootstrapBlazor.OpcDa;
using System.Runtime.Versioning;

namespace Microsoft.Extensions.DependencyInjection;

/// <summary>
/// Opc Da 服务扩展类
/// </summary>
public static class ServiceCollectionExtensions
{
/// <summary>
/// 增加 Opc 操作服务
/// </summary>
/// <param name="services"></param>
/// <returns></returns>
[SupportedOSPlatform("windows")]
public static IServiceCollection AddOpcServer(this IServiceCollection services)
{
services.AddSingleton<IOpcServer, OpcServer>();
return services;
}
}
16 changes: 16 additions & 0 deletions src/extensions/BootstrapBlazor.OpcDa/IOpcItem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
// Website: https://www.blazor.zone or https://argozhang.github.io/

namespace BootstrapBlazor.OpcDa;

/// <summary>
///
/// </summary>
public interface IOpcItem
{
/// <summary>
///
/// </summary>
string Name { get; }
}
62 changes: 62 additions & 0 deletions src/extensions/BootstrapBlazor.OpcDa/IOpcServer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
// Website: https://www.blazor.zone or https://argozhang.github.io/

namespace BootstrapBlazor.OpcDa;

/// <summary>
/// Opc Server 接口定义
/// </summary>
public interface IOpcServer : IDisposable
{
/// <summary>
/// 获得 OPC Server 是否已连接
/// </summary>
bool IsConnected { get; }

/// <summary>
/// 获得 OPC Server 名称
/// </summary>
string? ServerName { get; }

/// <summary>
/// 连接到 OPC Server 方法
/// </summary>
/// <param name="serverName"></param>
/// <returns></returns>
bool Connect(string serverName);

/// <summary>
/// 断开连接方法
/// </summary>
void Disconnect();

/// <summary>
/// 取消订阅方法
/// </summary>
/// <param name="subscription"></param>
void CancelSubscription(ISubscription subscription);

/// <summary>
/// 创建订阅方法
/// </summary>
/// <param name="name">订阅名称</param>
/// <param name="updateRate">更新频率 默认 1000 毫秒</param>
/// <param name="active">是否激活 默认 true</param>
/// <returns></returns>
ISubscription CreateSubscription(string name, int updateRate = 1000, bool active = true);

/// <summary>
/// 读取 Item 值方法
/// </summary>
/// <param name="items"></param>
/// <returns></returns>
HashSet<OpcReadItem> Read(params HashSet<string> items);

/// <summary>
/// 读取 Item 值方法
/// </summary>
/// <param name="items"></param>
/// <returns></returns>
HashSet<OpcWriteItem> Write(params HashSet<OpcWriteItem> items);
}
33 changes: 33 additions & 0 deletions src/extensions/BootstrapBlazor.OpcDa/ISubscription.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
// Website: https://www.blazor.zone or https://argozhang.github.io/

namespace BootstrapBlazor.OpcDa;

/// <summary>
/// 订阅接口定义
/// </summary>
public interface ISubscription
{
/// <summary>
/// 获得/设置 是否保留最后一个值
/// </summary>
public bool KeepLastValue { get; set; }

/// <summary>
/// 获得/设置 数据变更回调
/// </summary>
Action<List<OpcReadItem>>? DataChanged { get; set; }

/// <summary>
/// 获得 <see cref="Opc.Da.ISubscription"/> 实例
/// </summary>
/// <returns></returns>
Opc.Da.ISubscription GetSubscription();

/// <summary>
/// 增加数据项
/// </summary>
/// <param name="items"></param>
void AddItems(IEnumerable<string> items);
}
31 changes: 31 additions & 0 deletions src/extensions/BootstrapBlazor.OpcDa/OpcItemEqualityComparer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
// Website: https://www.blazor.zone or https://argozhang.github.io/

namespace BootstrapBlazor.OpcDa;

/// <summary>
/// <see cref="IOpcItem"/> 比较器
/// </summary>
public class OpcItemEqualityComparer<TItem> : IEqualityComparer<TItem> where TItem : IOpcItem
{
/// <summary>
/// 获得 <see cref="OpcItemEqualityComparer{TItem}"/> 实例
/// </summary>
public static OpcItemEqualityComparer<TItem> Default { get; } = new();

/// <summary>
/// <inheritdoc/>
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <returns></returns>
public bool Equals(TItem? x, TItem? y) => x?.Name == y?.Name;

/// <summary>
/// <inheritdoc/>
/// </summary>
/// <param name="item"></param>
/// <returns></returns>
public int GetHashCode([DisallowNull] TItem item) => item.Name.GetHashCode();
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue: GetHashCode does not handle null Name property.

Add a null check for Name or enforce that Name cannot be null to prevent NullReferenceException.

}
16 changes: 16 additions & 0 deletions src/extensions/BootstrapBlazor.OpcDa/OpcReadItem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
// Website: https://www.blazor.zone or https://argozhang.github.io/

namespace BootstrapBlazor.OpcDa;

/// <summary>
/// OPC Item 读取实体类
/// </summary>
public record struct OpcReadItem(string Name, Quality Quality, DateTime Timestamp, object? Value) : IOpcItem
{
/// <summary>
/// 获得 Opc Item 上次值
/// </summary>
public object? LastValue { get; set; }
}
Loading
Loading