package bo import ( "errors" "fmt" "scd_check_tools/logger" "scd_check_tools/models/enum" "scd_check_tools/tools" "strconv" "strings" "sync" "github.com/astaxie/beego/orm" ) //检测时间隔管理 type CheckAreaMgr struct { DeviceBaseModel //SCD文件ID ScdId int64 //电压等级定义 VoltageLevelDef map[string]int //设备类型定义 DeviceTypeDef map[string]int CacheAreaID map[string]int64 CacheAreaIDByIedNameNo map[string]int //检测模型列表 CheckModelList []orm.Params //模型内装置关系定义 CheckModelDef sync.Map CacheLock sync.RWMutex } type T_data_check_area struct { Id int64 `orm:"pk"` AreaName string ScdId int64 VoltageLevel int AreaType string ModelId int Cr int // '创建人' , Ct string `orm:"-"` // '创建时间' , Ur int // '更新人' , Ut string `orm:"-"` // '更新时间' } type t_data_check_area_ied struct { Id int64 `orm:"pk"` AreaId int64 IedName string IedType string ScdId int64 PType string Cr int // '创建人' , Ct string `orm:"-"` // '创建时间' , Ur int // '更新人' , Ut string `orm:"-"` // '更新时间' } func init() { orm.RegisterModel(new(T_data_check_area)) orm.RegisterModel(new(t_data_check_area_ied)) } func (c *CheckAreaMgr) Init(scdid int64) { c.VoltageLevelDef = map[string]int{} c.DeviceTypeDef = map[string]int{} c.CacheAreaIDByIedNameNo = map[string]int{} c.CacheAreaID = map[string]int64{} c.CacheLock = sync.RWMutex{} c.ScdId = scdid db := orm.NewOrm() rowset := []orm.Params{} db.Raw("select * from global_const_code where parentcode=?", "voltage_level").Values(&rowset) for _, row := range rowset { vl := strings.ToLower(tools.IsEmpty(row["code"])) id, _ := strconv.ParseInt(tools.IsEmpty(row["id"]), 10, 32) c.VoltageLevelDef[strings.ReplaceAll(vl, "v_level_", "")] = int(id) } db.Raw("select * from global_const_code where parentcode=?", "device_type").Values(&rowset) for _, row := range rowset { vl := tools.IsEmpty(row["code"]) c.DeviceTypeDef[vl] = 1 } v, _ := GetSysParamValue("OtherIedNameList", "") otherIedNameList = map[string]bool{} if v != "" { vs := strings.Split(v, ",") for _, vv := range vs { otherIedNameList[vv] = true } } //先清除ied与间隔关联关系 clearSql := "delete from t_data_check_area_ied where area_id in(select id from t_data_check_area where scd_id=?)" _, err := db.Raw(clearSql, c.ScdId).Exec() if err != nil { logger.Logger.Error(err, fmt.Sprintf("SQL:%s 参数:%+v", clearSql, []interface{}{c.ScdId})) } clearSql = "delete from t_data_check_area where scd_id=?" _, err = db.Raw(clearSql, c.ScdId).Exec() if err != nil { logger.Logger.Error(err, fmt.Sprintf("SQL:%s 参数:%+v", clearSql, []interface{}{c.ScdId})) } //获取当前scd信息中获取到对应的电压等级id /* scdMgr := new(ScdMgr) scdinfo, _ := scdMgr.One(fmt.Sprintf("%d", c.ScdId)) stationid := tools.IsEmpty(scdinfo["station_id"]) volid := 0 if stationid != "" { basearea := new(BasicArea) stationonof, _ := basearea.One(stationid) volid = stationonof.AreaLevel } */ tmplist, _ := new(SysCheckModelMgr).GetModelsByVolid() scdModels, _, _ := new(TaskMgr).GetModelsByScdID(c.ScdId) ms := map[string]interface{}{} for _, row := range scdModels { ms[tools.IsEmpty(row["model_id"])] = row } for _, row := range tmplist { modelid := tools.IsEmpty(row["id"]) if ms[modelid] != nil { c.CheckModelList = append(c.CheckModelList, row) } } logger.Logger.Debug(fmt.Sprintf("任务的模型列表:%+v", c.CheckModelList)) ms = nil tmplist = nil } //保存指定间隔所属的电压等级 func (c *CheckAreaMgr) SetVoltageLevel(id string, voltagelevel int) error { db := orm.NewOrm() _, err := db.Raw("update t_data_check_area set voltage_level=? where id=?", voltagelevel, id).Exec() return err } //修改指定间隔的名称 func (c *CheckAreaMgr) UpdateName(scdid int64, area_id int, name string) error { db := orm.NewOrm() areaM := T_data_check_area{Id: int64(area_id), ScdId: scdid} err := db.Read(&areaM) if err != nil { logger.Logger.Error(err) return err } areaM.AreaName = name _, err = db.Update(&areaM) if err != nil { logger.Logger.Error(err) } return err } //修改指定IED的所属间隔 func (c *CheckAreaMgr) UpdateIedArea(scdid int64, iedname string, area_id int) error { db := orm.NewOrm() _, err := db.Raw("update t_data_check_area_ied set area_id=? where scd_id=? and ied_name=?", area_id, scdid, iedname).Exec() return err } //获取指定scd的间隔信息 func (c *CheckAreaMgr) GetAreaList(scdid int64) ([]orm.Params, error) { db := orm.NewOrm() sql := "select t.*,(select count(1) from t_data_check_area_ied where area_id=t.id) iedcount from t_data_check_area t where t.scd_id=? order by t.name" rowset := []orm.Params{} _, err := db.Raw(sql, scdid).Values(&rowset) sqllog := fmt.Sprintf("SQL:%s 参数:%+v", sql, []interface{}{scdid}) if err != nil { logger.Logger.Error(err, sqllog) new(SystemLog).Fail(enum.AuditType_scd_show, enum.LogType_Query, enum.OptEventType_Bus, enum.OptEventLevel_Low, sqllog, c.GetUserInfo()) } else { new(SystemLog).Success(enum.AuditType_scd_show, enum.LogType_Query, enum.OptEventType_Bus, enum.OptEventLevel_Low, sqllog, c.GetUserInfo()) } return rowset, nil } //获取指定scd和电压等级的间隔信息 func (c *CheckAreaMgr) GetAreaListByVol(scdid int64, vl, linkstyleid int) ([]orm.Params, error) { db := orm.NewOrm() sql := "select t1.id model_id, t1.model_name,t1.vol_id,g1.name vol_name,t1.line_link_style,ls.name,t.id area_id, t.area_name,t.ut,t.ur from t_data_check_area t right join t_data_model_defualt t1 on t.model_id=t1.id left join t_data_link_style ls on t1.line_link_style=ls.id left join global_const_code g1 on t1.vol_id=g1.id and g1.parentcode='voltage_level' where t.scd_id=? " params := []interface{}{scdid} if vl > 0 { sql = sql + " and t1.vol_id=? " params = append(params, vl) } if linkstyleid > 0 { sql = sql + " and t1.line_link_style=? " params = append(params, linkstyleid) } rowset := []orm.Params{} _, err := db.Raw(sql+" order by t1.vol_id,t1.line_link_style,t1.id", params).Values(&rowset) sqllog := fmt.Sprintf("SQL:%s 参数:%+v", sql, []interface{}{scdid, vl}) if err != nil { logger.Logger.Error(err, sqllog) new(SystemLog).Fail(enum.AuditType_scd_show, enum.LogType_Query, enum.OptEventType_Bus, enum.OptEventLevel_Low, sqllog, c.GetUserInfo()) } else { new(SystemLog).Success(enum.AuditType_scd_show, enum.LogType_Query, enum.OptEventType_Bus, enum.OptEventLevel_Low, sqllog, c.GetUserInfo()) } return rowset, nil } //获取指定间隔下的IED列表 func (c *CheckAreaMgr) GetIedList(scdid int64, areaid int) ([]orm.Params, error) { db := orm.NewOrm() sql := "select t1.* from t_data_check_area t,t_data_check_area_ied t1 where t.scd_id=? and t.id=t1.area_id " sqlParamters := []interface{}{} sqlParamters = append(sqlParamters, scdid) if areaid > 0 { sql = sql + " and t1.area_id=?" sqlParamters = append(sqlParamters, areaid) } scdXmlObj, serr := new(ScdParse).GetScdXmlObjectBySCDID(tools.IsEmpty(scdid)) if serr != nil { return nil, serr } if scdXmlObj == nil { return nil, errors.New("无效的SCD") } rowset := []orm.Params{} _, err := db.Raw(sql, sqlParamters).Values(&rowset) sqllog := fmt.Sprintf("SQL:%s 参数:%+v", sql, sqlParamters) if err != nil { logger.Logger.Error(err, sqllog) new(SystemLog).Fail(enum.AuditType_scd_show, enum.LogType_Query, enum.OptEventType_Bus, enum.OptEventLevel_Low, sqllog, c.GetUserInfo()) } else { scdNode := new(ScdNode) for _, row := range rowset { iedid, _ := strconv.ParseInt(tools.IsEmpty(row["ied_name"]), 10, 64) iedObj := scdNode.GetIedByID(scdXmlObj, tools.IsEmpty(scdid), iedid) if iedObj == nil { continue } row["attr_name"] = iedObj.Name row["attr_desc"] = iedObj.Desc row["attr_config_version"] = iedObj.ConfigVersion row["attr_type"] = iedObj.Type row["attr_manufacturer"] = iedObj.Manufacturer row["ied_id"] = iedObj.NodeId } new(SystemLog).Success(enum.AuditType_scd_show, enum.LogType_Query, enum.OptEventType_Bus, enum.OptEventLevel_Low, sqllog, c.GetUserInfo()) } return rowset, nil } //更新指定间隔下的装置定义 func (c *CheckAreaMgr) UpdateIeds(scdid int64, areaid int, ieds string) error { db := orm.NewOrm() iedlist := strings.Split(ieds, ",") _, err := db.Raw("delete from t_data_check_area_ied where scd_id=? and area_id=?", scdid, areaid).Exec() if err != nil { logger.Logger.Error(err) return err } for _, row := range iedlist { _, err = db.Raw("insert into t_data_check_area_ied(scd_id,area_id,ied_name)values(?,?,?)", scdid, areaid, row).Exec() if err != nil { logger.Logger.Error(err) break } } return err } //获取指定SCD的IED类型列表 func (c *CheckAreaMgr) GetIedTypeList(scdid int64) ([]orm.Params, error) { db := orm.NewOrm() sql := "select t2.* from t_data_check_area_ied t1,global_const_code t2 where t1.scd_id=? and t1.ied_type=t2.code and t2.parentcode='device_type' group by t1.ied_type " sqlParamters := []interface{}{} rowset := []orm.Params{} sqlParamters = append(sqlParamters, scdid) _, err := db.Raw(sql, sqlParamters).Values(&rowset) sqllog := fmt.Sprintf("SQL:%s 参数:%+v", sql, sqlParamters) if err != nil { logger.Logger.Error(err, sqllog) new(SystemLog).Fail(enum.AuditType_scd_show, enum.LogType_Query, enum.OptEventType_Bus, enum.OptEventLevel_Low, sqllog, c.GetUserInfo()) } return rowset, nil } func (c *CheckAreaMgr) One(id string) (interface{}, error) { db := orm.NewOrm() idInt, err := strconv.ParseInt(id, 10, 64) if err != nil { return nil, err } areaM := T_data_check_area{Id: idInt} err = db.Read(&areaM) if err == nil { return areaM, nil } return nil, err } //重置scd的间隔信息 func (c *CheckAreaMgr) Reset() error { dbo := orm.NewOrm() dbo.Raw("delete from t_data_check_area where scd_id=?", c.ScdId).Exec() dbo.Raw("delete from t_data_check_area_ied where scd_id=?", c.ScdId).Exec() c.ParseModelArea() logdesc := fmt.Sprintf("重置SCD[%d]检测模型间隔成功", c.ScdId) new(SystemLog).Success(enum.AuditType_check_task, enum.LogType_bind, enum.OptEventType_Bus, enum.OptEventLevel_Mid, logdesc, c.GetUserInfo()) return nil } //解析模型间隔 func (c *CheckAreaMgr) ParseModelArea() { c.Init(c.ScdId) // 取得当前scd所有ied及名称解析结果 dbo := orm.NewOrm() sql := "select t.*,t1.name area_name from t_area_ied_relation t,t_substation_area t1 where t.area_id=t1.id and t.scd_id=? order by t.p_type" iedlst := []orm.Params{} _, err := dbo.Raw(sql, c.ScdId).Values(&iedlst) if err != nil { logger.Logger.Error(err) return } logger.Logger.Debug(fmt.Sprintf("=====总装置数:%d", len(iedlst))) iedMap := map[string]orm.Params{} for _, r := range iedlst { iedMap[tools.IsEmpty(r["ied_name"])] = r } //先分析母联间隔,如果没有选择母联间隔时,主变间隔中不包含母联终端装置 HasAreaJ := false for _, row := range c.CheckModelList { areaCode := tools.IsEmpty(row["area_type_code"]) if areaCode == "J" { HasAreaJ = true modelid, _ := strconv.Atoi(tools.IsEmpty(row["id"])) //modelname := tools.IsEmpty(row["model_name"]) iedtypes := tools.IsEmpty(row["ied_types"]) volcode := strings.ReplaceAll(tools.IsEmpty(row["vol_code"]), "v_level_", "") c.pJ(modelid, volcode, iedtypes, iedMap, "PE") c.pJ(modelid, volcode, iedtypes, iedMap, "PJ") c.pJ(modelid, volcode, iedtypes, iedMap, "PK") c.pJ(modelid, volcode, iedtypes, iedMap, "PF") } } for _, row := range c.CheckModelList { //逐一分析模型定义 modelid, _ := strconv.Atoi(tools.IsEmpty(row["id"])) modelname := tools.IsEmpty(row["model_name"]) iedtypes := tools.IsEmpty(row["ied_types"]) //模型对应的间隔代码 /* S 站用变压器 C 电容器 B 断路器 K 母分 J 母联 M 母线 X 电抗器 L 线路 T 主变压器 */ areaCode := tools.IsEmpty(row["area_type_code"]) //模型对应的电压等级 //10:10KV 35:35KV 66:66KV 11:110KV 22:220KV 50:500KV 75:750KV 33:330KV T0:1000KV volcode := strings.ReplaceAll(tools.IsEmpty(row["vol_code"]), "v_level_", "") if modelname == "" || iedtypes == "" { continue } //母联间隔已经提前分析,如果没有母联间隔时,主变间隔中不包含母联终端装置 if areaCode == "J" { continue } //获取模型内中装备关系定义 //主变间隔分析:需要查站内该电压等级下的高中低压侧装置或者高低压装置组成一个间隔,以主变保护装置(PT)为起始 if areaCode == "T" { c.pT(modelid, iedtypes, iedMap, HasAreaJ) } //线路保护间隔分析:以线路保护测控装置(PL)为开始分析 if areaCode == "L" { c.pL(modelid, volcode, iedtypes, iedMap) } } } //变压器间隔分析 func (c *CheckAreaMgr) pT(modelid int, iedtypes string, ieds map[string]orm.Params, HasAreaJ bool) { scdParseMgr := new(ScdParse) db := orm.NewOrm() //获取当前站的各电压等级 volRows := []orm.Params{} _, err := db.Raw("select t.vol, CAST(REPLACE(UPPER(g.name),'KV','') as SIGNED) volname from t_area_ied_relation t,global_const_code g where g.code=CONCAT('v_level_',t.vol) and g.parentcode='voltage_level' and t.vol!=999 and t.scd_id=? GROUP BY t.vol ORDER BY volname desc", c.ScdId).Values(&volRows) if err != nil { logger.Logger.Error(err) return } if len(volRows) == 0 { logger.Logger.Error(errors.New("该scd未发现任何电压等级的装置")) return } volMap := map[string]string{} volMap["hight"] = tools.IsEmpty(volRows[0]["vol"]) //高压电压 if len(volRows) == 2 { volMap["middle"] = "" volMap["low"] = volRows[1]["vol"].(string) //低压电压等级 } else { volMap["middle"] = volRows[1]["vol"].(string) //中压电压等级 volMap["low"] = volRows[len(volRows)-1]["vol"].(string) //低压电压等级 } for _, row := range ieds { if tools.IsEmpty(row["ied_type"]) != "P" || tools.IsEmpty(row["p_type"]) != "T" { continue } //pmIedName := "" //mmIedName := "" pl_iedname := tools.IsEmpty(row["ied_name"]) iednameParts := scdParseMgr.ParseIedName(pl_iedname) //添加间隔数据 dbdata := T_data_check_area{ ModelId: modelid, ScdId: c.ScdId, AreaType: "T", AreaName: tools.IsEmpty(row["area_name"]) + iednameParts[7], } newid, err := db.Insert(&dbdata) if err != nil { logger.Logger.Error(err) return } ins1 := "insert into t_data_check_area_ied(scd_id,area_id,ied_name,ied_type,p_type)values" insvalues := []string{} inAreaIedName := pl_iedname insvalues = append(insvalues, fmt.Sprintf("(%d,%d,'%s','%s','%s')", c.ScdId, newid, inAreaIedName, "P", "T")) //合智一体IMT/MIT,分高中低压 h, m, l := c.getIedListByVol("IMT", ieds, volMap) h = append(h, m...) h = append(h, l...) for _, r := range h { inAreaIedName = tools.IsEmpty(r["ied_name"]) tmpIednameParts := scdParseMgr.ParseIedName(inAreaIedName) lastChar := tmpIednameParts[7] if lastChar == iednameParts[7] { insvalues = append(insvalues, fmt.Sprintf("(%d,%d,'%s','%s','%s')", c.ScdId, newid, inAreaIedName, "IM", "T")) } } h, m, l = c.getIedListByVol("MIT", ieds, volMap) h = append(h, m...) h = append(h, l...) for _, r := range h { inAreaIedName = tools.IsEmpty(r["ied_name"]) tmpIednameParts := scdParseMgr.ParseIedName(inAreaIedName) lastChar := tmpIednameParts[7] if lastChar == iednameParts[7] { insvalues = append(insvalues, fmt.Sprintf("(%d,%d,'%s','%s','%s')", c.ScdId, newid, inAreaIedName, "MI", "T")) } } //母联智能终端IE需要分高中压,无低压侧 if HasAreaJ { h, m, l = c.getIedListByVol("IE", ieds, volMap) for _, r := range h { //高压侧,AB套必须与PT装置相同 inAreaIedName = tools.IsEmpty(r["ied_name"]) tmpIednameParts := scdParseMgr.ParseIedName(inAreaIedName) lastChar := tmpIednameParts[7] if lastChar == iednameParts[7] { insvalues = append(insvalues, fmt.Sprintf("(%d,%d,'%s','%s','%s')", c.ScdId, newid, inAreaIedName, "I", "E")) } } for _, r := range m { //中压侧 inAreaIedName = tools.IsEmpty(r["ied_name"]) tmpIednameParts := scdParseMgr.ParseIedName(inAreaIedName) lastChar := tmpIednameParts[7] if lastChar == "" || lastChar == iednameParts[7] { insvalues = append(insvalues, fmt.Sprintf("(%d,%d,'%s','%s','%s')", c.ScdId, newid, inAreaIedName, "I", "E")) } } } //合并单元MT分高中低压侧;低压侧无关联母线合并单元MM h, m, l = c.getIedListByVol("MT", ieds, volMap) h = append(h, m...) h = append(h, l...) for _, r := range h { inAreaIedName = tools.IsEmpty(r["ied_name"]) tmpIednameParts := scdParseMgr.ParseIedName(inAreaIedName) lastChar := tmpIednameParts[7] if lastChar == iednameParts[7] { insvalues = append(insvalues, fmt.Sprintf("(%d,%d,'%s','%s','%s')", c.ScdId, newid, inAreaIedName, "M", "T")) } } //测控装置CT分高中低压侧,且可能是多套合并单元MT共用,既不分AB套 h, m, l = c.getIedListByVol("CT", ieds, volMap) h = append(h, m...) h = append(h, l...) for _, r := range h { inAreaIedName = tools.IsEmpty(r["ied_name"]) tmpIednameParts := scdParseMgr.ParseIedName(inAreaIedName) lastChar := tmpIednameParts[7] tmpVol := tmpIednameParts[3] + tmpIednameParts[4] //高中低压电压等级相同的 if (tmpVol == volMap["low"] || tmpVol == volMap["middle"] || tmpVol == volMap["hight"]) && (lastChar == "" || lastChar == iednameParts[7]) { insvalues = append(insvalues, fmt.Sprintf("(%d,%d,'%s','%s','%s')", c.ScdId, newid, inAreaIedName, "C", "T")) } } //智能终端(IB:开关\IT:分支\IF:分段)分高中低压侧 h, m, l = c.getIedListByVol("IB", ieds, volMap) h = append(h, m...) h = append(h, l...) for _, r := range h { inAreaIedName = tools.IsEmpty(r["ied_name"]) tmpIednameParts := scdParseMgr.ParseIedName(inAreaIedName) lastChar := tmpIednameParts[7] tmpVol := tmpIednameParts[3] + tmpIednameParts[4] //高中低压电压等级相同的 if (tmpVol == volMap["low"] || tmpVol == volMap["middle"] || tmpVol == volMap["hight"]) && (lastChar == "" || lastChar == iednameParts[7]) { insvalues = append(insvalues, fmt.Sprintf("(%d,%d,'%s','%s','%s')", c.ScdId, newid, inAreaIedName, "I", "B")) } } h, m, l = c.getIedListByVol("IT", ieds, volMap) h = append(h, m...) h = append(h, l...) for _, r := range h { inAreaIedName = tools.IsEmpty(r["ied_name"]) tmpIednameParts := scdParseMgr.ParseIedName(inAreaIedName) lastChar := tmpIednameParts[7] tmpVol := tmpIednameParts[3] + tmpIednameParts[4] //高中低压电压等级相同的 if (tmpVol == volMap["low"] || tmpVol == volMap["middle"] || tmpVol == volMap["hight"]) && (lastChar == "" || lastChar == iednameParts[7]) { insvalues = append(insvalues, fmt.Sprintf("(%d,%d,'%s','%s','%s')", c.ScdId, newid, inAreaIedName, "I", "T")) } } h, m, l = c.getIedListByVol("IF", ieds, volMap) h = append(h, m...) h = append(h, l...) for _, r := range h { inAreaIedName = tools.IsEmpty(r["ied_name"]) tmpIednameParts := scdParseMgr.ParseIedName(inAreaIedName) lastChar := tmpIednameParts[7] tmpVol := tmpIednameParts[3] + tmpIednameParts[4] //高中低压电压等级相同的 if (tmpVol == volMap["low"] || tmpVol == volMap["middle"] || tmpVol == volMap["hight"]) && (lastChar == "" || lastChar == iednameParts[7]) { insvalues = append(insvalues, fmt.Sprintf("(%d,%d,'%s','%s','%s')", c.ScdId, newid, inAreaIedName, "I", "F")) } } //母线保护PM及母线合并单元MM,可能是多套合并单元MT共用,既不分AB套;低压侧智能终端无关联母线保护 h, m, l = c.getIedListByVol("PM", ieds, volMap) for _, r := range h { //高压侧,AB套必须与PT装置相同 inAreaIedName = tools.IsEmpty(r["ied_name"]) tmpIednameParts := scdParseMgr.ParseIedName(inAreaIedName) lastChar := tmpIednameParts[7] if lastChar == iednameParts[7] { insvalues = append(insvalues, fmt.Sprintf("(%d,%d,'%s','%s','%s')", c.ScdId, newid, inAreaIedName, "P", "M")) //MM装置 mmIedName := c.getMMName(tmpIednameParts, ieds, iednameParts[7]) insvalues = append(insvalues, fmt.Sprintf("(%d,%d,'%s','%s','%s')", c.ScdId, newid, mmIedName, "M", "M")) break } } for _, r := range m { //中压侧 inAreaIedName = tools.IsEmpty(r["ied_name"]) tmpIednameParts := scdParseMgr.ParseIedName(inAreaIedName) lastChar := tmpIednameParts[7] if lastChar == "" || lastChar == iednameParts[7] { insvalues = append(insvalues, fmt.Sprintf("(%d,%d,'%s','%s','%s')", c.ScdId, newid, inAreaIedName, "P", "M")) //MM装置 mmIedName := c.getMMName(tmpIednameParts, ieds, iednameParts[7]) insvalues = append(insvalues, fmt.Sprintf("(%d,%d,'%s','%s','%s')", c.ScdId, newid, mmIedName, "M", "M")) break } } _, err = db.Raw(ins1 + strings.Join(insvalues, ",")).Exec() if err != nil { logger.Logger.Error(err) return } } } //线路间隔分析 //vol:电压等级 func (c *CheckAreaMgr) pL(modelid int, vol, iedtypes string, ieds map[string]orm.Params) { scdParseMgr := new(ScdParse) //scdNodeMgr := new(ScdNode) db := orm.NewOrm() //scdXmlObject, _ := scdParseMgr.GetScdXmlObjectBySCDID(tools.IsEmpty(c.ScdId)) for _, row := range ieds { if tools.IsEmpty(row["vol"]) != vol || tools.IsEmpty(row["ied_type"]) != "P" || tools.IsEmpty(row["p_type"]) != "L" { continue } pmIedName := "" mmIedName := "" pl_iedname := tools.IsEmpty(row["ied_name"]) iednameParts := scdParseMgr.ParseIedName(pl_iedname) //添加间隔数据 dbdata := T_data_check_area{ ModelId: modelid, ScdId: c.ScdId, AreaType: "L", AreaName: tools.IsEmpty(row["area_name"]) + iednameParts[7], } newid, err := db.Insert(&dbdata) if err != nil { logger.Logger.Error(err) return } ins1 := "insert into t_data_check_area_ied(scd_id,area_id,ied_name,ied_type,p_type)values" insvalues := []string{} for _, ty := range strings.Split(iedtypes, ",") { inAreaIedName := "" if ty == "PM" { //母线保护和母线合并单元装置编号跟随变压器 //查找变压器编号 //1号变压器->2号变压器->3号 inAreaIedName = c.getPMName(iednameParts, ieds) pmIedName = inAreaIedName if mmIedName == "" { insvalues = append(insvalues, fmt.Sprintf("(%d,%d,'%s','%s','%s')", c.ScdId, newid, inAreaIedName, ty[0:1], ty[1:2])) pmIedNameParts := scdParseMgr.ParseIedName(pmIedName) //使用PM装置的名称去定义MM的名称 ty = "MM" inAreaIedName = c.getMMName(pmIedNameParts, ieds, iednameParts[7]) mmIedName = inAreaIedName } } else if ty == "MM" { if pmIedName != "" && mmIedName == "" { pmIedNameParts := scdParseMgr.ParseIedName(pmIedName) //使用PM装置的名称去定义MM的名称 inAreaIedName = c.getMMName(pmIedNameParts, ieds, iednameParts[7]) mmIedName = inAreaIedName } else { continue } } else { inAreaIedName = ty + iednameParts[3] + iednameParts[4] + iednameParts[5] + iednameParts[6] + iednameParts[7] } if strings.Index("ABCDE", iednameParts[7]) > -1 { //最后一位是字母则说明是AB套 switch ty { case "CL": //测控装置,先判断是否分了AB套,没有标识(ied名称的最后一位是否是字母)则说明是多套共用装置 clIedname := inAreaIedName + iednameParts[7] iedObj := ieds[inAreaIedName] if iedObj != nil { //当前测控装置也分了AB套 inAreaIedName = clIedname } break default: break } } insvalues = append(insvalues, fmt.Sprintf("(%d,%d,'%s','%s','%s')", c.ScdId, newid, inAreaIedName, ty[0:1], ty[1:2])) } _, err = db.Raw(ins1 + strings.Join(insvalues, ",")).Exec() if err != nil { logger.Logger.Error(err) return } //如果mm装置还未确定 if mmIedName == "" { pmIedNameParts := scdParseMgr.ParseIedName(pmIedName) inAreaIedName := c.getMMName(pmIedNameParts, ieds, iednameParts[7]) _, err = db.Raw(ins1 + fmt.Sprintf("(%d,%d,'%s','%s','%s')", c.ScdId, newid, inAreaIedName, "M", "M")).Exec() if err != nil { logger.Logger.Error(err) return } } } } //母联间隔分析 func (c *CheckAreaMgr) pJ(modelid int, vol, iedtypes string, ieds map[string]orm.Params, pjIed string) { scdParseMgr := new(ScdParse) //scdNodeMgr := new(ScdNode) db := orm.NewOrm() //scdXmlObject, _ := scdParseMgr.GetScdXmlObjectBySCDID(tools.IsEmpty(c.ScdId)) for _, row := range ieds { if tools.IsEmpty(row["vol"]) != vol || tools.IsEmpty(row["ied_type"]) != "P" || tools.IsEmpty(row["p_type"]) != pjIed[1:2] { continue } pmIedName := "" mmIedName := "" pl_iedname := tools.IsEmpty(row["ied_name"]) iednameParts := scdParseMgr.ParseIedName(pl_iedname) //添加间隔数据 dbdata := T_data_check_area{ ModelId: modelid, ScdId: c.ScdId, AreaType: "J", AreaName: tools.IsEmpty(row["area_name"]) + iednameParts[7], } newid, err := db.Insert(&dbdata) if err != nil { logger.Logger.Error(err) return } ins1 := "insert into t_data_check_area_ied(scd_id,area_id,ied_name,ied_type,p_type)values" insvalues := []string{} for _, ty := range strings.Split(iedtypes, ",") { inAreaIedName := "" if ty == "PM" { //母线保护和母线合并单元装置编号跟随变压器 //查找变压器编号 //1号变压器->2号变压器->3号 inAreaIedName = c.getPMName(iednameParts, ieds) pmIedName = inAreaIedName if mmIedName == "" { insvalues = append(insvalues, fmt.Sprintf("(%d,%d,'%s','%s','%s')", c.ScdId, newid, inAreaIedName, ty[0:1], ty[1:2])) pmIedNameParts := scdParseMgr.ParseIedName(pmIedName) //使用PM装置的名称去定义MM的名称 ty = "MM" inAreaIedName = c.getMMName(pmIedNameParts, ieds, iednameParts[7]) mmIedName = inAreaIedName } } else if ty == "MM" { if pmIedName != "" && mmIedName == "" { pmIedNameParts := scdParseMgr.ParseIedName(pmIedName) //使用PM装置的名称去定义MM的名称 inAreaIedName = c.getMMName(pmIedNameParts, ieds, iednameParts[7]) mmIedName = inAreaIedName } else { continue } } else { ty = ty[0:1] + pjIed[1:2] inAreaIedName = ty + iednameParts[3] + iednameParts[4] + iednameParts[5] + iednameParts[6] + iednameParts[7] //判断与基准保护装置相同套号的装置是否存在 if ieds[inAreaIedName] == nil { //尝试去除套号 inAreaIedName = ty + iednameParts[3] + iednameParts[4] + iednameParts[5] + iednameParts[6] } } insvalues = append(insvalues, fmt.Sprintf("(%d,%d,'%s','%s','%s')", c.ScdId, newid, inAreaIedName, ty[0:1], ty[1:2])) } _, err = db.Raw(ins1 + strings.Join(insvalues, ",")).Exec() if err != nil { logger.Logger.Error(err) return } } } //根据参考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] iedObj := ieds[tmpIedName] if iedObj != nil { } else { tmpIedName = "PM" + iednameParts[3] + iednameParts[4] + iednameParts[5] + "2" + iednameParts[7] iedObj = ieds[tmpIedName] if iedObj != nil { return tmpIedName } } return tmpIedName } //根据参考ied name找出应该关联MM装置 func (c *CheckAreaMgr) getMMName(iednameParts []string, ieds map[string]orm.Params, ab string) string { tmpIedName := "MM" + iednameParts[3] + iednameParts[4] + iednameParts[5] + iednameParts[6] + ab if ieds[tmpIedName] == nil { tmpIedName = "MM" + iednameParts[3] + iednameParts[4] + iednameParts[5] + iednameParts[6] + iednameParts[7] } return tmpIedName } //根据当前设备列表,分析出电压等级(高、中、低)的设备列表 // CT测控、IT智能终端、MT合并单元需要判断是否是本体装置,是则将其归为主变高压侧 func (c *CheckAreaMgr) getIedListByVol(iedtype string, ieds map[string]orm.Params, vollevel map[string]string) (hightLst, middleLst, lowLst []orm.Params) { tmpLst := map[string][]orm.Params{} for _, v := range vollevel { tmpLst[v] = []orm.Params{} } scdParseMgr := new(ScdParse) for _, row := range ieds { pl_iedname := tools.IsEmpty(row["ied_name"]) if pl_iedname[0:len(iedtype)] != iedtype { continue } iednameParts := scdParseMgr.ParseIedName(pl_iedname) volvalue := iednameParts[3] + iednameParts[4] if tmpLst[volvalue] == nil { tmpLst[volvalue] = []orm.Params{row} } else { tmpLst[volvalue] = append(tmpLst[volvalue], row) } } return tmpLst[vollevel["hight"]], tmpLst[vollevel["middle"]], tmpLst[vollevel["low"]] } //测试 func (c *CheckAreaMgr) TestAppendNode(iedname string) { //t := t_scd_node_scl{NodeName: iedname} //c.AppendIedNode(&t) }