|
@@ -5,6 +5,7 @@ import (
|
|
|
"fmt"
|
|
|
"scd_check_tools/logger"
|
|
|
"scd_check_tools/models/enum"
|
|
|
+ "scd_check_tools/models/node_attr"
|
|
|
"scd_check_tools/tools"
|
|
|
"strconv"
|
|
|
"strings"
|
|
@@ -307,6 +308,139 @@ func (c *CheckAreaMgr) Reset() error {
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
+//检测间隔装置关系正确性
|
|
|
+func (c *CheckAreaMgr) CheckAreaIedRelation() error {
|
|
|
+ // 获取当前scd中需要检查的间隔
|
|
|
+ arealist := []orm.Params{}
|
|
|
+ db := orm.NewOrm()
|
|
|
+ _, err := db.Raw("select id,area_name,area_type,model_id from t_data_check_area where scd_id=?", c.ScdId).Values(&arealist)
|
|
|
+ if err != nil {
|
|
|
+ logger.Logger.Error(err)
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ scdNodeRule := new(ScdNodeRule)
|
|
|
+ area_ruleid := ""
|
|
|
+ area_ruleList, _, _ := scdNodeRule.GetDefList(map[string]interface{}{"check_name": "间隔装置与检查模型不符"}, 1, 1)
|
|
|
+ if len(area_ruleList) > 0 {
|
|
|
+ area_ruleid = tools.IsEmpty(area_ruleList[0]["id"])
|
|
|
+ }
|
|
|
+ if area_ruleid == "" {
|
|
|
+ return errors.New(fmt.Sprintf("未定义间隔装置的检查规则“间隔装置与检查模型不符”"))
|
|
|
+ }
|
|
|
+ scdParseMgr := new(ScdParse)
|
|
|
+ scdXmlObj, serr := scdParseMgr.GetScdXmlObjectBySCDID(tools.IsEmpty(c.ScdId))
|
|
|
+ if serr != nil {
|
|
|
+ return serr
|
|
|
+ }
|
|
|
+ if scdXmlObj == nil {
|
|
|
+ return errors.New("无效的SCD")
|
|
|
+ }
|
|
|
+ scdNode := new(ScdNode)
|
|
|
+ model_refs := map[string][]orm.Params{} //模型定义的装置关系定义
|
|
|
+ area_ieds := map[string][]orm.Params{} //间隔下的装置列表
|
|
|
+ for _, row := range arealist {
|
|
|
+ //获取间隔标准装置及关系
|
|
|
+ modelid := tools.IsEmpty(row["model_id"])
|
|
|
+ //area_name := tools.IsEmpty(row["area_name"])
|
|
|
+ //area_type := tools.IsEmpty(row["area_type"]) //间隔模型类型
|
|
|
+ area_id := tools.IsEmpty(row["id"])
|
|
|
+ s := []orm.Params{}
|
|
|
+ _, err = db.Raw("select from_ied_code,to_ied_code,in_type from t_data_model_relation_def where model_id=?", modelid).Values(&s)
|
|
|
+ if err != nil {
|
|
|
+ logger.Logger.Error(err)
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ if len(s) == 0 {
|
|
|
+ return errors.New(fmt.Sprintf("模型%d还未配置装置关系", modelid))
|
|
|
+ }
|
|
|
+ model_refs[modelid] = s
|
|
|
+ /*
|
|
|
+ hasIeds := map[string]bool{}
|
|
|
+ for _, row1 := range s {
|
|
|
+ iedname := tools.IsEmpty(row1["from_ied_code"])
|
|
|
+ if !hasIeds[iedname] {
|
|
|
+ hasIeds[iedname] = true
|
|
|
+ }
|
|
|
+ iedname = tools.IsEmpty(row1["to_ied_code"])
|
|
|
+ if !hasIeds[iedname] {
|
|
|
+ hasIeds[iedname] = true
|
|
|
+ }
|
|
|
+ }
|
|
|
+ */
|
|
|
+ s1 := []orm.Params{}
|
|
|
+ _, err = db.Raw("select ied_name from t_data_check_area_ied where area_id=?", area_id).Values(&s1)
|
|
|
+ if err != nil {
|
|
|
+ logger.Logger.Error(err)
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ if len(s) == 0 {
|
|
|
+ return errors.New(fmt.Sprintf("间隔%s未发现任何装置", tools.IsEmpty(row["area_name"])))
|
|
|
+ }
|
|
|
+ area_ieds[area_id] = s1
|
|
|
+ /*
|
|
|
+ curIeds := map[string]string{}
|
|
|
+ for _, row1 := range s1 {
|
|
|
+ iedname := strings.Trim(tools.IsEmpty(row1["ied_name"]), " ")
|
|
|
+ iedParts := scdParseMgr.ParseIedName(iedname)
|
|
|
+ iedtype := iedParts[0] + iedParts[1] + iedParts[2]
|
|
|
+ curIeds[iedtype] = iedname
|
|
|
+ }
|
|
|
+ for k, _ := range hasIeds {
|
|
|
+ iedname := curIeds[k]
|
|
|
+ if iedname == "" {
|
|
|
+ parse_result := fmt.Sprintf("间隔%s缺失类型为%s的装置", area_name, k)
|
|
|
+ r := map[string]interface{}{"scdid": c.ScdId, "lineno": 0, "ruleid": area_ruleid, "nodeid": 0, "parse_result": parse_result}
|
|
|
+ //检查未通过
|
|
|
+ scdNodeRule.AppendPaseResult(r)
|
|
|
+ } else {
|
|
|
+ //判断装置是否存在
|
|
|
+ if scdNode.GetIed(scdXmlObj, "", iedname) == nil {
|
|
|
+ parse_result := fmt.Sprintf("间隔%s内装置%s未定义", area_name, iedname)
|
|
|
+ r := map[string]interface{}{"scdid": c.ScdId, "lineno": 0, "ruleid": area_ruleid, "nodeid": 0, "parse_result": parse_result}
|
|
|
+ //检查未通过
|
|
|
+ scdNodeRule.AppendPaseResult(r)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }*/
|
|
|
+ }
|
|
|
+ //装置关联关系分析
|
|
|
+ //先分析母联间隔,如果没有选择母联间隔时,主变间隔中不包含母联终端装置
|
|
|
+ HasAreaJ := false
|
|
|
+ for _, row := range arealist {
|
|
|
+ area_name := tools.IsEmpty(row["area_name"])
|
|
|
+ areaCode := tools.IsEmpty(row["area_type"]) //间隔模型类型
|
|
|
+ area_id := tools.IsEmpty(row["id"])
|
|
|
+ if areaCode == "J" {
|
|
|
+ HasAreaJ = true
|
|
|
+ modelid := tools.IsEmpty(row["model_id"])
|
|
|
+ c.cJ(scdXmlObj, scdNode, scdNodeRule, area_name, model_refs[modelid], area_ieds[area_id], "PE", area_ruleid)
|
|
|
+ c.cJ(scdXmlObj, scdNode, scdNodeRule, area_name, model_refs[modelid], area_ieds[area_id], "PJ", area_ruleid)
|
|
|
+ c.cJ(scdXmlObj, scdNode, scdNodeRule, area_name, model_refs[modelid], area_ieds[area_id], "PK", area_ruleid)
|
|
|
+ c.cJ(scdXmlObj, scdNode, scdNodeRule, area_name, model_refs[modelid], area_ieds[area_id], "PF", area_ruleid)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ for _, row := range arealist {
|
|
|
+ area_name := tools.IsEmpty(row["area_name"])
|
|
|
+ areaCode := tools.IsEmpty(row["area_type"]) //间隔模型类型
|
|
|
+ area_id := tools.IsEmpty(row["id"])
|
|
|
+ modelid := tools.IsEmpty(row["model_id"])
|
|
|
+ if areaCode == "J" {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ if areaCode == "L" {
|
|
|
+ //线路间隔
|
|
|
+ c.cL(scdXmlObj, scdNode, scdNodeRule, area_name, model_refs[modelid], area_ieds[area_id], area_ruleid)
|
|
|
+ }
|
|
|
+ if areaCode == "T" {
|
|
|
+ //变压器齐间隔
|
|
|
+ c.cT(scdXmlObj, scdNode, scdNodeRule, area_name, model_refs[modelid], area_ieds[area_id], area_ruleid, HasAreaJ)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ scdNodeRule.CheckFinish()
|
|
|
+ scdNodeRule.Flush()
|
|
|
+ return nil
|
|
|
+}
|
|
|
+
|
|
|
//解析模型间隔
|
|
|
func (c *CheckAreaMgr) ParseModelArea() {
|
|
|
c.Init(c.ScdId)
|
|
@@ -743,6 +877,313 @@ func (c *CheckAreaMgr) pJ(modelid int, vol, iedtypes string, ieds map[string]orm
|
|
|
|
|
|
}
|
|
|
|
|
|
+//母联间隔装置关系检查
|
|
|
+func (c *CheckAreaMgr) cJ(scdXmlObj *node_attr.SCL, scdNodeMgr *ScdNode, scdNodeRule *ScdNodeRule, area_name string, ied_refs []orm.Params, area_ieds []orm.Params, pjIed, area_ruleid string) {
|
|
|
+
|
|
|
+ masterIed := new(node_attr.NIED)
|
|
|
+ findIedName := ""
|
|
|
+ for _, row2 := range area_ieds {
|
|
|
+ findIedName = tools.IsEmpty(row2["ied_name"])
|
|
|
+ if strings.HasPrefix(findIedName, pjIed) {
|
|
|
+ masterIed = scdNodeMgr.GetIed(scdXmlObj, "", findIedName)
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if masterIed == nil {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ dealFromIed := map[string]int{}
|
|
|
+ for _, row := range ied_refs {
|
|
|
+ fromiedtype := tools.IsEmpty(row["from_ied_code"])
|
|
|
+ toiedtype := tools.IsEmpty(row["to_ied_code"])
|
|
|
+ reftype := tools.IsEmpty(row["in_type"])
|
|
|
+ tmpFromAreaIeds := []orm.Params{}
|
|
|
+ tmpToAreaIeds := []orm.Params{}
|
|
|
+ for _, row2 := range area_ieds {
|
|
|
+ findIedName = tools.IsEmpty(row2["ied_name"])
|
|
|
+ if strings.HasPrefix(findIedName, fromiedtype) {
|
|
|
+ masterIed = scdNodeMgr.GetIed(scdXmlObj, "", findIedName)
|
|
|
+ if masterIed != nil {
|
|
|
+ tmpFromAreaIeds = append(tmpFromAreaIeds, row2)
|
|
|
+ } else {
|
|
|
+ if dealFromIed[findIedName] == 0 {
|
|
|
+ parse_result := fmt.Sprintf("间隔%s的装置%s缺失", area_name, findIedName)
|
|
|
+ r := map[string]interface{}{"scdid": c.ScdId, "lineno": 0, "ruleid": area_ruleid, "nodeid": 0, "parse_result": parse_result}
|
|
|
+ //检查未通过
|
|
|
+ scdNodeRule.AppendPaseResult(r)
|
|
|
+ }
|
|
|
+ dealFromIed[findIedName] = 1
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if strings.HasPrefix(findIedName, toiedtype) {
|
|
|
+ tmpToAreaIeds = append(tmpToAreaIeds, row2)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if len(tmpFromAreaIeds) == 0 {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ if len(tmpToAreaIeds) == 0 {
|
|
|
+ parse_result := fmt.Sprintf("间隔%s缺失类型为%s的装置", area_name, toiedtype)
|
|
|
+ r := map[string]interface{}{"scdid": c.ScdId, "lineno": 0, "ruleid": area_ruleid, "nodeid": 0, "parse_result": parse_result}
|
|
|
+ //检查未通过
|
|
|
+ scdNodeRule.AppendPaseResult(r, masterIed)
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ toIedname := ""
|
|
|
+ for _, row2 := range tmpFromAreaIeds {
|
|
|
+ findIedName = tools.IsEmpty(row2["ied_name"])
|
|
|
+ hasToIedRef := false
|
|
|
+ hasToIed := false
|
|
|
+ for _, row3 := range tmpToAreaIeds {
|
|
|
+ toIedname = tools.IsEmpty(row3["ied_name"])
|
|
|
+ masterIed = scdNodeMgr.GetIed(scdXmlObj, "", toIedname)
|
|
|
+ if masterIed != nil {
|
|
|
+ hasToIed = true
|
|
|
+ // 获取该ied的输出(ref_type为0)装置,并从中检测是否存在toiedtype类型的装置
|
|
|
+ inout, _ := scdNodeMgr.GetIedRelations(map[string]interface{}{"scd_id": c.ScdId, "ied_name": findIedName})
|
|
|
+ logger.Logger.Debug(fmt.Sprintf("ied:%s refs:%+v", findIedName, inout))
|
|
|
+ if inout != nil {
|
|
|
+ outiedlist := inout[findIedName].(orm.Params)["list"].([]orm.Params)
|
|
|
+ for _, ieditem := range outiedlist {
|
|
|
+ outiedname := ieditem["ref_ied_name"].(string)
|
|
|
+ if outiedname == toIedname && ieditem["ref_type"].(string) == "0" {
|
|
|
+ hasToIedRef = true
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if !hasToIedRef {
|
|
|
+ parse_result := fmt.Sprintf("间隔%s的装置%s缺失与装置%s的%s信号关联", area_name, findIedName, toIedname, reftype)
|
|
|
+ r := map[string]interface{}{"scdid": c.ScdId, "lineno": 0, "ruleid": area_ruleid, "nodeid": 0, "parse_result": parse_result}
|
|
|
+ //检查未通过
|
|
|
+ scdNodeRule.AppendPaseResult(r, masterIed)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if !hasToIed {
|
|
|
+ parse_result := fmt.Sprintf("间隔%s的装置%s缺失关联装置%s", area_name, findIedName, toIedname)
|
|
|
+ r := map[string]interface{}{"scdid": c.ScdId, "lineno": 0, "ruleid": area_ruleid, "nodeid": 0, "parse_result": parse_result}
|
|
|
+ //检查未通过
|
|
|
+ scdNodeRule.AppendPaseResult(r, masterIed)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+//线路间隔装置关系检查
|
|
|
+func (c *CheckAreaMgr) cL(scdXmlObj *node_attr.SCL, scdNodeMgr *ScdNode, scdNodeRule *ScdNodeRule, area_name string, ied_refs []orm.Params, area_ieds []orm.Params, area_ruleid string) {
|
|
|
+ masterIed := new(node_attr.NIED)
|
|
|
+ findIedName := ""
|
|
|
+ for _, row2 := range area_ieds {
|
|
|
+ findIedName = tools.IsEmpty(row2["ied_name"])
|
|
|
+ if strings.HasPrefix(findIedName, "PL") {
|
|
|
+ masterIed = scdNodeMgr.GetIed(scdXmlObj, "", findIedName)
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if masterIed == nil {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ dealFromIed := map[string]int{}
|
|
|
+ for _, row := range ied_refs {
|
|
|
+ fromiedtype := tools.IsEmpty(row["from_ied_code"])
|
|
|
+ toiedtype := tools.IsEmpty(row["to_ied_code"])
|
|
|
+ reftype := tools.IsEmpty(row["in_type"])
|
|
|
+ tmpFromAreaIeds := []orm.Params{}
|
|
|
+ tmpToAreaIeds := []orm.Params{}
|
|
|
+ for _, row2 := range area_ieds {
|
|
|
+ findIedName = tools.IsEmpty(row2["ied_name"])
|
|
|
+ if strings.HasPrefix(findIedName, fromiedtype) {
|
|
|
+ masterIed = scdNodeMgr.GetIed(scdXmlObj, "", findIedName)
|
|
|
+ if masterIed != nil {
|
|
|
+ tmpFromAreaIeds = append(tmpFromAreaIeds, row2)
|
|
|
+ } else {
|
|
|
+ if dealFromIed[findIedName] == 0 {
|
|
|
+ parse_result := fmt.Sprintf("间隔%s的装置%s缺失", area_name, findIedName)
|
|
|
+ r := map[string]interface{}{"scdid": c.ScdId, "lineno": 0, "ruleid": area_ruleid, "nodeid": 0, "parse_result": parse_result}
|
|
|
+ //检查未通过
|
|
|
+ scdNodeRule.AppendPaseResult(r)
|
|
|
+ }
|
|
|
+ dealFromIed[findIedName] = 1
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if strings.HasPrefix(findIedName, toiedtype) {
|
|
|
+ tmpToAreaIeds = append(tmpToAreaIeds, row2)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if len(tmpFromAreaIeds) == 0 {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ if len(tmpToAreaIeds) == 0 {
|
|
|
+ parse_result := fmt.Sprintf("间隔%s缺失类型为%s的装置", area_name, toiedtype)
|
|
|
+ r := map[string]interface{}{"scdid": c.ScdId, "lineno": 0, "ruleid": area_ruleid, "nodeid": 0, "parse_result": parse_result}
|
|
|
+ //检查未通过
|
|
|
+ scdNodeRule.AppendPaseResult(r, masterIed)
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ toIedname := ""
|
|
|
+ for _, row2 := range tmpFromAreaIeds {
|
|
|
+ findIedName = tools.IsEmpty(row2["ied_name"])
|
|
|
+ hasToIedRef := false
|
|
|
+ hasToIed := false
|
|
|
+ for _, row3 := range tmpToAreaIeds {
|
|
|
+ toIedname = tools.IsEmpty(row3["ied_name"])
|
|
|
+ masterIed = scdNodeMgr.GetIed(scdXmlObj, "", toIedname)
|
|
|
+ if masterIed != nil {
|
|
|
+ hasToIed = true
|
|
|
+ // 获取该ied的输出(ref_type为0)装置,并从中检测是否存在toiedtype类型的装置
|
|
|
+ inout, _ := scdNodeMgr.GetIedRelations(map[string]interface{}{"scd_id": c.ScdId, "ied_name": findIedName})
|
|
|
+ logger.Logger.Debug(fmt.Sprintf("ied:%s refs:%+v", findIedName, inout))
|
|
|
+ if inout != nil {
|
|
|
+ outiedlist := inout[findIedName].(orm.Params)["list"].([]orm.Params)
|
|
|
+ for _, ieditem := range outiedlist {
|
|
|
+ outiedname := ieditem["ref_ied_name"].(string)
|
|
|
+ if outiedname == toIedname && ieditem["ref_type"].(string) == "0" {
|
|
|
+ hasToIedRef = true
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if !hasToIedRef {
|
|
|
+ parse_result := fmt.Sprintf("间隔%s的装置%s缺失与装置%s的%s信号关联", area_name, findIedName, toIedname, reftype)
|
|
|
+ r := map[string]interface{}{"scdid": c.ScdId, "lineno": 0, "ruleid": area_ruleid, "nodeid": 0, "parse_result": parse_result}
|
|
|
+ //检查未通过
|
|
|
+ scdNodeRule.AppendPaseResult(r, masterIed)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if !hasToIed {
|
|
|
+ parse_result := fmt.Sprintf("间隔%s的装置%s缺失关联装置%s", area_name, findIedName, toIedname)
|
|
|
+ r := map[string]interface{}{"scdid": c.ScdId, "lineno": 0, "ruleid": area_ruleid, "nodeid": 0, "parse_result": parse_result}
|
|
|
+ //检查未通过
|
|
|
+ scdNodeRule.AppendPaseResult(r, masterIed)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+//变压器间隔装置关系检查
|
|
|
+func (c *CheckAreaMgr) cT(scdXmlObj *node_attr.SCL, scdNodeMgr *ScdNode, scdNodeRule *ScdNodeRule, area_name string, ied_refs []orm.Params, area_ieds []orm.Params, area_ruleid string, HasAreaJ bool) {
|
|
|
+ masterIed := new(node_attr.NIED)
|
|
|
+ findIedName := ""
|
|
|
+ for _, row2 := range area_ieds {
|
|
|
+ findIedName = tools.IsEmpty(row2["ied_name"])
|
|
|
+ if strings.HasPrefix(findIedName, "PT") {
|
|
|
+ masterIed = scdNodeMgr.GetIed(scdXmlObj, "", findIedName)
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if masterIed == nil {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ scdParseMgr := new(ScdParse)
|
|
|
+ dealFromIed := map[string]int{}
|
|
|
+ for _, row := range ied_refs {
|
|
|
+ fromiedtype := tools.IsEmpty(row["from_ied_code"])
|
|
|
+ toiedtype := tools.IsEmpty(row["to_ied_code"])
|
|
|
+ reftype := tools.IsEmpty(row["in_type"])
|
|
|
+ tmpFromAreaIeds := []orm.Params{}
|
|
|
+ tmpToAreaIeds := []orm.Params{}
|
|
|
+ for _, row2 := range area_ieds {
|
|
|
+ findIedName = tools.IsEmpty(row2["ied_name"])
|
|
|
+ if strings.HasPrefix(findIedName, fromiedtype) {
|
|
|
+ masterIed = scdNodeMgr.GetIed(scdXmlObj, "", findIedName)
|
|
|
+ if masterIed != nil {
|
|
|
+ tmpFromAreaIeds = append(tmpFromAreaIeds, row2)
|
|
|
+ } else {
|
|
|
+ if dealFromIed[findIedName] == 0 {
|
|
|
+ parse_result := fmt.Sprintf("间隔%s的装置%s缺失", area_name, findIedName)
|
|
|
+ r := map[string]interface{}{"scdid": c.ScdId, "lineno": 0, "ruleid": area_ruleid, "nodeid": 0, "parse_result": parse_result}
|
|
|
+ //检查未通过
|
|
|
+ scdNodeRule.AppendPaseResult(r)
|
|
|
+ }
|
|
|
+ dealFromIed[findIedName] = 1
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if strings.HasPrefix(findIedName, toiedtype) {
|
|
|
+ tmpToAreaIeds = append(tmpToAreaIeds, row2)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if len(tmpFromAreaIeds) == 0 {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ if len(tmpToAreaIeds) == 0 {
|
|
|
+ logger.Logger.Debug(fmt.Sprintf("缺失类型关联装置 :%+v", row))
|
|
|
+ parse_result := fmt.Sprintf("间隔%s缺失类型为%s的装置", area_name, toiedtype)
|
|
|
+ r := map[string]interface{}{"scdid": c.ScdId, "lineno": 0, "ruleid": area_ruleid, "nodeid": 0, "parse_result": parse_result}
|
|
|
+ //检查未通过
|
|
|
+ scdNodeRule.AppendPaseResult(r, masterIed)
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ toIedname := ""
|
|
|
+ for _, row2 := range tmpFromAreaIeds {
|
|
|
+ findIedName = tools.IsEmpty(row2["ied_name"])
|
|
|
+ hasToIedRef := false
|
|
|
+ hasToIed := false
|
|
|
+ t1 := fromiedtype + "->" + toiedtype
|
|
|
+ volLevel := "" //电压等级
|
|
|
+ if t1 == "CT->IT" || t1 == "IT->CT" || t1 == "CT->IB" || t1 == "IB->CT" || t1 == "MM->MT" || t1 == "PM->IB" || t1 == "IB->PM" || t1 == "PM->IT" || t1 == "IT->PM" {
|
|
|
+ ps := scdParseMgr.ParseIedName(findIedName)
|
|
|
+ volLevel = ps[3] + ps[4]
|
|
|
+ }
|
|
|
+ hasSameVolIed := false
|
|
|
+ for _, row3 := range tmpToAreaIeds {
|
|
|
+ toIedname = tools.IsEmpty(row3["ied_name"])
|
|
|
+ if volLevel != "" {
|
|
|
+ ps := scdParseMgr.ParseIedName(toIedname)
|
|
|
+ if volLevel != ps[3]+ps[4] {
|
|
|
+ //排除不是同一电压等级的装置
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ hasSameVolIed = true
|
|
|
+ }
|
|
|
+ if scdNodeMgr.GetIed(scdXmlObj, "", toIedname) != nil {
|
|
|
+ hasToIed = true
|
|
|
+ // 获取该ied的输出(ref_type为0)装置,并从中检测是否存在toiedtype类型的装置
|
|
|
+ inout, _ := scdNodeMgr.GetIedRelations(map[string]interface{}{"scd_id": c.ScdId, "ied_name": findIedName})
|
|
|
+ logger.Logger.Debug(fmt.Sprintf("ied:%s refs:%+v", findIedName, inout))
|
|
|
+ if inout != nil {
|
|
|
+ outiedlist := inout[findIedName].(orm.Params)["list"].([]orm.Params)
|
|
|
+ for _, ieditem := range outiedlist {
|
|
|
+ outiedname := ieditem["ref_ied_name"].(string)
|
|
|
+ if outiedname == toIedname && ieditem["ref_type"].(string) == "0" {
|
|
|
+ hasToIedRef = true
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if !hasToIedRef {
|
|
|
+ parse_result := fmt.Sprintf("间隔%s的装置%s缺失与装置%s的%s信号关联", area_name, findIedName, toIedname, reftype)
|
|
|
+ r := map[string]interface{}{"scdid": c.ScdId, "lineno": 0, "ruleid": area_ruleid, "nodeid": 0, "parse_result": parse_result}
|
|
|
+ //检查未通过
|
|
|
+ scdNodeRule.AppendPaseResult(r, masterIed)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if hasSameVolIed {
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if toiedtype != "PT" {
|
|
|
+ if volLevel != "" && !hasSameVolIed {
|
|
|
+ parse_result := fmt.Sprintf("间隔%s的装置%s缺失同电压等级的关联类型%s装置", area_name, findIedName, toiedtype)
|
|
|
+ r := map[string]interface{}{"scdid": c.ScdId, "lineno": 0, "ruleid": area_ruleid, "nodeid": 0, "parse_result": parse_result}
|
|
|
+ //检查未通过
|
|
|
+ scdNodeRule.AppendPaseResult(r, masterIed)
|
|
|
+ } else if !hasToIed {
|
|
|
+ parse_result := fmt.Sprintf("间隔%s的装置%s缺失关联装置%s", area_name, findIedName, toIedname)
|
|
|
+ r := map[string]interface{}{"scdid": c.ScdId, "lineno": 0, "ruleid": area_ruleid, "nodeid": 0, "parse_result": parse_result}
|
|
|
+ //检查未通过
|
|
|
+ scdNodeRule.AppendPaseResult(r, masterIed)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
//根据参考ied name找出应该关联PM装置
|
|
|
func (c *CheckAreaMgr) getPMName(iednameParts []string, ieds map[string]orm.Params) string {
|
|
|
tmpIedName := "PM" + iednameParts[3] + iednameParts[4] + iednameParts[5] + "1" + iednameParts[7]
|