mirror of
https://github.com/OPCFoundation/UA-.NETStandard.git
synced 2026-10-17 05:11:13 +08:00
281596a24d
> Tracking issue #4576. #4577 and #4578 are merged, so this branch is rebased > onto `master` and contains only the Pumps commits. ## Summary Third of four stacked PRs. Adds OPC 40223 Pumps and Vacuum Pumps as a model package plus a server and a client SDK, over the Machinery and DI packages. | Package | Content | |---|---| | `Opc.Ua.Pumps` | OPC 40223 1.0.0, generated from the unmodified UA-Nodeset publication, plus the snapshot contracts both sides share (`PumpNameplate`, `PumpConfigurationData`, `PumpOperationalData`, `PumpMaintenanceData`, `PumpSupervisionStatus`, `PumpPortDescriptor`, `MultiPumpConfiguration`, gathered into `PumpSnapshot`) | | `Opc.Ua.Pumps.Server` | `AddPumps()` / `ConfigurePumps(...)`; `PumpsNodeManager : DiNodeManager` places each pump below `DeviceSet` and organizes it into the Machinery `Machines` folder; browse-name-addressed builders reach all ~3000 optional children without a method per child and create them through the model's own `CreateChild` | | `Opc.Ua.Pumps.Client` | discovery in both places (de-duplicated, vendor subtypes included), a reader per `PumpType` group, whole-pump snapshots; the open groups come back as a `PumpValueSet` keyed by the generated `BrowseNames` | The model requires Machinery 1.0.0 and DI 1.02.2 and resolves against the newer Machinery 1.04.1 and DI packages in this repository, since a `RequiredModel` version is a lower bound. The OPC 40223 NodeSet is large, so the model commit is too; the hand-written code starts at the server commit. `samples/DI/PumpDeviceIntegrationServer` is left as it is: its local NodeSet copies are also fixtures of `Opc.Ua.Types.Tests` and `Opc.Ua.WotCon.Tests`. Moving it onto these packages would be a separate follow-up (see #4576). ## Review follow-ups Separate commits after the docs/samples commit, each with a test that fails without it. - Copilot review: `PumpValue.AsStringArray` and `PumpValueSet.Names` return `ArrayOf<string>` with its null sentinel instead of `Nullable<ArrayOf<string>>`; the `PumpBuilder` uses `Variant.Null`. - Own review with the rubric in `.github/copilot-instructions.md`: pump creation is serialized from the duplicate check to the registration, so two concurrent calls with the same name no longer both add a pump; the client lets a failed browse call propagate instead of reading it as "no children"; the `ReadSupervisionAsync` docs say which read options apply. ## Testing - `tests/Opc.Ua.Pumps.Tests`: 73 tests on net8 and net10 and with the netstandard2.1 libraries; the client/server tests connect a real session over `opc.tcp` to a hosted `PumpsNodeManager`. - `UA.slnx` builds for net472, net48, netstandard2.0/2.1 and net8/9/10 with SDK 10.0.401 and no warnings. - Changed-line coverage of this layer (`check-coverage.ps1`): 97.30 % (1550 of 1593 changed lines, against `master`). - Fork CI, full PR matrix incl. macOS: green, all 184 jobs ([run 36622243774](https://github.com/biancode/UA-.NETStandard/actions/runs/36622243774)); CodeQL: green ([run 36622248255](https://github.com/biancode/UA-.NETStandard/actions/runs/36622248255)). - Together with the other layer (Pumps and Scales merged on top of Machinery), built for every target framework and tested on net8, net10 and with the netstandard2.1 libraries, with the samples published. - Beyond the in-repo tests the implementation has been validated end to end against a separate, non-public OPC UA client and server. ## Reviewing Commits: model package → server → client → tests → docs and samples → review follow-ups.
78 lines
3.2 KiB
C#
78 lines
3.2 KiB
C#
/* ========================================================================
|
|
* Copyright (c) 2005-2026 The OPC Foundation, Inc. All rights reserved.
|
|
*
|
|
* OPC Foundation MIT License 1.00
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person
|
|
* obtaining a copy of this software and associated documentation
|
|
* files (the "Software"), to deal in the Software without
|
|
* restriction, including without limitation the rights to use,
|
|
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
* copies of the Software, and to permit persons to whom the
|
|
* Software is furnished to do so, subject to the following
|
|
* conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be
|
|
* included in all copies or substantial portions of the Software.
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
* OTHER DEALINGS IN THE SOFTWARE.
|
|
*
|
|
* The complete license agreement can be found here:
|
|
* http://opcfoundation.org/License/MIT/1.00/
|
|
* ======================================================================*/
|
|
|
|
using System;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.Extensions.DependencyInjection.Extensions;
|
|
using Opc.Ua;
|
|
using Opc.Ua.Client;
|
|
using Opc.Ua.Pumps.Client;
|
|
|
|
namespace Microsoft.Extensions.DependencyInjection
|
|
{
|
|
/// <summary>
|
|
/// Registers the Pumps client over the managed OPC UA session.
|
|
/// </summary>
|
|
public static class OpcUaPumpsClientBuilderExtensions
|
|
{
|
|
/// <summary>
|
|
/// Registers a <see cref="PumpsClient"/> factory. The Pumps client
|
|
/// composes the Device Integration client - pump discovery starts at
|
|
/// the DeviceSet - so the DI client services are registered as well.
|
|
/// </summary>
|
|
/// <param name="builder">The client builder returned by <c>AddClient</c>.</param>
|
|
public static IOpcUaClientBuilder AddPumpsClient(
|
|
this IOpcUaClientBuilder builder)
|
|
{
|
|
builder.ThrowIfNull(nameof(builder));
|
|
|
|
builder.AddOpcUaDi();
|
|
builder.Services.TryAddSingleton(sp =>
|
|
{
|
|
Func<CancellationToken, Task<ManagedSession>> sessionFactory =
|
|
sp.GetService<Func<CancellationToken, Task<ManagedSession>>>() ??
|
|
throw new InvalidOperationException(
|
|
"AddPumpsClient requires AddClient to be called first.");
|
|
ITelemetryContext telemetry = sp.GetRequiredService<ITelemetryContext>();
|
|
return new PumpsClientFactory(sessionFactory, telemetry);
|
|
});
|
|
|
|
builder.Services.TryAddSingleton<
|
|
Func<CancellationToken, Task<PumpsClient>>>(sp =>
|
|
{
|
|
PumpsClientFactory factory = sp.GetRequiredService<PumpsClientFactory>();
|
|
return factory.CreateAsync;
|
|
});
|
|
|
|
return builder;
|
|
}
|
|
}
|
|
}
|