scd_file_parse.go 85 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263
  1. package bo
  2. import (
  3. "scd_check_tools/global"
  4. "scd_check_tools/logger"
  5. "scd_check_tools/models/enum"
  6. "scd_check_tools/models/node_attr"
  7. "scd_check_tools/mqtt"
  8. "scd_check_tools/tools"
  9. "bufio"
  10. "encoding/json"
  11. "encoding/xml"
  12. "errors"
  13. "fmt"
  14. "io"
  15. "io/fs"
  16. "io/ioutil"
  17. "log"
  18. "os"
  19. "os/exec"
  20. "path/filepath"
  21. "runtime"
  22. "sort"
  23. "strconv"
  24. "strings"
  25. "sync"
  26. "time"
  27. "github.com/astaxie/beego/orm"
  28. //"github.com/go-xmlfmt/xmlfmt"
  29. //"github.com/krolaw/xsd"
  30. )
  31. //当前消费的本实例数
  32. //需要通过该实例数进行运算,得到该实例下的启始ID段。每个实例分配了5000000个ID用于业务数据的消费
  33. //主要消费ID的业务数据就是节点,即单个SCD文件节点数量不能超过500W.
  34. var instanNum = 1
  35. //scd文件解析锁。同一文件不能同时多次解析
  36. var parseLock = sync.Map{}
  37. //节点引用缓存
  38. type NodeCacheMap struct {
  39. ParentNodeId int64 //父节点
  40. ObjAddr any //引用节点对象地址
  41. }
  42. var spaceMap = sync.Map{} // map[string]string{}
  43. //SCD节点存储。格式:map[int64]map[int64]NodeCacheMap{}
  44. var GlobalNodeMap = sync.Map{}
  45. type ScdParse struct {
  46. DeviceBaseModel
  47. SclModel map[string]interface{}
  48. //是否是管控SCD,1为管控SCD,0为非管控SCD
  49. IsCheckinScd int
  50. }
  51. type sortInt64 []int64
  52. func (p sortInt64) Len() int { return len(p) }
  53. func (p sortInt64) Less(i, j int) bool { return p[i] < p[j] }
  54. func (p sortInt64) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
  55. //释放使用频率低的scd缓存
  56. func (c *ScdParse) RemoveScdCache(toscdid ...string) {
  57. scdid := ""
  58. if len(toscdid) == 0 {
  59. logger.Logger.Println("系统正在尝试释放使用频率低的scd缓存")
  60. lastUsedList := map[int64]string{}
  61. keylist := []int64{}
  62. global.CachedScdMap.Range(func(k, v any) bool {
  63. lastUsedList[v.(int64)] = k.(string)
  64. keylist = append(keylist, v.(int64))
  65. return true
  66. })
  67. if len(keylist) == 0 {
  68. logger.Logger.Println("当前系统内已无scd缓存")
  69. return
  70. }
  71. if len(keylist) == 1 {
  72. logger.Logger.Println("当前无scd缓存可以释放")
  73. return
  74. }
  75. sort.Sort(sortInt64(keylist))
  76. //释放最长时间的第一个scd
  77. lasttime := keylist[0]
  78. scdid = lastUsedList[lasttime]
  79. if time.Now().Unix()-lasttime < 300 {
  80. //如果5分钟使用过scd,则不能释放
  81. logger.Logger.Println(fmt.Sprintf("SCD %s最近5分钟内有访问记录,不允许释放!", scdid))
  82. return
  83. }
  84. } else {
  85. scdid = toscdid[0]
  86. }
  87. logger.Logger.Println("系统正在释放scd【" + scdid + "】的缓存")
  88. global.CachedScdCrc.Delete(fmt.Sprintf("crc_%s", scdid))
  89. global.IedCrcMakeState.Delete(fmt.Sprintf("crc_%s", scdid))
  90. scdXmlObj, serr := c.GetScdXmlObjectBySCDID(scdid)
  91. if serr != nil {
  92. logger.Logger.Error(serr, fmt.Sprintf("SCD %s获取异常!", scdid))
  93. return
  94. }
  95. cachekey := ""
  96. if scdXmlObj != nil {
  97. for _, ied := range scdXmlObj.IED {
  98. cachekey = fmt.Sprintf("GetIedCtrlBlock_%s_%s", scdid, ied.Name)
  99. global.GoCahce.Delete(cachekey)
  100. cachekey = "GetIedRelations_" + scdid + ied.Name
  101. global.GoCahce.Delete(cachekey)
  102. cachekey = fmt.Sprintf("GetIedBlockRelations_%s_%s", scdid, ied.Name)
  103. global.GoCahce.Delete(cachekey)
  104. cachekey = "GetIedInputsRelations_" + scdid + ied.Name
  105. global.GoCahce.Delete(cachekey)
  106. }
  107. }
  108. cachekey = fmt.Sprintf("networkinfo_%s", scdid)
  109. global.GoCahce.Delete(cachekey)
  110. cachekey = fmt.Sprintf("cachebBlockDetail_%s", scdid)
  111. global.GoCahce.Delete(cachekey)
  112. cachekey = "GetIedRelations_" + scdid
  113. global.GoCahce.Delete(cachekey)
  114. global.GoCahce.Delete(scdid)
  115. cachekey = fmt.Sprintf("scd_netinfo_%d", scdid)
  116. global.GoCahce.Delete(cachekey)
  117. cachekey = fmt.Sprintf("scd_info_%s", scdid)
  118. global.GoCahce.Delete(cachekey)
  119. scdidint64, _ := strconv.ParseInt(scdid, 10, 64)
  120. GlobalNodeMap.Delete(scdidint64)
  121. global.CachedScdMap.Delete(scdidint64)
  122. runtime.GC()
  123. }
  124. //语法验证
  125. func (c *ScdParse) SchemaValid(scdid, scdname, scdFilePath string) ([]string, error) {
  126. if scdid == "" && scdname == "" {
  127. logger.Logger.Error(errors.New("SCD编号和名称不能同时不空"))
  128. return nil, errors.New("SCD编号和名称不能同时不空")
  129. }
  130. stationid := ""
  131. if scdid != "" {
  132. scdmgr := new(ScdMgr)
  133. scdinfo, err := scdmgr.One(scdid)
  134. if err != nil {
  135. logger.Logger.Error("无效的SCD编号:" + scdid)
  136. return nil, err
  137. }
  138. scdFilePath = tools.IsEmpty(scdinfo["path"])
  139. stationid = tools.IsEmpty(scdinfo["station_id"])
  140. } else {
  141. scdmgr := new(ScdMgr)
  142. scdinfo, err := scdmgr.OneByName(scdname, scdFilePath)
  143. if err != nil {
  144. logger.Logger.Error(fmt.Sprintf("无效的SCD名称%s和路径%s", scdname, scdFilePath))
  145. return nil, err
  146. }
  147. scdid = tools.IsEmpty(scdinfo["id"])
  148. scdFilePath = tools.IsEmpty(scdinfo["path"])
  149. stationid = tools.IsEmpty(scdinfo["station_id"])
  150. }
  151. if scdFilePath == "" {
  152. logger.Logger.Error("该SCD文件路径为空,可能已被删除")
  153. return nil, errors.New("该SCD文件路径为空,可能已被删除")
  154. }
  155. chr := string(os.PathSeparator)
  156. dir, _ := filepath.Abs(filepath.Dir(os.Args[0]))
  157. xsdPath := strings.Join([]string{dir, "schema", "SCL.xsd"}, chr)
  158. validResultPath := strings.Join([]string{dir, "static", "upload", scdid + ".schema_valid"}, chr)
  159. osname := string(runtime.GOOS)
  160. var subProcess *exec.Cmd
  161. scdAbsPath := scdFilePath
  162. if scdFilePath[0:1] == "." {
  163. //相对路径
  164. scdAbsPath = dir + strings.ReplaceAll(strings.Replace(scdFilePath, ".", "", 1), "\\", chr)
  165. }
  166. data := map[string]string{"name": scdname, "stationid": stationid, "rootid": scdid, "state": "0", "node": "check-file", "msg": ""}
  167. dataMsg, _ := json.Marshal(data)
  168. mqtt.PublishMessage(fmt.Sprintf("/jujutong/scd_check_tools/parse/%s/%s", stationid, scdid), string(dataMsg))
  169. checkObj := new(ScdNodeRule)
  170. checkObj.ScdID, _ = strconv.ParseInt(scdid, 10, 64)
  171. yfrulelist, _, _ := checkObj.GetDefList(map[string]interface{}{
  172. "enable": 1,
  173. "check_name": "语法校验",
  174. }, 1, 1)
  175. scdYFcheckRuleid := ""
  176. if len(yfrulelist) > 0 {
  177. scdYFcheckRuleid = tools.IsEmpty(yfrulelist[0]["id"])
  178. }
  179. logger.Logger.Debug(fmt.Sprintf("开始校验scd文件%s的语法正确性", scdAbsPath))
  180. if scdYFcheckRuleid != "" {
  181. if osname == "windows" {
  182. //logger.Logger.Debug("=====jar路径:" + dir + chr + `scd_schema_valid1.0_prod.jar`)
  183. subProcess = exec.Command("java", "-jar", "-Dfile.encoding=utf-8", dir+chr+`scd_schema_valid1.0_prod.jar`, "1", scdAbsPath, xsdPath, validResultPath)
  184. } else {
  185. javaCmd := `export LANG="zh_CN.UTF-8" && java -jar -Dfile.encoding=utf-8 ` + dir + chr + `scd_schema_valid1.0_prod.jar 1 "` + scdAbsPath + `" "` + xsdPath + `" "` + validResultPath + `"`
  186. subProcess = exec.Command("bash", "-c", javaCmd)
  187. logger.Logger.Debug(fmt.Sprintf("javaCmd:%s", javaCmd))
  188. }
  189. stdin, err := subProcess.StdinPipe()
  190. if err != nil {
  191. logger.Logger.Error(err)
  192. return nil, err
  193. }
  194. defer stdin.Close()
  195. stdout, _ := subProcess.StdoutPipe()
  196. if err = subProcess.Start(); err != nil {
  197. logger.Logger.Error(err)
  198. return nil, err
  199. }
  200. txt := make([]byte, 1024)
  201. ValidErrMsg := []string{}
  202. for {
  203. time.Sleep(100 * time.Millisecond)
  204. n, err := stdout.Read(txt)
  205. if err == io.EOF { //读取结束,会报EOF
  206. break
  207. }
  208. str := tools.ConvertByte2String(txt[0:n], "UTF-8")
  209. logger.Logger.Debug(str)
  210. if str == "ValidOverWithOK" {
  211. break
  212. }
  213. if strings.Count(str, "ValidOverWithError") == 1 {
  214. strs := strings.Split(str[len("ValidOverWithError:"):], ",")
  215. stdout.Close()
  216. if len(strs) == 1 {
  217. ValidErrMsg = []string{"0", strs[0]}
  218. break
  219. //return nil, errors.New(fmt.Sprintf("校验SCD文件语法时发生严重错误:%s 无法继续校验该SCD文件!", strs[0]))
  220. }
  221. //ValidErrMsg = fmt.Sprintf("SCD文件第%s行配置发生严重错误:%s 无法继续校验该SCD文件!", strs[0], strs[1])
  222. ValidErrMsg = []string{strs[0], strs[1]}
  223. break
  224. //return nil, errors.New(fmt.Sprintf("SCD文件第%s行配置发生严重错误:%s 无法继续校验该SCD文件!", strs[0], strs[1]))
  225. }
  226. }
  227. stdout.Close()
  228. logger.Logger.Debug(fmt.Sprintf("scd文件%s的语法校验完成", scdAbsPath))
  229. db := orm.NewOrm()
  230. db.Raw("delete from t_scd_node_rule_parse where scd_id=?", scdid).Exec()
  231. insertRuleSql := "insert into t_scd_node_rule_parse(scd_id,line_no,ied_name,rule_id,parse_result,line_xml)values"
  232. if len(ValidErrMsg) > 0 {
  233. db.Raw(fmt.Sprintf("%s(%s,%s,'%s',%s,'%s','%s')", insertRuleSql, scdid, ValidErrMsg[0], "", scdYFcheckRuleid, ValidErrMsg[1], "")).Exec()
  234. }
  235. go func(scdid, stationid, validResultPath, scdYFcheckRuleid string) {
  236. rfile, err := os.Open(validResultPath) // For read access.
  237. if err != nil {
  238. logger.Logger.Error(err, "异常SCD语法校验结果文件:"+validResultPath)
  239. return
  240. }
  241. defer rfile.Close()
  242. buf := bufio.NewReader(rfile)
  243. var errorlist []string
  244. //将结果写入t_scd_node_rule_parse表
  245. for {
  246. line, err := buf.ReadString('\n')
  247. line = strings.TrimSpace(line)
  248. if err != nil {
  249. if err == io.EOF { //读取结束,会报EOF
  250. break
  251. }
  252. logger.Logger.Error(err)
  253. return
  254. }
  255. linestrs := strings.Split(strings.ReplaceAll(line, "'", ""), "|")
  256. if ind := strings.Index(linestrs[1], ":"); ind > 1 {
  257. linestrs[1] = linestrs[1][ind+1:]
  258. }
  259. errorlist = append(errorlist, fmt.Sprintf("(%s,%s,'%s',%s,'%s','%s')", scdid, linestrs[0], "", scdYFcheckRuleid, linestrs[1], linestrs[2]))
  260. if len(errorlist) == 2000 {
  261. _, err = db.Raw(fmt.Sprintf("%s%s", insertRuleSql, strings.Join(errorlist, ","))).Exec()
  262. if err != nil {
  263. logger.Logger.Error(err)
  264. }
  265. errorlist = []string{}
  266. }
  267. }
  268. if len(errorlist) > 0 {
  269. _, err = db.Raw(fmt.Sprintf("%s%s", insertRuleSql, strings.Join(errorlist, ","))).Exec()
  270. if err != nil {
  271. logger.Logger.Error(err)
  272. }
  273. errorlist = []string{}
  274. }
  275. insertRuleSql = ""
  276. data := map[string]string{"name": scdname, "stationid": stationid, "rootid": scdid, "state": "1", "node": "check-file", "msg": ""}
  277. dataMsg, _ := json.Marshal(data)
  278. mqtt.PublishMessage(fmt.Sprintf("/jujutong/scd_check_tools/parse/%s/%s", stationid, scdid), string(dataMsg))
  279. }(scdid, stationid, validResultPath, scdYFcheckRuleid)
  280. }
  281. //开始语义校验
  282. logger.Logger.Info("======开始进行语义校验")
  283. checkObj.TestCheckRule()
  284. return nil, nil
  285. }
  286. //格式化scd源文件。主要考虑有些源文件没有缩进格式,这样获取节点行数时是错误的
  287. func (c *ScdParse) ForamtScdPath(scdFilePath string) (int64, error) {
  288. logger.Logger.Debug(fmt.Sprintf("开始格式化SCD文件%s", scdFilePath))
  289. var tmpFileSCD = fmt.Sprintf("%s.tmp", scdFilePath)
  290. tmpFileHander, err := os.OpenFile(tmpFileSCD, os.O_RDWR|os.O_TRUNC|os.O_CREATE, 0644)
  291. if err != nil {
  292. logger.Logger.Error(err)
  293. }
  294. defer tmpFileHander.Close()
  295. var item xml.Token
  296. xmlhander, err2 := os.Open(scdFilePath)
  297. if err2 != nil {
  298. logger.Logger.Error(err2)
  299. return 0, err2
  300. }
  301. defer xmlhander.Close()
  302. de := xml.NewDecoder(xmlhander)
  303. var startElementLoaded = false
  304. var nodeText = ""
  305. var node_cnt = int64(0) //节点总数
  306. iedContentList := []string{`<?xml version="1.0" encoding="UTF-8"?>`, "\n"}
  307. for {
  308. item, err2 = de.Token()
  309. if err2 == io.EOF {
  310. break
  311. }
  312. if err2 != nil {
  313. log.Println(err2)
  314. break
  315. }
  316. switch token := item.(type) {
  317. case xml.StartElement:
  318. node_cnt = node_cnt + 1 //节点数量
  319. startElementLoaded = true
  320. name := token.Name.Local
  321. node := []string{}
  322. //判断节点名称是否有名空间
  323. ndoeSpace := ""
  324. if v, ok := spaceMap.Load(token.Name.Space); ok {
  325. ndoeSpace = tools.IsEmpty(v)
  326. }
  327. if ndoeSpace != "" {
  328. node = append(node, "<"+ndoeSpace+":"+name)
  329. } else {
  330. node = append(node, "<"+name)
  331. }
  332. if len(token.Attr) != 0 {
  333. for _, xmlAttr := range token.Attr {
  334. v_attrname := xmlAttr.Name.Local
  335. v_attrvalue := xmlAttr.Value
  336. if name == "SCL" {
  337. //处理名空间
  338. if v_attrname != "xmlns" && len(v_attrvalue) > 4 {
  339. if v_attrname == "schemaLocation" {
  340. spaceMap.Store(v_attrvalue, "xsi")
  341. v_attrname = "xsi:" + v_attrname
  342. } else if v_attrvalue[0:4] == "http" && v_attrname != "scl" {
  343. spaceMap.Store(v_attrvalue, v_attrname)
  344. v_attrname = "xmlns:" + v_attrname
  345. }
  346. }
  347. } else if xmlAttr.Name.Space != "" {
  348. //logger.Logger.Info(fmt.Sprintf("attr space:%s attrname:%s attrvalue:%s", xmlAttr.Name.Space, v_attrname, v_attrvalue))
  349. //获取名空间名称
  350. if v, h := spaceMap.Load(xmlAttr.Name.Space); h && v.(string) != "scl" {
  351. v_attrname = v.(string) + ":" + v_attrname
  352. } else {
  353. spaceMap.Store(v_attrvalue, v_attrname)
  354. v_attrname = xmlAttr.Name.Space + ":" + v_attrname
  355. }
  356. }
  357. v_attrvalue = strings.ReplaceAll(v_attrvalue, "'", "''")
  358. v_attrvalue = strings.ReplaceAll(v_attrvalue, "<", "")
  359. v_attrvalue = strings.ReplaceAll(v_attrvalue, ">", "")
  360. node = append(node, " "+v_attrname+"=\""+v_attrvalue+"\"")
  361. }
  362. }
  363. node = append(node, ">\n")
  364. iedContentList = append(iedContentList, strings.Join(node, ""))
  365. break
  366. case xml.EndElement:
  367. name := token.Name.Local
  368. ndoeSpace := ""
  369. if v, ok := spaceMap.Load(token.Name.Space); ok {
  370. ndoeSpace = v.(string)
  371. }
  372. if ndoeSpace != "" && ndoeSpace != "xmlns" {
  373. name = ndoeSpace + ":" + name
  374. }
  375. if nodeText != "" {
  376. iedContentList = append(iedContentList, "</"+name+">\n")
  377. } else {
  378. lastNode := strings.ReplaceAll(iedContentList[len(iedContentList)-1], "\n", "")
  379. lastSize := len(lastNode)
  380. if lastSize <= len(name) {
  381. iedContentList = append(iedContentList, "</"+name+">\n")
  382. } else {
  383. if lastNode[0:len(name)+1] == "<"+name {
  384. //判断上一个节点是否结束,如果已经结束时,则使用单独的结束标签,否则使用简化结束标签"/>"
  385. if lastNode[lastSize-2:] == "/>" {
  386. //上个节点已经结束
  387. iedContentList = append(iedContentList, "</"+name+">\n")
  388. } else {
  389. iedContentList[len(iedContentList)-1] = lastNode[0:lastSize-1] + "/>\n"
  390. }
  391. } else {
  392. iedContentList = append(iedContentList, "</"+name+">\n")
  393. }
  394. }
  395. }
  396. nodeText = ""
  397. startElementLoaded = false
  398. break
  399. case xml.CharData:
  400. if startElementLoaded {
  401. nodeText = string(token)
  402. nodeText = strings.ReplaceAll(strings.ReplaceAll(nodeText, "'", "''"), "\n", "")
  403. nodeText = strings.ReplaceAll(nodeText, "\t", "")
  404. nodeText = strings.ReplaceAll(nodeText, "\r", "")
  405. nodeText = strings.ReplaceAll(nodeText, "<", "")
  406. nodeText = strings.ReplaceAll(nodeText, ">", "")
  407. nodeText = strings.Trim(nodeText, " ")
  408. //log.Println("NODE ["+startName+"] Text:", nodeText)
  409. if nodeText != "" {
  410. lastnode := iedContentList[len(iedContentList)-1]
  411. iedContentList[len(iedContentList)-1] = lastnode[:len(lastnode)-1]
  412. iedContentList = append(iedContentList, nodeText)
  413. }
  414. }
  415. break
  416. case xml.Comment:
  417. case xml.ProcInst:
  418. case xml.Directive:
  419. default:
  420. log.Println("解析失败!")
  421. break
  422. }
  423. }
  424. tmpFileHander.WriteString(strings.Join(iedContentList, ""))
  425. tmpFileHander.Close()
  426. xmlhander.Close()
  427. //time.Sleep(1 * time.Second)
  428. err = os.Rename(tmpFileSCD, scdFilePath)
  429. if err != nil {
  430. logger.Logger.Error(err, "格式化SCD文件异常:"+scdFilePath)
  431. } else {
  432. logger.Logger.Debug(fmt.Sprintf("SCD文件%s格式化完成!", scdFilePath))
  433. }
  434. return node_cnt, nil
  435. }
  436. func (c *ScdParse) LoadCcdXml(ccdPath string) (*node_attr.CcdIed, error) {
  437. file, err := os.Open(ccdPath) // For read access.
  438. if err != nil {
  439. logger.Logger.Error(err, "异常CCD文件:"+ccdPath)
  440. return nil, err
  441. }
  442. defer file.Close()
  443. data, err := ioutil.ReadAll(file)
  444. if err != nil {
  445. logger.Logger.Error(err, "异常CCD文件:"+ccdPath)
  446. return nil, err
  447. }
  448. scl := new(node_attr.CcdIed)
  449. err = xml.Unmarshal(data, &scl)
  450. if err != nil {
  451. logger.Logger.Error(err, "异常CCD文件:"+ccdPath)
  452. return nil, err
  453. }
  454. return scl, nil
  455. }
  456. func (c *ScdParse) LoadScdXml(scdPath string) (*node_attr.SCL, error) {
  457. file, err := os.Open(scdPath) // For read access.
  458. if err != nil {
  459. logger.Logger.Error(err, "异常SCD文件:"+scdPath)
  460. return nil, err
  461. }
  462. defer file.Close()
  463. data, err := ioutil.ReadAll(file)
  464. if err != nil {
  465. logger.Logger.Error(err, "异常SCD文件:"+scdPath)
  466. return nil, err
  467. }
  468. scl := new(node_attr.SCL)
  469. err = xml.Unmarshal(data, &scl)
  470. if err != nil {
  471. logger.Logger.Error(err, "异常SCD文件:"+scdPath)
  472. return nil, err
  473. }
  474. return scl, nil
  475. }
  476. func (c *ScdParse) GetScdXmlObject(scdPath string) (*node_attr.SCL, error) {
  477. if scdid, h := global.GoCahce.Get(scdPath); h {
  478. //已经解析到内存中,则不再解析
  479. return c.GetScdXmlObjectBySCDID(tools.IsEmpty(scdid))
  480. }
  481. return nil, nil
  482. }
  483. func (c *ScdParse) GetScdXmlObjectBySCDID(scdid string) (*node_attr.SCL, error) {
  484. defer func() {
  485. //解析完成,解锁
  486. parseLock.Delete(scdid)
  487. }()
  488. waitTime := 0
  489. for {
  490. if waitTime > 5*60 {
  491. logger.Logger.Error(errors.New(fmt.Sprintf("等待SCD%s解析超时(大于5分钟)", scdid)))
  492. break
  493. }
  494. if _, h := parseLock.Load(scdid); !h {
  495. break
  496. }
  497. waitTime = waitTime + 1
  498. //当前scd正在解析,等待1秒后再检查
  499. time.Sleep(1 * time.Second)
  500. }
  501. if scl, h := global.GoCahce.Get(scdid); h {
  502. //已经解析到内存中,则不再解析
  503. global.CachedScdMap.Store(scdid, time.Now().Unix())
  504. return scl.(*node_attr.SCL), nil
  505. }
  506. parseLock.Store(scdid, 1)
  507. db := orm.NewOrm()
  508. sql := "select * from t_scd_scl where id=?"
  509. rowset := []orm.Params{}
  510. db.Raw(sql, scdid).Values(&rowset)
  511. if len(rowset) == 0 {
  512. logger.Logger.Error(errors.New(fmt.Sprintf("未在数据库中找到SCD%s的记录!", scdid)))
  513. return nil, nil
  514. }
  515. scdpath := tools.IsEmpty(rowset[0]["path"])
  516. enable := tools.IsEmpty(rowset[0]["enable"])
  517. enableInt, _ := strconv.Atoi(enable)
  518. err := c.XmlParse(
  519. tools.IsEmpty(rowset[0]["station_id"]),
  520. scdpath,
  521. tools.IsEmpty(rowset[0]["scd_name"]),
  522. enableInt,
  523. )
  524. if err == nil {
  525. scl, _ := global.GoCahce.Get(scdid)
  526. if scl == nil {
  527. logger.Logger.Error(errors.New(fmt.Sprintf("SCD%s已解析,但未在内存中找到缓存对象", scdid)))
  528. return nil, nil
  529. }
  530. global.CachedScdMap.Store(scdid, time.Now().Unix())
  531. return scl.(*node_attr.SCL), nil
  532. } else {
  533. logger.Logger.Error(err)
  534. }
  535. return nil, err
  536. }
  537. //获取指定的ICD对象
  538. func (c *ScdParse) GetIcdXmlObject(scdid, iedname string) (*node_attr.SCL, error) {
  539. key := fmt.Sprintf("icd_%s_%s", scdid, iedname)
  540. for {
  541. if _, h := parseLock.Load(key); !h {
  542. break
  543. }
  544. //当前scd正在解析,等待1秒后再检查
  545. time.Sleep(1 * time.Second)
  546. }
  547. if scl, h := global.GoCahce.Get(key); h {
  548. //已经解析到内存中,则不再解析
  549. return scl.(*node_attr.SCL), nil
  550. }
  551. parseLock.Store(key, 1)
  552. err := c.IcdParse(scdid, iedname)
  553. //解析完成,解锁
  554. parseLock.Delete(key)
  555. if err == nil {
  556. scl, _ := global.GoCahce.Get(key)
  557. return scl.(*node_attr.SCL), nil
  558. }
  559. return nil, err
  560. }
  561. //获取指定的CID对象
  562. func (c *ScdParse) GetCidXmlObject(scdid, iedname string) (*node_attr.SCL, error) {
  563. key := fmt.Sprintf("cid_%s_%s", scdid, iedname)
  564. for {
  565. if _, h := parseLock.Load(key); !h {
  566. break
  567. }
  568. //当前scd正在解析,等待1秒后再检查
  569. time.Sleep(1 * time.Second)
  570. }
  571. if scl, h := global.GoCahce.Get(key); h {
  572. //已经解析到内存中,则不再解析
  573. return scl.(*node_attr.SCL), nil
  574. }
  575. parseLock.Store(key, 1)
  576. err := c.IcdParse(scdid, iedname)
  577. //解析完成,解锁
  578. parseLock.Delete(key)
  579. if err == nil {
  580. scl, _ := global.GoCahce.Get(key)
  581. return scl.(*node_attr.SCL), nil
  582. }
  583. return nil, err
  584. }
  585. //缓存指定scd的节点ID与节点对象关联
  586. //主要缓存IED下的常用节点
  587. func (c *ScdParse) cacheGlobalNodeIds(scdid string, sclNodeObj *node_attr.SCL) {
  588. scdidint, _ := strconv.ParseInt(scdid, 10, 64)
  589. cachenode := NodeCacheMap{ParentNodeId: scdidint, ObjAddr: sclNodeObj}
  590. nodeidCacheMap := map[int64]NodeCacheMap{sclNodeObj.BaseNode.NodeId: cachenode}
  591. for i, ied := range sclNodeObj.IED {
  592. nodeidCacheMap[ied.NodeId] = NodeCacheMap{
  593. ParentNodeId: sclNodeObj.NodeId, //上级节点ID
  594. ObjAddr: sclNodeObj.IED[i], //缓存对象地址指针
  595. }
  596. for i1, pri := range ied.Priavate {
  597. nodeidCacheMap[pri.NodeId] = NodeCacheMap{
  598. ParentNodeId: ied.NodeId, //上级节点ID
  599. ObjAddr: ied.Priavate[i1], //缓存对象地址指针
  600. }
  601. }
  602. for i1, accp := range ied.AccessPoint {
  603. nodeidCacheMap[accp.NodeId] = NodeCacheMap{
  604. ParentNodeId: ied.NodeId, //上级节点ID
  605. ObjAddr: sclNodeObj.IED[i].AccessPoint[i1], //缓存对象地址指针
  606. }
  607. if accp.Server == nil {
  608. continue
  609. }
  610. nodeidCacheMap[accp.Server.NodeId] = NodeCacheMap{
  611. ParentNodeId: accp.NodeId, //上级节点ID
  612. ObjAddr: sclNodeObj.IED[i].AccessPoint[i1].Server, //缓存对象地址指针
  613. }
  614. for i2, ld := range accp.Server.LDevice {
  615. nodeidCacheMap[ld.NodeId] = NodeCacheMap{
  616. ParentNodeId: accp.Server.NodeId, //上级节点ID
  617. ObjAddr: sclNodeObj.IED[i].AccessPoint[i1].Server.LDevice[i2], //缓存LDevice对象地址指针
  618. }
  619. if ld.LN0 != nil {
  620. nodeidCacheMap[ld.LN0.NodeId] = NodeCacheMap{
  621. ParentNodeId: ld.NodeId, //上级节点ID
  622. ObjAddr: sclNodeObj.IED[i].AccessPoint[i1].Server.LDevice[i2].LN0, //缓存LN0对象地址指针
  623. }
  624. for i3, ds := range ld.LN0.DataSet {
  625. nodeidCacheMap[ds.NodeId] = NodeCacheMap{
  626. ParentNodeId: ld.LN0.NodeId, //上级节点ID
  627. ObjAddr: sclNodeObj.IED[i].AccessPoint[i1].Server.LDevice[i2].LN0.DataSet[i3], //缓存对象地址指针
  628. }
  629. for i4, fcda := range ds.FCDA {
  630. nodeidCacheMap[fcda.NodeId] = NodeCacheMap{
  631. ParentNodeId: ds.NodeId, //上级节点ID
  632. ObjAddr: sclNodeObj.IED[i].AccessPoint[i1].Server.LDevice[i2].LN0.DataSet[i3].FCDA[i4], //缓存对象地址指针
  633. }
  634. }
  635. }
  636. for i3, ds := range ld.LN0.GSEControl {
  637. nodeidCacheMap[ds.NodeId] = NodeCacheMap{
  638. ParentNodeId: ld.LN0.NodeId, //上级节点ID
  639. ObjAddr: sclNodeObj.IED[i].AccessPoint[i1].Server.LDevice[i2].LN0.GSEControl[i3], //缓存对象地址指针
  640. }
  641. }
  642. for i3, ds := range ld.LN0.SampledValueControl {
  643. nodeidCacheMap[ds.NodeId] = NodeCacheMap{
  644. ParentNodeId: ld.LN0.NodeId, //上级节点ID
  645. ObjAddr: sclNodeObj.IED[i].AccessPoint[i1].Server.LDevice[i2].LN0.SampledValueControl[i3], //缓存对象地址指针
  646. }
  647. }
  648. for i3, doi := range ld.LN0.DOI {
  649. nodeidCacheMap[doi.NodeId] = NodeCacheMap{
  650. ParentNodeId: ld.LN0.NodeId, //上级节点ID
  651. ObjAddr: sclNodeObj.IED[i].AccessPoint[i1].Server.LDevice[i2].LN0.DOI[i3], //缓存对象地址指针
  652. }
  653. }
  654. if ld.LN0.Inputs != nil {
  655. nodeidCacheMap[ld.LN0.Inputs.NodeId] = NodeCacheMap{
  656. ParentNodeId: ld.LN0.NodeId, //上级节点ID
  657. ObjAddr: sclNodeObj.IED[i].AccessPoint[i1].Server.LDevice[i2].LN0.Inputs, //缓存对象地址指针
  658. }
  659. for i3, ds := range ld.LN0.Inputs.ExtRef {
  660. nodeidCacheMap[ds.NodeId] = NodeCacheMap{
  661. ParentNodeId: ld.LN0.Inputs.NodeId, //上级节点ID
  662. ObjAddr: sclNodeObj.IED[i].AccessPoint[i1].Server.LDevice[i2].LN0.Inputs.ExtRef[i3], //缓存对象地址指针
  663. }
  664. }
  665. }
  666. }
  667. for i3, ln := range ld.LN {
  668. nodeidCacheMap[ln.NodeId] = NodeCacheMap{
  669. ParentNodeId: ld.NodeId, //上级节点ID
  670. ObjAddr: sclNodeObj.IED[i].AccessPoint[i1].Server.LDevice[i2].LN[i3], //缓存LN对象地址指针
  671. }
  672. for i4, doi := range ln.DOI {
  673. nodeidCacheMap[doi.NodeId] = NodeCacheMap{
  674. ParentNodeId: ld.LN[i3].NodeId, //上级节点ID
  675. ObjAddr: sclNodeObj.IED[i].AccessPoint[i1].Server.LDevice[i2].LN[i3].DOI[i4], //缓存DOI对象地址指针
  676. }
  677. }
  678. }
  679. }
  680. }
  681. }
  682. nodeidCacheMap[sclNodeObj.DataTypeTemplates.NodeId] = NodeCacheMap{
  683. ParentNodeId: sclNodeObj.NodeId, //上级节点ID
  684. ObjAddr: sclNodeObj.DataTypeTemplates, //缓存对象地址指针
  685. }
  686. GlobalNodeMap.Store(scdidint, nodeidCacheMap)
  687. }
  688. //解析SCD到内存中
  689. func (c *ScdParse) XmlParse(stationid, scdPath, scdName string, isenable int, autocompscdid ...int64) (err error) {
  690. if scdPath == "" || scdName == "" {
  691. return errors.New("无效的SCD名称")
  692. }
  693. logger.Logger.Debug("===开始解析SCD:" + scdName)
  694. c.SclModel = map[string]interface{}{}
  695. fileFirstChar := scdPath[0:1]
  696. fline := string(os.PathSeparator)
  697. if fileFirstChar != "." && fileFirstChar != "G" {
  698. if fileFirstChar == fline {
  699. scdPath = "." + scdPath
  700. } else {
  701. scdPath = "." + fline + scdPath
  702. }
  703. }
  704. //判断该scd是否已经存在,已存在则不再解析
  705. db := orm.NewOrm()
  706. sql := "select id from t_scd_scl where scd_name=? and path=?"
  707. rowset := []orm.Params{}
  708. db.Raw(sql, scdName, scdPath).Values(&rowset)
  709. scdid := ""
  710. if len(rowset) > 0 {
  711. scdid = tools.IsEmpty(rowset[0]["id"])
  712. if _, h := global.GoCahce.Get(scdid); h {
  713. //已经解析到内存中,则不再解析
  714. return nil
  715. } else {
  716. db.Raw("update t_scd_scl set enable=? where id=?", isenable, scdid).Exec()
  717. //判断是否有解析完成的持久化文件
  718. parsedFile := strings.ReplaceAll(scdPath, "\\", "/") + ".parsed.xml"
  719. f, err := os.Stat(parsedFile)
  720. logger.Logger.Debug(fmt.Sprintf("%s:%+v ====== %+v", parsedFile, f, err))
  721. if f != nil || os.IsExist(err) {
  722. logger.Logger.Debug("=====结果文件" + scdPath + ".parsed.xml已存在,直接加载")
  723. data := map[string]string{"name": scdName, "stationid": stationid, "rootid": "", "state": "0", "node": "load-file", "msg": ""}
  724. dataMsg, _ := json.Marshal(data)
  725. mqtt.PublishMessage(fmt.Sprintf("/jujutong/scd_check_tools/parse/%s", stationid), string(dataMsg))
  726. sclNodeObj, err := c.LoadScdXml(scdPath + ".parsed.xml")
  727. if err == nil {
  728. global.GoCahce.Set(scdPath, scdid, -1)
  729. global.GoCahce.Set(scdid, sclNodeObj, -1)
  730. data := map[string]string{"name": scdName, "stationid": stationid, "rootid": "", "state": "1", "node": "load-file", "msg": ""}
  731. dataMsg, _ := json.Marshal(data)
  732. mqtt.PublishMessage(fmt.Sprintf("/jujutong/scd_check_tools/parse/%s", stationid), string(dataMsg))
  733. c.cacheGlobalNodeIds(scdid, sclNodeObj)
  734. //crc提取
  735. //go new(ScdMgr).CrcCheck(scdid)
  736. //开始校验该SCD
  737. //go c.SchemaValid(scdid, scdName, scdPath)
  738. } else {
  739. logger.Logger.Error(err, "异常SCD文件:"+scdPath)
  740. return err
  741. }
  742. return nil
  743. } else {
  744. //没有缓存,也没有解析结果文件,则重新解析
  745. logger.Logger.Debug("=====没有缓存及结果文件,全新解析:" + scdPath)
  746. }
  747. }
  748. }
  749. //判断当前服务器性能是否达到阀值
  750. canparse, msg := new(ScdMgr).CheckParseMaxLimit()
  751. if canparse {
  752. return errors.New("系统繁忙:" + msg + ",请稍候(约5分钟)再试")
  753. }
  754. logger.Logger.Debug(fmt.Sprintf("=======开始加载解析SCD:%s", scdName))
  755. data := map[string]string{"name": scdName, "stationid": stationid, "rootid": "", "state": "0", "node": "load-file", "msg": ""}
  756. dataMsg, _ := json.Marshal(data)
  757. mqtt.PublishMessage(fmt.Sprintf("/jujutong/scd_check_tools/parse/%s", stationid), string(dataMsg))
  758. //新解析scd,先进行文件格式化。搞成一行一行的
  759. node_cnt, err2 := c.ForamtScdPath(scdPath)
  760. if err2 != nil {
  761. //解除该站的签入锁定,如果是签入解析
  762. new(Flow).CheckInFail(stationid)
  763. mqtt.PublishMessage(fmt.Sprintf("/jujutong/scd_check_tools/parse/%s/%d/error", stationid, 0), scdName+"解析时发生错误,解析终止!")
  764. logger.Logger.Error(err2, "异常SCD文件:"+scdPath)
  765. return err2
  766. }
  767. sclNodeObj, err := c.LoadScdXml(scdPath)
  768. if err != nil {
  769. //解除该站的签入锁定,如果是签入解析
  770. new(Flow).CheckInFail(stationid)
  771. mqtt.PublishMessage(fmt.Sprintf("/jujutong/scd_check_tools/parse/%s/%d/error", stationid, 0), scdName+"解析时发生错误,解析终止!")
  772. logger.Logger.Error(err, "异常SCD文件:"+scdPath)
  773. return err
  774. }
  775. iedList := []string{}
  776. isBay := false //是否有间隔节点
  777. bayList := []*node_attr.NVoltage{}
  778. iedlist := []*node_attr.NIED{}
  779. scdmgr := new(ScdNode)
  780. scdmgr.SetUserInfo(c.GetUserInfo())
  781. scdmgr.Idseq = c.Idseq //初始化节点管理对象的ID序列
  782. if scdid == "" {
  783. scdmgr.RootID = scdmgr.GetID()
  784. } else {
  785. scdmgr.RootID, _ = strconv.ParseInt(scdid, 10, 64)
  786. }
  787. var calNodeAnyLineNumber = func(lst []*node_attr.NAny) int64 {
  788. lineno := 0
  789. for _, any1 := range lst {
  790. lineno = lineno + 1
  791. if len(any1.Any) > 0 {
  792. for _, any2 := range any1.Any {
  793. lineno = lineno + 1
  794. if len(any2.Any) > 0 {
  795. for range any2.Any {
  796. lineno = lineno + 1
  797. }
  798. lineno = lineno + 1
  799. }
  800. }
  801. lineno = lineno + 1
  802. }
  803. }
  804. return int64(lineno)
  805. }
  806. lineno := int64(1)
  807. //生成节点行号及ID
  808. lineno = lineno + 1
  809. sclNodeObj.BaseNode.Lineno = lineno
  810. sclNodeObj.BaseNode.NodeId = scdmgr.RootID + sclNodeObj.BaseNode.Lineno
  811. for i, _ := range sclNodeObj.Private {
  812. lineno = lineno + 1
  813. sclNodeObj.Private[i].BaseNode.Lineno = lineno
  814. sclNodeObj.Private[i].BaseNode.NodeId = scdmgr.RootID + lineno
  815. //电压级及间隔分析
  816. if len(sclNodeObj.Private[i].Voltage) > 0 {
  817. for v1, _ := range sclNodeObj.Private[i].Voltage {
  818. lineno = lineno + 1
  819. sclNodeObj.Private[i].Voltage[v1].BaseNode.Lineno = lineno
  820. sclNodeObj.Private[i].Voltage[v1].BaseNode.NodeId = scdmgr.RootID + lineno
  821. if len(sclNodeObj.Private[i].Voltage[v1].Bay) > 0 {
  822. isBay = true
  823. bayList = sclNodeObj.Private[i].Voltage
  824. for bayi, _ := range sclNodeObj.Private[i].Voltage[v1].Bay {
  825. lineno = lineno + 1
  826. sclNodeObj.Private[i].Voltage[v1].Bay[bayi].BaseNode.Lineno = lineno
  827. sclNodeObj.Private[i].Voltage[v1].Bay[bayi].BaseNode.NodeId = scdmgr.RootID + lineno
  828. if len(sclNodeObj.Private[i].Voltage[v1].Bay[bayi].IED) > 0 {
  829. for iedi, _ := range sclNodeObj.Private[i].Voltage[v1].Bay[bayi].IED {
  830. lineno = lineno + 1
  831. sclNodeObj.Private[i].Voltage[v1].Bay[bayi].IED[iedi].BaseNode.Lineno = lineno
  832. sclNodeObj.Private[i].Voltage[v1].Bay[bayi].IED[iedi].BaseNode.NodeId = scdmgr.RootID + lineno
  833. }
  834. lineno = lineno + 1 //多加一行</Bay>
  835. }
  836. }
  837. lineno = lineno + 1 //多加一行</Voltage>
  838. }
  839. }
  840. lineno = lineno + 1 //多加一行</Private>
  841. }
  842. if len(sclNodeObj.Private[i].Any) > 0 {
  843. lineno = lineno + calNodeAnyLineNumber(sclNodeObj.Private[i].Any)
  844. lineno = lineno + 1
  845. }
  846. }
  847. if sclNodeObj.Header != nil {
  848. lineno = lineno + 1
  849. sclNodeObj.Header.BaseNode.Lineno = lineno
  850. sclNodeObj.Header.BaseNode.NodeId = scdmgr.RootID + lineno
  851. if sclNodeObj.Header.History != nil {
  852. lineno = lineno + 1
  853. sclNodeObj.Header.History.BaseNode.Lineno = lineno
  854. sclNodeObj.Header.History.BaseNode.NodeId = scdmgr.RootID + lineno
  855. if len(sclNodeObj.Header.History.Hitem) > 0 {
  856. for i, _ := range sclNodeObj.Header.History.Hitem {
  857. lineno = lineno + 1
  858. sclNodeObj.Header.History.Hitem[i].BaseNode.Lineno = lineno
  859. sclNodeObj.Header.History.Hitem[i].BaseNode.NodeId = scdmgr.RootID + lineno
  860. }
  861. lineno = lineno + 1 //多加一行</History>
  862. }
  863. lineno = lineno + 1
  864. }
  865. }
  866. if sclNodeObj.Substation != nil {
  867. lineno = lineno + 1
  868. sclNodeObj.Substation.BaseNode.Lineno = lineno
  869. sclNodeObj.Substation.BaseNode.NodeId = scdmgr.RootID + lineno
  870. isEmptyNode := true
  871. if len(sclNodeObj.Substation.Private) > 0 {
  872. isEmptyNode = false
  873. for i1, _ := range sclNodeObj.Substation.Private {
  874. lineno = lineno + 1
  875. sclNodeObj.Substation.Private[i1].BaseNode.Lineno = lineno
  876. sclNodeObj.Substation.Private[i1].BaseNode.NodeId = scdmgr.RootID + lineno
  877. if len(sclNodeObj.Substation.Private[i1].Any) > 0 {
  878. anyLines := calNodeAnyLineNumber(sclNodeObj.Substation.Private[i1].Any)
  879. lineno = lineno + anyLines
  880. lineno = lineno + 1 //多加一行Priavate
  881. }
  882. }
  883. }
  884. if len(sclNodeObj.Substation.Any) > 0 {
  885. isEmptyNode = false
  886. anyLines := calNodeAnyLineNumber(sclNodeObj.Substation.Any)
  887. lineno = lineno + anyLines
  888. }
  889. if len(sclNodeObj.Substation.VoltageLevel) > 0 {
  890. isEmptyNode = false
  891. for i1, _ := range sclNodeObj.Substation.VoltageLevel {
  892. lineno = lineno + 1
  893. sclNodeObj.Substation.VoltageLevel[i1].BaseNode.Lineno = lineno
  894. sclNodeObj.Substation.VoltageLevel[i1].BaseNode.NodeId = scdmgr.RootID + lineno
  895. isEmptyNode := true
  896. if len(sclNodeObj.Substation.VoltageLevel[i1].Bay) > 0 {
  897. isEmptyNode = false
  898. for b1, _ := range sclNodeObj.Substation.VoltageLevel[i1].Bay {
  899. lineno = lineno + 1
  900. if len(sclNodeObj.Substation.VoltageLevel[i1].Bay[b1].Any) > 0 {
  901. anyLines := calNodeAnyLineNumber(sclNodeObj.Substation.VoltageLevel[i1].Bay[b1].Any)
  902. lineno = lineno + anyLines
  903. }
  904. }
  905. }
  906. if sclNodeObj.Substation.VoltageLevel[i1].Voltage != nil {
  907. isEmptyNode = false
  908. lineno = lineno + 1
  909. if len(sclNodeObj.Substation.VoltageLevel[i1].Voltage.Any) > 0 {
  910. anyLines := calNodeAnyLineNumber(sclNodeObj.Substation.VoltageLevel[i1].Voltage.Any)
  911. lineno = lineno + anyLines
  912. }
  913. }
  914. if len(sclNodeObj.Substation.VoltageLevel[i1].Any) > 0 {
  915. isEmptyNode = false
  916. anyLines := calNodeAnyLineNumber(sclNodeObj.Substation.VoltageLevel[i1].Any)
  917. lineno = lineno + anyLines
  918. }
  919. if !isEmptyNode {
  920. lineno = lineno + 1 //多加一行VoltageLevel
  921. }
  922. }
  923. }
  924. if !isEmptyNode {
  925. lineno = lineno + 1
  926. }
  927. }
  928. if sclNodeObj.Communication != nil {
  929. lineno = lineno + 1
  930. sclNodeObj.Communication.BaseNode.Lineno = lineno
  931. sclNodeObj.Communication.BaseNode.NodeId = scdmgr.RootID + lineno
  932. if sclNodeObj.Communication.SubNetwork != nil {
  933. for i, item := range sclNodeObj.Communication.SubNetwork {
  934. lineno = lineno + 1
  935. sclNodeObj.Communication.SubNetwork[i].BaseNode.Lineno = lineno
  936. sclNodeObj.Communication.SubNetwork[i].BaseNode.NodeId = scdmgr.RootID + lineno
  937. if sclNodeObj.Communication.SubNetwork[i].BitRate != nil {
  938. lineno = lineno + 1
  939. sclNodeObj.Communication.SubNetwork[i].BitRate.BaseNode.Lineno = lineno
  940. sclNodeObj.Communication.SubNetwork[i].BitRate.BaseNode.NodeId = scdmgr.RootID + lineno
  941. }
  942. for i2, item2 := range item.ConnectedAP {
  943. lineno = lineno + 1
  944. item.ConnectedAP[i2].BaseNode.Lineno = lineno
  945. item.ConnectedAP[i2].BaseNode.NodeId = scdmgr.RootID + lineno
  946. if len(item2.Private) > 0 {
  947. for p1, _ := range item2.Private {
  948. lineno = lineno + 1
  949. item.ConnectedAP[i2].Private[p1].BaseNode.Lineno = lineno
  950. item.ConnectedAP[i2].Private[p1].BaseNode.NodeId = scdmgr.RootID + lineno
  951. if len(item.ConnectedAP[i2].Private[p1].Any) > 0 {
  952. lineno = lineno + calNodeAnyLineNumber(item.ConnectedAP[i2].Private[p1].Any)
  953. lineno = lineno + 1
  954. }
  955. }
  956. }
  957. if item2.Address != nil {
  958. lineno = lineno + 1
  959. item.ConnectedAP[i2].Address.BaseNode.Lineno = lineno
  960. item.ConnectedAP[i2].Address.BaseNode.NodeId = scdmgr.RootID + lineno
  961. for i3, _ := range item2.Address.P {
  962. lineno = lineno + 1
  963. item2.Address.P[i3].BaseNode.Lineno = lineno
  964. item2.Address.P[i3].BaseNode.NodeId = scdmgr.RootID + lineno
  965. }
  966. lineno = lineno + 1 //多加一行
  967. }
  968. if len(item2.GSE) > 0 {
  969. for i3, _ := range item2.GSE {
  970. lineno = lineno + 1
  971. item2.GSE[i3].BaseNode.Lineno = lineno
  972. item2.GSE[i3].BaseNode.NodeId = scdmgr.RootID + lineno
  973. if item2.GSE[i3].Address != nil || item2.GSE[i3].MinTime != nil || item2.GSE[i3].MaxTime != nil {
  974. if item2.GSE[i3].Address != nil {
  975. lineno = lineno + 1
  976. item2.GSE[i3].Address.BaseNode.Lineno = lineno
  977. item2.GSE[i3].Address.BaseNode.NodeId = scdmgr.RootID + lineno
  978. for i4, _ := range item2.GSE[i3].Address.P {
  979. lineno = lineno + 1
  980. item2.GSE[i3].Address.P[i4].BaseNode.Lineno = lineno
  981. item2.GSE[i3].Address.P[i4].BaseNode.NodeId = scdmgr.RootID + lineno
  982. }
  983. lineno = lineno + 1 //多加一行
  984. }
  985. if item2.GSE[i3].MinTime != nil {
  986. lineno = lineno + 1
  987. item2.GSE[i3].MinTime.BaseNode.Lineno = lineno
  988. item2.GSE[i3].MinTime.BaseNode.NodeId = scdmgr.RootID + lineno
  989. }
  990. if item2.GSE[i3].MaxTime != nil {
  991. lineno = lineno + 1
  992. item2.GSE[i3].MaxTime.BaseNode.Lineno = lineno
  993. item2.GSE[i3].MaxTime.BaseNode.NodeId = scdmgr.RootID + lineno
  994. }
  995. lineno = lineno + 1 //多加一行
  996. }
  997. }
  998. }
  999. if len(item2.SMV) > 0 {
  1000. for i, item3 := range item2.SMV {
  1001. lineno = lineno + 1
  1002. item2.SMV[i].BaseNode.Lineno = lineno
  1003. item2.SMV[i].BaseNode.NodeId = scdmgr.RootID + lineno
  1004. isEmptyNode := true
  1005. if item3.Address != nil {
  1006. isEmptyNode = false
  1007. lineno = lineno + 1
  1008. item2.SMV[i].Address.BaseNode.Lineno = lineno
  1009. item2.SMV[i].Address.BaseNode.NodeId = scdmgr.RootID + lineno
  1010. for i1, _ := range item3.Address.P {
  1011. lineno = lineno + 1
  1012. item3.Address.P[i1].BaseNode.Lineno = lineno
  1013. item3.Address.P[i1].BaseNode.NodeId = scdmgr.RootID + lineno
  1014. }
  1015. if len(item3.Address.P) > 0 {
  1016. lineno = lineno + 1 //多加一行Address
  1017. }
  1018. }
  1019. if item2.SMV[i].MinTime != nil {
  1020. isEmptyNode = false
  1021. lineno = lineno + 1
  1022. item2.SMV[i].MinTime.BaseNode.Lineno = lineno
  1023. item2.SMV[i].MinTime.BaseNode.NodeId = scdmgr.RootID + lineno
  1024. }
  1025. if item2.SMV[i].MaxTime != nil {
  1026. isEmptyNode = false
  1027. lineno = lineno + 1
  1028. item2.SMV[i].MaxTime.BaseNode.Lineno = lineno
  1029. item2.SMV[i].MaxTime.BaseNode.NodeId = scdmgr.RootID + lineno
  1030. }
  1031. if !isEmptyNode {
  1032. lineno = lineno + 1 //多加一行SMV
  1033. }
  1034. }
  1035. }
  1036. if len(item2.PhysConn) > 0 {
  1037. for i, item3 := range item2.PhysConn {
  1038. lineno = lineno + 1
  1039. item2.PhysConn[i].BaseNode.Lineno = lineno
  1040. item2.PhysConn[i].BaseNode.NodeId = scdmgr.RootID + lineno
  1041. if len(item3.P) > 0 {
  1042. for i1, _ := range item3.P {
  1043. lineno = lineno + 1
  1044. item3.P[i1].BaseNode.Lineno = lineno
  1045. item3.P[i1].BaseNode.NodeId = scdmgr.RootID + lineno
  1046. }
  1047. lineno = lineno + 1 //多加一行
  1048. }
  1049. }
  1050. }
  1051. if item2.Address != nil || len(item2.GSE) > 0 || len(item2.SMV) > 0 || len(item2.PhysConn) > 0 {
  1052. lineno = lineno + 1 //多加一行
  1053. }
  1054. }
  1055. if len(item.ConnectedAP) > 0 || item.BitRate != nil {
  1056. lineno = lineno + 1 //多加一行:SubNetwork
  1057. }
  1058. }
  1059. lineno = lineno + 1 //多加一行:Communication
  1060. }
  1061. }
  1062. for i, item := range sclNodeObj.IED {
  1063. lineno = lineno + 1
  1064. sclNodeObj.IED[i].BaseNode.Lineno = lineno
  1065. sclNodeObj.IED[i].BaseNode.NodeId = scdmgr.RootID + lineno
  1066. iedList = append(iedList, fmt.Sprintf("(%d,%d,'%s','%s',%d)", sclNodeObj.IED[i].BaseNode.NodeId, scdmgr.RootID, "IED", item.Name, lineno))
  1067. if !isBay {
  1068. //非bay模式时,记录所有的IED节点
  1069. iedlist = append(iedlist, sclNodeObj.IED[i])
  1070. }
  1071. if item.Priavate != nil {
  1072. for i1, _ := range item.Priavate {
  1073. lineno = lineno + 1
  1074. item.Priavate[i1].BaseNode.Lineno = lineno
  1075. item.Priavate[i1].BaseNode.NodeId = scdmgr.RootID + lineno
  1076. if len(item.Priavate[i1].Any) > 0 {
  1077. anyLines := calNodeAnyLineNumber(item.Priavate[i1].Any)
  1078. lineno = lineno + anyLines
  1079. lineno = lineno + 1 //多加一行Priavate
  1080. }
  1081. }
  1082. }
  1083. if sclNodeObj.IED[i].Services == nil {
  1084. logger.Logger.Error(errors.New(fmt.Sprintf("%s中未发现Services定义", sclNodeObj.IED[i].Desc)))
  1085. } else {
  1086. lineno = lineno + 1
  1087. sclNodeObj.IED[i].Services.BaseNode.Lineno = lineno
  1088. sclNodeObj.IED[i].Services.BaseNode.NodeId = scdmgr.RootID + lineno
  1089. if sclNodeObj.IED[i].Services.DynAssociation != nil {
  1090. lineno = lineno + 1
  1091. sclNodeObj.IED[i].Services.DynAssociation.BaseNode.Lineno = lineno
  1092. sclNodeObj.IED[i].Services.DynAssociation.BaseNode.NodeId = scdmgr.RootID + lineno
  1093. }
  1094. if sclNodeObj.IED[i].Services.SettingGroups != nil {
  1095. lineno = lineno + 1
  1096. sclNodeObj.IED[i].Services.SettingGroups.BaseNode.Lineno = lineno
  1097. sclNodeObj.IED[i].Services.SettingGroups.BaseNode.NodeId = scdmgr.RootID + lineno
  1098. if sclNodeObj.IED[i].Services.SettingGroups.SGEdit != nil || sclNodeObj.IED[i].Services.SettingGroups.ConfSG != nil {
  1099. if sclNodeObj.IED[i].Services.SettingGroups.SGEdit != nil {
  1100. lineno = lineno + 1
  1101. sclNodeObj.IED[i].Services.SettingGroups.SGEdit.BaseNode.Lineno = lineno
  1102. sclNodeObj.IED[i].Services.SettingGroups.SGEdit.BaseNode.NodeId = scdmgr.RootID + lineno
  1103. }
  1104. if sclNodeObj.IED[i].Services.SettingGroups.ConfSG != nil {
  1105. lineno = lineno + 1
  1106. sclNodeObj.IED[i].Services.SettingGroups.ConfSG.BaseNode.Lineno = lineno
  1107. sclNodeObj.IED[i].Services.SettingGroups.ConfSG.BaseNode.NodeId = scdmgr.RootID + lineno
  1108. }
  1109. lineno = lineno + 1 //多加一行</SettingGroups>
  1110. }
  1111. }
  1112. if sclNodeObj.IED[i].Services.GetDirectory != nil {
  1113. lineno = lineno + 1
  1114. sclNodeObj.IED[i].Services.GetDirectory.BaseNode.Lineno = lineno
  1115. sclNodeObj.IED[i].Services.GetDirectory.BaseNode.NodeId = scdmgr.RootID + lineno
  1116. }
  1117. if sclNodeObj.IED[i].Services.GetDataObjectDefinition != nil {
  1118. lineno = lineno + 1
  1119. sclNodeObj.IED[i].Services.GetDataObjectDefinition.BaseNode.Lineno = lineno
  1120. sclNodeObj.IED[i].Services.GetDataObjectDefinition.BaseNode.NodeId = scdmgr.RootID + lineno
  1121. }
  1122. if sclNodeObj.IED[i].Services.DataObjectDirectory != nil {
  1123. lineno = lineno + 1
  1124. sclNodeObj.IED[i].Services.DataObjectDirectory.BaseNode.Lineno = lineno
  1125. sclNodeObj.IED[i].Services.DataObjectDirectory.BaseNode.NodeId = scdmgr.RootID + lineno
  1126. }
  1127. if sclNodeObj.IED[i].Services.GetDataSetValue != nil {
  1128. lineno = lineno + 1
  1129. sclNodeObj.IED[i].Services.GetDataSetValue.BaseNode.Lineno = lineno
  1130. sclNodeObj.IED[i].Services.GetDataSetValue.BaseNode.NodeId = scdmgr.RootID + lineno
  1131. }
  1132. if sclNodeObj.IED[i].Services.SetDataSetValue != nil {
  1133. lineno = lineno + 1
  1134. sclNodeObj.IED[i].Services.SetDataSetValue.BaseNode.Lineno = lineno
  1135. sclNodeObj.IED[i].Services.SetDataSetValue.BaseNode.NodeId = scdmgr.RootID + lineno
  1136. }
  1137. if sclNodeObj.IED[i].Services.DataSetDirectory != nil {
  1138. lineno = lineno + 1
  1139. sclNodeObj.IED[i].Services.DataSetDirectory.BaseNode.Lineno = lineno
  1140. sclNodeObj.IED[i].Services.DataSetDirectory.BaseNode.NodeId = scdmgr.RootID + lineno
  1141. }
  1142. if sclNodeObj.IED[i].Services.ConfDataSet != nil {
  1143. lineno = lineno + 1
  1144. sclNodeObj.IED[i].Services.ConfDataSet.BaseNode.Lineno = lineno
  1145. sclNodeObj.IED[i].Services.ConfDataSet.BaseNode.NodeId = scdmgr.RootID + lineno
  1146. }
  1147. if sclNodeObj.IED[i].Services.DynDataSet != nil {
  1148. lineno = lineno + 1
  1149. sclNodeObj.IED[i].Services.DynDataSet.BaseNode.Lineno = lineno
  1150. sclNodeObj.IED[i].Services.DynDataSet.BaseNode.NodeId = scdmgr.RootID + lineno
  1151. }
  1152. if sclNodeObj.IED[i].Services.ReadWrite != nil {
  1153. lineno = lineno + 1
  1154. sclNodeObj.IED[i].Services.ReadWrite.BaseNode.Lineno = lineno
  1155. sclNodeObj.IED[i].Services.ReadWrite.BaseNode.NodeId = scdmgr.RootID + lineno
  1156. }
  1157. if sclNodeObj.IED[i].Services.TimerActivatedControl != nil {
  1158. lineno = lineno + 1
  1159. sclNodeObj.IED[i].Services.TimerActivatedControl.BaseNode.Lineno = lineno
  1160. sclNodeObj.IED[i].Services.TimerActivatedControl.BaseNode.NodeId = scdmgr.RootID + lineno
  1161. }
  1162. if sclNodeObj.IED[i].Services.ConfReportControl != nil {
  1163. lineno = lineno + 1
  1164. sclNodeObj.IED[i].Services.ConfReportControl.BaseNode.Lineno = lineno
  1165. sclNodeObj.IED[i].Services.ConfReportControl.BaseNode.NodeId = scdmgr.RootID + lineno
  1166. }
  1167. if sclNodeObj.IED[i].Services.GetCBValues != nil {
  1168. lineno = lineno + 1
  1169. sclNodeObj.IED[i].Services.GetCBValues.BaseNode.Lineno = lineno
  1170. sclNodeObj.IED[i].Services.GetCBValues.BaseNode.NodeId = scdmgr.RootID + lineno
  1171. }
  1172. if sclNodeObj.IED[i].Services.ConfLogControl != nil {
  1173. lineno = lineno + 1
  1174. sclNodeObj.IED[i].Services.ConfLogControl.BaseNode.Lineno = lineno
  1175. sclNodeObj.IED[i].Services.ConfLogControl.BaseNode.NodeId = scdmgr.RootID + lineno
  1176. }
  1177. if sclNodeObj.IED[i].Services.ReportSettings != nil {
  1178. lineno = lineno + 1
  1179. sclNodeObj.IED[i].Services.ReportSettings.BaseNode.Lineno = lineno
  1180. sclNodeObj.IED[i].Services.ReportSettings.BaseNode.NodeId = scdmgr.RootID + lineno
  1181. }
  1182. if sclNodeObj.IED[i].Services.LogSettings != nil {
  1183. lineno = lineno + 1
  1184. sclNodeObj.IED[i].Services.LogSettings.BaseNode.Lineno = lineno
  1185. sclNodeObj.IED[i].Services.LogSettings.BaseNode.NodeId = scdmgr.RootID + lineno
  1186. }
  1187. if sclNodeObj.IED[i].Services.GSESettings != nil {
  1188. lineno = lineno + 1
  1189. sclNodeObj.IED[i].Services.GSESettings.BaseNode.Lineno = lineno
  1190. sclNodeObj.IED[i].Services.GSESettings.BaseNode.NodeId = scdmgr.RootID + lineno
  1191. }
  1192. if sclNodeObj.IED[i].Services.SMVSettings != nil {
  1193. lineno = lineno + 1
  1194. sclNodeObj.IED[i].Services.SMVSettings.BaseNode.Lineno = lineno
  1195. sclNodeObj.IED[i].Services.SMVSettings.BaseNode.NodeId = scdmgr.RootID + lineno
  1196. if sclNodeObj.IED[i].Services.SMVSettings.SmpRateObj != nil {
  1197. lineno = lineno + 1
  1198. sclNodeObj.IED[i].Services.SMVSettings.SmpRateObj.BaseNode.Lineno = lineno
  1199. sclNodeObj.IED[i].Services.SMVSettings.SmpRateObj.BaseNode.NodeId = scdmgr.RootID + lineno
  1200. lineno = lineno + 1 //多加一行</SettingGroups>
  1201. }
  1202. }
  1203. if sclNodeObj.IED[i].Services.GSEDir != nil {
  1204. lineno = lineno + 1
  1205. sclNodeObj.IED[i].Services.GSEDir.BaseNode.Lineno = lineno
  1206. sclNodeObj.IED[i].Services.GSEDir.BaseNode.NodeId = scdmgr.RootID + lineno
  1207. }
  1208. if sclNodeObj.IED[i].Services.GOOSE != nil {
  1209. lineno = lineno + 1
  1210. sclNodeObj.IED[i].Services.GOOSE.BaseNode.Lineno = lineno
  1211. sclNodeObj.IED[i].Services.GOOSE.BaseNode.NodeId = scdmgr.RootID + lineno
  1212. }
  1213. if sclNodeObj.IED[i].Services.GSSE != nil {
  1214. lineno = lineno + 1
  1215. sclNodeObj.IED[i].Services.GSSE.BaseNode.Lineno = lineno
  1216. sclNodeObj.IED[i].Services.GSSE.BaseNode.NodeId = scdmgr.RootID + lineno
  1217. }
  1218. if sclNodeObj.IED[i].Services.SMV != nil {
  1219. lineno = lineno + 1
  1220. sclNodeObj.IED[i].Services.SMV.BaseNode.Lineno = lineno
  1221. sclNodeObj.IED[i].Services.SMV.BaseNode.NodeId = scdmgr.RootID + lineno
  1222. }
  1223. if sclNodeObj.IED[i].Services.FileHandling != nil {
  1224. lineno = lineno + 1
  1225. sclNodeObj.IED[i].Services.FileHandling.BaseNode.Lineno = lineno
  1226. sclNodeObj.IED[i].Services.FileHandling.BaseNode.NodeId = scdmgr.RootID + lineno
  1227. }
  1228. if sclNodeObj.IED[i].Services.ConfLNs != nil {
  1229. lineno = lineno + 1
  1230. sclNodeObj.IED[i].Services.ConfLNs.BaseNode.Lineno = lineno
  1231. sclNodeObj.IED[i].Services.ConfLNs.BaseNode.NodeId = scdmgr.RootID + lineno
  1232. }
  1233. if sclNodeObj.IED[i].Services.ClientServices != nil {
  1234. lineno = lineno + 1
  1235. sclNodeObj.IED[i].Services.ClientServices.BaseNode.Lineno = lineno
  1236. sclNodeObj.IED[i].Services.ClientServices.BaseNode.NodeId = scdmgr.RootID + lineno
  1237. }
  1238. lineno = lineno + 1 //多加一行</Services>
  1239. }
  1240. for i1, item2 := range item.AccessPoint {
  1241. lineno = lineno + 1
  1242. item.AccessPoint[i1].BaseNode.Lineno = lineno
  1243. item.AccessPoint[i1].BaseNode.NodeId = scdmgr.RootID + lineno
  1244. if len(item.AccessPoint[i1].Any) > 0 {
  1245. lineno = lineno + calNodeAnyLineNumber(item.AccessPoint[i1].Any)
  1246. }
  1247. if item.AccessPoint[i1].Priavate != nil {
  1248. lineno = lineno + 1
  1249. item.AccessPoint[i1].Priavate.BaseNode.Lineno = lineno
  1250. item.AccessPoint[i1].Priavate.BaseNode.NodeId = scdmgr.RootID + lineno
  1251. if len(item.AccessPoint[i1].Priavate.Any) > 0 {
  1252. lineno = lineno + calNodeAnyLineNumber(item.AccessPoint[i1].Priavate.Any)
  1253. lineno = lineno + 1
  1254. }
  1255. }
  1256. if item.AccessPoint[i1].Server != nil {
  1257. lineno = lineno + 1
  1258. item.AccessPoint[i1].Server.BaseNode.Lineno = lineno
  1259. item.AccessPoint[i1].Server.BaseNode.NodeId = scdmgr.RootID + lineno
  1260. //if len(item.AccessPoint[i1].Server.Private) > 0 {
  1261. //fmt.Println(fmt.Sprintf("=======%s item.AccessPoint[i1].Server.Private:%d", item.Name, len(item.AccessPoint[i1].Server.Private)))
  1262. //}
  1263. for i300, _ := range item.AccessPoint[i1].Server.Private {
  1264. lineno = lineno + 1
  1265. item.AccessPoint[i1].Server.Private[i300].BaseNode.Lineno = lineno
  1266. item.AccessPoint[i1].Server.Private[i300].BaseNode.NodeId = scdmgr.RootID + lineno
  1267. if len(item.AccessPoint[i1].Server.Private[i300].Any) > 0 {
  1268. lineno = lineno + calNodeAnyLineNumber(item.AccessPoint[i1].Server.Private[i300].Any)
  1269. lineno = lineno + 1
  1270. }
  1271. }
  1272. if item.AccessPoint[i1].Server.Authentication != nil {
  1273. lineno = lineno + 1
  1274. item.AccessPoint[i1].Server.Authentication.BaseNode.Lineno = lineno
  1275. item.AccessPoint[i1].Server.Authentication.BaseNode.NodeId = scdmgr.RootID + lineno
  1276. }
  1277. for i2, item3 := range item2.Server.LDevice {
  1278. lineno = lineno + 1
  1279. item2.Server.LDevice[i2].BaseNode.Lineno = lineno
  1280. item2.Server.LDevice[i2].BaseNode.NodeId = scdmgr.RootID + lineno
  1281. if item3.LN0 != nil {
  1282. lineno = lineno + 1
  1283. item2.Server.LDevice[i2].LN0.BaseNode.Lineno = lineno
  1284. item2.Server.LDevice[i2].LN0.BaseNode.NodeId = scdmgr.RootID + lineno
  1285. isEmptyNode := true //是否是空节点
  1286. if item3.LN0.DataSet != nil {
  1287. isEmptyNode = false
  1288. for i3, item4 := range item3.LN0.DataSet {
  1289. lineno = lineno + 1
  1290. item3.LN0.DataSet[i3].BaseNode.Lineno = lineno
  1291. item3.LN0.DataSet[i3].BaseNode.NodeId = scdmgr.RootID + lineno
  1292. for i4, _ := range item4.FCDA {
  1293. lineno = lineno + 1
  1294. item4.FCDA[i4].BaseNode.Lineno = lineno
  1295. item4.FCDA[i4].BaseNode.NodeId = scdmgr.RootID + lineno
  1296. }
  1297. for i4, _ := range item4.FCCB {
  1298. lineno = lineno + 1
  1299. item4.FCCB[i4].BaseNode.Lineno = lineno
  1300. item4.FCCB[i4].BaseNode.NodeId = scdmgr.RootID + lineno
  1301. }
  1302. lineno = lineno + 1 //多加一行
  1303. }
  1304. }
  1305. if item3.LN0.ReportControl != nil {
  1306. isEmptyNode = false
  1307. for i3, item4 := range item3.LN0.ReportControl {
  1308. lineno = lineno + 1
  1309. item3.LN0.ReportControl[i3].BaseNode.Lineno = lineno
  1310. item3.LN0.ReportControl[i3].BaseNode.NodeId = scdmgr.RootID + lineno
  1311. isEmptyNode2 := true
  1312. if len(item3.LN0.ReportControl[i3].Private) > 0 {
  1313. isEmptyNode2 = false
  1314. //又是南瑞的定义Private子节点<Private sznari:ScanRate="0.5"/>
  1315. for p1, _ := range item3.LN0.ReportControl[i3].Private {
  1316. lineno = lineno + 1
  1317. item3.LN0.ReportControl[i3].Private[p1].BaseNode.Lineno = lineno
  1318. item3.LN0.ReportControl[i3].Private[p1].BaseNode.NodeId = scdmgr.RootID + lineno
  1319. }
  1320. }
  1321. if item4.TrgOps != nil {
  1322. isEmptyNode2 = false
  1323. lineno = lineno + 1
  1324. item3.LN0.ReportControl[i3].TrgOps.BaseNode.Lineno = lineno
  1325. item3.LN0.ReportControl[i3].TrgOps.BaseNode.NodeId = scdmgr.RootID + lineno
  1326. }
  1327. if item4.OptFields != nil {
  1328. isEmptyNode2 = false
  1329. lineno = lineno + 1
  1330. item3.LN0.ReportControl[i3].OptFields.BaseNode.Lineno = lineno
  1331. item3.LN0.ReportControl[i3].OptFields.BaseNode.NodeId = scdmgr.RootID + lineno
  1332. }
  1333. if item4.RptEnabled != nil {
  1334. isEmptyNode2 = false
  1335. lineno = lineno + 1
  1336. item3.LN0.ReportControl[i3].RptEnabled.BaseNode.Lineno = lineno
  1337. item3.LN0.ReportControl[i3].RptEnabled.BaseNode.NodeId = scdmgr.RootID + lineno
  1338. if len(item4.RptEnabled.ClientLN) > 0 {
  1339. for c1, _ := range item4.RptEnabled.ClientLN {
  1340. lineno = lineno + 1
  1341. item3.LN0.ReportControl[i3].RptEnabled.ClientLN[c1].BaseNode.Lineno = lineno
  1342. item3.LN0.ReportControl[i3].RptEnabled.ClientLN[c1].BaseNode.NodeId = scdmgr.RootID + lineno
  1343. }
  1344. lineno = lineno + 1 //多加一行RptEnabled结束
  1345. }
  1346. }
  1347. if !isEmptyNode2 {
  1348. lineno = lineno + 1
  1349. }
  1350. }
  1351. }
  1352. if item3.LN0.LogControl != nil {
  1353. isEmptyNode = false
  1354. for i3, item4 := range item3.LN0.LogControl {
  1355. lineno = lineno + 1
  1356. item3.LN0.LogControl[i3].BaseNode.Lineno = lineno
  1357. item3.LN0.LogControl[i3].BaseNode.NodeId = scdmgr.RootID + lineno
  1358. if item4.TrgOps != nil {
  1359. lineno = lineno + 1
  1360. item3.LN0.LogControl[i3].TrgOps.BaseNode.Lineno = lineno
  1361. item3.LN0.LogControl[i3].TrgOps.BaseNode.NodeId = scdmgr.RootID + lineno
  1362. }
  1363. lineno = lineno + 1
  1364. }
  1365. }
  1366. if len(item3.LN0.DOI) > 0 {
  1367. isEmptyNode = false
  1368. for i3, item4 := range item3.LN0.DOI {
  1369. lineno = lineno + 1
  1370. item3.LN0.DOI[i3].BaseNode.Lineno = lineno
  1371. item3.LN0.DOI[i3].BaseNode.NodeId = scdmgr.RootID + lineno
  1372. if item4.SDI != nil || item4.DAI != nil {
  1373. if item4.SDI != nil {
  1374. for i4, sdi1 := range item3.LN0.DOI[i3].SDI {
  1375. lineno = lineno + 1
  1376. item3.LN0.DOI[i3].SDI[i4].BaseNode.Lineno = lineno
  1377. item3.LN0.DOI[i3].SDI[i4].BaseNode.NodeId = scdmgr.RootID + lineno
  1378. //fmt.Println(fmt.Sprintf("%s %+v", lineno, sdi1))
  1379. if sdi1.SDI != nil {
  1380. for i04, sdi01 := range item3.LN0.DOI[i3].SDI[i4].SDI {
  1381. lineno = lineno + 1
  1382. item3.LN0.DOI[i3].SDI[i4].SDI[i04].BaseNode.Lineno = lineno
  1383. item3.LN0.DOI[i3].SDI[i4].SDI[i04].BaseNode.NodeId = scdmgr.RootID + lineno
  1384. if sdi01.SDI != nil {
  1385. for i24, _ := range sdi01.SDI {
  1386. lineno = lineno + 1
  1387. sdi01.SDI[i24].BaseNode.Lineno = lineno
  1388. sdi01.SDI[i24].BaseNode.NodeId = scdmgr.RootID + lineno
  1389. if sdi01.SDI[i24].DAI != nil {
  1390. for i25, _ := range sdi01.SDI[i24].DAI {
  1391. lineno = lineno + 1
  1392. sdi01.SDI[i24].DAI[i25].BaseNode.Lineno = lineno
  1393. sdi01.SDI[i24].DAI[i25].BaseNode.NodeId = scdmgr.RootID + lineno
  1394. if sdi01.SDI[i24].DAI[i25].Val != nil {
  1395. lineno = lineno + 1
  1396. sdi01.SDI[i24].DAI[i25].Val.BaseNode.Lineno = lineno
  1397. sdi01.SDI[i24].DAI[i25].Val.BaseNode.NodeId = scdmgr.RootID + lineno
  1398. lineno = lineno + 1 //多加一行
  1399. }
  1400. }
  1401. lineno = lineno + 1 //多加一行 </SDI>
  1402. }
  1403. }
  1404. lineno = lineno + 1 //多加一行 </SDI>
  1405. }
  1406. if sdi1.SDI[i04].DAI != nil {
  1407. for i05, _ := range sdi1.SDI[i04].DAI {
  1408. lineno = lineno + 1
  1409. sdi1.SDI[i04].DAI[i05].BaseNode.Lineno = lineno
  1410. sdi1.SDI[i04].DAI[i05].BaseNode.NodeId = scdmgr.RootID + lineno
  1411. if sdi1.SDI[i04].DAI[i05].Val != nil {
  1412. lineno = lineno + 1
  1413. sdi1.SDI[i04].DAI[i05].Val.BaseNode.Lineno = lineno
  1414. sdi1.SDI[i04].DAI[i05].Val.BaseNode.NodeId = scdmgr.RootID + lineno
  1415. lineno = lineno + 1 //多加一行
  1416. }
  1417. }
  1418. lineno = lineno + 1 //多加一行 </SDI>
  1419. }
  1420. }
  1421. if len(item3.LN0.DOI[i3].SDI[i4].SDI) > 0 && item3.LN0.DOI[i3].SDI[i4].DAI == nil {
  1422. lineno = lineno + 1 //多加一行 </SDI>
  1423. }
  1424. }
  1425. if item4.SDI[i4].DAI != nil {
  1426. for i5, _ := range item4.SDI[i4].DAI {
  1427. lineno = lineno + 1
  1428. item4.SDI[i4].DAI[i5].BaseNode.Lineno = lineno
  1429. item4.SDI[i4].DAI[i5].BaseNode.NodeId = scdmgr.RootID + lineno
  1430. if item4.SDI[i4].DAI[i5].Val != nil {
  1431. lineno = lineno + 1
  1432. item4.SDI[i4].DAI[i5].Val.BaseNode.Lineno = lineno
  1433. item4.SDI[i4].DAI[i5].Val.BaseNode.NodeId = scdmgr.RootID + lineno
  1434. lineno = lineno + 1 //多加一行
  1435. }
  1436. }
  1437. lineno = lineno + 1 //多加一行 </SDI>
  1438. }
  1439. }
  1440. }
  1441. if item4.DAI != nil {
  1442. for i4, _ := range item4.DAI {
  1443. lineno = lineno + 1
  1444. item4.DAI[i4].BaseNode.Lineno = lineno
  1445. item4.DAI[i4].BaseNode.NodeId = scdmgr.RootID + lineno
  1446. if item4.DAI[i4].Val != nil {
  1447. lineno = lineno + 1
  1448. item4.DAI[i4].Val.BaseNode.Lineno = lineno
  1449. item4.DAI[i4].Val.BaseNode.NodeId = scdmgr.RootID + lineno
  1450. lineno = lineno + 1 //多加一行
  1451. }
  1452. }
  1453. }
  1454. lineno = lineno + 1 //多加一行
  1455. }
  1456. }
  1457. }
  1458. if item3.LN0.Inputs != nil {
  1459. isEmptyNode = false
  1460. lineno = lineno + 1
  1461. item2.Server.LDevice[i2].LN0.Inputs.BaseNode.Lineno = lineno
  1462. item2.Server.LDevice[i2].LN0.Inputs.BaseNode.NodeId = scdmgr.RootID + lineno
  1463. if len(item3.LN0.Inputs.ExtRef) > 0 {
  1464. for i3, _ := range item3.LN0.Inputs.ExtRef {
  1465. lineno = lineno + 1
  1466. item3.LN0.Inputs.ExtRef[i3].BaseNode.Lineno = lineno
  1467. item3.LN0.Inputs.ExtRef[i3].BaseNode.NodeId = scdmgr.RootID + lineno
  1468. }
  1469. lineno = lineno + 1 //多加一行
  1470. }
  1471. }
  1472. if len(item3.LN0.Log) > 0 {
  1473. isEmptyNode = false
  1474. for i3, _ := range item3.LN0.Log {
  1475. lineno = lineno + 1
  1476. item3.LN0.Log[i3].BaseNode.Lineno = lineno
  1477. item3.LN0.Log[i3].BaseNode.NodeId = scdmgr.RootID + lineno
  1478. }
  1479. }
  1480. for i3, _ := range item3.LN0.GSEControl {
  1481. isEmptyNode = false
  1482. lineno = lineno + 1
  1483. item3.LN0.GSEControl[i3].BaseNode.Lineno = lineno
  1484. item3.LN0.GSEControl[i3].BaseNode.NodeId = scdmgr.RootID + lineno
  1485. if item3.LN0.GSEControl[i3].Private != nil || len(item3.LN0.GSEControl[i3].IEDName) > 0 {
  1486. if item3.LN0.GSEControl[i3].Private != nil {
  1487. //又是南瑞的定义Private子节点sznari:P
  1488. lineno = lineno + 1
  1489. item3.LN0.GSEControl[i3].Private.BaseNode.Lineno = lineno
  1490. item3.LN0.GSEControl[i3].Private.BaseNode.NodeId = scdmgr.RootID + lineno
  1491. //fmt.Println(fmt.Sprintf("%d %+v", lineno, item3.LN0.GSEControl[i3].Private))
  1492. if len(item3.LN0.GSEControl[i3].Private.Any) > 0 {
  1493. lineno = lineno + calNodeAnyLineNumber(item3.LN0.GSEControl[i3].Private.Any)
  1494. lineno = lineno + 1 //多加一行</Private>
  1495. }
  1496. }
  1497. if len(item3.LN0.GSEControl[i3].IEDName) > 0 {
  1498. for i4, _ := range item3.LN0.GSEControl[i3].IEDName {
  1499. lineno = lineno + 1
  1500. item3.LN0.GSEControl[i3].IEDName[i4].BaseNode.Lineno = lineno
  1501. item3.LN0.GSEControl[i3].IEDName[i4].BaseNode.NodeId = scdmgr.RootID + lineno
  1502. }
  1503. }
  1504. lineno = lineno + 1 //多加一行</GSEControl>
  1505. }
  1506. }
  1507. if len(item3.LN0.SampledValueControl) > 0 {
  1508. isEmptyNode = false
  1509. for i3, _ := range item3.LN0.SampledValueControl {
  1510. lineno = lineno + 1
  1511. item3.LN0.SampledValueControl[i3].BaseNode.Lineno = lineno
  1512. item3.LN0.SampledValueControl[i3].BaseNode.NodeId = scdmgr.RootID + lineno
  1513. if len(item3.LN0.SampledValueControl[i3].Private) > 0 {
  1514. for _, pitem := range item3.LN0.SampledValueControl[i3].Private {
  1515. lineno = lineno + 1
  1516. if len(pitem.Any) > 0 {
  1517. lineno = lineno + calNodeAnyLineNumber(pitem.Any)
  1518. lineno = lineno + 1
  1519. }
  1520. }
  1521. }
  1522. if len(item3.LN0.SampledValueControl[i3].IEDName) > 0 {
  1523. for i4, _ := range item3.LN0.SampledValueControl[i3].IEDName {
  1524. lineno = lineno + 1
  1525. item3.LN0.SampledValueControl[i3].IEDName[i4].BaseNode.Lineno = lineno
  1526. item3.LN0.SampledValueControl[i3].IEDName[i4].BaseNode.NodeId = scdmgr.RootID + lineno
  1527. }
  1528. }
  1529. lineno = lineno + 1
  1530. item3.LN0.SampledValueControl[i3].SmvOpts.BaseNode.Lineno = lineno
  1531. item3.LN0.SampledValueControl[i3].SmvOpts.BaseNode.NodeId = scdmgr.RootID + lineno
  1532. lineno = lineno + 1 //多加一行
  1533. }
  1534. }
  1535. if item3.LN0.SettingControl != nil {
  1536. isEmptyNode = false
  1537. lineno = lineno + 1
  1538. item3.LN0.SettingControl.BaseNode.Lineno = lineno
  1539. item3.LN0.SettingControl.BaseNode.NodeId = scdmgr.RootID + lineno
  1540. }
  1541. if item3.LN0.SCLControl != nil {
  1542. isEmptyNode = false
  1543. lineno = lineno + 1
  1544. item3.LN0.SCLControl.BaseNode.Lineno = lineno
  1545. item3.LN0.SCLControl.BaseNode.NodeId = scdmgr.RootID + lineno
  1546. }
  1547. if len(item3.LN0.Any) > 0 {
  1548. isEmptyNode = false
  1549. lineno = lineno + calNodeAnyLineNumber(item3.LN0.Any)
  1550. }
  1551. if !isEmptyNode {
  1552. lineno = lineno + 1 //多加一行:LN0
  1553. }
  1554. }
  1555. if len(item3.LN) > 0 {
  1556. for i2, _ := range item3.LN {
  1557. lineno = lineno + 1
  1558. item3.LN[i2].BaseNode.Lineno = lineno
  1559. item3.LN[i2].BaseNode.NodeId = scdmgr.RootID + lineno
  1560. if len(item3.LN[i2].Any) > 0 {
  1561. anyLines := calNodeAnyLineNumber(item3.LN[i2].Any)
  1562. lineno = lineno + anyLines
  1563. }
  1564. if item3.LN[i2].DataSet != nil {
  1565. for i3, item4 := range item3.LN[i2].DataSet {
  1566. lineno = lineno + 1
  1567. item3.LN[i2].DataSet[i3].BaseNode.Lineno = lineno
  1568. item3.LN[i2].DataSet[i3].BaseNode.NodeId = scdmgr.RootID + lineno
  1569. for i4, _ := range item4.FCDA {
  1570. lineno = lineno + 1
  1571. item4.FCDA[i4].BaseNode.Lineno = lineno
  1572. item4.FCDA[i4].BaseNode.NodeId = scdmgr.RootID + lineno
  1573. }
  1574. for i4, _ := range item4.FCCB {
  1575. lineno = lineno + 1
  1576. item4.FCCB[i4].BaseNode.Lineno = lineno
  1577. item4.FCCB[i4].BaseNode.NodeId = scdmgr.RootID + lineno
  1578. }
  1579. lineno = lineno + 1 //多加一行
  1580. }
  1581. }
  1582. if item3.LN[i2].ReportControl != nil {
  1583. for i3, item4 := range item3.LN[i2].ReportControl {
  1584. lineno = lineno + 1
  1585. item3.LN[i2].ReportControl[i3].BaseNode.Lineno = lineno
  1586. item3.LN[i2].ReportControl[i3].BaseNode.NodeId = scdmgr.RootID + lineno
  1587. isEmptyNode := true
  1588. if item4.TrgOps != nil {
  1589. isEmptyNode = false
  1590. lineno = lineno + 1
  1591. item3.LN[i2].ReportControl[i3].TrgOps.BaseNode.Lineno = lineno
  1592. item3.LN[i2].ReportControl[i3].TrgOps.BaseNode.NodeId = scdmgr.RootID + lineno
  1593. }
  1594. if item4.OptFields != nil {
  1595. isEmptyNode = false
  1596. lineno = lineno + 1
  1597. item3.LN[i2].ReportControl[i3].OptFields.BaseNode.Lineno = lineno
  1598. item3.LN[i2].ReportControl[i3].OptFields.BaseNode.NodeId = scdmgr.RootID + lineno
  1599. }
  1600. if item4.RptEnabled != nil {
  1601. isEmptyNode = false
  1602. lineno = lineno + 1
  1603. item3.LN[i2].ReportControl[i3].RptEnabled.BaseNode.Lineno = lineno
  1604. item3.LN[i2].ReportControl[i3].RptEnabled.BaseNode.NodeId = scdmgr.RootID + lineno
  1605. if len(item4.RptEnabled.ClientLN) > 0 {
  1606. for c1, _ := range item4.RptEnabled.ClientLN {
  1607. lineno = lineno + 1
  1608. item3.LN[i2].ReportControl[i3].RptEnabled.ClientLN[c1].BaseNode.Lineno = lineno
  1609. item3.LN[i2].ReportControl[i3].RptEnabled.ClientLN[c1].BaseNode.NodeId = scdmgr.RootID + lineno
  1610. }
  1611. lineno = lineno + 1 //多加一行RptEnabled结束
  1612. }
  1613. }
  1614. if !isEmptyNode {
  1615. lineno = lineno + 1
  1616. }
  1617. }
  1618. }
  1619. if item3.LN[i2].LogControl != nil {
  1620. for i3, item4 := range item3.LN[i2].LogControl {
  1621. lineno = lineno + 1
  1622. item3.LN[i2].LogControl[i3].BaseNode.Lineno = lineno
  1623. item3.LN[i2].LogControl[i3].BaseNode.NodeId = scdmgr.RootID + lineno
  1624. if item4.TrgOps != nil {
  1625. lineno = lineno + 1
  1626. item3.LN[i2].ReportControl[i3].TrgOps.BaseNode.Lineno = lineno
  1627. item3.LN[i2].ReportControl[i3].TrgOps.BaseNode.NodeId = scdmgr.RootID + lineno
  1628. }
  1629. lineno = lineno + 1
  1630. }
  1631. }
  1632. if len(item3.LN[i2].DOI) > 0 {
  1633. for i3, item4 := range item3.LN[i2].DOI {
  1634. lineno = lineno + 1
  1635. item3.LN[i2].DOI[i3].BaseNode.Lineno = lineno
  1636. item3.LN[i2].DOI[i3].BaseNode.NodeId = scdmgr.RootID + lineno
  1637. if item4.SDI != nil || item4.DAI != nil {
  1638. if item4.SDI != nil {
  1639. for i4, sdi1 := range item3.LN[i2].DOI[i3].SDI {
  1640. lineno = lineno + 1
  1641. item3.LN[i2].DOI[i3].SDI[i4].BaseNode.Lineno = lineno
  1642. item3.LN[i2].DOI[i3].SDI[i4].BaseNode.NodeId = scdmgr.RootID + lineno
  1643. //fmt.Println(fmt.Sprintf("%d %+v", lineno, sdi1))
  1644. if sdi1.SDI != nil {
  1645. for i04, sdi01 := range item3.LN[i2].DOI[i3].SDI[i4].SDI {
  1646. lineno = lineno + 1
  1647. item3.LN[i2].DOI[i3].SDI[i4].SDI[i04].BaseNode.Lineno = lineno
  1648. item3.LN[i2].DOI[i3].SDI[i4].SDI[i04].BaseNode.NodeId = scdmgr.RootID + lineno
  1649. if sdi01.SDI != nil {
  1650. for i24, _ := range sdi01.SDI {
  1651. lineno = lineno + 1
  1652. sdi01.SDI[i24].BaseNode.Lineno = lineno
  1653. sdi01.SDI[i24].BaseNode.NodeId = scdmgr.RootID + lineno
  1654. if sdi01.SDI[i24].DAI != nil {
  1655. for i25, _ := range sdi01.SDI[i24].DAI {
  1656. lineno = lineno + 1
  1657. sdi01.SDI[i24].DAI[i25].BaseNode.Lineno = lineno
  1658. sdi01.SDI[i24].DAI[i25].BaseNode.NodeId = scdmgr.RootID + lineno
  1659. if sdi01.SDI[i24].DAI[i25].Val != nil {
  1660. lineno = lineno + 1
  1661. sdi01.SDI[i24].DAI[i25].Val.BaseNode.Lineno = lineno
  1662. sdi01.SDI[i24].DAI[i25].Val.BaseNode.NodeId = scdmgr.RootID + lineno
  1663. lineno = lineno + 1 //多加一行<DAI>
  1664. }
  1665. }
  1666. lineno = lineno + 1 //多加一行 </SDI>
  1667. }
  1668. }
  1669. lineno = lineno + 1 //多加一行 </SDI>
  1670. }
  1671. if sdi1.SDI[i04].DAI != nil {
  1672. for i05, _ := range sdi1.SDI[i04].DAI {
  1673. lineno = lineno + 1
  1674. sdi1.SDI[i04].DAI[i05].BaseNode.Lineno = lineno
  1675. sdi1.SDI[i04].DAI[i05].BaseNode.NodeId = scdmgr.RootID + lineno
  1676. if sdi1.SDI[i04].DAI[i05].Val != nil {
  1677. lineno = lineno + 1
  1678. sdi1.SDI[i04].DAI[i05].Val.BaseNode.Lineno = lineno
  1679. sdi1.SDI[i04].DAI[i05].Val.BaseNode.NodeId = scdmgr.RootID + lineno
  1680. lineno = lineno + 1 //多加一行
  1681. }
  1682. }
  1683. lineno = lineno + 1 //多加一行 </SDI>
  1684. }
  1685. }
  1686. if len(item3.LN[i2].DOI[i3].SDI[i4].SDI) > 0 && item3.LN[i2].DOI[i3].SDI[i4].DAI == nil {
  1687. lineno = lineno + 1 //多加一行 </SDI>
  1688. }
  1689. }
  1690. if item4.SDI[i4].DAI != nil {
  1691. for i5, _ := range item4.SDI[i4].DAI {
  1692. lineno = lineno + 1
  1693. item4.SDI[i4].DAI[i5].BaseNode.Lineno = lineno
  1694. item4.SDI[i4].DAI[i5].BaseNode.NodeId = scdmgr.RootID + lineno
  1695. if item4.SDI[i4].DAI[i5].Val != nil {
  1696. lineno = lineno + 1
  1697. item4.SDI[i4].DAI[i5].Val.BaseNode.Lineno = lineno
  1698. item4.SDI[i4].DAI[i5].Val.BaseNode.NodeId = scdmgr.RootID + lineno
  1699. lineno = lineno + 1 //多加一行
  1700. }
  1701. }
  1702. lineno = lineno + 1 //多加一行 </SDI>
  1703. }
  1704. }
  1705. }
  1706. if item4.DAI != nil {
  1707. for i4, _ := range item4.DAI {
  1708. lineno = lineno + 1
  1709. item4.DAI[i4].BaseNode.Lineno = lineno
  1710. item4.DAI[i4].BaseNode.NodeId = scdmgr.RootID + lineno
  1711. if item4.DAI[i4].Val != nil {
  1712. lineno = lineno + 1
  1713. item4.DAI[i4].Val.BaseNode.Lineno = lineno
  1714. item4.DAI[i4].Val.BaseNode.NodeId = scdmgr.RootID + lineno
  1715. lineno = lineno + 1 //多加一行
  1716. }
  1717. }
  1718. }
  1719. lineno = lineno + 1 //多加一行
  1720. }
  1721. }
  1722. lineno = lineno + 1 //多加一行LN
  1723. }
  1724. if item3.LN[i2].Inputs != nil {
  1725. lineno = lineno + 1
  1726. item2.Server.LDevice[i2].LN[i2].Inputs.BaseNode.Lineno = lineno
  1727. item2.Server.LDevice[i2].LN[i2].Inputs.BaseNode.NodeId = scdmgr.RootID + lineno
  1728. if len(item3.LN[i2].Inputs.ExtRef) > 0 {
  1729. for i3, _ := range item3.LN[i2].Inputs.ExtRef {
  1730. lineno = lineno + 1
  1731. item3.LN[i2].Inputs.ExtRef[i3].BaseNode.Lineno = lineno
  1732. item3.LN[i2].Inputs.ExtRef[i3].BaseNode.NodeId = scdmgr.RootID + lineno
  1733. }
  1734. lineno = lineno + 1 //多加一行
  1735. }
  1736. }
  1737. if item3.LN[i2].Log != nil {
  1738. for i3, _ := range item3.LN[i2].Log {
  1739. lineno = lineno + 1
  1740. item3.LN[i2].Log[i3].BaseNode.Lineno = lineno
  1741. item3.LN[i2].Log[i3].BaseNode.NodeId = scdmgr.RootID + lineno
  1742. }
  1743. }
  1744. }
  1745. }
  1746. if item3.LN0 != nil || len(item3.LN) > 0 {
  1747. lineno = lineno + 1 //多加一行 LDevice
  1748. }
  1749. }
  1750. for i2, _ := range item.AccessPoint[i1].GOOSESecurity {
  1751. lineno = lineno + 1
  1752. item.AccessPoint[i1].GOOSESecurity[i2].BaseNode.Lineno = lineno
  1753. item.AccessPoint[i1].GOOSESecurity[i2].BaseNode.NodeId = scdmgr.RootID + lineno
  1754. isEmptyNode := true
  1755. if item.AccessPoint[i1].GOOSESecurity[i2].Subject != nil {
  1756. isEmptyNode = false
  1757. lineno = lineno + 1
  1758. item.AccessPoint[i1].GOOSESecurity[i2].Subject.BaseNode.Lineno = lineno
  1759. item.AccessPoint[i1].GOOSESecurity[i2].Subject.BaseNode.NodeId = scdmgr.RootID + lineno
  1760. }
  1761. if item.AccessPoint[i1].GOOSESecurity[i2].IssuerName != nil {
  1762. isEmptyNode = false
  1763. lineno = lineno + 1
  1764. item.AccessPoint[i1].GOOSESecurity[i2].IssuerName.BaseNode.Lineno = lineno
  1765. item.AccessPoint[i1].GOOSESecurity[i2].IssuerName.BaseNode.NodeId = scdmgr.RootID + lineno
  1766. }
  1767. if !isEmptyNode {
  1768. lineno = lineno + 1 //多加一个结束节点
  1769. }
  1770. }
  1771. for i2, _ := range item.AccessPoint[i1].SMVSecurity {
  1772. lineno = lineno + 1
  1773. item.AccessPoint[i1].SMVSecurity[i2].BaseNode.Lineno = lineno
  1774. item.AccessPoint[i1].SMVSecurity[i2].BaseNode.NodeId = scdmgr.RootID + lineno
  1775. isEmptyNode := true
  1776. if item.AccessPoint[i1].SMVSecurity[i2].Subject != nil {
  1777. isEmptyNode = false
  1778. lineno = lineno + 1
  1779. item.AccessPoint[i1].SMVSecurity[i2].Subject.BaseNode.Lineno = lineno
  1780. item.AccessPoint[i1].SMVSecurity[i2].Subject.BaseNode.NodeId = scdmgr.RootID + lineno
  1781. }
  1782. if item.AccessPoint[i1].SMVSecurity[i2].IssuerName != nil {
  1783. lineno = lineno + 1
  1784. item.AccessPoint[i1].SMVSecurity[i2].IssuerName.BaseNode.Lineno = lineno
  1785. item.AccessPoint[i1].SMVSecurity[i2].IssuerName.BaseNode.NodeId = scdmgr.RootID + lineno
  1786. }
  1787. if !isEmptyNode {
  1788. lineno = lineno + 1 //多加一个结束节点
  1789. }
  1790. }
  1791. lineno = lineno + 1 //多加一行 Server
  1792. }
  1793. lineno = lineno + 1 //多加一行 AccessPoint
  1794. }
  1795. lineno = lineno + 1 //多加一行 </IED>
  1796. }
  1797. if sclNodeObj.DataTypeTemplates != nil {
  1798. lineno = lineno + 1
  1799. sclNodeObj.DataTypeTemplates.BaseNode.Lineno = lineno
  1800. sclNodeObj.DataTypeTemplates.BaseNode.NodeId = scdmgr.RootID + lineno
  1801. for i, item := range sclNodeObj.DataTypeTemplates.LNodeType {
  1802. lineno = lineno + 1
  1803. sclNodeObj.DataTypeTemplates.LNodeType[i].BaseNode.Lineno = lineno
  1804. sclNodeObj.DataTypeTemplates.LNodeType[i].BaseNode.NodeId = scdmgr.RootID + lineno
  1805. for i1, _ := range item.DO {
  1806. lineno = lineno + 1
  1807. sclNodeObj.DataTypeTemplates.LNodeType[i].DO[i1].BaseNode.Lineno = lineno
  1808. sclNodeObj.DataTypeTemplates.LNodeType[i].DO[i1].BaseNode.NodeId = scdmgr.RootID + lineno
  1809. }
  1810. lineno = lineno + 1 //多加一行
  1811. }
  1812. for i, item := range sclNodeObj.DataTypeTemplates.DOType {
  1813. lineno = lineno + 1
  1814. sclNodeObj.DataTypeTemplates.DOType[i].BaseNode.Lineno = lineno
  1815. sclNodeObj.DataTypeTemplates.DOType[i].BaseNode.NodeId = scdmgr.RootID + lineno
  1816. for i1, _ := range item.SDO {
  1817. lineno = lineno + 1
  1818. sclNodeObj.DataTypeTemplates.DOType[i].SDO[i1].BaseNode.Lineno = lineno
  1819. sclNodeObj.DataTypeTemplates.DOType[i].SDO[i1].BaseNode.NodeId = scdmgr.RootID + lineno
  1820. }
  1821. for i1, _ := range item.DA {
  1822. lineno = lineno + 1
  1823. sclNodeObj.DataTypeTemplates.DOType[i].DA[i1].BaseNode.Lineno = lineno
  1824. sclNodeObj.DataTypeTemplates.DOType[i].DA[i1].BaseNode.NodeId = scdmgr.RootID + lineno
  1825. if sclNodeObj.DataTypeTemplates.DOType[i].DA[i1].Val != nil {
  1826. lineno = lineno + 1
  1827. sclNodeObj.DataTypeTemplates.DOType[i].DA[i1].Val.BaseNode.Lineno = lineno
  1828. sclNodeObj.DataTypeTemplates.DOType[i].DA[i1].Val.BaseNode.NodeId = scdmgr.RootID + lineno
  1829. lineno = lineno + 1 //多加一行
  1830. }
  1831. }
  1832. lineno = lineno + 1 //多加一行
  1833. }
  1834. for i, item := range sclNodeObj.DataTypeTemplates.DAType {
  1835. lineno = lineno + 1
  1836. sclNodeObj.DataTypeTemplates.DAType[i].BaseNode.Lineno = lineno
  1837. sclNodeObj.DataTypeTemplates.DAType[i].BaseNode.NodeId = scdmgr.RootID + lineno
  1838. for i1, _ := range item.BDA {
  1839. lineno = lineno + 1
  1840. sclNodeObj.DataTypeTemplates.DAType[i].BDA[i1].BaseNode.Lineno = lineno
  1841. sclNodeObj.DataTypeTemplates.DAType[i].BDA[i1].BaseNode.NodeId = scdmgr.RootID + lineno
  1842. if sclNodeObj.DataTypeTemplates.DAType[i].BDA[i1].Val != nil {
  1843. lineno = lineno + 1
  1844. sclNodeObj.DataTypeTemplates.DAType[i].BDA[i1].Val.BaseNode.Lineno = lineno
  1845. sclNodeObj.DataTypeTemplates.DAType[i].BDA[i1].Val.BaseNode.NodeId = scdmgr.RootID + lineno
  1846. lineno = lineno + 1 //多加一行
  1847. }
  1848. }
  1849. lineno = lineno + 1 //多加一行
  1850. }
  1851. for i, item := range sclNodeObj.DataTypeTemplates.EnumType {
  1852. lineno = lineno + 1
  1853. sclNodeObj.DataTypeTemplates.EnumType[i].BaseNode.Lineno = lineno
  1854. sclNodeObj.DataTypeTemplates.EnumType[i].BaseNode.NodeId = scdmgr.RootID + lineno
  1855. if len(item.EnumVal) > 0 {
  1856. for i1, _ := range item.EnumVal {
  1857. lineno = lineno + 1
  1858. sclNodeObj.DataTypeTemplates.EnumType[i].EnumVal[i1].BaseNode.Lineno = lineno
  1859. sclNodeObj.DataTypeTemplates.EnumType[i].EnumVal[i1].BaseNode.NodeId = scdmgr.RootID + lineno
  1860. }
  1861. lineno = lineno + 1 //多加一行
  1862. }
  1863. }
  1864. }
  1865. //logger.Logger.Debug(fmt.Sprintf("\n-----GlobalNodeMap------- \n:%+v", GlobalNodeMap))
  1866. xmlStr, err := xml.MarshalIndent(sclNodeObj, "", " ")
  1867. if err == nil {
  1868. //生成解析完成结果副本文件
  1869. os.WriteFile(scdPath+".parsed.xml", xmlStr, fs.ModePerm)
  1870. } else {
  1871. //解除该站的签入锁定,如果是签入解析
  1872. new(Flow).CheckInFail(stationid)
  1873. mqtt.PublishMessage(fmt.Sprintf("/jujutong/scd_check_tools/parse/%s/%d/error", stationid, scdmgr.RootID), scdName+"格式化时发生错误,解析终止!")
  1874. logger.Logger.Error(err)
  1875. return err
  1876. }
  1877. if stationid == "" || stationid == "0" {
  1878. return
  1879. }
  1880. scdid = tools.IsEmpty(scdmgr.RootID)
  1881. global.GoCahce.Set(scdPath, scdid, -1)
  1882. global.GoCahce.Set(scdid, sclNodeObj, -1)
  1883. c.cacheGlobalNodeIds(scdid, sclNodeObj)
  1884. //新的scd文件
  1885. stationidint, _ := strconv.Atoi(stationid)
  1886. newscdid, err := scdmgr.Init(stationidint, scdName, scdPath, isenable, c.IsCheckinScd)
  1887. if err != nil {
  1888. //解除该站的签入锁定,如果是签入解析
  1889. new(Flow).CheckInFail(stationid)
  1890. mqtt.PublishMessage(fmt.Sprintf("/jujutong/scd_check_tools/parse/%s/%d/error", stationid, scdmgr.RootID), scdName+"初始化创建时发生错误,解析终止!")
  1891. logger.Logger.Error(err)
  1892. return err
  1893. }
  1894. scdmgr.RootID = newscdid
  1895. if isenable == 1 {
  1896. //该scd需要默认启用且是在运版本
  1897. scdmgr.IsDefaultRunVersion = 1
  1898. }
  1899. //间隔解析.如果间隔解析是Bay方式,需要根据节点数据进行解析
  1900. if isBay {
  1901. logger.Logger.Debug(fmt.Sprintf("当前采集Bay间隔模式"))
  1902. scdmgr.AreaMgr.ParseBay(stationidint, bayList)
  1903. } else {
  1904. logger.Logger.Debug(fmt.Sprintf("当前采集IED分析间隔模式,共解析IED节点数:%d", len(iedlist)))
  1905. for _, ieditem := range iedlist {
  1906. scdmgr.AreaMgr.AppendIedNode(scdmgr.RootID, ieditem.BaseNode.NodeId, ieditem.Name, ieditem.Desc)
  1907. }
  1908. }
  1909. mqttData := map[string]string{"name": scdName, "stationid": stationid, "rootid": scdid, "state": "1", "node": "load-file", "msg": ""}
  1910. dataMsg, _ = json.Marshal(mqttData)
  1911. mqtt.PublishMessage(fmt.Sprintf("/jujutong/scd_check_tools/parse/%s/%d", stationid, scdmgr.RootID), string(dataMsg))
  1912. //开始校验该SCD
  1913. _, err = c.SchemaValid(tools.IsEmpty(newscdid), scdName, scdPath)
  1914. if err != nil {
  1915. //解除该站的签入锁定,如果是签入解析
  1916. //new(Flow).CheckInFail(stationid)
  1917. mqtt.PublishMessage(fmt.Sprintf("/jujutong/scd_check_tools/parse/%s/%d/error", stationid, scdmgr.RootID), scdName+"校验发生错误,语法校验终止!")
  1918. logger.Logger.Error(err)
  1919. //return err
  1920. }
  1921. scdmgr.Flush()
  1922. //写入ied节点到节点表中
  1923. db.Raw("update t_scd_scl set node_cnt=? where id=?", node_cnt, scdmgr.RootID).Exec()
  1924. db.Raw("delete from t_scd_node_scl where scd_id=?", scdmgr.RootID).Exec()
  1925. node_ins := "insert into t_scd_node_scl(id,scd_id,node_name,ied_name,line_no)values"
  1926. _, err = db.Raw(fmt.Sprintf("%s%s", node_ins, strings.Join(iedList, ","))).Exec()
  1927. if err != nil {
  1928. //解除该站的签入锁定,如果是签入解析
  1929. new(Flow).CheckInFail(stationid)
  1930. logger.Logger.Error(err, fmt.Sprintf("SQL:%s", fmt.Sprintf("%s%s", node_ins, strings.Join(iedList, ","))))
  1931. }
  1932. return nil
  1933. }
  1934. //解析ICD到内存中
  1935. func (c *ScdParse) IcdParse(scdid, iedname string) error {
  1936. fline := string(os.PathSeparator)
  1937. icddir := strings.Join([]string{".", "static", "download", "icd", scdid, ""}, fline)
  1938. icdPath := icddir + iedname + ".icd"
  1939. f, err := os.Stat(icdPath)
  1940. if err != nil {
  1941. os.MkdirAll(icddir, fs.ModePerm)
  1942. logger.Logger.Error(err, icdPath)
  1943. return err
  1944. }
  1945. if f == nil {
  1946. os.MkdirAll(icddir, fs.ModePerm)
  1947. return errors.New("icd文件" + icdPath + "未找到!")
  1948. }
  1949. sclNodeObj, err := c.LoadScdXml(icdPath)
  1950. if err != nil {
  1951. logger.Logger.Error(err, "异常ICD文件:"+icdPath)
  1952. return err
  1953. }
  1954. key := fmt.Sprintf("icd_%s_%s", scdid, iedname)
  1955. global.GoCahce.Set(key, sclNodeObj, 1*time.Hour)
  1956. return nil
  1957. }
  1958. //解析CID到内存中
  1959. func (c *ScdParse) CidParse(scdid, iedname string) error {
  1960. fline := string(os.PathSeparator)
  1961. icddir := strings.Join([]string{".", "static", "download", "cid", scdid, ""}, fline)
  1962. icdPath := icddir + iedname + ".cid"
  1963. f, err := os.Stat(icdPath)
  1964. if err != nil {
  1965. os.MkdirAll(icddir, fs.ModePerm)
  1966. logger.Logger.Error(err, icdPath)
  1967. return err
  1968. }
  1969. if f == nil {
  1970. os.MkdirAll(icddir, fs.ModePerm)
  1971. return errors.New("cid文件" + icdPath + "未找到!")
  1972. }
  1973. sclNodeObj, err := c.LoadScdXml(icdPath)
  1974. if err != nil {
  1975. logger.Logger.Error(err, "异常CID文件:"+icdPath)
  1976. return err
  1977. }
  1978. key := fmt.Sprintf("cid_%s_%s", scdid, iedname)
  1979. global.GoCahce.Set(key, sclNodeObj, 1*time.Hour)
  1980. return nil
  1981. }
  1982. func GetScdParseInstance(userinfo ...map[string]interface{}) *ScdParse {
  1983. ins := new(ScdParse)
  1984. ins.ModelTableName = "t_scd_scl"
  1985. if len(userinfo) > 0 {
  1986. ins.SetUserInfo(userinfo[0])
  1987. } else {
  1988. ins.SetUserInfo(map[string]interface{}{"name": "", "ip": "127.0.0.1"})
  1989. }
  1990. //获取最大的ID,当前解析对象的ID序列为数据库中最大ID+4000000,以保证不同文件解析入库中的ID不重复
  1991. if tools.GlobalID == 0 {
  1992. db := orm.NewOrm()
  1993. r := []orm.Params{}
  1994. _, err := db.Raw("select ifnull(max(id),0) maxid from t_scd_scl").Values(&r)
  1995. if err != nil {
  1996. log.Println(err)
  1997. } else {
  1998. insSeqID, _ := strconv.Atoi(r[0]["maxid"].(string))
  1999. tools.GlobalID = int64(insSeqID)
  2000. }
  2001. }
  2002. ins.Idseq = tools.GetSeqID() + int64(instanNum*4000000)
  2003. instanNum = instanNum + 1
  2004. //初始化命名空间定义
  2005. new(sync.Once).Do(func() {
  2006. logger.Logger.Debug(fmt.Sprintf("正在加载命名空间(scd_node_space)系统字典定义"))
  2007. syscode := new(Global)
  2008. _, ishasd, _ := syscode.QueryGlobalCodeList(map[string]interface{}{"code": "scd_node_space"})
  2009. if ishasd == 0 {
  2010. //新增字典
  2011. SaveGlobalCode(Global_const_code{
  2012. Code: "scd_node_space",
  2013. Parentcode: "systemconstcode",
  2014. Name: "SCD命名空间",
  2015. })
  2016. }
  2017. lst, _ := syscode.GetChildrenGlobalCode("scd_node_space")
  2018. if len(lst) > 0 {
  2019. for _, row := range lst {
  2020. spaceMap.Store(tools.IsEmpty(row["code"]), tools.IsEmpty(row["name"]))
  2021. }
  2022. }
  2023. })
  2024. return ins
  2025. }
  2026. //原数据库存储方式,已废弃
  2027. func (c *ScdParse) Parse_UnUsed(stationid, scdpath, scdName string, isenable int, autocompscdid ...int64) (err error) {
  2028. if scdpath == "" || scdName == "" {
  2029. return errors.New("无效的SCD名称")
  2030. }
  2031. c.SclModel = map[string]interface{}{}
  2032. fileFirstChar := scdpath[0:1]
  2033. fline := string(os.PathSeparator)
  2034. if fileFirstChar != "." {
  2035. if fileFirstChar == fline {
  2036. scdpath = "." + scdpath
  2037. } else {
  2038. scdpath = "." + fline + scdpath
  2039. }
  2040. }
  2041. //判断该scd是否已经存在,已存在则不再解析
  2042. db := orm.NewOrm()
  2043. sql := "select 1 from t_scd_scl where scd_name=? and path=?"
  2044. rowset := []orm.Params{}
  2045. db.Raw(sql, scdName, scdpath).Values(&rowset)
  2046. if len(rowset) > 0 {
  2047. db.Raw("update t_scd_scl set enable=? where scd_name=? and path=?", isenable, scdName, scdpath).Exec()
  2048. return nil
  2049. }
  2050. xmlhander, err2 := os.Open(scdpath)
  2051. if err2 != nil {
  2052. log.Println(err2)
  2053. return err2
  2054. }
  2055. defer xmlhander.Close()
  2056. //通知开始实时性能监测
  2057. global.PerformanceRuntimeMonitorChan <- 1
  2058. var item xml.Token
  2059. de := xml.NewDecoder(xmlhander)
  2060. var startElementLoaded = false
  2061. var isRoot = true
  2062. var startName = ""
  2063. var nodeText = ""
  2064. var startTime = time.Now().Unix()
  2065. scdmgr := new(ScdNode)
  2066. scdmgr.SetUserInfo(c.GetUserInfo())
  2067. scdmgr.Idseq = c.Idseq //初始化节点管理对象的ID序列
  2068. iedContentList := []string{}
  2069. scdID := int64(0)
  2070. iedName := ""
  2071. lineno := int64(1) //起始行号。跳过xml标注行
  2072. for {
  2073. item, err2 = de.Token()
  2074. if err2 == io.EOF {
  2075. break
  2076. }
  2077. if err2 != nil {
  2078. log.Println(err2)
  2079. break
  2080. }
  2081. switch token := item.(type) {
  2082. case xml.StartElement:
  2083. name := token.Name.Local
  2084. if name == "IED" {
  2085. //创建IED文件
  2086. iedContentList = []string{}
  2087. }
  2088. iedContentList = append(iedContentList, "<"+name)
  2089. attr := map[string]interface{}{}
  2090. if len(token.Attr) != 0 {
  2091. for _, xmlAttr := range token.Attr {
  2092. v_attrname := xmlAttr.Name.Local
  2093. attr[v_attrname] = strings.ReplaceAll(xmlAttr.Value, "'", "''")
  2094. iedContentList = append(iedContentList, " "+v_attrname+"=\""+xmlAttr.Value+"\"")
  2095. if name == "IED" && v_attrname == "name" {
  2096. iedName = xmlAttr.Value
  2097. }
  2098. }
  2099. }
  2100. iedContentList = append(iedContentList, ">")
  2101. if isRoot {
  2102. isRoot = false
  2103. stationidint, _ := strconv.Atoi(stationid)
  2104. scdID, err = scdmgr.Init(stationidint, scdName, scdpath, isenable, c.IsCheckinScd)
  2105. if err != nil {
  2106. return
  2107. }
  2108. if isenable == 1 {
  2109. //该scd需要默认启用且是在运版本
  2110. scdmgr.IsDefaultRunVersion = 1
  2111. }
  2112. } else {
  2113. startName = name
  2114. startElementLoaded = true
  2115. }
  2116. lineno = lineno + 1
  2117. err = scdmgr.AddNode(name, attr, lineno)
  2118. if err != nil {
  2119. return
  2120. }
  2121. case xml.EndElement:
  2122. name := token.Name.Local
  2123. if name == "IED" {
  2124. iedContentList = append(iedContentList, "</IED>")
  2125. //创建该IED文件
  2126. //fmt.Println("创建该IED文件:" + iedName)
  2127. //log.Println(fmt.Sprintf("%v", iedContentList))
  2128. go func(ied_name, iedTxt string) {
  2129. defer func() {
  2130. iedTxt = ""
  2131. }()
  2132. dirChar := string(os.PathSeparator)
  2133. tmpPart := []string{"static", "download", "ied", tools.IsEmpty(scdID)}
  2134. iedpath := strings.Join(tmpPart, dirChar)
  2135. f, _ := exec.LookPath(os.Args[0])
  2136. fp, _ := filepath.Abs(f)
  2137. i := strings.LastIndex(fp, dirChar)
  2138. absdir := string(fp[0:i])
  2139. iedpath = absdir + dirChar + iedpath
  2140. os.MkdirAll(iedpath, fs.ModePerm)
  2141. ferr := os.WriteFile(iedpath+dirChar+ied_name+".ied", []byte(iedTxt), fs.ModePerm)
  2142. if ferr != nil {
  2143. logger.Logger.Error(ferr, "生成ied["+ied_name+"]单个配置文件错误!")
  2144. new(SystemLog).Fail(enum.AuditType_scd_parse,
  2145. enum.LogType_Execute,
  2146. enum.OptEventType_System,
  2147. enum.OptEventLevel_Hight,
  2148. fmt.Sprintf("SCD%s中IED文件%s生成失败", scdName, ied_name),
  2149. c.GetUserInfo(),
  2150. )
  2151. }
  2152. }(iedName, strings.Join(iedContentList, ""))
  2153. } else {
  2154. lastNode := iedContentList[len(iedContentList)-1]
  2155. lastNodeLastChar := lastNode[len(lastNode)-1:]
  2156. if lastNode[0:1] == "<" && lastNodeLastChar == ">" {
  2157. iedContentList = append(iedContentList, "</"+name+">")
  2158. } else if lastNode == "/>" {
  2159. iedContentList = append(iedContentList, "</"+name+">")
  2160. } else if lastNodeLastChar != ">" {
  2161. iedContentList = append(iedContentList, "</"+name+">")
  2162. } else {
  2163. for i := len(iedContentList) - 1; i > 0; i-- {
  2164. lastNode2 := iedContentList[i-1]
  2165. if lastNode2[0:1] != "<" {
  2166. continue
  2167. }
  2168. if lastNode2 == ("<" + name) {
  2169. iedContentList[len(iedContentList)-1] = "/>"
  2170. }
  2171. break
  2172. }
  2173. }
  2174. }
  2175. err = scdmgr.EndNode(name, nodeText)
  2176. if err != nil {
  2177. return
  2178. }
  2179. if startName != name {
  2180. lineno = lineno + 1
  2181. }
  2182. nodeText = ""
  2183. startElementLoaded = false
  2184. case xml.CharData:
  2185. if startElementLoaded {
  2186. nodeText = string(token)
  2187. nodeText = strings.Replace(strings.ReplaceAll(nodeText, "'", "''"), "\n", "", -1)
  2188. //log.Println("NODE ["+startName+"] Text:", nodeText)
  2189. if nodeText != "" {
  2190. iedContentList = append(iedContentList, string(token))
  2191. }
  2192. }
  2193. case xml.Comment:
  2194. case xml.ProcInst:
  2195. case xml.Directive:
  2196. default:
  2197. log.Println("解析失败!")
  2198. break
  2199. }
  2200. }
  2201. iedContentList = []string{}
  2202. scdmgr.StationID, _ = strconv.Atoi(stationid)
  2203. if autocompscdid != nil && len(autocompscdid) > 0 {
  2204. scdmgr.AutoCompScdID = autocompscdid[0]
  2205. }
  2206. scdmgr.Flush()
  2207. var endTime = time.Now().Unix()
  2208. log.Println(fmt.Sprintf("===========SCD 加载完毕!,总耗时:%d秒", endTime-startTime))
  2209. new(SystemLog).Success(enum.AuditType_scd_parse,
  2210. enum.LogType_Execute,
  2211. enum.OptEventType_System,
  2212. enum.OptEventLevel_Hight,
  2213. fmt.Sprintf("SCD%s解析", scdName),
  2214. c.GetUserInfo(),
  2215. )
  2216. //通知结束实时性能监测
  2217. global.PerformanceRuntimeMonitorChan <- 2
  2218. return err
  2219. }