package bo import ( "bufio" "encoding/json" "encoding/xml" "errors" "fmt" "io" "io/fs" "io/ioutil" "log" "os" "os/exec" "path/filepath" "runtime" "scd_check_tools/global" "scd_check_tools/logger" "scd_check_tools/models/enum" "scd_check_tools/models/node_attr" "scd_check_tools/mqtt" "scd_check_tools/tools" "sort" "strconv" "strings" "sync" "time" "github.com/astaxie/beego/orm" //"github.com/go-xmlfmt/xmlfmt" //"github.com/krolaw/xsd" ) //当前消费的本实例数 //需要通过该实例数进行运算,得到该实例下的启始ID段。每个实例分配了5000000个ID用于业务数据的消费 //主要消费ID的业务数据就是节点,即单个SCD文件节点数量不能超过500W. var instanNum = 1 //scd文件解析锁。同一文件不能同时多次解析 var parseLock = sync.Map{} //节点引用缓存 type NodeCacheMap struct { ParentNodeId int64 //父节点 ObjAddr any //引用节点对象地址 } var spaceMap = sync.Map{} // map[string]string{} //SCD节点存储。格式:map[int64]map[int64]NodeCacheMap{} var GlobalNodeMap = sync.Map{} type ScdParse struct { DeviceBaseModel SclModel map[string]interface{} //是否是管控SCD,1为管控SCD,0为非管控SCD IsCheckinScd int } type sortInt64 []int64 func (p sortInt64) Len() int { return len(p) } func (p sortInt64) Less(i, j int) bool { return p[i] < p[j] } func (p sortInt64) Swap(i, j int) { p[i], p[j] = p[j], p[i] } //释放使用频率低的scd缓存 func (c *ScdParse) RemoveScdCache(toscdid ...string) { scdid := "" if len(toscdid) == 0 { logger.Logger.Println("系统正在尝试释放使用频率低的scd缓存") lastUsedList := map[int64]string{} keylist := []int64{} global.CachedScdMap.Range(func(k, v any) bool { lastUsedList[v.(int64)] = k.(string) keylist = append(keylist, v.(int64)) return true }) if len(keylist) == 0 { logger.Logger.Println("当前系统内已无scd缓存") return } if len(keylist) == 1 { logger.Logger.Println("当前无scd缓存可以释放") return } sort.Sort(sortInt64(keylist)) //释放最长时间的第一个scd lasttime := keylist[0] scdid = lastUsedList[lasttime] if time.Now().Unix()-lasttime < 300 { //如果5分钟使用过scd,则不能释放 logger.Logger.Println(fmt.Sprintf("SCD %s最近5分钟内有访问记录,不允许释放!", scdid)) return } } else { scdid = toscdid[0] } logger.Logger.Println("系统正在释放scd【" + scdid + "】的缓存") global.CachedScdCrc.Delete(fmt.Sprintf("crc_%s", scdid)) global.IedCrcMakeState.Delete(fmt.Sprintf("crc_%s", scdid)) scdXmlObj, serr := c.GetScdXmlObjectBySCDID(scdid) if serr != nil { logger.Logger.Error(serr, fmt.Sprintf("SCD %s获取异常!", scdid)) return } cachekey := "" if scdXmlObj != nil { for _, ied := range scdXmlObj.IED { cachekey = fmt.Sprintf("GetIedCtrlBlock_%s_%s", scdid, ied.Name) global.GoCahce.Delete(cachekey) cachekey = "GetIedRelations_" + scdid + ied.Name global.GoCahce.Delete(cachekey) cachekey = fmt.Sprintf("GetIedBlockRelations_%s_%s", scdid, ied.Name) global.GoCahce.Delete(cachekey) cachekey = "GetIedInputsRelations_" + scdid + ied.Name global.GoCahce.Delete(cachekey) } } cachekey = fmt.Sprintf("networkinfo_%s", scdid) global.GoCahce.Delete(cachekey) cachekey = fmt.Sprintf("cachebBlockDetail_%s", scdid) global.GoCahce.Delete(cachekey) cachekey = "GetIedRelations_" + scdid global.GoCahce.Delete(cachekey) global.GoCahce.Delete(scdid) cachekey = fmt.Sprintf("scd_netinfo_%d", scdid) global.GoCahce.Delete(cachekey) cachekey = fmt.Sprintf("scd_info_%s", scdid) global.GoCahce.Delete(cachekey) scdidint64, _ := strconv.ParseInt(scdid, 10, 64) GlobalNodeMap.Delete(scdidint64) global.CachedScdMap.Delete(scdidint64) runtime.GC() } //语法验证 func (c *ScdParse) SchemaValid(scdid, scdname, scdFilePath string) ([]string, error) { if scdid == "" && scdname == "" { logger.Logger.Error(errors.New("SCD编号和名称不能同时不空")) return nil, errors.New("SCD编号和名称不能同时不空") } stationid := "" if scdid != "" { scdmgr := new(ScdMgr) scdinfo, err := scdmgr.One(scdid) if err != nil { logger.Logger.Error("无效的SCD编号:" + scdid) return nil, err } scdFilePath = tools.IsEmpty(scdinfo["path"]) stationid = tools.IsEmpty(scdinfo["station_id"]) } else { scdmgr := new(ScdMgr) scdinfo, err := scdmgr.OneByName(scdname, scdFilePath) if err != nil { logger.Logger.Error(fmt.Sprintf("无效的SCD名称%s和路径%s", scdname, scdFilePath)) return nil, err } scdid = tools.IsEmpty(scdinfo["id"]) scdFilePath = tools.IsEmpty(scdinfo["path"]) stationid = tools.IsEmpty(scdinfo["station_id"]) } if scdFilePath == "" { logger.Logger.Error("该SCD文件路径为空,可能已被删除") return nil, errors.New("该SCD文件路径为空,可能已被删除") } chr := string(os.PathSeparator) dir, _ := filepath.Abs(filepath.Dir(os.Args[0])) xsdPath := strings.Join([]string{dir, "schema", "SCL.xsd"}, chr) validResultPath := strings.Join([]string{dir, "static", "upload", scdid + ".schema_valid"}, chr) osname := string(runtime.GOOS) var subProcess *exec.Cmd scdAbsPath := scdFilePath if scdFilePath[0:1] == "." { //相对路径 scdAbsPath = dir + strings.ReplaceAll(strings.Replace(scdFilePath, ".", "", 1), "\\", chr) } data := map[string]string{"name": scdname, "stationid": stationid, "rootid": scdid, "state": "0", "node": "check-file", "msg": ""} dataMsg, _ := json.Marshal(data) mqtt.PublishMessage(fmt.Sprintf("/jujutong/scd_check_tools/parse/%s/%s", stationid, scdid), string(dataMsg)) checkObj := new(ScdNodeRule) checkObj.ScdID, _ = strconv.ParseInt(scdid, 10, 64) yfrulelist, _, _ := checkObj.GetDefList(map[string]interface{}{ "enable": 1, "check_name": "语法校验", }, 1, 1) scdYFcheckRuleid := "" if len(yfrulelist) > 0 { scdYFcheckRuleid = tools.IsEmpty(yfrulelist[0]["id"]) } logger.Logger.Debug(fmt.Sprintf("开始校验scd文件%s的语法正确性", scdAbsPath)) if scdYFcheckRuleid != "" { if osname == "windows" { //logger.Logger.Debug("=====jar路径:" + dir + chr + `scd_schema_valid1.0_prod.jar`) subProcess = exec.Command("java", "-jar", "-Dfile.encoding=utf-8", dir+chr+`scd_schema_valid1.0_prod.jar`, "1", scdAbsPath, xsdPath, validResultPath) } else { 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 + `"` subProcess = exec.Command("bash", "-c", javaCmd) logger.Logger.Debug(fmt.Sprintf("javaCmd:%s", javaCmd)) } stdin, err := subProcess.StdinPipe() if err != nil { logger.Logger.Error(err) return nil, err } defer stdin.Close() stdout, _ := subProcess.StdoutPipe() if err = subProcess.Start(); err != nil { logger.Logger.Error(err) return nil, err } txt := make([]byte, 1024) ValidErrMsg := []string{} for { time.Sleep(100 * time.Millisecond) n, err := stdout.Read(txt) if err == io.EOF { //读取结束,会报EOF break } str := tools.ConvertByte2String(txt[0:n], "UTF-8") logger.Logger.Debug(str) if str == "ValidOverWithOK" { break } if strings.Count(str, "ValidOverWithError") == 1 { strs := strings.Split(str[len("ValidOverWithError:"):], ",") stdout.Close() if len(strs) == 1 { ValidErrMsg = []string{"0", strs[0]} break //return nil, errors.New(fmt.Sprintf("校验SCD文件语法时发生严重错误:%s 无法继续校验该SCD文件!", strs[0])) } //ValidErrMsg = fmt.Sprintf("SCD文件第%s行配置发生严重错误:%s 无法继续校验该SCD文件!", strs[0], strs[1]) ValidErrMsg = []string{strs[0], strs[1]} break //return nil, errors.New(fmt.Sprintf("SCD文件第%s行配置发生严重错误:%s 无法继续校验该SCD文件!", strs[0], strs[1])) } } stdout.Close() logger.Logger.Debug(fmt.Sprintf("scd文件%s的语法校验完成", scdAbsPath)) db := orm.NewOrm() db.Raw("delete from t_scd_node_rule_parse where scd_id=?", scdid).Exec() insertRuleSql := "insert into t_scd_node_rule_parse(scd_id,line_no,ied_name,rule_id,parse_result,line_xml)values" if len(ValidErrMsg) > 0 { db.Raw(fmt.Sprintf("%s(%s,%s,'%s',%s,'%s','%s')", insertRuleSql, scdid, ValidErrMsg[0], "", scdYFcheckRuleid, ValidErrMsg[1], "")).Exec() } go func(scdid, stationid, validResultPath, scdYFcheckRuleid string) { rfile, err := os.Open(validResultPath) // For read access. if err != nil { logger.Logger.Error(err, "异常SCD语法校验结果文件:"+validResultPath) return } defer rfile.Close() buf := bufio.NewReader(rfile) var errorlist []string //将结果写入t_scd_node_rule_parse表 for { line, err := buf.ReadString('\n') line = strings.TrimSpace(line) if err != nil { if err == io.EOF { //读取结束,会报EOF break } logger.Logger.Error(err) return } linestrs := strings.Split(strings.ReplaceAll(line, "'", ""), "|") if ind := strings.Index(linestrs[1], ":"); ind > 1 { linestrs[1] = linestrs[1][ind+1:] } errorlist = append(errorlist, fmt.Sprintf("(%s,%s,'%s',%s,'%s','%s')", scdid, linestrs[0], "", scdYFcheckRuleid, linestrs[1], linestrs[2])) if len(errorlist) == 2000 { _, err = db.Raw(fmt.Sprintf("%s%s", insertRuleSql, strings.Join(errorlist, ","))).Exec() if err != nil { logger.Logger.Error(err) } errorlist = []string{} } } if len(errorlist) > 0 { _, err = db.Raw(fmt.Sprintf("%s%s", insertRuleSql, strings.Join(errorlist, ","))).Exec() if err != nil { logger.Logger.Error(err) } errorlist = []string{} } insertRuleSql = "" data := map[string]string{"name": scdname, "stationid": stationid, "rootid": scdid, "state": "1", "node": "check-file", "msg": ""} dataMsg, _ := json.Marshal(data) mqtt.PublishMessage(fmt.Sprintf("/jujutong/scd_check_tools/parse/%s/%s", stationid, scdid), string(dataMsg)) }(scdid, stationid, validResultPath, scdYFcheckRuleid) } new(TaskMgr).SetStep(tools.IsEmpty(scdid), enum.TaskStep_SCD_syntax_parse.Code(), 2) //开始语义校验 logger.Logger.Info("======开始进行语义校验") checkObj.TestCheckRule() return nil, nil } //格式化scd源文件。主要考虑有些源文件没有缩进格式,这样获取节点行数时是错误的 func (c *ScdParse) ForamtScdPath(scdFilePath string) (int64, error) { logger.Logger.Debug(fmt.Sprintf("开始格式化SCD文件%s", scdFilePath)) var tmpFileSCD = fmt.Sprintf("%s.tmp", scdFilePath) tmpFileHander, err := os.OpenFile(tmpFileSCD, os.O_RDWR|os.O_TRUNC|os.O_CREATE, 0644) if err != nil { logger.Logger.Error(err) } defer tmpFileHander.Close() var item xml.Token xmlhander, err2 := os.Open(scdFilePath) if err2 != nil { logger.Logger.Error(err2) return 0, err2 } defer xmlhander.Close() de := xml.NewDecoder(xmlhander) var startElementLoaded = false var nodeText = "" var node_cnt = int64(0) //节点总数 iedContentList := []string{``, "\n"} for { item, err2 = de.Token() if err2 == io.EOF { break } if err2 != nil { log.Println(err2) break } switch token := item.(type) { case xml.StartElement: node_cnt = node_cnt + 1 //节点数量 startElementLoaded = true name := token.Name.Local node := []string{} //判断节点名称是否有名空间 ndoeSpace := "" if v, ok := spaceMap.Load(token.Name.Space); ok { ndoeSpace = tools.IsEmpty(v) } if ndoeSpace != "" { node = append(node, "<"+ndoeSpace+":"+name) } else { node = append(node, "<"+name) } if len(token.Attr) != 0 { for _, xmlAttr := range token.Attr { v_attrname := xmlAttr.Name.Local v_attrvalue := xmlAttr.Value if name == "SCL" { //处理名空间 if v_attrname != "xmlns" && len(v_attrvalue) > 4 { if v_attrname == "schemaLocation" { spaceMap.Store(v_attrvalue, "xsi") v_attrname = "xsi:" + v_attrname } else if v_attrvalue[0:4] == "http" && v_attrname != "scl" { spaceMap.Store(v_attrvalue, v_attrname) v_attrname = "xmlns:" + v_attrname } } } else if xmlAttr.Name.Space != "" { //logger.Logger.Info(fmt.Sprintf("attr space:%s attrname:%s attrvalue:%s", xmlAttr.Name.Space, v_attrname, v_attrvalue)) //获取名空间名称 if v, h := spaceMap.Load(xmlAttr.Name.Space); h && v.(string) != "scl" { v_attrname = v.(string) + ":" + v_attrname } else { spaceMap.Store(v_attrvalue, v_attrname) v_attrname = xmlAttr.Name.Space + ":" + v_attrname } } v_attrvalue = strings.ReplaceAll(v_attrvalue, "'", "''") v_attrvalue = strings.ReplaceAll(v_attrvalue, "<", "") v_attrvalue = strings.ReplaceAll(v_attrvalue, ">", "") node = append(node, " "+v_attrname+"=\""+v_attrvalue+"\"") } } node = append(node, ">\n") iedContentList = append(iedContentList, strings.Join(node, "")) break case xml.EndElement: name := token.Name.Local ndoeSpace := "" if v, ok := spaceMap.Load(token.Name.Space); ok { ndoeSpace = v.(string) } if ndoeSpace != "" && ndoeSpace != "xmlns" { name = ndoeSpace + ":" + name } if nodeText != "" { iedContentList = append(iedContentList, "\n") } else { lastNode := strings.ReplaceAll(iedContentList[len(iedContentList)-1], "\n", "") lastSize := len(lastNode) if lastSize <= len(name) { iedContentList = append(iedContentList, "\n") } else { if lastNode[0:len(name)+1] == "<"+name { //判断上一个节点是否结束,如果已经结束时,则使用单独的结束标签,否则使用简化结束标签"/>" if lastNode[lastSize-2:] == "/>" { //上个节点已经结束 iedContentList = append(iedContentList, "\n") } else { iedContentList[len(iedContentList)-1] = lastNode[0:lastSize-1] + "/>\n" } } else { iedContentList = append(iedContentList, "\n") } } } nodeText = "" startElementLoaded = false break case xml.CharData: if startElementLoaded { nodeText = string(token) nodeText = strings.ReplaceAll(strings.ReplaceAll(nodeText, "'", "''"), "\n", "") nodeText = strings.ReplaceAll(nodeText, "\t", "") nodeText = strings.ReplaceAll(nodeText, "\r", "") nodeText = strings.ReplaceAll(nodeText, "<", "") nodeText = strings.ReplaceAll(nodeText, ">", "") nodeText = strings.Trim(nodeText, " ") //log.Println("NODE ["+startName+"] Text:", nodeText) if nodeText != "" { lastnode := iedContentList[len(iedContentList)-1] iedContentList[len(iedContentList)-1] = lastnode[:len(lastnode)-1] iedContentList = append(iedContentList, nodeText) } } break case xml.Comment: case xml.ProcInst: case xml.Directive: default: log.Println("解析失败!") break } } tmpFileHander.WriteString(strings.Join(iedContentList, "")) tmpFileHander.Close() xmlhander.Close() //time.Sleep(1 * time.Second) err = os.Rename(tmpFileSCD, scdFilePath) if err != nil { logger.Logger.Error(err, "格式化SCD文件异常:"+scdFilePath) } else { logger.Logger.Debug(fmt.Sprintf("SCD文件%s格式化完成!", scdFilePath)) } return node_cnt, nil } func (c *ScdParse) LoadCcdXml(ccdPath string) (*node_attr.CcdIed, error) { file, err := os.Open(ccdPath) // For read access. if err != nil { logger.Logger.Error(err, "异常CCD文件:"+ccdPath) return nil, err } defer file.Close() data, err := ioutil.ReadAll(file) if err != nil { logger.Logger.Error(err, "异常CCD文件:"+ccdPath) return nil, err } scl := new(node_attr.CcdIed) err = xml.Unmarshal(data, &scl) if err != nil { logger.Logger.Error(err, "异常CCD文件:"+ccdPath) return nil, err } return scl, nil } func (c *ScdParse) LoadScdXml(scdPath string) (*node_attr.SCL, error) { file, err := os.Open(scdPath) // For read access. if err != nil { logger.Logger.Error(err, "异常SCD文件:"+scdPath) return nil, err } defer file.Close() data, err := ioutil.ReadAll(file) if err != nil { logger.Logger.Error(err, "异常SCD文件:"+scdPath) return nil, err } scl := new(node_attr.SCL) err = xml.Unmarshal(data, &scl) if err != nil { logger.Logger.Error(err, "异常SCD文件:"+scdPath) return nil, err } return scl, nil } func (c *ScdParse) GetScdXmlObject(scdPath string) (*node_attr.SCL, error) { if scdid, h := global.GoCahce.Get(scdPath); h { //已经解析到内存中,则不再解析 return c.GetScdXmlObjectBySCDID(tools.IsEmpty(scdid)) } return nil, nil } func (c *ScdParse) GetScdXmlObjectBySCDID(scdid string) (*node_attr.SCL, error) { defer func() { //解析完成,解锁 parseLock.Delete(scdid) }() waitTime := 0 for { if waitTime > 5*60 { logger.Logger.Error(errors.New(fmt.Sprintf("等待SCD%s解析超时(大于5分钟)", scdid))) break } if _, h := parseLock.Load(scdid); !h { break } waitTime = waitTime + 1 //当前scd正在解析,等待1秒后再检查 time.Sleep(1 * time.Second) } if scl, h := global.GoCahce.Get(scdid); h { //已经解析到内存中,则不再解析 global.CachedScdMap.Store(scdid, time.Now().Unix()) return scl.(*node_attr.SCL), nil } parseLock.Store(scdid, 1) db := orm.NewOrm() sql := "select * from t_scd_scl where id=?" rowset := []orm.Params{} db.Raw(sql, scdid).Values(&rowset) if len(rowset) == 0 { logger.Logger.Error(errors.New(fmt.Sprintf("未在数据库中找到SCD%s的记录!", scdid))) return nil, nil } scdpath := tools.IsEmpty(rowset[0]["path"]) enable := tools.IsEmpty(rowset[0]["enable"]) enableInt, _ := strconv.Atoi(enable) err := c.XmlParse( tools.IsEmpty(rowset[0]["station_id"]), scdpath, tools.IsEmpty(rowset[0]["scd_name"]), enableInt, ) if err == nil { scl, _ := global.GoCahce.Get(scdid) if scl == nil { logger.Logger.Error(errors.New(fmt.Sprintf("SCD%s已解析,但未在内存中找到缓存对象", scdid))) return nil, nil } global.CachedScdMap.Store(scdid, time.Now().Unix()) return scl.(*node_attr.SCL), nil } else { logger.Logger.Error(err) } return nil, err } //获取指定的ICD对象 func (c *ScdParse) GetIcdXmlObject(scdid, iedname string) (*node_attr.SCL, error) { key := fmt.Sprintf("icd_%s_%s", scdid, iedname) for { if _, h := parseLock.Load(key); !h { break } //当前scd正在解析,等待1秒后再检查 time.Sleep(1 * time.Second) } if scl, h := global.GoCahce.Get(key); h { //已经解析到内存中,则不再解析 return scl.(*node_attr.SCL), nil } parseLock.Store(key, 1) err := c.IcdParse(scdid, iedname) //解析完成,解锁 parseLock.Delete(key) if err == nil { scl, _ := global.GoCahce.Get(key) return scl.(*node_attr.SCL), nil } return nil, err } //获取指定的CID对象 func (c *ScdParse) GetCidXmlObject(scdid, iedname string) (*node_attr.SCL, error) { key := fmt.Sprintf("cid_%s_%s", scdid, iedname) for { if _, h := parseLock.Load(key); !h { break } //当前scd正在解析,等待1秒后再检查 time.Sleep(1 * time.Second) } if scl, h := global.GoCahce.Get(key); h { //已经解析到内存中,则不再解析 return scl.(*node_attr.SCL), nil } parseLock.Store(key, 1) err := c.IcdParse(scdid, iedname) //解析完成,解锁 parseLock.Delete(key) if err == nil { scl, _ := global.GoCahce.Get(key) return scl.(*node_attr.SCL), nil } return nil, err } //缓存指定scd的节点ID与节点对象关联 //主要缓存IED下的常用节点 func (c *ScdParse) cacheGlobalNodeIds(scdid string, sclNodeObj *node_attr.SCL) { scdidint, _ := strconv.ParseInt(scdid, 10, 64) cachenode := NodeCacheMap{ParentNodeId: scdidint, ObjAddr: sclNodeObj} nodeidCacheMap := map[int64]NodeCacheMap{sclNodeObj.BaseNode.NodeId: cachenode} for i, ied := range sclNodeObj.IED { nodeidCacheMap[ied.NodeId] = NodeCacheMap{ ParentNodeId: sclNodeObj.NodeId, //上级节点ID ObjAddr: sclNodeObj.IED[i], //缓存对象地址指针 } for i1, pri := range ied.Priavate { nodeidCacheMap[pri.NodeId] = NodeCacheMap{ ParentNodeId: ied.NodeId, //上级节点ID ObjAddr: ied.Priavate[i1], //缓存对象地址指针 } } for i1, accp := range ied.AccessPoint { nodeidCacheMap[accp.NodeId] = NodeCacheMap{ ParentNodeId: ied.NodeId, //上级节点ID ObjAddr: sclNodeObj.IED[i].AccessPoint[i1], //缓存对象地址指针 } if accp.Server == nil { continue } nodeidCacheMap[accp.Server.NodeId] = NodeCacheMap{ ParentNodeId: accp.NodeId, //上级节点ID ObjAddr: sclNodeObj.IED[i].AccessPoint[i1].Server, //缓存对象地址指针 } for i2, ld := range accp.Server.LDevice { nodeidCacheMap[ld.NodeId] = NodeCacheMap{ ParentNodeId: accp.Server.NodeId, //上级节点ID ObjAddr: sclNodeObj.IED[i].AccessPoint[i1].Server.LDevice[i2], //缓存LDevice对象地址指针 } if ld.LN0 != nil { nodeidCacheMap[ld.LN0.NodeId] = NodeCacheMap{ ParentNodeId: ld.NodeId, //上级节点ID ObjAddr: sclNodeObj.IED[i].AccessPoint[i1].Server.LDevice[i2].LN0, //缓存LN0对象地址指针 } for i3, ds := range ld.LN0.DataSet { nodeidCacheMap[ds.NodeId] = NodeCacheMap{ ParentNodeId: ld.LN0.NodeId, //上级节点ID ObjAddr: sclNodeObj.IED[i].AccessPoint[i1].Server.LDevice[i2].LN0.DataSet[i3], //缓存对象地址指针 } for i4, fcda := range ds.FCDA { nodeidCacheMap[fcda.NodeId] = NodeCacheMap{ ParentNodeId: ds.NodeId, //上级节点ID ObjAddr: sclNodeObj.IED[i].AccessPoint[i1].Server.LDevice[i2].LN0.DataSet[i3].FCDA[i4], //缓存对象地址指针 } } } for i3, ds := range ld.LN0.GSEControl { nodeidCacheMap[ds.NodeId] = NodeCacheMap{ ParentNodeId: ld.LN0.NodeId, //上级节点ID ObjAddr: sclNodeObj.IED[i].AccessPoint[i1].Server.LDevice[i2].LN0.GSEControl[i3], //缓存对象地址指针 } } for i3, ds := range ld.LN0.SampledValueControl { nodeidCacheMap[ds.NodeId] = NodeCacheMap{ ParentNodeId: ld.LN0.NodeId, //上级节点ID ObjAddr: sclNodeObj.IED[i].AccessPoint[i1].Server.LDevice[i2].LN0.SampledValueControl[i3], //缓存对象地址指针 } } for i3, doi := range ld.LN0.DOI { nodeidCacheMap[doi.NodeId] = NodeCacheMap{ ParentNodeId: ld.LN0.NodeId, //上级节点ID ObjAddr: sclNodeObj.IED[i].AccessPoint[i1].Server.LDevice[i2].LN0.DOI[i3], //缓存对象地址指针 } } if ld.LN0.Inputs != nil { nodeidCacheMap[ld.LN0.Inputs.NodeId] = NodeCacheMap{ ParentNodeId: ld.LN0.NodeId, //上级节点ID ObjAddr: sclNodeObj.IED[i].AccessPoint[i1].Server.LDevice[i2].LN0.Inputs, //缓存对象地址指针 } for i3, ds := range ld.LN0.Inputs.ExtRef { nodeidCacheMap[ds.NodeId] = NodeCacheMap{ ParentNodeId: ld.LN0.Inputs.NodeId, //上级节点ID ObjAddr: sclNodeObj.IED[i].AccessPoint[i1].Server.LDevice[i2].LN0.Inputs.ExtRef[i3], //缓存对象地址指针 } } } } for i3, ln := range ld.LN { nodeidCacheMap[ln.NodeId] = NodeCacheMap{ ParentNodeId: ld.NodeId, //上级节点ID ObjAddr: sclNodeObj.IED[i].AccessPoint[i1].Server.LDevice[i2].LN[i3], //缓存LN对象地址指针 } for i4, doi := range ln.DOI { nodeidCacheMap[doi.NodeId] = NodeCacheMap{ ParentNodeId: ld.LN[i3].NodeId, //上级节点ID ObjAddr: sclNodeObj.IED[i].AccessPoint[i1].Server.LDevice[i2].LN[i3].DOI[i4], //缓存DOI对象地址指针 } } } } } } nodeidCacheMap[sclNodeObj.DataTypeTemplates.NodeId] = NodeCacheMap{ ParentNodeId: sclNodeObj.NodeId, //上级节点ID ObjAddr: sclNodeObj.DataTypeTemplates, //缓存对象地址指针 } GlobalNodeMap.Store(scdidint, nodeidCacheMap) } //scd完整解析过程一:只解析SCD的间隔和IED func (c *ScdParse) XmlIEDParse(stationid, scdPath, scdName string) (scdid string, err error) { if scdPath == "" || scdName == "" { return "", errors.New("无效的SCD名称") } if stationid == "" || stationid == "0" { return "", errors.New("变站电不能为空") } logger.Logger.Debug("===开始解析SCD:" + scdName) c.SclModel = map[string]interface{}{} fileFirstChar := scdPath[0:1] fline := string(os.PathSeparator) if fileFirstChar != "." && fileFirstChar != "G" { if fileFirstChar == fline { scdPath = "." + scdPath } else { scdPath = "." + fline + scdPath } } data := map[string]string{"name": scdName, "stationid": stationid, "rootid": "", "state": "0", "node": "load-file", "msg": ""} dataMsg, _ := json.Marshal(data) mqtt.PublishMessage(fmt.Sprintf("/jujutong/scd_check_tools/parse/%s", stationid), string(dataMsg)) //判断该scd是否已经存在,已存在则不再解析 db := orm.NewOrm() sql := "select id from t_scd_scl where scd_name=? and path=?" rowset := []orm.Params{} db.Raw(sql, scdName, scdPath).Values(&rowset) if len(rowset) > 0 { scdid = tools.IsEmpty(rowset[0]["id"]) new(TaskMgr).SetStep(scdid, enum.TaskStep_SCD_Loading.Code(), 1) if _, h := global.GoCahce.Get(scdid); h { //已经解析到内存中,则不再解析 data := map[string]string{"name": scdName, "stationid": stationid, "rootid": "", "state": "1", "node": "load-file", "msg": ""} dataMsg, _ := json.Marshal(data) mqtt.PublishMessage(fmt.Sprintf("/jujutong/scd_check_tools/parse/%s", stationid), string(dataMsg)) new(TaskMgr).SetStep(scdid, enum.TaskStep_SCD_Loading.Code(), 2) return scdid, nil } else { //判断是否有解析完成的持久化文件 parsedFile := strings.ReplaceAll(scdPath, "\\", "/") + ".parsed.xml" f, err := os.Stat(parsedFile) logger.Logger.Debug(fmt.Sprintf("%s:%+v ====== %+v", parsedFile, f, err)) if f != nil || os.IsExist(err) { logger.Logger.Debug("=====结果文件" + scdPath + ".parsed.xml已存在,直接加载") sclNodeObj, err := c.LoadScdXml(scdPath + ".parsed.xml") if err == nil { new(TaskMgr).SetStep(scdid, enum.TaskStep_SCD_Loading.Code(), 2) new(TaskMgr).SetStep(scdid, enum.TaskStep_SCD_Parse.Code(), 1) global.GoCahce.Set(scdPath, scdid, -1) global.GoCahce.Set(scdid, sclNodeObj, -1) data := map[string]string{"name": scdName, "stationid": stationid, "rootid": "", "state": "1", "node": "load-file", "msg": ""} dataMsg, _ := json.Marshal(data) mqtt.PublishMessage(fmt.Sprintf("/jujutong/scd_check_tools/parse/%s", stationid), string(dataMsg)) c.cacheGlobalNodeIds(scdid, sclNodeObj) //crc提取 //go new(ScdMgr).CrcCheck(scdid) //开始校验该SCD //go c.SchemaValid(scdid, scdName, scdPath) new(TaskMgr).SetStep(scdid, enum.TaskStep_SCD_Parse.Code(), 2) } else { logger.Logger.Error(err, "异常SCD文件:"+scdPath) new(TaskMgr).SetStep(scdid, enum.TaskStep_SCD_Parse.Code(), 3, err.Error()) return "", err } return scdid, nil } else { //没有缓存,也没有解析结果文件,则重新解析 logger.Logger.Debug("=====没有缓存及结果文件,全新解析:" + scdPath) } } } //判断当前服务器性能是否达到阀值 canparse, msg := new(ScdMgr).CheckParseMaxLimit() if canparse { mqtt.PublishMessage(fmt.Sprintf("/jujutong/scd_check_tools/parse/%s/%d/error", stationid, 0), "系统繁忙:"+msg+",请稍候(约5分钟)再试") return "", errors.New("系统繁忙:" + msg + ",请稍候(约5分钟)再试") } logger.Logger.Debug(fmt.Sprintf("=======开始加载解析SCD:%s", scdName)) new(TaskMgr).SetStep(scdid, enum.TaskStep_SCD_Loading.Code(), 1) //新解析scd,先进行文件格式化。搞成一行一行的 node_cnt, err2 := c.ForamtScdPath(scdPath) if err2 != nil { mqtt.PublishMessage(fmt.Sprintf("/jujutong/scd_check_tools/parse/%s/%d/error", stationid, 0), scdName+"解析时发生错误,解析终止!") logger.Logger.Error(err2, "异常SCD文件:"+scdPath) new(TaskMgr).SetStep(scdid, enum.TaskStep_SCD_Loading.Code(), 3, err2.Error()) return "", err2 } sclNodeObj, err := c.LoadScdXml(scdPath) if err != nil { mqtt.PublishMessage(fmt.Sprintf("/jujutong/scd_check_tools/parse/%s/%d/error", stationid, 0), scdName+"解析时发生错误,解析终止!") logger.Logger.Error(err, "异常SCD文件:"+scdPath) new(TaskMgr).SetStep(scdid, enum.TaskStep_SCD_Loading.Code(), 3, err.Error()) return "", err } new(TaskMgr).SetStep(scdid, enum.TaskStep_SCD_Loading.Code(), 2) new(TaskMgr).SetStep(scdid, enum.TaskStep_SCD_Parse.Code(), 1) iedList := []string{} isBay := false //是否有间隔节点 bayList := []*node_attr.NVoltage{} iedlist := []*node_attr.NIED{} scdmgr := new(ScdNode) scdmgr.SetUserInfo(c.GetUserInfo()) scdmgr.Idseq = c.Idseq //初始化节点管理对象的ID序列 if scdid == "" { scdmgr.RootID = scdmgr.GetID() scdid = tools.IsEmpty(scdmgr.RootID) } else { scdmgr.RootID, _ = strconv.ParseInt(scdid, 10, 64) } var calNodeAnyLineNumber = func(lst []*node_attr.NAny) int64 { lineno := 0 for _, any1 := range lst { lineno = lineno + 1 if len(any1.Any) > 0 { for _, any2 := range any1.Any { lineno = lineno + 1 if len(any2.Any) > 0 { for range any2.Any { lineno = lineno + 1 } lineno = lineno + 1 } } lineno = lineno + 1 } } return int64(lineno) } lineno := int64(1) //生成节点行号及ID lineno = lineno + 1 sclNodeObj.BaseNode.Lineno = lineno sclNodeObj.BaseNode.NodeId = scdmgr.RootID + sclNodeObj.BaseNode.Lineno for i, _ := range sclNodeObj.Private { lineno = lineno + 1 sclNodeObj.Private[i].BaseNode.Lineno = lineno sclNodeObj.Private[i].BaseNode.NodeId = scdmgr.RootID + lineno //电压级及间隔分析 if len(sclNodeObj.Private[i].Voltage) > 0 { for v1, _ := range sclNodeObj.Private[i].Voltage { lineno = lineno + 1 sclNodeObj.Private[i].Voltage[v1].BaseNode.Lineno = lineno sclNodeObj.Private[i].Voltage[v1].BaseNode.NodeId = scdmgr.RootID + lineno if len(sclNodeObj.Private[i].Voltage[v1].Bay) > 0 { isBay = true bayList = sclNodeObj.Private[i].Voltage for bayi, _ := range sclNodeObj.Private[i].Voltage[v1].Bay { lineno = lineno + 1 sclNodeObj.Private[i].Voltage[v1].Bay[bayi].BaseNode.Lineno = lineno sclNodeObj.Private[i].Voltage[v1].Bay[bayi].BaseNode.NodeId = scdmgr.RootID + lineno if len(sclNodeObj.Private[i].Voltage[v1].Bay[bayi].IED) > 0 { for iedi, _ := range sclNodeObj.Private[i].Voltage[v1].Bay[bayi].IED { lineno = lineno + 1 sclNodeObj.Private[i].Voltage[v1].Bay[bayi].IED[iedi].BaseNode.Lineno = lineno sclNodeObj.Private[i].Voltage[v1].Bay[bayi].IED[iedi].BaseNode.NodeId = scdmgr.RootID + lineno } lineno = lineno + 1 //多加一行 } } lineno = lineno + 1 //多加一行 } } lineno = lineno + 1 //多加一行 } if len(sclNodeObj.Private[i].Any) > 0 { lineno = lineno + calNodeAnyLineNumber(sclNodeObj.Private[i].Any) lineno = lineno + 1 } } if sclNodeObj.Header != nil { lineno = lineno + 1 sclNodeObj.Header.BaseNode.Lineno = lineno sclNodeObj.Header.BaseNode.NodeId = scdmgr.RootID + lineno if sclNodeObj.Header.History != nil { lineno = lineno + 1 sclNodeObj.Header.History.BaseNode.Lineno = lineno sclNodeObj.Header.History.BaseNode.NodeId = scdmgr.RootID + lineno if len(sclNodeObj.Header.History.Hitem) > 0 { for i, _ := range sclNodeObj.Header.History.Hitem { lineno = lineno + 1 sclNodeObj.Header.History.Hitem[i].BaseNode.Lineno = lineno sclNodeObj.Header.History.Hitem[i].BaseNode.NodeId = scdmgr.RootID + lineno } lineno = lineno + 1 //多加一行 } lineno = lineno + 1 } } if sclNodeObj.Substation != nil { lineno = lineno + 1 sclNodeObj.Substation.BaseNode.Lineno = lineno sclNodeObj.Substation.BaseNode.NodeId = scdmgr.RootID + lineno isEmptyNode := true if len(sclNodeObj.Substation.Private) > 0 { isEmptyNode = false for i1, _ := range sclNodeObj.Substation.Private { lineno = lineno + 1 sclNodeObj.Substation.Private[i1].BaseNode.Lineno = lineno sclNodeObj.Substation.Private[i1].BaseNode.NodeId = scdmgr.RootID + lineno if len(sclNodeObj.Substation.Private[i1].Any) > 0 { anyLines := calNodeAnyLineNumber(sclNodeObj.Substation.Private[i1].Any) lineno = lineno + anyLines lineno = lineno + 1 //多加一行Priavate } } } if len(sclNodeObj.Substation.Any) > 0 { isEmptyNode = false anyLines := calNodeAnyLineNumber(sclNodeObj.Substation.Any) lineno = lineno + anyLines } if len(sclNodeObj.Substation.VoltageLevel) > 0 { isEmptyNode = false for i1, _ := range sclNodeObj.Substation.VoltageLevel { lineno = lineno + 1 sclNodeObj.Substation.VoltageLevel[i1].BaseNode.Lineno = lineno sclNodeObj.Substation.VoltageLevel[i1].BaseNode.NodeId = scdmgr.RootID + lineno isEmptyNode := true if len(sclNodeObj.Substation.VoltageLevel[i1].Bay) > 0 { isEmptyNode = false for b1, _ := range sclNodeObj.Substation.VoltageLevel[i1].Bay { lineno = lineno + 1 if len(sclNodeObj.Substation.VoltageLevel[i1].Bay[b1].Any) > 0 { anyLines := calNodeAnyLineNumber(sclNodeObj.Substation.VoltageLevel[i1].Bay[b1].Any) lineno = lineno + anyLines } } } if sclNodeObj.Substation.VoltageLevel[i1].Voltage != nil { isEmptyNode = false lineno = lineno + 1 if len(sclNodeObj.Substation.VoltageLevel[i1].Voltage.Any) > 0 { anyLines := calNodeAnyLineNumber(sclNodeObj.Substation.VoltageLevel[i1].Voltage.Any) lineno = lineno + anyLines } } if len(sclNodeObj.Substation.VoltageLevel[i1].Any) > 0 { isEmptyNode = false anyLines := calNodeAnyLineNumber(sclNodeObj.Substation.VoltageLevel[i1].Any) lineno = lineno + anyLines } if !isEmptyNode { lineno = lineno + 1 //多加一行VoltageLevel } } } if !isEmptyNode { lineno = lineno + 1 } } if sclNodeObj.Communication != nil { lineno = lineno + 1 sclNodeObj.Communication.BaseNode.Lineno = lineno sclNodeObj.Communication.BaseNode.NodeId = scdmgr.RootID + lineno if sclNodeObj.Communication.SubNetwork != nil { for i, item := range sclNodeObj.Communication.SubNetwork { lineno = lineno + 1 sclNodeObj.Communication.SubNetwork[i].BaseNode.Lineno = lineno sclNodeObj.Communication.SubNetwork[i].BaseNode.NodeId = scdmgr.RootID + lineno if sclNodeObj.Communication.SubNetwork[i].BitRate != nil { lineno = lineno + 1 sclNodeObj.Communication.SubNetwork[i].BitRate.BaseNode.Lineno = lineno sclNodeObj.Communication.SubNetwork[i].BitRate.BaseNode.NodeId = scdmgr.RootID + lineno } for i2, item2 := range item.ConnectedAP { lineno = lineno + 1 item.ConnectedAP[i2].BaseNode.Lineno = lineno item.ConnectedAP[i2].BaseNode.NodeId = scdmgr.RootID + lineno if len(item2.Private) > 0 { for p1, _ := range item2.Private { lineno = lineno + 1 item.ConnectedAP[i2].Private[p1].BaseNode.Lineno = lineno item.ConnectedAP[i2].Private[p1].BaseNode.NodeId = scdmgr.RootID + lineno if len(item.ConnectedAP[i2].Private[p1].Any) > 0 { lineno = lineno + calNodeAnyLineNumber(item.ConnectedAP[i2].Private[p1].Any) lineno = lineno + 1 } } } if item2.Address != nil { lineno = lineno + 1 item.ConnectedAP[i2].Address.BaseNode.Lineno = lineno item.ConnectedAP[i2].Address.BaseNode.NodeId = scdmgr.RootID + lineno for i3, _ := range item2.Address.P { lineno = lineno + 1 item2.Address.P[i3].BaseNode.Lineno = lineno item2.Address.P[i3].BaseNode.NodeId = scdmgr.RootID + lineno } lineno = lineno + 1 //多加一行 } if len(item2.GSE) > 0 { for i3, _ := range item2.GSE { lineno = lineno + 1 item2.GSE[i3].BaseNode.Lineno = lineno item2.GSE[i3].BaseNode.NodeId = scdmgr.RootID + lineno if item2.GSE[i3].Address != nil || item2.GSE[i3].MinTime != nil || item2.GSE[i3].MaxTime != nil { if item2.GSE[i3].Address != nil { lineno = lineno + 1 item2.GSE[i3].Address.BaseNode.Lineno = lineno item2.GSE[i3].Address.BaseNode.NodeId = scdmgr.RootID + lineno for i4, _ := range item2.GSE[i3].Address.P { lineno = lineno + 1 item2.GSE[i3].Address.P[i4].BaseNode.Lineno = lineno item2.GSE[i3].Address.P[i4].BaseNode.NodeId = scdmgr.RootID + lineno } lineno = lineno + 1 //多加一行 } if item2.GSE[i3].MinTime != nil { lineno = lineno + 1 item2.GSE[i3].MinTime.BaseNode.Lineno = lineno item2.GSE[i3].MinTime.BaseNode.NodeId = scdmgr.RootID + lineno } if item2.GSE[i3].MaxTime != nil { lineno = lineno + 1 item2.GSE[i3].MaxTime.BaseNode.Lineno = lineno item2.GSE[i3].MaxTime.BaseNode.NodeId = scdmgr.RootID + lineno } lineno = lineno + 1 //多加一行 } } } if len(item2.SMV) > 0 { for i, item3 := range item2.SMV { lineno = lineno + 1 item2.SMV[i].BaseNode.Lineno = lineno item2.SMV[i].BaseNode.NodeId = scdmgr.RootID + lineno isEmptyNode := true if item3.Address != nil { isEmptyNode = false lineno = lineno + 1 item2.SMV[i].Address.BaseNode.Lineno = lineno item2.SMV[i].Address.BaseNode.NodeId = scdmgr.RootID + lineno for i1, _ := range item3.Address.P { lineno = lineno + 1 item3.Address.P[i1].BaseNode.Lineno = lineno item3.Address.P[i1].BaseNode.NodeId = scdmgr.RootID + lineno } if len(item3.Address.P) > 0 { lineno = lineno + 1 //多加一行Address } } if item2.SMV[i].MinTime != nil { isEmptyNode = false lineno = lineno + 1 item2.SMV[i].MinTime.BaseNode.Lineno = lineno item2.SMV[i].MinTime.BaseNode.NodeId = scdmgr.RootID + lineno } if item2.SMV[i].MaxTime != nil { isEmptyNode = false lineno = lineno + 1 item2.SMV[i].MaxTime.BaseNode.Lineno = lineno item2.SMV[i].MaxTime.BaseNode.NodeId = scdmgr.RootID + lineno } if !isEmptyNode { lineno = lineno + 1 //多加一行SMV } } } if len(item2.PhysConn) > 0 { for i, item3 := range item2.PhysConn { lineno = lineno + 1 item2.PhysConn[i].BaseNode.Lineno = lineno item2.PhysConn[i].BaseNode.NodeId = scdmgr.RootID + lineno if len(item3.P) > 0 { for i1, _ := range item3.P { lineno = lineno + 1 item3.P[i1].BaseNode.Lineno = lineno item3.P[i1].BaseNode.NodeId = scdmgr.RootID + lineno } lineno = lineno + 1 //多加一行 } } } if item2.Address != nil || len(item2.GSE) > 0 || len(item2.SMV) > 0 || len(item2.PhysConn) > 0 { lineno = lineno + 1 //多加一行 } } if len(item.ConnectedAP) > 0 || item.BitRate != nil { lineno = lineno + 1 //多加一行:SubNetwork } } lineno = lineno + 1 //多加一行:Communication } } for i, item := range sclNodeObj.IED { lineno = lineno + 1 sclNodeObj.IED[i].BaseNode.Lineno = lineno sclNodeObj.IED[i].BaseNode.NodeId = scdmgr.RootID + lineno iedList = append(iedList, fmt.Sprintf("(%d,%d,'%s','%s',%d)", sclNodeObj.IED[i].BaseNode.NodeId, scdmgr.RootID, "IED", item.Name, lineno)) if !isBay { //非bay模式时,记录所有的IED节点 iedlist = append(iedlist, sclNodeObj.IED[i]) } if item.Priavate != nil { for i1, _ := range item.Priavate { lineno = lineno + 1 item.Priavate[i1].BaseNode.Lineno = lineno item.Priavate[i1].BaseNode.NodeId = scdmgr.RootID + lineno if len(item.Priavate[i1].Any) > 0 { anyLines := calNodeAnyLineNumber(item.Priavate[i1].Any) lineno = lineno + anyLines lineno = lineno + 1 //多加一行Priavate } } } if sclNodeObj.IED[i].Services == nil { logger.Logger.Error(errors.New(fmt.Sprintf("%s中未发现Services定义", sclNodeObj.IED[i].Desc))) } else { lineno = lineno + 1 sclNodeObj.IED[i].Services.BaseNode.Lineno = lineno sclNodeObj.IED[i].Services.BaseNode.NodeId = scdmgr.RootID + lineno if sclNodeObj.IED[i].Services.DynAssociation != nil { lineno = lineno + 1 sclNodeObj.IED[i].Services.DynAssociation.BaseNode.Lineno = lineno sclNodeObj.IED[i].Services.DynAssociation.BaseNode.NodeId = scdmgr.RootID + lineno } if sclNodeObj.IED[i].Services.SettingGroups != nil { lineno = lineno + 1 sclNodeObj.IED[i].Services.SettingGroups.BaseNode.Lineno = lineno sclNodeObj.IED[i].Services.SettingGroups.BaseNode.NodeId = scdmgr.RootID + lineno if sclNodeObj.IED[i].Services.SettingGroups.SGEdit != nil || sclNodeObj.IED[i].Services.SettingGroups.ConfSG != nil { if sclNodeObj.IED[i].Services.SettingGroups.SGEdit != nil { lineno = lineno + 1 sclNodeObj.IED[i].Services.SettingGroups.SGEdit.BaseNode.Lineno = lineno sclNodeObj.IED[i].Services.SettingGroups.SGEdit.BaseNode.NodeId = scdmgr.RootID + lineno } if sclNodeObj.IED[i].Services.SettingGroups.ConfSG != nil { lineno = lineno + 1 sclNodeObj.IED[i].Services.SettingGroups.ConfSG.BaseNode.Lineno = lineno sclNodeObj.IED[i].Services.SettingGroups.ConfSG.BaseNode.NodeId = scdmgr.RootID + lineno } lineno = lineno + 1 //多加一行 } } if sclNodeObj.IED[i].Services.GetDirectory != nil { lineno = lineno + 1 sclNodeObj.IED[i].Services.GetDirectory.BaseNode.Lineno = lineno sclNodeObj.IED[i].Services.GetDirectory.BaseNode.NodeId = scdmgr.RootID + lineno } if sclNodeObj.IED[i].Services.GetDataObjectDefinition != nil { lineno = lineno + 1 sclNodeObj.IED[i].Services.GetDataObjectDefinition.BaseNode.Lineno = lineno sclNodeObj.IED[i].Services.GetDataObjectDefinition.BaseNode.NodeId = scdmgr.RootID + lineno } if sclNodeObj.IED[i].Services.DataObjectDirectory != nil { lineno = lineno + 1 sclNodeObj.IED[i].Services.DataObjectDirectory.BaseNode.Lineno = lineno sclNodeObj.IED[i].Services.DataObjectDirectory.BaseNode.NodeId = scdmgr.RootID + lineno } if sclNodeObj.IED[i].Services.GetDataSetValue != nil { lineno = lineno + 1 sclNodeObj.IED[i].Services.GetDataSetValue.BaseNode.Lineno = lineno sclNodeObj.IED[i].Services.GetDataSetValue.BaseNode.NodeId = scdmgr.RootID + lineno } if sclNodeObj.IED[i].Services.SetDataSetValue != nil { lineno = lineno + 1 sclNodeObj.IED[i].Services.SetDataSetValue.BaseNode.Lineno = lineno sclNodeObj.IED[i].Services.SetDataSetValue.BaseNode.NodeId = scdmgr.RootID + lineno } if sclNodeObj.IED[i].Services.DataSetDirectory != nil { lineno = lineno + 1 sclNodeObj.IED[i].Services.DataSetDirectory.BaseNode.Lineno = lineno sclNodeObj.IED[i].Services.DataSetDirectory.BaseNode.NodeId = scdmgr.RootID + lineno } if sclNodeObj.IED[i].Services.ConfDataSet != nil { lineno = lineno + 1 sclNodeObj.IED[i].Services.ConfDataSet.BaseNode.Lineno = lineno sclNodeObj.IED[i].Services.ConfDataSet.BaseNode.NodeId = scdmgr.RootID + lineno } if sclNodeObj.IED[i].Services.DynDataSet != nil { lineno = lineno + 1 sclNodeObj.IED[i].Services.DynDataSet.BaseNode.Lineno = lineno sclNodeObj.IED[i].Services.DynDataSet.BaseNode.NodeId = scdmgr.RootID + lineno } if sclNodeObj.IED[i].Services.ReadWrite != nil { lineno = lineno + 1 sclNodeObj.IED[i].Services.ReadWrite.BaseNode.Lineno = lineno sclNodeObj.IED[i].Services.ReadWrite.BaseNode.NodeId = scdmgr.RootID + lineno } if sclNodeObj.IED[i].Services.TimerActivatedControl != nil { lineno = lineno + 1 sclNodeObj.IED[i].Services.TimerActivatedControl.BaseNode.Lineno = lineno sclNodeObj.IED[i].Services.TimerActivatedControl.BaseNode.NodeId = scdmgr.RootID + lineno } if sclNodeObj.IED[i].Services.ConfReportControl != nil { lineno = lineno + 1 sclNodeObj.IED[i].Services.ConfReportControl.BaseNode.Lineno = lineno sclNodeObj.IED[i].Services.ConfReportControl.BaseNode.NodeId = scdmgr.RootID + lineno } if sclNodeObj.IED[i].Services.GetCBValues != nil { lineno = lineno + 1 sclNodeObj.IED[i].Services.GetCBValues.BaseNode.Lineno = lineno sclNodeObj.IED[i].Services.GetCBValues.BaseNode.NodeId = scdmgr.RootID + lineno } if sclNodeObj.IED[i].Services.ConfLogControl != nil { lineno = lineno + 1 sclNodeObj.IED[i].Services.ConfLogControl.BaseNode.Lineno = lineno sclNodeObj.IED[i].Services.ConfLogControl.BaseNode.NodeId = scdmgr.RootID + lineno } if sclNodeObj.IED[i].Services.ReportSettings != nil { lineno = lineno + 1 sclNodeObj.IED[i].Services.ReportSettings.BaseNode.Lineno = lineno sclNodeObj.IED[i].Services.ReportSettings.BaseNode.NodeId = scdmgr.RootID + lineno } if sclNodeObj.IED[i].Services.LogSettings != nil { lineno = lineno + 1 sclNodeObj.IED[i].Services.LogSettings.BaseNode.Lineno = lineno sclNodeObj.IED[i].Services.LogSettings.BaseNode.NodeId = scdmgr.RootID + lineno } if sclNodeObj.IED[i].Services.GSESettings != nil { lineno = lineno + 1 sclNodeObj.IED[i].Services.GSESettings.BaseNode.Lineno = lineno sclNodeObj.IED[i].Services.GSESettings.BaseNode.NodeId = scdmgr.RootID + lineno } if sclNodeObj.IED[i].Services.SMVSettings != nil { lineno = lineno + 1 sclNodeObj.IED[i].Services.SMVSettings.BaseNode.Lineno = lineno sclNodeObj.IED[i].Services.SMVSettings.BaseNode.NodeId = scdmgr.RootID + lineno if sclNodeObj.IED[i].Services.SMVSettings.SmpRateObj != nil { lineno = lineno + 1 sclNodeObj.IED[i].Services.SMVSettings.SmpRateObj.BaseNode.Lineno = lineno sclNodeObj.IED[i].Services.SMVSettings.SmpRateObj.BaseNode.NodeId = scdmgr.RootID + lineno lineno = lineno + 1 //多加一行 } } if sclNodeObj.IED[i].Services.GSEDir != nil { lineno = lineno + 1 sclNodeObj.IED[i].Services.GSEDir.BaseNode.Lineno = lineno sclNodeObj.IED[i].Services.GSEDir.BaseNode.NodeId = scdmgr.RootID + lineno } if sclNodeObj.IED[i].Services.GOOSE != nil { lineno = lineno + 1 sclNodeObj.IED[i].Services.GOOSE.BaseNode.Lineno = lineno sclNodeObj.IED[i].Services.GOOSE.BaseNode.NodeId = scdmgr.RootID + lineno } if sclNodeObj.IED[i].Services.GSSE != nil { lineno = lineno + 1 sclNodeObj.IED[i].Services.GSSE.BaseNode.Lineno = lineno sclNodeObj.IED[i].Services.GSSE.BaseNode.NodeId = scdmgr.RootID + lineno } if sclNodeObj.IED[i].Services.SMV != nil { lineno = lineno + 1 sclNodeObj.IED[i].Services.SMV.BaseNode.Lineno = lineno sclNodeObj.IED[i].Services.SMV.BaseNode.NodeId = scdmgr.RootID + lineno } if sclNodeObj.IED[i].Services.FileHandling != nil { lineno = lineno + 1 sclNodeObj.IED[i].Services.FileHandling.BaseNode.Lineno = lineno sclNodeObj.IED[i].Services.FileHandling.BaseNode.NodeId = scdmgr.RootID + lineno } if sclNodeObj.IED[i].Services.ConfLNs != nil { lineno = lineno + 1 sclNodeObj.IED[i].Services.ConfLNs.BaseNode.Lineno = lineno sclNodeObj.IED[i].Services.ConfLNs.BaseNode.NodeId = scdmgr.RootID + lineno } if sclNodeObj.IED[i].Services.ClientServices != nil { lineno = lineno + 1 sclNodeObj.IED[i].Services.ClientServices.BaseNode.Lineno = lineno sclNodeObj.IED[i].Services.ClientServices.BaseNode.NodeId = scdmgr.RootID + lineno } lineno = lineno + 1 //多加一行 } for i1, item2 := range item.AccessPoint { lineno = lineno + 1 item.AccessPoint[i1].BaseNode.Lineno = lineno item.AccessPoint[i1].BaseNode.NodeId = scdmgr.RootID + lineno if len(item.AccessPoint[i1].Any) > 0 { lineno = lineno + calNodeAnyLineNumber(item.AccessPoint[i1].Any) } if item.AccessPoint[i1].Priavate != nil { lineno = lineno + 1 item.AccessPoint[i1].Priavate.BaseNode.Lineno = lineno item.AccessPoint[i1].Priavate.BaseNode.NodeId = scdmgr.RootID + lineno if len(item.AccessPoint[i1].Priavate.Any) > 0 { lineno = lineno + calNodeAnyLineNumber(item.AccessPoint[i1].Priavate.Any) lineno = lineno + 1 } } if item.AccessPoint[i1].Server != nil { lineno = lineno + 1 item.AccessPoint[i1].Server.BaseNode.Lineno = lineno item.AccessPoint[i1].Server.BaseNode.NodeId = scdmgr.RootID + lineno //if len(item.AccessPoint[i1].Server.Private) > 0 { //fmt.Println(fmt.Sprintf("=======%s item.AccessPoint[i1].Server.Private:%d", item.Name, len(item.AccessPoint[i1].Server.Private))) //} for i300, _ := range item.AccessPoint[i1].Server.Private { lineno = lineno + 1 item.AccessPoint[i1].Server.Private[i300].BaseNode.Lineno = lineno item.AccessPoint[i1].Server.Private[i300].BaseNode.NodeId = scdmgr.RootID + lineno if len(item.AccessPoint[i1].Server.Private[i300].Any) > 0 { lineno = lineno + calNodeAnyLineNumber(item.AccessPoint[i1].Server.Private[i300].Any) lineno = lineno + 1 } } if item.AccessPoint[i1].Server.Authentication != nil { lineno = lineno + 1 item.AccessPoint[i1].Server.Authentication.BaseNode.Lineno = lineno item.AccessPoint[i1].Server.Authentication.BaseNode.NodeId = scdmgr.RootID + lineno } for i2, item3 := range item2.Server.LDevice { lineno = lineno + 1 item2.Server.LDevice[i2].BaseNode.Lineno = lineno item2.Server.LDevice[i2].BaseNode.NodeId = scdmgr.RootID + lineno if item3.LN0 != nil { lineno = lineno + 1 item2.Server.LDevice[i2].LN0.BaseNode.Lineno = lineno item2.Server.LDevice[i2].LN0.BaseNode.NodeId = scdmgr.RootID + lineno isEmptyNode := true //是否是空节点 if item3.LN0.DataSet != nil { isEmptyNode = false for i3, item4 := range item3.LN0.DataSet { lineno = lineno + 1 item3.LN0.DataSet[i3].BaseNode.Lineno = lineno item3.LN0.DataSet[i3].BaseNode.NodeId = scdmgr.RootID + lineno for i4, _ := range item4.FCDA { lineno = lineno + 1 item4.FCDA[i4].BaseNode.Lineno = lineno item4.FCDA[i4].BaseNode.NodeId = scdmgr.RootID + lineno } for i4, _ := range item4.FCCB { lineno = lineno + 1 item4.FCCB[i4].BaseNode.Lineno = lineno item4.FCCB[i4].BaseNode.NodeId = scdmgr.RootID + lineno } lineno = lineno + 1 //多加一行 } } if item3.LN0.ReportControl != nil { isEmptyNode = false for i3, item4 := range item3.LN0.ReportControl { lineno = lineno + 1 item3.LN0.ReportControl[i3].BaseNode.Lineno = lineno item3.LN0.ReportControl[i3].BaseNode.NodeId = scdmgr.RootID + lineno isEmptyNode2 := true if len(item3.LN0.ReportControl[i3].Private) > 0 { isEmptyNode2 = false //又是南瑞的定义Private子节点 for p1, _ := range item3.LN0.ReportControl[i3].Private { lineno = lineno + 1 item3.LN0.ReportControl[i3].Private[p1].BaseNode.Lineno = lineno item3.LN0.ReportControl[i3].Private[p1].BaseNode.NodeId = scdmgr.RootID + lineno } } if item4.TrgOps != nil { isEmptyNode2 = false lineno = lineno + 1 item3.LN0.ReportControl[i3].TrgOps.BaseNode.Lineno = lineno item3.LN0.ReportControl[i3].TrgOps.BaseNode.NodeId = scdmgr.RootID + lineno } if item4.OptFields != nil { isEmptyNode2 = false lineno = lineno + 1 item3.LN0.ReportControl[i3].OptFields.BaseNode.Lineno = lineno item3.LN0.ReportControl[i3].OptFields.BaseNode.NodeId = scdmgr.RootID + lineno } if item4.RptEnabled != nil { isEmptyNode2 = false lineno = lineno + 1 item3.LN0.ReportControl[i3].RptEnabled.BaseNode.Lineno = lineno item3.LN0.ReportControl[i3].RptEnabled.BaseNode.NodeId = scdmgr.RootID + lineno if len(item4.RptEnabled.ClientLN) > 0 { for c1, _ := range item4.RptEnabled.ClientLN { lineno = lineno + 1 item3.LN0.ReportControl[i3].RptEnabled.ClientLN[c1].BaseNode.Lineno = lineno item3.LN0.ReportControl[i3].RptEnabled.ClientLN[c1].BaseNode.NodeId = scdmgr.RootID + lineno } lineno = lineno + 1 //多加一行RptEnabled结束 } } if !isEmptyNode2 { lineno = lineno + 1 } } } if item3.LN0.LogControl != nil { isEmptyNode = false for i3, item4 := range item3.LN0.LogControl { lineno = lineno + 1 item3.LN0.LogControl[i3].BaseNode.Lineno = lineno item3.LN0.LogControl[i3].BaseNode.NodeId = scdmgr.RootID + lineno if item4.TrgOps != nil { lineno = lineno + 1 item3.LN0.LogControl[i3].TrgOps.BaseNode.Lineno = lineno item3.LN0.LogControl[i3].TrgOps.BaseNode.NodeId = scdmgr.RootID + lineno } lineno = lineno + 1 } } if len(item3.LN0.DOI) > 0 { isEmptyNode = false for i3, item4 := range item3.LN0.DOI { lineno = lineno + 1 item3.LN0.DOI[i3].BaseNode.Lineno = lineno item3.LN0.DOI[i3].BaseNode.NodeId = scdmgr.RootID + lineno if item4.SDI != nil || item4.DAI != nil { if item4.SDI != nil { for i4, sdi1 := range item3.LN0.DOI[i3].SDI { lineno = lineno + 1 item3.LN0.DOI[i3].SDI[i4].BaseNode.Lineno = lineno item3.LN0.DOI[i3].SDI[i4].BaseNode.NodeId = scdmgr.RootID + lineno //fmt.Println(fmt.Sprintf("%s %+v", lineno, sdi1)) if sdi1.SDI != nil { for i04, sdi01 := range item3.LN0.DOI[i3].SDI[i4].SDI { lineno = lineno + 1 item3.LN0.DOI[i3].SDI[i4].SDI[i04].BaseNode.Lineno = lineno item3.LN0.DOI[i3].SDI[i4].SDI[i04].BaseNode.NodeId = scdmgr.RootID + lineno if sdi01.SDI != nil { for i24, _ := range sdi01.SDI { lineno = lineno + 1 sdi01.SDI[i24].BaseNode.Lineno = lineno sdi01.SDI[i24].BaseNode.NodeId = scdmgr.RootID + lineno if sdi01.SDI[i24].DAI != nil { for i25, _ := range sdi01.SDI[i24].DAI { lineno = lineno + 1 sdi01.SDI[i24].DAI[i25].BaseNode.Lineno = lineno sdi01.SDI[i24].DAI[i25].BaseNode.NodeId = scdmgr.RootID + lineno if sdi01.SDI[i24].DAI[i25].Val != nil { lineno = lineno + 1 sdi01.SDI[i24].DAI[i25].Val.BaseNode.Lineno = lineno sdi01.SDI[i24].DAI[i25].Val.BaseNode.NodeId = scdmgr.RootID + lineno lineno = lineno + 1 //多加一行 } } lineno = lineno + 1 //多加一行 } } lineno = lineno + 1 //多加一行 } if sdi1.SDI[i04].DAI != nil { for i05, _ := range sdi1.SDI[i04].DAI { lineno = lineno + 1 sdi1.SDI[i04].DAI[i05].BaseNode.Lineno = lineno sdi1.SDI[i04].DAI[i05].BaseNode.NodeId = scdmgr.RootID + lineno if sdi1.SDI[i04].DAI[i05].Val != nil { lineno = lineno + 1 sdi1.SDI[i04].DAI[i05].Val.BaseNode.Lineno = lineno sdi1.SDI[i04].DAI[i05].Val.BaseNode.NodeId = scdmgr.RootID + lineno lineno = lineno + 1 //多加一行 } } lineno = lineno + 1 //多加一行 } } if len(item3.LN0.DOI[i3].SDI[i4].SDI) > 0 && item3.LN0.DOI[i3].SDI[i4].DAI == nil { lineno = lineno + 1 //多加一行 } } if item4.SDI[i4].DAI != nil { for i5, _ := range item4.SDI[i4].DAI { lineno = lineno + 1 item4.SDI[i4].DAI[i5].BaseNode.Lineno = lineno item4.SDI[i4].DAI[i5].BaseNode.NodeId = scdmgr.RootID + lineno if item4.SDI[i4].DAI[i5].Val != nil { lineno = lineno + 1 item4.SDI[i4].DAI[i5].Val.BaseNode.Lineno = lineno item4.SDI[i4].DAI[i5].Val.BaseNode.NodeId = scdmgr.RootID + lineno lineno = lineno + 1 //多加一行 } } lineno = lineno + 1 //多加一行 } } } if item4.DAI != nil { for i4, _ := range item4.DAI { lineno = lineno + 1 item4.DAI[i4].BaseNode.Lineno = lineno item4.DAI[i4].BaseNode.NodeId = scdmgr.RootID + lineno if item4.DAI[i4].Val != nil { lineno = lineno + 1 item4.DAI[i4].Val.BaseNode.Lineno = lineno item4.DAI[i4].Val.BaseNode.NodeId = scdmgr.RootID + lineno lineno = lineno + 1 //多加一行 } } } lineno = lineno + 1 //多加一行 } } } if item3.LN0.Inputs != nil { isEmptyNode = false lineno = lineno + 1 item2.Server.LDevice[i2].LN0.Inputs.BaseNode.Lineno = lineno item2.Server.LDevice[i2].LN0.Inputs.BaseNode.NodeId = scdmgr.RootID + lineno if len(item3.LN0.Inputs.ExtRef) > 0 { for i3, _ := range item3.LN0.Inputs.ExtRef { lineno = lineno + 1 item3.LN0.Inputs.ExtRef[i3].BaseNode.Lineno = lineno item3.LN0.Inputs.ExtRef[i3].BaseNode.NodeId = scdmgr.RootID + lineno } lineno = lineno + 1 //多加一行 } } if len(item3.LN0.Log) > 0 { isEmptyNode = false for i3, _ := range item3.LN0.Log { lineno = lineno + 1 item3.LN0.Log[i3].BaseNode.Lineno = lineno item3.LN0.Log[i3].BaseNode.NodeId = scdmgr.RootID + lineno } } for i3, _ := range item3.LN0.GSEControl { isEmptyNode = false lineno = lineno + 1 item3.LN0.GSEControl[i3].BaseNode.Lineno = lineno item3.LN0.GSEControl[i3].BaseNode.NodeId = scdmgr.RootID + lineno if item3.LN0.GSEControl[i3].Private != nil || len(item3.LN0.GSEControl[i3].IEDName) > 0 { if item3.LN0.GSEControl[i3].Private != nil { //又是南瑞的定义Private子节点sznari:P lineno = lineno + 1 item3.LN0.GSEControl[i3].Private.BaseNode.Lineno = lineno item3.LN0.GSEControl[i3].Private.BaseNode.NodeId = scdmgr.RootID + lineno //fmt.Println(fmt.Sprintf("%d %+v", lineno, item3.LN0.GSEControl[i3].Private)) if len(item3.LN0.GSEControl[i3].Private.Any) > 0 { lineno = lineno + calNodeAnyLineNumber(item3.LN0.GSEControl[i3].Private.Any) lineno = lineno + 1 //多加一行 } } if len(item3.LN0.GSEControl[i3].IEDName) > 0 { for i4, _ := range item3.LN0.GSEControl[i3].IEDName { lineno = lineno + 1 item3.LN0.GSEControl[i3].IEDName[i4].BaseNode.Lineno = lineno item3.LN0.GSEControl[i3].IEDName[i4].BaseNode.NodeId = scdmgr.RootID + lineno } } lineno = lineno + 1 //多加一行 } } if len(item3.LN0.SampledValueControl) > 0 { isEmptyNode = false for i3, _ := range item3.LN0.SampledValueControl { lineno = lineno + 1 item3.LN0.SampledValueControl[i3].BaseNode.Lineno = lineno item3.LN0.SampledValueControl[i3].BaseNode.NodeId = scdmgr.RootID + lineno if len(item3.LN0.SampledValueControl[i3].Private) > 0 { for _, pitem := range item3.LN0.SampledValueControl[i3].Private { lineno = lineno + 1 if len(pitem.Any) > 0 { lineno = lineno + calNodeAnyLineNumber(pitem.Any) lineno = lineno + 1 } } } if len(item3.LN0.SampledValueControl[i3].IEDName) > 0 { for i4, _ := range item3.LN0.SampledValueControl[i3].IEDName { lineno = lineno + 1 item3.LN0.SampledValueControl[i3].IEDName[i4].BaseNode.Lineno = lineno item3.LN0.SampledValueControl[i3].IEDName[i4].BaseNode.NodeId = scdmgr.RootID + lineno } } lineno = lineno + 1 item3.LN0.SampledValueControl[i3].SmvOpts.BaseNode.Lineno = lineno item3.LN0.SampledValueControl[i3].SmvOpts.BaseNode.NodeId = scdmgr.RootID + lineno lineno = lineno + 1 //多加一行 } } if item3.LN0.SettingControl != nil { isEmptyNode = false lineno = lineno + 1 item3.LN0.SettingControl.BaseNode.Lineno = lineno item3.LN0.SettingControl.BaseNode.NodeId = scdmgr.RootID + lineno } if item3.LN0.SCLControl != nil { isEmptyNode = false lineno = lineno + 1 item3.LN0.SCLControl.BaseNode.Lineno = lineno item3.LN0.SCLControl.BaseNode.NodeId = scdmgr.RootID + lineno } if len(item3.LN0.Any) > 0 { isEmptyNode = false lineno = lineno + calNodeAnyLineNumber(item3.LN0.Any) } if !isEmptyNode { lineno = lineno + 1 //多加一行:LN0 } } if len(item3.LN) > 0 { for i2, _ := range item3.LN { lineno = lineno + 1 item3.LN[i2].BaseNode.Lineno = lineno item3.LN[i2].BaseNode.NodeId = scdmgr.RootID + lineno if len(item3.LN[i2].Any) > 0 { anyLines := calNodeAnyLineNumber(item3.LN[i2].Any) lineno = lineno + anyLines } if item3.LN[i2].DataSet != nil { for i3, item4 := range item3.LN[i2].DataSet { lineno = lineno + 1 item3.LN[i2].DataSet[i3].BaseNode.Lineno = lineno item3.LN[i2].DataSet[i3].BaseNode.NodeId = scdmgr.RootID + lineno for i4, _ := range item4.FCDA { lineno = lineno + 1 item4.FCDA[i4].BaseNode.Lineno = lineno item4.FCDA[i4].BaseNode.NodeId = scdmgr.RootID + lineno } for i4, _ := range item4.FCCB { lineno = lineno + 1 item4.FCCB[i4].BaseNode.Lineno = lineno item4.FCCB[i4].BaseNode.NodeId = scdmgr.RootID + lineno } lineno = lineno + 1 //多加一行 } } if item3.LN[i2].ReportControl != nil { for i3, item4 := range item3.LN[i2].ReportControl { lineno = lineno + 1 item3.LN[i2].ReportControl[i3].BaseNode.Lineno = lineno item3.LN[i2].ReportControl[i3].BaseNode.NodeId = scdmgr.RootID + lineno isEmptyNode := true if item4.TrgOps != nil { isEmptyNode = false lineno = lineno + 1 item3.LN[i2].ReportControl[i3].TrgOps.BaseNode.Lineno = lineno item3.LN[i2].ReportControl[i3].TrgOps.BaseNode.NodeId = scdmgr.RootID + lineno } if item4.OptFields != nil { isEmptyNode = false lineno = lineno + 1 item3.LN[i2].ReportControl[i3].OptFields.BaseNode.Lineno = lineno item3.LN[i2].ReportControl[i3].OptFields.BaseNode.NodeId = scdmgr.RootID + lineno } if item4.RptEnabled != nil { isEmptyNode = false lineno = lineno + 1 item3.LN[i2].ReportControl[i3].RptEnabled.BaseNode.Lineno = lineno item3.LN[i2].ReportControl[i3].RptEnabled.BaseNode.NodeId = scdmgr.RootID + lineno if len(item4.RptEnabled.ClientLN) > 0 { for c1, _ := range item4.RptEnabled.ClientLN { lineno = lineno + 1 item3.LN[i2].ReportControl[i3].RptEnabled.ClientLN[c1].BaseNode.Lineno = lineno item3.LN[i2].ReportControl[i3].RptEnabled.ClientLN[c1].BaseNode.NodeId = scdmgr.RootID + lineno } lineno = lineno + 1 //多加一行RptEnabled结束 } } if !isEmptyNode { lineno = lineno + 1 } } } if item3.LN[i2].LogControl != nil { for i3, item4 := range item3.LN[i2].LogControl { lineno = lineno + 1 item3.LN[i2].LogControl[i3].BaseNode.Lineno = lineno item3.LN[i2].LogControl[i3].BaseNode.NodeId = scdmgr.RootID + lineno if item4.TrgOps != nil { lineno = lineno + 1 item3.LN[i2].ReportControl[i3].TrgOps.BaseNode.Lineno = lineno item3.LN[i2].ReportControl[i3].TrgOps.BaseNode.NodeId = scdmgr.RootID + lineno } lineno = lineno + 1 } } if len(item3.LN[i2].DOI) > 0 { for i3, item4 := range item3.LN[i2].DOI { lineno = lineno + 1 item3.LN[i2].DOI[i3].BaseNode.Lineno = lineno item3.LN[i2].DOI[i3].BaseNode.NodeId = scdmgr.RootID + lineno if item4.SDI != nil || item4.DAI != nil { if item4.SDI != nil { for i4, sdi1 := range item3.LN[i2].DOI[i3].SDI { lineno = lineno + 1 item3.LN[i2].DOI[i3].SDI[i4].BaseNode.Lineno = lineno item3.LN[i2].DOI[i3].SDI[i4].BaseNode.NodeId = scdmgr.RootID + lineno //fmt.Println(fmt.Sprintf("%d %+v", lineno, sdi1)) if sdi1.SDI != nil { for i04, sdi01 := range item3.LN[i2].DOI[i3].SDI[i4].SDI { lineno = lineno + 1 item3.LN[i2].DOI[i3].SDI[i4].SDI[i04].BaseNode.Lineno = lineno item3.LN[i2].DOI[i3].SDI[i4].SDI[i04].BaseNode.NodeId = scdmgr.RootID + lineno if sdi01.SDI != nil { for i24, _ := range sdi01.SDI { lineno = lineno + 1 sdi01.SDI[i24].BaseNode.Lineno = lineno sdi01.SDI[i24].BaseNode.NodeId = scdmgr.RootID + lineno if sdi01.SDI[i24].DAI != nil { for i25, _ := range sdi01.SDI[i24].DAI { lineno = lineno + 1 sdi01.SDI[i24].DAI[i25].BaseNode.Lineno = lineno sdi01.SDI[i24].DAI[i25].BaseNode.NodeId = scdmgr.RootID + lineno if sdi01.SDI[i24].DAI[i25].Val != nil { lineno = lineno + 1 sdi01.SDI[i24].DAI[i25].Val.BaseNode.Lineno = lineno sdi01.SDI[i24].DAI[i25].Val.BaseNode.NodeId = scdmgr.RootID + lineno lineno = lineno + 1 //多加一行 } } lineno = lineno + 1 //多加一行 } } lineno = lineno + 1 //多加一行 } if sdi1.SDI[i04].DAI != nil { for i05, _ := range sdi1.SDI[i04].DAI { lineno = lineno + 1 sdi1.SDI[i04].DAI[i05].BaseNode.Lineno = lineno sdi1.SDI[i04].DAI[i05].BaseNode.NodeId = scdmgr.RootID + lineno if sdi1.SDI[i04].DAI[i05].Val != nil { lineno = lineno + 1 sdi1.SDI[i04].DAI[i05].Val.BaseNode.Lineno = lineno sdi1.SDI[i04].DAI[i05].Val.BaseNode.NodeId = scdmgr.RootID + lineno lineno = lineno + 1 //多加一行 } } lineno = lineno + 1 //多加一行 } } if len(item3.LN[i2].DOI[i3].SDI[i4].SDI) > 0 && item3.LN[i2].DOI[i3].SDI[i4].DAI == nil { lineno = lineno + 1 //多加一行 } } if item4.SDI[i4].DAI != nil { for i5, _ := range item4.SDI[i4].DAI { lineno = lineno + 1 item4.SDI[i4].DAI[i5].BaseNode.Lineno = lineno item4.SDI[i4].DAI[i5].BaseNode.NodeId = scdmgr.RootID + lineno if item4.SDI[i4].DAI[i5].Val != nil { lineno = lineno + 1 item4.SDI[i4].DAI[i5].Val.BaseNode.Lineno = lineno item4.SDI[i4].DAI[i5].Val.BaseNode.NodeId = scdmgr.RootID + lineno lineno = lineno + 1 //多加一行 } } lineno = lineno + 1 //多加一行 } } } if item4.DAI != nil { for i4, _ := range item4.DAI { lineno = lineno + 1 item4.DAI[i4].BaseNode.Lineno = lineno item4.DAI[i4].BaseNode.NodeId = scdmgr.RootID + lineno if item4.DAI[i4].Val != nil { lineno = lineno + 1 item4.DAI[i4].Val.BaseNode.Lineno = lineno item4.DAI[i4].Val.BaseNode.NodeId = scdmgr.RootID + lineno lineno = lineno + 1 //多加一行 } } } lineno = lineno + 1 //多加一行 } } lineno = lineno + 1 //多加一行LN } if item3.LN[i2].Inputs != nil { lineno = lineno + 1 item2.Server.LDevice[i2].LN[i2].Inputs.BaseNode.Lineno = lineno item2.Server.LDevice[i2].LN[i2].Inputs.BaseNode.NodeId = scdmgr.RootID + lineno if len(item3.LN[i2].Inputs.ExtRef) > 0 { for i3, _ := range item3.LN[i2].Inputs.ExtRef { lineno = lineno + 1 item3.LN[i2].Inputs.ExtRef[i3].BaseNode.Lineno = lineno item3.LN[i2].Inputs.ExtRef[i3].BaseNode.NodeId = scdmgr.RootID + lineno } lineno = lineno + 1 //多加一行 } } if item3.LN[i2].Log != nil { for i3, _ := range item3.LN[i2].Log { lineno = lineno + 1 item3.LN[i2].Log[i3].BaseNode.Lineno = lineno item3.LN[i2].Log[i3].BaseNode.NodeId = scdmgr.RootID + lineno } } } } if item3.LN0 != nil || len(item3.LN) > 0 { lineno = lineno + 1 //多加一行 LDevice } } for i2, _ := range item.AccessPoint[i1].GOOSESecurity { lineno = lineno + 1 item.AccessPoint[i1].GOOSESecurity[i2].BaseNode.Lineno = lineno item.AccessPoint[i1].GOOSESecurity[i2].BaseNode.NodeId = scdmgr.RootID + lineno isEmptyNode := true if item.AccessPoint[i1].GOOSESecurity[i2].Subject != nil { isEmptyNode = false lineno = lineno + 1 item.AccessPoint[i1].GOOSESecurity[i2].Subject.BaseNode.Lineno = lineno item.AccessPoint[i1].GOOSESecurity[i2].Subject.BaseNode.NodeId = scdmgr.RootID + lineno } if item.AccessPoint[i1].GOOSESecurity[i2].IssuerName != nil { isEmptyNode = false lineno = lineno + 1 item.AccessPoint[i1].GOOSESecurity[i2].IssuerName.BaseNode.Lineno = lineno item.AccessPoint[i1].GOOSESecurity[i2].IssuerName.BaseNode.NodeId = scdmgr.RootID + lineno } if !isEmptyNode { lineno = lineno + 1 //多加一个结束节点 } } for i2, _ := range item.AccessPoint[i1].SMVSecurity { lineno = lineno + 1 item.AccessPoint[i1].SMVSecurity[i2].BaseNode.Lineno = lineno item.AccessPoint[i1].SMVSecurity[i2].BaseNode.NodeId = scdmgr.RootID + lineno isEmptyNode := true if item.AccessPoint[i1].SMVSecurity[i2].Subject != nil { isEmptyNode = false lineno = lineno + 1 item.AccessPoint[i1].SMVSecurity[i2].Subject.BaseNode.Lineno = lineno item.AccessPoint[i1].SMVSecurity[i2].Subject.BaseNode.NodeId = scdmgr.RootID + lineno } if item.AccessPoint[i1].SMVSecurity[i2].IssuerName != nil { lineno = lineno + 1 item.AccessPoint[i1].SMVSecurity[i2].IssuerName.BaseNode.Lineno = lineno item.AccessPoint[i1].SMVSecurity[i2].IssuerName.BaseNode.NodeId = scdmgr.RootID + lineno } if !isEmptyNode { lineno = lineno + 1 //多加一个结束节点 } } lineno = lineno + 1 //多加一行 Server } lineno = lineno + 1 //多加一行 AccessPoint } lineno = lineno + 1 //多加一行 } if sclNodeObj.DataTypeTemplates != nil { lineno = lineno + 1 sclNodeObj.DataTypeTemplates.BaseNode.Lineno = lineno sclNodeObj.DataTypeTemplates.BaseNode.NodeId = scdmgr.RootID + lineno for i, item := range sclNodeObj.DataTypeTemplates.LNodeType { lineno = lineno + 1 sclNodeObj.DataTypeTemplates.LNodeType[i].BaseNode.Lineno = lineno sclNodeObj.DataTypeTemplates.LNodeType[i].BaseNode.NodeId = scdmgr.RootID + lineno for i1, _ := range item.DO { lineno = lineno + 1 sclNodeObj.DataTypeTemplates.LNodeType[i].DO[i1].BaseNode.Lineno = lineno sclNodeObj.DataTypeTemplates.LNodeType[i].DO[i1].BaseNode.NodeId = scdmgr.RootID + lineno } lineno = lineno + 1 //多加一行 } for i, item := range sclNodeObj.DataTypeTemplates.DOType { lineno = lineno + 1 sclNodeObj.DataTypeTemplates.DOType[i].BaseNode.Lineno = lineno sclNodeObj.DataTypeTemplates.DOType[i].BaseNode.NodeId = scdmgr.RootID + lineno for i1, _ := range item.SDO { lineno = lineno + 1 sclNodeObj.DataTypeTemplates.DOType[i].SDO[i1].BaseNode.Lineno = lineno sclNodeObj.DataTypeTemplates.DOType[i].SDO[i1].BaseNode.NodeId = scdmgr.RootID + lineno } for i1, _ := range item.DA { lineno = lineno + 1 sclNodeObj.DataTypeTemplates.DOType[i].DA[i1].BaseNode.Lineno = lineno sclNodeObj.DataTypeTemplates.DOType[i].DA[i1].BaseNode.NodeId = scdmgr.RootID + lineno if sclNodeObj.DataTypeTemplates.DOType[i].DA[i1].Val != nil { lineno = lineno + 1 sclNodeObj.DataTypeTemplates.DOType[i].DA[i1].Val.BaseNode.Lineno = lineno sclNodeObj.DataTypeTemplates.DOType[i].DA[i1].Val.BaseNode.NodeId = scdmgr.RootID + lineno lineno = lineno + 1 //多加一行 } } lineno = lineno + 1 //多加一行 } for i, item := range sclNodeObj.DataTypeTemplates.DAType { lineno = lineno + 1 sclNodeObj.DataTypeTemplates.DAType[i].BaseNode.Lineno = lineno sclNodeObj.DataTypeTemplates.DAType[i].BaseNode.NodeId = scdmgr.RootID + lineno for i1, _ := range item.BDA { lineno = lineno + 1 sclNodeObj.DataTypeTemplates.DAType[i].BDA[i1].BaseNode.Lineno = lineno sclNodeObj.DataTypeTemplates.DAType[i].BDA[i1].BaseNode.NodeId = scdmgr.RootID + lineno if sclNodeObj.DataTypeTemplates.DAType[i].BDA[i1].Val != nil { lineno = lineno + 1 sclNodeObj.DataTypeTemplates.DAType[i].BDA[i1].Val.BaseNode.Lineno = lineno sclNodeObj.DataTypeTemplates.DAType[i].BDA[i1].Val.BaseNode.NodeId = scdmgr.RootID + lineno lineno = lineno + 1 //多加一行 } } lineno = lineno + 1 //多加一行 } for i, item := range sclNodeObj.DataTypeTemplates.EnumType { lineno = lineno + 1 sclNodeObj.DataTypeTemplates.EnumType[i].BaseNode.Lineno = lineno sclNodeObj.DataTypeTemplates.EnumType[i].BaseNode.NodeId = scdmgr.RootID + lineno if len(item.EnumVal) > 0 { for i1, _ := range item.EnumVal { lineno = lineno + 1 sclNodeObj.DataTypeTemplates.EnumType[i].EnumVal[i1].BaseNode.Lineno = lineno sclNodeObj.DataTypeTemplates.EnumType[i].EnumVal[i1].BaseNode.NodeId = scdmgr.RootID + lineno } lineno = lineno + 1 //多加一行 } } } //logger.Logger.Debug(fmt.Sprintf("\n-----GlobalNodeMap------- \n:%+v", GlobalNodeMap)) xmlStr, err := xml.MarshalIndent(sclNodeObj, "", " ") if err == nil { //生成解析完成结果副本文件 os.WriteFile(scdPath+".parsed.xml", xmlStr, fs.ModePerm) } else { mqtt.PublishMessage(fmt.Sprintf("/jujutong/scd_check_tools/parse/%s/%d/error", stationid, scdmgr.RootID), scdName+"格式化时发生错误,解析终止!") logger.Logger.Error(err) new(TaskMgr).SetStep(scdid, enum.TaskStep_SCD_Parse.Code(), 3, err.Error()) return "", err } scdid = tools.IsEmpty(scdmgr.RootID) //新的scd文件 stationidint, _ := strconv.Atoi(stationid) newscdid, err := scdmgr.Init(stationidint, scdName, scdPath, 0, 0) if err != nil { mqtt.PublishMessage(fmt.Sprintf("/jujutong/scd_check_tools/parse/%s/%d/error", stationid, scdmgr.RootID), scdName+"初始化创建时发生错误,解析终止!") logger.Logger.Error(err) new(TaskMgr).SetStep(scdid, enum.TaskStep_SCD_Parse.Code(), 3, err.Error()) return "", err } scdmgr.RootID = newscdid //间隔解析.如果间隔解析是Bay方式,需要根据节点数据进行解析 db.Raw("delete from t_area_ied_relation where scd_id=? ", scdmgr.RootID).Exec() db.Raw("delete from t_substation_area where scd_id=? ", scdmgr.RootID).Exec() if isBay { logger.Logger.Debug(fmt.Sprintf("当前采集Bay间隔模式")) scdmgr.AreaMgr.ParseBay(stationidint, bayList) } else { logger.Logger.Debug(fmt.Sprintf("当前采集IED分析间隔模式,共解析IED节点数:%d", len(iedlist))) go func(stationid, scdid, scdName string, iedtotal int) { //检查间隔是否解析完成,完成后发送通知 for { time.Sleep(2 * time.Second) dbo := orm.NewOrm() rs := []orm.Params{} _, err := dbo.Raw("select count(1) cnt from t_area_ied_relation where scd_id=? ", scdid).Values(&rs) if err != nil { logger.Logger.Error(err) return } if len(rs) > 0 && tools.IsEmpty(rs[0]["cnt"]) == tools.IsEmpty(iedtotal) { mqttData := map[string]string{"name": scdName, "stationid": stationid, "rootid": scdid, "state": "1", "node": "load-area", "msg": "间隔分析完成"} dataMsg, _ = json.Marshal(mqttData) mqtt.PublishMessage(fmt.Sprintf("/jujutong/scd_check_tools/parse/%s/%d", stationid, scdmgr.RootID), string(dataMsg)) checkAreaMgr := new(CheckAreaMgr) checkAreaMgr.ScdId, _ = strconv.ParseInt(scdid, 10, 64) checkAreaMgr.ParseModelArea() return } } }(stationid, tools.IsEmpty(scdmgr.RootID), scdName, len(iedlist)) for _, ieditem := range iedlist { scdmgr.AreaMgr.AppendIedNode(scdmgr.RootID, ieditem.BaseNode.NodeId, ieditem.Name, ieditem.Desc) } } mqttData := map[string]string{"name": scdName, "stationid": stationid, "rootid": scdid, "state": "1", "node": "load-file", "msg": "文件加载完成"} dataMsg, _ = json.Marshal(mqttData) mqtt.PublishMessage(fmt.Sprintf("/jujutong/scd_check_tools/parse/%s/%d", stationid, scdmgr.RootID), string(dataMsg)) //写入ied节点到节点表中 db.Raw("update t_scd_scl set node_cnt=? where id=?", node_cnt, scdmgr.RootID).Exec() db.Raw("delete from t_scd_node_scl where scd_id=?", scdmgr.RootID).Exec() node_ins := "insert into t_scd_node_scl(id,scd_id,node_name,ied_name,line_no)values" _, err = db.Raw(fmt.Sprintf("%s%s", node_ins, strings.Join(iedList, ","))).Exec() if err != nil { logger.Logger.Error(err, fmt.Sprintf("SQL:%s", fmt.Sprintf("%s%s", node_ins, strings.Join(iedList, ",")))) } new(TaskMgr).SetStep(tools.IsEmpty(scdmgr.RootID), enum.TaskStep_SCD_Parse.Code(), 2) return fmt.Sprintf("%d", scdmgr.RootID), nil } //scd完整解析过程二:校验SCD func (c *ScdParse) XmlCheckParse(scdid int64) (err error) { //开始校验该SCD new(TaskMgr).SetStep(tools.IsEmpty(scdid), enum.TaskStep_SCD_syntax_parse.Code(), 1) _, err = c.SchemaValid(tools.IsEmpty(scdid), "", "") if err != nil { logger.Logger.Error(err) new(TaskMgr).SetStep(tools.IsEmpty(scdid), enum.TaskStep_SCD_syntax_parse.Code(), 3, err.Error()) return err } scdmgr := new(ScdNode) scdmgr.SetUserInfo(c.GetUserInfo()) scdmgr.RootID = scdid scdmgr.Flush() return nil } //解析SCD到内存中 func (c *ScdParse) XmlParse(stationid, scdPath, scdName string, isenable int, autocompscdid ...int64) (err error) { if scdPath == "" || scdName == "" { return errors.New("无效的SCD名称") } logger.Logger.Debug("===开始解析SCD:" + scdName) c.SclModel = map[string]interface{}{} fileFirstChar := scdPath[0:1] fline := string(os.PathSeparator) if fileFirstChar != "." && fileFirstChar != "G" { if fileFirstChar == fline { scdPath = "." + scdPath } else { scdPath = "." + fline + scdPath } } //判断该scd是否已经存在,已存在则不再解析 db := orm.NewOrm() sql := "select id from t_scd_scl where scd_name=? and path=?" rowset := []orm.Params{} db.Raw(sql, scdName, scdPath).Values(&rowset) scdid := "" if len(rowset) > 0 { scdid = tools.IsEmpty(rowset[0]["id"]) if _, h := global.GoCahce.Get(scdid); h { //已经解析到内存中,则不再解析 return nil } else { db.Raw("update t_scd_scl set enable=? where id=?", isenable, scdid).Exec() //判断是否有解析完成的持久化文件 parsedFile := strings.ReplaceAll(scdPath, "\\", "/") + ".parsed.xml" f, err := os.Stat(parsedFile) logger.Logger.Debug(fmt.Sprintf("%s:%+v ====== %+v", parsedFile, f, err)) if f != nil || os.IsExist(err) { logger.Logger.Debug("=====结果文件" + scdPath + ".parsed.xml已存在,直接加载") data := map[string]string{"name": scdName, "stationid": stationid, "rootid": "", "state": "0", "node": "load-file", "msg": ""} dataMsg, _ := json.Marshal(data) mqtt.PublishMessage(fmt.Sprintf("/jujutong/scd_check_tools/parse/%s", stationid), string(dataMsg)) sclNodeObj, err := c.LoadScdXml(scdPath + ".parsed.xml") if err == nil { global.GoCahce.Set(scdPath, scdid, -1) global.GoCahce.Set(scdid, sclNodeObj, -1) data := map[string]string{"name": scdName, "stationid": stationid, "rootid": "", "state": "1", "node": "load-file", "msg": ""} dataMsg, _ := json.Marshal(data) mqtt.PublishMessage(fmt.Sprintf("/jujutong/scd_check_tools/parse/%s", stationid), string(dataMsg)) c.cacheGlobalNodeIds(scdid, sclNodeObj) //crc提取 //go new(ScdMgr).CrcCheck(scdid) //开始校验该SCD //go c.SchemaValid(scdid, scdName, scdPath) } else { logger.Logger.Error(err, "异常SCD文件:"+scdPath) return err } return nil } else { //没有缓存,也没有解析结果文件,则重新解析 logger.Logger.Debug("=====没有缓存及结果文件,全新解析:" + scdPath) } } } //判断当前服务器性能是否达到阀值 canparse, msg := new(ScdMgr).CheckParseMaxLimit() if canparse { return errors.New("系统繁忙:" + msg + ",请稍候(约5分钟)再试") } logger.Logger.Debug(fmt.Sprintf("=======开始加载解析SCD:%s", scdName)) data := map[string]string{"name": scdName, "stationid": stationid, "rootid": "", "state": "0", "node": "load-file", "msg": ""} dataMsg, _ := json.Marshal(data) mqtt.PublishMessage(fmt.Sprintf("/jujutong/scd_check_tools/parse/%s", stationid), string(dataMsg)) //新解析scd,先进行文件格式化。搞成一行一行的 node_cnt, err2 := c.ForamtScdPath(scdPath) if err2 != nil { //解除该站的签入锁定,如果是签入解析 new(Flow).CheckInFail(stationid) mqtt.PublishMessage(fmt.Sprintf("/jujutong/scd_check_tools/parse/%s/%d/error", stationid, 0), scdName+"解析时发生错误,解析终止!") logger.Logger.Error(err2, "异常SCD文件:"+scdPath) return err2 } sclNodeObj, err := c.LoadScdXml(scdPath) if err != nil { //解除该站的签入锁定,如果是签入解析 new(Flow).CheckInFail(stationid) mqtt.PublishMessage(fmt.Sprintf("/jujutong/scd_check_tools/parse/%s/%d/error", stationid, 0), scdName+"解析时发生错误,解析终止!") logger.Logger.Error(err, "异常SCD文件:"+scdPath) return err } iedList := []string{} isBay := false //是否有间隔节点 bayList := []*node_attr.NVoltage{} iedlist := []*node_attr.NIED{} scdmgr := new(ScdNode) scdmgr.SetUserInfo(c.GetUserInfo()) scdmgr.Idseq = c.Idseq //初始化节点管理对象的ID序列 if scdid == "" { scdmgr.RootID = scdmgr.GetID() } else { scdmgr.RootID, _ = strconv.ParseInt(scdid, 10, 64) } var calNodeAnyLineNumber = func(lst []*node_attr.NAny) int64 { lineno := 0 for _, any1 := range lst { lineno = lineno + 1 if len(any1.Any) > 0 { for _, any2 := range any1.Any { lineno = lineno + 1 if len(any2.Any) > 0 { for range any2.Any { lineno = lineno + 1 } lineno = lineno + 1 } } lineno = lineno + 1 } } return int64(lineno) } lineno := int64(1) //生成节点行号及ID lineno = lineno + 1 sclNodeObj.BaseNode.Lineno = lineno sclNodeObj.BaseNode.NodeId = scdmgr.RootID + sclNodeObj.BaseNode.Lineno for i, _ := range sclNodeObj.Private { lineno = lineno + 1 sclNodeObj.Private[i].BaseNode.Lineno = lineno sclNodeObj.Private[i].BaseNode.NodeId = scdmgr.RootID + lineno //电压级及间隔分析 if len(sclNodeObj.Private[i].Voltage) > 0 { for v1, _ := range sclNodeObj.Private[i].Voltage { lineno = lineno + 1 sclNodeObj.Private[i].Voltage[v1].BaseNode.Lineno = lineno sclNodeObj.Private[i].Voltage[v1].BaseNode.NodeId = scdmgr.RootID + lineno if len(sclNodeObj.Private[i].Voltage[v1].Bay) > 0 { isBay = true bayList = sclNodeObj.Private[i].Voltage for bayi, _ := range sclNodeObj.Private[i].Voltage[v1].Bay { lineno = lineno + 1 sclNodeObj.Private[i].Voltage[v1].Bay[bayi].BaseNode.Lineno = lineno sclNodeObj.Private[i].Voltage[v1].Bay[bayi].BaseNode.NodeId = scdmgr.RootID + lineno if len(sclNodeObj.Private[i].Voltage[v1].Bay[bayi].IED) > 0 { for iedi, _ := range sclNodeObj.Private[i].Voltage[v1].Bay[bayi].IED { lineno = lineno + 1 sclNodeObj.Private[i].Voltage[v1].Bay[bayi].IED[iedi].BaseNode.Lineno = lineno sclNodeObj.Private[i].Voltage[v1].Bay[bayi].IED[iedi].BaseNode.NodeId = scdmgr.RootID + lineno } lineno = lineno + 1 //多加一行 } } lineno = lineno + 1 //多加一行 } } lineno = lineno + 1 //多加一行 } if len(sclNodeObj.Private[i].Any) > 0 { lineno = lineno + calNodeAnyLineNumber(sclNodeObj.Private[i].Any) lineno = lineno + 1 } } if sclNodeObj.Header != nil { lineno = lineno + 1 sclNodeObj.Header.BaseNode.Lineno = lineno sclNodeObj.Header.BaseNode.NodeId = scdmgr.RootID + lineno if sclNodeObj.Header.History != nil { lineno = lineno + 1 sclNodeObj.Header.History.BaseNode.Lineno = lineno sclNodeObj.Header.History.BaseNode.NodeId = scdmgr.RootID + lineno if len(sclNodeObj.Header.History.Hitem) > 0 { for i, _ := range sclNodeObj.Header.History.Hitem { lineno = lineno + 1 sclNodeObj.Header.History.Hitem[i].BaseNode.Lineno = lineno sclNodeObj.Header.History.Hitem[i].BaseNode.NodeId = scdmgr.RootID + lineno } lineno = lineno + 1 //多加一行 } lineno = lineno + 1 } } if sclNodeObj.Substation != nil { lineno = lineno + 1 sclNodeObj.Substation.BaseNode.Lineno = lineno sclNodeObj.Substation.BaseNode.NodeId = scdmgr.RootID + lineno isEmptyNode := true if len(sclNodeObj.Substation.Private) > 0 { isEmptyNode = false for i1, _ := range sclNodeObj.Substation.Private { lineno = lineno + 1 sclNodeObj.Substation.Private[i1].BaseNode.Lineno = lineno sclNodeObj.Substation.Private[i1].BaseNode.NodeId = scdmgr.RootID + lineno if len(sclNodeObj.Substation.Private[i1].Any) > 0 { anyLines := calNodeAnyLineNumber(sclNodeObj.Substation.Private[i1].Any) lineno = lineno + anyLines lineno = lineno + 1 //多加一行Priavate } } } if len(sclNodeObj.Substation.Any) > 0 { isEmptyNode = false anyLines := calNodeAnyLineNumber(sclNodeObj.Substation.Any) lineno = lineno + anyLines } if len(sclNodeObj.Substation.VoltageLevel) > 0 { isEmptyNode = false for i1, _ := range sclNodeObj.Substation.VoltageLevel { lineno = lineno + 1 sclNodeObj.Substation.VoltageLevel[i1].BaseNode.Lineno = lineno sclNodeObj.Substation.VoltageLevel[i1].BaseNode.NodeId = scdmgr.RootID + lineno isEmptyNode := true if len(sclNodeObj.Substation.VoltageLevel[i1].Bay) > 0 { isEmptyNode = false for b1, _ := range sclNodeObj.Substation.VoltageLevel[i1].Bay { lineno = lineno + 1 if len(sclNodeObj.Substation.VoltageLevel[i1].Bay[b1].Any) > 0 { anyLines := calNodeAnyLineNumber(sclNodeObj.Substation.VoltageLevel[i1].Bay[b1].Any) lineno = lineno + anyLines } } } if sclNodeObj.Substation.VoltageLevel[i1].Voltage != nil { isEmptyNode = false lineno = lineno + 1 if len(sclNodeObj.Substation.VoltageLevel[i1].Voltage.Any) > 0 { anyLines := calNodeAnyLineNumber(sclNodeObj.Substation.VoltageLevel[i1].Voltage.Any) lineno = lineno + anyLines } } if len(sclNodeObj.Substation.VoltageLevel[i1].Any) > 0 { isEmptyNode = false anyLines := calNodeAnyLineNumber(sclNodeObj.Substation.VoltageLevel[i1].Any) lineno = lineno + anyLines } if !isEmptyNode { lineno = lineno + 1 //多加一行VoltageLevel } } } if !isEmptyNode { lineno = lineno + 1 } } if sclNodeObj.Communication != nil { lineno = lineno + 1 sclNodeObj.Communication.BaseNode.Lineno = lineno sclNodeObj.Communication.BaseNode.NodeId = scdmgr.RootID + lineno if sclNodeObj.Communication.SubNetwork != nil { for i, item := range sclNodeObj.Communication.SubNetwork { lineno = lineno + 1 sclNodeObj.Communication.SubNetwork[i].BaseNode.Lineno = lineno sclNodeObj.Communication.SubNetwork[i].BaseNode.NodeId = scdmgr.RootID + lineno if sclNodeObj.Communication.SubNetwork[i].BitRate != nil { lineno = lineno + 1 sclNodeObj.Communication.SubNetwork[i].BitRate.BaseNode.Lineno = lineno sclNodeObj.Communication.SubNetwork[i].BitRate.BaseNode.NodeId = scdmgr.RootID + lineno } for i2, item2 := range item.ConnectedAP { lineno = lineno + 1 item.ConnectedAP[i2].BaseNode.Lineno = lineno item.ConnectedAP[i2].BaseNode.NodeId = scdmgr.RootID + lineno if len(item2.Private) > 0 { for p1, _ := range item2.Private { lineno = lineno + 1 item.ConnectedAP[i2].Private[p1].BaseNode.Lineno = lineno item.ConnectedAP[i2].Private[p1].BaseNode.NodeId = scdmgr.RootID + lineno if len(item.ConnectedAP[i2].Private[p1].Any) > 0 { lineno = lineno + calNodeAnyLineNumber(item.ConnectedAP[i2].Private[p1].Any) lineno = lineno + 1 } } } if item2.Address != nil { lineno = lineno + 1 item.ConnectedAP[i2].Address.BaseNode.Lineno = lineno item.ConnectedAP[i2].Address.BaseNode.NodeId = scdmgr.RootID + lineno for i3, _ := range item2.Address.P { lineno = lineno + 1 item2.Address.P[i3].BaseNode.Lineno = lineno item2.Address.P[i3].BaseNode.NodeId = scdmgr.RootID + lineno } lineno = lineno + 1 //多加一行 } if len(item2.GSE) > 0 { for i3, _ := range item2.GSE { lineno = lineno + 1 item2.GSE[i3].BaseNode.Lineno = lineno item2.GSE[i3].BaseNode.NodeId = scdmgr.RootID + lineno if item2.GSE[i3].Address != nil || item2.GSE[i3].MinTime != nil || item2.GSE[i3].MaxTime != nil { if item2.GSE[i3].Address != nil { lineno = lineno + 1 item2.GSE[i3].Address.BaseNode.Lineno = lineno item2.GSE[i3].Address.BaseNode.NodeId = scdmgr.RootID + lineno for i4, _ := range item2.GSE[i3].Address.P { lineno = lineno + 1 item2.GSE[i3].Address.P[i4].BaseNode.Lineno = lineno item2.GSE[i3].Address.P[i4].BaseNode.NodeId = scdmgr.RootID + lineno } lineno = lineno + 1 //多加一行 } if item2.GSE[i3].MinTime != nil { lineno = lineno + 1 item2.GSE[i3].MinTime.BaseNode.Lineno = lineno item2.GSE[i3].MinTime.BaseNode.NodeId = scdmgr.RootID + lineno } if item2.GSE[i3].MaxTime != nil { lineno = lineno + 1 item2.GSE[i3].MaxTime.BaseNode.Lineno = lineno item2.GSE[i3].MaxTime.BaseNode.NodeId = scdmgr.RootID + lineno } lineno = lineno + 1 //多加一行 } } } if len(item2.SMV) > 0 { for i, item3 := range item2.SMV { lineno = lineno + 1 item2.SMV[i].BaseNode.Lineno = lineno item2.SMV[i].BaseNode.NodeId = scdmgr.RootID + lineno isEmptyNode := true if item3.Address != nil { isEmptyNode = false lineno = lineno + 1 item2.SMV[i].Address.BaseNode.Lineno = lineno item2.SMV[i].Address.BaseNode.NodeId = scdmgr.RootID + lineno for i1, _ := range item3.Address.P { lineno = lineno + 1 item3.Address.P[i1].BaseNode.Lineno = lineno item3.Address.P[i1].BaseNode.NodeId = scdmgr.RootID + lineno } if len(item3.Address.P) > 0 { lineno = lineno + 1 //多加一行Address } } if item2.SMV[i].MinTime != nil { isEmptyNode = false lineno = lineno + 1 item2.SMV[i].MinTime.BaseNode.Lineno = lineno item2.SMV[i].MinTime.BaseNode.NodeId = scdmgr.RootID + lineno } if item2.SMV[i].MaxTime != nil { isEmptyNode = false lineno = lineno + 1 item2.SMV[i].MaxTime.BaseNode.Lineno = lineno item2.SMV[i].MaxTime.BaseNode.NodeId = scdmgr.RootID + lineno } if !isEmptyNode { lineno = lineno + 1 //多加一行SMV } } } if len(item2.PhysConn) > 0 { for i, item3 := range item2.PhysConn { lineno = lineno + 1 item2.PhysConn[i].BaseNode.Lineno = lineno item2.PhysConn[i].BaseNode.NodeId = scdmgr.RootID + lineno if len(item3.P) > 0 { for i1, _ := range item3.P { lineno = lineno + 1 item3.P[i1].BaseNode.Lineno = lineno item3.P[i1].BaseNode.NodeId = scdmgr.RootID + lineno } lineno = lineno + 1 //多加一行 } } } if item2.Address != nil || len(item2.GSE) > 0 || len(item2.SMV) > 0 || len(item2.PhysConn) > 0 { lineno = lineno + 1 //多加一行 } } if len(item.ConnectedAP) > 0 || item.BitRate != nil { lineno = lineno + 1 //多加一行:SubNetwork } } lineno = lineno + 1 //多加一行:Communication } } for i, item := range sclNodeObj.IED { lineno = lineno + 1 sclNodeObj.IED[i].BaseNode.Lineno = lineno sclNodeObj.IED[i].BaseNode.NodeId = scdmgr.RootID + lineno iedList = append(iedList, fmt.Sprintf("(%d,%d,'%s','%s',%d)", sclNodeObj.IED[i].BaseNode.NodeId, scdmgr.RootID, "IED", item.Name, lineno)) if !isBay { //非bay模式时,记录所有的IED节点 iedlist = append(iedlist, sclNodeObj.IED[i]) } if item.Priavate != nil { for i1, _ := range item.Priavate { lineno = lineno + 1 item.Priavate[i1].BaseNode.Lineno = lineno item.Priavate[i1].BaseNode.NodeId = scdmgr.RootID + lineno if len(item.Priavate[i1].Any) > 0 { anyLines := calNodeAnyLineNumber(item.Priavate[i1].Any) lineno = lineno + anyLines lineno = lineno + 1 //多加一行Priavate } } } if sclNodeObj.IED[i].Services == nil { logger.Logger.Error(errors.New(fmt.Sprintf("%s中未发现Services定义", sclNodeObj.IED[i].Desc))) } else { lineno = lineno + 1 sclNodeObj.IED[i].Services.BaseNode.Lineno = lineno sclNodeObj.IED[i].Services.BaseNode.NodeId = scdmgr.RootID + lineno if sclNodeObj.IED[i].Services.DynAssociation != nil { lineno = lineno + 1 sclNodeObj.IED[i].Services.DynAssociation.BaseNode.Lineno = lineno sclNodeObj.IED[i].Services.DynAssociation.BaseNode.NodeId = scdmgr.RootID + lineno } if sclNodeObj.IED[i].Services.SettingGroups != nil { lineno = lineno + 1 sclNodeObj.IED[i].Services.SettingGroups.BaseNode.Lineno = lineno sclNodeObj.IED[i].Services.SettingGroups.BaseNode.NodeId = scdmgr.RootID + lineno if sclNodeObj.IED[i].Services.SettingGroups.SGEdit != nil || sclNodeObj.IED[i].Services.SettingGroups.ConfSG != nil { if sclNodeObj.IED[i].Services.SettingGroups.SGEdit != nil { lineno = lineno + 1 sclNodeObj.IED[i].Services.SettingGroups.SGEdit.BaseNode.Lineno = lineno sclNodeObj.IED[i].Services.SettingGroups.SGEdit.BaseNode.NodeId = scdmgr.RootID + lineno } if sclNodeObj.IED[i].Services.SettingGroups.ConfSG != nil { lineno = lineno + 1 sclNodeObj.IED[i].Services.SettingGroups.ConfSG.BaseNode.Lineno = lineno sclNodeObj.IED[i].Services.SettingGroups.ConfSG.BaseNode.NodeId = scdmgr.RootID + lineno } lineno = lineno + 1 //多加一行 } } if sclNodeObj.IED[i].Services.GetDirectory != nil { lineno = lineno + 1 sclNodeObj.IED[i].Services.GetDirectory.BaseNode.Lineno = lineno sclNodeObj.IED[i].Services.GetDirectory.BaseNode.NodeId = scdmgr.RootID + lineno } if sclNodeObj.IED[i].Services.GetDataObjectDefinition != nil { lineno = lineno + 1 sclNodeObj.IED[i].Services.GetDataObjectDefinition.BaseNode.Lineno = lineno sclNodeObj.IED[i].Services.GetDataObjectDefinition.BaseNode.NodeId = scdmgr.RootID + lineno } if sclNodeObj.IED[i].Services.DataObjectDirectory != nil { lineno = lineno + 1 sclNodeObj.IED[i].Services.DataObjectDirectory.BaseNode.Lineno = lineno sclNodeObj.IED[i].Services.DataObjectDirectory.BaseNode.NodeId = scdmgr.RootID + lineno } if sclNodeObj.IED[i].Services.GetDataSetValue != nil { lineno = lineno + 1 sclNodeObj.IED[i].Services.GetDataSetValue.BaseNode.Lineno = lineno sclNodeObj.IED[i].Services.GetDataSetValue.BaseNode.NodeId = scdmgr.RootID + lineno } if sclNodeObj.IED[i].Services.SetDataSetValue != nil { lineno = lineno + 1 sclNodeObj.IED[i].Services.SetDataSetValue.BaseNode.Lineno = lineno sclNodeObj.IED[i].Services.SetDataSetValue.BaseNode.NodeId = scdmgr.RootID + lineno } if sclNodeObj.IED[i].Services.DataSetDirectory != nil { lineno = lineno + 1 sclNodeObj.IED[i].Services.DataSetDirectory.BaseNode.Lineno = lineno sclNodeObj.IED[i].Services.DataSetDirectory.BaseNode.NodeId = scdmgr.RootID + lineno } if sclNodeObj.IED[i].Services.ConfDataSet != nil { lineno = lineno + 1 sclNodeObj.IED[i].Services.ConfDataSet.BaseNode.Lineno = lineno sclNodeObj.IED[i].Services.ConfDataSet.BaseNode.NodeId = scdmgr.RootID + lineno } if sclNodeObj.IED[i].Services.DynDataSet != nil { lineno = lineno + 1 sclNodeObj.IED[i].Services.DynDataSet.BaseNode.Lineno = lineno sclNodeObj.IED[i].Services.DynDataSet.BaseNode.NodeId = scdmgr.RootID + lineno } if sclNodeObj.IED[i].Services.ReadWrite != nil { lineno = lineno + 1 sclNodeObj.IED[i].Services.ReadWrite.BaseNode.Lineno = lineno sclNodeObj.IED[i].Services.ReadWrite.BaseNode.NodeId = scdmgr.RootID + lineno } if sclNodeObj.IED[i].Services.TimerActivatedControl != nil { lineno = lineno + 1 sclNodeObj.IED[i].Services.TimerActivatedControl.BaseNode.Lineno = lineno sclNodeObj.IED[i].Services.TimerActivatedControl.BaseNode.NodeId = scdmgr.RootID + lineno } if sclNodeObj.IED[i].Services.ConfReportControl != nil { lineno = lineno + 1 sclNodeObj.IED[i].Services.ConfReportControl.BaseNode.Lineno = lineno sclNodeObj.IED[i].Services.ConfReportControl.BaseNode.NodeId = scdmgr.RootID + lineno } if sclNodeObj.IED[i].Services.GetCBValues != nil { lineno = lineno + 1 sclNodeObj.IED[i].Services.GetCBValues.BaseNode.Lineno = lineno sclNodeObj.IED[i].Services.GetCBValues.BaseNode.NodeId = scdmgr.RootID + lineno } if sclNodeObj.IED[i].Services.ConfLogControl != nil { lineno = lineno + 1 sclNodeObj.IED[i].Services.ConfLogControl.BaseNode.Lineno = lineno sclNodeObj.IED[i].Services.ConfLogControl.BaseNode.NodeId = scdmgr.RootID + lineno } if sclNodeObj.IED[i].Services.ReportSettings != nil { lineno = lineno + 1 sclNodeObj.IED[i].Services.ReportSettings.BaseNode.Lineno = lineno sclNodeObj.IED[i].Services.ReportSettings.BaseNode.NodeId = scdmgr.RootID + lineno } if sclNodeObj.IED[i].Services.LogSettings != nil { lineno = lineno + 1 sclNodeObj.IED[i].Services.LogSettings.BaseNode.Lineno = lineno sclNodeObj.IED[i].Services.LogSettings.BaseNode.NodeId = scdmgr.RootID + lineno } if sclNodeObj.IED[i].Services.GSESettings != nil { lineno = lineno + 1 sclNodeObj.IED[i].Services.GSESettings.BaseNode.Lineno = lineno sclNodeObj.IED[i].Services.GSESettings.BaseNode.NodeId = scdmgr.RootID + lineno } if sclNodeObj.IED[i].Services.SMVSettings != nil { lineno = lineno + 1 sclNodeObj.IED[i].Services.SMVSettings.BaseNode.Lineno = lineno sclNodeObj.IED[i].Services.SMVSettings.BaseNode.NodeId = scdmgr.RootID + lineno if sclNodeObj.IED[i].Services.SMVSettings.SmpRateObj != nil { lineno = lineno + 1 sclNodeObj.IED[i].Services.SMVSettings.SmpRateObj.BaseNode.Lineno = lineno sclNodeObj.IED[i].Services.SMVSettings.SmpRateObj.BaseNode.NodeId = scdmgr.RootID + lineno lineno = lineno + 1 //多加一行 } } if sclNodeObj.IED[i].Services.GSEDir != nil { lineno = lineno + 1 sclNodeObj.IED[i].Services.GSEDir.BaseNode.Lineno = lineno sclNodeObj.IED[i].Services.GSEDir.BaseNode.NodeId = scdmgr.RootID + lineno } if sclNodeObj.IED[i].Services.GOOSE != nil { lineno = lineno + 1 sclNodeObj.IED[i].Services.GOOSE.BaseNode.Lineno = lineno sclNodeObj.IED[i].Services.GOOSE.BaseNode.NodeId = scdmgr.RootID + lineno } if sclNodeObj.IED[i].Services.GSSE != nil { lineno = lineno + 1 sclNodeObj.IED[i].Services.GSSE.BaseNode.Lineno = lineno sclNodeObj.IED[i].Services.GSSE.BaseNode.NodeId = scdmgr.RootID + lineno } if sclNodeObj.IED[i].Services.SMV != nil { lineno = lineno + 1 sclNodeObj.IED[i].Services.SMV.BaseNode.Lineno = lineno sclNodeObj.IED[i].Services.SMV.BaseNode.NodeId = scdmgr.RootID + lineno } if sclNodeObj.IED[i].Services.FileHandling != nil { lineno = lineno + 1 sclNodeObj.IED[i].Services.FileHandling.BaseNode.Lineno = lineno sclNodeObj.IED[i].Services.FileHandling.BaseNode.NodeId = scdmgr.RootID + lineno } if sclNodeObj.IED[i].Services.ConfLNs != nil { lineno = lineno + 1 sclNodeObj.IED[i].Services.ConfLNs.BaseNode.Lineno = lineno sclNodeObj.IED[i].Services.ConfLNs.BaseNode.NodeId = scdmgr.RootID + lineno } if sclNodeObj.IED[i].Services.ClientServices != nil { lineno = lineno + 1 sclNodeObj.IED[i].Services.ClientServices.BaseNode.Lineno = lineno sclNodeObj.IED[i].Services.ClientServices.BaseNode.NodeId = scdmgr.RootID + lineno } lineno = lineno + 1 //多加一行 } for i1, item2 := range item.AccessPoint { lineno = lineno + 1 item.AccessPoint[i1].BaseNode.Lineno = lineno item.AccessPoint[i1].BaseNode.NodeId = scdmgr.RootID + lineno if len(item.AccessPoint[i1].Any) > 0 { lineno = lineno + calNodeAnyLineNumber(item.AccessPoint[i1].Any) } if item.AccessPoint[i1].Priavate != nil { lineno = lineno + 1 item.AccessPoint[i1].Priavate.BaseNode.Lineno = lineno item.AccessPoint[i1].Priavate.BaseNode.NodeId = scdmgr.RootID + lineno if len(item.AccessPoint[i1].Priavate.Any) > 0 { lineno = lineno + calNodeAnyLineNumber(item.AccessPoint[i1].Priavate.Any) lineno = lineno + 1 } } if item.AccessPoint[i1].Server != nil { lineno = lineno + 1 item.AccessPoint[i1].Server.BaseNode.Lineno = lineno item.AccessPoint[i1].Server.BaseNode.NodeId = scdmgr.RootID + lineno //if len(item.AccessPoint[i1].Server.Private) > 0 { //fmt.Println(fmt.Sprintf("=======%s item.AccessPoint[i1].Server.Private:%d", item.Name, len(item.AccessPoint[i1].Server.Private))) //} for i300, _ := range item.AccessPoint[i1].Server.Private { lineno = lineno + 1 item.AccessPoint[i1].Server.Private[i300].BaseNode.Lineno = lineno item.AccessPoint[i1].Server.Private[i300].BaseNode.NodeId = scdmgr.RootID + lineno if len(item.AccessPoint[i1].Server.Private[i300].Any) > 0 { lineno = lineno + calNodeAnyLineNumber(item.AccessPoint[i1].Server.Private[i300].Any) lineno = lineno + 1 } } if item.AccessPoint[i1].Server.Authentication != nil { lineno = lineno + 1 item.AccessPoint[i1].Server.Authentication.BaseNode.Lineno = lineno item.AccessPoint[i1].Server.Authentication.BaseNode.NodeId = scdmgr.RootID + lineno } for i2, item3 := range item2.Server.LDevice { lineno = lineno + 1 item2.Server.LDevice[i2].BaseNode.Lineno = lineno item2.Server.LDevice[i2].BaseNode.NodeId = scdmgr.RootID + lineno if item3.LN0 != nil { lineno = lineno + 1 item2.Server.LDevice[i2].LN0.BaseNode.Lineno = lineno item2.Server.LDevice[i2].LN0.BaseNode.NodeId = scdmgr.RootID + lineno isEmptyNode := true //是否是空节点 if item3.LN0.DataSet != nil { isEmptyNode = false for i3, item4 := range item3.LN0.DataSet { lineno = lineno + 1 item3.LN0.DataSet[i3].BaseNode.Lineno = lineno item3.LN0.DataSet[i3].BaseNode.NodeId = scdmgr.RootID + lineno for i4, _ := range item4.FCDA { lineno = lineno + 1 item4.FCDA[i4].BaseNode.Lineno = lineno item4.FCDA[i4].BaseNode.NodeId = scdmgr.RootID + lineno } for i4, _ := range item4.FCCB { lineno = lineno + 1 item4.FCCB[i4].BaseNode.Lineno = lineno item4.FCCB[i4].BaseNode.NodeId = scdmgr.RootID + lineno } lineno = lineno + 1 //多加一行 } } if item3.LN0.ReportControl != nil { isEmptyNode = false for i3, item4 := range item3.LN0.ReportControl { lineno = lineno + 1 item3.LN0.ReportControl[i3].BaseNode.Lineno = lineno item3.LN0.ReportControl[i3].BaseNode.NodeId = scdmgr.RootID + lineno isEmptyNode2 := true if len(item3.LN0.ReportControl[i3].Private) > 0 { isEmptyNode2 = false //又是南瑞的定义Private子节点 for p1, _ := range item3.LN0.ReportControl[i3].Private { lineno = lineno + 1 item3.LN0.ReportControl[i3].Private[p1].BaseNode.Lineno = lineno item3.LN0.ReportControl[i3].Private[p1].BaseNode.NodeId = scdmgr.RootID + lineno } } if item4.TrgOps != nil { isEmptyNode2 = false lineno = lineno + 1 item3.LN0.ReportControl[i3].TrgOps.BaseNode.Lineno = lineno item3.LN0.ReportControl[i3].TrgOps.BaseNode.NodeId = scdmgr.RootID + lineno } if item4.OptFields != nil { isEmptyNode2 = false lineno = lineno + 1 item3.LN0.ReportControl[i3].OptFields.BaseNode.Lineno = lineno item3.LN0.ReportControl[i3].OptFields.BaseNode.NodeId = scdmgr.RootID + lineno } if item4.RptEnabled != nil { isEmptyNode2 = false lineno = lineno + 1 item3.LN0.ReportControl[i3].RptEnabled.BaseNode.Lineno = lineno item3.LN0.ReportControl[i3].RptEnabled.BaseNode.NodeId = scdmgr.RootID + lineno if len(item4.RptEnabled.ClientLN) > 0 { for c1, _ := range item4.RptEnabled.ClientLN { lineno = lineno + 1 item3.LN0.ReportControl[i3].RptEnabled.ClientLN[c1].BaseNode.Lineno = lineno item3.LN0.ReportControl[i3].RptEnabled.ClientLN[c1].BaseNode.NodeId = scdmgr.RootID + lineno } lineno = lineno + 1 //多加一行RptEnabled结束 } } if !isEmptyNode2 { lineno = lineno + 1 } } } if item3.LN0.LogControl != nil { isEmptyNode = false for i3, item4 := range item3.LN0.LogControl { lineno = lineno + 1 item3.LN0.LogControl[i3].BaseNode.Lineno = lineno item3.LN0.LogControl[i3].BaseNode.NodeId = scdmgr.RootID + lineno if item4.TrgOps != nil { lineno = lineno + 1 item3.LN0.LogControl[i3].TrgOps.BaseNode.Lineno = lineno item3.LN0.LogControl[i3].TrgOps.BaseNode.NodeId = scdmgr.RootID + lineno } lineno = lineno + 1 } } if len(item3.LN0.DOI) > 0 { isEmptyNode = false for i3, item4 := range item3.LN0.DOI { lineno = lineno + 1 item3.LN0.DOI[i3].BaseNode.Lineno = lineno item3.LN0.DOI[i3].BaseNode.NodeId = scdmgr.RootID + lineno if item4.SDI != nil || item4.DAI != nil { if item4.SDI != nil { for i4, sdi1 := range item3.LN0.DOI[i3].SDI { lineno = lineno + 1 item3.LN0.DOI[i3].SDI[i4].BaseNode.Lineno = lineno item3.LN0.DOI[i3].SDI[i4].BaseNode.NodeId = scdmgr.RootID + lineno //fmt.Println(fmt.Sprintf("%s %+v", lineno, sdi1)) if sdi1.SDI != nil { for i04, sdi01 := range item3.LN0.DOI[i3].SDI[i4].SDI { lineno = lineno + 1 item3.LN0.DOI[i3].SDI[i4].SDI[i04].BaseNode.Lineno = lineno item3.LN0.DOI[i3].SDI[i4].SDI[i04].BaseNode.NodeId = scdmgr.RootID + lineno if sdi01.SDI != nil { for i24, _ := range sdi01.SDI { lineno = lineno + 1 sdi01.SDI[i24].BaseNode.Lineno = lineno sdi01.SDI[i24].BaseNode.NodeId = scdmgr.RootID + lineno if sdi01.SDI[i24].DAI != nil { for i25, _ := range sdi01.SDI[i24].DAI { lineno = lineno + 1 sdi01.SDI[i24].DAI[i25].BaseNode.Lineno = lineno sdi01.SDI[i24].DAI[i25].BaseNode.NodeId = scdmgr.RootID + lineno if sdi01.SDI[i24].DAI[i25].Val != nil { lineno = lineno + 1 sdi01.SDI[i24].DAI[i25].Val.BaseNode.Lineno = lineno sdi01.SDI[i24].DAI[i25].Val.BaseNode.NodeId = scdmgr.RootID + lineno lineno = lineno + 1 //多加一行 } } lineno = lineno + 1 //多加一行 } } lineno = lineno + 1 //多加一行 } if sdi1.SDI[i04].DAI != nil { for i05, _ := range sdi1.SDI[i04].DAI { lineno = lineno + 1 sdi1.SDI[i04].DAI[i05].BaseNode.Lineno = lineno sdi1.SDI[i04].DAI[i05].BaseNode.NodeId = scdmgr.RootID + lineno if sdi1.SDI[i04].DAI[i05].Val != nil { lineno = lineno + 1 sdi1.SDI[i04].DAI[i05].Val.BaseNode.Lineno = lineno sdi1.SDI[i04].DAI[i05].Val.BaseNode.NodeId = scdmgr.RootID + lineno lineno = lineno + 1 //多加一行 } } lineno = lineno + 1 //多加一行 } } if len(item3.LN0.DOI[i3].SDI[i4].SDI) > 0 && item3.LN0.DOI[i3].SDI[i4].DAI == nil { lineno = lineno + 1 //多加一行 } } if item4.SDI[i4].DAI != nil { for i5, _ := range item4.SDI[i4].DAI { lineno = lineno + 1 item4.SDI[i4].DAI[i5].BaseNode.Lineno = lineno item4.SDI[i4].DAI[i5].BaseNode.NodeId = scdmgr.RootID + lineno if item4.SDI[i4].DAI[i5].Val != nil { lineno = lineno + 1 item4.SDI[i4].DAI[i5].Val.BaseNode.Lineno = lineno item4.SDI[i4].DAI[i5].Val.BaseNode.NodeId = scdmgr.RootID + lineno lineno = lineno + 1 //多加一行 } } lineno = lineno + 1 //多加一行 } } } if item4.DAI != nil { for i4, _ := range item4.DAI { lineno = lineno + 1 item4.DAI[i4].BaseNode.Lineno = lineno item4.DAI[i4].BaseNode.NodeId = scdmgr.RootID + lineno if item4.DAI[i4].Val != nil { lineno = lineno + 1 item4.DAI[i4].Val.BaseNode.Lineno = lineno item4.DAI[i4].Val.BaseNode.NodeId = scdmgr.RootID + lineno lineno = lineno + 1 //多加一行 } } } lineno = lineno + 1 //多加一行 } } } if item3.LN0.Inputs != nil { isEmptyNode = false lineno = lineno + 1 item2.Server.LDevice[i2].LN0.Inputs.BaseNode.Lineno = lineno item2.Server.LDevice[i2].LN0.Inputs.BaseNode.NodeId = scdmgr.RootID + lineno if len(item3.LN0.Inputs.ExtRef) > 0 { for i3, _ := range item3.LN0.Inputs.ExtRef { lineno = lineno + 1 item3.LN0.Inputs.ExtRef[i3].BaseNode.Lineno = lineno item3.LN0.Inputs.ExtRef[i3].BaseNode.NodeId = scdmgr.RootID + lineno } lineno = lineno + 1 //多加一行 } } if len(item3.LN0.Log) > 0 { isEmptyNode = false for i3, _ := range item3.LN0.Log { lineno = lineno + 1 item3.LN0.Log[i3].BaseNode.Lineno = lineno item3.LN0.Log[i3].BaseNode.NodeId = scdmgr.RootID + lineno } } for i3, _ := range item3.LN0.GSEControl { isEmptyNode = false lineno = lineno + 1 item3.LN0.GSEControl[i3].BaseNode.Lineno = lineno item3.LN0.GSEControl[i3].BaseNode.NodeId = scdmgr.RootID + lineno if item3.LN0.GSEControl[i3].Private != nil || len(item3.LN0.GSEControl[i3].IEDName) > 0 { if item3.LN0.GSEControl[i3].Private != nil { //又是南瑞的定义Private子节点sznari:P lineno = lineno + 1 item3.LN0.GSEControl[i3].Private.BaseNode.Lineno = lineno item3.LN0.GSEControl[i3].Private.BaseNode.NodeId = scdmgr.RootID + lineno //fmt.Println(fmt.Sprintf("%d %+v", lineno, item3.LN0.GSEControl[i3].Private)) if len(item3.LN0.GSEControl[i3].Private.Any) > 0 { lineno = lineno + calNodeAnyLineNumber(item3.LN0.GSEControl[i3].Private.Any) lineno = lineno + 1 //多加一行 } } if len(item3.LN0.GSEControl[i3].IEDName) > 0 { for i4, _ := range item3.LN0.GSEControl[i3].IEDName { lineno = lineno + 1 item3.LN0.GSEControl[i3].IEDName[i4].BaseNode.Lineno = lineno item3.LN0.GSEControl[i3].IEDName[i4].BaseNode.NodeId = scdmgr.RootID + lineno } } lineno = lineno + 1 //多加一行 } } if len(item3.LN0.SampledValueControl) > 0 { isEmptyNode = false for i3, _ := range item3.LN0.SampledValueControl { lineno = lineno + 1 item3.LN0.SampledValueControl[i3].BaseNode.Lineno = lineno item3.LN0.SampledValueControl[i3].BaseNode.NodeId = scdmgr.RootID + lineno if len(item3.LN0.SampledValueControl[i3].Private) > 0 { for _, pitem := range item3.LN0.SampledValueControl[i3].Private { lineno = lineno + 1 if len(pitem.Any) > 0 { lineno = lineno + calNodeAnyLineNumber(pitem.Any) lineno = lineno + 1 } } } if len(item3.LN0.SampledValueControl[i3].IEDName) > 0 { for i4, _ := range item3.LN0.SampledValueControl[i3].IEDName { lineno = lineno + 1 item3.LN0.SampledValueControl[i3].IEDName[i4].BaseNode.Lineno = lineno item3.LN0.SampledValueControl[i3].IEDName[i4].BaseNode.NodeId = scdmgr.RootID + lineno } } lineno = lineno + 1 item3.LN0.SampledValueControl[i3].SmvOpts.BaseNode.Lineno = lineno item3.LN0.SampledValueControl[i3].SmvOpts.BaseNode.NodeId = scdmgr.RootID + lineno lineno = lineno + 1 //多加一行 } } if item3.LN0.SettingControl != nil { isEmptyNode = false lineno = lineno + 1 item3.LN0.SettingControl.BaseNode.Lineno = lineno item3.LN0.SettingControl.BaseNode.NodeId = scdmgr.RootID + lineno } if item3.LN0.SCLControl != nil { isEmptyNode = false lineno = lineno + 1 item3.LN0.SCLControl.BaseNode.Lineno = lineno item3.LN0.SCLControl.BaseNode.NodeId = scdmgr.RootID + lineno } if len(item3.LN0.Any) > 0 { isEmptyNode = false lineno = lineno + calNodeAnyLineNumber(item3.LN0.Any) } if !isEmptyNode { lineno = lineno + 1 //多加一行:LN0 } } if len(item3.LN) > 0 { for i2, _ := range item3.LN { lineno = lineno + 1 item3.LN[i2].BaseNode.Lineno = lineno item3.LN[i2].BaseNode.NodeId = scdmgr.RootID + lineno if len(item3.LN[i2].Any) > 0 { anyLines := calNodeAnyLineNumber(item3.LN[i2].Any) lineno = lineno + anyLines } if item3.LN[i2].DataSet != nil { for i3, item4 := range item3.LN[i2].DataSet { lineno = lineno + 1 item3.LN[i2].DataSet[i3].BaseNode.Lineno = lineno item3.LN[i2].DataSet[i3].BaseNode.NodeId = scdmgr.RootID + lineno for i4, _ := range item4.FCDA { lineno = lineno + 1 item4.FCDA[i4].BaseNode.Lineno = lineno item4.FCDA[i4].BaseNode.NodeId = scdmgr.RootID + lineno } for i4, _ := range item4.FCCB { lineno = lineno + 1 item4.FCCB[i4].BaseNode.Lineno = lineno item4.FCCB[i4].BaseNode.NodeId = scdmgr.RootID + lineno } lineno = lineno + 1 //多加一行 } } if item3.LN[i2].ReportControl != nil { for i3, item4 := range item3.LN[i2].ReportControl { lineno = lineno + 1 item3.LN[i2].ReportControl[i3].BaseNode.Lineno = lineno item3.LN[i2].ReportControl[i3].BaseNode.NodeId = scdmgr.RootID + lineno isEmptyNode := true if item4.TrgOps != nil { isEmptyNode = false lineno = lineno + 1 item3.LN[i2].ReportControl[i3].TrgOps.BaseNode.Lineno = lineno item3.LN[i2].ReportControl[i3].TrgOps.BaseNode.NodeId = scdmgr.RootID + lineno } if item4.OptFields != nil { isEmptyNode = false lineno = lineno + 1 item3.LN[i2].ReportControl[i3].OptFields.BaseNode.Lineno = lineno item3.LN[i2].ReportControl[i3].OptFields.BaseNode.NodeId = scdmgr.RootID + lineno } if item4.RptEnabled != nil { isEmptyNode = false lineno = lineno + 1 item3.LN[i2].ReportControl[i3].RptEnabled.BaseNode.Lineno = lineno item3.LN[i2].ReportControl[i3].RptEnabled.BaseNode.NodeId = scdmgr.RootID + lineno if len(item4.RptEnabled.ClientLN) > 0 { for c1, _ := range item4.RptEnabled.ClientLN { lineno = lineno + 1 item3.LN[i2].ReportControl[i3].RptEnabled.ClientLN[c1].BaseNode.Lineno = lineno item3.LN[i2].ReportControl[i3].RptEnabled.ClientLN[c1].BaseNode.NodeId = scdmgr.RootID + lineno } lineno = lineno + 1 //多加一行RptEnabled结束 } } if !isEmptyNode { lineno = lineno + 1 } } } if item3.LN[i2].LogControl != nil { for i3, item4 := range item3.LN[i2].LogControl { lineno = lineno + 1 item3.LN[i2].LogControl[i3].BaseNode.Lineno = lineno item3.LN[i2].LogControl[i3].BaseNode.NodeId = scdmgr.RootID + lineno if item4.TrgOps != nil { lineno = lineno + 1 item3.LN[i2].ReportControl[i3].TrgOps.BaseNode.Lineno = lineno item3.LN[i2].ReportControl[i3].TrgOps.BaseNode.NodeId = scdmgr.RootID + lineno } lineno = lineno + 1 } } if len(item3.LN[i2].DOI) > 0 { for i3, item4 := range item3.LN[i2].DOI { lineno = lineno + 1 item3.LN[i2].DOI[i3].BaseNode.Lineno = lineno item3.LN[i2].DOI[i3].BaseNode.NodeId = scdmgr.RootID + lineno if item4.SDI != nil || item4.DAI != nil { if item4.SDI != nil { for i4, sdi1 := range item3.LN[i2].DOI[i3].SDI { lineno = lineno + 1 item3.LN[i2].DOI[i3].SDI[i4].BaseNode.Lineno = lineno item3.LN[i2].DOI[i3].SDI[i4].BaseNode.NodeId = scdmgr.RootID + lineno //fmt.Println(fmt.Sprintf("%d %+v", lineno, sdi1)) if sdi1.SDI != nil { for i04, sdi01 := range item3.LN[i2].DOI[i3].SDI[i4].SDI { lineno = lineno + 1 item3.LN[i2].DOI[i3].SDI[i4].SDI[i04].BaseNode.Lineno = lineno item3.LN[i2].DOI[i3].SDI[i4].SDI[i04].BaseNode.NodeId = scdmgr.RootID + lineno if sdi01.SDI != nil { for i24, _ := range sdi01.SDI { lineno = lineno + 1 sdi01.SDI[i24].BaseNode.Lineno = lineno sdi01.SDI[i24].BaseNode.NodeId = scdmgr.RootID + lineno if sdi01.SDI[i24].DAI != nil { for i25, _ := range sdi01.SDI[i24].DAI { lineno = lineno + 1 sdi01.SDI[i24].DAI[i25].BaseNode.Lineno = lineno sdi01.SDI[i24].DAI[i25].BaseNode.NodeId = scdmgr.RootID + lineno if sdi01.SDI[i24].DAI[i25].Val != nil { lineno = lineno + 1 sdi01.SDI[i24].DAI[i25].Val.BaseNode.Lineno = lineno sdi01.SDI[i24].DAI[i25].Val.BaseNode.NodeId = scdmgr.RootID + lineno lineno = lineno + 1 //多加一行 } } lineno = lineno + 1 //多加一行 } } lineno = lineno + 1 //多加一行 } if sdi1.SDI[i04].DAI != nil { for i05, _ := range sdi1.SDI[i04].DAI { lineno = lineno + 1 sdi1.SDI[i04].DAI[i05].BaseNode.Lineno = lineno sdi1.SDI[i04].DAI[i05].BaseNode.NodeId = scdmgr.RootID + lineno if sdi1.SDI[i04].DAI[i05].Val != nil { lineno = lineno + 1 sdi1.SDI[i04].DAI[i05].Val.BaseNode.Lineno = lineno sdi1.SDI[i04].DAI[i05].Val.BaseNode.NodeId = scdmgr.RootID + lineno lineno = lineno + 1 //多加一行 } } lineno = lineno + 1 //多加一行 } } if len(item3.LN[i2].DOI[i3].SDI[i4].SDI) > 0 && item3.LN[i2].DOI[i3].SDI[i4].DAI == nil { lineno = lineno + 1 //多加一行 } } if item4.SDI[i4].DAI != nil { for i5, _ := range item4.SDI[i4].DAI { lineno = lineno + 1 item4.SDI[i4].DAI[i5].BaseNode.Lineno = lineno item4.SDI[i4].DAI[i5].BaseNode.NodeId = scdmgr.RootID + lineno if item4.SDI[i4].DAI[i5].Val != nil { lineno = lineno + 1 item4.SDI[i4].DAI[i5].Val.BaseNode.Lineno = lineno item4.SDI[i4].DAI[i5].Val.BaseNode.NodeId = scdmgr.RootID + lineno lineno = lineno + 1 //多加一行 } } lineno = lineno + 1 //多加一行 } } } if item4.DAI != nil { for i4, _ := range item4.DAI { lineno = lineno + 1 item4.DAI[i4].BaseNode.Lineno = lineno item4.DAI[i4].BaseNode.NodeId = scdmgr.RootID + lineno if item4.DAI[i4].Val != nil { lineno = lineno + 1 item4.DAI[i4].Val.BaseNode.Lineno = lineno item4.DAI[i4].Val.BaseNode.NodeId = scdmgr.RootID + lineno lineno = lineno + 1 //多加一行 } } } lineno = lineno + 1 //多加一行 } } lineno = lineno + 1 //多加一行LN } if item3.LN[i2].Inputs != nil { lineno = lineno + 1 item2.Server.LDevice[i2].LN[i2].Inputs.BaseNode.Lineno = lineno item2.Server.LDevice[i2].LN[i2].Inputs.BaseNode.NodeId = scdmgr.RootID + lineno if len(item3.LN[i2].Inputs.ExtRef) > 0 { for i3, _ := range item3.LN[i2].Inputs.ExtRef { lineno = lineno + 1 item3.LN[i2].Inputs.ExtRef[i3].BaseNode.Lineno = lineno item3.LN[i2].Inputs.ExtRef[i3].BaseNode.NodeId = scdmgr.RootID + lineno } lineno = lineno + 1 //多加一行 } } if item3.LN[i2].Log != nil { for i3, _ := range item3.LN[i2].Log { lineno = lineno + 1 item3.LN[i2].Log[i3].BaseNode.Lineno = lineno item3.LN[i2].Log[i3].BaseNode.NodeId = scdmgr.RootID + lineno } } } } if item3.LN0 != nil || len(item3.LN) > 0 { lineno = lineno + 1 //多加一行 LDevice } } for i2, _ := range item.AccessPoint[i1].GOOSESecurity { lineno = lineno + 1 item.AccessPoint[i1].GOOSESecurity[i2].BaseNode.Lineno = lineno item.AccessPoint[i1].GOOSESecurity[i2].BaseNode.NodeId = scdmgr.RootID + lineno isEmptyNode := true if item.AccessPoint[i1].GOOSESecurity[i2].Subject != nil { isEmptyNode = false lineno = lineno + 1 item.AccessPoint[i1].GOOSESecurity[i2].Subject.BaseNode.Lineno = lineno item.AccessPoint[i1].GOOSESecurity[i2].Subject.BaseNode.NodeId = scdmgr.RootID + lineno } if item.AccessPoint[i1].GOOSESecurity[i2].IssuerName != nil { isEmptyNode = false lineno = lineno + 1 item.AccessPoint[i1].GOOSESecurity[i2].IssuerName.BaseNode.Lineno = lineno item.AccessPoint[i1].GOOSESecurity[i2].IssuerName.BaseNode.NodeId = scdmgr.RootID + lineno } if !isEmptyNode { lineno = lineno + 1 //多加一个结束节点 } } for i2, _ := range item.AccessPoint[i1].SMVSecurity { lineno = lineno + 1 item.AccessPoint[i1].SMVSecurity[i2].BaseNode.Lineno = lineno item.AccessPoint[i1].SMVSecurity[i2].BaseNode.NodeId = scdmgr.RootID + lineno isEmptyNode := true if item.AccessPoint[i1].SMVSecurity[i2].Subject != nil { isEmptyNode = false lineno = lineno + 1 item.AccessPoint[i1].SMVSecurity[i2].Subject.BaseNode.Lineno = lineno item.AccessPoint[i1].SMVSecurity[i2].Subject.BaseNode.NodeId = scdmgr.RootID + lineno } if item.AccessPoint[i1].SMVSecurity[i2].IssuerName != nil { lineno = lineno + 1 item.AccessPoint[i1].SMVSecurity[i2].IssuerName.BaseNode.Lineno = lineno item.AccessPoint[i1].SMVSecurity[i2].IssuerName.BaseNode.NodeId = scdmgr.RootID + lineno } if !isEmptyNode { lineno = lineno + 1 //多加一个结束节点 } } lineno = lineno + 1 //多加一行 Server } lineno = lineno + 1 //多加一行 AccessPoint } lineno = lineno + 1 //多加一行 } if sclNodeObj.DataTypeTemplates != nil { lineno = lineno + 1 sclNodeObj.DataTypeTemplates.BaseNode.Lineno = lineno sclNodeObj.DataTypeTemplates.BaseNode.NodeId = scdmgr.RootID + lineno for i, item := range sclNodeObj.DataTypeTemplates.LNodeType { lineno = lineno + 1 sclNodeObj.DataTypeTemplates.LNodeType[i].BaseNode.Lineno = lineno sclNodeObj.DataTypeTemplates.LNodeType[i].BaseNode.NodeId = scdmgr.RootID + lineno for i1, _ := range item.DO { lineno = lineno + 1 sclNodeObj.DataTypeTemplates.LNodeType[i].DO[i1].BaseNode.Lineno = lineno sclNodeObj.DataTypeTemplates.LNodeType[i].DO[i1].BaseNode.NodeId = scdmgr.RootID + lineno } lineno = lineno + 1 //多加一行 } for i, item := range sclNodeObj.DataTypeTemplates.DOType { lineno = lineno + 1 sclNodeObj.DataTypeTemplates.DOType[i].BaseNode.Lineno = lineno sclNodeObj.DataTypeTemplates.DOType[i].BaseNode.NodeId = scdmgr.RootID + lineno for i1, _ := range item.SDO { lineno = lineno + 1 sclNodeObj.DataTypeTemplates.DOType[i].SDO[i1].BaseNode.Lineno = lineno sclNodeObj.DataTypeTemplates.DOType[i].SDO[i1].BaseNode.NodeId = scdmgr.RootID + lineno } for i1, _ := range item.DA { lineno = lineno + 1 sclNodeObj.DataTypeTemplates.DOType[i].DA[i1].BaseNode.Lineno = lineno sclNodeObj.DataTypeTemplates.DOType[i].DA[i1].BaseNode.NodeId = scdmgr.RootID + lineno if sclNodeObj.DataTypeTemplates.DOType[i].DA[i1].Val != nil { lineno = lineno + 1 sclNodeObj.DataTypeTemplates.DOType[i].DA[i1].Val.BaseNode.Lineno = lineno sclNodeObj.DataTypeTemplates.DOType[i].DA[i1].Val.BaseNode.NodeId = scdmgr.RootID + lineno lineno = lineno + 1 //多加一行 } } lineno = lineno + 1 //多加一行 } for i, item := range sclNodeObj.DataTypeTemplates.DAType { lineno = lineno + 1 sclNodeObj.DataTypeTemplates.DAType[i].BaseNode.Lineno = lineno sclNodeObj.DataTypeTemplates.DAType[i].BaseNode.NodeId = scdmgr.RootID + lineno for i1, _ := range item.BDA { lineno = lineno + 1 sclNodeObj.DataTypeTemplates.DAType[i].BDA[i1].BaseNode.Lineno = lineno sclNodeObj.DataTypeTemplates.DAType[i].BDA[i1].BaseNode.NodeId = scdmgr.RootID + lineno if sclNodeObj.DataTypeTemplates.DAType[i].BDA[i1].Val != nil { lineno = lineno + 1 sclNodeObj.DataTypeTemplates.DAType[i].BDA[i1].Val.BaseNode.Lineno = lineno sclNodeObj.DataTypeTemplates.DAType[i].BDA[i1].Val.BaseNode.NodeId = scdmgr.RootID + lineno lineno = lineno + 1 //多加一行 } } lineno = lineno + 1 //多加一行 } for i, item := range sclNodeObj.DataTypeTemplates.EnumType { lineno = lineno + 1 sclNodeObj.DataTypeTemplates.EnumType[i].BaseNode.Lineno = lineno sclNodeObj.DataTypeTemplates.EnumType[i].BaseNode.NodeId = scdmgr.RootID + lineno if len(item.EnumVal) > 0 { for i1, _ := range item.EnumVal { lineno = lineno + 1 sclNodeObj.DataTypeTemplates.EnumType[i].EnumVal[i1].BaseNode.Lineno = lineno sclNodeObj.DataTypeTemplates.EnumType[i].EnumVal[i1].BaseNode.NodeId = scdmgr.RootID + lineno } lineno = lineno + 1 //多加一行 } } } //logger.Logger.Debug(fmt.Sprintf("\n-----GlobalNodeMap------- \n:%+v", GlobalNodeMap)) xmlStr, err := xml.MarshalIndent(sclNodeObj, "", " ") if err == nil { //生成解析完成结果副本文件 os.WriteFile(scdPath+".parsed.xml", xmlStr, fs.ModePerm) } else { //解除该站的签入锁定,如果是签入解析 new(Flow).CheckInFail(stationid) mqtt.PublishMessage(fmt.Sprintf("/jujutong/scd_check_tools/parse/%s/%d/error", stationid, scdmgr.RootID), scdName+"格式化时发生错误,解析终止!") logger.Logger.Error(err) return err } if stationid == "" || stationid == "0" { return } scdid = tools.IsEmpty(scdmgr.RootID) global.GoCahce.Set(scdPath, scdid, -1) global.GoCahce.Set(scdid, sclNodeObj, -1) c.cacheGlobalNodeIds(scdid, sclNodeObj) //新的scd文件 stationidint, _ := strconv.Atoi(stationid) newscdid, err := scdmgr.Init(stationidint, scdName, scdPath, isenable, c.IsCheckinScd) if err != nil { //解除该站的签入锁定,如果是签入解析 new(Flow).CheckInFail(stationid) mqtt.PublishMessage(fmt.Sprintf("/jujutong/scd_check_tools/parse/%s/%d/error", stationid, scdmgr.RootID), scdName+"初始化创建时发生错误,解析终止!") logger.Logger.Error(err) return err } scdmgr.RootID = newscdid if isenable == 1 { //该scd需要默认启用且是在运版本 scdmgr.IsDefaultRunVersion = 1 } //间隔解析.如果间隔解析是Bay方式,需要根据节点数据进行解析 if isBay { logger.Logger.Debug(fmt.Sprintf("当前采集Bay间隔模式")) scdmgr.AreaMgr.ParseBay(stationidint, bayList) } else { logger.Logger.Debug(fmt.Sprintf("当前采集IED分析间隔模式,共解析IED节点数:%d", len(iedlist))) for _, ieditem := range iedlist { scdmgr.AreaMgr.AppendIedNode(scdmgr.RootID, ieditem.BaseNode.NodeId, ieditem.Name, ieditem.Desc) } } mqttData := map[string]string{"name": scdName, "stationid": stationid, "rootid": scdid, "state": "1", "node": "load-file", "msg": ""} dataMsg, _ = json.Marshal(mqttData) mqtt.PublishMessage(fmt.Sprintf("/jujutong/scd_check_tools/parse/%s/%d", stationid, scdmgr.RootID), string(dataMsg)) //开始校验该SCD _, err = c.SchemaValid(tools.IsEmpty(newscdid), scdName, scdPath) if err != nil { //解除该站的签入锁定,如果是签入解析 //new(Flow).CheckInFail(stationid) mqtt.PublishMessage(fmt.Sprintf("/jujutong/scd_check_tools/parse/%s/%d/error", stationid, scdmgr.RootID), scdName+"校验发生错误,语法校验终止!") logger.Logger.Error(err) //return err } scdmgr.Flush() //写入ied节点到节点表中 db.Raw("update t_scd_scl set node_cnt=? where id=?", node_cnt, scdmgr.RootID).Exec() db.Raw("delete from t_scd_node_scl where scd_id=?", scdmgr.RootID).Exec() node_ins := "insert into t_scd_node_scl(id,scd_id,node_name,ied_name,line_no)values" _, err = db.Raw(fmt.Sprintf("%s%s", node_ins, strings.Join(iedList, ","))).Exec() if err != nil { //解除该站的签入锁定,如果是签入解析 new(Flow).CheckInFail(stationid) logger.Logger.Error(err, fmt.Sprintf("SQL:%s", fmt.Sprintf("%s%s", node_ins, strings.Join(iedList, ",")))) } return nil } //解析ICD到内存中 func (c *ScdParse) IcdParse(scdid, iedname string) error { fline := string(os.PathSeparator) icddir := strings.Join([]string{".", "static", "download", "icd", scdid, ""}, fline) icdPath := icddir + iedname + ".icd" f, err := os.Stat(icdPath) if err != nil { os.MkdirAll(icddir, fs.ModePerm) logger.Logger.Error(err, icdPath) return err } if f == nil { os.MkdirAll(icddir, fs.ModePerm) return errors.New("icd文件" + icdPath + "未找到!") } sclNodeObj, err := c.LoadScdXml(icdPath) if err != nil { logger.Logger.Error(err, "异常ICD文件:"+icdPath) return err } key := fmt.Sprintf("icd_%s_%s", scdid, iedname) global.GoCahce.Set(key, sclNodeObj, 1*time.Hour) return nil } //解析CID到内存中 func (c *ScdParse) CidParse(scdid, iedname string) error { fline := string(os.PathSeparator) icddir := strings.Join([]string{".", "static", "download", "cid", scdid, ""}, fline) icdPath := icddir + iedname + ".cid" f, err := os.Stat(icdPath) if err != nil { os.MkdirAll(icddir, fs.ModePerm) logger.Logger.Error(err, icdPath) return err } if f == nil { os.MkdirAll(icddir, fs.ModePerm) return errors.New("cid文件" + icdPath + "未找到!") } sclNodeObj, err := c.LoadScdXml(icdPath) if err != nil { logger.Logger.Error(err, "异常CID文件:"+icdPath) return err } key := fmt.Sprintf("cid_%s_%s", scdid, iedname) global.GoCahce.Set(key, sclNodeObj, 1*time.Hour) return nil } func GetScdParseInstance(userinfo ...map[string]interface{}) *ScdParse { ins := new(ScdParse) ins.ModelTableName = "t_scd_scl" if len(userinfo) > 0 { ins.SetUserInfo(userinfo[0]) } else { ins.SetUserInfo(map[string]interface{}{"name": "", "ip": "127.0.0.1"}) } //获取最大的ID,当前解析对象的ID序列为数据库中最大ID+4000000,以保证不同文件解析入库中的ID不重复 if tools.GlobalID == 0 { db := orm.NewOrm() r := []orm.Params{} _, err := db.Raw("select ifnull(max(id),0) maxid from t_scd_scl").Values(&r) if err != nil { log.Println(err) } else { insSeqID, _ := strconv.Atoi(r[0]["maxid"].(string)) tools.GlobalID = int64(insSeqID) } } ins.Idseq = tools.GetSeqID() + int64(instanNum*4000000) instanNum = instanNum + 1 //初始化命名空间定义 new(sync.Once).Do(func() { logger.Logger.Debug(fmt.Sprintf("正在加载命名空间(scd_node_space)系统字典定义")) syscode := new(Global) _, ishasd, _ := syscode.QueryGlobalCodeList(map[string]interface{}{"code": "scd_node_space"}) if ishasd == 0 { //新增字典 SaveGlobalCode(Global_const_code{ Code: "scd_node_space", Parentcode: "systemconstcode", Name: "SCD命名空间", }) } lst, _ := syscode.GetChildrenGlobalCode("scd_node_space") if len(lst) > 0 { for _, row := range lst { spaceMap.Store(tools.IsEmpty(row["code"]), tools.IsEmpty(row["name"])) } } }) return ins } //解析Ied Name为标准8位 //标准命名规则:1、2为IED装置类型;3位表示功能类型或归属设备类型;4、5为电压等级代码;6、7位为功能编码或归属设备编号;8位为间隔内编号,多套时有值 func (c *ScdParse) ParseIedName(name string) []string { //补全实际ied name为8位 new_ied_name_full := []string{"", "", "", "", "", "", "", ""} tl := len(name) logger.Logger.Debug(fmt.Sprintf("ied name:%s", name)) if tl > 4 { //至少有5位置编码才可能补全 lastchar := name[tl-1:] if lastchar >= "9" { //字母表示是N套 new_ied_name_full[7] = lastchar name = name[0 : tl-1] } tl = len(name) //最倒数第4位 last4 := name[tl-4 : tl-3] //如果是数字 if last4 >= "9" { //只有3位数字 new_ied_name_full[6] = name[tl-1 : tl] new_ied_name_full[4] = name[tl-2 : tl-1] new_ied_name_full[3] = name[tl-3 : tl-2] name = name[0 : tl-3] } else { //有4位数字 new_ied_name_full[6] = name[tl-1 : tl] new_ied_name_full[5] = name[tl-2 : tl-1] new_ied_name_full[4] = name[tl-3 : tl-2] new_ied_name_full[3] = name[tl-4 : tl-3] name = name[0 : tl-4] } tl = len(name) new_ied_name_full[2] = name[tl-1 : tl] if tl == 2 { new_ied_name_full[0] = name[0:1] } else if tl > 2 { logger.Logger.Debug(fmt.Sprintf("ied name:%s", name)) new_ied_name_full[1] = name[1:2] new_ied_name_full[0] = name[0:1] } } else { for i := 0; i < len(new_ied_name_full); i++ { if i < tl { new_ied_name_full[i] = name[i : i+1] } } } return new_ied_name_full } //原数据库存储方式,已废弃 func (c *ScdParse) Parse_UnUsed(stationid, scdpath, scdName string, isenable int, autocompscdid ...int64) (err error) { if scdpath == "" || scdName == "" { return errors.New("无效的SCD名称") } c.SclModel = map[string]interface{}{} fileFirstChar := scdpath[0:1] fline := string(os.PathSeparator) if fileFirstChar != "." { if fileFirstChar == fline { scdpath = "." + scdpath } else { scdpath = "." + fline + scdpath } } //判断该scd是否已经存在,已存在则不再解析 db := orm.NewOrm() sql := "select 1 from t_scd_scl where scd_name=? and path=?" rowset := []orm.Params{} db.Raw(sql, scdName, scdpath).Values(&rowset) if len(rowset) > 0 { db.Raw("update t_scd_scl set enable=? where scd_name=? and path=?", isenable, scdName, scdpath).Exec() return nil } xmlhander, err2 := os.Open(scdpath) if err2 != nil { log.Println(err2) return err2 } defer xmlhander.Close() //通知开始实时性能监测 global.PerformanceRuntimeMonitorChan <- 1 var item xml.Token de := xml.NewDecoder(xmlhander) var startElementLoaded = false var isRoot = true var startName = "" var nodeText = "" var startTime = time.Now().Unix() scdmgr := new(ScdNode) scdmgr.SetUserInfo(c.GetUserInfo()) scdmgr.Idseq = c.Idseq //初始化节点管理对象的ID序列 iedContentList := []string{} scdID := int64(0) iedName := "" lineno := int64(1) //起始行号。跳过xml标注行 for { item, err2 = de.Token() if err2 == io.EOF { break } if err2 != nil { log.Println(err2) break } switch token := item.(type) { case xml.StartElement: name := token.Name.Local if name == "IED" { //创建IED文件 iedContentList = []string{} } iedContentList = append(iedContentList, "<"+name) attr := map[string]interface{}{} if len(token.Attr) != 0 { for _, xmlAttr := range token.Attr { v_attrname := xmlAttr.Name.Local attr[v_attrname] = strings.ReplaceAll(xmlAttr.Value, "'", "''") iedContentList = append(iedContentList, " "+v_attrname+"=\""+xmlAttr.Value+"\"") if name == "IED" && v_attrname == "name" { iedName = xmlAttr.Value } } } iedContentList = append(iedContentList, ">") if isRoot { isRoot = false stationidint, _ := strconv.Atoi(stationid) scdID, err = scdmgr.Init(stationidint, scdName, scdpath, isenable, c.IsCheckinScd) if err != nil { return } if isenable == 1 { //该scd需要默认启用且是在运版本 scdmgr.IsDefaultRunVersion = 1 } } else { startName = name startElementLoaded = true } lineno = lineno + 1 err = scdmgr.AddNode(name, attr, lineno) if err != nil { return } case xml.EndElement: name := token.Name.Local if name == "IED" { iedContentList = append(iedContentList, "") //创建该IED文件 //fmt.Println("创建该IED文件:" + iedName) //log.Println(fmt.Sprintf("%v", iedContentList)) go func(ied_name, iedTxt string) { defer func() { iedTxt = "" }() dirChar := string(os.PathSeparator) tmpPart := []string{"static", "download", "ied", tools.IsEmpty(scdID)} iedpath := strings.Join(tmpPart, dirChar) f, _ := exec.LookPath(os.Args[0]) fp, _ := filepath.Abs(f) i := strings.LastIndex(fp, dirChar) absdir := string(fp[0:i]) iedpath = absdir + dirChar + iedpath os.MkdirAll(iedpath, fs.ModePerm) ferr := os.WriteFile(iedpath+dirChar+ied_name+".ied", []byte(iedTxt), fs.ModePerm) if ferr != nil { logger.Logger.Error(ferr, "生成ied["+ied_name+"]单个配置文件错误!") new(SystemLog).Fail(enum.AuditType_scd_parse, enum.LogType_Execute, enum.OptEventType_System, enum.OptEventLevel_Hight, fmt.Sprintf("SCD%s中IED文件%s生成失败", scdName, ied_name), c.GetUserInfo(), ) } }(iedName, strings.Join(iedContentList, "")) } else { lastNode := iedContentList[len(iedContentList)-1] lastNodeLastChar := lastNode[len(lastNode)-1:] if lastNode[0:1] == "<" && lastNodeLastChar == ">" { iedContentList = append(iedContentList, "") } else if lastNode == "/>" { iedContentList = append(iedContentList, "") } else if lastNodeLastChar != ">" { iedContentList = append(iedContentList, "") } else { for i := len(iedContentList) - 1; i > 0; i-- { lastNode2 := iedContentList[i-1] if lastNode2[0:1] != "<" { continue } if lastNode2 == ("<" + name) { iedContentList[len(iedContentList)-1] = "/>" } break } } } err = scdmgr.EndNode(name, nodeText) if err != nil { return } if startName != name { lineno = lineno + 1 } nodeText = "" startElementLoaded = false case xml.CharData: if startElementLoaded { nodeText = string(token) nodeText = strings.Replace(strings.ReplaceAll(nodeText, "'", "''"), "\n", "", -1) //log.Println("NODE ["+startName+"] Text:", nodeText) if nodeText != "" { iedContentList = append(iedContentList, string(token)) } } case xml.Comment: case xml.ProcInst: case xml.Directive: default: log.Println("解析失败!") break } } iedContentList = []string{} scdmgr.StationID, _ = strconv.Atoi(stationid) if autocompscdid != nil && len(autocompscdid) > 0 { scdmgr.AutoCompScdID = autocompscdid[0] } scdmgr.Flush() var endTime = time.Now().Unix() log.Println(fmt.Sprintf("===========SCD 加载完毕!,总耗时:%d秒", endTime-startTime)) new(SystemLog).Success(enum.AuditType_scd_parse, enum.LogType_Execute, enum.OptEventType_System, enum.OptEventLevel_Hight, fmt.Sprintf("SCD%s解析", scdName), c.GetUserInfo(), ) //通知结束实时性能监测 global.PerformanceRuntimeMonitorChan <- 2 return err }