Skip to content

Commit 459473c

Browse files
committed
feat: 增加 Opc 服务
1 parent 5723e03 commit 459473c

8 files changed

Lines changed: 150 additions & 45 deletions

File tree

NuGet.Config

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,6 @@
22
<configuration>
33
<packageSources>
44
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
5+
<add key="Opc" value="C:\Program Files (x86)\OPC Foundation\NuGetPackages" />
56
</packageSources>
67
</configuration>

src/extensions/BootstrapBlazor.OpcDa/BootstrapBlazor.OpcDa.csproj

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,38 @@
22

33
<PropertyGroup>
44
<Version>9.0.0</Version>
5+
<RootNamespace>BootstrapBlazor.OpcDa</RootNamespace>
56
</PropertyGroup>
67

78
<PropertyGroup>
89
<PackageTags>Bootstrap Blazor WebAssembly wasm UI Components SqlSugar</PackageTags>
910
<Description>Bootstrap UI components extensions of SqlSugar</Description>
1011
</PropertyGroup>
1112

12-
<ItemGroup>
13-
<Using Remove="BootstrapBlazor.Components" />
14-
<Using Remove="Microsoft.AspNetCore.Components" />
15-
<Using Remove="Microsoft.Extensions.DependencyInjection" />
13+
<ItemGroup Condition="'$(TargetFramework)' == 'net6.0'">
14+
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.*" />
15+
</ItemGroup>
16+
17+
<ItemGroup Condition="'$(TargetFramework)' == 'net7.0'">
18+
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.*" />
19+
</ItemGroup>
20+
21+
<ItemGroup Condition="'$(TargetFramework)' == 'net8.0'">
22+
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.*" />
23+
</ItemGroup>
24+
25+
<ItemGroup Condition="'$(TargetFramework)' == 'net9.0'">
26+
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.*" />
1627
</ItemGroup>
1728

1829
<ItemGroup>
1930
<PackageReference Include="OpcNetApi.Com" Version="2.1.108" />
2031
</ItemGroup>
2132

33+
<ItemGroup>
34+
<Using Remove="BootstrapBlazor.Components" />
35+
<Using Remove="Microsoft.AspNetCore.Components" />
36+
<Using Remove="Microsoft.Extensions.DependencyInjection" />
37+
</ItemGroup>
38+
2239
</Project>

