dict.go 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. package faultRecordProtocol
  2. import (
  3. "fmt"
  4. "strconv"
  5. "strings"
  6. )
  7. // FunctionCodeNames 命令控制符(功能码),FaultFilter 文档 5.4.1
  8. var FunctionCodeNames = map[int]string{
  9. 1: "清除设备故障波形",
  10. 2: "采样通道配置",
  11. 3: "手动触发故障录波",
  12. 4: "设备对时",
  13. 5: "故障录波采样频率",
  14. 6: "配置可配采样通道",
  15. 7: "故障录波功能状态控制",
  16. }
  17. // DangerousFunctionCodes 设置前需要醒目确认的功能码
  18. var DangerousFunctionCodes = map[int]string{
  19. 1: "清除设备上的故障波形,不可恢复",
  20. 3: "立即触发一次故障录波",
  21. 4: "修改设备时间",
  22. }
  23. // 设备种类(界面与平台使用;协议 type 见 DeviceKindProtocolType)
  24. const (
  25. DeviceKindAGate = "aGate" // aGate/MCA,平台设备类型 1
  26. DeviceKindAPowerPE = "aPowerPE" // aPower-PE,平台设备类型 0
  27. DeviceKindAPowerMPPT = "aPowerMPPT" // aPower-MPPT,平台设备类型 2,SN 与 aPower 相同
  28. DeviceKindAHub = "aHub" // aHub(即 aPbox2.0),平台设备类型 3
  29. )
  30. // DeviceKindProtocolType 设备种类对应 377 报文中的 type(用户确认,2026-10-20);空字符串表示暂不支持
  31. var DeviceKindProtocolType = map[string]string{
  32. DeviceKindAGate: DeviceTypeAGate,
  33. DeviceKindAPowerPE: DeviceTypePE,
  34. DeviceKindAPowerMPPT: DeviceTypeMPPT,
  35. DeviceKindAHub: DeviceTypeAPbox,
  36. }
  37. // PeHwVerNames aPower PE 硬件版本 → 版本名称(内部名称)
  38. var PeHwVerNames = map[int]string{
  39. 0: "aPower 1.0",
  40. 2: "aPower 1.2(澳洲)/aPower 1.3(北美)",
  41. 4: "aPower 1.4",
  42. 20: "aPower 2/aPower 2(LR)",
  43. 21: "aPower S",
  44. 22: "aPower 2(SH)",
  45. 23: "aPower 2.1",
  46. 24: "aPower 2.1S",
  47. }
  48. // mpptPeHwVers 支持 aPower-MPPT 的 PE 硬件版本(目前只有 aPower S、aPower 2.1S,后续可能扩展)
  49. var mpptPeHwVers = map[int]bool{21: true, 24: true}
  50. // SupportsMPPT 该 PE 硬件版本的 aPower 是否带 MPPT
  51. func SupportsMPPT(peHwVer int) bool { return mpptPeHwVers[peHwVer] }
  52. // RealtimeCodeNames 实时数据类别,FaultFilter 文档 5.1
  53. var RealtimeCodeNames = map[int]string{
  54. 1: "故障总体信息",
  55. 2: "设备故障录波功能基本信息",
  56. 3: "故障录波总目录",
  57. }
  58. // TriggerSourceNames 事件触发源(F15),FaultFilter 文档 10.4
  59. var TriggerSourceNames = map[uint16]string{
  60. 0x0FF0: "手动触发 _Fix",
  61. 0x0FF1: "模拟故障触发 _Auto",
  62. 0x1000: "SL_DSP 预留触发源 16_1",
  63. 0x1001: "并网发生状态切换故障",
  64. 0x1002: "离网发生 aPower 离运问题",
  65. 0x1003: "油机发生状态切换故障",
  66. 0x5000: "PE_INV 预留触发源 16_1",
  67. 0x5001: "运行态下逆变故障",
  68. 0xD000: "MPPT 预留触发源 16_1",
  69. 0xD001: "运行态下 MPPT 故障",
  70. 0xD800: "APBOX2.0 预留触发源 16_1",
  71. 0xD801: "运行态下 APBOX2.0 故障",
  72. 0xE000: "DIF 预留触发源 16_1",
  73. 0xE001: "并网发生状态切换故障",
  74. 0xE002: "离网发生 aPower 离运问题",
  75. }
  76. // internalErrorCodes 设备内部通信错误判定码(F13),FaultFilter 文档 10.5
  77. var internalErrorCodes = map[uint64]string{
  78. 0x3: "下发命令与子设备回复的命令不一致",
  79. 0x4: "数据读取阶段:子设备回复错误",
  80. 0x5: "数据读取阶段:回复的数据类别不符",
  81. 0x6: "记录传输阶段:起始报文接收错误",
  82. 0x7: "记录传输阶段:后续数据未接收完成",
  83. 0x8: "记录传输阶段:数据块不连续",
  84. 0x9: "记录传输阶段:数据块内序号不连续",
  85. 0xa: "记录传输阶段:收到多余的后续数据",
  86. 0xb: "记录传输阶段:首包数据过短",
  87. 0xc: "记录传输结束阶段:后续数据未接收完成",
  88. 0xd: "数据读取阶段:接收超时",
  89. 0xe: "记录传输阶段:接收超时",
  90. 0xf: "记录传输结束阶段:接收超时",
  91. 0x10: "其他命令:接收超时",
  92. 0x11: "记录传输阶段:后续数据接收超时",
  93. 0x12: "参数读写阶段:读/写类型不一致",
  94. 0x13: "参数读写阶段:回复的功能码不一致",
  95. 0x14: "参数读写阶段:回复数据过短",
  96. 0x15: "参数读写阶段:接收超时",
  97. 0x16: "参数读写阶段:后续数据未接收完成",
  98. }
  99. // subDeviceErrorCodes 子设备错误码(F12),FaultFilter 文档 10.6
  100. var subDeviceErrorCodes = map[uint64]string{
  101. 0x10: "GeneralReject 诊断服务被拒绝",
  102. 0x11: "serviceNotSupported 不支持该诊断请求",
  103. 0x12: "subFunctionNotSupported 不支持该子功能",
  104. 0x13: "incorrectMessageLengthOrInvalidFormat 报文长度或格式错误",
  105. 0x14: "ResponseTooLong 响应过长",
  106. 0x22: "conditionsNotCorrect 条件错误",
  107. 0x23: "commTimeoutError 通信超时",
  108. 0x31: "requestOutOfRange 请求超过范围",
  109. 0x33: "securityAccessDenied 安全访问拒绝",
  110. 0x35: "invalidKey 密钥错误",
  111. 0x36: "exceedNumberOfAttempts 尝试次数超限",
  112. 0x37: "requiredTimeDelayNotExpired 延时未到期",
  113. 0x70: "UploadDownloadNotAccepted 上传或下载失败",
  114. 0x71: "TransferDataSuspended 数据传输中断",
  115. 0x72: "GeneralProgrammingFailure 擦写 Flash 错误",
  116. 0x73: "WrongBlockSequenceCounter 数据包序号错误",
  117. 0x78: "ResponsePending 子设备正忙",
  118. 0x7F: "serviceNotSupportedInActiveSession 当前模式不支持",
  119. }
  120. var fixedResultOne = map[string]string{
  121. "ok": "成功",
  122. "cancomerr:time out": "与子设备通信超时",
  123. "emserr:can p null": "未取到目标子设备",
  124. "emserr:can data null": "子设备返回数据为空",
  125. "emserr:set cmd err": "下发命令失败",
  126. "emserr:other": "其他错误",
  127. }
  128. var errorReplyResults = map[string]string{
  129. "json unpack err": "消息体不是合法 JSON",
  130. "cmd unpack err": "缺少 cmd 字段",
  131. "data unpack err": "缺少 data 字段",
  132. "busy": "设备正在处理其他命令",
  133. "pe sn not find": "pe 设备序列号无法匹配",
  134. "cmd no define": "不支持的命令码",
  135. "test fail": "连通性测试失败",
  136. }
  137. // DescribeResultOne 子项结果的中文说明,未知值原样返回
  138. func DescribeResultOne(s string) string {
  139. if d, ok := fixedResultOne[s]; ok {
  140. return d
  141. }
  142. if v, ok := strings.CutPrefix(s, "cancomerr:suberrcode="); ok {
  143. return describeCode("子设备错误码", v, subDeviceErrorCodes)
  144. }
  145. if v, ok := strings.CutPrefix(s, "cancomerr:index="); ok {
  146. return describeCode("设备内部通信错误", v, internalErrorCodes)
  147. }
  148. return s
  149. }
  150. // DescribeReplyResult 379 整体结果的中文说明
  151. func DescribeReplyResult(s string) string {
  152. switch s {
  153. case ResultOk:
  154. return "全部成功"
  155. case ResultError:
  156. return "存在失败的子项"
  157. }
  158. if d, ok := errorReplyResults[s]; ok {
  159. return d
  160. }
  161. return s
  162. }
  163. func describeCode(prefix, hexStr string, table map[uint64]string) string {
  164. code, err := strconv.ParseUint(strings.TrimPrefix(strings.ToLower(hexStr), "0x"), 16, 32)
  165. if err != nil {
  166. return fmt.Sprintf("%s %s", prefix, hexStr)
  167. }
  168. if d, ok := table[code]; ok {
  169. return fmt.Sprintf("%s 0x%X:%s", prefix, code, d)
  170. }
  171. return fmt.Sprintf("%s 0x%X", prefix, code)
  172. }
  173. // TriggerSourceName 触发源名称,表外代码返回空字符串
  174. func TriggerSourceName(code uint16) string {
  175. return TriggerSourceNames[code]
  176. }