1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930 |
- package bo
- import (
- "encoding/json"
- "errors"
- "fmt"
- "os"
- "runtime"
- "scd_check_tools/logger"
- "scd_check_tools/models/enum"
- "scd_check_tools/models/node_attr"
- "scd_check_tools/mqtt"
- "scd_check_tools/tools"
- "strconv"
- "strings"
- "sync"
- "time"
- "github.com/astaxie/beego/orm"
- )
- type t_scd_diff_compare struct {
- Id int64 `orm:"pk;auto"`
- Name string
- //对比的文件类型。值为scd|icd等
- FileType string
- SourceId int64
- TargetId int64
- StationId int
- NodeState int
- AttrState int
- SourceFile string
- TargetFile string
- }
- type t_scd_diff_compare_detail struct {
- Id int64 `orm:"pk;auto"`
- IedName string `json:"ied_name"`
- IedDesc string `json:"ied_desc"`
- CompareId int64 `json:"compare_id"`
- //发生差异的对象类型:node\attr
- DiffObjectType string `json:"diff_object_type"`
- DiffObjectNodeId int64 `json:"diff_object_node_id"`
- DiffObjectName string `json:"diff_object_name"`
- DiffSourceNodeId int64 `json:"diff_source_node_id"`
- SourceLineNo int64 `json:"source_line_no"`
- ObjectLineNo int64 `json:"object_line_no"`
- //发生差异的操作:新增i\修改u\删除d
- DiffOpt string `json:"diff_opt"`
- //差异描述
- DiffDesc string `json:"diff_desc"`
- }
- //文件scd文件差异对比
- type ScdCompare struct {
- Userinfo map[string]interface{}
- lock sync.RWMutex
- StationId int
- //如果是2个对比文件时,需要对比的文件ID列表。仅当CompareType为ccd\cid\ccd_cid_scd\icd_scd时有效
- CompFileIds []string
- //对比的文件类型码:scd|icd|ccd|...。全大写
- CompareType string
- //用于对比的scd文件ID
- Sourceid int64
- //被比较的scd文件id
- Targetid int64
- //当前对比记录ID
- CurrCompareRecord t_scd_diff_compare
- //对比结果队列
- CompareResultList []t_scd_diff_compare_detail
- //对比文件的基本信息
- CompareBaseInfo map[string]interface{}
- }
- func init() {
- orm.RegisterModel(new(t_scd_diff_compare))
- orm.RegisterModel(new(t_scd_diff_compare_detail))
- }
- func (c *ScdCompare) GetCheckToolsTreeRoot(scdid, id, pid int64, datatype string) ([]orm.Params, error) {
- db := orm.NewOrm()
- reuslt := []orm.Params{}
- areaMgr := new(ScdAreaMgr)
- if id == 0 {
- //获取间隔列表
- areaList, err := areaMgr.GetAreaList(scdid)
- if err != nil {
- return nil, err
- }
- //获取该电压等级下的间隔列表
- for _, ararow := range areaList {
- //if tools.IsEmpty(ararow["voltage_level"]) == tools.IsEmpty(row2["id"]) {
- ararow["title"] = ararow["name"]
- ararow["datatype"] = "area"
- ararow["isParent"] = "true"
- ararow["pid"] = tools.IsEmpty(ararow["voltage_level"])
- reuslt = append(reuslt, ararow)
- //}
- }
- sql := "SELECT id,(select scd_name from t_scd_scl where id=?) title,0 pid,'true' isParent,'SCL' datatype from t_scd_node_scl WHERE scd_id=? and parent_node_id=? union SELECT id,node_name title,parent_node_id pid,'false' isParent,node_name datatype from t_scd_node_scl where scd_id=? and parent_node_id=(SELECT id from t_scd_node_scl WHERE scd_id=? and parent_node_id=?) GROUP BY node_name order by id "
- rowset := []orm.Params{}
- db.Raw(sql, scdid, scdid, scdid, scdid, scdid, scdid).Values(&rowset)
- for _, row := range rowset {
- reuslt = append(reuslt, row)
- if tools.IsEmpty(row["title"]) == "IED" {
- iednodeid := tools.IsEmpty(row["id"])
- //添加电压等级子节点
- row["isParent"] = "true"
- sql = "select voltage_level id,t1.name title,0 pid ,'true' isParent,'voltage_level' datatype from t_substation_area t,global_const_code t1 where t.voltage_level=t1.id and scd_id=? GROUP BY voltage_level ORDER BY voltage_level"
- voltagelevelRowset := []orm.Params{}
- db.Raw(sql, scdid).Values(&voltagelevelRowset)
- for _, row2 := range voltagelevelRowset {
- row2["pid"] = iednodeid
- reuslt = append(reuslt, row2)
- }
- }
- }
- } else {
- if datatype == "area" {
- //当前为间隔时,则返回该间隔下的IED
- iedList, err := areaMgr.GetIedList(scdid, 0, int32(id), "")
- if err != nil {
- return nil, err
- }
- for _, row := range iedList {
- row["isParent"] = "false"
- row["pid"] = id
- row["id"] = row["node_id"]
- row["title"] = strings.Replace(tools.IsEmpty(row["attr_desc"]), tools.IsEmpty(row["name"]), "..", 1)
- row["datatype"] = "ied"
- }
- reuslt = iedList
- }
- }
- new(SystemLog).Success(enum.AuditType_scd_diffcompare, enum.LogType_Query, enum.OptEventType_Bus, enum.OptEventLevel_Low, "查询IED结构树", c.Userinfo)
- return reuslt, nil
- }
- func (c *ScdCompare) List() ([]orm.Params, error) {
- db := orm.NewOrm()
- sql := "select t.*,t1.scd_name source_name,case when t1.enable=0 then '签入中' else t1.version end source_version ,t2.scd_name target_name,case when t2.enable=0 then '签入中' else t2.version end target_version from t_scd_diff_compare t left JOIN t_scd_scl t1 on t.source_id=t1.id left JOIN t_scd_scl t2 on t.target_id=t2.id where t.station_id=? order by CREATED_TIME desc"
- rowset := []orm.Params{}
- _, err := db.Raw(sql, c.StationId).Values(&rowset)
- sqllog := fmt.Sprintf("SQL:%s,参数:%+v", sql, c.StationId)
- if err != nil {
- logger.Logger.Error(err, sqllog)
- new(SystemLog).Fail(enum.AuditType_scd_diffcompare, enum.LogType_Query, enum.OptEventType_Bus, enum.OptEventLevel_Low, sqllog, c.Userinfo)
- } else {
- new(SystemLog).Success(enum.AuditType_scd_diffcompare, enum.LogType_Query, enum.OptEventType_Bus, enum.OptEventLevel_Low, sqllog, c.Userinfo)
- }
- return rowset, err
- }
- func (c *ScdCompare) ExpResultList(id int, nodetype string, nodeid string) ([]orm.Params, error) {
- db := orm.NewOrm()
- diffObjectTypeTransSql := `case diff_object_type when 'scd.version' then 'SCD版本号'
- when 'scd.crc' then 'SCD CRC'
- when 'scd.ied' then '装置基本信息'
- when 'scd.ied.Communication' then '通信接入点'
- when 'scd.ied.Communication.S1' then '站控层通信参数'
- when 'scd.ied.Communication.GSE' then 'GOOSE 通信参数'
- when 'scd.ied.Communication.SMV' then 'SV 通信参数'
- when 'scd.ied.YX' then '遥信测点'
- when 'scd.ied.YK' then '遥控测点'
- when 'scd.ied.YC' then '遥测测点'
- when 'scd.ied.YM' then '遥脉测点'
- when 'scd.ied.DZ' then '定值测点'
- when 'scd.ied.FCDA' then '发布虚端子'
- when 'scd.ied.ExtRef' then '定阅虚端子'
- when 'scd.ied.DatSet' then '数据集'
- when 'scd.ied.DatSetMeber' then '数据集'
- when 'scd.ied.GSEControl' then 'GOOSE控制块'
- when 'scd.ied.SampledValueControl' then 'SV控制块'
- when 'scd.ied.ReportControl' then '报告控制块'
- when 'scd.ied.LogControl' then '日志控制块'
- else '' end`
- sql := `select a.scd_name source_scd_name,b.scd_name target_scd_name,case when t0.diff_opt='i' then '新增' when t0.diff_opt='u' then '修改' else '删除' end opt,t0.diff_desc 'desc',ied_name,ied_desc,` + diffObjectTypeTransSql + ` diff_object_type,diff_object_name from t_scd_diff_compare t inner join t_scd_diff_compare_detail t0 on t.id=t0.compare_id left join t_scd_scl a on t.source_id=a.id left join t_scd_scl b on t.target_id=b.id where t.id=? and t0.diff_source_node_id is not null`
- param := []interface{}{}
- if nodetype == "ied" {
- sql = `select t.* from t_scd_diff_compare_detail t0 ,t_scd_ied_attrs s,t_scd_node_scl t1 where s.scd_id=? and s.node_id=? and t1.scd_id=? and t1.ied_name=s.attr_name and t0.diff_source_node_id=t1.id and t0.compare_id=? and t.diff_source_node_id is not null`
- param = append(param, nodeid)
- param = append(param, id)
- } else {
- param = append(param, id)
- }
- rowset := []orm.Params{}
- sqllog := fmt.Sprintf("SQL:%s,参数:%+v", sql+" ORDER BY t0.ied_name,t0.diff_object_type limit 0,65535", param)
- _, err := db.Raw(sql+" ORDER BY t0.ied_name,t0.diff_object_type limit 0,65535", param).Values(&rowset)
- if err != nil {
- logger.Logger.Error(err, sqllog)
- new(SystemLog).Fail(enum.AuditType_scd_diffcompare, enum.LogType_exp, enum.OptEventType_Bus, enum.OptEventLevel_Low, sqllog, c.Userinfo)
- } else {
- new(SystemLog).Success(enum.AuditType_scd_diffcompare, enum.LogType_exp, enum.OptEventType_Bus, enum.OptEventLevel_Low, sqllog, c.Userinfo)
- }
- return rowset, err
- }
- //已废弃
- func (c *ScdCompare) ResultList(dirction string, scdid int64, id int, nodetype, nodeid string, pageno, pagesize int) ([]orm.Params, int, error) {
- db := orm.NewOrm()
- sql := ""
- comp_col_name := "diff_source_node_id"
- if dirction == "target" {
- comp_col_name = "diff_object_node_id"
- }
- where := ""
- param := []interface{}{}
- if nodetype == "ied" {
- sql = `select t.* from t_scd_diff_compare_detail t where t.compare_id=? and EXISTS(select 1 from t_scd_node_scl where t.` + comp_col_name + `=id and ied_name=? and scd_id=?)`
- param = append(param, id)
- param = append(param, nodeid)
- param = append(param, scdid)
- } else {
- if nodetype != "" {
- sql = `select t.* from t_scd_diff_compare_detail t where t.compare_id=?`
- param = append(param, id)
- if nodetype == "area" {
- //间隔
- where += " and EXISTS(select 1 from t_area_ied_relation a,t_scd_node_scl s,t_scd_node_scl s1 where a.ied_id=s.id and s1.ied_name=s.ied_name and t." + comp_col_name + "=s1.id and a.area_id=? and s.scd_id=? and s1.scd_id=?)"
- param = append(param, nodeid)
- param = append(param, scdid)
- param = append(param, scdid)
- } else if nodetype == "voltage_level" {
- //电压等级
- where += " and EXISTS(select 1 from t_substation_area v1, t_area_ied_relation v2,t_scd_node_scl s,t_scd_node_scl s1 where v2.ied_id=s.id and s1.ied_name=s.ied_name and t." + comp_col_name + "=s1.id and v1.id=v2.area_id and v1.voltage_level=? and v1.scd_id=? and s.scd_id=? and s1.scd_id=?)"
- param = append(param, nodeid)
- param = append(param, scdid)
- param = append(param, scdid)
- param = append(param, scdid)
- } else if nodetype == "Communication" {
- //通讯类
- where += " and EXISTS(select 1 from t_scd_ied_node_parents_info v2 where t." + comp_col_name + "=v2.node_id and v2.path_names like ? and v2.scd_id=? )"
- param = append(param, "SubNetwork%")
- param = append(param, scdid)
- } else if nodetype == "DataTypeTemplates" {
- //通讯类
- where += " and EXISTS(select 1 from t_scd_ied_node_parents_info v2 where t." + comp_col_name + "=v2.node_id and v2.path_names like ? and v2.scd_id=? )"
- param = append(param, "DataTypeTemplates%")
- param = append(param, scdid)
- } else {
- //Header类
- where += " and t." + comp_col_name + "=?"
- param = append(param, nodeid)
- }
- } else {
- sql = `select t.* from t_scd_diff_compare_detail t,t_scd_node_scl t1 where t1.scd_id=? and t.` + comp_col_name + `=t1.id and t.compare_id=?`
- param = append(param, scdid)
- param = append(param, id)
- }
- }
- limit := fmt.Sprintf(" order by t.id limit %d,%d", (pageno-1)*pagesize, pagesize)
- rowset := []orm.Params{}
- sqllog := fmt.Sprintf("SQL:%s,参数:%+v", sql+where+limit, param)
- _, err := db.Raw(sql+where+limit, param).Values(&rowset)
- if err != nil {
- logger.Logger.Error(err, sqllog)
- new(SystemLog).Fail(enum.AuditType_scd_diffcompare, enum.LogType_Query, enum.OptEventType_Bus, enum.OptEventLevel_Low, sqllog, c.Userinfo)
- } else {
- new(SystemLog).Success(enum.AuditType_scd_diffcompare, enum.LogType_Query, enum.OptEventType_Bus, enum.OptEventLevel_Low, sqllog, c.Userinfo)
- }
- totalNum := 0
- if err == nil {
- tmpRowset := []orm.Params{}
- sql = strings.ReplaceAll(sql+where, "t.*", "count(1) cnt")
- sqllog = fmt.Sprintf("SQL:%s,参数:%+v", sql, param)
- _, err = db.Raw(sql, param).Values(&tmpRowset)
- if err != nil {
- logger.Logger.Error(err, sqllog)
- } else if len(tmpRowset) > 0 {
- for _, r1 := range tmpRowset {
- totalNumi, _ := strconv.Atoi(tools.IsEmpty(r1["cnt"]))
- totalNum += totalNumi
- }
- }
- }
- return rowset, totalNum, err
- }
- //汇总统计校验结果数量
- func (c *ScdCompare) SumCompareResult(compare_id int) ([]orm.Params, error) {
- db := orm.NewOrm()
- sql := `SELECT 'u' diff_opt, diff_object_type,'' ied_name,'' ied_desc,diff_desc from t_scd_diff_compare_detail t where compare_id=? and ied_name='' GROUP BY diff_object_type
- UNION
- SELECT 'i' diff_opt,'scd.ied' diff_object_type, ied_name,ied_desc ,'' diff_desc from t_scd_diff_compare_detail t where compare_id=? and ied_name=diff_object_name and diff_opt='i'
- UNION
- SELECT 'u' diff_opt,'scd.ied' diff_object_type, ied_name,ied_desc,'' diff_desc from t_scd_diff_compare_detail t where compare_id=? and diff_object_type = 'scd.ied' and ied_name=diff_object_name and diff_opt='u'
- UNION
- SELECT 'd' diff_opt,'scd.ied' diff_object_type, ied_name,ied_desc,'' diff_desc from t_scd_diff_compare_detail t where compare_id=? and diff_object_type = 'scd.ied' and ied_name=diff_object_name and diff_opt='d'
- union
- SELECT 'u' diff_opt,'scd.ied' diff_object_type, ied_name,ied_desc,'' diff_desc from t_scd_diff_compare_detail t where compare_id=? and diff_object_type like 'scd.ied.%' GROUP BY ied_name`
- rowset := []orm.Params{}
- _, err := db.Raw(sql, compare_id, compare_id, compare_id, compare_id, compare_id).Values(&rowset)
- if err != nil {
- logger.Logger.Error(err, fmt.Sprintf("SQL:%s 参数:%d", sql, compare_id))
- return nil, err
- }
- return rowset, nil
- }
- //统计指定IED各分类数量
- func (c *ScdCompare) SumCompareTypeResult(compareId int, iedname, comptype string) (map[string]interface{}, error) {
- compObj := t_scd_diff_compare{Id: int64(compareId)}
- db := orm.NewOrm()
- err := db.Read(&compObj)
- if err != nil {
- logger.Logger.Error(err)
- return nil, err
- }
- sourceScdXmlObj, serr := new(ScdParse).GetScdXmlObjectBySCDID(tools.IsEmpty(compObj.SourceId))
- if serr != nil {
- return nil, serr
- }
- if sourceScdXmlObj == nil {
- return nil, errors.New("无效校验的源SCD,文件可能已被删除")
- }
- sourceIedObj := new(ScdNode).GetIed(sourceScdXmlObj, "", iedname)
- targetScdXmlObj, serr := new(ScdParse).GetScdXmlObjectBySCDID(tools.IsEmpty(compObj.TargetId))
- if serr != nil {
- return nil, serr
- }
- if targetScdXmlObj == nil {
- return nil, errors.New("无效的比对SCD,文件可能已被删除")
- }
- targetIedObj := new(ScdNode).GetIed(targetScdXmlObj, "", iedname)
- result := map[string]interface{}{}
- switch comptype {
- case "i":
- //装置基本信息
- result["scd.ied"] = 1
- break
- case "d":
- //装置基本信息
- result["scd.ied"] = 1
- break
- case "u":
- //装置基本信息
- num := 0
- if sourceIedObj.Desc != targetIedObj.Desc {
- num = num + 1
- }
- if sourceIedObj.Type != targetIedObj.Type {
- num = num + 1
- }
- if sourceIedObj.ConfigVersion != targetIedObj.ConfigVersion {
- num = num + 1
- }
- if sourceIedObj.Manufacturer != targetIedObj.Manufacturer {
- num = num + 1
- }
- if num > 0 {
- result["scd.ied"] = 1
- }
- sql := "select diff_object_type,count(1) cnt from t_scd_diff_compare_detail t WHERE compare_id=? and ied_name=? GROUP BY diff_object_type"
- rowset := []orm.Params{}
- _, err := db.Raw(sql, compareId, iedname).Values(&rowset)
- if err != nil {
- return nil, err
- }
- for _, r := range rowset {
- result[tools.IsEmpty(r["diff_object_type"])] = tools.IsEmpty(r["cnt"])
- }
- break
- }
- return result, nil
- }
- //查询IED指定差异类型的信息
- //compareId:比对ID
- //iedname:装置名称
- //comptype:差异类型(i\u\d)
- //item:比对内容项代码
- func (c *ScdCompare) GetCompItemDetailInfo(compareId int, iedname, comptype, itemcode string) ([]interface{}, error) {
- compObj := t_scd_diff_compare{Id: int64(compareId)}
- db := orm.NewOrm()
- err := db.Read(&compObj)
- if err != nil {
- logger.Logger.Error(err)
- return nil, err
- }
- sourceScdXmlObj, serr := new(ScdParse).GetScdXmlObjectBySCDID(tools.IsEmpty(compObj.SourceId))
- if serr != nil {
- return nil, serr
- }
- if sourceScdXmlObj == nil {
- return nil, errors.New("无效校验的源SCD,文件可能已被删除")
- }
- sourceIedObj := new(ScdNode).GetIed(sourceScdXmlObj, "", iedname)
- targetScdXmlObj, serr := new(ScdParse).GetScdXmlObjectBySCDID(tools.IsEmpty(compObj.TargetId))
- if serr != nil {
- return nil, serr
- }
- if targetScdXmlObj == nil {
- return nil, errors.New("无效的比对SCD,文件可能已被删除")
- }
- if itemcode == "scd.ied.Relation" {
- //虚回路配置
- scdNode := new(ScdNode)
- sourceRel, err1 := scdNode.GetIedInputsRelations(map[string]interface{}{
- "ied_name": iedname,
- "scd_id": compObj.SourceId,
- })
- if err1 != nil {
- return nil, err1
- }
- targetRel, err2 := scdNode.GetIedInputsRelations(map[string]interface{}{
- "ied_name": iedname,
- "scd_id": compObj.TargetId,
- })
- if err2 != nil {
- return nil, err2
- }
- iedDescMap := map[string]string{
- iedname: sourceIedObj.Desc,
- }
- result := []interface{}{}
- sourceRelMap := map[string]orm.Params{}
- targetRelMap := map[string]orm.Params{}
- for _, r := range sourceRel {
- sourceRelMap[fmt.Sprintf("%s%s%s", tools.IsEmpty(r["ied_name"]), tools.IsEmpty(r["ied_name"]), tools.IsEmpty(r["attr_int_addr"]), tools.IsEmpty(r["inout_type"]))] = r
- }
- for _, r := range targetRel {
- targetRelMap[fmt.Sprintf("%s%s%s", tools.IsEmpty(r["ied_name"]), tools.IsEmpty(r["ied_name"]), tools.IsEmpty(r["attr_int_addr"]), tools.IsEmpty(r["inout_type"]))] = r
- }
- //logger.Logger.Debug(fmt.Sprintf("sourceRelMap:%+v", sourceRelMap))
- //logger.Logger.Debug(fmt.Sprintf("targetRelMap:%+v", targetRelMap))
- for key, item := range sourceRelMap {
- if _, h := targetRelMap[key]; !h {
- //新增的端子
- item["opt"] = "i"
- tmpIedName := tools.IsEmpty(item["ied_name"])
- ieddesc := iedDescMap[tmpIedName]
- item["scd_id"] = compObj.SourceId
- if ieddesc != "" {
- item["ied_desc"] = ieddesc
- } else {
- tmpIedObj := new(ScdNode).GetIed(sourceScdXmlObj, "", tmpIedName)
- if tmpIedObj != nil {
- iedDescMap[tmpIedName] = tmpIedObj.Desc
- item["ied_desc"] = tmpIedObj.Desc
- }
- }
- result = append(result, item)
- }
- }
- for key, item := range targetRelMap {
- if _, h := sourceRelMap[key]; !h {
- //删除的端子
- item["opt"] = "d"
- tmpIedName := tools.IsEmpty(item["ied_name"])
- ieddesc := iedDescMap[tmpIedName]
- item["scd_id"] = compObj.TargetId
- if ieddesc != "" {
- item["ied_desc"] = ieddesc
- } else {
- tmpIedObj := new(ScdNode).GetIed(targetScdXmlObj, "", tmpIedName)
- if tmpIedObj != nil {
- iedDescMap[tmpIedName] = tmpIedObj.Desc
- item["ied_desc"] = tmpIedObj.Desc
- }
- }
- result = append(result, item)
- }
- }
- sourceRelMap = nil
- targetRelMap = nil
- return result, nil
- }
- targetIedObj := new(ScdNode).GetIed(targetScdXmlObj, "", iedname)
- result := []interface{}{}
- if itemcode == "scd.ied" {
- //IED基本信息
- if comptype == "i" {
- result = append(result, new(node_attr.BaseNode).ToMap(sourceIedObj))
- } else if comptype == "d" {
- result = append(result, new(node_attr.BaseNode).ToMap(targetIedObj))
- } else if comptype == "u" {
- result = append(result, new(node_attr.BaseNode).ToMap(sourceIedObj))
- result = append(result, new(node_attr.BaseNode).ToMap(targetIedObj))
- }
- } else {
- //需要统计新增、删除、编辑的测点
- sql := "SELECT diff_object_type,diff_object_name,diff_opt,diff_desc from t_scd_diff_compare_detail where compare_id=? and ied_name=? and diff_object_type=? order by diff_opt desc,diff_object_name asc"
- rowset := []orm.Params{}
- _, err := db.Raw(sql, compareId, iedname, itemcode).Values(&rowset)
- if err != nil {
- logger.Logger.Error(err, fmt.Sprintf("SQL:%s 参数:%+v", sql, []interface{}{compareId, iedname, itemcode}))
- return nil, err
- }
- for _, r := range rowset {
- result = append(result, r)
- }
- }
- return result, nil
- }
- //开始比较2个文件。如果比较过程中发生错误则返回错误对象
- //对比结果会存储到数据表,同时以mqtt方式进行实时发布
- func (c *ScdCompare) Compare(oldid int) error {
- db := orm.NewOrm()
- if oldid > 0 {
- c.CurrCompareRecord = t_scd_diff_compare{Id: int64(oldid)}
- db.Read(&c.CurrCompareRecord)
- if c.CurrCompareRecord.NodeState == 0 {
- return errors.New("其他用户正在进行校验,需等待其完成!")
- }
- c.Sourceid = c.CurrCompareRecord.SourceId
- c.Targetid = c.CurrCompareRecord.TargetId
- sourceScdXmlObj, serr := new(ScdParse).GetScdXmlObjectBySCDID(tools.IsEmpty(c.Sourceid))
- if serr != nil {
- return serr
- }
- if sourceScdXmlObj == nil {
- return errors.New("无效校验的源SCD,文件可能已被删除")
- }
- targetScdXmlObj, serr := new(ScdParse).GetScdXmlObjectBySCDID(tools.IsEmpty(c.Targetid))
- if serr != nil {
- return serr
- }
- if targetScdXmlObj == nil {
- return errors.New("无效的比对SCD,文件可能已被删除")
- }
- //对原有比对进行重新比对,需要清除原有结果
- db.Raw("delete from t_scd_diff_compare_detail where compare_id=?", oldid).Exec()
- db.Raw("delete from t_scd_diff_compare_stat where compare_id=?", oldid).Exec()
- db.Raw("update t_scd_diff_compare set node_state=0,attr_state=0 where id=?", oldid).Exec()
- if c.CompareType == "SCD" {
- c.ScdCompare(sourceScdXmlObj, targetScdXmlObj)
- }
- return nil
- }
- if c.CompareType == "" {
- return errors.New("未指定校验的类型!")
- }
- if c.CompareType == "CID" {
- return c.CidCompare()
- }
- if c.CompareType == "CCD" {
- return c.CcdCompare()
- }
- if c.CompareType == "CCD_SCD" {
- return c.CcdScdCompare()
- }
- if c.CompareType == "CID_SCD" {
- return c.CidScdCompare()
- }
- if c.StationId == 0 {
- return errors.New("变电站ID不能为空!")
- }
- if c.Sourceid == 0 || c.Targetid == 0 {
- return errors.New("用于校验的源scd文件ID或目标文件ID不能为空!")
- }
- sourceScdXmlObj, serr := new(ScdParse).GetScdXmlObjectBySCDID(tools.IsEmpty(c.Sourceid))
- if serr != nil {
- return serr
- }
- if sourceScdXmlObj == nil {
- return errors.New("无效校验的源SCD")
- }
- targetScdXmlObj, serr := new(ScdParse).GetScdXmlObjectBySCDID(tools.IsEmpty(c.Targetid))
- if serr != nil {
- return serr
- }
- if targetScdXmlObj == nil {
- return errors.New("无效的目标SCD")
- }
- //判断当前2个文件是否正在校验中
- sql := "select 1 from t_scd_diff_compare where source_id=? and target_id=?"
- rowset := []orm.Params{}
- _, err := db.Raw(sql, c.Sourceid, c.Targetid).Values(&rowset)
- if err != nil {
- logger.Logger.Error(err, sql)
- return err
- }
- if len(rowset) > 0 {
- //当前2个文件正在校验中或者已经有校验结果
- return nil
- }
- master := t_scd_diff_compare{StationId: c.StationId, FileType: c.CompareType, SourceId: c.Sourceid, SourceFile: "", TargetId: c.Targetid, TargetFile: "", NodeState: 0, AttrState: 0}
- master.Name = fmt.Sprintf("%s对比%s", c.CompareType, time.Now().Format("200601021504"))
- _, err = db.Insert(&master)
- if err != nil {
- logger.Logger.Error(err)
- return err
- }
- c.CurrCompareRecord = master
- //fmt.Println(fmt.Sprintf("==================%v", c.CurrCompareRecord))
- if c.CompareType == "SCD" {
- c.ScdCompare(sourceScdXmlObj, targetScdXmlObj)
- } else {
- return errors.New("无效的校验文件类型:" + c.CompareType)
- }
- return nil
- }
- //Scd文件节点差异对比
- func (c *ScdCompare) ScdCompare(sourceScdXmlObj *node_attr.SCL, targetScdXmlObj *node_attr.SCL) {
- go mqtt.PublishMessage("/jujutong/scd_check_tools/comp/"+fmt.Sprintf("%d", c.CurrCompareRecord.Id), `{"id":"`+fmt.Sprintf("%d", c.CurrCompareRecord.Id)+`","stationid":"`+fmt.Sprintf("%d", c.CurrCompareRecord.StationId)+`","state":0}`)
- t1 := time.Now().Unix()
- //scd版本、crc对比
- sourcever := ""
- targetver := ""
- detailrow := t_scd_diff_compare_detail{}
- if sourceScdXmlObj.Header != nil && sourceScdXmlObj.Header.History != nil && len(sourceScdXmlObj.Header.History.Hitem) > 0 {
- ver := sourceScdXmlObj.Header.History.Hitem[len(sourceScdXmlObj.Header.History.Hitem)-1]
- sourcever = ver.Version + "," + ver.Revision
- detailrow.SourceLineNo = sourceScdXmlObj.Header.History.Lineno
- detailrow.DiffSourceNodeId = sourceScdXmlObj.Header.History.NodeId
- }
- if targetScdXmlObj.Header != nil && targetScdXmlObj.Header.History != nil && len(targetScdXmlObj.Header.History.Hitem) > 0 {
- ver := targetScdXmlObj.Header.History.Hitem[len(targetScdXmlObj.Header.History.Hitem)-1]
- targetver = ver.Version + "," + ver.Revision
- detailrow.DiffObjectNodeId = targetScdXmlObj.Header.History.NodeId
- detailrow.ObjectLineNo = targetScdXmlObj.Header.History.Lineno
- }
- //logger.Logger.Debug(fmt.Sprintf("=====sourceScdXmlObj sourcever:%s targetScdXmlObj targetver:%s", sourcever, targetver))
- if targetver != sourcever {
- //scd版本差异
- detailrow.CompareId = c.CurrCompareRecord.Id
- detailrow.DiffDesc = fmt.Sprintf(`["%s","%s"]`, sourcever, targetver)
- detailrow.DiffObjectType = "scd.version"
- detailrow.DiffOpt = "u"
- detailrow.DiffObjectName = "version"
- c.CompareResultList = append(c.CompareResultList, detailrow)
- }
- //scd CRC对比
- sourcecrc := ""
- targetcrc := ""
- detailrow_crc := t_scd_diff_compare_detail{}
- if len(sourceScdXmlObj.Private) > 0 {
- for _, p := range sourceScdXmlObj.Private {
- if p.Type == "Substation virtual terminal conection CRC" {
- sourcecrc = p.InnerText
- detailrow_crc.SourceLineNo = p.Lineno
- detailrow_crc.DiffSourceNodeId = p.NodeId
- break
- }
- }
- }
- if len(targetScdXmlObj.Private) > 0 {
- for _, p := range targetScdXmlObj.Private {
- if p.Type == "Substation virtual terminal conection CRC" {
- targetcrc = p.InnerText
- detailrow_crc.ObjectLineNo = p.Lineno
- detailrow_crc.DiffObjectNodeId = p.NodeId
- break
- }
- }
- }
- //logger.Logger.Debug(fmt.Sprintf("=====sourceScdXmlObj sourcecrc:%s targetScdXmlObj targetcrc:%s", sourcecrc, targetcrc))
- if sourcecrc != targetcrc {
- //scd差异
- detailrow_crc.CompareId = c.CurrCompareRecord.Id
- detailrow_crc.DiffDesc = fmt.Sprintf(`["%s","%s"]`, sourcecrc, targetcrc)
- detailrow_crc.DiffObjectType = "scd.crc"
- detailrow_crc.DiffOpt = "u"
- detailrow.DiffObjectName = "crc"
- c.CompareResultList = append(c.CompareResultList, detailrow_crc)
- }
- //IED差异对比
- sourceIedlist := map[string]*node_attr.NIED{}
- targetIedList := map[string]*node_attr.NIED{}
- for _, ied := range sourceScdXmlObj.IED {
- sourceIedlist[ied.Name] = ied
- }
- for _, ied := range targetScdXmlObj.IED {
- targetIedList[ied.Name] = ied
- }
- for iedname, iedObj := range sourceIedlist {
- if tmpIed, h := targetIedList[iedname]; !h {
- //基准scd中新增了该iED
- c.addResult(iedname, iedObj.Desc, "i", "scd.ied", iedname, iedname, iedObj.NodeId, iedObj.Lineno)
- } else {
- sourceedit := fmt.Sprintf(`{"desc":"%s","type":"%s","manufacturer":"%s","configVersion":"%s"}`, iedObj.Desc, iedObj.Type, iedObj.Manufacturer, iedObj.ConfigVersion)
- targetedit := fmt.Sprintf(`{"desc":"%s","type":"%s","manufacturer":"%s","configVersion":"%s"}`, tmpIed.Desc, tmpIed.Type, tmpIed.Manufacturer, tmpIed.ConfigVersion)
- //编辑了ied属性
- if sourceedit != targetedit {
- desc := fmt.Sprintf(`[%s,%s]`, sourceedit, targetedit)
- c.addResult(iedname, iedObj.Desc, "u", "scd.ied", iedname, desc, iedObj.NodeId, iedObj.Lineno)
- }
- //比较通讯层参数:装置IP、掩码、网关
- c.iedCommunicationCompare(sourceScdXmlObj, targetScdXmlObj, iedname, iedObj.Desc)
- //比较回路虚端子配置
- c.iedFcdaCompare(sourceScdXmlObj, targetScdXmlObj, iedname, iedObj.Desc)
- }
- }
- for iedname, iedObj := range targetIedList {
- if _, h := sourceIedlist[iedname]; !h {
- //基准scd中删除了该iED
- c.addResult(iedname, iedObj.Desc, "d", "scd.ied", iedname, iedname, iedObj.NodeId, iedObj.Lineno)
- }
- }
- //差异结果写入数据库
- c.writeResult()
- c.CurrCompareRecord.NodeState = 1
- _, err := orm.NewOrm().Update(&c.CurrCompareRecord)
- if err != nil {
- logger.Logger.Error(err)
- return
- }
- t2 := time.Now().Unix()
- logger.Logger.Debug(fmt.Sprintf("文件差异对比完成,耗时:%d秒", t2-t1))
- new(SystemLog).Success(enum.AuditType_scd_diffcompare, enum.LogType_Execute, enum.OptEventType_Bus, enum.OptEventLevel_Hight, "SCD差异对比", c.Userinfo)
- go mqtt.PublishMessage("/jujutong/scd_check_tools/comp/"+fmt.Sprintf("%d", c.CurrCompareRecord.Id), `{"id":"`+fmt.Sprintf("%d", c.CurrCompareRecord.Id)+`","stationid":"`+fmt.Sprintf("%d", c.CurrCompareRecord.StationId)+`","state":1}`)
- }
- //CID文件节点差异对比
- func (c *ScdCompare) CidCompare() error {
- if len(c.CompFileIds) != 2 {
- return errors.New("CID一致性校验仅支持2个文件校验")
- }
- //根据文件id获取路径
- cid1id, _ := strconv.Atoi(c.CompFileIds[0])
- if cid1id == 0 {
- //非文件id时,表示是当前scd中的装置name
- fileinfo, _ := new(AttachmentMgr).GetInfoByIed(c.Sourceid, c.CompFileIds[0], "cid")
- if fileinfo.Id == 0 {
- return errors.New("基准CID文件ID(" + c.CompFileIds[0] + ")不正确")
- }
- cid1id = int(fileinfo.Id)
- }
- cid2id, _ := strconv.Atoi(c.CompFileIds[1])
- if cid2id == 0 {
- return errors.New("比对CID文件ID(" + c.CompFileIds[1] + ")不正确")
- }
- cidmodel := new(AttachmentMgr)
- cidmodel.Model.Id = int32(cid1id)
- cidfileobj, err := cidmodel.One()
- if err != nil {
- return err
- }
- cid1FileName := cidfileobj.FileName
- cid1Ct := cidfileobj.CreatedTime
- pathChar := string(os.PathSeparator)
- //解析文件为对象
- cid1XmlObj, err := new(ScdParse).LoadScdXml("." + strings.ReplaceAll(cidfileobj.SavePath, "\\", pathChar))
- if err != nil {
- return err
- }
- cidmodel.Model.Id = int32(cid2id)
- cidfileobj, err = cidmodel.One()
- if err != nil {
- return err
- }
- cid2FileName := cidfileobj.FileName
- cid2Ct := cidfileobj.CreatedTime
- cid2XmlObj, err := new(ScdParse).LoadScdXml("." + strings.ReplaceAll(cidfileobj.SavePath, "\\", pathChar))
- if err != nil {
- return err
- }
- if len(cid1XmlObj.IED) != 1 || len(cid2XmlObj.IED) != 1 {
- return errors.New("CID文件中的IED不正确,有且仅允许1个IED")
- }
- if cid1XmlObj.IED[0].Name != cid2XmlObj.IED[0].Name {
- return errors.New("两个CID文件中的IED不是同一装置,不能比对")
- }
- f1 := map[string]interface{}{"filename": cid1FileName, "ct": cid1Ct}
- f2 := map[string]interface{}{"filename": cid2FileName, "ct": cid2Ct}
- return c.cidCompe(f1, f2, cid1XmlObj, cid2XmlObj)
- }
- //CID与SCD文件节点差异对比
- func (c *ScdCompare) CidScdCompare() error {
- if len(c.CompFileIds) != 1 {
- return errors.New("请选择一个CID文件!")
- }
- //根据文件id获取路径
- if c.Sourceid == 0 {
- return errors.New("基准SCD文件ID(" + tools.IsEmpty(c.Sourceid) + ")不正确")
- }
- cid2id, _ := strconv.Atoi(c.CompFileIds[0])
- if cid2id == 0 {
- return errors.New("比对CID文件ID(" + c.CompFileIds[0] + ")不正确")
- }
- cidmodel := new(AttachmentMgr)
- cidmodel.Model.Id = int32(cid2id)
- cidfileobj, err := cidmodel.One()
- if err != nil {
- return err
- }
- pathChar := string(os.PathSeparator)
- cid2FileName := cidfileobj.FileName
- cid2Ct := cidfileobj.CreatedTime
- cid2XmlObj, err := new(ScdParse).LoadScdXml("." + strings.ReplaceAll(cidfileobj.SavePath, "\\", pathChar))
- if err != nil {
- return err
- }
- if len(cid2XmlObj.IED) != 1 {
- return errors.New("无效的Cid文件:" + cid2FileName)
- }
- iedname := cid2XmlObj.IED[0].Name
- scdinfo, _ := new(ScdMgr).One(tools.IsEmpty(c.Sourceid))
- if scdinfo == nil {
- return errors.New("无效的SCD")
- }
- //解析基准文件为对象
- cid1Paths := []string{".", "static", "upload", "ied", tools.IsEmpty(c.Sourceid), iedname + ".cid"}
- cid1Path := strings.Join(cid1Paths, pathChar)
- cid1Finfo, _ := os.Stat(cid1Path)
- if cid1Finfo == nil {
- return errors.New("在SCD(" + tools.IsEmpty(scdinfo["scd_name"]) + ")中未找到装置" + iedname + "的CID文件")
- }
- cid1XmlObj, err := new(ScdParse).LoadScdXml(cid1Path)
- if err != nil {
- return err
- }
- if len(cid1XmlObj.IED) != 1 || len(cid2XmlObj.IED) != 1 {
- return errors.New("CID文件中的IED不正确,有且仅允许1个IED")
- }
- if cid1XmlObj.IED[0].Name != cid2XmlObj.IED[0].Name {
- return errors.New("SCD与CID文件中的IED不是同一装置,不能比对")
- }
- f1 := map[string]interface{}{"filename": tools.IsEmpty(scdinfo["scd_name"]), "ct": tools.IsEmpty(scdinfo["CREATED_TIME"])}
- f2 := map[string]interface{}{"filename": cid2FileName, "ct": cid2Ct}
- return c.cidCompe(f1, f2, cid1XmlObj, cid2XmlObj)
- }
- func (c *ScdCompare) cidCompe(cid1info, cid2onfo map[string]interface{}, cid1XmlObj *node_attr.SCL, cid2XmlObj *node_attr.SCL) error {
- iedname := cid1XmlObj.IED[0].Name
- c.CompareBaseInfo = map[string]interface{}{}
- c.CompareBaseInfo["iedname"] = iedname
- c.CompareBaseInfo["ieddesc"] = cid1XmlObj.IED[0].Desc
- c.CompareBaseInfo["f1"] = cid1info
- c.CompareBaseInfo["f2"] = cid2onfo
- //对比Communication
- sourceedit := fmt.Sprintf(`{"desc":"%s","type":"%s","manufacturer":"%s","configVersion":"%s"}`, cid1XmlObj.IED[0].Desc, cid1XmlObj.IED[0].Type, cid1XmlObj.IED[0].Manufacturer, cid1XmlObj.IED[0].ConfigVersion)
- targetedit := fmt.Sprintf(`{"desc":"%s","type":"%s","manufacturer":"%s","configVersion":"%s"}`, cid2XmlObj.IED[0].Desc, cid2XmlObj.IED[0].Type, cid2XmlObj.IED[0].Manufacturer, cid2XmlObj.IED[0].ConfigVersion)
- //编辑了ied属性
- if sourceedit != targetedit {
- desc := fmt.Sprintf(`[%s,%s]`, sourceedit, targetedit)
- c.addResult(iedname, cid1XmlObj.IED[0].Desc, "u", "scd.ied", iedname, desc, 0, 0)
- }
- //比较通讯层参数:装置IP、掩码、网关
- c.iedCommunicationCompare(cid1XmlObj, cid2XmlObj, iedname, cid1XmlObj.IED[0].Desc)
- //比较回路虚端子配置
- c.iedFcdaCompare(cid1XmlObj, cid2XmlObj, iedname, cid2XmlObj.IED[0].Desc)
- return nil
- }
- //CCD文件节点差异对比
- func (c *ScdCompare) CcdCompare() error {
- if len(c.CompFileIds) != 2 {
- return errors.New("CCD一致性校验仅支持2个文件校验")
- }
- //根据文件id获取路径
- ccd1id, _ := strconv.Atoi(c.CompFileIds[0])
- if ccd1id == 0 {
- //非文件id时,表示是当前scd中的装置name
- fileinfo, _ := new(AttachmentMgr).GetInfoByIed(c.Sourceid, c.CompFileIds[0], "ccd")
- if fileinfo.Id == 0 {
- return errors.New("基准CCD文件ID(" + c.CompFileIds[0] + ")不正确")
- }
- ccd1id = int(fileinfo.Id)
- }
- ccd2id, _ := strconv.Atoi(c.CompFileIds[1])
- if ccd2id == 0 {
- return errors.New("比对CCD文件ID(" + c.CompFileIds[1] + ")不正确")
- }
- ccdmodel := new(AttachmentMgr)
- ccdmodel.Model.Id = int32(ccd1id)
- ccdfileobj, err := ccdmodel.One()
- if err != nil {
- return err
- }
- ccd1FileName := ccdfileobj.FileName
- ccd1Ct := ccdfileobj.CreatedTime
- pathChar := string(os.PathSeparator)
- //解析文件为对象
- ccd1XmlObj, err := new(ScdParse).LoadCcdXml("." + strings.ReplaceAll(ccdfileobj.SavePath, "\\", pathChar))
- if err != nil {
- return err
- }
- ccdmodel.Model.Id = int32(ccd2id)
- ccdfileobj, err = ccdmodel.One()
- if err != nil {
- return err
- }
- ccd2FileName := ccdfileobj.FileName
- ccd2Ct := ccdfileobj.CreatedTime
- //解析文件为对象
- ccd2XmlObj, err := new(ScdParse).LoadCcdXml("." + strings.ReplaceAll(ccdfileobj.SavePath, "\\", pathChar))
- if err != nil {
- return err
- }
- if ccd1XmlObj.Name != ccd2XmlObj.Name {
- return errors.New("两个CCD文件中的IED不是同一装置,不能比对")
- }
- f1 := map[string]interface{}{"filename": ccd1FileName, "ct": ccd1Ct}
- f2 := map[string]interface{}{"filename": ccd2FileName, "ct": ccd2Ct}
- return c.ccdCompe(f1, f2, ccd1XmlObj, ccd2XmlObj)
- }
- //CCD文件节点差异对比
- func (c *ScdCompare) CcdScdCompare() error {
- if len(c.CompFileIds) != 1 {
- return errors.New("请选择一个CCD文件!")
- }
- //根据文件id获取路径
- if c.Sourceid == 0 {
- return errors.New("基准SCD文件ID(" + tools.IsEmpty(c.Sourceid) + ")不正确")
- }
- ccd2id, _ := strconv.Atoi(c.CompFileIds[0])
- if ccd2id == 0 {
- return errors.New("比对CCD文件ID(" + c.CompFileIds[0] + ")不正确")
- }
- ccdmodel := new(AttachmentMgr)
- pathChar := string(os.PathSeparator)
- ccdmodel.Model.Id = int32(ccd2id)
- ccdfileobj, err := ccdmodel.One()
- if err != nil {
- return err
- }
- ccd2FileName := ccdfileobj.FileName
- ccd2Ct := ccdfileobj.CreatedTime
- //解析比对文件为对象
- ccd2XmlObj, err := new(ScdParse).LoadCcdXml("." + strings.ReplaceAll(ccdfileobj.SavePath, "\\", pathChar))
- if err != nil {
- return err
- }
- iedname := ccd2XmlObj.Name
- scdinfo, _ := new(ScdMgr).One(tools.IsEmpty(c.Sourceid))
- if scdinfo == nil {
- return errors.New("无效的SCD")
- }
- //解析基准文件为对象
- ccd1Paths := []string{".", "static", "upload", "ied", tools.IsEmpty(c.Sourceid), iedname + ".ccd"}
- ccd1Path := strings.Join(ccd1Paths, pathChar)
- ccd1Finfo, _ := os.Stat(ccd1Path)
- if ccd1Finfo == nil {
- return errors.New("在SCD(" + tools.IsEmpty(scdinfo["scd_name"]) + ")中未找到装置" + iedname + "的CCD文件")
- }
- ccd1XmlObj, err := new(ScdParse).LoadCcdXml(ccd1Path)
- if err != nil {
- return err
- }
- f1 := map[string]interface{}{"filename": tools.IsEmpty(scdinfo["scd_name"]), "ct": tools.IsEmpty(scdinfo["CREATED_TIME"])}
- f2 := map[string]interface{}{"filename": ccd2FileName, "ct": ccd2Ct}
- return c.ccdCompe(f1, f2, ccd1XmlObj, ccd2XmlObj)
- }
- //ccd校验
- func (c *ScdCompare) ccdCompe(ccd1info, ccd2onfo map[string]interface{}, ccd1XmlObj *node_attr.CcdIed, ccd2XmlObj *node_attr.CcdIed) error {
- iedname := ccd1XmlObj.Name
- c.CompareBaseInfo = map[string]interface{}{}
- c.CompareBaseInfo["iedname"] = iedname
- c.CompareBaseInfo["ieddesc"] = ccd1XmlObj.Desc
- c.CompareBaseInfo["f1"] = ccd1info
- c.CompareBaseInfo["f2"] = ccd2onfo
- sourceedit := fmt.Sprintf(`{"desc":"%s","type":"%s","manufacturer":"%s","configVersion":"%s","crc":"%s"}`, ccd1XmlObj.Desc, ccd1XmlObj.Type, ccd1XmlObj.Manufacturer, ccd1XmlObj.ConfigVersion, ccd1XmlObj.CRC.Id)
- targetedit := fmt.Sprintf(`{"desc":"%s","type":"%s","manufacturer":"%s","configVersion":"%s","crc":"%s"}`, ccd2XmlObj.Desc, ccd2XmlObj.Type, ccd2XmlObj.Manufacturer, ccd2XmlObj.ConfigVersion, ccd2XmlObj.CRC.Id)
- //编辑了ied属性
- if sourceedit != targetedit {
- desc := fmt.Sprintf(`[%s,%s]`, sourceedit, targetedit)
- c.addResult(iedname, ccd1XmlObj.Desc, "u", "scd.ied", iedname, desc, 0, 0)
- }
- sourceGoosePub := map[string]*node_attr.CcdGOCBref{}
- targetGoosePub := map[string]*node_attr.CcdGOCBref{}
- sourceGooseSub := map[string]*node_attr.CcdGOCBref{}
- targetGooseSub := map[string]*node_attr.CcdGOCBref{}
- sourceConnectedAPPub := map[string]*node_attr.NConnectedAP{}
- targetConnectedAPPub := map[string]*node_attr.NConnectedAP{}
- sourceConnectedAPSub := map[string]*node_attr.NConnectedAP{}
- targetConnectedAPSub := map[string]*node_attr.NConnectedAP{}
- sourceGooseDatsetPub := map[string]*node_attr.CcdDataSet{}
- targetGooseDatsetPub := map[string]*node_attr.CcdDataSet{}
- sourceGooseDatsetSub := map[string]*node_attr.CcdDataSet{}
- targetGooseDatsetSub := map[string]*node_attr.CcdDataSet{}
- if ccd1XmlObj.GOOSEPUB != nil {
- for _, item := range ccd1XmlObj.GOOSEPUB.GOCBref {
- sourceGoosePub[item.Name] = item
- if item.ConnectedAP != nil {
- sourceConnectedAPPub[item.GSEControl.AppID+"-"+item.ConnectedAP.ApName] = item.ConnectedAP
- }
- if item.DataSet != nil {
- sourceGooseDatsetPub[item.GSEControl.AppID+"-"+item.DataSet.Name] = item.DataSet
- }
- }
- }
- if ccd2XmlObj.GOOSEPUB != nil {
- for _, item := range ccd2XmlObj.GOOSEPUB.GOCBref {
- targetGoosePub[item.Name] = item
- if item.ConnectedAP != nil {
- targetConnectedAPPub[item.GSEControl.AppID+"-"+item.ConnectedAP.ApName] = item.ConnectedAP
- }
- if item.DataSet != nil {
- targetGooseDatsetPub[item.GSEControl.AppID+"-"+item.DataSet.Name] = item.DataSet
- }
- }
- }
- if ccd1XmlObj.GOOSESUB != nil {
- for _, item := range ccd1XmlObj.GOOSESUB.GOCBref {
- sourceGooseSub[item.Name] = item
- if item.ConnectedAP != nil {
- sourceConnectedAPSub[item.GSEControl.AppID+"-"+item.ConnectedAP.ApName] = item.ConnectedAP
- }
- if item.DataSet != nil {
- sourceGooseDatsetSub[item.GSEControl.AppID+"-"+item.DataSet.Name] = item.DataSet
- }
- }
- }
- if ccd2XmlObj.GOOSESUB != nil {
- for _, item := range ccd2XmlObj.GOOSESUB.GOCBref {
- targetGooseSub[item.Name] = item
- targetConnectedAPSub[item.GSEControl.AppID+"-"+item.ConnectedAP.ApName] = item.ConnectedAP
- if item.DataSet != nil {
- targetGooseDatsetSub[item.GSEControl.AppID+"-"+item.DataSet.Name] = item.DataSet
- }
- }
- }
- var compgoose = func(typecode string, g1, g2 map[string]*node_attr.CcdGOCBref) {
- for k, additem := range g1 {
- g2h := g2[k]
- if g2h == nil {
- //新增的
- desc := fmt.Sprintf(`{"appID":"%s","confRev":"%s","datSet":"%s","name":"%s","type":"%s"}`, additem.GSEControl.AppID, additem.GSEControl.ConfRev, additem.GSEControl.DatSet, additem.GSEControl.Name, additem.GSEControl.Type)
- c.addResult(iedname, ccd1XmlObj.Desc, "i", typecode, k, desc, 0, 0)
- } else {
- //是否有修改
- desc1 := fmt.Sprintf(`{"appID":"%s","confRev":"%s","datSet":"%s","name":"%s","type":"%s"}`, additem.GSEControl.AppID, additem.GSEControl.ConfRev, additem.GSEControl.DatSet, additem.GSEControl.Name, additem.GSEControl.Type)
- desc2 := fmt.Sprintf(`{"appID":"%s","confRev":"%s","datSet":"%s","name":"%s","type":"%s"}`, g2h.GSEControl.AppID, g2h.GSEControl.ConfRev, g2h.GSEControl.DatSet, g2h.GSEControl.Name, g2h.GSEControl.Type)
- if desc1 != desc2 {
- c.addResult(iedname, ccd1XmlObj.Desc, "u", typecode, k, fmt.Sprintf("[%s,%s]", desc1, desc2), 0, 0)
- }
- }
- }
- for k, additem := range g2 {
- if g1[k] == nil {
- //删除的
- desc := fmt.Sprintf(`{"appID":"%s","confRev":"%s","datSet":"%s","name":"%s","type":"%s"}`, additem.GSEControl.AppID, additem.GSEControl.ConfRev, additem.GSEControl.DatSet, additem.GSEControl.Name, additem.GSEControl.Type)
- c.addResult(iedname, ccd1XmlObj.Desc, "d", typecode, k, desc, 0, 0)
- }
- }
- }
- //GOOSE发布
- compgoose("scd.ied.goosepub", sourceGoosePub, targetGoosePub)
- //GOOSE订阅
- compgoose("scd.ied.goosesub", sourceGooseSub, targetGooseSub)
- var compsv = func(typecode string, g1, g2 map[string]*node_attr.CcdSMVCBref) {
- for k, additem := range g1 {
- g2h := g2[k]
- if g2h == nil {
- //新增的
- desc := fmt.Sprintf(`{"smvID":"%s","confRev":"%s","datSet":"%s","name":"%s","multicast":"%s","nofASDU":"%s","smpRate":"%s"}`, additem.SampledValueControl.SmvID, additem.SampledValueControl.ConfRev, additem.SampledValueControl.DatSet, additem.SampledValueControl.Name, additem.SampledValueControl.Multicast, additem.SampledValueControl.NofASDU, additem.SampledValueControl.SmpRate)
- c.addResult(iedname, ccd1XmlObj.Desc, "i", typecode, k, desc, 0, 0)
- } else {
- //是否有修改
- desc1 := fmt.Sprintf(`{"smvID":"%s","confRev":"%s","datSet":"%s","name":"%s","multicast":"%s","nofASDU":"%s","smpRate":"%s"}`, additem.SampledValueControl.SmvID, additem.SampledValueControl.ConfRev, additem.SampledValueControl.DatSet, additem.SampledValueControl.Name, additem.SampledValueControl.Multicast, additem.SampledValueControl.NofASDU, additem.SampledValueControl.SmpRate)
- desc2 := fmt.Sprintf(`{"smvID":"%s","confRev":"%s","datSet":"%s","name":"%s","multicast":"%s","nofASDU":"%s","smpRate":"%s"}`, g2h.SampledValueControl.SmvID, g2h.SampledValueControl.ConfRev, g2h.SampledValueControl.DatSet, g2h.SampledValueControl.Name, g2h.SampledValueControl.Multicast, g2h.SampledValueControl.NofASDU, g2h.SampledValueControl.SmpRate)
- if desc1 != desc2 {
- c.addResult(iedname, ccd1XmlObj.Desc, "u", typecode, k, fmt.Sprintf("[%s,%s]", desc1, desc2), 0, 0)
- }
- }
- }
- for k, additem := range g2 {
- if g1[k] == nil {
- //删除的
- desc := fmt.Sprintf(`{"smvID":"%s","confRev":"%s","datSet":"%s","name":"%s","multicast":"%s","nofASDU":"%s","smpRate":"%s"}`, additem.SampledValueControl.SmvID, additem.SampledValueControl.ConfRev, additem.SampledValueControl.DatSet, additem.SampledValueControl.Name, additem.SampledValueControl.Multicast, additem.SampledValueControl.NofASDU, additem.SampledValueControl.SmpRate)
- c.addResult(iedname, ccd1XmlObj.Desc, "d", typecode, k, desc, 0, 0)
- }
- }
- }
- sourceSVPub := map[string]*node_attr.CcdSMVCBref{}
- targetSVPub := map[string]*node_attr.CcdSMVCBref{}
- sourceSVSub := map[string]*node_attr.CcdSMVCBref{}
- targetSVSub := map[string]*node_attr.CcdSMVCBref{}
- sourceSVAPPub := map[string]*node_attr.NConnectedAP{}
- targetSVAPPub := map[string]*node_attr.NConnectedAP{}
- sourceSVAPSub := map[string]*node_attr.NConnectedAP{}
- targetSVAPSub := map[string]*node_attr.NConnectedAP{}
- sourceSVDatsetPub := map[string]*node_attr.CcdDataSet{}
- targetSVDatsetPub := map[string]*node_attr.CcdDataSet{}
- sourceSVDatsetSub := map[string]*node_attr.CcdDataSet{}
- targetSVDatsetSub := map[string]*node_attr.CcdDataSet{}
- if ccd1XmlObj.SVPUB != nil {
- for _, item := range ccd1XmlObj.SVPUB.SMVCBref {
- sourceSVPub[item.Name] = item
- if item.ConnectedAP != nil {
- sourceSVAPPub[item.SampledValueControl.SmvID+"-"+item.ConnectedAP.ApName] = item.ConnectedAP
- }
- if item.DataSet != nil {
- sourceSVDatsetPub[item.SampledValueControl.SmvID+"-"+item.DataSet.Name] = item.DataSet
- }
- }
- }
- if ccd2XmlObj.SVPUB != nil {
- for _, item := range ccd2XmlObj.SVPUB.SMVCBref {
- targetSVPub[item.Name] = item
- if item.ConnectedAP != nil {
- targetSVAPPub[item.SampledValueControl.SmvID+"-"+item.ConnectedAP.ApName] = item.ConnectedAP
- }
- if item.DataSet != nil {
- targetSVDatsetPub[item.SampledValueControl.SmvID+"-"+item.DataSet.Name] = item.DataSet
- }
- }
- }
- if ccd1XmlObj.SVSUB != nil {
- for _, item := range ccd1XmlObj.SVSUB.SMVCBref {
- sourceSVSub[item.Name] = item
- if item.ConnectedAP != nil {
- sourceSVAPSub[item.SampledValueControl.SmvID+"-"+item.ConnectedAP.ApName] = item.ConnectedAP
- }
- if item.DataSet != nil {
- sourceSVDatsetSub[item.SampledValueControl.SmvID+"-"+item.DataSet.Name] = item.DataSet
- }
- }
- }
- if ccd2XmlObj.SVSUB != nil {
- for _, item := range ccd2XmlObj.SVSUB.SMVCBref {
- targetSVSub[item.Name] = item
- if item.ConnectedAP != nil {
- targetSVAPSub[item.SampledValueControl.SmvID+"-"+item.ConnectedAP.ApName] = item.ConnectedAP
- }
- if item.DataSet != nil {
- targetSVDatsetSub[item.SampledValueControl.SmvID+"-"+item.DataSet.Name] = item.DataSet
- }
- }
- }
- //SV发布
- compsv("scd.ied.svpub", sourceSVPub, targetSVPub)
- //SV订阅
- compsv("scd.ied.svsub", sourceSVSub, targetSVSub)
- //通讯接入点比对
- var compap = func(typecode string, g1, g2 map[string]*node_attr.NConnectedAP) {
- ieddesc := ccd1XmlObj.Desc
- for k, additem := range g1 {
- g2h := g2[k]
- if g2h == nil {
- //新增的
- desc := fmt.Sprintf(`{"apName":"%s"}`, additem.ApName)
- c.addResult(iedname, ieddesc, "i", typecode, k, desc, 0, 0)
- if len(additem.GSE) > 0 {
- for _, item := range additem.GSE {
- key := additem.ApName + "/" + item.LdInst + "/" + item.CbName
- desc, _ := json.Marshal(item.Address)
- c.addResult(iedname, ieddesc, "i", typecode+".GSE", key, string(desc), 0, 0)
- }
- }
- } else {
- //通讯参数对比
- //GOOSE通信参数对比
- sourceGse := map[string]*node_attr.NGSE{}
- targetGse := map[string]*node_attr.NGSE{}
- if len(additem.GSE) > 0 {
- for _, item := range additem.GSE {
- sourceGse[additem.ApName+"/"+item.LdInst+"/"+item.CbName] = item
- }
- }
- if len(g2h.GSE) > 0 {
- for _, item := range g2h.GSE {
- targetGse[additem.ApName+"/"+item.LdInst+"/"+item.CbName] = item
- }
- }
- //logger.Logger.Debug(fmt.Sprintf("sourceGse====:%+v", sourceGse))
- //logger.Logger.Debug(fmt.Sprintf("targetGse====:%+v", targetGse))
- for cbname, gse := range sourceGse {
- //新增的gse
- if tmpGse, h := targetGse[cbname]; !h {
- desc, _ := json.Marshal(gse.Address)
- c.addResult(iedname, ieddesc, "i", typecode+".GSE", cbname, string(desc), gse.NodeId, gse.Lineno)
- } else {
- gse1, _ := json.Marshal(gse.Address)
- gse2, _ := json.Marshal(tmpGse.Address)
- str1 := string(gse1)
- str2 := string(gse2)
- if str1 != str2 {
- desc := fmt.Sprintf(`[%s,%s]`, str1, str2)
- c.addResult(iedname, ieddesc, "u", typecode+".GSE", cbname, desc, gse.NodeId, gse.Lineno)
- }
- }
- }
- //删除的GSE
- for cbname, gse := range targetGse {
- if _, h := sourceGse[cbname]; !h {
- desc, _ := json.Marshal(gse.Address)
- c.addResult(iedname, ieddesc, "d", typecode+".GSE", cbname, string(desc), gse.NodeId, gse.Lineno)
- }
- }
- //SV通信参数对比
- sourceSmv := map[string]*node_attr.NSMV{}
- targetSmv := map[string]*node_attr.NSMV{}
- if len(additem.SMV) > 0 {
- for _, item := range additem.SMV {
- sourceSmv[additem.ApName+"/"+item.LdInst+"/"+item.CbName] = item
- }
- }
- if len(g2h.SMV) > 0 {
- for _, item := range g2h.SMV {
- targetSmv[additem.ApName+"/"+item.LdInst+"/"+item.CbName] = item
- }
- }
- for cbname, gse := range sourceSmv {
- //新增的SMV
- if tmpGse, h := targetSmv[cbname]; !h {
- desc, _ := json.Marshal(gse.Address)
- c.addResult(iedname, ieddesc, "i", typecode+".SMV", cbname, string(desc), gse.NodeId, gse.Lineno)
- } else {
- gse1, _ := json.Marshal(gse.Address)
- gse2, _ := json.Marshal(tmpGse.Address)
- str1 := string(gse1)
- str2 := string(gse2)
- if str1 != str2 {
- desc := fmt.Sprintf(`[%s,%s]`, str1, str2)
- c.addResult(iedname, ieddesc, "u", typecode+".SMV", cbname, (desc), gse.NodeId, gse.Lineno)
- }
- }
- }
- //删除的SMV
- for cbname, gse := range targetSmv {
- if _, h := sourceSmv[cbname]; !h {
- desc, _ := json.Marshal(gse.Address)
- c.addResult(iedname, ieddesc, "d", typecode+".SMV", cbname, string(desc), gse.NodeId, gse.Lineno)
- }
- }
- }
- }
- for k, additem := range g2 {
- if g1[k] == nil {
- //删除的
- desc := fmt.Sprintf(`{"apName":"%s"}`, additem.ApName)
- c.addResult(iedname, ccd1XmlObj.Desc, "d", typecode, k, desc, 0, 0)
- if len(additem.GSE) > 0 {
- for _, item := range additem.GSE {
- key := additem.ApName + "/" + item.LdInst + "/" + item.CbName
- desc, _ := json.Marshal(item.Address)
- c.addResult(iedname, ieddesc, "d", typecode+".GSE", key, string(desc), 0, 0)
- }
- }
- }
- }
- }
- //GOOSE发布接入点
- compap("scd.ied.goosepub.Communication", sourceConnectedAPPub, targetConnectedAPPub)
- //GOOSE订阅接入点
- compap("scd.ied.goosesub.Communication", sourceConnectedAPSub, targetConnectedAPSub)
- //SV发布接入点
- compap("scd.ied.smvpub.Communication", sourceSVAPPub, targetSVAPPub)
- //SV订阅接入点
- compap("scd.ied.smvsub.Communication", sourceSVAPSub, targetSVAPSub)
- //Dataset虚端子比对
- var fcdaToJsonStr = func(fcda *node_attr.CcdFCDA) (key, jsonstr string) {
- key = fmt.Sprintf("%s/%s%s", fcda.LdInst, fcda.LnClass, fcda.LnInst)
- desc := ""
- if len(fcda.IntAddr) > 0 {
- if len(fcda.IntAddr) == 1 {
- if fcda.IntAddr[0].DAI != nil {
- desc = fmt.Sprintf(
- `{"bType":"%s","daName":"%s","desc":"%s","doName":"%s","fc":"%s","prefix":"%s","intAddr.name":"%s","intAddr.desc":"%s","intAddr.sAddr":"%s"}`,
- fcda.BType, fcda.DaName, fcda.Desc, fcda.DoName, fcda.Fc, fcda.Prefix, fcda.IntAddr[0].Name, fcda.IntAddr[0].Desc, fcda.IntAddr[0].DAI.SAddr,
- )
- } else {
- desc = fmt.Sprintf(
- `{"bType":"%s","daName":"%s","desc":"%s","doName":"%s","fc":"%s","prefix":"%s","intAddr.name":"%s","intAddr.desc":"%s"}`,
- fcda.BType, fcda.DaName, fcda.Desc, fcda.DoName, fcda.Fc, fcda.Prefix, fcda.IntAddr[0].Name, fcda.IntAddr[0].Desc,
- )
- }
- } else {
- desc = fmt.Sprintf(
- `{"bType":"%s","daName":"%s","desc":"%s","doName":"%s","fc":"%s","prefix":"%s",`,
- fcda.BType, fcda.DaName, fcda.Desc, fcda.DoName, fcda.Fc, fcda.Prefix,
- )
- // 有多个intAddr
- addrsList := []string{}
- for i, temp := range fcda.IntAddr {
- if temp.DAI == nil {
- addrsList = append(addrsList, fmt.Sprintf(`"intAddr.%d.name":"%s","intAddr.%d.desc":"%s"`, i, temp.Name, temp.Desc))
- } else {
- addrsList = append(addrsList, fmt.Sprintf(`"intAddr.%d.name":"%s","intAddr.%d.desc":"%s","intAddr.%d.sAddr":"%s"`, i, temp.Name, temp.Desc, temp.DAI.SAddr))
- }
- }
- desc = desc + strings.Join(addrsList, ",") + "}"
- }
- } else if fcda.DAI != nil {
- desc = fmt.Sprintf(
- `{"bType":"%s","daName":"%s","desc":"%s","doName":"%s","fc":"%s","prefix":"%s","DAI.sAddr":"%s"}`,
- fcda.BType, fcda.DaName, fcda.Desc, fcda.DoName, fcda.Fc, fcda.Prefix, fcda.DAI.SAddr,
- )
- } else {
- desc = fmt.Sprintf(
- `{"bType":"%s","daName":"%s","desc":"%s","doName":"%s","fc":"%s","prefix":"%s"}`,
- fcda.BType, fcda.DaName, fcda.Desc, fcda.DoName, fcda.Fc, fcda.Prefix,
- )
- }
- return key, desc
- }
- var compDatset = func(typecode string, sourceDatasets, targetDatasets map[string]*node_attr.CcdDataSet) {
- ieddesc := ccd1XmlObj.Desc
- for key, item := range sourceDatasets {
- if t2, h := targetDatasets[key]; !h {
- for _, fcda := range item.FCDA {
- fcdakey, fcdaStr := fcdaToJsonStr(fcda)
- c.addResult(iedname, ieddesc, "i", typecode, fcdakey, fcdaStr, item.NodeId, item.Lineno)
- }
- } else {
- //判断相同数据集中fcda是否有变化
- sourceFcdaList := map[string]string{}
- targetFcdaList := map[string]string{}
- for _, fcda := range item.FCDA {
- fcdakey, fcdaStr := fcdaToJsonStr(fcda)
- sourceFcdaList[fcdakey] = fcdaStr
- }
- for _, fcda := range t2.FCDA {
- fcdakey, fcdaStr := fcdaToJsonStr(fcda)
- targetFcdaList[fcdakey] = fcdaStr
- }
- for skey, s1 := range sourceFcdaList {
- s2, h := targetFcdaList[skey]
- if !h {
- c.addResult(iedname, ieddesc, "i", typecode, skey, s1, 0, 0)
- } else if s1 != s2 {
- c.addResult(iedname, ieddesc, "u", typecode, skey, fmt.Sprintf(`[%s,%s]`, s1, s2), 0, 0)
- }
- }
- for skey, s1 := range targetFcdaList {
- if _, h := sourceFcdaList[skey]; !h {
- c.addResult(iedname, ieddesc, "d", typecode, skey, s1, 0, 0)
- }
- }
- sourceFcdaList = nil
- targetFcdaList = nil
- }
- }
- for k, item := range targetDatasets {
- if _, h := sourceDatasets[k]; !h {
- for _, fcda := range item.FCDA {
- fcdakey, fcdaStr := fcdaToJsonStr(fcda)
- c.addResult(iedname, ieddesc, "d", typecode, fcdakey, fcdaStr, item.NodeId, item.Lineno)
- }
- }
- }
- }
- //GOOSE发布虚端子
- compDatset("scd.ied.goosepub.FCDA", sourceGooseDatsetPub, targetGooseDatsetPub)
- //GOOSE订阅虚端子
- compDatset("scd.ied.goosesub.FCDA", sourceGooseDatsetSub, targetGooseDatsetSub)
- //SV发布虚端子
- compDatset("scd.ied.smvpub.FCDA", sourceSVDatsetPub, targetSVDatsetPub)
- //SV订阅虚端子
- compDatset("scd.ied.smvsub.FCDA", sourceSVDatsetSub, targetSVDatsetSub)
- return nil
- }
- //IED节点通信层对比。主要对比有没新增和删除:装置IP、掩码、网关等
- func (c *ScdCompare) iedCommunicationCompare(sourceScdXmlObj *node_attr.SCL, targetScdXmlObj *node_attr.SCL, iedname, ieddesc string) {
- sourceCommu := map[string]*node_attr.NConnectedAP{}
- targetCommu := map[string]*node_attr.NConnectedAP{}
- //获取基准scd中该ied的网络列表及属性
- for _, net := range sourceScdXmlObj.Communication.SubNetwork {
- for _, ap := range net.ConnectedAP {
- if ap.IedName == iedname {
- sourceCommu[fmt.Sprintf("%s:%s", net.Name, ap.ApName)] = ap
- }
- }
- }
- //获取对比scd中该ied的网络列表及属性
- for _, net := range targetScdXmlObj.Communication.SubNetwork {
- for _, ap := range net.ConnectedAP {
- if ap.IedName == iedname {
- targetCommu[fmt.Sprintf("%s:%s", net.Name, ap.ApName)] = ap
- }
- }
- }
- //对比新增的子网接入点
- for key, net := range sourceCommu {
- if tmpNet, h := targetCommu[key]; !h {
- desc, _ := json.Marshal(net)
- c.addResult(iedname, "", "i", "scd.ied.Communication", key, string(desc), net.NodeId, net.Lineno)
- } else {
- //对比接入点是否有更改
- if net.Desc != tmpNet.Desc || net.ApName != tmpNet.ApName {
- desc := fmt.Sprintf(`[{"desc":"%s","apName":"%s"},{"desc":"%s","apName":"%s"}]`, net.Desc, net.ApName, tmpNet.Desc, tmpNet.ApName)
- c.addResult(iedname, ieddesc, "u", "scd.ied.Communication", key, desc, net.NodeId, net.Lineno)
- }
- //站控层通讯参数对比
- if net.Address != nil && tmpNet.Address != nil {
- address1, _ := json.Marshal(net.Address)
- address2, _ := json.Marshal(tmpNet.Address)
- str1 := string(address1)
- str2 := string(address2)
- if str1 != str2 {
- desc := fmt.Sprintf(`[%s,%s]`, str1, str2)
- c.addResult(iedname, ieddesc, "u", "scd.ied.Communication.S1", key, desc, net.NodeId, net.Lineno)
- }
- } else {
- //对比address是否有变化
- if net.Address != nil && tmpNet.Address == nil {
- desc, _ := json.Marshal(net.Address)
- c.addResult(iedname, ieddesc, "i", "scd.ied.Communication.S1", key, string(desc), net.NodeId, net.Lineno)
- }
- //对比address是否有变化
- if net.Address == nil && tmpNet.Address != nil {
- desc, _ := json.Marshal(tmpNet.Address)
- c.addResult(iedname, ieddesc, "d", "scd.ied.Communication.S1", key, string(desc), net.NodeId, net.Lineno)
- }
- }
- //GOOSE通信参数对比
- sourceGse := map[string]*node_attr.NGSE{}
- targetGse := map[string]*node_attr.NGSE{}
- if len(net.GSE) > 0 {
- for _, item := range net.GSE {
- sourceGse[item.CbName] = item
- }
- }
- if len(tmpNet.GSE) > 0 {
- for _, item := range tmpNet.GSE {
- targetGse[item.CbName] = item
- }
- }
- for cbname, gse := range sourceGse {
- //新增的gse
- if tmpGse, h := targetGse[cbname]; !h {
- desc, _ := json.Marshal(gse)
- c.addResult(iedname, ieddesc, "i", "scd.ied.Communication.GSE", cbname, string(desc), gse.NodeId, gse.Lineno)
- } else {
- gse1, _ := json.Marshal(gse)
- gse2, _ := json.Marshal(tmpGse)
- str1 := string(gse1)
- str2 := string(gse2)
- if str1 != str2 {
- desc := fmt.Sprintf(`[%s,%s]`, str1, str2)
- c.addResult(iedname, ieddesc, "u", "scd.ied.Communication.GSE", cbname, desc, gse.NodeId, gse.Lineno)
- }
- }
- }
- //删除的GSE
- for cbname, gse := range targetGse {
- if _, h := sourceGse[cbname]; !h {
- desc, _ := json.Marshal(gse)
- c.addResult(iedname, ieddesc, "d", "scd.ied.Communication.GSE", cbname, string(desc), gse.NodeId, gse.Lineno)
- }
- }
- //SV通信参数对比
- sourceSmv := map[string]*node_attr.NSMV{}
- targetSmv := map[string]*node_attr.NSMV{}
- if len(net.SMV) > 0 {
- for _, item := range net.SMV {
- sourceSmv[item.CbName] = item
- }
- }
- if len(tmpNet.SMV) > 0 {
- for _, item := range tmpNet.SMV {
- targetSmv[item.CbName] = item
- }
- }
- for cbname, gse := range sourceSmv {
- //新增的SMV
- if tmpGse, h := targetSmv[cbname]; !h {
- desc, _ := json.Marshal(gse)
- c.addResult(iedname, ieddesc, "i", "scd.ied.Communication.SMV", cbname, string(desc), gse.NodeId, gse.Lineno)
- } else {
- gse1, _ := json.Marshal(gse)
- gse2, _ := json.Marshal(tmpGse)
- str1 := string(gse1)
- str2 := string(gse2)
- if str1 != str2 {
- desc := fmt.Sprintf(`[%s,%s]`, str1, str2)
- c.addResult(iedname, ieddesc, "u", "scd.ied.Communication.SMV", cbname, (desc), gse.NodeId, gse.Lineno)
- }
- }
- }
- //删除的SMV
- for cbname, gse := range targetSmv {
- if _, h := sourceSmv[cbname]; !h {
- desc, _ := json.Marshal(gse)
- c.addResult(iedname, ieddesc, "d", "scd.ied.Communication.SMV", cbname, string(desc), gse.NodeId, gse.Lineno)
- }
- }
- }
- }
- //对比删除的接入点
- for key, net := range targetCommu {
- if _, h := sourceCommu[key]; !h {
- desc, _ := json.Marshal(net)
- c.addResult(iedname, ieddesc, "d", "scd.ied.Communication", key, string(desc), net.NodeId, net.Lineno)
- }
- }
- }
- //IED回路虚端子配置及控制块、测点信息对比
- func (c *ScdCompare) iedFcdaCompare(sourceScdXmlObj *node_attr.SCL, targetScdXmlObj *node_attr.SCL, iedname, ieddesc string) {
- //Goose及SV控制块提取
- sourceGooseBlock := map[string]*node_attr.NGSEControl{}
- sourceSvBlock := map[string]*node_attr.NSampledValueControl{}
- targetGooseBlock := map[string]*node_attr.NGSEControl{}
- targetSvBlock := map[string]*node_attr.NSampledValueControl{}
- sourceIedObj := new(ScdNode).GetIed(sourceScdXmlObj, "", iedname)
- targetIedObj := new(ScdNode).GetIed(targetScdXmlObj, "", iedname)
- sourcePublishFcda := map[string]*node_attr.NFCDA{} //发布虚端子
- targetPublishFcda := map[string]*node_attr.NFCDA{} //发布虚端子
- sourceSubExtref := map[string]*node_attr.NExtRef{} //订阅虚端子
- targetSubExtref := map[string]*node_attr.NExtRef{} //订阅虚端子
- sourceReportControl := map[string]*node_attr.NReportControl{}
- targetReportControl := map[string]*node_attr.NReportControl{}
- sourceLogControl := map[string]*node_attr.NLogControl{}
- targetLogControl := map[string]*node_attr.NLogControl{}
- //比较IED内的遥控是否存在新增、删除、变动
- sourceYaoKongDoiList := new(ScdMgr).GetYaoKongDOIMap(sourceScdXmlObj, iedname)
- targetYaoKongDoiList := new(ScdMgr).GetYaoKongDOIMap(targetScdXmlObj, iedname)
- //比较IED内的定值是否存在新增、删除、变动
- sourceDingZhiDoiList := new(ScdMgr).GetDingZhiDOIMap(sourceScdXmlObj, iedname)
- targetDingZhiDoiList := new(ScdMgr).GetDingZhiDOIMap(targetScdXmlObj, iedname)
- //比较IED内的遥信是否存在新增、删除、变动
- sourceYaoCe, sourceYaoXin, sourceYaoMai := new(ScdMgr).GetYcYkYmMap(sourceScdXmlObj, iedname)
- targetYaoCe, targetYaoXin, targetYaoMai := new(ScdMgr).GetYcYkYmMap(targetScdXmlObj, iedname)
- //数据集及成员
- sourceDatasets := map[string]*node_attr.NDataSet{}
- targetDatasets := map[string]*node_attr.NDataSet{}
- for k, item := range sourceYaoKongDoiList {
- if tempItem, h := targetYaoKongDoiList[k]; !h {
- desc, _ := json.Marshal(item)
- c.addResult(iedname, ieddesc, "i", "scd.ied.YK", k, string(desc), item.NodeId, item.Lineno)
- } else {
- bye1, _ := json.Marshal(item)
- bye2, _ := json.Marshal(tempItem)
- str1 := string(bye1)
- str2 := string(bye2)
- if str1 != str2 {
- logger.Logger.Debug(fmt.Sprintf("发现遥控测点有更改,byte1:%+v byte2:%+v", bye1, bye2))
- desc := fmt.Sprintf(`[%s,%s]`, (str1), (str2))
- c.addResult(iedname, ieddesc, "u", "scd.ied.YK", k, desc, item.NodeId, item.Lineno)
- }
- }
- }
- for k, item := range targetYaoKongDoiList {
- if _, h := sourceYaoKongDoiList[k]; !h {
- desc, _ := json.Marshal(item)
- c.addResult(iedname, ieddesc, "d", "scd.ied.YK", k, string(desc), item.NodeId, item.Lineno)
- }
- }
- for k, item := range sourceDingZhiDoiList {
- if tempItem, h := targetDingZhiDoiList[k]; !h {
- desc, _ := json.Marshal(item)
- c.addResult(iedname, ieddesc, "i", "scd.ied.DZ", k, string(desc), item.NodeId, item.Lineno)
- } else {
- bye1, _ := json.Marshal(item)
- bye2, _ := json.Marshal(tempItem)
- str1 := string(bye1)
- str2 := string(bye2)
- if str1 != str2 {
- desc := fmt.Sprintf(`[%s,%s]`, (str1), (str2))
- c.addResult(iedname, ieddesc, "u", "scd.ied.DZ", k, desc, item.NodeId, item.Lineno)
- }
- }
- }
- for k, item := range targetDingZhiDoiList {
- if _, h := sourceDingZhiDoiList[k]; !h {
- desc, _ := json.Marshal(item)
- c.addResult(iedname, ieddesc, "d", "scd.ied.DZ", k, string(desc), item.NodeId, item.Lineno)
- }
- }
- for _, ap := range sourceIedObj.AccessPoint {
- if ap.Server == nil {
- continue
- }
- for _, ld := range ap.Server.LDevice {
- if ld.LN0 == nil {
- break
- }
- for _, goose := range ld.LN0.GSEControl {
- sourceGooseBlock[ld.Inst+"."+goose.Name] = goose
- }
- for _, smv := range ld.LN0.SampledValueControl {
- sourceSvBlock[ld.Inst+"."+smv.Name] = smv
- }
- //发布虚端子列表
- for _, dst := range ld.LN0.DataSet {
- sourceDatasets[ld.Inst+"."+dst.Name] = dst
- for _, fcda := range dst.FCDA {
- key := fmt.Sprintf("%s/%s%s%s.%s.%s", fcda.LdInst, fcda.Prefix, fcda.LnClass, fcda.LnInst, fcda.DoName, fcda.DaName)
- sourcePublishFcda[key] = fcda
- }
- }
- //订阅虚端子
- if ld.LN0.Inputs != nil {
- for _, extref := range ld.LN0.Inputs.ExtRef {
- sourceSubExtref[extref.IntAddr] = extref
- }
- }
- //报告控制块
- for _, rpb := range ld.LN0.ReportControl {
- sourceReportControl[ld.Inst+rpb.Name] = rpb
- }
- //日志控制块
- for _, rpb := range ld.LN0.LogControl {
- sourceLogControl[ld.Inst+rpb.Name] = rpb
- }
- }
- }
- for _, ap := range targetIedObj.AccessPoint {
- if ap.Server == nil {
- continue
- }
- for _, ld := range ap.Server.LDevice {
- if ld.LN0 == nil {
- break
- }
- for _, goose := range ld.LN0.GSEControl {
- targetGooseBlock[ld.Inst+"."+goose.Name] = goose
- }
- for _, smv := range ld.LN0.SampledValueControl {
- targetSvBlock[ld.Inst+"."+smv.Name] = smv
- }
- //发布虚端子列表
- for _, dst := range ld.LN0.DataSet {
- targetDatasets[ld.Inst+"."+dst.Name] = dst
- for _, fcda := range dst.FCDA {
- key := fmt.Sprintf("%s/%s%s%s.%s.%s", fcda.LdInst, fcda.Prefix, fcda.LnClass, fcda.LnInst, fcda.DoName, fcda.DaName)
- targetPublishFcda[key] = fcda
- }
- }
- //订阅虚端子
- if ld.LN0.Inputs != nil {
- for _, extref := range ld.LN0.Inputs.ExtRef {
- targetSubExtref[extref.IntAddr] = extref
- }
- }
- //报告控制块
- for _, rpb := range ld.LN0.ReportControl {
- targetReportControl[ld.Inst+rpb.Name] = rpb
- }
- //日志控制块
- for _, rpb := range ld.LN0.LogControl {
- targetLogControl[ld.Inst+rpb.Name] = rpb
- }
- }
- }
- //GOOSE控制块
- for blockkey, item := range sourceGooseBlock {
- if tmpItem, h := targetGooseBlock[blockkey]; !h {
- //新增了控制块
- desc, _ := json.Marshal(item)
- c.addResult(iedname, ieddesc, "i", "scd.ied.GSEControl", blockkey, string(desc), item.NodeId, item.Lineno)
- } else {
- b1, _ := json.Marshal(item)
- b2, _ := json.Marshal(tmpItem)
- //块参数是否更改
- paraSource := string(b1)
- paraTarget := string(b2)
- if paraSource != paraTarget {
- desc := fmt.Sprintf(`[%s,%s]`, paraSource, paraTarget)
- c.addResult(iedname, ieddesc, "u", "scd.ied.GSEControl", blockkey, desc, item.NodeId, item.Lineno)
- }
- }
- }
- for blockkey, item := range targetGooseBlock {
- if _, h := sourceGooseBlock[blockkey]; !h {
- //删除了控制块
- desc, _ := json.Marshal(item)
- c.addResult(iedname, ieddesc, "d", "scd.ied.GSEControl", blockkey, string(desc), item.NodeId, item.Lineno)
- }
- }
- //SV控制块
- for blockkey, item := range sourceSvBlock {
- if tmpItem, h := targetSvBlock[blockkey]; !h {
- //新增了控制块
- desc, _ := json.Marshal(item)
- c.addResult(iedname, ieddesc, "i", "scd.ied.SampledValueControl", blockkey, string(desc), item.NodeId, item.Lineno)
- } else {
- b1, _ := json.Marshal(item)
- b2, _ := json.Marshal(tmpItem)
- //块参数是否更改
- paraSource := string(b1)
- paraTarget := string(b2)
- if paraSource != paraTarget {
- desc := fmt.Sprintf(`[%s,%s]`, paraSource, paraTarget)
- c.addResult(iedname, ieddesc, "u", "scd.ied.SampledValueControl", blockkey, desc, item.NodeId, item.Lineno)
- }
- }
- }
- for blockkey, item := range targetGooseBlock {
- if _, h := sourceGooseBlock[blockkey]; !h {
- //删除了控制块
- desc, _ := json.Marshal(item)
- c.addResult(iedname, ieddesc, "d", "scd.ied.SampledValueControl", blockkey, string(desc), item.NodeId, item.Lineno)
- }
- }
- //控制块及发布虚端子对比
- for key, item := range sourcePublishFcda {
- //新增的发布虚端子
- if _, h := targetPublishFcda[key]; !h {
- desc, _ := json.Marshal(item)
- c.addResult(iedname, ieddesc, "i", "scd.ied.FCDA", key, string(desc), item.NodeId, item.Lineno)
- //发布虚端子同时也是数据集成员
- c.addResult(iedname, ieddesc, "i", "scd.ied.DatSetMeber", key, string(desc), item.NodeId, item.Lineno)
- }
- }
- for key, item := range targetPublishFcda {
- //删除的发布虚端子
- if _, h := sourcePublishFcda[key]; !h {
- desc, _ := json.Marshal(item)
- c.addResult(iedname, ieddesc, "d", "scd.ied.FCDA", key, string(desc), item.NodeId, item.Lineno)
- //发布虚端子同时也是数据集成员
- c.addResult(iedname, ieddesc, "d", "scd.ied.DatSetMeber", key, string(desc), item.NodeId, item.Lineno)
- }
- }
- //控制块及订阅虚端子对比
- for key, item := range sourceSubExtref {
- //新增的订阅虚端子
- if _, h := targetSubExtref[key]; !h {
- desc, _ := json.Marshal(item)
- c.addResult(iedname, ieddesc, "i", "scd.ied.ExtRef", key, string(desc), item.NodeId, item.Lineno)
- }
- }
- for key, item := range targetSubExtref {
- //删除的订阅虚端子
- if _, h := sourceSubExtref[key]; !h {
- desc, _ := json.Marshal(item)
- c.addResult(iedname, ieddesc, "d", "scd.ied.ExtRef", key, string(desc), item.NodeId, item.Lineno)
- }
- }
- //报告控制块
- for key, item := range sourceReportControl {
- if tmpItem, h := targetReportControl[key]; !h {
- desc, _ := json.Marshal(item)
- c.addResult(iedname, ieddesc, "i", "scd.ied.ReportControl", key, string(desc), item.NodeId, item.Lineno)
- } else {
- //判断是否更改
- b1, _ := json.Marshal(item)
- b2, _ := json.Marshal(tmpItem)
- paraSource := string(b1)
- paraTarget := string(b2)
- if paraSource != paraTarget {
- desc := fmt.Sprintf(`[%s,%s]`, paraSource, paraTarget)
- c.addResult(iedname, ieddesc, "u", "scd.ied.ReportControl", key, desc, item.NodeId, item.Lineno)
- }
- }
- }
- for key, item := range targetReportControl {
- if _, h := sourceReportControl[key]; !h {
- desc, _ := json.Marshal(item)
- c.addResult(iedname, ieddesc, "d", "scd.ied.ReportControl", key, string(desc), item.NodeId, item.Lineno)
- }
- }
- //日志控制块
- for key, item := range sourceLogControl {
- if tmpItem, h := targetLogControl[key]; !h {
- desc, _ := json.Marshal(item)
- c.addResult(iedname, ieddesc, "i", "scd.ied.LogControl", key, string(desc), item.NodeId, item.Lineno)
- } else {
- //判断是否更改
- b1, _ := json.Marshal(item)
- b2, _ := json.Marshal(tmpItem)
- paraSource := string(b1)
- paraTarget := string(b2)
- if paraSource != paraTarget {
- desc := fmt.Sprintf(`[%s,%s]`, paraSource, paraTarget)
- c.addResult(iedname, ieddesc, "u", "scd.ied.LogControl", key, desc, item.NodeId, item.Lineno)
- }
- }
- }
- for key, item := range targetLogControl {
- if _, h := sourceLogControl[key]; !h {
- desc, _ := json.Marshal(item)
- c.addResult(iedname, ieddesc, "d", "scd.ied.LogControl", key, string(desc), item.NodeId, item.Lineno)
- }
- }
- //遥测对比
- for k, item := range sourceYaoCe {
- if tempitem, h := targetYaoCe[k]; !h {
- desc, _ := json.Marshal(item)
- c.addResult(iedname, ieddesc, "i", "scd.ied.YC", k, string(desc), int64(0), int64(0))
- } else {
- b1, _ := json.Marshal(item)
- b2, _ := json.Marshal(tempitem)
- str1 := string(b1)
- str2 := string(b2)
- if str1 != str2 {
- desc := fmt.Sprintf(`[%s,%s]`, str1, str2)
- c.addResult(iedname, ieddesc, "u", "scd.ied.YC", k, desc, int64(0), int64(0))
- }
- }
- }
- for k, item := range targetYaoCe {
- if _, h := sourceYaoCe[k]; !h {
- desc, _ := json.Marshal(item)
- c.addResult(iedname, ieddesc, "d", "scd.ied.YC", k, string(desc), int64(0), int64(0))
- }
- }
- //遥信测点对比
- for k, item := range sourceYaoXin {
- if tempitem, h := targetYaoXin[k]; !h {
- desc, _ := json.Marshal(item)
- c.addResult(iedname, ieddesc, "i", "scd.ied.YX", k, string(desc), int64(0), int64(0))
- } else {
- b1, _ := json.Marshal(item)
- b2, _ := json.Marshal(tempitem)
- str1 := string(b1)
- str2 := string(b2)
- if str1 != str2 {
- desc := fmt.Sprintf(`[%s,%s]`, str1, str2)
- c.addResult(iedname, ieddesc, "u", "scd.ied.YX", k, desc, int64(0), int64(0))
- }
- }
- }
- for k, item := range targetYaoXin {
- if _, h := sourceYaoXin[k]; !h {
- desc, _ := json.Marshal(item)
- c.addResult(iedname, ieddesc, "d", "scd.ied.YX", k, string(desc), int64(0), int64(0))
- }
- }
- //遥脉测点对比
- for k, item := range sourceYaoMai {
- if tempitem, h := targetYaoMai[k]; !h {
- desc, _ := json.Marshal(item)
- c.addResult(iedname, ieddesc, "i", "scd.ied.YM", k, string(desc), int64(0), int64(0))
- } else {
- b1, _ := json.Marshal(item)
- b2, _ := json.Marshal(tempitem)
- str1 := string(b1)
- str2 := string(b2)
- if str1 != str2 {
- desc := fmt.Sprintf(`[%s,%s]`, str1, str2)
- c.addResult(iedname, ieddesc, "u", "scd.ied.YM", k, desc, int64(0), int64(0))
- }
- }
- }
- for k, item := range targetYaoMai {
- if _, h := sourceYaoMai[k]; !h {
- desc, _ := json.Marshal(item)
- c.addResult(iedname, ieddesc, "d", "scd.ied.YM", k, string(desc), int64(0), int64(0))
- }
- }
- //数据集对比
- for key, item := range sourceDatasets {
- if tempitem, h := targetDatasets[key]; !h {
- desc := fmt.Sprintf(`{"desc":"%s","name":"%s"}`, item.Desc, item.Name)
- c.addResult(iedname, ieddesc, "i", "scd.ied.DataSet", key, desc, item.NodeId, item.Lineno)
- } else {
- b1 := fmt.Sprintf(`{"desc":"%s","name":"%s"}`, item.Desc, item.Name)
- b2 := fmt.Sprintf(`{"desc":"%s","name":"%s"}`, tempitem.Desc, tempitem.Name)
- if b1 != b2 {
- desc := fmt.Sprintf(`[%s,%s]`, b1, b2)
- c.addResult(iedname, ieddesc, "u", "scd.ied.DataSet", key, desc, int64(0), int64(0))
- }
- }
- }
- for k, item := range targetDatasets {
- if _, h := sourceDatasets[k]; !h {
- desc := fmt.Sprintf(`{"desc":"%s","name":"%s"}`, item.Desc, item.Name)
- c.addResult(iedname, ieddesc, "d", "scd.ied.DataSet", k, desc, item.NodeId, item.Lineno)
- }
- }
- sourceGooseBlock = nil
- sourceSvBlock = nil
- targetGooseBlock = nil
- targetSvBlock = nil
- sourceIedObj = nil
- targetIedObj = nil
- sourcePublishFcda = nil
- targetPublishFcda = nil
- sourceSubExtref = nil
- targetSubExtref = nil
- sourceReportControl = nil
- targetReportControl = nil
- sourceLogControl = nil
- targetLogControl = nil
- sourceYaoXin = nil
- targetYaoXin = nil
- sourceYaoKongDoiList = nil
- targetYaoKongDoiList = nil
- sourceYaoCe = nil
- targetYaoCe = nil
- sourceYaoMai = nil
- targetYaoMai = nil
- sourceDingZhiDoiList = nil
- targetDingZhiDoiList = nil
- }
- func (c *ScdCompare) addResult(iedname, ieddesc, opt, objtype, objname, desc string, nodeid, lineno int64) {
- detailrow := t_scd_diff_compare_detail{}
- detailrow.CompareId = c.CurrCompareRecord.Id
- detailrow.DiffDesc = desc
- detailrow.DiffObjectType = objtype
- detailrow.DiffOpt = opt
- detailrow.IedName = iedname
- detailrow.IedDesc = ieddesc
- detailrow.DiffObjectName = objname
- detailrow.DiffObjectNodeId = nodeid
- detailrow.ObjectLineNo = lineno
- c.CompareResultList = append(c.CompareResultList, detailrow)
- }
- //将对比结果批量写入数据库
- func (c *ScdCompare) writeResult() {
- if len(c.CompareResultList) == 0 {
- return
- }
- db := orm.NewOrm()
- nodeCols := "(compare_id,diff_object_type,diff_object_node_id,diff_object_name,diff_opt,diff_desc,diff_source_node_id,source_line_no,object_line_no,ied_name,ied_desc)"
- loadedRec := 0
- nodeSqlValuesAry := []string{}
- c.lock.Lock()
- compareId := int64(0)
- for _, m := range c.CompareResultList {
- if compareId == 0 {
- compareId = m.CompareId
- }
- nodeSqlValuesAry = append(nodeSqlValuesAry, fmt.Sprintf("(%d,'%s',%d,'%s','%s','%s',%d,%d,%d,'%s','%s')", m.CompareId, m.DiffObjectType, m.DiffObjectNodeId, m.DiffObjectName, m.DiffOpt, m.DiffDesc, m.DiffSourceNodeId, m.SourceLineNo, m.ObjectLineNo, m.IedName, m.IedDesc))
- if len(nodeSqlValuesAry) == 1000 {
- sql := "insert into t_scd_diff_compare_detail" + nodeCols + "values" + strings.Join(nodeSqlValuesAry, ",")
- _, err := db.Raw(sql).Exec()
- if err != nil {
- logger.Logger.Error(err)
- }
- loadedRec = loadedRec + 1000
- nodeSqlValuesAry = nil
- nodeSqlValuesAry = []string{}
- }
- }
- if len(nodeSqlValuesAry) > 0 {
- sql := "insert into t_scd_diff_compare_detail" + nodeCols + "values" + strings.Join(nodeSqlValuesAry, ",")
- _, err := db.Raw(sql).Exec()
- if err != nil {
- logger.Logger.Error(err, sql)
- }
- nodeSqlValuesAry = nil
- }
- c.CompareResultList = nil
- c.lock.Unlock()
- runtime.GC()
- }
|