123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093 |
- package bo
- import (
- "bufio"
- "encoding/json"
- "errors"
- "fmt"
- "io"
- "log"
- "os"
- "runtime"
- "scd_check_tools/global"
- "scd_check_tools/logger"
- "scd_check_tools/models/enum"
- "scd_check_tools/models/node_attr"
- "scd_check_tools/mqtt"
- "scd_check_tools/tools"
- "strconv"
- "strings"
- "time"
- "github.com/astaxie/beego/orm"
- )
- type ScdNode struct {
- RootID int64
- ScdName string
- ScdPath string
- Name string
- DeviceBaseModel
- //未结束的XML标签列表
- NotEndNodeIdList []int64
- //节点队列
- NodeQue map[int64]*t_scd_node_scl
- //节点属性入库队列
- NodeAttrQue []interface{}
- //节点验证规则定义
- NodeRuleList map[string][]orm.Params
- //节点属性验证规则定义
- NodeAttrRuleList map[string][]orm.Params
- //节点属性唯一性验证规则定义
- NodeAttrUniqueRuleList []orm.Params
- //节点验证规则列表:内置验证程序实现
- NodeRuleFunctionList []orm.Params
- //间隔管理对象
- AreaMgr *ScdAreaMgr
- //解析完后自动比对的scdID,如果未设置 ,则解析后不做比对
- AutoCompScdID int64
- StationID int
- //是否默认为在运版。当签入流程只有一个节点时,需要设备该属性为1,此时在解析完文件后将该scd设置为在运版本
- IsDefaultRunVersion int
- //间隔解析方式.分为Bay方式和自定义解析方式(根据name和des进行分词解析),默认为自定义解析方式解析
- IsBay bool
- }
- type t_scd_node_scl struct {
- Id int64 `orm:"pk"`
- ScdId int64
- ParentNodeId int64
- NodeName string
- NodeValue string
- LineNo int64
- CreatedBy int
- CreatedTime string
- }
- type t_scd_scl struct {
- Id int64 `orm:"pk"`
- ScdName string
- Path string
- Version string
- Enable int
- StationId int
- //签出锁定
- CheckoutLock int
- //是否是管控SCD,true为管控SCD,false为非管控SCD
- IsCheckinScd int
- CreatedBy int
- CreatedTime string
- }
- type t_ied_ctrl_relation struct {
- Id int `orm:"pk"`
- ScdId int64
- MasterIedId int64
- MasterIedName string
- RefType int
- SourceIedId int64
- SourceIedName string
- TargetIedId int64
- TargetIedName string
- OutLdId int64
- OutLdInst string
- OutLdDesc string
- LdId int64
- LdInst string
- LdDesc string
- CtrlId int64
- CtrlType string
- CtrlName string
- DatsetId int64
- DatsetName string
- DatsetDesc string
- Cnt int
- }
- func init() {
- orm.RegisterModel(new(t_scd_scl))
- orm.RegisterModel(new(t_scd_node_scl))
- orm.RegisterModel(new(t_ied_ctrl_relation))
- }
- func (c *ScdNode) GetCheckToolsTreeRoot(id, pid int64, datatype string) ([]orm.Params, error) {
- sclObj, serr := new(ScdParse).GetScdXmlObjectBySCDID(tools.IsEmpty(c.RootID))
- if serr != nil {
- return nil, serr
- }
- if sclObj == nil {
- return nil, errors.New("无效的SCD编号")
- }
- alertDef := map[string]int{
- "": 0,
- "hint": 1,
- "waring": 2,
- "error": 3,
- }
- noderuleObj := new(ScdNodeRule)
- noderuleObj.ScdID = c.RootID
- ruleHintLevel, _ := noderuleObj.SumCheckResult()
- alertlevelMap := map[string]string{}
- for _, levelrow := range ruleHintLevel {
- key := fmt.Sprintf("%s%s", levelrow["object_name"], levelrow["ied_name"])
- if v, h := alertlevelMap[key]; h {
- level := tools.IsEmpty(levelrow["alert_level"])
- if alertDef[level] > alertDef[v] {
- alertlevelMap[key] = level
- }
- } else {
- alertlevelMap[key] = tools.IsEmpty(levelrow["alert_level"])
- }
- }
- db := orm.NewOrm()
- reuslt := []orm.Params{}
- areaMgr := new(ScdAreaMgr)
- if id == 0 {
- sclAlertLevel := ""
- if alertDef[alertlevelMap["Header"]] > alertDef[sclAlertLevel] {
- sclAlertLevel = alertlevelMap["Header"]
- }
- if alertDef[alertlevelMap["Substation"]] > alertDef[sclAlertLevel] {
- sclAlertLevel = alertlevelMap["Substation"]
- }
- reuslt = append(reuslt, orm.Params{
- "id": "9999",
- "title": "基本语法校验结果",
- "pid": sclObj.NodeId,
- "isParent": "false",
- "datatype": "SCLSyntax",
- "alert_level": alertlevelMap["SCLSyntax"],
- })
- sclAlertLevel = alertlevelMap["SCLSyntax"]
- //添加通信节点
- reuslt = append(reuslt, orm.Params{
- "id": sclObj.Communication.NodeId,
- "title": "Communication",
- "pid": sclObj.NodeId,
- "isParent": "false",
- "datatype": "Communication",
- "alert_level": alertlevelMap["Communication"],
- })
- if alertDef[alertlevelMap["Communication"]] > alertDef[sclAlertLevel] {
- sclAlertLevel = alertlevelMap["Communication"]
- }
- //添加数据模板节点
- reuslt = append(reuslt, orm.Params{
- "id": sclObj.DataTypeTemplates.NodeId,
- "title": "DataTypeTemplates",
- "pid": sclObj.NodeId,
- "isParent": "false",
- "datatype": "DataTypeTemplates",
- "alert_level": alertlevelMap["DataTypeTemplates"],
- })
- if alertDef[alertlevelMap["DataTypeTemplates"]] > alertDef[sclAlertLevel] {
- sclAlertLevel = alertlevelMap["DataTypeTemplates"]
- }
- //获取间隔列表
- areaList, err := areaMgr.GetAreaList(c.RootID)
- if err != nil {
- return reuslt, err
- }
- voltageLevel := map[string]string{} //电压等级的告警级别
- //获取该电压等级下的间隔列表
- for _, ararow := range areaList {
- ararow["title"] = ararow["name"]
- ararow["datatype"] = "area"
- ararow["isParent"] = "true"
- ararow["alert_level"] = ""
- ararow["pid"] = tools.IsEmpty(ararow["voltage_level"])
- areaid, _ := strconv.Atoi(tools.IsEmpty(ararow["id"]))
- iedList, err := areaMgr.GetIedList(c.RootID, 0, int32(areaid), "")
- if err != nil {
- continue
- }
- //获取间隔下的IED
- alertLevel := ""
- for _, row := range iedList {
- row["isParent"] = "false"
- row["pid"] = ararow["id"]
- row["id"] = row["node_id"]
- row["title"] = "[" + tools.IsEmpty(row["attr_name"]) + "]" + strings.Replace(tools.IsEmpty(row["attr_desc"]), tools.IsEmpty(row["name"]), "..", 1)
- iedAlart := alertlevelMap["IED"+tools.IsEmpty(row["attr_name"])]
- row["alert_level"] = iedAlart
- reuslt = append(reuslt, row)
- if alertDef[iedAlart] > alertDef[alertLevel] {
- alertLevel = iedAlart
- }
- }
- ararow["alert_level"] = alertLevel //间隔的告警级别
- reuslt = append(reuslt, ararow)
- vol := tools.IsEmpty(ararow["voltage_level"])
- if v, h := voltageLevel[vol]; h {
- if alertDef[alertLevel] > alertDef[v] {
- voltageLevel[vol] = alertLevel
- }
- } else {
- voltageLevel[vol] = alertLevel
- }
- }
- //添加电压等级子节点
- 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, c.RootID).Values(&voltagelevelRowset)
- for _, row2 := range voltagelevelRowset {
- row2["pid"] = sclObj.NodeId
- vollevel := voltageLevel[tools.IsEmpty(row2["id"])]
- row2["alert_level"] = vollevel
- reuslt = append(reuslt, row2)
- if alertDef[vollevel] > alertDef[sclAlertLevel] {
- sclAlertLevel = vollevel
- }
- }
- //添加SCL节点
- reuslt = append(reuslt, orm.Params{
- "id": sclObj.NodeId,
- "title": "SCL",
- "pid": 0,
- "isParent": "true",
- "datatype": "SCL",
- "alert_level": sclAlertLevel,
- })
- } else {
- if datatype == "area" {
- //当前为间隔时,则返回该间隔下的IED
- iedList, err := areaMgr.GetIedList(c.RootID, 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)
- }
- reuslt = iedList
- }
- }
- new(SystemLog).Success(enum.AuditType_scd_show, enum.LogType_Query, enum.OptEventType_Bus, enum.OptEventLevel_Low, "查询IED结构树", c.GetUserInfo())
- return reuslt, nil
- }
- //查询指定scd的节点列表
- func (c *ScdNode) List(param map[string]interface{}) ([]orm.Params, int, error) {
- scdid := tools.IsEmpty(param["scd_id"])
- scdXmlObj, serr := new(ScdParse).GetScdXmlObjectBySCDID(scdid)
- if serr != nil {
- return nil, 0, serr
- }
- if scdXmlObj == nil {
- return nil, 0, errors.New("无效的SCD文件")
- }
- iedname := tools.IsEmpty(param["ied_name"])
- rowset := []orm.Params{}
- if v, ok := param["name"]; ok {
- name := tools.IsEmpty(v)
- switch name {
- case "SubNetwork":
- for _, item := range scdXmlObj.Communication.SubNetwork {
- rowobj := orm.Params{
- "node_id": item.NodeId,
- "node_name": "SubNetwork",
- "node_value": "",
- "parent_node_id": scdXmlObj.Communication.NodeId,
- "attr_desc": item.Desc,
- "attr_name": item.Name,
- "attr_type": item.Type,
- }
- rowset = append(rowset, rowobj)
- }
- break
- case "ConnectedAP":
- for _, item := range scdXmlObj.Communication.SubNetwork {
- for _, c1 := range item.ConnectedAP {
- rowobj := orm.Params{
- "node_id": c1.NodeId,
- "node_name": "ConnectedAP",
- "node_value": "",
- "parent_node_id": item.NodeId,
- "attr_desc": c1.Desc,
- "attr_ied_name": c1.IedName,
- "attr_ap_name": c1.ApName,
- }
- rowset = append(rowset, rowobj)
- }
- }
- break
- case "AccessPoint":
- if iedname == "" {
- return nil, 0, errors.New("IED Name不能为空")
- }
- iedObj := new(ScdNode).GetIed(scdXmlObj, scdid, iedname)
- if iedObj == nil {
- return nil, 0, errors.New("无效的IED Name")
- }
- for _, item := range iedObj.AccessPoint {
- rowobj := orm.Params{
- "node_id": item.NodeId,
- "node_name": "AccessPoint",
- "node_value": "",
- "parent_node_id": iedObj.NodeId,
- "attr_desc": item.Desc,
- "ied_name": iedObj.Name,
- "attr_name": item.Name,
- "attr_clock": item.Clock,
- "attr_router": item.Router,
- }
- rowset = append(rowset, rowobj)
- }
- break
- case "DataSet":
- if iedname == "" {
- return nil, 0, errors.New("IED Name不能为空")
- }
- iedObj := new(ScdNode).GetIed(scdXmlObj, scdid, iedname)
- if iedObj == nil {
- return nil, 0, errors.New("无效的IED Name")
- }
- for _, item := range iedObj.AccessPoint {
- if item.Server == nil {
- continue
- }
- for _, c1 := range item.Server.LDevice {
- for _, ds := range c1.LN0.DataSet {
- rowobj := orm.Params{
- "node_id": ds.NodeId,
- "node_name": "DataSet",
- "node_value": "",
- "parent_node_id": c1.NodeId,
- "attr_desc": ds.Desc,
- "ied_name": iedObj.Name,
- "attr_name": ds.Name,
- }
- rowset = append(rowset, rowobj)
- }
- }
- }
- break
- case "LN0":
- parent_node_id, _ := strconv.ParseInt(tools.IsEmpty(param["parent_node_id"]), 10, 64)
- scdidint64, _ := strconv.ParseInt(scdid, 10, 64)
- v_scdcache, _ := GlobalNodeMap.Load(scdidint64)
- if v_scdcache == nil {
- break
- }
- scdcache := v_scdcache.(map[int64]NodeCacheMap)
- ldevice := scdcache[parent_node_id].ObjAddr.(*node_attr.NLDevice)
- rowobj := orm.Params{
- "node_id": ldevice.LN0.NodeId,
- "node_name": "LN0",
- "node_value": "",
- "parent_node_id": parent_node_id,
- "attr_desc": ldevice.LN0.Desc,
- "ied_name": "",
- "attr_inst": ldevice.LN0.Inst,
- "attr_ln_class": ldevice.LN0.LnClass,
- "attr_ln_type": ldevice.LN0.LnType,
- "attr_prefix": ldevice.LN0.Prefix,
- }
- rowset = append(rowset, rowobj)
- break
- case "LN":
- parent_node_id, _ := strconv.ParseInt(tools.IsEmpty(param["parent_node_id"]), 10, 64)
- scdidint64, _ := strconv.ParseInt(scdid, 10, 64)
- v_scdcache, _ := GlobalNodeMap.Load(scdidint64)
- if v_scdcache == nil {
- break
- }
- scdcache := v_scdcache.(map[int64]NodeCacheMap)
- ldevice := scdcache[parent_node_id].ObjAddr.(*node_attr.NLDevice)
- for _, ln := range ldevice.LN {
- rowobj := orm.Params{
- "node_id": ln.NodeId,
- "node_name": "LN",
- "node_value": "",
- "parent_node_id": parent_node_id,
- "attr_desc": ln.Desc,
- "ied_name": "",
- "attr_inst": ln.Inst,
- "attr_ln_class": ln.LnClass,
- "attr_ln_type": ln.LnType,
- "attr_prefix": ln.Prefix,
- }
- rowset = append(rowset, rowobj)
- }
- break
- case "FCDA":
- parent_node_id, _ := strconv.ParseInt(tools.IsEmpty(param["parent_node_id"]), 10, 64)
- scdidint64, _ := strconv.ParseInt(scdid, 10, 64)
- v_scdcache, _ := GlobalNodeMap.Load(scdidint64)
- if v_scdcache == nil {
- break
- }
- scdcache := v_scdcache.(map[int64]NodeCacheMap)
- ds := scdcache[parent_node_id].ObjAddr.(*node_attr.NDataSet)
- for _, fcda := range ds.FCDA {
- rowobj := orm.Params{
- "node_id": fcda.NodeId,
- "node_name": "FCDA",
- "node_value": "",
- "parent_node_id": parent_node_id,
- "attr_da_name": fcda.DaName,
- "attr_do_name": fcda.DoName,
- "attr_fc": fcda.Fc,
- "attr_ld_inst": fcda.LdInst,
- "attr_ln_class": fcda.LnClass,
- "attr_ln_inst": fcda.LnInst,
- "attr_prefix": fcda.Prefix,
- }
- rowset = append(rowset, rowobj)
- }
- default:
- break
- }
- }
- return rowset, len(rowset), nil
- }
- //获取指定节点的所有属性及属性值
- func (c *ScdNode) GetAttrValues(param map[string]interface{}) (interface{}, error) {
- node_id := tools.IsEmpty(param["node_id"])
- if node_id == "" {
- return nil, errors.New("节点编号不能为空")
- }
- node_id_int, _ := strconv.ParseInt(node_id, 10, 64)
- scdid := tools.IsEmpty(param["scd_id"])
- scdidint64, _ := strconv.ParseInt(scdid, 10, 64)
- v_scdcache, _ := GlobalNodeMap.Load(scdidint64)
- if v_scdcache == nil {
- return nil, errors.New("无效的节点")
- }
- nodeInfo := v_scdcache.(map[int64]NodeCacheMap)
- nodeobj := nodeInfo[node_id_int].ObjAddr
- if nodeobj == nil {
- return nil, errors.New("无效的节点")
- }
- return new(node_attr.BaseNode).ToMap(nodeobj), nil
- }
- //统计指定节点的下级节点类型及数量
- func (c *ScdNode) GetChildrenStat(scdid, nodeid string) ([]orm.Params, int, error) {
- if scdid == "" {
- return nil, 0, errors.New("SCD文件编号不能为空!")
- }
- if nodeid == "" {
- return nil, 0, errors.New("节点编号不能为空!")
- }
- db := orm.NewOrm()
- rowset := []orm.Params{}
- sql := "select node_name,count(1) cnt from t_scd_node_scl t where 1=1 and t.scd_id=? and t.parent_node_id=? GROUP BY t.node_name"
- sqllog := fmt.Sprintf("SQL:%s,参数:%s,%s", sql, scdid, nodeid)
- _, err := db.Raw(sql, scdid, nodeid).Values(&rowset)
- if err != nil {
- logger.Logger.Error(err, sqllog)
- new(SystemLog).Fail(enum.AuditType_scd_show, enum.LogType_datastat, enum.OptEventType_Bus, enum.OptEventLevel_Low, sqllog, c.GetUserInfo())
- return rowset, 0, err
- }
- new(SystemLog).Success(enum.AuditType_scd_show, enum.LogType_datastat, enum.OptEventType_Bus, enum.OptEventLevel_Low, sqllog, c.GetUserInfo())
- return rowset, len(rowset), nil
- }
- //获取指定accessPoint下的Ldevice节点列表
- func (c *ScdNode) GetLdeviceList(scdid, accesspointid string) ([]orm.Params, int, error) {
- if scdid == "" {
- return nil, 0, errors.New("SCD文件编号不能为空!")
- }
- if accesspointid == "" {
- return nil, 0, errors.New("AccessPoint编号不能为空!")
- }
- scdXmlObj, serr := new(ScdParse).GetScdXmlObjectBySCDID(scdid)
- if serr != nil {
- return nil, 0, serr
- }
- if scdXmlObj == nil {
- return nil, 0, errors.New("无效的SCD文件!")
- }
- rowset := []orm.Params{}
- accesspointidInt, _ := strconv.ParseInt(accesspointid, 10, 64)
- for _, row := range scdXmlObj.IED {
- for _, r1 := range row.AccessPoint {
- if r1.Server == nil {
- continue
- }
- if r1.NodeId == accesspointidInt {
- for _, r2 := range r1.Server.LDevice {
- rowset = append(rowset, orm.Params{
- "node_id": r2.NodeId,
- "attr_inst": r2.Inst,
- "attr_desc": r2.Desc,
- })
- }
- break
- }
- }
- }
- return rowset, len(rowset), nil
- }
- func (c *ScdNode) GetIedByID(sclObj *node_attr.SCL, scdid string, ied_id int64) *node_attr.NIED {
- if sclObj == nil {
- return nil
- }
- var masterIed *node_attr.NIED
- for _, row := range sclObj.IED {
- if row.NodeId == ied_id {
- masterIed = row
- break
- }
- }
- return masterIed
- }
- //获取IED
- func (c *ScdNode) GetIed(sclObj *node_attr.SCL, scdid string, ied_name string) *node_attr.NIED {
- if sclObj == nil {
- return nil
- }
- var masterIed *node_attr.NIED
- for _, row := range sclObj.IED {
- if row.Name == ied_name {
- masterIed = row
- break
- }
- }
- return masterIed
- }
- //获取指定IED节点的关联关系
- func (c *ScdNode) GetIedRelations(param map[string]interface{}) (map[string]interface{}, error) {
- scdid := tools.IsEmpty(param["scd_id"])
- //判断是否需要重新分析关系
- //isreset := tools.IsEmpty(param["reset"])
- v_iedname := tools.IsEmpty(param["ied_name"])
- cacheKey := "GetIedRelations_" + scdid
- cacheKey2 := "GetIedRelations_" + scdid + v_iedname
- if v_iedname == "" {
- if v, h := global.GoCahce.Get(cacheKey); h {
- return v.(map[string]interface{}), nil
- }
- } else {
- if v, h := global.GoCahce.Get(cacheKey2); h {
- return v.(map[string]interface{}), nil
- }
- if v, h := global.GoCahce.Get(cacheKey); h {
- alldata := v.(map[string]interface{})
- result := map[string]interface{}{}
- result[v_iedname] = alldata[v_iedname]
- return result, nil
- }
- }
- //logger.Logger.Debug(fmt.Sprintf("\n\n加载IED装置%s的关联IED\n", v_iedname))
- scdXmlObj, serr := new(ScdParse).GetScdXmlObjectBySCDID(scdid)
- if serr != nil {
- return nil, serr
- }
- if scdXmlObj == nil {
- return nil, errors.New("无效的SCD")
- }
- result := map[string]interface{}{}
- //ref为1时,查询的是该IED的输入关联IED
- //ref为0时,查询的是该iED的输出关联IED
- for _, row := range scdXmlObj.IED {
- ied_name := row.Name
- //查找输入的ied
- obj := orm.Params{"desc": row.Desc, "ied_name": row.Name, "node_id": row.NodeId, "list": []orm.Params{}}
- tmpAry := map[string]orm.Params{}
- for _, alist := range row.AccessPoint {
- if alist.Server == nil {
- logger.Logger.Error(errors.New(fmt.Sprintf("%s装置中的%s未发现Server定义", ied_name, alist.Name)))
- continue
- }
- for _, ldlist := range alist.Server.LDevice {
- if ldlist.LN0.Inputs != nil {
- for _, extreflist := range ldlist.LN0.Inputs.ExtRef {
- ref_ied_name := extreflist.IedName
- if _, h := tmpAry[ref_ied_name]; h {
- continue
- }
- refIedObj := c.GetIed(scdXmlObj, scdid, ref_ied_name)
- if refIedObj != nil {
- tmpAry[ref_ied_name] = orm.Params{"ied_desc": row.Desc, "ied_name": row.Name, "node_id": row.NodeId, "ref_ied_id": refIedObj.NodeId, "ref_ied_desc": refIedObj.Desc, "ref_ied_name": ref_ied_name, "ref_type": "1"}
- }
- }
- }
- }
- }
- for _, k := range tmpAry {
- obj["list"] = append(obj["list"].([]orm.Params), k)
- }
- //查找输出的ied
- tmpAry = map[string]orm.Params{}
- for _, outrow := range scdXmlObj.IED {
- if ied_name == outrow.Name {
- continue
- }
- for _, alist := range outrow.AccessPoint {
- if alist.Server == nil {
- logger.Logger.Error(errors.New(fmt.Sprintf("%s装置中的%s未发现Server定义", ied_name, alist.Name)))
- continue
- }
- for _, ldlist := range alist.Server.LDevice {
- if ldlist.LN0.Inputs != nil {
- for _, extreflist := range ldlist.LN0.Inputs.ExtRef {
- ref_ied_name := extreflist.IedName
- if ref_ied_name != ied_name {
- continue
- }
- if _, h := tmpAry[outrow.Name]; h {
- continue
- }
- refIedObj := c.GetIed(scdXmlObj, scdid, outrow.Name)
- if refIedObj != nil {
- tmpAry[outrow.Name] = orm.Params{"ied_desc": row.Desc, "ied_name": row.Name, "node_id": row.NodeId, "ref_ied_id": refIedObj.NodeId, "ref_ied_desc": outrow.Desc, "ref_ied_name": outrow.Name, "ref_type": "0"}
- }
- }
- }
- }
- }
- }
- for _, k := range tmpAry {
- obj["list"] = append(obj["list"].([]orm.Params), k)
- }
- result[ied_name] = obj
- }
- global.GoCahce.Set(cacheKey, result, -1)
- if v_iedname != "" {
- result2 := map[string]interface{}{}
- result2[v_iedname] = result[v_iedname]
- global.GoCahce.Set(cacheKey2, result2, -1)
- return result2, nil
- }
- return result, nil
- }
- //获取指定IED的控制块信息
- func (c *ScdNode) GetIedCtrlBlock(scdid int64, iedname string) (map[string]interface{}, error) {
- key := fmt.Sprintf("GetIedCtrlBlock_%d_%s", scdid, iedname)
- if v, h := global.GoCahce.Get(key); h {
- return v.(map[string]interface{}), nil
- }
- scdXmlObj, serr := new(ScdParse).GetScdXmlObjectBySCDID(tools.IsEmpty(scdid))
- if serr != nil {
- return nil, serr
- }
- if scdXmlObj == nil {
- return nil, errors.New("无效的SCD")
- }
- var iedObj *node_attr.NIED
- for _, row := range scdXmlObj.IED {
- if row.Name == iedname {
- iedObj = row
- break
- }
- }
- if iedObj == nil {
- return nil, errors.New("无效的IED装置名称")
- }
- result := map[string]interface{}{}
- gselist := []orm.Params{}
- smvlist := []orm.Params{}
- for _, row := range iedObj.AccessPoint {
- if row.Server == nil {
- logger.Logger.Error(errors.New(fmt.Sprintf("%s装置中的%s未发现Server定义", iedObj.Name, row.Name)))
- continue
- }
- for _, ld := range row.Server.LDevice {
- ldinst := ld.Inst
- if ld.LN0 != nil {
- for _, gse := range ld.LN0.GSEControl {
- datSetdesc := ""
- for _, ds := range ld.LN0.DataSet {
- if ds.Name == gse.DatSet {
- datSetdesc = ds.Desc
- break
- }
- }
- gooseaddress := orm.Params{}
- //获取控制块appid
- for _, subn := range scdXmlObj.Communication.SubNetwork {
- if subn.Type == "IECGOOSE" {
- for _, ap := range subn.ConnectedAP {
- if ap.IedName == iedObj.Name {
- for _, gse1 := range ap.GSE {
- if gse1.CbName == gse.Name && gse1.LdInst == ld.Inst {
- if gse1.Address != nil {
- for _, addrP := range gse1.Address.P {
- gooseaddress[strings.ReplaceAll(addrP.Type, "-", "_")] = addrP.InnerText
- }
- }
- break
- }
- }
- break
- }
- }
- break
- }
- }
- gselist = append(gselist, orm.Params{
- "attr_appid": gse.AppID,
- "attr_dat_set": gse.DatSet,
- "attr_name": gse.Name,
- "attr_conf_rev": gse.ConfRev,
- "attr_desc": "",
- "attr_type": gse.Type,
- "datset_desc": datSetdesc,
- "ldinst": ldinst,
- "node_id": gse.NodeId,
- "address": gooseaddress,
- })
- }
- for _, sv := range ld.LN0.SampledValueControl {
- datSetdesc := ""
- //获取控制块数据集信息
- for _, ds := range ld.LN0.DataSet {
- if ds.Name == sv.DatSet {
- datSetdesc = ds.Desc
- break
- }
- }
- svaddress := orm.Params{}
- //获取控制块appid
- for _, subn := range scdXmlObj.Communication.SubNetwork {
- if subn.Type == "SMV" {
- for _, ap := range subn.ConnectedAP {
- if ap.IedName == iedObj.Name {
- for _, smv := range ap.SMV {
- if smv.CbName == sv.Name && smv.LdInst == ld.Inst {
- if smv.Address != nil {
- for _, addrP := range smv.Address.P {
- svaddress[strings.ReplaceAll(addrP.Type, "-", "_")] = addrP.InnerText
- }
- }
- break
- }
- }
- break
- }
- }
- break
- }
- }
- smvlist = append(smvlist, orm.Params{
- "attr_smv_id": sv.SmvID,
- "attr_dat_set": sv.DatSet,
- "attr_smp_rate": sv.SmpRate,
- "attr_name": sv.Name,
- "attr_conf_rev": sv.ConfRev,
- "attr_desc": "",
- "attr_multicast": sv.Multicast,
- "datset_desc": datSetdesc,
- "ldinst": ldinst,
- "attr_nof_asdu": sv.NofASDU,
- "node_id": sv.NodeId,
- "address": svaddress,
- })
- }
- }
- }
- }
- result["GSEControl"] = gselist
- result["SampledValueControl"] = smvlist
- global.GoCahce.Set(key, result, -1)
- return result, nil
- }
- //获取指定IED的指定SMV控制块发送端子列表
- func (c *ScdNode) GetIedSMVCtrlBlockSendFcdaList(scdid int64, iedname string, ctrl_id int64) ([]orm.Params, error) {
- rowset := []orm.Params{}
- v_scdcache, _ := GlobalNodeMap.Load(scdid)
- if v_scdcache == nil {
- return nil, errors.New("无效的节点")
- }
- scdCacheObj := v_scdcache.(map[int64]NodeCacheMap)
- ctrlObj1 := scdCacheObj[ctrl_id]
- if ctrlObj1.ObjAddr == nil {
- return rowset, errors.New("无效的控制块ID")
- }
- //获取当前IED的输出IED
- relIed, err := c.GetIedRelations(map[string]interface{}{"scd_id": scdid, "ied_name": iedname})
- if relIed == nil {
- return nil, err
- }
- ieds0 := relIed[iedname].(orm.Params)
- if ieds0 == nil {
- return rowset, nil
- }
- ieds := ieds0["list"].([]orm.Params)
- outtoieds := []*node_attr.NIED{}
- //获取当前IED输出的目标IED,即ref_type为0的.结果中需要返回输出IED中对应的端子信息
- for _, r := range ieds {
- if tools.IsEmpty(r["ref_type"]) == "0" {
- iedid, _ := strconv.ParseInt(tools.IsEmpty(r["ref_ied_id"]), 10, 64)
- tmpIedObj := scdCacheObj[iedid].ObjAddr.(*node_attr.NIED)
- if tmpIedObj.Name == iedname {
- continue
- }
- outtoieds = append(outtoieds, tmpIedObj)
- }
- }
- if len(outtoieds) == 0 {
- return rowset, nil
- }
- ctrlObj := ctrlObj1.ObjAddr.(*node_attr.NSampledValueControl)
- datasetname := ctrlObj.DatSet
- ln0 := scdCacheObj[ctrlObj1.ParentNodeId].ObjAddr.(*node_attr.NLN0)
- ldid := scdCacheObj[ctrlObj1.ParentNodeId].ParentNodeId
- ld := scdCacheObj[ldid].ObjAddr.(*node_attr.NLDevice)
- for _, ds := range ln0.DataSet {
- if ds.Name == datasetname {
- for _, fcda := range ds.FCDA {
- obj := orm.Params{
- "do_desc": "",
- "do_name": fcda.DoName,
- "ld_inst": fcda.LdInst,
- "ln_inst": fcda.LnInst,
- "ln_class": fcda.LnClass,
- "prefix": fcda.Prefix,
- "out_intaddr": "",
- "out_ied_name": "",
- "out_ied_desc": "",
- "out_do_desc": "",
- }
- doi_desc := ""
- if fcda.LnClass == "LLN0" {
- for _, doi := range ld.LN0.DOI {
- if doi.Name == fcda.DoName {
- doi_desc = doi.Desc
- break
- }
- }
- } else {
- for _, ln := range ld.LN {
- if ln.Inst == fcda.LnInst && ln.LnClass == fcda.LnClass && ln.Prefix == fcda.Prefix {
- for _, doi := range ln.DOI {
- if doi.Name == fcda.DoName {
- doi_desc = doi.Desc
- break
- }
- }
- }
- if doi_desc != "" {
- break
- }
- }
- }
- obj["do_desc"] = doi_desc //内部端子描述
- //获取外部信息及端子描述
- doi_desc = ""
- outFound := false //是否查找到对应的外部端子
- out_lns := map[string]*node_attr.NLN{}
- for _, ied := range outtoieds {
- for _, acc := range ied.AccessPoint {
- if acc.Server != nil {
- for _, ld := range acc.Server.LDevice {
- if ld.LN0.Inputs != nil {
- for _, extref := range ld.LN0.Inputs.ExtRef {
- if extref.IedName == iedname && extref.DoName == fcda.DoName && extref.LdInst == fcda.LdInst && extref.LnClass == fcda.LnClass && extref.LnInst == fcda.LnInst && extref.Prefix == fcda.Prefix {
- outFound = true
- obj["out_intaddr"] = extref.IntAddr
- obj["out_ied_name"] = ied.Name
- obj["out_ied_desc"] = ied.Desc
- outLnStr := strings.Split(extref.IntAddr, ".")[0]
- outDoName := strings.Split(extref.IntAddr, ".")[1]
- var ln *node_attr.NLN
- if v, h := out_lns[outLnStr]; h {
- ln = v
- } else {
- //查找内部地址指向的Ln
- lnFound := false
- for _, tLd := range acc.Server.LDevice {
- if extref.LnClass == "LLN0" {
- for _, doi := range tLd.LN0.DOI {
- if doi.Name == fcda.DoName {
- doi_desc = doi.Desc
- lnFound = true
- break
- }
- }
- }
- if doi_desc != "" {
- obj["out_do_desc"] = doi_desc
- break
- }
- for _, tLn := range tLd.LN {
- if outLnStr == fmt.Sprintf("%s/%s%s%s", tLd.Inst, tLn.Prefix, tLn.LnClass, tLn.Inst) {
- out_lns[outLnStr] = tLn
- ln = tLn
- lnFound = true
- break
- }
- }
- if lnFound {
- break
- }
- }
- }
- if ln == nil {
- continue
- }
- for _, doi := range ln.DOI {
- if doi.Name == outDoName {
- obj["out_do_desc"] = doi.Desc
- break
- }
- }
- break
- }
- }
- }
- if outFound {
- break
- }
- }
- if outFound {
- break
- }
- }
- if outFound {
- break
- }
- }
- if outFound {
- break
- }
- }
- rowset = append(rowset, obj)
- }
- break
- }
- }
- return rowset, nil
- }
- //获取指定IED的SMV接收块及端子列表
- func (c *ScdNode) GetIedSMVCtrlBlockRevList(scdid int64, iedname string) ([]orm.Params, error) {
- rowset := []orm.Params{}
- scdXmlObj, serr := new(ScdParse).GetScdXmlObjectBySCDID(tools.IsEmpty(scdid))
- if serr != nil {
- return nil, serr
- }
- if scdXmlObj == nil {
- return nil, errors.New("无效的SCD")
- }
- currentIedObj := c.GetIed(scdXmlObj, tools.IsEmpty(scdid), iedname)
- if currentIedObj == nil {
- return rowset, errors.New("无效的IED装置名称")
- }
- fromiedObjs := map[string]interface{}{}
- for _, acc := range currentIedObj.AccessPoint {
- if acc.Server != nil {
- for _, ld := range acc.Server.LDevice {
- if ld.LN0 != nil && ld.LN0.Inputs != nil {
- for _, extref := range ld.LN0.Inputs.ExtRef {
- form_ied_name := extref.IedName
- var tmpFromIed *node_attr.NIED
- if v, h := fromiedObjs[form_ied_name]; h {
- tmpFromIed = v.(*node_attr.NIED)
- } else {
- tmpFromIed = c.GetIed(scdXmlObj, tools.IsEmpty(scdid), form_ied_name)
- }
- if tmpFromIed == nil {
- logger.Logger.Error(fmt.Sprintf("未发现IED装置%s", form_ied_name))
- break
- }
- //获取目标IED的块
- iedBlockList, _ := c.GetIedCtrlBlock(scdid, form_ied_name)
- //logger.Logger.Debug(fmt.Sprintf("=====%s 装置,extref:%+v", form_ied_name, iedBlockList))
- if iedBlockList == nil {
- continue
- }
- smvBlcokList := iedBlockList["SampledValueControl"].([]orm.Params)
- if len(smvBlcokList) == 0 {
- continue
- }
- smvDataSetMap := map[string]int{}
- for _, smvRow := range smvBlcokList {
- smvDataSetMap[tools.IsEmpty(smvRow["attr_dat_set"])] = 1
- }
- found := false
- out_lns := map[string]*node_attr.NLN{}
- for _, fromacc := range tmpFromIed.AccessPoint {
- if fromacc.Server != nil {
- for _, fromld := range fromacc.Server.LDevice {
- if fromld.Inst == extref.LdInst {
- for _, ds := range fromld.LN0.DataSet {
- _, h := smvDataSetMap[ds.Name]
- if !h {
- continue
- }
- for _, fromfcda := range ds.FCDA {
- if extref.LnClass == fromfcda.LnClass && extref.Prefix == fromfcda.Prefix && extref.LnInst == fromfcda.LnInst && extref.DoName == fromfcda.DoName {
- obj := orm.Params{
- "int_addr": extref.IntAddr,
- "out_do_name": fromfcda.DoName,
- "out_ied_name": tmpFromIed.Name,
- "out_ied_desc": tmpFromIed.Desc,
- "out_dataset_name": ds.Name,
- "out_dataset_desc": ds.Desc,
- "out_smv_ctrl_name": "",
- "out_smv_ctrl_address": "",
- }
- //获取内部信号描述
- doi_desc := ""
- outLnStr := strings.Split(extref.IntAddr, ".")[0]
- outDoName := strings.Split(extref.IntAddr, ".")[1]
- var ln *node_attr.NLN
- if v, h := out_lns[outLnStr]; h {
- ln = v
- } else {
- //查找内部地址指向的Ln
- lnFound := false
- for _, tLd := range acc.Server.LDevice {
- if extref.LnClass == "LLN0" {
- for _, doi := range tLd.LN0.DOI {
- if doi.Name == outDoName {
- doi_desc = doi.Desc
- lnFound = true
- break
- }
- }
- }
- if doi_desc != "" {
- obj["do_desc"] = doi_desc
- break
- }
- for _, tLn := range tLd.LN {
- if outLnStr == fmt.Sprintf("%s/%s%s%s", tLd.Inst, tLn.Prefix, tLn.LnClass, tLn.Inst) {
- out_lns[outLnStr] = tLn
- ln = tLn
- lnFound = true
- break
- }
- }
- if lnFound {
- break
- }
- }
- }
- if ln != nil {
- for _, doi := range ln.DOI {
- if doi.Name == outDoName {
- obj["do_desc"] = doi.Desc
- break
- }
- }
- }
- //获取输入块信息
- for _, smvRow := range smvBlcokList {
- if tools.IsEmpty(smvRow["attr_dat_set"]) == ds.Name {
- obj["out_smv_ctrl_name"] = smvRow["attr_name"]
- obj["out_smv_ctrl_address"] = smvRow["address"]
- break
- }
- }
- doi_desc = ""
- if fromfcda.LnClass == "LLN0" {
- for _, doi := range fromld.LN0.DOI {
- if doi.Name == fromfcda.DoName {
- doi_desc = doi.Desc
- break
- }
- }
- } else {
- for _, ln := range fromld.LN {
- if ln.Inst == fromfcda.LnInst && ln.LnClass == fromfcda.LnClass && ln.Prefix == fromfcda.Prefix {
- for _, doi := range ln.DOI {
- if doi.Name == fromfcda.DoName {
- doi_desc = doi.Desc
- break
- }
- }
- }
- if doi_desc != "" {
- break
- }
- }
- }
- if doi_desc != "" {
- obj["out_do_desc"] = doi_desc
- }
- rowset = append(rowset, obj)
- }
- }
- }
- found = true
- break
- }
- }
- if found {
- break
- }
- }
- }
- }
- }
- }
- }
- }
- return rowset, nil
- }
- //获取指定IED的goose控制块发送端子列表
- func (c *ScdNode) GetIedGooseCtrlBlockSendFcdaList(scdid int64, iedname string, ctrl_id int64) ([]orm.Params, error) {
- rowset := []orm.Params{}
- v_scdcache, _ := GlobalNodeMap.Load(scdid)
- if v_scdcache == nil {
- return nil, errors.New("无效的SCD")
- }
- scdCacheObj := v_scdcache.(map[int64]NodeCacheMap)
- ctrlObj1 := scdCacheObj[ctrl_id]
- if ctrlObj1.ObjAddr == nil {
- return rowset, errors.New("无效的控制块ID")
- }
- //获取当前IED的输出IED
- relIed, err := c.GetIedRelations(map[string]interface{}{"scd_id": scdid, "ied_name": iedname})
- if relIed == nil {
- return nil, err
- }
- ieds0 := relIed[iedname].(orm.Params)
- if ieds0 == nil {
- return rowset, nil
- }
- ieds := ieds0["list"].([]orm.Params)
- outtoieds := []*node_attr.NIED{}
- //获取当前IED输出的目标IED,即ref_type为0的.结果中需要返回输出IED中对应的端子信息
- for _, r := range ieds {
- if tools.IsEmpty(r["ref_type"]) == "0" {
- iedid, _ := strconv.ParseInt(tools.IsEmpty(r["ref_ied_id"]), 10, 64)
- tmpIedObj := scdCacheObj[iedid].ObjAddr.(*node_attr.NIED)
- if tmpIedObj.Name == iedname {
- continue
- }
- outtoieds = append(outtoieds, tmpIedObj)
- }
- }
- if len(outtoieds) == 0 {
- return rowset, nil
- }
- ctrlObj := ctrlObj1.ObjAddr.(*node_attr.NGSEControl)
- datasetname := ctrlObj.DatSet
- ln0 := scdCacheObj[ctrlObj1.ParentNodeId].ObjAddr.(*node_attr.NLN0)
- ldid := scdCacheObj[ctrlObj1.ParentNodeId].ParentNodeId
- ld := scdCacheObj[ldid].ObjAddr.(*node_attr.NLDevice)
- for _, ds := range ln0.DataSet {
- if ds.Name == datasetname {
- for _, fcda := range ds.FCDA {
- obj := orm.Params{
- "do_desc": "",
- "do_name": fcda.DoName,
- "ld_inst": fcda.LdInst,
- "ln_inst": fcda.LnInst,
- "ln_class": fcda.LnClass,
- "prefix": fcda.Prefix,
- "out_intaddr": "",
- "out_ied_name": "",
- "out_ied_desc": "",
- "out_do_desc": "",
- }
- doi_desc := ""
- if fcda.LnClass == "LLN0" {
- for _, doi := range ld.LN0.DOI {
- if doi.Name == fcda.DoName {
- doi_desc = doi.Desc
- break
- }
- }
- } else {
- for _, ln := range ld.LN {
- if ln.Inst == fcda.LnInst && ln.LnClass == fcda.LnClass && ln.Prefix == fcda.Prefix {
- for _, doi := range ln.DOI {
- if doi.Name == fcda.DoName {
- doi_desc = doi.Desc
- break
- }
- }
- }
- if doi_desc != "" {
- break
- }
- }
- }
- obj["do_desc"] = doi_desc //内部端子描述
- //获取外部信息及端子描述
- doi_desc = ""
- outFound := false //是否查找到对应的外部端子
- out_lns := map[string]*node_attr.NLN{}
- for _, ied := range outtoieds {
- for _, acc := range ied.AccessPoint {
- if acc.Server != nil {
- for _, ld := range acc.Server.LDevice {
- if ld.LN0.Inputs != nil {
- for _, extref := range ld.LN0.Inputs.ExtRef {
- if extref.IedName == iedname && extref.DoName == fcda.DoName && extref.LdInst == fcda.LdInst && extref.LnClass == fcda.LnClass && extref.LnInst == fcda.LnInst && extref.Prefix == fcda.Prefix {
- outFound = true
- obj["out_intaddr"] = extref.IntAddr
- obj["out_ied_name"] = ied.Name
- obj["out_ied_desc"] = ied.Desc
- outLnStr := strings.Split(extref.IntAddr, ".")[0]
- outDoName := strings.Split(extref.IntAddr, ".")[1]
- var ln *node_attr.NLN
- if v, h := out_lns[outLnStr]; h {
- ln = v
- } else {
- //查找内部地址指向的Ln
- lnFound := false
- for _, tLd := range acc.Server.LDevice {
- if extref.LnClass == "LLN0" {
- for _, doi := range tLd.LN0.DOI {
- if doi.Name == fcda.DoName {
- doi_desc = doi.Desc
- lnFound = true
- break
- }
- }
- }
- if doi_desc != "" {
- obj["out_do_desc"] = doi_desc
- break
- }
- for _, tLn := range tLd.LN {
- if outLnStr == fmt.Sprintf("%s/%s%s%s", tLd.Inst, tLn.Prefix, tLn.LnClass, tLn.Inst) {
- out_lns[outLnStr] = tLn
- ln = tLn
- lnFound = true
- break
- }
- }
- if lnFound {
- break
- }
- }
- }
- if ln == nil {
- continue
- }
- for _, doi := range ln.DOI {
- if doi.Name == outDoName {
- obj["out_do_desc"] = doi.Desc
- break
- }
- }
- break
- }
- }
- }
- if outFound {
- break
- }
- }
- if outFound {
- break
- }
- }
- if outFound {
- break
- }
- }
- if outFound {
- break
- }
- }
- rowset = append(rowset, obj)
- }
- break
- }
- }
- return rowset, nil
- }
- //获取指定IED的goose接收块及端子列表
- func (c *ScdNode) GetIedGooseCtrlBlockRevList(scdid int64, iedname string) ([]orm.Params, error) {
- rowset := []orm.Params{}
- scdXmlObj, serr := new(ScdParse).GetScdXmlObjectBySCDID(tools.IsEmpty(scdid))
- if serr != nil {
- return nil, serr
- }
- if scdXmlObj == nil {
- return nil, errors.New("无效的SCD")
- }
- currentIedObj := c.GetIed(scdXmlObj, tools.IsEmpty(scdid), iedname)
- if currentIedObj == nil {
- return rowset, errors.New("无效的IED装置名称")
- }
- fromiedObjs := map[string]interface{}{}
- for _, acc := range currentIedObj.AccessPoint {
- if acc.Server != nil {
- for _, ld := range acc.Server.LDevice {
- if ld.LN0 != nil && ld.LN0.Inputs != nil {
- for _, extref := range ld.LN0.Inputs.ExtRef {
- form_ied_name := extref.IedName
- var tmpFromIed *node_attr.NIED
- if v, h := fromiedObjs[form_ied_name]; h {
- tmpFromIed = v.(*node_attr.NIED)
- } else {
- tmpFromIed = c.GetIed(scdXmlObj, tools.IsEmpty(scdid), form_ied_name)
- }
- if tmpFromIed == nil {
- logger.Logger.Error(fmt.Sprintf("未发现IED装置%s", form_ied_name))
- break
- }
- //获取目标IED的块
- iedBlockList, _ := c.GetIedCtrlBlock(scdid, form_ied_name)
- //logger.Logger.Debug(fmt.Sprintf("=====%s 装置,iedBlockList:%+v", form_ied_name, iedBlockList))
- if iedBlockList == nil {
- continue
- }
- smvBlcokList := iedBlockList["GSEControl"].([]orm.Params)
- if len(smvBlcokList) == 0 {
- continue
- }
- gooseDataSetMap := map[string]int{}
- for _, smvRow := range smvBlcokList {
- gooseDataSetMap[tools.IsEmpty(smvRow["attr_dat_set"])] = 1
- }
- found := false
- out_lns := map[string]*node_attr.NLN{}
- for _, fromacc := range tmpFromIed.AccessPoint {
- if fromacc.Server != nil {
- for _, fromld := range fromacc.Server.LDevice {
- if fromld.Inst == extref.LdInst {
- for _, ds := range fromld.LN0.DataSet {
- _, h := gooseDataSetMap[ds.Name]
- if !h {
- continue
- }
- for _, fromfcda := range ds.FCDA {
- if extref.LnClass == fromfcda.LnClass && extref.Prefix == fromfcda.Prefix && extref.LnInst == fromfcda.LnInst && extref.DoName == fromfcda.DoName {
- obj := orm.Params{
- "int_addr": extref.IntAddr,
- "out_do_name": fromfcda.DoName,
- "out_ied_name": tmpFromIed.Name,
- "out_ied_desc": tmpFromIed.Desc,
- "out_dataset_name": ds.Name,
- "out_dataset_desc": ds.Desc,
- "out_gse_ctrl_name": "",
- "out_gse_ctrl_address": "",
- }
- //获取内部信号描述
- doi_desc := ""
- outLnStr := strings.Split(extref.IntAddr, ".")[0]
- outDoName := strings.Split(extref.IntAddr, ".")[1]
- var ln *node_attr.NLN
- if v, h := out_lns[outLnStr]; h {
- ln = v
- } else {
- //查找内部地址指向的Ln
- lnFound := false
- for _, tLd := range acc.Server.LDevice {
- if extref.LnClass == "LLN0" {
- for _, doi := range tLd.LN0.DOI {
- if doi.Name == outDoName {
- doi_desc = doi.Desc
- lnFound = true
- break
- }
- }
- }
- if doi_desc != "" {
- obj["do_desc"] = doi_desc
- break
- }
- for _, tLn := range tLd.LN {
- if outLnStr == fmt.Sprintf("%s/%s%s%s", tLd.Inst, tLn.Prefix, tLn.LnClass, tLn.Inst) {
- out_lns[outLnStr] = tLn
- ln = tLn
- lnFound = true
- break
- }
- }
- if lnFound {
- break
- }
- }
- }
- if ln != nil {
- for _, doi := range ln.DOI {
- if doi.Name == outDoName {
- obj["do_desc"] = doi.Desc
- break
- }
- }
- }
- //获取输入块信息
- for _, smvRow := range smvBlcokList {
- if tools.IsEmpty(smvRow["attr_dat_set"]) == ds.Name {
- obj["out_gse_ctrl_name"] = smvRow["attr_name"]
- obj["out_gse_ctrl_address"] = smvRow["address"]
- break
- }
- }
- doi_desc = ""
- if fromfcda.LnClass == "LLN0" {
- for _, doi := range fromld.LN0.DOI {
- if doi.Name == fromfcda.DoName {
- doi_desc = doi.Desc
- break
- }
- }
- } else {
- for _, ln := range fromld.LN {
- if ln.Inst == fromfcda.LnInst && ln.LnClass == fromfcda.LnClass && ln.Prefix == fromfcda.Prefix {
- for _, doi := range ln.DOI {
- if doi.Name == fromfcda.DoName {
- doi_desc = doi.Desc
- break
- }
- }
- }
- if doi_desc != "" {
- break
- }
- }
- }
- if doi_desc != "" {
- obj["out_do_desc"] = doi_desc
- }
- rowset = append(rowset, obj)
- }
- }
- }
- found = true
- break
- }
- }
- if found {
- break
- }
- }
- }
- }
- }
- }
- }
- }
- return rowset, nil
- }
- //生成指定scd下的ied输入输出关系数据
- func (c *ScdNode) MakeIedRelations(scdid int64, iedname ...string) error {
- db := orm.NewOrm()
- rowset := []orm.Params{}
- v_iedname := ""
- if len(iedname) > 0 {
- v_iedname = iedname[0]
- }
- var err error
- sql := ""
- if v_iedname != "" {
- sql = "select node_id, attr_name from t_scd_ied_attrs where scd_id=? and attr_name=?"
- _, err = db.Raw(sql, scdid, v_iedname).Values(&rowset)
- } else {
- sql = "select node_id, attr_name from t_scd_ied_attrs where scd_id=?"
- _, err = db.Raw(sql, scdid).Values(&rowset)
- }
- sqllog := fmt.Sprintf("SQL:%s,参数:%d,%s", sql, scdid, v_iedname)
- 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 err
- }
- new(SystemLog).Success(enum.AuditType_scd_show, enum.LogType_Query, enum.OptEventType_Bus, enum.OptEventLevel_Low, sqllog, c.GetUserInfo())
- if len(rowset) == 0 {
- return errors.New("无效的SCD文件编号")
- }
- //wg := sync.WaitGroup{}
- //wg.Add(len(rowset))
- for _, row := range rowset {
- ied_name := tools.IsEmpty(row["attr_name"])
- iedid := tools.IsEmpty(row["node_id"])
- //go func(iedid, ied_name string) {
- // defer wg.Done()
- // time.Sleep(100 * time.Millisecond)
- //db0 := orm.NewOrm()
- //ref为1时,查询的是该IED的输入关联IED
- //ref为0时,查询的是该iED的输出关联IED
- sql := `insert into t_ied_relation(scd_id,ied_id,ied_name,ref_type,ref_ied_name) select ` + fmt.Sprintf("%d", scdid) + ` scdid, ` + iedid + ` iedid, '` + ied_name + `' iedname, '1' ref, t1.attr_ied_name ied_name from t_scd_node_scl t,t_scd_extref_attrs t1 where t.id =t1.node_id and t.scd_id=? and t1.scd_id=? and t.ied_name=? and t.node_name='ExtRef' GROUP BY t1.attr_ied_name
- union
- select ` + fmt.Sprintf("%d", scdid) + ` scdid, ` + iedid + ` iedid, '` + ied_name + `' iedname,'0' ref, t.ied_name from t_scd_extref_attrs t1,t_scd_node_scl t where t.id=t1.node_id and t.scd_id=? and t1.scd_id=? and t1.attr_ied_name=? GROUP BY t.ied_name`
- _, err = db.Raw(sql, scdid, scdid, ied_name, scdid, scdid, ied_name).Exec()
- sqllog := fmt.Sprintf("SQL:%s,参数:%+v", sql, []interface{}{scdid, scdid, ied_name, scdid, scdid, ied_name})
- if err != nil {
- logger.Logger.Error(err, sqllog)
- new(SystemLog).Fail(enum.AuditType_scd_show, enum.LogType_Insert, enum.OptEventType_Bus, enum.OptEventLevel_Hight, sqllog, c.GetUserInfo())
- return err
- }
- new(SystemLog).Success(enum.AuditType_scd_show, enum.LogType_Insert, enum.OptEventType_Bus, enum.OptEventLevel_Hight, sqllog, c.GetUserInfo())
- //}(ied_id, ied_name)
- }
- //wg.Wait()
- return nil
- }
- //获取指定IEd节点的控制块关系
- func (c *ScdNode) GetIedBlockRelations(scdid int64, ied_name string, forcerefresh ...bool) ([]orm.Params, error) {
- if ied_name == "" {
- return nil, errors.New("IEDname不能同时为空")
- }
- if scdid == 0 {
- return nil, errors.New("scd编号不能为空")
- }
- cacheKey := fmt.Sprintf("GetIedBlockRelations_%d_%s", scdid, ied_name)
- if v, h := global.GoCahce.Get(cacheKey); h {
- return v.([]orm.Params), nil
- }
- scdXmlObj, serr := new(ScdParse).GetScdXmlObjectBySCDID(tools.IsEmpty(scdid))
- if serr != nil {
- return nil, serr
- }
- if scdXmlObj == nil {
- return nil, errors.New("无效的SCD")
- }
- queryRowset := []orm.Params{}
- var masterIed = c.GetIed(scdXmlObj, tools.IsEmpty(scdid), ied_name)
- if masterIed == nil {
- return nil, errors.New("无效的IED装备名称")
- }
- extreflist, _ := c.GetIedInputsRelations(map[string]interface{}{"ied_name": masterIed.Name, "scd_id": scdid})
- if extreflist == nil || len(extreflist) == 0 {
- return nil, nil
- }
- //缓存每个块关联的详情
- cachebBlockDetail := map[string][]orm.Params{}
- //获取当前IED的控制块,获取输入的IED及块
- inputBlock := map[string]orm.Params{}
- for _, row := range extreflist {
- //"attr_ld_inst","attr_prefix","attr_ln_class","attr_ln_inst","attr_do_name","attr_da_name"
- tmpIedName := tools.IsEmpty(row["ied_name"])
- if tmpIedName == masterIed.Name {
- continue
- }
- if tools.IsEmpty(row["inout_type"]) == "out" {
- //过滤该ied中的输出ExtRef
- continue
- }
- extrefid := row["node_id"]
- ldInst := tools.IsEmpty(row["attr_ld_inst"])
- prefix := tools.IsEmpty(row["attr_prefix"])
- lnClass := tools.IsEmpty(row["attr_ln_class"])
- lnInst := tools.IsEmpty(row["attr_ln_inst"])
- doName := tools.IsEmpty(row["attr_do_name"])
- //daName := tools.IsEmpty(row["attr_da_name"])
- inout := tools.IsEmpty(row["inout_type"]) //in:输入当前IED out:输出到其他IED
- inIed := c.GetIed(scdXmlObj, tools.IsEmpty(scdid), tmpIedName)
- if inIed.AccessPoint == nil {
- continue
- }
- for _, t1 := range inIed.AccessPoint {
- if t1.Server == nil {
- continue
- }
- for _, t2 := range t1.Server.LDevice {
- if t2.Inst == ldInst {
- for _, dataset := range t2.LN0.DataSet {
- foundCnt := 0
- isfound := false
- obj := orm.Params{"scd_id": scdid, "master_ied_id": masterIed.NodeId, "master_ied_name": masterIed.Name, "ref_type": "", "inputs_cnt": 0, "out_ld_id": "", "out_ld_inst": "", "out_id_desc": "", "ld_id": "", "ld_inst": "", "id_desc": "", "ctrl_id": "", "ctrl_type": "", "ctrl_name": "", "datset_id": "", "datset_desc": "", "datset_name": ""}
- for _, fcda := range dataset.FCDA {
- if prefix == fcda.Prefix && doName == fcda.DoName && fcda.LdInst == ldInst && fcda.LnInst == lnInst && fcda.LnClass == lnClass {
- if foundCnt == 0 {
- obj["ld_id"] = t2.NodeId
- obj["ld_inst"] = t2.Inst
- obj["ld_desc"] = t2.Desc
- obj["datset_id"] = dataset.NodeId
- obj["datset_desc"] = dataset.Desc
- obj["datset_name"] = dataset.Name
- obj["fcda_id"] = fcda.NodeId
- obj["extref_id"] = extrefid
- }
- foundCnt = foundCnt + 1 //计算关联的端子数量
- isfound = true
- break
- }
- }
- obj["inputs_cnt"] = foundCnt
- if isfound {
- datasetName := tools.IsEmpty(obj["datset_name"])
- //获取控制块信息
- for _, gse := range t2.LN0.GSEControl {
- if gse.DatSet == datasetName {
- obj["ctrl_id"] = gse.NodeId
- obj["ctrl_type"] = gse.Type
- obj["ctrl_name"] = gse.Name
- }
- }
- for _, smv := range t2.LN0.SampledValueControl {
- if smv.DatSet == datasetName {
- obj["ctrl_id"] = smv.NodeId
- obj["ctrl_type"] = "smv"
- obj["ctrl_name"] = smv.Name
- }
- }
- obj["ref_type"] = "1"
- obj["inout_type"] = inout
- obj["source_ied_id"] = masterIed.NodeId
- obj["source_ied_name"] = masterIed.Name
- obj["target_ied_id"] = inIed.NodeId
- obj["target_ied_name"] = tmpIedName
- obj["out_ld_id"] = t2.NodeId
- obj["out_ld_desc"] = t2.Desc
- obj["out_ld_inst"] = t2.Inst
- key := fmt.Sprintf("%d%s%s%d", scdid, masterIed.Name, tmpIedName, obj["ctrl_id"])
- if v, h := inputBlock[key]; h {
- v1, _ := strconv.Atoi(tools.IsEmpty(v["inputs_cnt"]))
- v["inputs_cnt"] = v1 + 1
- inputBlock[key] = v
- cachebBlockDetail[key] = append(cachebBlockDetail[key], obj)
- } else {
- //queryRowset = append(queryRowset, obj)
- inputBlock[key] = obj
- cachebBlockDetail[key] = []orm.Params{obj}
- }
- }
- }
- }
- }
- }
- }
- for _, r := range inputBlock {
- queryRowset = append(queryRowset, r)
- }
- //获取关联IED的控制块,获取输出的IED及块
- inputBlock = map[string]orm.Params{}
- relIedlist, _ := c.GetIedRelations(map[string]interface{}{"scd_id": scdid, "ied_name": masterIed.Name})
- if relIedlist != nil {
- relIedlist = relIedlist[masterIed.Name].(orm.Params)
- vList := relIedlist["list"].([]orm.Params)
- for _, refIed := range vList {
- if refIed["ref_ied_name"] == nil {
- continue
- }
- if refIed["ref_type"] == "1" {
- //输入IED
- continue
- }
- tmpIedName := refIed["ref_ied_name"].(string)
- extreflist, _ := c.GetIedInputsRelations(map[string]interface{}{"ied_name": tmpIedName, "scd_id": scdid})
- if extreflist == nil || len(extreflist) == 0 {
- continue
- }
- for _, extref := range extreflist {
- if tools.IsEmpty(extref["inout_type"]) == "out" {
- //过滤该ied中的输出ExtRef
- continue
- }
- toIedName := tools.IsEmpty(extref["ied_name"])
- if toIedName != masterIed.Name {
- //过虑输入ied非当前查询ied的extref
- continue
- }
- extrefid := extref["node_id"]
- ldInst := tools.IsEmpty(extref["attr_ld_inst"])
- prefix := tools.IsEmpty(extref["attr_prefix"])
- lnClass := tools.IsEmpty(extref["attr_ln_class"])
- lnInst := tools.IsEmpty(extref["attr_ln_inst"])
- doName := tools.IsEmpty(extref["attr_do_name"])
- //daName := tools.IsEmpty(row["attr_da_name"])
- inout := tools.IsEmpty(extref["inout_type"]) //in:输入当前IED out:输出到其他IED
- inIed := masterIed //c.GetIed(scdXmlObj, tools.IsEmpty(scdid), tmpIedName)
- if inIed.AccessPoint == nil {
- continue
- }
- for _, t1 := range inIed.AccessPoint {
- if t1.Server == nil {
- continue
- }
- for _, t2 := range t1.Server.LDevice {
- //logger.Logger.Debug(fmt.Sprintf("%s LDevice%+v:", tmpIedName, t2.Desc))
- for _, dataset := range t2.LN0.DataSet {
- foundCnt := 0
- isfound := false
- obj := orm.Params{"scd_id": scdid, "master_ied_id": masterIed.NodeId, "master_ied_name": masterIed.Name, "ref_type": "", "inputs_cnt": 0, "out_ld_id": "", "out_ld_inst": "", "out_id_desc": "", "ld_id": "", "ld_inst": "", "id_desc": "", "ctrl_id": "", "ctrl_type": "", "ctrl_name": "", "datset_id": "", "datset_desc": "", "datset_name": ""}
- for _, fcda := range dataset.FCDA {
- if prefix == fcda.Prefix && doName == fcda.DoName && fcda.LdInst == ldInst && fcda.LnInst == lnInst && fcda.LnClass == lnClass {
- if foundCnt == 0 {
- obj["ld_id"] = t2.NodeId
- obj["ld_inst"] = t2.Inst
- obj["ld_desc"] = t2.Desc
- obj["datset_id"] = dataset.NodeId
- obj["datset_desc"] = dataset.Desc
- obj["datset_name"] = dataset.Name
- obj["fcda_id"] = fcda.NodeId
- obj["extref_id"] = extrefid
- }
- foundCnt = foundCnt + 1 //计算关联的端子数量
- isfound = true
- break
- }
- }
- obj["inputs_cnt"] = foundCnt
- if isfound {
- datasetName := tools.IsEmpty(obj["datset_name"])
- //获取控制块信息
- for _, gse := range t2.LN0.GSEControl {
- if gse.DatSet == datasetName {
- obj["ctrl_id"] = gse.NodeId
- obj["ctrl_type"] = gse.Type
- obj["ctrl_name"] = gse.Name
- }
- }
- for _, smv := range t2.LN0.SampledValueControl {
- if smv.DatSet == datasetName {
- obj["ctrl_id"] = smv.NodeId
- obj["ctrl_type"] = "smv"
- obj["ctrl_name"] = smv.Name
- }
- }
- obj["ref_type"] = "0"
- obj["source_ied_id"] = inIed.NodeId
- obj["source_ied_name"] = tmpIedName
- obj["target_ied_id"] = masterIed.NodeId
- obj["target_ied_name"] = masterIed.Name
- obj["out_ld_id"] = t2.NodeId
- obj["out_ld_desc"] = t2.Desc
- obj["out_ld_inst"] = t2.Inst
- obj["inout_type"] = inout
- key := fmt.Sprintf("%d%s%s%d", scdid, masterIed.Name, tmpIedName, obj["ctrl_id"])
- if v, h := inputBlock[key]; h {
- v1, _ := strconv.Atoi(tools.IsEmpty(v["inputs_cnt"]))
- v["inputs_cnt"] = v1 + 1
- inputBlock[key] = v
- cachebBlockDetail[key] = append(cachebBlockDetail[key], obj)
- } else {
- //queryRowset = append(queryRowset, obj)
- inputBlock[key] = obj
- cachebBlockDetail[key] = []orm.Params{obj}
- }
- }
- }
- }
- }
- }
- }
- }
- for _, r := range inputBlock {
- queryRowset = append(queryRowset, r)
- }
- mqtt.PublishMessage("/jujutong/scd_check_tools/iedblockrelations/"+tools.IsEmpty(scdid)+"/"+ied_name, `{"ied_name":"`+ied_name+`","code":1}`)
- //缓存块关联详情
- global.GoCahce.Set(fmt.Sprintf("cachebBlockDetail_%d", scdid), cachebBlockDetail, -1)
- return queryRowset, nil
- }
- //获取指定IED节点的虚端子关系
- func (c *ScdNode) GetIedInputsRelations(param map[string]interface{}) ([]orm.Params, error) {
- iedid := tools.IsEmpty(param["ied_id"])
- ied_name := tools.IsEmpty(param["ied_name"])
- if iedid == "" && ied_name == "" {
- return nil, errors.New("IED编号和name不能同时为空")
- }
- scdid := tools.IsEmpty(param["scd_id"])
- if scdid == "" {
- return nil, errors.New("scd编号不能为空")
- }
- cacheKey1 := "GetIedInputsRelations_" + scdid + ied_name
- if v, h := global.GoCahce.Get(cacheKey1); h {
- return v.([]orm.Params), nil
- }
- scdobj, serr := new(ScdParse).GetScdXmlObjectBySCDID(scdid)
- if serr != nil {
- return nil, serr
- }
- if scdobj == nil {
- return nil, errors.New("该scd还未解析或解析未完成!")
- }
- if iedid != "" {
- has := false
- for _, item := range scdobj.IED {
- if tools.IsEmpty(item.NodeId) == iedid {
- has = true
- ied_name = item.Name
- break
- }
- }
- if !has {
- return nil, errors.New("无效的IED编号")
- }
- }
- attrsrows := []orm.Params{} //input输入输出虚端子关系
- for _, item := range scdobj.IED {
- for _, accpointitem := range item.AccessPoint {
- if accpointitem.Server == nil {
- continue
- }
- for _, lditem := range accpointitem.Server.LDevice {
- if lditem.LN0.Inputs == nil {
- continue
- }
- no := 0
- for _, extrefitem := range lditem.LN0.Inputs.ExtRef {
- no = no + 1
- inout := ""
- tmpIedName := ""
- doinDesc := ""
- dooutDesc := ""
- if item.Name == ied_name {
- inout = "in"
- tmpIedName = extrefitem.IedName
- //获取内部地址的描述
- _, _, doinDesc = c.GetIntAddrDesc(item, extrefitem.IntAddr)
- fcda_addr := fmt.Sprintf("%s/%s%s%s.%s", extrefitem.LdInst, extrefitem.Prefix, extrefitem.LnClass, extrefitem.LnInst, extrefitem.DoName)
- if extrefitem.DaName != "" {
- fcda_addr = fcda_addr + "." + extrefitem.DaName
- }
- extrefIed := c.GetIed(scdobj, scdid, tmpIedName)
- _, _, dooutDesc = c.GetIntAddrDesc(extrefIed, fcda_addr)
- } else if extrefitem.IedName == ied_name {
- inout = "out"
- tmpIedName = item.Name
- _, _, doinDesc = c.GetIntAddrDesc(item, extrefitem.IntAddr)
- //获取fcda的描述
- fcda_addr := fmt.Sprintf("%s/%s%s%s.%s", extrefitem.LdInst, extrefitem.Prefix, extrefitem.LnClass, extrefitem.LnInst, extrefitem.DoName)
- if extrefitem.DaName != "" {
- fcda_addr = fcda_addr + "." + extrefitem.DaName
- }
- mIed := c.GetIed(scdobj, scdid, ied_name)
- _, _, dooutDesc = c.GetIntAddrDesc(mIed, fcda_addr)
- } else {
- continue
- }
- v_o := orm.Params{
- "no": no,
- "inout_type": inout,
- "ied_name": tmpIedName,
- "node_id": extrefitem.NodeId,
- "attr_ld_inst": extrefitem.LdInst,
- "attr_prefix": extrefitem.Prefix,
- "attr_ln_class": extrefitem.LnClass,
- "attr_ln_inst": extrefitem.LnInst,
- "attr_do_name": extrefitem.DoName,
- "attr_da_name": extrefitem.DaName,
- "attr_int_addr": extrefitem.IntAddr,
- "line_no": extrefitem.Lineno,
- "do_target_desc": doinDesc,
- "do_source_desc": dooutDesc,
- }
- attrsrows = append(attrsrows, v_o)
- }
- }
- }
- }
- //logger.Logger.Debug(fmt.Sprintf("%+v", attrsrows))
- global.GoCahce.Set(cacheKey1, attrsrows, -1)
- return attrsrows, nil
- }
- //获取指定IED节点及控制块ID的虚端子关系
- func (c *ScdNode) GetIedCtrlInputsRelations(param map[string]interface{}) ([]orm.Params, error) {
- m_ied_name := tools.IsEmpty(param["m_ied_name"])
- if m_ied_name == "" {
- return nil, errors.New("源IED name不能为空")
- }
- s_ied_name := tools.IsEmpty(param["s_ied_name"])
- if s_ied_name == "" {
- return nil, errors.New("目标IED name不能为空")
- }
- scdid := tools.IsEmpty(param["scd_id"])
- if scdid == "" {
- return nil, errors.New("scd编号不能为空")
- }
- scdidint64, _ := strconv.ParseInt(scdid, 10, 64)
- //缓存块关联详情
- cachebBlockDetail, _ := global.GoCahce.Get(fmt.Sprintf("cachebBlockDetail_%s", scdid))
- if cachebBlockDetail == nil {
- return nil, errors.New("未查询到数据")
- }
- scdXmlObj, serr := new(ScdParse).GetScdXmlObjectBySCDID(scdid)
- if serr != nil {
- return nil, serr
- }
- if scdXmlObj == nil {
- return nil, errors.New("无效的SCD")
- }
- m_ctrlid := tools.IsEmpty(param["m_ctrlid"])
- s_ctrlid := tools.IsEmpty(param["s_ctrlid"])
- key := fmt.Sprintf("%s%s%s%s%s", scdid, m_ied_name, s_ied_name, m_ctrlid, s_ctrlid)
- cachebBlockDetailMap := cachebBlockDetail.(map[string][]orm.Params)
- //logger.Logger.Debug(fmt.Sprintf("获取指定IED节点及控制块ID的虚端子关系:%s\n%+v", key, cachebBlockDetailMap))
- attrsrows := cachebBlockDetailMap[key]
- //返回数据:id,fcda_id as node_id,from_doi_desc,from_ied,from_ln_desc,to_doi_desc,to_ied,to_ln_desc,attr_ld_inst,attr_ln_class,attr_ln_inst,attr_prefix,attr_ix,attr_int_addr,attr_fc,attr_do_name,attr_da_name
- rowset := []orm.Params{}
- v_scdcache, _ := GlobalNodeMap.Load(scdidint64)
- if v_scdcache == nil {
- return nil, errors.New("无效的SCD")
- }
- cacheNodeList := v_scdcache.(map[int64]NodeCacheMap)
- mIed := new(ScdNode).GetIed(scdXmlObj, scdid, m_ied_name)
- sIed := new(ScdNode).GetIed(scdXmlObj, scdid, s_ied_name)
- for _, row := range attrsrows {
- obj := orm.Params{}
- ln_desc := ""
- doi_desc := ""
- extrefid := tools.IsEmpty(row["extref_id"])
- fcdaid := tools.IsEmpty(row["fcda_id"])
- target_ied_name := tools.IsEmpty(row["target_ied_name"])
- master_ied_name := tools.IsEmpty(row["master_ied_name"])
- if m_ctrlid != "" && master_ied_name == m_ied_name {
- fcdaidint64, _ := strconv.ParseInt(fcdaid, 10, 64)
- //主IED向外输出,根据主IED的fcda查找from_doi等信息
- nodeInfo := cacheNodeList[fcdaidint64]
- if nodeInfo.ObjAddr != nil {
- fcda := nodeInfo.ObjAddr.(*node_attr.NFCDA)
- //logger.Logger.Debug(fmt.Sprintf("fcda %s info:%+v", fcdaid, fcda))
- obj["node_id"] = fcda.NodeId
- obj["attr_ld_inst"] = fcda.LdInst
- obj["attr_ln_class"] = fcda.LnClass
- obj["attr_ln_inst"] = fcda.LnInst
- obj["attr_prefix"] = fcda.Prefix
- obj["attr_ix"] = fcda.Ix
- obj["attr_fc"] = fcda.Fc
- obj["attr_do_name"] = fcda.DoName
- obj["attr_da_name"] = fcda.DaName
- var ld *node_attr.NLDevice
- ld, ln_desc, doi_desc = c.GetFcdaDesc(mIed, fcda)
- if ld != nil {
- obj["attr_ld_desc"] = ld.Desc
- }
- /*
- for _, ied := range mIed.AccessPoint {
- if ied.Server != nil {
- for _, ld := range ied.Server.LDevice {
- //logger.Logger.Debug(fmt.Sprintf(" ld========%s=============%s", ld.Inst, fcda.LdInst))
- if ld.Inst == fcda.LdInst {
- obj["attr_ld_desc"] = ld.Desc
- if fcda.LnClass == "LLN0" {
- ln_desc = ld.LN0.Desc
- for _, doi := range ld.LN0.DOI {
- if doi.Name == fcda.DoName {
- doi_desc = doi.Desc
- break
- }
- }
- break
- }
- for _, ln := range ld.LN {
- if ln.Inst == fcda.LnInst && ln.LnClass == fcda.LnClass && ln.Prefix == fcda.Prefix {
- ln_desc = ln.Desc
- //logger.Logger.Debug(fmt.Sprintf(" LN=====================%+v", ln))
- for _, doi := range ln.DOI {
- if doi.Name == fcda.DoName {
- doi_desc = doi.Desc
- break
- }
- }
- }
- if doi_desc != "" {
- break
- }
- }
- }
- if doi_desc != "" {
- break
- }
- }
- }
- if doi_desc != "" {
- break
- }
- }
- */
- }
- obj["from_doi_desc"] = doi_desc
- obj["from_ln_desc"] = ln_desc
- //主IED向外输出,根据接收IED的extref的内部地址查找to_doi等信息
- extrefidint64, _ := strconv.ParseInt(extrefid, 10, 64)
- nodeInfo = cacheNodeList[extrefidint64]
- ln_desc = ""
- doi_desc = ""
- var ld *node_attr.NLDevice
- if nodeInfo.ObjAddr != nil {
- extref := nodeInfo.ObjAddr.(*node_attr.NExtRef)
- //logger.Logger.Debug(fmt.Sprintf("extref %s info:%+v", extrefid, extref))
- obj["attr_int_addr"] = extref.IntAddr
- ld, ln_desc, doi_desc = c.GetIntAddrDesc(sIed, extref.IntAddr)
- if ld != nil {
- obj["to_ld_inst"] = ld.Inst
- obj["to_ld_desc"] = ld.Desc
- }
- /*
- addrparts := strings.Split(extref.IntAddr, "/")
- to_ldinst := addrparts[0]
- //to_lnPri := addrparts[1] //ln标识符,由prefix+lnClass+inst.doname.daname组成
- to_lnPriParts := strings.Split(addrparts[1], ".")
- to_doname := to_lnPriParts[1]
- for _, ied := range sIed.AccessPoint {
- if ied.Server != nil {
- for _, ld := range ied.Server.LDevice {
- if ld.Inst == to_ldinst {
- obj["to_ld_inst"] = ld.Inst
- obj["to_ld_desc"] = ld.Desc
- for _, ln := range ld.LN {
- //logger.Logger.Debug(fmt.Sprintf("to: %s==%s", ln.Prefix+ln.LnClass+ln.Inst, to_lnPriParts[0]))
- if (ln.Prefix + ln.LnClass + ln.Inst) == to_lnPriParts[0] {
- ln_desc = ln.Desc
- for _, doi := range ln.DOI {
- if doi.Name == to_doname {
- doi_desc = doi.Desc
- break
- }
- }
- }
- if doi_desc != "" {
- break
- }
- }
- }
- if doi_desc != "" {
- break
- }
- }
- }
- if doi_desc != "" {
- break
- }
- }
- */
- }
- obj["to_doi_desc"] = doi_desc
- obj["to_ln_desc"] = ln_desc
- rowset = append(rowset, obj)
- }
- if s_ctrlid != "" && target_ied_name == s_ied_name {
- //向主IED输入
- fcdaidint64, _ := strconv.ParseInt(fcdaid, 10, 64)
- //主IED向外输出,根据主IED的fcda查找from_doi等信息
- nodeInfo := cacheNodeList[fcdaidint64]
- if nodeInfo.ObjAddr != nil {
- fcda := nodeInfo.ObjAddr.(*node_attr.NFCDA)
- //logger.Logger.Debug(fmt.Sprintf("fcda %s info:%+v", fcdaid, fcda))
- obj["node_id"] = fcda.NodeId
- obj["attr_ld_inst"] = fcda.LdInst
- obj["attr_ln_class"] = fcda.LnClass
- obj["attr_ln_inst"] = fcda.LnInst
- obj["attr_prefix"] = fcda.Prefix
- obj["attr_ix"] = fcda.Ix
- obj["attr_fc"] = fcda.Fc
- obj["attr_do_name"] = fcda.DoName
- obj["attr_da_name"] = fcda.DaName
- var ld *node_attr.NLDevice
- ld, ln_desc, doi_desc = c.GetFcdaDesc(sIed, fcda)
- if ld != nil {
- obj["attr_ld_desc"] = ld.Desc
- }
- /*
- for _, ied := range sIed.AccessPoint {
- if ied.Server != nil {
- for _, ld := range ied.Server.LDevice {
- //logger.Logger.Debug(fmt.Sprintf(" ld========%s=============%s", ld.Inst, fcda.LdInst))
- if ld.Inst == fcda.LdInst {
- obj["attr_ld_desc"] = ld.Desc
- if fcda.LnClass == "LLN0" {
- ln_desc = ld.LN0.Desc
- for _, doi := range ld.LN0.DOI {
- if doi.Name == fcda.DoName {
- doi_desc = doi.Desc
- break
- }
- }
- break
- }
- for _, ln := range ld.LN {
- if ln.Inst == fcda.LnInst && ln.LnClass == fcda.LnClass && ln.Prefix == fcda.Prefix {
- ln_desc = ln.Desc
- //logger.Logger.Debug(fmt.Sprintf(" LN=====================%+v", ln))
- for _, doi := range ln.DOI {
- if doi.Name == fcda.DoName {
- doi_desc = doi.Desc
- break
- }
- }
- }
- if doi_desc != "" {
- break
- }
- }
- }
- if doi_desc != "" {
- break
- }
- }
- }
- if doi_desc != "" {
- break
- }
- }
- */
- }
- obj["from_doi_desc"] = doi_desc
- obj["from_ln_desc"] = ln_desc
- //主IED向外输出,根据接收IED的extref的内部地址查找to_doi等信息
- extrefidint64, _ := strconv.ParseInt(extrefid, 10, 64)
- nodeInfo = cacheNodeList[extrefidint64]
- ln_desc = ""
- doi_desc = ""
- var ld *node_attr.NLDevice
- if nodeInfo.ObjAddr != nil {
- extref := nodeInfo.ObjAddr.(*node_attr.NExtRef)
- //logger.Logger.Debug(fmt.Sprintf("extref %s info:%+v", extrefid, extref))
- obj["attr_int_addr"] = extref.IntAddr
- ld, ln_desc, doi_desc = c.GetIntAddrDesc(mIed, extref.IntAddr)
- if ld != nil {
- obj["to_ld_inst"] = ld.Inst
- obj["to_ld_desc"] = ld.Desc
- }
- /*
- addrparts := strings.Split(extref.IntAddr, "/")
- to_ldinst := addrparts[0]
- //to_lnPri := addrparts[1] //ln标识符,由prefix+lnClass+inst.doname.daname组成
- to_lnPriParts := strings.Split(addrparts[1], ".")
- to_doname := to_lnPriParts[1]
- for _, ied := range mIed.AccessPoint {
- if ied.Server != nil {
- for _, ld := range ied.Server.LDevice {
- if ld.Inst == to_ldinst {
- obj["to_ld_inst"] = ld.Inst
- obj["to_ld_desc"] = ld.Desc
- for _, ln := range ld.LN {
- //logger.Logger.Debug(fmt.Sprintf("to: %s==%s", ln.Prefix+ln.LnClass+ln.Inst, to_lnPriParts[0]))
- if (ln.Prefix + ln.LnClass + ln.Inst) == to_lnPriParts[0] {
- ln_desc = ln.Desc
- for _, doi := range ln.DOI {
- if doi.Name == to_doname {
- doi_desc = doi.Desc
- break
- }
- }
- }
- if doi_desc != "" {
- break
- }
- }
- }
- if doi_desc != "" {
- break
- }
- }
- }
- if doi_desc != "" {
- break
- }
- }*/
- }
- obj["to_doi_desc"] = doi_desc
- obj["to_ln_desc"] = ln_desc
- rowset = append(rowset, obj)
- }
- }
- return rowset, nil
- }
- //获取指定FCDA的do或者Da描述
- func (c *ScdNode) GetFcdaDesc(mIed *node_attr.NIED, fcda *node_attr.NFCDA) (rld *node_attr.NLDevice, lndesc string, dodesc string) {
- doi_desc := ""
- ln_desc := ""
- if mIed == nil || fcda == nil {
- return nil, ln_desc, doi_desc
- }
- doParts := strings.Split(fcda.DoName, ".") //拆分do中的有效name部分
- to_doname := doParts[0]
- for _, ied := range mIed.AccessPoint {
- if ied.Server != nil {
- for _, ld := range ied.Server.LDevice {
- //logger.Logger.Debug(fmt.Sprintf(" ld========%s=============%s", ld.Inst, fcda.LdInst))
- if ld.Inst == fcda.LdInst {
- rld = ld
- if fcda.LnClass == "LLN0" {
- ln_desc = ld.LN0.Desc
- for _, doi := range ld.LN0.DOI {
- if doi.Name == to_doname {
- doi_desc = doi.Desc
- break
- }
- }
- break
- }
- for _, ln := range ld.LN {
- if ln.Inst == fcda.LnInst && ln.LnClass == fcda.LnClass && ln.Prefix == fcda.Prefix {
- ln_desc = ln.Desc
- //logger.Logger.Debug(fmt.Sprintf(" LN=====================%+v", ln))
- for _, doi := range ln.DOI {
- if doi.Name == to_doname {
- doi_desc = doi.Desc
- break
- }
- }
- }
- if doi_desc != "" {
- break
- }
- }
- }
- if doi_desc != "" {
- break
- }
- }
- }
- if doi_desc != "" {
- break
- }
- }
- return rld, ln_desc, doi_desc
- }
- //获取指定Extref的本地描述
- func (c *ScdNode) GetIntAddrDesc(mIed *node_attr.NIED, intAddr string) (rld *node_attr.NLDevice, lndesc string, dodesc string) {
- doi_desc := ""
- ln_desc := ""
- if mIed == nil || intAddr == "" {
- return nil, ln_desc, doi_desc
- }
- addrs := strings.Split(intAddr, ":")
- if len(addrs) == 2 {
- intAddr = addrs[1]
- }
- addrparts := strings.Split(intAddr, "/")
- to_ldinst := addrparts[0]
- //addrparts[1] //ln标识符,由prefix+lnClass+inst.doname.daname组成
- to_lnPriParts := strings.Split(addrparts[1], ".")
- to_doname := to_lnPriParts[1]
- for _, ied := range mIed.AccessPoint {
- if ied.Server != nil {
- for _, ld := range ied.Server.LDevice {
- if ld.Inst == to_ldinst {
- rld = ld
- for _, ln := range ld.LN {
- //logger.Logger.Debug(fmt.Sprintf("to: %s==%s", ln.Prefix+ln.LnClass+ln.Inst, to_lnPriParts[0]))
- if (ln.Prefix + ln.LnClass + ln.Inst) == to_lnPriParts[0] {
- ln_desc = ln.Desc
- for _, doi := range ln.DOI {
- if doi.Name == to_doname {
- doi_desc = doi.Desc
- break
- }
- }
- }
- if doi_desc != "" {
- break
- }
- }
- }
- if doi_desc != "" {
- break
- }
- }
- }
- if doi_desc != "" {
- break
- }
- }
- return rld, ln_desc, doi_desc
- }
- //获取指定IED的网络配置信息
- func (c *ScdNode) GetIedNetworkInfo(scdid int64, ied_name string) ([]orm.Params, error) {
- cacheKey := fmt.Sprintf("networkinfo_%d", scdid)
- if scdid == 0 {
- return nil, errors.New("SCD编号不能为空")
- }
- if ied_name == "" {
- return nil, errors.New("IED名称不能为空")
- }
- networkInfo := []orm.Params{}
- cachedata, h := global.GoCahce.Get(cacheKey)
- if h {
- t1 := cachedata.([]orm.Params)
- if ied_name != "" {
- for _, row := range t1 {
- if row["ied_name"] == ied_name {
- networkInfo = append(networkInfo, row)
- }
- }
- } else {
- networkInfo = t1
- }
- return networkInfo, nil
- }
- scdXmlObj, serr := new(ScdParse).GetScdXmlObjectBySCDID(tools.IsEmpty(scdid))
- if serr != nil {
- return nil, serr
- }
- if scdXmlObj == nil {
- return nil, errors.New("无效的SCD")
- }
- iedList := []orm.Params{}
- for _, item1 := range scdXmlObj.Communication.SubNetwork {
- net_type := "GSE"
- if len(item1.Name) >= 3 && item1.Name[0:3] == "MMS" {
- net_type = "MMS"
- }
- for _, item2 := range item1.ConnectedAP {
- if len(item2.SMV) > 0 {
- net_type = "SV"
- for _, svitem := range item2.SMV {
- obj := orm.Params{
- "ap_node_id": item2.NodeId,
- "ied_name": item2.IedName,
- "ap_name": item2.ApName,
- "subnetwork_name": item1.Name,
- "subnetwork_desc": item1.Desc,
- "subnetwork_type": item1.Type,
- "net_type": net_type,
- "net_node_id": svitem.NodeId,
- "cb_name": svitem.CbName,
- "ld_inst": svitem.LdInst,
- "address_json": "",
- }
- if svitem.Address != nil {
- jsonmap := map[string]string{}
- for _, r1 := range svitem.Address.P {
- jsonmap[r1.Type] = r1.InnerText
- }
- jsnstr, _ := json.Marshal(jsonmap)
- obj["address_json"] = string(jsnstr)
- }
- networkInfo = append(networkInfo, obj)
- if ied_name != "" && ied_name == item2.IedName {
- iedList = append(iedList, obj)
- }
- }
- } else if len(item2.GSE) > 0 {
- net_type = "GSE"
- for _, gseitem := range item2.GSE {
- obj := orm.Params{
- "ap_node_id": item2.NodeId,
- "ied_name": item2.IedName,
- "ap_name": item2.ApName,
- "subnetwork_name": item1.Name,
- "subnetwork_desc": item1.Desc,
- "subnetwork_type": item1.Type,
- "net_type": net_type,
- "net_node_id": gseitem.NodeId,
- "cb_name": gseitem.CbName,
- "ld_inst": gseitem.LdInst,
- "address_json": "",
- }
- if gseitem.Address != nil {
- jsonmap := map[string]string{}
- for _, r1 := range gseitem.Address.P {
- jsonmap[r1.Type] = r1.InnerText
- }
- jsnstr, _ := json.Marshal(jsonmap)
- obj["address_json"] = string(jsnstr)
- }
- networkInfo = append(networkInfo, obj)
- if ied_name != "" && ied_name == item2.IedName {
- iedList = append(iedList, obj)
- }
- }
- } else {
- obj := orm.Params{
- "ap_node_id": item2.NodeId,
- "ied_name": item2.IedName,
- "ap_name": item2.ApName,
- "subnetwork_name": item1.Name,
- "subnetwork_desc": item1.Desc,
- "subnetwork_type": item1.Type,
- "net_type": net_type,
- "net_node_id": item2.NodeId,
- "cb_name": "",
- "ld_inst": "",
- "address_json": "",
- }
- if item2.Address != nil {
- jsonmap := map[string]string{}
- for _, r1 := range item2.Address.P {
- jsonmap[r1.Type] = r1.InnerText
- }
- jsnstr, _ := json.Marshal(jsonmap)
- obj["address_json"] = string(jsnstr)
- }
- networkInfo = append(networkInfo, obj)
- if ied_name != "" && ied_name == item2.IedName {
- iedList = append(iedList, obj)
- }
- }
- }
- }
- global.GoCahce.Set(cacheKey, networkInfo, -1)
- if ied_name != "" {
- return iedList, nil
- }
- return networkInfo, nil
- }
- //获取指定IEd的指定GSEControl的网络配置信息
- func (c *ScdNode) GetIedGseNetWorkInfo(scdid int64, ied_name, gocb_name string) (orm.Params, error) {
- if scdid == 0 {
- return nil, errors.New("SCD编号不能为空")
- }
- if ied_name == "" {
- return nil, errors.New("IED名称不能为空")
- }
- if gocb_name == "" {
- return nil, errors.New("gocb_name不能为空")
- }
- iedNetinfo, er := c.GetIedNetworkInfo(scdid, ied_name)
- if er != nil {
- return nil, er
- }
- for _, row := range iedNetinfo {
- cb_name := tools.IsEmpty(row["cb_name"])
- if cb_name == gocb_name {
- return row, nil
- }
- }
- return nil, nil
- }
- func (c *ScdNode) Init(stationidint int, name, path string, isenable int, ischeckinscd int) (int64, error) {
- c.ScdName = name
- c.ScdPath = path
- c.StationID = stationidint
- c.NodeRuleList = map[string][]orm.Params{}
- c.NodeAttrRuleList = map[string][]orm.Params{}
- c.NodeAttrUniqueRuleList = []orm.Params{}
- c.NodeRuleFunctionList = []orm.Params{}
- c.NotEndNodeIdList = []int64{}
- c.NodeQue = map[int64]*t_scd_node_scl{}
- c.NodeAttrQue = []interface{}{}
- c.AreaMgr = new(ScdAreaMgr)
- m := t_scd_scl{ScdName: name, Path: path}
- m.IsCheckinScd = ischeckinscd
- m.Enable = isenable
- m.StationId = stationidint
- if c.RootID > 0 {
- m.Id = c.RootID
- }
- c.AreaMgr.ScdId = m.Id
- m.CreatedBy, _ = strconv.Atoi(c.GetUserId())
- m.CreatedTime = tools.NowTime()
- db := orm.NewOrm()
- _, err := db.Insert(&m)
- if err != nil {
- //判断SCD是否已经存在
- if !strings.Contains(err.Error(), "PRIMARY") {
- logger.Logger.Error(err, fmt.Sprintf("操作数据:%+v", m))
- return 0, err
- }
- }
- c.Name = name
- //初始化间隔管理
- c.AreaMgr.ScdId = m.Id //再次赋值,保证当scd不存在时,获取到新添加的SCD ID
- c.AreaMgr.Init(m.Id)
- //加载规则列表
- //获取节点验证规则定义
- lst := []orm.Params{}
- /*
- db.Raw("select * from t_scd_node_check").Values(&lst)
- for _, r := range lst {
- check_object := r["check_object"].(string)
- keys := strings.Split(check_object, ":")
- if ss, ok := c.NodeRuleList[keys[0]]; ok {
- c.NodeRuleList[keys[0]] = append(ss, r)
- } else {
- c.NodeRuleList[keys[0]] = []orm.Params{r}
- }
- }
- */
- //获取节点属性验证规则
- db.Raw("select * from t_scd_scl_check").Values(&lst)
- for _, r := range lst {
- object_name := r["object_name"].(string)
- object_type := r["object_type"].(string)
- if tools.IsEmpty(r["func_name"]) != "" {
- c.NodeRuleFunctionList = append(c.NodeRuleFunctionList, r)
- continue
- }
- //过滤出全局唯一或父节点下唯一的规则单独保存
- if tools.IsEmpty(r["isunique_by_parent"]) == "1" || tools.IsEmpty(r["isunique_by_global"]) == "1" {
- c.NodeAttrUniqueRuleList = append(c.NodeAttrUniqueRuleList, r)
- continue
- }
- if object_type == "node" {
- if ss, ok := c.NodeRuleList[object_name]; ok {
- c.NodeRuleList[object_name] = append(ss, r)
- } else {
- c.NodeRuleList[object_name] = []orm.Params{r}
- }
- } else {
- //node_path := tools.IsEmpty(r["node_path"])
- keys := strings.Split(object_name, "||")
- for _, k := range keys {
- if ss, ok := c.NodeAttrRuleList[k]; ok {
- c.NodeAttrRuleList[k] = append(ss, r)
- } else {
- c.NodeAttrRuleList[k] = []orm.Params{r}
- }
- }
- }
- }
- return m.Id, nil
- }
- func (c *ScdNode) AddNode(name string, attrs map[string]interface{}, lineno int64) error {
- m := new(t_scd_node_scl)
- m.CreatedBy = 0
- m.CreatedTime = tools.NowTime()
- m.NodeName = name
- m.NodeValue = ""
- m.LineNo = lineno
- m.ScdId = c.RootID
- m.Id = c.GetID()
- c.NodeQue[m.Id] = m
- if attrs != nil && len(attrs) > 0 {
- if name == "Bay" {
- //如果存在bay元素,则间隔方式为Bay解析
- c.IsBay = true
- }
- parentNodeNodeName := ""
- parentNode, ok := c.NodeQue[m.ParentNodeId]
- if ok {
- parentNodeNodeName = parentNode.NodeName
- }
- c.NodeAttrQue = append(c.NodeAttrQue, map[string]interface{}{"scdid": c.RootID, "parentNodeName": parentNodeNodeName, "nodeid": m.Id, "nodename": name, "lineno": m.LineNo, "attrs": attrs})
- if !c.IsBay && m.NodeName == "IED" {
- c.AreaMgr.AppendIedNode(c.RootID, m.Id, tools.IsEmpty(attrs["name"]), tools.IsEmpty(attrs["desc"]))
- }
- }
- return nil
- }
- func (c *ScdNode) EndNode(name, txt string) error {
- return nil
- }
- func (c *ScdNode) Flush() {
- //更新关联附件项的scd id
- new(AttachmentMgr).UpdateScdID(c.StationID, c.ScdName, c.ScdPath, c.RootID)
- //c.writeNodeDB()
- //c.writeNodeAttrDB()
- //通知SCD管理对象,解析完成,更新状态
- new(ScdMgr).ParseFinish(c.RootID, c.IsDefaultRunVersion)
- //test
- //c.GetIedInputsRelations(map[string]interface{}{"scd_id": c.RootID, "ied_name": "PB7520A"})
- /*
- if c.AutoCompScdID > 0 {
- comp := new(ScdCompare)
- comp.CompareType = "SCD"
- comp.Sourceid = c.RootID
- comp.Targetid = c.AutoCompScdID
- comp.StationId = c.StationID
- comp.Compare(0)
- }
- */
- }
- //获取指定SCD的校验码
- func (c *ScdNode) GetScdCRC(scdid string) (string, error) {
- scdXmlObj, serr := new(ScdParse).GetScdXmlObjectBySCDID(scdid)
- if serr != nil {
- return "", serr
- }
- if scdXmlObj == nil {
- return "", errors.New("无效的SCD")
- }
- for _, pri := range scdXmlObj.Private {
- if pri.Type == "Substation virtual terminal conection CRC" {
- return pri.InnerText, nil
- }
- }
- return "", nil
- }
- //获取指定SCD的校验码
- func (c *ScdNode) GetIedCRC(scdid, iedname string) (string, error) {
- scdXmlObj, serr := new(ScdParse).GetScdXmlObjectBySCDID(scdid)
- if serr != nil {
- return "", serr
- }
- if scdXmlObj == nil {
- return "", errors.New("无效的SCD")
- }
- iedObj := c.GetIed(scdXmlObj, scdid, iedname)
- if iedObj == nil {
- return "", errors.New("无效的IED装置名称")
- }
- for _, pri := range iedObj.Priavate {
- if pri.Type == "IED virtual terminal conection CRC" {
- return pri.InnerText, nil
- }
- }
- return "", nil
- }
- func (c *ScdNode) writeNodeDB() {
- stationIdStr := fmt.Sprintf("%d", c.StationID)
- scdIdStr := fmt.Sprintf("%d", c.RootID)
- db := orm.NewOrm()
- s1 := time.Now().Unix()
- nodeCols := "(id,scd_id,parent_node_id,node_name,node_value,line_no)"
- totalRec := tools.IsEmpty(len(c.NodeQue))
- loadedRec := 0
- nodeSqlValuesAry := []string{}
- data := map[string]string{"name": c.Name, "stationid": stationIdStr, "rootid": scdIdStr, "state": "0", "node": "write-db", "total": totalRec, "load": fmt.Sprintf("%d", loadedRec), "msg": ""}
- dataMsg, _ := json.Marshal(data)
- go mqtt.PublishMessage("/jujutong/scd_check_tools/parse/"+scdIdStr, string(dataMsg))
- for _, m := range c.NodeQue {
- nodeSqlValuesAry = append(nodeSqlValuesAry, fmt.Sprintf("(%d,%d,%d,'%s','%s',%d)", m.Id, m.ScdId, m.ParentNodeId, m.NodeName, m.NodeValue, m.LineNo))
- if len(nodeSqlValuesAry) == 5000 {
- sql := "insert into t_scd_node_scl" + nodeCols + "values" + strings.Join(nodeSqlValuesAry, ",")
- _, err := db.Raw(sql).Exec()
- if err != nil {
- logger.Logger.Error(err)
- }
- loadedRec = loadedRec + 5000
- nodeSqlValuesAry = []string{}
- data = map[string]string{"name": c.Name, "stationid": stationIdStr, "rootid": scdIdStr, "state": "2", "node": "write-db", "total": totalRec, "load": fmt.Sprintf("%d", loadedRec), "msg": ""}
- dataMsg, _ = json.Marshal(data)
- go mqtt.PublishMessage("/jujutong/scd_check_tools/parse/"+scdIdStr, string(dataMsg))
- }
- m = nil
- }
- if len(nodeSqlValuesAry) > 0 {
- sql := "insert into t_scd_node_scl" + nodeCols + "values" + strings.Join(nodeSqlValuesAry, ",")
- _, err := db.Raw(sql).Exec()
- if err != nil {
- log.Println(err)
- }
- nodeSqlValuesAry = nil
- }
- c.NodeQue = nil
- runtime.GC()
- data = map[string]string{"name": c.Name, "stationid": stationIdStr, "rootid": fmt.Sprintf("%d", c.RootID), "state": "1", "node": "write-db", "total": totalRec, "load": totalRec, "msg": ""}
- dataMsg, _ = json.Marshal(data)
- go mqtt.PublishMessage("/jujutong/scd_check_tools/parse/"+fmt.Sprintf("%d", c.RootID), string(dataMsg))
- s2 := time.Now().Unix()
- logger.Logger.Println(fmt.Sprintf("===================Flush NodeQue 完成!。耗时:%d秒", s2-s1))
- logger.Logger.Println("===========节点入库完成")
- }
- //查询定值
- func (t *ScdNode) GetScdIedDingzhiList(scdid int64, ied_name string) ([]orm.Params, error) {
- scdXmlObj, serr := new(ScdParse).GetScdXmlObjectBySCDID(tools.IsEmpty(scdid))
- if serr != nil {
- return nil, serr
- }
- if scdXmlObj == nil {
- return nil, errors.New("无效的SCD")
- }
- iedObj := t.GetIed(scdXmlObj, tools.IsEmpty(scdid), ied_name)
- if iedObj == nil {
- return nil, errors.New("无效的IED装置名称")
- }
- scdMgr := new(ScdMgr)
- mapTargetLNodeType := scdMgr.GetLNodeType(scdXmlObj)
- mapTargetLDoType := scdMgr.GetDOType(scdXmlObj)
- rowset := []orm.Params{}
- for _, acc := range iedObj.AccessPoint {
- if acc.Server != nil {
- for _, ld := range acc.Server.LDevice {
- if ld.LN0 != nil {
- for _, ds := range ld.LN0.DataSet {
- if ds.Name == "dsParameter" || ds.Name == "dsSetting" {
- obj := orm.Params{
- "accesspoint_name": acc.Name,
- "ld_desc": ld.Desc,
- "ld_name": ld.Inst,
- "dataset_desc": ds.Desc,
- "dataset_name": ds.Name,
- "list": []orm.Params{},
- }
- for _, fcda := range ds.FCDA {
- fcdaobj := orm.Params{}
- fcdaobj["short_addr"] = fmt.Sprintf("%s/%s%s%s.%s", fcda.LdInst, fcda.Prefix, fcda.LnClass, fcda.LnInst, fcda.DoName)
- fcdaobj["doi_name"] = fcda.DoName
- fcdaobj["doi_desc"] = ""
- fcdaobj["da_maxval"] = ""
- fcdaobj["da_minval"] = ""
- fcdaobj["da_stepsize"] = ""
- fcdaobj["da_units"] = ""
- found := false
- if fcda.LnClass == "LLN0" {
- if lnnodetpye, h := mapTargetLNodeType[ld.LN0.LnType]; h {
- for _, doitem := range lnnodetpye.DO {
- if doitem.Name == fcda.DoName {
- dotype := doitem.Type
- if dotypeobj, h := mapTargetLDoType[dotype]; h {
- fcdaobj["da_datatype"] = scdMgr.GetCdcDataTypeName(dotypeobj.Cdc)
- }
- break
- }
- }
- }
- for _, doi := range ld.LN0.DOI {
- if doi.Name == fcda.DoName {
- fcdaobj["doi_desc"] = doi.Desc
- for _, da := range doi.DAI {
- if da.Name == "maxVal" && da.Val != nil {
- fcdaobj["da_maxval"] = da.Val.InnerText
- }
- if da.Name == "minVal" && da.Val != nil {
- fcdaobj["da_minval"] = da.Val.InnerText
- }
- if da.Name == "stepSize" && da.Val != nil {
- fcdaobj["da_stepsize"] = da.Val.InnerText
- }
- if da.Name == "units" && da.Val != nil {
- fcdaobj["da_units"] = da.Val.InnerText
- }
- }
- found = true
- break
- }
- }
- } else {
- for _, ln := range ld.LN {
- if ln.LnClass == fcda.LnClass && ln.Inst == fcda.LnInst {
- if lnnodetpye, h := mapTargetLNodeType[ln.LnType]; h {
- for _, doitem := range lnnodetpye.DO {
- if doitem.Name == fcda.DoName {
- dotype := doitem.Type
- if dotypeobj, h := mapTargetLDoType[dotype]; h {
- fcdaobj["da_datatype"] = scdMgr.GetCdcDataTypeName(dotypeobj.Cdc)
- }
- break
- }
- }
- }
- for _, doi := range ln.DOI {
- if doi.Name == fcda.DoName {
- fcdaobj["doi_desc"] = doi.Desc
- for _, da := range doi.DAI {
- if da.Name == "maxVal" && da.Val != nil {
- fcdaobj["da_maxval"] = da.Val.InnerText
- }
- if da.Name == "minVal" && da.Val != nil {
- fcdaobj["da_minval"] = da.Val.InnerText
- }
- if da.Name == "stepSize" && da.Val != nil {
- fcdaobj["da_stepsize"] = da.Val.InnerText
- }
- if da.Name == "units" && da.Val != nil {
- fcdaobj["da_units"] = da.Val.InnerText
- }
- }
- if fcdaobj["da_maxval"] == "" {
- for _, sdi := range doi.SDI {
- if sdi.Name == "maxVal" {
- for _, dai2 := range sdi.DAI {
- if dai2.Name == "f" && dai2.Val != nil {
- fcdaobj["da_maxval"] = dai2.Val.InnerText
- }
- }
- }
- }
- }
- if fcdaobj["da_minval"] == "" {
- for _, sdi := range doi.SDI {
- if sdi.Name == "minVal" {
- for _, dai2 := range sdi.DAI {
- if dai2.Name == "f" && dai2.Val != nil {
- fcdaobj["da_minval"] = dai2.Val.InnerText
- }
- }
- }
- }
- }
- if fcdaobj["da_stepsize"] == "" {
- for _, sdi := range doi.SDI {
- if sdi.Name == "stepSize" {
- for _, dai2 := range sdi.DAI {
- if dai2.Name == "f" && dai2.Val != nil {
- fcdaobj["da_stepsize"] = dai2.Val.InnerText
- }
- }
- }
- }
- }
- unintsFound := false
- if fcdaobj["da_units"] == "" {
- for _, sdi := range doi.SDI {
- if sdi.Name == "units" {
- for _, dai2 := range sdi.DAI {
- if dai2.Name == "SIUnit" {
- for _, enumtype := range scdXmlObj.DataTypeTemplates.EnumType {
- if enumtype.Id == dai2.Name {
- for _, t123 := range enumtype.EnumVal {
- if dai2.Val == nil {
- fcdaobj["da_units"] = ""
- } else if t123.Ord == dai2.Val.InnerText {
- fcdaobj["da_units"] = t123.InnerText
- unintsFound = true
- break
- }
- }
- }
- if unintsFound {
- break
- }
- }
- }
- if unintsFound {
- break
- }
- }
- }
- if unintsFound {
- break
- }
- }
- }
- found = true
- break
- }
- }
- }
- if found {
- break
- }
- }
- }
- obj["list"] = append(obj["list"].([]orm.Params), fcdaobj)
- }
- rowset = append(rowset, obj)
- }
- }
- }
- }
- }
- }
- return rowset, nil
- }
- //查询信息点表
- func (t *ScdNode) GetScdIedPointTableList(scdid int64, ied_name string) ([]orm.Params, error) {
- scdXmlObj, serr := new(ScdParse).GetScdXmlObjectBySCDID(tools.IsEmpty(scdid))
- if serr != nil {
- return nil, serr
- }
- if scdXmlObj == nil {
- return nil, errors.New("无效的SCD")
- }
- iedObj := t.GetIed(scdXmlObj, tools.IsEmpty(scdid), ied_name)
- if iedObj == nil {
- return nil, errors.New("无效的IED装置名称")
- }
- scdMgr := new(ScdMgr)
- mapTargetLNodeType := scdMgr.GetLNodeType(scdXmlObj)
- mapTargetLDoType := scdMgr.GetDOType(scdXmlObj)
- rowset := []orm.Params{}
- for _, acc := range iedObj.AccessPoint {
- if acc.Server != nil {
- for _, ld := range acc.Server.LDevice {
- if ld.LN0 != nil {
- for _, rpc := range ld.LN0.ReportControl {
- obj := orm.Params{
- "accesspoint_name": acc.Name,
- "ld_desc": ld.Desc,
- "ld_inst": ld.Inst,
- "block_desc": rpc.Desc,
- "block_name": rpc.Name,
- "block_datset": rpc.DatSet,
- "block_rptid": rpc.RptID,
- "block_intgpd": rpc.IntgPd,
- "block_confrev": rpc.ConfRev,
- "block_buftime": rpc.BufTime,
- "block_buffered": rpc.Buffered,
- "list": []orm.Params{},
- }
- for _, ds := range ld.LN0.DataSet {
- if ds.Name == rpc.DatSet {
- for _, fcda := range ds.FCDA {
- fcdaobj := orm.Params{
- "short_addr": fmt.Sprintf("%s/%s%s%s.%s", fcda.LdInst, fcda.Prefix, fcda.LnClass, fcda.LnInst, fcda.DoName),
- "doi_name": fcda.DoName,
- "doi_desc": "",
- }
- found := false
- if fcda.LnClass == "LLN0" {
- if lnnodetpye, h := mapTargetLNodeType[ld.LN0.LnType]; h {
- for _, doitem := range lnnodetpye.DO {
- if doitem.Name == fcda.DoName {
- dotype := doitem.Type
- if dotypeobj, h := mapTargetLDoType[dotype]; h {
- fcdaobj["da_datatype"] = scdMgr.GetCdcDataTypeName(dotypeobj.Cdc)
- }
- break
- }
- }
- }
- for _, doi := range ld.LN0.DOI {
- if doi.Name == fcda.DoName {
- fcdaobj["doi_desc"] = doi.Desc
- found = true
- break
- }
- }
- } else {
- for _, ln := range ld.LN {
- if ln.LnClass == fcda.LnClass && ln.Inst == fcda.LnInst {
- if lnnodetpye, h := mapTargetLNodeType[ln.LnType]; h {
- for _, doitem := range lnnodetpye.DO {
- if doitem.Name == fcda.DoName {
- dotype := doitem.Type
- if dotypeobj, h := mapTargetLDoType[dotype]; h {
- fcdaobj["da_datatype"] = scdMgr.GetCdcDataTypeName(dotypeobj.Cdc)
- }
- break
- }
- }
- }
- for _, doi := range ln.DOI {
- if doi.Name == fcda.DoName {
- fcdaobj["doi_desc"] = doi.Desc
- found = true
- break
- }
- }
- }
- if found {
- break
- }
- }
- }
- obj["list"] = append(obj["list"].([]orm.Params), fcdaobj)
- }
- break
- }
- }
- rowset = append(rowset, obj)
- }
- }
- }
- }
- }
- return rowset, nil
- }
- //查询源XML
- func (t *ScdNode) GetScdIedSourceXML(scdid int64, ied_name string) (string, error) {
- scdXmlObj, serr := new(ScdParse).GetScdXmlObjectBySCDID(tools.IsEmpty(scdid))
- if serr != nil {
- return "", serr
- }
- if scdXmlObj == nil {
- return "", errors.New("无效的SCD")
- }
- startLineNo := int64(0)
- endLineNo := int64(0)
- for _, ied := range scdXmlObj.IED {
- if ied.Name == ied_name {
- //当前ied的开始行号
- startLineNo = ied.Lineno
- } else {
- if startLineNo > 0 {
- //结束行为下一个ied的开始行减1
- endLineNo = ied.Lineno - 1
- break
- }
- }
- }
- //判断是不是最后一ied
- if startLineNo > 0 && endLineNo == 0 {
- //最后一个ied的结束行号
- endLineNo = scdXmlObj.DataTypeTemplates.Lineno - 1
- }
- if startLineNo == 0 {
- return "", errors.New("无效的IED装置名称")
- }
- logger.Logger.Debug(fmt.Sprintf("====startLineNo:%d,endLineNo:%d====", startLineNo, endLineNo))
- scdinfo, _ := new(ScdMgr).One(tools.IsEmpty(scdid))
- scdpath := scdinfo["path"].(string)
- parsedFile := strings.ReplaceAll(scdpath, "\\", "/")
- _, err := os.Stat(parsedFile)
- if err != nil {
- logger.Logger.Error(err)
- return "", err
- }
- f, _ := os.Open(parsedFile)
- reslist := []string{}
- if f != nil {
- defer f.Close()
- r1 := bufio.NewReader(f)
- startLineNo = startLineNo - 1 //跳过第一行xml标记行
- lineno := int64(0) //初始行记数器。
- for {
- txt, err := r1.ReadString('\n')
- if err == io.EOF {
- break
- }
- if lineno >= startLineNo {
- reslist = append(reslist, txt)
- }
- lineno = lineno + 1
- if lineno == endLineNo {
- break
- }
- }
- }
- return strings.Join(reslist, ""), nil
- }
- //查询源XML
- func (t *ScdNode) GetScdLineSourceXML(scdid int64, lineno int64) ([]string, error) {
- scdXmlObj, serr := new(ScdParse).GetScdXmlObjectBySCDID(tools.IsEmpty(scdid))
- if serr != nil {
- return nil, serr
- }
- if scdXmlObj == nil {
- return nil, errors.New("无效的SCD")
- }
- startLineNo := int64(0)
- endLineNo := int64(0)
- if lineno < 0 {
- lineno = 0
- }
- if lineno < 100 {
- startLineNo = 0 //从最开始获取
- endLineNo = lineno + 100
- } else {
- startLineNo = lineno - 100
- endLineNo = lineno + 100
- }
- logger.Logger.Debug(fmt.Sprintf("====startLineNo:%d,endLineNo:%d====", startLineNo, endLineNo))
- scdinfo, _ := new(ScdMgr).One(tools.IsEmpty(scdid))
- scdpath := scdinfo["path"].(string)
- parsedFile := strings.ReplaceAll(scdpath, "\\", "/")
- _, err := os.Stat(parsedFile)
- if err != nil {
- logger.Logger.Error(err)
- return nil, err
- }
- f, _ := os.Open(parsedFile)
- reslist := []string{}
- if f != nil {
- defer f.Close()
- r1 := bufio.NewReader(f)
- startLineNo = startLineNo - 1 //跳过第一行xml标记行
- c_lineno := int64(0) //初始行记数器。
- for {
- txt, err := r1.ReadString('\n')
- if err == io.EOF {
- break
- }
- if c_lineno >= startLineNo {
- reslist = append(reslist, fmt.Sprintf("%d %s", c_lineno+1, txt))
- }
- c_lineno = c_lineno + 1
- if c_lineno == endLineNo {
- break
- }
- }
- }
- return reslist, nil
- }
|