磁导航1.0内部交管和信号交互
This commit is contained in:
@@ -1,41 +1,47 @@
|
||||
using System.ComponentModel;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace StandardScene.Signal.Model
|
||||
{
|
||||
/// <summary>
|
||||
/// 握手点配置。对应老地图点上的 <c>SignalStop</c>(SignalType + SignalParams)。
|
||||
/// 握手点。JGControl / PointControl 填机构、工位、动作;定时充电 / 限流走附加参数。
|
||||
/// 旧 JSON 仅有 SignalParams 时仍可解析。
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 站点 fields 若已填写同名键,扫车优先用站点字段,本表该站点不再生效。
|
||||
/// SignalParams 按分号切分,各类型格式见 <see cref="StandardScene.Signal.Logic.SignalStopSpec"/>。
|
||||
/// 列表主键展示为「站点号 + 类型」,同一站点建议只配一条。
|
||||
/// </remarks>
|
||||
[SignalTable("handshake", "handshake-points.json", "握手点", Order = 3)]
|
||||
[Category("握手点数据管理")]
|
||||
[DisplayName("握手点配置列表")]
|
||||
public class HandshakePointModel
|
||||
{
|
||||
/// <summary>地图站点号,与车 PositionId(siteID / GetLastSite)对应。</summary>
|
||||
[DisplayName("站点")]
|
||||
public int Sit { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 握手类型:<c>JGControl</c> 机构进出、
|
||||
/// <c>PointControl</c> 销钉升降、
|
||||
/// <c>TimedCharging</c> 定时充电、
|
||||
/// <c>RateFlowControl</c> 区域限流。
|
||||
/// 其它字符串会每 10s 打一次「未找到业务模块」日志。
|
||||
/// </summary>
|
||||
/// <summary>JGControl / PointControl / TimedCharging / RateFlowControl。</summary>
|
||||
[DisplayName("信号类型")]
|
||||
[SignalSelect("JGControl", "PointControl", "TimedCharging", "RateFlowControl")]
|
||||
public string SignalType { get; set; } = "JGControl";
|
||||
|
||||
[DisplayName("机构名称")]
|
||||
public string JgName { get; set; } = "";
|
||||
|
||||
[DisplayName("工位编号")]
|
||||
public string DockId { get; set; } = "";
|
||||
|
||||
/// <summary>JGControl:RequestIn / Arrived;PointControl:UP1 / UP2 / Down1 / Down2。</summary>
|
||||
[DisplayName("动作")]
|
||||
[SignalSelect("RequestIn", "Arrived", "UP1", "UP2", "Down1", "Down2")]
|
||||
public string Action { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// 类型参数。示例:
|
||||
/// JGControl <c>上线机构1;RequestIn</c> / <c>上线机构1;Arrived</c> / 第三段限流 <c>缓存区-A-2-60,61</c>;
|
||||
/// PointControl <c>UP1;下线机构1</c>;
|
||||
/// TimedCharging <c>300;95;20</c>;
|
||||
/// RateFlowControl <c>缓存区;A;2;60,61,62</c>。
|
||||
/// TimedCharging:最长秒;上限电量;下限电量。
|
||||
/// RateFlowControl:区域;车组;限额;点列表。
|
||||
/// JGControl 可选限流:区域-车组-限额-点列表。
|
||||
/// </summary>
|
||||
[DisplayName("信号参数")]
|
||||
public string SignalParams { get; set; } = "";
|
||||
[DisplayName("附加参数")]
|
||||
public string ExtraParams { get; set; } = "";
|
||||
|
||||
/// <summary>旧字段。新配置可空,加载时由上面几列拼回。</summary>
|
||||
[Browsable(false)]
|
||||
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
|
||||
public string SignalParams { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace StandardScene.Signal.Model
|
||||
{
|
||||
/// <summary>
|
||||
/// 磁条管控区一行。仅 MagCar:车在触发点停稳等待,进程按区名排队后发启动。
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 主键为 <see cref="TriggerSit"/>。同 <see cref="AreaName"/> 的多行绑成一个路口排队。
|
||||
/// 区名为空时,该触发点自成一区(兼容旧表)。
|
||||
/// 放行时查本行 <see cref="ControlArea"/> 与同区冲突对向线站点的并集当前占用;不用 pending。
|
||||
/// <see cref="ControlReleaseStartStop"/> 保留兼容,MagCar 放行走 FASS 1.0 启动指令,不使用该字节。
|
||||
/// </remarks>
|
||||
[SignalTable("mag-control", "mag-control-areas.json", "磁条管控区", Order = 5)]
|
||||
[Category("磁条交管")]
|
||||
[DisplayName("管控区配置列表")]
|
||||
public class MagControlAreaModel
|
||||
{
|
||||
/// <summary>管控触发站点。MagCar 到此停稳后进入该区排队。</summary>
|
||||
[DisplayName("管控触发站点")]
|
||||
public int TriggerSit { get; set; }
|
||||
|
||||
/// <summary>管控区名称。同名多行绑成一个路口;空则本触发点单独成区。</summary>
|
||||
[DisplayName("管控区名称")]
|
||||
public string AreaName { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// 兼容组。同区里互不干扰的线路填不同组名;会打架的填同组。
|
||||
/// 空则与同区其他空组互斥。站点列表有交集时即使组名不同也互斥。
|
||||
/// </summary>
|
||||
[DisplayName("兼容组")]
|
||||
public string CompatGroup { get; set; } = "";
|
||||
|
||||
/// <summary>优先级,数值越大越先放。干道高、支路低。只在冲突线路之间生效。</summary>
|
||||
[DisplayName("优先级")]
|
||||
public int Priority { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 等待时长(秒)。同区取最长;≤0 不做插队。只在冲突线路之间生效。
|
||||
/// </summary>
|
||||
[DisplayName("等待时长")]
|
||||
public int WaitSeconds { get; set; }
|
||||
|
||||
/// <summary>本线路路口内部站点,如 <c>10,11</c>。不要把排队触发点写进来。空则回退触发点。</summary>
|
||||
[DisplayName("管控区站点列表")]
|
||||
public string ControlArea { get; set; } = "";
|
||||
|
||||
/// <summary>本线路区内最多几辆。含占用本行站点的车和与本行冲突的在途车。默认 1。</summary>
|
||||
[DisplayName("区内最多几辆")]
|
||||
public int ControlCapacity { get; set; } = 1;
|
||||
|
||||
/// <summary>兼容字段,MagCar 放行不使用。</summary>
|
||||
[DisplayName("放行后启停字节")]
|
||||
public byte ControlReleaseStartStop { get; set; } = 11;
|
||||
|
||||
/// <summary>false 时该条保留在 JSON 里但不生效。</summary>
|
||||
[DisplayName("启用")]
|
||||
public bool IsUse { get; set; } = true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
using System.ComponentModel;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace StandardScene.Signal.Model
|
||||
{
|
||||
/// <summary>
|
||||
/// 机构工位:一块 DB 上的一组 BOOL 点 + 地标。同一机构可多行(dock1 / dock2 / …)。
|
||||
/// </summary>
|
||||
[SignalTable("docks", "station-docks.json", "机构工位", Order = 2)]
|
||||
[Category("PLC数据管理")]
|
||||
[DisplayName("机构工位列表(机构名称+工位编号不能重复)")]
|
||||
public class PlcStationDockModel
|
||||
{
|
||||
/// <summary>外键,对应 <see cref="PlcStationModel.JgName"/>。</summary>
|
||||
[Category("基本")]
|
||||
[DisplayName("机构名称")]
|
||||
public string JgName { get; set; } = "";
|
||||
|
||||
/// <summary>机构内唯一。空则按 default。</summary>
|
||||
[Category("基本")]
|
||||
[DisplayName("工位编号")]
|
||||
public string DockId { get; set; } = "dock1";
|
||||
|
||||
[Category("PLC 读 BOOL")]
|
||||
[DisplayName("允许进入字节")]
|
||||
public int AllowInByte { get; set; }
|
||||
|
||||
[Category("PLC 读 BOOL")]
|
||||
[DisplayName("允许进入位")]
|
||||
public int AllowInBit { get; set; }
|
||||
|
||||
[Category("PLC 读 BOOL")]
|
||||
[DisplayName("允许离开字节")]
|
||||
public int AllowOutByte { get; set; }
|
||||
|
||||
[Category("PLC 读 BOOL")]
|
||||
[DisplayName("允许离开位")]
|
||||
public int AllowOutBit { get; set; } = 1;
|
||||
|
||||
[Category("PLC 写 BOOL")]
|
||||
[DisplayName("进入中字节")]
|
||||
public int EnteringByte { get; set; } = 2;
|
||||
|
||||
[Category("PLC 写 BOOL")]
|
||||
[DisplayName("进入中位")]
|
||||
public int EnteringBit { get; set; }
|
||||
|
||||
[Category("PLC 写 BOOL")]
|
||||
[DisplayName("到位字节")]
|
||||
public int ArrivedByte { get; set; } = 2;
|
||||
|
||||
[Category("PLC 写 BOOL")]
|
||||
[DisplayName("到位位")]
|
||||
public int ArrivedBit { get; set; } = 1;
|
||||
|
||||
[Category("PLC 写 BOOL")]
|
||||
[DisplayName("离开中字节")]
|
||||
public int LeavingByte { get; set; } = 2;
|
||||
|
||||
[Category("PLC 写 BOOL")]
|
||||
[DisplayName("离开中位")]
|
||||
public int LeavingBit { get; set; } = 2;
|
||||
|
||||
[Category("PLC 写 BOOL")]
|
||||
[DisplayName("已离开字节")]
|
||||
public int LeftByte { get; set; } = 2;
|
||||
|
||||
[Category("PLC 写 BOOL")]
|
||||
[DisplayName("已离开位")]
|
||||
public int LeftBit { get; set; } = 3;
|
||||
|
||||
[Category("地标")]
|
||||
[DisplayName("进入地标")]
|
||||
public int JgInPointId { get; set; }
|
||||
|
||||
[Category("地标")]
|
||||
[DisplayName("进入包含地标")]
|
||||
public string JgInContains { get; set; } = "";
|
||||
|
||||
[Category("地标")]
|
||||
[DisplayName("机构地标")]
|
||||
public int JgPointId { get; set; }
|
||||
|
||||
[Category("地标")]
|
||||
[DisplayName("机构包含地标")]
|
||||
public string JgContains { get; set; } = "";
|
||||
|
||||
/// <summary>旧配置合成:按一字节枚举读写,不走 BOOL。</summary>
|
||||
[Browsable(false)]
|
||||
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
|
||||
public bool UseByteIo { get; set; }
|
||||
|
||||
/// <summary>仅 UseByteIo 时使用的读字节地址。</summary>
|
||||
[Browsable(false)]
|
||||
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
|
||||
public string ReadDb { get; set; }
|
||||
|
||||
/// <summary>仅 UseByteIo 时使用的写字节地址。</summary>
|
||||
[Browsable(false)]
|
||||
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
|
||||
public string WriteDb { get; set; }
|
||||
|
||||
public string ResolvedDockId =>
|
||||
string.IsNullOrWhiteSpace(DockId) ? "default" : DockId.Trim();
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,17 @@
|
||||
using System.ComponentModel;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace StandardScene.Signal.Model
|
||||
{
|
||||
/// <summary>
|
||||
/// PLC 机构静态配置,对应反编译 <c>PLCModel</c> 可存档字段。
|
||||
/// 读写运行态(当前字节、机构内车号)在 <see cref="StandardScene.Signal.Plc.PlcStationRuntime"/>,不进本类、不进 JSON。
|
||||
/// 机构名称不能重复,列表编辑器用 JgName 做主键。
|
||||
/// PLC 机构:一把 S7 连接 + 一块 DB。点位和地标在 <see cref="PlcStationDockModel"/>。
|
||||
/// </summary>
|
||||
[SignalTable("stations", "stations.json", "PLC机构", Order = 1)]
|
||||
[Category("PLC数据管理")]
|
||||
[DisplayName("PLC配置列表(机构名称不能重复)")]
|
||||
public class PlcStationModel
|
||||
{
|
||||
/// <summary>逻辑名,握手点 SignalParams 第一段、Worker 线程名都用它。不能空、不能重复。</summary>
|
||||
/// <summary>逻辑名,握手点机构名、Worker 线程名都用它。不能空、不能重复。</summary>
|
||||
[DisplayName("机构名称")]
|
||||
public string JgName { get; set; } = "";
|
||||
|
||||
@@ -23,53 +23,55 @@ namespace StandardScene.Signal.Model
|
||||
[DisplayName("端口")]
|
||||
public int Port { get; set; } = 102;
|
||||
|
||||
/// <summary>
|
||||
/// 读字节地址(PLC→调度:允许进入/离开)。
|
||||
/// 支持 <c>DB1.DBB0</c> 或 Hsl 风格 <c>DB1.0</c>。空则跳过读取。
|
||||
/// </summary>
|
||||
[DisplayName("读地址")]
|
||||
public string ReadDb { get; set; } = "";
|
||||
/// <summary>西门子系列。跟随进程则用信号交互进程的 PlcVersion。</summary>
|
||||
[DisplayName("PLC类型")]
|
||||
public SignalPlcType PlcType { get; set; } = SignalPlcType.跟随进程;
|
||||
|
||||
/// <summary>
|
||||
/// 写字节地址(调度→PLC:进入中/到位/离开中/已离开)。
|
||||
/// Worker 会先回读再按需写入。空则跳过写和回读。
|
||||
/// </summary>
|
||||
[DisplayName("写地址")]
|
||||
public string WriteDb { get; set; } = "";
|
||||
/// <summary>DB 块号。工位 BOOL 与心跳都拼到这块 DB。</summary>
|
||||
[DisplayName("DB块号")]
|
||||
public int DbNumber { get; set; } = 100;
|
||||
|
||||
/// <summary>
|
||||
/// 心跳位地址,如 <c>DB1.DBX2.0</c>。
|
||||
/// Worker 每拍读当前值再写反码,让 PLC 判断调度进程存活。空则不做心跳。
|
||||
/// </summary>
|
||||
[DisplayName("写心跳地址")]
|
||||
public string HeartDb { get; set; } = "";
|
||||
/// <summary>心跳字节偏移。未填 HeartDb 时拼 DB{n}.DBX{HeartByte}.{HeartBit}。</summary>
|
||||
[DisplayName("心跳字节")]
|
||||
public int HeartByte { get; set; } = 32;
|
||||
|
||||
/// <summary>机构进入地标(预留,与老 PLCModel 字段对齐;上线跟车主要用 JgInContains)。</summary>
|
||||
[DisplayName("机构进入地标")]
|
||||
public int JgInPointId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 进入过程包含的站点列表(逗号/分号/空格分隔)。
|
||||
/// 上线:写字节=进入中 且车已不在此列表 → 视为到位。
|
||||
/// </summary>
|
||||
[DisplayName("机构进入包含地标")]
|
||||
public string JgInContains { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// 机构工作地标。下线 RequestIn 用它查「机构内是否已有车」;
|
||||
/// 下线/等待通行离站时,车必须停在此点才响应允许离开。
|
||||
/// </summary>
|
||||
[DisplayName("机构地标")]
|
||||
public int JgPointId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 机构占用包含的站点列表。车已不在此列表且写字节还不是已离开 → 写已离开。
|
||||
/// </summary>
|
||||
[DisplayName("机构包含地标")]
|
||||
public string JgContains { get; set; } = "";
|
||||
/// <summary>心跳位,0~7。</summary>
|
||||
[DisplayName("心跳位")]
|
||||
public int HeartBit { get; set; }
|
||||
|
||||
/// <summary>上线 / 单牵引下线 / 双牵引下线 / 等待通行,决定 AutoLeave 分支。</summary>
|
||||
[DisplayName("上下机构")]
|
||||
public SignalLineType LineType { get; set; } = SignalLineType.未知;
|
||||
|
||||
/// <summary>旧配置读字节地址。有工位表后不再使用;无工位表时合成 default 工位。</summary>
|
||||
[Browsable(false)]
|
||||
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
|
||||
public string ReadDb { get; set; }
|
||||
|
||||
/// <summary>旧配置写字节地址。</summary>
|
||||
[Browsable(false)]
|
||||
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
|
||||
public string WriteDb { get; set; }
|
||||
|
||||
/// <summary>旧配置心跳位整段地址,优先于心跳字节/位。</summary>
|
||||
[Browsable(false)]
|
||||
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
|
||||
public string HeartDb { get; set; }
|
||||
|
||||
[Browsable(false)]
|
||||
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
|
||||
public int JgInPointId { get; set; }
|
||||
|
||||
[Browsable(false)]
|
||||
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
|
||||
public string JgInContains { get; set; }
|
||||
|
||||
[Browsable(false)]
|
||||
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
|
||||
public int JgPointId { get; set; }
|
||||
|
||||
[Browsable(false)]
|
||||
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
|
||||
public string JgContains { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ namespace StandardScene.Signal.Model
|
||||
/// 同一站点不要同时配握手点:扫车先握手再放行,可能把还在等允许进入的车开走。
|
||||
/// 站点号不能重复,列表编辑器用 Sit 做主键。
|
||||
/// </remarks>
|
||||
[SignalTable("release", "release-points.json", "放行点", Order = 4)]
|
||||
[Category("放行点数据管理")]
|
||||
[DisplayName("放行点配置列表")]
|
||||
public class ReleasePointModel
|
||||
|
||||
@@ -38,6 +38,34 @@ namespace StandardScene.Signal.Model
|
||||
已离开 = 4
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 西门子系列,名称与 IoTClient <c>SiemensVersion</c> 对齐(不含 <c>None</c>)。
|
||||
/// 机构表选「跟随进程」时用信号交互进程的 <c>PlcVersion</c>。
|
||||
/// </summary>
|
||||
public enum SignalPlcType : byte
|
||||
{
|
||||
/// <summary>0:未单独指定,建连时用进程字段 PlcVersion。</summary>
|
||||
跟随进程 = 0,
|
||||
|
||||
/// <summary>S7-1500,现场最常见。</summary>
|
||||
S7_1500 = 1,
|
||||
|
||||
/// <summary>S7-1200。</summary>
|
||||
S7_1200 = 2,
|
||||
|
||||
/// <summary>S7-300。</summary>
|
||||
S7_300 = 3,
|
||||
|
||||
/// <summary>S7-400。</summary>
|
||||
S7_400 = 4,
|
||||
|
||||
/// <summary>S7-200 Smart。</summary>
|
||||
S7_200Smart = 5,
|
||||
|
||||
/// <summary>S7-200。</summary>
|
||||
S7_200 = 6
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 机构类型。对齐反编译 <c>ENUM_JGTYPE</c>。
|
||||
/// 决定 <see cref="StandardScene.Signal.Plc.PlcStationLogic.AutoLeave"/> 走哪套离站,以及 RequestIn 要不要查机构内是否有车。
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
|
||||
namespace StandardScene.Signal.Model
|
||||
{
|
||||
/// <summary>
|
||||
/// 迷毂数据中心把该字符串字段渲染成下拉。反射列定义时读取。
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Property)]
|
||||
public sealed class SignalSelectAttribute : Attribute
|
||||
{
|
||||
public SignalSelectAttribute(params string[] options)
|
||||
{
|
||||
Options = options ?? Array.Empty<string>();
|
||||
}
|
||||
|
||||
public string[] Options { get; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
using System;
|
||||
|
||||
namespace StandardScene.Signal.Model
|
||||
{
|
||||
/// <summary>
|
||||
/// 标记一张迷毂数据中心表。迷毂从插件 DLL 反射本特性,不再依赖 signal-tables.json 的列定义。
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Class, Inherited = false)]
|
||||
public sealed class SignalTableAttribute : Attribute
|
||||
{
|
||||
public SignalTableAttribute(string id, string fileName, string title)
|
||||
{
|
||||
Id = id ?? "";
|
||||
FileName = fileName ?? "";
|
||||
Title = title ?? "";
|
||||
}
|
||||
|
||||
public string Id { get; }
|
||||
|
||||
public string FileName { get; }
|
||||
|
||||
public string Title { get; }
|
||||
|
||||
/// <summary>侧栏顺序,越小越靠前。</summary>
|
||||
public int Order { get; set; }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user