Merge b626-mtconnect (batch #626+)
Claude-Session: https://claude.ai/code/session_01Ef2ozxS7QPanGT8uoATbTe
This commit is contained in:
@@ -5,6 +5,7 @@ using ZB.MOM.WW.OtOpcUa.AdminUI.Uns.TagEditors;
|
||||
using ZB.MOM.WW.OtOpcUa.Commons.Types;
|
||||
using ZB.MOM.WW.OtOpcUa.Configuration;
|
||||
using ZB.MOM.WW.OtOpcUa.Configuration.Entities;
|
||||
using ZB.MOM.WW.OtOpcUa.Configuration.Validation;
|
||||
using ZB.MOM.WW.OtOpcUa.Core.Abstractions;
|
||||
|
||||
namespace ZB.MOM.WW.OtOpcUa.AdminUI.Uns;
|
||||
@@ -615,9 +616,16 @@ public sealed class RawTreeService(IDbContextFactory<OtOpcUaConfigDbContext> dbF
|
||||
|
||||
await using var db = await dbFactory.CreateDbContextAsync(ct);
|
||||
|
||||
if (!await db.DriverInstances.AnyAsync(d => d.DriverInstanceId == driverInstanceId, ct))
|
||||
var owner = await db.DriverInstances.FirstOrDefaultAsync(d => d.DriverInstanceId == driverInstanceId, ct);
|
||||
if (owner is null)
|
||||
return new UnsMutationResult(false, $"Driver '{driverInstanceId}' not found.");
|
||||
|
||||
// #628: MTConnect owns one agent client per driver — mirror the deploy gate
|
||||
// (DraftValidator.ValidateMTConnectSingleDevice) so the second Device is refused where it is authored.
|
||||
if (string.Equals(owner.DriverType, DriverTypeNames.MTConnect, StringComparison.Ordinal)
|
||||
&& await db.Devices.AnyAsync(dev => dev.DriverInstanceId == driverInstanceId, ct))
|
||||
return new UnsMutationResult(false, DraftValidator.MTConnectMultipleDevicesMessage(owner.Name));
|
||||
|
||||
if (await db.Devices.AnyAsync(dev => dev.DriverInstanceId == driverInstanceId && dev.Name == name, ct))
|
||||
return new UnsMutationResult(false, $"A device named '{name}' already exists on this driver.");
|
||||
|
||||
|
||||
@@ -229,10 +229,25 @@ public sealed class MTConnectTagConfigModel
|
||||
/// passed as null; it can only DEMOTE an item to String (DATA_SET/TABLE), which cannot create a false
|
||||
/// warning because a numeric declaration on a String-inferred item is warned either way, and a SAMPLE
|
||||
/// inferred Float64 is only warned about for a non-numeric, non-String declaration or an integer one.
|
||||
/// TIME_SERIES arrays are not detectable without it and are not covered.
|
||||
/// TIME_SERIES arrays are covered separately by the isArray rule in <see cref="Warnings"/>.
|
||||
/// </remarks>
|
||||
/// <returns>Zero or more human-readable warnings.</returns>
|
||||
public IReadOnlyList<string> Warnings()
|
||||
{
|
||||
// #627: an array (TIME_SERIES) tag is served as double[] only. Independent of the probe metadata —
|
||||
// the array flag is authored on the tag, and any other declared element type reads BadNotSupported.
|
||||
var arrayWarning = _bag.TryGetPropertyValue("isArray", out var arr)
|
||||
&& arr is JsonValue av && av.TryGetValue<bool>(out var isArray) && isArray
|
||||
&& DataType != DriverDataType.Float64
|
||||
? $"Data type {DataType} on an array tag: MTConnect TIME_SERIES arrays are served as Float64 (double[]) only; "
|
||||
+ "declare Float64 or the tag reads BadNotSupported. Saving is still allowed."
|
||||
: null;
|
||||
|
||||
var scalar = ScalarWarnings();
|
||||
return arrayWarning is null ? scalar : [arrayWarning, .. scalar];
|
||||
}
|
||||
|
||||
private IReadOnlyList<string> ScalarWarnings()
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(MtCategory)) { return []; }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user