瀏覽代碼

添加遥信端子解析时规则:单点和双点类型匹配规则
解决已发现的bug

liling 1 年之前
父節點
當前提交
5630c6a714

+ 2 - 2
service/main.go

@@ -99,8 +99,8 @@ func main() {
 		db.ConnSqlite("conf/db.cnf")
 	}
 	//new(test.UnitTest).TestIntAddrParse("RPIT/GOINGGIO1.SPCSO1.stVal")
-	//new(test.UnitTest).TestDoiNameRex("(断路器)&(跳|合|闸){1,}&(位置)", "断路器跳位置")
-	//new(test.UnitTest).TestDoiNameRex("Ia1&A&保护", "保护A相电流Ia1(正)")
+	//new(test.UnitTest).TestDoiNameRex("(断路器)&(跳|合|闸){1,}&(位置)", "断路器跳位置")
+	//new(test.UnitTest).TestDoiNameRex("[断|路|器]", "保护A相电流Ia1(正)")
 	go mqtt.Start()
 	if runmode == "dev" {
 		//自动生成接口权限定义

+ 6 - 4
service/models/bo/check_sysmodel_ied_func.go

@@ -226,10 +226,12 @@ func (c *SysCheckModelIedFuncMgr) Delete(onlyFunc ...bool) (err error) {
 }
 
 func (c *SysCheckModelIedFuncMgr) GetList(modelid int, iedType string) ([]orm.Params, error) {
-	mappresult := new(SysCheckModelIedtypeMappingMgr).GetMappingType(modelid, iedType)
-	if mappresult != "" {
-		iedType = mappresult
-	}
+	/*
+		mappresult := new(SysCheckModelIedtypeMappingMgr).GetMappingType(modelid, iedType)
+		if mappresult != "" {
+			iedType = mappresult
+		}
+	*/
 	//获取装置分组信息
 	bgm := new(SysCheckModelIedtypeGroupMgr)
 	bgm.Model = T_data_model_iedtype_group{ModelId: modelid}

+ 6 - 4
service/models/bo/check_sysmodel_ied_func_fcda.go

@@ -302,10 +302,12 @@ func (c *SysCheckModelIedFuncFcdaMgr) GetList(refIedtype string, funcids ...[]st
 	sqlParamters := []interface{}{c.Model.ModelId}
 	outsql := ""
 	desc := ""
-	mappresult := new(SysCheckModelIedtypeMappingMgr).GetMappingType(c.Model.ModelId, refIedtype)
-	if mappresult != "" {
-		refIedtype = mappresult
-	}
+	/*
+		mappresult := new(SysCheckModelIedtypeMappingMgr).GetMappingType(c.Model.ModelId, refIedtype)
+		if mappresult != "" {
+			refIedtype = mappresult
+		}
+	*/
 	//获取装置分组信息
 	bgm := new(SysCheckModelIedtypeGroupMgr)
 	bgm.Model = T_data_model_iedtype_group{ModelId: c.Model.ModelId}

+ 30 - 4
service/models/bo/checktools_area.go

@@ -604,7 +604,7 @@ func (c *CheckAreaMgr) CheckIedFcda() error {
 	//iedRelationMgr := new(SysCheckModelIedRelationMgr)
 	modelFcda := sync.Map{}
 	//已经加载过遥信的装置
-	isLoadYxIed := map[string]map[*node_attr.NExtRef]string{}
+	isLoadYxIed := map[string]map[*node_attr.NExtRef][]string{}
 	//已经处理过遥信端子的装置
 	isDealYxIed := map[string]int{}
 	//已获取端子的装置
@@ -854,11 +854,13 @@ func (c *CheckAreaMgr) CheckIedFcda() error {
 					}
 				}
 				//判断装置是否具备遥信功能,具备时需要单独处理遥信类端子
-				//遥信类端子处理规则:以scd中实际配置为准,通过检查装置双方的端子名称是否完全一致,以及是否有缺失和多余的遥信端子
+				//遥信类端子处理规则:以scd中实际配置为准,通过检查装置双方的端子名称是否完全一致以及单双点类型是否相同,以及是否有缺失和多余的遥信端子
 				if len(yx) > 0 && isDealYxIed[iedname] == 0 {
 					//logger.Logger.Debug(fmt.Sprintf("=============正在处理装置%s遥信端子数:%d  %+v", iedname, len(yx), isDealYxIed))
 					isDealYxIed[iedname] = 1
-					for extref, doiDesc := range yx {
+					for extref, doiinfo := range yx {
+						doiDesc := doiinfo[0]
+						doiCdc := doiinfo[1]
 						daname := ""
 						if extref.DaName != "" {
 							daname = "." + extref.DaName
@@ -882,7 +884,31 @@ func (c *CheckAreaMgr) CheckIedFcda() error {
 							}
 							//检查未通过
 							scdNodeRule.AppendFcdaCheckResult(re)
-						} else if outFcdaDoi.(*node_attr.NDOI).Desc != doiDesc {
+							continue
+						}
+						if doiCdc != "" && (!YaoXinDBType[doiCdc] || !YaoXinSiType[doiCdc]) {
+							//判断是否是双点或单点遥信端子
+							fcdaCdcCode := new(ScdMgr).GetDoiCdcInfo(scdXmlObj, c.ScdId, outFcdaDoi.(*node_attr.NDOI))
+							if doiCdc != fcdaCdcCode {
+								//错误:cdc类型不一致
+								parse_result := fmt.Sprintf("间隔%s的接收装置%s遥信端子%s与输出装置%s端子%s的CDC类型不一致(%s,%s)", area_name, iedname, doiDesc, tmpIedObj.Name, outFcdaDoi.(*node_attr.NDOI).Desc, doiCdc, fcdaCdcCode)
+								re := map[string]interface{}{"scdid": c.ScdId, "lineno": 0, "ruleid": area_ruleid, "nodeid": 0, "parse_result": parse_result,
+									"ied_name":      iedname,
+									"ied_desc":      iedObj.Desc,
+									"out_ied_name":  tmpIedObj.Name,
+									"out_ied_desc":  tmpIedObj.Desc,
+									"fcda_desc":     doiDesc,
+									"fcda_addr":     extref.IntAddr,
+									"out_fcda_desc": outFcdaDoi.(*node_attr.NDOI).Desc,
+									"out_fcda_addr": fmt.Sprintf("%s/%s%s%s.%s%s", extref.LdInst, extref.Prefix, extref.LnClass, extref.LnInst, extref.DoName, daname),
+									"error_type":    "2",
+								}
+								//检查未通过
+								scdNodeRule.AppendFcdaCheckResult(re)
+								continue
+							}
+						}
+						if outFcdaDoi.(*node_attr.NDOI).Desc != doiDesc {
 							//关联错误
 							parse_result := fmt.Sprintf("间隔%s的装置%s遥信端子%s与装置%s端子%s名称不匹配", area_name, iedname, doiDesc, tmpIedObj.Name, outFcdaDoi.(*node_attr.NDOI).Desc)
 							re := map[string]interface{}{"scdid": c.ScdId, "lineno": 0, "ruleid": area_ruleid, "nodeid": 0, "parse_result": parse_result,

+ 39 - 3
service/models/bo/scd_mgr.go

@@ -1257,6 +1257,18 @@ var YaoXinMap = map[string]string{
 	"DPL": "DPL",
 	"SEC": "安全违例计数",
 }
+
+//双点遥信类型
+var YaoXinDBType = map[string]bool{
+	"DPS": true,
+	"DPC": true,
+}
+
+//单点遥信类型
+var YaoXinSiType = map[string]bool{
+	"SPS": true,
+	"SPC": true,
+}
 var YaoKongMap = map[string]string{
 	"SPC": "SPC",
 	"DPC": "DPC",
@@ -1633,8 +1645,9 @@ func (c *ScdMgr) GetYcYkYmMap(scdXmlObj *node_attr.SCL, iedname string) (yc map[
 }
 
 //获取指定IED下遥信接收端子
-func (c *ScdMgr) GetYxExtref(scdXmlObj *node_attr.SCL, scdid int64, iedname string) map[*node_attr.NExtRef]string {
-	result := map[*node_attr.NExtRef]string{}
+//return: map对象。key为端子对象地址,value为字符串数组,固定2个元素。第一个元素为端子描述,第二个元素为端子的cdc类型码
+func (c *ScdMgr) GetYxExtref(scdXmlObj *node_attr.SCL, scdid int64, iedname string) map[*node_attr.NExtRef][]string {
+	result := map[*node_attr.NExtRef][]string{}
 	targetIedObj := new(ScdNode).GetIed(scdXmlObj, "", iedname)
 	mapTargetLNodeType := c.GetLNodeType(scdXmlObj)
 	mapTargetLDoType := c.GetDOType(scdXmlObj)
@@ -1665,7 +1678,7 @@ func (c *ScdMgr) GetYxExtref(scdXmlObj *node_attr.SCL, scdid int64, iedname stri
 									if dotypeobj, h := mapTargetLDoType[dotype]; h {
 										cdctype := new(ScdMgr).GetDoTypePointType(dotypeobj, nil)
 										if cdctype == "YX" {
-											result[extref] = doiObj.Desc
+											result[extref] = []string{doiObj.Desc, dotypeobj.Cdc}
 										}
 									}
 									break
@@ -1740,3 +1753,26 @@ func (c *ScdMgr) GetDoTypePointType(dotype *node_attr.NDOType, fcda *node_attr.N
 	}
 	return ""
 }
+
+//根据doi对象获取对应的cdc代码及名称
+func (c *ScdMgr) GetDoiCdcInfo(scdXmlObj *node_attr.SCL, scdid int64, doiObj *node_attr.NDOI) string {
+	mapTargetLNodeType := c.GetLNodeType(scdXmlObj)
+	mapTargetLDoType := c.GetDOType(scdXmlObj)
+
+	tmpdata, _ := GlobalNodeMap.Load(scdid)
+	nodeCacheMap := tmpdata.(map[int64]NodeCacheMap)
+	lnnode := nodeCacheMap[nodeCacheMap[doiObj.NodeId].ParentNodeId]
+	lnType := lnnode.ObjAddr.(*node_attr.NLNode).LnType
+	if lnnodetpye, h := mapTargetLNodeType[lnType]; h {
+		for _, doitem := range lnnodetpye.DO {
+			if doitem.Name == doiObj.Name {
+				dotype := doitem.Type
+				if dotypeobj, h := mapTargetLDoType[dotype]; h {
+					return dotypeobj.Cdc
+				}
+				break
+			}
+		}
+	}
+	return ""
+}

+ 1 - 1
service/models/node_attr/scl.go

@@ -1,9 +1,9 @@
 package node_attr
 
 import (
-	"scd_check_tools/logger"
 	"errors"
 	"fmt"
+	"scd_check_tools/logger"
 
 	"github.com/astaxie/beego/orm"
 )