using System; using System.Collections.Generic; using System.Linq; using StandardScene.Signal.Model; namespace StandardScene.Signal.Plc { /// /// 加载机构 + 工位。没有工位表时,用旧机构行的 ReadDb/WriteDb/地标合成 default 工位(一字节枚举)。 /// internal static class PlcConfigLoader { public const string DefaultDockId = "default"; public sealed class StationBundle { public PlcStationModel Station { get; init; } public List Docks { get; init; } } public static List Load(string stationsPath, string docksPath) { var stations = SignalConfigStore.Load(stationsPath) .Where(s => s != null && !string.IsNullOrWhiteSpace(s.JgName)) .ToList(); var docks = SignalConfigStore.Load(docksPath) .Where(d => d != null && !string.IsNullOrWhiteSpace(d.JgName)) .ToList(); var byName = docks .GroupBy(d => d.JgName.Trim(), StringComparer.OrdinalIgnoreCase) .ToDictionary(g => g.Key, g => g.ToList(), StringComparer.OrdinalIgnoreCase); var list = new List(); foreach (var station in stations) { if (!byName.TryGetValue(station.JgName.Trim(), out var rows) || rows.Count == 0) rows = HasLegacyIo(station) ? new List { Synthesize(station) } : new List(); list.Add(new StationBundle { Station = station, Docks = rows }); } return list; } public static int ResolveDb(PlcStationModel station) { if (station == null) return 100; if (station.DbNumber > 0) return station.DbNumber; if (PlcAddress.TryParse(station.HeartDb, out var db, out _, out _)) return db; if (PlcAddress.TryParse(station.ReadDb, out db, out _, out _)) return db; if (PlcAddress.TryParse(station.WriteDb, out db, out _, out _)) return db; return 100; } public static string ResolveHeartAddress(PlcStationModel station) { if (station == null) return ""; if (!string.IsNullOrWhiteSpace(station.HeartDb)) return station.HeartDb.Trim(); return PlcAddress.Bit(ResolveDb(station), station.HeartByte, station.HeartBit); } private static bool HasLegacyIo(PlcStationModel station) => station != null && (!string.IsNullOrWhiteSpace(station.ReadDb) || !string.IsNullOrWhiteSpace(station.WriteDb) || station.JgPointId > 0 || !string.IsNullOrWhiteSpace(station.JgContains)); private static PlcStationDockModel Synthesize(PlcStationModel station) => new PlcStationDockModel { JgName = station.JgName, DockId = DefaultDockId, UseByteIo = true, ReadDb = station.ReadDb, WriteDb = station.WriteDb, JgInPointId = station.JgInPointId, JgInContains = station.JgInContains, JgPointId = station.JgPointId, JgContains = station.JgContains }; } }