EquipmentSettingViewModel.cs 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703
  1. using SWRIS.Dtos;
  2. using SWRIS.Enums;
  3. using SWRIS.Extensions;
  4. using System;
  5. using System.Collections.Generic;
  6. using System.ComponentModel;
  7. namespace SWRIS.Models.ViewModel
  8. {
  9. public class EquipmentSettingViewModel : INotifyPropertyChanged
  10. {
  11. private int ropeNumber;
  12. private string ropeName;
  13. private int trolleyId;
  14. private string ipAddress;
  15. private string serialNo;
  16. private string supplier;
  17. private int ropeCoreType;
  18. private int wireMaterialType;
  19. private int wireSurfaceType;
  20. private int layType;
  21. private bool disableAlarm;
  22. private int[] inUseSensor = new int[] { 1, 2, 3, 4 };
  23. private double liftHightRatio = 1;
  24. private RiskLevel soundRiskLevel = RiskLevel.Moderate;
  25. private ParameterData parameter;
  26. private bool isConnected;
  27. private RunningStatus runningStatus = RunningStatus.SpatialNormal;
  28. private double hoistDrumDiameter = 750;
  29. private double encoderResolution = 1000;
  30. private double ratedHeight;
  31. /// <summary>
  32. /// 绳号
  33. /// </summary>
  34. public int RopeNumber
  35. {
  36. get { return ropeNumber; }
  37. set
  38. {
  39. ropeNumber = value;
  40. OnPropertyChanged(nameof(RopeNumber));
  41. }
  42. }
  43. /// <summary>
  44. /// 钢丝绳名称
  45. /// </summary>
  46. public string RopeName
  47. {
  48. get { return ropeName; }
  49. set
  50. {
  51. ropeName = value;
  52. OnPropertyChanged(nameof(RopeName));
  53. }
  54. }
  55. public int TrolleyId
  56. {
  57. get { return trolleyId; }
  58. set
  59. {
  60. trolleyId = value;
  61. OnPropertyChanged(nameof(TrolleyId));
  62. }
  63. }
  64. /// <summary>
  65. /// Ip地址
  66. /// </summary>
  67. public string IpAddress
  68. {
  69. get { return ipAddress; }
  70. set
  71. {
  72. ipAddress = value;
  73. OnPropertyChanged(nameof(IpAddress));
  74. }
  75. }
  76. /// <summary>
  77. /// 序列号
  78. /// </summary>
  79. public string SerialNo
  80. {
  81. get { return serialNo; }
  82. set
  83. {
  84. serialNo = value;
  85. OnPropertyChanged(nameof(SerialNo));
  86. }
  87. }
  88. /// <summary>
  89. /// 供应商
  90. /// </summary>
  91. public string Supplier
  92. {
  93. get { return supplier; }
  94. set
  95. {
  96. supplier = value;
  97. OnPropertyChanged(nameof(Supplier));
  98. }
  99. }
  100. /// <summary>
  101. /// 绳芯类型 1 钢芯 2 纤维芯
  102. /// </summary>
  103. public int RopeCoreType
  104. {
  105. get { return ropeCoreType; }
  106. set
  107. {
  108. ropeCoreType = value;
  109. OnPropertyChanged(nameof(RopeCoreType));
  110. }
  111. }
  112. /// <summary>
  113. /// 钢丝材质 1 碳钢 2 不锈钢
  114. /// </summary>
  115. public int WireMaterialType
  116. {
  117. get { return wireMaterialType; }
  118. set
  119. {
  120. wireMaterialType = value;
  121. OnPropertyChanged(nameof(WireMaterialType));
  122. }
  123. }
  124. /// <summary>
  125. /// 表面状态 1 光面 2 A级镀锌 3 B级镀锌
  126. /// </summary>
  127. public int WireSurfaceType
  128. {
  129. get { return wireSurfaceType; }
  130. set
  131. {
  132. wireSurfaceType = value;
  133. OnPropertyChanged(nameof(WireSurfaceType));
  134. }
  135. }
  136. /// <summary>
  137. /// 捻向 1 右交互捻 2 左交互捻 3 右同向捻 4 左同向捻
  138. /// </summary>
  139. public int LayType
  140. {
  141. get { return layType; }
  142. set
  143. {
  144. layType = value;
  145. OnPropertyChanged(nameof(LayType));
  146. }
  147. }
  148. /// <summary>
  149. /// 绳长/高度倍率
  150. /// </summary>
  151. public double LiftHightRatio
  152. {
  153. get { return liftHightRatio; }
  154. set
  155. {
  156. // 倍率最小为 1
  157. liftHightRatio = value < 1 ? 1 : value;
  158. OnPropertyChanged(nameof(LiftHightRatio));
  159. // 倍率变化时按 钢丝绳长度 = 额定高度 × 倍率 重新计算
  160. UpdateWireRopeLength();
  161. }
  162. }
  163. public RiskLevel SoundRiskLevel
  164. {
  165. get { return soundRiskLevel; }
  166. set
  167. {
  168. soundRiskLevel = value;
  169. OnPropertyChanged(nameof(SoundRiskLevel));
  170. }
  171. }
  172. public ParameterData Parameter
  173. {
  174. get { return parameter; }
  175. set
  176. {
  177. if (parameter != null)
  178. {
  179. parameter.PropertyChanged -= OnParameterPropertyChanged;
  180. }
  181. parameter = value;
  182. OnPropertyChanged(nameof(Parameter));
  183. if (parameter != null)
  184. {
  185. // 分频系数变化时联动重算采样步长
  186. parameter.PropertyChanged += OnParameterPropertyChanged;
  187. }
  188. // 参数加载后按当前卷筒直径/编码器分辨率重新计算采样步长
  189. UpdateSamplingStep();
  190. }
  191. }
  192. public bool IsConnected
  193. {
  194. get { return isConnected; }
  195. set
  196. {
  197. isConnected = value;
  198. OnPropertyChanged(nameof(IsConnected));
  199. }
  200. }
  201. public bool DisableAlarm
  202. {
  203. get { return disableAlarm; }
  204. set
  205. {
  206. disableAlarm = value;
  207. OnPropertyChanged(nameof(DisableAlarm));
  208. }
  209. }
  210. public int[] InUseSensor
  211. {
  212. get { return inUseSensor; }
  213. set
  214. {
  215. inUseSensor = value;
  216. OnPropertyChanged(nameof(InUseSensor));
  217. }
  218. }
  219. public RunningStatus RunningStatus
  220. {
  221. get { return runningStatus; }
  222. set
  223. {
  224. runningStatus = value;
  225. OnPropertyChanged(nameof(RunningStatus));
  226. }
  227. }
  228. /// <summary>
  229. /// 卷筒/米轮直径 mm
  230. /// </summary>
  231. public double HoistDrumDiameter
  232. {
  233. get => hoistDrumDiameter; set
  234. {
  235. hoistDrumDiameter = value;
  236. OnPropertyChanged(nameof(HoistDrumDiameter));
  237. // 卷筒直径变化时重新计算采样步长
  238. UpdateSamplingStep();
  239. }
  240. }
  241. /// <summary>
  242. /// 编码器分辨率
  243. /// </summary>
  244. public double EncoderResolution
  245. {
  246. get => encoderResolution; set
  247. {
  248. encoderResolution = value;
  249. OnPropertyChanged(nameof(EncoderResolution));
  250. // 编码器分辨率变化时重新计算采样步长
  251. UpdateSamplingStep();
  252. }
  253. }
  254. /// <summary>
  255. /// 额定高度(起升高度)m
  256. /// </summary>
  257. public double RatedHeight
  258. {
  259. get { return ratedHeight; }
  260. set
  261. {
  262. ratedHeight = value;
  263. OnPropertyChanged(nameof(RatedHeight));
  264. // 额定高度变化时按 钢丝绳长度 = 额定高度 × 倍率 重新计算
  265. UpdateWireRopeLength();
  266. }
  267. }
  268. /// <summary>
  269. /// 根据额定高度与滑轮组倍率计算钢丝绳长度并赋值(钢丝绳长度 = 额定高度 × 倍率),单位 m。
  270. /// </summary>
  271. private void UpdateWireRopeLength()
  272. {
  273. if (parameter == null || ratedHeight <= 0 || liftHightRatio <= 0)
  274. {
  275. return;
  276. }
  277. parameter.WireRopeLength = (float)(ratedHeight * liftHightRatio);
  278. }
  279. /// <summary>
  280. /// 通过卷筒/米轮直径、编码器分辨率与分频系数计算采样步长(mm/点)并同步到设备参数。
  281. /// 设备每 分频系数 个编码器脉冲采样一个点,故:
  282. /// 采样步长 = 每脉冲位移 × 分频系数 = π × 直径 × 分频系数 / 分辨率
  283. /// </summary>
  284. private void UpdateSamplingStep()
  285. {
  286. if (parameter == null || encoderResolution <= 0 || hoistDrumDiameter <= 0 || parameter.FrequencyDivisionFactor <= 0)
  287. {
  288. return;
  289. }
  290. parameter.SamplingStep = (float)(Math.PI * hoistDrumDiameter * parameter.FrequencyDivisionFactor / encoderResolution);
  291. }
  292. /// <summary>
  293. /// 参数属性变化时联动重算采样步长(分频系数变化场景)
  294. /// </summary>
  295. private void OnParameterPropertyChanged(object sender, PropertyChangedEventArgs e)
  296. {
  297. if (e.PropertyName == nameof(ParameterData.FrequencyDivisionFactor))
  298. {
  299. UpdateSamplingStep();
  300. }
  301. }
  302. public List<KeyAndValueDto> RopeCoreTypes => TypeExtension.ToKeyAndDescriptionList(typeof(RopeCoreType));
  303. public List<KeyAndValueDto> WireMaterialTypes => TypeExtension.ToKeyAndDescriptionList(typeof(WireMaterialType));
  304. public List<KeyAndValueDto> LayTypes => TypeExtension.ToKeyAndDescriptionList(typeof(LayType));
  305. public List<KeyAndValueDto> WireSurfaceTypes => TypeExtension.ToKeyAndDescriptionList(typeof(WireSurfaceType));
  306. public List<KeyAndValueDto> RiskLevels => TypeExtension.ToKeyAndDescriptionList(typeof(RiskLevel));
  307. public event PropertyChangedEventHandler PropertyChanged;
  308. protected internal virtual void OnPropertyChanged(string propertyName)
  309. {
  310. PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
  311. }
  312. }
  313. public class ParameterData : INotifyPropertyChanged
  314. {
  315. private string mainBoardSoftwareVersion;
  316. private short sensorCount;
  317. private float samplingStep;
  318. private short frequencyDivisionFactor;
  319. private short damageInterval;
  320. private short damageThreshold;
  321. private short scrapUpperLimit;
  322. private short frontMagnetLength;
  323. private short backMagnetLength;
  324. private float valueCoefficient;
  325. private float effectiveStrokeLength;
  326. private short zeroPositionCorrectionDuration;
  327. private short zeroPositionCorrectionOffset;
  328. private float warningValue;
  329. private float alarmValue;
  330. private short soundLightAlarmAutoResetMode;
  331. private short wireRopeType;
  332. private short wireRopeCount;
  333. private float wireRopeLength;
  334. private float wireRopeDiameter;
  335. private short wireRopeStrandCount;
  336. private short wireRopeStrandWireCount;
  337. private EncoderDirection encoderDirection;
  338. private DateTime? systemTime;
  339. private float twistFactor;
  340. private float firstCalibrationPositiont;
  341. private float secondCalibrationPositiont;
  342. /// <summary>
  343. /// 主板软件版本号
  344. /// </summary>
  345. public string MainBoardSoftwareVersion
  346. {
  347. get => mainBoardSoftwareVersion;
  348. set
  349. {
  350. mainBoardSoftwareVersion = value;
  351. OnPropertyChanged(nameof(MainBoardSoftwareVersion));
  352. }
  353. }
  354. /// <summary>
  355. /// 传感器数量
  356. /// </summary>
  357. public short SensorCount
  358. {
  359. get => sensorCount;
  360. set
  361. {
  362. sensorCount = value;
  363. OnPropertyChanged(nameof(SensorCount));
  364. }
  365. }
  366. /// <summary>
  367. /// 采样步长 单位:mm/点 4字节浮点数
  368. /// </summary>
  369. public float SamplingStep
  370. {
  371. get => samplingStep;
  372. set
  373. {
  374. samplingStep = value;
  375. OnPropertyChanged(nameof(SamplingStep));
  376. }
  377. }
  378. /// <summary>
  379. /// 分频系数
  380. /// </summary>
  381. public short FrequencyDivisionFactor
  382. {
  383. get => frequencyDivisionFactor;
  384. set
  385. {
  386. frequencyDivisionFactor = value;
  387. OnPropertyChanged(nameof(FrequencyDivisionFactor));
  388. }
  389. }
  390. /// <summary>
  391. /// 判伤间隔 2字节整型
  392. /// </summary>
  393. public short DamageInterval
  394. {
  395. get => damageInterval;
  396. set
  397. {
  398. damageInterval = value;
  399. OnPropertyChanged(nameof(DamageInterval));
  400. }
  401. }
  402. /// <summary>
  403. /// 损伤门限 2字节整型
  404. /// </summary>
  405. public short DamageThreshold
  406. {
  407. get => damageThreshold;
  408. set
  409. {
  410. damageThreshold = value;
  411. OnPropertyChanged(nameof(DamageThreshold));
  412. }
  413. }
  414. /// <summary>
  415. /// 报废上限
  416. /// </summary>
  417. public short ScrapUpperLimit
  418. {
  419. get => scrapUpperLimit;
  420. set
  421. {
  422. scrapUpperLimit = value;
  423. OnPropertyChanged(nameof(ScrapUpperLimit));
  424. }
  425. }
  426. /// <summary>
  427. /// 前磁极长度 单位:mm 2字节整型
  428. /// </summary>
  429. public short FrontMagnetLength
  430. {
  431. get => frontMagnetLength;
  432. set
  433. {
  434. frontMagnetLength = value;
  435. OnPropertyChanged(nameof(FrontMagnetLength));
  436. }
  437. }
  438. /// <summary>
  439. /// 后磁极长度 单位:mm 2字节整型
  440. /// </summary>
  441. public short BackMagnetLength
  442. {
  443. get => backMagnetLength;
  444. set
  445. {
  446. backMagnetLength = value;
  447. OnPropertyChanged(nameof(BackMagnetLength));
  448. }
  449. }
  450. /// <summary>
  451. /// 量值系数 4字节浮点数
  452. /// </summary>
  453. public float ValueCoefficient
  454. {
  455. get => valueCoefficient;
  456. set
  457. {
  458. valueCoefficient = value;
  459. OnPropertyChanged(nameof(ValueCoefficient));
  460. }
  461. }
  462. /// <summary>
  463. /// 零位有效行程长度,单位:m 4字节浮点数
  464. /// </summary>
  465. public float EffectiveStrokeLength
  466. {
  467. get => effectiveStrokeLength;
  468. set
  469. {
  470. effectiveStrokeLength = value;
  471. OnPropertyChanged(nameof(EffectiveStrokeLength));
  472. }
  473. }
  474. /// <summary>
  475. /// 零位矫正静止时长,单位:秒 2字节整型
  476. /// </summary>
  477. public short ZeroPositionCorrectionDuration
  478. {
  479. get => zeroPositionCorrectionDuration;
  480. set
  481. {
  482. zeroPositionCorrectionDuration = value;
  483. OnPropertyChanged(nameof(ZeroPositionCorrectionDuration));
  484. }
  485. }
  486. /// <summary>
  487. /// 零位矫正允许偏移量,单位:mm 2字节整型
  488. /// </summary>
  489. public short ZeroPositionCorrectionOffset
  490. {
  491. get => zeroPositionCorrectionOffset;
  492. set
  493. {
  494. zeroPositionCorrectionOffset = value;
  495. OnPropertyChanged(nameof(ZeroPositionCorrectionOffset));
  496. }
  497. }
  498. /// <summary>
  499. /// 预警(黄色报警)量值 4字节浮点数
  500. /// </summary>
  501. public float WarningValue
  502. {
  503. get => warningValue;
  504. set
  505. {
  506. warningValue = value;
  507. OnPropertyChanged(nameof(WarningValue));
  508. }
  509. }
  510. /// <summary>
  511. /// 报警(红色报警)量值 4字节浮点数
  512. /// </summary>
  513. public float AlarmValue
  514. {
  515. get => alarmValue;
  516. set
  517. {
  518. alarmValue = value;
  519. OnPropertyChanged(nameof(AlarmValue));
  520. }
  521. }
  522. /// <summary>
  523. /// 声光报警自动重置方式,0=不自动重置,>0=延时自动重置,-1=开始新一次检测时重置
  524. /// </summary>
  525. public short SoundLightAlarmAutoResetMode
  526. {
  527. get => soundLightAlarmAutoResetMode;
  528. set
  529. {
  530. soundLightAlarmAutoResetMode = value;
  531. OnPropertyChanged(nameof(SoundLightAlarmAutoResetMode));
  532. }
  533. }
  534. /// <summary>
  535. /// 钢丝绳类型 0=塔吊单绳,1=电梯排绳
  536. /// </summary>
  537. public short WireRopeType
  538. {
  539. get => wireRopeType;
  540. set
  541. {
  542. wireRopeType = value;
  543. OnPropertyChanged(nameof(WireRopeType));
  544. }
  545. }
  546. /// <summary>
  547. ///钢丝绳数量 1字节
  548. /// </summary>
  549. public short WireRopeCount
  550. {
  551. get => wireRopeCount;
  552. set
  553. {
  554. wireRopeCount = value;
  555. OnPropertyChanged(nameof(WireRopeCount));
  556. }
  557. }
  558. /// <summary>
  559. /// 钢丝绳长度,单位:m 4字节浮点数(供协议打包/持久化使用)
  560. /// </summary>
  561. public float WireRopeLength
  562. {
  563. get => wireRopeLength;
  564. set
  565. {
  566. // 统一保留 2 位小数,避免浮点运算产生冗长小数位
  567. wireRopeLength = (float)Math.Round(value, 2, MidpointRounding.AwayFromZero);
  568. OnPropertyChanged(nameof(WireRopeLength));
  569. OnPropertyChanged(nameof(WireRopeLengthValue));
  570. }
  571. }
  572. /// <summary>
  573. /// 钢丝绳长度(double 显示值,供输入框绑定)。
  574. /// float 转 double 会产生二进制噪声(如 41.2f → 41.200000762939453),
  575. /// 故暴露 double 值并四舍五入到 2 位小数后再绑定。
  576. /// </summary>
  577. public double WireRopeLengthValue
  578. {
  579. get => Math.Round(wireRopeLength, 2);
  580. set
  581. {
  582. wireRopeLength = (float)Math.Round(value, 2, MidpointRounding.AwayFromZero);
  583. OnPropertyChanged(nameof(WireRopeLength));
  584. OnPropertyChanged(nameof(WireRopeLengthValue));
  585. }
  586. }
  587. /// <summary>
  588. /// 钢丝绳直径,单位:mm 4字节浮点数
  589. /// </summary>
  590. public float WireRopeDiameter
  591. {
  592. get => wireRopeDiameter;
  593. set
  594. {
  595. wireRopeDiameter = value;
  596. OnPropertyChanged(nameof(WireRopeDiameter));
  597. }
  598. }
  599. /// <summary>
  600. /// 钢丝绳股数 1字节
  601. /// </summary>
  602. public short WireRopeStrandCount
  603. {
  604. get => wireRopeStrandCount;
  605. set
  606. {
  607. wireRopeStrandCount = value;
  608. OnPropertyChanged(nameof(WireRopeStrandCount));
  609. }
  610. }
  611. /// <summary>
  612. /// 钢丝绳每股丝数,2字节整型
  613. /// </summary>
  614. public short WireRopeStrandWireCount
  615. {
  616. get => wireRopeStrandWireCount;
  617. set
  618. {
  619. wireRopeStrandWireCount = value;
  620. OnPropertyChanged(nameof(WireRopeStrandWireCount));
  621. }
  622. }
  623. /// <summary>
  624. /// 编码器方向,1=正向,2=反向
  625. /// </summary>
  626. public EncoderDirection EncoderDirection
  627. {
  628. get => encoderDirection;
  629. set
  630. {
  631. encoderDirection = value;
  632. OnPropertyChanged(nameof(EncoderDirection));
  633. }
  634. }
  635. /// <summary>
  636. /// 系统时间
  637. /// </summary>
  638. public DateTime? SystemTime
  639. {
  640. get => systemTime;
  641. set
  642. {
  643. systemTime = value;
  644. OnPropertyChanged(nameof(SystemTime));
  645. }
  646. }
  647. /// <summary>
  648. /// 判伤捻距系数,浮点数,判伤捻距默认为7d,可通过此参数设置系数来调整(与损伤判定相关)。
  649. /// 默认值为1.0,设置2.0表示判伤捻距为2 x 7 = 14d
  650. /// </summary>
  651. public float TwistFactor
  652. {
  653. get => twistFactor;
  654. set
  655. {
  656. twistFactor = value;
  657. OnPropertyChanged(nameof(TwistFactor));
  658. }
  659. }
  660. /// <summary>
  661. /// 限位1校准位置
  662. /// </summary>
  663. public float FirstCalibrationPositiont
  664. {
  665. get => firstCalibrationPositiont;
  666. set
  667. {
  668. firstCalibrationPositiont = value;
  669. OnPropertyChanged(nameof(FirstCalibrationPositiont));
  670. }
  671. }
  672. /// <summary>
  673. /// 限位2校准位置
  674. /// </summary>
  675. public float SecondCalibrationPositiont
  676. {
  677. get => secondCalibrationPositiont;
  678. set
  679. {
  680. secondCalibrationPositiont = value;
  681. OnPropertyChanged(nameof(SecondCalibrationPositiont));
  682. }
  683. }
  684. public event PropertyChangedEventHandler PropertyChanged;
  685. protected internal virtual void OnPropertyChanged(string propertyName)
  686. {
  687. PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
  688. }
  689. }
  690. }