src/extensions/BootstrapBlazor.OpcDa/Extensions/Extensions.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,9 @@ public static Quality ToQuality(this Opc.Da.Quality quality)
1515
? Quality.Good
1616
: Quality.Bad;
1717
}
18+
19+
public static ISubscription ToOpcSubscription(this Opc.Da.ISubscription subscription)
20+
{
21+
return new OpcSubscription(subscription);
22+
}
1823
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
// Website: https://www.blazor.zone or https://argozhang.github.io/
4+
5+
using BootstrapBlazor.OpcDa;
6+
using System.Runtime.Versioning;
7+
8+
namespace Microsoft.Extensions.DependencyInjection;
9+
10+
/// <summary>
11+
/// Opc Da 服务扩展类
12+
/// </summary>
13+
public static class ServiceCollectionExtensions
14+
{
15+
/// <summary>
16+
/// 增加 Opc 操作服务
17+
/// </summary>
18+
/// <param name="services"></param>
19+
/// <returns></returns>
20+
[SupportedOSPlatform("windows")]
21+
public static IServiceCollection AddOpcServer(this IServiceCollection services)
22+
{
23+
services.AddSingleton<IOpcServer, OpcServer>();
24+
return services;
25+
}
26+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
// Website: https://www.blazor.zone or https://argozhang.github.io/
4+
5+
namespace BootstrapBlazor.OpcDa;
6+
7+
/// <summary>
8+
/// Opc Server 接口定义
9+
/// </summary>
10+
public interface IOpcServer : IDisposable
11+
{
12+
/// <summary>
13+
/// 获得 OPC Server 是否已连接
14+
/// </summary>
15+
bool IsConnected { get; }
16+
17+
/// <summary>
18+
/// 获得 OPC Server 名称
19+
/// </summary>
20+
string? ServerName { get; }
21+
22+
/// <summary>
23+
/// 连接到 OPC Server 方法
24+
/// </summary>
25+
/// <param name="serverName"></param>
26+
/// <returns></returns>
27+
bool Connect(string serverName);
28+
29+
/// <summary>
30+
/// 断开连接方法
31+
/// </summary>
32+
void Disconnect();
33+
34+
/// <summary>
35+
/// 取消订阅方法
36+
/// </summary>
37+
/// <param name="subscription"></param>
38+
void CancelSubscription(ISubscription subscription);
39+
40+
/// <summary>
41+
/// 创建订阅方法
42+
/// </summary>
43+
/// <param name="name">订阅名称</param>
44+
/// <param name="updateRate">更新频率 默认 1000 毫秒</param>
45+
/// <param name="active">是否激活 默认 true</param>
46+
/// <returns></returns>
47+
ISubscription CreateSubscription(string name, int updateRate = 1000, bool active = true);
48+
49+
/// <summary>
50+
/// 读取 Item 值方法
51+
/// </summary>
52+
/// <param name="items"></param>
53+
/// <returns></returns>
54+
HashSet<OpcItem> Read(params List<string> items);
55+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
// Website: https://www.blazor.zone or https://argozhang.github.io/
4+
5+
namespace BootstrapBlazor.OpcDa;
6+
7+
/// <summary>
8+
/// 订阅接口定义
9+
/// </summary>
10+
public interface ISubscription
11+
{
12+
/// <summary>
13+
/// 数据变更回调
14+
/// </summary>
15+
Func<List<OpcItem>>? DataChanged { get; set; }
16+
17+
/// <summary>
18+
/// 获得 <see cref="Opc.Da.ISubscription"/> 实例
19+
/// </summary>
20+
/// <returns></returns>
21+
Opc.Da.ISubscription GetSubscription();
22+
}

src/extensions/BootstrapBlazor.OpcDa/OpcServer.cs

Lines changed: 8 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ namespace BootstrapBlazor.OpcDa;
1313
/// OPC Server 操作类
1414
/// </summary>
1515
[SupportedOSPlatform("windows")]
16-
public partial class OpcServer : IDisposable
16+
class OpcServer : IOpcServer
1717
{
1818
private Opc.Da.Server? _server = null;
1919
private readonly ConcurrentDictionary<string, HashSet<OpcItem>> _valuesCache = [];
@@ -69,53 +69,20 @@ public void Disconnect()
6969
/// 创建订阅方法
7070
/// </summary>
7171
/// <param name="name">订阅名称</param>
72-
/// <param name="updateRate"></param>
73-
/// <param name="active"></param>
74-
/// <param name="items"></param>
72+
/// <param name="updateRate">更新频率 默认 1000 毫秒</param>
73+
/// <param name="active">是否激活 默认 true</param>
7574
/// <returns></returns>
76-
public ISubscription CreateSubscription(string name, int updateRate, bool active = true, Item[]? items = null)
75+
public ISubscription CreateSubscription(string name, int updateRate = 1000, bool active = true)
7776
{
7877
var server = GetOpcServer();
7978
var subscription = server.CreateSubscription(new SubscriptionState
8079
{
8180
Name = name,
82-
Active = active,
81+
Deadband = 0,
8382
UpdateRate = updateRate,
84-
Deadband = 0
83+
Active = active
8584
});
86-
87-
if (items is { Length: > 0 })
88-
{
89-
subscription.AddItems(items);
90-
subscription.DataChanged += (subscriptionHandle, requestHandle, values) =>
91-
{
92-
foreach (var value in values)
93-
{
94-
_valuesCache.AddOrUpdate(name, key => AddFactory(value), (key, v) => UpdateFactory(v, value));
95-
}
96-
};
97-
}
98-
return subscription;
99-
}
100-
101-
private static HashSet<OpcItem> AddFactory(ItemValueResult value)
102-
{
103-
return new HashSet<OpcItem>(OpcItemEqualityComparer.Default)
104-
{
105-
new(value.ItemName, value.Quality.ToQuality() , value.Timestamp, value.Value)
106-
};
107-
}
108-
109-
private static HashSet<OpcItem> UpdateFactory(HashSet<OpcItem> items, ItemValueResult value)
110-
{
111-
var item = new OpcItem(value.ItemName, value.Quality.ToQuality(), value.Timestamp, value.Value);
112-
if (items.TryGetValue(item, out var v))
113-
{
114-
item.LastValue = v.Value;
115-
}
116-
items.Remove(item);
117-
items.Add(item);
118-
return items;
85+
return subscription.ToOpcSubscription();
11986
}
12087

12188
/// <summary>
@@ -126,7 +93,7 @@ private static HashSet<OpcItem> UpdateFactory(HashSet<OpcItem> items, ItemValueR
12693
public void CancelSubscription(ISubscription subscription)
12794
{
12895
var server = GetOpcServer();
129-
server.CancelSubscription(subscription);
96+
server.CancelSubscription(subscription.GetSubscription());
13097
}
13198

13299
/// <summary>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
// Website: https://www.blazor.zone or https://argozhang.github.io/
4+
5+
namespace BootstrapBlazor.OpcDa;
6+
7+
class OpcSubscription(Opc.Da.ISubscription subscription) : ISubscription
8+
{
9+
public Func<List<OpcItem>>? DataChanged { get; set; }
10+
11+
public Opc.Da.ISubscription GetSubscription() => subscription;
12+
}

0 commit comments

Comments
 (0)