realtime.go 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. package faultRecordFile
  2. import (
  3. "fmt"
  4. proto "fwh-toolbox-server/function/FaultRecordProtocol"
  5. )
  6. // Overview code=1 故障总体信息
  7. type Overview struct {
  8. MaxRecords uint8 `json:"maxRecords"`
  9. CurrentRecords uint8 `json:"currentRecords"`
  10. EarliestTime string `json:"earliestTime"` // 设备时间
  11. LatestTime string `json:"latestTime"`
  12. ChannelGroups
  13. }
  14. // DirectoryEntry code=3 目录项(14 字节)
  15. type DirectoryEntry struct {
  16. Index uint8 `json:"index"`
  17. Time string `json:"time"` // 设备时间
  18. ParamListVersion string `json:"paramListVersion"`
  19. TriggerSource uint16 `json:"triggerSource"`
  20. TriggerSourceName string `json:"triggerSourceName,omitempty"`
  21. }
  22. const directoryEntrySize = 14
  23. // ParseOverview 解析 code=1
  24. func ParseOverview(b []byte) (Overview, error) {
  25. r := &byteReader{b: b}
  26. o := Overview{
  27. MaxRecords: r.u8("maxRecords"),
  28. CurrentRecords: r.u8("currentRecords"),
  29. EarliestTime: r.time("earliestTime").String(),
  30. LatestTime: r.time("latestTime").String(),
  31. }
  32. o.ChannelGroups = readChannelGroups(r, false)
  33. return o, r.err
  34. }
  35. // ParseBasicInfo 解析 code=2
  36. func ParseBasicInfo(b []byte) (BasicInfo, error) {
  37. if len(b) != 16 {
  38. return BasicInfo{}, fmt.Errorf("basic info must be 16 bytes, got %d", len(b))
  39. }
  40. r := &byteReader{b: b}
  41. return readBasicInfo(r), r.err
  42. }
  43. // ParseDirectory 解析 code=3:1 字节条数 + N × 14 字节
  44. func ParseDirectory(b []byte) ([]DirectoryEntry, error) {
  45. if len(b) < 1 {
  46. return nil, fmt.Errorf("directory is empty")
  47. }
  48. n := int(b[0])
  49. if len(b) != 1+n*directoryEntrySize {
  50. return nil, fmt.Errorf("directory length %d does not match %d entries", len(b), n)
  51. }
  52. r := &byteReader{b: b[1:]}
  53. list := make([]DirectoryEntry, 0, n)
  54. for i := 0; i < n; i++ {
  55. e := DirectoryEntry{
  56. Index: r.u8("index"),
  57. Time: r.time("time").String(),
  58. ParamListVersion: fmt.Sprintf("%08X", r.u32("paramListVersion")),
  59. TriggerSource: r.u16("triggerSource"),
  60. }
  61. e.TriggerSourceName = proto.TriggerSourceName(e.TriggerSource)
  62. list = append(list, e)
  63. }
  64. return list, r.err
  65. }
  66. // ParseRealtime 按 code 解析 hexData,返回对应结构
  67. func ParseRealtime(code int, hexData string) (any, error) {
  68. b, err := proto.DecodeHex(hexData)
  69. if err != nil {
  70. return nil, err
  71. }
  72. switch code {
  73. case 1:
  74. return ParseOverview(b)
  75. case 2:
  76. return ParseBasicInfo(b)
  77. case 3:
  78. return ParseDirectory(b)
  79. default:
  80. return nil, fmt.Errorf("unsupported code %d", code)
  81. }
  82. }