feat(uns): S7/AbCip/AbLegacy/TwinCAT/Focas typed tag-config editors (F-uns-1 T4-T8)

This commit is contained in:
Joseph Doherty
2026-06-09 09:42:40 -04:00
parent 5990b673cc
commit 75021fa2c9
15 changed files with 860 additions and 0 deletions
@@ -0,0 +1,42 @@
@using ZB.MOM.WW.OtOpcUa.AdminUI.Uns.TagEditors
@using ZB.MOM.WW.OtOpcUa.Driver.AbCip
<div class="row g-2">
<div class="col-md-4"><label class="form-label">Device host</label>
<input class="form-control form-control-sm mono" value="@_m.DeviceHostAddress" placeholder="ab://gateway[:port]/cip-path" @onchange="@(e => Update(() => _m.DeviceHostAddress = e.Value?.ToString() ?? string.Empty))" /></div>
<div class="col-md-5"><label class="form-label">Tag path</label>
<input class="form-control form-control-sm mono" value="@_m.TagPath" placeholder="e.g. Motor1.Speed" @onchange="@(e => Update(() => _m.TagPath = e.Value?.ToString() ?? string.Empty))" /></div>
<div class="col-md-3"><label class="form-label">Data type</label>
<select class="form-select form-select-sm" value="@_m.DataType" @onchange="@(e => Update(() => _m.DataType = ParseEnum(e.Value, AbCipDataType.DInt)))">
@foreach (var v in Enum.GetValues<AbCipDataType>()) { <option value="@v">@v</option> }
</select></div>
</div>
@code {
[Parameter] public string? ConfigJson { get; set; }
[Parameter] public EventCallback<string> ConfigJsonChanged { get; set; }
private AbCipTagConfigModel _m = new();
private string? _lastConfigJson;
// Re-parse only when the incoming JSON actually changes, so an unrelated parent re-render
// (Blazor Server live-status pushes do this) can't reset the user's in-progress edits.
protected override void OnParametersSet()
{
if (ConfigJson == _lastConfigJson) { return; }
_lastConfigJson = ConfigJson;
_m = AbCipTagConfigModel.FromJson(ConfigJson);
}
private static int ParseInt(object? v, int fallback = 0) => int.TryParse(v?.ToString(), out var i) ? i : fallback;
// TryParse so a bad/empty change value can never throw into the Blazor circuit — it falls back.
private static TEnum ParseEnum<TEnum>(object? v, TEnum fallback) where TEnum : struct, Enum
=> Enum.TryParse<TEnum>(v?.ToString(), out var r) ? r : fallback;
private async Task Update(Action apply)
{
apply();
await ConfigJsonChanged.InvokeAsync(_m.ToJson());
}
}
@@ -0,0 +1,42 @@
@using ZB.MOM.WW.OtOpcUa.AdminUI.Uns.TagEditors
@using ZB.MOM.WW.OtOpcUa.Driver.AbLegacy
<div class="row g-2">
<div class="col-md-4"><label class="form-label">Device host</label>
<input class="form-control form-control-sm mono" value="@_m.DeviceHostAddress" placeholder="ab://host" @onchange="@(e => Update(() => _m.DeviceHostAddress = e.Value?.ToString() ?? string.Empty))" /></div>
<div class="col-md-5"><label class="form-label">Address</label>
<input class="form-control form-control-sm mono" value="@_m.Address" placeholder="e.g. N7:0, B3:0/0" @onchange="@(e => Update(() => _m.Address = e.Value?.ToString() ?? string.Empty))" /></div>
<div class="col-md-3"><label class="form-label">Data type</label>
<select class="form-select form-select-sm" value="@_m.DataType" @onchange="@(e => Update(() => _m.DataType = ParseEnum(e.Value, AbLegacyDataType.Int)))">
@foreach (var v in Enum.GetValues<AbLegacyDataType>()) { <option value="@v">@v</option> }
</select></div>
</div>
@code {
[Parameter] public string? ConfigJson { get; set; }
[Parameter] public EventCallback<string> ConfigJsonChanged { get; set; }
private AbLegacyTagConfigModel _m = new();
private string? _lastConfigJson;
// Re-parse only when the incoming JSON actually changes, so an unrelated parent re-render
// (Blazor Server live-status pushes do this) can't reset the user's in-progress edits.
protected override void OnParametersSet()
{
if (ConfigJson == _lastConfigJson) { return; }
_lastConfigJson = ConfigJson;
_m = AbLegacyTagConfigModel.FromJson(ConfigJson);
}
private static int ParseInt(object? v, int fallback = 0) => int.TryParse(v?.ToString(), out var i) ? i : fallback;
// TryParse so a bad/empty change value can never throw into the Blazor circuit — it falls back.
private static TEnum ParseEnum<TEnum>(object? v, TEnum fallback) where TEnum : struct, Enum
=> Enum.TryParse<TEnum>(v?.ToString(), out var r) ? r : fallback;
private async Task Update(Action apply)
{
apply();
await ConfigJsonChanged.InvokeAsync(_m.ToJson());
}
}
@@ -0,0 +1,42 @@
@using ZB.MOM.WW.OtOpcUa.AdminUI.Uns.TagEditors
@using ZB.MOM.WW.OtOpcUa.Driver.FOCAS
<div class="row g-2">
<div class="col-md-4"><label class="form-label">Device host</label>
<input class="form-control form-control-sm mono" value="@_m.DeviceHostAddress" placeholder="host[:port]" @onchange="@(e => Update(() => _m.DeviceHostAddress = e.Value?.ToString() ?? string.Empty))" /></div>
<div class="col-md-5"><label class="form-label">Address</label>
<input class="form-control form-control-sm mono" value="@_m.Address" placeholder="e.g. X0.0, R100, PARAM:1815/0, MACRO:500" @onchange="@(e => Update(() => _m.Address = e.Value?.ToString() ?? string.Empty))" /></div>
<div class="col-md-3"><label class="form-label">Data type</label>
<select class="form-select form-select-sm" value="@_m.DataType" @onchange="@(e => Update(() => _m.DataType = ParseEnum(e.Value, FocasDataType.Int32)))">
@foreach (var v in Enum.GetValues<FocasDataType>()) { <option value="@v">@v</option> }
</select></div>
</div>
@code {
[Parameter] public string? ConfigJson { get; set; }
[Parameter] public EventCallback<string> ConfigJsonChanged { get; set; }
private FocasTagConfigModel _m = new();
private string? _lastConfigJson;
// Re-parse only when the incoming JSON actually changes, so an unrelated parent re-render
// (Blazor Server live-status pushes do this) can't reset the user's in-progress edits.
protected override void OnParametersSet()
{
if (ConfigJson == _lastConfigJson) { return; }
_lastConfigJson = ConfigJson;
_m = FocasTagConfigModel.FromJson(ConfigJson);
}
private static int ParseInt(object? v, int fallback = 0) => int.TryParse(v?.ToString(), out var i) ? i : fallback;
// TryParse so a bad/empty change value can never throw into the Blazor circuit — it falls back.
private static TEnum ParseEnum<TEnum>(object? v, TEnum fallback) where TEnum : struct, Enum
=> Enum.TryParse<TEnum>(v?.ToString(), out var r) ? r : fallback;
private async Task Update(Action apply)
{
apply();
await ConfigJsonChanged.InvokeAsync(_m.ToJson());
}
}
@@ -0,0 +1,42 @@
@using ZB.MOM.WW.OtOpcUa.AdminUI.Uns.TagEditors
@using ZB.MOM.WW.OtOpcUa.Driver.S7
<div class="row g-2">
<div class="col-md-5"><label class="form-label">Address</label>
<input class="form-control form-control-sm mono" value="@_m.Address" placeholder="e.g. DB1.DBW0, M0.0, I0.0, QD4" @onchange="@(e => Update(() => _m.Address = e.Value?.ToString() ?? string.Empty))" /></div>
<div class="col-md-4"><label class="form-label">Data type</label>
<select class="form-select form-select-sm" value="@_m.DataType" @onchange="@(e => Update(() => _m.DataType = ParseEnum(e.Value, S7DataType.Int16)))">
@foreach (var v in Enum.GetValues<S7DataType>()) { <option value="@v">@v</option> }
</select></div>
<div class="col-md-3"><label class="form-label">String len</label>
<input type="number" class="form-control form-control-sm" value="@_m.StringLength" @onchange="@(e => Update(() => _m.StringLength = ParseInt(e.Value)))" /></div>
</div>
@code {
[Parameter] public string? ConfigJson { get; set; }
[Parameter] public EventCallback<string> ConfigJsonChanged { get; set; }
private S7TagConfigModel _m = new();
private string? _lastConfigJson;
// Re-parse only when the incoming JSON actually changes, so an unrelated parent re-render
// (Blazor Server live-status pushes do this) can't reset the user's in-progress edits.
protected override void OnParametersSet()
{
if (ConfigJson == _lastConfigJson) { return; }
_lastConfigJson = ConfigJson;
_m = S7TagConfigModel.FromJson(ConfigJson);
}
private static int ParseInt(object? v, int fallback = 0) => int.TryParse(v?.ToString(), out var i) ? i : fallback;
// TryParse so a bad/empty change value can never throw into the Blazor circuit — it falls back.
private static TEnum ParseEnum<TEnum>(object? v, TEnum fallback) where TEnum : struct, Enum
=> Enum.TryParse<TEnum>(v?.ToString(), out var r) ? r : fallback;
private async Task Update(Action apply)
{
apply();
await ConfigJsonChanged.InvokeAsync(_m.ToJson());
}
}
@@ -0,0 +1,42 @@
@using ZB.MOM.WW.OtOpcUa.AdminUI.Uns.TagEditors
@using ZB.MOM.WW.OtOpcUa.Driver.TwinCAT
<div class="row g-2">
<div class="col-md-4"><label class="form-label">Device host</label>
<input class="form-control form-control-sm mono" value="@_m.DeviceHostAddress" placeholder="AmsNetId[:port]" @onchange="@(e => Update(() => _m.DeviceHostAddress = e.Value?.ToString() ?? string.Empty))" /></div>
<div class="col-md-5"><label class="form-label">Symbol path</label>
<input class="form-control form-control-sm mono" value="@_m.SymbolPath" placeholder="e.g. MAIN.bStart, GVL.Counter" @onchange="@(e => Update(() => _m.SymbolPath = e.Value?.ToString() ?? string.Empty))" /></div>
<div class="col-md-3"><label class="form-label">Data type</label>
<select class="form-select form-select-sm" value="@_m.DataType" @onchange="@(e => Update(() => _m.DataType = ParseEnum(e.Value, TwinCATDataType.DInt)))">
@foreach (var v in Enum.GetValues<TwinCATDataType>()) { <option value="@v">@v</option> }
</select></div>
</div>
@code {
[Parameter] public string? ConfigJson { get; set; }
[Parameter] public EventCallback<string> ConfigJsonChanged { get; set; }
private TwinCATTagConfigModel _m = new();
private string? _lastConfigJson;
// Re-parse only when the incoming JSON actually changes, so an unrelated parent re-render
// (Blazor Server live-status pushes do this) can't reset the user's in-progress edits.
protected override void OnParametersSet()
{
if (ConfigJson == _lastConfigJson) { return; }
_lastConfigJson = ConfigJson;
_m = TwinCATTagConfigModel.FromJson(ConfigJson);
}
private static int ParseInt(object? v, int fallback = 0) => int.TryParse(v?.ToString(), out var i) ? i : fallback;
// TryParse so a bad/empty change value can never throw into the Blazor circuit — it falls back.
private static TEnum ParseEnum<TEnum>(object? v, TEnum fallback) where TEnum : struct, Enum
=> Enum.TryParse<TEnum>(v?.ToString(), out var r) ? r : fallback;
private async Task Update(Action apply)
{
apply();
await ConfigJsonChanged.InvokeAsync(_m.ToJson());
}
}