ProjectProfile.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  1. namespace YZWater.Core.Models;
  2. /// <summary>
  3. /// 项目档案 - 定义一个项目的设备清单、PLC 地址映射和报警阈值
  4. /// 从 projects/ 目录下的 JSON 文件加载
  5. /// </summary>
  6. public class ProjectProfile
  7. {
  8. /// <summary>项目名称(如 "扬杰二厂泵站")</summary>
  9. public string Name { get; set; } = "";
  10. /// <summary>项目描述</summary>
  11. public string Description { get; set; } = "";
  12. /// <summary>
  13. /// 视图模板名称(决定使用哪种 View 布局)
  14. /// 如 "PumpStation" = 泵站布局, "Default" = 默认4水箱布局
  15. /// </summary>
  16. public string ViewTemplate { get; set; } = "Default";
  17. /// <summary>泵设备列表</summary>
  18. public List<PumpConfig> Pumps { get; set; } = new();
  19. /// <summary>水箱/水池列表</summary>
  20. public List<TankConfig> Tanks { get; set; } = new();
  21. /// <summary>仪表列表(压力、流量等带刻度的模拟量)</summary>
  22. public List<GaugeConfig> Gauges { get; set; } = new();
  23. /// <summary>通用传感器(日流量、温度等简单模拟量)</summary>
  24. public List<SensorConfig> Sensors { get; set; } = new();
  25. /// <summary>通用数字量输入(变频器故障等)</summary>
  26. public List<DigitalInputConfig> DigitalInputs { get; set; } = new();
  27. /// <summary>通用数字量输出(复位按钮等)</summary>
  28. public List<DigitalOutputConfig> DigitalOutputs { get; set; } = new();
  29. /// <summary>报警阈值配置</summary>
  30. public AlarmThresholds AlarmThresholds { get; set; } = new();
  31. /// <summary>
  32. /// 全局中控/屏控切换地址(所有泵共用,0=中控 1=屏控)
  33. /// 如 M1.0 — 所有泵要么全中控,要么全屏控
  34. /// </summary>
  35. public string? ModeSelectAddress { get; set; }
  36. /// <summary>控制策略配置 — 决定上位机是否参与自动控制</summary>
  37. public ControlConfig Control { get; set; } = new();
  38. /// <summary>页面布局配置 — 决定 ProjectView 的 UI 区域显隐和尺寸</summary>
  39. public PageLayoutConfig Layout { get; set; } = new();
  40. }
  41. /// <summary>
  42. /// 页面布局配置 — 控制 ProjectView 各区域显隐和尺寸
  43. /// 缺失字段使用默认值,旧 JSON 无需改动即可兼容
  44. /// </summary>
  45. public class PageLayoutConfig
  46. {
  47. /// <summary>右侧数据面板宽度(像素),0 = 隐藏整个右列。默认 300</summary>
  48. public int RightColumnWidth { get; set; } = 300;
  49. /// <summary>隐藏的区块名称列表。
  50. /// 可选值:"Tanks"(液位监控), "Gauges"(仪表), "Sensors"(累计), "Faults"(故障状态)
  51. /// 被隐藏的区块即使有数据也不显示</summary>
  52. public List<string> HiddenSections { get; set; } = new();
  53. }
  54. /// <summary>
  55. /// 控制策略配置 — 决定上位机在该项目中的控制角色
  56. /// EnableAutoControl=false 时上位机仅监控,自动逻辑由 PLC 处理
  57. /// </summary>
  58. public class ControlConfig
  59. {
  60. /// <summary>是否启用上位机自动控制(默认 false = PLC 自行处理)</summary>
  61. public bool EnableAutoControl { get; set; } = false;
  62. /// <summary>控制模式描述(UI 显示用,如 "PLC自动" / "远程中控")</summary>
  63. public string ControlModeDescription { get; set; } = "PLC自动";
  64. /// <summary>是否允许上位机手动启停泵</summary>
  65. public bool AllowManualControl { get; set; } = true;
  66. /// <summary>是否允许参数同步写入 PLC</summary>
  67. public bool AllowParameterSync { get; set; } = true;
  68. }
  69. /// <summary>
  70. /// 泵设备配置 - 涵盖泵的读/写/状态点位
  71. /// </summary>
  72. public class PumpConfig
  73. {
  74. /// <summary>泵名称(如 "1#泵")</summary>
  75. public string Name { get; set; } = "";
  76. // ─── 读取地址 ───
  77. /// <summary>运行状态地址 (DO 区,如 Q0.1) - 起停共用地址时与 StartAddress 相同</summary>
  78. public string RunAddress { get; set; } = "";
  79. /// <summary>变频器故障地址 (DI 区,如 I0.1)</summary>
  80. public string FaultAddress { get; set; } = "";
  81. /// <summary>电流地址 (AI 区,如 AIW18 或对应的 VD 地址)</summary>
  82. public string CurrentAddress { get; set; } = "";
  83. /// <summary>
  84. /// 额定电流(A,可选)。配置后泵卡电流条按「当前/额定」显示负荷比例,
  85. /// 超载(≥100%)变红提醒;未配置(0)时电流条退化为组内相对比例。
  86. /// </summary>
  87. public float RatedCurrent { get; set; }
  88. /// <summary>手自动状态地址 (读,如 M2.6, 1=自动 0=手动)</summary>
  89. public string AutoStateAddress { get; set; } = "";
  90. /// <summary>日台时-小时地址 (读,如 VD950)</summary>
  91. public string DailyHoursAddress { get; set; } = "";
  92. /// <summary>日台时-小时数据类型: "REAL" / "INT" / "DINT" (默认 REAL)</summary>
  93. public string DailyHoursDataType { get; set; } = "REAL";
  94. /// <summary>日台时-分钟地址 (读,如 VD10)</summary>
  95. public string DailyMinutesAddress { get; set; } = "";
  96. /// <summary>日台时-分钟数据类型: "REAL" / "INT" / "DINT" (默认 REAL)</summary>
  97. public string DailyMinutesDataType { get; set; } = "REAL";
  98. // ─── 写入地址 ───
  99. /// <summary>手动启动地址 (写,如 M1.3, 点动)</summary>
  100. public string StartAddress { get; set; } = "";
  101. /// <summary>手动停止地址 (写,如 M1.4, 点动)</summary>
  102. public string StopAddress { get; set; } = "";
  103. /// <summary>自动命令地址 (写,如 M2.2, 点动)</summary>
  104. public string AutoCommandAddress { get; set; } = "";
  105. /// <summary>手动命令地址 (写,如 M2.1, 点动)</summary>
  106. public string ManualCommandAddress { get; set; } = "";
  107. /// <summary>日台时清零地址 (写,如 M19.4)</summary>
  108. public string DailyResetAddress { get; set; } = "";
  109. }
  110. /// <summary>
  111. /// 水箱/水池配置
  112. /// </summary>
  113. public class TankConfig
  114. {
  115. /// <summary>名称(如 "集水池")</summary>
  116. public string Name { get; set; } = "";
  117. /// <summary>即时液位地址 (读,如 VD62)</summary>
  118. public string LevelAddress { get; set; } = "";
  119. /// <summary>启动 1 台泵的液位设定值</summary>
  120. public float? StartPump1Level { get; set; }
  121. /// <summary>启动 2 台泵的液位设定值</summary>
  122. public float? StartPump2Level { get; set; }
  123. /// <summary>启动 3 台泵的液位设定值</summary>
  124. public float? StartPump3Level { get; set; }
  125. /// <summary>停泵液位设定值</summary>
  126. public float? StopLevel { get; set; }
  127. /// <summary>保护液位设定值</summary>
  128. public float? ProtectionLevel { get; set; }
  129. /// <summary>池体满量程高度(米),用于 UI 液位归一化显示。未配置时自动取阈值中最大值</summary>
  130. public float? MaxLevel { get; set; }
  131. /// <summary>启动 1 台泵液位地址 (读写,如 VD500)</summary>
  132. public string StartPump1LevelAddress { get; set; } = "";
  133. /// <summary>启动 2 台泵液位地址 (读写,如 VD504)</summary>
  134. public string StartPump2LevelAddress { get; set; } = "";
  135. /// <summary>启动 3 台泵液位地址 (读写,如 VD508)</summary>
  136. public string StartPump3LevelAddress { get; set; } = "";
  137. /// <summary>停泵液位地址 (读写,如 VD528)</summary>
  138. public string StopLevelAddress { get; set; } = "";
  139. /// <summary>保护液位地址 (读写,如 VD962)</summary>
  140. public string ProtectionLevelAddress { get; set; } = "";
  141. // ─── 按索引访问(动态泵数量支持,向后兼容旧字段)───
  142. /// <summary>获取第 N 台泵启泵液位地址(1-based,N=1/2/3 取旧字段,N≥4 取扩展列表)</summary>
  143. public string GetStartPumpLevelAddress(int pumpIndex) => pumpIndex switch
  144. {
  145. 1 => StartPump1LevelAddress,
  146. 2 => StartPump2LevelAddress,
  147. 3 => StartPump3LevelAddress,
  148. _ => pumpIndex - 1 < StartPumpLevelAddresses.Count ? StartPumpLevelAddresses[pumpIndex - 1] : ""
  149. };
  150. /// <summary>获取第 N 台泵启泵液位值(1-based)</summary>
  151. public float? GetStartPumpLevel(int pumpIndex) => pumpIndex switch
  152. {
  153. 1 => StartPump1Level,
  154. 2 => StartPump2Level,
  155. 3 => StartPump3Level,
  156. _ => pumpIndex - 1 < StartPumpLevels.Count ? StartPumpLevels[pumpIndex - 1] : null
  157. };
  158. /// <summary>设置第 N 台泵启泵液位值(1-based)</summary>
  159. public void SetStartPumpLevel(int pumpIndex, float value)
  160. {
  161. switch (pumpIndex)
  162. {
  163. case 1: StartPump1Level = value; break;
  164. case 2: StartPump2Level = value; break;
  165. case 3: StartPump3Level = value; break;
  166. default:
  167. while (StartPumpLevels.Count < pumpIndex) StartPumpLevels.Add(null);
  168. StartPumpLevels[pumpIndex - 1] = value;
  169. break;
  170. }
  171. }
  172. /// <summary>扩展启泵液位地址列表(N≥4 时使用)</summary>
  173. public List<string> StartPumpLevelAddresses { get; set; } = new();
  174. /// <summary>扩展启泵液位值列表(N≥4 时使用)</summary>
  175. public List<float?> StartPumpLevels { get; set; } = new();
  176. }
  177. /// <summary>
  178. /// 仪表配置(压力、流量等带刻度/上下限的模拟量)
  179. /// </summary>
  180. public class GaugeConfig
  181. {
  182. /// <summary>名称(如 "压力"、"流量")</summary>
  183. public string Name { get; set; } = "";
  184. /// <summary>单位(如 "MPa"、"m³/h")</summary>
  185. public string Unit { get; set; } = "";
  186. /// <summary>即时值地址 (读,如 VD6600)</summary>
  187. public string ValueAddress { get; set; } = "";
  188. /// <summary>高压/上限设置地址 (读写,如 VD6704)</summary>
  189. public string HighSetAddress { get; set; } = "";
  190. /// <summary>低压/下限设置地址 (读写,如 VD6700)</summary>
  191. public string LowSetAddress { get; set; } = "";
  192. /// <summary>高压报警设定值(同步到 HighSetAddress)</summary>
  193. public float? HighAlarmSet { get; set; }
  194. /// <summary>低压报警设定值(同步到 LowSetAddress)</summary>
  195. public float? LowAlarmSet { get; set; }
  196. /// <summary>仪表最小刻度值</summary>
  197. public double MinValue { get; set; }
  198. /// <summary>仪表最大刻度值</summary>
  199. public double MaxValue { get; set; } = 100;
  200. }
  201. /// <summary>
  202. /// 通用传感器配置(简单模拟量,如日流量)
  203. /// </summary>
  204. public class SensorConfig
  205. {
  206. /// <summary>名称(如 "日流量")</summary>
  207. public string Name { get; set; } = "";
  208. /// <summary>单位(如 "m³")</summary>
  209. public string Unit { get; set; } = "";
  210. /// <summary>数据地址(如 VD884)</summary>
  211. public string Address { get; set; } = "";
  212. /// <summary>数据类型: "REAL" / "INT" / "DWORD"</summary>
  213. public string DataType { get; set; } = "REAL";
  214. /// <summary>访问权限: "R" (只读) / "RW" (读写)</summary>
  215. public string Access { get; set; } = "R";
  216. }
  217. /// <summary>
  218. /// 通用数字量输入配置
  219. /// </summary>
  220. public class DigitalInputConfig
  221. {
  222. /// <summary>名称(如 "泵1变频器故障")</summary>
  223. public string Name { get; set; } = "";
  224. /// <summary>地址(如 I0.1)</summary>
  225. public string Address { get; set; } = "";
  226. /// <summary>备注</summary>
  227. public string Remark { get; set; } = "";
  228. }
  229. /// <summary>
  230. /// 通用数字量输出配置
  231. /// </summary>
  232. public class DigitalOutputConfig
  233. {
  234. /// <summary>名称(如 "复位按钮")</summary>
  235. public string Name { get; set; } = "";
  236. /// <summary>地址(如 M30.0)</summary>
  237. public string Address { get; set; } = "";
  238. /// <summary>备注</summary>
  239. public string Remark { get; set; } = "";
  240. }
  241. /// <summary>
  242. /// 报警阈值
  243. /// </summary>
  244. public class AlarmThresholds
  245. {
  246. /// <summary>
  247. /// 报警来源:PLC / Host / Both
  248. /// PLC = 只信任 PLC 的 DI 开关量报警,上位机不做模拟量阈值判断
  249. /// Host = 只走上位机的模拟量阈值判断,忽略 PLC 的 DI 报警
  250. /// Both = 两套都检查(可能产生重复报警)
  251. /// 默认 PLC
  252. /// </summary>
  253. public string AlarmSource { get; set; } = "PLC";
  254. public float? LevelHigh { get; set; }
  255. public float? LevelLow { get; set; }
  256. public float? FlowHigh { get; set; }
  257. public float? FlowLow { get; set; }
  258. public float? PressureHigh { get; set; }
  259. public float? PressureLow { get; set; }
  260. }