updateEmspara.go 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. package main
  2. import (
  3. "bufio"
  4. "fmt"
  5. "fwh-toolbox-server/domain"
  6. "os"
  7. "regexp"
  8. "strconv"
  9. "strings"
  10. "gorm.io/driver/sqlite"
  11. "gorm.io/gorm"
  12. "gorm.io/gorm/clause"
  13. )
  14. type MacroItem struct {
  15. MacroName string // 宏名 VID_XXX PID_XXX
  16. SubNo uint // 子序号-在本组ID中的序号
  17. TotalNo uint // 总序号-在总内存中的序号
  18. Type string // 数据类型 UINT32 INT32 FLOAT CHAR*
  19. Description string // 描述
  20. }
  21. // 更新vid_macro.h和pid_macro.h的数据到sqlite
  22. func main() {
  23. // 打开 GBK 编码的文件
  24. vidFile, err := os.Open("./utils/emspara/updateCmd/vid_macro.h")
  25. if err != nil {
  26. panic(err)
  27. }
  28. defer vidFile.Close()
  29. pidFile, err := os.Open("./utils/emspara/updateCmd/pid_macro.h")
  30. if err != nil {
  31. panic(err)
  32. }
  33. defer pidFile.Close()
  34. // 打开 SQLite
  35. db, err := gorm.Open(sqlite.Open("./utils/emspara/emspara.db"), &gorm.Config{})
  36. if err != nil {
  37. panic(err)
  38. }
  39. // 自动建表
  40. if err := db.AutoMigrate(&domain.ParamsVidMacroModel{}, &domain.ParamsPidMacroModel{}); err != nil {
  41. panic(err)
  42. }
  43. // 处理vid文件
  44. err = parserMacroFile(vidFile, func(line string) error {
  45. item, err := parserMacroLine(line)
  46. if err != nil {
  47. return err
  48. }
  49. // 非 macro 数据行
  50. if item == nil {
  51. return nil
  52. }
  53. // 检查多组数据,如PE、MPPT、APbox2.0等
  54. itemList := checkMacroDataGroup(*item)
  55. for _, it := range itemList {
  56. if it.TotalNo == 0 {
  57. // 0无法插入,抛弃
  58. continue
  59. }
  60. // 插入VID数据
  61. db.Clauses(clause.OnConflict{UpdateAll: true}).Create(&domain.ParamsVidMacroModel{ID: it.TotalNo, MacroName: it.MacroName, Description: it.Description})
  62. }
  63. return nil
  64. })
  65. if err != nil {
  66. panic(err)
  67. }
  68. // 处理pid文件
  69. err = parserMacroFile(pidFile, func(line string) error {
  70. item, err := parserMacroLine(line)
  71. if err != nil {
  72. return err
  73. }
  74. // 非 macro 数据行
  75. if item == nil {
  76. return nil
  77. }
  78. // 检查多组数据,如PE、MPPT、APbox2.0等
  79. itemList := checkMacroDataGroup(*item)
  80. for _, it := range itemList {
  81. if it.TotalNo == 0 {
  82. // 0无法插入,抛弃
  83. continue
  84. }
  85. // 插入VID数据
  86. db.Clauses(clause.OnConflict{UpdateAll: true}).Create(&domain.ParamsPidMacroModel{ID: it.TotalNo, MacroName: it.MacroName, Description: it.Description})
  87. }
  88. return nil
  89. })
  90. if err != nil {
  91. panic(err)
  92. }
  93. }
  94. func parserMacroFile(file *os.File, fn func(line string) error) error {
  95. // 使用 transform 将 GBK 转成 UTF-8
  96. // reader := transform.NewReader(file, simplifiedchinese.GBK.NewDecoder())
  97. // scanner := bufio.NewScanner(reader)
  98. scanner := bufio.NewScanner(file)
  99. for scanner.Scan() {
  100. line := scanner.Text() // 已经是 UTF-8 的字符串
  101. line = strings.TrimSpace(line) // 去掉前后空格、制表符和换行符
  102. fmt.Println("原始行:", line)
  103. if err := fn(line); err != nil {
  104. fmt.Printf("[Warn]\nline: %s\nerror: %s\n", line, err.Error())
  105. }
  106. }
  107. return scanner.Err()
  108. }
  109. func parserMacroLine(line string) (*MacroItem, error) {
  110. if strings.HasPrefix(line, "VID_") || strings.HasPrefix(line, "PID_") {
  111. // macro 数据
  112. // 正则匹配:
  113. // ^(\w+),\s*///<\s*\((\d+)/(\d+)\)\s*(\w+)\s+(.*)$
  114. // 解释:
  115. // 1. ^(\w+), -> 宏名 + 逗号
  116. // 2. \s*///<\s* -> 注释标记,空格可有可无
  117. // 3. \((\d+)/(\d+)\) -> 括号中的两个数字
  118. // 4. (UINT32|INT32|FLOAT|CHAR\*) -> 类型
  119. // 5. (.*)$ -> 剩余描述
  120. re := regexp.MustCompile(`^(\w+),\s*///<\s*\((\d+)/(\d+)\)\s*(UINT32|INT32|FLOAT|CHAR\*)\s+(.*)$`)
  121. matches := re.FindStringSubmatch(line)
  122. if len(matches) == 6 {
  123. macroName := matches[1]
  124. subNoStr := matches[2]
  125. totalNoStr := matches[3]
  126. typ := matches[4]
  127. desc := matches[5]
  128. fmt.Println("宏名:", macroName)
  129. fmt.Println("子序号:", subNoStr)
  130. fmt.Println("总序号:", totalNoStr)
  131. fmt.Println("类型:", typ)
  132. fmt.Println("描述:", desc)
  133. subNo, err := strconv.ParseUint(subNoStr, 10, 64)
  134. if err != nil {
  135. return nil, err
  136. }
  137. totalNo, err := strconv.ParseUint(totalNoStr, 10, 64)
  138. if err != nil {
  139. return nil, err
  140. }
  141. return &MacroItem{
  142. MacroName: macroName,
  143. SubNo: uint(subNo),
  144. TotalNo: uint(totalNo),
  145. Type: typ,
  146. Description: desc,
  147. }, nil
  148. } else {
  149. return nil, fmt.Errorf("无法匹配该行")
  150. }
  151. }
  152. // 非macro 数据
  153. return nil, nil
  154. }
  155. func checkMacroDataGroup(item MacroItem) []MacroItem {
  156. // 排除_MAX_NUM
  157. if strings.HasSuffix(item.MacroName, "_MAX_NUM") {
  158. return []MacroItem{}
  159. }
  160. var subMaxNum uint = 0
  161. var groupNum uint = 1
  162. if strings.HasPrefix(item.MacroName, "VID_PE_") {
  163. // VID_PE_ 每组128个数据,共16组
  164. subMaxNum = 128
  165. groupNum = 16
  166. } else if strings.HasPrefix(item.MacroName, "VID_BMS_") { // NOSONAR
  167. // VID_BMS_ 每组128个数据,共16组
  168. subMaxNum = 128
  169. groupNum = 16
  170. } else if strings.HasPrefix(item.MacroName, "VID_MPPT_") { // NOSONAR
  171. // VID_MPPT_ 每组128个数据,共16组
  172. subMaxNum = 128
  173. groupNum = 16
  174. } else if strings.HasPrefix(item.MacroName, "VID_APBOX20_") {
  175. // VID_APBOX20_ 每组256个数据,共4组
  176. subMaxNum = 256
  177. groupNum = 4
  178. } else if strings.HasPrefix(item.MacroName, "PID_APOWER_") { // NOSONAR
  179. // PID_APOWER_ 每组128个数据,共16组
  180. subMaxNum = 128
  181. groupNum = 16
  182. } else if strings.HasPrefix(item.MacroName, "PID_APBOX20_") { // NOSONAR
  183. // VID_APBOX20_ 每组256个数据,共4组
  184. subMaxNum = 256
  185. groupNum = 4
  186. }
  187. if groupNum == 1 {
  188. return []MacroItem{item}
  189. }
  190. var itemList []MacroItem = []MacroItem{}
  191. for i := uint(0); i < groupNum; i++ {
  192. itemList = append(itemList, MacroItem{
  193. MacroName: fmt.Sprintf("%s_%s", item.MacroName, strconv.FormatUint(uint64(i+1), 10)),
  194. SubNo: item.SubNo,
  195. TotalNo: item.TotalNo + (i * subMaxNum),
  196. Type: item.Type,
  197. Description: item.Description,
  198. })
  199. }
  200. return itemList
  201. }